Chinaunix首页 | 论坛 | 博客
  • 博客访问: 301088
  • 博文数量: 76
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 715
  • 用 户 组: 普通用户
  • 注册时间: 2015-05-20 20:38
文章分类
文章存档

2016年(20)

2015年(56)

分类: 嵌入式

2015-08-23 16:39:07

display_manager.c

15年8月22日12:55:21

#include <config.h>

#include <disp_manager.h>

#include <string.h>


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\n", 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;

}


display_manager.h

#ifndef _DISP_MANAGER_H

#define _DISP_MANAGER_H


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;


int RegisterDispOpr(PT_DispOpr ptDispOpr);

void ShowDispOpr(void);

int DisplayInit(void);

int FBInit(void);


#endif /* _DISP_MANAGER_H */


下面来分析这两个文件:

首先来分析display_manager.h这个头文件:

1)文件的开头用了一个这样的技巧,是为了防止包含重复的头文件,这个技巧应该会运用。

#ifndef _DISP_MANAGER_H

#define _DISP_MANAGER_H

2)分析DispOpr 这个结构体:

typedef struct DispOpr {

char *name; /* 名称,根据名字来找到这个设备 */

int iXres; /* x方向的最大分辨率 */

int iYres; /* y方向的最大分辨率 */

int iBpp; /* bit per pixel */

int (*DeviceInit)(void); /* 初始化设备 */

int (*ShowPixel)(int iPenX, int iPenY, unsigned int dwColor);

/* (iPenXiPenY)这个点上显示 dwColor这个颜色 */

int (*CleanScreen)(unsigned int dwBackColor); /* 清屏 */

struct DispOpr *ptNext; /* 链表中指向下一个结构体的指针 */

}T_DispOpr, *PT_DispOpr;

这个结构体中这样设置成员是因为在显示的时候,需要使用到比如说lcd屏幕的xy方向的最大值,bpp等信息,同时,包含显示所用到的函数,包括设备的初始化DeviceInit,显示像素 ShowPixel和清屏 CleanScreen等操作。对于每一个显示器,它都应该对应一个这样的结构体,而这个结构体应该包含所有显示器用到的所有特点。


3)其他的是diaplay_manager.c中定义的函数的声明。


下面分析diaplay_manager.c这个文件:

diaplay_manager.c这个文件中定义了可以供draw.c调用的用于显示的函数。

1)首先定义一个链表头:static PT_DispOpr g_ptDispOprHead;这个电子书所有支持的显示器都包含在这个链表中,如fbLCD)和crt(串口)。

2)注册显示器操作函数,每个显示器对应一个 PT_DispOpr结构体,这个函数是将所有的显示器对应的结构体添加到 g_ptDispOprHead这个链表中,这样用到的时候就可以通过名字来从这个链表中找到对应的结构体,找到以后在初始化这个显示器。

int RegisterDispOpr(PT_DispOpr ptDispOpr)

{

PT_DispOpr ptTmp;


if (!g_ptDispOprHead)

{

g_ptDispOprHead = ptDispOpr;

ptDispOpr->ptNext = NULL;

}

/* 如果链表头为空的话, ptDispOpr就为这个链表中的第一项,同时, ptDispOpr->ptNext

* 向一个NULL,这是链表的基本操作。

*/

else

{

ptTmp = g_ptDispOprHead;

while (ptTmp->ptNext)

{

ptTmp = ptTmp->ptNext;

}

ptTmp->ptNext = ptDispOpr;

ptDispOpr->ptNext = NULL;

}

/* 如果链表头不为空,用while循环来遍历链表,直到找到这个链表的最后一项(即ptTmp->ptNext

* 空的一项),将最后一项的ptNext指向新加入的结构体,同时 ptDispOpr->ptNext指向NULL

*/

return 0;

}

函数返回值: 成功 --- 0

失败 --- 其他值

3)这个函数将链表中的每一项一一取出,打印出来他们的名字。

void ShowDispOpr(void)

{

int i = 0;

PT_DispOpr ptTmp = g_ptDispOprHead;


while (ptTmp) /* 遍历链表中的每一项 */

{

printf("%02d %s\n", i++, ptTmp->name);

ptTmp = ptTmp->ptNext;

}

}

4)获取显示操作函数:

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;

}

/* 将函数传进来的参数pcName与链表中每一项的名字做比较,如果相同,就返回这个结构体,如果遍历

* 链表以后仍没有找到名字相同的一项,则返回NULL

*/

5)显示器初始化函数:

int DisplayInit(void)

{

int iError;

iError = FBInit();


return iError;

}

/* 这个函数只是调用 FBInit()函数注册了一下。 */


阅读(1396) | 评论(0) | 转发(0) |
0

上一篇:freetype-example1.c

下一篇:电子书-Draw.c

给主人留下些什么吧!~~