fortify/xcb/c.go

125 lines
2.9 KiB
Go
Raw Normal View History

package xcb
import (
"runtime"
"unsafe"
)
/*
#cgo linux pkg-config: xcb
#include <stdlib.h>
#include <xcb/xcb.h>
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)
}