This is an autogenerated patch header for a single-debian-patch file. The
delta against upstream is either kept as a single patch, or maintained
in some VCS, and exported as a single patch instead of more manageable
atomic patches.

--- gromit-mpx-1.4.orig/CMakeLists.txt
+++ gromit-mpx-1.4/CMakeLists.txt
@@ -4,6 +4,7 @@ include(GNUInstallDirs)
 
 set(target_name gromit-mpx)
 set(version 1.4)
+set(LOCALE_DOMAIN ${CMAKE_PROJECT_NAME})
 set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
 if(CMAKE_GENERATOR MATCHES "Unix Makefiles|Ninja")
 # some LSP servers expect compile_commands.json in the project root
@@ -17,14 +18,19 @@ endif(CMAKE_GENERATOR MATCHES "Unix Make
 
 set(CMAKE_C_FLAGS  " ${CMAKE_C_FLAGS} -Wall -Wextra -Wno-unused-parameter")
 
-configure_file(build-config.h_cmake_in build-config.h)
-
 find_package(PkgConfig)
+find_package(Gettext)
 
 pkg_check_modules(gtk3 REQUIRED "gtk+-3.0 >= 3.22")
-pkg_check_modules(appindicator3 REQUIRED "appindicator3-0.1 >= 0.4.92")
 pkg_check_modules(xinput REQUIRED "xi >= 1.3")
 pkg_check_modules(x11 REQUIRED x11)
+pkg_check_modules(appindicator3 "ayatana-appindicator3-0.1 >= 0.5")
+if(NOT appindicator3_FOUND)
+  pkg_check_modules(appindicator3 REQUIRED "appindicator3-0.1 >= 0.4.92")
+  set(APPINDICATOR_IS_LEGACY 1)
+endif()
+
+configure_file(build-config.h_cmake_in build-config.h)
 
 include_directories(
     ${CMAKE_CURRENT_BINARY_DIR}
@@ -46,8 +52,10 @@ set(sources
     src/callbacks.h
     src/config.c
     src/config.h
-    src/gromit-mpx.c
-    src/gromit-mpx.h
+    src/drawing.c
+    src/drawing.h
+    src/main.c
+    src/main.h
     src/input.c
     src/input.h
     src/paint_cursor.xpm
@@ -65,14 +73,22 @@ target_link_libraries(${target_name}
 )
 
 
+GETTEXT_PROCESS_PO_FILES(de ALL PO_FILES po/de.po)
+GETTEXT_PROCESS_PO_FILES(es ALL PO_FILES po/es.po)
+GETTEXT_PROCESS_PO_FILES(it ALL PO_FILES po/it.po)
+
+
 install(TARGETS ${target_name} RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
 install(FILES data/net.christianbeier.Gromit-MPX.desktop DESTINATION ${CMAKE_INSTALL_DATADIR}/applications)
 install(FILES data/gromit-mpx.cfg DESTINATION ${CMAKE_INSTALL_SYSCONFDIR}/gromit-mpx)
 install(FILES README.md AUTHORS ChangeLog NEWS.md DESTINATION ${CMAKE_INSTALL_DOCDIR})
 install(FILES gromit-mpx.1 DESTINATION ${CMAKE_INSTALL_MANDIR}/man1)
-install(FILES data/gromit-mpx.png data/gromit-mpx_active.png data/gromit-mpx.xpm DESTINATION ${CMAKE_INSTALL_DATADIR}/pixmaps)
-install(FILES data/net.christianbeier.Gromit-MPX.svg data/gromit-mpx.svg data/gromit-mpx_active.svg DESTINATION ${CMAKE_INSTALL_DATADIR}/icons/hicolor/scalable/apps)
+install(FILES data/net.christianbeier.Gromit-MPX.png data/net.christianbeier.Gromit-MPX.active.png DESTINATION ${CMAKE_INSTALL_DATADIR}/pixmaps)
+install(FILES data/net.christianbeier.Gromit-MPX.svg data/net.christianbeier.Gromit-MPX.active.svg DESTINATION ${CMAKE_INSTALL_DATADIR}/icons/hicolor/scalable/apps)
 install(FILES data/net.christianbeier.Gromit-MPX.appdata.xml DESTINATION ${CMAKE_INSTALL_DATADIR}/metainfo)
+install(FILES ${CMAKE_CURRENT_BINARY_DIR}/de.gmo DESTINATION ${CMAKE_INSTALL_DATADIR}/locale/de/LC_MESSAGES/ RENAME ${LOCALE_DOMAIN}.mo)
+install(FILES ${CMAKE_CURRENT_BINARY_DIR}/es.gmo DESTINATION ${CMAKE_INSTALL_DATADIR}/locale/es/LC_MESSAGES/ RENAME ${LOCALE_DOMAIN}.mo)
+install(FILES ${CMAKE_CURRENT_BINARY_DIR}/it.gmo DESTINATION ${CMAKE_INSTALL_DATADIR}/locale/it/LC_MESSAGES/ RENAME ${LOCALE_DOMAIN}.mo)
 
 configure_file(
     "${CMAKE_CURRENT_SOURCE_DIR}/cmake_uninstall.cmake.in"
--- /dev/null
+++ gromit-mpx-1.4/CONTRIBUTING.md
@@ -0,0 +1,5 @@
+# Pull Requests
+* DON't submit one huge commit with all changes, DO try to make commits as atomic as possible.
+* DO prefix commits messages with subsystem touched, for example "config: added new key".
+* DON'T end commit messages with a period.
+* DO formulate commit messages so they complete the sentence "When applied, this commit will ...".
--- gromit-mpx-1.4.orig/README.md
+++ gromit-mpx-1.4/README.md
@@ -6,6 +6,8 @@
 [![Donate](https://img.shields.io/badge/paypal-donate-yellow.png)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=N7GSSPRPUSTPU&source=url)
 [![Gitter](https://badges.gitter.im/gromit-mpx/community.svg)](https://gitter.im/gromit-mpx/community?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge)
 
+[<img src="https://flathub.org/assets/badges/flathub-badge-i-en.png" width="190px" />](https://flathub.org/apps/details/net.christianbeier.Gromit-MPX)
+
 Gromit-MPX is an on-screen annotation tool that works with any Unix
 desktop environment under X11 as well as Wayland.
 
@@ -14,10 +16,12 @@ Normally, you would have to move the mou
 interest until hopefully everybody noticed it.  With Gromit-MPX, you
 can draw everywhere onto the screen, highlighting some button or area.
 
+<img src="https://github.com/bk138/gromit-mpx/blob/master/data/on-gnome-wayland.png" width="75%" />
+
 Key features include:
 
   * **Desktop-independent**. Gromit-MPX works with GNOME, KDE, XFCE, ...
-	under X11 as well as with a Wayland session.
+	under X11 as well as with a Wayland session using XWayland.
   * **Hotkey-based**. The fundamental philosophy is that Gromit-MPX does not
     get into your way of doing things by sticking some UI widget on your
 	desktop, potentially obscuring more important contents. It *does*
@@ -67,7 +71,10 @@ grabbing a key.
 
 You can specify the opacity simply via:
 
-    gromit-mpx -o <opacity>
+    gromit-mpx -o <opacity as real value in [0,1]>
+
+As opacity is not a tool but a canvas property, it is not configured via
+`gromit-mpx.cfg` but remembered over restarts.
 
 Alternatively you can invoke Gromit-MPX with various arguments to
 control an already running Gromit-MPX .
@@ -124,10 +131,11 @@ MPX setup.
 ### Configuration
 
 Gromit-MPX is configurable via the file `gromit-mpx.cfg` in the
-directory defined by `$XDG_CONFIG_HOME` (usually `~/.config`).  Here
-you can specify which Device/Button/Modifier combination invokes which
-tool.  See the copy of `gromit-mpx.cfg` distributed with this program
-for an example.  An overview on the syntax:
+directory defined by `$XDG_CONFIG_HOME` (usually `~/.config` or
+`~/.var/app/net.christianbeier.Gromit-MPX/config/` if you installed
+the Flatpak). Here you can specify which Device/Button/Modifier
+combination invokes which tool. See the copy of `gromit-mpx.cfg`
+distributed with this program for an example. An overview on the syntax:
 
     # Comments can be either # Shell-Style or
     /* C-Style. */
@@ -149,6 +157,15 @@ like this:
 
 	"red Marker" = "red Pen" (minsize=14);
 
+You can set a maximum size as well:
+
+	"red Marker" = "red Pen" (maxsize=20);
+
+Both `minsize` and `maxsize` can be combined to define a tool that's
+not allowed to change size:
+
+	"red fixed Marker" = "red Pen" (minsize=10 maxsize=10);
+
 You can also draw lines that end in an arrow head. For this you
 have to specify `arrowsize`. This is a factor relative to the width
 of the line. For reasonable arrowheads start with 1.
@@ -219,8 +236,10 @@ Type=Application
 Exec=gromit-mpx
 ```
 
-You can freely add command line arguments to the 'Exec' stanza, configuring
-the autostarted instance to your needs.
+If you have the Flatpak installed, the last line needs to start with
+`Exec=flatpak run net.christianbeier.Gromit-MPX`. You can freely add
+command line arguments to the 'Exec' stanza, configuring the autostarted
+instance to your needs.
 
 ## Building it
 
@@ -238,7 +257,11 @@ from the root of the source tree.
 XFCE per default grabs Ctrl-F1 to Ctrl-F12 (switch to workspace 1-12)
 and Alt-F9 (minimize window) which renders Gromit-MPX's default hotkey
 mapping unusable. Gromit-MPX detects XFCE and changes the default hotkeys
-to Home and End. Those can can still be overridden by the user.
+to Home and End. Those can can still be overridden by the user. In case
+you're using XFCE 4.14 or newer, chances are that all 'special' keys are
+grabbed by XFCE itself, which means you'll have to modify XFCE's keybindings
+(Settings->Window Manager->Keyboard) manually in order to 'make room' for
+Gromit-MPX's ones.
 
 When there is no [compositing manager](https://en.wikipedia.org/wiki/Compositing_window_manager)
 such as Mutter or KWin running, Gromit-MPX falls back to a legacy drawing mode. This may
@@ -248,6 +271,10 @@ quite expensive if you paint a complex p
 terminal-programs tend to scroll incredibly slow if something is
 painted over their window.
 
+If Gromit-MPX under Wayland complains about "cannot open display", make
+sure you have XWayland runnning or its autostart configured. Gromit-MPX
+needs XWayland when running in a Wayland session.
+
 ## Similar Tools
 
 In the Unix-world, similar but different tools are *Ardesia*, *Pylote*
--- gromit-mpx-1.4.orig/build-config.h_cmake_in
+++ gromit-mpx-1.4/build-config.h_cmake_in
@@ -1,33 +1,24 @@
 #ifndef BUILD_CONFIG_H
 #define BUILD_CONFIG_H
 
-/* Name of package */
-#define PACKAGE "gromit-mpx"
-
-/* Define to the address where bug reports for this package should be sent. */
-#define PACKAGE_BUGREPORT "Christian Beier <dontmind@freeshell.org>"
-
 /* Define to the full name of this package. */
 #define PACKAGE_NAME "gromit-mpx"
 
-/* Define to the full name and version of this package. */
-#define PACKAGE_STRING "gromit-mpx ${version}"
-
-/* Define to the one symbol short name of this package. */
-#define PACKAGE_TARNAME "gromit-mpx"
-
 /* Define to the home page for this package. */
 #define PACKAGE_URL "https://github.com/bk138/gromit-mpx"
 
 /* Define to the version of this package. */
 #define PACKAGE_VERSION "${version}"
 
-/* Define to 1 if you have the ANSI C header files. */
-#define STDC_HEADERS 1
+/* The package's locale domain. */
+#define PACKAGE_LOCALE_DOMAIN "${LOCALE_DOMAIN}"
 
-/* Version number of package */
-#define VERSION "${version}"
+/* The directory where the package's translations reside. */
+#define PACKAGE_LOCALE_DIR "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_DATADIR}/locale"
 
 #define SYSCONFDIR "${CMAKE_INSTALL_FULL_SYSCONFDIR}"
 
+/* This is defined when libappindicator is not libayatana-libappindicator. */
+#cmakedefine APPINDICATOR_IS_LEGACY 1
+
 #endif /* BUILD_CONFIG_H */
--- /dev/null
+++ gromit-mpx-1.4/data/net.christianbeier.Gromit-MPX.active.svg
@@ -0,0 +1,93 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   version="1.1"
+   id="svg2816"
+   height="33"
+   width="33"
+   inkscape:version="0.92.4 (5da689c313, 2019-01-14)"
+   sodipodi:docname="gromit-mpx_active.svg">
+  <sodipodi:namedview
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1"
+     objecttolerance="10"
+     gridtolerance="10"
+     guidetolerance="10"
+     inkscape:pageopacity="0"
+     inkscape:pageshadow="2"
+     inkscape:window-width="1920"
+     inkscape:window-height="1017"
+     id="namedview15"
+     showgrid="false"
+     inkscape:zoom="14.75"
+     inkscape:cx="5.0068641"
+     inkscape:cy="8.0567076"
+     inkscape:window-x="0"
+     inkscape:window-y="27"
+     inkscape:window-maximized="1"
+     inkscape:current-layer="svg2816" />
+  <defs
+     id="defs2818" />
+  <metadata
+     id="metadata2821">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title></dc:title>
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     style="fill:#ff0000;fill-opacity:1;stroke:#000000;stroke-width:32;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+     id="g2851"
+     transform="matrix(0.03125,0,0,-0.03125,-80.149238,140.26418)">
+    <path
+       d="m 2977.99,3741.2909 c -21.75,9.32 -27.96,42.26 -0.93,70.53 27.03,28.28 87.31,51.89 152.87,81.41 65.57,29.52 136.41,64.94 183.33,63.39 46.92,-1.56 87.4643,-45.9314 91.5043,-103.1114 4.04,-57.17 -8.9295,-132.98 -24.1495,-187.05 -15.23,-54.07 -17.1067,-80.5286 -37.9267,-90.1586 -20.82,-9.63 -58.6229,-14.1343 -57.3829,36.8157 1.24,50.96 22.0281,153.4833 28.8681,197.6033 6.84,44.12 -21.7333,47.401 -45.0333,40.881 -23.31,-6.53 -55,-18.96 -88.87,-35.12 -33.87,-16.15 -69.91,-36.04 -106.58,-53.13 -36.66,-17.09 -73.95,-31.38 -95.7,-22.06"
+       style="fill:#ff0000;fill-opacity:1;stroke:#000000;stroke-width:32;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+       id="path2855"
+       inkscape:connector-curvature="0" />
+    <path
+       d="m 3071.77,4272.08 c -72.7,-59.34 -136.71,-134.54 -183.94,-206.31 -47.23,-71.78 -77.68,-140.14 -95.71,-201.66 -18.01,-61.52 -23.61,-116.21 -12.42,-169.97 11.18,-53.75 39.15,-106.57 87.62,-125.53 48.47,-18.95 117.45,-4.04 175.25,18.03 57.79,22.06 104.4,51.27 136.09,98.49 31.7,47.23 48.47,112.48 69.6,138.58 21.13,26.11 46.61,13.06 50.34,-26.72 3.73,-39.77 -14.3,-106.26 -41.95,-156.29 -27.65,-50.02 -64.94,-83.58 -114.96,-111.86 -50.03,-28.27 -112.8,-51.27 -175.87,-60.9 -63.08,-9.63 -126.46,-5.9 -175.87,19.27 -49.4,25.17 -84.83,71.77 -101.91,142.93 -17.09,71.15 -15.85,166.85 5.59,258.2 21.44,91.36 63.07,178.36 132.67,266.91 69.61,88.56 167.17,178.67 251.07,231.8 83.89,53.13 154.11,69.29 209.73,71.47 55.62,2.17 96.64,-9.64 128.64,-27.97 32.01,-18.33 55,-43.19 59.66,-64.94 4.66,-21.75 -9.01,-40.39 -40.08,-31.07 -31.08,9.32 -79.55,46.61 -144.49,43.5 -64.94,-3.11 -146.35,-46.61 -219.06,-105.96"
+       style="fill:#ff0000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:32;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+       id="path2857"
+       inkscape:connector-curvature="0" />
+    <path
+       d="m 3071.77,4272.08 c -72.7,-59.34 -148.4129,-134.54 -195.6429,-206.31 -47.23,-71.78 -75.7295,-134.2886 -93.7595,-195.8086 -18.01,-61.52 -19.709,-127.9128 -8.519,-181.6728 11.18,-53.75 37.1995,-110.471 85.6695,-129.431 48.47,-18.95 129.1529,-2.0895 186.9529,19.9805 57.79,22.06 100.499,59.0719 132.189,106.2919 31.7,47.23 30.9157,108.579 52.0457,134.679 21.13,26.11 64.1643,16.961 67.8943,-22.819 3.73,-39.77 -14.3,-106.26 -41.95,-156.29 -27.65,-50.02 -64.94,-83.58 -114.96,-111.86 -50.03,-28.27 -112.8,-51.27 -175.87,-60.9 -63.08,-9.63 -114.7571,-9.801 -164.1671,15.369 -49.4,25.17 -98.4834,89.3243 -115.5634,160.4843 -17.09,71.15 -19.7509,145.3948 1.6891,236.7448 21.44,91.36 68.9214,186.1619 138.5214,274.7119 69.61,88.56 167.17,178.67 251.07,231.8 83.89,53.13 154.11,69.29 209.73,71.47 55.62,2.17 96.64,-9.64 128.64,-27.97 32.01,-18.33 61.896,-44.5692 66.556,-66.3192 4.66,-21.75 -20.0436,-54.1819 -51.1136,-44.8619 -31.08,9.32 -74.0332,56.2643 -138.9732,53.1543 -64.94,-3.11 -147.7292,-41.0932 -220.4392,-100.4432"
+       style="fill:#ff0000;fill-opacity:1;stroke:#000000;stroke-width:32;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+       id="path2859"
+       inkscape:connector-curvature="0" />
+  </g>
+  <text
+     xml:space="preserve"
+     style="font-style:italic;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:10px;line-height:0%;font-family:Rufscript;-inkscape-font-specification:'Rufscript Italic';letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none"
+     x="5.3012805"
+     y="24.940329"
+     id="text2990"><tspan
+       id="tspan2992" /></text>
+  <text
+     xml:space="preserve"
+     style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:12px;line-height:0%;font-family:'Droid Sans';-inkscape-font-specification:'Droid Sans Bold';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#00ff00;fill-opacity:1;stroke:#000000;stroke-width:0.25429109;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+     x="7.5139546"
+     y="32.150459"
+     id="text2994"><tspan
+       id="tspan2996"
+       x="7.5139546"
+       y="32.150459"
+       style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:10px;line-height:125%;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Bold';text-align:start;writing-mode:lr-tb;text-anchor:start;stroke-width:0.25429109">MPX</tspan></text>
+  <circle
+     style="fill:#ff0000;fill-opacity:1;stroke-width:1.21212125"
+     id="path841"
+     cx="22.033899"
+     cy="10.694916"
+     r="4.0677967" />
+</svg>
--- gromit-mpx-1.4.orig/data/net.christianbeier.Gromit-MPX.appdata.xml
+++ gromit-mpx-1.4/data/net.christianbeier.Gromit-MPX.appdata.xml
@@ -8,7 +8,10 @@
   
   <metadata_license>CC-BY-4.0</metadata_license>
   <project_license>GPL-2.0-only</project_license>
-  
+
+  <content_rating type="oars-1.0">
+  </content_rating>
+
   <url type="homepage">https://github.com/bk138/gromit-mpx</url>
 
   <developer_name>Christian Beier</developer_name>
--- /dev/null
+++ gromit-mpx-1.4/flatpak/README.md
@@ -0,0 +1,6 @@
+This the in-development version of Gromit-MPX's flatpak packaging. The release version can be found at
+in [this repository](https://github.com/flathub/net.christianbeier.Gromit-MPX).
+
+Build and install a local flatpak via `flatpak-builder --force-clean --user --install build-dir net.christianbeier.Gromit-MPX.yml`.
+
+Run the local flatpak via `flatpak run net.christianbeier.Gromit-MPX`.
--- /dev/null
+++ gromit-mpx-1.4/flatpak/dconf-override.patch
@@ -0,0 +1,23 @@
+diff --git a/engine/dconf-engine-source-user.c b/engine/dconf-engine-source-user.c
+index 1657875..e4f8786 100644
+--- a/engine/dconf-engine-source-user.c
++++ b/engine/dconf-engine-source-user.c
+@@ -39,11 +39,17 @@ dconf_engine_source_user_open_gvdb (const gchar *name)
+ {
+   GvdbTable *table;
+   gchar *filename;
++  const gchar *override;
++
++  override = g_getenv ("DCONF_USER_CONFIG_DIR");
++  if (override == NULL)
++    filename = g_build_filename (g_get_user_config_dir (), "dconf", name, NULL);
++  else
++    filename = g_build_filename (g_get_home_dir (), override, name, NULL);
+ 
+   /* This can fail in the normal case of the user not having any
+    * settings.  That's OK and it shouldn't be considered as an error.
+    */
+-  filename = g_build_filename (g_get_user_config_dir (), "dconf", name, NULL);
+   table = gvdb_table_new (filename, FALSE, NULL);
+   g_free (filename);
+ 
--- gromit-mpx-1.4.orig/flatpak/net.christianbeier.Gromit-MPX.yml
+++ gromit-mpx-1.4/flatpak/net.christianbeier.Gromit-MPX.yml
@@ -1,15 +1,18 @@
 id: net.christianbeier.Gromit-MPX
 runtime: org.gnome.Platform # using GNOME for the time being as we need dconf for setting hotkeys under Wayland
-runtime-version: '3.36'
+runtime-version: '3.38'
 sdk: org.gnome.Sdk
 command: gromit-mpx
 finish-args:
   - --socket=x11
+  # needed to show appindicator in Ubuntu
+  - --talk-name=org.kde.StatusNotifierWatcher
   # this is the dconf hole for setting hotkeys under Wayland
   - --filesystem=xdg-run/dconf
   - --filesystem=~/.config/dconf:ro
   - --talk-name=ca.desrt.dconf
   - --env=DCONF_USER_CONFIG_DIR=.config/dconf
+  - --env=GIO_EXTRA_MODULES=/app/lib/gio/modules/
 modules:
   - shared-modules/libappindicator/libappindicator-gtk3-12.10.json
   # ship media-keys schema for settings hotkeys under Wayland
@@ -21,8 +24,24 @@ modules:
       - glib-compile-schemas /app/share/glib-2.0/schemas
     sources:
       - type: archive
-        url: https://github.com/GNOME/gnome-settings-daemon/archive/GNOME_SETTINGS_DAEMON_3_36_1.tar.gz
-        sha256: e345411f79b4a1175349e144cc772c7a9eb7ab9ae3a542a73609bee471b72748
+        url: https://github.com/GNOME/gnome-settings-daemon/archive/GNOME_SETTINGS_DAEMON_3_38_1.tar.gz
+        sha256: 736a961ccdb314b9a157e29710743563dc67652ebc3ca69c0f37df2776863523
+  - name: dconf
+    buildsystem: meson
+    config-opts:
+      - -Dbash_completion=false
+      - -Dman=false
+    cleanup:
+      - /include
+      - /lib/pkgconfig
+      - /libexec
+      - /share/dbus-1
+    sources:
+      - type: archive
+        url: https://download.gnome.org/sources/dconf/0.38/dconf-0.38.0.tar.xz
+        sha256: 45f60f41330d27715cce1315af123f94f1c2cdedb68b6bed3b309866eec44f58
+      - type: patch
+        path: dconf-override.patch
   - name: gromit-mpx
     buildsystem: cmake
     sources:
--- /dev/null
+++ gromit-mpx-1.4/po/README.md
@@ -0,0 +1,5 @@
+# Add or Update Translation
+
+1. Run `./mkpot.sh` from this directory which will create a `gromit-mpx.pot` translation template file.
+2. Use poedit or a similar tool to create or update a translation, save the resulting .po file in this directory.
+3. Adjust CMakeLists.txt to build and install the corresponding .mo file.
--- /dev/null
+++ gromit-mpx-1.4/po/de.po
@@ -0,0 +1,209 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the Gromit-MPX package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Gromit-MPX\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2021-02-05 11:36+0100\n"
+"PO-Revision-Date: 2021-02-05 11:39+0100\n"
+"Last-Translator: Christian Beier <info@christianbeier.net>\n"
+"Language-Team: \n"
+"Language: de\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Generator: Poedit 2.2.1\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+#: ../src/callbacks.c:647
+msgid "About Gromit-MPX"
+msgstr "Über Gromit-MPX"
+
+#: ../src/gromit-mpx.c:977
+msgid "Bigger Opacity"
+msgstr "Höhere Deckkraft"
+
+#: ../src/gromit-mpx.c:971
+#, c-format
+msgid "Clear Screen (SHIFT-%s)"
+msgstr "Annotationen löschen (SHIFT-%s)"
+
+#: ../src/callbacks.c:713
+msgid ""
+"Do you want to show this introduction again on the next start of Gromit-"
+"MPX?\n"
+"You can always access it again via the sys tray menu.\n"
+msgstr ""
+"Möchten Sie diese Einleitung beim nächsten Start von Gromit-MPX wieder "
+"anzeigen?\n"
+"Sie können sie jederzeit wieder über das Tray-Menü aufrufen.\n"
+
+#: ../src/config.c:471
+#, c-format
+msgid "Failed parsing config file %s, falling back to default tools."
+msgstr ""
+"Das Parsen der Konfigurationsdatei %s ist fehlgeschlagen, es wird auf die "
+"Standardwerkzeuge zurückgegriffen."
+
+#: ../src/callbacks.c:648
+msgid ""
+"Gromit-MPX (GRaphics Over MIscellaneous Things - Multi-Pointer-EXtension) is "
+"an on-screen annotation tool that works with any Unix desktop environment "
+"under X11 as well as Wayland."
+msgstr ""
+"Gromit-MPX (GRaphics Over MIscellaneous Things - Multi-Pointer-EXtension) "
+"ist ein Bildschirmannotationstool, das mit jeder Unix-Desktopumgebung unter "
+"X11 sowie Wayland funktioniert."
+
+#: ../src/callbacks.c:673
+msgid ""
+"Gromit-MPX (GRaphics Over MIscellaneous Things) is a small tool to make\n"
+"annotations on the screen.\n"
+"\n"
+"Its main use is for making presentations of some application. Normally,\n"
+"you would have to move the mouse pointer around the point of interest\n"
+"until hopefully everybody noticed it.  With Gromit-MPX, you can draw\n"
+"everywhere onto the screen, highlighting some button or area.\n"
+"\n"
+"If you happen to enjoy using Gromit-MPX, please consider supporting\n"
+"its development by using one of the donation options on the project's\n"
+"website or directly via the support options available from the tray menu.\n"
+msgstr ""
+"Gromit-MPX (GRaphics Over MIscellaneous Things) ist ein kleines Werkzeug\n"
+"zum Erstellen von Annotationen auf dem Bildschirm.\n"
+"\n"
+"Seine Hauptanwendung ist die Erstellung von Präsentationen für eine "
+"Anwendung.\n"
+"Normalerweise müsste der Mauszeiger um einen interessanten Punkt herum "
+"bewegt\n"
+"werden, um die Aufmerksamkeit auf diesen zu lenken. Mit Gromit-MPX können "
+"Sie\n"
+"überall auf den Bildschirm zeichnen und dabei eine Schaltfläche oder einen "
+"Bereich\n"
+"hervorheben.\n"
+"\n"
+"Wenn Ihnen Gromit-MPX gefällt, ziehen Sie bitte in Betracht, seine "
+"Entwicklung zu\n"
+"unterstützen, indem Sie eine der Spendenoptionen auf der Website des "
+"Projekts\n"
+"oder direkt die im Tray-Menü verfügbaren Support-Optionen nutzen.\n"
+
+#: ../src/callbacks.c:707
+msgid "Gromit-MPX - How to use it"
+msgstr "Gromit-MPX - Wie es benutzt wird"
+
+#: ../src/callbacks.c:683
+msgid "Gromit-MPX - What is it?"
+msgstr "Gromit-MPX - Was ist es?"
+
+#: ../src/gromit-mpx.c:978
+msgid "Lesser Opacity"
+msgstr "Geringere Deckkraft"
+
+#: ../src/config.c:155
+msgid "No usable config file found, falling back to default tools."
+msgstr ""
+"Keine brauchbare Konfigurationsdatei gefunden, Rückgriff auf Standard-Tools."
+
+#: ../src/gromit-mpx.c:981
+#, c-format
+msgid "Redo (SHIFT-%s)"
+msgstr "Wiederherstellen (SHIFT-%s)"
+
+#: ../src/callbacks.c:715
+msgid "Show again on startup"
+msgstr "Beim Start erneut anzeigen"
+
+#: ../src/gromit-mpx.c:975
+msgid "Thicker Lines"
+msgstr "Dickere Linien"
+
+#: ../src/gromit-mpx.c:976
+msgid "Thinner Lines"
+msgstr "Dünnere Linien"
+
+#: ../src/gromit-mpx.c:969
+#, c-format
+msgid "Toggle Painting (%s)"
+msgstr "Annotationsmodus an/ausschalten (%s)"
+
+#: ../src/gromit-mpx.c:973
+#, c-format
+msgid "Toggle Visibility (CTRL-%s)"
+msgstr "Sichtbarkeit an/ausschalten (STRG-%s)"
+
+#: ../src/gromit-mpx.c:979
+#, c-format
+msgid "Undo (%s)"
+msgstr "Rückgängig (%s)"
+
+#: ../src/gromit-mpx.c:1083
+msgid "Via LiberaPay"
+msgstr "Über LiberaPay"
+
+#: ../src/gromit-mpx.c:1084
+msgid "Via Patreon"
+msgstr "Über Patreon"
+
+#: ../src/gromit-mpx.c:1085
+msgid "Via PayPal"
+msgstr "Über PayPal"
+
+#: ../src/callbacks.c:691
+#, c-format
+msgid ""
+"You can operate Gromit-MPX using its tray icon (if your desktop environment\n"
+"provides a sys tray), but since you typically want to use the program you "
+"are\n"
+"demonstrating and highlighting something is a short interruption of your\n"
+"workflow, Gromit-MPX can be toggled on and off on the fly via a hotkey:\n"
+"\n"
+"It grabs the `%s` and `%s` keys, so that no other application can use them\n"
+"and they are available to Gromit-MPX only.  The available commands are:\n"
+"\n"
+"<tt><b>   toggle painting:         %s\n"
+"   clear screen:            SHIFT-%s\n"
+"   toggle visibility:       CTRL-%s\n"
+"   quit:                    ALT-%s\n"
+"   undo last stroke:        %s\n"
+"   redo last undone stroke: SHIFT-%s</b></tt>"
+msgstr ""
+"Sie können Gromit-MPX über sein Tray-Symbol bedienen (falls Ihre "
+"Desktopumgebung\n"
+"einen Sys-Tray bereitstellt), aber da Sie typischerweise das Programm "
+"benutzen wollen,\n"
+"das Sie demonstrieren wollen und das Hervorheben von etwas eine kurze "
+"Unterbrechung\n"
+"Ihres Arbeitsablaufs ist, kann Gromit-MPX über einen Hotkey ein/"
+"ausgeschaltet werden:\n"
+"\n"
+"Es belegt die Tasten \"%s\" und \"%s\", so dass keine andere Anwendung sie "
+"benutzen kann\n"
+"und sie nur für Gromit-MPX verfügbar sind. Die verfügbaren Befehle sind:\n"
+"\n"
+"<tt><b>   Annotation an/auschalten:            %s\n"
+"   Annotationen löschen:                SHIFT-%s\n"
+"   Sichtbarkeit an/ausschalten:         STRG-%s\n"
+"   Beenden:                             ALT-%s\n"
+"   Letzte Annotation rückgängig machen: %s\n"
+"   Letzte Annotation wiederherstellen:  SHIFT-%s</b></tt>"
+
+#: ../src/gromit-mpx.c:987
+msgid "_About"
+msgstr "_Über"
+
+#: ../src/gromit-mpx.c:985
+msgid "_Introduction"
+msgstr "_Einführung"
+
+#: ../src/gromit-mpx.c:988
+#, c-format
+msgid "_Quit (ALT-%s)"
+msgstr "_Beenden (ALT-%s)"
+
+#: ../src/gromit-mpx.c:986
+msgid "_Support Gromit-MPX"
+msgstr "_Unterstützung für Gromit-MPX"
--- /dev/null
+++ gromit-mpx-1.4/po/es.po
@@ -0,0 +1,202 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the Gromit-MPX package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Gromit-MPX\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2021-02-05 11:36+0100\n"
+"PO-Revision-Date: 2021-02-05 11:39+0100\n"
+"Last-Translator: Christian Beier <info@christianbeier.net>\n"
+"Language-Team: \n"
+"Language: es\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Generator: Poedit 2.2.1\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+#: ../src/callbacks.c:647
+msgid "About Gromit-MPX"
+msgstr "Sobre Gromit-MPX"
+
+#: ../src/gromit-mpx.c:977
+msgid "Bigger Opacity"
+msgstr "Aumentar opacidad"
+
+#: ../src/gromit-mpx.c:971
+#, c-format
+msgid "Clear Screen (SHIFT-%s)"
+msgstr "Borrar pantalla (SHIFT-%s)"
+
+#: ../src/callbacks.c:713
+msgid ""
+"Do you want to show this introduction again on the next start of Gromit-"
+"MPX?\n"
+"You can always access it again via the sys tray menu.\n"
+msgstr ""
+"¿Quiere mostrar esta introducción de nuevo en el próximo inicio de Gromit-"
+"MPX?\n"
+"Siempre puede acceder de nuevo a través del menú de la bandeja del sistema.\n"
+
+#: ../src/config.c:471
+#, c-format
+msgid "Failed parsing config file %s, falling back to default tools."
+msgstr ""
+"Fallo al analizar el archivo de configuración %s, volviendo a las "
+"herramientas por defecto."
+
+#: ../src/callbacks.c:648
+msgid ""
+"Gromit-MPX (GRaphics Over MIscellaneous Things - Multi-Pointer-EXtension) is "
+"an on-screen annotation tool that works with any Unix desktop environment "
+"under X11 as well as Wayland."
+msgstr ""
+"Gromit-MPX (GRaphics Over MIscellaneous Things - Multi-Pointer-EXtension) es "
+"una herramienta de anotación en pantalla que funciona con cualquier entorno "
+"de escritorio Unix bajo X11 así como con Wayland."
+
+#: ../src/callbacks.c:673
+msgid ""
+"Gromit-MPX (GRaphics Over MIscellaneous Things) is a small tool to make\n"
+"annotations on the screen.\n"
+"\n"
+"Its main use is for making presentations of some application. Normally,\n"
+"you would have to move the mouse pointer around the point of interest\n"
+"until hopefully everybody noticed it.  With Gromit-MPX, you can draw\n"
+"everywhere onto the screen, highlighting some button or area.\n"
+"\n"
+"If you happen to enjoy using Gromit-MPX, please consider supporting\n"
+"its development by using one of the donation options on the project's\n"
+"website or directly via the support options available from the tray menu.\n"
+msgstr ""
+"Gromit-MPX (GRaphics Over MIscellaneous Things) es una pequeña\n"
+"herramienta para hacer anotaciones en la pantalla.\n"
+"\n"
+"Su uso principal es para realizar presentaciones de alguna aplicación.\n"
+"Normalmente, tendría que mover el puntero del mouse alrededor del\n"
+"punto de interés hasta que, con suerte, todos lo noten. Con Gromit-MPX,\n"
+"puede dibujar en cualquier lugar de la pantalla, resaltando algún botón\n"
+"o área.\n"
+"\n"
+"Si disfruta usando Gromit-MPX, considere apoyar su desarrollo usando\n"
+"una de las opciones de donación en el sitio web del proyecto o\n"
+"directamente a través de las opciones de soporte disponibles en el menú\n"
+"de la bandeja.\n"
+
+#: ../src/callbacks.c:707
+msgid "Gromit-MPX - How to use it"
+msgstr "Gromit-MPX - Cómo usarlo"
+
+#: ../src/callbacks.c:683
+msgid "Gromit-MPX - What is it?"
+msgstr "Gromit-MPX - ¿Qué es?"
+
+#: ../src/gromit-mpx.c:978
+msgid "Lesser Opacity"
+msgstr "Disminuir opacidad"
+
+#: ../src/config.c:155
+msgid "No usable config file found, falling back to default tools."
+msgstr ""
+"No se ha encontrado ningún archivo de configuración utilizable, volviendo a "
+"las herramientas por defecto."
+
+#: ../src/gromit-mpx.c:981
+#, c-format
+msgid "Redo (SHIFT-%s)"
+msgstr "Rehacer (SHIFT-%s)"
+
+#: ../src/callbacks.c:715
+msgid "Show again on startup"
+msgstr "Mostrar de nuevo al inicio"
+
+#: ../src/gromit-mpx.c:975
+msgid "Thicker Lines"
+msgstr "Líneas más gruesas"
+
+#: ../src/gromit-mpx.c:976
+msgid "Thinner Lines"
+msgstr "Líneas más finas"
+
+#: ../src/gromit-mpx.c:969
+#, c-format
+msgid "Toggle Painting (%s)"
+msgstr "Activar/desactivar anotación (%s)"
+
+#: ../src/gromit-mpx.c:973
+#, c-format
+msgid "Toggle Visibility (CTRL-%s)"
+msgstr "Activar/desactivar visibilidad (CTRL-%s)"
+
+#: ../src/gromit-mpx.c:979
+#, c-format
+msgid "Undo (%s)"
+msgstr "Deshacer (%s)"
+
+#: ../src/gromit-mpx.c:1083
+msgid "Via LiberaPay"
+msgstr "A través de LiberaPay"
+
+#: ../src/gromit-mpx.c:1084
+msgid "Via Patreon"
+msgstr "A través de Patreon"
+
+#: ../src/gromit-mpx.c:1085
+msgid "Via PayPal"
+msgstr "A través de PayPal"
+
+#: ../src/callbacks.c:691
+#, c-format
+msgid ""
+"You can operate Gromit-MPX using its tray icon (if your desktop environment\n"
+"provides a sys tray), but since you typically want to use the program you "
+"are\n"
+"demonstrating and highlighting something is a short interruption of your\n"
+"workflow, Gromit-MPX can be toggled on and off on the fly via a hotkey:\n"
+"\n"
+"It grabs the `%s` and `%s` keys, so that no other application can use them\n"
+"and they are available to Gromit-MPX only.  The available commands are:\n"
+"\n"
+"<tt><b>   toggle painting:         %s\n"
+"   clear screen:            SHIFT-%s\n"
+"   toggle visibility:       CTRL-%s\n"
+"   quit:                    ALT-%s\n"
+"   undo last stroke:        %s\n"
+"   redo last undone stroke: SHIFT-%s</b></tt>"
+msgstr ""
+"Puede operar Gromit-MPX usando su ícono de bandeja (si su entorno de\n"
+"escritorio proporciona una bandeja del sistema), pero como típicamente\n"
+"quiere usar el programa que está demostrando y resaltar algo es una corta\n"
+"interrupción de su flujo de trabajo, Gromit-MPX puede ser activado y\n"
+"desactivado al vuelo vía una tecla de acceso rápido:\n"
+"\n"
+"Toma las claves `%s` y `%s`, de modo que ninguna otra aplicación pueda\n"
+"usarlas y solo están disponibles para Gromit-MPX. Los comandos\n"
+"disponibles son:\n"
+"\n"
+"<tt><b>    Activar/desactivar anotación:   %s\n"
+"    Borrar pantalla:                SHIFT-%s\n"
+"    Activar/desactivar visibilidad: CTRL-%s\n"
+"    Salir:                          ALT-%s\n"
+"    Deshacer:                       %s\n"
+"    Rehacer:                        SHIFT-%s </b></tt>"
+
+#: ../src/gromit-mpx.c:987
+msgid "_About"
+msgstr "S_obre"
+
+#: ../src/gromit-mpx.c:985
+msgid "_Introduction"
+msgstr "_Introducción"
+
+#: ../src/gromit-mpx.c:988
+#, c-format
+msgid "_Quit (ALT-%s)"
+msgstr "_Salir (ALT-%s)"
+
+#: ../src/gromit-mpx.c:986
+msgid "_Support Gromit-MPX"
+msgstr "_Apoyar a Gromit-MPX"
--- /dev/null
+++ gromit-mpx-1.4/po/it.po
@@ -0,0 +1,197 @@
+# ITALIAN TRANSLATION FOR GROMIX-MPX.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the Gromit-MPX package.
+# ALBANO BATTISTELLA <albano_battistella@hotmail.com>, 2021.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Gromit-MPX\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2021-02-05 11:36+0100\n"
+"PO-Revision-Date: 2021-03-08 19:39+0100\n"
+"Last-Translator: albano battistella <albano_battistella@hotmail.com>\n"
+"Language-Team:it\n"
+"Language:it\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Generator: Poedit 2.2.1\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+#: ../src/callbacks.c:647
+msgid "About Gromit-MPX"
+msgstr "Informazioni su Gromit-MPX"
+
+#: ../src/gromit-mpx.c:977
+msgid "Bigger Opacity"
+msgstr "Aumenta Opacità"
+
+#: ../src/gromit-mpx.c:971
+#, c-format
+msgid "Clear Screen (SHIFT-%s)"
+msgstr "Pulisci Schermo (SHIFT-%s)"
+
+#: ../src/callbacks.c:713
+msgid ""
+"Do you want to show this introduction again on the next start of Gromit-"
+"MPX?\n"
+"You can always access it again via the sys tray menu.\n"
+msgstr ""
+"Vuoi mostrare di nuovo questa introduzione al prossimo avvio di Gromit-"
+"MPX?\n"
+"Puoi sempre accedervi di nuovo tramite il menu della barra delle applicazioni.\n"
+
+#: ../src/config.c:471
+#, c-format
+msgid "Failed parsing config file %s, falling back to default tools."
+msgstr ""
+"Analisi del file di configurazione %s non riuscita, ritorno agli strumenti predefiniti."
+
+
+#: ../src/callbacks.c:648
+msgid ""
+"Gromit-MPX (GRaphics Over MIscellaneous Things - Multi-Pointer-EXtension) is "
+"an on-screen annotation tool that works with any Unix desktop environment "
+"under X11 as well as Wayland."
+msgstr ""
+"Gromit-MPX (GRaphics Over MIscellaneous Things - Multi-Pointer-EXtension) è "
+"uno strumento di annotazione su schermo che funziona con qualsiasi ambiente desktop Unix "
+"sotto X11 così come Wayland."
+
+#: ../src/callbacks.c:673
+msgid ""
+"Gromit-MPX (GRaphics Over MIscellaneous Things) is a small tool to make\n"
+"annotations on the screen.\n"
+"\n"
+"Its main use is for making presentations of some application. Normally,\n"
+"you would have to move the mouse pointer around the point of interest\n"
+"until hopefully everybody noticed it.  With Gromit-MPX, you can draw\n"
+"everywhere onto the screen, highlighting some button or area.\n"
+"\n"
+"If you happen to enjoy using Gromit-MPX, please consider supporting\n"
+"its development by using one of the donation options on the project's\n"
+"website or directly via the support options available from the tray menu.\n"
+msgstr ""
+"Gromit-MPX (GRaphics Over MIscellaneous Things) è un piccolo strumento per creare\n"
+"annotazioni sullo schermo.\n"
+"\n"
+"Il suo utilizzo principale è per fare presentazioni di alcune applicazioni. Normalmente,\n"
+"dovresti spostare il puntatore del mouse intorno al punto di interesse\n"
+"fino a quando si spera che tutti lo notino. Con Gromit-MPX, puoi disegnare\n"
+"ovunque sullo schermo, evidenziando un pulsante o un'area.\n"
+"\n"
+"Se ti piace usare Gromit-MPX, considera di supportare\n"
+"il suo sviluppo utilizzando una delle opzioni di donazione sul sito web del progetto\n"
+"o direttamente tramite le opzioni di supporto disponibili dal menu della barra delle applicazioni.\n"
+
+#: ../src/callbacks.c:707
+msgid "Gromit-MPX - How to use it"
+msgstr "Gromit-MPX - Come usarlo"
+
+#: ../src/callbacks.c:683
+msgid "Gromit-MPX - What is it?"
+msgstr "Gromit-MPX - Che cos'è"
+
+#: ../src/gromit-mpx.c:978
+msgid "Lesser Opacity"
+msgstr "Diminuisci Opacità"
+
+#: ../src/config.c:155
+msgid "No usable config file found, falling back to default tools."
+msgstr "Nessun file di configurazione utilizzabile trovato, ritorno agli strumenti predefiniti."
+
+#: ../src/gromit-mpx.c:981
+#, c-format
+msgid "Redo (SHIFT-%s)"
+msgstr "Rifai (SHIFT-%s)"
+
+#: ../src/callbacks.c:715
+msgid "Show again on startup"
+msgstr "Mostra di nuovo all'avvio"
+
+#: ../src/gromit-mpx.c:975
+msgid "Thicker Lines"
+msgstr "Linee più spesse"
+
+#: ../src/gromit-mpx.c:976
+msgid "Thinner Lines"
+msgstr "Linee più sottili"
+
+#: ../src/gromit-mpx.c:969
+#, c-format
+msgid "Toggle Painting (%s)"
+msgstr "Attiva/disattiva pittura (%s)"
+
+#: ../src/gromit-mpx.c:973
+#, c-format
+msgid "Toggle Visibility (CTRL-%s)"
+msgstr "Attiva/disattiva visibilità (CTRL-%s)"
+
+#: ../src/gromit-mpx.c:979
+#, c-format
+msgid "Undo (%s)"
+msgstr "Annulla (%s)"
+
+#: ../src/gromit-mpx.c:1083
+msgid "Via LiberaPay"
+msgstr "Tramite LiberaPay"
+
+#: ../src/gromit-mpx.c:1084
+msgid "Via Patreon"
+msgstr "Tramite Patreon"
+
+#: ../src/gromit-mpx.c:1085
+msgid "Via PayPal"
+msgstr "Tramite PayPal"
+
+#: ../src/callbacks.c:691
+#, c-format
+msgid ""
+"You can operate Gromit-MPX using its tray icon (if your desktop environment\n"
+"provides a sys tray), but since you typically want to use the program you "
+"are\n"
+"demonstrating and highlighting something is a short interruption of your\n"
+"workflow, Gromit-MPX can be toggled on and off on the fly via a hotkey:\n"
+"\n"
+"It grabs the `%s` and `%s` keys, so that no other application can use them\n"
+"and they are available to Gromit-MPX only.  The available commands are:\n"
+"\n"
+"<tt><b>   toggle painting:         %s\n"
+"   clear screen:            SHIFT-%s\n"
+"   toggle visibility:       CTRL-%s\n"
+"   quit:                    ALT-%s\n"
+"   undo last stroke:        %s\n"
+"   redo last undone stroke: SHIFT-%s</b></tt>"
+msgstr ""
+"Puoi utilizzare Gromit-MPX utilizzando la sua icona nella barra delle applicazioni (se il tuo ambiente desktop\n"
+"fornisce una sys tray), ma dal momento che in genere si desidera utilizzare il programma "
+"per\n"
+"mostrare ed evidenziare qualcosa o una breve interruzione del tuo\n"
+"flusso di lavoro, Gromit-MPX può essere attivato e disattivato al volo tramite un tasto di scelta rapida:\n"
+"\n"
+"Afferra i tasti` %s` e` %s`in modo che nessun'altra applicazione possa usarli\n"
+"e siano disponibili solo per Gromit-MPX. I comandi disponibili sono:\n"
+"\n"
+"<tt><b>    attiva/disattiva  pittura:    %s\n"
+"    pulisci schermo:              SHIFT-%s\n"
+"    attiva/disattiva visibilità:   CTRL-%s\n"
+"    esci:                          ALT-%s\n"
+"    annulla ultima azione:         %s\n"
+"    ripeti l'ultima azione annullata: SHIFT-%s </b></tt>"
+
+#: ../src/gromit-mpx.c:987
+msgid "_About"
+msgstr "Informazioni"
+
+#: ../src/gromit-mpx.c:985
+msgid "_Introduction"
+msgstr "_Introduzione"
+
+#: ../src/gromit-mpx.c:988
+#, c-format
+msgid "_Quit (ALT-%s)"
+msgstr "_Esci (ALT-%s)"
+
+#: ../src/gromit-mpx.c:986
+msgid "_Support Gromit-MPX"
+msgstr "_Supporto a Gromit-MPX"
--- /dev/null
+++ gromit-mpx-1.4/po/mkpot.sh
@@ -0,0 +1,3 @@
+#!/bin/sh
+
+xgettext --language=C --from-code=UTF-8 --keyword=_ --keyword=N_ --keyword=C_:1c,2 --keyword=NC_:1c,2 -s --package-name=Gromit-MPX ../src/*.c -o gromit-mpx.pot
--- gromit-mpx-1.4.orig/src/callbacks.c
+++ gromit-mpx-1.4/src/callbacks.c
@@ -24,10 +24,11 @@
 #include <string.h>
 #include <stdlib.h>
 #include <stdint.h>
-#include "gromit-mpx.h"
+#include "main.h"
 #include "input.h"
 #include "callbacks.h"
 #include "config.h"
+#include "drawing.h"
 #include "build-config.h"
 
 
@@ -128,9 +129,9 @@ void on_monitors_changed ( GdkScreen *sc
 
 
   data->default_pen = paint_context_new (data, GROMIT_PEN,
-					 data->red, 7, 0, 1);
+					 data->red, 7, 0, 1, G_MAXUINT);
   data->default_eraser = paint_context_new (data, GROMIT_ERASER,
-					    data->red, 75, 0, 1);
+					    data->red, 75, 0, 1, G_MAXUINT);
 
   if(!data->composited) // set shape
     {
@@ -274,6 +275,9 @@ gboolean on_buttonpress (GtkWidget *win,
 			      devdata->cur_context->minwidth) +
 		    devdata->cur_context->minwidth);
 
+  if(data->maxwidth > devdata->cur_context->maxwidth)
+    data->maxwidth = devdata->cur_context->maxwidth;
+
   if (ev->button <= 5)
     draw_line (data, ev->device, ev->x, ev->y, ev->x, ev->y);
 
@@ -324,6 +328,9 @@ gboolean on_motion (GtkWidget *win,
 					  devdata->cur_context->minwidth) +
 				devdata->cur_context->minwidth);
 
+	      if(data->maxwidth > devdata->cur_context->maxwidth)
+		data->maxwidth = devdata->cur_context->maxwidth;
+
               gdk_device_get_axis(ev->device, coords[i]->axes,
                                   GDK_AXIS_X, &x);
               gdk_device_get_axis(ev->device, coords[i]->axes,
@@ -351,6 +358,9 @@ gboolean on_motion (GtkWidget *win,
 				  devdata->cur_context->minwidth) +
 			devdata->cur_context->minwidth);
 
+      if(data->maxwidth > devdata->cur_context->maxwidth)
+	data->maxwidth = devdata->cur_context->maxwidth;
+
       if(devdata->motion_time > 0)
 	{
 	  draw_line (data, ev->device, devdata->lastx, devdata->lasty, ev->x, ev->y);
@@ -634,11 +644,11 @@ void on_about(GtkMenuItem *menuitem,
                                  NULL };
     gtk_show_about_dialog (NULL,
 			   "program-name", "Gromit-MPX",
-			   "logo-icon-name", "gromit-mpx",
-			   "title", "About Gromit-MPX",
-			   "comments", "Gromit-MPX (GRaphics Over MIscellaneous Things - Multi-Pointer-EXtension) is an on-screen annotation tool that works with any Unix desktop environment under X11 as well as Wayland.",
-			   "version", VERSION,
-			   "website", "https://github.com/bk138/gromit-mpx",
+			   "logo-icon-name", "net.christianbeier.Gromit-MPX",
+			   "title", _("About Gromit-MPX"),
+			   "comments", _("Gromit-MPX (GRaphics Over MIscellaneous Things - Multi-Pointer-EXtension) is an on-screen annotation tool that works with any Unix desktop environment under X11 as well as Wayland."),
+			   "version", PACKAGE_VERSION,
+			   "website", PACKAGE_URL,
 			   "authors", authors,
 			   "copyright", "2009-2020 Christian Beier, Copyright 2000 Simon Budig",
 			   "license-type", GTK_LICENSE_GPL_2_0,
@@ -661,7 +671,7 @@ void on_intro(GtkMenuItem *menuitem,
     gtk_window_set_position (GTK_WINDOW(assistant), GTK_WIN_POS_CENTER);
 
     // set page one
-    GtkWidget *widgetOne = gtk_label_new ("Gromit-MPX (GRaphics Over MIscellaneous Things) is a small tool to make\n"
+    GtkWidget *widgetOne = gtk_label_new(_("Gromit-MPX (GRaphics Over MIscellaneous Things) is a small tool to make\n"
 					  "annotations on the screen.\n\n"
 					  "Its main use is for making presentations of some application. Normally,\n"
 					  "you would have to move the mouse pointer around the point of interest\n"
@@ -669,9 +679,9 @@ void on_intro(GtkMenuItem *menuitem,
 					  "everywhere onto the screen, highlighting some button or area.\n\n"
                                           "If you happen to enjoy using Gromit-MPX, please consider supporting\n"
 					  "its development by using one of the donation options on the project's\n"
-					  "website or directly via the support options available from the tray menu.\n");
+					  "website or directly via the support options available from the tray menu.\n"));
     gtk_assistant_append_page (GTK_ASSISTANT (assistant), widgetOne);
-    gtk_assistant_set_page_title (GTK_ASSISTANT (assistant), widgetOne, "Gromit-MPX - What is it?");
+    gtk_assistant_set_page_title (GTK_ASSISTANT (assistant), widgetOne, _("Gromit-MPX - What is it?"));
     gtk_assistant_set_page_type (GTK_ASSISTANT (assistant), widgetOne, GTK_ASSISTANT_PAGE_INTRO);
     gtk_assistant_set_page_complete (GTK_ASSISTANT (assistant), widgetOne, TRUE);
 
@@ -679,7 +689,7 @@ void on_intro(GtkMenuItem *menuitem,
     GtkWidget *widgetTwo = gtk_label_new (NULL);
     char widgetTwoBuf[4096];
     snprintf(widgetTwoBuf, sizeof(widgetTwoBuf),
-	     "You can operate Gromit-MPX using its tray icon (if your desktop environment\n"
+	     _("You can operate Gromit-MPX using its tray icon (if your desktop environment\n"
 	     "provides a sys tray), but since you typically want to use the program you are\n"
 	     "demonstrating and highlighting something is a short interruption of your\n"
 	     "workflow, Gromit-MPX can be toggled on and off on the fly via a hotkey:\n\n"
@@ -690,20 +700,20 @@ void on_intro(GtkMenuItem *menuitem,
 	     "   toggle visibility:       CTRL-%s\n"
 	     "   quit:                    ALT-%s\n"
 	     "   undo last stroke:        %s\n"
-	     "   redo last undone stroke: SHIFT-%s</b></tt>",
+	     "   redo last undone stroke: SHIFT-%s</b></tt>"),
 	     data->hot_keyval, data->undo_keyval,
 	     data->hot_keyval, data->hot_keyval, data->hot_keyval, data->hot_keyval, data->undo_keyval, data->undo_keyval);
     gtk_label_set_markup (GTK_LABEL (widgetTwo), widgetTwoBuf);
     gtk_assistant_append_page (GTK_ASSISTANT (assistant), widgetTwo);
-    gtk_assistant_set_page_title (GTK_ASSISTANT (assistant), widgetTwo, "Gromit-MPX - How to use it");
+    gtk_assistant_set_page_title (GTK_ASSISTANT (assistant), widgetTwo, _("Gromit-MPX - How to use it"));
     gtk_assistant_set_page_type (GTK_ASSISTANT (assistant), widgetTwo, GTK_ASSISTANT_PAGE_CONTENT);
     gtk_assistant_set_page_complete (GTK_ASSISTANT (assistant), widgetTwo, TRUE);
 
     // set page three
     GtkWidget *widgetThree = gtk_grid_new ();
-    GtkWidget *widgetThreeText = gtk_label_new ("Do you want to show this introduction again on the next start of Gromit-MPX?\n"
-						"You can always access it again via the sys tray menu.\n");
-    GtkWidget *widgetThreeButton = gtk_check_button_new_with_label ("Show again on startup");
+    GtkWidget *widgetThreeText = gtk_label_new (_("Do you want to show this introduction again on the next start of Gromit-MPX?\n"
+						  "You can always access it again via the sys tray menu.\n"));
+    GtkWidget *widgetThreeButton = gtk_check_button_new_with_label (_("Show again on startup"));
     gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widgetThreeButton), data->show_intro_on_startup);
     gtk_grid_attach (GTK_GRID (widgetThree), widgetThreeText, 0, 0, 1, 1);
     gtk_grid_attach_next_to (GTK_GRID (widgetThree), widgetThreeButton, widgetThreeText, GTK_POS_BOTTOM, 1, 1);
--- gromit-mpx-1.4.orig/src/config.c
+++ gromit-mpx-1.4/src/config.c
@@ -29,7 +29,7 @@
 #include <errno.h>
 
 #include "config.h"
-#include "gromit-mpx.h"
+#include "main.h"
 #include "build-config.h"
 
 #define KEY_DFLT_SHOW_INTRO_ON_STARTUP TRUE
@@ -58,7 +58,7 @@ static gchar* parse_name (GScanner *scan
     {
       g_scanner_unexp_token (scanner, G_TOKEN_STRING, NULL,
                              NULL, NULL, "aborting", TRUE);
-      exit (1);
+      return NULL;
     }
 
   len = strlen (scanner->value.v_string);
@@ -110,8 +110,9 @@ static gchar* parse_name (GScanner *scan
   return name;
 }
 
-void parse_config (GromitData *data)
+gboolean parse_config (GromitData *data)
 {
+  gboolean status = FALSE;
   GromitPaintContext *context=NULL;
   GromitPaintContext *context_template=NULL;
   GScanner *scanner;
@@ -123,7 +124,7 @@ void parse_config (GromitData *data)
 
   GromitPaintType type;
   GdkRGBA *fg_color=NULL;
-  guint width, arrowsize, minwidth;
+  guint width, arrowsize, minwidth, maxwidth;
 
   /* try user config location */
   filename = g_strjoin (G_DIR_SEPARATOR_S,
@@ -146,9 +147,15 @@ void parse_config (GromitData *data)
 
   /* was the last possibility, no use to go on */
   if (file < 0) {
-      g_printerr("No usable config found, leaving tools unconfigured!\n");
       g_free(filename);
-      return;
+      GtkWidget *dialog = gtk_message_dialog_new(GTK_WINDOW(data->win),
+						 GTK_DIALOG_DESTROY_WITH_PARENT,
+						 GTK_MESSAGE_WARNING,
+						 GTK_BUTTONS_CLOSE,
+						 _("No usable config file found, falling back to default tools."));
+      gtk_dialog_run (GTK_DIALOG (dialog));
+      gtk_widget_destroy (dialog);
+      return FALSE;
   }
 
   scanner = g_scanner_new (NULL);
@@ -180,6 +187,7 @@ void parse_config (GromitData *data)
   g_scanner_scope_add_symbol (scanner, 2, "color",     (gpointer) 2);
   g_scanner_scope_add_symbol (scanner, 2, "arrowsize", (gpointer) 3);
   g_scanner_scope_add_symbol (scanner, 2, "minsize",   (gpointer) 4);
+  g_scanner_scope_add_symbol (scanner, 2, "maxsize",   (gpointer) 5);
 
   g_scanner_set_scope (scanner, 0);
   scanner->config->scope_0_fallback = 0;
@@ -196,23 +204,27 @@ void parse_config (GromitData *data)
            */
 
           name = parse_name (scanner);
+
+	  if(!name)
+	      goto cleanup;
+
           token = g_scanner_cur_token(scanner);
 
           if (token != G_TOKEN_EQUAL_SIGN)
             {
               g_scanner_unexp_token (scanner, G_TOKEN_EQUAL_SIGN, NULL,
                                      NULL, NULL, "aborting", TRUE);
-              exit (1);
+              goto cleanup;
             }
 
           token = g_scanner_get_next_token (scanner);
 
           /* defaults */
-
           type = GROMIT_PEN;
           width = 7;
           arrowsize = 0;
           minwidth = 1;
+          maxwidth = G_MAXUINT;
           fg_color = data->red;
 
           if (token == G_TOKEN_SYMBOL)
@@ -223,6 +235,8 @@ void parse_config (GromitData *data)
           else if (token == G_TOKEN_STRING)
             {
               copy = parse_name (scanner);
+	      if(!copy)
+		  goto cleanup;
               token = g_scanner_cur_token(scanner);
               context_template = g_hash_table_lookup (data->tool_config, copy);
               if (context_template)
@@ -231,6 +245,7 @@ void parse_config (GromitData *data)
                   width = context_template->width;
                   arrowsize = context_template->arrowsize;
                   minwidth = context_template->minwidth;
+		  maxwidth = context_template->maxwidth;
                   fg_color = context_template->paint_color;
                 }
               else
@@ -243,7 +258,7 @@ void parse_config (GromitData *data)
             {
               g_printerr ("Expected Tool-definition "
                           "or name of template tool\n");
-              exit (1);
+              goto cleanup;
             }
 
           /* Are there any tool-options?
@@ -265,13 +280,13 @@ void parse_config (GromitData *data)
                           if (token != G_TOKEN_EQUAL_SIGN)
                             {
                               g_printerr ("Missing \"=\"... aborting\n");
-                              exit (1);
+                              goto cleanup;
                             }
                           token = g_scanner_get_next_token (scanner);
                           if (token != G_TOKEN_FLOAT)
                             {
                               g_printerr ("Missing Size (float)... aborting\n");
-                              exit (1);
+                              goto cleanup;
                             }
                           width = (guint) (scanner->value.v_float + 0.5);
                         }
@@ -281,14 +296,14 @@ void parse_config (GromitData *data)
                           if (token != G_TOKEN_EQUAL_SIGN)
                             {
                               g_printerr ("Missing \"=\"... aborting\n");
-                              exit (1);
+                              goto cleanup;
                             }
                           token = g_scanner_get_next_token (scanner);
                           if (token != G_TOKEN_STRING)
                             {
                               g_printerr ("Missing Color (string)... "
                                           "aborting\n");
-                              exit (1);
+                              goto cleanup;
                             }
                           color = g_malloc (sizeof (GdkRGBA));
                           if (gdk_rgba_parse (color, scanner->value.v_string))
@@ -309,14 +324,14 @@ void parse_config (GromitData *data)
                           if (token != G_TOKEN_EQUAL_SIGN)
                             {
                               g_printerr ("Missing \"=\"... aborting\n");
-                              exit (1);
+                              goto cleanup;
                             }
                           token = g_scanner_get_next_token (scanner);
                           if (token != G_TOKEN_FLOAT)
                             {
                               g_printerr ("Missing Arrowsize (float)... "
                                           "aborting\n");
-                              exit (1);
+                              goto cleanup;
                             }
                           arrowsize = scanner->value.v_float;
                         }
@@ -326,17 +341,34 @@ void parse_config (GromitData *data)
                           if (token != G_TOKEN_EQUAL_SIGN)
                             {
                               g_printerr ("Missing \"=\"... aborting\n");
-                              exit (1);
+                              goto cleanup;
                             }
                           token = g_scanner_get_next_token (scanner);
                           if (token != G_TOKEN_FLOAT)
                             {
                               g_printerr ("Missing Minsize (float)... "
                                           "aborting\n");
-                              exit (1);
+                              goto cleanup;
                             }
                           minwidth = scanner->value.v_float;
                         }
+                      else if ((intptr_t) scanner->value.v_symbol == 5)
+                        {
+                          token = g_scanner_get_next_token (scanner);
+                          if (token != G_TOKEN_EQUAL_SIGN)
+                            {
+                              g_printerr ("Missing \"=\"... aborting\n");
+                              goto cleanup;
+                            }
+                          token = g_scanner_get_next_token (scanner);
+                          if (token != G_TOKEN_FLOAT)
+                            {
+                              g_printerr ("Missing Maxsize (float)... "
+                                          "aborting\n");
+                              goto cleanup;
+                            }
+                          maxwidth = scanner->value.v_float;
+                        }
 		      else
                         {
                           g_printerr ("Unknown tool type?????\n");
@@ -359,10 +391,10 @@ void parse_config (GromitData *data)
           if (token != ';')
             {
               g_printerr ("Expected \";\"\n");
-              exit (1);
+              goto cleanup;
             }
 
-          context = paint_context_new (data, type, fg_color, width, arrowsize, minwidth);
+          context = paint_context_new (data, type, fg_color, width, arrowsize, minwidth, maxwidth);
           g_hash_table_insert (data->tool_config, name, context);
         }
       else if (token == G_TOKEN_SYMBOL &&
@@ -380,7 +412,7 @@ void parse_config (GromitData *data)
             {
               g_scanner_unexp_token (scanner, G_TOKEN_EQUAL_SIGN, NULL,
                                      NULL, NULL, "aborting", TRUE);
-              exit (1);
+              goto cleanup;
             }
 
           token = g_scanner_get_next_token (scanner);
@@ -389,14 +421,14 @@ void parse_config (GromitData *data)
             {
               g_scanner_unexp_token (scanner, G_TOKEN_STRING, NULL,
                                      NULL, NULL, "aborting", TRUE);
-              exit (1);
+              goto cleanup;
             }
 
-          if (key_type == HOTKEY_SYMBOL_VALUE && g_strcmp0(data->hot_keyval, DEFAULT_HOTKEY) == 0)
+          if (key_type == HOTKEY_SYMBOL_VALUE)
             {
               data->hot_keyval = g_strdup(scanner->value.v_string);
             }
-          else if (key_type == UNDOKEY_SYMBOL_VALUE && g_strcmp0(data->undo_keyval, DEFAULT_UNDOKEY) == 0)
+          else if (key_type == UNDOKEY_SYMBOL_VALUE)
             {
               data->undo_keyval = g_strdup(scanner->value.v_string);
             }
@@ -406,20 +438,166 @@ void parse_config (GromitData *data)
           if (token != ';')
             {
               g_printerr ("Expected \";\"\n");
-              exit (1);
+              goto cleanup;
             }
         }
       else
         {
           g_printerr ("Expected name of Tool to define or Hot key definition\n");
-          exit(1);
+          goto cleanup;
         }
 
       token = g_scanner_get_next_token (scanner);
     }
+
+  status = TRUE;
+
+ cleanup:
+
+  if (!status) {
+      /* purge incomplete tool config */
+      GHashTableIter it;
+      gpointer value;
+      g_hash_table_iter_init (&it, data->tool_config);
+      while (g_hash_table_iter_next (&it, NULL, &value))
+	  paint_context_free(value);
+      g_hash_table_remove_all(data->tool_config);
+
+      /* alert user */
+      GtkWidget *dialog = gtk_message_dialog_new(GTK_WINDOW(data->win),
+						 GTK_DIALOG_DESTROY_WITH_PARENT,
+						 GTK_MESSAGE_WARNING,
+						 GTK_BUTTONS_CLOSE,
+						 _("Failed parsing config file %s, falling back to default tools."),
+						 filename);
+      gtk_dialog_run (GTK_DIALOG (dialog));
+      gtk_widget_destroy (dialog);
+  }
+
   g_scanner_destroy (scanner);
   close (file);
   g_free (filename);
+
+  return status;
+}
+
+
+int parse_args (int argc, char **argv, GromitData *data)
+{
+   gint      i;
+   gchar    *arg;
+   gboolean  wrong_arg = FALSE;
+   gboolean  activate = FALSE;
+
+   for (i=1; i < argc ; i++)
+     {
+       arg = argv[i];
+       if (strcmp (arg, "-a") == 0 ||
+           strcmp (arg, "--active") == 0)
+         {
+           activate = TRUE;
+         }
+       else if (strcmp (arg, "-d") == 0 ||
+                strcmp (arg, "--debug") == 0)
+         {
+           data->debug = 1;
+         }
+       else if (strcmp (arg, "-k") == 0 ||
+                strcmp (arg, "--key") == 0)
+         {
+           if (i+1 < argc)
+             {
+               data->hot_keyval = argv[i+1];
+               data->hot_keycode = 0;
+               i++;
+             }
+           else
+             {
+               g_printerr ("-k requires an Key-Name as argument\n");
+               wrong_arg = TRUE;
+             }
+         }
+       else if (strcmp (arg, "-K") == 0 ||
+                strcmp (arg, "--keycode") == 0)
+         {
+           if (i+1 < argc && atoi (argv[i+1]) > 0)
+             {
+               data->hot_keyval = NULL;
+               data->hot_keycode = atoi (argv[i+1]);
+               i++;
+             }
+           else
+             {
+               g_printerr ("-K requires an keycode > 0 as argument\n");
+               wrong_arg = TRUE;
+             }
+         }
+      else if (strcmp (arg, "-o") == 0 ||
+                strcmp (arg, "--opacity") == 0)
+         {
+           if (i+1 < argc && strtod (argv[i+1], NULL) >= 0.0 && strtod (argv[i+1], NULL) <= 1.0)
+             {
+               data->opacity = strtod (argv[i+1], NULL);
+               g_printerr ("Opacity set to: %.2f\n", data->opacity);
+               gtk_widget_set_opacity(data->win, data->opacity);
+               i++;
+             }
+           else
+             {
+               g_printerr ("-o requires an opacity >=0 and <=1 as argument\n");
+               wrong_arg = TRUE;
+             }
+         }
+       else if (strcmp (arg, "-u") == 0 ||
+                strcmp (arg, "--undo-key") == 0)
+         {
+           if (i+1 < argc)
+             {
+               data->undo_keyval = argv[i+1];
+               data->undo_keycode = 0;
+               i++;
+             }
+           else
+             {
+               g_printerr ("-u requires an Key-Name as argument\n");
+               wrong_arg = TRUE;
+             }
+         }
+       else if (strcmp (arg, "-U") == 0 ||
+                strcmp (arg, "--undo-keycode") == 0)
+         {
+           if (i+1 < argc && atoi (argv[i+1]) > 0)
+             {
+               data->undo_keyval = NULL;
+               data->undo_keycode = atoi (argv[i+1]);
+               i++;
+             }
+           else
+             {
+               g_printerr ("-U requires an keycode > 0 as argument\n");
+               wrong_arg = TRUE;
+             }
+         }
+       else if (strcmp (arg, "-V") == 0 ||
+		strcmp (arg, "--version") == 0)
+         {
+	     g_print("Gromit-MPX " PACKAGE_VERSION "\n");
+	     exit(0);
+         }
+       else
+         {
+           g_printerr ("Unknown Option for Gromit-MPX startup: \"%s\"\n", arg);
+           wrong_arg = TRUE;
+         }
+
+       if (wrong_arg)
+         {
+           g_printerr ("Please see the Gromit-MPX manpage for the correct usage\n");
+           exit (1);
+         }
+     }
+
+   return activate;
 }
 
 
--- gromit-mpx-1.4.orig/src/config.h
+++ gromit-mpx-1.4/src/config.h
@@ -24,12 +24,17 @@
 #ifndef CONFIG_H
 #define CONFIG_H
 
-#include "gromit-mpx.h"
+#include "main.h"
 
 /* fallback device name for config file */
 #define DEFAULT_DEVICE_NAME "default"
 
-void parse_config (GromitData *data);
+/**
+   Select and parse system or user .cfg file.
+   Returns TRUE if something got parsed successfully, FALSE otherwise.
+*/
+gboolean parse_config (GromitData *data);
+int parse_args (int argc, char **argv, GromitData *data);
 
 /* fallback hot key, if not specified on command line or in config file */
 #ifndef DEFAULT_HOTKEY
--- /dev/null
+++ gromit-mpx-1.4/src/drawing.c
@@ -0,0 +1,207 @@
+
+#include <math.h>
+#include "drawing.h"
+
+typedef struct
+{
+  gint x;
+  gint y;
+  gint width;
+} GromitStrokeCoordinate;
+
+
+void draw_line (GromitData *data,
+		GdkDevice *dev,
+		gint x1, gint y1,
+		gint x2, gint y2)
+{
+  GdkRectangle rect;
+  GromitDeviceData *devdata = g_hash_table_lookup(data->devdatatable, dev);
+
+  rect.x = MIN (x1,x2) - data->maxwidth / 2;
+  rect.y = MIN (y1,y2) - data->maxwidth / 2;
+  rect.width = ABS (x1-x2) + data->maxwidth;
+  rect.height = ABS (y1-y2) + data->maxwidth;
+
+  if(data->debug)
+    g_printerr("DEBUG: draw line from %d %d to %d %d\n", x1, y1, x2, y2);
+
+  if (devdata->cur_context->paint_ctx)
+    {
+      cairo_set_line_width(devdata->cur_context->paint_ctx, data->maxwidth);
+      cairo_set_line_cap(devdata->cur_context->paint_ctx, CAIRO_LINE_CAP_ROUND);
+      cairo_set_line_join(devdata->cur_context->paint_ctx, CAIRO_LINE_JOIN_ROUND);
+ 
+      cairo_move_to(devdata->cur_context->paint_ctx, x1, y1);
+      cairo_line_to(devdata->cur_context->paint_ctx, x2, y2);
+      cairo_stroke(devdata->cur_context->paint_ctx);
+
+      data->modified = 1;
+
+      gdk_window_invalidate_rect(gtk_widget_get_window(data->win), &rect, 0); 
+    }
+
+  data->painted = 1;
+}
+
+
+void draw_arrow (GromitData *data, 
+		 GdkDevice *dev,
+		 gint x1, gint y1,
+		 gint width,
+		 gfloat direction)
+{
+  GdkRectangle rect;
+  GdkPoint arrowhead [4];
+
+  /* get the data for this device */
+  GromitDeviceData *devdata = g_hash_table_lookup(data->devdatatable, dev);
+
+  width = width / 2;
+
+  /* I doubt that calculating the boundary box more exact is very useful */
+  rect.x = x1 - 4 * width - 1;
+  rect.y = y1 - 4 * width - 1;
+  rect.width = 8 * width + 2;
+  rect.height = 8 * width + 2;
+
+  arrowhead [0].x = x1 + 4 * width * cos (direction);
+  arrowhead [0].y = y1 + 4 * width * sin (direction);
+
+  arrowhead [1].x = x1 - 3 * width * cos (direction)
+                       + 3 * width * sin (direction);
+  arrowhead [1].y = y1 - 3 * width * cos (direction)
+                       - 3 * width * sin (direction);
+
+  arrowhead [2].x = x1 - 2 * width * cos (direction);
+  arrowhead [2].y = y1 - 2 * width * sin (direction);
+
+  arrowhead [3].x = x1 - 3 * width * cos (direction)
+                       - 3 * width * sin (direction);
+  arrowhead [3].y = y1 + 3 * width * cos (direction)
+                       - 3 * width * sin (direction);
+
+  if (devdata->cur_context->paint_ctx)
+    {
+      cairo_set_line_width(devdata->cur_context->paint_ctx, 1);
+      cairo_set_line_cap(devdata->cur_context->paint_ctx, CAIRO_LINE_CAP_ROUND);
+      cairo_set_line_join(devdata->cur_context->paint_ctx, CAIRO_LINE_JOIN_ROUND);
+ 
+      cairo_move_to(devdata->cur_context->paint_ctx, arrowhead[0].x, arrowhead[0].y);
+      cairo_line_to(devdata->cur_context->paint_ctx, arrowhead[1].x, arrowhead[1].y);
+      cairo_line_to(devdata->cur_context->paint_ctx, arrowhead[2].x, arrowhead[2].y);
+      cairo_line_to(devdata->cur_context->paint_ctx, arrowhead[3].x, arrowhead[3].y);
+      cairo_fill(devdata->cur_context->paint_ctx);
+
+      gdk_cairo_set_source_rgba(devdata->cur_context->paint_ctx, data->black);
+
+      cairo_move_to(devdata->cur_context->paint_ctx, arrowhead[0].x, arrowhead[0].y);
+      cairo_line_to(devdata->cur_context->paint_ctx, arrowhead[1].x, arrowhead[1].y);
+      cairo_line_to(devdata->cur_context->paint_ctx, arrowhead[2].x, arrowhead[2].y);
+      cairo_line_to(devdata->cur_context->paint_ctx, arrowhead[3].x, arrowhead[3].y);
+      cairo_line_to(devdata->cur_context->paint_ctx, arrowhead[0].x, arrowhead[0].y);
+      cairo_stroke(devdata->cur_context->paint_ctx);
+
+      gdk_cairo_set_source_rgba(devdata->cur_context->paint_ctx, devdata->cur_context->paint_color);
+    
+      data->modified = 1;
+
+      gdk_window_invalidate_rect(gtk_widget_get_window(data->win), &rect, 0); 
+    }
+
+  data->painted = 1;
+}
+
+
+void coord_list_prepend (GromitData *data, 
+			 GdkDevice* dev, 
+			 gint x, 
+			 gint y, 
+			 gint width)
+{
+  /* get the data for this device */
+  GromitDeviceData *devdata = g_hash_table_lookup(data->devdatatable, dev);
+
+  GromitStrokeCoordinate *point;
+
+  point = g_malloc (sizeof (GromitStrokeCoordinate));
+  point->x = x;
+  point->y = y;
+  point->width = width;
+
+  devdata->coordlist = g_list_prepend (devdata->coordlist, point);
+}
+
+
+void coord_list_free (GromitData *data, 
+		      GdkDevice* dev)
+{
+  /* get the data for this device */
+  GromitDeviceData *devdata = g_hash_table_lookup(data->devdatatable, dev);
+
+  GList *ptr;
+  ptr = devdata->coordlist;
+
+  while (ptr)
+    {
+      g_free (ptr->data);
+      ptr = ptr->next;
+    }
+
+  g_list_free (devdata->coordlist);
+
+  devdata->coordlist = NULL;
+}
+
+
+gboolean coord_list_get_arrow_param (GromitData *data,
+				     GdkDevice  *dev,
+				     gint        search_radius,
+				     gint       *ret_width,
+				     gfloat     *ret_direction)
+{
+  gint x0, y0, r2, dist;
+  gboolean success = FALSE;
+  GromitStrokeCoordinate  *cur_point, *valid_point;
+  /* get the data for this device */
+  GromitDeviceData *devdata = g_hash_table_lookup(data->devdatatable, dev);
+  GList *ptr = devdata->coordlist;
+  gfloat width;
+
+  valid_point = NULL;
+
+  if (ptr)
+    {
+      cur_point = ptr->data;
+      x0 = cur_point->x;
+      y0 = cur_point->y;
+      r2 = search_radius * search_radius;
+      dist = 0;
+
+      while (ptr && dist < r2)
+        {
+          ptr = ptr->next;
+          if (ptr)
+            {
+              cur_point = ptr->data;
+              dist = (cur_point->x - x0) * (cur_point->x - x0) +
+                     (cur_point->y - y0) * (cur_point->y - y0);
+              width = cur_point->width * devdata->cur_context->arrowsize;
+              if (width * 2 <= dist &&
+                  (!valid_point || valid_point->width < cur_point->width))
+                valid_point = cur_point;
+            }
+        }
+
+      if (valid_point)
+        {
+          *ret_width = MAX (valid_point->width * devdata->cur_context->arrowsize,
+                            2);
+          *ret_direction = atan2 (y0 - valid_point->y, x0 - valid_point->x);
+          success = TRUE;
+        }
+    }
+
+  return success;
+}
+
--- /dev/null
+++ gromit-mpx-1.4/src/drawing.h
@@ -0,0 +1,23 @@
+#ifndef DRAWING_H
+#define DRAWING_H
+
+/*
+  Functions that manipulate the surfaces pixel-wise.
+  Does not include functions that treat a surface like a buffer, like undo/redo etc.
+*/
+
+#include "main.h"
+
+void draw_line (GromitData *data, GdkDevice *dev, gint x1, gint y1, gint x2, gint y2);
+void draw_arrow (GromitData *data, GdkDevice *dev, gint x1, gint y1, gint width, gfloat direction);
+
+gboolean coord_list_get_arrow_param (GromitData *data,
+					    GdkDevice  *dev,
+					    gint        search_radius,
+					    gint       *ret_width,
+					    gfloat     *ret_direction);
+void coord_list_prepend (GromitData *data, GdkDevice* dev, gint x, gint y, gint width);
+void coord_list_free (GromitData *data, GdkDevice* dev);
+
+
+#endif
--- gromit-mpx-1.4.orig/src/input.h
+++ gromit-mpx-1.4/src/input.h
@@ -3,7 +3,7 @@
 #ifndef INPUT_H
 #define INPUT_H
 
-#include "gromit-mpx.h"
+#include "main.h"
 
 void setup_input_devices (GromitData *data);
 void shutdown_input_devices (GromitData *data);
--- /dev/null
+++ gromit-mpx-1.4/src/main.c
@@ -0,0 +1,1104 @@
+/* 
+ * Gromit-MPX -- a program for painting on the screen
+ *
+ * Gromit Copyright (C) 2000 Simon Budig <Simon.Budig@unix-ag.org>
+ *
+ * Gromit-MPX Copyright (C) 2009,2010 Christian Beier <dontmind@freeshell.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#include <string.h>
+#include <stdlib.h>
+
+#include "callbacks.h"
+#include "config.h"
+#include "input.h"
+#include "main.h"
+#include "build-config.h"
+
+#include "paint_cursor.xpm"
+#include "erase_cursor.xpm"
+
+
+
+GromitPaintContext *paint_context_new (GromitData *data, 
+				       GromitPaintType type,
+				       GdkRGBA *paint_color, 
+				       guint width,
+				       guint arrowsize,
+				       guint minwidth,
+				       guint maxwidth)
+{
+  GromitPaintContext *context;
+
+  context = g_malloc (sizeof (GromitPaintContext));
+
+  context->type = type;
+  context->width = width;
+  context->arrowsize = arrowsize;
+  context->minwidth = minwidth;
+  context->maxwidth = maxwidth;
+  context->paint_color = paint_color;
+
+  
+  context->paint_ctx = cairo_create (data->backbuffer);
+
+  gdk_cairo_set_source_rgba(context->paint_ctx, paint_color);
+  if(!data->composited)
+    cairo_set_antialias(context->paint_ctx, CAIRO_ANTIALIAS_NONE);
+  cairo_set_line_width(context->paint_ctx, width);
+  cairo_set_line_cap(context->paint_ctx, CAIRO_LINE_CAP_ROUND);
+  cairo_set_line_join(context->paint_ctx, CAIRO_LINE_JOIN_ROUND);
+  
+  if (type == GROMIT_ERASER)
+    cairo_set_operator(context->paint_ctx, CAIRO_OPERATOR_CLEAR);
+  else
+    if (type == GROMIT_RECOLOR)
+      cairo_set_operator(context->paint_ctx, CAIRO_OPERATOR_ATOP);
+    else /* GROMIT_PEN */
+      cairo_set_operator(context->paint_ctx, CAIRO_OPERATOR_OVER);
+
+  return context;
+}
+
+
+void paint_context_print (gchar *name, 
+			  GromitPaintContext *context)
+{
+  g_printerr ("Tool name: \"%-20s\": ", name);
+  switch (context->type)
+  {
+    case GROMIT_PEN:
+      g_printerr ("Pen,     "); break;
+    case GROMIT_ERASER:
+      g_printerr ("Eraser,  "); break;
+    case GROMIT_RECOLOR:
+      g_printerr ("Recolor, "); break;
+    default:
+      g_printerr ("UNKNOWN, "); break;
+  }
+
+  g_printerr ("width: %u, ", context->width);
+  g_printerr ("minwidth: %u, ", context->minwidth);
+  g_printerr ("maxwidth: %u, ", context->maxwidth);
+  g_printerr ("arrowsize: %.2f, ", context->arrowsize);
+  g_printerr ("color: %s\n", gdk_rgba_to_string(context->paint_color));
+}
+
+
+void paint_context_free (GromitPaintContext *context)
+{
+  cairo_destroy(context->paint_ctx);
+  g_free (context);
+}
+
+
+void hide_window (GromitData *data)
+{
+  if (!data->hidden)
+    {
+      /* save grab state of each device */
+      GHashTableIter it;
+      gpointer value;
+      GromitDeviceData* devdata; 
+      g_hash_table_iter_init (&it, data->devdatatable);
+      while (g_hash_table_iter_next (&it, NULL, &value)) 
+        {
+          devdata = value;
+          devdata->was_grabbed = devdata->is_grabbed;
+        }
+      data->hidden = 1;
+      release_grab (data, NULL); /* release all */
+      gtk_widget_hide (data->win);
+      
+      if(data->debug)
+        g_printerr ("DEBUG: Hiding window.\n");
+    }
+}
+
+
+void show_window (GromitData *data)
+{
+  if (data->hidden)
+    {
+      gtk_widget_show (data->win);
+      data->hidden = 0;
+
+      /* restore grab state of each device */
+      GHashTableIter it;
+      gpointer value;
+      GromitDeviceData* devdata; 
+      g_hash_table_iter_init (&it, data->devdatatable);
+      while (g_hash_table_iter_next (&it, NULL, &value)) 
+        {
+          devdata = value;
+          if(devdata->was_grabbed)
+            acquire_grab (data, devdata->device);
+        }
+      if(data->debug)
+        g_printerr ("DEBUG: Showing window.\n");
+    }
+  gdk_window_raise (gtk_widget_get_window(data->win));
+}
+
+
+
+void toggle_visibility (GromitData *data)
+{
+  if (data->hidden)
+    show_window (data);
+  else
+    hide_window (data);
+}
+
+
+
+void clear_screen (GromitData *data)
+{
+  cairo_t *cr = cairo_create(data->backbuffer);
+  cairo_set_source_rgba(cr, 0, 0, 0, 0);
+  cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
+  cairo_paint (cr);
+  cairo_destroy(cr);
+
+  GdkRectangle rect = {0, 0, data->width, data->height};
+  gdk_window_invalidate_rect(gtk_widget_get_window(data->win), &rect, 0); 
+  
+  if(!data->composited)
+    {
+      cairo_region_t* r = gdk_cairo_region_create_from_surface(data->backbuffer);
+      gtk_widget_shape_combine_region(data->win, r);
+      cairo_region_destroy(r);
+      // try to set transparent for input
+      r =  cairo_region_create();
+      gtk_widget_input_shape_combine_region(data->win, r);
+      cairo_region_destroy(r);
+    }
+
+  data->painted = 0;
+
+  if(data->debug)
+    g_printerr ("DEBUG: Cleared screen.\n");
+}
+
+
+gint reshape (gpointer user_data)
+{
+  GromitData *data = (GromitData *) user_data;
+
+  if (data->modified && !data->composited)
+    {
+      if (gtk_events_pending () && data->delayed < 5)
+        {
+          data->delayed++ ;
+        }
+      else
+        {
+	  cairo_region_t* r = gdk_cairo_region_create_from_surface(data->backbuffer);
+	  gtk_widget_shape_combine_region(data->win, r);
+	  cairo_region_destroy(r);
+	  // try to set transparent for input
+	  r =  cairo_region_create();
+	  gtk_widget_input_shape_combine_region(data->win, r);
+	  cairo_region_destroy(r);
+
+	  /*
+	    this is not needed when there is user input, i.e. when drawing,
+	    but needed when uing the undo functionality.
+	  */
+	  gtk_widget_queue_draw(data->win);
+
+          data->modified = 0;
+          data->delayed = 0;
+        }
+    }
+  return 1;
+}
+
+
+void select_tool (GromitData *data, 
+		  GdkDevice *device, 
+		  GdkDevice *slave_device,
+		  guint state)
+{
+  guint buttons = 0, modifier = 0, slave_len = 0, len = 0, default_len = 0;
+  guint req_buttons = 0, req_modifier = 0;
+  guint i, j, success = 0;
+  GromitPaintContext *context = NULL;
+  guchar *slave_name;
+  guchar *name;
+  guchar *default_name;
+
+  /* get the data for this device */
+  GromitDeviceData *devdata = g_hash_table_lookup(data->devdatatable, device);
+ 
+  if (device)
+    {
+      slave_len = strlen (gdk_device_get_name(slave_device));
+      slave_name = (guchar*) g_strndup (gdk_device_get_name(slave_device), slave_len + 3);
+      len = strlen (gdk_device_get_name(device));
+      name = (guchar*) g_strndup (gdk_device_get_name(device), len + 3);
+      default_len = strlen(DEFAULT_DEVICE_NAME);
+      default_name = (guchar*) g_strndup (DEFAULT_DEVICE_NAME, default_len + 3);
+      
+      
+      /* Extract Button/Modifiers from state (see GdkModifierType) */
+      req_buttons = (state >> 8) & 31;
+
+      req_modifier = (state >> 1) & 7;
+      if (state & GDK_SHIFT_MASK) req_modifier |= 1;
+
+      slave_name [slave_len] = 124;
+      slave_name [slave_len+3] = 0;
+      name [len] = 124;
+      name [len+3] = 0;
+      default_name [default_len] = 124;
+      default_name [default_len+3] = 0;
+
+      /*
+	Iterate i up until <= req_buttons.
+	For each i, find out if bits of i are _all_ in `req_buttons`.
+	- If yes, lookup if there is tool and select if there is.
+	- If no, try next i, no tool lookup.
+      */
+      context = NULL;
+      i=-1;
+      do
+        {
+          i++;
+
+	  /*
+	    For all i > 0, find out if _all_ bits representing the iterator 'i'
+	    are present in req_buttons as well. If not (none or only some are),
+	    then go on.
+	    The condition i==0 handles the config cases where no button is given.
+	  */
+	  buttons = i & req_buttons;
+	  if(i > 0 && (buttons == 0 || buttons != i))
+	      continue;
+
+          j=-1;
+          do
+            {
+              j++;
+              modifier = req_modifier & ((1 << j)-1);
+              slave_name [slave_len+1] = buttons + 64;
+              slave_name [slave_len+2] = modifier + 48;
+              name [len+1] = buttons + 64;
+              name [len+2] = modifier + 48;
+              default_name [default_len+1] = buttons + 64;
+              default_name [default_len+2] = modifier + 48;
+
+	            if(data->debug)
+                g_printerr("DEBUG: select_tool looking up context for '%s' attached to '%s'\n", slave_name, name);
+
+              context = g_hash_table_lookup (data->tool_config, slave_name);
+              if(context) {
+                  if(data->debug)
+                    g_printerr("DEBUG: select_tool set context for '%s'\n", slave_name);
+                  devdata->cur_context = context;
+                  success = 1;
+              }
+              else /* try master name */
+              if ((context = g_hash_table_lookup (data->tool_config, name)))
+                {
+                  if(data->debug)
+                    g_printerr("DEBUG: select_tool set context for '%s'\n", name);
+                  devdata->cur_context = context;
+                  success = 1;
+                }
+              else /* try default_name */
+                if((context = g_hash_table_lookup (data->tool_config, default_name)))
+                  {
+                    if(data->debug)
+                      g_printerr("DEBUG: select_tool set default context '%s' for '%s'\n", default_name, name);
+                    devdata->cur_context = context;
+                    success = 1;
+                  }
+                
+            }
+          while (j<=3 && req_modifier >= (1u << j));
+        }
+      while (i < req_buttons);
+
+      g_free (name);
+      g_free (default_name);
+
+      if (!success)
+        {
+          if (gdk_device_get_source(device) == GDK_SOURCE_ERASER)
+            devdata->cur_context = data->default_eraser;
+          else
+            devdata->cur_context = data->default_pen;
+
+	  if(data->debug)
+	      g_printerr("DEBUG: select_tool set fallback context for '%s'\n", name);
+        }
+    }
+  else
+    g_printerr ("ERROR: select_tool attempted to select nonexistent device!\n");
+
+  GdkCursor *cursor;
+  if(devdata->cur_context && devdata->cur_context->type == GROMIT_ERASER)
+    cursor = data->erase_cursor; 
+  else
+    cursor = data->paint_cursor;
+
+
+  if(data->debug)
+    g_printerr("DEBUG: select_tool setting cursor %p\n",cursor);
+
+
+  //FIXME!  Should be:
+  //gdk_window_set_cursor(gtk_widget_get_window(data->win), cursor);
+  // doesn't work during a grab?
+  gdk_device_grab(device,
+  		  gtk_widget_get_window(data->win),
+  		  GDK_OWNERSHIP_NONE,
+  		  FALSE,
+  		  GROMIT_MOUSE_EVENTS,
+  		  cursor,
+  		  GDK_CURRENT_TIME);
+
+  devdata->state = state;
+  devdata->lastslave = slave_device;
+}
+
+
+
+void snap_undo_state (GromitData *data)
+{
+  if(data->debug)
+    g_printerr ("DEBUG: Snapping undo buffer %d.\n", data->undo_head);
+
+  copy_surface(data->undobuffer[data->undo_head], data->backbuffer);
+
+  // Increment head position
+  data->undo_head++;
+  if(data->undo_head >= GROMIT_MAX_UNDO)
+    data->undo_head -= GROMIT_MAX_UNDO;
+  data->undo_depth++;
+  // See if we ran out of undo levels with oldest undo overwritten
+  if(data->undo_depth > GROMIT_MAX_UNDO)
+    data->undo_depth = GROMIT_MAX_UNDO;
+  // Invalidate any redo from this position
+  data->redo_depth = 0;
+}
+
+
+
+void copy_surface (cairo_surface_t *dst, cairo_surface_t *src)
+{
+  cairo_t *cr = cairo_create(dst);
+  cairo_set_source_surface(cr, src, 0, 0);
+  cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
+  cairo_paint (cr);
+  cairo_destroy(cr);
+}
+
+
+
+void swap_surfaces (cairo_surface_t *a, cairo_surface_t *b)
+{
+  int width = cairo_image_surface_get_width(a);
+  int height = cairo_image_surface_get_height(a);
+  cairo_surface_t *temp = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height);
+  copy_surface(temp, a);
+  copy_surface(a, b);
+  copy_surface(b, temp);
+  cairo_surface_destroy(temp);
+}
+
+
+
+void undo_drawing (GromitData *data)
+{
+  /* Swap undobuffer[head-1]->backbuffer */
+  if(data->undo_depth <= 0)
+    return;
+  data->undo_depth--;
+  data->redo_depth++;
+  if(data->redo_depth > GROMIT_MAX_UNDO)
+    data->redo_depth -= GROMIT_MAX_UNDO;
+  data->undo_head--;
+  if(data->undo_head < 0)
+    data->undo_head += GROMIT_MAX_UNDO;
+
+  swap_surfaces(data->backbuffer, data->undobuffer[data->undo_head]);
+
+  GdkRectangle rect = {0, 0, data->width, data->height};
+  gdk_window_invalidate_rect(gtk_widget_get_window(data->win), &rect, 0); 
+
+  data->modified = 1;
+
+  if(data->debug)
+    g_printerr ("DEBUG: Undo drawing %d.\n", data->undo_head);
+}
+
+
+
+void redo_drawing (GromitData *data)
+{
+  if(data->redo_depth <= 0)
+    return;
+
+  swap_surfaces(data->backbuffer, data->undobuffer[data->undo_head]);
+
+  data->redo_depth--;
+  data->undo_depth++;
+  data->undo_head++;
+  if(data->undo_head >= GROMIT_MAX_UNDO)
+    data->undo_head -= GROMIT_MAX_UNDO;
+  
+  GdkRectangle rect = {0, 0, data->width, data->height};
+  gdk_window_invalidate_rect(gtk_widget_get_window(data->win), &rect, 0); 
+
+  data->modified = 1;
+
+  if(data->debug)
+    g_printerr("DEBUG: Redo drawing.\n");
+}
+
+
+
+
+
+
+/*
+ * Functions for handling various (GTK+)-Events
+ */
+
+
+void main_do_event (GdkEventAny *event,
+		    GromitData  *data)
+{
+  guint keycode = ((GdkEventKey *) event)->hardware_keycode;
+  if ((event->type == GDK_KEY_PRESS ||
+       event->type == GDK_KEY_RELEASE) &&
+      event->window == data->root &&
+      (keycode == data->hot_keycode || keycode == data->undo_keycode))
+    {
+      /* redirect the event to our main window, so that GTK+ doesn't
+       * throw it away (there is no GtkWidget for the root window...)
+       */
+      event->window = gtk_widget_get_window(data->win);
+      g_object_ref (gtk_widget_get_window(data->win));
+    }
+
+  gtk_main_do_event ((GdkEvent *) event);
+}
+
+
+
+
+
+void setup_main_app (GromitData *data, int argc, char ** argv)
+{
+  gboolean activate;
+
+  if(getenv("GDK_CORE_DEVICE_EVENTS")) {
+      g_printerr("GDK is set to not use the XInput extension, Gromit-MPX can not work this way.\n"
+		 "Probably the GDK_CORE_DEVICE_EVENTS environment variable is set, try to start Gromit-MPX with this variable unset.\n");
+      exit(1);
+  }
+
+  /*
+    l18n
+   */
+  bindtextdomain(PACKAGE_LOCALE_DOMAIN, PACKAGE_LOCALE_DIR);
+  textdomain(PACKAGE_LOCALE_DOMAIN);
+
+  /*
+    HOT KEYS
+  */
+  data->hot_keyval = DEFAULT_HOTKEY;
+  data->hot_keycode = 0;
+
+  data->undo_keyval = DEFAULT_UNDOKEY;
+  data->undo_keycode = 0;
+
+  char *xdg_current_desktop = getenv("XDG_CURRENT_DESKTOP");
+  if (xdg_current_desktop && strcmp(xdg_current_desktop, "XFCE") == 0) {
+      /*
+	XFCE per default grabs Ctrl-F1 to Ctrl-F12 (switch to workspace 1-12)
+	and Alt-F9 (minimize window) which renders Gromit-MPX's default hotkey
+	mapping unusable. Provide different defaults for that desktop environment.
+      */
+      data->hot_keyval = DEFAULT_HOTKEY_XFCE;
+      data->undo_keyval = DEFAULT_UNDOKEY_XFCE;
+      g_print("Detected XFCE, changing default hot keys to '" DEFAULT_HOTKEY_XFCE "' and '" DEFAULT_UNDOKEY_XFCE "'\n");
+  }
+
+  /* COLOURS */
+  g_free(data->white);
+  g_free(data->black);
+  g_free(data->red);
+  data->white = g_malloc (sizeof (GdkRGBA));
+  data->black = g_malloc (sizeof (GdkRGBA));
+  data->red   = g_malloc (sizeof (GdkRGBA));
+  gdk_rgba_parse(data->white, "#FFFFFF");
+  gdk_rgba_parse(data->black, "#000000");
+  gdk_rgba_parse(data->red, "#FF0000");
+
+
+  /* 
+     CURSORS
+  */
+  GdkPixbuf* paint_cursor_pixbuf = gdk_pixbuf_new_from_xpm_data(paint_cursor_xpm);
+  data->paint_cursor = gdk_cursor_new_from_pixbuf(data->display,
+						  paint_cursor_pixbuf,
+						  paint_cursor_x_hot,
+						  paint_cursor_y_hot);
+  g_object_unref (paint_cursor_pixbuf);
+
+  GdkPixbuf* erase_cursor_pixbuf = gdk_pixbuf_new_from_xpm_data(erase_cursor_xpm);
+  data->erase_cursor = gdk_cursor_new_from_pixbuf(data->display,
+						  erase_cursor_pixbuf,
+						  erase_cursor_x_hot,
+						  erase_cursor_y_hot);
+  g_object_unref (erase_cursor_pixbuf);
+
+
+  /*
+    DRAWING AREA
+  */
+  /* SHAPE SURFACE*/
+  cairo_surface_destroy(data->backbuffer);
+  data->backbuffer = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, data->width, data->height);
+  
+  /*
+    UNDO STATE
+  */
+  data->undo_head = 0;
+  data->undo_depth = 0;
+  data->redo_depth = 0;
+  int i;
+  for (i = 0; i < GROMIT_MAX_UNDO; i++)
+    {
+      cairo_surface_destroy(data->undobuffer[i]);
+      data->undobuffer[i] = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, data->width, data->height);
+    }
+  
+
+
+  /* EVENTS */
+  gtk_widget_add_events (data->win, GROMIT_WINDOW_EVENTS);
+  g_signal_connect (data->win, "draw",
+		    G_CALLBACK (on_expose), data);
+  g_signal_connect (data->win,"configure_event",
+		    G_CALLBACK (on_configure), data);
+  g_signal_connect (data->win,"screen-changed",
+		    G_CALLBACK (on_screen_changed), data);
+  g_signal_connect (data->screen,"monitors_changed",
+		    G_CALLBACK (on_monitors_changed), data);
+  g_signal_connect (data->screen,"composited-changed",
+		    G_CALLBACK (on_composited_changed), data);
+  g_signal_connect (gdk_display_get_device_manager (data->display), "device-added",
+                    G_CALLBACK (on_device_added), data);
+  g_signal_connect (gdk_display_get_device_manager (data->display), "device-removed",
+                    G_CALLBACK (on_device_removed), data);
+  g_signal_connect (data->win, "motion_notify_event",
+		    G_CALLBACK (on_motion), data);
+  g_signal_connect (data->win, "button_press_event", 
+		    G_CALLBACK (on_buttonpress), data);
+  g_signal_connect (data->win, "button_release_event",
+		    G_CALLBACK (on_buttonrelease), data);
+  /* disconnect previously defined selection handlers */
+  g_signal_handlers_disconnect_by_func (data->win, 
+					G_CALLBACK (on_clientapp_selection_get),
+					data);
+  g_signal_handlers_disconnect_by_func (data->win, 
+					G_CALLBACK (on_clientapp_selection_received),
+					data);
+  /* and re-connect them to mainapp functions */
+  g_signal_connect (data->win, "selection_get",
+		    G_CALLBACK (on_mainapp_selection_get), data);
+  g_signal_connect (data->win, "selection_received",
+		    G_CALLBACK (on_mainapp_selection_received), data);
+
+
+  if(!data->composited) // set initial shape
+    {
+      cairo_region_t* r = gdk_cairo_region_create_from_surface(data->backbuffer);
+      gtk_widget_shape_combine_region(data->win, r);
+      cairo_region_destroy(r);
+    }
+  
+
+  /* reset settings from client setup */
+  gtk_selection_remove_all (data->win);
+  gtk_selection_owner_set (data->win, GA_CONTROL, GDK_CURRENT_TIME);
+
+  gtk_selection_add_target (data->win, GA_CONTROL, GA_STATUS, 0);
+  gtk_selection_add_target (data->win, GA_CONTROL, GA_QUIT, 1);
+  gtk_selection_add_target (data->win, GA_CONTROL, GA_ACTIVATE, 2);
+  gtk_selection_add_target (data->win, GA_CONTROL, GA_DEACTIVATE, 3);
+  gtk_selection_add_target (data->win, GA_CONTROL, GA_TOGGLE, 4);
+  gtk_selection_add_target (data->win, GA_CONTROL, GA_VISIBILITY, 5);
+  gtk_selection_add_target (data->win, GA_CONTROL, GA_CLEAR, 6);
+  gtk_selection_add_target (data->win, GA_CONTROL, GA_RELOAD, 7);
+  gtk_selection_add_target (data->win, GA_CONTROL, GA_UNDO, 8);
+  gtk_selection_add_target (data->win, GA_CONTROL, GA_REDO, 9);
+
+
+ 
+
+  /*
+   * Parse Config file
+   */
+  data->tool_config = g_hash_table_new (g_str_hash, g_str_equal);
+  parse_config (data);
+  g_hash_table_foreach (data->tool_config, parse_print_help, NULL);
+
+  /*
+    parse key file
+  */
+  read_keyfile(data);
+
+  /*
+    parse cmdline
+  */
+  activate = parse_args (argc, argv, data);
+
+  // might have been in key file
+  gtk_widget_set_opacity(data->win, data->opacity);
+
+  /* 
+     FIND HOTKEY KEYCODE 
+  */
+  if (data->hot_keyval)
+    {
+      GdkKeymap    *keymap;
+      GdkKeymapKey *keys;
+      gint          n_keys;
+      guint         keyval;
+
+      if (strlen (data->hot_keyval) > 0 &&
+          strcasecmp (data->hot_keyval, "none") != 0)
+        {
+          keymap = gdk_keymap_get_for_display (data->display);
+          keyval = gdk_keyval_from_name (data->hot_keyval);
+
+          if (!keyval || !gdk_keymap_get_entries_for_keyval (keymap, keyval,
+                                                             &keys, &n_keys))
+            {
+              g_printerr ("cannot find the key \"%s\"\n", data->hot_keyval);
+              exit (1);
+            }
+
+          data->hot_keycode = keys[0].keycode;
+          g_free (keys);
+        }
+    }
+
+  /*
+     FIND UNDOKEY KEYCODE 
+  */
+  if (data->undo_keyval)
+    {
+      GdkKeymap    *keymap;
+      GdkKeymapKey *keys;
+      gint          n_keys;
+      guint         keyval;
+
+      if (strlen (data->undo_keyval) > 0 &&
+          strcasecmp (data->undo_keyval, "none") != 0)
+        {
+          keymap = gdk_keymap_get_for_display (data->display);
+          keyval = gdk_keyval_from_name (data->undo_keyval);
+
+          if (!keyval || !gdk_keymap_get_entries_for_keyval (keymap, keyval,
+                                                             &keys, &n_keys))
+            {
+              g_printerr ("cannot find the key \"%s\"\n", data->undo_keyval);
+              exit (1);
+            }
+
+          data->undo_keycode = keys[0].keycode;
+          g_free (keys);
+        }
+    }
+
+
+  /* 
+     INPUT DEVICES
+  */
+  data->devdatatable = g_hash_table_new(NULL, NULL);
+  setup_input_devices (data);
+
+
+
+  gtk_widget_show_all (data->win);
+
+  data->painted = 0;
+  hide_window (data);
+
+  data->timeout_id = g_timeout_add (20, reshape, data);
+ 
+  data->modified = 0;
+
+  data->default_pen = paint_context_new (data, GROMIT_PEN,
+					 data->red, 7, 0, 1, G_MAXUINT);
+  data->default_eraser = paint_context_new (data, GROMIT_ERASER,
+					    data->red, 75, 0, 1, G_MAXUINT);
+
+  
+
+  gdk_event_handler_set ((GdkEventFunc) main_do_event, data, NULL);
+  gtk_key_snooper_install (snoop_key_press, data);
+
+  if (activate)
+    acquire_grab (data, NULL); /* grab all */
+
+  /* 
+     TRAY ICON
+  */
+  data->trayicon = app_indicator_new (PACKAGE_NAME,
+				      "net.christianbeier.Gromit-MPX",
+				      APP_INDICATOR_CATEGORY_APPLICATION_STATUS);
+
+  app_indicator_set_status (data->trayicon, APP_INDICATOR_STATUS_ACTIVE);
+
+
+
+  /* create the menu */
+  GtkWidget *menu = gtk_menu_new ();
+
+  char labelBuf[128];
+  /* Create the menu items */
+  snprintf(labelBuf, sizeof(labelBuf), _("Toggle Painting (%s)"), data->hot_keyval);
+  GtkWidget* toggle_paint_item = gtk_menu_item_new_with_label (labelBuf);
+  snprintf(labelBuf, sizeof(labelBuf), _("Clear Screen (SHIFT-%s)"), data->hot_keyval);
+  GtkWidget* clear_item = gtk_menu_item_new_with_label (labelBuf);
+  snprintf(labelBuf, sizeof(labelBuf), _("Toggle Visibility (CTRL-%s)"), data->hot_keyval);
+  GtkWidget* toggle_vis_item = gtk_menu_item_new_with_label (labelBuf);
+  GtkWidget* thicker_lines_item = gtk_menu_item_new_with_label (_("Thicker Lines"));
+  GtkWidget* thinner_lines_item = gtk_menu_item_new_with_label (_("Thinner Lines"));
+  GtkWidget* opacity_bigger_item = gtk_menu_item_new_with_label (_("Bigger Opacity"));
+  GtkWidget* opacity_lesser_item = gtk_menu_item_new_with_label (_("Lesser Opacity"));
+  snprintf(labelBuf, sizeof(labelBuf), _("Undo (%s)"), data->undo_keyval);
+  GtkWidget* undo_item = gtk_menu_item_new_with_label (labelBuf);
+  snprintf(labelBuf, sizeof(labelBuf), _("Redo (SHIFT-%s)"), data->undo_keyval);
+  GtkWidget* redo_item = gtk_menu_item_new_with_label (labelBuf);
+
+  GtkWidget* sep_item = gtk_separator_menu_item_new();
+  GtkWidget* intro_item = gtk_menu_item_new_with_mnemonic(_("_Introduction"));
+  GtkWidget* support_item = gtk_menu_item_new_with_mnemonic(_("_Support Gromit-MPX"));
+  GtkWidget* about_item = gtk_menu_item_new_with_mnemonic(_("_About"));
+  snprintf(labelBuf, sizeof(labelBuf), _("_Quit (ALT-%s)"), data->hot_keyval);
+  GtkWidget* quit_item = gtk_menu_item_new_with_mnemonic(labelBuf);
+
+
+  /* Add them to the menu */
+  gtk_menu_shell_append (GTK_MENU_SHELL (menu), toggle_paint_item);
+  gtk_menu_shell_append (GTK_MENU_SHELL (menu), clear_item);
+  gtk_menu_shell_append (GTK_MENU_SHELL (menu), toggle_vis_item);
+  gtk_menu_shell_append (GTK_MENU_SHELL (menu), thicker_lines_item);
+  gtk_menu_shell_append (GTK_MENU_SHELL (menu), thinner_lines_item);
+  gtk_menu_shell_append (GTK_MENU_SHELL (menu), opacity_bigger_item);
+  gtk_menu_shell_append (GTK_MENU_SHELL (menu), opacity_lesser_item);
+  gtk_menu_shell_append (GTK_MENU_SHELL (menu), undo_item);
+  gtk_menu_shell_append (GTK_MENU_SHELL (menu), redo_item);
+
+  gtk_menu_shell_append (GTK_MENU_SHELL (menu), sep_item);
+  gtk_menu_shell_append (GTK_MENU_SHELL (menu), intro_item);
+  gtk_menu_shell_append (GTK_MENU_SHELL (menu), support_item);
+  gtk_menu_shell_append (GTK_MENU_SHELL (menu), about_item);
+  gtk_menu_shell_append (GTK_MENU_SHELL (menu), quit_item);
+
+
+  /* Attach the callback functions to the respective activate signal */
+  char *desktop = getenv("XDG_CURRENT_DESKTOP");
+  if (desktop && strcmp(desktop, "KDE") == 0) {
+      // KDE does not handle the device-specific "button-press-event" from a menu
+      g_signal_connect(G_OBJECT (toggle_paint_item), "activate",
+		       G_CALLBACK (on_toggle_paint_all),
+		       data);
+  } else {
+      g_signal_connect(toggle_paint_item, "button-press-event",
+		       G_CALLBACK(on_toggle_paint), data);
+  }
+  g_signal_connect(G_OBJECT (clear_item), "activate",
+		   G_CALLBACK (on_clear),
+		   data);
+  g_signal_connect(G_OBJECT (toggle_vis_item), "activate",
+		   G_CALLBACK (on_toggle_vis),
+		   data);
+  g_signal_connect(G_OBJECT (thicker_lines_item), "activate",
+		   G_CALLBACK (on_thicker_lines),
+		   data);
+  g_signal_connect(G_OBJECT (thinner_lines_item), "activate",
+		   G_CALLBACK (on_thinner_lines),
+		   data);
+  g_signal_connect(G_OBJECT (opacity_bigger_item), "activate",
+		   G_CALLBACK (on_opacity_bigger),
+		   data);
+  g_signal_connect(G_OBJECT (opacity_lesser_item), "activate",
+		   G_CALLBACK (on_opacity_lesser),
+		   data);
+  g_signal_connect(G_OBJECT (undo_item), "activate",
+		   G_CALLBACK (on_undo),
+		   data);
+  g_signal_connect(G_OBJECT (redo_item), "activate",
+		   G_CALLBACK (on_redo),
+		   data);
+
+  g_signal_connect(G_OBJECT (intro_item), "activate",
+		   G_CALLBACK (on_intro),
+		   data);
+  g_signal_connect(G_OBJECT (about_item), "activate",
+		   G_CALLBACK (on_about),
+		   NULL);
+  g_signal_connect(G_OBJECT (quit_item), "activate",
+		   G_CALLBACK (gtk_main_quit),
+		   NULL);
+
+
+  /* We do need to show menu items */
+  gtk_widget_show (toggle_paint_item);
+  gtk_widget_show (clear_item);
+  gtk_widget_show (toggle_vis_item);
+  gtk_widget_show (thicker_lines_item);
+  gtk_widget_show (thinner_lines_item);
+  gtk_widget_show (opacity_bigger_item);
+  gtk_widget_show (opacity_lesser_item);
+  gtk_widget_show (undo_item);
+  gtk_widget_show (redo_item);
+
+  gtk_widget_show (sep_item);
+  gtk_widget_show (intro_item);
+  gtk_widget_show (support_item);
+  gtk_widget_show (about_item);
+  gtk_widget_show (quit_item);
+
+
+  app_indicator_set_menu (data->trayicon, GTK_MENU(menu));
+
+  /*
+    Build the support menu
+   */
+  GtkWidget *support_menu = gtk_menu_new ();
+  gtk_menu_item_set_submenu(GTK_MENU_ITEM(support_item), support_menu);
+
+  GtkWidget* support_liberapay_item = gtk_menu_item_new_with_label(_("Via LiberaPay"));
+  GtkWidget* support_patreon_item = gtk_menu_item_new_with_label(_("Via Patreon"));
+  GtkWidget* support_paypal_item = gtk_menu_item_new_with_label(_("Via PayPal"));
+
+  gtk_menu_shell_append (GTK_MENU_SHELL (support_menu), support_liberapay_item);
+  gtk_menu_shell_append (GTK_MENU_SHELL (support_menu), support_patreon_item);
+  gtk_menu_shell_append (GTK_MENU_SHELL (support_menu), support_paypal_item);
+
+  g_signal_connect(G_OBJECT (support_liberapay_item), "activate",
+		   G_CALLBACK (on_support_liberapay),
+		   data);
+  g_signal_connect(G_OBJECT (support_patreon_item), "activate",
+		   G_CALLBACK (on_support_patreon),
+		   data);
+  g_signal_connect(G_OBJECT (support_paypal_item), "activate",
+		   G_CALLBACK (on_support_paypal),
+		   data);
+
+  gtk_widget_show(support_liberapay_item);
+  gtk_widget_show(support_patreon_item);
+  gtk_widget_show(support_paypal_item);
+
+
+  if(data->show_intro_on_startup)
+      on_intro(NULL, data);
+}
+
+
+void parse_print_help (gpointer key, gpointer value, gpointer user_data)
+{
+  paint_context_print ((gchar *) key, (GromitPaintContext *) value);
+}
+
+
+
+/*
+ * Main programs
+ */
+
+int main_client (int argc, char **argv, GromitData *data)
+{
+   GdkAtom   action = GDK_NONE;
+   gint      i;
+   gchar    *arg;
+   gboolean  wrong_arg = FALSE;
+
+   for (i=1; i < argc ; i++)
+     {
+       arg = argv[i];
+       action = GDK_NONE;
+       if (strcmp (arg, "-d") == 0 ||
+           strcmp (arg, "--debug") == 0)
+         {
+           data->debug = 1;
+         }
+       else if (strcmp (arg, "-t") == 0 ||
+           strcmp (arg, "--toggle") == 0)
+         {
+           action = GA_TOGGLE;
+           if (i+1 < argc && argv[i+1][0] != '-') /* there is an id supplied */
+             {
+               data->clientdata  = argv[i+1];
+               ++i;
+             }
+           else
+             data->clientdata = "-1"; /* default to grab all */
+         }
+       else if (strcmp (arg, "-v") == 0 ||
+                strcmp (arg, "--visibility") == 0)
+         {
+           action = GA_VISIBILITY;
+         }
+       else if (strcmp (arg, "-q") == 0 ||
+                strcmp (arg, "--quit") == 0)
+         {
+           action = GA_QUIT;
+         }
+       else if (strcmp (arg, "-c") == 0 ||
+                strcmp (arg, "--clear") == 0)
+         {
+           action = GA_CLEAR;
+         }
+       else if (strcmp (arg, "-r") == 0 ||
+                strcmp (arg, "--reload") == 0)
+         {
+           action = GA_RELOAD;
+         }
+       else if (strcmp (arg, "-z") == 0 ||
+                strcmp (arg, "--undo") == 0)
+         {
+           action = GA_UNDO;
+         }
+       else if (strcmp (arg, "-y") == 0 ||
+                strcmp (arg, "--redo") == 0)
+         {
+           action = GA_REDO;
+         }
+       else
+         {
+           g_printerr ("Unknown Option to control a running Gromit-MPX process: \"%s\"\n", arg);
+           wrong_arg = TRUE;
+         }
+
+       if (!wrong_arg && action != GDK_NONE)
+         {
+           gtk_selection_convert (data->win, GA_CONTROL,
+                                  action, GDK_CURRENT_TIME);
+           gtk_main ();  /* Wait for the response */
+         }
+       else if(wrong_arg)
+         {
+           g_printerr ("Please see the Gromit-MPX manpage for the correct usage\n");
+           return 1;
+         }
+     }
+
+
+   return 0;
+}
+
+int main (int argc, char **argv)
+{
+  GromitData *data;
+
+  /*
+      we run okay under XWayland, but not native Wayland
+  */
+  gdk_set_allowed_backends ("x11");
+
+  gtk_init (&argc, &argv);
+  data = g_malloc0(sizeof (GromitData));
+
+  /* 
+     init basic stuff
+  */
+  data->display = gdk_display_get_default ();
+  data->screen = gdk_display_get_default_screen (data->display);
+  data->xinerama = gdk_screen_get_n_monitors (data->screen) > 1;
+  data->composited = gdk_screen_is_composited (data->screen);
+  data->root = gdk_screen_get_root_window (data->screen);
+  data->width = gdk_screen_get_width (data->screen);
+  data->height = gdk_screen_get_height (data->screen);
+  data->opacity = DEFAULT_OPACITY;
+
+  /*
+    init our window
+  */
+  data->win = gtk_window_new (GTK_WINDOW_POPUP);
+  // this trys to set an alpha channel
+  on_screen_changed(data->win, NULL, data);
+
+  gtk_window_fullscreen(GTK_WINDOW(data->win)); 
+  gtk_window_set_skip_taskbar_hint(GTK_WINDOW(data->win), TRUE);
+  gtk_widget_set_opacity(data->win, data->opacity);
+  gtk_widget_set_app_paintable (data->win, TRUE);
+  gtk_window_set_decorated (GTK_WINDOW (data->win), FALSE);
+
+  gtk_widget_set_size_request (GTK_WIDGET (data->win), data->width, data->height-1);
+
+  gtk_widget_add_events (data->win, GROMIT_WINDOW_EVENTS);
+
+  g_signal_connect (data->win, "delete-event", gtk_main_quit, NULL);
+  g_signal_connect (data->win, "destroy", gtk_main_quit, NULL);
+  /* the selection event handlers will be overwritten if we become a mainapp */
+  g_signal_connect (data->win, "selection_received", 
+		    G_CALLBACK (on_clientapp_selection_received), data);
+  g_signal_connect (data->win, "selection_get",
+		    G_CALLBACK (on_clientapp_selection_get), data);
+  
+  gtk_widget_realize (data->win);
+
+  // try to set transparent for input
+  cairo_region_t* r =  cairo_region_create();
+  gtk_widget_input_shape_combine_region(data->win, r);
+  cairo_region_destroy(r);
+
+  gtk_selection_owner_set (data->win, GA_DATA, GDK_CURRENT_TIME);
+  gtk_selection_add_target (data->win, GA_DATA, GA_TOGGLEDATA, 1007);
+
+
+
+  /* Try to get a status message. If there is a response gromit
+   * is already active.
+   */
+
+  gtk_selection_convert (data->win, GA_CONTROL, GA_STATUS,
+                         GDK_CURRENT_TIME);
+  gtk_main ();  /* Wait for the response */
+
+  if (data->client)
+    return main_client (argc, argv, data);
+
+  /* Main application */
+  setup_main_app (data, argc, argv);
+  gtk_main ();
+  shutdown_input_devices(data);
+  write_keyfile(data); // save keyfile config
+  g_free (data);
+  return 0;
+}
+
+void indicate_active(GromitData *data, gboolean YESNO)
+{
+    if(YESNO)
+	app_indicator_set_icon(data->trayicon, "net.christianbeier.Gromit-MPX.active");
+    else
+	app_indicator_set_icon(data->trayicon, "net.christianbeier.Gromit-MPX");
+}
--- /dev/null
+++ gromit-mpx-1.4/src/main.h
@@ -0,0 +1,173 @@
+/* 
+ * Gromit -- a program for painting on the screen
+ * Copyright (C) 2000 Simon Budig <Simon.Budig@unix-ag.org>
+ *
+ * MPX modifications Copyright (C) 2009 Christian Beier <dontmind@freeshell.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#ifndef GROMIT_MPX_MAIN_H
+#define GROMIT_MPX_MAIN_H
+
+#include "build-config.h"
+
+#include <glib.h>
+#include <glib/gi18n.h>
+#include <gdk/gdk.h>
+#include <gtk/gtk.h>
+#ifdef APPINDICATOR_IS_LEGACY
+#include <libappindicator/app-indicator.h>
+#else
+#include <libayatana-appindicator/app-indicator.h>
+#endif
+
+#define GROMIT_MOUSE_EVENTS ( GDK_BUTTON_MOTION_MASK | \
+                              GDK_BUTTON_PRESS_MASK | \
+                              GDK_BUTTON_RELEASE_MASK )
+
+#define GROMIT_WINDOW_EVENTS ( GROMIT_MOUSE_EVENTS | GDK_EXPOSURE_MASK)
+
+/* Atoms used to control Gromit */
+#define GA_CONTROL    gdk_atom_intern ("Gromit/control", FALSE)
+#define GA_STATUS     gdk_atom_intern ("Gromit/status", FALSE)
+#define GA_QUIT       gdk_atom_intern ("Gromit/quit", FALSE)
+#define GA_ACTIVATE   gdk_atom_intern ("Gromit/activate", FALSE)
+#define GA_DEACTIVATE gdk_atom_intern ("Gromit/deactivate", FALSE)
+#define GA_TOGGLE     gdk_atom_intern ("Gromit/toggle", FALSE)
+#define GA_VISIBILITY gdk_atom_intern ("Gromit/visibility", FALSE)
+#define GA_CLEAR      gdk_atom_intern ("Gromit/clear", FALSE)
+#define GA_RELOAD     gdk_atom_intern ("Gromit/reload", FALSE)
+#define GA_UNDO       gdk_atom_intern ("Gromit/undo", FALSE)
+#define GA_REDO       gdk_atom_intern ("Gromit/redo", FALSE)
+
+#define GA_DATA       gdk_atom_intern ("Gromit/data", FALSE)
+#define GA_TOGGLEDATA gdk_atom_intern ("Gromit/toggledata", FALSE)
+
+#define GROMIT_MAX_UNDO 4
+
+typedef enum
+{
+  GROMIT_PEN,
+  GROMIT_ERASER,
+  GROMIT_RECOLOR
+} GromitPaintType;
+
+typedef struct
+{
+  GromitPaintType type;
+  guint           width;
+  gfloat          arrowsize;
+  guint           minwidth;
+  guint           maxwidth;
+  GdkRGBA         *paint_color;
+  cairo_t         *paint_ctx;
+  gdouble         pressure;
+} GromitPaintContext;
+
+typedef struct
+{
+  gdouble      lastx;
+  gdouble      lasty;
+  guint32      motion_time;
+  GList*       coordlist;
+  GdkDevice*   device;
+  guint        index;
+  guint        state;
+  GromitPaintContext *cur_context;
+  gboolean     is_grabbed;
+  gboolean     was_grabbed;
+  GdkDevice*   lastslave;
+} GromitDeviceData;
+
+
+typedef struct
+{
+  GtkWidget   *win;
+  AppIndicator *trayicon;
+
+  GdkCursor   *paint_cursor;
+  GdkCursor   *erase_cursor;
+
+  GdkDisplay  *display;
+  GdkScreen   *screen;
+  gboolean     xinerama;
+  gboolean     composited;
+  GdkWindow   *root;
+  gchar       *hot_keyval;
+  guint        hot_keycode;
+  gchar       *undo_keyval;
+  guint        undo_keycode;
+  gdouble      opacity;
+
+  GdkRGBA     *white;
+  GdkRGBA     *black;
+  GdkRGBA     *red;
+
+  GromitPaintContext *default_pen;
+  GromitPaintContext *default_eraser;
+ 
+  GHashTable  *tool_config;
+
+  cairo_surface_t *backbuffer;
+
+  GHashTable  *devdatatable;
+
+  guint        timeout_id;
+  guint        modified;
+  guint        delayed;
+  guint        maxwidth;
+  guint        width;
+  guint        height;
+  guint        client;
+  guint        painted;
+  gboolean     hidden;
+  gboolean     debug;
+
+  gchar       *clientdata;
+
+  cairo_surface_t *undobuffer[GROMIT_MAX_UNDO];
+  gint            undo_head, undo_depth, redo_depth;
+
+  gboolean show_intro_on_startup;
+
+} GromitData;
+
+
+void toggle_visibility (GromitData *data);
+void hide_window (GromitData *data);
+void show_window (GromitData *data);
+
+void parse_print_help (gpointer key, gpointer value, gpointer user_data);
+
+void select_tool (GromitData *data, GdkDevice *device, GdkDevice *slave_device, guint state);
+
+void copy_surface (cairo_surface_t *dst, cairo_surface_t *src);
+void swap_surfaces (cairo_surface_t *a, cairo_surface_t *b);
+void snap_undo_state (GromitData *data);
+void undo_drawing (GromitData *data);
+void redo_drawing (GromitData *data);
+
+void clear_screen (GromitData *data);
+
+GromitPaintContext *paint_context_new (GromitData *data, GromitPaintType type,
+				       GdkRGBA *fg_color, guint width, guint arrowsize,
+                                       guint minwidth, guint maxwidth);
+void paint_context_free (GromitPaintContext *context);
+
+void indicate_active(GromitData *data, gboolean YESNO);
+
+#endif
