A minttyrc for black on white with red block cursor

I don’t particularly like the tradition of light text on dark backgrounds in everything that (shell) coders or Unix admins seem to use. But even the Jetbrains folks provide a Darcula theme now.

Anyway, I want more light in my mintty – which is the default Cygwin terminal – and an easy to find cursor:

oliver@windowsbox ~
$ cat .minttyrc 

BoldAsFont=yes
BoldAsColour=yes
BackgroundColour=240,220,180
ForegroundColour=0,0,0
CursorColour=255,0,0
CursorType=block
Black=0,0,0
BoldBlack=0,0,0
Red=160,0,0
BoldRed=80,0,0
Green=0,160,0
BoldGreen=0,80,0
Yellow=80,80,0
BoldYellow=40,40,0
Blue=0,0,160
BoldBlue=0,0,80
Magenta=100,0,60
BoldMagenta=50,0,30
Cyan=60,0,100
BoldCyan=30,0,50
White=60,60,60
BoldWhite=40,40,40
Font=Lucida Console
FontHeight=10

If you come across other colors that are too light to be readable on white background, just add more ColorName=0,0,0 lines in this file. Make sure you consult the related mintty reference documentation.

For existing work on more beautiful(?) but IMHO less ergonomic palettes of colors, you might want to check out these “Solarized” color configs for mintty.

Open Source games using libgdx

There are these demos.

And I found a list at the bottom of the main libgdx documentation page and used it as a startting point for the list below. I haven’t verified yet whether their respective licensing is covered by the OSI Open source definition.

I am actively maintaining this list, so feel free to send me additions or corrections:

I have also asked for a more comprehensive list on the libgdx forum and on libgdx lead developer Mario Zechner’s blog.

Create single copyright holder, GPL licensed source code repository

I sometimes want to create a source code repository and build process for a GPL licensed software project, where the sole copyright holder (“owner”) is a single legal entity, like a company or a foundation.

This is how I do it:

  • Link to the license from README.md (e.g. the Free Software Foundation’s GPL, version 2)
  • At top of each source file: Copyright notice, license statement, warranty disclaimer
  • Include a plain-text copy of the full license in the root of your distributable package(s)
  • In the README.md, indicate that the project mandates copyright assignment
  • Define the legal agreement process between code contributors and the project owner

The GPL was chosen for its strong copyleft nature and combined with the sole copyright holder approach to enable dual licensing business models.

On sites like github, the code contribution itself is usually done by pull request. The legal agreement process between code contributor and project owner should be complete before the pull request is accepted.

I am not yet sure how to best automate updating the year range in the copyright notice, probably at commit time.

XFCE 4.8 panel : Fix missing Suspend and Hibernate icons

The “Action Buttons” panel plugin of XFCE 4.8 on Debian “wheezy” has a known bug regarding missing icons for the Suspend and Hibernate actions and users will only see a generic placeholder icon.

Ognyan Kulev who reported the bug says this is because most icon themes do not provide icons named “system-suspend” and “system-hibernate”.

As a work-around he suggests linking to the corresponding xfce4-power-manager icons. This fixed the issue on my Debian laptop:

sudo apt-get install xfce4-power-manager-data
cd /usr/share/icons/hicolor/scalable/actions
sudo ln -s xfpm-suspend.svg system-suspend.svg
sudo ln -s xfpm-hibernate.svg system-hibernate.svg
sudo gtk-update-icon-cache-3.0 -f ../..

I saved save the commands into a shell script so I can run it again if the symbolic links get deleted during an apt-get update or accidental apt-get remove:

echo "#! /bin/sh" > /usr/local/bin/fix-xfce-action-icons.sh
chmod ugo+x /usr/local/bin/fix-xfce-action-icons.sh
sudo vim /usr/local/bin/fix-xfce-action-icons.sh

Using libgdx for cross-platform app development

I am looking for a framework that allows me to develop modern apps (mobile, web, desktop) all from one Java codebase. I prefer Java because I know it very well, it is already cross-platform and a statically typed language that allows IntelliJ, Eclipse and Netbeans to be better than any dynamically typed scripting language editor could ever be.

Currently my favorite is libgdx. I am planning to use it with IntelliJ Community Edition and with Maven.

By using RoboVM, libgdx even supports iOS.

For user input (forms) libgdx provides the scene2d.ui widgets. I hope that will be sufficient for most of my UIs. Now I just have to get OpenGL to work on my Linux box …

Java map comparison with detailed error messages using Guava

When you compare two Java maps that are supposed to be equal, i.e. contain the same name/value pairs, you might want to give some details about potential mismatches, for example in your log output.

The Guava library from Google provides a convenient tool for that, namely the class com.google.common.collect.MapDifference.

In the sample code below I have implemented a simple utitily method that compares two maps and logs detailed error messages if they are not equal.

This code is also the first item in my guava-based github project.

Maven dependencies

Put this into pom.xml :

<dependency>
    <groupId>com.google.guava</groupId>
    <artifactId>guava</artifactId>
    <version>16.0</version>
</dependency>
<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-api</artifactId>
    <version>1.7.5</version>
</dependency>

You will also need an slf4j implementation, like logback. For testing, we can use this :

<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-simple</artifactId>
    <version>1.7.5</version>
</dependency>

And for the JUnit tests further below you will need this :

<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.10</version>
    <scope>test</scope>
</dependency>

Java class

Save this as src/main/java/net/doepner/util/MapDiffUtil.java :

package net.doepner.util;

import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.common.collect.MapDifference;
import com.google.common.collect.Maps;

import static com.google.common.collect.MapDifference.ValueDifference;

/**
 * Map comparison with detailed log messages
 */
public class MapDiffUtil {

    private static final Logger log =
        LoggerFactory.getLogger(MapDiffUtil.class);

    public static <K, V> boolean validateEqual(
               Map<K, V> map1, Map<K, V> map2,
               String map1Name, String map2Name) {

        final MapDifference<K, V> diff = Maps.difference(map1, map2);

        if (diff.areEqual()) {
            log.info("Maps '{}' and '{}' contain exactly the same "
                   + "name/value pairs", map1Name, map2Name);
            return true;

        } else {
            logKeys(diff.entriesOnlyOnLeft(), map1Name, map2Name);
            logKeys(diff.entriesOnlyOnRight(), map2Name, map1Name);
            logEntries(diff.entriesDiffering(), map1Name, map2Name);
            return false;
        }
    }

    private static <K, V> void logKeys(
                Map<K, V> mapSubset, String n1, String n2) {
        if (not(mapSubset.isEmpty())) {
            log.error("Keys found in {} but not in {}: {}",
                n1, n2, mapSubset.keySet());
        }
    }

    private static <K, V> void logEntries(
                Map<K, ValueDifference<V>> differing, 
                String n1, String n2) {
        if (not(differing.isEmpty())) {
            log.error("Differing values found {key={}-value,{}-value}: {}",
                        n1, n2, differing);
        }
    }

    private static boolean not(boolean b) {
        return !b;
    }
}

Unit tests

Save this as src/main/java/net/doepner/util/MapDiffUtilTest.java :

package net.doepner.util;

import java.util.HashMap;
import java.util.Map;

import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TestName;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;

/**
 * Tests MapDiffUtil
 */
public class MapDiffUtilTest {

    private final Logger log = LoggerFactory.getLogger(getClass());

    @Rule
    public TestName testName = new TestName();

    @Before
    public void logTestName() {
        log.info("Executing {}", testName.getMethodName());
    }

    @Test
    public void testEqual() {
        final Map<String, Integer> map1 = new HashMap<String, Integer>();
        map1.put("A", 1);
        map1.put("B", 2);

        final Map<String, Integer> map2 = new HashMap<String, Integer>();
        map2.put("B", 2);
        map2.put("A", 1);

        assertTrue("Maps should be equal", MapDiffUtil.validateEqual(
            map1, map2, "map1", "map2"));
    }

    @Test
    public void testSubset() {
        final Map<String, Integer> map1 = new HashMap<String, Integer>();
        map1.put("A", 1);

        final Map<String, Integer> map2 = new HashMap<String, Integer>();
        map2.put("B", 2);
        map2.put("A", 1);

        assertFalse("Maps should be unequal", MapDiffUtil.validateEqual(
            map1, map2, "map1", "map2"));

    }

    @Test
    public void testSeparate() {
        final Map<String, Integer> map1 = new HashMap<String, Integer>();
        map1.put("A", 1);

        final Map<String, Integer> map2 = new HashMap<String, Integer>();
        map2.put("B", 2);

        assertFalse("Maps should be unequal", MapDiffUtil.validateEqual(
            map1, map2, "map1", "map2"));
    }

    @Test
    public void testMismatches() {
        final Map<String, Integer> map1 = new HashMap<String, Integer>();
        map1.put("A", 1);
        map1.put("B", 2);

        final Map<String, Integer> map2 = new HashMap<String, Integer>();
        map2.put("B", 20);
        map2.put("C", 3);

        assertFalse("Maps should be unequal", MapDiffUtil.validateEqual(
            map1, map2, "map1", "map2"));

    }
}

Append entries to Windows user PATH from script or command line

If you have to work in a Windows environment where you do not want to or cannot change the system level PATH, you can usually still use the “setx” command to change the user level PATH variable.

But what if you want to add (append) a directory to the user level PATH? The following would set your user PATH variable to the full (system + user) PATH plus the appended directory.

setx PATH "%PATH%;c:\whatever\else"

But this would duplicate the system PATH into your user PATH variable, which would ultimately cause duplicate entries in the full PATH.

Instead we want to append only to the user PATH variable. Unfortunately, to get its value from the Windows command-line you must query the “HKCU\Environment” registry entry and then parse the relevant part from the output string.

I wrote the add-to-user-path.bat script below to fix the problem. It has been tested on Windows 7, where “req query” uses 4 spaces to delimit its output, and it works even when the user PATH value already contains spaces:

@echo off 
setlocal EnableDelayedExpansion 

if %1.==. ( 
  echo Usage: %0 directory 
  goto End 
) 

for /f "skip=2 tokens=*" %%A in ('reg query "HKCU\Environment" /v PATH') do ( 
   set regstr=%%A
    
   for /f "tokens=3 delims=|" %%X in ("!regstr:    =^|!") do ( 
     setx PATH "%%X;%1" 
     echo PATH changes will only take effect for newly started processes. 
   ) 
) 

:End 

Organize image and video files by creation date with exiftool

I use a simple bash script /usr/local/bin/move-cam-files.sh to let exiftool move photos and videos from our camera to directories on our file server, based on creation date as per media file metadata:

#! /bin/bash -x

move() {
  exiftool -r -v -ext $2 '-directory<DateTimeOriginal' \
           -d "/home/storage/$3/%Y/%m" "$1"
}

# directory where to read media files from is $1
# if unspecified use current directory
dir=${1:-.}

move $dir AVI videos
move $dir JPG photos

Install and maintain Cygwin without Windows admin rights

Sometimes you work on Windows as a restricted user, without admin rights. Like many other good software packages, Cygwin can be installed anyway (see the respective FAQ entry).

These are the steps I used:

  1. Download setup-x86.exe (32bit) or setup-x86_64.exe (64bit).
  2. Run it with the “--no-admin” option
  3. During installation select the “wget” package
  4. Create /usr/local/bin/cygwin-setup.sh (for 32bit omit the “_64”):
    #! /bin/sh
    rm setup-x86_64.exe
    wget http://cygwin.com/setup-x86_64.exe
    chmod u+x setup-x86_64.exe
    run ./setup-x86_64.exe --no-admin
    
  5. Make the script executable:
    chmod ugo+x /usr/local/bin/cygwin-setup.sh
  6. Create a copy of the Cygwin terminal shortcut, rename it “Cygwin setup”
  7. Edit the shortcut target, replace
    mintty.exe -i /Cygwin-Terminal.ico -

    with

    mintty.exe -i /Cygwin-Terminal.ico /bin/bash -l -c 'cygwin-setup.sh'

Whenever you want to run the Cygwin installer to install or remove packages, you can just execute the shortcut or run cygwin-setup.sh from the Cygwin command prompt.

Alternatively, you could also use the pure command-line tool apt-cyg.