From d3a297447fb4a825b596e31baacb504a5c5516c4 Mon Sep 17 00:00:00 2001 From: wipedlifepotato <60944239+wipedlifepotato@users.noreply.github.com> Date: Thu, 18 Jun 2026 12:27:19 +0300 Subject: [PATCH 1/3] haiku gui os pre init tunnel show --- daemon/HaikuDaemon.cpp | 56 ++++++++++++++++++++++++++++++++++-------- 1 file changed, 46 insertions(+), 10 deletions(-) diff --git a/daemon/HaikuDaemon.cpp b/daemon/HaikuDaemon.cpp index 8e20cd45..da9c1a58 100644 --- a/daemon/HaikuDaemon.cpp +++ b/daemon/HaikuDaemon.cpp @@ -29,7 +29,6 @@ #include "Transports.h" #include "Daemon.h" #include "ClientContext.h" - enum { M_GRACEFUL_SHUTDOWN = 1, @@ -38,7 +37,8 @@ enum C_GRACEFUL_SHUTDOWN_UPDATE, C_MAIN_VIEW_UPDATE, M_SHOW_TUNNEL, - C_OPENHTTP + C_OPENHTTP, + M_SHOWMAIN }; constexpr bigtime_t GRACEFUL_SHUTDOWN_UPDATE_INTERVAL = 1000*1100; // in microseconds, ~ 1 sec constexpr int GRACEFUL_SHUTDOWN_UPDATE_COUNT = 600; // 10 minutes @@ -55,12 +55,14 @@ class MainWindow: public BWindow void GetInfoAboutTunnel(BMessage * msg); void UpdateMainView (); void OpenHTTPInterface(void); - template void DrawTunnel(T tun); + void DrawTunnel(std::stringstream & s); private: BMessenger m_Messenger; BStringView * m_MainView; std::unique_ptr m_MainViewUpdateTimer, m_GracefulShutdownTimer; bool m_IsGracefulShutdownComplete = false; + bool m_IsDrawTunnel = false; + i2p::data::IdentHash m_IdentHash; }; class I2PApp: public BApplication @@ -81,6 +83,7 @@ MainWindow::MainWindow (): auto runMenu = new BMenu ("Run"); runMenu->AddItem (new BMenuItem ("Open web interface", new BMessage(C_OPENHTTP))); runMenu->AddItem (new BMenuItem ("Graceful shutdown", new BMessage (M_GRACEFUL_SHUTDOWN), 'G')); + runMenu->AddItem (new BMenuItem ("Show Main page", new BMessage (M_SHOWMAIN), 'M')); runMenu->AddItem (new BMenuItem ("Quit", new BMessage (B_QUIT_REQUESTED), 'Q')); menuBar->AddItem (runMenu); auto commandsMenu = new BMenu ("Commands"); @@ -116,14 +119,38 @@ MainWindow::MainWindow (): void MainWindow::UpdateMainView () { std::stringstream s; - i2p::util::PrintMainWindowText (s); + if(!m_IsDrawTunnel) + i2p::util::PrintMainWindowText (s); + else + DrawTunnel(s); + ////std::cout << s.str() << std::endl; m_MainView->SetText (s.str ().c_str ()); } -template -void MainWindow :: DrawTunnel(T tun) // idk about type, so todo: change to normal type +void MainWindow :: DrawTunnel(std::stringstream & s) { - m_MainView->SetText( i2p::client::context.GetAddressBook().ToAddress(tun).c_str() ); + s << "\r\n"; + s << "I2P Address: " << i2p::client::context.GetAddressBook().ToAddress(m_IdentHash) << ".b32.i2p\r\n"; + s << "\r\n"; + auto dest = i2p::client::context.FindLocalDestination (m_IdentHash); + if(!dest) + { + s << "Can't found local dest\r\n"; + } + else + { + s << "Streams: \r\n"; + for (auto stream : dest->GetAllStreams()) + { + auto streamDest = i2p::client::context.GetAddressBook().ToAddress(stream->GetRemoteIdentity()); + std::string streamDestShort = streamDest.substr(0,12) + ".b32.i2p"; + s << streamDestShort << "out:" << stream->GetNumSentBytes() << ";in:" << stream->GetNumReceivedBytes() << "\r\n"; + /* + * void ShowLocalDestination in daemon/HTTPServer.cpp + */ + } + s << "\r\n"; + } } void MainWindow :: GetInfoAboutTunnel(BMessage * msg) @@ -140,7 +167,9 @@ void MainWindow :: GetInfoAboutTunnel(BMessage * msg) if( BString(it.second->GetName()) == name ) { auto & ident = it.second->GetLocalDestination()->GetIdentHash(); - return DrawTunnel(ident); + m_IdentHash = ident; + m_IsDrawTunnel = true; + return UpdateMainView(); //TODO: } } @@ -150,7 +179,9 @@ void MainWindow :: GetInfoAboutTunnel(BMessage * msg) if( BString(it.second->GetName()) == name) { auto & ident = it.second->GetLocalDestination()->GetIdentHash(); - return DrawTunnel(ident); + m_IdentHash = ident; + m_IsDrawTunnel = true; + return UpdateMainView(); //TODO: } } @@ -167,7 +198,7 @@ void MainWindow :: OpenHTTPInterface() return m_MainView->SetText("Not enabled http server"); } std::ostringstream com; - com << "WebPositive http://" << address << ":" << port; + com << "/bin/open 'http://" << address << ":" << port<<"'"; //char * argv[] = {(char*)url.str().c_str() , NULL, NULL}; //BRoster{}.Launch( "application/x-vnd.Haiku-WebPositive", 2, argv); std::string com_s{com.str()}; @@ -182,6 +213,11 @@ void MainWindow::MessageReceived (BMessage * msg) if (!msg) return; switch (msg->what) { + case M_SHOWMAIN: + m_IsDrawTunnel = false; + m_IdentHash = {}; + UpdateMainView(); + break; case C_MAIN_VIEW_UPDATE: UpdateMainView (); break; From 5b8bf014f3199b4e4f62a4ef00d836251511dba7 Mon Sep 17 00:00:00 2001 From: wipedlifepotato <60944239+wipedlifepotato@users.noreply.github.com> Date: Sat, 20 Jun 2026 16:54:57 +0300 Subject: [PATCH 2/3] pre-init: Tab view for tunnels --- daemon/HaikuDaemon.cpp | 68 ++++++++++++++++++++++++++++++++++++------ 1 file changed, 59 insertions(+), 9 deletions(-) diff --git a/daemon/HaikuDaemon.cpp b/daemon/HaikuDaemon.cpp index da9c1a58..e8ad2d81 100644 --- a/daemon/HaikuDaemon.cpp +++ b/daemon/HaikuDaemon.cpp @@ -15,6 +15,10 @@ #include #include #include +#include +#include +#include +#include #include #include #include @@ -38,7 +42,8 @@ enum C_MAIN_VIEW_UPDATE, M_SHOW_TUNNEL, C_OPENHTTP, - M_SHOWMAIN + M_SHOWMAIN, + M_CLOSETUNNEL }; constexpr bigtime_t GRACEFUL_SHUTDOWN_UPDATE_INTERVAL = 1000*1100; // in microseconds, ~ 1 sec constexpr int GRACEFUL_SHUTDOWN_UPDATE_COUNT = 600; // 10 minutes @@ -56,8 +61,10 @@ class MainWindow: public BWindow void UpdateMainView (); void OpenHTTPInterface(void); void DrawTunnel(std::stringstream & s); + size_t m_counter_streams = 0; private: BMessenger m_Messenger; + BTabView * m_tab_view; BStringView * m_MainView; std::unique_ptr m_MainViewUpdateTimer, m_GracefulShutdownTimer; bool m_IsGracefulShutdownComplete = false; @@ -105,51 +112,91 @@ MainWindow::MainWindow (): tunnelsMenu->AddItem (new BMenuItem (it.second->GetName (), msg)); } menuBar->AddItem (tunnelsMenu); - m_MainView = new BStringView (BRect (20, 21, 300, 250), nullptr, "Starting...", B_FOLLOW_ALL, B_WILL_DRAW); + + m_tab_view = new BTabView(Bounds().OffsetByCopy(0, 20), "tabview"); + AddChild(m_tab_view); + + BRect tabRect = m_tab_view->ContainerView()->Bounds(); + auto bview = new BView(tabRect, "main_tab", B_FOLLOW_ALL, B_WILL_DRAW); + bview->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR)); + + m_MainView = new BStringView(BRect(10, 10, tabRect.right - 10, tabRect.bottom - 10),"info_view", "Starting...", B_FOLLOW_ALL); + bview->AddChild(m_MainView); + + m_tab_view->AddTab(bview); + m_tab_view->TabAt(m_counter_streams)->SetLabel("Info"); + m_MainView->SetViewColor (255, 255, 255); m_MainView->SetHighColor (0xD4, 0x3B, 0x69); BFont font = *be_plain_font; font.SetSize (12); m_MainView->SetFont (&font); - AddChild (m_MainView); m_MainViewUpdateTimer = std::make_unique(m_Messenger, BMessage (C_MAIN_VIEW_UPDATE), MAIN_VIEW_UPDATE_INTERVAL); -} +} void MainWindow::UpdateMainView () { std::stringstream s; if(!m_IsDrawTunnel) + { i2p::util::PrintMainWindowText (s); + } else + { DrawTunnel(s); + } ////std::cout << s.str() << std::endl; m_MainView->SetText (s.str ().c_str ()); } void MainWindow :: DrawTunnel(std::stringstream & s) { - s << "\r\n"; + + s << "\n"; s << "I2P Address: " << i2p::client::context.GetAddressBook().ToAddress(m_IdentHash) << ".b32.i2p\r\n"; - s << "\r\n"; + auto dest = i2p::client::context.FindLocalDestination (m_IdentHash); + while(m_tab_view->CountTabs() > 1) + { + m_tab_view->RemoveTab(m_tab_view->CountTabs() - 1); + } + m_counter_streams = 0; + //std::cout << "Draw List View" << std::endl;; if(!dest) { s << "Can't found local dest\r\n"; } else { - s << "Streams: \r\n"; + s << "Streams: \n"; for (auto stream : dest->GetAllStreams()) { + std::stringstream s1; auto streamDest = i2p::client::context.GetAddressBook().ToAddress(stream->GetRemoteIdentity()); std::string streamDestShort = streamDest.substr(0,12) + ".b32.i2p"; - s << streamDestShort << "out:" << stream->GetNumSentBytes() << ";in:" << stream->GetNumReceivedBytes() << "\r\n"; + s1 << streamDestShort << "|out|" << stream->GetNumSentBytes() << "|in:" << stream->GetNumReceivedBytes() <<"|"; + + BRect tabRect = m_tab_view->ContainerView()->Bounds(); + auto bview = new BView(tabRect, streamDestShort.c_str(), B_FOLLOW_ALL, B_WILL_DRAW); + bview->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR)); + + auto tunnel_view = new BStringView(BRect(0, 0, tabRect.right - 10, tabRect.bottom - 10),"tunnel_view", "tunnel_view...", B_FOLLOW_ALL); + + tunnel_view->SetText (s.str ().c_str ()); + bview->AddChild(tunnel_view); + + + m_tab_view->AddTab(bview); + m_tab_view->TabAt(++m_counter_streams)->SetLabel(streamDestShort.c_str()); + + /* * void ShowLocalDestination in daemon/HTTPServer.cpp */ + s << s1.str() << "\n"; } - s << "\r\n"; + //s << "\r\n"; } } @@ -213,6 +260,9 @@ void MainWindow::MessageReceived (BMessage * msg) if (!msg) return; switch (msg->what) { + case M_CLOSETUNNEL: + std::cout << "Close Tunnel (DEBUG NOT WORKS)" << std::endl; + break; case M_SHOWMAIN: m_IsDrawTunnel = false; m_IdentHash = {}; From 7f3df4382ff5829cb368f580ae6c9ac6da505692 Mon Sep 17 00:00:00 2001 From: wipedlifepotato <60944239+wipedlifepotato@users.noreply.github.com> Date: Sat, 20 Jun 2026 20:03:35 +0300 Subject: [PATCH 3/3] Haiku gui, close button --- daemon/HaikuDaemon.cpp | 40 +++++++++++++++++++++++++++++++++------- 1 file changed, 33 insertions(+), 7 deletions(-) diff --git a/daemon/HaikuDaemon.cpp b/daemon/HaikuDaemon.cpp index e8ad2d81..f4a31618 100644 --- a/daemon/HaikuDaemon.cpp +++ b/daemon/HaikuDaemon.cpp @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -43,7 +44,7 @@ enum M_SHOW_TUNNEL, C_OPENHTTP, M_SHOWMAIN, - M_CLOSETUNNEL + M_CLOSETUNNEL }; constexpr bigtime_t GRACEFUL_SHUTDOWN_UPDATE_INTERVAL = 1000*1100; // in microseconds, ~ 1 sec constexpr int GRACEFUL_SHUTDOWN_UPDATE_COUNT = 600; // 10 minutes @@ -149,7 +150,12 @@ void MainWindow::UpdateMainView () ////std::cout << s.str() << std::endl; m_MainView->SetText (s.str ().c_str ()); } - +/* + * Логика - создать вектор с streamID + vector dest. + * не перерисовывать каждый раз а лишь добавлять которых нет + * и удалять те которые есть + * кнопка close работает + * */ void MainWindow :: DrawTunnel(std::stringstream & s) { @@ -181,12 +187,19 @@ void MainWindow :: DrawTunnel(std::stringstream & s) auto bview = new BView(tabRect, streamDestShort.c_str(), B_FOLLOW_ALL, B_WILL_DRAW); bview->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR)); - auto tunnel_view = new BStringView(BRect(0, 0, tabRect.right - 10, tabRect.bottom - 10),"tunnel_view", "tunnel_view...", B_FOLLOW_ALL); + auto tunnel_view = new BStringView(BRect(0, 0, tabRect.right - 100, tabRect.bottom - 100),"tunnel_view", "tunnel_view...", B_FOLLOW_ALL); - tunnel_view->SetText (s.str ().c_str ()); + tunnel_view->SetText (s1.str ().c_str ()); + BRect btnRect{10,10,90,35};//10+32,10+12); + auto msg = new BMessage(M_CLOSETUNNEL); + msg->AddUInt32("tunnel_val", stream->GetRecvStreamID()); + BButton * closeButton = new BButton( + btnRect,"close leaseset", "close", msg + ); + bview->AddChild(closeButton); bview->AddChild(tunnel_view); - + m_tab_view->AddTab(bview); m_tab_view->TabAt(++m_counter_streams)->SetLabel(streamDestShort.c_str()); @@ -256,12 +269,25 @@ void MainWindow :: OpenHTTPInterface() void MainWindow::MessageReceived (BMessage * msg) { - if (!msg) return; + uint32_t tunnel_val;// streamID (to method) switch (msg->what) { + // to method case M_CLOSETUNNEL: - std::cout << "Close Tunnel (DEBUG NOT WORKS)" << std::endl; + //std::cout << "Close Tunnel (DEBUG NOT WORKS)" << std::endl; + msg->FindUInt32("tunnel_val", &tunnel_val); + if(tunnel_val) + { + auto dest = + i2p::client::context.FindLocalDestination + (m_IdentHash); + if(dest) + { + dest->DeleteStream(tunnel_val); + } + } + break; case M_SHOWMAIN: m_IsDrawTunnel = false;