Description: <short summary of the patch>
 TODO: Put a short summary on the line above and replace this paragraph
 with a longer explanation of this change. Complete the meta-information
 with other relevant fields (see below for details). To make it easier, the
 information below has been extracted from the changelog. Adjust it or drop
 it.
 .
 pdf-presenter-console (4.1.2-3) unstable; urgency=medium
 .
   * track upstream, for bug fixes and features
Author: Barak A. Pearlmutter <bap@debian.org>

---
The information above should follow the Patch Tagging Guidelines, please
checkout http://dep.debian.net/deps/dep3/ to learn about the format. Here
are templates for supplementary fields that you might want to add:

Origin: <vendor|upstream|other>, <url of original patch>
Bug: <url in upstream bugtracker>
Bug-Debian: https://bugs.debian.org/<bugnumber>
Bug-Ubuntu: https://launchpad.net/bugs/<bugnumber>
Forwarded: <no|not-needed|url proving that it has been forwarded>
Reviewed-By: <name and email of someone who approved the patch>
Last-Update: 2018-10-09

--- pdf-presenter-console-4.1.2.orig/FAQ.rst
+++ pdf-presenter-console-4.1.2/FAQ.rst
@@ -10,7 +10,7 @@ window, you can try the::
 
     --wayland-workaround
 
-flag. See issue #312 and #214 for more informations.
+flag. See issue #312 and #214 for more information.
 
 Embedded video playback is not working.
 =======================================
--- pdf-presenter-console-4.1.2.orig/README.rst
+++ pdf-presenter-console-4.1.2/README.rst
@@ -31,6 +31,10 @@ Installation
 
         sudo pacman -S pdfpc
 
+- On FreeBSD::
+
+        It's available under graphics/pdfpc. A pre built binary is also available.
+
 - On Windows 10 (with *Windows Subsystem for Linux (WSL)*)::
 
         Install:
--- pdf-presenter-console-4.1.2.orig/icons/README.icons
+++ pdf-presenter-console-4.1.2/icons/README.icons
@@ -7,3 +7,6 @@ snow.svg based on icon by bocian
 
 locked.svg based on document-encrypted.svg from
 https://github.com/KDE/breeze-icons
+
+move.svg is mono-move.svg, linewidth.svg is mono-linewidth.svg, and
+settings.svg is settings-button from https://openclipart.org
--- /dev/null
+++ pdf-presenter-console-4.1.2/icons/linewidth.svg
@@ -0,0 +1,156 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+    xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+    xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+    xmlns="http://www.w3.org/2000/svg"
+    xmlns:dc="http://purl.org/dc/elements/1.1/"
+    xmlns:ns1="http://sozi.baierouge.fr"
+    xmlns:cc="http://web.resource.org/cc/"
+    xmlns:xlink="http://www.w3.org/1999/xlink"
+    xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+    id="svg1"
+    sodipodi:docname="line_width.svg"
+    viewBox="0 0 60 60"
+    sodipodi:version="0.32"
+    _SVGFile__filename="oldscale/actions/line_width.svg"
+    version="1.0"
+    y="0"
+    x="0"
+    inkscape:version="0.40"
+    sodipodi:docbase="/home/danny/work/flat/SVG/mono/scalable/actions"
+  >
+  <sodipodi:namedview
+      id="base"
+      bordercolor="#666666"
+      inkscape:pageshadow="2"
+      inkscape:window-y="0"
+      pagecolor="#ffffff"
+      inkscape:window-height="699"
+      inkscape:zoom="4.9119411"
+      inkscape:window-x="0"
+      borderopacity="1.0"
+      inkscape:current-layer="svg1"
+      inkscape:cx="35.524813"
+      inkscape:cy="2.1056077"
+      inkscape:window-width="1024"
+      inkscape:pageopacity="0.0"
+  />
+  <g
+      id="g2366"
+      style="stroke:#ffffff"
+      transform="translate(129.86 3.8153)"
+    >
+    <rect
+        id="rect1739"
+        style="stroke-linejoin:round;color:#000000;stroke:#ffffff;stroke-linecap:round;stroke-width:5;fill:none"
+        height="7.5"
+        width="53.75"
+        y="-.68729"
+        x="-126.73"
+    />
+    <rect
+        id="rect1740"
+        style="stroke-linejoin:round;color:#000000;stroke:#ffffff;stroke-linecap:round;stroke-width:5;fill:none"
+        height="15"
+        width="53.75"
+        y="11.185"
+        x="-126.73"
+    />
+    <rect
+        id="rect1741"
+        style="stroke-linejoin:round;color:#000000;stroke:#ffffff;stroke-linecap:round;stroke-width:5;fill:none"
+        height="22.5"
+        width="53.75"
+        y="30.557"
+        x="-126.73"
+    />
+  </g
+  >
+  <rect
+      id="rect1094"
+      style="fill-rule:evenodd;color:#000000;fill:#000000"
+      transform="translate(79.857 3.8153)"
+      height="7.5"
+      width="53.75"
+      y="-.68729"
+      x="-76.732"
+  />
+  <rect
+      id="rect1716"
+      style="fill-rule:evenodd;color:#000000;fill:#000000"
+      transform="translate(79.857 3.8153)"
+      height="15"
+      width="53.75"
+      y="11.185"
+      x="-76.732"
+  />
+  <rect
+      id="rect1717"
+      style="fill-rule:evenodd;color:#000000;fill:#000000"
+      transform="translate(79.857 3.8153)"
+      height="22.5"
+      width="53.75"
+      y="30.557"
+      x="-76.732"
+  />
+  <path
+      id="path1696"
+      style="stroke-linejoin:round;stroke:#ffffff;stroke-linecap:round;stroke-width:9.2564;fill:none"
+      d="m47.686-7.5643l-12.92 9.2813 12.611 10.312 0.309-19.593z"
+      transform="matrix(0 -.77048 1 0 43.283 82.099)"
+  />
+  <path
+      id="path869"
+      style="stroke-linejoin:round;fill-rule:evenodd;stroke:#000000;stroke-linecap:round;stroke-width:3.5602;fill:#000000"
+      d="m47.686-7.5643l-12.92 9.2813 12.611 10.312 0.309-19.593z"
+      transform="matrix(0 -.77048 1 0 43.283 82.099)"
+  />
+  <metadata
+    >
+    <rdf:RDF
+      >
+      <cc:Work
+        >
+        <dc:format
+          >image/svg+xml</dc:format
+        >
+        <dc:type
+            rdf:resource="http://purl.org/dc/dcmitype/StillImage"
+        />
+        <cc:license
+            rdf:resource="http://creativecommons.org/licenses/publicdomain/"
+        />
+        <dc:publisher
+          >
+          <cc:Agent
+              rdf:about="http://openclipart.org/"
+            >
+            <dc:title
+              >Openclipart</dc:title
+            >
+          </cc:Agent
+          >
+        </dc:publisher
+        >
+      </cc:Work
+      >
+      <cc:License
+          rdf:about="http://creativecommons.org/licenses/publicdomain/"
+        >
+        <cc:permits
+            rdf:resource="http://creativecommons.org/ns#Reproduction"
+        />
+        <cc:permits
+            rdf:resource="http://creativecommons.org/ns#Distribution"
+        />
+        <cc:permits
+            rdf:resource="http://creativecommons.org/ns#DerivativeWorks"
+        />
+      </cc:License
+      >
+    </rdf:RDF
+    >
+  </metadata
+  >
+</svg
+>
--- /dev/null
+++ pdf-presenter-console-4.1.2/icons/move.svg
@@ -0,0 +1,96 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+    xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+    xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+    xmlns="http://www.w3.org/2000/svg"
+    xmlns:dc="http://purl.org/dc/elements/1.1/"
+    xmlns:ns1="http://sozi.baierouge.fr"
+    xmlns:cc="http://web.resource.org/cc/"
+    xmlns:xlink="http://www.w3.org/1999/xlink"
+    xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+    id="svg1"
+    sodipodi:docname="move.svg"
+    viewBox="0 0 60 60"
+    sodipodi:version="0.32"
+    _SVGFile__filename="oldscale/actions/move.svg"
+    version="1.0"
+    y="0"
+    x="0"
+    inkscape:version="0.40"
+    sodipodi:docbase="/home/danny/work/flat/SVG/mono/scalable/actions"
+  >
+  <sodipodi:namedview
+      id="base"
+      bordercolor="#666666"
+      inkscape:pageshadow="2"
+      inkscape:window-y="0"
+      pagecolor="#ffffff"
+      inkscape:window-height="699"
+      inkscape:zoom="5.9557621"
+      inkscape:window-x="0"
+      borderopacity="1.0"
+      inkscape:current-layer="svg1"
+      inkscape:cx="54.854709"
+      inkscape:cy="8.2067074"
+      inkscape:window-width="1024"
+      inkscape:pageopacity="0.0"
+  />
+  <path
+      id="path1717"
+      style="stroke-linejoin:round;stroke:#ffffff;stroke-linecap:round;stroke-width:8.125;fill:none"
+      d="m29.827 4.6873l-9.647 8.9267 7.401-0.028v14.024h-13.995l0.028-7.401-8.9267 9.647 8.8407 9.964 0.029-7.401h14.024v13.995l-7.401-0.028 9.647 8.927 9.964-8.841-7.401-0.029v-14.024h14.024l0.029 7.401 8.87-9.964-8.927-9.647 0.028 7.401h-14.024v-14.024l7.401-0.029-9.964-8.8697z"
+  />
+  <path
+      id="path878"
+      style="stroke-linejoin:round;fill-rule:evenodd;stroke:#000000;stroke-linecap:round;stroke-width:3.125;fill:#000000"
+      d="m29.827 4.6873l-9.647 8.9267 7.401-0.028v14.024h-13.995l0.028-7.401-8.9267 9.647 8.8407 9.964 0.029-7.401h14.024v13.995l-7.401-0.028 9.647 8.927 9.964-8.841-7.401-0.029v-14.024h14.024l0.029 7.401 8.87-9.964-8.927-9.647 0.028 7.401h-14.024v-14.024l7.401-0.029-9.964-8.8697z"
+  />
+  <metadata
+    >
+    <rdf:RDF
+      >
+      <cc:Work
+        >
+        <dc:format
+          >image/svg+xml</dc:format
+        >
+        <dc:type
+            rdf:resource="http://purl.org/dc/dcmitype/StillImage"
+        />
+        <cc:license
+            rdf:resource="http://creativecommons.org/licenses/publicdomain/"
+        />
+        <dc:publisher
+          >
+          <cc:Agent
+              rdf:about="http://openclipart.org/"
+            >
+            <dc:title
+              >Openclipart</dc:title
+            >
+          </cc:Agent
+          >
+        </dc:publisher
+        >
+      </cc:Work
+      >
+      <cc:License
+          rdf:about="http://creativecommons.org/licenses/publicdomain/"
+        >
+        <cc:permits
+            rdf:resource="http://creativecommons.org/ns#Reproduction"
+        />
+        <cc:permits
+            rdf:resource="http://creativecommons.org/ns#Distribution"
+        />
+        <cc:permits
+            rdf:resource="http://creativecommons.org/ns#DerivativeWorks"
+        />
+      </cc:License
+      >
+    </rdf:RDF
+    >
+  </metadata
+  >
+</svg
+>
--- /dev/null
+++ pdf-presenter-console-4.1.2/icons/settings.svg
@@ -0,0 +1,12 @@
+<?xml version="1.0" standalone="no"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg width="100%" height="100%" viewBox="0 0 800 800" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:1.41421;">
+    <g id="Ebene1">
+        <g transform="matrix(6.08836,0,0,6.08757,-1388.06,-794.792)">
+            <circle cx="293.685" cy="196.267" r="65.165" style="fill:rgb(185,185,185);"/>
+        </g>
+        <g transform="matrix(1.29538,0,0,1.29538,117.749,32.3418)">
+            <path d="M235.111,21.335C223.643,20.582 212.138,20.582 200.67,21.335L177.401,80.201C168.505,81.97 159.734,84.321 151.145,87.237L101.56,47.891C91.252,52.973 81.289,58.726 71.733,65.112L81.015,127.726C74.195,133.706 67.775,140.127 61.794,146.947L-0.82,137.665C-7.206,147.221 -12.958,157.184 -18.041,167.492L21.305,217.077C18.389,225.666 16.039,234.437 14.27,243.333L-44.597,266.602C-45.35,278.07 -45.35,289.575 -44.597,301.043L14.27,324.312C16.039,333.209 18.389,341.979 21.305,350.568L-18.041,400.153C-12.958,410.461 -7.206,420.425 -0.82,429.98L61.794,420.698C67.775,427.518 74.195,433.939 81.015,439.919L71.733,502.534C81.289,508.919 91.252,514.672 101.56,519.754L151.145,480.409C159.734,483.325 168.505,485.675 177.401,487.444L200.67,546.311C212.138,547.063 223.643,547.063 235.111,546.311L258.38,487.444C267.277,485.675 276.047,483.325 284.636,480.409L334.221,519.754C344.529,514.672 354.493,508.919 364.048,502.534L354.766,439.919C361.586,433.939 368.007,427.518 373.987,420.698L436.602,429.98C442.987,420.425 448.74,410.461 453.822,400.153L414.477,350.568C417.393,341.979 419.743,333.209 421.512,324.312L480.379,301.043C481.131,289.575 481.131,278.07 480.379,266.602L421.512,243.333C419.743,234.437 417.393,225.666 414.477,217.077L453.822,167.492C448.74,157.184 442.987,147.221 436.602,137.665L373.987,146.947C368.007,140.127 361.586,133.706 354.766,127.726L364.048,65.112C354.493,58.726 344.529,52.973 334.221,47.891L284.636,87.237C276.047,84.321 267.277,81.97 258.38,80.201L235.111,21.335ZM217.891,161.899C285.182,161.899 339.815,216.531 339.815,283.823C339.815,351.114 285.182,405.747 217.891,405.747C150.599,405.747 95.967,351.114 95.967,283.823C95.967,216.531 150.599,161.899 217.891,161.899Z" style="fill:white;"/>
+        </g>
+    </g>
+</svg>
--- pdf-presenter-console-4.1.2.orig/man/pdfpc.in
+++ pdf-presenter-console-4.1.2/man/pdfpc.in
@@ -143,36 +143,41 @@ Input a slide number to jump to
 .B Plus / Equal / KP_Add / Bracket Left
 Increase font size of notes
 .TP
-.B Minus / KP_Substract / Bracket Right
+.B Minus / KP_Subtract / Bracket Right
 Decrease font size of notes
 .TP
-.B 8
+.B 8 / KP_8
 Toggle pointer mode
 .TP
-.B 7
+.B 7 / KP_7
 Decrease pointer size
 .TP
-.B 9
+.B 9 / KP_9
 Increase pointer size
 .TP
-.B 5
+.B 5 / KP_5
 Toggle drawing mode
 .TP
-.B 6
+.B 6 / KP_6
 Clear the current drawing
 .TP
-.B 4
+.B 4 / KP_4
 Temporarily hide the current drawing and exit drawing mode
 .TP
-.B 1
+.B 1 / KP_1
 Decrease the pen or eraser size for drawing
 .TP
-.B 3
+.B 3 / KP_3
 Increase the pen or eraser size for drawing
 .TP
-.B 2
+.B 2 / KP_2
 Toggle between the pen and eraser tool for drawing
 .TP
+.B Shift-1 / Shift-KP_2 ... Shift-8 / Shift-KP_8
+Switch the drawing color to red/orange/yellow/green/blue/violet/black/white,
+respectively. (Depending on your keyboard layout, not all options will work
+in the main section of the keyboard.)
+.TP
 .B Escape / q
 Exit pdfpc
 .TP
@@ -443,7 +448,7 @@ See
 for a full example.
 
 .PP
-See the bugs section for further informations.
+See the bugs section for further information.
 
 .SS Pointer mode
 .PP
--- pdf-presenter-console-4.1.2.orig/man/pdfpcrc.in
+++ pdf-presenter-console-4.1.2/man/pdfpcrc.in
@@ -9,14 +9,10 @@
 .SH NAME
 pdfpcrc \- pdfpc configuration file
 
-.SH SYNOPSIS
-.B @SYSCONFDIR@/pdfpcrc / $XDG_CONFIG_DIR/pdfpc/pdfpcrc
-
 .SH DESCRIPTION
 .PP
-pdfpc(1) reads its configuration from @SYSCONFDIR@/pdfpcrc.  It also reads
-$XDG_CONFIG_DIR/pdfpc/pdfpcrc if this file exists (if $XDG_CONFIG_DIR is not
-set, $HOME/.config will be used).
+\fBpdfpc\fR(1) first reads its system-wide configuration file, followed by the
+user-specific one if it exists.
 
 .SS Keybindings
 .PP
@@ -42,7 +38,7 @@ Clear all the mouse bindings
 
 .PP
 A list of all possible functions can be obtained
-via the \-L command line option of pdfpc(1).
+via the \-L command line option of \fBpdfpc\fR(1).
 
 .SS Options
 .PP
@@ -65,11 +61,11 @@ Percentage of the presenter screen to be
 .TP
 .BI disable-caching
 see
-.B pdfpc(1)
+.B \fBpdfpc\fR(1)
 .TP
 .BI disable-compression
 see
-.B pdfpc(1)
+.B \fBpdfpc\fR(1)
 .TP
 .BI disable-scrolling
 Disable scrolling events on the presenter window (bool, Default false)
@@ -84,14 +80,23 @@ Minimum width for the overview miniature
 Switch the presentation and the presenter screen. (bool, Default false)
 .TP
 .B time-of-day
-see
-.B pdfpc(1)
+Display the current time instead of the timer
 .TP
 .B timer-pace-color
 Enable color hints of the timer, continuously indicating whether the
 presentation is progressing according to the expected pace (bool, Default true).
 See the timer operation description in
-.B pdfpc(1).
+.B \fBpdfpc\fR(1).
+.TP
+.B toolbox
+Show the toolbox on startup (bool, Default false)
+.TP
+.B toolbox-direction
+Set the toolbox direction (LtoR, RtoL, TtoB, or BtoT for the left-to-right,
+right-to-left, top-to-bottom, or botton-to-top, respectively). Default is LtoR.
+.TP
+.B toolbox-minimized
+Set the initial toolbox state minimized (bool, Default false)
 
 .SH EXAMPLES
 
@@ -123,6 +128,19 @@ config file
 option black-on-end true
 .RE
 
+.SH FILES
+.PP
+.B @SYSCONFDIR@/pdfpcrc
+.RS 4
+System-wide configuration file
+.RE
+.PP
+.B $XDG_CONFIG_DIR/pdfpc/pdfpcrc
+.RS 4
+User configuration file (if $XDG_CONFIG_DIR is not set, $HOME/.config will be
+used).
+
+
 .SH SEE ALSO
 .PP
-pdfpc(1)
+\fBpdfpc\fR(1)
--- pdf-presenter-console-4.1.2.orig/rc/pdfpc.css
+++ pdf-presenter-console-4.1.2/rc/pdfpc.css
@@ -1,7 +1,5 @@
-* {
-    background-image: none;
+*:not(button):not(label) {
     border: none;
-    color: white;
     font-family: Verdana;
     /* This will be deprecated in GTK 3.20,
      * but the alternative of Widget's min-width
@@ -19,6 +17,7 @@ scrolledwindow trough {
 }
 
 progressbar trough * {
+    background-image: none;
     background-color: blue;
 }
 
@@ -26,20 +25,17 @@ progressbar trough {
     background-color: white;
 }
 
-GtkProgressBar {
-    background-color: white;
-}
-
-GtkProgressBar * {
-    background-color: blue;
+entry, iconview, textview *, window {
+    background-color: black;
+    color: white;
 }
 
-GtkEntry, GtkIconView, GtkTextView, GtkWindow {
-    background-color: black;
+.toolbox button:not(.color) * {
+    background-color: gray;
 }
 
-entry, iconview, textview *, window {
-    background-color: black;
+.overviewWindow {
+    font-size: 4em;
 }
 
 /* The bottom text is automatically sized based on the resolution of
@@ -70,7 +66,3 @@ entry, iconview, textview *, window {
 .too-slow {
     color: orange;
 }
-
-.overviewWindow {
-    font-size: 4em;
-}
--- pdf-presenter-console-4.1.2.orig/rc/pdfpcrc
+++ pdf-presenter-console-4.1.2/rc/pdfpcrc
@@ -53,6 +53,9 @@ bind e         endSlide
 bind S+s       lastSlide
 bind S+r       jumpLastSlide
 
+# Toolbox
+bind t toggleToolbox
+
 # Font scaling
 bind plus      increaseFontSize
 bind equal     increaseFontSize
@@ -63,18 +66,27 @@ bind KP_Subtract decreaseFontSize
 bind bracketright decreaseFontSize
 
 # Pointer
-bind 8 togglePointer
-bind 7 decreasePointer
-bind 9 increasePointer
+bind 8         togglePointer
+bind KP_8      togglePointer
+bind 7         decreasePointer
+bind KP_7      decreasePointer
+bind 9         increasePointer
+bind KP_9      increasePointer
 
 # Drawing
-bind 5 toggleDrawing
-bind 6 clearDrawing
-bind 4 hideDrawing
-
-bind 1 decreasePen
-bind 2 toggleEraser
-bind 3 increasePen
+bind 5         toggleDrawing
+bind KP_5      toggleDrawing
+bind 6         clearDrawing
+bind KP_6      clearDrawing
+bind 4         hideDrawing
+bind KP_4      hideDrawing
+
+bind 1         decreasePen
+bind KP_1      decreasePen
+bind 2         toggleEraser
+bind KP_2      toggleEraser
+bind 3         increasePen
+bind KP_3      increasePen
 
 #### Mouse bindings
 mouse 1        next
@@ -90,14 +102,23 @@ bind S+numbersign setPenColor yellow
 bind S+dollar     setPenColor green
 bind S+percent    setPenColor blue
 bind S+asciicircum setPenColor violet
+bind S+dead_circumflex setPenColor violet
 bind S+ampersand  setPenColor black
 bind S+asterisk   setPenColor white
 
-bind S+1 setPenColor red
-bind S+2 setPenColor orange
-bind S+3 setPenColor yellow
-bind S+4 setPenColor green
-bind S+5 setPenColor blue
-bind S+6 setPenColor violet
-bind S+7 setPenColor black
-bind S+8 setPenColor white
+bind S+1          setPenColor red
+bind S+KP_1       setPenColor red
+bind S+2          setPenColor orange
+bind S+KP_2       setPenColor orange
+bind S+3          setPenColor yellow
+bind S+KP_3       setPenColor yellow
+bind S+4          setPenColor green
+bind S+KP_4       setPenColor green
+bind S+5          setPenColor blue
+bind S+KP_5       setPenColor blue
+bind S+6          setPenColor violet
+bind S+KP_6       setPenColor violet
+bind S+7          setPenColor black
+bind S+KP_7       setPenColor black
+bind S+8          setPenColor white
+bind S+KP_8       setPenColor white
--- pdf-presenter-console-4.1.2.orig/rc/rcfile-logitech
+++ pdf-presenter-console-4.1.2/rc/rcfile-logitech
@@ -1,5 +1,5 @@
-# Config file for Logitech Wireless Presetners
+# Config file for Logitech Wireless Presenters
 
 bind Escape exitState
 bind period blank
-bind F5 freezeOn
\ No newline at end of file
+bind F5 freezeOn
--- pdf-presenter-console-4.1.2.orig/src/CMakeLists.txt
+++ pdf-presenter-console-4.1.2/src/CMakeLists.txt
@@ -3,7 +3,7 @@ pkg_check_modules(GOBJECT REQUIRED gobje
 pkg_check_modules(GIO REQUIRED gio-2.0)
 pkg_check_modules(GEE REQUIRED gee-0.8)
 pkg_check_modules(POPPLER REQUIRED poppler-glib>=0.22)
-pkg_check_modules(GTK REQUIRED gtk+-3.0>=3.10)
+pkg_check_modules(GTK REQUIRED gtk+-3.0>=3.20)
 list (FIND GTK_STATIC_LIBRARIES "X11" _index)
 if (${_index} GREATER -1)
     set(WITH_X11 1)
@@ -80,6 +80,27 @@ else ()
     LIST(REMOVE_ITEM VALA_SRC classes/action/movie.vala)
 endif ()
 
+# Check for some compiler flags to suppress excessive Vala-triggered warnings
+# Since gcc >= 4.4 can silently ignore unrecognized -W-no* flags, we test
+# for positive options instead.
+include(CheckCCompilerFlag)
+check_c_compiler_flag(-Wdiscarded-qualifiers CC_HAS_DISCARDED_QUALIFIERS)
+if (CC_HAS_DISCARDED_QUALIFIERS)
+    add_definitions("-Wno-discarded-qualifiers")
+endif()
+check_c_compiler_flag(-Wincompatible-pointer-types CC_HAS_INCOMPATIBLE_POINTER_TYPES)
+if (CC_HAS_INCOMPATIBLE_POINTER_TYPES)
+    add_definitions("-Wno-incompatible-pointer-types")
+endif()
+check_c_compiler_flag(-Wdeprecated-declarations CC_HAS_DEPRECATED_DECLARATIONS)
+if (CC_HAS_DEPRECATED_DECLARATIONS)
+    add_definitions("-Wno-deprecated-declarations")
+endif()
+check_c_compiler_flag(-Wimplicit-function-declaration CC_HAS_IMPLICIT_FUNCTION_DECLARATION)
+if (CC_HAS_IMPLICIT_FUNCTION_DECLARATION)
+    add_definitions("-Wno-implicit-function-declaration")
+endif()
+
 vala_precompile(VALA_C
     ${VALA_SRC}
 PACKAGES
--- pdf-presenter-console-4.1.2.orig/src/classes/action/action_mapping.vala
+++ pdf-presenter-console-4.1.2/src/classes/action/action_mapping.vala
@@ -109,6 +109,13 @@ namespace pdfpc {
         public abstract bool on_button_press(Gtk.Widget widget, Gdk.EventButton event);
 
         /**
+         * Override this method to get notified of the freeze toggle events.
+         */
+        public virtual void on_freeze(bool frozen) {
+            return;
+        }
+
+        /**
          * Called when leaving the page.  Override to clean up after yourself.
          */
         public virtual void deactivate() {
--- pdf-presenter-console-4.1.2.orig/src/classes/action/movie.vala
+++ pdf-presenter-console-4.1.2/src/classes/action/movie.vala
@@ -148,13 +148,39 @@ namespace pdfpc {
             }
         }
 
+        /**
+         * Auxiliary part of init_movie() that can be called asynchronously
+         * via GLib.Idle.add()
+         */
+        protected void init_movie2(ControlledMovie movie,
+                string uri, bool autostart) {
+            movie.establish_pipeline(uri);
+            if (movie.pipeline == null) {
+                return;
+            }
+
+            // initial seek to set the starting point. *Cause the video to
+            // be displayed on the page*.
+            movie.pipeline.set_state(Gst.State.PAUSED);
+            // waits until the pipeline is actually in PAUSED mode
+            movie.pipeline.get_state(null, null, Gst.CLOCK_TIME_NONE);
+            movie.pipeline.seek_simple(Gst.Format.TIME, Gst.SeekFlags.FLUSH,
+                movie.starttime * Gst.SECOND);
+
+            movie.hide();
+
+            if (autostart) {
+                movie.play();
+            }
+        }
 
         /**
          * Inits  the movie
          */
         public void init_movie(ActionMapping other, Poppler.Rectangle area,
                 PresentationController controller, Poppler.Document document,
-                string uri, bool autostart, bool loop, bool noprogress, bool noaudio, int start = 0, int stop = 0, bool temp=false) {
+                string uri, bool autostart, bool loop, bool noprogress,
+                bool noaudio, int start = 0, int stop = 0, bool temp = false) {
             other.init(area, controller, document);
             ControlledMovie movie = (ControlledMovie) other;
             movie.loop = loop;
@@ -164,23 +190,14 @@ namespace pdfpc {
             movie.stoptime = stop;
             movie.temp = temp ? uri.substring(7) : "";
 
+#if MOVIE_LOAD_ASYNC
             GLib.Idle.add( () => {
-                movie.establish_pipeline(uri);
-
-                // initial seek to set the starting point. *Cause the video to
-                // be displayed on the page*.
-                movie.pipeline.set_state(Gst.State.PAUSED);
-                // waits until the pipeline is actually in PAUSED mode
-                movie.pipeline.get_state(null, null, Gst.CLOCK_TIME_NONE);
-                movie.pipeline.seek_simple(Gst.Format.TIME, Gst.SeekFlags.FLUSH, movie.starttime * Gst.SECOND);
-
-                movie.hide();
-
-                if (autostart) {
-                    movie.play();
-                }
+                this.init_movie2(movie, uri, autostart);
                 return false;
             } );
+#else
+            this.init_movie2(movie, uri, autostart);
+#endif
         }
 
         /**
@@ -367,6 +384,10 @@ namespace pdfpc {
          * drag state.
          */
         public override bool on_button_press(Gtk.Widget widget, Gdk.EventButton event) {
+            if (this.pipeline == null) {
+                return false;
+            }
+
             Gst.State state;
             Gst.ClockTime time = Gst.Util.get_timestamp();
             this.pipeline.get_state(out state, null, time);
@@ -407,6 +428,20 @@ namespace pdfpc {
             return false;
         }
 
+        public override void on_freeze(bool frozen) {
+            // if a video was forcefully hidden but we're no longer in the
+            // freeze mode, show it and clear the respective flag
+            foreach (var sink in this.sinks) {
+                bool sink_is_frozen = sink.get_data("pdfpc_frozen");
+                if (!frozen && sink_is_frozen) {
+                    sink.set_opacity(1);
+                    sink.set_data("pdfpc_frozen", false);
+                }
+            }
+
+            return;
+        }
+
         /**
          * Everytime we get a new frame, update the progress bar.
          */
@@ -493,11 +528,14 @@ namespace pdfpc {
         }
 
         /**
-         * Show all video widgets
+         * Show all video widgets except those created while the view was frozen
          */
         public void show() {
             foreach (var sink in this.sinks) {
-                sink.set_opacity(1);
+                bool sink_is_frozen = sink.get_data("pdfpc_frozen");
+                if (!sink_is_frozen) {
+                    sink.set_opacity(1);
+                }
             }
         }
 
@@ -580,6 +618,8 @@ namespace pdfpc {
          * Set up the gstreamer pipeline.
          */
         protected void establish_pipeline(string uri) {
+            this.pipeline = null;
+
             Gst.Bin bin = new Gst.Bin("bin");
             Gst.Element tee = Gst.ElementFactory.make("tee", "tee");
             bin.add_many(tee);
@@ -625,7 +665,15 @@ namespace pdfpc {
                     continue;
                 }
 
-                Gst.Element sink = Gst.ElementFactory.make("gtksink", @"sink$n");
+                Gst.Element sink;
+                try {
+                    sink = gst_element_make("gtksink", @"sink$n");
+                } catch (PipelineError e) {
+                    GLib.printerr("Error creating video sink: %s\n", e.message);
+                    GLib.printerr("Gstreamer installation may be incomplete.\n");
+                    return;
+                }
+
                 Gtk.Widget video_area;
                 sink.get("widget", out video_area);
                 Gst.Element queue = Gst.ElementFactory.make("queue", @"queue$n");
@@ -648,6 +696,12 @@ namespace pdfpc {
                 }
                 sink.set("force_aspect_ratio", false);
 
+                // mark the video widget on the "frozen" presentation screen
+                // with a custom flag
+                if (conf.display_num == 1 && controller.frozen) {
+                    video_area.set_data("pdfpc_frozen", true);
+                }
+
                 conf.window.video_surface.add_video(video_area, conf.rect);
                 this.sinks.add(video_area);
 
@@ -784,7 +838,9 @@ namespace pdfpc {
          * Stop playback.
          */
         public virtual void stop() {
-            this.pipeline.set_state(Gst.State.NULL);
+            if (this.pipeline != null) {
+                this.pipeline.set_state(Gst.State.NULL);
+            }
         }
 
         /**
--- pdf-presenter-console-4.1.2.orig/src/classes/config_file_reader.vala
+++ pdf-presenter-console-4.1.2/src/classes/config_file_reader.vala
@@ -278,6 +278,16 @@ namespace pdfpc {
                     bool timer_pace_color = bool.parse(fields[2]);
                     Options.timer_pace_color = timer_pace_color;
                     break;
+                case "toolbox":
+                    Options.toolbox_shown = bool.parse(fields[2]);
+                    break;
+                case "toolbox-direction":
+                    Options.toolbox_direction =
+                        Options.ToolboxDirection.parse(fields[2]);
+                    break;
+                case "toolbox-minimized":
+                    Options.toolbox_minimized = bool.parse(fields[2]);
+                    break;
                 default:
                     GLib.printerr("Unknown option %s in pdfpcrc\n", fields[1]);
                     break;
--- pdf-presenter-console-4.1.2.orig/src/classes/dbus_server.vala
+++ pdf-presenter-console-4.1.2/src/classes/dbus_server.vala
@@ -75,11 +75,11 @@ namespace pdfpc {
                 }, () => {}, () => GLib.printerr("Could not acquire DBus bus.\n"));
         }
 
-        public void trigger_action(string name) {
+        public void trigger_action(string name) throws GLib.Error {
             this.controller.trigger_action(name);
         }
 
-        public string get_notes() {
+        public string get_notes() throws GLib.Error {
             return this.metadata.get_notes().get_note_for_slide(controller.current_user_slide_number);
         }
     }
--- pdf-presenter-console-4.1.2.orig/src/classes/metadata/pdf.vala
+++ pdf-presenter-console-4.1.2/src/classes/metadata/pdf.vala
@@ -442,10 +442,12 @@ namespace pdfpc.Metadata {
                                 note_text += "\n";
                             }
                             note_text += a.get_contents();
+
+                            // Remove the annotation to avoid its rendering
+                            page.remove_annot(a);
+
                             break;
                     }
-                    // Remove the annotation to avoid its rendering
-                    page.remove_annot(a);
                 }
                 if (note_text != "") {
                     this.notes.set_note(note_text, user_slide, true);
--- pdf-presenter-console-4.1.2.orig/src/classes/options.vala
+++ pdf-presenter-console-4.1.2/src/classes/options.vala
@@ -210,5 +210,46 @@ namespace pdfpc {
          * Used to post pone binding execution in presentation controller
          */
         public static Gee.List<BindTuple> mouse_bindings;
+
+        /**
+         * Defines direction/orientation of the toolbox
+         */
+        public enum ToolboxDirection {
+            LtoR,
+            RtoL,
+            TtoB,
+            BtoT;
+
+            public static ToolboxDirection parse(string? dir) {
+                if (dir == null) {
+                    return LtoR;
+                }
+
+                switch (dir.down()) {
+                    case "ltor":
+                        return LtoR;
+                    case "rtol":
+                        return RtoL;
+                    case "ttob":
+                        return TtoB;
+                    case "btot":
+                        return BtoT;
+                    default:
+                        return LtoR;
+                }
+            }
+        }
+
+        /**
+         * Direction of the toolbox
+         */
+        public static ToolboxDirection toolbox_direction =
+            ToolboxDirection.LtoR;
+
+        /**
+         * State of the toolbox
+         */
+        public static bool toolbox_shown = false;
+        public static bool toolbox_minimized = false;
     }
 }
--- pdf-presenter-console-4.1.2.orig/src/classes/presentation_controller.vala
+++ pdf-presenter-console-4.1.2/src/classes/presentation_controller.vala
@@ -31,8 +31,8 @@
 
 [DBus (name = "org.freedesktop.ScreenSaver")]
 public interface ScreenSaver : Object {
-    public abstract async uint32 inhibit(string application_name, string reason) throws IOError;
-    public abstract void un_inhibit(uint32 cookie) throws IOError;
+    public abstract async uint32 inhibit(string application_name, string reason) throws DBusError, IOError;
+    public abstract void un_inhibit(uint32 cookie) throws DBusError, IOError;
 }
 
 namespace pdfpc {
@@ -227,8 +227,10 @@ namespace pdfpc {
             }
 
             public uint hash() {
-                var uintHashFunc = Gee.Functions.get_hash_func_for(Type.from_name("uint"));
-                return uintHashFunc(this.keycode | this.modMask); // | is probable the best combinator, but for this small application it should suffice
+                // see gdk/gdkkeysyms.h modMask is usally in the form of
+                // 0xFF??. Keycodes are usally 0x??. We shift modMask by 8 bits
+                // to combine both codes.
+                return (this.modMask << 8) | this.keycode;
             }
 
             public bool equal_to(KeyDef other) {
@@ -316,7 +318,7 @@ namespace pdfpc {
         /* pen mode state */
         public Gtk.DrawingArea? presenter_pen_surface;
         public Gtk.DrawingArea? presentation_pen_surface;
-        private Drawings.Drawing pen_drawing;
+        public Drawings.Drawing pen_drawing;
         private Drawings.DrawingTool? current_mouse_tool = null;
         private Drawings.DrawingTool? current_pen_drawing_tool = null;
         private bool mouse_tool_is_eraser = false;
@@ -438,7 +440,21 @@ namespace pdfpc {
             queue_pen_surface_draws();
         }
 
-        private void queue_pen_surface_draws() {
+        public void set_pen_size(double width) {
+            if (width > 500) {
+                width = 500;
+            } else
+            if (width < pen_step) {
+                width = pen_step;
+            }
+            current_pen_drawing_tool.width = width;
+        }
+
+        public double get_pen_size() {
+            return current_pen_drawing_tool.width;
+        }
+
+        public void queue_pen_surface_draws() {
             if (presenter != null) {
                 presenter_pen_surface.queue_draw();
             }
@@ -679,11 +695,9 @@ namespace pdfpc {
         }
 
         protected void draw_pointer(Cairo.Context context, Gtk.Allocation a) {
-            int x = (int)(a.width*pointer_x);
-            int y = (int)(a.height*pointer_y);
-            int r = (int)(a.height*0.001*pointer_size);
-
-            if (highlight_w>0) {
+            // Draw the highlighted area, but ignore very short drags
+            // made unintentionally by mouse clicks
+            if (highlight_w > 0.01 && highlight_h > 0.01) {
                 context.rectangle(0,0,a.width, a.height);
                 context.new_sub_path();
                 context.rectangle((int)(highlight_x*a.width), (int)(highlight_y*a.height), (int)(highlight_w*a.width), (int)(highlight_h*a.height));
@@ -692,12 +706,14 @@ namespace pdfpc {
                 context.set_source_rgba(0,0,0,0.5);
                 context.fill_preserve();
 
-                //cursor
                 context.new_path();
-                context.set_source_rgba(255,0,0,0.5);
-                context.arc(x, y, r, 0, 2*Math.PI);
-                context.fill();
-            } else {
+            }
+            // Draw the pointer when not dragging
+            if (drag_x == -1) {
+                int x = (int)(a.width*pointer_x);
+                int y = (int)(a.height*pointer_y);
+                int r = (int)(a.height*0.001*pointer_size);
+
                 context.set_source_rgba(255,0,0,0.5);
                 context.arc(x, y, r, 0, 2*Math.PI);
                 context.fill();
@@ -818,6 +834,8 @@ namespace pdfpc {
             add_action("increaseFontSize", this.increase_font_size);
             add_action("decreaseFontSize", this.decrease_font_size);
 
+            add_action("toggleToolbox", this.toggle_toolbox);
+
             add_action("exitState", this.exit_state);
             add_action("quit", this.quit);
         }
@@ -835,44 +853,55 @@ namespace pdfpc {
         }
 
         /**
-         * Gets an array wit all function names
+         * Get an array with all action names
          *
-         * It would be more legant yo use the keys property of actionNames, but
+         * It would be more elegant to use the key property of actionNames, but
          * we would need an instance for doing this...
          */
         public static string[] getActionDescriptions() {
-            return {"next", "Go to next slide",
+            return {
+                "next", "Go to the next slide",
                 "next10", "Jump 10 slides forward",
                 "lastOverlay", "Jump to the last overlay of the current slide",
-                "nextOverlay", "Jump forward outside of current overlay",
-                "prev", "Go to previous slide",
+                "nextOverlay", "Jump forward outside of the current overlay",
+                "prev", "Go to the previous slide",
                 "prev10", "Jump 10 slides back",
-                "prevOverlay", "Jump back outside of current overlay",
+                "prevOverlay", "Jump back outside of the current overlay",
                 "goto", "Ask for a page to jump to",
-                "gotoFirst", "Jump to first slide",
-                "gotoLast", "Jump to last slide",
+                "gotoFirst", "Jump to the first slide",
+                "gotoLast", "Jump to the last slide",
+                "nextUnseen", "Jump to the next unseen slide",
+                "prevSeen", "Jump to the last previously seen slide",
                 "overview", "Show the overview mode",
                 "histBack", "Go back in history",
                 "start", "Start the timer",
                 "pause", "Pause the timer",
                 "resetTimer", "Reset the timer",
                 "reset", "Reset the presentation",
-                "blank", "Blank presentation screen",
-                "freeze", "Toggle freeze presentation screen",
-                "freezeOn", "Freeze presentation screen if unfrozen",
-                "overlay", "Mark current slide as overlay slide",
-                "note", "Edit note for current slide",
-                "endSlide", "Set current slide as end slide",
-                "lastSlide", "Set last displayed slide",
-                "jumpLastSlide", "Goto last displayed slide",
-                "increaseFontSize", "Increase the current font size by 10%",
-                "decreaseFontSize", "Decrease the current font size by 10%",
-                "togglePointer", "Toggle pointer mode",
-                "increasePointer", "Increase pointer size",
-                "decreasePointer", "Decrease pointer size",
+                "blank", "Blank the presentation screen",
+                "hide", "Hide the presentation screen",
+                "freeze", "Toggle freeze the presentation screen",
+                "freezeOn", "Freeze the presentation screen",
+                "overlay", "Mark the current slide as an overlay slide",
+                "note", "Edit notes for the current slide",
+                "endSlide", "Set the current slide as the end slide",
+                "lastSlide", "Set the last displayed slide",
+                "jumpLastSlide", "Goto the last displayed slide",
+                "increaseFontSize", "Increase the current font size by 2pt",
+                "decreaseFontSize", "Decrease the current font size by 2pt",
+                "togglePointer", "Toggle the pointer mode",
+                "increasePointer", "Increase the pointer size",
+                "decreasePointer", "Decrease the pointer size",
+                "toggleDrawing", "Toggle the drawing mode",
+                "toggleEraser", "Toggle between eraser/pen in the drawing mode",
+                "increasePen", "Increase the pen size",
+                "decreasePen", "Decrease the pen size",
+                "clearDrawing", "Clear all drawings on the current slide",
+                "hideDrawing", "Hide all drawings on the current slide",
+                "toggleToolbox", "Toggle the toolbox",
                 "exitState", "Exit \"special\" state (pause, freeze, blank)",
                 "quit", "Exit pdfpc",
-                "setPenColor", "Change pen color (requires argument)",
+                "setPenColor", "Change the pen color (requires an argument)",
             };
         }
 
@@ -1585,7 +1614,7 @@ namespace pdfpc {
         /**
          * Fill the presentation display with black
          */
-        protected void fade_to_black() {
+        public void fade_to_black() {
             this.faded_to_black = !this.faded_to_black;
             this.controllables_update();
         }
@@ -1593,7 +1622,7 @@ namespace pdfpc {
         /**
          * Hide the presentation window
          */
-        protected void hide_presentation() {
+        public void hide_presentation() {
             this.hidden = !this.hidden;
             this.controllables_update();
         }
@@ -1621,12 +1650,13 @@ namespace pdfpc {
         /**
          * Freeze the display
          */
-        protected void toggle_freeze() {
+        public void toggle_freeze() {
             this.frozen = !this.frozen;
             if (!this.frozen) {
                 this.faded_to_black = false;
             }
             this.controllables_update();
+            main_view.freeze_toggled(this.frozen);
         }
 
         /**
@@ -1658,7 +1688,7 @@ namespace pdfpc {
         /**
          * Pause the timer
          */
-        protected void toggle_pause() {
+        public void toggle_pause() {
             this.timer.pause();
             this.controllables_update();
         }
@@ -1678,6 +1708,14 @@ namespace pdfpc {
             this.decrease_font_size_request();
         }
 
+        /**
+         * Toggle toolbox visibility
+         */
+        public void toggle_toolbox() {
+            Options.toolbox_shown = !Options.toolbox_shown;
+            this.controllables_update();
+        }
+
         protected void exit_state() {
             if (this.faded_to_black) {
                 this.fade_to_black();
--- pdf-presenter-console-4.1.2.orig/src/classes/view/behaviour/pdf_link.vala
+++ pdf-presenter-console-4.1.2/src/classes/view/behaviour/pdf_link.vala
@@ -61,6 +61,7 @@ namespace pdfpc.View.Behaviour {
             view.motion_notify_event.connect(this.on_mouse_move);
             view.entering_slide.connect(this.on_entering_slide);
             view.leaving_slide.connect(this.on_leaving_slide);
+            view.freeze_toggled.connect(this.on_freeze_toggle);
         }
 
         /**
@@ -172,5 +173,14 @@ namespace pdfpc.View.Behaviour {
             // Free memory of precalculated rectangles
             this.precalculated_mapping_rectangles = null;
         }
+
+        /**
+         * Update the mappings on freeze toggle
+         */
+        public void on_freeze_toggle(View.Pdf source, bool frozen) {
+            foreach(var mapping in this.page_link_mappings) {
+                mapping.on_freeze(frozen);
+            }
+        }
     }
 }
--- pdf-presenter-console-4.1.2.orig/src/classes/view/pdf.vala
+++ pdf-presenter-console-4.1.2/src/classes/view/pdf.vala
@@ -74,6 +74,11 @@ namespace pdfpc {
         public signal void prerendering_started();
 
         /**
+         * Signal emitted on toggling the freeze state
+         */
+        public signal void freeze_toggled(bool frozen);
+
+        /**
          * The currently displayed slide
          */
         protected int current_slide_number;
--- pdf-presenter-console-4.1.2.orig/src/classes/window/fullscreen.vala
+++ pdf-presenter-console-4.1.2/src/classes/window/fullscreen.vala
@@ -96,16 +96,15 @@ namespace pdfpc.Window {
 
                 // Start in the given monitor
                 this.screen_to_use = Gdk.Screen.get_default();
-                this.screen_to_use.get_monitor_geometry(this.screen_num_to_use, out this.screen_geometry);
             } else {
                 // Start in the monitor the cursor is in
-                var display = Gdk.Display.get_default().get_device_manager().get_client_pointer();
+                var device = Gdk.Display.get_default().get_default_seat().get_pointer();
                 int pointerx, pointery;
-                display.get_position(out this.screen_to_use, out pointerx, out pointery);
+                device.get_position(out this.screen_to_use, out pointerx, out pointery);
 
                 this.screen_num_to_use = this.screen_to_use.get_monitor_at_point(pointerx, pointery);
-                this.screen_to_use.get_monitor_geometry(this.screen_num_to_use, out this.screen_geometry);
             }
+            this.screen_to_use.get_monitor_geometry(this.screen_num_to_use, out this.screen_geometry);
 
             this.gdk_scale = this.screen_to_use.get_monitor_scale_factor(this.screen_num_to_use);
             if (Pdfpc.is_Wayland_backend() && Options.wayland_workaround) {
--- pdf-presenter-console-4.1.2.orig/src/classes/window/presenter.vala
+++ pdf-presenter-console-4.1.2/src/classes/window/presenter.vala
@@ -119,6 +119,11 @@ namespace pdfpc.Window {
         protected Gtk.TextView notes_view;
 
         /**
+         * CSS provider for setting note font size
+         */
+        protected Gtk.CssProvider css_provider;
+
+        /**
          * Indication that the highlight tool is selected
          */
         protected Gtk.Image highlight_icon;
@@ -144,6 +149,37 @@ namespace pdfpc.Window {
         protected Gtk.Stack slide_stack;
 
         /**
+         * Fixed layout - container of the toolbox.
+         */
+        protected Gtk.Fixed toolbox_container;
+
+        /**
+         * The toolbox with action buttons
+         */
+        protected Gtk.Box toolbox;
+
+        /**
+         * Drawing color selector button of the toolbox
+         */
+        protected Gtk.ColorButton color_button;
+
+        /**
+         * Drawing scale selector button of the toolbox
+         */
+        protected Gtk.ScaleButton scale_button;
+
+        /**
+         * Coordinates of the click event at the beginning of toolbox dragging
+         **/
+        private int toolbox_x0;
+        private int toolbox_y0;
+
+        /**
+         * Size of the toolbox button icons
+         **/
+        private int toolbox_icon_height;
+
+        /**
          * Metadata of the slides
          */
         protected Metadata.Pdf metadata;
@@ -153,7 +189,93 @@ namespace pdfpc.Window {
          **/
         protected int next_allocated_width;
 
-        /**
+        protected bool on_button_press(Gtk.Widget pbut, Gdk.EventButton event) {
+	    if (event.button == 1 ) {
+                var w = this.get_window();
+
+                w.get_position(out this.toolbox_x0, out this.toolbox_y0);
+
+                this.toolbox_x0 += (int) event.x;
+	        this.toolbox_y0 += (int) event.y;
+            }
+
+	    return true;
+        }
+
+        protected bool on_move_pointer(Gtk.Widget pbut, Gdk.EventMotion event) {
+            int x = (int) event.x_root - this.toolbox_x0;
+            int y = (int) event.y_root - this.toolbox_y0;
+
+            if (true) {
+                int dest_x, dest_y;
+                toolbox.translate_coordinates(pbut, x, y,
+                    out dest_x, out dest_y);
+                this.toolbox_container.move(toolbox, dest_x, dest_y);
+            }
+
+            return true;
+        }
+
+        protected Gtk.Button add_toolbox_button(Gtk.Box panel,
+            bool tbox_inverse, string icon_fname) {
+            var bimage = this.load_icon(icon_fname, toolbox_icon_height);
+            bimage.show();
+            var button = new Gtk.Button();
+            button.add(bimage);
+            if (tbox_inverse) {
+                panel.pack_end(button);
+            } else {
+                panel.pack_start(button);
+            }
+
+            return button;
+        }
+
+        protected Gtk.ColorButton add_toolbox_cbutton(Gtk.Box panel,
+            bool tbox_inverse) {
+            var button = new Gtk.ColorButton();
+            if (tbox_inverse) {
+                panel.pack_end(button);
+            } else {
+                panel.pack_start(button);
+            }
+
+            return button;
+        }
+
+        protected Gtk.ScaleButton add_toolbox_sbutton(Gtk.Box panel,
+            bool tbox_inverse, string icon_fname) {
+
+            var button = new Gtk.ScaleButton(Gtk.IconSize.DIALOG,
+                0, 50, 2, null);
+
+            var bimage = this.load_icon(icon_fname, toolbox_icon_height);
+            bimage.show();
+            button.set_image(bimage);
+
+            button.set_relief(Gtk.ReliefStyle.NORMAL);
+            button.get_adjustment().set_page_increment(4);
+
+            if (tbox_inverse) {
+                panel.pack_end(button);
+            } else {
+                panel.pack_start(button);
+            }
+
+            // ignore input events on the main window while the scale popup
+            // is active
+            var popup = button.get_popup();
+            popup.show.connect(() => {
+                this.presentation_controller.set_ignore_input_events(true);
+            });
+            popup.hide.connect(() => {
+                this.presentation_controller.set_ignore_input_events(false);
+            });
+
+            return button;
+        }
+
+       /**
          * Base constructor instantiating a new presenter window
          */
         public Presenter(Metadata.Pdf metadata, int screen_num,
@@ -185,7 +307,7 @@ namespace pdfpc.Window {
             // should use as a percentage value. The maximal height is 90% of
             // the screen, as we need a place to display the timer and slide
             // count.
-            Gdk.Rectangle current_scale_rect;
+            Gdk.Rectangle current_slide_rect;
             int current_allocated_width = (int) Math.floor(
                 this.screen_geometry.width * Options.current_size / (double) 100);
             this.current_view = new View.Pdf.from_metadata(
@@ -197,7 +319,7 @@ namespace pdfpc.Window {
                 true,
                 this.presentation_controller,
                 this.gdk_scale,
-                out current_scale_rect
+                out current_slide_rect
             );
 
             // The next slide is right to the current one and takes up the
@@ -208,7 +330,7 @@ namespace pdfpc.Window {
             int next_allocated_width = (int)Math.fmax(this.screen_geometry.width - current_allocated_width - 4, 0);
             this.next_allocated_width = next_allocated_width;
             // We leave a bit of margin between the two views
-            Gdk.Rectangle next_scale_rect;
+            Gdk.Rectangle next_slide_rect;
             this.next_view = new View.Pdf.from_metadata(
                 metadata,
                 next_allocated_width,
@@ -218,9 +340,10 @@ namespace pdfpc.Window {
                 false,
                 this.presentation_controller,
                 this.gdk_scale,
-                out next_scale_rect
+                out next_slide_rect
             );
 
+            Gdk.Rectangle strict_next_slide_rect;
             this.strict_next_view = new View.Pdf.from_metadata(
                 metadata,
                 (int) Math.floor(0.5 * current_allocated_width),
@@ -230,8 +353,9 @@ namespace pdfpc.Window {
                 false,
                 this.presentation_controller,
                 this.gdk_scale,
-                out next_scale_rect
+                out strict_next_slide_rect
             );
+            Gdk.Rectangle strict_prev_slide_rect;
             this.strict_prev_view = new View.Pdf.from_metadata(
                 metadata,
                 (int) Math.floor(0.5 * current_allocated_width),
@@ -241,9 +365,13 @@ namespace pdfpc.Window {
                 false,
                 this.presentation_controller,
                 this.gdk_scale,
-                out next_scale_rect
+                out strict_prev_slide_rect
             );
 
+            this.css_provider = new Gtk.CssProvider();
+            Gtk.StyleContext.add_provider_for_screen(this.screen_to_use,
+                css_provider, Gtk.STYLE_PROVIDER_PRIORITY_USER);
+
             // TextView for notes in the slides
             this.notes_view = new Gtk.TextView();
             this.notes_view.name = "notesView";
@@ -254,16 +382,13 @@ namespace pdfpc.Window {
             this.notes_view.buffer.text = "";
             this.notes_view.key_press_event.connect(this.on_key_press_notes_view);
             if (this.metadata.font_size >= 0) {
-                Pango.FontDescription font_desc = get_notes_font_description();
-
-                // LEGCAY font size detection
+                // LEGACY font size detection
                 // Before, we had the font size in absolute (device) units.
-                // These where typically larger then 1000
+                // These were typically larger than 1000
                 if (this.metadata.font_size >= 1000) {
                     this.metadata.font_size /= Pango.SCALE;
                 }
-                font_desc.set_size(this.metadata.font_size * Pango.SCALE);
-                this.notes_view.override_font(font_desc);
+                this.set_font_size(this.metadata.font_size);
             }
 
             // The countdown timer is centered in the 90% bottom part of the screen
@@ -302,7 +427,7 @@ namespace pdfpc.Window {
             this.prerender_progress.no_show_all = true;
             this.prerender_progress.valign = Gtk.Align.END;
 
-            int icon_height = (int)Math.round(bottom_height*0.9);;
+            int icon_height = (int)Math.round(bottom_height*0.9);
 
             this.blank_icon = this.load_icon("blank.svg", icon_height);
             this.hidden_icon = this.load_icon("hidden.svg", icon_height);
@@ -327,7 +452,7 @@ namespace pdfpc.Window {
             // resize the bottom text based on the window height
             // (see http://stackoverflow.com/a/35237445/730138)
             var bottom_text_css_provider = new Gtk.CssProvider();
-            Gtk.StyleContext.add_provider_for_screen(Gdk.Screen.get_default(),
+            Gtk.StyleContext.add_provider_for_screen(this.screen_to_use,
                 bottom_text_css_provider, Gtk.STYLE_PROVIDER_PRIORITY_FALLBACK);
 
             const string bottom_text_css_template = ".bottomText { font-size: %dpx; }";
@@ -380,6 +505,7 @@ namespace pdfpc.Window {
             this.next_view.halign = Gtk.Align.CENTER;
             this.next_view.valign = Gtk.Align.CENTER;
             nextViewWithNotes.pack_start(next_view, false, false, 0);
+
             var notes_sw = new Gtk.ScrolledWindow(null, null);
             notes_sw.set_size_request(this.next_allocated_width, -1);
             notes_sw.add(this.notes_view);
@@ -424,7 +550,143 @@ namespace pdfpc.Window {
             full_layout.pack_start(this.slide_stack, true, true, 0);
             full_layout.pack_end(bottom_row, false, false, 0);
 
-            this.add(full_layout);
+            Gtk.Overlay full_overlay = new Gtk.Overlay();
+            full_overlay.add_overlay(full_layout);
+
+            // maybe should be calculated based on screen dimensions?
+            this.toolbox_icon_height = 36;
+
+            Gtk.Orientation toolbox_orientation = Gtk.Orientation.HORIZONTAL;
+            bool tbox_inverse = false;
+            int tb_offset = (int) Math.round(0.1*strict_prev_slide_rect.height);
+
+            int tbox_x = 0, tbox_y = 0;
+            switch (Options.toolbox_direction) {
+                case Options.ToolboxDirection.LtoR:
+                    toolbox_orientation = Gtk.Orientation.HORIZONTAL;
+                    tbox_inverse = false;
+                    tbox_x = strict_prev_slide_rect.width + tb_offset;
+                    tbox_y = current_slide_rect.height + tb_offset;
+                    break;
+                case Options.ToolboxDirection.RtoL:
+                    toolbox_orientation = Gtk.Orientation.HORIZONTAL;
+                    tbox_inverse = true;
+                    tbox_x = strict_next_slide_rect.width - tb_offset;
+                    tbox_y = current_slide_rect.height + tb_offset;
+                    break;
+                case Options.ToolboxDirection.TtoB:
+                    toolbox_orientation = Gtk.Orientation.VERTICAL;
+                    tbox_inverse = false;
+                    tbox_x = current_slide_rect.width + tb_offset;
+                    tbox_y = next_slide_rect.height + tb_offset;
+                    break;
+                case Options.ToolboxDirection.BtoT:
+                    toolbox_orientation = Gtk.Orientation.VERTICAL;
+                    tbox_inverse = true;
+                    tbox_x = current_slide_rect.width + tb_offset;
+                    tbox_y = next_slide_rect.height + tb_offset;
+                    break;
+            }
+            tbox_x /= this.gdk_scale;
+            tbox_y /= this.gdk_scale;
+            toolbox = new Gtk.Box(toolbox_orientation, 0);
+            toolbox.get_style_context().add_class("toolbox");
+            toolbox.halign = Gtk.Align.START;
+            toolbox.valign = Gtk.Align.START;
+
+            toolbox.set_child_visible(Options.toolbox_shown);
+
+            /* Toolbox handle consisting of an image + eventbox */
+            var himage = this.load_icon("move.svg", 30);
+            himage.show();
+
+            var heventbox = new Gtk.EventBox();
+            heventbox.button_press_event.connect(on_button_press);
+            heventbox.motion_notify_event.connect(on_move_pointer);
+            heventbox.add(himage);
+            heventbox.set_events(
+                  Gdk.EventMask.BUTTON_PRESS_MASK |
+                  Gdk.EventMask.BUTTON1_MOTION_MASK
+            );
+            if (tbox_inverse) {
+                this.toolbox.pack_end(heventbox);
+            } else {
+                this.toolbox.pack_start(heventbox);
+            }
+
+            Gtk.Button tb;
+            tb = add_toolbox_button(this.toolbox, tbox_inverse, "settings.svg");
+
+            /* Toolbox panel that contains the buttons */
+            var button_panel = new Gtk.Box(toolbox_orientation, 0);
+            button_panel.set_spacing(0);
+            button_panel.set_homogeneous(true);
+
+            if (Options.toolbox_minimized) {
+                button_panel.set_child_visible(false);
+            }
+            if (tbox_inverse) {
+                this.toolbox.pack_end(button_panel);
+            } else {
+                this.toolbox.pack_start(button_panel);
+            }
+
+            tb.clicked.connect(() => {
+                    var state = button_panel.get_child_visible();
+                    button_panel.set_child_visible(!state);
+		});
+
+            tb = add_toolbox_button(button_panel, tbox_inverse, "highlight.svg");
+            tb.clicked.connect(() => {
+		    this.presentation_controller.toggle_pointers();
+		});
+            tb = add_toolbox_button(button_panel, tbox_inverse, "pen.svg");
+            tb.clicked.connect(() => {
+		    this.presentation_controller.toggle_pen_drawing();
+		});
+            tb = add_toolbox_button(button_panel, tbox_inverse, "eraser.svg");
+            tb.clicked.connect(() => {
+		    this.presentation_controller.toggle_eraser();
+		});
+            tb = add_toolbox_button(button_panel, tbox_inverse, "snow.svg");
+            tb.clicked.connect(() => {
+		    this.presentation_controller.toggle_freeze();
+		});
+            tb = add_toolbox_button(button_panel, tbox_inverse, "blank.svg");
+            tb.clicked.connect(() => {
+		    this.presentation_controller.fade_to_black();
+		});
+            tb = add_toolbox_button(button_panel, tbox_inverse, "hidden.svg");
+            tb.clicked.connect(() => {
+		    this.presentation_controller.hide_presentation();
+		});
+            tb = add_toolbox_button(button_panel, tbox_inverse, "pause.svg");
+            tb.clicked.connect(() => {
+		    this.presentation_controller.toggle_pause();
+		});
+
+            scale_button = add_toolbox_sbutton(button_panel, tbox_inverse,
+                "linewidth.svg");
+            scale_button.set_child_visible(false);
+            scale_button.value_changed.connect((val) => {
+                this.presentation_controller.set_pen_size(val);
+            });
+
+            color_button = add_toolbox_cbutton(button_panel, tbox_inverse);
+            color_button.set_child_visible(false);
+            color_button.color_set.connect(() => {
+                    var rgba = color_button.rgba;
+                    this.presentation_controller.pen_drawing.pen.set_rgba(rgba);
+                    this.presentation_controller.queue_pen_surface_draws();
+		});
+
+            this.toolbox_container = new Gtk.Fixed();
+            this.toolbox_container.put(toolbox, tbox_x, tbox_y);
+
+            full_overlay.add_overlay(this.toolbox_container);
+            full_overlay.set_overlay_pass_through(this.toolbox_container, true);
+
+            this.add(full_overlay);
         }
 
         public override void show() {
@@ -482,6 +744,20 @@ namespace pdfpc.Window {
             this.slide_progress.set_text("%d/%u".printf(current, total));
         }
 
+        protected void update_toolbox() {
+            toolbox.set_child_visible(Options.toolbox_shown);
+
+            var controller = this.presentation_controller;
+
+            var rgba = controller.pen_drawing.pen.get_rgba();
+            color_button.set_rgba(rgba);
+            color_button.set_child_visible(controller.is_pen_active());
+
+            scale_button.set_value(controller.get_pen_size());
+            scale_button.set_child_visible(controller.is_pen_active() ||
+                controller.is_eraser_active());
+        }
+
         public void update() {
             int current_slide_number = this.presentation_controller.current_slide_number;
             int current_user_slide_number = this.presentation_controller.current_user_slide_number;
@@ -547,6 +823,8 @@ namespace pdfpc.Window {
             this.saved_icon.hide();
             this.loaded_icon.hide();
             this.locked_icon.hide();
+
+            this.update_toolbox();
         }
 
         /**
@@ -683,34 +961,43 @@ namespace pdfpc.Window {
          * Increase font sizes for Widgets
          */
         public void increase_font_size() {
-            Pango.FontDescription font_desc = get_notes_font_description();
-
-            int font_size = font_desc.get_size() / Pango.SCALE;
+            int font_size = get_font_size();
             font_size += 2;
-            font_desc.set_size(font_size * Pango.SCALE);
             this.metadata.font_size = font_size;
-            this.notes_view.override_font(font_desc);
+            set_font_size(font_size);
         }
 
         /**
          * Decrease font sizes for Widgets
          */
         public void decrease_font_size() {
-            Pango.FontDescription font_desc = get_notes_font_description();
-
-            int font_size = font_desc.get_size() / Pango.SCALE;
-            font_size = (int)GLib.Math.fmax(font_size - 2, 0);
-            font_desc.set_size(font_size * Pango.SCALE);
+            int font_size = get_font_size();
+            font_size -= 2;
+            if (font_size < 2) {
+                font_size = 2;
+            }
             this.metadata.font_size = font_size;
-            this.notes_view.override_font(font_desc);
+            set_font_size(font_size);
         }
 
-        private Pango.FontDescription get_notes_font_description() {
+        private int get_font_size() {
             Gtk.StyleContext style_context = this.notes_view.get_style_context();
             Pango.FontDescription font_desc;
             style_context.get(style_context.get_state(), "font", out font_desc, null);
 
-            return font_desc;
+            return font_desc.get_size()/Pango.SCALE;
+        }
+
+        private void set_font_size(int size) {
+
+            const string text_css_template = "#notesView { font-size: %dpt; }";
+            var css = text_css_template.printf(size);
+
+            try {
+                css_provider.load_from_data(css, -1);
+            } catch (Error e) {
+                GLib.printerr("Warning: failed to set CSS for notes.\n");
+            }
         }
     }
 }
--- pdf-presenter-console-4.1.2.orig/src/pdfpc.vala
+++ pdf-presenter-console-4.1.2/src/pdfpc.vala
@@ -194,6 +194,13 @@ namespace pdfpc {
                 GLib.printerr("--notes option detected. Disable auto grouping.\n");
             }
 
+            // if pdfpc runs at a tablet we force the toolbox to be shown
+            var seat = Gdk.Display.get_default().get_default_seat();
+            var touchSeats = seat.get_slaves(Gdk.SeatCapabilities.TOUCH);
+            if (touchSeats.length() > 0) {
+                Options.toolbox_shown = true;
+            }
+
             ConfigFileReader configFileReader = new ConfigFileReader();
             configFileReader.readConfig(Path.build_filename(Paths.SOURCE_PATH, "rc/pdfpcrc"));
             configFileReader.readConfig(Path.build_filename(Paths.CONF_PATH, "pdfpcrc"));
@@ -216,9 +223,9 @@ namespace pdfpc {
                 string[] actions = PresentationController.getActionDescriptions();
                 for (int i = 0; i < actions.length; i+=2) {
                     string tabAlignment = "\t";
-                    if (actions[i].length < 8)
+                    if (actions[i].length < 12)
                         tabAlignment += "\t";
-                    GLib.print("\t%s%s=> %s\n", actions[i], tabAlignment, actions[i+1]);
+                    GLib.print("    %s%s=> %s\n", actions[i], tabAlignment, actions[i+1]);
                 }
 
                 return;
@@ -275,14 +282,12 @@ namespace pdfpc {
 
             var screen = Gdk.Screen.get_default();
             if (!Options.windowed && !Options.single_screen && screen.get_n_monitors() > 1) {
-                int presenter_monitor, presentation_monitor;
-                if (Options.display_switch != true) {
-                    presenter_monitor = screen.get_primary_monitor();
-                } else {
-                    presenter_monitor = (screen.get_primary_monitor() + 1) % 2;
+                int presenter_monitor = screen.get_primary_monitor();
+                if (Options.display_switch) {
+                    presenter_monitor = (presenter_monitor + 1) % 2;
                 }
 
-                presentation_monitor = (presenter_monitor + 1) % 2;
+                int presentation_monitor = (presenter_monitor + 1) % 2;
                 this.controller.presenter = this.create_presenter(metadata, presenter_monitor);
                 this.controller.presentation = this.create_presentation(metadata, presentation_monitor, width, height);
             } else if (Options.windowed && !Options.single_screen) {
