]> git.draconx.ca Git - fvwmconf.git/commitdiff
Remove obsolete mpd scripts.
authorNick Bowler <nbowler@draconx.ca>
Fri, 11 Aug 2023 00:35:50 +0000 (20:35 -0400)
committerNick Bowler <nbowler@draconx.ca>
Fri, 11 Aug 2023 00:58:50 +0000 (20:58 -0400)
These scripts should no longer be used as their maintenance has moved
to the "mpdhacks" repository.  We can add that as a git submodule to
achieve a similar level of convenience.

Fix up all the rootmenu scripts to follow the new world order by adding
a new global script that removes most of this code duplication.

As the mpdmenu.pl script is the only user of the MUSIC environment
variable, and it has its own fallback, let's remove the toplevel
assignment of this variable too.

.gitmodules [new file with mode: 0644]
alastor/rootmenu
amythaon/rootmenu
artemis/rootmenu
atropos/rootmenu
config
emergent/rootmenu
gitmodules/mpdhacks [new submodule]
global/mpdmenu [new file with mode: 0644]
scripts/mpdexec.pl [deleted file]
scripts/mpdmenu.pl [deleted file]

diff --git a/.gitmodules b/.gitmodules
new file mode 100644 (file)
index 0000000..c3dbd2f
--- /dev/null
@@ -0,0 +1,3 @@
+[submodule "gitmodules/mpdhacks"]
+       path = gitmodules/mpdhacks
+       url = https://git.draconx.ca/mpdhacks.git
index 39804157c58f26be0aa4d7962c82ad02f85ffebe..1574edf400411b230f7dfae7bff15bf1c7cfba4d 100644 (file)
@@ -1,8 +1,5 @@
 MenuStyle * !TitleWarp
 
-CopyMenuStyle * MenuMPD
-MenuStyle MenuMPD ItemFormat "%.2|%3.5l%.5l%2.3>%-80.5r%.5i%1|"
-
 DestroyMenu MenuFvwmRoot
 AddToMenu   MenuFvwmRoot
 + DynamicPopupAction MakeMenuFvwmRoot
@@ -35,14 +32,3 @@ AddToMenu   MenuNetwork
 DestroyMenu MenuGames
 AddToMenu   MenuGames
 + "Gens%sonic.png%" Exec exec gens
-
-DestroyMenu MenuMPD
-AddToMenu   MenuMPD
-+ DynamicPopUpAction   MakeMenuMPD
-+ DynamicPopDownAction KillMenuMPD
-ChangeMenuStyle MenuMPD MenuMPD
-
-DestroyFunc MakeMenuMPD
-AddToFunc   MakeMenuMPD
-+ I DestroyMenu recreate MenuMPD
-+ I PipeRead "exec $[FVWM_USERDIR]/scripts/mpdmenu.pl --menu MenuMPD"
index 643dff5c9a96e7d48ce7d997fe3eed972da65092..e3b006e820f0d3368ba58e9f1f2533b3592dd3e1 100644 (file)
@@ -1,8 +1,5 @@
 MenuStyle * !TitleWarp
 
-CopyMenuStyle * MenuMPD
-MenuStyle MenuMPD ItemFormat "%.2|%3.5l%.5l%2.3>%-80.5r%.5i%1|"
-
 DestroyMenu MenuFvwmRoot
 AddToMenu   MenuFvwmRoot
 + DynamicPopupAction MakeMenuFvwmRoot
@@ -36,15 +33,4 @@ DestroyMenu MenuGames
 AddToMenu   MenuGames
 + "Gens%sonic.png%" Exec exec gens
 
-DestroyMenu MenuMPD
-AddToMenu   MenuMPD
-+ DynamicPopUpAction   MakeMenuMPD
-+ DynamicPopDownAction KillMenuMPD
-ChangeMenuStyle MenuMPD MenuMPD
-
-DestroyFunc MakeMenuMPD
-AddToFunc   MakeMenuMPD
-+ I DestroyMenu recreate MenuMPD
-+ I PipeRead "exec $[FVWM_USERDIR]/scripts/mpdmenu.pl --menu MenuMPD"
-
 Mouse 3 R A Menu MenuFvwmRoot
index 919d73e15f0ce574090f1a0adde0afca8f15c016..05a3e0e649612b172a86de6a42f07e46f9468ed9 100644 (file)
@@ -1,8 +1,5 @@
 MenuStyle * !TitleWarp
 
-CopyMenuStyle * MenuMPD
-MenuStyle MenuMPD ItemFormat "%.2|%3.5l%.5l%2.3>%-70.5r%.5i%1|"
-
 DestroyMenu MenuFvwmRoot
 AddToMenu   MenuFvwmRoot
 + DynamicPopupAction MakeMenuFvwmRoot
@@ -33,15 +30,4 @@ AddToMenu   MenuNetwork
 + "Valknut%valknut.png%" Exec exec valknut
 + "aMule GUI%amule.png%" Exec exec amulegui
 
-DestroyMenu MenuMPD
-AddToMenu   MenuMPD
-+ DynamicPopUpAction   MakeMenuMPD
-+ DynamicPopDownAction KillMenuMPD
-ChangeMenuStyle MenuMPD MenuMPD
-
-DestroyFunc MakeMenuMPD
-AddToFunc   MakeMenuMPD
-+ I DestroyMenu recreate MenuMPD
-+ I PipeRead "exec $[FVWM_USERDIR]/scripts/mpdmenu.pl --menu MenuMPD"
-
 Mouse 3 R A Menu MenuFvwmRoot
index 1fcf8207cc32b044562d71dd15791172926878ce..acb96500cbb578a571ba616b8457aa7fc88d17a4 100644 (file)
@@ -1,8 +1,5 @@
 MenuStyle * !TitleWarp
 
-CopyMenuStyle * MenuMPD
-MenuStyle MenuMPD ItemFormat "%.2|%3.5l%.5l%2.3>%-80.5r%.5i%1|"
-
 DestroyMenu MenuFvwmRoot
 AddToMenu   MenuFvwmRoot
 + DynamicPopupAction MakeMenuFvwmRoot
@@ -36,15 +33,4 @@ DestroyMenu MenuGames
 AddToMenu   MenuGames
 + "Gens%sonic.png%" Exec exec gens
 
-DestroyMenu MenuMPD
-AddToMenu   MenuMPD
-+ DynamicPopUpAction   MakeMenuMPD
-+ DynamicPopDownAction KillMenuMPD
-ChangeMenuStyle MenuMPD MenuMPD
-
-DestroyFunc MakeMenuMPD
-AddToFunc   MakeMenuMPD
-+ I DestroyMenu recreate MenuMPD
-+ I PipeRead "exec $[FVWM_USERDIR]/scripts/mpdmenu.pl --menu MenuMPD"
-
 Mouse 3 R A Menu MenuFvwmRoot
diff --git a/config b/config
index 43359aefd2a14c265d6d6ac356dc6a9c466a4eeb..c96d3f4a47d09e62a0ab8363577776f3442f0346 100644 (file)
--- a/config
+++ b/config
@@ -9,9 +9,6 @@ DestroyFunc ExitFunction
 SetEnv TERMINAL $[HOME]/bin/urxvt.sh
 PipeRead 'echo SetEnv HOST `hostname`'
 
-SetEnv MPD_HOST aidos
-SetEnv MUSIC /srv/music
-
 SetEnv XMODIFIERS '@im=uim'
 SetEnv GTK_IM_MODULE 'uim'
 SetEnv QT_IM_MODULE 'uim'
@@ -30,6 +27,7 @@ PipeRead "[ -f '$[FVWM_USERDIR]/$[HOST]/config' ] \
          || echo Read default/config"
 
 # Menus (must be loaded after themes)
+Read global/mpdmenu
 Read global/windowmenu
 Read global/alttab
 
index 4b99bc26af16b4d0e507423c2175fbcc0ae99b52..fb7a96149784feb42cc6ea2fffc778bfdf19fd23 100644 (file)
@@ -1,8 +1,5 @@
 MenuStyle * !TitleWarp
 
-CopyMenuStyle * MenuMPD
-MenuStyle MenuMPD ItemFormat "%.2|%3.5l%.5l%2.3>%-65.5r%.5i%1|"
-
 DestroyMenu MenuFvwmRoot
 AddToMenu   MenuFvwmRoot
 + DynamicPopupAction MakeMenuFvwmRoot
@@ -30,15 +27,4 @@ AddToMenu   MenuNetwork
 + "Pan Newsreader%pan.png%" Exec exec env LC_ALL=en_CA.UTF-8 pan
 + "VNC Viewer" Exec exec vncviewer
 
-DestroyMenu MenuMPD
-AddToMenu   MenuMPD
-+ DynamicPopUpAction   MakeMenuMPD
-+ DynamicPopDownAction KillMenuMPD
-ChangeMenuStyle MenuMPD MenuMPD
-
-DestroyFunc MakeMenuMPD
-AddToFunc   MakeMenuMPD
-+ I DestroyMenu recreate MenuMPD
-+ I PipeRead "exec $[FVWM_USERDIR]/scripts/mpdmenu.pl --menu MenuMPD"
-
 Mouse 3 R A Menu MenuFvwmRoot
diff --git a/gitmodules/mpdhacks b/gitmodules/mpdhacks
new file mode 160000 (submodule)
index 0000000..4464a71
--- /dev/null
@@ -0,0 +1 @@
+Subproject commit 4464a71e9bee10cfccfaf652d20c688b13cad11d
diff --git a/global/mpdmenu b/global/mpdmenu
new file mode 100644 (file)
index 0000000..a319211
--- /dev/null
@@ -0,0 +1,24 @@
+# Copyright © 2008-2009, 2019, 2023 Nick Bowler
+#
+# Helper to create the dynamic MPD menu functions.
+#
+# License WTFPL2: Do What The Fuck You Want To Public License, version 2.
+# This is free software: you are free to do what the fuck you want to.
+# There is NO WARRANTY, to the extent permitted by law.
+
+CopyMenuStyle * MenuMPD
+MenuStyle MenuMpd ItemFormat "%.2|%3.5l%.5l%2.3>%-16.3i%1|"
+
+DestroyMenu MenuMPD
+AddToMenu   MenuMPD
++ DynamicPopUpAction   MakeMenuMPD
++ DynamicPopDownAction KillMenuMPD
+ChangeMenuStyle MenuMPD MenuMPD
+
+DestroyFunc MakeMenuMPD
+AddToFunc   MakeMenuMPD
++ I DestroyMenu recreate MenuMPD
++ I PipeRead "exec $[infostore.mpdmenu_cmd] --menu MenuMPD"
+
+Test (!EnvMatch infostore.mpdmenu_cmd *?) \
+  InfoStoreAdd mpdmenu_cmd "$[FVWM_USERDIR]/gitmodules/mpdhacks/mpdmenu.pl"
diff --git a/scripts/mpdexec.pl b/scripts/mpdexec.pl
deleted file mode 100755 (executable)
index 962656f..0000000
+++ /dev/null
@@ -1,72 +0,0 @@
-#!/usr/bin/env perl
-#
-# Copyright © 2012,2019 Nick Bowler
-#
-# Simple program to send a command to MPD.  Each command-line argument is
-# quoted as necessary so it appears as a single argument at the protocol
-# level.  The result is printed to standard output.
-#
-# License WTFPL2: Do What The Fuck You Want To Public License, version 2.
-# This is free software: you are free to do what the fuck you want to.
-# There is NO WARRANTY, to the extent permitted by law.
-
-use strict;
-
-use utf8;
-
-use Encode::Locale qw(decode_argv);
-decode_argv(Encode::FB_CROAK);
-
-binmode(STDOUT, ":utf8");
-binmode(STDIN, ":utf8");
-use IO::Socket::INET6;
-
-my $host = $ENV{MPD_HOST} // "localhost";
-my $port = $ENV{MPD_PORT} // 6600;
-
-my $sock = new IO::Socket::INET6(
-       PeerAddr => $host,
-       PeerPort => $port,
-       Proto    => 'tcp',
-) or die "failed to connect to MPD: $!";
-binmode($sock, ":utf8");
-
-if (!(<$sock> =~ /^OK MPD ([0-9]+)\.([0-9]+)\.([0-9]+)$/)) {
-       die "MPD failed to announce version: $!";
-}
-
-sub mpd_escape {
-       ($_) = @_;
-
-       # No way to encode literal newlines in the protocol, so we convert
-       # any newlines in the arguments into a space, which can help with
-       # shell quoting.
-       s/\n/ /g;
-
-       if (/[ \t\\"]/) {
-               s/[\\"]/\\$&/g;
-               return "\"$_\"";
-       }
-       return $_;
-}
-
-sub mpd_exec {
-       print $sock join(' ', @_), "\n";
-       while (<$sock>) {
-               last if (/^OK/);
-               print;
-               exit 1 if (/^ACK/);
-       }
-}
-
-if (@ARGV) {
-       mpd_exec(map { mpd_escape($_) } @ARGV)
-} else {
-       while (<>) {
-               chomp;
-               mpd_exec($_);
-       }
-}
-
-print $sock "close\n";
-close $sock;
diff --git a/scripts/mpdmenu.pl b/scripts/mpdmenu.pl
deleted file mode 100755 (executable)
index c36fad7..0000000
+++ /dev/null
@@ -1,438 +0,0 @@
-#!/usr/bin/perl
-#
-# Copyright © 2018,2010,2012,2019 Nick Bowler
-#
-# Silly little script to generate an FVWM menu with various bits of MPD
-# status information and controls.
-#
-# License WTFPL2: Do What The Fuck You Want To Public License, version 2.
-# This is free software: you are free to do what the fuck you want to.
-# There is NO WARRANTY, to the extent permitted by law.
-
-use strict;
-
-use Getopt::Long;
-use IO::Socket::INET6;
-
-use constant {
-       MPD_MJR_MIN => 0,
-       MPD_MNR_MIN => 13,
-       MPD_REV_MIN => 0,
-};
-
-use utf8;
-use open qw(:std :utf8);
-binmode(STDOUT, ":utf8");
-use Encode;
-
-sub cmd
-{
-       print "$_[0]\n";
-}
-
-# Global hash for tracking what is to be "accepted".
-my %accept = ();
-
-my $FVWM = (defined $ENV{FVWM_USERDIR}) ? $ENV{FVWM_USERDIR}
-                                        : $ENV{HOME}."/.fvwm";
-my $icons = "$FVWM/icons";
-
-# Default values for stuff.
-my ($album, $artist, $title, $menu) = (undef, undef, undef, undef);
-my $host = (defined $ENV{MPD_HOST}) ? $ENV{MPD_HOST} : "localhost";
-my $port = (defined $ENV{MPD_PORT}) ? $ENV{MPD_PORT} : "6600";
-
-GetOptions(
-       'host|h=s'   => \&host,   # Host that MPD is running on.
-       'port|p=s'   => \&port,   # Port that MPD is listening on.
-       'menu|m=s'   => \$menu,   # Name of the menu to create.
-       'album=s'    => \$album,  # Album to get tracks from
-       'artist=s'   => \$artist, # Artist to limit results to
-       'title=s'    => \$title,  # Title to create menu for
-);
-
-$album  = decode_utf8($album)  if defined($album);
-$artist = decode_utf8($artist) if defined($artist);
-$title  = decode_utf8($title)  if defined($title);;
-
-# Connect to MPD.
-my $sock = new IO::Socket::INET6(
-       PeerAddr => $host,
-       PeerPort => $port,
-       Proto => 'tcp',
-       Timeout => 2
-) or die("could not open socket: $!.\n");
-binmode($sock, ":utf8");
-
-die("could not connect to MPD: $!.\n")
-       if (!(<$sock> =~ /^OK MPD ([0-9]+)\.([0-9]+)\.([0-9]+)$/));
-
-die("MPD version $1.$2.$3 insufficient.\n")
-       if (  ($1 <  MPD_MJR_MIN)
-          || ($1 == MPD_MJR_MIN && $2 <  MPD_MNR_MIN)
-          || ($1 == MPD_MJR_MIN && $2 == MPD_MNR_MIN && $3 < MPD_REV_MIN));
-
-if (defined $album) {
-       # Create an album menu.
-       my @playlist = ();
-       my $entry;
-
-       $menu = "MenuMPDAlbum" unless defined $menu;
-
-       $album =~ s/"/\\"/g;
-       print $sock "playlistfind album \"$album\"\n";
-       while (<$sock>) {
-               last if (/^OK/);
-               die($_) if (/^ACK/);
-
-               if (/^(\w+): (.*)$/) {
-                       if ($1 eq "file") {
-                               if (keys(%$entry) > 0) {
-                                       addalbumentry(\@playlist, $entry)
-                               }
-
-                               $entry = {};
-                       }
-
-                       $entry->{$1} = $2;
-               }
-       }
-       addalbumentry(\@playlist, $entry) if (keys(%$entry) > 0);
-
-       die("No tracks found.\n") if (!@playlist);
-       foreach (sort albumsort @playlist) {
-               my ($t_file, $t_trackno, $t_artist, $t_title, $t_id) = (
-                       $_->{file},
-                       $_->{Track},
-                       $_->{Artist},
-                       $_->{Title},
-                       $_->{Id},
-               );
-
-               next if (defined $artist && !$accept{albumdir($t_file)});
-
-               $t_artist = sanitise($t_artist, 0);
-               $t_title  = sanitise($t_title, 0);
-
-               my $cmd = sprintf "AddToMenu $menu \"%d\t%s - %s\""
-                                 ." Exec exec $FVWM/scripts/mpdexec.pl"
-                                 ." playid %d",
-                                 $t_trackno, $t_artist, $t_title, $t_id;
-
-               cmd($cmd);
-       }
-} elsif (defined $artist) {
-       # Create an artist menu.
-       my %albums = ();
-       my $file;
-       my $quoteartist = $artist;
-
-       $menu = "MenuMPDArtist" unless defined $menu;
-
-       $quoteartist =~ s/"/\\"/g;
-       print $sock "playlistfind artist \"$quoteartist\"\n";
-       while (<$sock>) {
-               last if (/^OK/);
-               die($_) if (/^ACK/);
-
-               if (/^(\w+): (.*)$/) {
-                       $file       = $2    if ($1 eq "file");
-                       $albums{$2} = $file if ($1 eq "Album");
-               }
-       }
-
-       die("No albums found.\n") if (!keys(%albums));
-
-{ # work around 'use locale' breaking s///i
-       my $i = 0;
-       use locale;
-       foreach (sort keys(%albums)) {
-               my $key      = $_;
-               my $a_album  = sanitise($key, 1);
-
-               open THUMB, "-|", "$FVWM/scripts/thumbnail.zsh",
-                                        "--small", "--music", $albums{$key};
-               my $thumb = <THUMB>;
-               close THUMB;
-               die("Incompetent use of thumbnail.zsh") if ($?);
-
-               $thumb =~ s/\n//sg;
-               $thumb = "%$thumb%" if (-f $thumb);
-
-               cmd("AddToMenu $menu \"$thumb$a_album\" Popup MenuMPDArt_$i");
-
-               cmd("AddToMenu MenuMPDArt_$i DynamicPopUpAction MakeMenuMPDArt_$i");
-
-               cmd("DestroyFunc MakeMenuMPDArt_$i");
-               cmd("AddToFunc   MakeMenuMPDArt_$i
-                    + I DestroyMenu MenuMPDArt_$i
-                    + I -PipeRead \"exec $FVWM/scripts/mpdmenu.pl "
-                          ."--menu MenuMPDArt_$i "
-                          ."--album  ".shellify($key, 1)." "
-                          ."--artist ".shellify($artist, 1)."\"");
-
-               cmd("AddToFunc KillMenuMPD I DestroyMenu MenuMPDArt_$i");
-               cmd("AddToFunc KillMenuMPD I DestroyFunc MakeMenuMPDArt_$i");
-
-               $i++;
-       }
-} # end use locale workaround
-} elsif (defined $title) {
-       # Create a title menu.
-       my @titles;
-       my $entry;
-
-       $menu = "MenuMPDTitle" unless defined $menu;
-
-       # Open and close brackets.
-       my ($ob, $cb) = ("[\[~〜<〈(ー−-]", "[\]~〜>〉)ー−-]");
-
-       $_ = $title;
-
-       # Deal with specific cases.
-       s/ちいさな(?=ヘミソフィア)//;                 # ヘミソフィア
-       s/ "mix on air flavor" dear EIKO SHIMAMIYA//; # Spiral wind
-       s/ "So,you need me" Style//;                  # I need you
-       s/ ::Symphony Second movement:://;            # Disintegration
-       s/-\[instrumental\]//;                        # 青い果実
-       s/ -Practice Track-//;                        # Fair Heaven
-       s/〜世界で一番アナタが好き〜//;               # Pure Heart
-       s/〜彼方への哀歌//;                           # 十二幻夢
-       s/ sora no uta ver.//;                       # 美しい星
-
-       s/\s*-remix-$//; # Otherwise "D-THREAD -remix-" doesn't work right.
-
-       # Deal with titles like "blah (ABC version)".
-       s/\s*$ob.*(style|mix|edit|edition|ver\.?|version|melody|カラオケ)$cb?$//i;
-
-       # Deal with titles like "blah (without XYZ)".
-       s/\s*$ob\s*((e\.)?piano|english|japanese|inst|tv|without|w\/o|off|back|short|karaoke|game).*//i;
-
-       # Deal with titles like "blah instrumental".
-       s/\s+(instrumental|off vocal|short|tv)([\s-]+(mix|size|version))?$//i;
-       s/\s+without\s+\w+$//i;
-
-       # Deal with separate movements in classical pieces.
-       s/: [IVX]+\..*//;
-
-       my $basetitle  = $_;
-       my $_basetitle = $basetitle;
-
-       $_basetitle =~ s/"/\\"/g;
-       print $sock "playlistsearch title \"$_basetitle\"\n";
-       while (<$sock>) {
-               last if (/^OK/);
-               die($_) if (/^ACK/);
-
-               if (/^(\w+): (.*)$/) {
-                       if ($1 eq "file") {
-                               push @titles, $entry if (keys(%$entry) > 0);
-                               $entry = {};
-                       }
-
-                       $entry->{$1} = $2;
-               }
-       }
-       push @titles, $entry if (keys(%$entry) > 0);
-
-{ # work around 'use locale' breaking s///i
-       use locale;
-       foreach (sort titlesort @titles) {
-               my ($t_file, $t_artist, $t_title, $t_id) = (
-                       $_->{file},
-                       $_->{Artist},
-                       $_->{Title},
-                       $_->{Id},
-               );
-
-               # MPD searches are case-insensitive.
-               next if (!($t_title =~ m/(\P{Latin}|^)\Q$basetitle\E(\P{Latin}|$)/ || $t_title =~ m/\Q$basetitle\E/i));
-
-               $t_artist = sanitise($t_artist, 1);
-               $t_title  = sanitise($t_title, 1);
-
-               open THUMB, "-|", "$FVWM/scripts/thumbnail.zsh",
-                                        "--small", "--music", $t_file;
-               my $thumb = <THUMB>;
-               close(THUMB);
-               die("Incompetent use of thumbnail.zsh") if ($?);
-
-               $thumb =~ s/\n//sg;
-               $thumb = "%$thumb%" if (-f $thumb);
-
-               cmd("AddToMenu $menu \"$thumb$t_artist - $t_title\""
-                   ." Exec exec $FVWM/scripts/mpdexec.pl"
-                   ." playid $t_id");
-       }
-} # end use locale workaround
-} else {
-       # Make MPD base menu
-       my ($state, $songid) = (undef, undef);
-       my %entry = ();
-
-       $menu = "MenuMPD" unless defined $menu;
-
-       print $sock "status\n";
-       while (<$sock>) {
-               last if (/^OK/);
-               die($_) if (/^ACK/);
-
-               if (/^(\w+): (.*)$/) {
-                       $state  = $2 if ($1 eq "state");
-                       $songid = $2 if ($1 eq "songid");
-               }
-       }
-       die("Failed status query\n") unless (defined $state);
-
-       cmd("AddToMenu $menu Playing Title") if ($state eq "play");
-       cmd("AddToMenu $menu Paused Title")  if ($state eq "pause");
-       cmd("AddToMenu $menu Stopped Title") if ($state eq "stop");
-
-       if (defined $songid) {
-               print $sock "playlistid $songid\n";
-               while (<$sock>) {
-                       last if (/^OK/);
-                       die($_) if (/^ACK/);
-
-                       if (/^(\w+): (.*)$/) {
-                               $entry{$1} = $2;
-                       }
-               }
-               die("Failed data query\n") unless (keys(%entry) > 0);
-
-               open THUMB, "-|", "$FVWM/scripts/thumbnail.zsh",
-                                        "--image", "--music",  $entry{file};
-               my $thumb = <THUMB>;
-               my $scan  = <THUMB>;
-               close(THUMB);
-               die("Incompetent use of thumbnail.sh") if ($?);
-
-               $thumb =~ s/\n//sg;
-               $scan  =~ s/\n//sg;
-
-               if (-f $thumb) {
-                       cmd("AddToMenu $menu \"*$thumb*\" "
-                               ."Exec exec geeqie ".shellify($scan, 0));
-               }
-               cmd("AddToMenu $menu \"Title:   ".sanitise($entry{Title}, 0)
-                       ."\" Popup MenuMPDTitle");
-               cmd("AddToMenu $menu \"Artist:  ".sanitise($entry{Artist}, 0)
-                       ."\" Popup MenuMPDArtist");
-               cmd("AddToMenu $menu \"Album:   ".sanitise($entry{Album}, 0)
-                       ."\" Popup MenuMPDAlbum");
-               cmd("AddToMenu $menu \"\" Nop");
-       } else {
-               cmd("AddToMenu $menu \"<Song info unavailable>\"");
-               cmd("AddToMenu $menu \"\" Nop");
-       }
-
-       if ($state eq "play" || $state eq "pause") {
-               cmd("AddToMenu $menu \"\t\tNext%$icons/next.svg:16x16%\" "
-                       ."Exec exec $FVWM/scripts/mpdexec.pl next");
-               cmd("AddToMenu $menu \"\t\tPause%$icons/pause.svg:16x16%\" "
-                       ."Exec exec $FVWM/scripts/mpdexec.pl pause");
-               cmd("AddToMenu $menu \"\t\tPlay%$icons/play.svg:16x16%\" "
-                       ."Exec exec $FVWM/scripts/mpdexec.pl play");
-               cmd("AddToMenu $menu \"\t\tStop%$icons/stop.svg:16x16%\" "
-                       ."Exec exec $FVWM/scripts/mpdexec.pl stop");
-               cmd("AddToMenu $menu \"\t\tPrev%$icons/prev.svg:16x16%\" "
-                       ."Exec exec $FVWM/scripts/mpdexec.pl previous");
-       } elsif ($state eq "stop") {
-               cmd("AddToMenu $menu \"\t\tPlay%$icons/play.svg:16x16%\" "
-                       ."Exec exec $FVWM/scripts/mpdexec.pl play");
-       } else {
-               die("Unknown MPD state!\n");
-       }
-
-       cmd("AddToMenu $menu \"\" Nop");
-       cmd("AddToMenu $menu \"\t\tShuffle%$icons/shuffle.svg:16x16%\" "
-               ."Exec exec $FVWM/scripts/mpdexec.pl shuffle");
-
-       cmd("DestroyMenu MenuMPDTitle");
-       cmd("AddToMenu   MenuMPDTitle  DynamicPopUpAction MakeMenuMPDTitle");
-       cmd("DestroyMenu MenuMPDArtist");
-       cmd("AddToMenu   MenuMPDArtist DynamicPopUpAction MakeMenuMPDArtist");
-       cmd("DestroyMenu MenuMPDAlbum");
-       cmd("AddToMenu   MenuMPDAlbum  DynamicPopUpAction MakeMenuMPDAlbum");
-
-       cmd("DestroyFunc MakeMenuMPDTitle");
-       cmd("AddToFunc   MakeMenuMPDTitle
-            + I DestroyMenu MenuMPDTitle
-            + I -PipeRead \"exec $FVWM/scripts/mpdmenu.pl "
-                          ."--menu MenuMPDTitle "
-                          ."--title ".shellify($entry{Title}, 1)."\"");
-
-       cmd("DestroyFunc MakeMenuMPDAlbum");
-       cmd("AddToFunc   MakeMenuMPDAlbum
-            + I DestroyMenu MenuMPDAlbum
-            + I -PipeRead \"exec $FVWM/scripts/mpdmenu.pl "
-                          ."--menu MenuMPDAlbum "
-                          ."--album  ".shellify($entry{Album}, 1)." "
-                          ."--artist ".shellify($entry{Artist}, 1)."\"");
-
-       cmd("DestroyFunc MakeMenuMPDArtist");
-       cmd("AddToFunc   MakeMenuMPDArtist
-            + I DestroyMenu MenuMPDArtist
-            + I -PipeRead \"exec $FVWM/scripts/mpdmenu.pl "
-                          ."--menu MenuMPDArtist "
-                          ."--artist ".shellify($entry{Artist}, 1)."\"");
-
-       cmd("DestroyFunc KillMenuMPD");
-       cmd("AddToFunc   KillMenuMPD I Nop");
-}
-
-# Finished.
-print $sock "close\n";
-
-sub sanitise
-{
-       $_ = $_[0];
-       s/&/&&/g if ($_[1]);
-       s/([\$@%^*])/\1\1/g;
-       s/"/\\"/g;
-       return $_;
-}
-
-sub addalbumentry
-{
-       my ($playlist, $entry) = @_;
-
-       push(@$playlist, $entry);
-
-       if (defined $artist && $artist eq $entry->{Artist}) {
-               my $albumdir = albumdir($entry->{file});
-               $accept{$albumdir} = 1;
-       }
-}
-
-sub albumdir
-{
-       my $file = $_[0];
-
-       $file =~ s:(/Disk [0-9]+[^/]*)?/[^/]*$::;
-       return $file
-}
-
-sub albumsort
-{
-       return ($a->{Disc} <=> $b->{Disc}) if ($a->{Disc} != $b->{Disc});
-       return ($a->{Track} <=> $b->{Track});
-}
-
-sub titlesort
-{
-       return ($a->{Album}  cmp $b->{Album})  if($a->{Album}  ne $b->{Album});
-       return ($a->{Artist} cmp $b->{Artist}) if($a->{Artist} ne $b->{Artist});
-       return ($a->{Title}  cmp $b->{Title});
-}
-
-sub shellify
-{
-       my ($str, $quoted) = @_;
-       $str =~ s/'/'\\''/g;
-       if ($quoted) {
-               $str =~ s/\\/\\\\/g;
-               $str =~ s/"/\\"/g;
-       }
-       return "'$str'";
-}