From ddb003e39b64c2417cabc291383d99b4ad64ac8f Mon Sep 17 00:00:00 2001 From: Ophestra Date: Sat, 30 Aug 2025 20:02:18 +0900 Subject: [PATCH] system/internal/xcb: refactor and clean up 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 --- .../xcb/{export.go => changehosts.go} | 15 +-- system/internal/xcb/{c.go => xcb.go} | 97 ++++++++++--------- 2 files changed, 55 insertions(+), 57 deletions(-) rename system/internal/xcb/{export.go => changehosts.go} (55%) rename system/internal/xcb/{c.go => xcb.go} (50%) diff --git a/system/internal/xcb/export.go b/system/internal/xcb/changehosts.go similarity index 55% rename from system/internal/xcb/export.go rename to system/internal/xcb/changehosts.go index 1ed9997..8b05614 100644 --- a/system/internal/xcb/export.go +++ b/system/internal/xcb/changehosts.go @@ -1,21 +1,16 @@ -// Package xcb implements X11 ChangeHosts via libxcb. package xcb -import ( - "errors" -) +import "errors" var ErrChangeHosts = errors.New("xcb_change_hosts() failed") func ChangeHosts(mode HostMode, family Family, address string) error { - var conn *connection - - if c, err := connect(); err != nil { - c.disconnect() + conn := new(connection) + if err := conn.connect(); err != nil { + conn.disconnect() return err } else { - defer c.disconnect() - conn = c + defer conn.disconnect() } return conn.changeHostsChecked(mode, family, address) diff --git a/system/internal/xcb/c.go b/system/internal/xcb/xcb.go similarity index 50% rename from system/internal/xcb/c.go rename to system/internal/xcb/xcb.go index f2703f9..3dc62c3 100644 --- a/system/internal/xcb/c.go +++ b/system/internal/xcb/xcb.go @@ -1,3 +1,4 @@ +// Package xcb implements X11 ChangeHosts via libxcb. package xcb import ( @@ -11,22 +12,28 @@ import ( #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); +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; - int errno = xcb_connection_has_error(c); - if (errno != 0) - return errno; + cookie = xcb_change_hosts_checked(c, mode, family, address_len, address); + free((void *)address); - 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; - } + ret = xcb_connection_has_error(c); + if (ret != 0) + return ret; - return 0; + 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" @@ -48,49 +55,60 @@ type ( ) func (conn *connection) changeHostsChecked(mode HostMode, family Family, address string) error { - errno := C._go_xcb_change_hosts_checked( + 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 errno { + switch ret { case 0: return nil case -1: return ErrChangeHosts default: - return &ConnectionError{errno} + return ConnectionError(ret) } } type connection struct{ c *C.xcb_connection_t } -func connect() (*connection, error) { - conn := newConnection(C.xcb_connect(nil, nil)) - return conn, conn.hasError() +func (conn *connection) connect() error { + conn.c = C.xcb_connect(nil, nil) + runtime.SetFinalizer(conn, (*connection).disconnect) + return conn.hasError() } -func newConnection(c *C.xcb_connection_t) *connection { - conn := &connection{c} - runtime.SetFinalizer(conn, (*connection).disconnect) - return conn +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 = 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 + 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 ) -type ConnectionError struct{ errno C.int } +// ConnectionError represents an error returned by xcb_connection_has_error. +type ConnectionError int -func (ce *ConnectionError) Error() string { - switch ce.errno { +func (ce ConnectionError) Error() string { + switch ce { case ConnError: return "connection error" case ConnClosedExtNotSupported: @@ -107,18 +125,3 @@ func (ce *ConnectionError) Error() string { 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) -}