Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

23 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

webOS Second Screen

Turn an HP TouchPad (webOS 3.0.5, released 2011) into a wireless second monitor for your Mac — Duet/Sidecar-style. The Mac creates a real virtual 1024×768 display, streams it to the TouchPad over WiFi at ~20–25 fps, and taps on the TouchPad control the Mac's cursor.

app icon

What you get

  • A true extended desktop (not a mirror): the virtual display shows up in System Settings → Displays, you arrange it like any monitor, and windows dragged onto it appear on the TouchPad.
  • Touch control: tap, drag, double-tap on the TouchPad → mouse on the Mac.
  • Plug-and-play setup: connect the TouchPad over USB once, open the Mac app — it configures and launches the receiver automatically (streaming itself runs over WiFi).
  • ~150 ms latency, ~12 Mbps on your LAN. Fine for dashboards, chat, documents, video; it won't replace Sidecar for fast motion.

app demo

Quick start

0. Pre-requisites

1. TouchPad

2. Mac

  • Download the latest Release.

  • Launch webOS Second Screen.app (or build it from source: cd sender && ./package-app.sh).

  • IMPORTANT: Grant the Screen Recording and Accessibility permissions when prompted, launch again, and the virtual display comes up.

  • If the TouchPad is connected over USB, the receiver is automatically pointed at your Mac and started automatically.

  • If you cannot connect via USB, the TouchPad finds the Mac by itself: after a few failed connection attempts it sweeps its own subnet for the sender, asks whatever answers to identify itself, and saves the address it finds. The first sweep runs about fifteen seconds after the receiver starts, and repeats every thirty seconds or so until it connects — so the launch order of the two apps doesn't matter.

  • Discovery only covers the /24 the TouchPad is on, and can't find a sender that is already streaming to another device. To set the server (that is, the Mac sender) address by hand instead:

grep -v '^host=' /media/internal/secondscreen.conf 2>/dev/null > /tmp/ss.conf
echo "host=<your-mac-ip>" >> /tmp/ss.conf
mv /tmp/ss.conf /media/internal/secondscreen.conf

Then launch the TouchPad app manually.

Note that a hand-set address is only used for as long as it answers: if it stops responding, discovery replaces it and rewrites host= with whatever it finds. To pin the receiver to one machine and turn the sweep off entirely, add discover=0 to the same file.

  • The receiver reconnects automatically every 2 s, so start/stop order never matters. If your Mac's IP changes, the receiver re-reads the config every minute while disconnected and self-heals. After an hour with no connection it exits on its own so it won't keep the TouchPad's screen on all night.

  • The receiver checks the App Catalog for updates at startup and offers to install a newer version via Preware.

3. Freedom

  • You can disconnect USB once the connection is established -- it works over WiFi. Re-connect if you reconfigure anything on either side, or on the network.

Parts

Directory What it is
sender/ Mac app (Swift, macOS 13+). Virtual display via CGVirtualDisplay, ScreenCaptureKit capture, MJPEG over TCP, CGEvent touch injection.
receiver/ TouchPad PDK app (C, SDL 1.2 + OpenGL ES 1.1, NEON libjpeg-turbo).
receiver/PROTOCOL.md The tiny wire protocol between them.
server-test/ Python reference server for receiver development.
artwork/ Icons.
experiments/, PLAN.md The development journal: how this was figured out, ffmpeg-based prototypes, and every webOS/macOS gotcha hit along the way.

Building

How it works (short version)

The Mac side creates a 1024×768 virtual monitor with the private-but- stable CGVirtualDisplay API, captures it with ScreenCaptureKit, and encodes baseline JPEGs (the TouchPad's PDK apps can't reach the hardware H.264 decoder, so MJPEG + NEON libjpeg-turbo is the sweet spot: ~30 ms decode + ~5 ms RGB565 GL upload per frame on the Cortex-A8). Frames are framed over a single TCP connection with latest-frame-wins pacing on both ends, so latency stays bounded instead of growing with TCP backpressure. The receiver sends touch events back on the same socket; the sender maps them into the virtual display's coordinates and injects CGEvents. PLAN.md has the long version, including all measurements.

Acknowledgements

  • libjpeg-turbo (vendored static NEON build for the receiver).
  • The CGVirtualDisplay interface shapes follow prior art in FluffyDisplay and DeskPad.
  • The webOS homebrew community, for keeping these lovely devices alive.

About

Use your webOS TouchPad as a second screen for your modern Mac!

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Contributors

Languages