I have a Panasonic Toughbook CF-33 as my backup/outdoor/camping laptop. It’s a rugged laptop with a 2K display and a detachable keyboard/touchpad base. It has a multitouch screen and pen input as well.
These are my notes for running Linux on it because I sometimes forget parts of the setup that are annoying to re-research if I need them again.
I want to run Linux on this thing with the following requirements:
The laptop should be usable completely without the keyboard/touchpad base. There are a few distinct phases of usage that each need to be configured.
The CF-33 can be configured to provide an on-screen keyboard in EFI. This is enough to operate GRUB and the EFI shell.
initrd  I use full disk encryption so I need an on-screen keyboard in the initrd environment.
I use unl0kr for that, and an entry in /etc/crypttab to make it part of the initial ramdisk:
1$ doas apt install unl0kr
The entry in /etc/crypttab looks like this.
It needs to be adjusted to match the device UUID and name, but the Debian setup process already configures that.
This is mostly about the keyscript part:
sda3_crypt UUID=bc262d7a-3762-4b42-8641-b148bd944111 none luks,discard,x-initrd.attach,keyscript=/usr/share/initramfs-tools/scripts/unl0kr-keyscript
Configure unl0kr in /etc/unl0kr.conf.
The defaults are usually OK though.
After configuring it, update the initrd:
1$ doas update-initramfs -u
To get an on-screen keyboard on the frame buffer, I use buffyboard which I have installed to /usr/local/bin.
This is the wrapper I use to start it:
 1#!/bin/bash
 2
 3set -xu
 4
 5active=$(fgconsole)
 6
 7if [[ "$active" == "7" ]]; then
 8        # Turn it off always if we're in X.
 9        # TODO: Start onboard if necessary.
10        doas systemctl stop buffyboard.service
11else
12        isActive=$(systemctl is-active buffyboard.service)
13        if [[ "$isActive" == "active" ]]; then
14                doas systemctl stop buffyboard.service
15        else
16                doas systemctl start buffyboard.service
17        fi
18fi
The script stops buffyboard if it detects TTY 7 as the active TTY so that it doesn’t conflict with onboard for my X11 setup.
The systemd service is buffyboard.service from buffyboard’s repository.
To start buffyboard, I use triggerhappy with the following configuration in /etc/triggerhappy/triggers.d/keyboard.conf:
KEY_PROG3       1       /usr/local/bin/osk.sh
My /etc/doas.conf allows the user nobody (which triggerhappy runs as) to start/stop the buffyboard systemd service like this:
1permit keepenv nopass nobody cmd systemctl args stop buffyboard.service
2permit keepenv nopass nobody cmd systemctl args start buffyboard.service
My X on-screen keyboard of choice is onboard:
1$ doas apt install onboard
My /etc/lightdm/lightdm-gtk-greeter.conf looks like this:
[greeter]
keyboard=onboard
I use xbindkeys to always have working keyboard bindings, no matter which window manager is running.
My .xbindkeysrc looks like this:
"lxterm"
        mod4 + space
"pkill onboard; onboard"
        XF86Launch3
"/bin/bash -c /home/gbe/bin/r.sh"
        mod4 + XF86Eject
"polybar-msg action pulseaudio toggle"
        XF86AudioMute
"polybar-msg action pulseaudio dec"
        XF86AudioLowerVolume
"polybar-msg action pulseaudio inc"
        XF86AudioRaiseVolume
"xscreensaver-command -lock"
        mod4 + ctrl + q
I run my own fork of DWM that I am in the process of porting to Zig. It has a few patches in it that add XFT support and a system tray. They’re from DWM’s patch selection.
I have patched the panasonic-laptop kernel driver to map the keys labelled “A1” and “A2” on the tablet bezel to the key symbols LAUNCH3 and LAUNCH4.
These are LAUNCHx keys instead of MACROxy because X11 apparently doesn’t register those macro keys.
I don’t know precisely where I have that information from (probably one of the evdev headers), but it matches my observations.
There is also a patch to the HID multitouch driver that ignores events at the very right edge of the display because after some time of use, the multitouch controller for the display seems to generate a lot of spurious click events there. I don’t know if this is an issue with my particular touch screen though.
I use QGIS as my GNSS client, and connect it to gpsd with its “GPS” toolbar.
Works quite nicely.
My polybar setup (~/.config/polybar/config.ini) looks like this:
[colors]
	background = #cccccc
	foreground = #111111
	primary = #4a799c
	disabled = #707880
[bar/main]
	height = 24pt
	dpi = 144
	background = ${colors.background}
	foreground = ${colors.foreground}
	line-size = 3pt
	border-size = 0pt
	padding-left = 0
	padding-right = 1
	module-margin = 1
	separator = |
	separator-foreground = ${colors.disabled}
	font-0 = Ubuntu
	font-1 = Noto Color Emoji:scale=7
	font-2 = Font Awesome 6 Free Solid
	font-3 = Weather Icons:style=Regular
	font-4 = DejaVu Sans
	modules-right = backlight project pulseaudio battery1 battery2 date
	cursor-click = pointer
	cursor-scroll = ns-resize
	enable-ipc = true
	override-redirect = false
	wm-restack = i3
[module/pulseaudio]
	type = internal/pulseaudio
	format-volume = <ramp-volume> <label-volume>
	ramp-volume-0 = 
	ramp-volume-0-foreground = ${colors.primary}
	ramp-volume-1 = 
	ramp-volume-1-foreground = ${colors.primary}
	ramp-volume-2 = 
	ramp-volume-2-foreground = ${colors.primary}
	label-volume = %percentage%%
	label-muted = M
	label-muted-foreground = ${colors.disabled}
	click-right = pavucontrol
[module/backlight]
	type = internal/backlight
	ramp-4 = 🌕
	ramp-3 = 🌔
	ramp-2 = 🌓
	ramp-1 = 🌒
	ramp-0 = 🌑
	format = <ramp>
[module/battery1]
	type = internal/battery
	battery = BAT1
	label-charging = %percentage%%
	label-discharging = %percentage%%
	label-low = %percentage%%
	format-charging = <animation-charging> <label-charging>
	format-discharging = <ramp-capacity> <label-discharging>
	format-low = <animation-low> <label-low>
	ramp-capacity-0 = 
	ramp-capacity-0-foreground = ${colors.primary}
	ramp-capacity-1 = 
	ramp-capacity-1-foreground = ${colors.primary}
	ramp-capacity-2 = 
	ramp-capacity-2-foreground = ${colors.primary}
	ramp-capacity-3 = 
	ramp-capacity-3-foreground = ${colors.primary}
	ramp-capacity-4 = 
	ramp-capacity-4-foreground = ${colors.primary}
	animation-charging-0 = 
	animation-charging-0-foreground = ${colors.primary}
	animation-charging-1 = 
	animation-charging-1-foreground = ${colors.primary}
	animation-charging-2 = 
	animation-charging-2-foreground = ${colors.primary}
	animation-charging-3 = 
	animation-charging-3-foreground = ${colors.primary}
	animation-charging-4 = 
	animation-charging-4-foreground = ${colors.primary}
	animation-charging-framerate = 750
	animation-low-0 = "|"
	animation-low-0-foreground = ${colors.primary}
	animation-low-1 = !
	animation-low-1-foreground = ${colors.primary}
	animation-low-framerate = 500
[module/battery2]
	inherit = module/battery1
	battery = BAT2
[module/project]
	type = custom/script
	exec = /home/gbe/bin/newproject.sh
	click-left = /home/gbe/bin/newproject.sh clicked
[module/ddate]
	type = custom/script
	interval = 600
	exec = ddate +"%{%A, %e %B%} %Y%N (%H)"
[module/date]
	type = internal/date
	interval = 1
	date = %m-%d %H:%M
	date-alt = %d%H%M%Z %b%y
	label = %date%
	label-foreground = ${colors.primary}
[settings]
	screenchange-reload = true
	pseudo-transparency = true