about summary refs log tree commit diff
path: root/pkgs
diff options
context:
space:
mode:
Diffstat (limited to 'pkgs')
-rwxr-xr-xpkgs/aacolorize/aacolorize.py182
-rw-r--r--pkgs/aacolorize/default.nix13
-rw-r--r--pkgs/axbo/default.nix49
-rw-r--r--pkgs/beehive/default.nix17
-rw-r--r--pkgs/beehive/godeps.nix378
-rw-r--r--pkgs/blop/default.nix16
-rw-r--r--pkgs/build-support/channel.nix32
-rw-r--r--pkgs/default.nix31
-rw-r--r--pkgs/games/COPYING20
-rw-r--r--pkgs/games/LICENSE.APACHE202
-rw-r--r--pkgs/games/base-module.nix15
-rw-r--r--pkgs/games/default.nix25
-rw-r--r--pkgs/games/humblebundle/bastion.nix62
-rw-r--r--pkgs/games/humblebundle/cavestoryplus.nix39
-rw-r--r--pkgs/games/humblebundle/default.nix50
-rw-r--r--pkgs/games/humblebundle/fetch-humble-bundle/default.nix87
-rw-r--r--pkgs/games/humblebundle/fez.nix35
-rw-r--r--pkgs/games/humblebundle/ftl.nix38
-rw-r--r--pkgs/games/humblebundle/guacamelee.nix61
-rw-r--r--pkgs/games/humblebundle/hammerwatch.nix40
-rw-r--r--pkgs/games/humblebundle/jamestown.nix55
-rw-r--r--pkgs/games/humblebundle/liads.nix43
-rw-r--r--pkgs/games/humblebundle/megabytepunch.nix18
-rw-r--r--pkgs/games/humblebundle/rocketbirds.nix11
-rw-r--r--pkgs/games/humblebundle/spaz.nix39
-rw-r--r--pkgs/games/humblebundle/swordsandsoldiers.nix43
-rw-r--r--pkgs/games/humblebundle/unepic.nix44
-rw-r--r--pkgs/games/steam/default.nix38
-rw-r--r--pkgs/games/steam/fetchsteam/default.nix91
-rw-r--r--pkgs/games/steam/fetchsteam/downloader.patch34
-rw-r--r--pkgs/games/steam/starbound.nix132
-rw-r--r--pkgs/grandpa/default.nix20
-rw-r--r--pkgs/greybird-xfce-theme/default.nix26
-rw-r--r--pkgs/kpatches/bfqsched/default.nix45
-rw-r--r--pkgs/libcmt/default.nix25
-rw-r--r--pkgs/librxtx-java/default.nix29
-rw-r--r--pkgs/list-gamecontrollers/default.nix10
-rw-r--r--pkgs/list-gamecontrollers/list-gc.c31
-rw-r--r--pkgs/lockdev/default.nix23
-rw-r--r--pkgs/nixops/default.nix37
-rw-r--r--pkgs/pvolctrl/default.nix35
-rw-r--r--pkgs/show-qr-code/default.nix28
-rw-r--r--pkgs/sidplayfp/default.nix29
-rw-r--r--pkgs/tkabber-urgent-plugin/default.nix26
-rw-r--r--pkgs/tomahawk/default.nix89
-rw-r--r--pkgs/twitchstream/default.nix112
46 files changed, 2505 insertions, 0 deletions
diff --git a/pkgs/aacolorize/aacolorize.py b/pkgs/aacolorize/aacolorize.py
new file mode 100755
index 00000000..ff19b687
--- /dev/null
+++ b/pkgs/aacolorize/aacolorize.py
@@ -0,0 +1,182 @@
+#!/usr/bin/env python
+import os
+import sys
+
+from optparse import Option, OptionParser
+
+COLORS = {
+    "k": (30, "Black"),
+    "r": (31, "Red"),
+    "g": (32, "Green"),
+    "y": (33, "Yellow"),
+    "b": (34, "Blue"),
+    "p": (35, "Pink"),
+    "c": (36, "Cyan"),
+    "w": (37, "White"),
+}
+
+ESC = chr(27)
+
+class ColorizeError(Exception):
+    pass
+
+class Color(object):
+    def __init__(self, ident=None):
+        """
+        Initialize a color object, if no `ident` is given or it's invalid,
+        the Color object represents "no color".
+        """
+        if ident is not None:
+            spec = COLORS.get(ident.lower(), None)
+        else:
+            spec = None
+
+        if spec is None:
+            self.ident = None
+            self.bold = False
+            self.code = None
+            self.name = "None"
+        else:
+            self.ident = ident
+            self.code, self.name = spec
+
+            if ident.isupper():
+                self.bold = True
+            else:
+                self.bold = False
+
+    @property
+    def attrs(self):
+        """
+        A tuple consisting of the SGR attributes.
+        """
+        if self.ident is None:
+            return ()
+
+        if self.bold:
+            return (1, self.code)
+        else:
+            return (self.code,)
+
+    def sgr_attrs(self, *attrs):
+        """
+        Return the attributes specified by `attrs` formatted according
+        to the CSI specification.
+        """
+        return ';'.join(map(lambda c: str(c), attrs))
+
+    def sgr(self, *attrs):
+        """
+        Start Set Graphics Rendition
+        Return the CSI escape code for `attrs`.
+        """
+        return "%s[%sm" % (ESC, self.sgr_attrs(*attrs))
+
+    def sgr_start(self):
+        """
+        Start Set Graphics Rendition
+        Return the CSI start escape code for the current color.
+        """
+        return self.sgr(*self.attrs)
+
+    def sgr_stop(self):
+        """
+        Clear Set Graphics Rendition
+        """
+        return self.sgr()
+
+    def apply(self, value):
+        """
+        Apply the current color to the string in `value`.
+        """
+        return "%s%s%s" % (self.sgr_start(), value, self.sgr_stop())
+
+    def describe(self):
+        """
+        Return the description of the current color IN color :-)
+        """
+        fmt = "%c: <ESC>[%sm -> [%s]"
+        return fmt % (
+            self.ident,
+            self.sgr_attrs(*self.attrs),
+            self.apply(self.name)
+        )
+
+    def transform_to(self, new_color):
+        """
+        Return the CSI sequences needed to transform into `new_color`.
+        """
+        if self.ident is None and new_color.ident is not None:
+            return new_color.sgr_start()
+        elif self.ident is not None and new_color.ident is None:
+            return self.sgr_stop()
+        elif self.ident is None and new_color.ident is None:
+            return ''
+        elif self.code == new_color.code:
+            if not self.bold and new_color.bold:
+                return self.sgr(1)
+            elif self.bold and not new_color.bold:
+                return self.sgr(22)
+            elif self.bold == new_color.bold:
+                return ''
+        else:
+            if self.bold and new_color.bold:
+                return new_color.sgr(new_color.code)
+
+        return self.sgr_stop()+new_color.sgr_start()
+
+    def __repr__(self):
+        if self.bold:
+            return "<Bold color %s>" % self.name.lower()
+        else:
+            return "<Color %s>" % self.name.lower()
+
+def print_colortable():
+    for ident in COLORS.iterkeys():
+        normal = Color(ident).describe()
+        bold = Color(ident.upper()).describe()
+        sys.stdout.write("%-35s%s\n" % (normal, bold))
+
+def colorize_art(art, colmap):
+    if len(art) != len(colmap):
+        raise ColorizeError("Art and colormap differ in size!")
+
+    no_color = Color()
+
+    out = ""
+    last_color = no_color
+    for i, char in enumerate(colmap):
+        color = Color(char)
+        out += last_color.transform_to(color) + art[i]
+        last_color = color
+
+    last_color.transform_to(no_color)
+
+    return out
+
+def colorize_file(artfile, mapfile=None):
+    if mapfile is None:
+        mapfile = os.path.splitext(artfile)[0]+'.colmap'
+
+    asciiart = open(artfile, 'r').read()
+    colormap = open(mapfile, 'r').read()
+
+    return colorize_art(asciiart, colormap)
+
+if __name__ == "__main__":
+    parser = OptionParser(usage="%prog [options] artfile [mapfile]")
+    parser.add_option("-t", "--table", action="store_true", dest="table",
+                      help="Show color table and exit.")
+
+    (options, args) = parser.parse_args()
+
+    if options.table:
+        print_colortable()
+        parser.exit()
+
+    if not len(args) in (1, 2):
+        parser.print_help()
+        parser.exit()
+    else:
+        colorized = colorize_file(*args)
+        sys.stdout.write(colorized)
diff --git a/pkgs/aacolorize/default.nix b/pkgs/aacolorize/default.nix
new file mode 100644
index 00000000..a7a3c3f1
--- /dev/null
+++ b/pkgs/aacolorize/default.nix
@@ -0,0 +1,13 @@
+{ buildPythonPackage, runCommand }:
+
+buildPythonPackage {
+  name = "aacolorize";
+  src = runCommand "aacolorize-src" {} ''
+    mkdir -p "$out"
+    cp "${./aacolorize.py}" "$out/aacolorize"
+    cat > "$out/setup.py" <<SETUP
+    from distutils.core import setup
+    setup(name='aacolorize', scripts=['aacolorize'])
+    SETUP
+  '';
+}
diff --git a/pkgs/axbo/default.nix b/pkgs/axbo/default.nix
new file mode 100644
index 00000000..93f8ffad
--- /dev/null
+++ b/pkgs/axbo/default.nix
@@ -0,0 +1,49 @@
+{ stdenv, fetchurl, fetchFromGitHub, jdk, jre, ant, makeWrapper
+, commonsLogging, librxtx_java
+}:
+
+stdenv.mkDerivation rec {
+  name = "axbo-research-${version}";
+  version = "3.0.12";
+
+  src = fetchFromGitHub {
+    owner = "jansolo";
+    repo = "aXbo-research";
+    rev = "aXbo-research_${version}";
+    sha256 = "0p2my5bczmwnrs3c0l9wyq3gsc5vydw0nh9n8jkdp9vm77z0kgvd";
+  };
+
+  sourceRoot = "${src.name}/aXbo-research";
+
+  buildInputs = [ jdk ant makeWrapper ];
+
+  buildPhase = ''
+    ant -Dplatforms.JDK_1.7.home="$JAVA_HOME" jar
+  '';
+
+  extraJars = [
+    "commons-beanutils-1.8.3"
+    "commons-digester3-3.2"
+    "jcommon-1.0.20"
+    "jfreechart-1.0.16"
+    "swingx-all-1.6.4"
+  ];
+
+  installPhase = with stdenv.lib; let
+    classpath = makeSearchPath "share/java/\\*" [
+      "$out"
+      commonsLogging
+      librxtx_java
+    ];
+  in ''
+    for dep in $extraJars; do
+      install -vD -m 644 "lib/$dep.jar" "$out/share/java/$dep.jar"
+    done
+    install -vD -m 644 dist/axbo.jar "$out/share/java/axbo.jar"
+
+    mkdir -p "$out/bin"
+    makeWrapper "${jre}/bin/java" "$out/bin/axbo-research" \
+      --add-flags "-Djava.library.path='${librxtx_java}/lib'" \
+      --add-flags "-cp ${classpath} com.dreikraft.axbo.Axbo"
+  '';
+}
diff --git a/pkgs/beehive/default.nix b/pkgs/beehive/default.nix
new file mode 100644
index 00000000..7fcca398
--- /dev/null
+++ b/pkgs/beehive/default.nix
@@ -0,0 +1,17 @@
+{ goPackages, lib, fetchFromGitHub, fetchhg, fetchgit }:
+
+goPackages.buildGoPackage {
+  name = "beehive";
+  goPackagePath = "github.com/muesli/beehive";
+  src = fetchFromGitHub {
+    owner = "muesli";
+    repo = "beehive";
+    rev = "74a7fc4927b8ef14b199254e04630c24f44429f7";
+    sha256 = "1clgc6245yb3yxqdc14xj0f8hc8v4b9hgkv22c89zp0n1by8xrqx";
+  };
+  buildInputs = lib.mapAttrsToList (name: val: val) (import ./godeps.nix {
+    inherit (goPackages) buildGoPackage;
+    inherit lib fetchFromGitHub fetchhg fetchgit;
+  });
+  meta.broken = true;
+}
diff --git a/pkgs/beehive/godeps.nix b/pkgs/beehive/godeps.nix
new file mode 100644
index 00000000..a0e7526e
--- /dev/null
+++ b/pkgs/beehive/godeps.nix
@@ -0,0 +1,378 @@
+{ buildGoPackage, lib, fetchFromGitHub, fetchgit, fetchhg }:
+
+rec {
+  cascadia = buildGoPackage {
+    name = "cascadia";
+    goPackagePath = "code.google.com/p/cascadia";
+    src = fetchhg {
+      url = "https://code.google.com/p/cascadia";
+      rev = "5d796540e3cb93ea0556c897e6a3c7690f614d35";
+      sha256 = "1mxmj4vbh47j3nvmdqdah4fprkyww3pf8i9sy0zcar52bpa4j69c";
+    };
+    buildInputs = [ net ];
+  };
+
+  charset = buildGoPackage {
+    name = "go-charset";
+    goPackagePath = "code.google.com/p/go-charset";
+    src = fetchhg {
+      url = "https://code.google.com/p/go-charset";
+      rev = "ebbeafdc430eb6c7e44e9a730a38eaff4c56ba3a";
+      sha256 = "162jd0ryvwaj7bwxbdwrs1vi6ig3bhd6m4n16wf54frrzyqxh34p";
+    };
+  };
+
+  gonet = buildGoPackage {
+    name = "go.net";
+    goPackagePath = "code.google.com/p/go.net";
+    src = fetchhg {
+      url = "https://code.google.com/p/go.net";
+      rev = "937a34c9de13c766c814510f76bca091dee06028";
+      sha256 = "1f91yzjllw2pdk68yjvf8hjix4mrlqn7fh97h9n7qjy903rwnb9q";
+    };
+    buildInputs = [ net text ];
+  };
+
+  gomock = buildGoPackage {
+    name = "gomock";
+    goPackagePath = "code.google.com/p/gomock";
+    src = fetchgit {
+      url = "https://code.google.com/p/gomock";
+      rev = "e033c7513ca3d743bbb64df299bdec29e93fed03";
+      sha256 = "0vmpqibyx09bdqnqsy8g4xiw3hpw0j9kww7ak2z7fdzxpd9ly337";
+    };
+  };
+
+  anaconda = buildGoPackage {
+    name = "anaconda";
+    goPackagePath = "github.com/ChimeraCoder/anaconda";
+    src = fetchFromGitHub {
+      owner = "ChimeraCoder";
+      repo = "anaconda";
+      rev = "964821c05001e5a38dd234d681ce9a929858481a";
+      sha256 = "077fxb4iazsjfsbmj966ifias84agxbzip742w9cbc7fv1bpy085";
+    };
+    buildInputs = [ tokenbucket jsonpointer oauth ];
+  };
+
+  tokenbucket = buildGoPackage {
+    name = "tokenbucket";
+    goPackagePath = "github.com/ChimeraCoder/tokenbucket";
+    src = fetchFromGitHub {
+      owner = "ChimeraCoder";
+      repo = "tokenbucket";
+      rev = "c5a927568de7aad8a58127d80bcd36ca4e71e454";
+      sha256 = "1cyzlvk1mgdvdfmqsdsy5y2rflfz5q54a9rz9jylc2mg40c1d6dq";
+    };
+  };
+
+  gotumblr = buildGoPackage {
+    name = "gotumblr";
+    goPackagePath = "github.com/MariaTerzieva/gotumblr";
+    src = fetchFromGitHub {
+      owner = "MariaTerzieva";
+      repo = "gotumblr";
+      rev = "62f45d64049aeab0b3835351edc66704c7210f7a";
+      sha256 = "06bqc6c4j9g8l0xqhc9g5jmx4q6dq5jid5bpj4skca30gsqgldgr";
+    };
+    buildInputs = [ oauth1a ];
+  };
+
+  goquery = buildGoPackage {
+    name = "goquery";
+    goPackagePath = "github.com/PuerkitoBio/goquery";
+    src = fetchFromGitHub {
+      owner = "PuerkitoBio";
+      repo = "goquery";
+      rev = "4cf64c51f7e80d56d9ae2ffe7d684d3dd5dbd5d0";
+      sha256 = "1d6cl0qhfx9ngj3hn56mxwwy7yak62c5wxa77f7yfarql84r8h4n";
+    };
+    buildInputs = [ cascadia net ];
+  };
+
+  GoOse = buildGoPackage {
+    name = "GoOse";
+    goPackagePath = "github.com/advancedlogic/GoOse";
+    src = fetchFromGitHub {
+      owner = "advancedlogic";
+      repo = "GoOse";
+      rev = "e210b2436fec0a3ce1b5f9209ee3340314b408e2";
+      sha256 = "0sjqy295x9rn93b5k3r8hdbi5gjbdd3h2dn89v4nzpnzmlrfbc2c";
+    };
+    buildInputs = [ cascadia charset gojs-config goquery net latinx set ];
+  };
+
+  gojs-config = buildGoPackage {
+    name = "gojs-config";
+    goPackagePath = "github.com/advancedlogic/gojs-config";
+    src = fetchFromGitHub {
+      owner = "advancedlogic";
+      repo = "gojs-config";
+      rev = "bff36193fca8bd2f6269e8c4e8c723991fd20565";
+      sha256 = "1k0wgn3pj384sqai2c9dkv06j0z439i3xqzfl3kplb0wdf8a2vy0";
+    };
+  };
+
+  latinx = buildGoPackage {
+    name = "latinx";
+    goPackagePath = "github.com/bjarneh/latinx";
+    src = fetchFromGitHub {
+      owner = "bjarneh";
+      repo = "latinx";
+      rev = "4dfe9ba2a293f28a5e06fc7ffe56b1d71a47b8c8";
+      sha256 = "0lavz5m0dz1rxyl20var3xqj2ndcmai2v893p83pjwm4333yb5g0";
+    };
+  };
+
+  jsonpointer = buildGoPackage {
+    name = "go-jsonpointer";
+    goPackagePath = "github.com/dustin/go-jsonpointer";
+    src = fetchFromGitHub {
+      owner = "dustin";
+      repo = "go-jsonpointer";
+      rev = "75939f54b39e7dafae879e61f65438dadc5f288c";
+      sha256 = "1vcv5xb6v6akbbi71q4srfla311s4p9kspqya2h40x8fxx00lkxp";
+    };
+    propagatedBuildInputs = [ gojson ];
+  };
+
+  gojson = buildGoPackage {
+    name = "gojson";
+    goPackagePath = "github.com/dustin/gojson";
+    src = fetchFromGitHub {
+      owner = "dustin";
+      repo = "gojson";
+      rev = "af16e0e771e2ed110f2785564ae33931de8829e4";
+      sha256 = "0626n6a5hwb0zwi6dwsmqdv2g5fwzsfx22rbxscaydpb90b6qnin";
+    };
+  };
+
+  restful = buildGoPackage {
+    name = "go-restful";
+    goPackagePath = "github.com/emicklei/go-restful";
+    src = fetchFromGitHub {
+      owner = "emicklei";
+      repo = "go-restful";
+      rev = "7ef8ec372029a3112fdb94a53b1ca8eedf666e67";
+      sha256 = "0rrpa9xiqkzapn6axjl19nnhxk0ljjq20a8jpam80hkzw4waa955";
+    };
+    postPatch = ''
+      rm -rf examples
+    '';
+    buildInputs = [ schema ];
+  };
+
+  goirc = buildGoPackage {
+    name = "goirc";
+    goPackagePath = "github.com/fluffle/goirc";
+    src = fetchFromGitHub {
+      owner = "fluffle";
+      repo = "goirc";
+      rev = "0cac69d2eec69bb08bb29b776d045a78b9699791";
+      sha256 = "0iba19rslsyww3qsf9d4ncdxjjz7pv8k36ar5s1i6f4fwv42d56q";
+    };
+    buildInputs = [ glog golog gomock ];
+  };
+
+  golog = buildGoPackage {
+    name = "golog";
+    goPackagePath = "github.com/fluffle/golog";
+    src = fetchFromGitHub {
+      owner = "fluffle";
+      repo = "golog";
+      rev = "3b86dae249b53d7dc2d9e817ff019fa01a155b06";
+      sha256 = "0b8fzkk9bshkfsnbx2nq6dn0dcngsh5awpym98sinkkfwywvlq2f";
+    };
+    buildInputs = [ gomock ];
+  };
+
+  oauth = buildGoPackage {
+    name = "go-oauth";
+    goPackagePath = "github.com/garyburd/go-oauth";
+    src = fetchFromGitHub {
+      owner = "garyburd";
+      repo = "go-oauth";
+      rev = "fa02955a8929c2f007c533fbdfb8ddc91bb6a731";
+      sha256 = "0zx9azdhjxf18fk4y3hnp70cz75iyllqfvfxma02i8f63q364d94";
+    };
+    postPatch = ''
+      rm -rf examples
+    '';
+  };
+
+  glog = buildGoPackage {
+    name = "glog";
+    goPackagePath = "github.com/golang/glog";
+    src = fetchFromGitHub {
+      owner = "golang";
+      repo = "glog";
+      rev = "44145f04b68cf362d9c4df2182967c2275eaefed";
+      sha256 = "1k7sf6qmpgm0iw81gx2dwggf9di6lgw0n54mni7862hihwfrb5rq";
+    };
+  };
+
+  protobuf = buildGoPackage {
+    name = "protobuf";
+    goPackagePath = "github.com/golang/protobuf";
+    src = fetchFromGitHub {
+      owner = "golang";
+      repo = "protobuf";
+      rev = "f7137ae6b19afbfd61a94b746fda3b3fe0491874";
+      sha256 = "05n1ws6y9qpp3imxjvl3jnknq6kca2vc5g475fqr2l67ap3w5lwk";
+    };
+    subPackages = [ "proto" "protoc-gen-go" ];
+  };
+
+  schema = buildGoPackage {
+    name = "schema";
+    goPackagePath = "github.com/gorilla/schema";
+    src = fetchFromGitHub {
+      owner = "gorilla";
+      repo = "schema";
+      rev = "c8422571edf3131506bab7df27e18980fe2598d5";
+      sha256 = "10czpd111l834aam52bh1cxv31pq4h8mi1w994v4848rmbw3jpp4";
+    };
+  };
+
+  dbus = buildGoPackage {
+    name = "go.dbus";
+    goPackagePath = "github.com/guelfey/go.dbus";
+    src = fetchFromGitHub {
+      owner = "guelfey";
+      repo = "go.dbus";
+      rev = "f6a3a2366cc39b8479cadc499d3c735fb10fbdda";
+      sha256 = "15rnpvclg4b3cblcxwwgkdfgamhigiyla0s1rwhfjraqhn94r3ph";
+    };
+    postPatch = ''
+      rm -rf _examples
+    '';
+  };
+
+  web = buildGoPackage {
+    name = "web";
+    goPackagePath = "github.com/hoisie/web";
+    src = fetchFromGitHub {
+      owner = "hoisie";
+      repo = "web";
+      rev = "5a66d0fa07a54688eba8fa506576a78a942ef243";
+      sha256 = "1h4ary4ac51xznr41996k3xqlclm3r5mjba71y6anfwdrhaa2qf1";
+    };
+    buildInputs = [ gonet ];
+    postPatch = ''
+      rm -rf examples
+    '';
+  };
+
+  goserial = buildGoPackage {
+    name = "goserial";
+    goPackagePath = "github.com/huin/goserial";
+    src = fetchFromGitHub {
+      owner = "huin";
+      repo = "goserial";
+      rev = "7b90efdb22b1c168a57b998b2780cf541b2c4740";
+      sha256 = "05ha3yvhvbfrbxlqi8x1fwcliginw0vxhh76mh6vycn9n7yjpacy";
+    };
+  };
+
+  rss = buildGoPackage {
+    name = "go-pkg-rss";
+    goPackagePath = "github.com/jteeuwen/go-pkg-rss";
+    src = fetchFromGitHub {
+      owner = "jteeuwen";
+      repo = "go-pkg-rss";
+      rev = "2382fc0262cb000be19e9042cdbc8459105b4f00";
+      sha256 = "0rss5sj128qwai60wpkm5cy2q8d9yfakdm4pqb8p4lhgpq26g05h";
+    };
+    buildInputs = [ xmlx ];
+  };
+
+  xmlx = buildGoPackage {
+    name = "go-pkg-xmlx";
+    goPackagePath = "github.com/jteeuwen/go-pkg-xmlx";
+    src = fetchFromGitHub {
+      owner = "jteeuwen";
+      repo = "go-pkg-xmlx";
+      rev = "cf505b97c711dd1c5a4682f68ea04dd35e385b8f";
+      sha256 = "01pdjndl1i0p7lr8svi1j0f79zyl36s0xn7yb8d8yziksbczbcrj";
+    };
+  };
+
+  oauth1a = buildGoPackage {
+    name = "oauth1a";
+    goPackagePath = "github.com/kurrik/oauth1a";
+    src = fetchFromGitHub {
+      owner = "kurrik";
+      repo = "oauth1a";
+      rev = "fc2542bc5f2532ed4a437960d2d51ff6e18a5cb6";
+      sha256 = "1v9zsn80y5x5fklc7q8rxixjrh5g01rsdlz247lgf3rag0hb3d39";
+    };
+  };
+
+  xmpp = buildGoPackage {
+    name = "go-xmpp";
+    goPackagePath = "github.com/mattn/go-xmpp";
+    src = fetchFromGitHub {
+      owner = "mattn";
+      repo = "go-xmpp";
+      rev = "8b13d0ad771420685f85ed09d8e9bf81757e7e20";
+      sha256 = "022all0cphxmrg015jzfsqd5xd5nli7fpw32wx6ql79s4rsy3bwb";
+    };
+    postPatch = ''
+      rm -rf _example
+    '';
+  };
+
+  goefa = buildGoPackage {
+    name = "goefa";
+    goPackagePath = "github.com/michiwend/goefa";
+    src = fetchFromGitHub {
+      owner = "michiwend";
+      repo = "goefa";
+      rev = "381f3d7b77fc04d9a81d2bc9e3e6d2fc742757b1";
+      sha256 = "1aiiafbpvw2xlvjgh27mfljd3d0j443iz7sp9w9w3109ay1q2gk4";
+    };
+    buildInputs = [ charset ];
+  };
+
+  hue = buildGoPackage {
+    name = "go.hue";
+    goPackagePath = "github.com/muesli/go.hue";
+    src = fetchFromGitHub {
+      owner = "muesli";
+      repo = "go.hue";
+      rev = "8aefcc693cafb5b2b4ef8ca8d51ab880849e8c12";
+      sha256 = "158q3g5rg9wra1wxkvyb1c2v868gp9mslhf6gmbifj516lsb1agi";
+    };
+  };
+
+  net = buildGoPackage {
+    name = "net";
+    goPackagePath = "golang.org/x/net";
+    src = fetchgit {
+      url = "https://go.googlesource.com/net";
+      rev = "97d8e4e174133a4d1d2171380e510eb4dea8f5ea";
+      sha256 = "0jydngilxhgw8f1zgz11hbjk87bhj0jpar89a2py1pii4ncx9w04";
+    };
+    buildInputs = [ text ];
+  };
+
+  text = buildGoPackage {
+    name = "text";
+    goPackagePath = "golang.org/x/text";
+    src = fetchgit {
+      url = "https://go.googlesource.com/text";
+      rev = "26df76be81cdb060ed9820481a0d67b2d0b04ac2";
+      sha256 = "1vmgzzi0r1idjfgfwibq2r3xlnab3w2v6nmm3c5l2bb994w376gn";
+    };
+  };
+
+  set = buildGoPackage {
+    name = "set.v0";
+    goPackagePath = "gopkg.in/fatih/set.v0";
+    src = fetchgit {
+      url = "https://gopkg.in/fatih/set.v0";
+      rev = "27c40922c40b43fe04554d8223a402af3ea333f3";
+      sha256 = "1d8yz8p4jvyqvmpim40x5y7kj91c5hcc5hbmxhv0j32ifz01nacl";
+    };
+  };
+}
diff --git a/pkgs/blop/default.nix b/pkgs/blop/default.nix
new file mode 100644
index 00000000..6f1f49c5
--- /dev/null
+++ b/pkgs/blop/default.nix
@@ -0,0 +1,16 @@
+{ stdenv, fetchurl, ladspaH }:
+
+stdenv.mkDerivation rec {
+  name = "blop-${version}";
+  version = "0.2.8";
+
+  configureFlags = [
+    "--with-ladspa-prefix=${ladspaH}"
+    "--with-ladspa-plugin-dir=$(out)/lib/ladspa"
+  ];
+
+  src = fetchurl {
+    url = "mirror://sourceforge/blop/${name}.tar.gz";
+    sha256 = "02iymw84dml8glyqgx1mxq4fz2fifgi1jca28hx2r3a2mi7i71vy";
+  };
+}
diff --git a/pkgs/build-support/channel.nix b/pkgs/build-support/channel.nix
new file mode 100644
index 00000000..a837177f
--- /dev/null
+++ b/pkgs/build-support/channel.nix
@@ -0,0 +1,32 @@
+{ stdenv }:
+
+{ name, src, constituents ? [], meta ? {}, ... }@args:
+
+stdenv.mkDerivation ({
+  inherit name src constituents;
+  preferLocalBuild = true;
+  _hydraAggregate = true;
+
+  phases = [ "unpackPhase" "patchPhase" "installPhase" ];
+  installPhase = ''
+    mkdir -p "$out/tarballs" "$out/nix-support"
+
+    tar cJf "$out/tarballs/nixexprs.tar.xz" \
+      --owner=0 --group=0 --mtime="1970-01-01 00:00:00 UTC" \
+      --transform='s!^\.!${name}!' .
+
+    echo "channel - $out/tarballs/nixexprs.tar.xz" \
+      > "$out/nix-support/hydra-build-products"
+
+    echo $constituents > "$out/nix-support/hydra-aggregate-constituents"
+    for i in $constituents; do
+      if [ -e "$i/nix-support/failed" ]; then
+        touch "$out/nix-support/failed"
+      fi
+    done
+  '';
+
+  meta = meta // {
+    isHydraChannel = true;
+  };
+} // removeAttrs args [ "name" "channelName" "src" "constituents" "meta" ])
diff --git a/pkgs/default.nix b/pkgs/default.nix
new file mode 100644
index 00000000..6eec67a4
--- /dev/null
+++ b/pkgs/default.nix
@@ -0,0 +1,31 @@
+{ pkgs ? import (import ../nixpkgs-path.nix) {} }:
+
+let
+  callPackage = pkgs.lib.callPackageWith (pkgs // self.vuizvui);
+
+  self.vuizvui = {
+    mkChannel = callPackage ./build-support/channel.nix { };
+
+    aacolorize = callPackage ./aacolorize { };
+    axbo = callPackage ./axbo { };
+    beehive = callPackage ./beehive { };
+    blop = callPackage ./blop { };
+    grandpa = callPackage ./grandpa { };
+    greybird-xfce-theme = callPackage ./greybird-xfce-theme { };
+    nixops = callPackage ./nixops { };
+    libCMT = callPackage ./libcmt { };
+    librxtx_java = callPackage ./librxtx-java { };
+    list-gamecontrollers = callPackage ./list-gamecontrollers { };
+    lockdev = callPackage ./lockdev { };
+    pvolctrl = callPackage ./pvolctrl { };
+    show-qr-code = callPackage ./show-qr-code { };
+    sidplayfp = callPackage ./sidplayfp { };
+    tkabber_urgent_plugin = callPackage ./tkabber-urgent-plugin { };
+    tomahawk = callPackage ./tomahawk { qt5 = pkgs.qt55; };
+    twitchstream = callPackage ./twitchstream { };
+
+    kernelPatches = {
+      bfqsched = callPackage ./kpatches/bfqsched { };
+    };
+  };
+in pkgs // self
diff --git a/pkgs/games/COPYING b/pkgs/games/COPYING
new file mode 100644
index 00000000..581a4b68
--- /dev/null
+++ b/pkgs/games/COPYING
@@ -0,0 +1,20 @@
+Everything except files that end with ".patch" are copyright (C) 2014
+aszlig and licensed under the Apache License, Version 2.0 (the
+"License"); you may not use these files except in compliance with the
+License. You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+If the URL to the license is unavailable, please see LICENSE.APACHE in
+this directory.
+
+All of the .patch files are copyright (C) 2014 aszlig as well, but are
+licensed under the licenses of the corresponding projects. Please look
+at accompanying Nix expressions for more information about the
+licenses of the respective projects and thus my patches.
diff --git a/pkgs/games/LICENSE.APACHE b/pkgs/games/LICENSE.APACHE
new file mode 100644
index 00000000..d6456956
--- /dev/null
+++ b/pkgs/games/LICENSE.APACHE
@@ -0,0 +1,202 @@
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
diff --git a/pkgs/games/base-module.nix b/pkgs/games/base-module.nix
new file mode 100644
index 00000000..08855379
--- /dev/null
+++ b/pkgs/games/base-module.nix
@@ -0,0 +1,15 @@
+{ lib, ... }:
+
+with lib;
+
+{
+  options = {
+    packages = mkOption {
+      type = types.attrsOf types.unspecified;
+      default = {};
+      description = "Available NixGames packages.";
+    };
+  };
+
+  config._module.args.pkgs = import <nixpkgs> {};
+}
diff --git a/pkgs/games/default.nix b/pkgs/games/default.nix
new file mode 100644
index 00000000..d85bd191
--- /dev/null
+++ b/pkgs/games/default.nix
@@ -0,0 +1,25 @@
+{ configuration ? null }:
+
+let
+  configFilePath = let
+    xdgConfig = builtins.getEnv "XDG_CONFIG_HOME";
+    fallback = "${builtins.getEnv "HOME"}/.config";
+    basedir = if xdgConfig == "" then fallback else xdgConfig;
+  in "${basedir}/nixgames.nix";
+
+  configFile = if !builtins.pathExists configFilePath then throw ''
+    The config file "${configFilePath}" doesn't exist! Be sure to create it and
+    put your HumbleBundle email address and password in it, like this:
+
+    {
+      humblebundle.email = "fancyuser@example.com";
+      humblebundle.password = "my_super_secret_password";
+    }
+  '' else configFilePath;
+
+in ((import <nixpkgs/lib>).evalModules {
+  modules = [
+    (if configuration == null then configFilePath else configuration)
+    ./base-module.nix ./humblebundle ./steam
+  ];
+}).config.packages
diff --git a/pkgs/games/humblebundle/bastion.nix b/pkgs/games/humblebundle/bastion.nix
new file mode 100644
index 00000000..b4acda6b
--- /dev/null
+++ b/pkgs/games/humblebundle/bastion.nix
@@ -0,0 +1,62 @@
+{ stdenv, fetchHumbleBundle, lzma, xorg, libpulseaudio}:
+
+let
+  arch = {
+    "i686-linux" = "x86";
+    "x86_64-linux" = "x86_64";
+  }.${stdenv.system};
+in stdenv.mkDerivation rec {
+  name = "bastion-1.4";
+
+  src = fetchHumbleBundle {
+    name = "Bastion-HIB-2012-06-20.sh";
+    machineName = "bastion_linux";
+    downloadName = ".sh";
+    md5 = "aa6ccaead3b4b8a5fbd156f4019e8c8b";
+  };
+
+  dontStrip = true;
+  phases = ["installPhase"];
+
+  installPhase = let
+    rpath = stdenv.lib.makeLibraryPath [
+      "$dest"
+      xorg.libX11
+      xorg.libXi
+      stdenv.cc.cc
+      libpulseaudio
+    ];
+   in ''
+    dest="$out/opt/games/bastion"
+    libdir="$dest/lib" #${stdenv.lib.optionalString (arch=="x86_64") "64"}"
+
+    # Unpack binaries and data into $dest
+    mkdir -p "$dest"
+    sh "$src" --tar xf ./instarchive_all -O           | ${lzma}/bin/lzcat | tar x -C "$dest"
+    sh "$src" --tar xf ./instarchive_linux_${arch} -O | ${lzma}/bin/lzcat | tar x -C "$dest"
+
+    # Ensure that $dest is a valid library path.
+    mv $dest/lib64 $libdir || true
+
+    # Patch heavily :-)
+    patchelf \
+      --set-interpreter "$(cat $NIX_CC/nix-support/dynamic-linker)" \
+      --set-rpath "${rpath}" "$dest/Bastion.bin.${arch}"
+    patchelf --set-rpath "${rpath}" "$libdir/libmono-2.0.so.1"
+    patchelf --set-rpath "${rpath}" "$libdir/libfmodex.so"
+    patchelf --set-rpath "${rpath}" "$libdir/libSDL-1.2.so.0"
+
+    # Fixup permissions, just to be sure.
+    find "$dest" -type f -exec chmod 644 "{}" +
+    chmod 755 "$dest/Bastion.bin.${arch}"
+
+    # Taken from ArchLinux; might be useful to actually implement
+    #install -Dm644 "''${pkgname}".desktop "''${pkgdir}"/usr/share/applications/"''${pkgname}".desktop
+    #install -Dm755 "mesa''${pkgname}" "''${pkgdir}"/usr/bin/"''${pkgname}"mesa
+    #install -Dm644 "''${pkgdir}"/opt/games/Bastion/Bastion.png "''${pkgdir}"/usr/share/icons/"''${pkgname}".png
+
+    # XXX: Make wrapper instead of symlink ? See ArchLinux's bastionmesa above.
+    mkdir -p "$out/bin"
+    ln -s "$dest/Bastion.bin.${arch}" "$out/bin/bastion"
+  '';
+}
diff --git a/pkgs/games/humblebundle/cavestoryplus.nix b/pkgs/games/humblebundle/cavestoryplus.nix
new file mode 100644
index 00000000..d4c744d4
--- /dev/null
+++ b/pkgs/games/humblebundle/cavestoryplus.nix
@@ -0,0 +1,39 @@
+{ stdenv, fetchHumbleBundle, makeWrapper, SDL, mesa }:
+
+stdenv.mkDerivation rec {
+  name = "cave-story-plus-${version}";
+  version = "r100";
+
+  src = fetchHumbleBundle {
+    machineName = "cavestoryplus_linux";
+    downloadName = ".tar.bz2";
+    suffix = "tar.bz2";
+    md5 = "b7ecd65644b8607bc177d7ce670f2185";
+  };
+
+  buildInputs = [ makeWrapper ];
+
+  patchPhase = let
+    rpath = stdenv.lib.makeLibraryPath [
+      SDL "$out" stdenv.cc.cc mesa
+    ];
+  in ''
+    patchelf \
+      --set-interpreter "$(cat $NIX_CC/nix-support/dynamic-linker)" \
+      --set-rpath "${rpath}" CaveStory+_64
+  '';
+
+  installPhase = ''
+    install -vD CaveStory+_64 "$out/libexec/cave-story-plus/cave-story-plus"
+    mkdir -p "$out/bin"
+    makeWrapper \
+      "$out/libexec/cave-story-plus/cave-story-plus" \
+      "$out/bin/cave-story-plus" \
+      --run "cd '$out/share/cave-story-plus'"
+
+    mkdir -p "$out/share/cave-story-plus"
+    cp -vrt "$out/share/cave-story-plus" data
+  '';
+
+  dontStrip = true;
+}
diff --git a/pkgs/games/humblebundle/default.nix b/pkgs/games/humblebundle/default.nix
new file mode 100644
index 00000000..237a5dc6
--- /dev/null
+++ b/pkgs/games/humblebundle/default.nix
@@ -0,0 +1,50 @@
+{ config, lib, pkgs, ... }:
+
+let
+  cfg = config.humblebundle;
+
+  self = rec {
+    callPackage = pkgs.lib.callPackageWith (pkgs // self);
+    callPackage_i686 = pkgs.lib.callPackageWith (pkgs.pkgsi686Linux // self);
+
+    fetchHumbleBundle = callPackage ./fetch-humble-bundle {
+      inherit (config.humblebundle) email password;
+    };
+
+    bastion = callPackage ./bastion.nix {};
+    cavestoryplus = callPackage ./cavestoryplus.nix {};
+    fez = callPackage ./fez.nix {};
+    ftl = callPackage ./ftl.nix {};
+    guacamelee = callPackage_i686 ./guacamelee.nix {};
+    hammerwatch = callPackage ./hammerwatch.nix {};
+    jamestown = callPackage ./jamestown.nix {};
+    liads = callPackage ./liads.nix {};
+    megabytepunch = callPackage ./megabytepunch.nix {};
+    rocketbirds = callPackage ./rocketbirds.nix {};
+    spaz = callPackage ./spaz.nix {};
+    swordsandsoldiers = callPackage ./swordsandsoldiers.nix {};
+    unepic = callPackage ./unepic.nix {};
+  };
+in with lib; {
+  options.humblebundle = {
+    email = mkOption {
+      type = types.nullOr types.str;
+      default = null;
+      description = ''
+        Email address for your HumbleBundle account.
+      '';
+    };
+
+    password = mkOption {
+      type = types.nullOr types.str;
+      default = null;
+      description = ''
+        Password for your HumbleBundle account.
+      '';
+    };
+  };
+
+  config.packages = {
+    humblebundle = mkIf (cfg.email != null && cfg.password != null) self;
+  };
+}
diff --git a/pkgs/games/humblebundle/fetch-humble-bundle/default.nix b/pkgs/games/humblebundle/fetch-humble-bundle/default.nix
new file mode 100644
index 00000000..fbabaa8c
--- /dev/null
+++ b/pkgs/games/humblebundle/fetch-humble-bundle/default.nix
@@ -0,0 +1,87 @@
+{ stdenv, curl, cacert, writeText, fetchFromGitHub, fetchpatch
+, python, buildPythonPackage, pythonPackages
+
+, email, password
+}:
+
+{ name ? null, machineName, downloadName ? "Download", suffix ? "humblebundle", md5 }: let
+  cafile = "${cacert}/etc/ssl/certs/ca-bundle.crt";
+
+  humbleAPI = buildPythonPackage rec {
+    name = "humblebundle-${version}";
+    version = "0.1.1";
+
+    src = fetchFromGitHub {
+      owner = "saik0";
+      repo = "humblebundle-python";
+      rev = version;
+      sha256 = "1kcg42nh7sbjabim1pbqx14468pypznjy7fx2bv7dicy0sqd9b8j";
+    };
+
+    propagatedBuildInputs = with pythonPackages; [ requests2 ];
+  };
+
+  pyStr = str: "'${stdenv.lib.escape ["'" "\\"] str}'";
+
+  getDownloadURL = writeText "gethburl.py" ''
+    import sys, humblebundle
+
+    def get_products(client):
+      gamekeys = client.get_gamekeys()
+      for gamekey in gamekeys:
+        order = hb.get_order(gamekey)
+        if order.subproducts is None:
+          continue
+        for subproduct in order.subproducts:
+          prodname = subproduct.human_name.encode('ascii', 'replace')
+          downloads = [(download.machine_name, download.download_struct)
+                       for download in subproduct.downloads]
+          yield (prodname, downloads)
+
+    def find_download(downloads):
+      for machine_name, dstruct in sum(downloads.values(), []):
+        if machine_name == ${pyStr machineName}:
+          for ds in dstruct:
+            if ds.name == ${pyStr downloadName}:
+              return ds
+          print >>sys.stderr, \
+            ${pyStr "Unable to find ${downloadName} for ${machineName}!"}
+          print >>sys.stderr, 'Available download types:'
+          for ds in dstruct:
+            print >>sys.stderr, "  " + ds.name
+          raise SystemExit(1)
+
+    hb = humblebundle.HumbleApi()
+    hb.login(${pyStr email}, ${pyStr password})
+    products = dict(get_products(hb))
+    dstruct = find_download(products)
+
+    if dstruct is None:
+      print >>sys.stderr, ${pyStr "Cannot find download for ${machineName}!"}
+      print >>sys.stderr, 'Available machine names:'
+      for name, dstructs in sorted(products.items(), key=lambda x: x[0]):
+        print >>sys.stderr, "  * " + name
+        print >>sys.stderr, "    " + ', '.join(map(lambda x: x[0], dstructs))
+      raise SystemExit(1)
+    elif dstruct.md5 != ${pyStr md5}:
+      print >>sys.stderr, \
+        ${pyStr "MD5 for ${machineName} is not ${md5} but "} \
+        + dstruct.md5 + '.'
+      raise SystemExit(1)
+    else:
+      print dstruct.url.web
+  '';
+in stdenv.mkDerivation {
+  name = if name != null then name else "${machineName}.${suffix}";
+  outputHashAlgo = "md5";
+  outputHash = md5;
+
+  buildInputs = [ python humbleAPI ];
+
+  buildCommand = ''
+    url="$(python "${getDownloadURL}")"
+    header "downloading $name from $url"
+    ${curl}/bin/curl --cacert "${cafile}" --fail --output "$out" "$url"
+    stopNest
+  '';
+}
diff --git a/pkgs/games/humblebundle/fez.nix b/pkgs/games/humblebundle/fez.nix
new file mode 100644
index 00000000..5f23b97c
--- /dev/null
+++ b/pkgs/games/humblebundle/fez.nix
@@ -0,0 +1,35 @@
+{ stdenv, fetchHumbleBundle, unzip, mono, openal, SDL2 }:
+
+let
+  version = "1.0.2";
+  usVersion = stdenv.lib.replaceChars ["."] ["_"] version;
+in stdenv.mkDerivation rec {
+  name = "fez-${version}";
+  version = "09152013";
+
+  src = fetchHumbleBundle {
+    name = "${name}-bin";
+    md5 = "4ac954101835311f3528f5369e1fecb7";
+  };
+
+  unpackPhase = ''
+    ${unzip}/bin/unzip -qq "$src" 'data/*' || true
+    sourceRoot=data
+  '';
+
+  dontStrip = true;
+
+  buildPhase = ''
+    patchelf \
+      --set-interpreter "$(cat $NIX_CC/nix-support/dynamic-linker)" \
+      --set-rpath "${stdenv.lib.makeLibraryPath [ mono openal SDL2 ]}" \
+      FEZ.bin.x86_64
+  '';
+
+  installPhase = ''
+    ensureDir "$out/bin" "$out/libexec/fez/mono/2.0"
+    install -vD FEZ.bin.x86_64 "$out/libexec/fez/fez"
+    install -vt "$out/libexec/fez/mono/2.0" *.dll
+    ln -s "$out/libexec/fez/fez" "$out/bin/fez"
+  '';
+}
diff --git a/pkgs/games/humblebundle/ftl.nix b/pkgs/games/humblebundle/ftl.nix
new file mode 100644
index 00000000..7423951a
--- /dev/null
+++ b/pkgs/games/humblebundle/ftl.nix
@@ -0,0 +1,38 @@
+{ stdenv, fetchHumbleBundle, makeWrapper, SDL, mesa, libdevil, freetype }:
+
+stdenv.mkDerivation rec {
+  name = "ftl-${version}";
+  version = "1.5.13";
+
+  src = fetchHumbleBundle {
+    machineName = "ftlfasterthanlight_soundtrack_linux";
+    downloadName = ".tar.gz";
+    suffix = "tar.gz";
+    md5 = "791e0bc8de73fcdcd5f461a4548ea2d8";
+  };
+
+  buildInputs = [ makeWrapper ];
+
+  patchPhase = let
+    rpath = stdenv.lib.makeLibraryPath [
+      SDL "$out" stdenv.cc.cc mesa libdevil freetype
+    ];
+  in ''
+    patchelf \
+      --set-interpreter "$(cat $NIX_CC/nix-support/dynamic-linker)" \
+      --set-rpath "${rpath}" data/amd64/bin/FTL
+  '';
+
+  installPhase = ''
+    install -vD "data/amd64/bin/FTL" "$out/libexec/ftl/FTL"
+    install -vD "data/amd64/lib/libbass.so" "$out/lib/libbass.so"
+    install -vD "data/amd64/lib/libbassmix.so" "$out/lib/libbassmix.so"
+
+    mkdir -p "$out/bin" "$out/share/ftl"
+    cp -vrt "$out/share/ftl" data/resources
+    makeWrapper "$out/libexec/ftl/FTL" "$out/bin/ftl" \
+      --run "cd '$out/share/ftl'"
+  '';
+
+  dontStrip = true;
+}
diff --git a/pkgs/games/humblebundle/guacamelee.nix b/pkgs/games/humblebundle/guacamelee.nix
new file mode 100644
index 00000000..537ec945
--- /dev/null
+++ b/pkgs/games/humblebundle/guacamelee.nix
@@ -0,0 +1,61 @@
+{ stdenv, fetchHumbleBundle, unzip, SDL2, mesa, writeText, makeWrapper }:
+
+stdenv.mkDerivation rec {
+  name = "guacamelee-${version}";
+  version = "1393037377";
+
+  src = fetchHumbleBundle {
+    machineName = "guacamelee_goldedition_linux";
+    suffix = "sh";
+    md5 = "b06af932c1aaefb8f157c977061388ef";
+  };
+
+  unpackCmd = ''
+    ${unzip}/bin/unzip "$src" 'data/*' || :
+  '';
+
+  preloader = writeText "guacamelee-preloader.c" ''
+    #define _GNU_SOURCE
+    #include <dlfcn.h>
+
+    int chdir(const char *path) {
+      int (*_chdir) (const char *) = dlsym(RTLD_NEXT, "chdir");
+      return _chdir(DATA);
+    }
+  '';
+
+  buildInputs = [ makeWrapper ];
+
+  buildPhase = let
+    rpath = stdenv.lib.makeLibraryPath [ SDL2 stdenv.cc.cc mesa ];
+    fmodRpath = stdenv.lib.makeLibraryPath [ stdenv.cc.cc ];
+  in ''
+    gcc -Werror -shared "$preloader" -o preloader.so -ldl \
+      -DDATA=\"$out/share/guacamelee\"
+
+    for i in libfmodevent-4.44.27.so libfmodex-4.44.27.so; do
+      patchelf --set-rpath "${fmodRpath}:$out/libexec/guacamelee" \
+        "x86/lib32/$i"
+    done
+    patchelf \
+      --set-interpreter "$(cat $NIX_CC/nix-support/dynamic-linker)" \
+      --set-rpath "${rpath}:$out/libexec/guacamelee" x86/game-bin
+  '';
+
+  installPhase = ''
+    install -vD x86/game-bin "$out/libexec/guacamelee/guacamelee"
+    install -vD preloader.so "$out/libexec/guacamelee/preloader.so"
+
+    makeWrapper "$out/libexec/guacamelee/guacamelee" "$out/bin/guacamelee" \
+      --set LD_PRELOAD "$out/libexec/guacamelee/preloader.so"
+
+    for i in libfmodevent-4.44.27.so libfmodex-4.44.27.so; do
+      install -vD "x86/lib32/$i" "$out/libexec/guacamelee/$i"
+    done
+
+    mkdir -p "$out/share"
+    cp -vRd noarch "$out/share/guacamelee"
+  '';
+
+  dontStrip = true;
+}
diff --git a/pkgs/games/humblebundle/hammerwatch.nix b/pkgs/games/humblebundle/hammerwatch.nix
new file mode 100644
index 00000000..8cf65211
--- /dev/null
+++ b/pkgs/games/humblebundle/hammerwatch.nix
@@ -0,0 +1,40 @@
+{ stdenv, fetchHumbleBundle, makeWrapper, unzip, mono, SDL2, mesa, openal
+, pulseaudio
+}:
+
+# FIXME: Dosn't support the XDG Base Directory Specification,
+#        so enforce it using LD_PRELOAD maybe?
+
+stdenv.mkDerivation rec {
+  name = "hammerwatch-${version}";
+  version = "1.3";
+
+  src = fetchHumbleBundle {
+    machineName = "hammerwatch_linux";
+    suffix = "zip";
+    md5 = "7cd77e4395f394c3062322c96e418732";
+  };
+
+  buildInputs = [ unzip makeWrapper ];
+
+  installPhase = let
+    rpath = stdenv.lib.makeLibraryPath [ SDL2 mesa openal pulseaudio ];
+    monoNoLLVM = mono.override { withLLVM = false; };
+  in ''
+    mkdir -p "$out/lib"
+    cp -rt "$out/lib" SDL2-CS.dll SDL2-CS.dll.config \
+      TiltedEngine.dll Lidgren.Network.dll FarseerPhysicsOTK.dll \
+      ICSharpCode.SharpZipLib.dll SteamworksManaged.dll NVorbis.dll
+
+    libexec="$out/libexec/hammerwatch"
+    install -vD Hammerwatch.exe "$libexec/hammerwatch.exe"
+    cp -rt "$libexec" assets.bin editor levels
+
+    makeWrapper "${monoNoLLVM}/bin/mono" "$out/bin/hammerwatch" \
+      --add-flags "$libexec/hammerwatch.exe" \
+      --set MONO_PATH "$out/lib" \
+      --set LD_LIBRARY_PATH "${rpath}"
+  '';
+
+  dontStrip = true;
+}
diff --git a/pkgs/games/humblebundle/jamestown.nix b/pkgs/games/humblebundle/jamestown.nix
new file mode 100644
index 00000000..15900bba
--- /dev/null
+++ b/pkgs/games/humblebundle/jamestown.nix
@@ -0,0 +1,55 @@
+{ stdenv, fetchHumbleBundle, unzip, pkgsi686Linux, expect, makeWrapper
+, SDL, openal
+}:
+
+let
+  version = "1.0.2";
+  usVersion = stdenv.lib.replaceChars ["."] ["_"] version;
+in stdenv.mkDerivation rec {
+  name = "jamestown-${version}";
+
+  src = fetchHumbleBundle {
+    machineName = "jamestown_linux";
+    downloadName = ".zip";
+    suffix = "zip";
+    md5 = "dcfb4348aba89f0f26bf5b4c7e05d936";
+  };
+
+  buildInputs = [ makeWrapper ];
+
+  unpackPhase = ''
+    ${unzip}/bin/unzip -q "$src"
+    patchelf --set-interpreter "${pkgsi686Linux.glibc}"/lib/ld-linux.so.* \
+      "JamestownInstaller_${usVersion}-bin"
+    ${expect}/bin/expect <<INSTALL
+    spawn "./JamestownInstaller_${usVersion}-bin"
+    expect "see more?"
+    send "n\r"
+    expect "Accept this license?"
+    send "y\r"
+    expect "Press enter to continue."
+    send "\r"
+    expect "Enter path"
+    send "$(pwd)/${name}\r"
+    expect eof
+    INSTALL
+    sourceRoot="$(pwd)/${name}"
+  '';
+
+  installPhase = let
+    rpath = stdenv.lib.makeLibraryPath [ SDL openal ];
+  in ''
+    libexec="$out/libexec/jamestown"
+    install -vD Jamestown-amd64 "$libexec/jamestown"
+
+    mkdir -p "$out/share"
+    mv Archives "$out/share/jamestown"
+
+    makeWrapper "$(cat "$NIX_CC/nix-support/dynamic-linker")" \
+      "$out/bin/jamestown" \
+      --add-flags "$libexec/jamestown" \
+      --set LD_LIBRARY_PATH "${rpath}"
+
+    false # Both amd64 and i686 binaries are fucking BROKEN, wait for 1.0.3...
+  '';
+}
diff --git a/pkgs/games/humblebundle/liads.nix b/pkgs/games/humblebundle/liads.nix
new file mode 100644
index 00000000..a96af8e0
--- /dev/null
+++ b/pkgs/games/humblebundle/liads.nix
@@ -0,0 +1,43 @@
+{ stdenv, fetchHumbleBundle, unzip, mesa, xorg, libpulseaudio }:
+
+stdenv.mkDerivation rec {
+  name = "liads-${version}";
+  version = "20160121";
+
+  src = fetchHumbleBundle {
+    machineName = "loversinadangerousspacetime_linux";
+    suffix = "zip";
+    md5 = "0d81adb63ca9233165fb5de415fa5963";
+  };
+
+  unpackCmd = ''
+    ${unzip}/bin/unzip -qq -d liads "$src" || :
+  '';
+
+  arch = if stdenv.system == "x86_64-linux" then "x86_64" else "x86";
+  executable = "LoversInADangerousSpacetime.${arch}";
+
+  buildPhase = let
+    rpath = stdenv.lib.makeLibraryPath [
+      stdenv.cc.cc mesa xorg.libX11 xorg.libXcursor xorg.libXrandr libpulseaudio
+    ];
+  in ''
+    patchelf \
+      --set-interpreter "$(cat $NIX_CC/nix-support/dynamic-linker)" \
+      --set-rpath "${rpath}" "$executable"
+  '';
+
+  installPhase = ''
+    install -vD "$executable" "$out/libexec/liads/liads"
+    ln -s "$out/share/liads" "$out/libexec/liads/Data"
+
+    mkdir -p "$out/bin"
+    ln -s "$out/libexec/liads/liads" "$out/bin/liads"
+
+    mkdir -p "$out/share"
+    cp -vRd LoversInADangerousSpacetime_Data "$out/share/liads"
+  '';
+
+  dontStrip = true;
+  dontPatchELF = true;
+}
diff --git a/pkgs/games/humblebundle/megabytepunch.nix b/pkgs/games/humblebundle/megabytepunch.nix
new file mode 100644
index 00000000..643e5835
--- /dev/null
+++ b/pkgs/games/humblebundle/megabytepunch.nix
@@ -0,0 +1,18 @@
+{ stdenv, fetchHumbleBundle }:
+
+stdenv.mkDerivation rec {
+  name = "megabytepunch-${version}";
+  version = "1.12";
+
+  src = fetchHumbleBundle {
+    machineName = "megabytepunch_linux";
+    suffix = "tar.gz";
+    md5 = "13487ae35c99817ce5f19b45fa51158b";
+  };
+
+  patchPhase = ''
+    patchelf \
+      --set-interpreter "$(cat $NIX_GCC/nix-support/dynamic-linker)" \
+
+  '';
+}
diff --git a/pkgs/games/humblebundle/rocketbirds.nix b/pkgs/games/humblebundle/rocketbirds.nix
new file mode 100644
index 00000000..a57d1562
--- /dev/null
+++ b/pkgs/games/humblebundle/rocketbirds.nix
@@ -0,0 +1,11 @@
+{ stdenv, fetchHumbleBundle }:
+
+stdenv.mkDerivation rec {
+  name = "rocketbirds-${version}";
+  version = "20130917";
+
+  src = fetchHumbleBundle {
+    name = "Rocketbirds${version}.sh";
+    md5 = "7c5e6da4cd7fc7f2f51861f8b96a386f";
+  };
+}
diff --git a/pkgs/games/humblebundle/spaz.nix b/pkgs/games/humblebundle/spaz.nix
new file mode 100644
index 00000000..5e40ea49
--- /dev/null
+++ b/pkgs/games/humblebundle/spaz.nix
@@ -0,0 +1,39 @@
+{ stdenv, fetchHumbleBundle, unzip, pkgsi686Linux }:
+
+stdenv.mkDerivation rec {
+  name = "spaz-${version}";
+  version = "09182012";
+
+  src = fetchHumbleBundle {
+    name = "spaz-linux-humblebundle-${version}-bin";
+    md5 = "9b2f28009949f2dff9f3a737e46fabfd";
+  };
+
+  buildInputs = [ pkgsi686Linux.makeWrapper ];
+
+  unpackCmd = ''
+    ${unzip}/bin/unzip -qq "$src" 'data/*' || true
+  '';
+
+  dontStrip = true;
+
+  buildPhase = let
+    libs = pkgsi686Linux.stdenv.lib.makeLibraryPath [
+      pkgsi686Linux.stdenv.cc.cc pkgsi686Linux.SDL
+    ];
+  in ''
+    patchelf --set-interpreter "${pkgsi686Linux.glibc}"/lib/ld-linux.so.* \
+             --set-rpath "${libs}" SPAZ
+  '';
+
+  installPhase = let
+    libs = pkgsi686Linux.stdenv.lib.makeLibraryPath [
+      pkgsi686Linux.mesa pkgsi686Linux.openal pkgsi686Linux.alsaPlugins
+    ];
+  in ''
+    install -vD SPAZ "$out/libexec/spaz/spaz"
+    cp -rt "$out/libexec/spaz" audio.so common game mods
+    makeWrapper "$out/libexec/spaz/spaz" "$out/bin/spaz" \
+      --set LD_LIBRARY_PATH "${libs}"
+  '';
+}
diff --git a/pkgs/games/humblebundle/swordsandsoldiers.nix b/pkgs/games/humblebundle/swordsandsoldiers.nix
new file mode 100644
index 00000000..2fd4fc4b
--- /dev/null
+++ b/pkgs/games/humblebundle/swordsandsoldiers.nix
@@ -0,0 +1,43 @@
+{ stdenv, fetchHumbleBundle, makeWrapper
+, SDL, mesa, zlib, openal, libvorbis, xorg, fontconfig, freetype, libogg
+}:
+
+stdenv.mkDerivation rec {
+  name = "swordsandsoldiers-${version}";
+  version = "20120325";
+
+  src = fetchHumbleBundle {
+    machineName = "swordsandsoldiers_android_and_pc_linux";
+    downloadName = "x86_64.tar.gz";
+    suffix = "tar.gz";
+    md5 = "5f0c9789fa053cbf6bac021a338245bb";
+  };
+
+  buildInputs = [ makeWrapper ];
+
+  patchPhase = let
+    rpath = stdenv.lib.makeLibraryPath [
+      SDL mesa zlib openal libvorbis fontconfig freetype stdenv.cc.cc libogg
+      xorg.libX11 xorg.libXft xorg.libXinerama xorg.libXext xorg.libXpm
+    ];
+  in ''
+    for i in SwordsAndSoldiers.bin SwordsAndSoldiersSetup.bin; do
+      patchelf \
+        --set-interpreter "$(cat $NIX_CC/nix-support/dynamic-linker)" \
+        --set-rpath "${rpath}" "$i"
+    done
+  '';
+
+  installPhase = ''
+    libexec="$out/libexec/swordsandsoldiers"
+    install -vD SwordsAndSoldiers.bin "$libexec/swordsandsoldiers"
+    install -vD SwordsAndSoldiersSetup.bin "$libexec/setup"
+    mv Data "$libexec/"
+
+    mkdir -p "$out/bin"
+    ln -s "$libexec/swordsandsoldiers" "$out/bin/swordsandsoldiers"
+    ln -s "$libexec/setup" "$out/bin/swordsandsoldiers-setup"
+  '';
+
+  dontStrip = true;
+}
diff --git a/pkgs/games/humblebundle/unepic.nix b/pkgs/games/humblebundle/unepic.nix
new file mode 100644
index 00000000..cc4099f5
--- /dev/null
+++ b/pkgs/games/humblebundle/unepic.nix
@@ -0,0 +1,44 @@
+{ stdenv, fetchHumbleBundle, unzip, makeWrapper, SDL2, SDL2_mixer, zlib }:
+
+let
+  version = "1.50.5";
+  versionName = "15005";
+  arch = { 
+    "i686-linux" = "32";
+    "x86_64-linux" = "64";
+  }.${stdenv.system};
+in stdenv.mkDerivation rec {
+  name = "unepic-${version}";
+
+  src = fetchHumbleBundle {
+    name = "unepic-15005.run";
+    machineName = "unepic_linux";
+    downloadName = ".run";
+    md5 = "940824c4de6e48522845f63423e87783";
+  };
+
+  phases = [ "installPhase" ];
+
+  buildInputs = [ unzip makeWrapper ];
+
+  installPhase = let
+    rpath = stdenv.lib.makeLibraryPath [ SDL2 SDL2_mixer zlib stdenv.cc.cc ];
+  in ''
+    dest="$out/opt/games/unepic"
+    exe="$dest/unepic${arch}"
+
+    mkdir -p "$out/opt/games"
+    unzip "$src" "data/*" -d "$out/opt/games" || [ "$?" -eq 1 ]
+    mv "$out/opt/games/data" "$dest"
+    rm -r "$dest"/lib*
+
+    # Patch $exe acccording to arch.
+    patchelf \
+      --set-interpreter "$(cat $NIX_CC/nix-support/dynamic-linker)" \
+      --set-rpath "${rpath}" "$exe"
+
+    mkdir -p "$out/bin"
+
+    makeWrapper "$exe" "$out/bin/unepic" --run "cd '$dest'"
+  '';
+}
diff --git a/pkgs/games/steam/default.nix b/pkgs/games/steam/default.nix
new file mode 100644
index 00000000..03e6b180
--- /dev/null
+++ b/pkgs/games/steam/default.nix
@@ -0,0 +1,38 @@
+{ config, lib, pkgs, ... }:
+
+let
+  cfg = config.steam;
+
+  self = rec {
+    callPackage = pkgs.lib.callPackageWith (pkgs // self);
+
+    fetchSteam = callPackage ./fetchsteam {
+      inherit (config.steam) username password;
+    };
+
+    starbound = callPackage ./starbound.nix { flavor = "stable"; };
+    starbound-unstable = callPackage ./starbound.nix { flavor = "unstable"; };
+  };
+in with lib; {
+  options.steam = {
+    username = mkOption {
+      type = types.nullOr types.str;
+      default = null;
+      description = ''
+        User name for your Steam account.
+      '';
+    };
+
+    password = mkOption {
+      type = types.nullOr types.str;
+      default = null;
+      description = ''
+        Password for your Steam account.
+      '';
+    };
+  };
+
+  config.packages = {
+    steam = mkIf (cfg.username != null && cfg.password != null) self;
+  };
+}
diff --git a/pkgs/games/steam/fetchsteam/default.nix b/pkgs/games/steam/fetchsteam/default.nix
new file mode 100644
index 00000000..cccddb51
--- /dev/null
+++ b/pkgs/games/steam/fetchsteam/default.nix
@@ -0,0 +1,91 @@
+{ stdenv, runCommand, writeText, fetchFromGitHub, buildDotnetPackage
+, username, password
+}:
+
+{ name, appId, depotId, manifestId, sha256, fileList ? [] }:
+
+let
+  protobuf-net = buildDotnetPackage rec {
+    baseName = "protobuf-net";
+    version = "2.0.0.668";
+
+    src = fetchFromGitHub {
+      owner = "mgravell";
+      repo = "protobuf-net";
+      rev = "r668";
+      sha256 = "1060pihqkbr9pd2z6m01d6fsbc9nj56m6y5a0pch9mqdmviv4896";
+    };
+
+    sourceRoot = "${src.name}/${baseName}";
+  };
+
+  SteamKit2 = buildDotnetPackage rec {
+    baseName = "SteamKit2";
+    version = "1.6.4";
+
+    src = fetchFromGitHub {
+      owner = "SteamRE";
+      repo = "SteamKit";
+      rev = "SteamKit_${version}";
+      sha256 = "17d7wi2f396qhp4w9sf37lazvsaqws8x071hfis9gv5llv6s7q46";
+    };
+
+    buildInputs = [ protobuf-net ];
+
+    xBuildFiles = [ "SteamKit2/SteamKit2.sln" ];
+    outputFiles = [ "SteamKit2/SteamKit2/bin/Release/*" ];
+  };
+
+  DepotDownloader = buildDotnetPackage rec {
+    baseName = "DepotDownloader";
+    version = "2.1.1git20160207";
+
+    src = fetchFromGitHub {
+      owner = "SteamRE";
+      repo = baseName;
+      rev = "5fa6621d9f9448fcd20c974b427a8bd2cb044cb4";
+      sha256 = "0vb566d7x1scd96c8ybq6gdbc2cv5jjq453ld458qcvfy587amfn";
+    };
+
+    patches = [ ./downloader.patch ];
+
+    postPatch = ''
+      sed -i \
+        -e 's/\(<[Rr]eference *[Ii]nclude="[^", ]\+\)[^"]*/\1/g' \
+        -e 's,<[Ss]pecific[Vv]ersion>[Tt]rue</[Ss]pecific[Vv]ersion>,,g' \
+        DepotDownloader/DepotDownloader.csproj
+      sed -i -e 's/ version="[^"]*"//g' DepotDownloader/packages.config
+    '';
+
+    buildInputs = [ SteamKit2 protobuf-net ];
+
+    outputFiles = [ "${baseName}/bin/Release/*" ];
+
+    # UUUGLY, but I don't want to spend a week trying to get this working
+    # without that nasty wrapper.
+    makeWrapperArgs = let
+      mkMono = name: path: "${path}/lib/dotnet/${name}";
+      paths = stdenv.lib.mapAttrsToList mkMono {
+        inherit SteamKit2 protobuf-net;
+      };
+      monoPath = stdenv.lib.concatStringsSep ":" paths;
+    in [ "--prefix MONO_PATH : \"${monoPath}\"" ];
+  };
+
+  fileListFile = let
+    content = stdenv.lib.concatStringsSep "\n" fileList;
+  in writeText "steam-file-list-${name}.txt" content;
+
+in with stdenv.lib; runCommand "${name}-src" {
+  buildInputs = [ DepotDownloader ];
+  inherit username password appId depotId manifestId;
+  outputHashAlgo = "sha256";
+  outputHash = sha256;
+  outputHashMode = "recursive";
+} ''
+  depotdownloader -app "$appId" -depot "$depotId" -manifest "$manifestId" \
+    ${optionalString (fileList != []) "-filelist \"${fileListFile}\""} \
+    -username "$username" -password "$password" -dir "$out"
+  rm -r "$out/.DepotDownloader"
+  rm "$out/_steam_depot_manifest_$depotId.csv"
+''
diff --git a/pkgs/games/steam/fetchsteam/downloader.patch b/pkgs/games/steam/fetchsteam/downloader.patch
new file mode 100644
index 00000000..72e5c473
--- /dev/null
+++ b/pkgs/games/steam/fetchsteam/downloader.patch
@@ -0,0 +1,34 @@
+diff --git a/DepotDownloader/ContentDownloader.cs b/DepotDownloader/ContentDownloader.cs
+index 21c317e..81f2a93 100644
+--- a/DepotDownloader/ContentDownloader.cs
++++ b/DepotDownloader/ContentDownloader.cs
+@@ -34,7 +34,7 @@ namespace DepotDownloader
+             public string installDir { get; private set; }
+             public string contentName { get; private set; }
+ 
+-            public ulong manifestId { get; private set; }
++            public ulong manifestId { get; set; }
+             public byte[] depotKey;
+ 
+             public DepotDownloadInfo(uint depotid, ulong manifestId, string installDir, string contentName)
+@@ -198,9 +198,6 @@ namespace DepotDownloader
+ 
+         static ulong GetSteam3DepotManifest(uint depotId, uint appId, string branch)
+         {
+-            if (Config.ManifestId != INVALID_MANIFEST_ID)
+-                return Config.ManifestId;
+-
+             KeyValue depots = GetSteam3AppSection(appId, EAppInfoSection.Depots);
+             KeyValue depotChild = depots[depotId.ToString()];
+ 
+@@ -583,6 +580,10 @@ namespace DepotDownloader
+                 ConfigStore.TheConfig.LastManifests[depot.id] = INVALID_MANIFEST_ID;
+                 ConfigStore.Save();
+ 
++                Console.WriteLine("Latest manifest ID is {0}.", depot.manifestId);
++                if (Config.ManifestId != INVALID_MANIFEST_ID)
++                    depot.manifestId = Config.ManifestId;
++
+                 if (lastManifestId != INVALID_MANIFEST_ID)
+                 {
+                     var oldManifestFileName = Path.Combine(configDir, string.Format("{0}.bin", lastManifestId));
diff --git a/pkgs/games/steam/starbound.nix b/pkgs/games/steam/starbound.nix
new file mode 100644
index 00000000..ba63fcfa
--- /dev/null
+++ b/pkgs/games/steam/starbound.nix
@@ -0,0 +1,132 @@
+{ stdenv, fetchSteam, makeWrapper, SDL, mesa, flavor ? "stable" }:
+
+let
+  renameAttrs = f: let
+    rename = name: value: {
+      name = f name;
+      inherit value;
+    };
+  in stdenv.lib.mapAttrs' rename;
+
+  darwinize = renameAttrs (bin: "Starbound.app/Contents/MacOS/${bin}");
+  winize = renameAttrs (bin: "${bin}.exe");
+
+  mkOsBinaryDeps = with stdenv.lib;
+    if stdenv.system == "x86_64-darwin" then darwinize
+    else if elem stdenv.system [ "i686-cygwin" "x86_64-cygwin" ] then winize
+    else id;
+
+  binaryDeps = mkOsBinaryDeps {
+    starbound.deps = [ SDL mesa ];
+    starbound_server.name = "starbound-server";
+    asset_packer.name = "starbound-asset-packer";
+    asset_unpacker.name = "starbound-asset-unpacker";
+    dump_versioned_json.name = "starbound-dump-versioned-json";
+    make_versioned_json.name = "starbound-make-versioned-json";
+    planet_mapgen.name = "starbound-planet-mapgen";
+  };
+
+  binpath = if stdenv.system == "x86_64-linux" then "linux64"
+            else if stdenv.system == "i686-linux" then "linux32"
+            else if stdenv.system == "x86_64-darwin" then "osx"
+            else if stdenv.system == "i686-cygwin" then "win32"
+            else if stdenv.system == "x86_64-cygwin" then "win64"
+            else throw "Unsupported system ${stdenv.system} for Starbound";
+
+  upstream = let
+    attrs = if flavor == "stable" then {
+      name = "starbound";
+      appId = 211820;
+      depotId = 211821;
+      manifestId = 1842730272313189605;
+      sha256 = "0qppfn56c778wsg38hi6sxgi3rl9nv72h9rmmxybi1vzpf3p49py";
+    } else if flavor == "unstable" then {
+      name = "starbound-unstable";
+      appId = 367540;
+      depotId = 367541;
+      manifestId = 6970641909803280413;
+      sha256 = "0qppfn56c778wsg38hi6sxgi3rl9nv72h9rmmxybi1vzpf3p49py";
+    } else throw "Unsupported flavor, use either `stable' or `unstable'.";
+  in fetchSteam (attrs // {
+    fileList = [
+      "^(?:assets|tiled)/"
+      ( "^${binpath}(?:/Starbound\\.app/Contents/MacOS)?"
+      + "/(?:[a-zA-Z0-9_-]+(?:\\.exe)?|sbboot\\.config)$")
+    ];
+  });
+
+in stdenv.mkDerivation {
+  name = "${upstream.name}-20160208";
+
+  unpackPhase = ":";
+
+  configurePhase = ''
+    libexec="$out/libexec/starbound"
+    data="$out/share/starbound"
+  '';
+
+  inherit binpath upstream;
+
+  buildInputs = [ makeWrapper ];
+
+  buildPhase = with stdenv.lib; ''
+    mkdir -p patched
+    sed -e 's,\.\./assets,'"$data/assets"',g' \
+        -e 's,\.\./giraffe_storage,.,g' \
+        "$upstream/$binpath/sbboot.config" > "patched/sbboot.config"
+  '' + concatStrings (mapAttrsToList (bin: attrs: ''
+    mkdir -p "patched/$(dirname "${bin}")"
+    cp -t "patched/$(dirname "${bin}")" "$upstream/$binpath/${bin}"
+    chmod +x "patched/$(basename "${bin}")"
+    patchelf \
+      --set-interpreter "$(cat $NIX_CC/nix-support/dynamic-linker)" \
+      --set-rpath "${stdenv.lib.makeLibraryPath (attrs.deps or [])}" \
+      "patched/$(basename "${bin}")"
+    if ldd "patched/$(basename "${bin}")" | grep -F 'not found'; then
+      exit 1;
+    fi
+  '') binaryDeps);
+
+  doCheck = true;
+
+  checkPhase = ''
+    checkFailed=
+    for i in "$upstream/$binpath"/*; do
+      [ -f "$i" ] || continue
+      [ "$(basename "$i")" != launcher ] || continue
+      [ ! -e "patched/$(basename "$i")" ] || continue
+
+      echo "Found missing binary $i from the upstream tree."
+      checkFailed=1
+    done
+    [ -z "$checkFailed" ]
+  '';
+
+  installPhase = ''
+    mkdir -p "$out/bin"
+    ${stdenv.lib.concatStrings (stdenv.lib.mapAttrsToList (bin: attrs: ''
+      prog="$(basename "${bin}")"
+      install -vD "patched/$prog" "$libexec/$prog"
+      cat > "$out/bin/${attrs.name or "$prog"}" <<EOF
+      #!${stdenv.shell} -e
+      [ -n "\$XDG_DATA_HOME" ] || XDG_DATA_HOME="\$HOME/.local/share"
+      mkdir -p "\$XDG_DATA_HOME/starbound/mods"
+      ln -sf "$out/etc/sbboot.config" "\$XDG_DATA_HOME/starbound/sbboot.config"
+      cd "\$XDG_DATA_HOME/starbound"
+      exec "$libexec/$prog" "\$@"
+      EOF
+      chmod +x "$out/bin/${attrs.name or "$prog"}"
+    '') binaryDeps)}
+
+    install -vD -m 644 patched/sbboot.config "$out/etc/sbboot.config"
+
+    mkdir -p "$data"
+    for i in assets tiled; do
+      echo -n "Installing $i..."
+      cp -rt "$data" "$upstream/$i"
+      echo " done."
+    done
+  '';
+
+  dontStrip = true;
+}
diff --git a/pkgs/grandpa/default.nix b/pkgs/grandpa/default.nix
new file mode 100644
index 00000000..b1704538
--- /dev/null
+++ b/pkgs/grandpa/default.nix
@@ -0,0 +1,20 @@
+{ fetchFromGitHub, buildPythonPackage, pythonPackages, cython, gpm }:
+
+pythonPackages.buildPythonPackage {
+  name = "grandpa-0.5";
+  namePrefix = "";
+
+  src = fetchFromGitHub {
+    owner = "aszlig";
+    repo = "GrandPA";
+    rev = "d8d2571f732a68ed18be7533244db2cfb822b4c1";
+    sha256 = "19zf3pnr1adngncvinvn8yyvc0sj66lp7lwiql6379rf78xxlmhn";
+  };
+
+  doCheck = false;
+
+  buildInputs = [ cython gpm ];
+  propagatedBuildInputs = with pythonPackages; [
+    bsddb curses pyserial
+  ];
+}
diff --git a/pkgs/greybird-xfce-theme/default.nix b/pkgs/greybird-xfce-theme/default.nix
new file mode 100644
index 00000000..80b26e85
--- /dev/null
+++ b/pkgs/greybird-xfce-theme/default.nix
@@ -0,0 +1,26 @@
+{ stdenv, fetchFromGitHub }:
+
+stdenv.mkDerivation {
+  name = "greybird-xfce-theme";
+
+  src = fetchFromGitHub {
+    repo = "Greybird";
+    owner = "shimmerproject";
+    rev = "d0a50a8ea75f11d668229287e83189ef038a56f0";
+    sha256 = "08lf39qbx85ldxfh4qyj9fd42mbsg3vs2r0bg1csl6qx13lffiay";
+  };
+
+  phases = [ "unpackPhase" "installPhase" ];
+
+  installPhase = ''
+    mkdir -p "$out/share/themes/Greybird"
+    cp -vrt "$out/share/themes/Greybird" \
+      gtk-* metacity-1 unity xfce-notify-4.0 xfwm4
+
+    for i in a11y compact; do
+      outdir="$out/share/themes/Greybird-$i/xfwm4"
+      mkdir -p "$outdir"
+      cp -vrt "$outdir" xfwm4-$i/*
+    done
+  '';
+}
diff --git a/pkgs/kpatches/bfqsched/default.nix b/pkgs/kpatches/bfqsched/default.nix
new file mode 100644
index 00000000..fd6c6f81
--- /dev/null
+++ b/pkgs/kpatches/bfqsched/default.nix
@@ -0,0 +1,45 @@
+{ stdenv, fetchurl }:
+
+let
+  bfqVersion = "v7r11";
+  kernelVersion = "4.4";
+  fullKernelVersion = "${kernelVersion}.0";
+  version = "${fullKernelVersion}-${bfqVersion}";
+
+  baseURL = "http://algo.ing.unimo.it/people/paolo/disk_sched/patches";
+
+  fetchPatch = { name, sha256 }: fetchurl {
+    url = "${baseURL}/${version}/${name}.patch";
+    inherit sha256;
+  };
+
+  allPatches = [
+    (fetchPatch {
+      name = "0001-block-cgroups-kconfig-build-bits-for-BFQ-"
+           + "${bfqVersion}-${fullKernelVersion}";
+      sha256 = "1kmlfz63610zc4lxhanjsn4hhw43cdsbk3pyaij723vbd7619kyi";
+    })
+    (fetchPatch {
+      name = "0002-block-introduce-the-BFQ-"
+           + "${bfqVersion}-I-O-sched-for-${fullKernelVersion}";
+      sha256 = "1i5jqkxglp3ah76i4vyi13pnmjkr6qlqy69qbaj2132vijqkyz5i";
+    })
+    (fetchPatch {
+      name = "0003-block-bfq-add-Early-Queue-Merge-EQM-to-BFQ-"
+           + "${bfqVersion}-for";
+      sha256 = "09bv31s8d2aphi3d9py4sz1gcvyb5645a8s7zj614a56hv11p8k9";
+    })
+  ];
+
+  patch = stdenv.mkDerivation {
+    name = "bfqsched-${version}.patch";
+    inherit allPatches;
+    buildCommand = ''
+      cat $allPatches > "$out"
+    '';
+  };
+
+in {
+  name = "bfqsched-${version}";
+  inherit version patch;
+}
diff --git a/pkgs/libcmt/default.nix b/pkgs/libcmt/default.nix
new file mode 100644
index 00000000..e255ef25
--- /dev/null
+++ b/pkgs/libcmt/default.nix
@@ -0,0 +1,25 @@
+{ stdenv, fetchurl, ladspaH }:
+
+stdenv.mkDerivation rec {
+  name = "libcmt-${version}";
+  version = "1.16";
+
+  buildInputs = [ ladspaH ];
+
+  setSourceRoot = ''
+    sourceRoot=cmt/src
+  '';
+
+  makeFlags = [
+    "INSTALL_PLUGINS_DIR=$(out)/lib/ladspa"
+  ];
+
+  preInstall = ''
+    mkdir -p "$out/lib/ladspa"
+  '';
+
+  src = fetchurl {
+    url = "http://www.ladspa.org/download/cmt_src_${version}.tgz";
+    sha256 = "0dan83pvljij3972bv214balc26p9fgw40i2d5y0x7lbd5z1saji";
+  };
+}
diff --git a/pkgs/librxtx-java/default.nix b/pkgs/librxtx-java/default.nix
new file mode 100644
index 00000000..14b0a9da
--- /dev/null
+++ b/pkgs/librxtx-java/default.nix
@@ -0,0 +1,29 @@
+{ stdenv, fetchurl, unzip, jdk, lockdev }:
+
+stdenv.mkDerivation rec {
+  name = "rxtx-${version}";
+  version = "2.2pre2";
+
+  src = fetchurl {
+    urls = [
+      "http://rxtx.qbang.org/pub/rxtx/${name}.zip"
+      "ftp://ftp.freebsd.org/pub/FreeBSD/ports/distfiles/${name}.zip"
+    ];
+    sha256 = "00sv9604hkq81mshih0fhqfzn4mf01d6rish6vplsi0gfqz3fc1w";
+  };
+
+  buildInputs = [ unzip jdk lockdev ];
+
+  NIX_CFLAGS_COMPILE = "-DUTS_RELEASE=\"3.8.0\"";
+
+  configureFlags = [ "--enable-liblock" ];
+
+  makeFlags = [
+    "JHOME=$(out)/share/java"
+    "RXTX_PATH=$(out)/lib"
+  ];
+
+  preInstall = ''
+    mkdir -p "$out/lib" "$out/share/java"
+  '';
+}
diff --git a/pkgs/list-gamecontrollers/default.nix b/pkgs/list-gamecontrollers/default.nix
new file mode 100644
index 00000000..c207d2eb
--- /dev/null
+++ b/pkgs/list-gamecontrollers/default.nix
@@ -0,0 +1,10 @@
+{ runCommand, pkgconfig, SDL2 }:
+
+runCommand "list-gamecontrollers" {
+  buildInputs = [ pkgconfig SDL2 ];
+} ''
+  mkdir -p "$out/bin"
+  gcc -Werror "${./list-gc.c}" \
+    $(pkg-config --libs --cflags sdl2) \
+    -o "$out/bin/list-gamecontrollers"
+''
diff --git a/pkgs/list-gamecontrollers/list-gc.c b/pkgs/list-gamecontrollers/list-gc.c
new file mode 100644
index 00000000..f40b7da6
--- /dev/null
+++ b/pkgs/list-gamecontrollers/list-gc.c
@@ -0,0 +1,31 @@
+#include <SDL.h>
+
+void dump_guid(SDL_Joystick *js) {
+    SDL_JoystickGUID guid;
+    const char *name;
+    char guidstr[33];
+
+    guid = SDL_JoystickGetGUID(js);
+    name = SDL_JoystickName(js);
+    SDL_JoystickGetGUIDString(guid, guidstr, sizeof(guidstr));
+
+    printf("%s: %s\n", name, guidstr);
+}
+
+int main()
+{
+    int i;
+    SDL_Joystick *js;
+
+    SDL_Init(SDL_INIT_JOYSTICK);
+    atexit(SDL_Quit);
+
+    for (i = 0; i < SDL_NumJoysticks(); ++i) {
+        if ((js = SDL_JoystickOpen(i)) != NULL) {
+            dump_guid(js);
+            SDL_JoystickClose(js);
+        }
+    }
+
+    return EXIT_SUCCESS;
+}
diff --git a/pkgs/lockdev/default.nix b/pkgs/lockdev/default.nix
new file mode 100644
index 00000000..52e78eb5
--- /dev/null
+++ b/pkgs/lockdev/default.nix
@@ -0,0 +1,23 @@
+{ stdenv, fetchurl, perl }:
+
+let
+  baseurl = "ftp://ftp.debian.org/debian/pool/main/l/lockdev/";
+in stdenv.mkDerivation rec {
+  name = "lockdev-${version}";
+  version = "1.0.3";
+
+  buildInputs = [ perl ];
+
+  patches = stdenv.lib.singleton (fetchurl {
+    url = baseurl + "lockdev_1.0.3-1.5.diff.gz";
+    sha256 = "1l3pq1nfb5qx3i91cjaiz3c53368gw6m28a5mv9391n5gmsdmi3r";
+  });
+
+  NIX_CFLAGS_COMPILE = "-fPIC -D_PATH_LOCK=\"/tmp\"";
+  installFlags = [ "basedir=$(out)" ];
+
+  src = fetchurl {
+    url = baseurl + "lockdev_${version}.orig.tar.gz";
+    sha256 = "10lzhq6r2dn8y3ki7wlqsa8s3ndkf842bszcjw4dbzf3g9fn7bnc";
+  };
+}
diff --git a/pkgs/nixops/default.nix b/pkgs/nixops/default.nix
new file mode 100644
index 00000000..af16b56c
--- /dev/null
+++ b/pkgs/nixops/default.nix
@@ -0,0 +1,37 @@
+{ stdenv, fetchFromGitHub, fetchpatch, git }:
+
+let
+  rev = "9076dbc722a4125b2a08d4b49d94b2073b71578f";
+  sha256 = "05zc12spjk9pcspqq88wz3k4rgqy8bsxy28ysjw752959b95ys1z";
+
+  master = stdenv.mkDerivation rec {
+    name = "nixops-upstream-patched";
+
+    src = fetchFromGitHub {
+      owner = "NixOS";
+      repo = "nixops";
+      inherit rev sha256;
+    };
+
+    phases = [ "unpackPhase" "patchPhase" "installPhase" ];
+
+    postPatch = ''
+      sed -i -re 's!<nixpkgs([^>]*)>!${import ../../nixpkgs-path.nix}\1!g' \
+        release.nix doc/manual/default.nix doc/manual/resource.nix
+    '';
+
+    installPhase = ''
+      cp -a . "$out"
+    '';
+  };
+
+  release = import "${master}/release.nix" {
+    nixopsSrc = {
+      outPath = master;
+      inherit rev;
+      revCount = 0;
+      shortRev = builtins.substring 0 7 rev;
+    };
+    officialRelease = false;
+  };
+in stdenv.lib.getAttr stdenv.system release.build
diff --git a/pkgs/pvolctrl/default.nix b/pkgs/pvolctrl/default.nix
new file mode 100644
index 00000000..5701c19e
--- /dev/null
+++ b/pkgs/pvolctrl/default.nix
@@ -0,0 +1,35 @@
+{ stdenv, fetchurl, pkgconfig, libpulseaudio }:
+
+stdenv.mkDerivation rec {
+  name = "pvolctrl-0.23";
+
+  unpackPhase = let
+    baseurl = "https://sites.google.com/site/guenterbartsch/blog/"
+            + "volumecontrolutilityforpulseaudio/";
+    makefile = fetchurl {
+      url = baseurl + "Makefile";
+      sha256 = "0l2ffvb617csk6h29y64v6ywhpcp7la6vvcip1w4nq0yry6jhrqz";
+    };
+    source = fetchurl {
+      url = baseurl + "pvolctrl.c";
+      sha256 = "0vcd5dlw9l47jpabwmmzdvlkn67fz55dr3sryyh56sl263mibjda";
+    };
+  in ''
+    mkdir -p "${name}"
+    sed -e 's|/usr/bin/||' "${makefile}" > "${name}/Makefile"
+    sed -e 's/PA_VOLUME_MAX/PA_VOLUME_NORM/
+    /avg_vol += (avg_vol \* vol_mod) \/ 100;/ {
+      s/(avg_vol/((int)PA_VOLUME_NORM/
+    }
+    /if (vol_mod)/i \
+      if (info->name == NULL || strncmp(info->name, "combined", 8) != 0) \
+        return;' "${source}" > "${name}/pvolctrl.c"
+    sourceRoot="${name}"
+  '';
+
+  installPhase = ''
+    install -D -T pvolctrl "$out/bin/pvolctrl"
+  '';
+
+  buildInputs = [ pkgconfig libpulseaudio ];
+}
diff --git a/pkgs/show-qr-code/default.nix b/pkgs/show-qr-code/default.nix
new file mode 100644
index 00000000..17d9847a
--- /dev/null
+++ b/pkgs/show-qr-code/default.nix
@@ -0,0 +1,28 @@
+{ stdenv, writeScriptBin, gtkdialog, qrencode }:
+
+let script = writeScriptBin "show-qr-code" ''
+  #!/bin/sh
+  TMP=$(mktemp)
+  ${qrencode}/bin/qrencode -s 8 -o "$TMP" -t PNG "$1"
+
+  export DIALOG='
+  <vbox>
+      <pixmap>
+          <input file>'$TMP'</input>
+      </pixmap>
+  </vbox>
+  '
+
+  ${gtkdialog}/bin/gtkdialog --program=DIALOG > /dev/null &
+
+  sleep 0.2
+
+  rm "$TMP"
+
+  '';
+
+in script // {
+  meta = {
+    description = "Show the given string as qr code in a gtk window";
+  };
+}
diff --git a/pkgs/sidplayfp/default.nix b/pkgs/sidplayfp/default.nix
new file mode 100644
index 00000000..c06da466
--- /dev/null
+++ b/pkgs/sidplayfp/default.nix
@@ -0,0 +1,29 @@
+{ stdenv, fetchurl, pkgconfig, alsaLib, libpulseaudio }:
+
+let
+  libsidplayfp = stdenv.mkDerivation rec {
+    name = "libsidplayfp-${version}";
+    version = "1.3.0";
+
+    src = fetchurl {
+      url = "mirror://sourceforge/sidplay-residfp/${name}.tar.gz";
+      sha256 = "1gd4pn445v3wzr95z1b8642w016dnhq2hi8dgpc9imxig4xhx47d";
+    };
+  };
+
+in stdenv.mkDerivation rec {
+  name = "sidplayfp-${version}";
+  version = "1.1.0.1";
+
+  src = fetchurl {
+    url = "mirror://sourceforge/sidplay-residfp/${name}.tar.gz";
+    sha256 = "0m8gk4xw2g4s3rcc3qy7nw6i08ivijjnbf3b6s5y3ryysyjjmc50";
+  };
+
+  postPatch = ''
+    sed -i -e '/cerr.*\(Clear screen\|Move cursor\)/d' src/menu.cpp
+  '';
+
+  buildInputs = [ pkgconfig libsidplayfp alsaLib libpulseaudio ];
+}
+
diff --git a/pkgs/tkabber-urgent-plugin/default.nix b/pkgs/tkabber-urgent-plugin/default.nix
new file mode 100644
index 00000000..b39e5ea8
--- /dev/null
+++ b/pkgs/tkabber-urgent-plugin/default.nix
@@ -0,0 +1,26 @@
+{ stdenv, fetchsvn, xlibs }:
+
+stdenv.mkDerivation {
+  name = "tkabber-urgent-plugin";
+
+  src = fetchsvn {
+    url = "http://svn.xmpp.ru/repos/tkabber-3rd-party/trunk/plugins/urgent";
+    rev = 528;
+    sha256 = "1qr7i0559ad5y1l5h2gp8aix4nsfgm0bx7jqb030hgbxaw1xnbp5";
+  };
+
+  buildInputs = [ xlibs.libX11 ];
+
+  patchPhase = ''
+    sed -i -e 's|exec xwininfo|exec ${xlibs.xwininfo}/bin/xwininfo|' urgent.tcl
+  '';
+
+  buildPhase = ''
+    gcc -lX11 -o urgent urgent.c
+  '';
+
+  installPhase = ''
+    install -vd "$out/share/tkabber-plugins/urgent"
+    cp -vpt "$out/share/tkabber-plugins/urgent" urgent urgent.tcl
+  '';
+}
diff --git a/pkgs/tomahawk/default.nix b/pkgs/tomahawk/default.nix
new file mode 100644
index 00000000..d8d9cbc6
--- /dev/null
+++ b/pkgs/tomahawk/default.nix
@@ -0,0 +1,89 @@
+{ stdenv, fetchFromGitHub, fetchurl, cmake, pkgconfig, attica, boost, gnutls
+, libechonest, liblastfm, lucenepp, vlc_qt5, qca-qt5, qt5, qtkeychain
+, kde5_latest, sparsehash, taglib, websocketpp, makeWrapper, ffmpeg_2, v4l_utils
+
+, enableXMPP      ? true,  libjreen     ? null
+, enableKDE       ? false, kdelibs      ? null
+, enableTelepathy ? false, telepathy_qt ? null
+}:
+
+assert enableXMPP      -> libjreen     != null;
+assert enableKDE       -> kdelibs      != null;
+assert enableTelepathy -> telepathy_qt != null;
+
+with stdenv.lib;
+
+let
+  useQT5 = pkg: let
+    qt5variant = pkg.override (attrs: {
+      ${if attrs ? qt4 then "qt4" else "qt"} = qt5.qtbase;
+    });
+  in qt5variant.overrideDerivation (drv: {
+    postInstall = (drv.postInstall or "") + ''
+      for i in "$out"/include/*; do
+        [ -d "$i" ] || continue
+        ! expr "$i" : '.*5$$' > /dev/null || continue
+        ln -sv "$i" "''${i}5"
+      done
+      for l in "$out"/lib*/*.so*; do
+        bn="$(basename "$l")"
+        ! expr "''${bn%.so*}" : '.*5$$' > /dev/null || continue
+        ln -sv "$l" "$(dirname "$l")/''${bn%.so*}5.''${bn#*.}"
+      done
+    '';
+  });
+
+  libechonestQT5 = overrideDerivation ((useQT5 libechonest).override {
+    qjson = null;
+  }) (drv: {
+    cmakeFlags = (drv.cmakeFlags or []) ++ [ "-DBUILD_WITH_QT4=OFF" ];
+  });
+
+  qtkeychainQT5 = overrideDerivation (useQT5 qtkeychain) (drv: {
+    cmakeFlags = (drv.cmakeFlags or []) ++ [
+      "-DBUILD_WITH_QT4=OFF"
+      "-DQt5LinguistTools_DIR=${qt5.qttools}/lib/cmake/Qt5LinguistTools"
+    ];
+  });
+
+  vlc = vlc_qt5.override {
+    ffmpeg = ffmpeg_2.override {
+      v4l_utils = v4l_utils.override { withQt4 = false; };
+    };
+  };
+
+in stdenv.mkDerivation rec {
+  name = "tomahawk-${version}";
+  version = "0.9.0-git";
+
+  src = fetchFromGitHub {
+    owner = "tomahawk-player";
+    repo = "tomahawk";
+    rev = "d4c3f24232f09e352868cf8592efcfb1f228b2db";
+    sha256 = "0hn7fa2a17i76ai657h6l9f4yp3sz75xpv3yparky9kir6zjbrrz";
+  };
+
+  cmakeFlags = [
+    "-DLUCENEPP_INCLUDE_DIR=${lucenepp}/include"
+    "-DLUCENEPP_LIBRARY_DIR=${lucenepp}/lib"
+  ];
+
+  buildInputs = (map useQT5 [ liblastfm qt5.quazip ]) ++ [
+    qca-qt5 qtkeychainQT5 libechonestQT5 kde5_latest.attica cmake pkgconfig
+    kde5_latest.extra-cmake-modules boost gnutls lucenepp vlc qt5.qtbase
+    qt5.qtsvg qt5.qttools qt5.qtwebkit qt5.qtx11extras sparsehash taglib
+    websocketpp makeWrapper
+  ] ++ stdenv.lib.optional enableXMPP      (useQT5 libjreen)
+    ++ stdenv.lib.optional enableKDE       (useQT5 kdelibs)
+    ++ stdenv.lib.optional enableTelepathy (useQT5 telepathy_qt);
+
+  enableParallelBuilding = true;
+
+  meta = with stdenv.lib; {
+    description = "A multi-source music player";
+    homepage = "http://tomahawk-player.org/";
+    license = licenses.gpl3Plus;
+    platforms = platforms.all;
+    maintainers = [ maintainers.aszlig ];
+  };
+}
diff --git a/pkgs/twitchstream/default.nix b/pkgs/twitchstream/default.nix
new file mode 100644
index 00000000..b6d0b523
--- /dev/null
+++ b/pkgs/twitchstream/default.nix
@@ -0,0 +1,112 @@
+{ stdenv, fetchurl, writeScriptBin, ffmpeg_2, libpulseaudio }:
+
+# FIXME: Clean up this whole file!
+
+with stdenv.lib;
+
+let
+  streams = {
+    dnyarri = {
+      width = 1920;
+      height = 1080;
+      monitor = 1;
+    };
+    mmrnmhrm = {
+      width = 1600;
+      height = 1280;
+      monitor = 1;
+    };
+  };
+
+  sumAttr = name: attrs: acc: acc + (getAttr name attrs);
+  maxAttr = name: attrs: acc: let
+    current = getAttr name attrs;
+  in if acc > current then acc else current;
+
+  fullwidth = fold (sumAttr "width") 0 (attrValues streams);
+  maxheight = fold (maxAttr "height") 0 (attrValues streams);
+
+  resolution = "1920x1080";
+  fps = 15;
+  quality = "slow";
+
+  encoder = let
+    aacenc = stdenv.mkDerivation rec {
+      name = "vo-aacenc-0.1.3";
+      src = fetchurl {
+        url = "mirror://sourceforge/opencore-amr/${name}.tar.gz";
+        sha256 = "0dhghm3c8pqrriwwyj5x9i0yf52fmdfijbgqqkvqvwarldvp86p5";
+      };
+    };
+    base = ffmpeg_2.override { x11grabSupport = true; };
+  in stdenv.lib.overrideDerivation base (attrs: {
+    configureFlags = attrs.configureFlags ++ [
+      "--enable-libpulse"
+      "--enable-version3"
+      "--enable-libvo-aacenc"
+    ];
+    preConfigure = ''
+      addPkgConfigPath "${libpulseaudio}"
+      addPkgConfigPath "${aacenc}"
+    '';
+    NIX_CFLAGS_COMPILE = "-I${aacenc}/include -L${aacenc}/lib";
+    buildInputs = attrs.buildInputs ++ [ libpulseaudio aacenc ];
+  });
+
+  script = let
+    combine = [
+      "color=c=black:s=1248x640 [surface]"
+      "[0:v] setpts=PTS-STARTPTS, scale=680x540 [left]"
+      "[1:v] setpts=PTS-STARTPTS, scale=568x640 [right]"
+      "[surface][left] overlay=0:0 [leftonly]"
+      "[leftonly][right] overlay=680:0 [out]"
+    ];
+  /*
+    combine = [
+      "color=c=black:s=${toString fullwidth}x${toString maxheight} [surface]"
+      "[surface][0:v] overlay=0:0 [leftonly]"
+      "[leftonly][1:v] overlay=${toString streams.dnyarri.width}:0 [out]"
+    ];
+  */
+    nop = x: "\\";
+  in ''
+    #!${stdenv.shell}
+    keyfile="$HOME/.twitch.key"
+    if [ ! -e "$keyfile" ]; then
+      echo "You need to put your streaming key into $keyfile!" >&2
+      echo "To obtain the key, please visit the following URL:" >&2
+      echo "http://www.twitch.tv/broadcast/dashboard/streamkey" >&2
+      exit 1
+    fi
+
+    ${encoder}/bin/ffmpeg -loglevel warning \
+      -f x11grab -s "${resolution}" -r "${toString fps}" -i "$DISPLAY+1920,0" \
+      -f pulse -ac 2 -i default \
+      -codec:v libx264 -s 1280x720 -preset:v fast -crf 24 -pix_fmt yuv420p \
+      -codec:a libvo_aacenc -ar 44100 -threads auto -b:a 128k -bufsize 8k \
+      -f flv "rtmp://live-fra.twitch.tv/app/$(< "$keyfile")" "$@"
+  '';
+
+  disabled = ''
+    ${encoder}/bin/ffmpeg \
+      -f x11grab -s "${resolution}" -r "${toString fps}" -i "$DISPLAY+1920,0" \
+      ${nop ''
+      -i 'tcp://dnyarri:7891?listen' \
+      ''}
+      -f pulse -ac 2 -i default \
+      ${nop ''
+      -filter_complex "${concatStringsSep "; " combine}" \
+      -map "[out]" -map 2:a,0:v \
+      -c:v libx264 -preset "${quality}" -s 1280x720 \
+                   -b 2500k -minrate 2500k -maxrate 2500k \
+                   -tune film -qscale:v 1 -threads:v 4 -crf 1 -tune animation \
+      -c:a libmp3lame -ar 44100 -qscale:a 1 -bufsize 512k -threads 4 \
+      -framerate "${toString fps}" \
+      -force_key_frames 2 -b 2500k -minrate 2500k -maxrate 2500k \
+      -g 2 -keyint_min 2 \
+      ''}
+      -c:v libx264 -preset fast -pix_fmt yuv420p -s 1280x800 -threads 0 \
+      -c:a libmp3lame -ab 128k -ar 44100 -threads 0 \
+      -f flv "rtmp://live-fra.twitch.tv/app/$(< "$keyfile")" "$@"
+  '';
+in writeScriptBin "twitchstream" script