Overview

Installation notes for a FreeBSD 11 graphical workstation.

X11 & Fluxbox

Compile from ports:

x11/xorg
  curl+libssh+smb
  gmp+assembly_opts
  mesa_libs+wayland
  webp+x11
  (xterm+xinerama)
x11/nvidia-driver
x11-wm/fluxbox

Add the following line to /etc/rc.conf, rebooting or using kldload before attempting to start X.

kld_list="nvidia-modeset"

Create the following configuration file at /usr/local/etc/X11/xorg.conf.d/driver-nvidia.conf.

Section "Device"
        Identifier "NVIDIA Card"
        VendorName "NVIDIA Corporation"
        Driver "nvidia"
EndSection

Create /home/ataylor/.xinitrc to load Fluxbox and set resolution/orientation/etc.

xrandr --output HDMI-0 --mode 3840x2160 --pos 0x0 --output DVI-D-0 --rotate left --mode 2560x1600 --pos 3840x-150
/usr/local/bin/fluxbox

After starting X, use the Fluxbox config menus to set:

Overwrite ~/.fluxbox/keys with my keys file:

# click on the desktop to get menus
OnDesktop Mouse1 :HideMenus
OnDesktop Mouse2 :WorkspaceMenu
OnDesktop Mouse3 :RootMenu

# scroll on the desktop to change workspaces
OnDesktop Mouse4 :PrevWorkspace
OnDesktop Mouse5 :NextWorkspace

# alt + left/right click to move/resize a window
OnWindow Mod1 Mouse1 :MacroCmd {Raise} {Focus} {StartMoving}
OnWindowBorder Move1 :StartMoving

OnWindow Mod1 Mouse3 :MacroCmd {Raise} {Focus} {StartResizing NearestCorner}
OnLeftGrip Move1 :StartResizing bottomleft
OnRightGrip Move1 :StartResizing bottomright

# control-click a window's titlebar and drag to attach windows
OnTitlebar Control Mouse1 :StartTabbing

# double click on the titlebar to shade
OnTitlebar Double Mouse1 :Shade

# left click on the titlebar to move the window
OnTitlebar Mouse1 :MacroCmd {Raise} {Focus} {ActivateTab}
OnTitlebar Move1  :StartMoving

# middle click on the titlebar to lower
OnTitlebar Mouse2 :Lower

# right click on the titlebar for a menu of options
OnTitlebar Mouse3 :WindowMenu

# open a terminal
Mod1 F1 :Exec xterm
# open a dialog to run programs
Mod1 F2 :Exec fbrun
# Open file manager
#Mod1 F3 :Exec spacefm
# current window commands
Mod1 F4 :Close

# Take a screenshot
111 :Exec /home/ataylor/bin/take_screenshot.sh

# Start screensaver, lock screen
110 :Exec xscreensaver-command -lock

# Window sizing commands
Control F1 :Minimize
Control F2 :Shade
Control F3 :Maximize
Control F4 :Fullscreen

Control F5 :MacroCmd {ResizeTo 1600 1250} {Moveto 0 0 UpperLeft}
Control F6 :MacroCmd {ResizeTo 1600 1250} {Moveto 0 0 LowerLeft}

Control F7 :MacroCmd {ResizeTo 1905 2160} {Moveto 0 0 UpperLeft}
Control F8 :MacroCmd {ResizeTo 1905 2160} {Moveto 0 0 UpperRight}

Control F9 :MacroCmd {ResizeTo 1920 1080} {Moveto 0 0 UpperLeft}
Control F10 :MacroCmd {ResizeTo 1920 1080} {Moveto 0 0 UpperRight}
Control F11 :MacroCmd {ResizeTo 1920 1080} {Moveto 0 0 LowerLeft}
Control F12 :MacroCmd {ResizeTo 1920 1080} {Moveto 0 0 LowerRight}

Set the system clock by modifying ~/.fluxbox/init to contain:

session.screen0.strftimeFormat: %a, %b %d %H:%M:%S

Ports - Misc

To enable searching ports via make search key=text-string, execute the following command.

cd /usr/ports && make index

Some packages with auto-updating strings (like version number) fail checksum tests. Both print/texinfo and security/trousers are common examples. When encountering a message about size mismatches during the fetch stage, perform the following steps.

  1. Download the source file manually with wget.
  2. Use make fetch-list with grep to find out where the file should go. Should be somewhere under /usr/ports/distfiles.
  3. Copy the file to the proper location.
  4. In the folder of the port you are trying to build, run make makesum to update the checksum based on the currently present file.
  5. Resume making the port as normal.

Compile and install the following ports:

sysutils/screen
ftp/wget
editors/vim
  Set EDITOR=vim in ~/.profile
www/firefox
  Build failing on ffmpeg dependency
    going into ffmpeg folder and building directly solved it.
  Also had to run (as root) dbus-uuidgen > /etc/machine-id
    Otherwise firefox coredumps with:
    "D-Bus library appears to be incorrectly set up; failed to read machine uuid: Failed to open "/etc/machine-id": No such file or directory"
mail/mutt
  +sidebar
www/links (start with links -g)
sysutils/nitrogen
net/samba46
  -ads,ad_dc,ldap
  mount_smbfs -I 192.168.1.5 //ataylor@talisker/zfs_stripe_0 /mnt/zfs_stripe_0
graphics/geeqie
multimedia/vlc
  +x264/x265 support
sysutils/fusefs-exfat
  fuse_load="YES" -> /boot/loader.conf
  /dev/nvd0s3        /mnt/windows      exfat   rw,mountprog=/usr/local/sbin/mount.exfat      0       0   -> /etc/fstab
devel/git
  git config --global user.name "Aaron Taylor"
  git config --global user.email "ataylor@subgeniuskitty.com"
devel/sdl20
graphics/ImageMagick-nox11
graphics/sdl2_image
net-p2p/deluge
irc/irssi
dns/bind-tools
www/apache24
  apache24_enable="yes" -> rc.conf
  in httpd.conf set:
    ServerName
    ServerAdmin
    and uncomment the cgi (not cgid) module in the MPMPREFORK IFDEF
net-mgmt/icmpmonitor
emulators/simh
emulators/virtualbox-ose
  Add "vboxdrv_load="YES"" to /boot/loader.conf
  pw groupmod vboxusers -m ataylor
  Add "vboxnet_enable="YES"" to /etc/rc.conf for bridging support
multimedia/quodlibet
devel/arm-none-eabi-gdb
devel/valgrind
devel/arm-none-eabi-gcc
editors/libreoffice
graphics/inkscape
graphics/okular
math/gnuplot
editors/texmaker
devel/openocd
  Enable USB for non-root users:
    pw groupmod operator -m ataylor
    setup the devfs subsystem by adding these lines to the following files:
      ***/etc/devfs.rules (FreeBSD >= 8):
             [localrules=10]
             add path 'ugen*' mode 0660 group operator
             add path 'usb/*'  mode 0660 group operator
             add path 'usb' mode 0770 group operator
      ***/etc/rc.conf:
             devfs_system_ruleset="localrules"
graphics/gimp
  -gutenprint (brings in samba-4.4 and conflicts with installed samba-4.6)
x11-fm/qtfm
x11-fm/twander
  TODO: Re-work ~/.twander for FreeBSD
www/py-beautifulsoup
www/py-requests
www/py3-requests
games/linux-dwarffortress
games/openmw

Mounting SMB/CIFS at Boot

Add to /etc/fstab:

//ataylor@TALISKER/zfs_mirror_0         /mnt/zfs_mirror_0       smbfs   rw,late,-N,-I192.168.1.5   0       0
//ataylor@TALISKER/zfs_stripe_0         /mnt/zfs_stripe_0       smbfs   rw,late,-N,-I192.168.1.5   0       0

Set ownership to ataylor:ataylor on /mnt/zfs_stripe_0 and /mnt/zfs_mirror_0 since mount_smbfs uses default “owner and group IDs from the directory where the volume is mounted.” (from mount_smbfs manpage)

Add to /etc/nsmbd.conf [TALISKER:ATAYLOR] password=password-goes-here

Firefox Configuration

In about:config:

browser.newtabpage.enabled = false
general.useragent.override = NCSA Mosaic/1.0 (X11;SunOS 4.1.4 sun4m)
gfx.canvas.azure.backends = cairo
gfx.content.azure.backends = cairo
gfx.canvas.azure.accelerated = true

Note that the gfx.* entries enable hardware acceleration since the Nvidia drivers I am using support cairo but not skia, or is it that cairo supports my video drivers and skia doesn’t?

In preferences:

Install plugins:

Execute touch ~/.null and then create ~/.config/user-dirs.dirs as below.

XDG_DESKTOP_DIR="$HOME/.null"
XDG_DOWNLOAD_DIR="$HOME/.null"
XDG_TEMPLATES_DIR="$HOME/.null"
XDG_PUBLICSHARE_DIR="$HOME/.null"
XDG_DOCUMENTS_DIR="$HOME/.null"
XDG_MUSIC_DIR="$HOME/.null"
XDG_PICTURES_DIR="$HOME/.null"
XDG_VIDEOS_DIR="$HOME/.null"

To make scrollbars move one-page-per-click rather than jumping to the cursor, create the file ~/.config/gtk-3.0/settings.ini with contents:

[Settings]
gtk-primary-button-warps-slider=false

Audio Configuration

By default, FreeBSD only provides 16 virtual audio channels via /dev/dsp. Since Firefox appears to open a new connection for each tab that plays audio and does not release those connections as long as the tab remains open, I sometimes encounter error messages like the following.

mpv: can't open /dev/dsp!

To verify the problem, use fstat to confirm that too many connections exist.

ataylor@lagavulin:~ % fstat | grep dsp
ataylor  mpv        42458   27 /dev        215 crw-rw-rw-  dsp0.15  w
ataylor  mpv        36531   27 /dev        194 crw-rw-rw-  dsp0.11  w
ataylor  mpv        24332   25 /dev        204 crw-rw-rw-  dsp0.13  w
ataylor  firefox    61929   48 /dev        209 crw-rw-rw-  dsp0.14  w
ataylor  firefox    61718   23 /dev        259 crw-rw-rw-  dsp0.22  w
ataylor  firefox    61718   47 /dev        296 crw-rw-rw-  dsp0.46  w
ataylor  firefox    61718   51 /dev        273 crw-rw-rw-  dsp0.30  w
ataylor  firefox    61718   64 /dev        284 crw-rw-rw-  dsp0.40  w
ataylor  firefox    61718   68 /dev        245 crw-rw-rw-  dsp0.17  w
ataylor  firefox    61718   70 /dev        265 crw-rw-rw-  dsp0.25  w
ataylor  firefox    61718   73 /dev        280 crw-rw-rw-  dsp0.36  w
ataylor  firefox    61718   74 /dev        188 crw-rw-rw-  dsp0.10  w
ataylor  firefox    61718   75 /dev        278 crw-rw-rw-  dsp0.34  w
ataylor  firefox    61718   76 /dev        272 crw-rw-rw-  dsp0.29  w
ataylor  firefox    61718   79 /dev        282 crw-rw-rw-  dsp0.38  w
ataylor  firefox    61718   80 /dev        293 crw-rw-rw-  dsp0.43  w
ataylor  firefox    61695   47 /dev        264 crw-rw-rw-  dsp0.24  w
ataylor  firefox    61695   48 /dev        279 crw-rw-rw-  dsp0.35  w
ataylor  firefox    61695   66 /dev        274 crw-rw-rw-  dsp0.31  w
ataylor  firefox    61695   69 /dev        292 crw-rw-rw-  dsp0.42  w
ataylor  firefox    61620   17 /dev        247 crw-rw-rw-  dsp0.18  w
ataylor  firefox    61620   72 /dev        291 crw-rw-rw-  dsp0.41  w
ataylor  firefox    61208   17 /dev        254 crw-rw-rw-  dsp0.20  w
ataylor  firefox    61208   18 /dev        275 crw-rw-rw-  dsp0.32  w
ataylor  firefox    61208   48 /dev        201 crw-rw-rw-  dsp0.12  w
ataylor  firefox    59654   45 /dev        276 crw-rw-rw-  dsp0.33  w
ataylor  firefox    59654   70 /dev        295 crw-rw-rw-  dsp0.45  w
ataylor  python2.7  82359   20 /dev        145 crw-rw-rw-  dsp0.16  w

Before proceeding, ensure that no processes have /dev/dsp open. IOW, the above fstat list should be empty.

With nothing using the audio device, increase the number of virtual channels with sysctl.

root@lagavulin:~ % sysctl -a | grep vchans
hw.snd.maxautovchans: 16
dev.pcm.2.play.vchans: 1
dev.pcm.1.play.vchans: 1
dev.pcm.0.rec.vchans: 4
dev.pcm.0.play.vchans: 16

root@lagavulin:~ # sysctl dev.pcm.0.play.vchans=256
dev.pcm.0.play.vchans: 16 -> 256

root@lagavulin:~ # sysctl hw.snd.maxautovchans=256
hw.snd.maxautovchans: 16 -> 256

Add the following two lines to /etc/sysctl.conf so the change persists.

dev.pcm.0.play.vchans=256
hw.snd.maxautovchans=256

X11 Configuration

In ~/.Xresources:

xterm*faceName: Liberaqtion Mono:size=12:antialias=true
xterm*font: 7x13

In ~/.Xmodmap:

!
! Swap Caps_Lock and Control_L
!
remove Lock = Caps_Lock
remove Control = Control_L
keycode  9 = Caps_Lock NoSymbol Caps_Lock
keycode 37 = Escape NoSymbol Escape      
keycode 66 = Control_L NoSymbol Control_L
add Lock = Caps_Lock
add Control = Control_L

In ~/.xinitrc:

xrdb /home/ataylor/.Xresources
xmodmap /home/ataylor/.Xmodmap

FreeBSD Configuration

Add to /etc/sysctl.conf:

kern.corefile=/dev/null

Screensaver/Screenlock

Compile the x11/xscreensaver port and execute xscreensaver-demo to configure the screensaver.

Add xscreensaver -nosplash & to ~/.xinitrc.

Add a line like the one below to ~/.fluxbox/keys.

110 :Exec xscreensaver-command -lock

Wallpaper Configuration

Create ~/bin/wallpaper_rotation.sh and add to ~/.xinitrc. Remember to make it executable.

#!/usr/local/bin/python3
# This script creates a wallpaper slideshow.

##### Configuration

# List of image source directories
# Each sublist is of the form:
# [monitor ID, absolute path to directory containing images for this monitor]
source_dir = [
              [0,"/mnt/zfs_mirror_0/wallpaper/ratio_10_16"],
              [1,"/mnt/zfs_mirror_0/wallpaper/ratio_16_9"]
             ]

# This list will be populated during runtime.
# Each sublist is of the form:
# [monitor ID, absolute path to image file to display on this monitor]
current_wallpaper = [
                     [0,""],
                     [1,""]
                    ]

# Path to nitrogen configuration file
nitrogen_config = "/home/ataylor/.config/nitrogen/bg-saved.cfg"

##### Dependencies

from subprocess import call
from os import listdir
from os.path import isfile, join
from random import choice
from time import sleep

##### Source Code

def write_config():
        config_file = open(nitrogen_config, 'w')
        for monitor in current_wallpaper:
                # Indenting the following triple-quoted text inserts leading whitespace in the
                # nitrogen config file. However, nitrogen strips leading whitespace before
                # processing its config file and the extra whitespace makes this Python script
                # more readable.
                template = """[xin_{monitor_n}]
                              file={wallpaper_file}
                              mode=0
                              bgcolor=#000000
                           """
                context = {
                           "monitor_n":monitor[0],
                           "wallpaper_file":monitor[1]
                          }
                config_file.write(template.format(**context))
        config_file.close()

def refresh_wallpaper():
        write_config()
        call(["/usr/local/bin/nitrogen", "--restore"])

def get_rand_from_dir():
        file_choices = [x for x in listdir(source_dir[current_monitor][1]) if isfile(join(source_dir[current_monitor][1], x))]
        filename = choice(file_choices)
        filename = join(source_dir[current_monitor][1], filename)
        current_wallpaper[current_monitor][1] = filename

# Put something up on all monitors
for i in range(len(source_dir)):
        current_monitor = i
        get_rand_from_dir()
refresh_wallpaper()

# Eternal slideshow loop
while 1:
        current_monitor = (current_monitor + 1) % len(source_dir)
        get_rand_from_dir()
        refresh_wallpaper()
        sleep(10)

Vim Configuration

Create ~/.vimrc as follows.

set nocompatible              " be iMproved, required
filetype off                  " required

set number
syntax on
set tabstop=4
set expandtab
"set background=dark
"colorscheme solarized

"Folding
"http://vim.wikia.com/wiki/Folding_for_plain_text_files_based_on_indentation
"set foldmethod=expr
"set foldexpr=(getline(v:lnum)=~'^$')?-1:((indent(v:lnum)<indent(v:lnum+1))?('>'.indent(v:lnum+1)):indent(v:lnum))
"set foldtext=getline(v:foldstart)
"set fillchars=fold:\ "(there's a space after that \)
"highlight Folded ctermfg=DarkGreen ctermbg=Black
"set foldcolumn=6

" Color the 100th column.
set colorcolumn=100
highlight ColorColumn ctermbg = lightgray

Deluge Configuration

Follow instructions at https://whatbox.ca/wiki/deluge. Add check boxes in Connection Manager:

Personal Software

Compile and install wallproc. Requires the following dependencies from ports:

devel/sdl20
graphics/ImageMagick-nox11
graphics/sdl2_image

Printer Configuration

Create a spool directory:

mkdir -p /var/spool/lpd/lp
chown daemon:daemon /var/spool/lpd/lp
chmod 770 /var/spool/lpd/lp

Add an entry to /etc/printcap.

# HP LaserJet, M's Office
lp:\
        :lp=:rm=192.168.1.252:rp=raw:\
        :sh:\
        :mx#0:\
        :sd=/var/spool/lpd/lp:\
        :lf=/var/log/lpd-errs:

Edit /etc/rc.conf to add the line lpd_enable="YES".

Note that plaintext files print in stairstep. See the link below if I want to fix this. Consider adding a smart filter to only apply this to text and pass PS straight through.

https://www.freebsd.org/doc/en_US.ISO8859-1/books/handbook/printing-lpd.html#printing-lpd-filters-stairstep

TODO

After reboot:
  Setup virtualbox and verify CAD software runs
Firefox:
  Menus/tabs/etc use AA fonts but websites don't. Why not?
    YES: wiki.archlinux.org
    NO: reddit
https://forums.freebsd.org/threads/firefox-no-gpu-acceleration-since-50-0.59089/
Check Debian & FreeBSD install notes from previous desktop systems
Add lagavulin to tape backup schedule over network. Where to spool?
  sysutils/bacula-client

temp notes from ports compiles


Virtualbox USB Support
USB Support:
============

For USB support your user needs to be in the operator group and needs read
and write permissions to the USB device.

% pw groupmod operator -m jerry

Add the following to /etc/devfs.rules (create if it doesn't exist):

[system=10]
add path 'usb/*' mode 0660 group operator

To load these new rule add the following to /etc/rc.conf:

devfs_system_ruleset="system"

Then restart devfs to load the new rules:

% /etc/rc.d/devfs restart

FreeBSD USB NOTE:
 To allow an ordinary user to acces any of the the hotplug USB interface
 add him/her to the operator group  (pw groupmod operator -m username), then
 setup the devfs subsystem by adding these lines to the following files:

 ***/etc/devfs.rules (FreeBSD >= 8):
 [localrules=10]
        add path 'ugen*' mode 0660 group operator
        add path 'usb/*'  mode 0660 group operator
        add path 'usb' mode 0770 group operator

 ***/etc/devfs.rules (FreeBSD <= 7):
 [localrules=10]
        add path 'ugen*' mode 0660 group operator

 ***/etc/rc.conf:
        devfs_system_ruleset="localrules"