Chinaunix首页 | 论坛 | 博客
  • 博客访问: 389149
  • 博文数量: 107
  • 博客积分: 2536
  • 博客等级: 少校
  • 技术积分: 781
  • 用 户 组: 普通用户
  • 注册时间: 2009-06-14 15:19
文章分类

全部博文(107)

文章存档

2017年(11)

2016年(8)

2015年(14)

2014年(32)

2012年(1)

2011年(1)

2010年(7)

2009年(33)

我的朋友

分类: 嵌入式

2010-06-02 19:12:51

                              清单 5  Native 图形引擎的核心数据结构

typedef struct _screendevice {
int xres; /* X screen res (real) */
int yres; /* Y screen res (real) */
int planes; /* # planes*/
int bpp; /* # bits per pixel*/
int linelen; /* line length in bytes for bpp 1,2,4,8, line length in pixels for bpp 16, 24, 32*/
int size; /* size of memory allocated*/
gfx_pixel gr_foreground; /* current foreground color */
gfx_pixel gr_background; /* current background color */
int gr_mode;
int flags; /* device flags*/
void * addr; /* address of memory allocated (memdc or fb)*/

PSD (*Open)(PSD psd);
void (*Close)(PSD psd);
void (*SetPalette)(PSD psd,int first,int count,gfx_color *cmap);
void (*GetPalette)(PSD psd,int first,int count,gfx_color *cmap);
PSD (*AllocateMemGC)(PSD psd);
BOOL (*MapMemGC)(PSD mempsd,int w,int h,int planes,int bpp, int linelen,int size,void *addr);
void (*FreeMemGC)(PSD mempsd);
void (*FillRect)(PSD psd,int x,int y,int w,int h,gfx_pixel c);
void (*DrawPixel)(PSD psd, int x, int y, gfx_pixel c);
gfx_pixel (*ReadPixel)(PSD psd, int x, int y);
void (*DrawHLine)(PSD psd, int x, int y, int w, gfx_pixel c);
void (*PutHLine) (GAL gal, int x, int y, int w, void* buf);
void (*GetHLine) (GAL gal, int x, int y, int w, void* buf);
void (*DrawVLine)(PSD psd, int x, int y, int w, gfx_pixel c);
void (*PutVLine) (GAL gal, int x, int y, int w, void* buf);
void (*GetVLine) (GAL gal, int x, int y, int w, void* buf);
void (*Blit)(PSD dstpsd, int dstx, int dsty, int w, int h, PSD srcpsd, int srcx, int srcy);
void (*PutBox)( GAL gal, int x, int y, int w, int h, void* buf );
void (*GetBox)( GAL gal, int x, int y, int w, int h, void* buf );
void (*PutBoxMask)( GAL gal, int x, int y, int w, int h, void *buf);
void (*CopyBox)(PSD psd,int x1, int y1, int w, int h, int x2, int y2);
} SCREENDEVICE;

                     清单 6  Native 图形引擎的子驱动程序接口

typedef struct {
int (*Init)(PSD psd);
void (*DrawPixel)(PSD psd, int x, int y, gfx_pixel c);
gfx_pixel (*ReadPixel)(PSD psd, int x, int y);
void (*DrawHLine)(PSD psd, int x, int y, int w, gfx_pixel c);
void (*PutHLine) (GAL gal, int x, int y, int w, void* buf);
void (*GetHLine) (GAL gal, int x, int y, int w, void* buf);
void (*DrawVLine)(PSD psd, int x, int y, int w, gfx_pixel c);
void (*PutVLine) (GAL gal, int x, int y, int w, void* buf);
void (*GetVLine) (GAL gal, int x, int y, int w, void* buf);
void (*Blit)(PSD dstpsd, int dstx, int dsty, int w, int h, PSD srcpsd, int srcx, int srcy);
void (*PutBox)( GAL gal, int x, int y, int w, int h, void* buf );
void (*GetBox)( GAL gal, int x, int y, int w, int h, void* buf );
void (*PutBoxMask)( GAL gal, int x, int y, int w, int h, void *buf);
void (*CopyBox)(PSD psd,int x1, int y1, int w, int h, int x2, int y2);
} SUBDRIVER, *PSUBDRIVER;

事实上,鼠标驱动程序的实现是利用内核或者其他驱动程序提供的接口来完成任务的。Linux 内核驱动程序使用设备文件对大多数硬件进行了抽象,比如,我们眼中的 ps/2 鼠标就是 /dev/psaux, 鼠标驱动程序接口如清单 7 所示。

                       清单 7  Native 输入引擎的鼠标驱动程序接口

typedef struct _mousedevice {
int (*Open)(void);
void (*Close)(void);
int (*GetButtonInfo)(void);
void (*GetDefaultAccel)(int *pscale,int *pthresh);
int (*Read)(int *dx,int *dy,int *dz,int *bp);
void (*Suspend)(void);
void (*Resume)(void);
} MOUSEDEVICE;

static int GPM_Open(void)
{
mouse_fd = open(GPM_DEV_FILE, O_NONBLOCK);
if (mouse_fd < 0)
return -1;
return mouse_fd;
}

static int PS2_Open(void)
{
uint8 initdata_ps2[] = { PS2_DEFAULT, PS2_SCALE11, PS2_ENABLE };
mouse_fd = open(PS2_DEV_FILE, O_RDWR | O_NOCTTY | O_NONBLOCK);
if (mouse_fd < 0)
return -1;
write(mouse_fd, initdata_ps2, sizeof(initdata_ps2));
return mouse_fd;
}

		dx = thresh + (dx - thresh) * scale;
dy = thresh + (dy - thresh) * scale;

在实现键盘驱动程序中遇到的第一个问题就是使用设备文件 /dev/tty还是 /dev/tty0。

# echo 1 > /dev/tty0
# echo 1 > /dev/tty

/dev/tty 是和进程的每一个终端联系起来的,/dev/tty 的驱动程序所做的只是把所有的请求送到合适的终端。

缺省情况下,/dev/tty 是普通用户可读写的,而/dev/tty0 则只有超级用户能够读写,主要是基于这个原因,我们目前使用 /dev/tty 作为设备文件。后面所有有关终端处理的程序的都采用它作为当前终端文件,这样也可以和传统的 Unix 相兼容。

                     清单 8  Native 输入引擎的键盘驱动程序接口

typedef struct _kbddevice {
int (*Open)(void);
void (*Close)(void);
void (*GetModifierInfo)(int *modifiers);
int (*Read)(unsigned char *buf,int *modifiers);
void (*Suspend)(void);
void (*Resume)(void);
} KBDDEVICE;

基本原理非常简单,初始化时打开 /dev/tty,以后就从该文件读出所有的数据。由于MiniGUI 需要捕获 KEY_DOWN 和 KEY_UP 消息,键盘被置于原始(raw)模式。这样,程序从 /dev/tty 中直接读出键盘的扫描码,比如用户按下A 键,就可以读到158,放下,又读到30。原始模式下,程序必须自己记下各键的状态,特别是shift,ctrl,alt,caps lock 等,所以程序维护一个数组,记录了所有键盘的状态。

这里说明一下鼠标移动,按键等事件是如何被传送到上层消息队列的。MiniGUI工作在用户态,所以它不可能利用中断这种高效的 机制。没有内核驱动程序的支持,它也很难利用信号等Unix系统的IPC机制。MiniGUI可以做到的就是看 /dev/tty, /dev/mouse 等文件是否有数据可以读。上层通过不断调用 GAL_WaitEvent 尝试读取这些文件。这也是线程Parser的主要任务。GAL_WaitEvent 主要利用了系统调用select 这一类Unix系统中地位仅次于ioctl的系统调用完成该功能。并将等待到的事件作为返回值返回。

                          清单 9  定义 Native 引擎的子驱动程序


16 /* define or undefine these macros
17 to include or exclude specific fb driver.
18 */
19 #undef _FBLIN1_SUPPORT
20 // #define _FBLIN1_SUPPORT 1
21
22 #undef _FBLIN2_SUPPORT
23 // #define _FBLIN2_SUPPORT 1
24
22 #undef _FBLIN_2_SUPPORT
23 // #define _FBLIN_2_SUPPORT 1
24
25 //#undef _FBLIN4_SUPPORT
26 #define _FBLIN4_SUPPORT 1
27
28 // #undef _FBLIN8_SUPPORT
29 #define _FBLIN8_SUPPORT 1
30
31 // #undef _FBLIN16_SUPPORT
32 #define _FBLIN16_SUPPORT 1
33
34 #undef _FBLIN24_SUPPORT
35 // #define _FBLIN24_SUPPORT 1
36
37 #undef _FBLIN32_SUPPORT
38 // #define _FBLIN32_SUPPORT 1
39
40 #define HAVETEXTMODE 1 /* =0 for graphics only systems*/

           清单 10  为 ADS 公司基于 StrongARM 的嵌入式开发系统编写的输入引擎

30
31 #include
32 #include
33 #include
34 #include
35 #include
36 #include
37 #include
38 #include
39 #include
40 #include
41 #include
42
43 #include "common.h"
44 #include "misc.h"
45 #include "ads_internal.h"
46 #include "ial.h"
47 #include "ads.h"
48
49 #ifndef NR_KEYS
50 #define NR_KEYS 128
51 #endif
52
53 static int ts;
54 static int mousex = 0;
55 static int mousey = 0;
56 static POS pos;
57
58 static unsigned char state[NR_KEYS];
59
60 /************************ Low Level Input Operations **********************/
61 /*
62 * Mouse operations -- Event
63 */
64 static int mouse_update(void)
65 {
66 return 0;
67 }
68
69 static int mouse_getx(void)
70 {
71 return mousex;
72 }
73
74 static int mouse_gety(void)
75 {
76 return mousey;
77 }
78
79 static void mouse_setposition(int x, int y)
80 {
81 }
82
83 static int mouse_getbutton(void)
84 {
85 return pos.b;
86 }
87
88 static void mouse_setrange(int minx,int miny,int maxx,int maxy)
89 {
90 }
91
92 static int keyboard_update(void)
93 {
94 return 0;
95 }
96
97 static char * keyboard_getstate(void)
98 {
99 return (char *)state;
100 }
101
102 #ifdef _LITE_VERSION
103 static int wait_event (int which, int maxfd, fd_set *in, fd_set *out, fd_set *except,
104 struct timeval *timeout)
105 {
106 fd_set rfds;
107 int e;
108
109 if (!in) {
110 in = &rfds;
111 FD_ZERO (in);
112 }
113
114 if (which & IAL_MOUSEEVENT) {
115 FD_SET (ts, in);
116 if (ts > maxfd) maxfd = ts;
117 }
118
119 e = select (maxfd + 1, in, out, except, timeout) ;
120
121 if (e > 0) {
122 if (ts >= 0 && FD_ISSET (ts, in))
123 {
124 FD_CLR (ts, in);
125 read (ts, &pos, sizeof (POS));
126 if ( pos.x !=-1 && pos.y !=-1) {
127 mousex = pos.x;
128 mousey = pos.y;
129 }
130 pos.b = ( pos.b > 0 ? 4:0);
131 return IAL_MOUSEEVENT;
132 }
133
134 } else if (e < 0) {
135 return -1;
136 }
137 return 0;
138 }
139 #else
140 static int wait_event (int which, fd_set *in, fd_set *out, fd_set *except,
141 struct timeval *timeout)
142 {
143 struct pollfd ufd;
144 if ( (which & IAL_MOUSEEVENT) == IAL_MOUSEEVENT)
145 {
146 ufd.fd = ts;
147 ufd.events = POLLIN;
148 if ( poll (&ufd, 1, timeout) > 0)
149 {
150 read (ts, &pos, sizeof(POS));
151 return IAL_MOUSEEVENT;
152 }
153 }
154 return 0;
155 }
156 #endif
157
158 static void set_leds (unsigned int leds)
159 {
160 }
161
162 BOOL InitADSInput (INPUT* input, const char* mdev, const char* mtype)
163 {
164 int i;
165
166 ts = open ("/dev/ts", O_RDONLY);
167 if ( ts < 0 ) {
168 fprintf (stderr, "IAL: Can not open touch screen!\n");
169 return FALSE;
170 }
171
172 for(i = 0; i < NR_KEYS; i++)
173 state[i] = 0;
174
175 input->update_mouse = mouse_update;
176 input->get_mouse_x = mouse_getx;
177 input->get_mouse_y = mouse_gety;
178 input->set_mouse_xy = mouse_setposition;
179 input->get_mouse_button = mouse_getbutton;
180 input->set_mouse_range = mouse_setrange;
181
182 input->update_keyboard = keyboard_update;
183 input->get_keyboard_state = keyboard_getstate;
184 input->set_leds = set_leds;
185
186 input->wait_event = wait_event;
187 mousex = 0;
188 mousey = 0;
189 return TRUE;
190 }
191
192 void TermADSInput (void)
193 {
194 if ( ts >= 0 )
195 close(ts);
196 }
197

阅读(997) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~