使用 directfb绘制图像(draw image with directfb)

本文档详细介绍了如何使用DirectFB库在Linux环境下初始化帧缓冲,并创建和管理DirectFB表面,用于在全屏模式下绘制图像。代码示例包括了创建和释放DirectFB对象、设置合作级别、创建输入事件缓冲区、处理鼠标事件以及更新屏幕显示。此外,还展示了如何在屏幕上绘制鼠标光标并处理鼠标移动。

/**********************************************************************
** Copyright (C) 2010 FreeC ORG.  All rights reserved.
** Author: Carlson Lee.
**
** This file is part of FreeC.
**
** This file may be distributed and/or modified under the terms of the
** GNU General Public License version 2 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the
** packaging of this file.
**
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
**
** See http://freec.sourceforge.net
**
** Contact CarlsonLee_FreeC@hotmail.com if any conditions of this licensing are
** not clear to you.
**
**********************************************************************/
 
#include "config.h"
#include "typedef.h"
#include <linux/fb.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
//#include <asm/page.h>
#include <sys/mman.h>
#include <directfb.h>
 
#include <asm/errno.h>
#include <pthread.h>
#include "errcode.h"
#include "cncui.h"
#include "disp.h"
#include "cncdisplay.h"
#include "cnctask.h"
 
static IDirectFB *dfb = NULL;
static IDirectFBSurface *primary = NULL;
static IDirectFBDisplayLayer *layer = NULL;
static IDirectFBSurface *imageSurface = NULL;
static IDirectFBEventBuffer *mouse_events = NULL;
 
static pthread_mutex_t mutex_display = PTHREAD_MUTEX_INITIALIZER;
 
static UINT8 *pCursorBuf = NULL;
static UINT8 *mouse_bg_data = NULL;
 
#define DFBCHECK(x...)                                         /
{                                                            /
    DFBResult err = x;                                         /
    if (err != DFB_OK)                                         /
    {                                                        /
        printf("%s <%d>:/n/t", __FILE__, __LINE__ ); /
        DirectFBErrorFatal( #x, err );                         /
        goto exit;                                            /
    }                                                        /
}
#define MOUSE_WIDTH        12
#define MOUSE_HEIGHT    20
 
/* init framebuffer*/
CNC_RET dispInit(void)
{
    DFBSurfaceDescription dsc;
    pthread_t key_thread_id;    
 
    if(dfb || primary || imageSurface)
        return CERR_NONE;
 
    DFBCHECK (DirectFBInit (0, 0));
    DFBCHECK (DirectFBCreate (&dfb));
    DFBCHECK (dfb->SetCooperativeLevel (dfb, DFSCL_FULLSCREEN));
    dsc.flags = DSDESC_CAPS | DSDESC_WIDTH | DSDESC_HEIGHT | DSDESC_PIXELFORMAT;
    dsc.caps  = DSCAPS_PRIMARY;
    dsc.width   = SCREEN_WIDTH;
    dsc.height   = SCREEN_HEIGHT;
//#if BYTES_PER_PIXEL==3
//    dsc.pixelformat  = DSPF_RGB24 ;
//#elif BYTES_PER_PIXEL==4
    dsc.pixelformat  = DSPF_RGB32 ;
    dfb->GetDisplayLayer(dfb, 0, &layer);
    layer->EnableCursor(layer, 1);
//#endif
    DFBCHECK (dfb->CreateSurface( dfb, &dsc, &primary ));
    dsc.flags = DSDESC_WIDTH | DSDESC_HEIGHT | DSDESC_PIXELFORMAT;
    dsc.width   = SCREEN_WIDTH;
    dsc.height   = SCREEN_HEIGHT;
//#if BYTES_PER_PIXEL==3
//    dsc.pixelformat  = DSPF_RGB24 ;
//#elif BYTES_PER_PIXEL==4
    dsc.pixelformat  = DSPF_RGB32 ;
//#endif
    DFBCHECK(dfb->CreateSurface( dfb, &dsc, &imageSurface));
    DFBCHECK(dfb->CreateInputEventBuffer( dfb, DICAPS_ALL,
                                   DFB_FALSE, &mouse_events));
    printf("pthread_create procKeyMsg /n");
 
    if(0 != pthread_create(&key_thread_id,NULL,procKeyMsg,NULL))
    {
        printf("pthread_create procKeyMsg failed/n");
        goto exit;
    }
    pCursorBuf = (UINT8*)malloc(4*60*BYTES_PER_PIXEL);
    mouse_bg_data = (UINT8*)malloc(SCREEN_WIDTH*SCREEN_HEIGHT*4);
    return CERR_NONE;
exit:
    if(mouse_events)
        mouse_events->Release( mouse_events );
    if(imageSurface)
        imageSurface->Release( imageSurface );
    if(primary)
        primary->Release( primary );
    if(layer)
        layer->Release( layer );
    if(dfb)
        dfb->Release( dfb );
    return CERR_DISPLAY_INIT_FAIL;
}
 
void dispUninit()
{
    if(mouse_events)
        mouse_events->Release( mouse_events );
    if(imageSurface)
        imageSurface->Release( imageSurface );
    if(primary)
        primary->Release( primary );
    if(layer)
        layer->Release( layer );
    if(dfb)
        dfb->Release( dfb );
    if(pCursorBuf)
     {
         free(pCursorBuf);
         pCursorBuf = NULL;
     }
    if(mouse_bg_data)
     {
         free(mouse_bg_data);
         mouse_bg_data = NULL;
     }
 
    mouse_events = NULL;
    imageSurface = NULL;
    primary = NULL;
    dfb = NULL;
    pthread_mutex_destroy(&mutex_display);
}
 
 
const unsigned char mouse_data[720] =  
{
    0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  
    0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x01, 0x01, 0x01, 0xFF, 0xFF,  
    0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x01,  
    0x01, 0x01, 0x01, 0x01, 0x01, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  
    0xFF, 0xFF, 0xFF, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0xFF, 0xFF, 0xFF, 0x00,  
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  
    0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,  
    0x01, 0x01, 0x01, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x01, 0x01, 0x01, 0x01, 0x01,  
    0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00,  
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x01,  
    0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,  
    0x01, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  
    0xFF, 0xFF, 0xFF, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,  
    0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00,  
    0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,  
    0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0xFF,  
    0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x01, 0x01, 0x01, 0x01, 0x01,  
    0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,  
    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x01,  
    0x01, 0x01, 0x01, 0x01, 0x01, 0xFF, 0xFF, 0xFF, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0xFF, 0xFF,  
    0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  
    0xFF, 0xFF, 0xFF, 0x01, 0x01, 0x01, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x01,  
    0x01, 0x01, 0x01, 0x01, 0x01, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  
    0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  
    0xFF, 0xFF, 0xFF, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00,  
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00,  
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,  
    0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x01, 0x01,  
    0x01, 0x01, 0x01, 0x01, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  
    0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0xFF, 0xFF, 0xFF, 0x00, 0x00,  
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0xFF,  
    0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF,  
    0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
 
static int old_mouse_x = MOUSE_WIDTH/2;
static int old_mouse_y = MOUSE_HEIGHT/2;
static int old_mouse_width = -1;
static int old_mouse_height = -1;
static BOOL gbMouseShow = FALSE;
 
void    dispHideMouse()
{
    gbMouseShow = FALSE;
}
 
static void dispUpdateMouse(int x, int y)
{
    UINT8* display_buf = NULL;
    int display_buf_len = 0;
    DFBRectangle oldrect = {0,0,0,0};
    int mouse_width = MOUSE_WIDTH;
    int mouse_height = MOUSE_HEIGHT;
    int i, j;
 
    if(dfb==NULL || primary==NULL || imageSurface == NULL)
        return;
 
    if(x<0 || y<0 || x>=SCREEN_WIDTH || y>=SCREEN_HEIGHT)
        return;
 
    if(pthread_mutex_trylock(&mutex_display) == EBUSY)
         return;
 
    DFBCHECK(imageSurface->Lock(imageSurface, DSLF_WRITE, (void*)&display_buf, &display_buf_len));
    //copy old mouse bg buffer to screen
    if(old_mouse_x >=0 && old_mouse_y>=0 && old_mouse_width> 0 && old_mouse_height>0 && gbMouseShow)
    {
        if(old_mouse_x+MOUSE_WIDTH>SCREEN_WIDTH)
        {
            mouse_width = SCREEN_WIDTH - old_mouse_x;
        }
        if(old_mouse_y+MOUSE_HEIGHT>SCREEN_HEIGHT)
        {
            mouse_height = SCREEN_HEIGHT - old_mouse_y;
        }
        for(i=0; i<mouse_height; i++)
        {
            memcpy(display_buf+((old_mouse_y+i)*SCREEN_WIDTH+old_mouse_x)*BYTES_PER_PIXEL, mouse_bg_data+(i*MOUSE_WIDTH*BYTES_PER_PIXEL),mouse_width*BYTES_PER_PIXEL);
        }
        oldrect.x = old_mouse_x;
        oldrect.y = old_mouse_y;
        oldrect.w = mouse_width;
        oldrect.h = mouse_height;
    }
 
    //copy new mouse bg to old mouse bg buffer
    {
        if(x+MOUSE_WIDTH>SCREEN_WIDTH)
        {
            mouse_width = SCREEN_WIDTH - x;
        }
        if(y+MOUSE_HEIGHT>SCREEN_HEIGHT)
        {
            mouse_height = SCREEN_HEIGHT - y;
        }
        for(i=0; i<mouse_height; i++)
        {
            memcpy(mouse_bg_data+(i*MOUSE_WIDTH*BYTES_PER_PIXEL), display_buf+((y+i)*SCREEN_WIDTH+x)*BYTES_PER_PIXEL, mouse_width*BYTES_PER_PIXEL);
        }
        gbMouseShow = TRUE;
    }
    //set mouse icon to new place
    {
        //unsigned char *pTmp = mouse_data;
        if(x+MOUSE_WIDTH>SCREEN_WIDTH)
        {
            mouse_width = SCREEN_WIDTH - x;
        }
        if(y+MOUSE_HEIGHT>SCREEN_HEIGHT)
        {
            mouse_height = SCREEN_HEIGHT - y;
        }
        for(i=0; i<mouse_height; i++)
        {
            unsigned char* pTmp = (unsigned char*)mouse_data + i*MOUSE_WIDTH*3;
            for(j=0; j<mouse_width; j++)
            {
                if(*pTmp != 0x00)
                {
                    *(display_buf+((y+i)*SCREEN_WIDTH+x+j)*BYTES_PER_PIXEL) = *pTmp;
                    *(display_buf+((y+i)*SCREEN_WIDTH+x+j)*BYTES_PER_PIXEL+1) = *pTmp;
                    *(display_buf+((y+i)*SCREEN_WIDTH+x+j)*BYTES_PER_PIXEL+2) = *pTmp;
                //    *(display_buf+((y+i)*SCREEN_WIDTH+x+j)*BYTES_PER_PIXEL+3) = 0xFF;
                }
                pTmp+=3;
            }
        }
        old_mouse_x = x;
        old_mouse_y = y;
        old_mouse_width = mouse_height;
        old_mouse_height = mouse_width;
    }
 
    DFBCHECK(imageSurface->Unlock(imageSurface));
     primary->Blit (primary, imageSurface, &oldrect, oldrect.x, oldrect.y);
    oldrect.x = x;
    oldrect.y = y;
    oldrect.h = mouse_height;
    oldrect.w = mouse_width;
     primary->Blit (primary, imageSurface, &oldrect, oldrect.x, oldrect.y);
exit:
    pthread_mutex_unlock(&mutex_display);
    return;
}
 
int mouse_x = SCREEN_WIDTH/2;
int mouse_y = SCREEN_HEIGHT/2;
 
void* procKeyMsg(void* pParam)
{
    DFBInputEvent evt;
 
    mouse_events->WaitForEvent( mouse_events );
    cncTask_SetKeyThreadExited(FALSE);
    while (mouse_events->GetEvent( mouse_events, DFB_EVENT(&evt) ) == DFB_OK)
    {
        switch (evt.type)  
        {
        case DIET_KEYRELEASE:
            cncDisp_ProcMsg(UI_OPERATE_KEYUP, evt.key_symbol, 0);
            break;
        case DIET_KEYPRESS:
            cncDisp_ProcMsg(UI_OPERATE_KEYDOWN, evt.key_symbol, 0);
            break;
        case DIET_BUTTONPRESS:
            if(evt.buttons & DIBM_LEFT)
            {
                UINT32 lParam = ((mouse_y<<16)&0xFFFF0000)+mouse_x;
                cncDisp_ProcMsg(UI_OPERATE_LBTN_DOWN, 0, lParam);
            }
            if(evt.buttons & DIBM_RIGHT)
            {
                cncTask_SetExit(TRUE);
            }
            break;
        case DIET_BUTTONRELEASE:
            if(evt.button == DIBI_LEFT)
            {
                UINT32 lParam = ((mouse_y<<16)&0xFFFF0000)+mouse_x;
                cncDisp_ProcMsg(UI_OPERATE_LBTN_UP, 0, lParam);
            }
            break;
         case DIET_AXISMOTION:
         {
            if (evt.flags & DIEF_AXISREL)  
            {
                switch (evt.axis)  
                {
                case DIAI_X:
                     mouse_x += evt.axisrel;
                    break;
                case DIAI_Y:
                    mouse_y += evt.axisrel;
                    break;
                default:
                break;
                }
            }
            if(mouse_x>=SCREEN_WIDTH)
            {
                mouse_x =SCREEN_WIDTH-1;
            }
            if(mouse_x<0)
            {
                mouse_x =0;
            }
            if(mouse_y>=SCREEN_HEIGHT)
            {
                mouse_y =SCREEN_HEIGHT-1;
            }
            if(mouse_y<0)
            {
                mouse_y =0;
            }
            dispUpdateMouse(mouse_x,mouse_y);
            {
                UINT32 lParam = ((mouse_y<<16)&0xFFFF0000)+mouse_x;
                cncDisp_ProcMsg(UI_OPERATE_MOUSE_MOVE, 0, lParam);
            }
        }
        default:
           break;
        }
        if(cncTask_GetExit())
            break;
        mouse_events->WaitForEvent( mouse_events );
    }
    cncTask_SetKeyThreadExited(TRUE);
 
    return NULL;
}
 
void dispUpdateScreen()
{
    void* display_buf = NULL;
    int display_buf_len = 0;
    int i, j;
    const DFBRectangle rect = {0,0, SCREEN_WIDTH, SCREEN_HEIGHT};
    if(dfb==NULL || primary==NULL || imageSurface == NULL)
        return;
 
    if(pthread_mutex_trylock(&mutex_display) == EBUSY)
        return;
    disp_num++;
    DFBCHECK(imageSurface->Lock(imageSurface, DSLF_WRITE, &display_buf, &display_buf_len));
    printf("dispUpdateScreen = %d/n", disp_num);
    if(!uiGetBuffer(display_buf))
    {
        DFBCHECK(imageSurface->Unlock(imageSurface));
        pthread_mutex_unlock(&mutex_display);
        return;
    }
    
    for(i=0; i<old_mouse_width; i++)
    {
        memcpy(mouse_bg_data+(i*MOUSE_WIDTH*BYTES_PER_PIXEL), display_buf+((old_mouse_y+i)*SCREEN_WIDTH+old_mouse_x)*BYTES_PER_PIXEL, old_mouse_width*BYTES_PER_PIXEL);
    }
 
    if(gbMouseShow)
    {
        old_mouse_width = MOUSE_WIDTH;
        old_mouse_height = MOUSE_HEIGHT;
 
        if(old_mouse_x+MOUSE_WIDTH>SCREEN_WIDTH)
        {
            old_mouse_width = SCREEN_WIDTH - old_mouse_x;
        }
        if(old_mouse_y+MOUSE_HEIGHT>SCREEN_HEIGHT)
        {
            old_mouse_height = SCREEN_HEIGHT - old_mouse_y;
        }
        for(i=0; i<old_mouse_height; i++)
        {
            unsigned char* pTmp = (unsigned char*)mouse_data + i*MOUSE_WIDTH*3;
            for(j=0; j<old_mouse_width; j++)
            {
                if(*pTmp != 0x00)
                {
                    *((UINT8*)display_buf+((old_mouse_y+i)*SCREEN_WIDTH+old_mouse_x+j)*BYTES_PER_PIXEL) = *pTmp;
                    *((UINT8*)display_buf+((old_mouse_y+i)*SCREEN_WIDTH+old_mouse_x+j)*BYTES_PER_PIXEL+1) = *pTmp;
                    *((UINT8*)display_buf+((old_mouse_y+i)*SCREEN_WIDTH+old_mouse_x+j)*BYTES_PER_PIXEL+2) = *pTmp;
                }
                pTmp+=3;
            }
        }
    }
 
 
    DFBCHECK(imageSurface->Unlock(imageSurface));
    primary->Blit (primary, imageSurface, &rect, 0, 0);
exit:
    pthread_mutex_unlock(&mutex_display);
    return;
}

基于VM和secureCRT的linux开发板做智能终端电子相册要求密码锁登录,然后来到几个界面,第一个界面:功能的代表界面(如手动切,自动遍历,退出)第二个界面:手动切,点击特定区域范围 上下切换,退出返回到主界面,第三个界面:今日自动循环遍历图片,结束返回到第一个界面,界面是在开发板展示 这个是示例代码,按这个输出并解释一下各个代码的作用#include <stdio.h> #include <string.h> #include <stdlib.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> #include <sys/mman.h> #include <linux/input.h> char *picname[3] = {"04.bmp","05.bmp","06.bmp"};//picname[0] = "04.bmp" void show_color_w()//刷一个全屏白色 { //1、打开lcd文件 int lcd_fd = open("/dev/fb0",O_RDWR);//绝对路径 开发板 if(lcd_fd==-1) { printf("打开lcd失败\n"); } else { printf("打开lcdok\n"); } //2、内存映射 char *shared_addr = mmap(NULL,//系统自动分配 800*480*4,//申请空间大小 PROT_READ|PROT_WRITE,//权限 MAP_SHARED,//性质 lcd_fd,//文件描述符 0); //3、全屏白色 int x,y; for(x=0;x<800;x++) { for(y=0;y<480;y++) { shared_addr[0+4*x+4*800*y] = 255;//B shared_addr[1+4*x+4*800*y] = 255;//G shared_addr[2+4*x+4*800*y] = 255;//r shared_addr[3+4*x+4*800*y] = 0;//a } } //4、关闭 撤销 close(lcd_fd); munmap(shared_addr,800*480*4); } int show_bmp(int x,int y,char *pathname) { //1.lcd屏幕打开 int lcdfd = open("/dev/fb0",O_RDWR); if(lcdfd == -1) { perror("open lcd error\n"); return -1; } //2.bmp打开 int bmpfd = open(pathname,O_RDWR); if(bmpfd == -1) { perror("open bmp error\n"); return -1; } //3.内存映射 int *lcdmmap =(int *)mmap(NULL,800*480*4,PROT_WRITE|PROT_READ,MAP_SHARED,lcdfd,0); if(lcdmmap == NULL) { perror("mmap user error\n"); return -1; } //从图片中读取头文件 char headinfo[54]; read(bmpfd,headinfo,54); //从图片的头文件中获取图片的宽度和高度 int bmp_w = *((int *)&headinfo[18]); int bmp_h = *((int *)&headinfo[22]); printf("bmp_w =%d,bmp_h=%d\n",bmp_w,bmp_h); int win_size = (4-bmp_w*3%4)%4;//windows补齐的字节数 unsigned int bmp_lenth = bmp_w*3 + win_size;//图片一行的字节数=像素点个数*3+windows补齐的字节数 char *bmpbuf = malloc(bmp_lenth*bmp_h);//bmp图片总共的颜色数据 字节数 //4.跳过前54个字节 lseek(bmpfd,54,SEEK_SET); //5.读取bmp颜色数据 int ret = read(bmpfd,bmpbuf,bmp_lenth*bmp_h); if(ret == -1) { perror("read bmp error\n"); return -1; } unsigned int lcdbuf[bmp_w*bmp_h];//字节转换存储 //6.将24位颜色数据转换为32位 for(int j = 0;j<bmp_h;j++) { for(int i=0;i<bmp_w;i++) { lcdbuf[i+bmp_w*j] = (bmpbuf[3*i+0]<<0)+(bmpbuf[3*i+1]<<8)+(bmpbuf[3*i+2]<<16)+(0x00<<24); } bmpbuf += bmp_w*3+win_size; } //7.图片的翻转 for(int j = 0;j<bmp_h;j++) { for(int i=0;i<bmp_w;i++) { lcdmmap[(y+j)*800+(x+i)] = lcdbuf[(bmp_h-1-j)*bmp_w+i]; } } //8.关闭文件 撤销映射 munmap(lcdmmap,800*480*4); close(lcdfd); close(bmpfd); return 0; } //蓝色 void get_xy(int *x,int *y) { //1、打开触摸屏 int ts_fd = open("/dev/input/event0",O_RDWR); if(ts_fd==-1) { printf("触摸屏打开失败\n"); } else { printf("触摸屏打开成功\n"); } //2、分析结构体值 struct input_event ts; while(1) { read(ts_fd,&ts,sizeof(ts)); if(ts.type==EV_ABS)//判断有没有发生触摸屏事件 { if(ts.code==ABS_X)//进一步判断有没有发生x轴事件 { *x = ts.value*800/1024; } } if(ts.type==EV_ABS)//判断有没有发生触摸屏事件 { if(ts.code==ABS_Y)//进一步判断有没有发生y轴事件 { *y = ts.value*480/600; } } if(ts.type==EV_KEY && ts.code==BTN_TOUCH && ts.value==0) { printf("x:%d y:%d\n",*x,*y); break; } } //3、关闭 close(ts_fd); } void show_album()//手动 { int x,y; int i; i=0; //show_bmp(0,0,"04.bmp"); show_bmp(0,0,picname[i]); while(1) { get_xy(&x,&y); if(x<200)//上一张 { printf("上一张\n"); if(i==0) { i=3; } show_bmp(0,0,picname[--i]); } else if(x>200 && x<400)//退出 { break; } else if(x>600)//下一张 { printf("下一张\n"); if(i==3) { i=0; } show_bmp(0,0,picname[i++]); } } } void show_free()//自动播放 { int i ; for(i=0;i<=2;i++) { show_bmp(0,0,picname[i]); sleep(1); } } int main() { int x,y; show_color_w();//全屏的白色 show_bmp(100,100,"01.bmp");//先显示 show_bmp(300,100,"02.bmp"); show_bmp(500,100,"03.bmp"); while(1) { get_xy(&x,&y); if(x>100 && x<250 && y>100 && y<200)//1.手动相册 { printf("手动相册\n"); show_album(); } if(x>300 && x<450 && y>100 && y<200)//2.自动相册 { printf("自动相册\n"); show_free(); } if(x>500 && x<650 && y>100 && y<200)//3.退出 { printf("退出\n"); break; } } }
最新发布
11-02
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值