func startScanner(dir string) { lock.Lock() chans[dir] = make(chan string) lock.Unlock() cpaths := C.fswatch_make_mutable_array() defer C.free(unsafe.Pointer(cpaths)) path := C.CString(dir) str := C.CFStringCreateWithCString(nil, path, C.kCFStringEncodingUTF8) defer C.free(unsafe.Pointer(path)) defer C.free(unsafe.Pointer(str)) C.CFArrayAppendValue(cpaths, unsafe.Pointer(str)) ctx := C.FSEventStreamContext{info: unsafe.Pointer(C.CString(dir))} stream := C.fswatch_create(&ctx, cpaths, now, C.CFTimeInterval(interval/time.Second), cflags) go func() { C.FSEventStreamScheduleWithRunLoop(stream, C.CFRunLoopGetCurrent(), C.kCFRunLoopCommonModes) C.FSEventStreamStart(stream) C.CFRunLoopRun() }() }
func (w *Watcher) watchPath(path string, options *Options) error { path, _ = filepath.Abs(path) w.wmut.Lock() _, found := w.watches[path] w.wmut.Unlock() if !found { cPaths := C.ArrayCreateMutable(C.int(1)) defer C.CFRelease(C.CFTypeRef(cPaths)) cpath := C.CString(path) defer C.free(unsafe.Pointer(cpath)) str := C.CFStringCreateWithCString(nil, cpath, C.kCFStringEncodingUTF8) C.CFArrayAppendValue(cPaths, unsafe.Pointer(str)) context := C.FSEventStreamContext{info: unsafe.Pointer(&w.internalEvent)} latency := C.CFTimeInterval(0) if options != nil && options.Throttle { latency = C.CFTimeInterval(options.ThrottleDuration / time.Second) } stream := C.EventStreamCreate(&context, cPaths, C.kFSEventStreamEventIdSinceNow+(1<<64), latency) w.wmut.Lock() w.watches[path] = stream w.wmut.Unlock() C.FSEventStreamScheduleWithRunLoop(stream, w.rlref, C.kCFRunLoopDefaultMode) C.FSEventStreamStart(stream) } return nil }
func New(dev Device, since EventID, interval time.Duration, flags CreateFlags, paths ...string) *Stream { cpaths := C.fswatch_make_mutable_array() defer C.free(unsafe.Pointer(cpaths)) for _, dir := range paths { path := C.CString(dir) defer C.free(unsafe.Pointer(path)) str := C.CFStringCreateWithCString(nil, path, C.kCFStringEncodingUTF8) defer C.free(unsafe.Pointer(str)) C.CFArrayAppendValue(cpaths, unsafe.Pointer(str)) } csince := C.FSEventStreamEventId(since) cinterval := C.CFTimeInterval(interval / time.Second) cflags := C.FSEventStreamCreateFlags(flags &^ CF_USECFTYPES) s := new(Stream) s.Chan = make(chan []Event) ctx := C.FSEventStreamContext{info: unsafe.Pointer(&s.Chan)} var cstream C.FSEventStreamRef if dev == 0 { cstream = C.fswatch_create(&ctx, cpaths, csince, cinterval, cflags) } else { cdev := C.dev_t(dev) cstream = C.fswatch_create_relative_to_device( cdev, &ctx, cpaths, csince, cinterval, cflags) } s.cstream = cstream return s }
func stringToCFString(str string, callback func(cfStr C.CFStringRef)) { cStr := C.CString(str) cfStr := C.CFStringCreateWithCString(nil, cStr, C.kCFStringEncodingMacRoman) defer C.free(unsafe.Pointer(cStr)) defer C.CFRelease((C.CFTypeRef)(cfStr)) callback(cfStr) }
func (display Display) SetBrightness(value float64) { doWithBrightness(func(key *C.char) { C.IODisplaySetFloatParameter( C.CGDisplayIOServicePort(C.CGDirectDisplayID(display.id)), C.kNilOptions, C.CFStringCreateWithCString(nil, key, C.kCFStringEncodingMacRoman), C.float(value)) }) }
func (display Display) Brightness() float64 { value := C.float(0.0) doWithBrightness(func(key *C.char) { C.IODisplayGetFloatParameter( C.CGDisplayIOServicePort(C.CGDirectDisplayID(display.id)), C.kNilOptions, C.CFStringCreateWithCString(nil, key, C.kCFStringEncodingMacRoman), &value) }) return float64(value) }
/* Based on youpy's version in go-coremidi */ func strToCfstr(str string) C.CFStringRef { cStr := C.CString(str) cfStr := C.CFStringCreateWithCString(nil, cStr, C.kCFStringEncodingMacRoman) /* The next two lines cause C.MIDICreateClient to hang in client.go's MakeClient method. Removing them makes things work just fine. Potential memory leak by not freeing these? Need to understand better. youpy has all of this in a callback. */ //defer C.free(unsafe.Pointer(cStr)) //defer C.CFRelease((C.CFTypeRef)(cfStr)) return cfStr }
// Start listening to an event stream. func (es *EventStream) Start() { cPaths := C.ArrayCreateMutable(C.int(len(es.Paths))) defer C.CFRelease(C.CFTypeRef(cPaths)) for _, p := range es.Paths { p, _ = filepath.Abs(p) cpath := C.CString(p) defer C.free(unsafe.Pointer(cpath)) str := C.CFStringCreateWithCString(nil, cpath, C.kCFStringEncodingUTF8) C.CFArrayAppendValue(cPaths, unsafe.Pointer(str)) } since := C.FSEventStreamEventId(EventIDSinceNow) if es.Resume { since = C.FSEventStreamEventId(es.EventID) } if es.Events == nil { es.Events = make(chan []Event) } es.registryID = registry.Add(es) context := C.FSEventStreamContext{} info := C.uintptr_t(es.registryID) latency := C.CFTimeInterval(float64(es.Latency) / float64(time.Second)) if es.Device != 0 { es.stream = C.EventStreamCreateRelativeToDevice(&context, info, C.dev_t(es.Device), cPaths, since, latency, C.FSEventStreamCreateFlags(es.Flags)) } else { es.stream = C.EventStreamCreate(&context, info, cPaths, since, latency, C.FSEventStreamCreateFlags(es.Flags)) } started := make(chan struct{}) go func() { runtime.LockOSThread() es.rlref = C.CFRunLoopGetCurrent() C.FSEventStreamScheduleWithRunLoop(es.stream, es.rlref, C.kCFRunLoopDefaultMode) C.FSEventStreamStart(es.stream) close(started) C.CFRunLoopRun() }() if !es.hasFinalizer { runtime.SetFinalizer(es, finalizer) es.hasFinalizer = true } <-started }
func convertCStringToCFString(cstring *C.char) C.CFStringRef { return C.CFStringCreateWithCString(C.kCFAllocatorDefault, cstring, C.kCFStringEncodingUTF8) }