All checks were successful
		
		
	
	Test / Create distribution (push) Successful in 35s
				
			Test / Sandbox (push) Successful in 1m52s
				
			Test / Hakurei (push) Successful in 3m16s
				
			Test / Hpkg (push) Successful in 3m39s
				
			Test / Sandbox (race detector) (push) Successful in 4m17s
				
			Test / Hakurei (race detector) (push) Successful in 5m22s
				
			Test / Flake checks (push) Successful in 1m36s
				
			This package still does not deserve to be out of internal, but at least it is less haunting now. I am still not handling the xcb error though, the struct is almost entirely undocumented and the implementation is unreadable. Not even going to try. Signed-off-by: Ophestra <cat@gensokyo.uk>
		
			
				
	
	
		
			128 lines
		
	
	
		
			3.1 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			128 lines
		
	
	
		
			3.1 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
// Package xcb implements X11 ChangeHosts via libxcb.
 | 
						|
package xcb
 | 
						|
 | 
						|
import (
 | 
						|
	"runtime"
 | 
						|
	"unsafe"
 | 
						|
)
 | 
						|
 | 
						|
/*
 | 
						|
#cgo linux pkg-config: --static xcb
 | 
						|
 | 
						|
#include <stdlib.h>
 | 
						|
#include <xcb/xcb.h>
 | 
						|
 | 
						|
static int hakurei_xcb_change_hosts_checked(xcb_connection_t *c,
 | 
						|
                                            uint8_t mode, uint8_t family,
 | 
						|
                                            uint16_t address_len, const uint8_t *address) {
 | 
						|
  int ret;
 | 
						|
  xcb_generic_error_t *e;
 | 
						|
  xcb_void_cookie_t cookie;
 | 
						|
 | 
						|
  cookie = xcb_change_hosts_checked(c, mode, family, address_len, address);
 | 
						|
  free((void *)address);
 | 
						|
 | 
						|
  ret = xcb_connection_has_error(c);
 | 
						|
  if (ret != 0)
 | 
						|
    return ret;
 | 
						|
 | 
						|
  e = xcb_request_check(c, cookie);
 | 
						|
  if (e != NULL) {
 | 
						|
    // don't want to deal with xcb errors
 | 
						|
    free((void *)e);
 | 
						|
    ret = -1;
 | 
						|
  }
 | 
						|
 | 
						|
  return ret;
 | 
						|
}
 | 
						|
*/
 | 
						|
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 {
 | 
						|
	ret := C.hakurei_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 ret {
 | 
						|
	case 0:
 | 
						|
		return nil
 | 
						|
	case -1:
 | 
						|
		return ErrChangeHosts
 | 
						|
	default:
 | 
						|
		return ConnectionError(ret)
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
type connection struct{ c *C.xcb_connection_t }
 | 
						|
 | 
						|
func (conn *connection) connect() error {
 | 
						|
	conn.c = C.xcb_connect(nil, nil)
 | 
						|
	runtime.SetFinalizer(conn, (*connection).disconnect)
 | 
						|
	return conn.hasError()
 | 
						|
}
 | 
						|
 | 
						|
func (conn *connection) hasError() error {
 | 
						|
	ret := C.xcb_connection_has_error(conn.c)
 | 
						|
	if ret == 0 {
 | 
						|
		return nil
 | 
						|
	}
 | 
						|
	return ConnectionError(ret)
 | 
						|
}
 | 
						|
 | 
						|
func (conn *connection) disconnect() {
 | 
						|
	C.xcb_disconnect(conn.c)
 | 
						|
 | 
						|
	// no need for a finalizer anymore
 | 
						|
	runtime.SetFinalizer(conn, nil)
 | 
						|
}
 | 
						|
 | 
						|
const (
 | 
						|
	ConnError                 ConnectionError = C.XCB_CONN_ERROR
 | 
						|
	ConnClosedExtNotSupported ConnectionError = C.XCB_CONN_CLOSED_EXT_NOTSUPPORTED
 | 
						|
	ConnClosedMemInsufficient ConnectionError = C.XCB_CONN_CLOSED_MEM_INSUFFICIENT
 | 
						|
	ConnClosedReqLenExceed    ConnectionError = C.XCB_CONN_CLOSED_REQ_LEN_EXCEED
 | 
						|
	ConnClosedParseErr        ConnectionError = C.XCB_CONN_CLOSED_PARSE_ERR
 | 
						|
	ConnClosedInvalidScreen   ConnectionError = C.XCB_CONN_CLOSED_INVALID_SCREEN
 | 
						|
)
 | 
						|
 | 
						|
// ConnectionError represents an error returned by xcb_connection_has_error.
 | 
						|
type ConnectionError int
 | 
						|
 | 
						|
func (ce ConnectionError) Error() string {
 | 
						|
	switch ce {
 | 
						|
	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"
 | 
						|
	}
 | 
						|
}
 |