import Foundation #if canImport(Glibc) import Glibc #endif import ark_ui_basic // Protocol struct (25 bytes) // UInt8 cmd // Int32 x, y, w, h // UInt8 r, g, b, a struct UIDaemonCmd { var cmd: UInt8 var x: Int32 var y: Int32 var w: Int32 var h: Int32 var r: UInt8 var g: UInt8 var b: UInt8 var a: UInt8 } public class ArkGraphics { private var fd: Int32 = -1 public init() { fd = socket(AF_UNIX, Int32(SOCK_STREAM.rawValue), 0) if fd < 0 { return } var addr = sockaddr_un() addr.sun_family = sa_family_t(AF_UNIX) let socketPath = "/dev/display.sock" let pathBytes = socketPath.utf8CString withUnsafeMutablePointer(to: &addr.sun_path) { sunPathPtr in let rawPtr = UnsafeMutableRawPointer(sunPathPtr).assumingMemoryBound(to: CChar.self) for i in 0...size let connectResult = withUnsafePointer(to: &addr) { addrPtr in addrPtr.withMemoryRebound(to: sockaddr.self, capacity: 1) { saPtr in connect(fd, saPtr, socklen_t(addrSize)) } } if connectResult < 0 { close(fd) fd = -1 } } deinit { if fd >= 0 { close(fd) } } func fillRect(x: Int, y: Int, w: Int, h: Int, color: Color) { if fd < 0 { return } // For simplicity, handle standard colors manually since Color doesn't easily expose raw RGB in standard swiftUI without bridging var r: UInt8 = 0 var g: UInt8 = 0 var b: UInt8 = 0 // Very hacky Color comparison just for the test if color == Color.blue { r = 0; g = 0; b = 255 } else if color == Color.black { r = 0; g = 0; b = 0 } var msg = UIDaemonCmd(cmd: 1, x: Int32(x), y: Int32(y), w: Int32(w), h: Int32(h), r: r, g: g, b: b, a: 255) withUnsafeBytes(of: &msg) { bytes in _ = write(fd, bytes.baseAddress, bytes.count) } } public func fillRectRGB(x: Int, y: Int, w: Int, h: Int, r: UInt8, g: UInt8, b: UInt8) { if fd < 0 { return } var msg = UIDaemonCmd(cmd: 1, x: Int32(x), y: Int32(y), w: Int32(w), h: Int32(h), r: r, g: g, b: b, a: 255) withUnsafeBytes(of: &msg) { bytes in _ = write(fd, bytes.baseAddress, bytes.count) } } public func pan() { if fd < 0 { return } var msg = UIDaemonCmd(cmd: 2, x: 0, y: 0, w: 0, h: 0, r: 0, g: 0, b: 0, a: 0) withUnsafeBytes(of: &msg) { bytes in _ = write(fd, bytes.baseAddress, bytes.count) } } }