diff options
Diffstat (limited to 'pkgs/servers/x11/xquartz')
-rwxr-xr-x | pkgs/servers/x11/xquartz/X11 | 20 | ||||
-rw-r--r-- | pkgs/servers/x11/xquartz/default.nix | 187 | ||||
-rwxr-xr-x | pkgs/servers/x11/xquartz/font_cache | 240 | ||||
-rw-r--r-- | pkgs/servers/x11/xquartz/org.nixos.xquartz.privileged_startx.plist | 23 | ||||
-rw-r--r-- | pkgs/servers/x11/xquartz/org.nixos.xquartz.startx.plist | 27 | ||||
-rw-r--r-- | pkgs/servers/x11/xquartz/patch_plist.rb | 47 | ||||
-rwxr-xr-x | pkgs/servers/x11/xquartz/privileged | 43 | ||||
-rwxr-xr-x | pkgs/servers/x11/xquartz/startx | 232 | ||||
-rw-r--r-- | pkgs/servers/x11/xquartz/system-fonts.nix | 36 | ||||
-rwxr-xr-x | pkgs/servers/x11/xquartz/xinitrc | 40 |
10 files changed, 895 insertions, 0 deletions
diff --git a/pkgs/servers/x11/xquartz/X11 b/pkgs/servers/x11/xquartz/X11 new file mode 100755 index 00000000000..39bcce2c10b --- /dev/null +++ b/pkgs/servers/x11/xquartz/X11 @@ -0,0 +1,20 @@ +#!/bin/bash + +set "$(dirname "$0")"/X11.bin "${@}" + +export XQUARTZ_DEFAULT_CLIENT="@DEFAULT_CLIENT@" +export XQUARTZ_DEFAULT_SHELL="@DEFAULT_SHELL@" +export XQUARTZ_DEFAULT_STARTX="@DEFAULT_STARTX@" +export FONTCONFIG_FILE="@FONTCONFIG_FILE@" + +if [ -x ~/.x11run ]; then + exec ~/.x11run "${@}" +fi + +case $(basename "${SHELL}") in + bash) exec -l "${SHELL}" --login -c 'exec "${@}"' - "${@}" ;; + ksh|sh|zsh) exec -l "${SHELL}" -c 'exec "${@}"' - "${@}" ;; + csh|tcsh) exec -l "${SHELL}" -c 'exec $argv:q' "${@}" ;; + es|rc) exec -l "${SHELL}" -l -c 'exec $*' "${@}" ;; + *) exec "${@}" ;; +esac diff --git a/pkgs/servers/x11/xquartz/default.nix b/pkgs/servers/x11/xquartz/default.nix new file mode 100644 index 00000000000..abcae211f42 --- /dev/null +++ b/pkgs/servers/x11/xquartz/default.nix @@ -0,0 +1,187 @@ +{ stdenv, lib, buildEnv, makeFontsConf, gnused, writeScript, xorg, bashInteractive, substituteAll, xterm, makeWrapper, ruby +, openssl, quartz-wm, fontconfig, xkeyboard_config, xlsfonts, xfontsel +, ttf_bitstream_vera, freefont_ttf, liberation_ttf +, shell ? "${bashInteractive}/bin/bash" +}: + +# ------------ +# Installation +# ------------ +# +# First, assuming you've previously installed XQuartz from macosforge.com, +# unload and remove the existing launch agents: +# +# $ sudo launchctl unload /Library/LaunchAgents/org.macosforge.xquartz.startx.plist +# $ sudo launchctl unload /Library/LaunchDaemons/org.macosforge.xquartz.privileged_startx.plist +# $ sudo rm /Library/LaunchAgents/org.macosforge.xquartz.startx.plist +# $ sudo rm /Library/LaunchDaemons/org.macosforge.xquartz.privileged_startx.plist +# +# (You will need to log out for the above changes to take effect.) +# +# Then install xquartz from nixpkgs: +# +# $ nix-env -i xquartz +# $ xquartz-install +# +# You'll also want to add the following to your shell's profile (after you +# source nix.sh, so $NIX_LINK points to your user profile): +# +# if [ "$(uname)" = "Darwin" -a -n "$NIX_LINK" -a -f $NIX_LINK/etc/X11/fonts.conf ]; then +# export FONTCONFIG_FILE=$NIX_LINK/etc/X11/fonts.conf +# fi + +# A note about dependencies: +# Xquartz wants to exec XQuartz.app, XQuartz.app wants to exec xstart, and +# xstart wants to exec Xquartz, so we must bundle all three to prevent a cycle. +# Coincidentally, this also makes it trivial to install launch agents/daemons +# that point into the user's profile. + +let + shellEscape = x: "'${lib.replaceChars ["'"] [("'\\'" + "'")] x}'"; + installer = writeScript "xquartz-install" '' + NIX_LINK=$HOME/.nix-profile + + tmpdir=$(/usr/bin/mktemp -d $TMPDIR/xquartz-installer-XXXXXXXX) + agentName=org.nixos.xquartz.startx.plist + daemonName=org.nixos.xquartz.privileged_startx.plist + sed=${gnused}/bin/sed + + cp ${./org.nixos.xquartz.startx.plist} $tmpdir/$agentName + $sed -i "s|@LAUNCHD_STARTX@|$NIX_LINK/etc/X11/xinit/launchd_startx|" $tmpdir/$agentName + $sed -i "s|@STARTX@|$NIX_LINK/bin/startx|" $tmpdir/$agentName + $sed -i "s|@XQUARTZ@|$NIX_LINK/bin/Xquartz|" $tmpdir/$agentName + + cp ${./org.nixos.xquartz.privileged_startx.plist} $tmpdir/$daemonName + $sed -i "s|@PRIVILEGED_STARTX@|$NIX_LINK/lib/X11/xinit/privileged_startx|" $tmpdir/$daemonName + $sed -i "s|@PRIVILEGED_STARTX_D@|$NIX_LINK/lib/X11/xinit/privileged_startx.d|" $tmpdir/$daemonName + + sudo cp $tmpdir/$agentName /Library/LaunchAgents/$agentName + sudo cp $tmpdir/$daemonName /Library/LaunchDaemons/$daemonName + sudo launchctl load -w /Library/LaunchAgents/$agentName + sudo launchctl load -w /Library/LaunchDaemons/$daemonName + ''; + fontDirs = [ + xorg.fontbhttf + xorg.fontbhlucidatypewriter100dpi + xorg.fontbhlucidatypewriter75dpi + ttf_bitstream_vera + freefont_ttf + liberation_ttf + xorg.fontbh100dpi + xorg.fontmiscmisc + xorg.fontcursormisc + ]; + fontsConf = makeFontsConf { + fontDirectories = fontDirs ++ [ + "/Library/Fonts" + "~/Library/Fonts" + ]; + }; + fonts = import ./system-fonts.nix { + inherit stdenv xorg fontDirs; + }; + # any X related programs expected to be available via $PATH + env = buildEnv { + name = "xquartz-env"; + pathsToLink = [ "/bin" ]; + paths = with xorg; [ + # non-xorg + quartz-wm xterm fontconfig + # xorg + xlsfonts xfontsel + bdftopcf fontutil iceauth libXpm lndir luit makedepend mkfontdir + mkfontscale sessreg setxkbmap smproxy twm x11perf xauth xbacklight xclock + xcmsdb xcursorgen xdm xdpyinfo xdriinfo xev xeyes xfs xgamma xhost + xinput xkbcomp xkbevd xkbutils xkill xlsatoms xlsclients xmessage xmodmap + xpr xprop xrandr xrdb xrefresh xset xsetroot xvinfo xwd xwininfo xwud + ]; + }; +in stdenv.mkDerivation { + name = "xquartz"; + buildInputs = [ ruby makeWrapper ]; + unpackPhase = "sourceRoot=."; + buildPhase = ":"; + installPhase = '' + cp -rT ${xorg.xinit} $out + chmod -R u+w $out + cp -rT ${xorg.xorgserver} $out + chmod -R u+w $out + + cp ${installer} $out/bin/xquartz-install + + rm -r $out/LaunchAgents + + fontsConfPath=$out/etc/X11/fonts.conf + cp ${fontsConf} $fontsConfPath + + cp ${./startx} $out/bin/startx + substituteInPlace $out/bin/startx \ + --replace "@PATH@" "$out/bin:${env}" \ + --replace "@XAUTH@" "${xorg.xauth}/bin/xauth" \ + --replace "@FONT_CACHE@" "$out/bin/font_cache" \ + --replace "@PRIVILEGED_STARTX@" "$out/lib/X11/xinit/privileged_startx" \ + --replace "@DEFAULT_SERVER@" "$out/bin/Xquartz" \ + --replace "@DEFAULT_CLIENT@" "${xterm}/bin/xterm" \ + --replace "@XINIT@" "$out/bin/xinit" \ + --replace "@XINITRC@" "$out/etc/X11/xinit/xinitrc" \ + --replace "@XKEYBOARD_CONFIG@" "${xkeyboard_config}/etc/X11/xkb" \ + --replace "@FONTCONFIG_FILE@" "$fontsConfPath" + + wrapProgram $out/bin/Xquartz \ + --set XQUARTZ_X11 $out/Applications/XQuartz.app/Contents/MacOS/X11 \ + --set XKB_BINDIR "${xorg.xkbcomp}/bin" + + defaultStartX="$out/bin/startx -- $out/bin/Xquartz" + + ruby ${./patch_plist.rb} \ + ${shellEscape (builtins.toXML { + XQUARTZ_DEFAULT_CLIENT = "${xterm}/bin/xterm"; + XQUARTZ_DEFAULT_SHELL = "${shell}"; + XQUARTZ_DEFAULT_STARTX = "@STARTX@"; + FONTCONFIG_FILE = "@FONTCONFIG_FILE@"; + XKB_BINDIR = "${xorg.xkbcomp}/bin"; + })} \ + $out/Applications/XQuartz.app/Contents/Info.plist + substituteInPlace $out/Applications/XQuartz.app/Contents/Info.plist \ + --replace "@STARTX@" "$defaultStartX" \ + --replace "@FONTCONFIG_FILE@" "$fontsConfPath" + + rm $out/lib/X11/xinit/privileged_startx.d/* + cp ${./privileged} $out/lib/X11/xinit/privileged_startx.d/privileged + substituteInPlace $out/lib/X11/xinit/privileged_startx.d/privileged \ + --replace "@PATH@" "$out/bin:${env}" \ + --replace "@FONTCONFIG_FILE@" "$fontsConfPath" \ + --replace "@FONT_CACHE@" "$out/bin/font_cache" + + cp ${./font_cache} $out/bin/font_cache + substituteInPlace $out/bin/font_cache \ + --replace "@PATH@" "$out/bin:${env}" \ + --replace "@ENCODINGSDIR@" "${xorg.encodings}/share/fonts/X11/encodings" \ + --replace "@MKFONTDIR@" "${xorg.mkfontdir}/bin/mkfontdir" \ + --replace "@MKFONTSCALE@" "${xorg.mkfontscale}/bin/mkfontscale" \ + --replace "@FC_CACHE@" "${fontconfig}/bin/fc-cache" \ + --replace "@FONTCONFIG_FILE@" "$fontsConfPath" + + cp ${./xinitrc} $out/etc/X11/xinit/xinitrc + substituteInPlace $out/etc/X11/xinit/xinitrc \ + --replace "@PATH@" "$out/bin:${env}" \ + --replace "@XSET@" "${xorg.xset}/bin/xset" \ + --replace "@XMODMAP@" "${xorg.xmodmap}/bin/xmodmap" \ + --replace "@XRDB@" "${xorg.xrdb}/bin/xrdb" \ + --replace "@SYSTEM_FONTS@" "${fonts}/share/X11-fonts/" \ + --replace "@QUARTZ_WM@" "${quartz-wm}/bin/quartz-wm" \ + --replace "@FONTCONFIG_FILE@" "$fontsConfPath" + + cp ${./X11} $out/Applications/XQuartz.app/Contents/MacOS/X11 + substituteInPlace $out/Applications/XQuartz.app/Contents/MacOS/X11 \ + --replace "@DEFAULT_SHELL@" "${shell}" \ + --replace "@DEFAULT_STARTX@" "$defaultStartX" \ + --replace "@DEFAULT_CLIENT@" "${xterm}/bin/xterm" \ + --replace "@FONTCONFIG_FILE@" "$fontsConfPath" + ''; + meta = with lib; { + platforms = platforms.darwin; + maintainers = with maintainers; [ cstrahan ]; + license = licenses.mit; + }; +} diff --git a/pkgs/servers/x11/xquartz/font_cache b/pkgs/servers/x11/xquartz/font_cache new file mode 100755 index 00000000000..12858af8bc6 --- /dev/null +++ b/pkgs/servers/x11/xquartz/font_cache @@ -0,0 +1,240 @@ +#!/bin/bash + +export PATH=@PATH@:$PATH + +export FONTCONFIG_FILE="@FONTCONFIG_FILE@" +ENCODINGSDIR="@ENCODINGSDIR@" +FC_LOCKFILE="" + +# Are we caching system fonts or user fonts? +system=0 + +# Are we including OSX font dirs ({/,~/,/System/}Library/Fonts) +osxfonts=1 + +# Do we want to force a recache? +force=0 + +# How noisy are we? +verbose=0 + +# Check if the data in the given directory is newer than its cache +check_dirty() { + local dir=$1 + local fontfiles="" + local retval=1 + + # If the dir does not exist, we just exit + if [[ ! -d "${dir}" ]]; then + return 1 + fi + + # Create a list of all files in the dir + # Filter out config / cache files. Ugly... counting down the day until + # xfs finally goes away + fontfiles="$(find ${dir}/ -maxdepth 1 -type f | awk '$0 !~ /fonts\..*$|^.*\.dir$/ {print}')" + + # Fonts were deleted (or never there). Kill off the caches + if [[ -z "${fontfiles}" ]] ; then + local f + for f in "${dir}"/fonts.* "${dir}"/encodings.dir; do + if [[ -f ${f} ]] ; then + rm -f "${f}" + fi + done + return 1 + fi + + # Force a recache + if [[ ${force} == 1 ]] ; then + retval=0 + fi + + # If we don't have our caches, we are dirty + if [[ ! -f "${dir}/fonts.list" || ! -f "${dir}/fonts.dir" || ! -f "${dir}/encodings.dir" ]]; then + retval=0 + fi + + # Check that no files were added or removed.... + if [[ "${retval}" -ne 0 && "$(cat ${dir}/fonts.list)" != "${fontfiles}" ]] ; then + retval=0 + fi + + # Check that no files were updated.... + if [[ "${retval}" -ne 0 ]] ; then + local changed="$(find ${dir}/ -type f -cnewer ${dir}/fonts.dir | awk '$0 !~ /fonts\..*$|^.*\.dir$/ {print}')" + + if [[ -n "${changed}" ]] ; then + retval=0 + fi + fi + + # Recreate fonts.list since something changed + if [[ "${retval}" == 0 ]] ; then + echo "${fontfiles}" > "${dir}"/fonts.list + fi + + return ${retval} +} + +get_fontdirs() { + local d + if [[ $system == 1 ]] ; then + if [[ $osxfonts == 1 ]] ; then + find {/System/,/}Library/Fonts -type d + fi + else + if [[ $osxfonts == 1 && -d "${HOME}/Library/Fonts" ]] ; then + find "${HOME}/Library/Fonts" -type d + fi + + if [[ -d "${HOME}/.fonts" ]] ; then + find "${HOME}/.fonts" -type d + fi + fi +} + +setup_fontdirs() { + local x="" + local fontdirs="" + local changed="no" + + umask 022 + + if [[ $system == 1 ]] ; then + echo "font_cache: Scanning system font directories to generate X11 font caches" + else + echo "font_cache: Scanning user font directories to generate X11 font caches" + fi + + OIFS=$IFS + IFS=' +' + for x in $(get_fontdirs) ; do + if [[ -d "${x}" ]] && check_dirty "${x}" ; then + if [[ -z "${fontdirs}" ]] ; then + fontdirs="${x}" + else + fontdirs="${fontdirs}${IFS}${x}" + fi + fi + done + + if [[ -n "${fontdirs}" ]] ; then + echo "font_cache: Making fonts.dir for updated directories." + for x in ${fontdirs} ; do + if [[ $verbose == 1 ]] ; then + echo "font_cache: ${x}" + fi + + # First, generate fonts.scale for scaleable fonts that might be there + @MKFONTSCALE@ \ + -a $ENCODINGSDIR/encodings.dir \ + -a $ENCODINGSDIR/large/encodings.dir \ + -- ${x} + + # Next, generate fonts.dir + if [[ $verbose == 1 ]] ; then + @MKFONTDIR@ \ + -e $ENCODINGSDIR \ + -e $ENCODINGSDIR/large \ + -- ${x} + else + @MKFONTDIR@ \ + -e $ENCODINGSDIR \ + -e $ENCODINGSDIR/large \ + -- ${x} > /dev/null + fi + done + fi + IFS=$OIFS + + # Finally, update fontconfig's cache + echo "font_cache: Updating FC cache" + if [[ $system == 1 ]] ; then + @FC_CACHE@ -s \ + $([[ $force == 1 ]] && echo "-f -r") \ + $([[ $verbose == 1 ]] && echo "-v") + else + @FC_CACHE@ \ + $([[ $force == 1 ]] && echo "-f -r") \ + $([[ $verbose == 1 ]] && echo "-v") + fi + echo "font_cache: Done" +} + +do_usage() { + echo "font_cache [options]" + echo " -f, --force : Force cache recreation" + echo " -n, --no-osxfonts : Just cache X11 font directories" + echo " (-n just pertains to XFont cache, not fontconfig)" + echo " -s, --system : Cache system font dirs instead of user dirs" + echo " -v, --verbose : Verbose Output" +} + +cleanup() { + [[ -r "${FC_LOCKFILE}" ]] && rm -f "${FC_LOCKFILE}" + exit 1 +} + +while [[ $# -gt 0 ]] ; do + case $1 in + -s|--system) system=1 ;; + -f|--force) force=1 ;; + -v|--verbose) verbose=1 ;; + -n|--no-osxfonts) osxfonts=0 ;; + --help) do_usage ; exit 0 ;; + *) do_usage ; exit 1 ;; + esac + shift +done + +if [[ $system == 1 ]] ; then + FC_LOCKFILE="/tmp/font_cache.$UID.lock" +elif [[ -w "${TMPDIR}" ]] ; then + FC_LOCKFILE="${TMPDIR}/font_cache.lock" +elif [[ -w "/tmp" ]] ; then + FC_LOCKFILE="/tmp/font_cache.$UID.lock" +else + FC_LOCKFILE="${HOME}/.font_cache.lock" +fi + +if [[ -x /usr/bin/lockfile ]] ; then + if /usr/bin/lockfile -r 0 -l 240 -s 4 -! "${FC_LOCKFILE}" ; then + echo "font_cache is already running." >&2 + echo "If you believe this to be erroneous, please remove ${FC_LOCKFILE}." >&2 + exit 1 + fi +else + if [[ -r "${FC_LOCKFILE}" ]] ; then + read OLD_PID < "${FC_LOCKFILE}" + if kill -0 ${OLD_PID} >& /dev/null ; then + echo "font_cache is already running with PID ${OLD_PID}." >&2 + echo "If you believe this to be erroneous, please remove ${FC_LOCKFILE}." >&2 + exit 1 + fi + + echo "Removing stale ${FC_LOCKFILE}" >&2 + rm -f "${FC_LOCKFILE}" + fi + + echo $$ > "${FC_LOCKFILE}" + + if [[ ! -r "${FC_LOCKFILE}" ]] ; then + echo "Unable to write to ${FC_LOCKFILE}." >&2 + exit 1 + fi + + # Now make sure we didn't collide mid-air + read OLD_PID < "${FC_LOCKFILE}" + if [[ $$ != ${OLD_PID} ]] ; then + echo "font_cache is already running with PID ${OLD_PID}." >&2 + exit 1 + fi +fi + +trap cleanup SIGINT SIGQUIT SIGABRT SIGTERM + +setup_fontdirs + +rm -f "${FC_LOCKFILE}" diff --git a/pkgs/servers/x11/xquartz/org.nixos.xquartz.privileged_startx.plist b/pkgs/servers/x11/xquartz/org.nixos.xquartz.privileged_startx.plist new file mode 100644 index 00000000000..190b383676d --- /dev/null +++ b/pkgs/servers/x11/xquartz/org.nixos.xquartz.privileged_startx.plist @@ -0,0 +1,23 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> +<plist version="1.0"> + <dict> + <key>Label</key> + <string>org.nixos.xquartz.privileged_startx</string> + <key>ProgramArguments</key> + <array> + <string>@PRIVILEGED_STARTX@</string> + <string>-d</string> + <string>@PRIVILEGED_STARTX_D@</string> + </array> + <key>MachServices</key> + <dict> + <key>org.nixos.xquartz.privileged_startx</key> + <true/> + </dict> + <key>TimeOut</key> + <integer>120</integer> + <key>EnableTransactions</key> + <true/> + </dict> +</plist> diff --git a/pkgs/servers/x11/xquartz/org.nixos.xquartz.startx.plist b/pkgs/servers/x11/xquartz/org.nixos.xquartz.startx.plist new file mode 100644 index 00000000000..7a95916da16 --- /dev/null +++ b/pkgs/servers/x11/xquartz/org.nixos.xquartz.startx.plist @@ -0,0 +1,27 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> +<plist version="1.0"> + <dict> + <key>Label</key> + <string>org.nixos.xquartz.startx</string> + <key>ProgramArguments</key> + <array> + <string>@LAUNCHD_STARTX@</string> + <string>@STARTX@</string> + <string>--</string> + <string>@XQUARTZ@</string> + </array> + <key>Sockets</key> + <dict> + <key>org.nixos.xquartz:0</key> + <dict> + <key>SecureSocketWithKey</key> + <string>DISPLAY</string> + </dict> + </dict> + <key>ServiceIPC</key> + <true/> + <key>EnableTransactions</key> + <true/> + </dict> +</plist> diff --git a/pkgs/servers/x11/xquartz/patch_plist.rb b/pkgs/servers/x11/xquartz/patch_plist.rb new file mode 100644 index 00000000000..9b0f778426e --- /dev/null +++ b/pkgs/servers/x11/xquartz/patch_plist.rb @@ -0,0 +1,47 @@ +require 'rexml/document' + +# This script is for setting environment variables in OSX applications. +# +# This script takes two arguments: +# 1) A Nix attrset serialized via `builtins.toXML' +# 2) The path to an OSX app's Info.plist file. + +def main(serialized_attrs, plist_path) + env = attrs_to_hash(serialized_attrs) + doc = REXML::Document.new(File.open(plist_path, &:read)) + topmost_dict = doc.root.elements.detect { |e| e.name == "dict" } + topmost_dict.add_element("key").tap do |key| + key.text = "LSEnvironment" + end + topmost_dict.add_element(env_to_dict(env)) + + formatter = REXML::Formatters::Pretty.new(2) + formatter.compact = true + formatter.write(doc, File.open(plist_path, "w")) +end + +# Convert a `builtins.toXML' serialized attrs to a hash. +# This assumes the values are strings. +def attrs_to_hash(serialized_attrs) + hash = {} + env_vars = REXML::Document.new(serialized_attrs) + env_vars.root.elements[1].elements.each do |attr| + name = attr.attribute("name") + value = attr.elements.first.attribute("value") + hash[name] = value + end + hash +end + +def env_to_dict(env) + dict = REXML::Element.new("dict") + env.each do |k, v| + key = dict.add_element("key") + key.text = k + string = dict.add_element("string") + string.text = v + end + dict +end + +main(ARGV[0], ARGV[1]) diff --git a/pkgs/servers/x11/xquartz/privileged b/pkgs/servers/x11/xquartz/privileged new file mode 100755 index 00000000000..3eee9479411 --- /dev/null +++ b/pkgs/servers/x11/xquartz/privileged @@ -0,0 +1,43 @@ +#!/bin/sh + +export PATH=@PATH@:$PATH +export FONTCONFIG_FILE="@FONTCONFIG_FILE@" + +# Our usage of mktemp fails with GNU, so prefer /usr/bin to hopefully +# get BSD mktemp +if [ -x /usr/bin/mktemp ] ; then + MKTEMP=/usr/bin/mktemp +else + MKTEMP=mktemp +fi + +STAT=/usr/bin/stat + +for dir in /tmp/.ICE-unix /tmp/.X11-unix /tmp/.font-unix ; do + success=0 + for attempt in 1 2 3 4 5 ; do + check=`${STAT} -f '%#p %u %g' ${dir} 2> /dev/null` + if [ "${check}" = "041777 0 0" ] ; then + success=1 + break + elif [ -n "${check}" ] ; then + saved=$(${MKTEMP} -d ${dir}-XXXXXXXX) + mv ${dir} ${saved} + echo "${dir} exists but is insecure. It has been moved into ${saved}" >&2 + fi + + # if $dir exists and is a symlink (ie protect against a race) + if ${MKTEMP} -d ${dir} >& /dev/null ; then + chmod 1777 $dir + chown root:wheel $dir + success=1 + break + fi + done + + if [ "${success}" -eq 0 ] ; then + echo "Could not successfully create ${dir}" >&2 + fi +done + +@FONT_CACHE@ -s & diff --git a/pkgs/servers/x11/xquartz/startx b/pkgs/servers/x11/xquartz/startx new file mode 100755 index 00000000000..131fbc43b8b --- /dev/null +++ b/pkgs/servers/x11/xquartz/startx @@ -0,0 +1,232 @@ +#!/bin/sh + +# vim :set ts=4 sw=4 sts=4 et : + +# +# This is just a sample implementation of a slightly less primitive +# interface than xinit. It looks for user .xinitrc and .xserverrc +# files, then system xinitrc and xserverrc files, else lets xinit choose +# its default. The system xinitrc should probably do things like check +# for .Xresources files and merge them in, start up a window manager, +# and pop a clock and several xterms. +# +# Site administrators are STRONGLY urged to write nicer versions. +# + +unset DBUS_SESSION_BUS_ADDRESS +unset SESSION_MANAGER + + +# Bourne shell does not automatically export modified environment variables +# so export the new PATH just in case the user changes the shell +export PATH=@PATH@:$PATH + +export FONTCONFIG_FILE="@FONTCONFIG_FILE@" + +userclientrc=$HOME/.xinitrc +sysclientrc=@XINITRC@ + +userserverrc=$HOME/.xserverrc +sysserverrc=@XINITRC@ +defaultclient=@DEFAULT_CLIENT@ # xterm +defaultserver=@DEFAULT_SERVER@ +defaultclientargs="" +defaultserverargs="" +defaultdisplay=":0" +clientargs="" +serverargs="" + +export X11_PREFS_DOMAIN=org.nixos.xquartz".X11" + +# Initialize defaults (this will cut down on "safe" error messages) +if ! /usr/bin/defaults read $X11_PREFS_DOMAIN cache_fonts > /dev/null 2>&1 ; then + /usr/bin/defaults write $X11_PREFS_DOMAIN cache_fonts -bool true +fi + +if ! /usr/bin/defaults read $X11_PREFS_DOMAIN no_auth > /dev/null 2>&1 ; then + /usr/bin/defaults write $X11_PREFS_DOMAIN no_auth -bool false +fi + +if ! /usr/bin/defaults read $X11_PREFS_DOMAIN nolisten_tcp > /dev/null 2>&1 ; then + /usr/bin/defaults write $X11_PREFS_DOMAIN nolisten_tcp -bool true +fi + +# First, start caching fonts +if [ x`/usr/bin/defaults read $X11_PREFS_DOMAIN cache_fonts` = x1 ] ; then + @FONT_CACHE@ & +fi + +# a race to create /tmp/.X11-unix +@PRIVILEGED_STARTX@ + +if [ x`/usr/bin/defaults read $X11_PREFS_DOMAIN no_auth` = x0 ] ; then + enable_xauth=1 +else + enable_xauth=0 +fi + +if [ x`defaults read $X11_PREFS_DOMAIN nolisten_tcp` = x1 ] ; then + defaultserverargs="$defaultserverargs -nolisten tcp" +fi + +# The second check is the real one. The first is to hopefully avoid +# needless syslog spamming. +if /usr/bin/defaults read $X11_PREFS_DOMAIN 2> /dev/null | grep -q 'dpi' && /usr/bin/defaults read $X11_PREFS_DOMAIN dpi > /dev/null 2>&1 ; then + defaultserverargs="$defaultserverargs -dpi `/usr/bin/defaults read $X11_PREFS_DOMAIN dpi`" +fi + +# Automatically determine an unused $DISPLAY +d=0 +while true ; do + [ -e /tmp/.X$d-lock ] || break + d=$(($d + 1)) +done +defaultdisplay=":$d" +unset d + +whoseargs="client" +while [ x"$1" != x ]; do + case "$1" in + # '' required to prevent cpp from treating "/*" as a C comment. + /''*|\./''*) + if [ "$whoseargs" = "client" ]; then + if [ x"$client" = x ] && [ x"$clientargs" = x ]; then + client="$1" + else + clientargs="$clientargs $1" + fi + else + if [ x"$server" = x ] && [ x"$serverargs" = x ]; then + server="$1" + else + serverargs="$serverargs $1" + fi + fi + ;; + --) + whoseargs="server" + ;; + *) + if [ "$whoseargs" = "client" ]; then + clientargs="$clientargs $1" + else + # display must be the FIRST server argument + if [ x"$serverargs" = x ] && \ + expr "$1" : ':[0-9][0-9]*$' > /dev/null 2>&1; then + display="$1" + else + serverargs="$serverargs $1" + fi + fi + ;; + esac + shift +done + +# process client arguments +if [ x"$client" = x ]; then + client=$defaultclient + + # For compatibility reasons, only use startxrc if there were no client command line arguments + if [ x"$clientargs" = x ]; then + if [ -f "$userclientrc" ]; then + client=$userclientrc + elif [ -f "$sysclientrc" ]; then + client=$sysclientrc + fi + fi +fi + +# if no client arguments, use defaults +if [ x"$clientargs" = x ]; then + clientargs=$defaultclientargs +fi + +# process server arguments +if [ x"$server" = x ]; then + server=$defaultserver + + # For compatibility reasons, only use xserverrc if there were no server command line arguments + if [ x"$serverargs" = x -a x"$display" = x ]; then + if [ -f "$userserverrc" ]; then + server=$userserverrc + elif [ -f "$sysserverrc" ]; then + server=$sysserverrc + fi + fi +fi + +# if no server arguments, use defaults +if [ x"$serverargs" = x ]; then + serverargs=$defaultserverargs +fi + +# if no display, use default +if [ x"$display" = x ]; then + display=$defaultdisplay +fi + +if [ x"$enable_xauth" = x1 ] ; then + if [ x"$XAUTHORITY" = x ]; then + XAUTHORITY=$HOME/.Xauthority + export XAUTHORITY + fi + + removelist= + + # set up default Xauth info for this machine + hostname=`/bin/hostname` + + authdisplay=${display:-:0} + + mcookie=`/usr/bin/openssl rand -hex 16` + + if test x"$mcookie" = x; then + echo "Couldn't create cookie" + exit 1 + fi + dummy=0 + + # create a file with auth information for the server. ':0' is a dummy. + xserverauthfile=$HOME/.serverauth.$$ + trap "rm -f '$xserverauthfile'" HUP INT QUIT ILL TRAP KILL BUS TERM + @XAUTH@ -q -f "$xserverauthfile" << EOF +add :$dummy . $mcookie +EOF + + xserverauthfilequoted=$(echo ${xserverauthfile} | sed "s/'/'\\\\''/g") + serverargs=${serverargs}" -auth '"${xserverauthfilequoted}"'" + + # now add the same credentials to the client authority file + # if '$displayname' already exists do not overwrite it as another + # server man need it. Add them to the '$xserverauthfile' instead. + for displayname in $authdisplay $hostname$authdisplay; do + authcookie=`@XAUTH@ list "$displayname" \ + | sed -n "s/.*$displayname[[:space:]*].*[[:space:]*]//p"` 2>/dev/null; + if [ "z${authcookie}" = "z" ] ; then + @XAUTH@ -q << EOF +add $displayname . $mcookie +EOF + removelist="$displayname $removelist" + else + dummy=$(($dummy+1)); + @XAUTH@ -q -f "$xserverauthfile" << EOF +add :$dummy . $authcookie +EOF + fi + done +fi + +eval @XINIT@ \"$client\" $clientargs -- \"$server\" $display $serverargs "-xkbdir" "@XKEYBOARD_CONFIG@" +retval=$? + +if [ x"$enable_xauth" = x1 ] ; then + if [ x"$removelist" != x ]; then + @XAUTH@ remove $removelist + fi + if [ x"$xserverauthfile" != x ]; then + rm -f "$xserverauthfile" + fi +fi + +exit $retval diff --git a/pkgs/servers/x11/xquartz/system-fonts.nix b/pkgs/servers/x11/xquartz/system-fonts.nix new file mode 100644 index 00000000000..cf24bb439b9 --- /dev/null +++ b/pkgs/servers/x11/xquartz/system-fonts.nix @@ -0,0 +1,36 @@ +{ stdenv, xorg, fontDirs }: + +stdenv.mkDerivation { + name = "xquartz-system-fonts"; + buildInputs = [ + xorg.mkfontdir xorg.mkfontscale + ]; + buildCommand = '' + source $stdenv/setup + + for i in ${toString fontDirs} ; do + if [ -d $i/ ]; then + list="$list $i"; + fi; + done + list=$(find $list -name fonts.dir -o -name '*.ttf' -o -name '*.otf'); + fontDirs='''; + for i in $list ; do + fontDirs="$fontDirs $(dirname $i)"; + done; + mkdir -p $out/share/X11-fonts/; + find $fontDirs -type f -o -type l | while read i; do + j="''${i##*/}" + if ! test -e "$out/share/X11-fonts/''${j}"; then + ln -s "$i" "$out/share/X11-fonts/''${j}"; + fi; + done; + cd $out/share/X11-fonts/ + rm fonts.dir + rm fonts.scale + rm fonts.alias + mkfontdir + mkfontscale + cat $( find ${xorg.fontalias}/ -name fonts.alias) >fonts.alias + ''; +} diff --git a/pkgs/servers/x11/xquartz/xinitrc b/pkgs/servers/x11/xquartz/xinitrc new file mode 100755 index 00000000000..1a0c2ccf1c0 --- /dev/null +++ b/pkgs/servers/x11/xquartz/xinitrc @@ -0,0 +1,40 @@ +#!/bin/sh + +export PATH=@PATH@:$PATH + +userresources=$HOME/.Xresources +usermodmap=$HOME/.Xmodmap + +# Fix ridiculously slow key repeat. +@XSET@ r rate + +# merge in defaults and keymaps + +if [ -f "$userresources" ]; then + if [ -x /usr/bin/cpp ] ; then + @XRDB@ -merge "$userresources" + else + @XRDB@ -nocpp -merge "$userresources" + fi +fi + +if [ -f "$usermodmap" ]; then + @XMODMAP@ "$usermodmap" +fi + +fontpath="@SYSTEM_FONTS@" +[ -e "$HOME"/.fonts/fonts.dir ] && fontpath="$fontpath,$HOME/.fonts" +[ -e "$HOME"/Library/Fonts/fonts.dir ] && fontpath="$fontpath,$HOME/Library/Fonts" +[ -e /Library/Fonts/fonts.dir ] && fontpath="$fontpath,/Library/Fonts" +[ -e /System/Library/Fonts/fonts.dir ] && fontpath="$fontpath,/System/Library/Fonts" +@XSET@ fp= "$fontpath" +unset fontpath + +if [ -d "${HOME}/.xinitrc.d" ] ; then + for f in "${HOME}"/.xinitrc.d/*.sh ; do + [ -x "$f" ] && . "$f" + done + unset f +fi + +exec @QUARTZ_WM@ |