linux应用项目(一)数码相框数码相框之电子书

2019-07-13 08:53发布

一、整体思路

这一节我们重点学习框架,就是编程的思想。架构很重要。采用分层的思想,面向对象的编程思想。

1、怎样在LCD上显示一个文件


2、如何组织代码

分层的结构 main--draw--XXX_manager--fb.c等

二、分层编写-底层实现

1、显示部分代码编写

[cpp] view plain copy print?
  1. show_filedisplayfb.c  
  2. show_filedisplaydisp_manager.c  
  3. show_fileincludeconfig.h  
  4. show_fileincludedisp_manager.h  
  5. show_filedrawdraw.c  
show_filedisplayfb.c show_filedisplaydisp_manager.c show_fileincludeconfig.h show_fileincludedisp_manager.h show_filedrawdraw.c 先写fb.c 一面向对象编程思想 设置构造一个结构体 结构体需要有哪些成员呢: 显示部分,一定有一个显示函数,FB要显示就要初始化,所以有一个fb初始化函数,换页的时候我们要进行清屏操作,要有一个清屏函数,所以要有3个函数。 (1)    fb初始化 (2)    显示函数 (3)    清屏函数 只有函数还不全,还需要一些属性,如定义一个名字“fb”,X坐标,Y坐标,多少位表示一个像素等属性。 disp_manager.h中结构体设计如下 [cpp] view plain copy print?
  1. typedef struct DispOpr {  
  2.     char *name;  
  3.     int iXres;  
  4.     int iYres;  
  5.     int iBpp;  
  6.     int (*DeviceInit)(void);  
  7.     int (*ShowPixel)(int iPenX, int iPenY, unsigned int dwColor);  
  8.     int (*CleanScreen)(unsigned int dwBackColor);  
  9.     struct DispOpr *ptNext;  
  10. }T_DispOpr, *PT_DispOpr;  
typedef struct DispOpr { char *name; int iXres; int iYres; int iBpp; int (*DeviceInit)(void); int (*ShowPixel)(int iPenX, int iPenY, unsigned int dwColor); int (*CleanScreen)(unsigned int dwBackColor); struct DispOpr *ptNext; }T_DispOpr, *PT_DispOpr;fb.c初始化结构体,并写出对应的函数。
[cpp] view plain copy print?
  1. static T_DispOpr g_tFBOpr = {  
  2.     .name        = "fb",  
  3.     .DeviceInit  = FBDeviceInit,  
  4.     .ShowPixel   = FBShowPixel,  
  5.     .CleanScreen = FBCleanScreen,  
  6. };  
static T_DispOpr g_tFBOpr = { .name = "fb", .DeviceInit = FBDeviceInit, .ShowPixel = FBShowPixel, .CleanScreen = FBCleanScreen, }; 结构体用到这些函数 ,所以事先声明一下,都是static所以只能在本文件中使用,外面想用只能通过上一层。 [cpp] view plain copy print?
  1. static int FBDeviceInit(void);  
  2. static int FBShowPixel(int iX, int iY, unsigned int dwColor);  
  3. static int FBCleanScreen(unsigned int dwBackColor);  
static int FBDeviceInit(void); static int FBShowPixel(int iX, int iY, unsigned int dwColor); static int FBCleanScreen(unsigned int dwBackColor); 在哪注册? [cpp] view plain copy print?
  1. int FBInit(void)  
  2. {  
  3.     return RegisterDispOpr(&g_tFBOpr);  
  4. }  
int FBInit(void) { return RegisterDispOpr(&g_tFBOpr); } 这里就不能写成static了。 注册就是把结构体加入链表中,链表比数组更灵活,大小随意。 一开始链表头是空的,所以让指针指向这个结构体。在注册就让next指向新结构体。 实现三个函数: 注意这里是应用程序所以是一些open,read等函数。 如:g_fd = open(FB_DEVICE_NAME, O_RDWR); 这里不应该把设备名字定死,所以写一个config文件 [cpp] view plain copy print?
  1. #ifndef _CONFIG_H  
  2. #define _CONFIG_H  
  3.   
  4. #include   
  5.   
  6. #define FB_DEVICE_NAME "/dev/fb0"  
  7.   
  8. #define COLOR_BACKGROUND   0xE7DBB5  /* 泛黄的纸 */  
  9. #define COLOR_FOREGROUND   0x514438  /* 褐 {MOD}字体 */  
  10.   
  11. #define DBG_PRINTF(...)    
  12. //#define DBG_PRINTF printf  
  13.   
  14. #endif /* _CONFIG_H */  
#ifndef _CONFIG_H #define _CONFIG_H #include #define FB_DEVICE_NAME "/dev/fb0" #define COLOR_BACKGROUND 0xE7DBB5 /* 泛黄的纸 */ #define COLOR_FOREGROUND 0x514438 /* 褐 {MOD}字体 */ #define DBG_PRINTF(...) //#define DBG_PRINTF printf #endif /* _CONFIG_H */ DBG_PRINTF:这个宏可以控制打印开关。 显示做好了,但是我们显示内容在哪呢?需要设置显示字体,得到显示的点阵。如显示ASCII还是ABK,还是freetype。同理写出这部分代码。 代码: fb.c:重点是结构 [cpp] view plain copy print?
  1. #include   
  2. #include   
  3. #include   
  4. #include   
  5. #include   
  6. #include   
  7. #include   
  8. #include   
  9. #include   
  10.   
  11. static int FBDeviceInit(void);  
  12. static int FBShowPixel(int iX, int iY, unsigned int dwColor);  
  13. static int FBCleanScreen(unsigned int dwBackColor);  
  14.   
  15.   
  16. static int g_fd;  
  17.   
  18. static struct fb_var_screeninfo g_tFBVar;  //可变参数  
  19. static struct fb_fix_screeninfo g_tFBFix;    //固定参数  
  20. static unsigned char *g_pucFBMem;          //内存映射  
  21. static unsigned int g_dwScreenSize;        //FB屏幕大小  
  22.   
  23. static unsigned int g_dwLineWidth;         //一行宽度:一行的像素*像素位数/8字节      
  24. static unsigned int g_dwPixelWidth;        //每个像素占据多少字节:BPP/8=2字节(一个像素占据2字节)  
  25.   
  26. static T_DispOpr g_tFBOpr = {  
  27.     .name        = "fb",  
  28.     .DeviceInit  = FBDeviceInit,  
  29.     .ShowPixel   = FBShowPixel,  
  30.     .CleanScreen = FBCleanScreen,  
  31. };  
  32.   
  33. static int FBDeviceInit(void)  
  34. {  
  35.     int ret;  
  36.       
  37.     g_fd = open(FB_DEVICE_NAME, O_RDWR);  
  38.     if (0 > g_fd)  
  39.     {  
  40.         DBG_PRINTF("can't open %s ", FB_DEVICE_NAME);  
  41.     }  
  42.   
  43.     ret = ioctl(g_fd, FBIOGET_VSCREENINFO, &g_tFBVar);  
  44.     if (ret < 0)  
  45.     {  
  46.         DBG_PRINTF("can't get fb's var ");  
  47.         return -1;  
  48.     }  
  49.   
  50.     ret = ioctl(g_fd, FBIOGET_FSCREENINFO, &g_tFBFix);  
  51.     if (ret < 0)  
  52.     {  
  53.         DBG_PRINTF("can't get fb's fix ");  
  54.         return -1;  
  55.     }  
  56.       
  57.     g_dwScreenSize = g_tFBVar.xres * g_tFBVar.yres * g_tFBVar.bits_per_pixel / 8;  
  58.     g_pucFBMem = (unsigned char *)mmap(NULL , g_dwScreenSize, PROT_READ | PROT_WRITE, MAP_SHARED, g_fd, 0);  
  59.     if (0 > g_pucFBMem)    
  60.     {  
  61.         DBG_PRINTF("can't mmap ");  
  62.         return -1;  
  63.     }  
  64.   
  65.     g_tFBOpr.iXres       = g_tFBVar.xres;  
  66.     g_tFBOpr.iYres       = g_tFBVar.yres;  
  67.     g_tFBOpr.iBpp        = g_tFBVar.bits_per_pixel;  //设置坐标和多少位表示一个像素  
  68.   
  69.     g_dwLineWidth  = g_tFBVar.xres * g_tFBVar.bits_per_pixel / 8;  
  70.     g_dwPixelWidth = g_tFBVar.bits_per_pixel / 8;  
  71.       
  72.     return 0;  
  73. }  
  74.   
  75. //RRGGBB  16: 24转成565  
  76. static int FBShowPixel(int iX, int iY, unsigned int dwColor)  
  77. {  
  78.     unsigned char *pucFB;  
  79.     unsigned short *pwFB16bpp;  
  80.     unsigned int *pdwFB32bpp;  
  81.     unsigned short wColor16bpp; /* 565 */  
  82.     int iRed;  
  83.     int iGreen;  
  84.     int iBlue;  
  85.   
  86.     if ((iX >= g_tFBVar.xres) || (iY >= g_tFBVar.yres))  
  87.     {  
  88.         DBG_PRINTF("out of region ");  
  89.         return -1;  
  90.     }  
  91.   
  92.     pucFB      = g_pucFBMem + g_dwLineWidth * iY + g_dwPixelWidth * iX;  
  93.     pwFB16bpp  = (unsigned short *)pucFB;  
  94.     pdwFB32bpp = (unsigned int *)pucFB;  
  95.       
  96.     switch (g_tFBVar.bits_per_pixel)  
  97.     {  
  98.         case 8:  
  99.         {  
  100.             *pucFB = (unsigned char)dwColor;  
  101.             break;  
  102.         }  
  103.         case 16:  
  104.         {  
  105.             iRed   = (dwColor >> (16+3)) & 0x1f;  
  106.             iGreen = (dwColor >> (8+2)) & 0x3f;  
  107.             iBlue  = (dwColor >> 3) & 0x1f;  
  108.             wColor16bpp = (iRed << 11) | (iGreen << 5) | iBlue;  
  109.             *pwFB16bpp  = wColor16bpp;  
  110.             break;  
  111.         }  
  112.         case 32:  
  113.         {  
  114.             *pdwFB32bpp = dwColor;  
  115.             break;  
  116.         }  
  117.         default :  
  118.         {  
  119.             DBG_PRINTF("can't support %d bpp ", g_tFBVar.bits_per_pixel);  
  120.             return -1;  
  121.         }  
  122.     }  
  123.   
  124.     return 0;  
  125. }  
  126.   
  127. static int FBCleanScreen(unsigned int dwBackColor)  
  128. {  
  129.     unsigned char *pucFB;  
  130.     unsigned short *pwFB16bpp;  
  131.     unsigned int *pdwFB32bpp;  
  132.     unsigned short wColor16bpp; /* 565 */  
  133.     int iRed;  
  134.     int iGreen;  
  135.     int iBlue;  
  136.     int i = 0;  
  137.   
  138.     pucFB      = g_pucFBMem;  
  139.     pwFB16bpp  = (unsigned short *)pucFB;  
  140.     pdwFB32bpp = (unsigned int *)pucFB;  
  141.   
  142.     switch (g_tFBVar.bits_per_pixel)  
  143.     {  
  144.         case 8:  
  145.         {  
  146.             memset(g_pucFBMem, dwBackColor, g_dwScreenSize);  
  147.             break;  
  148.         }  
  149.         case 16:  
  150.         {  
  151.             iRed   = (dwBackColor >> (16+3)) & 0x1f;  
  152.             iGreen = (dwBackColor >> (8+2)) & 0x3f;  
  153.             iBlue  = (dwBackColor >> 3) & 0x1f;  
  154.             wColor16bpp = (iRed << 11) | (iGreen << 5) | iBlue;  
  155.             while (i < g_dwScreenSize)  
  156.             {  
  157.                 *pwFB16bpp  = wColor16bpp;  
  158.                 pwFB16bpp++;  
  159.                 i += 2;  
  160.             }  
  161.             break;  
  162.         }  
  163.         case 32:  
  164.         {  
  165.             while (i < g_dwScreenSize)  
  166.             {  
  167.                 *pdwFB32bpp = dwBackColor;  
  168.                 pdwFB32bpp++;  
  169.                 i += 4;  
  170.             }  
  171.             break;  
  172.         }  
  173.         default :  
  174.         {  
  175.             DBG_PRINTF("can't support %d bpp ", g_tFBVar.bits_per_pixel);  
  176.             return -1;  
  177.         }  
  178.     }  
  179.   
  180.     return 0;  
  181. }  
  182.   
  183. int FBInit(void)  
  184. {  
  185.     return RegisterDispOpr(&g_tFBOpr);  
  186. }  
#include #include #include #include #include #include #include #include #include static int FBDeviceInit(void); static int FBShowPixel(int iX, int iY, unsigned int dwColor); static int FBCleanScreen(unsigned int dwBackColor); static int g_fd; static struct fb_var_screeninfo g_tFBVar; //可变参数 static struct fb_fix_screeninfo g_tFBFix; //固定参数 static unsigned char *g_pucFBMem; //内存映射 static unsigned int g_dwScreenSize; //FB屏幕大小 static unsigned int g_dwLineWidth; //一行宽度:一行的像素*像素位数/8字节 static unsigned int g_dwPixelWidth; //每个像素占据多少字节:BPP/8=2字节(一个像素占据2字节) static T_DispOpr g_tFBOpr = { .name = "fb", .DeviceInit = FBDeviceInit, .ShowPixel = FBShowPixel, .CleanScreen = FBCleanScreen, }; static int FBDeviceInit(void) { int ret; g_fd = open(FB_DEVICE_NAME, O_RDWR); if (0 > g_fd) { DBG_PRINTF("can't open %s ", FB_DEVICE_NAME); } ret = ioctl(g_fd, FBIOGET_VSCREENINFO, &g_tFBVar); if (ret < 0) { DBG_PRINTF("can't get fb's var "); return -1; } ret = ioctl(g_fd, FBIOGET_FSCREENINFO, &g_tFBFix); if (ret < 0) { DBG_PRINTF("can't get fb's fix "); return -1; } g_dwScreenSize = g_tFBVar.xres * g_tFBVar.yres * g_tFBVar.bits_per_pixel / 8; g_pucFBMem = (unsigned char *)mmap(NULL , g_dwScreenSize, PROT_READ | PROT_WRITE, MAP_SHARED, g_fd, 0); if (0 > g_pucFBMem) { DBG_PRINTF("can't mmap "); return -1; } g_tFBOpr.iXres = g_tFBVar.xres; g_tFBOpr.iYres = g_tFBVar.yres; g_tFBOpr.iBpp = g_tFBVar.bits_per_pixel; //设置坐标和多少位表示一个像素 g_dwLineWidth = g_tFBVar.xres * g_tFBVar.bits_per_pixel / 8; g_dwPixelWidth = g_tFBVar.bits_per_pixel / 8; return 0; } //RRGGBB 16: 24转成565 static int FBShowPixel(int iX, int iY, unsigned int dwColor) { unsigned char *pucFB; unsigned short *pwFB16bpp; unsigned int *pdwFB32bpp; unsigned short wColor16bpp; /* 565 */ int iRed; int iGreen; int iBlue; if ((iX >= g_tFBVar.xres) || (iY >= g_tFBVar.yres)) { DBG_PRINTF("out of region "); return -1; } pucFB = g_pucFBMem + g_dwLineWidth * iY + g_dwPixelWidth * iX; pwFB16bpp = (unsigned short *)pucFB; pdwFB32bpp = (unsigned int *)pucFB; switch (g_tFBVar.bits_per_pixel) { case 8: { *pucFB = (unsigned char)dwColor; break; } case 16: { iRed = (dwColor >> (16+3)) & 0x1f; iGreen = (dwColor >> (8+2)) & 0x3f; iBlue = (dwColor >> 3) & 0x1f; wColor16bpp = (iRed << 11) | (iGreen << 5) | iBlue; *pwFB16bpp = wColor16bpp; break; } case 32: { *pdwFB32bpp = dwColor; break; } default : { DBG_PRINTF("can't support %d bpp ", g_tFBVar.bits_per_pixel); return -1; } } return 0; } static int FBCleanScreen(unsigned int dwBackColor) { unsigned char *pucFB; unsigned short *pwFB16bpp; unsigned int *pdwFB32bpp; unsigned short wColor16bpp; /* 565 */ int iRed; int iGreen; int iBlue; int i = 0; pucFB = g_pucFBMem; pwFB16bpp = (unsigned short *)pucFB; pdwFB32bpp = (unsigned int *)pucFB; switch (g_tFBVar.bits_per_pixel) { case 8: { memset(g_pucFBMem, dwBackColor, g_dwScreenSize); break; } case 16: { iRed = (dwBackColor >> (16+3)) & 0x1f; iGreen = (dwBackColor >> (8+2)) & 0x3f; iBlue = (dwBackColor >> 3) & 0x1f; wColor16bpp = (iRed << 11) | (iGreen << 5) | iBlue; while (i < g_dwScreenSize) { *pwFB16bpp = wColor16bpp; pwFB16bpp++; i += 2; } break; } case 32: { while (i < g_dwScreenSize) { *pdwFB32bpp = dwBackColor; pdwFB32bpp++; i += 4; } break; } default : { DBG_PRINTF("can't support %d bpp ", g_tFBVar.bits_per_pixel); return -1; } } return 0; } int FBInit(void) { return RegisterDispOpr(&g_tFBOpr); }disp_manager.c:重点是链表操作 [cpp] view plain copy print?
  1. #include   
  2. #include   
  3. #include   
  4.   
  5. static PT_DispOpr g_ptDispOprHead;  
  6.   
  7. int RegisterDispOpr(PT_DispOpr ptDispOpr)  
  8. {  
  9.     PT_DispOpr ptTmp;  
  10.   
  11.     if (!g_ptDispOprHead)  
  12.     {  
  13.         g_ptDispOprHead   = ptDispOpr;  
  14.         ptDispOpr->ptNext = NULL;  
  15.     }  
  16.     else  
  17.     {  
  18.         ptTmp = g_ptDispOprHead;  
  19.         while (ptTmp->ptNext)  
  20.         {  
  21.             ptTmp = ptTmp->ptNext;  
  22.         }  
  23.         ptTmp->ptNext      = ptDispOpr;  
  24.         ptDispOpr->ptNext = NULL;  
  25.     }  
  26.   
  27.     return 0;  
  28. }  
  29.   
  30.   
  31. void ShowDispOpr(void)  
  32. {  
  33.     int i = 0;  
  34.     PT_DispOpr ptTmp = g_ptDispOprHead;  
  35.   
  36.     while (ptTmp)  
  37.     {  
  38.         printf("%02d %s ", i++, ptTmp->name);  
  39.         ptTmp = ptTmp->ptNext;  
  40.     }  
  41. }  
  42.   
  43. PT_DispOpr GetDispOpr(char *pcName)  
  44. {  
  45.     PT_DispOpr ptTmp = g_ptDispOprHead;  
  46.       
  47.     while (ptTmp)  
  48.     {  
  49.         if (strcmp(ptTmp->name, pcName) == 0)  
  50.         {  
  51.             return ptTmp;  
  52.         }  
  53.         ptTmp = ptTmp->ptNext;  
  54.     }  
  55.     return NULL;  
  56. }  
  57.   
  58. int DisplayInit(void)  
  59. {  
  60.     int iError;  
  61.       
  62.     iError = FBInit();  
  63.   
  64.     return iError;  
  65. }  
#include #include #include static PT_DispOpr g_ptDispOprHead; int RegisterDispOpr(PT_DispOpr ptDispOpr) { PT_DispOpr ptTmp; if (!g_ptDispOprHead) { g_ptDispOprHead = ptDispOpr; ptDispOpr->ptNext = NULL; } else { ptTmp = g_ptDispOprHead; while (ptTmp->ptNext) { ptTmp = ptTmp->ptNext; } ptTmp->ptNext = ptDispOpr; ptDispOpr->ptNext = NULL; } return 0; } void ShowDispOpr(void) { int i = 0; PT_DispOpr ptTmp = g_ptDispOprHead; while (ptTmp) { printf("%02d %s ", i++, ptTmp->name); ptTmp = ptTmp->ptNext; } } PT_DispOpr GetDispOpr(char *pcName) { PT_DispOpr ptTmp = g_ptDispOprHead; while (ptTmp) { if (strcmp(ptTmp->name, pcName) == 0) { return ptTmp; } ptTmp = ptTmp->ptNext; } return NULL; } int DisplayInit(void) { int iError; iError = FBInit(); return iError; }

2、字体部分编写

思路如上一样,分配、设置、注册结构体。

3、编码部分编写

思路如上一样,分配、设置、注册结构体。

三、分层编写-上层实现

1、draw.c

组织底层代码

2、main.c

解析命令-打开文本-显示文本-换页-返回上一页等 [cpp] view plain copy print?
  1. #include   
  2. #include   
  3. #include   
  4. #include   
  5. #include   
  6. #include   
  7. #include   
  8. #include   
  9. #include   
  10.   
  11.   
  12. /* ./show_file [-s Size] [-f freetype_font_file] [-h HZK]  */  
  13. int main(int argc, char **argv)  
  14. {  
  15.     int iError;  
  16.     unsigned int dwFontSize = 16;  
  17.     char acHzkFile[128];  
  18.     char acFreetypeFile[128];  
  19.     char acTextFile[128];  
  20.   
  21.     char acDisplay[128];  
  22.   
  23.     char cOpr;  
  24.     int bList = 0;  
  25.   
  26.     acHzkFile[0]  = '