?? minigui 體系結構之四 圖形抽象層和輸入抽象層及 native engine 的實現(二).htm
字號:
<TR>
<TD><PRE># echo 1 > /dev/tty0
# echo 1 > /dev/tty
</PRE></TD></TR></TBODY></TABLE>
<P>結果都將把1 輸入到當前終端上。另外,如果從偽終端上運行它們,則第一條指令會將 1 輸出到控制臺的當前終端,而第二條指令會把 1
輸出到當前偽終端上。從而 tty0 表示當前控制臺終端,tty 表示當前終端(實際是當前進程控制終端的別名而已)。</P>
<P>tty0 的設備號是 4,0</P>
<P>tty1 的設備號是 5, 0</P>
<P>/dev/tty 是和進程的每一個終端聯系起來的,/dev/tty 的驅動程序所做的只是把所有的請求送到合適的終端。</P>
<P>缺省情況下,/dev/tty 是普通用戶可讀寫的,而/dev/tty0 則只有超級用戶能夠讀寫,主要是基于這個原因,我們目前使用
/dev/tty 作為設備文件。后面所有有關終端處理的程序的都采用它作為當前終端文件,這樣也可以和傳統的 Unix 相兼容。</P>
<P>鍵盤驅動程序接口如清單 8 所示。</P>
<TABLE class=code-sample cellPadding=0 width="100%" border=0>
<TBODY>
<TR>
<TD><PRE> 清單 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;
</PRE></TD></TR></TBODY></TABLE>
<P>基本原理非常簡單,初始化時打開 /dev/tty,以后就從該文件讀出所有的數據。由于MiniGUI 需要捕獲 KEY_DOWN 和
KEY_UP 消息,鍵盤被置于原始(raw)模式。這樣,程序從 /dev/tty 中直接讀出鍵盤的掃描碼,比如用戶按下A
鍵,就可以讀到158,放下,又讀到30。原始模式下,程序必須自己記下各鍵的狀態,特別是shift,ctrl,alt,caps lock
等,所以程序維護一個數組,記錄了所有鍵盤的狀態。</P>
<P>這里說明一下鼠標移動,按鍵等事件是如何被傳送到上層消息隊列的。MiniGUI工作在用戶態,所以它不可能利用中斷這種高效的機制。沒有內核驅動程序的支持,它也很難利用信號等Unix系統的IPC機制。MiniGUI可以做到的就是看
/dev/tty, /dev/mouse 等文件是否有數據可以讀。上層通過不斷調用 GAL_WaitEvent
嘗試讀取這些文件。這也是線程Parser的主要任務。GAL_WaitEvent 主要利用了系統調用select
這一類Unix系統中地位僅次于ioctl的系統調用完成該功能。并將等待到的事件作為返回值返回。</P>
<P>至此介紹了鍵盤和鼠標的驅動程序,作為簡單的輸入設備,它們的驅動是非常簡單的。事實上,它們的實現代碼也比較少,就是在嵌入式系統中要使用的觸摸屏,如果操作系統內核支持,其驅動程序也是非常簡單的:它只不過是一種特殊的鼠標。</P><A
id=5 name=5></A>
<P><STRONG class=subhead>5 特定嵌入式系統上圖形引擎和輸入引擎實現</STRONG></P>
<P>如前所述,基于 Linux 的嵌入式系統,其內核一般具備對 FrameBuffer 的支持,從而可以利用已有的 Native 圖形引擎。在
MiniGUI 代碼中,可通過調整 src/gal/native/native.h 中的宏定義而定義函數庫中是否包含特定的圖形引擎驅動程序(清單
9):</P>
<TABLE class=code-sample cellPadding=0 width="100%" border=0>
<TBODY>
<TR>
<TD><PRE> 清單 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*/
</PRE></TD></TR></TBODY></TABLE>
<P>其中,HAVETEXTMODE 定義系統是否有文本模式,可將 MiniGUI 中用來關閉文本模式的代碼屏蔽掉。_FBLIN_2_SUPPORT
和_FBLIN2_SUPPORT 分別用來定義 big endian 和 little endian 的 2bpp 驅動程序。</P>
<P>對于輸入引擎來說,情況就有些不同了。因為目前還沒有統一的處理輸出設備的接口,而且每個嵌入式系統的輸入設備也各不相同,所以,我們通常要針對特定嵌入式系統重新輸入引擎。下面的代碼就是針對
ADS 基于 StrongARM 的嵌入式開發系統編寫的輸入引擎(清單 10):</P>
<TABLE class=code-sample cellPadding=0 width="100%" border=0>
<TBODY>
<TR>
<TD><PRE> 清單 10 為 ADS 公司基于 StrongARM 的嵌入式開發系統編寫的輸入引擎
30
31 #include <stdio.h>
32 #include <stdlib.h>
33 #include <string.h>
34 #include <unistd.h>
35 #include <sys/io.h>
36 #include <sys/ioctl.h>
37 #include <sys/poll.h>
38 #include <linux/kd.h>
39 #include <sys/types.h>
40 #include <sys/stat.h>
41 #include <fcntl.h>
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)
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -