トップ «前の日記(2017-11-29) 最新 次の日記(2017-12-07)» 編集

Cocoa練習帳

iOS/iPhone/iPad/watchOS/tvOS/MacOSX/Android プログラミング, Objective-C, Cocoa, Swiftなど

2012|01|02|03|04|05|06|07|08|09|10|11|12|
2013|01|02|03|04|05|06|07|08|09|10|11|12|
2014|01|02|03|04|05|06|07|08|09|10|11|12|
2015|01|02|03|04|05|06|07|08|09|10|11|12|
2016|01|02|03|04|05|06|07|08|09|10|11|12|
2017|01|02|03|04|05|06|07|08|09|10|11|12|

2017-12-06 [I/O Kit] USB Device Interfaceを試す

以前、Cocoa LifeというCocoa勉強会の会誌で、ジョイスティックをアプリケーションで扱うお話として、HID Device Interface入門という記事を書いたが、これをSwiftで挑戦してみようと思う。

今回対象となるのは、SmartScroll。左手で扱うトラックボール。知人がドライバを書いていたのだが、最新のOSに対応していないので、挑戦することにした。

SmartScroll

以前の開発環境には、USB Proberというアプリが存在したが、今の開発環境ではなくなった。そこで、当時から存在していたIORegistryExplorerを使うことにする。これは、別途、Additional Toolsとしてダウンロードしてインストールするものだ。

以下が、その結果。

IORegistryExplorer

赤い枠で囲まれた値が、機器の特定に必要となる情報だ。

今回、デモ用ということでコマンドラインツールとしてアプリを製作することにしたのだが、戸惑ったのは、main()関数をSwiftではどう書くか?結論は、main()関数は書かないということのようだ。

import Foundation
import CoreFoundation
import IOKit
import IOKit.usb.IOUSBLib
 
exit(0)

main()関数の戻り値は、exit()関数の引数で渡すということになる。

IORegistryExplorerで取得した値のVendor IDとProduct IDを使って機器を特定することにするのだが、それを定数として定義する。

let kOurVendorID = 0x56a    /* Vendor ID of the USB device */
let kOurProductID = 0x50    /* Product ID of device */

機器を探す条件の辞書を用意する。

var masterPort: mach_port_t = 0
let usbVendor: Int32 = Int32(kOurVendorID)
let usbProduct: Int32 = Int32(kOurProductID)
 
let kr: kern_return_t = IOMasterPort(mach_port_t(MACH_PORT_NULL), &masterPort)
 
var matchingDict = IOServiceMatching(kIOUSBDeviceClassName) as? [String: Any]
matchingDict![kUSBVendorID] = usbVendor
matchingDict![kUSBProductID] = usbProduct

検索条件を設定して、RunLoopで待つことにする。

private var gNotifyPort: IONotificationPortRef? = nil
private var gAddedIter: io_iterator_t = 0
 
gNotifyPort = IONotificationPortCreate(masterPort)
let runLoopSource = IONotificationPortGetRunLoopSource(gNotifyPort).takeUnretainedValue()
 
private var gRunLoop: CFRunLoop? = CFRunLoopGetCurrent()
CFRunLoopAddSource(gRunLoop, runLoopSource, CFRunLoopMode.defaultMode)
 
let _ = IOServiceAddMatchingNotification(gNotifyPort, kIOFirstMatchNotification, matchingDict! as CFDictionary, DeviceAdded, nil, &gAddedIter)
 
DeviceAdded(nil, gAddedIter)
 
CFRunLoopRun()

機器を見つけると呼ばれる関数の定義は以下の感じだ。

func DeviceAdded(_ refCon: UnsafeMutableRawPointer?, _ iterator: io_iterator_t) {
    print(#function)
}

これで動作確認してみたのだが、うまく動かない。申し訳ないが今回は時間切ということで続きは勉強会で!

_ 【Cocoa練習帳】

http://www.bitz.co.jp/weblog/
http://ameblo.jp/bitz/(ミラー・サイト)
Qiita

トップ «前の日記(2017-11-29) 最新 次の日記(2017-12-07)» 編集