2008/12/16

Windows 7 Touch Digitizer 心得

本文要說明的主要來自微軟的文件

For Windows 7, touch digitizers appear through HID as a touch digitizer (page 0x0D, usage 0x04).
The following usages are required:
• X (page 0x01, usage 0x30) and Y (page 0x01, usage 0x31).
• Contact ID (page 0x0D, usage 0x51).
• Tip switch (page 0x0D, usage 0x42) - 指示出手指是否碰觸到螢幕(Digitizer Surface)
• In-range (page 0x0D, usage 0x32).

關於 z 軸我一直覺得很有用,微軟有一段說明如下:
If the device supports z-axis detection, it reports in-range correctly. If the device does not support z-axis detection, the driver reports packets with in-range and tip switch set when a finger comes in contact with the digitizer.

我試著解釋一下(不保證我的理解正確):
如果有 z 軸值,就放在 In-Range 中,此時 Tip Switch 不必設定。
如果沒有 z 軸值,那麼碰觸時請設定 Tip Switch 及傳回適當的 In-Range 值。
(註: 這一版本與之前的 OS 規範不一樣,如與 XP Tablet PC,請見Windows XP Tablet PC OEM Preinstallation Kit (OPK))

底下的資訊是選擇性的,意思是硬體有支援再提供即可:
• Confidence (page 0x0D, usage 0x47) - 這一點很奇怪,意思是前面的觸控點資訊有可能是意外產生時,可以由裝置設定這個值。
• Width and height (page 0x0D, usages 0x48 and 0x49).

來看看一個 USB HID device report 的 sample:

Here is a sample report descriptor for a touch digitizer device:
0x05, 0x0d, // USAGE_PAGE (Digitizers) 0
0x09, 0x04, // USAGE (Touch Screen) 2
0xa1, 0x01, // COLLECTION (Application) 4
0x85, REPORTID_TOUCH, // REPORT_ID (Touch) 6
0x09, 0x20, // USAGE (Stylus) 8
0xa1, 0x00, // COLLECTION (Physical) 10
0x09, 0x42, // USAGE (Tip Switch) 12
0x15, 0x00, // LOGICAL_MINIMUM (0) 14
0x25, 0x01, // LOGICAL_MAXIMUM (1) 16
0x75, 0x01, // REPORT_SIZE (1) 18
0x95, 0x01, // REPORT_COUNT (1) 20
0x81, 0x02, // INPUT (Data,Var,Abs) 22
0x95, 0x03, // REPORT_COUNT (3) 24
0x81, 0x03, // INPUT (Cnst,Ary,Abs) 26
0x09, 0x32, // USAGE (In Range) 28
0x09, 0x37, // USAGE (Data Valid-Finger) 30
0x95, 0x02, // REPORT_COUNT (2) 32
0x81, 0x02, // INPUT (Data,Var,Abs) 34
0x95, 0x0a, // REPORT_COUNT (10) 36
0x81, 0x03, // INPUT (Cnst,Ary,Abs) 38
0x05, 0x01, // USAGE_PAGE (Generic Desktop) 40
0x26, 0xff, 0x7f, // LOGICAL_MAXIMUM (32767) 42
0x75, 0x10, // REPORT_SIZE (16) 45
0x95, 0x01, // REPORT_COUNT (1) 47
0xa4, // PUSH 49
0x55, 0x0d, // UNIT_EXPONENT (-3) 50
0x65, 0x00, // UNIT (None) 52
0x09, 0x30, // USAGE (X) 54
0x35, 0x00, // PHYSICAL_MINIMUM (0) 56
0x46, 0x00, 0x00, // PHYSICAL_MAXIMUM (0) 58
0x81, 0x02, // INPUT (Data,Var,Abs) 61
0x09, 0x31, // USAGE (Y) 63
0x46, 0x00, 0x00, // PHYSICAL_MAXIMUM (0) 65
0x81, 0x02, // INPUT (Data,Var,Abs) 68
0xb4, // POP 70
0x05, 0x0d, // USAGE PAGE (Digitizers) 71
0x09, 0x60, // USAGE (Width) 73
0x09, 0x61, // USAGE (Height) 75
0x95, 0x02, // REPORT_COUNT (2) 77
0x81, 0x02, // INPUT (Data,Var,Abs) 79
0x95, 0x01, // REPORT_COUNT (1) 81
0x81, 0x03, // INPUT (Cnst,Ary,Abs) 83/85
#ifdef _ CUSTOMVENDORUSAGE _
0x06, 0x00, 0xff, // USAGE_PAGE (Vendor Defined) 0
0x09, 0x80, // USAGE (Vendor Usage 0x80) 3
0x09, 0x81, // USAGE (Vendor Usage 0x81) 5
0x15, 0x00, // LOGICAL_MINIMUM (0) 7
0x27, 0xff, 0xff, 0xff, 0xff, // LOGICAL_MAXIMUM (0xffffffff) 9
0x75, 0x20, // REPORT_SIZE (32) 14
0x95, 0x02, // REPORT_COUNT (2) 16
0x81, 0x02, // INPUT (Data,Var,Abs) 18/20
#endif
0xc0, // END_COLLECTION 0/1
0xc0, // END_COLLECTION 0/1


底下的資訊由微軟提出,隨時有可能修正:









Proposed Additions to the HID Specification to Support Multitouch
Description Page Type Name ID
Contact identifier Digitizer DV (Dynamic Value) Contact identifier 0x51
Configuration Digitizer CA (Collection Application) Configuration 0x0E
Input mode Digitizer DV (Dynamic Value) Input mode 0x52
Device index Digitizer DV (Dynamic Value) Device index 0x53
Actual contact count Digitizer DV (Dynamic Value) Contact count 0x54
Maximum number of contacts supported Digitizer DV (Dynamic Value) Maximum count 0x55


Reporting 模式有三種, 建議採用 Parallel Mode:
• Serial mode: 一次只有一個單一接觸點. 這種模式有可能會改變裝置報告的速度。
• Parallel mode: 每個封包夠寬,足以容納所有接觸
• Hybrid mode: 混合模式可以將前面兩個模式視為它的特例,它擁有固定寬度的封包,卻同時可以擁有多個封包內容。

Parallel Mode 會使用到 Actual contact count 及 Null Value, 底下有個範例,根據 maximum count 及 actual count 的不同可以視為 Parallel Mode 或 Hybrid Mode:

0x05, 0x0d, // USAGE_PAGE (Digitizers)
0x09, 0x04, // USAGE (Touch Screen)
0xa1, 0x01, // COLLECTION (Application)
0x85, REPORTID_PEN, // REPORT_ID (Touch)
0x09, 0x22, // USAGE (Finger)
0xa1, 0x02, // COLLECTION (Logical)
0x09, 0x42, // USAGE (Tip Switch)
0x15, 0x00, // LOGICAL_MINIMUM (0)
0x25, 0x01, // LOGICAL_MAXIMUM (1)
0x75, 0x01, // REPORT_SIZE (1)
0x95, 0x01, // REPORT_COUNT (1)
0x81, 0x02, // INPUT (Data,Var,Abs)
0x09, 0x32, // USAGE (In Range)
0x81, 0x02, // INPUT (Data,Var,Abs)
0x09, 0x47, // USAGE (Touch Valid)
0x81, 0x02, // INPUT (Data,Var,Abs)
0x95, 0x05, // REPORT_COUNT (5)
0x81, 0x03, // INPUT (Cnst,Ary,Abs)
0x75, 0x08, // REPORT_SIZE (8)
0x09, 0x51, // USAGE (Contact Identifier)
0x95, 0x01, // REPORT_COUNT (1)
0x81, 0x02, // INPUT (Data,Var,Abs)
0x05, 0x01, // USAGE_PAGE (Generic Desk..
0x26, 0xff, 0x7f, // LOGICAL_MAXIMUM (32767)
0x75, 0x10, // REPORT_SIZE (16)
0x55, 0x00, // UNIT_EXPONENT (0)
0x65, 0x00, // UNIT (None)
0x09, 0x30, // USAGE (X)
0x35, 0x00, // PHYSICAL_MINIMUM (0)
0x46, 0x00, 0x00, // PHYSICAL_MAXIMUM (0)
0x81, 0x02, // INPUT (Data,Var,Abs)
0x09, 0x31, // USAGE (Y)
0x46, 0x00, 0x00, // PHYSICAL_MAXIMUM (0)
0x81, 0x02, // INPUT (Data,Var,Abs)
0xc0, // END_COLLECTION
0xa1, 0x02, // COLLECTION (Logical)
0x05, 0x0d, // USAGE_PAGE (Digitizers)
0x09, 0x42, // USAGE (Tip Switch)
0x15, 0x00, // LOGICAL_MINIMUM (0)
0x25, 0x01, // LOGICAL_MAXIMUM (1)
0x75, 0x01, // REPORT_SIZE (1)
0x95, 0x01, // REPORT_COUNT (1)
0x81, 0x02, // INPUT (Data,Var,Abs)
0x09, 0x32, // USAGE (In Range)
0x81, 0x02, // INPUT (Data,Var,Abs)
0x09, 0x47, // USAGE (Touch Valid)
0x81, 0x02, // INPUT (Data,Var,Abs)
0x95, 0x05, // REPORT_COUNT (5)
0x81, 0x03, // INPUT (Cnst,Ary,Abs)
0x75, 0x08, // REPORT_SIZE (8)
0x09, 0x51, // USAGE ( Temp Identifier)
0x95, 0x01, // REPORT_COUNT (1)
0x81, 0x02, // INPUT (Data,Var,Abs)
0x05, 0x01, // USAGE_PAGE (Generic Desk..
0x26, 0xff, 0x7f, // LOGICAL_MAXIMUM (32767)
0x75, 0x10, // REPORT_SIZE (16)
0x55, 0x00, // UNIT_EXPONENT (0)
0x65, 0x00, // UNIT (None)
0x09, 0x30, // USAGE (X)
0x35, 0x00, // PHYSICAL_MINIMUM (0)
0x46, 0x00, 0x00, // PHYSICAL_MAXIMUM (0)
0x81, 0x02, // INPUT (Data,Var,Abs)
0x09, 0x31, // USAGE (Y)
0x46, 0x00, 0x00, // PHYSICAL_MAXIMUM (0)
0x81, 0x02, // INPUT (Data,Var,Abs)
0xc0, // END_COLLECTION
0x05, 0x0d, // USAGE_PAGE (Digitizers)
0x09, 0x54, // USAGE (Actual count)
0x95, 0x01, // REPORT_COUNT (1)
0x75, 0x08, // REPORT_SIZE (8)
0x15, 0x00, // LOGICAL_MINIMUM (0)
0x27, 0x08, // LOGICAL_MAXIMUM (255)
0x81, 0x02, // INPUT (Data,Var,Abs)
0x09, 0x56, // USAGE(Maximum Count)
0xb1, 0x02, // FEATURE (Data,Var,Abs)
0xc0, // END_COLLECTION


Top-Level Collection 每個裝置一定要有此描述內容,至少要指出來裝置是單點輸入、多點輸入或是滑鼠。

Collection Applications (CAs) 值對應的裝置若為底下的值,均可以用來做多點輸入:
Digitizer - 1
Pen - 2
Touch Screen - 4
Touch Pad - 5


多點觸控裝置應該在 top-level collections中採用 Finger (0x22) CL (Collection Logical) 來裝 data 及控制訊息。

多觸控裝置的尋找與組態能力:
尋找是透過 report descriptor 裡的 input mode 完成,也應該允許作業系統重新規劃成 multi-input, single-input, or mouse top-level collection。為了系統安全考量,此項 report descriptor 只允許作業系統存取,不開放第三方應用程式存取。這一點跟舊的 Vista 或 XP, 2000 都不一樣,舊的作業系統允許第三方應用程式透過 feature report 重設裝置為 single touch or the mouse。

Feature Report Requirements
所有裝置都需要一個 feature report 在其 report descriptor 中,以便報告裝置的組態。底下來看個實例:

0x06, 0x0d // USAGE_PAGE (Digitizer)
Ox09, 0x0E // USAGE (Configuration)
0x85, REPORTID_FEATURE, // REPORT_ID (Feature)
0xa1, 0x01, // COLLECTION (Application)
0x09, 0x52, // USAGE (Input Mode)
0x09, 0x53, // USAGE (Device Index)
0x15, 0x00, // LOGICAL_MINIMUM (0)
0x27, 0x08, // LOGICAL_MAXIMUM (255)
0x75, 0x08, // REPORT_SIZE (8)
0x95, 0x02, // REPORT_COUNT (2)
0xb1, 0x02, // FEATURE (Data,Var,Abs)
0xc0, // END_COLLECTION


Input Mode的值有:



Mode Value
Mouse (recommended default) 0x00
Single-input (single touch or stylus) 0x00
Multi-input 0x02

所以,多觸控點裝置是可以被重新設定成單一輸入裝置的,此時要表現的如作業系統所期望才行,而且微軟建議所有的多觸控裝置都預設採用 Mouse Mode。

Device Index
The device index usage selects the top-level collection to configure. A value of 0 tells the device to change the mode for every multi-input top-level collection in its report descriptor. A value of 1 and higher indicates the position of the top-level collection in the report descriptor. Applications that use values other than 0 must correctly handle the positions of the multi-input top-level collections in the report descriptor.

參考文獻:
  1. Device Class Definitions for Human Interface Devices (HID)
  2. HID Usage Tables

2008/12/08

Introduction to InterProcess Communication IPC 簡介

探討 IPC 的文章與文件相當多,例如 http://www.linuxhq.com/guides/LPG/node7.html, http://ai.ee.ccu.edu.tw/os/projects/2004fall/ipc_11/os-3.ppthttp://www.comms.scitech.susx.ac.uk/fft/computer/ipc.pdf是兩篇我覺得寫的很棒的文件,當然不是我寫的。

這邊畫蛇添足地說明一下,正常情況下,OS 為了保護每個 Process 的獨立性,不止從 User 來切割整個作業環境,而且也從 Process 來切割,意思是,每個 User 間是獨立的,互相不會影響,不會因為甲用戶惡搞當機而造成乙用戶也跟著當機,當然行程也是如此。這就導致行程間要互相溝通必須做到一件事:

透過 Kernel!

是可以自行利用 file lock 來溝通,但是這也會有問題,例如別人是否也想這麼做?同步問題怎麼解決?附件有提到幾種正規的作法我就不多談,只是要強調出來,正規作法,其實都是透過 kernel 來達成的。因此有必要對 Kernel 提供的機制進行瞭解,包括 Pipe, Name Pipe, Socket, 信號、共享記憶體等等作法都是如此。

事實上 Kernel 提供出來的機制除了 system call 外,還有其他作法,例如 /proc filesystem, 不過這一點有機會再來說明,這邊簡單的說一下,很多情況下,不止是 Process 間要溝通,連裝置間或是裝置與 Process 間要溝通,透過 /proc filesystem 是非常方便的,甚至比 ioctl 來得簡易。但是簡易不代表有效率。當然這作法有一種限制,你必須去改 kernel, 但是若你剛剛好是作嵌入式系統,必須動到 Kernel , 那麼順便修改並提供利用 /proc filesystem 來溝通的機制也是相當方便的。

/proc, /sys 等,都透露出 kernel 愈來愈 Open, 學習是值得的。


Best Regards
--
自由的精靈, 狂想的空間
Free Spirit, Fantasy Space
Marie von Ebner-Eschenbach  - "Even a stopped clock is right twice a day."

2008/12/02

Open Source 法律問題

想知道你的程式中,用了多少 Open Source 的片斷嗎?有一種暴力搜尋法軟體可以用,但是在說明之前先來回答一個問題,我猜會有人問「既然是 Open Source, 怎麼還會有法律問題」?答案其實很明顯,Open Source 所 Open 的是 Source, 並非智慧,也就是軟體並非免費,而是無價(ps:中文就是棒)。

台灣的自由軟體鑄造場裡頭還有工具可以幫你決定要採用哪一種授權,這邊直接回到主題:

http://www.blackducksoftware.com/ 上面問題的答案。
http://www.palamida.com/ 還可以幫你買保險,讓產品減少授權爭議的損失
http://fossology.org/ HP 丟出來的開源軟體