Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion PIwebVNC.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ int main(int argc, char *argv[])
std::cout << "\n[HINT] Open http://localhost:" << SERVER_PORT << " in your browser" << std::endl;
std::cout << "[HINT] ---OR---" << std::endl;
std::cout << "[HINT] Open http://Ip-of-PI:" << SERVER_PORT << " from different PC\n"<< std::endl;

vncServer.start(argc, argv);
Display *display = vncServer.xdisplay.getDisplay();
Websocket ws;
XInputs input(display);
Expand Down
Binary file added lib_Xvfb_x86.a
Binary file not shown.
64 changes: 58 additions & 6 deletions libs/display.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@
#include <string>
#include "websocket.hpp"


// forward declare dix_main from libXvfb.a
extern "C" int dix_main(int argc, char *argv[], char *envp[]);

struct ScreenInfo
{
int width;
Expand All @@ -39,22 +43,28 @@ struct ScreenInfo
class XDisplay
{
public:
XDisplay();
~XDisplay();
void close();
Display *getDisplay();
std::string getDisplayConfig();
ScreenInfo getScreenInfo();
std::string getCursorName();
int getBitPerLine();

void start();
void setArg(int argc, char **argv) {
this->argc = argc;
this->argv = argv;
}
private:
void startXvfb();
Display *display = 0;
int bitPerLine = 0;
std::thread xvfbThread;
int argc =0;
char **argv;
};

XDisplay::XDisplay()
{
void XDisplay::start() {
// get result of command "echo $DISPLAY"
try
{
Expand All @@ -78,14 +88,56 @@ XDisplay::XDisplay()
if (this->display == 0)
{
#if ERROR || DEBUG
std::cout << "[ERROR][EXIT APP] Could not open display. Please pass --display [id].\n\t eg: --display 18." << std::endl;
std::cout << "[ERROR][EXIT APP] Could not open display. The built-in X-server will be used !" << std::endl;
#endif
exit(1);
startXvfb();

// retry until Xvfb is ready
for (int i = 0; i < 50 && this->display == nullptr; i++)
{
std::this_thread::sleep_for(std::chrono::milliseconds(200));
this->display = XOpenDisplay(":0"); // assume :0
}

if (this->display == nullptr)
{
std::cerr << "[ERROR] Could not start built-in X-server, exiting app." << std::endl;
exit(1);
}
}
#if ERROR || DEBUG
std::cout << "[LOG] Display opened successfully." << std::endl;
#endif
}

void XDisplay::startXvfb()
{
int main_argc = this->argc;
char **orig_argv = this->argv;

xvfbThread = std::thread([main_argc, orig_argv]() {
// Copy argv safely
char **main_argv = new char*[main_argc + 1];
for (int i = 0; i < main_argc; i++) {
main_argv[i] = new char[strlen(orig_argv[i]) + 1];
strcpy(main_argv[i], orig_argv[i]);
}
main_argv[main_argc] = nullptr;

extern char **environ;
dix_main(main_argc, main_argv, environ); // blocks until server exit

// Cleanup after dix_main returns
for (int i = 0; i < main_argc; i++) {
delete[] main_argv[i];
}
delete[] main_argv;
});

xvfbThread.detach();
}


XDisplay::~XDisplay()
{
// free display
Expand Down
2 changes: 1 addition & 1 deletion libs/httpPage.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -9692,7 +9692,7 @@ void parseHttpPage()
return;
}
statusdiv.innerText = "connecting...";
let ws = new WebSocket("ws://" + location.host);
let ws = new WebSocket((location.protocol === 'https:' ? 'wss' : 'ws') + '://' + location.host);
webSocket = ws;
ws.onerror = function (evt) {
//console.log("WebSocket Error: ", e);
Expand Down
9 changes: 5 additions & 4 deletions libs/vncserver.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,11 @@ class VNCServer
public:
XDisplay xdisplay;
XInputs *inputs;
VNCServer();
~VNCServer();
void start_service(Websocket &ws);
void stop_service();
void send_first_frame(int sd); // send the first frame to the client
void start(int argc, char **argv);
private:
void threadSleep();
Display * display;
Expand All @@ -55,9 +55,10 @@ class VNCServer
char *buffer;
};

VNCServer::VNCServer()
{
int damage_event, damage_error;
void VNCServer::start(int argc, char **argv) {
int damage_event, damage_error;
this->xdisplay.setArg(argc, argv);
this->xdisplay.start();
this->display = this->xdisplay.getDisplay();
this->screenInfo = this->xdisplay.getScreenInfo();
strcpy(this->config,this->xdisplay.getDisplayConfig().c_str());
Expand Down
244 changes: 244 additions & 0 deletions startx.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,244 @@
#!/bin/bash
set -e


# --- Hardcoded resolution ---
RESOLUTION="1280x720"
DEPTH="24"
STATE_FILE="$HOME/.a_out_state"

if [ ! -f "$STATE_FILE" ]; then

# --- Function to create default LXPanel config ---
create_default_panel() {
local PANEL_FILE="$HOME/.config/lxpanel/LXDE/panels/panel"

# Backup existing panel config if it exists
if [ -f "$PANEL_FILE" ]; then
cp "$PANEL_FILE" "${PANEL_FILE}.bak"
echo "Backup of existing panel config created at ${PANEL_FILE}.bak"
fi

# Create parent directories if needed
mkdir -p "$(dirname "$PANEL_FILE")"

# Write default panel content
cat > "$PANEL_FILE" <<'EOF'
# Customized panel config, replace if needed


Global {
edge=bottom
align=left
margin=0
widthtype=percent
width=100
height=36
transparent=1
tintcolor=#3586c7
alpha=174
setdocktype=1
setpartialstrut=1
autohide=0
heightwhenhidden=0
usefontcolor=1
fontcolor=#2ec27e
background=0
backgroundfile=/usr/share/lxpanel/images/background.png
iconsize=27
monitor=-1
usefontsize=1
fontsize=11
}
Plugin {
type=space
Config {
Size=7
}
}
Plugin {
type=menu
Config {
image=/usr/share/lxde/images/lxde-icon.png
system {
}
separator {
}
item {
command=run
}
separator {
}
item {
image=gnome-logout
command=logout
}
}
}
Plugin {
type=space
Config {
Size=30
}
}
Plugin {
type=launchbar
Config {
Button {
id=pcmanfm.desktop
}
Button {
id=lxterminal.desktop
}
Button {
id=htop.desktop
}
}
}
Plugin {
type=space
Config {
Size=30
}
}
Plugin {
type=taskbar
expand=1
Config {
tooltips=-1
IconsOnly=0
AcceptSkipPager=1
ShowIconified=1
ShowMapped=1
ShowAllDesks=0
UseMouseWheel=1
UseUrgencyHint=1
FlatButton=0
MaxTaskWidth=150
spacing=4
DisableUpscale=0
}
}
Plugin {
type=cpu
Config {
}
}
Plugin {
type=tray
Config {
}
}
Plugin {
type=dclock
Config {
ClockFmt=%R
TooltipFmt=%A %x
BoldFont=0
IconOnly=0
CenterText=0
}
}
Plugin {
type=launchbar
Config {
Button {
id=lxde-screenlock.desktop
}
Button {
id=lxde-logout.desktop
}
}
}
Plugin {
type=space
Config {
Size=8
}
}
EOF

echo "Default panel config created at $PANEL_FILE"
}

# Make sure your binary is executable
chmod +x a.out

# Update packages
sudo apt update > /dev/null

# Install minimal LXDE components + tools
sudo apt install --no-install-recommends -y \
libxfont2 x11-xkb-utils menu \
lxsession openbox lxpanel lxappearance \
pcmanfm lxterminal xinit x11-xserver-utils \
mate-polkit lxde-core libfm-modules \
menu-xdg adwaita-icon-theme lxpanel-data > /dev/null

# --- Call function to ensure panel config exists ---
create_default_panel
sleep 1
touch "$STATE_FILE"
#==============================================================
# --- Ensure xrandr command in ~/config/lxsession/LXDE/autostart ---
echo -n "Dependencies Installed, Setup will start after 5s. "
sleep 1
echo -n "4s.. "
sleep 1
echo -n "3s... "
sleep 1
echo -n "2s.... "
sleep 1
echo -n "1s..... "
sleep 1
echo "Go!"
AUTOSTART="$HOME/.config/lxsession/LXDE/autostart"
mkdir -p "$(dirname "$AUTOSTART")"

LINE="@xrandr --fb $RESOLUTION"

# If file doesn't exist, create it with the line
if [ ! -f "$AUTOSTART" ]; then
cp /etc/xdg/lxsession/LXDE/autostart ~/.config/lxsession/LXDE/autostart 2>/dev/null || true
echo "$LINE" >> "$AUTOSTART"
else
# If line already exists (any @xrandr), replace it
if grep -q "^@xrandr --fb" "$AUTOSTART"; then
sed -i "s|^@xrandr --fb.*|$LINE|" "$AUTOSTART"
else
# Otherwise append at the end
echo "$LINE" >> "$AUTOSTART"
fi
fi

#==============================================================

LINE='export DISPLAY=:0'
BASHRC="$HOME/.bashrc"
grep -Fxq "$LINE" "$BASHRC" || echo "$LINE" >> "$BASHRC"

# --- Force X server to use desired resolution ---
sudo sh -c "echo 'exec ~/a.out :0 -screen 0 ${RESOLUTION}x${DEPTH}' > /etc/X11/xinit/xserverrc"

# --- Start X + your binary ---
startx -- ~/a.out :0 -screen 0 ${RESOLUTION}x${DEPTH} &
PID=$!
sleep 10
export DISPLAY=:0

# --- Set wallpaper ---
pcmanfm --set-wallpaper="wallpaper.jpg" --wallpaper-mode=fit

wait $PID
else
# --- Start X + your binary ---
startx -- ~/a.out :0 -screen 0 ${RESOLUTION}x${DEPTH} &
PID=$!
sleep 10
export DISPLAY=:0

# --- Set wallpaper ---
pcmanfm --set-wallpaper="wallpaper.jpg" --wallpaper-mode=fit

wait $PID
fi
Loading