|
|
@ -271,38 +271,73 @@ func get_private_key(path string, generate bool) ed25519.PrivateKey {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func print_decoration(window, channels, body ncurses.Window, top_left string) {
|
|
|
|
func print_decoration(window, title, channels, body ncurses.Window, top_left string) {
|
|
|
|
max_y := ncurses.GetMaxY(*ncurses.CurScr)
|
|
|
|
max_y := ncurses.GetMaxY(*ncurses.CurScr)
|
|
|
|
max_x := ncurses.GetMaxX(*ncurses.CurScr)
|
|
|
|
max_x := ncurses.GetMaxX(*ncurses.CurScr)
|
|
|
|
|
|
|
|
|
|
|
|
ncurses.WResize(channels, max_y - 2, (max_x / 4) - 1)
|
|
|
|
ncurses.WResize(window, max_y, max_x)
|
|
|
|
ncurses.WResize(body, max_y - 2, max_x - (max_x / 4) - 1)
|
|
|
|
ncurses.WResize(title, 1, max_x/4-2)
|
|
|
|
ncurses.MvWin(body, 2, (max_x / 4) + 1)
|
|
|
|
ncurses.MvWin(title, 1, 1)
|
|
|
|
|
|
|
|
ncurses.WResize(channels, max_y - 4, (max_x / 4) - 2)
|
|
|
|
|
|
|
|
ncurses.MvWin(channels, 3, 1)
|
|
|
|
|
|
|
|
ncurses.WResize(body, max_y - 2, max_x - (max_x / 4) - 2)
|
|
|
|
|
|
|
|
ncurses.MvWin(body, 1, (max_x / 4) + 1)
|
|
|
|
|
|
|
|
|
|
|
|
ncurses.MvWAddStr(window, 0, 0, top_left)
|
|
|
|
ncurses.MvWAddStr(title, 0, 0, top_left)
|
|
|
|
|
|
|
|
|
|
|
|
for i := 0; i < max_x; i++ {
|
|
|
|
for i := 1; i < max_x - 1; i++ {
|
|
|
|
ncurses.MvWAddStr(window, 1, i, "═")
|
|
|
|
ncurses.MvWAddStr(window, 0, i, "═")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
ncurses.MvWAddStr(window, 1, max_x/4, "╦")
|
|
|
|
for i := 1; i < max_x/4; i++ {
|
|
|
|
for i := 2; i < max_y; i++ {
|
|
|
|
ncurses.MvWAddStr(window, 2, i, "═")
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for i := 1; i < max_y-1; i++ {
|
|
|
|
|
|
|
|
ncurses.MvWAddStr(window, i, 0, "║")
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for i := 1; i < max_y-1; i++ {
|
|
|
|
|
|
|
|
ncurses.MvWAddStr(window, i, max_x-1, "║")
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for i := 1; i < max_y-1; i++ {
|
|
|
|
ncurses.MvWAddStr(window, i, max_x/4, "║")
|
|
|
|
ncurses.MvWAddStr(window, i, max_x/4, "║")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for i := 1; i < max_x-1; i++ {
|
|
|
|
|
|
|
|
ncurses.MvWAddStr(window, max_y - 1, i, "═")
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ncurses.MvWAddStr(window, 0, 0, "╔")
|
|
|
|
|
|
|
|
ncurses.MvWAddStr(window, 0, max_x-1, "╗")
|
|
|
|
|
|
|
|
ncurses.MvWAddStr(window, 0, max_x/4, "╦")
|
|
|
|
|
|
|
|
ncurses.MvWAddStr(window, 2, 0, "╠")
|
|
|
|
|
|
|
|
ncurses.MvWAddStr(window, 2, max_x/4, "╣")
|
|
|
|
|
|
|
|
ncurses.MvWAddStr(window, max_y-1, 0, "╚")
|
|
|
|
|
|
|
|
ncurses.MvWAddStr(window, max_y-1, max_x/4, "╩")
|
|
|
|
|
|
|
|
ncurses.MvWAddStr(window, max_y-1, max_x-1, "╝")
|
|
|
|
|
|
|
|
|
|
|
|
ncurses.WRefresh(window)
|
|
|
|
ncurses.WRefresh(window)
|
|
|
|
|
|
|
|
ncurses.WRefresh(title)
|
|
|
|
ncurses.WRefresh(channels)
|
|
|
|
ncurses.WRefresh(channels)
|
|
|
|
ncurses.WRefresh(body)
|
|
|
|
ncurses.WRefresh(body)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func main_loop(client *pnyx.Client, audio_data chan []int16, window ncurses.Window, packet_chan chan pnyx.Payload, user_chan chan []byte) {
|
|
|
|
func main_loop(client *pnyx.Client, audio_data chan []int16, window ncurses.Window, packet_chan chan pnyx.Payload, user_chan chan []byte, sigwinch_channel chan os.Signal) {
|
|
|
|
channels := ncurses.NewWin(0, 0, 2, 0)
|
|
|
|
channels := ncurses.NewWin(0, 0, 0, 0)
|
|
|
|
body := ncurses.NewWin(0, 0, 2, 0)
|
|
|
|
body := ncurses.NewWin(0, 0, 0, 0)
|
|
|
|
|
|
|
|
title := ncurses.NewWin(0, 0, 0, 0)
|
|
|
|
|
|
|
|
|
|
|
|
print_decoration(window, channels, body, fmt.Sprintf("pnyx client %X:%X", client.Key.Public().(ed25519.PublicKey)[:2], client.Session.ID[:2]))
|
|
|
|
print_decoration(window, title, channels, body, client.Remote())
|
|
|
|
|
|
|
|
|
|
|
|
for client.Active() {
|
|
|
|
for client.Active() {
|
|
|
|
select {
|
|
|
|
select {
|
|
|
|
|
|
|
|
case <-sigwinch_channel:
|
|
|
|
|
|
|
|
ncurses.EndWin()
|
|
|
|
|
|
|
|
ncurses.WRefresh(window)
|
|
|
|
|
|
|
|
ncurses.WClear(window)
|
|
|
|
|
|
|
|
print_decoration(window, title, channels, body, client.Remote())
|
|
|
|
case packet := <-packet_chan:
|
|
|
|
case packet := <-packet_chan:
|
|
|
|
switch packet := packet.(type) {
|
|
|
|
switch packet := packet.(type) {
|
|
|
|
case pnyx.ChannelCommandPacket:
|
|
|
|
case pnyx.ChannelCommandPacket:
|
|
|
@ -421,7 +456,10 @@ func main() {
|
|
|
|
panic(ret)
|
|
|
|
panic(ret)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
go main_loop(client, audio_data, window, packet_chan, user_chan)
|
|
|
|
sigwinch_channel := make(chan os.Signal, 1)
|
|
|
|
|
|
|
|
signal.Notify(sigwinch_channel, syscall.SIGWINCH)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
go main_loop(client, audio_data, window, packet_chan, user_chan, sigwinch_channel)
|
|
|
|
|
|
|
|
|
|
|
|
os_sigs := make(chan os.Signal, 1)
|
|
|
|
os_sigs := make(chan os.Signal, 1)
|
|
|
|
signal.Notify(os_sigs, syscall.SIGINT, syscall.SIGABRT)
|
|
|
|
signal.Notify(os_sigs, syscall.SIGINT, syscall.SIGABRT)
|
|
|
|