package xcb import ( "runtime" "unsafe" ) /* #cgo linux pkg-config: xcb #include #include static int _go_xcb_change_hosts_checked(xcb_connection_t *c, uint8_t mode, uint8_t family, uint16_t address_len, const uint8_t *address) { xcb_void_cookie_t cookie = xcb_change_hosts_checked(c, mode, family, address_len, address); free((void *)address); int errno = xcb_connection_has_error(c); if (errno != 0) return errno; xcb_generic_error_t *e = xcb_request_check(c, cookie); if (e != NULL) { // don't want to deal with xcb errors free((void *)e); return -1; } return 0; } */ import "C" const ( HostModeInsert = C.XCB_HOST_MODE_INSERT HostModeDelete = C.XCB_HOST_MODE_DELETE FamilyInternet = C.XCB_FAMILY_INTERNET FamilyDecnet = C.XCB_FAMILY_DECNET FamilyChaos = C.XCB_FAMILY_CHAOS FamilyServerInterpreted = C.XCB_FAMILY_SERVER_INTERPRETED FamilyInternet6 = C.XCB_FAMILY_INTERNET_6 ) type ( HostMode = C.xcb_host_mode_t Family = C.xcb_family_t ) func (conn *connection) changeHostsChecked(mode HostMode, family Family, address string) error { errno := C._go_xcb_change_hosts_checked( conn.c, C.uint8_t(mode), C.uint8_t(family), C.uint16_t(len(address)), (*C.uint8_t)(unsafe.Pointer(C.CString(address))), ) switch errno { case 0: return nil case -1: return ErrChangeHosts default: return &ConnectionError{errno} } } type connection struct{ c *C.xcb_connection_t } func connect() (*connection, error) { conn := newConnection(C.xcb_connect(nil, nil)) return conn, conn.hasError() } func newConnection(c *C.xcb_connection_t) *connection { conn := &connection{c} runtime.SetFinalizer(conn, (*connection).disconnect) return conn } const ( ConnError = C.XCB_CONN_ERROR ConnClosedExtNotSupported = C.XCB_CONN_CLOSED_EXT_NOTSUPPORTED ConnClosedMemInsufficient = C.XCB_CONN_CLOSED_MEM_INSUFFICIENT ConnClosedReqLenExceed = C.XCB_CONN_CLOSED_REQ_LEN_EXCEED ConnClosedParseErr = C.XCB_CONN_CLOSED_PARSE_ERR ConnClosedInvalidScreen = C.XCB_CONN_CLOSED_INVALID_SCREEN ) type ConnectionError struct{ errno C.int } func (ce *ConnectionError) Error() string { switch ce.errno { case ConnError: return "connection error" case ConnClosedExtNotSupported: return "extension not supported" case ConnClosedMemInsufficient: return "memory not available" case ConnClosedReqLenExceed: return "request length exceeded" case ConnClosedParseErr: return "invalid display string" case ConnClosedInvalidScreen: return "server has no screen matching display" default: return "generic X11 failure" } } func (conn *connection) hasError() error { errno := C.xcb_connection_has_error(conn.c) if errno == 0 { return nil } return &ConnectionError{errno} } func (conn *connection) disconnect() { C.xcb_disconnect(conn.c) // no need for a finalizer anymore runtime.SetFinalizer(conn, nil) }