天天看點

X Window研究筆記(6)

X Window研究筆記(6)

6.X Window輸入裝置(TinyX)

X Window支援的基本輸入裝置有keyboard、mouse和touchscreen,keyboard有自己的驅動接口,而後兩者具有相同的驅動接口。

輸入裝置的初始化。

  1. X Server在初始化時會調用InitInput函數初始化輸入裝置。
  2. InitInput調用KdInitInput完成TinyX輸入裝置的初始化。其參數LinuxMouseFuncs指向mouse驅動函數,LinuxKeyboardFuncs指向keyboard驅動的函數。
  3. 在KdInitInput中,建立一個KdMouseInfo對象,放入kdMouseInfo連結清單中,并初始化這個KdMouseInfo對象。
  4. 在KdInitInput中,把指向keyboard和mouse驅動的指針儲存到kdMouseFuncs和kdKeyboardFuncs兩個全局變量之中。
  5. 在KdInitInput中,加載鍵盤映射表,初始化按鍵重複的資料結構,重置輸入裝置的狀态。
  6. 在KdInitInput中,建立keyboard和mouse裝置,并注冊這兩個輸入裝置到系統中。
  7. 如果支援touchscreen,把kdTsFuncs指向TsFuncs。

keyboard的驅動接口

X Window研究筆記(6)
X Window研究筆記(6)

typedef struct _KdKeyboardFuncs ...{

X Window研究筆記(6)

    void            (*Load) (void);

X Window研究筆記(6)

    int             (*Init) (void);

X Window研究筆記(6)

    void            (*Leds) (int);

X Window研究筆記(6)

    void            (*Bell) (int, int, int);

X Window研究筆記(6)

    void            (*Fini) (void);

X Window研究筆記(6)

    int             LockLed;

X Window研究筆記(6)

} KdKeyboardFuncs;

下面我們來看一個實際例子(tinyx/linux/keyboard.c):

X Window研究筆記(6)
X Window研究筆記(6)

KdKeyboardFuncs LinuxKeyboardFuncs = ...{

X Window研究筆記(6)

    LinuxKeyboardLoad,

X Window研究筆記(6)

    LinuxKeyboardInit,

X Window研究筆記(6)

    LinuxKeyboardLeds,

X Window研究筆記(6)

    LinuxKeyboardBell,

X Window研究筆記(6)

    LinuxKeyboardFini,

X Window研究筆記(6)

    3,

X Window研究筆記(6)

};

X Window研究筆記(6)

LinuxKeyboardLoad: 建構一個鍵值映射表,即從原始的按鍵值到虛拟鍵值間VK之間的映射。讓虛拟鍵值獨立于硬體的,可以提高應用程式的可移植性。

X Window研究筆記(6)

static void

X Window研究筆記(6)

LinuxKeyboardLoad (void)

X Window研究筆記(6)
X Window研究筆記(6)

...{  

X Window研究筆記(6)

    readKernelMapping ();

X Window研究筆記(6)

}    

LinuxKeyboardInit:初始化一些資料結構,并注冊相關回調函數。這樣,在有按鍵事件時,LinuxConsoleFd喚醒select,并調用函數LinuxKeyboardRead讀取按鍵事件,經過一些轉換動作之後,調用KdHandleKeyboardEvent把事件分發出去。

X Window研究筆記(6)

static int

X Window研究筆記(6)

LinuxKeyboardInit (void)

X Window研究筆記(6)
X Window研究筆記(6)

...{

X Window研究筆記(6)

    if (!LinuxKbdType)

X Window研究筆記(6)

        LinuxKbdType = KdAllocInputType ();

X Window研究筆記(6)
X Window研究筆記(6)

    KdRegisterFd (LinuxKbdType, LinuxConsoleFd, LinuxKeyboardRead, 0);

X Window研究筆記(6)

    LinuxKeyboardEnable (LinuxConsoleFd, 0);

X Window研究筆記(6)

    KdRegisterFdEnableDisable (LinuxConsoleFd,

X Window研究筆記(6)

                               LinuxKeyboardEnable,

X Window研究筆記(6)

                               LinuxKeyboardDisable);

X Window研究筆記(6)

    return 1;

X Window研究筆記(6)

}

LinuxKeyboardLeds: 在某些鍵按下以後,需要點亮鍵盤燈(Caps Lock和 Num Lock等),這時候會調用這個函數,這是通過ioctl系統調用實作的。

X Window研究筆記(6)
X Window研究筆記(6)

LinuxKeyboardLeds (int leds)

X Window研究筆記(6)
X Window研究筆記(6)
X Window研究筆記(6)

    ioctl (LinuxConsoleFd, KDSETLED, leds & 7);

X Window研究筆記(6)
X Window研究筆記(6)

LinuxKeyboardBell:它的功能是發出蜂鳴聲,至于為什麼作為鍵盤驅動的一部分,可能是由于輸入某些鍵值時要響一聲吧(如,/a)。這也是通過ioctl系統調用實作的。

X Window研究筆記(6)
X Window研究筆記(6)

LinuxKeyboardBell (int volume, int pitch, int duration)

X Window研究筆記(6)
X Window研究筆記(6)
X Window研究筆記(6)

    if (volume && pitch)

X Window研究筆記(6)
X Window研究筆記(6)

    ...{

X Window研究筆記(6)

        ioctl(LinuxConsoleFd, KDMKTONE,

X Window研究筆記(6)

              ((1193190 / pitch) & 0xffff) |

X Window研究筆記(6)

              (((unsigned long)duration *

X Window研究筆記(6)

                volume / 50) << 16));

X Window研究筆記(6)
X Window研究筆記(6)

    }

X Window研究筆記(6)

LinuxKeyboardFini:~初始化keyboard裝置,即禁用keyboard,然後登出裝置描述符。

X Window研究筆記(6)
X Window研究筆記(6)

LinuxKeyboardFini (void)

X Window研究筆記(6)
X Window研究筆記(6)
X Window研究筆記(6)

    LinuxKeyboardDisable (LinuxConsoleFd, 0);

X Window研究筆記(6)

    KdUnregisterFds (LinuxKbdType, FALSE);

X Window研究筆記(6)
X Window研究筆記(6)

滑鼠的接口:

X Window研究筆記(6)
X Window研究筆記(6)

typedef struct _KdMouseFuncs ...{

X Window研究筆記(6)
X Window研究筆記(6)
X Window研究筆記(6)

} KdMouseFuncs;

下面看一個實際例子(tinyx/linux/mouse.c)

X Window研究筆記(6)
X Window研究筆記(6)

KdMouseFuncs LinuxMouseFuncs = ...{

X Window研究筆記(6)

    MouseInit,

X Window研究筆記(6)

    MouseFini,

X Window研究筆記(6)
X Window研究筆記(6)

MouseInit 打開裝置檔案,并注冊一些回調函數。這樣,在有mouse事件時,fd喚醒select,并調用函數MouseRead讀取mouse事件,經過一些轉換動作之後,調用KdHandleMouseEvent把事件分發出去。

X Window研究筆記(6)
X Window研究筆記(6)

char *kdefaultMouse[] =  ...{

X Window研究筆記(6)

    "/dev/mouse",

X Window研究筆記(6)

    "/dev/psaux",

X Window研究筆記(6)

    "/dev/input/mice",

X Window研究筆記(6)

    "/dev/adbmouse",

X Window研究筆記(6)

    "/dev/ttyS0",

X Window研究筆記(6)

    "/dev/ttyS1",

X Window研究筆記(6)
X Window研究筆記(6)
X Window研究筆記(6)

#define NUM_DEFAULT_MOUSE    (sizeof (kdefaultMouse) / sizeof (kdefaultMouse[0]))

X Window研究筆記(6)
X Window研究筆記(6)
X Window研究筆記(6)

MouseInit (void)

X Window研究筆記(6)
X Window研究筆記(6)
X Window研究筆記(6)

    int     i;

X Window研究筆記(6)

    int     fd = -1;

X Window研究筆記(6)

    Kmouse  *km;

X Window研究筆記(6)

    KdMouseInfo *mi, *next;

X Window研究筆記(6)

    int     n = 0;

X Window研究筆記(6)

    char    *prot;

X Window研究筆記(6)
X Window研究筆記(6)

    if (!MouseInputType)

X Window研究筆記(6)

    MouseInputType = KdAllocInputType ();

X Window研究筆記(6)
X Window研究筆記(6)

    for (mi = kdMouseInfo; mi; mi = next)

X Window研究筆記(6)
X Window研究筆記(6)
X Window研究筆記(6)

    next = mi->next;

X Window研究筆記(6)

    prot = mi->prot;

X Window研究筆記(6)

    if (mi->inputType)

X Window研究筆記(6)

        continue;

X Window研究筆記(6)

    if (!mi->name)

X Window研究筆記(6)
X Window研究筆記(6)
X Window研究筆記(6)

        for (i = 0; i < NUM_DEFAULT_MOUSE; i++)

X Window研究筆記(6)
X Window研究筆記(6)

        ...{

X Window研究筆記(6)

        if (kdNoSerialMouse && strstr(kdefaultMouse[i], "/dev/ttyS"))

X Window研究筆記(6)

            continue;

X Window研究筆記(6)

        fd = open (kdefaultMouse[i], 2);

X Window研究筆記(6)

        if (fd >= 0)

X Window研究筆記(6)
X Window研究筆記(6)
X Window研究筆記(6)

            mi->name = KdSaveString (kdefaultMouse[i]);

X Window研究筆記(6)

            break;

X Window研究筆記(6)

        }

X Window研究筆記(6)

        }  

X Window研究筆記(6)
X Window研究筆記(6)

    else

X Window研究筆記(6)

        fd = open (mi->name, 2);

X Window研究筆記(6)
X Window研究筆記(6)

    if (fd >= 0)

X Window研究筆記(6)
X Window研究筆記(6)
X Window研究筆記(6)

        km = (Kmouse *) xalloc (sizeof (Kmouse));

X Window研究筆記(6)

        if (km)

X Window研究筆記(6)
X Window研究筆記(6)
X Window研究筆記(6)

        km->iob.fd = fd;

X Window研究筆記(6)

        km->iob.avail = km->iob.used = 0;

X Window研究筆記(6)

       km->prot = 0;

X Window研究筆記(6)

        km->i_prot = 0;

X Window研究筆記(6)

        km->tty = isatty (fd);

X Window研究筆記(6)

        mi->driver = km;

X Window研究筆記(6)

        mi->inputType = MouseInputType;

X Window研究筆記(6)

        MouseFirstProtocol (km, mi->prot);

X Window研究筆記(6)

        if (KdRegisterFd (MouseInputType, fd, MouseRead, (void *) mi))

X Window研究筆記(6)

            n++;

X Window研究筆記(6)
X Window研究筆記(6)

        else

X Window研究筆記(6)

        close (fd);

X Window研究筆記(6)
X Window研究筆記(6)
X Window研究筆記(6)

    return n;

X Window研究筆記(6)
X Window研究筆記(6)

MouseFini: ~初始化mouse裝置,即登出回調函數,并釋放一些資料結構。

X Window研究筆記(6)
X Window研究筆記(6)

MouseFini (void)

X Window研究筆記(6)
X Window研究筆記(6)
X Window研究筆記(6)

    KdMouseInfo *mi;

X Window研究筆記(6)
X Window研究筆記(6)

    KdUnregisterFds (MouseInputType, TRUE);

X Window研究筆記(6)

    for (mi = kdMouseInfo; mi; mi = mi->next)

X Window研究筆記(6)
X Window研究筆記(6)
X Window研究筆記(6)

    if (mi->inputType == MouseInputType)

X Window研究筆記(6)
X Window研究筆記(6)
X Window研究筆記(6)

        xfree (mi->driver);

X Window研究筆記(6)

        mi->driver = 0;

X Window研究筆記(6)

        mi->inputType = 0;

X Window研究筆記(6)
X Window研究筆記(6)
X Window研究筆記(6)
X Window研究筆記(6)
X Window研究筆記(6)

觸摸屏的接口

X Window研究筆記(6)
X Window研究筆記(6)
X Window研究筆記(6)
X Window研究筆記(6)
X Window研究筆記(6)

觸摸屏是作為滑鼠來實作的。下面看一個實際例子(tinyx/linux/tslib.c)

X Window研究筆記(6)
X Window研究筆記(6)

KdMouseFuncs TsFuncs = ...{

X Window研究筆記(6)

    TslibInit,

X Window研究筆記(6)

    TslibFini

X Window研究筆記(6)
X Window研究筆記(6)

TslibInit:打開裝置檔案,并注冊一些回調函數。由于觸摸屏涉及到去抖、濾波、校準等功能,相關對于滑鼠來說,要複雜得多,是以這裡是調用tslib來實作的。

在有筆點事件時,fd喚醒select,并調用函數TsRead讀取筆點事件,經過一些轉換動作之後,調用KdHandleMouseEvent把事件分發出去。

X Window研究筆記(6)

int

X Window研究筆記(6)

TslibInit (void)

X Window研究筆記(6)
X Window研究筆記(6)
X Window研究筆記(6)

    int         i;

X Window研究筆記(6)
X Window研究筆記(6)

    int         fd= 0;

X Window研究筆記(6)

    int         n = 0;

X Window研究筆記(6)
X Window研究筆記(6)

    if (!TsInputType)

X Window研究筆記(6)

        TsInputType = KdAllocInputType ();

X Window研究筆記(6)
X Window研究筆記(6)
X Window研究筆記(6)
X Window研究筆記(6)
X Window研究筆記(6)

        next = mi->next;

X Window研究筆記(6)

        if (mi->inputType)

X Window研究筆記(6)
X Window研究筆記(6)
X Window研究筆記(6)

        if (!mi->name)

X Window研究筆記(6)
X Window研究筆記(6)
X Window研究筆記(6)

            for (i = 0; i < NUM_TS_NAMES; i++)

X Window研究筆記(6)
X Window研究筆記(6)

            ...{

X Window研究筆記(6)

                if(!(tsDev = ts_open(TsNames[i],0))) continue;

X Window研究筆記(6)

                ts_config(tsDev);

X Window研究筆記(6)

                fd=ts_fd(tsDev);

X Window研究筆記(6)

                if (fd >= 0)

X Window研究筆記(6)
X Window研究筆記(6)

                ...{

X Window研究筆記(6)

                    mi->name = KdSaveString (TsNames[i]);

X Window研究筆記(6)

                    break;

X Window研究筆記(6)

                }  

X Window研究筆記(6)

            }  

X Window研究筆記(6)
X Window研究筆記(6)
X Window研究筆記(6)

        if (fd > 0 && tsDev != 0)

X Window研究筆記(6)
X Window研究筆記(6)

          ...{

X Window研究筆記(6)

            mi->driver = (void *) fd;

X Window研究筆記(6)

            mi->inputType = TsInputType;

X Window研究筆記(6)

                if (KdRegisterFd (TsInputType, fd, TsRead, (void *) mi))

X Window研究筆記(6)

                    n++;

X Window研究筆記(6)

          }

X Window研究筆記(6)
X Window研究筆記(6)

          if (fd > 0) close(fd);

X Window研究筆記(6)
X Window研究筆記(6)

TslibFini: ~初始化touchscreen裝置,即登出相關的回調函數,并釋放一些資料結構。

X Window研究筆記(6)

void

X Window研究筆記(6)

TslibFini (void)

X Window研究筆記(6)
X Window研究筆記(6)
X Window研究筆記(6)
X Window研究筆記(6)
X Window研究筆記(6)

    KdUnregisterFds (TsInputType, TRUE);

X Window研究筆記(6)
X Window研究筆記(6)
X Window研究筆記(6)
X Window研究筆記(6)

        if (mi->inputType == TsInputType)

X Window研究筆記(6)
X Window研究筆記(6)
X Window研究筆記(6)

            if(mi->driver) ts_close(tsDev);

X Window研究筆記(6)

            mi->driver = 0;

X Window研究筆記(6)

            mi->inputType = 0;

X Window研究筆記(6)
X Window研究筆記(6)

            if (mi->name != NULL) ...{

X Window研究筆記(6)

                free(mi->name);

X Window研究筆記(6)

                mi->name = NULL;

X Window研究筆記(6)

            }

X Window研究筆記(6)
X Window研究筆記(6)
X Window研究筆記(6)

有意思的是,驅動本身的接口并不能說明裝置的特性,它隻提供初始化和~初始化這類通用接口,在初始化時才注冊裝置描述符和相應的讀取函數。

(待續)

繼續閱讀