Ophestra 4e7aab07d5
All checks were successful
Test / Create distribution (push) Successful in 35s
Test / Sandbox (push) Successful in 2m18s
Test / Hakurei (push) Successful in 3m17s
Test / Sandbox (race detector) (push) Successful in 4m7s
Test / Hpkg (push) Successful in 4m13s
Test / Hakurei (race detector) (push) Successful in 5m3s
Test / Flake checks (push) Successful in 1m40s
internal/system: relocate from system
These packages are highly specific to hakurei and are difficult to use safely from other pieces of code.

Their exported symbols are made available until v0.4.0 where they will be removed for #24.

Signed-off-by: Ophestra <cat@gensokyo.uk>
2025-11-13 01:17:47 +09:00

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