Posts

Showing posts from 2026

Plan 9: Multi-touch Touchpad

Synopsys DesignWare I²C on Intel LPSS (Alder Lake) The touchpad is connected through the Intel LPSS (Low Power Subsystem) I²C controller, which uses Synopsys DesignWare I²C IP. The following output demonstrates touch events being decoded and generated in userspace. n indicates the number of fingers reported by the touchpad. touch conf 1 tip 1 id 0 x 1377 y 1129 scan 13523 n 1 btn 0 touch conf 1 tip 1 id 0 x 1377 y 1129 scan 13691 n 1 btn 0 touch conf 1 tip 1 id 0 x 1377 y 1129 scan 14675 n 1 btn 0 touch conf 1 tip 1 id 0 x 1378 y 1129 scan 15659 n 1 btn 0 touch conf 1 tip 1 id 0 x 1381 y 1130 scan 16643 n 1 btn 0 touch conf 1 tip 1 id 0 x 1383 y 1131 scan 17627 n 1 btn 0 touch conf 1 tip 1 id 0 x 1386 y 1132 scan 18611 n 1 btn 0 touch conf 1 tip 0 id 0 x 1386 y 1132 scan 19599 n 1 btn 0 touch conf 1 tip 1 id 0 x 1580 y 1192 scan 34460 n 2 btn 0 touch conf 1 tip 1 id 0 x 1580 y 1192 scan 35343 n 2 btn 0 touch conf 1 tip 1 id 0 x 1580 y 1192 scan 36331 n 2 btn 0 touch conf 1 tip 1 id 0 ...

Plan 9: Realtek PCI Wifi Driver

Realtek PCI Wifi Driver for RTL8851BE based on Linux rtw89 driver. The code covers firmware download and H2C communication.   Files /sys/src/9/port/etherrtw89.c /sys/src/9/port/rtw89/   Code https://gitlab.com/atamariya/plan9front  (rtw89 branch) References Linux Realtek PCI Wifi Driver rtw89   PCI passthrough setup for QEMU    

Plan 9: Play Invidious Video

Image
  Play Youtube videos directly in Plan 9 via Invidious.  Invidious is an alternative front-end to YouTube treason is the video player in Plan 9 nvi is the interface to Youtube (via Invidious API) and Peertube   nvi -A 140 -V 134 -s /mnt/v1 ciWzklgc98o # Use lang id when available  nvi -A 140 :lang -V 134 -s /mnt/v1 ciWzklgc98o # Exit echo exit > /mnt/v1/ctl    treason -a /mnt/v1/audio /mnt/v1/video   # Download mode nvi -A 140 -V 134 -a /tmp/audio -v /tmp/video  ciWzklgc98o   treason file.mp4      # Wrapper script. Default a=140, v=136 yt ciWzklgc98o # Lowest quality yt -l ciWzklgc98o # Highest quality yt -h ciWzklgc98o     Installation Download the treason package - includes codecs and mcfs. rm -rf /tmp/treason mkdir /tmp/treason cd /tmp/treason hget https://ftrv.se/_/treason.gz | gunzip | disk/mkext -d . ./treason/install.rc    Replace treason, nvi and mcfs from repositories listed in t...

Plan 9: Poking PCI Hardware

Image
  Poking the VGA card  term% cat /dev/pci/*ctl 06.00.00 8086/29c0   0 03.00.00 1234/1111    0 0:fd000008 16777216 2:feb94000 4096 02.00.00 8086/10d3  11 0:feb40000 131072 1:feb60000 131072 2:0000c041 32 3:feb90000 16384 00.ff.00 1234/11e8  11 0:fea00000 1048576 06.01.00 8086/2918   0 01.06.01 8086/2922  10 4:0000c061 32 5:feb95000 4096 0c.05.00 8086/2930  10 4:00000701 64 term% cat /dev/vgactl type vesa size 1280x720x32 x8r8g8b8 tilt none hwgc soft hwaccel off hwblank on addr p 0xfd000000 v 0xfffffe80fd000000 size 0x1000000 softscreen on term% echo 1280*4 | bc 5120 term% grep -l  1234/1111 /dev/pci/*ctl /dev/pci/0.1.0ctl term% dd -if /dev/pci/0.1.0 bar0 -of /dev/pci/0.1.0 bar0 -bs 5120 -count 64 -oseek 200 64+0 records in 64+0 records out Don't worry about the display corruption. It will be redrawn by Rio when you move the cursor or the window.   Code devpnp.c and archacpi.c    

Plan 9: Code Assist (Rio)

Image
  This is part 2 of my vision of Plan 9 as an Infinity Notebook . This focuses on the developer tools expanding on these ideas . Text color   Syntax Highlight Highlight comment, string and keywords. This is triggered on demand presently. For more advanced rendering requirements, use plot . In general, syntax highlighting is a computing intensive operation. Each character needs an attribute to store font size, weight, slant and color attributes. Font attributes affect which font file (regular, bold, italic or bold-italic version) is used for rendering. Each of this also affects the box size calculations for line wrap. This implementation uses a simpler approach using spans to store color information: Scanner : table-driven matchers ( mblock , mline , mstring , mident ), first match wins, each returns a length and a class. Classes : one {name, rgba, img} table indexed by an enum, initialized once. Output : waddcolorspanclass stores sorted spans; spanfirst finds the first...

Plan 9: Code Assist

Image
Jump to definition with ctags    Use ctags for jump-to-defintion. Also, you can use Button3 in acme to jump to include files - both system and local headers. readtags uses binary search . So it makes jump to symbol faster on a large codebase.  Note: Use  sig  command for signature lookup.  Use  src  command for jumping to Plan 9 command sources.  If you have mounted contrib sources, use this . Alternatively, download tar from https://ctags.sourceforge.net/  . Make following changes: in Makefile, add '-DHAVE_REMOVE' (remove() instead of unlink()) and '-DHAVE_OPENDIR' (for directory recursion option) to DEFS in config.h, remove or comment out the definition of INT_MAX  # Use one below to enable APE bind -b /$objtype/bin/ape /bin ape/psh    # ls doesn't support -di option in Plan 9 sed 's/ls -di/ls/' configure > configure.new mv configure.new configure   # Fake presence of egrep cp /bin/grep /$objtype/bin/ ...

Plan 9: Devanagari Input with kbmap

Image
  Note : The demo uses layer 3 for better key visualization while using Devanagari.                The PS/2 interface presents two physical layers, switched on if the input scancode is one or two bytes. This second "escaped" layer is typically generated for keys like `Home' and `Ins'. Kbdfs additionally maintains eight more virtual layers that are switched on `Shift', `Ctl', `AltGr', and `Mod4' modifier key state. Not all permutations of these modifiers are represented as layers, the exhaustive list is as follows: none Key shift Shift + Key esc Escaped Key altgr AltGr + Key ctl Ctl + Key ctlesc Ctl + Escaped Key shiftesc Shift + Escaped Key shiftaltgr Shift + AltGr + Key mod4 Mod4 + Key altgr...

Plan 9: Key Visualizer

Image
Simple key visualizer for capturing keystrokes during a screencast using kbdfs, awk and statusmsg. Note : You need a Truetype font for arbitrary large display ( /n/ttf/mine/32/font  in the example).  Also, ensure truetypefs is running if you do use Truetype font.   #!/bin/rc fn notify {     scr=`{awk '{print $4, $5}' /dev/screen}     w=200     h=60     ws=$scr(1)     hs=$scr(2)     minx=`{echo $ws - $w | bc}     warg=`{echo -w  $minx,0,$ws,$h}     font=/n/ttf/mine/32/font aux/statusmsg $warg $1 } {     tee /dev/kbdtap |     tr '\000' '\034' |     awk -v 'RS=\034' '     BEGIN {         esc   = sprintf("%c", 033)         tab   = sprintf("%c", 011)         bksp  = sprintf("%c", 010)         del   = sprintf("%c", 0177)      ...

Plan 9: Emoji

Image
  Noto Emoji Font Note:  Noto Color emoji needs Color Bitmap Data (CBDT) or COLR/CPAL support.   Four independent bugs, spanning truetypefs.c , hint.c , and head.c : 1. assert(gs[i] != nil) crash in compilesub ( truetypefs.c ) ttffindchar returning glyph 0 for a rune inside a declared cmap segment (a genuine gap, not just the NUL special-case) skipped the retry-via-notdef path entirely. If the font's own .notdef then also failed to rasterize, the assert took the whole fileserver down. Fixed by replacing the assert with a synthesized blank placeholder as the last resort in the fallback chain. 2. No bounds checking on glyph geometry before blit() ( truetypefs.c ) blit() has zero validation of its own; compilesub sized the destination strip from the font's declared ascentpx + descentpx but never checked that an individual glyph's actual rendered width/height/vertical position fit inside that buffer. A decorative font ( architectsdaughter ) reporting ink extents...

Plan 9: Dynamic HTML

Image
  Render Dynamic HTML using plot and qjs. Render a simple website   Font zoom   E-Book Reader eBook is a collection of HTML files in a ZIP archive. Follow same steps for Comic Book reader which are collection of JPG/PNG images in a ZIP/RAR archive. For columns, pure HTML solution involves column-count CSS property. However, this works only for designed screen sizes. For non-standard sizes, the first column might span multiple pages before continuing in the second column. Hence, the page mode manages the split without relying on the column-count.   Keymap t                          Table of Content -/=                     Font zoom 1,2,3                  Column s                         Toggle scroll/page mode  ...

Plan 9 Plumber

Image
Plumb Zip file   View files inside a zip compressed file via Plumber without extraction. Zip file contents are accessible at /n/tapefs. (Note: sam displays the UTF Byte-Order-Mark (BOM) as is - the garbage in the beginning of the first line). #zip file content in a new window type    is    text data    matches    '([a-zA-Z¡-ï¿¿0-9_\-.,/]+)\.zip' arg    isfile    $0 plumb    start    window fs/zipfs $file; cd /n/tapefs; ls; rc   Plumber process, usually running in the parent process, does not have visibility into the folders mounted by the child process because of namespace isolation. Hence, you need the following changes: zipfs (or 32vfs, cpiofs, tapfs, tarfs, tpfs, v6fs, v10fs etc.) must expose a service in the /srv directory. ( fs.c ) plumber must mount the zipfs for paths starting with /n/tapefs before checking for file existence. ( match.c )   

Plan 9: Tiled Map

Image
  Use plot(1) to display tiled maps. The zoom factor decides the grid dimension. osm.js: Download tile images from OpenStreetMaps using hget. Cache the images. Convert the PNG image into Plan 9 format using png. Display the images using plot. Plot script   ra 0 0 200 200 m 0 100 im /file :Note - must end the script with a newline     Plot tries to center the drawing. Hence the origin is at the bottom with a slight offset from the left. However, image uses origin at the top left.     Interactive Plotting and Maps Use plot command in server mode (-s option). plot -s a.plt  mount /srv/plot /mnt/plot echo li 0 0 100 100 > /mnt/plot/ctl echo erase > /mnt/plot/ctl Usage as an interactive map.   OSM API Tiles https://tile.openstreetmap.org/zoom/x/y.png   The World map at zoom 0 https://tile.openstreetmap.org/0/0/0.png     Geocoding (Name to geographical co-ordinates) https://nominatim.openstreetmap.org/search?q=hebba...

Browser in Javascript

Image
  A Proof-of-Concept Browser written in Javascript for minimal Web 2.0 browsing experience. This DOES NOT depend on any browser engine like Blink, Gecko or Webkit. Use an existing HTML rendering engine like netsurf or roll-out your own . This uses QuickJS-ng for JS runtime, Linkedom for DOM API and curl for network downloads. Font decoration uses Terminal ANSI escape codes . Since linkedom is an npm module, it needs to be converted to ES6 module for use with quickjs.  sudo apt install npm  npm install linkedom npx esbuild node_modules/linkedom/esm/index.js \     --bundle \     --format=esm \     --outfile= linkedom.bundle.js \     --platform=neutral \     -- main-fields = module,main           Code https://gitlab.com/atamariya/quickjs/-/blob/dev/ldom.js https://gitlab.com/atamariya/quickjs/-/blob/dev/net.js https://gitlab.com/atamariya/quickjs/-/blob/dev/render.js   Lessons Learnt st...

Plan 9: Network Printer (HP Deskjet Ink Advantage 3545)

Image
Internet Printing Protocol Printing with  Internet Printing Protocol (IPP)  involves sending a Unirast   Format (URF) image with appropriate protocol headers to port 631. It is the basis for standards like  Windows Mopria Alliance , Apple   AirPrint , and IPP Everywhere .  It is also called  Driverless Printing   since this doesn't involve installing any printer specific driver. On Plan 9, printing involves three steps: Convert the document to PDF using lp Convert the PDF to URF using  gs  (use urfgray, urfrgb or urfcmyk device) Send the request to the printer using hget IPP header ( req.bin in the below script) contains page output options like paper size, margins etc. This is generated   using ippenc.c .        #!/bin/rc HOST=$1 FILE=$2 TFILE=/tmp/a.pdf URL=( http://$HOST:631/ipp/print/ ) if (! ~ $#* 2)    echo 'Usage: $0 <printer-ip> <file>'     lp -d stdout $FILE > $TFILE...

Plan 9: Audio-Video Pipeline

Image
Video pipeline in action Two important points about videos: A video is a series of images. RGB format is used for display. YUV format is used for storage and transmission.  Recording   ──────────────────────────────────────────────────────── [Video Source] → [Frame Processing] → [Video Encode] ┐                                                                                                      ├→ [Mux] → [Container Stream] [Audio Source] → [Audio Processing] → [Audio Encode] ┘ Playback   ──────────────────────────────────────────────────────── [Container Stream] → [Demux] → [Video Decode] → [Video Sink]                                   ...