diff --git a/configs/pepe/syncthing.nix b/configs/pepe/syncthing.nix index 80ff731..288e14e 100644 --- a/configs/pepe/syncthing.nix +++ b/configs/pepe/syncthing.nix @@ -75,6 +75,12 @@ video-material = { enable = true; path = "/media/syncthing/video-material"; + rescanInterval = 8 * 3600; + }; + processing = { + enable = true; + path = "/media/syncthing/sketchbook"; + rescanInterval = 8 * 3600; }; }; diff --git a/configs/sterni/packages.nix b/configs/sterni/packages.nix index 6a679fe..edd3ce4 100644 --- a/configs/sterni/packages.nix +++ b/configs/sterni/packages.nix @@ -23,6 +23,9 @@ in { # foto fuji-cam-wifi-tool + + # processing + processing ]; environment.variables.RECIPE_HOME = "$HOME/mahlzeit"; diff --git a/configs/sterni/syncthing.nix b/configs/sterni/syncthing.nix index 0da38cd..9292c1e 100644 --- a/configs/sterni/syncthing.nix +++ b/configs/sterni/syncthing.nix @@ -61,6 +61,10 @@ enable = true; path = "/home/palo/sync-to-workhorse"; }; + processing = { + enable = true; + path = "/home/palo/sketchbook"; + }; }; }; diff --git a/configs/workhorse/syncthing.nix b/configs/workhorse/syncthing.nix index bacb76f..8023a16 100644 --- a/configs/workhorse/syncthing.nix +++ b/configs/workhorse/syncthing.nix @@ -95,6 +95,11 @@ path = "/media/syncthing/smartphone-folder"; rescanInterval = 8 * 3600; }; + processing = { + enable = true; + path = "/media/syncthing/sketchbook"; + rescanInterval = 8 * 3600; + }; }; }; diff --git a/configs/workout/syncthing.nix b/configs/workout/syncthing.nix index 9fab980..7f137ea 100644 --- a/configs/workout/syncthing.nix +++ b/configs/workout/syncthing.nix @@ -70,6 +70,10 @@ enable = true; path = "/home/palo/zettlr"; }; + processing = { + enable = true; + path = "/home/palo/sketchbook"; + }; }; }; }; diff --git a/pkgs/default.nix b/pkgs/default.nix index c423522..48dc6c7 100644 --- a/pkgs/default.nix +++ b/pkgs/default.nix @@ -46,6 +46,10 @@ in { emo = callPackage ./emoji { }; + processing = callPackage ./processing { + jdk = super.oraclejdk8; + }; + otpmenu = callPackage ./otpmenu { }; taskwarrior-hooks = callPackage ./taskwarrior-hooks { }; diff --git a/pkgs/processing/default.nix b/pkgs/processing/default.nix new file mode 100644 index 0000000..0c5a8e9 --- /dev/null +++ b/pkgs/processing/default.nix @@ -0,0 +1,157 @@ +{ stdenv, lib, jdk, patchelf, makeWrapper, xorg, zip, unzip, rsync, fetchzip +, xdg_utils ? null, gsettings-desktop-schemas ? null }: +let + arch = "linux64"; + libs = (with xorg; [ libXext libX11 libXrender libXtst libXi libXxf86vm ]); + repeatString = n: str: + lib.concatStrings (lib.lists.map (lib.const str) (lib.range 1 n)); +in stdenv.mkDerivation rec { + pname = "processing"; + version = "3.5.4"; + + src = fetchzip { + url = "https://download.processing.org/${pname}-${version}-${arch}.tgz"; + sha256 = "0fqjsa1j05wriwpa7fzvv2rxhhsz6ixqzf52syxr4z74j3wkxk8k"; + }; + + nativeBuildInputs = [ patchelf makeWrapper zip unzip rsync ] + ++ (lib.optional (xdg_utils != null) xdg_utils); + buildInputs = [ jdk ] ++ libs; + + dontConfigure = true; + + # Suppress "Not fond of this Java VM" message box. + # The block of code we're replacing is: + # + # $ javap -v processing/app/platform/LinuxPlatform.class + # 52: ldc #42 // String Not fond of this Java VM + # 54: ldc #44 // String Processing requires Java 8 from Oracle. ... + # 56: aconst_null + # 57: invokestatic #46 // Method processing/app/Messages.showWarning:( + # // Ljava/lang/String;Ljava/lang/String;Ljava/lang/Throwable;)V + # + # which gets written to the .class file as the following bytes: + # + # $ xxd processing/app/platform/LinuxPlatform.class + # 00000c90: .... .... .... .... .... .... .... 122a + # 00000ca0: 122c 01b8 002e .... .... .... .... .... + # + # i.e. 8 bytes starting at 0xc9e (= 3230): + # + # 12 2a | ldc 42 + # 12 2c | ldc 44 + # 01 | aconst_null + # b8 00 2e | invokestatic 46 + # + # We overwrite those instructions with null bytes (`nop`) using `dd`. + # + # See the JVM instruction set specification: + # https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html + # Patching binary files with `dd`: + # https://stackoverflow.com/a/5586379 + + popupSuppress = true; + # Used by sha256sum -- can't be a base-32 Nix hash. + linuxPlatformSHA256 = + "b8ceb19e1c8d022f963d2abfb56abc02b5f037e32042f522e1f2663d0ee8f18d"; + popupClassToPatch = "processing/app/platform/LinuxPlatform.class"; + popupBytesToOverwrite = 8; + popupStartOverwritingAt = 3230; + + buildPhase = lib.optionalString popupSuppress '' + # `unzip` will need to make a directory named `processing`, but right now + # that's a shell script. Move it to the side and we'll move it back when + # we're done. + mv processing processing-bin + + unzip lib/pde.jar $popupClassToPatch + + # Make sure the extracted class has the right checksum -- if + # `LinuxPlatform.class` changes in a future release, we'll need to + # recalculate the correct offset. + echo $linuxPlatformSHA256 $popupClassToPatch \ + | sha256sum --check + + # Overwrite the 8 bytes / 4 instructions. + printf '${repeatString popupBytesToOverwrite "\\x00"}' \ + | dd of=$popupClassToPatch \ + bs=1 \ + seek=$popupStartOverwritingAt \ + conv=notrunc + + # Update `LinuxPlatform.class` in the `.jar`. + zip lib/pde.jar -u $popupClassToPatch + + # Remove the temporary directory named `processing` and move the shell + # script named `processing` back to its original location. + rm -r processing + mv processing-bin processing + ''; + + installPhase = '' + mkdir -p $out/${pname} + rsync --copy-links --safe-links --recursive . $out/${pname} + + # Use our JDK + rm -r $out/${pname}/java + ln -s ${jdk} $out/${pname}/java + + for binary in ${pname} ${pname}-java + do + makeWrapper $out/${pname}/$binary $out/bin/$binary \ + --argv0 $binary \ + ${ + lib.optionalString (gsettings-desktop-schemas == null) + "--prefix XDG_DATA_DIRS : ${gsettings-desktop-schemas}/share/gsettings-schemas/${gsettings-desktop-schemas.name}" + } \ + --prefix _JAVA_OPTIONS " " "-Dawt.useSystemAAFontSettings=lcd" \ + --prefix LD_LIBRARY_PATH : "${xorg.libXxf86vm}/lib" + done + '' + (lib.optionalString (xdg_utils != null) '' + # See: $out/processing/install.sh + resource_name="processing-pde" + desktop_file="$out/${pname}/lib/$resource_name.desktop" + mkdir -p $out/share/{applications,desktop-directories,icons,mime/packages,icons/hicolor} + mkdir -p $out/etc/xdg + + substitute "$out/${pname}/lib/desktop.template" "$desktop_file" \ + --replace "" "$out/bin/processing" \ + --replace "" "$resource_name" + + export XDG_UTILS_INSTALL_MODE="system" + export XDG_DATA_DIRS="$out/share" + export XDG_CONFIG_DIRS="$out/etc/xdg" + + for size in 16 32 48 64 128 256 512 1024 + do + for name in "$resource_name" text-x-processing + do + xdg-icon-resource install \ + --context mimetypes --size "$size" \ + "$out/${pname}/lib/icons/pde-$size.png" "$resource_name" + done + done + + # Install the created *.desktop file + xdg-desktop-menu install "$desktop_file" + + # Install Processing mime type + xdg-mime install "$out/${pname}/lib/$resource_name.xml" + ''); + + meta = with stdenv.lib; { + description = "A language and IDE for electronic arts"; + longDescription = '' + Processing is a flexible software sketchbook and a language for learning + how to code within the context of the visual arts. Since 2001, Processing + has promoted software literacy within the visual arts and visual literacy + within technology. There are tens of thousands of students, artists, + designers, researchers, and hobbyists who use Processing for learning and + prototyping. + ''; + homepage = "https://processing.org"; + downloadPage = "https://processing.org/download/"; + license = licenses.gpl2Plus; + platforms = platforms.linux; + }; +} diff --git a/system/all/syncthing.nix b/system/all/syncthing.nix index 8102696..b7cbbae 100644 --- a/system/all/syncthing.nix +++ b/system/all/syncthing.nix @@ -150,6 +150,15 @@ with lib; { watch = false; devices = [ "workout" "workhorse" "pepe" "mors" ]; }; + processing = { + enable = lib.mkDefault false; + watch = false; + devices = [ "workout" "workhorse" "pepe" "sterni" ]; + versioning = { + type = "simple"; + params.keep = "10"; + }; + }; music-projects = { enable = lib.mkDefault false; id = "acfhu-r4t4f";