// Open HID by vendorId, productId and serialNumber. // SerialNumber is optional and can be empty string (""). // Returns a *Devica and an error. func Open(vendorId uint16, productId uint16, serialNumber string) (*Device, error) { var err error // call hidInit(). hidInit() checks if actual call to hid_hidInit() is required. if err = hidInit(); err != nil { return nil, err } // serialNumberWchar value. Default nil. serialNumberWcharPtr := (*C.wchar_t)(nil) // if a serialNumber is given, create a WcharString and set the pointer to it's first position pointer if len(serialNumber) > 0 { serialNumberWchar, err := wchar.FromGoString(serialNumber) if err != nil { return nil, errors.New("Unable to convert serialNumber to WcharString") } serialNumberWcharPtr = (*C.wchar_t)(unsafe.Pointer(serialNumberWchar.Pointer())) } // call hid_open() hidHandle := C.hid_open(C.ushort(vendorId), C.ushort(productId), serialNumberWcharPtr) if hidHandle == nil { return nil, errors.New("Unable to open device.") } dev := &Device{ hidHandle: hidHandle, } // done return dev, nil }
// SetColorTemp changes the Xrandr colors to reflect the specified color temperature. func SetColorTemp(temp int) { dpy := C.XOpenDisplay(nil) screenCount := C.screenCount(dpy) for screen := C.int(0); screen < screenCount; screen++ { root := C.RootWindowMacro(dpy, screen) res := C.XRRGetScreenResourcesCurrent(dpy, root) if temp < 1000 || temp > 10000 { temp = 6500 } temp -= 1000 ratio := float64((temp-1000)%500) / 500.0 point := whitepoints[temp/500] gammar := point.r*(1-ratio) + point.r*ratio gammag := point.g*(1-ratio) + point.g*ratio gammab := point.b*(1-ratio) + point.b*ratio for c := C.int(0); c < res.ncrtc; c++ { crtcxid := C.crtcxid(res.crtcs, c) size := C.XRRGetCrtcGammaSize(dpy, crtcxid) crtc_gamma := C.XRRAllocGamma(size) for i := C.int(0); i < size; i++ { g := 65535.0 * float64(i) / float64(size) C.ushortSet(crtc_gamma.red, i, C.ushort(g*gammar)) C.ushortSet(crtc_gamma.green, i, C.ushort(g*gammag)) C.ushortSet(crtc_gamma.blue, i, C.ushort(g*gammab)) } C.XRRSetCrtcGamma(dpy, crtcxid, crtc_gamma) C.XFree(unsafe.Pointer(crtc_gamma)) } } }
func (t *pty) open(cols, rows int) error { var winp = new(C.struct_winsize) winp.ws_col = C.ushort(cols) winp.ws_row = C.ushort(rows) winp.ws_xpixel = 0 winp.ws_ypixel = 0 var master, slave C.int var name = make([]C.char, 40) if ret := int(C.GoOpenpty(&master, &slave, &name[0], winp)); ret == -1 { return errors.New("openpty(3) failed") } t.master = int(master) t.slave = int(slave) t.pty = C.GoString(&name[0]) if err := syscall.SetNonblock(t.master, true); err != nil { return err } if err := syscall.SetNonblock(t.slave, true); err != nil { return err } return nil }
func makeCWindowSize(sz *WindowSize) C.struct_winsize { var winsize C.struct_winsize winsize.ws_row = C.ushort(sz.Rows) winsize.ws_col = C.ushort(sz.Cols) winsize.ws_xpixel = C.ushort(sz.PixelWidth) winsize.ws_ypixel = C.ushort(sz.PixelHeight) return winsize }
// Retrieve a list of DeviceInfo objects that match the given vendorId and productId. // To retrieve a list of all HID devices': use 0x0 as vendorId and productId. func Enumerate(vendorId uint16, productId uint16) (DeviceInfoList, error) { var err error // call C.hid_enumerate with given parameters first := C.hid_enumerate(C.ushort(vendorId), C.ushort(productId)) // check for failure if first == nil { return nil, errors.New("Could not enumerate devices. Failure.") } // defer free-ing first defer C.hid_free_enumeration(first) // make DeviceInfoList to fill dil := make(DeviceInfoList, 0) // loop over linked list to fill DeviceInfoList for next := first; next != nil; next = next.next { // create DeviceInfo instance from next hid_device_info di := &DeviceInfo{ Path: C.GoString(next.path), VendorId: uint16(next.vendor_id), ProductId: uint16(next.product_id), ReleaseNumber: uint16(next.release_number), UsagePage: uint16(next.usage_page), Usage: uint16(next.usage), InterfaceNumber: int(next.interface_number), } // get and convert serial_number from next hid_device_info di.SerialNumber, err = wchar.WcharStringPtrToGoString(unsafe.Pointer(next.serial_number)) if err != nil { log.Println("Error converting the Serial Number, setting to empty string") di.SerialNumber = "" } // get and convert manufacturer_string from next hid_device_info di.Manufacturer, err = wchar.WcharStringPtrToGoString(unsafe.Pointer(next.manufacturer_string)) if err != nil { log.Println("Error converting the Manufacturer, setting to empty string") di.Manufacturer = "" } // get and convert product_string from next hid_device_info di.Product, err = wchar.WcharStringPtrToGoString(unsafe.Pointer(next.product_string)) if err != nil { return nil, fmt.Errorf("Could not convert *C.wchar_t product_string from hid_device_info to go string. Error: %s\n", err) } // store di in dil dil = append(dil, di) } // all done return dil, nil }
func ffi_type_make(size int, alignment int, typ CType, elements **C.ffi_type) C.ffi_type { csize := C.size_t(size) calign := C.ushort(alignment) ctype := C.ushort(typ) celem := (**_Cstruct__ffi_type)(elements) return C.ffi_type{csize, calign, ctype, celem} }
func (s *Sheet) getInfo(i int, handle unsafe.Pointer) error { var name *C.char var numRow C.uint var numCol C.ushort ret := C.freexl_get_worksheet_name(handle, C.ushort(i), &name) if ret != OK { return fmt.Errorf("Freexl: error get sheet name :%d", ret) } s.Name = C.GoString(name) ret = C.freexl_select_active_worksheet(handle, C.ushort(i)) if ret != OK { return fmt.Errorf("Freexl: failed to selct worksheet: %s", ret) } ret = C.freexl_worksheet_dimensions(handle, &numRow, &numCol) if ret != OK { return fmt.Errorf("Freexl: failed to get dimensions: %s", ret) } s.MaxRow = int(numRow) s.MaxCol = int(numCol) s.Values = make([][]string, s.MaxRow) for i, row := range s.Values { row = make([]string, s.MaxCol) var cell C.FreeXL_CellValue for j := range row { ret = C.freexl_get_cell_value(handle, C.uint(i), C.ushort(j), &cell) if ret != OK { continue } switch C.freexl_cell_get_type(cell) { case CELL_DOUBLE: row[j] = fmt.Sprintf("%1.12f", float64(C.freexl_cell_get_double_value(cell))) case CELL_INT: row[j] = fmt.Sprintf("%d", int(C.freexl_cell_get_int_value(cell))) case CELL_TEXT, CELL_SST_TEXT, CELL_DATE, CELL_DATETIME, CELL_TIME: row[j] = C.GoString(C.freexl_cell_get_text_value(cell)) default: fallthrough case CELL_NULL: row[j] = "" } } s.Values[i] = row } return nil }
func (this *GammaRamp) toPtr() (ptr *C.GLFWgammaramp) { size := C.size_t(unsafe.Sizeof(ptr)) ptr = (*C.GLFWgammaramp)(C.malloc(size)) for i := 0; i < GammaRampSize; i++ { ptr.red[i] = C.ushort(this.Red[i]) ptr.green[i] = C.ushort(this.Green[i]) ptr.blue[i] = C.ushort(this.Blue[i]) } return }
func (t *pty) resize(cols, rows int) error { var winp = new(C.struct_winsize) winp.ws_col = C.ushort(cols) winp.ws_row = C.ushort(rows) winp.ws_xpixel = 0 winp.ws_ypixel = 0 if ret := int(C.GoResize(C.int(t.fd), winp)); ret == -1 { return errors.New("ioctl(2) failed") } return nil }
//SetGammaRamp sets the current gamma ramp for the monitor. func (m *Monitor) SetGammaRamp(ramp *GammaRamp) { var rampC C.GLFWgammaramp length := len(ramp.Red) for i := 0; i < length; i++ { C.SetGammaAtIndex(rampC.red, C.int(i), C.ushort(ramp.Red[i])) C.SetGammaAtIndex(rampC.green, C.int(i), C.ushort(ramp.Green[i])) C.SetGammaAtIndex(rampC.blue, C.int(i), C.ushort(ramp.Blue[i])) } C.glfwSetGammaRamp(m.data, &rampC) }
func (z *zeroconf) addPrinter(name string, port uint16, ty, url, id string, online bool) error { r := record{ name: C.CString(name), port: port, ty: ty, url: url, id: id, online: online, } z.spMutex.Lock() defer z.spMutex.Unlock() if _, exists := z.printers[name]; exists { return fmt.Errorf("printer %s was already added to Avahi publishing", name) } if z.state == C.AVAHI_CLIENT_S_RUNNING { txt := prepareTXT(ty, url, id, online) defer C.avahi_string_list_free(txt) C.avahi_threaded_poll_lock(z.threadedPoll) defer C.avahi_threaded_poll_unlock(z.threadedPoll) if errstr := C.addAvahiGroup(z.threadedPoll, z.client, &r.group, r.name, C.ushort(r.port), txt); errstr != nil { err := fmt.Errorf("Failed to add Avahi group: %s", C.GoString(errstr)) return err } } z.printers[name] = r return nil }
func (s *Shout) updateParameters() { // set hostname p := C.CString(s.Host) C.shout_set_host(s.struc, p) C.free(unsafe.Pointer(p)) // set port C.shout_set_port(s.struc, C.ushort(s.Port)) // set username p = C.CString(s.User) C.shout_set_user(s.struc, p) C.free(unsafe.Pointer(p)) // set password p = C.CString(s.Password) C.shout_set_password(s.struc, p) C.free(unsafe.Pointer(p)) // set mount point p = C.CString(s.Mount) C.shout_set_mount(s.struc, p) C.free(unsafe.Pointer(p)) // set format C.shout_set_format(s.struc, C.uint(s.Format)) // set protocol C.shout_set_protocol(s.struc, C.uint(s.Protocol)) }
// WaitZero adds and operation that will block until a semaphore's number is 0. func (so *SemOps) WaitZero(num uint16, flags *SemOpFlags) error { *so = append(*so, C.struct_sembuf{ sem_num: C.ushort(num), sem_op: C.short(0), sem_flg: C.short(flags.flags()), }) return nil }
func (f *Freexl) getInfo(t int) (int, error) { var info C.uint ret := C.freexl_get_info(f.handle, C.ushort(t), &info) if ret != OK { return 0, fmt.Errorf("Freexl: error get info %d: %d", t, ret) } return int(info), nil }
// ConstDefined checks if the given constant is defined in the scope. // // This should be used, for example, before a call to Class, because a // failure in Class will crash your program (by design). You can retrieve // the Value of a Class by calling Value(). func (m *Mrb) ConstDefined(name string, scope Value) bool { cs := C.CString(name) defer C.free(unsafe.Pointer(cs)) scopeV := scope.MrbValue(m).value b := C.mrb_const_defined( m.state, scopeV, C.mrb_intern_cstr(m.state, cs)) return C.ushort(b) != 0 }
func (t *pty) fork(file string, args, env []string, cwd string, cols, rows, uid, gid int) error { var winp = new(C.struct_winsize) winp.ws_col = C.ushort(cols) winp.ws_row = C.ushort(rows) winp.ws_xpixel = 0 winp.ws_ypixel = 0 //fork the pty var master C.int = -1 var name []C.char = make([]C.char, 40) var pid C.int = C.GoForkpty(&master, &name[0], winp) t.fd = int(master) t.pid = int(pid) t.pty = C.GoString(&name[0]) switch t.pid { case -1: return errors.New("forkpty(3) failed") case 0: if cwd != "" { if err := syscall.Chdir(cwd); err != nil { panic("chdir failed") } } if uid != -1 && gid != -1 { if err := syscall.Setgid(gid); err != nil { panic("setgid failed") } if err := syscall.Setuid(uid); err != nil { panic("setuid failed") } } syscall.Exec(file, args, env) panic("exec failed") } return nil }
func Get(device string, width uint16, height uint16) []byte { deviceName := C.CString(device) defer C.free(unsafe.Pointer(deviceName)) // 80K ought to be enough for anybody :) buffer := unsafe.Pointer(C.calloc(80000, 1)) defer C.free(buffer) bufSize := C.camsnap_shot(deviceName, C.ushort(width), C.ushort(height), (*C.byte)(buffer)) var arrayptr = uintptr(buffer) var rawBytes = make([]byte, bufSize) for i := 0; i < len(rawBytes); i++ { rawBytes[i] = byte(*(*C.byte)(unsafe.Pointer(arrayptr))) arrayptr++ } return rawBytes }
// handleClientStateChange makes clean transitions as the connection with // avahi-daemon changes. //export handleClientStateChange func handleClientStateChange(client *C.AvahiClient, newState C.AvahiClientState, userdata unsafe.Pointer) { z := instance z.spMutex.Lock() defer z.spMutex.Unlock() // Name conflict. if newState == C.AVAHI_CLIENT_S_COLLISION { log.Warning("Avahi reports a host name collision.") } // Transition from not connecting to connecting. Warn in logs. if newState == C.AVAHI_CLIENT_CONNECTING { log.Warning("Cannot find Avahi daemon. Is it running?") } // Transition from running to not running. Free all groups. if newState != C.AVAHI_CLIENT_S_RUNNING { log.Info("Local printing disabled (Avahi client is not running).") for name, r := range z.printers { if r.group != nil { if errstr := C.removeAvahiGroup(z.threadedPoll, r.group); errstr != nil { err := errors.New(C.GoString(errstr)) log.Errorf("Failed to remove Avahi group: %s", err) } r.group = nil z.printers[name] = r } } } // Transition from not running to running. Recreate all groups. if newState == C.AVAHI_CLIENT_S_RUNNING { log.Info("Local printing enabled (Avahi client is running).") for name, r := range z.printers { txt := prepareTXT(r.ty, r.url, r.id, r.online) defer C.avahi_string_list_free(txt) if errstr := C.addAvahiGroup(z.threadedPoll, z.client, &r.group, r.name, C.ushort(r.port), txt); errstr != nil { err := errors.New(C.GoString(errstr)) log.Errorf("Failed to add Avahi group: %s", err) } z.printers[name] = r } } // Transition from not failure to failure. Recreate thread poll and client. if newState == C.AVAHI_CLIENT_FAILURE { z.restart <- struct{}{} } z.state = newState }
// Decrement adds an operation that will decrease a semaphore's number. func (so *SemOps) Decrement(num uint16, by int16, flags *SemOpFlags) error { if by <= 0 { return errors.New("sysvipc: by must be >0. use WaitZero or Increment") } *so = append(*so, C.struct_sembuf{ sem_num: C.ushort(num), sem_op: C.short(-by), sem_flg: C.short(flags.flags()), }) return nil }
// Set updates parameters of the semaphore set. func (ss *SemaphoreSet) Set(ssi *SemSetInfo) error { sds := &C.struct_semid_ds{ sem_perm: C.struct_ipc_perm{ uid: C.__uid_t(ssi.Perms.OwnerUID), gid: C.__gid_t(ssi.Perms.OwnerGID), mode: C.ushort(ssi.Perms.Mode & 0x1FF), }, } rc, err := C.semctl_buf(C.int(ss.id), C.IPC_SET, sds) if rc == -1 { return err } return nil }
// Set updates parameters of the shared memory segment. func (shm *SharedMem) Set(info *SHMInfo) error { shmds := &C.struct_shmid_ds{ shm_perm: C.struct_ipc_perm{ uid: C.__uid_t(info.Perms.OwnerUID), gid: C.__gid_t(info.Perms.OwnerGID), mode: C.ushort(info.Perms.Mode & 0x1FF), }, } rc, err := C.shmctl(C.int(shm.id), C.IPC_SET, shmds) if rc == -1 { return err } return nil }
// Set updates parameters of the queue. func (mq MessageQueue) Set(mqi *MQInfo) error { mqds := &C.struct_msqid_ds{ msg_perm: C.struct_ipc_perm{ uid: C.__uid_t(mqi.Perms.OwnerUID), gid: C.__gid_t(mqi.Perms.OwnerGID), mode: C.ushort(mqi.Perms.Mode & 0x1FF), }, msg_qbytes: C.msglen_t(mqi.MaxBytes), } rc, err := C.msgctl(C.int(mq), C.IPC_SET, mqds) if rc == -1 { return err } return nil }
// Setall sets the values of every semaphore in the set func (ss *SemaphoreSet) Setall(values []uint16) error { if uint(len(values)) != ss.count { return errors.New("sysvipc: wrong number of values for Setall") } carr := make([]C.ushort, ss.count) for i, val := range values { carr[i] = C.ushort(val) } rc, err := C.semctl_arr(C.int(ss.id), C.SETALL, &carr[0]) if rc == -1 { return err } return nil }
func (z *zeroconf) addPrinter(name string, port uint16, ty, url, id string, online bool) error { r := record{ name: C.CString(name), port: port, ty: ty, url: url, id: id, online: online, } z.spMutex.Lock() defer z.spMutex.Unlock() if _, exists := z.printers[name]; exists { return fmt.Errorf("printer %s was already added to Avahi publishing", name) } if z.state == C.AVAHI_CLIENT_S_RUNNING { tyC := C.CString(ty) defer C.free(unsafe.Pointer(tyC)) urlC := C.CString(url) defer C.free(unsafe.Pointer(urlC)) idC := C.CString(id) defer C.free(unsafe.Pointer(idC)) var onlineC *C.char if online { onlineC = C.CString("online") } else { onlineC = C.CString("offline") } defer C.free(unsafe.Pointer(onlineC)) C.avahi_threaded_poll_lock(z.threadedPoll) defer C.avahi_threaded_poll_unlock(z.threadedPoll) var errstr *C.char C.addAvahiGroup(z.threadedPoll, z.client, &r.group, r.name, C.ushort(port), tyC, urlC, idC, onlineC, &errstr) if errstr != nil { err := errors.New(C.GoString(errstr)) C.free(unsafe.Pointer(errstr)) return err } } z.printers[name] = r return nil }
// Initialize GoTypes in NumTypeMap func initTypeMap() { cgoNumMap["C.char"] = GetNumInfo(C.char(0)) cgoNumMap["C.schar"] = GetNumInfo(C.schar(0)) cgoNumMap["C.uchar"] = GetNumInfo(C.uchar(0)) cgoNumMap["C.short"] = GetNumInfo(C.short(0)) cgoNumMap["C.ushort"] = GetNumInfo(C.ushort(0)) cgoNumMap["C.wchar_t"] = GetNumInfo(C.wchar_t(0)) cgoNumMap["C.int"] = GetNumInfo(C.int(0)) cgoNumMap["C.uint"] = GetNumInfo(C.uint(0)) cgoNumMap["C.long"] = GetNumInfo(C.long(0)) cgoNumMap["C.ulong"] = GetNumInfo(C.ulong(0)) cgoNumMap["C.longlong"] = GetNumInfo(C.longlong(0)) cgoNumMap["C.ulonglong"] = GetNumInfo(C.ulonglong(0)) cgoNumMap["C.float"] = GetNumInfo(C.float(0)) cgoNumMap["C.double"] = GetNumInfo(C.double(0)) cgoNumMap["complex64"] = GetNumInfo(complex64(0)) cgoNumMap["complex128"] = GetNumInfo(complex128(0)) }
func (z *zeroconf) addPrinter(name string, port uint16, ty, url, id string, online bool) error { z.pMutex.RLock() if _, exists := z.printers[name]; exists { z.pMutex.RUnlock() return fmt.Errorf("Bonjour already has printer %s", name) } z.pMutex.RUnlock() nameC := C.CString(name) defer C.free(unsafe.Pointer(nameC)) serviceTypeC := C.CString(serviceType) defer C.free(unsafe.Pointer(serviceTypeC)) tyC := C.CString(ty) defer C.free(unsafe.Pointer(tyC)) urlC := C.CString(url) defer C.free(unsafe.Pointer(urlC)) idC := C.CString(id) defer C.free(unsafe.Pointer(idC)) var onlineC *C.char if online { onlineC = C.CString("online") } else { onlineC = C.CString("offline") } defer C.free(unsafe.Pointer(onlineC)) var errstr *C.char = nil service := C.startBonjour(nameC, serviceTypeC, C.ushort(port), tyC, urlC, idC, onlineC, &errstr) if errstr != nil { defer C.free(unsafe.Pointer(errstr)) return errors.New(C.GoString(errstr)) } z.pMutex.Lock() defer z.pMutex.Unlock() z.printers[name] = service return nil }
func (a *AdvancedSettings) toC() *C.FMOD_ADVANCEDSETTINGS { var as C.FMOD_ADVANCEDSETTINGS as.cbSize = C.int(a.CbSize) as.maxMPEGCodecs = C.int(a.MaxMPEGCodecs) as.maxADPCMCodecs = C.int(a.MaxADPCMCodecs) as.maxXMACodecs = C.int(a.MaxXMACodecs) as.maxVorbisCodecs = C.int(a.MaxVorbisCodecs) as.maxAT9Codecs = C.int(a.MaxAT9Codecs) as.maxFADPCMCodecs = C.int(a.MaxFADPCMCodecs) as.maxPCMCodecs = C.int(a.MaxPCMCodecs) as.ASIONumChannels = C.int(a.ASIONumChannels) outer := make([]*C.char, a.ASIONumChannels+1) for i, inner := range a.ASIOChannelList { outer[i] = C.CString(string(inner)) } as.ASIOChannelList = (**C.char)(unsafe.Pointer(&outer[0])) //as.ASIOSpeakerList = C.FMOD_SPEAKER(a.ASIOSpeakerList) //TODO as.HRTFMinAngle = C.float(a.HRTFMinAngle) as.HRTFMaxAngle = C.float(a.HRTFMaxAngle) as.HRTFFreq = C.float(a.HRTFFreq) as.vol0virtualvol = C.float(a.Vol0virtualvol) as.defaultDecodeBufferSize = C.uint(a.DefaultDecodeBufferSize) as.profilePort = C.ushort(a.ProfilePort) as.geometryMaxFadeTime = C.uint(a.GeometryMaxFadeTime) as.distanceFilterCenterFreq = C.float(a.DistanceFilterCenterFreq) as.reverb3Dinstance = C.int(a.Reverb3Dinstance) as.DSPBufferPoolSize = C.int(a.DSPBufferPoolSize) as.stackSizeStream = C.uint(a.StackSizeStream) as.stackSizeNonBlocking = C.uint(a.StackSizeNonBlocking) as.stackSizeMixer = C.uint(a.StackSizeMixer) as.resamplerMethod = C.FMOD_DSP_RESAMPLER(a.ReSamplerMethod) as.commandQueueSize = C.uint(a.CommandQueueSize) as.randomSeed = C.uint(a.RandomSeed) return *(**C.FMOD_ADVANCEDSETTINGS)(unsafe.Pointer(&as)) }
// Simple is the 'simple' interface. // If port is 0, the default remctl port is used // If principal is "", the default principal of "host/<hostname>" is used // // For more control of how the call is made, use the more 'complex' // interface. func Simple(host string, port uint16, principal string, command []string) (*RemctlResult, error) { var res *C.struct_remctl_result host_c := C.CString(host) defer C.free(unsafe.Pointer(host_c)) var principal_c *_Ctype_char if principal != "" { principal_c = C.CString(principal) defer C.free(unsafe.Pointer(principal_c)) } command_len := len(command) command_c := C.makeCharArray(C.int(command_len)) defer C.freeCharArray(command_c, C.int(command_len)) for i, s := range command { C.setArrayString(command_c, C.CString(s), C.int(i)) } res, err := C.remctl(host_c, C.ushort(port), principal_c, command_c) if res == nil { return nil, err } else { defer C.remctl_result_free((*C.struct_remctl_result)(unsafe.Pointer(res))) result := &RemctlResult{} stdout_len := (C.int)(res.stdout_len) stderr_len := (C.int)(res.stderr_len) result.Stdout = C.GoStringN(res.stdout_buf, stdout_len) result.Stderr = C.GoStringN(res.stderr_buf, stderr_len) result.Status = (int)(res.status) if res.error != nil { return nil, errors.New(C.GoString(res.error)) } return result, nil } }
// Open() a connection // // Open a connection to `host' on port `port'. If port is 0, use the default // remctl port. You may specify a principal to use in `principal', if it is // a blank string the remctl will use the default principal. func (r *remctl) Open(host string, port uint16, principal string) error { if r.isopen() { return errors.New("Already open") } host_c := C.CString(host) defer C.free(unsafe.Pointer(host_c)) port_c := C.ushort(port) principal_c := get_principal(principal) if principal != "" { // If principal is empty, principal_c is NULL, don't free defer C.free(unsafe.Pointer(principal_c)) } if opened := C.remctl_open(r.ctx, host_c, port_c, principal_c); opened != 1 { return r.get_error() } r.open = true return nil }
// handleClientStateChange makes clean transitions as the connection with // avahi-daemon changes. //export handleClientStateChange func handleClientStateChange(client *C.AvahiClient, newState C.AvahiClientState, userdata unsafe.Pointer) { z := instance z.spMutex.Lock() defer z.spMutex.Unlock() // Transition from not connecting to connecting. Warn in logs. if z.state != C.AVAHI_CLIENT_CONNECTING && newState == C.AVAHI_CLIENT_CONNECTING { glog.Warning("Avahi client is looking for avahi-daemon. Is it running?") } // Transition from running to not running. Free all groups. if z.state == C.AVAHI_CLIENT_S_RUNNING && newState != C.AVAHI_CLIENT_S_RUNNING { glog.Info("Avahi client stopped running.") for name, r := range z.printers { if r.group != nil { var errstr *C.char C.removeAvahiGroup(z.threadedPoll, r.group, &errstr) if errstr != nil { fmt.Println(C.GoString(errstr)) C.free(unsafe.Pointer(errstr)) } r.group = nil z.printers[name] = r } } } // Transition from not running to running. Recreate all groups. if z.state != C.AVAHI_CLIENT_S_RUNNING && newState == C.AVAHI_CLIENT_S_RUNNING { glog.Info("Avahi client running.") for name, r := range z.printers { tyC := C.CString(r.ty) defer C.free(unsafe.Pointer(tyC)) urlC := C.CString(r.url) defer C.free(unsafe.Pointer(urlC)) idC := C.CString(r.id) defer C.free(unsafe.Pointer(idC)) var onlineC *C.char if r.online { onlineC = C.CString("online") } else { onlineC = C.CString("offline") } defer C.free(unsafe.Pointer(onlineC)) var errstr *C.char C.addAvahiGroup(z.threadedPoll, z.client, &r.group, r.name, C.ushort(r.port), tyC, urlC, idC, onlineC, &errstr) if errstr != nil { err := errors.New(C.GoString(errstr)) C.free(unsafe.Pointer(errstr)) glog.Error(err) } z.printers[name] = r } } // Transition from not failure to failure. Recreate thread poll and client. if z.state != C.AVAHI_CLIENT_FAILURE && newState == C.AVAHI_CLIENT_FAILURE { z.restart <- struct{}{} } z.state = newState }