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"
 | |
| 	}
 | |
| }
 |