[racket] Fwd: FFI: Create reference to Objective C object
Okay that clears up one confusion. Now for the next.
I am trying to copy this Swift code:
import Foundation
import Cocoa
import Carbon
import AppKit
// The current text input source (read keyboard) has a layout in which
// we can lookup how key-codes are resolved.
// Get the a reference keyboard using the current layout.
var unmanagedKeyboard = TISCopyCurrentKeyboardLayoutInputSource()
var keyboard = unmanagedKeyboard.takeUnretainedValue() as TISInputSource
print("Keyboard: ") ; println(keyboard)
// Get the layout
var ptrLayout = TISGetInputSourceProperty(keyboard,
kTISPropertyUnicodeKeyLayoutData)
var layout = UnsafeMutablePointer<UCKeyboardLayout>(ptrLayout)
print("Layout: "); println(layout)
Running the code (as-is) in XCode prints:
Keyboard: <TSMInputSource 0x10051a930> KB Layout: U.S. (id=0)
Layout: 0x0000000102802000
In Racket I get #f (i.e. null) back as the layout.
I thought the problem was that I had defined the constant
kTISPropertyUnicodeKeyLayoutData
incorrectly, but since NSString is a reference, I think it is ok.
#lang racket
(require ffi/unsafe/objc)
(require ffi/unsafe
ffi/unsafe/objc
ffi/unsafe/define
mred/private/wx/cocoa/image
mred/private/wx/cocoa/types)
(define quartz-lib (ffi-lib
"/System/Library/Frameworks/Quartz.framework/Versions/Current/Quartz"))
(define carbon-lib (ffi-lib
"/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon"))
(define carbon-core-lib
(ffi-lib (string-append "/System/Library/Frameworks/CoreServices.framework/"
"Frameworks/CarbonCore.framework/Versions/Current/CarbonCore")))
(define cf-lib
(case (system-type)
[(macosx) (ffi-lib
"/System/Library/Frameworks/CoreFoundation.framework/CoreFoundation")]
[else #f]))
(define-ffi-definer define-quartz quartz-lib)
(define-ffi-definer define-carbon-core carbon-core-lib)
(define-ffi-definer define-carbon carbon-lib)
(define-ffi-definer define-cf cf-lib #:default-make-fail
make-not-available)
(import-class NSString CFData)
;;; API Constants
(define _CFStringRef _NSString)
(define kTISPropertyUnicodeKeyLayoutData
(tell (tell NSString alloc)
initWithUTF8String: #:type _string "kTISPropertyUnicodeKeyLayoutData"))
;;; Get the current text input source (read: the keyboard)
(define _TISInputSourceRef (_cpointer 'TISInputSourceRef))
(define-carbon TISCopyCurrentKeyboardLayoutInputSource
(_fun -> _TISInputSourceRef))
(define the-keyboard (TISCopyCurrentKeyboardLayoutInputSource))
(displayln (list 'keyboard the-keyboard))
;;; Get the layout of the keyboard
(define-cpointer-type _CFDataRef)
(define-carbon TISGetInputSourceProperty
(_fun (_inputSource : _TISInputSourceRef)
(_propertyKey : _CFStringRef)
-> (_or-null _CFDataRef)))
(define the-keyboard-layout-data
(TISGetInputSourceProperty the-keyboard "kTISPropertyUnicodeKeyLayoutData"))
(displayln (list 'layoutData the-keyboard-layout-data))
2015-01-02 14:56 GMT+01:00 Matthew Flatt <mflatt at cs.utah.edu>:
> In this example, `kTISPropertyUnicodeKeyLayoutData` is already a
> `CFStringRef` (a.k.a. `NSString*`).
>
> The type `_NSString` from `mred/private/wx/cocoa/types` (or, better for
> most purposes, from `ffi/unsafe/nsstring`) is really a pointer to an
> `_NSString`; it just gets tedious to put `Ref` or `-pointer`
> everywhere. I'll fix the docs for `_NSString`.
>
> At Fri, 2 Jan 2015 14:37:20 +0100, Jens Axel Søgaard wrote:
>> What is the best way of creating a reference to an existing Objective C object?
>>
>> Concretely given an CFString how do I get an CFStringRef (aka pointer
>> to a CFStringRef).
>>
>> /Jens Axel
>>
>>
>> #lang racket
>> (require ffi/unsafe/objc)
>> (require ffi/unsafe
>> ffi/unsafe/objc
>> ffi/unsafe/define
>> mred/private/wx/cocoa/types)
>>
>> ;; Import CoreFoundation
>> (define cf-lib
>> (case (system-type)
>> [(macosx) (ffi-lib
>> "/System/Library/Frameworks/CoreFoundation.framework/CoreFoundation")]
>> [else #f]))
>>
>> (define-ffi-definer define-cf cf-lib #:default-make-fail make-not-available)
>>
>> ;; CFString and NSString are equivalent (?)
>> (import-class NSString)
>> (define _CFString _NSString)
>>
>> ;; Create an CFString
>> (define kTISPropertyUnicodeKeyLayoutData
>> (tell (tell NSString alloc)
>> initWithUTF8String: #:type _string "kTISPropertyUnicodeKeyLayoutData"))
>>
>> ;; The API needs an CFStringRef that is a pointer to CFString.
>> (define _CFStringRef (_ptr i _CFString))
>>
>>
>> (define reference-to-kTISPropertyUnicodeKeyLayoutData '???)
>> ____________________
>> Racket Users list:
>> http://lists.racket-lang.org/users
--
--
Jens Axel Søgaard
--
--
Jens Axel Søgaard