x11: wrap libxcb ChangeHosts request

Even though many pure Go libxcb implementations exist, it is at least as complex and unreadable as libxcb, if not more. Since well known libraries like SDL, qt and gtk uses libxcb, and they somehow understand how to use it, I can only assume these people have read enough code to make sure it's correct enough. Call it wishful thinking. I don't care anymore.

Signed-off-by: Ophestra Umiker <cat@ophivana.moe>
This commit is contained in:
Ophestra Umiker 2024-07-14 18:31:53 +09:00
parent 65c02b540d
commit 518fd54ff3
Signed by: cat
SSH Key Fingerprint: SHA256:gQ67O0enBZ7UdZypgtspB2FDM1g3GVw8nX0XSdcFw8Q
2 changed files with 72 additions and 1 deletions

1
acl.go
View File

@ -1,6 +1,5 @@
package main
import "C"
import (
"errors"
"fmt"

72
x11.go Normal file
View File

@ -0,0 +1,72 @@
package main
import "C"
import (
"errors"
"unsafe"
)
//#include <stdlib.h>
//#include <xcb/xcb.h>
//#cgo linux LDFLAGS: -lxcb
import "C"
const (
xcbHostModeInsert = C.XCB_HOST_MODE_INSERT
xcbHostModeDelete = C.XCB_HOST_MODE_DELETE
xcbFamilyInternet = C.XCB_FAMILY_INTERNET
xcbFamilyDecnet = C.XCB_FAMILY_DECNET
xcbFamilyChaos = C.XCB_FAMILY_CHAOS
xcbFamilyServerInterpreted = C.XCB_FAMILY_SERVER_INTERPRETED
xcbFamilyInternet6 = C.XCB_FAMILY_INTERNET_6
)
func changeHosts(mode, family C.uint8_t, address string) error {
var c *C.xcb_connection_t
c = C.xcb_connect(nil, nil)
defer C.xcb_disconnect(c)
if err := xcbHandleConnectionError(c); err != nil {
return err
}
addr := C.CString(address)
cookie := C.xcb_change_hosts_checked(c, mode, family, C.ushort(len(address)), (*C.uchar)(unsafe.Pointer(addr)))
C.free(unsafe.Pointer(addr))
if err := xcbHandleConnectionError(c); err != nil {
return err
}
e := C.xcb_request_check(c, cookie)
if e != nil {
defer C.free(unsafe.Pointer(e))
return errors.New("xcb_change_hosts() failed")
}
return nil
}
func xcbHandleConnectionError(c *C.xcb_connection_t) error {
if errno := C.xcb_connection_has_error(c); errno != 0 {
switch errno {
case C.XCB_CONN_ERROR:
return errors.New("connection error")
case C.XCB_CONN_CLOSED_EXT_NOTSUPPORTED:
return errors.New("extension not supported")
case C.XCB_CONN_CLOSED_MEM_INSUFFICIENT:
return errors.New("memory not available")
case C.XCB_CONN_CLOSED_REQ_LEN_EXCEED:
return errors.New("request length exceeded")
case C.XCB_CONN_CLOSED_PARSE_ERR:
return errors.New("invalid display string")
case C.XCB_CONN_CLOSED_INVALID_SCREEN:
return errors.New("server has no screen matching display")
default:
return errors.New("generic X11 failure")
}
} else {
return nil
}
}