鼠標在UNIX系統(tǒng)中的應用程序中的使用
在當前眾多的個人電腦中, Windows 操作系統(tǒng)鋪天蓋地,鼠標在其上有著廣泛的應用。同樣,Unix 系統(tǒng)的 X Window,離開了鼠標,操作上也是顯得不太靈活方便。本文并不對X Window 中所應用的鼠標的隊列方式給予介紹,只是簡單地介紹一下如何利用系統(tǒng)調(diào)用實現(xiàn)對鼠標的直接訪問。 在大多數(shù)個人電腦中,使用的是輔口鼠標,由于本人條件所限,也只能對輔口鼠標在Unix系統(tǒng)中的應用給予粗淺的介紹。 輔口鼠標在AT&T Unix系統(tǒng)中應設(shè)置為PS/2鼠標,對應的設(shè)備文件為/dev/mouse;而在 SCO Unix系統(tǒng)中應設(shè)置為 kbmouse(即鍵盤鼠標),對應的設(shè)備文件為/dev/mouse/kb0。如果在編程中使用鼠標,應遵循以下順序: 1、打開鼠標對應的設(shè)備文件。 2、利用系統(tǒng)調(diào)用將鼠標設(shè)置為不等待方式。 3、通過系統(tǒng)調(diào)用來循環(huán)讀取鼠標的按鍵狀態(tài),根據(jù)按鍵狀態(tài)轉(zhuǎn)向執(zhí)行不同的程序功能模塊。 在這里,我先對用到的與鼠標有關(guān)的兩個系統(tǒng)功能調(diào)用給予簡單介紹。鼠標系統(tǒng)調(diào)用的方式為: int ioctl(int fd, int request,…/*arg*/) 其中:fd 為鼠標設(shè)備文件描述符 request 為系統(tǒng)調(diào)用請求的功能號 …表示系統(tǒng)功能調(diào)用的參數(shù) 對請求的功能號宏定義為: #define MOUSEIOC ('M'<<8) #define MOUSEIOCREAD (MOUSEI OC/60) #define MOUSEIOCNDELAY (MOU SEIOC/81) 功能描述 : MOUSEIOCNDELAY 將鼠標設(shè)置為不等待方式,在系統(tǒng)調(diào)用中,不需要參數(shù)。可將ioctl的參數(shù)項設(shè)為01(長整數(shù)零)。 MOUSEIOCREAD 用于讀取鼠標的位置和狀態(tài)數(shù)據(jù)。在 ioctl 中的參數(shù)項為一結(jié)構(gòu)指針。該結(jié)構(gòu)定義如下: struct mouseinfo { unsigned char status; char xmotion; char ymotion; } 該結(jié)構(gòu)的status字段包含鼠標按鍵狀態(tài)信息,具體格式為: 高位 7 6 5 4 3 2 1 0 低位 0 Mv Lc Mc Rc L M R Mv:如果鼠標自從上次執(zhí)行MOUSEIOCREAD 系統(tǒng)調(diào)用后移動過,則該位為1。 Lc:如果鼠標自從上次執(zhí)行MOUSEIOCREAD系統(tǒng)調(diào)用后左按鍵狀態(tài)已改變 ,則該位為1。 Mc:如果鼠標自從上次執(zhí)行MOUSEIOCREAD系統(tǒng)調(diào)用后中按鍵狀態(tài)已改變,則該位為1。 Rc:如果鼠標自從上次執(zhí)行MOUSEIOCREAD系統(tǒng)調(diào)用后右按鍵狀態(tài)已改變,則該位為1。 L:左按鍵當前狀態(tài)(按下為1,彈起為0)。 M:中按鍵當前狀態(tài)(按下為1,彈起為0,只用于三鍵鼠標)。 R:右按鍵當前狀態(tài)(按下為1,彈起為0)。 在使用時要注意: 1、如果自從上次調(diào)用MOUSEIOCREAD系統(tǒng)調(diào)用后,鼠標已被移動過,但x向(橫向)和y向(縱向)的位移量為0,要判斷鼠標是否被移動過,就需要查看Mv位。 2、如果鼠標自從上次調(diào)用MOUSEIOCREAD系統(tǒng)調(diào)用后,一個按鍵已被按下彈起過,該按鍵的當前狀態(tài)位將不會改變,但有時應用程序需要知道它改變過,這對要用到Lc,Mc和Rc位。 結(jié)構(gòu)mouseinfo中的xmotion和ymotion字段用于標識鼠標相對于上次調(diào)用MOUSEIOCREAD時在x方向和y方向的位移量。位移量的范圍為-127到127,超過兩端的部分被截去。 介紹完鼠標的兩個重要的系統(tǒng)調(diào)用,就可在實際編程中使用它了。本人在Unix系統(tǒng)下基于此方式編寫過使用鼠標的幾個程序(圖形方式和文本方式下)。以下是本人編寫的簡單的鼠標測試程序(此程序在AT&T Unix SVR 4.2下調(diào)試通過),功能不完備,僅供參考。 源程序清單如下: #include ″sys/types.h″ #include ″errno.h″ #include ″stdio.h″ #include ″sys/fcntl.h″ #include ″sys/ioctl.h″ #include ″signal.h″ #define BUTCHNGMASK 0x38 #define MOVEMENT 0x40 #define BUTSTATMASK 7 #define BUT3STAT 1 #define BUT2STAT 2 #define BUT1STAT 4 #define BUT3CHNG 8 #define BUT2CHNG 0x10 #define BUT1CHNG 0x20
#define MSE_BUTTON 0 #defing MSE_MOTION 1
struct mouseinfo unsigned char status; charxmotion, ymotion; }; /* Ioctl Command definitions */ #define MOUSEIOC ('M'<<8) #define MOUSEIOCREAD (MOUSEI OC| 60) #define MOUSEIOCNDELAY (MOU SEIOC| 81)
void (* s_quit)(); void (* s_intr)(); int fd; void EXIT(); void main() { unsigned long a,b; int i,j,status; char buf[80]; struct mouseinfo mseinfo; int xpos=1,ypos=1; s_quit=signal(SIGQUIT,EXIT); s_intr=signal(SIGINT,EXIT); if((fd=open(″dev/mouse″,0_RD WR))==-1){ perror(″不能打開鼠標設(shè)備文件!!!″); exit(1); } printf(″33[1c″);/*設(shè)置光標為塊方式/* ioctl(fd,MOUSEIOCNDELAY,OL); /*設(shè)置鼠標為非延遲等待方式*/ while(1){ ioctl(fd,MOUSEIOCREAD,&ms einfo); /*讀取鼠標狀態(tài)信息*/ if(mseinfo.status&MOVEMENT){ xpos=xpos+mseinfo.xmotion; if(xpos <=0) xpos=1; else if(xpos >80) xpos=80; ypos=ypos+mseinfo.ymotion; if(ypos <=0) ypos=1; else if(ypos > 25) ypos=25; printf(″033[%d;%dH″,ypos,xpos);/*調(diào)整光標位置*/ fflush(stdout); /*刷新輸出*/ } if(mseinfo.status&BUTCHNGMASK){ if(mseinfo.status&BUT1CHNG){ if(mseinfo.status&BUT1STAT){ printf(″Left Depressed″);/*左鍵被按下*/ fflush(stdout); } else { printf(″Left Relessed″);/*左鍵被釋放*/ fflush(stdout); } } if(mseinfo.status&BUT3CHNG){ if(mseinfo.status&BUT3STAT){ printf(″Right Depressed″); /*右鍵被按下*/ fflush(stdout); } else { printf(″Right Relessed″);/*右鍵被釋放*/ fflush(stdout); } } } } } void EXIT() /*本函數(shù)用于信號處理,實現(xiàn)整個程序的退出*/ { close(fd); printf(″33[0c″); signal(SIGQUIT,s_quit); signal(SIGINT,s_intr); exit(0); } /*———程序結(jié)束————*/
