# FreeBSD minimum desktop guide

I'm not going to cover the installation process, but it is worth noting
you might want to add your user to groups 'wheel operator video'.

The few services I use by default are local_unbound, powerd and ntpd.
local_unbound caches dns requests and needs no configuration, powerd
adjusts cpu frequency as is needed and enables hibernation and suspending,
ntpd makes your clock synced.

Once it's installed, I get the handbook from the post-installation menu.
One benefit is that this will also set up pkg and save you 10 seconds,
when you install packages for the first time.

Most of these steps are optional, so read carefully and decide for
yourself which are applicable to your usecase. This is simply what
I do to get a bare minimum FreeBSD desktop.

Let's reboot.

> If you see a line beginning with ' # ', that's a command to be run as
> root.
> If the line starts with ' $ ', that's a command to be run as local 
> user.
> Blocks between '```' are contents of files.

# first things tmux
The first thing I do is install tmux. Log in as root, or log in as user
and run ' $ su -' (this is why you would want your user to be in the
wheel group).

 # pkg install tmux

# ksh is king
FreeBSD does not come with ksh and ksh is what I need. If you're like me,
spoiled by the perfection that is OpenBSD's ksh, there is oksh in
FreeBSD's ports, which is the portable version of the spiked fish's 
shell.

 # pkg install oksh
 # ln -s /usr/local/bin/oksh /bin/ksh

The second command makes  a symbolic link to ksh in /bin/ksh. This is
just my habit of having ksh in the same place on all my machines. Next up
I change the default shell for both root and the user.

 # chsh
 # chsh <user>

In both cases I change the line:
Shell: /bin/<shell>

I add set -o vi to /root/.profile to get vi-like keybindings for the root
user.

 # echo "set -o vi" >> /root/.profile

Similarly I setup .profile for the user.

 $ vi ~/.profile

This is what my .profile looks like, I only keep the original fortune line.
I like to store away my scripts and programs in ~/.local/bin, so I change
PATH accordingly and mkdir the path.

$ mkdir -p ~/.local/bin

```
PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin:$HOME/.local/bin
export PATH HOME TERM
export EDITOR=vi
export PAGER=less
export ENV=$HOME/.kshrc
export PS1="\$ "
if [ -x /usr/bin/fortune ] ; then /usr/bin/fortune freebsd-tips ; fi
```

ENV is where you might want customize your ksh experience. For example:

 $ vi ~/.kshrc

```
set -o vi
alias l='ls -l'
```

# pf firewall
pf in FreeBSD is a fork of OpenBSD's pf, but the general use of it for
a desktop machine is virually the same.

Append rc.conf:

```
pf_enable="yes"
pf_flags=""
pf_rules="/etc/pf.conf"
pflog_enable="yes"
pflog_logfile="/var/log/pflog"
pflog_flags=""
```

Customize your pf ruleset in /etc/pf.conf. The following is a bare
minimum you can do. Blocks everything and only allows reaching ports 80, 
443, 22, 70 and 1965, dns and ntp servers for ip4 and ip6.

You can reach the the www, gopher and gemini like this, ping ips, but 
not much else.

```
tcp_serv="{http https ssh 70 1965}"
udp_serv="{domain ntp}"

set skip on lo0

block log all

pass out inet proto tcp to port $tcp_serv
pass out inet proto udp to port $udp_serv
pass out inet6 proto tcp to port $tcp_serv
pass out inet6 proto udp to port $udp_serv

pass out inet proto icmp
pass out inet6 proto icmp6
```

 # service pf start


# xorg
Finally we install a graphical environment and drivers for our graphics
card.

 # pkg install xorg gpu-firmware-intel-kmod-kabylake drm-510-kmod cwm xdm

Notice I'm not downloading the entire drm meta package. I only pick the one
my machine will use. You can do the same by finding your graphics card/CPU
here and selecting the proper driver:

AMD: https://wiki.freebsd.org/Graphics/AMD-GPU-Matrix
Intel: https://wiki.freebsd.org/Graphics/Intel-GPU-Matrix
As for NVIDIA GPU's, I don't know.

Use kldload to load the drm driver and put it in rc.conf so that it is 
loaded on boot.

 # kldload i915kms

```
kld_list="i915kms"
```

I use xdm as a display manager. I have yet to find something better.

Add to /etc/rc.conf:
```
xdm_enable="yes"
```

At this point, if your user is not in the group video, add it:
 # pw groupmod video -m user

I use cwm in this example. Before starting X or xdm, you must edit .xsession
or .xinitrc in your HOME. (the former if you're using a display manager, the
latter if you're starting x manually.)

 $ vi ~/.xsession

```
. ~/.profile
xset b off # disable bell
setxkbmap -layout us,cz -option grp:switch -option caps:escape
# us and czech layout, switch between by holding right alt, capslock is esc

exec cwm
```

Now you can start X or xdm and login.

 $ startx 
or
 # service xdm start


# It is done?
At this point you should have a fully working FreeBSD desktop machine, with
not much on it. 

Here are a few tips that may or may not be relevant to you.

## Software
Xorg comes with xterm, which is the only terminal emulator I use. Some other
tools I get at this point is the following:

 # pkg install links sacc amfora mpv neomutt msmtp feh xlockmore

links2 web browser, sacc gopher browser, amfora gemini browser

mpv media player

neomutt+msmtp for emailing

feh image viewer (can open local files, but also remote http, gopher and
gemini urls)

xlockmore for locking the X session/screen

## Changing default audio output
In some cases, you might want to change the default audio output. For 
example the sound doesn't come out of the speakers but from somwhere
within the box. If that's your issue, check the default sound device:

 $ sysctl hw.snd.default_unit

Change it to a higher/lower number.

 $ sysctl hw.snd.default_unit=2

To have it persist over reboots, append /etc/sysctl.conf:

```
hw.snd.default_unit=2
```

## Media-keyboards
I have a keyboard with a bunch of special keys for various tasks. Suspending,
volume control, calculator.. etc. These wont work unless the following is done:

Append kld_list in /etc/rc.conf:

```
kld_list="i915kms usbhid"
```

And append /boot/loader.conf

```
hw.usb.usbhid.enable="1"
```

You have to reboot. Then the keys can be bound to anything you want.
You can use:

 $ xev

to check if the keys are being registred and see what they are called.

## volume control

Volume control is done via mixer(8).

By default, mixer does not remember last volume level when muted. To
get the usual sound toggle functionality, I use the following script:

```
#!/bin/sh
touch /tmp/mixervol
VOL=$(mixer | awk -F ':' '/vol/{print $2}')
if [ $VOL -gt 0 ]; then
echo "${VOL}" > /tmp/mixervol
mixer vol 0 
else
OVOL=$(cat /tmp/mixervol)
mixer vol ${OVOL} 
fi
```

In my case it is placed in ~/.local/bin/vol-tog. Be sure to make it
executable.

 $ chmod u+x ~/.local/bin/vol-tog

To bind volume keys in cwm, we'll edit ~/.cwmrc and append like so:

```
bind-key XF86AudioRaiseVolume "mixer vol +3"
bind-key XF86AudioLowerVolume "mixer vol -3"
bind-key XF86AudioMute "/home/user/.local/bin/vol-tog"
```

LControl-LAlt-LShift-r to reload cwm config.


## powerd and apm
If you want to suspend your machine, run

 $ zzz

As stated at the top, you need the powerd service running. If it's not,
append /etc/rc.conf

```
powerd_enable="yes"
```

 # service powerd start

Your user must be in the operator group. Otherwise you will have to run
zzz as root.

 # pw groupmod operator -m <user>

## have fun and keep on computing