diff options
Diffstat (limited to 'pkgs')
28 files changed, 5893 insertions, 881 deletions
diff --git a/pkgs/applications/audio/pamixer/default.nix b/pkgs/applications/audio/pamixer/default.nix new file mode 100644 index 000000000000..4337164fe3a4 --- /dev/null +++ b/pkgs/applications/audio/pamixer/default.nix @@ -0,0 +1,38 @@ +{ stdenv, fetchgit, pulseaudio, boost }: + +let + tag = "1.1"; +in + +stdenv.mkDerivation rec { + + name = "pamixer-${tag}"; + + src = fetchgit { + url = git://github.com/cdemoulins/pamixer; + rev = "refs/tags/${tag}"; + sha256 = "03r0sbfj85wp6yxa87pjg69ivmk0mxxa2nykr8gf2c607igmb034"; + }; + + buildInputs = [ pulseaudio boost ]; + + installPhase = '' + mkdir -p $out/bin + cp pamixer $out/bin + ''; + + meta = with stdenv.lib; { + description = "pamixer is like amixer but for pulseaudio."; + longDescription = "Features: + - Get the current volume of the default sink, the default source or a selected one by his id + - Set the volume for the default sink, the default source or any other device + - List the sinks + - List the sources + - Increase / Decrease the volume for a device + - Mute or unmute a device"; + homepage = https://github.com/cdemoulins/pamixer; + license = licenses.gpl3; + platforms = platforms.linux; + maintainers = [ _1126 ]; + }; +} \ No newline at end of file diff --git a/pkgs/applications/networking/browsers/uzbl/default.nix b/pkgs/applications/networking/browsers/uzbl/default.nix index 4c6458d909fd..ba9c8bde37a2 100644 --- a/pkgs/applications/networking/browsers/uzbl/default.nix +++ b/pkgs/applications/networking/browsers/uzbl/default.nix @@ -1,45 +1,36 @@ -a : -let - fetchgit = a.fetchgit; +{ stdenv, fetchurl, pkgconfig, python, makeWrapper +, webkit, glib_networking, gsettings_desktop_schemas +}: - buildInputs = with a; [ - libsoup pkgconfig webkit gtk makeWrapper - kbproto glib pango cairo gdk_pixbuf atk - python3 - ]; -in -rec { - src = fetchgit { - url = "https://github.com/Dieterbe/uzbl.git"; - rev = "refs/tags/2012.05.14"; - sha256 = "1crvikb0qqsx5qb003i4w7ywh72psl37gjslrj5hx2fd2f215l0l"; - }; +stdenv.mkDerivation rec { + name = "uzbl-20120514"; - name = "uzbl-git"; + meta = with stdenv.lib; { + description = "Tiny externally controllable webkit browser"; + homepage = "http://uzbl.org/"; + license = licenses.gpl3; + platforms = platforms.linux; + maintainers = with maintainers; [ raskin ]; + }; - inherit buildInputs; - configureFlags = []; + src = fetchurl { + name = "${name}.tar.gz"; + url = "https://github.com/uzbl/uzbl/archive/2012.05.14.tar.gz"; + sha256 = "1flpf0rg0c3n9bjifr37zxljn9yxslg8vkll7ghkm341x76cbkwn"; + }; - /* doConfigure should be removed if not needed */ - phaseNames = ["addInputs" "setVars" "doMakeInstall" "doWrap"]; + preConfigure = '' + makeFlags="$makeFlags PREFIX=$out" + makeFlags="$makeFlags PYINSTALL_EXTRA=--prefix=$out" + ''; - setVars = a.noDepEntry ('' - export NIX_LDFLAGS="$NIX_LDFLAGS -L${a.libX11}/lib -lX11" - ''); + postInstall = '' + wrapProgram $out/bin/uzbl-core \ + --prefix GIO_EXTRA_MODULES : "${glib_networking}/lib/gio/modules" \ + --prefix XDG_DATA_DIRS : "${gsettings_desktop_schemas}/share:$out/share" + ''; - doWrap = a.makeManyWrappers "$out/bin/uzbl-core" - '' - --prefix GST_PLUGIN_PATH : ${a.webkit.gstreamer}/lib/gstreamer-* \ - --prefix GST_PLUGIN_PATH : ${a.webkit.gst_plugins_base}/lib/gstreamer-* \ - --prefix GST_PLUGIN_PATH : ${a.webkit.gst_plugins_good}/lib/gstreamer-* \ - --prefix GST_PLUGIN_PATH : ${a.webkit.gst_ffmpeg}/lib/gstreamer-* \ - --prefix GIO_EXTRA_MODULES : ${a.glib_networking}/lib/gio/modules - ''; + nativeBuildInputs = [ pkgconfig python makeWrapper ]; - installFlags = "PREFIX=$out PYINSTALL_EXTRA=\"--prefix=$out\""; - - meta = { - description = "Tiny externally controllable webkit browser"; - maintainers = [a.lib.maintainers.raskin]; - }; + buildInputs = [ webkit ]; } diff --git a/pkgs/applications/networking/browsers/vimprobable2/default.nix b/pkgs/applications/networking/browsers/vimprobable2/default.nix index f723e3791f3e..8e1e00795d24 100644 --- a/pkgs/applications/networking/browsers/vimprobable2/default.nix +++ b/pkgs/applications/networking/browsers/vimprobable2/default.nix @@ -2,11 +2,11 @@ pkgconfig, webkit, gsettings_desktop_schemas }: stdenv.mkDerivation rec { - version = "1.2.1"; + version = "1.4.2"; name = "vimprobable2-${version}"; src = fetchurl { url = "mirror://sourceforge/vimprobable/vimprobable2_${version}.tar.bz2"; - sha256 = "19zx1k3s2gnhzzd2wpyqsk151w9p52ifl64xaz9a6qkgvrxlli8p"; + sha256 = "13jdximksh9r3cgd2f8vms0pbsn3x0gxvyqdqiw16xp5fmdx5kzr"; }; # Nixos default ca bundle diff --git a/pkgs/applications/networking/mailreaders/thunderbird-bin/default.nix b/pkgs/applications/networking/mailreaders/thunderbird-bin/default.nix new file mode 100644 index 000000000000..1e8a7e301ed7 --- /dev/null +++ b/pkgs/applications/networking/mailreaders/thunderbird-bin/default.nix @@ -0,0 +1,264 @@ +{ stdenv, fetchurl, config +, gconf +, alsaLib +, at_spi2_atk +, atk +, cairo +, cups +, curl +, dbus_glib +, dbus_libs +, fontconfig +, freetype +, gdk_pixbuf +, glib +, glibc +, gst_plugins_base +, gstreamer +, gtk +, kerberos +, libX11 +, libXScrnSaver +, libXext +, libXinerama +, libXrender +, libXt +, libcanberra +, libgnome +, libgnomeui +, mesa +, nspr +, nss +, pango +}: + +let + version = "24.4.0"; + + sources = [ + { locale = "ar"; arch = "linux-x86_64"; sha256 = "dd570da273c047e0b4bf29a7ed4bb4356dcbdd8de62ecb65fcddfecaf156966f"; } + { locale = "ar"; arch = "linux-i686"; sha256 = "f96c30ad874adf10608f818e0d986070b2a577de4d9aeb6c8dc7ea1ccd6e72f1"; } + { locale = "ast"; arch = "linux-x86_64"; sha256 = "8a50ff6a4f0d2bf68f989c2d3e0bca75c9fbcfc73c37b6cc16d935c1e3c1a9cf"; } + { locale = "ast"; arch = "linux-i686"; sha256 = "ace08104be64c038f5337e5178a79cb3f909c233f8722f7d54db04aef87935f9"; } + { locale = "be"; arch = "linux-x86_64"; sha256 = "793c07b33e861a5e29ce906a9764d980a82238b7c078391b96480592f526f323"; } + { locale = "be"; arch = "linux-i686"; sha256 = "98f2a5390572df625e0600ab224d5171d0357e187a3743ad72ec94d31533d993"; } + { locale = "bg"; arch = "linux-i686"; sha256 = "7d2fbb1ecad6e7a81c481a6697429809dc76809bba537ab8bc576b19ba5938f5"; } + { locale = "bg"; arch = "linux-x86_64"; sha256 = "a0a551d1790969b11ad2dcfc277f487645abff2497f2e9104235e77c45e5120c"; } + { locale = "bn-BD"; arch = "linux-x86_64"; sha256 = "cb2a5549c3cdc9e159181cb9417c7f53158820f722e48d3ce2e4dcf10dea32d2"; } + { locale = "bn-BD"; arch = "linux-i686"; sha256 = "e395d07fb7b13443ccc97433d38a8845969cf854ace807950a364319c17861d6"; } + { locale = "br"; arch = "linux-i686"; sha256 = "8637d47dfb9b685a1034f5449d3481a5c62f74158f1a6318fe94504ad779dbb2"; } + { locale = "br"; arch = "linux-x86_64"; sha256 = "f36f6d2041a110ffc621249e6d92ec09f3b2bb7a1cf08b7892a0eb998b8a2bb3"; } + { locale = "ca"; arch = "linux-x86_64"; sha256 = "427a09458fe0d631a360b871db637d33bc0ad443ec443b7193db409321ab72da"; } + { locale = "ca"; arch = "linux-i686"; sha256 = "8531078cb31cb3035fdfd7397159cd42a6439868e954e1c9bd6eb7f9cd564bdb"; } + { locale = "cs"; arch = "linux-x86_64"; sha256 = "6fea39c9416357ec2902ed3dff84650a683dbe136790fa83cbca5d8bf869dc48"; } + { locale = "cs"; arch = "linux-i686"; sha256 = "c9e8d50e04dccd647ef7a566e68a3fe8374f86e9c1b7fe2001e3690270c5e7b9"; } + { locale = "da"; arch = "linux-x86_64"; sha256 = "41debf8c221063c4a5eafc3b769aabada6f3cebf35a354b7837c2ad737fa9b0f"; } + { locale = "da"; arch = "linux-i686"; sha256 = "77aa022e8c58dc60595f4600849da795faea4c20da6d5514f57e1b0033cda27c"; } + { locale = "de"; arch = "linux-x86_64"; sha256 = "05ec3d776de6060a82eea595b022b73c05ab7016419be5989929bd10ae282d27"; } + { locale = "de"; arch = "linux-i686"; sha256 = "471288d8660536508fe04b236eb72a7c245d27cadd59841a9bab0e73db271005"; } + { locale = "el"; arch = "linux-x86_64"; sha256 = "901c0097fb8072a37787a77758a0d6a2ced66acdf5a3588a0a6df3584034c309"; } + { locale = "el"; arch = "linux-i686"; sha256 = "da658a5f18a7162d513f8e0aac8d1648b18404bac7888a2f66c850f2084a54c5"; } + { locale = "en-GB"; arch = "linux-i686"; sha256 = "61c637e3b63a10d3c3eff91e9dcbd8558887a41d8e359aa637541bc4424a328a"; } + { locale = "en-GB"; arch = "linux-x86_64"; sha256 = "dcf399192062a7e3075125f550b0889fb4943c595814b8f6e755e9aa7e4656b1"; } + { locale = "en-US"; arch = "linux-i686"; sha256 = "376ab51e3c424db7e235b2e94494d48ce2fa9a8f1fbf5ef5cf9e367bbaf7422d"; } + { locale = "en-US"; arch = "linux-x86_64"; sha256 = "57917aa608131da4d569e791fc8167f4df54975b74c64d6df641858400dd4c1b"; } + { locale = "es-AR"; arch = "linux-x86_64"; sha256 = "47ecdb633bf1b246df84e796395a668fd98ac52a82177507da010b0174aa74d8"; } + { locale = "es-AR"; arch = "linux-i686"; sha256 = "9155d96fb14795bc5a22e10105ba0226a7b9c87a4d6ffa5cf7835dc77d69fa30"; } + { locale = "es-ES"; arch = "linux-i686"; sha256 = "3c41656512f1859b28abdf81d356dd90b720efd489d7021270114a9d28c54b38"; } + { locale = "es-ES"; arch = "linux-x86_64"; sha256 = "bad476b65d71744b9562a8548ca6cd608da92e62f45057688fef29ac77eb060e"; } + { locale = "et"; arch = "linux-i686"; sha256 = "06fdb2df4bcca189736fc6ae2fee6ba87f6b19d0b64f21bdb2b07e478fe6a0ba"; } + { locale = "et"; arch = "linux-x86_64"; sha256 = "f110d0940905e2cbe4ab14c1370ff88e533e030fb5a408bf4f06f517351d5979"; } + { locale = "eu"; arch = "linux-x86_64"; sha256 = "02bbb72fea711772d0dba0137641acb9f0293313a552e554443118324737fba4"; } + { locale = "eu"; arch = "linux-i686"; sha256 = "3a94fc161e98282691d668b68b3a8e7bf035dc87ec0d07be6eb1844b2a79cd39"; } + { locale = "fi"; arch = "linux-i686"; sha256 = "3f9c44306991554cf48fee4da86dec6ab06cb863baa8157d7adf29f6f8b0119f"; } + { locale = "fi"; arch = "linux-x86_64"; sha256 = "9883bfa54e331c17338bdf7e835a0a0f71a9366ad99ddc0fda12fd9d062f071b"; } + { locale = "fr"; arch = "linux-x86_64"; sha256 = "60e59c9b9ac78cba5604a051784a8721f84bfd10899d9575a4591ae4e5c48afc"; } + { locale = "fr"; arch = "linux-i686"; sha256 = "d16908d799fe667032d317b01db91cdfcd0b23654061203df84f5cb67d6ae837"; } + { locale = "fy-NL"; arch = "linux-x86_64"; sha256 = "21e209179135fd97207e878c415d112e6c01bd7686f45eef2891cd8508dd8f9c"; } + { locale = "fy-NL"; arch = "linux-i686"; sha256 = "c8463a38d5fc454ad80a519a9828c1c8808688aa140b5d5276b53a659ae7bf7d"; } + { locale = "ga-IE"; arch = "linux-x86_64"; sha256 = "22d6d90cd7490e36ef5df2106ba84bcd49038cecf70a60cebd4bf552a01bfdd7"; } + { locale = "ga-IE"; arch = "linux-i686"; sha256 = "5a7fcc013bcd09d327e40e5b0001057067f9e509e52f38681893f1a16cf8520a"; } + { locale = "gd"; arch = "linux-i686"; sha256 = "14c7d9a846a5d2a409089a16afdc97309d6818f97097d73757245b29cdeb73ae"; } + { locale = "gd"; arch = "linux-x86_64"; sha256 = "e4d3b093da2d80e2a2c02be8d03831c6a89e8969d3261a39f153a6d96f20c7eb"; } + { locale = "gl"; arch = "linux-i686"; sha256 = "73515b65314f8aa28fdb8708e821c01ba6edab5474e5140266b8ee8c0206807f"; } + { locale = "gl"; arch = "linux-x86_64"; sha256 = "7dd646cde4969243178237ea7fdf7b3c7c369e735a42f21292e8fcc3bce2c6ac"; } + { locale = "he"; arch = "linux-x86_64"; sha256 = "3fdf3750727f47628ffe4e7b28e8b7f180194be5985f4a10c703d3322a563e55"; } + { locale = "he"; arch = "linux-i686"; sha256 = "e4385cded8a13776890320780c6aa265c9562a6301f8f5ee7f4fbeb4aa54acf8"; } + { locale = "hr"; arch = "linux-x86_64"; sha256 = "ada94d6612f20642e6294a17334afb8d31b419132e725618a376728a6028454e"; } + { locale = "hr"; arch = "linux-i686"; sha256 = "bcbb85910f983145ff8df79574087cebaac6537600aa9a479f55298a7d6bc1c2"; } + { locale = "hu"; arch = "linux-i686"; sha256 = "0f41a925ee5c3ad59f24a6b59eed066d1fb37ea8ec81ab4bac70280437be2589"; } + { locale = "hu"; arch = "linux-x86_64"; sha256 = "9038e0358bb63a147835cacf91a7e7db888fc7b93662cca4919110e2a5daed76"; } + { locale = "hy-AM"; arch = "linux-i686"; sha256 = "24af2ffa71d5810f8e947de27e77a70310c22dc1cc89640b67416fe74a4a14b3"; } + { locale = "hy-AM"; arch = "linux-x86_64"; sha256 = "62cfce68247f5afd2c68a97ed230b515c1515ecd279a753bf9c728c552683f6c"; } + { locale = "id"; arch = "linux-i686"; sha256 = "a5e2d72cb0841848cd5a947d4cda2e84db1eae97a0735974690176ccd966eeea"; } + { locale = "id"; arch = "linux-x86_64"; sha256 = "f1d539fe69b8121205c5411096554cab41ae4f42a2018af6ba020a2d8fe660dc"; } + { locale = "is"; arch = "linux-i686"; sha256 = "6eacbd0b4b9f47f67818d6021600b5dddc79d2a38edac5c47f61ac039ed5cdb6"; } + { locale = "is"; arch = "linux-x86_64"; sha256 = "fcc86ac738b190012d38d32c6cee3c35d57f6a3b80867c0107f4b8a2717961bb"; } + { locale = "it"; arch = "linux-x86_64"; sha256 = "9b668a501c7da55c630761dbf89ae8fe2e32038af8ce4c10fc646eae7c2d08e2"; } + { locale = "it"; arch = "linux-i686"; sha256 = "f610b7d4a34635e7c3b5c355873b65558537224d5a241b92605a49499ba4d5e6"; } + { locale = "ja"; arch = "linux-i686"; sha256 = "185ee26eb9a33ba534805b5b3547b3524bf11c94614adc252f7d17b41279d312"; } + { locale = "ja"; arch = "linux-x86_64"; sha256 = "1be85c39fa8b09a6bc2b11a47d04f0447628c3ed8a775d27c8e04577627ed63e"; } + { locale = "ko"; arch = "linux-i686"; sha256 = "e868d431d77b419bae6fcc7e1e137815ca8cbad6673074469005c606023d7983"; } + { locale = "ko"; arch = "linux-x86_64"; sha256 = "fa4db6ff8047a5e11411e507df4f84baac5511a1709d5685a2a6e8da0d2e1f25"; } + { locale = "lt"; arch = "linux-i686"; sha256 = "40c1eeabbd9d877750bee7f5f4a6b6f2108aa364ace8eefff26806a5bafca5eb"; } + { locale = "lt"; arch = "linux-x86_64"; sha256 = "4bdff4418bc0c9acc7d3b00ccc6500d51e65a501c2438e99e22c03bbeb36dfff"; } + { locale = "nb-NO"; arch = "linux-i686"; sha256 = "541b5f434e6354bb6a4c50abb828a49383b1d1a9fb31d6b99c1f052ef73bc2f2"; } + { locale = "nb-NO"; arch = "linux-x86_64"; sha256 = "9e954408406762e55fd40487cad589c876285145931f8a12ff6ced29d9583cde"; } + { locale = "nl"; arch = "linux-i686"; sha256 = "06a57772563456d5283b9a36b9e6cbb5efb4f33e4ea29ac2446055e0a965b8c9"; } + { locale = "nl"; arch = "linux-x86_64"; sha256 = "42a8d995ac906c7fb4a1952db62d1717aa7c4660a2e7e794da3aae6aaac6f9c9"; } + { locale = "nn-NO"; arch = "linux-i686"; sha256 = "6fed1e74c6323d2909caf471ca733df46224afcb0c632d5fa0f0d80d6157efd3"; } + { locale = "nn-NO"; arch = "linux-x86_64"; sha256 = "c29d8ff69ec2a8b5f508b7c56cd8679fe3b322f7e2e87f10303fd8bca1b93230"; } + { locale = "pa-IN"; arch = "linux-i686"; sha256 = "a69a7ceb4fa85cc43c367f1ddebafa76808e83d3044c158287a5923b82fc3093"; } + { locale = "pa-IN"; arch = "linux-x86_64"; sha256 = "e38e75976891204fde647d389b6c89c807d378a534d6e04582024755a3cb6139"; } + { locale = "pl"; arch = "linux-x86_64"; sha256 = "39a0d3f865c462b5d3ae569825befd61dbf3ee5a6b2b81d3b9d31f4c98cf7b72"; } + { locale = "pl"; arch = "linux-i686"; sha256 = "3ccedf1ad79135d825f762dd09da88be23901591b27ea7e61a887d5398284a46"; } + { locale = "pt-BR"; arch = "linux-x86_64"; sha256 = "ea29e40d41442ab373855acd7b40927fc5a0408f9d3bb4a0c6a2021cd8b0fca2"; } + { locale = "pt-BR"; arch = "linux-i686"; sha256 = "f6170909b6527e935584673a17d1245c33142a755a9db45dda2de240871fc6c0"; } + { locale = "pt-PT"; arch = "linux-i686"; sha256 = "15531f4e4652d533fd8cb8d3be8b5e24717240160d885629eecc7f08d8cd0701"; } + { locale = "pt-PT"; arch = "linux-x86_64"; sha256 = "9100cdf6ba87959dfbdf756c925f6a2f35fc0c6ed453625a23eccc48f0bdf331"; } + { locale = "rm"; arch = "linux-x86_64"; sha256 = "9bd00e4e2634e9f922d6c1d4ef82dcba53f88fa6d7d1986037665a42109d39d2"; } + { locale = "rm"; arch = "linux-i686"; sha256 = "e2ca3832625efa908c6d88627960e1d98255d14095a36033cddaa50065172da0"; } + { locale = "ro"; arch = "linux-x86_64"; sha256 = "676120061a33c1bbbd381ea1d84b271c6e21d4a531ba776f67f7a02fd91fb99e"; } + { locale = "ro"; arch = "linux-i686"; sha256 = "c69d6b8a8de474e460c89ba442e25aa39fe761225f7c4b12eb1df88021a6b6c3"; } + { locale = "ru"; arch = "linux-x86_64"; sha256 = "5a6af10060b8ea8acd3955a4056765574873e9341e4627ddcbf9811724f5eac0"; } + { locale = "ru"; arch = "linux-i686"; sha256 = "92ce7cb5db9d94e291d7275b8817640c68dc061a3947317cba76ceb263a4b614"; } + { locale = "si"; arch = "linux-i686"; sha256 = "39849a4d38a96ebca9727b65093c36d8d50cadddcdea7ea404ee4aeff10fec0d"; } + { locale = "si"; arch = "linux-x86_64"; sha256 = "fa42ef419e173181166c6797e37571df6b7c25797a5caf8ca44c34b4f2faacdb"; } + { locale = "sk"; arch = "linux-x86_64"; sha256 = "2c9c81db8c15116e6061de0b44dcb34579ce305ca30af284cf9eac52630fef55"; } + { locale = "sk"; arch = "linux-i686"; sha256 = "b253607b29565169d74c491772ba2887c3e2c0dfcc3a7cedf91afa0bb073ff72"; } + { locale = "sl"; arch = "linux-x86_64"; sha256 = "03e7781cd0c3fef0596e55ba8a711ef8b8f300e48297ef3cad7885b2b118864f"; } + { locale = "sl"; arch = "linux-i686"; sha256 = "18fe799b1b675e5513ddf9edbe845bfaaafd67162e9d34250a31d0ee05bc9bba"; } + { locale = "sq"; arch = "linux-i686"; sha256 = "4fd1be2d2c6a703544b82bf977ea63df3e295c16c9ea97573ee57945e07639ee"; } + { locale = "sq"; arch = "linux-x86_64"; sha256 = "e96f7302d47897c3fc58a2777aed666aca29641500e912cee1bc59406df8e500"; } + { locale = "sr"; arch = "linux-x86_64"; sha256 = "ede709c9e6014edbc543511d99a61acfb0d40b796ed5ab42267ae7f8efb6583c"; } + { locale = "sr"; arch = "linux-i686"; sha256 = "fbfc0d476817c7076a72fd6fe2519c6a347fb062f696a8fe0c969182750d1d11"; } + { locale = "sv-SE"; arch = "linux-i686"; sha256 = "d30dda991111ae5bbf7252d889cef53258317d3570e56360db3d7676a8fc7602"; } + { locale = "sv-SE"; arch = "linux-x86_64"; sha256 = "eba61a1417ba4cb4885732d2eb621f5a385b4b433f706d52bd1b401d2298985e"; } + { locale = "ta-LK"; arch = "linux-i686"; sha256 = "92dc3a2aaf30c5bb16462ee7d73a5df6f8b5d2d1530f5d1fb4b90460e84dc77f"; } + { locale = "ta-LK"; arch = "linux-x86_64"; sha256 = "e5db15f32c819d3b0e670ac975d7afc118915abeaf4a9f0a02a5b67c490605d7"; } + { locale = "tr"; arch = "linux-x86_64"; sha256 = "0c689f622a0770a0b0d8f87d35513f9fbc110ca507d0b8b3bd426f763a0f77c4"; } + { locale = "tr"; arch = "linux-i686"; sha256 = "f49e5f3bf1b4616f52e82c480f9a4752269f393d79de2274fc0562cfe9fef1ea"; } + { locale = "uk"; arch = "linux-x86_64"; sha256 = "06100c2a82b3c31ea85f1f1d8856db62f2a73142fd1263e3db5df679f8843d8f"; } + { locale = "uk"; arch = "linux-i686"; sha256 = "8358a935935215fea5eb75c69cf63bb5fc5c22bcce76939cfb804f3ee9f89e54"; } + { locale = "vi"; arch = "linux-i686"; sha256 = "16a0f71efcf71640234501e3c8a3bd1befe15e1bb0bacc83ff590d6c780a0e5b"; } + { locale = "vi"; arch = "linux-x86_64"; sha256 = "d5d0371ade5603cb725d6677983df037da06acb13207550b8a1a88c2948e992b"; } + { locale = "zh-CN"; arch = "linux-x86_64"; sha256 = "287b1fda3bb2d8d27ea22ea4c8c21d7ee0b3a5d439ea32e72dfc882fd64c5765"; } + { locale = "zh-CN"; arch = "linux-i686"; sha256 = "3bddd9f4e742ad80bb6d35f3db8ea50cd496ad1be06003e67b4fcc290945bab8"; } + { locale = "zh-TW"; arch = "linux-x86_64"; sha256 = "5a5cb16f45d1c3ccd9e0fd0b21a7b55e90b49f0b37cd550bd89cb6c00d92046c"; } + { locale = "zh-TW"; arch = "linux-i686"; sha256 = "aea52fd5f8d8d5b720e1fde907b9a7b7638b384b71d01295b08749df06c578bc"; } + ]; + + arch = if stdenv.system == "i686-linux" + then "linux-i686" + else "linux-x86_64"; + + isPrefixOf = prefix: string: + builtins.substring 0 (builtins.stringLength prefix) string == prefix; + + sourceMatches = locale: source: + (isPrefixOf source.locale locale) && source.arch == arch; + + systemLocale = config.i18n.defaultLocale or "en-US"; + + defaultSource = stdenv.lib.findFirst (sourceMatches "en-US") {} sources; + + source = stdenv.lib.findFirst (sourceMatches systemLocale) defaultSource sources; + +in + +stdenv.mkDerivation { + name = "thunderbird-bin-${version}"; + + src = fetchurl { + url = "http://download-installer.cdn.mozilla.net/pub/thunderbird/releases/${version}/${source.arch}/${source.locale}/thunderbird-${version}.tar.bz2"; + inherit (source) sha256; + }; + + phases = "unpackPhase installPhase"; + + libPath = stdenv.lib.makeLibraryPath + [ stdenv.gcc.gcc + gconf + alsaLib + at_spi2_atk + atk + cairo + cups + curl + dbus_glib + dbus_libs + fontconfig + freetype + gdk_pixbuf + glib + glibc + gst_plugins_base + gstreamer + gtk + kerberos + libX11 + libXScrnSaver + libXext + libXinerama + libXrender + libXt + libcanberra + libgnome + libgnomeui + mesa + nspr + nss + pango + ] + ":" + stdenv.lib.makeSearchPath "lib64" [ + stdenv.gcc.gcc + ]; + + installPhase = + '' + mkdir -p "$prefix/usr/lib/thunderbird-bin-${version}" + cp -r * "$prefix/usr/lib/thunderbird-bin-${version}" + + mkdir -p "$out/bin" + ln -s "$prefix/usr/lib/thunderbird-bin-${version}/thunderbird" "$out/bin/" + + for executable in \ + thunderbird mozilla-xremote-client thunderbird-bin plugin-container \ + updater + do + patchelf --interpreter "$(cat $NIX_GCC/nix-support/dynamic-linker)" \ + "$out/usr/lib/thunderbird-bin-${version}/$executable" + done + + for executable in \ + thunderbird mozilla-xremote-client thunderbird-bin plugin-container \ + updater libxul.so + do + patchelf --set-rpath "$libPath" \ + "$out/usr/lib/thunderbird-bin-${version}/$executable" + done + + # Create a desktop item. + mkdir -p $out/share/applications + cat > $out/share/applications/thunderbird.desktop <<EOF + [Desktop Entry] + Type=Application + Exec=$out/bin/thunderbird + Icon=$out/lib/thunderbird-bin-${version}/chrome/icons/default/default256.png + Name=Thunderbird + GenericName=Mail Reader + Categories=Application;Network; + EOF + ''; + + meta = with stdenv.lib; { + description = "Mozilla Thunderbird, a full-featured email client"; + homepage = http://www.mozilla.org/thunderbird/; + license = { + shortName = "unfree"; # not sure + fullName = "unfree"; + url = http://www.mozilla.org/en-US/foundation/trademarks/policy/; + }; + platforms = platforms.linux; + }; +} + diff --git a/pkgs/applications/networking/sync/rsync/default.nix b/pkgs/applications/networking/sync/rsync/default.nix index 5447b21009ff..5265faf87b6f 100644 --- a/pkgs/applications/networking/sync/rsync/default.nix +++ b/pkgs/applications/networking/sync/rsync/default.nix @@ -6,16 +6,17 @@ assert enableACLs -> acl != null; stdenv.mkDerivation rec { - name = "rsync-3.0.9"; + name = "rsync-${version}"; + version = "3.1.0"; mainSrc = fetchurl { - url = http://rsync.samba.org/ftp/rsync/src/rsync-3.0.9.tar.gz; - sha256 = "01bw4klqsrlhh3i9lazd485sd9qx5djvnwa21lj2h3a9sn6hzw9h"; + url = "http://rsync.samba.org/ftp/rsync/src/rsync-${version}.tar.gz"; + sha256 = "0kirw8wglqvwi1v8bwxp373g03xg857h59j5k3mmgff9gzvj7jl1"; }; patchesSrc = fetchurl { - url = http://rsync.samba.org/ftp/rsync/rsync-patches-3.0.9.tar.gz; - sha256 = "0c1e9b56e99667dfc47641124460bac61a04c5d2ee89f575c6bc78c7a69005a9"; + url = "http://rsync.samba.org/ftp/rsync/rsync-patches-${version}.tar.gz"; + sha256 = "0sl8aadpjblvbb05vgais40z90yzhr09rwz0cykjdiv452gli75p"; }; srcs = [mainSrc] ++ stdenv.lib.optional enableCopyDevicesPatch patchesSrc; @@ -30,6 +31,6 @@ stdenv.mkDerivation rec { license = stdenv.lib.licenses.gpl3Plus; platforms = stdenv.lib.platforms.unix; - maintainers = [ stdenv.lib.maintainers.simons ]; + maintainers = [ stdenv.lib.maintainers.simons stdenv.lib.maintainers.emery ]; }; } diff --git a/pkgs/applications/science/misc/megam/default.nix b/pkgs/applications/science/misc/megam/default.nix new file mode 100644 index 000000000000..a0ee505dc97f --- /dev/null +++ b/pkgs/applications/science/misc/megam/default.nix @@ -0,0 +1,46 @@ +{ fetchurl, stdenv, ocaml, makeWrapper, ncurses }: + +let version = "0.92"; in +stdenv.mkDerivation rec { + name = "megam-${version}"; + + src = fetchurl { + url = "http://hal3.name/megam/megam_src.tgz"; + sha256 = "dc0e9f59ff8513449fe3bd40b260141f89c88a4edf6ddc8b8a394c758e49724e"; + }; + + patches = [ ./ocaml-includes.patch ./ocaml-3.12.patch ]; + + buildInputs = [ ocaml ncurses ]; + + nativeBuildInputs = [ makeWrapper ]; + + makeFlags = "CAML_INCLUDES=${ocaml}/lib/ocaml/caml"; + + # see https://bugzilla.redhat.com/show_bug.cgi?id=435559 + dontStrip = true; + + installPhase = '' + mkdir -pv $out/bin + cp -Rv megam $out/bin + ''; + + + meta = { + description = "MEGA Model Optimization Package"; + + longDescription = + '' The software here is an implementation of maximum likelihood + and maximum a posterior optimization of the parameters of + these models. The algorithms used are much more efficient + than the iterative scaling techniques used in almost every + other maxent package out there. ''; + + homepage = http://www.umiacs.umd.edu/~hal/megam; + + license = "non-commercial"; + + maintainers = [ ]; + platforms = stdenv.lib.platforms.gnu; # arbitrary choice + }; +} diff --git a/pkgs/applications/science/misc/megam/ocaml-3.12.patch b/pkgs/applications/science/misc/megam/ocaml-3.12.patch new file mode 100644 index 000000000000..8265acf6e4a7 --- /dev/null +++ b/pkgs/applications/science/misc/megam/ocaml-3.12.patch @@ -0,0 +1,12 @@ +diff -ru megam_0.92/Makefile megam_0.92-b/Makefile +--- megam_0.92/Makefile 2007-10-08 18:06:04.000000000 +0100 ++++ megam_0.92-b/Makefile 2013-11-25 10:14:20.000000000 +0000 +@@ -59,7 +59,7 @@ + + WITHUNIX =unix.cma -cclib -lunix + +-WITHSTR =str.cma -cclib -lstr ++WITHSTR =str.cma -cclib -lcamlstr + + WITHBIGARRAY =bigarray.cma -cclib -lbigarray + diff --git a/pkgs/applications/science/misc/megam/ocaml-includes.patch b/pkgs/applications/science/misc/megam/ocaml-includes.patch new file mode 100644 index 000000000000..b3a56643448c --- /dev/null +++ b/pkgs/applications/science/misc/megam/ocaml-includes.patch @@ -0,0 +1,21 @@ +diff -ru megam_0.92/Makefile megam_0.92-b/Makefile +--- megam_0.92/Makefile 2007-10-08 18:06:04.000000000 +0100 ++++ megam_0.92-b/Makefile 2013-11-25 10:14:20.000000000 +0000 +@@ -41,7 +41,7 @@ + # + # The Caml compilers. # + # You may fix here the path to access the Caml compiler on your machine +-CAMLC = ocamlc -g ++CAMLC = ocamlc -g $(WITHCLIBS) + CAMLOPT = ocamlopt -unsafe -ccopt -O4 -ccopt -ffast-math -inline 99999 + CAMLDEP = ocamldep + CAMLLEX = ocamllex +@@ -70,7 +70,7 @@ + WITHDBM =dbm.cma -cclib -lmldbm -cclib -lndbm + + #WITHCLIBS =-I /usr/lib/ocaml/3.09.2/caml +-WITHCLIBS =-I /usr/lib/ocaml/caml ++WITHCLIBS =-I $(CAML_INCLUDES) + + ################ End of user's variables ##################### + diff --git a/pkgs/applications/video/miro/default.nix b/pkgs/applications/video/miro/default.nix index 14aeca62a710..528eeff7e239 100644 --- a/pkgs/applications/video/miro/default.nix +++ b/pkgs/applications/video/miro/default.nix @@ -1,7 +1,7 @@ { stdenv, fetchurl, python, buildPythonPackage, pythonPackages, pkgconfig -, pyrex096, ffmpeg, boost, glib, pygobject, gtk2, webkit_gtk2, libsoup, pygtk +, pyrex096, ffmpeg, boost, glib, pygobject, gtk2, webkitgtk2, libsoup, pygtk , taglib, pysqlite, pycurl, mutagen, pycairo, pythonDBus, pywebkitgtk -, libtorrentRasterbar +, libtorrentRasterbar, glib_networking, gsettings_desktop_schemas , gst_python, gst_plugins_base, gst_plugins_good, gst_ffmpeg }: @@ -22,9 +22,6 @@ buildPythonPackage rec { patches = [ ./gconf.patch ]; postPatch = '' - sed -i -e '2i import os; os.environ["GST_PLUGIN_PATH"] = \\\ - '"'$GST_PLUGIN_PATH'" miro.real - sed -i -e 's/\$(shell which python)/python/' Makefile sed -i -e 's|/usr/bin/||' -e 's|/usr||' \ -e 's/BUILD_TIME[^,]*/BUILD_TIME=0/' setup.py @@ -55,10 +52,14 @@ buildPythonPackage rec { postInstall = '' mv "$out/bin/miro.real" "$out/bin/miro" + wrapProgram "$out/bin/miro" \ + --prefix GST_PLUGIN_SYSTEM_PATH : "$GST_PLUGIN_SYSTEM_PATH" \ + --prefix GIO_EXTRA_MODULES : "${glib_networking}/lib/gio/modules" \ + --prefix XDG_DATA_DIRS : "${gsettings_desktop_schemas}/share:$out/share" ''; buildInputs = [ - pkgconfig pyrex096 ffmpeg boost glib pygobject gtk2 webkit_gtk2 libsoup + pkgconfig pyrex096 ffmpeg boost glib pygobject gtk2 webkitgtk2 libsoup pygtk taglib ]; diff --git a/pkgs/build-support/build-fhs-chrootenv/default.nix b/pkgs/build-support/build-fhs-chrootenv/default.nix index 8756c4835b29..2f3aa14c6a0f 100644 --- a/pkgs/build-support/build-fhs-chrootenv/default.nix +++ b/pkgs/build-support/build-fhs-chrootenv/default.nix @@ -1,10 +1,12 @@ {stdenv, glibc, glibcLocales, gcc, coreutils, diffutils, findutils, gnused, gnugrep, gnutar, gzip, bzip2, -bashInteractive, xz, shadow, gawk, less, buildEnv}: +bashInteractive, xz, shadow, gawk, less, su, buildEnv}: {name, pkgs ? [], profile ? ""}: let - basePkgs = [ glibc glibcLocales gcc coreutils diffutils findutils gnused gnugrep gnutar gzip bzip2 -bashInteractive xz shadow gawk less ]; + basePkgs = [ + glibc glibcLocales gcc coreutils diffutils findutils gnused gnugrep gnutar + gzip bzip2 bashInteractive xz shadow gawk less su + ]; # Compose a global profile for the chroot environment profilePkg = stdenv.mkDerivation { @@ -31,16 +33,16 @@ bashInteractive xz shadow gawk less ]; mountSh = ./mount.sh.in; loadSh = ./load.sh.in; umountSh = ./umount.sh.in; - destroySh = ./destroy.sh.in; -in -stdenv.mkDerivation { - name = "${name}-chrootenv"; - buildCommand = '' - mkdir -p $out/sw - cd $out/sw - - for i in ${staticUsrProfile}/{etc,bin,lib{,32,64},sbin,var} - do + destroySh = ./destroy.sh.in; +in +stdenv.mkDerivation { + name = "${name}-chrootenv"; + buildCommand = '' + mkdir -p $out/sw + cd $out/sw + + for i in ${staticUsrProfile}/{etc,bin,lib{,32,64},sbin,var} + do if [ -x "$i" ] then ln -s "$i" diff --git a/pkgs/desktops/cinnamon/cinnamon-control-center.nix b/pkgs/desktops/cinnamon/cinnamon-control-center.nix new file mode 100644 index 000000000000..ab2f389b4f5f --- /dev/null +++ b/pkgs/desktops/cinnamon/cinnamon-control-center.nix @@ -0,0 +1,40 @@ + +{ stdenv, fetchurl, pkgconfig, autoreconfHook, glib, gettext, gnome_common, cinnamon-desktop, intltool, libxslt, gtk3, libnotify, +gnome-menus, libxml2, systemd, upower, cinnamon-settings-daemon, colord, polkit, ibus, libcanberra_gtk3, pulseaudio, isocodes, krb5, +libxkbfile}: + +let + version = "2.0.9"; +in +stdenv.mkDerivation { + name = "cinnamon-control-center-${version}"; + + src = fetchurl { + url = "http://github.com/linuxmint/cinnamon-control-center/archive/${version}.tar.gz"; + sha256 = "0kivqdgsf8w257j2ja6fap0dpvljcnb9gphr3knp7y6ma2d1gfv3"; + }; + + configureFlags = "--enable-systemd --disable-update-mimedb" ; + + patches = [ ./region.patch]; + + buildInputs = [ + pkgconfig autoreconfHook + glib gettext gnome_common + intltool libxslt gtk3 cinnamon-desktop + libnotify gnome-menus libxml2 systemd + upower cinnamon-settings-daemon colord + polkit ibus libcanberra_gtk3 pulseaudio + isocodes krb5 libxkbfile ]; + + preBuild = "patchShebangs ./scripts"; + + meta = { + homepage = "http://cinnamon.linuxmint.com"; + description = "The cinnamon session files" ; + + platforms = stdenv.lib.platforms.linux; + maintainers = [ stdenv.lib.maintainers.roelof ]; + }; +} + diff --git a/pkgs/desktops/cinnamon/region.patch b/pkgs/desktops/cinnamon/region.patch new file mode 100644 index 000000000000..7b8133e820ed --- /dev/null +++ b/pkgs/desktops/cinnamon/region.patch @@ -0,0 +1,5314 @@ + +diff -uNrp a/configure.ac b/configure.ac +--- a/configure.ac 2013-08-25 14:40:14.000000000 +0100 ++++ b/configure.ac 2013-08-25 16:50:30.000000000 +0100 +@@ -82,6 +82,22 @@ else + SYSTEMD= + fi + ++# IBus support ++IBUS_REQUIRED_VERSION=1.4.2 ++ ++#AC_ARG_ENABLE(ibus, ++# AS_HELP_STRING([--disable-ibus], ++# [Disable IBus support]), ++# enable_ibus=$enableval, ++# enable_ibus=yes) ++enable_ibus=yes ++#if test "x$enable_ibus" = "xyes" ; then ++IBUS_MODULE="ibus-1.0 >= $IBUS_REQUIRED_VERSION" ++AC_DEFINE(HAVE_IBUS, 1, [Defined if IBus support is enabled]) ++#else ++# IBUS_MODULE= ++#fi ++ + dnl ============================================== + dnl Check that we meet the dependencies + dnl ============================================== +@@ -119,9 +135,10 @@ PKG_CHECK_MODULES(NETWORK_PANEL, $COMMON + PKG_CHECK_MODULES(POWER_PANEL, $COMMON_MODULES upower-glib >= 0.9.1 + cinnamon-settings-daemon >= $CSD_REQUIRED_VERSION) + PKG_CHECK_MODULES(COLOR_PANEL, $COMMON_MODULES colord >= 0.1.8) +-PKG_CHECK_MODULES(REGION_PANEL, $COMMON_MODULES libgnomekbd >= 2.91.91 ++PKG_CHECK_MODULES(REGION_PANEL, $COMMON_MODULES + polkit-gobject-1 >= $POLKIT_REQUIRED_VERSION +- libxklavier >= 5.1 libgnomekbdui >= 2.91.91) ++ cinnamon-desktop >= $CINNAMON_DESKTOP_REQUIRED_VERSION ++ $IBUS_MODULE) + PKG_CHECK_MODULES(SCREEN_PANEL, $COMMON_MODULES) + PKG_CHECK_MODULES(SOUND_PANEL, $COMMON_MODULES libxml-2.0 + libcanberra-gtk3 >= $CANBERRA_REQUIRED_VERSION +diff -uNrp a/panels/region/cc-region-panel.c b/panels/region/cc-region-panel.c +--- a/panels/region/cc-region-panel.c 2013-08-25 14:40:14.000000000 +0100 ++++ b/panels/region/cc-region-panel.c 2013-09-21 13:24:15.329949897 +0100 +@@ -18,17 +18,18 @@ + * Author: Sergey Udaltsov <svu@gnome.org> + * + */ +-#include "config.h" ++ + #include "cc-region-panel.h" ++#include <config.h> + #include <gtk/gtk.h> + #include <glib/gi18n-lib.h> + +-#include "cinnamon-region-panel-xkb.h" ++#include "cinnamon-region-panel-input.h" + #include "cinnamon-region-panel-lang.h" + #include "cinnamon-region-panel-formats.h" + #include "cinnamon-region-panel-system.h" + +-G_DEFINE_DYNAMIC_TYPE (CcRegionPanel, cc_region_panel, CC_TYPE_PANEL) ++CC_PANEL_REGISTER (CcRegionPanel, cc_region_panel) + + #define REGION_PANEL_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), CC_TYPE_REGION_PANEL, CcRegionPanelPrivate)) + +@@ -48,14 +49,6 @@ enum { + SYSTEM_PAGE + }; + +- +-static gboolean +-languages_link_cb (GtkButton *button, gpointer user_data) +-{ +- g_spawn_command_line_async ("gnome-language-selector", NULL); +- return TRUE; +-} +- + static void + cc_region_panel_set_page (CcRegionPanel *panel, + const char *page) +@@ -116,13 +109,22 @@ cc_region_panel_finalize (GObject * obje + G_OBJECT_CLASS (cc_region_panel_parent_class)->finalize (object); + } + ++static const char * ++cc_region_panel_get_help_uri (CcPanel *panel) ++{ ++ return "help:gnome-help/prefs-language"; ++} ++ + static void + cc_region_panel_class_init (CcRegionPanelClass * klass) + { + GObjectClass *object_class = G_OBJECT_CLASS (klass); ++ CcPanelClass * panel_class = CC_PANEL_CLASS (klass); + + g_type_class_add_private (klass, sizeof (CcRegionPanelPrivate)); + ++ panel_class->get_help_uri = cc_region_panel_get_help_uri; ++ + object_class->set_property = cc_region_panel_set_property; + object_class->finalize = cc_region_panel_finalize; + +@@ -130,22 +132,14 @@ cc_region_panel_class_init (CcRegionPane + } + + static void +-cc_region_panel_class_finalize (CcRegionPanelClass * klass) +-{ +-} +- +-static void + cc_region_panel_init (CcRegionPanel * self) + { + CcRegionPanelPrivate *priv; + GtkWidget *prefs_widget; +- const char *desktop; + GError *error = NULL; + + priv = self->priv = REGION_PANEL_PRIVATE (self); + +- desktop = g_getenv ("XDG_CURRENT_DESKTOP"); +- + priv->builder = gtk_builder_new (); + gtk_builder_set_translation_domain (priv->builder, GETTEXT_PACKAGE); + gtk_builder_add_from_file (priv->builder, +@@ -157,29 +151,16 @@ cc_region_panel_init (CcRegionPanel * se + return; + } + +- prefs_widget = (GtkWidget *) gtk_builder_get_object (priv->builder, +- "region_notebook"); +- ++ prefs_widget = (GtkWidget *) gtk_builder_get_object (priv->builder, ++ "region_notebook"); + gtk_widget_set_size_request (GTK_WIDGET (prefs_widget), -1, 400); + + gtk_widget_reparent (prefs_widget, GTK_WIDGET (self)); + +- setup_xkb_tabs (priv->builder); +- +- setup_language (priv->builder); +- setup_formats (priv->builder); +- setup_system (priv->builder); +- +- /* set screen link */ +- +- GtkWidget *widget = GTK_WIDGET (gtk_builder_get_object (self->priv->builder, +- "get_languages_button")); +- +- gtk_button_set_label (GTK_BUTTON (widget), _("Get more languages...")); +- +- g_signal_connect (widget, "clicked", +- G_CALLBACK (languages_link_cb), +- self); ++ setup_input_tabs (priv->builder, self); ++ setup_language (priv->builder); ++ setup_formats (priv->builder); ++ setup_system (priv->builder); + } + + void +@@ -187,6 +168,7 @@ cc_region_panel_register (GIOModule * mo + { + bindtextdomain (GETTEXT_PACKAGE, "/usr/share/cinnamon/locale"); + bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); ++ + cc_region_panel_register_type (G_TYPE_MODULE (module)); + g_io_extension_point_implement (CC_SHELL_PANEL_EXTENSION_POINT, + CC_TYPE_REGION_PANEL, +diff -uNrp a/panels/region/cinnamon-region-panel-formats.h b/panels/region/cinnamon-region-panel-formats.h +--- a/panels/region/cinnamon-region-panel-formats.h 2013-08-25 14:40:14.000000000 +0100 ++++ b/panels/region/cinnamon-region-panel-formats.h 2013-09-21 13:24:15.332949789 +0100 +@@ -19,8 +19,8 @@ + * 02110-1335, USA. + */ + +-#ifndef __GNOME_REGION_PANEL_FORMATS_H +-#define __GNOME_REGION_PANEL_FORMATS_H ++#ifndef __CINNAMON_REGION_PANEL_FORMATS_H ++#define __CINNAMON_REGION_PANEL_FORMATS_H + + #include <gtk/gtk.h> + +diff -uNrp a/panels/region/cinnamon-region-panel-input.c b/panels/region/cinnamon-region-panel-input.c +--- a/panels/region/cinnamon-region-panel-input.c 1970-01-01 01:00:00.000000000 +0100 ++++ b/panels/region/cinnamon-region-panel-input.c 2013-09-21 13:24:15.338949572 +0100 +@@ -0,0 +1,1563 @@ ++/* ++ * Copyright (C) 2011 Red Hat, Inc. ++ * ++ * Written by: Matthias Clasen <mclasen@redhat.com> ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2, or (at your option) ++ * any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA ++ * 02110-1335, USA. ++ */ ++ ++#include <config.h> ++ ++#include <string.h> ++ ++#include <glib.h> ++#include <glib/gi18n.h> ++#include <gio/gdesktopappinfo.h> ++ ++#define GNOME_DESKTOP_USE_UNSTABLE_API ++#include <libcinnamon-desktop/gnome-xkb-info.h> ++ ++#ifdef HAVE_IBUS ++#include <ibus.h> ++#endif ++ ++#include "gdm-languages.h" ++#include "cinnamon-region-panel-input.h" ++ ++#define WID(s) GTK_WIDGET(gtk_builder_get_object (builder, s)) ++ ++#define GNOME_DESKTOP_INPUT_SOURCES_DIR "org.cinnamon.desktop.input-sources" ++ ++#define KEY_CURRENT_INPUT_SOURCE "current" ++#define KEY_INPUT_SOURCES "sources" ++ ++#define INPUT_SOURCE_TYPE_XKB "xkb" ++#define INPUT_SOURCE_TYPE_IBUS "ibus" ++ ++enum { ++ NAME_COLUMN, ++ TYPE_COLUMN, ++ ID_COLUMN, ++ SETUP_COLUMN, ++ N_COLUMNS ++}; ++ ++static GSettings *input_sources_settings = NULL; ++static GnomeXkbInfo *xkb_info = NULL; ++static GtkWidget *input_chooser = NULL; /* weak pointer */ ++ ++#ifdef HAVE_IBUS ++static IBusBus *ibus = NULL; ++static GHashTable *ibus_engines = NULL; ++static GCancellable *ibus_cancellable = NULL; ++static guint shell_name_watch_id = 0; ++ ++static const gchar *supported_ibus_engines[] = { ++ /* Simplified Chinese */ ++ "pinyin", ++ "bopomofo", ++ "wubi", ++ "erbi", ++ /* Default in Fedora, where ibus-libpinyin replaces ibus-pinyin */ ++ "libpinyin", ++ "libbopomofo", ++ ++ /* Traditional Chinese */ ++ /* https://bugzilla.gnome.org/show_bug.cgi?id=680840 */ ++ "chewing", ++ "cangjie5", ++ "cangjie3", ++ "quick5", ++ "quick3", ++ "stroke5", ++ ++ /* Japanese */ ++ "anthy", ++ "mozc-jp", ++ "skk", ++ ++ /* Korean */ ++ "hangul", ++ ++ /* Thai */ ++ "m17n:th:kesmanee", ++ "m17n:th:pattachote", ++ "m17n:th:tis820", ++ ++ /* Vietnamese */ ++ "m17n:vi:tcvn", ++ "m17n:vi:telex", ++ "m17n:vi:viqr", ++ "m17n:vi:vni", ++ "Unikey", ++ ++ /* Sinhala */ ++ "m17n:si:wijesekera", ++ "m17n:si:phonetic-dynamic", ++ "m17n:si:trans", ++ "sayura", ++ ++ /* Indic */ ++ /* https://fedoraproject.org/wiki/I18N/Indic#Keyboard_Layouts */ ++ ++ /* Assamese */ ++ "m17n:as:phonetic", ++ "m17n:as:inscript", ++ "m17n:as:itrans", ++ ++ /* Bengali */ ++ "m17n:bn:inscript", ++ "m17n:bn:itrans", ++ "m17n:bn:probhat", ++ ++ /* Gujarati */ ++ "m17n:gu:inscript", ++ "m17n:gu:itrans", ++ "m17n:gu:phonetic", ++ ++ /* Hindi */ ++ "m17n:hi:inscript", ++ "m17n:hi:itrans", ++ "m17n:hi:phonetic", ++ "m17n:hi:remington", ++ "m17n:hi:typewriter", ++ "m17n:hi:vedmata", ++ ++ /* Kannada */ ++ "m17n:kn:kgp", ++ "m17n:kn:inscript", ++ "m17n:kn:itrans", ++ ++ /* Kashmiri */ ++ "m17n:ks:inscript", ++ ++ /* Maithili */ ++ "m17n:mai:inscript", ++ ++ /* Malayalam */ ++ "m17n:ml:inscript", ++ "m17n:ml:itrans", ++ "m17n:ml:mozhi", ++ "m17n:ml:swanalekha", ++ ++ /* Marathi */ ++ "m17n:mr:inscript", ++ "m17n:mr:itrans", ++ "m17n:mr:phonetic", ++ ++ /* Nepali */ ++ "m17n:ne:rom", ++ "m17n:ne:trad", ++ ++ /* Oriya */ ++ "m17n:or:inscript", ++ "m17n:or:itrans", ++ "m17n:or:phonetic", ++ ++ /* Punjabi */ ++ "m17n:pa:inscript", ++ "m17n:pa:itrans", ++ "m17n:pa:phonetic", ++ "m17n:pa:jhelum", ++ ++ /* Sanskrit */ ++ "m17n:sa:harvard-kyoto", ++ ++ /* Sindhi */ ++ "m17n:sd:inscript", ++ ++ /* Tamil */ ++ "m17n:ta:tamil99", ++ "m17n:ta:inscript", ++ "m17n:ta:itrans", ++ "m17n:ta:phonetic", ++ "m17n:ta:lk-renganathan", ++ "m17n:ta:vutam", ++ "m17n:ta:typewriter", ++ ++ /* Telugu */ ++ "m17n:te:inscript", ++ "m17n:te:apple", ++ "m17n:te:pothana", ++ "m17n:te:rts", ++ ++ /* Urdu */ ++ "m17n:ur:phonetic", ++ ++ /* Inscript2 - https://bugzilla.gnome.org/show_bug.cgi?id=684854 */ ++ "m17n:as:inscript2", ++ "m17n:bn:inscript2", ++ "m17n:brx:inscript2-deva", ++ "m17n:doi:inscript2-deva", ++ "m17n:gu:inscript2", ++ "m17n:hi:inscript2", ++ "m17n:kn:inscript2", ++ "m17n:kok:inscript2-deva", ++ "m17n:mai:inscript2", ++ "m17n:ml:inscript2", ++ "m17n:mni:inscript2-beng", ++ "m17n:mni:inscript2-mtei", ++ "m17n:mr:inscript2", ++ "m17n:ne:inscript2-deva", ++ "m17n:or:inscript2", ++ "m17n:pa:inscript2-guru", ++ "m17n:sa:inscript2", ++ "m17n:sat:inscript2-deva", ++ "m17n:sat:inscript2-olck", ++ "m17n:sd:inscript2-deva", ++ "m17n:ta:inscript2", ++ "m17n:te:inscript2", ++ ++ /* No corresponding XKB map available for the languages */ ++ ++ /* Chinese Yi */ ++ "m17n:ii:phonetic", ++ ++ /* Tai-Viet */ ++ "m17n:tai:sonla", ++ ++ /* Kazakh in Arabic script */ ++ "m17n:kk:arabic", ++ ++ /* Yiddish */ ++ "m17n:yi:yivo", ++ ++ /* Canadian Aboriginal languages */ ++ "m17n:ath:phonetic", ++ "m17n:bla:phonetic", ++ "m17n:cr:western", ++ "m17n:iu:phonetic", ++ "m17n:nsk:phonetic", ++ "m17n:oj:phonetic", ++ ++ /* Non-trivial engines, like transliteration-based instead of ++ keymap-based. Confirmation needed that the engines below are ++ actually used by local language users. */ ++ ++ /* Tibetan */ ++ "m17n:bo:ewts", ++ "m17n:bo:tcrc", ++ "m17n:bo:wylie", ++ ++ /* Esperanto */ ++ "m17n:eo:h-f", ++ "m17n:eo:h", ++ "m17n:eo:plena", ++ "m17n:eo:q", ++ "m17n:eo:vi", ++ "m17n:eo:x", ++ ++ /* Amharic */ ++ "m17n:am:sera", ++ ++ /* Russian */ ++ "m17n:ru:translit", ++ ++ /* Classical Greek */ ++ "m17n:grc:mizuochi", ++ ++ /* Lao */ ++ "m17n:lo:lrt", ++ ++ /* Postfix modifier input methods */ ++ "m17n:da:post", ++ "m17n:sv:post", ++ NULL ++}; ++#endif /* HAVE_IBUS */ ++ ++static void populate_model (GtkListStore *store, ++ GtkListStore *active_sources_store); ++static GtkWidget *input_chooser_new (GtkWindow *main_window, ++ GtkListStore *active_sources); ++static gboolean input_chooser_get_selected (GtkWidget *chooser, ++ GtkTreeModel **model, ++ GtkTreeIter *iter); ++static GtkTreeModel *tree_view_get_actual_model (GtkTreeView *tv); ++ ++static gboolean ++strv_contains (const gchar * const *strv, ++ const gchar *str) ++{ ++ const gchar * const *p = strv; ++ for (p = strv; *p; p++) ++ if (g_strcmp0 (*p, str) == 0) ++ return TRUE; ++ ++ return FALSE; ++} ++ ++#ifdef HAVE_IBUS ++static void ++clear_ibus (void) ++{ ++ if (shell_name_watch_id > 0) ++ { ++ g_bus_unwatch_name (shell_name_watch_id); ++ shell_name_watch_id = 0; ++ } ++ g_cancellable_cancel (ibus_cancellable); ++ g_clear_object (&ibus_cancellable); ++ g_clear_pointer (&ibus_engines, g_hash_table_destroy); ++ g_clear_object (&ibus); ++} ++ ++static gchar * ++engine_get_display_name (IBusEngineDesc *engine_desc) ++{ ++ const gchar *name; ++ const gchar *language_code; ++ const gchar *language; ++ gchar *display_name; ++ ++ name = ibus_engine_desc_get_longname (engine_desc); ++ language_code = ibus_engine_desc_get_language (engine_desc); ++ language = ibus_get_language_name (language_code); ++ ++ display_name = g_strdup_printf ("%s (%s)", language, name); ++ ++ return display_name; ++} ++ ++static GDesktopAppInfo * ++setup_app_info_for_id (const gchar *id) ++{ ++ GDesktopAppInfo *app_info; ++ gchar *desktop_file_name; ++ gchar **strv; ++ ++ strv = g_strsplit (id, ":", 2); ++ desktop_file_name = g_strdup_printf ("ibus-setup-%s.desktop", strv[0]); ++ g_strfreev (strv); ++ ++ app_info = g_desktop_app_info_new (desktop_file_name); ++ g_free (desktop_file_name); ++ ++ return app_info; ++} ++ ++static void ++input_chooser_repopulate (GtkListStore *active_sources_store) ++{ ++ GtkBuilder *builder; ++ GtkListStore *model; ++ ++ if (!input_chooser) ++ return; ++ ++ builder = g_object_get_data (G_OBJECT (input_chooser), "builder"); ++ model = GTK_LIST_STORE (gtk_builder_get_object (builder, "input_source_model")); ++ ++ gtk_list_store_clear (model); ++ populate_model (model, active_sources_store); ++} ++ ++static void ++update_ibus_active_sources (GtkBuilder *builder) ++{ ++ GtkTreeView *tv; ++ GtkTreeModel *model; ++ GtkTreeIter iter; ++ gchar *type, *id; ++ gboolean ret; ++ ++ tv = GTK_TREE_VIEW (WID ("active_input_sources")); ++ model = tree_view_get_actual_model (tv); ++ ++ ret = gtk_tree_model_get_iter_first (model, &iter); ++ while (ret) ++ { ++ gtk_tree_model_get (model, &iter, ++ TYPE_COLUMN, &type, ++ ID_COLUMN, &id, ++ -1); ++ ++ if (g_str_equal (type, INPUT_SOURCE_TYPE_IBUS)) ++ { ++ IBusEngineDesc *engine_desc = NULL; ++ GDesktopAppInfo *app_info = NULL; ++ gchar *display_name = NULL; ++ ++ engine_desc = g_hash_table_lookup (ibus_engines, id); ++ if (engine_desc) ++ { ++ display_name = engine_get_display_name (engine_desc); ++ app_info = setup_app_info_for_id (id); ++ ++ gtk_list_store_set (GTK_LIST_STORE (model), &iter, ++ NAME_COLUMN, display_name, ++ SETUP_COLUMN, app_info, ++ -1); ++ g_free (display_name); ++ if (app_info) ++ g_object_unref (app_info); ++ } ++ } ++ ++ g_free (type); ++ g_free (id); ++ ++ ret = gtk_tree_model_iter_next (model, &iter); ++ } ++ ++ input_chooser_repopulate (GTK_LIST_STORE (model)); ++} ++ ++static void ++fetch_ibus_engines_result (GObject *object, ++ GAsyncResult *result, ++ GtkBuilder *builder) ++{ ++ gboolean show_all_sources; ++ GList *list, *l; ++ GError *error; ++ ++ error = NULL; ++ list = ibus_bus_list_engines_async_finish (ibus, result, &error); ++ ++ g_clear_object (&ibus_cancellable); ++ ++ if (!list && error) ++ { ++ g_warning ("Couldn't finish IBus request: %s", error->message); ++ g_error_free (error); ++ return; ++ } ++ ++ show_all_sources = g_settings_get_boolean (input_sources_settings, "show-all-sources"); ++ ++ /* Maps engine ids to engine description objects */ ++ ibus_engines = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, g_object_unref); ++ ++ for (l = list; l; l = l->next) ++ { ++ IBusEngineDesc *engine = l->data; ++ const gchar *engine_id = ibus_engine_desc_get_name (engine); ++ ++ if (show_all_sources || strv_contains (supported_ibus_engines, engine_id)) ++ g_hash_table_replace (ibus_engines, (gpointer)engine_id, engine); ++ else ++ g_object_unref (engine); ++ } ++ g_list_free (list); ++ ++ update_ibus_active_sources (builder); ++} ++ ++static void ++fetch_ibus_engines (GtkBuilder *builder) ++{ ++ ibus_cancellable = g_cancellable_new (); ++ ++ ibus_bus_list_engines_async (ibus, ++ -1, ++ ibus_cancellable, ++ (GAsyncReadyCallback)fetch_ibus_engines_result, ++ builder); ++ ++ /* We've got everything we needed, don't want to be called again. */ ++ g_signal_handlers_disconnect_by_func (ibus, fetch_ibus_engines, builder); ++} ++ ++static void ++maybe_start_ibus (void) ++{ ++ /* IBus doesn't export API in the session bus. The only thing ++ * we have there is a well known name which we can use as a ++ * sure-fire way to activate it. */ ++ g_bus_unwatch_name (g_bus_watch_name (G_BUS_TYPE_SESSION, ++ IBUS_SERVICE_IBUS, ++ G_BUS_NAME_WATCHER_FLAGS_AUTO_START, ++ NULL, ++ NULL, ++ NULL, ++ NULL)); ++} ++ ++static void ++on_shell_appeared (GDBusConnection *connection, ++ const gchar *name, ++ const gchar *name_owner, ++ gpointer data) ++{ ++ GtkBuilder *builder = data; ++ ++ if (!ibus) ++ { ++ ibus = ibus_bus_new (); ++ if (ibus_bus_is_connected (ibus)) ++ fetch_ibus_engines (builder); ++ else ++ g_signal_connect_swapped (ibus, "connected", ++ G_CALLBACK (fetch_ibus_engines), builder); ++ } ++ maybe_start_ibus (); ++} ++#endif /* HAVE_IBUS */ ++ ++static gboolean ++add_source_to_table (GtkTreeModel *model, ++ GtkTreePath *path, ++ GtkTreeIter *iter, ++ gpointer data) ++{ ++ GHashTable *hash = data; ++ gchar *type; ++ gchar *id; ++ ++ gtk_tree_model_get (model, iter, ++ TYPE_COLUMN, &type, ++ ID_COLUMN, &id, ++ -1); ++ ++ g_hash_table_add (hash, g_strconcat (type, id, NULL)); ++ ++ g_free (type); ++ g_free (id); ++ ++ return FALSE; ++} ++ ++static void ++populate_model (GtkListStore *store, ++ GtkListStore *active_sources_store) ++{ ++ GHashTable *active_sources_table; ++ GtkTreeIter iter; ++ const gchar *name; ++ GList *sources, *tmp; ++ gchar *source_id = NULL; ++ ++ active_sources_table = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); ++ ++ gtk_tree_model_foreach (GTK_TREE_MODEL (active_sources_store), ++ add_source_to_table, ++ active_sources_table); ++ ++ sources = gnome_xkb_info_get_all_layouts (xkb_info); ++ ++ for (tmp = sources; tmp; tmp = tmp->next) ++ { ++ g_free (source_id); ++ source_id = g_strconcat (INPUT_SOURCE_TYPE_XKB, tmp->data, NULL); ++ ++ if (g_hash_table_contains (active_sources_table, source_id)) ++ continue; ++ ++ gnome_xkb_info_get_layout_info (xkb_info, (const gchar *)tmp->data, ++ &name, NULL, NULL, NULL); ++ ++ gtk_list_store_append (store, &iter); ++ gtk_list_store_set (store, &iter, ++ NAME_COLUMN, name, ++ TYPE_COLUMN, INPUT_SOURCE_TYPE_XKB, ++ ID_COLUMN, tmp->data, ++ -1); ++ } ++ g_free (source_id); ++ ++ g_list_free (sources); ++ ++#ifdef HAVE_IBUS ++ if (ibus_engines) ++ { ++ gchar *display_name; ++ ++ sources = g_hash_table_get_keys (ibus_engines); ++ ++ source_id = NULL; ++ for (tmp = sources; tmp; tmp = tmp->next) ++ { ++ g_free (source_id); ++ source_id = g_strconcat (INPUT_SOURCE_TYPE_IBUS, tmp->data, NULL); ++ ++ if (g_hash_table_contains (active_sources_table, source_id)) ++ continue; ++ ++ display_name = engine_get_display_name (g_hash_table_lookup (ibus_engines, tmp->data)); ++ ++ gtk_list_store_append (store, &iter); ++ gtk_list_store_set (store, &iter, ++ NAME_COLUMN, display_name, ++ TYPE_COLUMN, INPUT_SOURCE_TYPE_IBUS, ++ ID_COLUMN, tmp->data, ++ -1); ++ g_free (display_name); ++ } ++ g_free (source_id); ++ ++ g_list_free (sources); ++ } ++#endif ++ ++ g_hash_table_destroy (active_sources_table); ++} ++ ++static void ++populate_with_active_sources (GtkListStore *store) ++{ ++ GVariant *sources; ++ GVariantIter iter; ++ const gchar *name; ++ const gchar *type; ++ const gchar *id; ++ gchar *display_name; ++ GDesktopAppInfo *app_info; ++ GtkTreeIter tree_iter; ++ ++ sources = g_settings_get_value (input_sources_settings, KEY_INPUT_SOURCES); ++ ++ g_variant_iter_init (&iter, sources); ++ while (g_variant_iter_next (&iter, "(&s&s)", &type, &id)) ++ { ++ display_name = NULL; ++ app_info = NULL; ++ ++ if (g_str_equal (type, INPUT_SOURCE_TYPE_XKB)) ++ { ++ gnome_xkb_info_get_layout_info (xkb_info, id, &name, NULL, NULL, NULL); ++ if (!name) ++ { ++ g_warning ("Couldn't find XKB input source '%s'", id); ++ continue; ++ } ++ display_name = g_strdup (name); ++ } ++ else if (g_str_equal (type, INPUT_SOURCE_TYPE_IBUS)) ++ { ++#ifdef HAVE_IBUS ++ IBusEngineDesc *engine_desc = NULL; ++ ++ if (ibus_engines) ++ engine_desc = g_hash_table_lookup (ibus_engines, id); ++ ++ if (engine_desc) ++ { ++ display_name = engine_get_display_name (engine_desc); ++ app_info = setup_app_info_for_id (id); ++ } ++#else ++ g_warning ("IBus input source type specified but IBus support was not compiled"); ++ continue; ++#endif ++ } ++ else ++ { ++ g_warning ("Unknown input source type '%s'", type); ++ continue; ++ } ++ ++ gtk_list_store_append (store, &tree_iter); ++ gtk_list_store_set (store, &tree_iter, ++ NAME_COLUMN, display_name, ++ TYPE_COLUMN, type, ++ ID_COLUMN, id, ++ SETUP_COLUMN, app_info, ++ -1); ++ g_free (display_name); ++ if (app_info) ++ g_object_unref (app_info); ++ } ++ ++ g_variant_unref (sources); ++} ++ ++static void ++update_configuration (GtkTreeModel *model) ++{ ++ GtkTreeIter iter; ++ gchar *type; ++ gchar *id; ++ GVariantBuilder builder; ++ GVariant *old_sources; ++ const gchar *old_current_type; ++ const gchar *old_current_id; ++ guint old_current_index; ++ guint old_n_sources; ++ guint index; ++ ++ old_sources = g_settings_get_value (input_sources_settings, KEY_INPUT_SOURCES); ++ old_current_index = g_settings_get_uint (input_sources_settings, KEY_CURRENT_INPUT_SOURCE); ++ old_n_sources = g_variant_n_children (old_sources); ++ ++ if (old_n_sources > 0 && old_current_index < old_n_sources) ++ { ++ g_variant_get_child (old_sources, ++ old_current_index, ++ "(&s&s)", ++ &old_current_type, ++ &old_current_id); ++ } ++ else ++ { ++ old_current_type = ""; ++ old_current_id = ""; ++ } ++ ++ g_variant_builder_init (&builder, G_VARIANT_TYPE ("a(ss)")); ++ index = 0; ++ gtk_tree_model_get_iter_first (model, &iter); ++ do ++ { ++ gtk_tree_model_get (model, &iter, ++ TYPE_COLUMN, &type, ++ ID_COLUMN, &id, ++ -1); ++ if (index != old_current_index && ++ g_str_equal (type, old_current_type) && ++ g_str_equal (id, old_current_id)) ++ { ++ g_settings_set_uint (input_sources_settings, KEY_CURRENT_INPUT_SOURCE, index); ++ } ++ g_variant_builder_add (&builder, "(ss)", type, id); ++ g_free (type); ++ g_free (id); ++ index += 1; ++ } ++ while (gtk_tree_model_iter_next (model, &iter)); ++ ++ g_settings_set_value (input_sources_settings, KEY_INPUT_SOURCES, g_variant_builder_end (&builder)); ++ g_settings_apply (input_sources_settings); ++ ++ g_variant_unref (old_sources); ++} ++ ++static gboolean ++get_selected_iter (GtkBuilder *builder, ++ GtkTreeModel **model, ++ GtkTreeIter *iter) ++{ ++ GtkTreeSelection *selection; ++ ++ selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (WID ("active_input_sources"))); ++ ++ return gtk_tree_selection_get_selected (selection, model, iter); ++} ++ ++static gint ++idx_from_model_iter (GtkTreeModel *model, ++ GtkTreeIter *iter) ++{ ++ GtkTreePath *path; ++ gint idx; ++ ++ path = gtk_tree_model_get_path (model, iter); ++ if (path == NULL) ++ return -1; ++ ++ idx = gtk_tree_path_get_indices (path)[0]; ++ gtk_tree_path_free (path); ++ ++ return idx; ++} ++ ++static void ++update_button_sensitivity (GtkBuilder *builder) ++{ ++ GtkWidget *remove_button; ++ GtkWidget *up_button; ++ GtkWidget *down_button; ++ GtkWidget *show_button; ++ GtkWidget *settings_button; ++ GtkTreeView *tv; ++ GtkTreeModel *model; ++ GtkTreeIter iter; ++ gint n_active; ++ gint index; ++ gboolean settings_sensitive; ++ GDesktopAppInfo *app_info; ++ ++ remove_button = WID("input_source_remove"); ++ show_button = WID("input_source_show"); ++ up_button = WID("input_source_move_up"); ++ down_button = WID("input_source_move_down"); ++ settings_button = WID("input_source_settings"); ++ ++ tv = GTK_TREE_VIEW (WID ("active_input_sources")); ++ n_active = gtk_tree_model_iter_n_children (gtk_tree_view_get_model (tv), NULL); ++ ++ if (get_selected_iter (builder, &model, &iter)) ++ { ++ index = idx_from_model_iter (model, &iter); ++ gtk_tree_model_get (model, &iter, SETUP_COLUMN, &app_info, -1); ++ } ++ else ++ { ++ index = -1; ++ app_info = NULL; ++ } ++ ++ settings_sensitive = (index >= 0 && app_info != NULL); ++ ++ if (app_info) ++ g_object_unref (app_info); ++ ++ gtk_widget_set_sensitive (remove_button, index >= 0 && n_active > 1); ++ gtk_widget_set_sensitive (show_button, index >= 0); ++ gtk_widget_set_sensitive (up_button, index > 0); ++ gtk_widget_set_sensitive (down_button, index >= 0 && index < n_active - 1); ++ gtk_widget_set_sensitive (settings_button, settings_sensitive); ++} ++ ++static void ++set_selected_path (GtkBuilder *builder, ++ GtkTreePath *path) ++{ ++ GtkTreeSelection *selection; ++ ++ selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (WID ("active_input_sources"))); ++ ++ gtk_tree_selection_select_path (selection, path); ++} ++ ++static GtkTreeModel * ++tree_view_get_actual_model (GtkTreeView *tv) ++{ ++ GtkTreeModel *filtered_store; ++ ++ filtered_store = gtk_tree_view_get_model (tv); ++ ++ return gtk_tree_model_filter_get_model (GTK_TREE_MODEL_FILTER (filtered_store)); ++} ++ ++static void ++chooser_response (GtkWidget *chooser, gint response_id, gpointer data) ++{ ++ GtkBuilder *builder = data; ++ ++ if (response_id == GTK_RESPONSE_OK) ++ { ++ GtkTreeModel *model; ++ GtkTreeIter iter; ++ ++ if (input_chooser_get_selected (chooser, &model, &iter)) ++ { ++ GtkTreeView *tv; ++ GtkListStore *child_model; ++ GtkTreeIter child_iter, filter_iter; ++ gchar *name; ++ gchar *type; ++ gchar *id; ++ GDesktopAppInfo *app_info = NULL; ++ ++ gtk_tree_model_get (model, &iter, ++ NAME_COLUMN, &name, ++ TYPE_COLUMN, &type, ++ ID_COLUMN, &id, ++ -1); ++ ++#ifdef HAVE_IBUS ++ if (g_str_equal (type, INPUT_SOURCE_TYPE_IBUS)) ++ app_info = setup_app_info_for_id (id); ++#endif ++ ++ tv = GTK_TREE_VIEW (WID ("active_input_sources")); ++ child_model = GTK_LIST_STORE (tree_view_get_actual_model (tv)); ++ ++ gtk_list_store_append (child_model, &child_iter); ++ ++ gtk_list_store_set (child_model, &child_iter, ++ NAME_COLUMN, name, ++ TYPE_COLUMN, type, ++ ID_COLUMN, id, ++ SETUP_COLUMN, app_info, ++ -1); ++ g_free (name); ++ g_free (type); ++ g_free (id); ++ if (app_info) ++ g_object_unref (app_info); ++ ++ gtk_tree_model_filter_convert_child_iter_to_iter (GTK_TREE_MODEL_FILTER (gtk_tree_view_get_model (tv)), ++ &filter_iter, ++ &child_iter); ++ gtk_tree_selection_select_iter (gtk_tree_view_get_selection (tv), &filter_iter); ++ ++ update_button_sensitivity (builder); ++ update_configuration (GTK_TREE_MODEL (child_model)); ++ } ++ else ++ { ++ g_debug ("nothing selected, nothing added"); ++ } ++ } ++ ++ gtk_widget_destroy (GTK_WIDGET (chooser)); ++} ++ ++static void ++add_input (GtkButton *button, gpointer data) ++{ ++ GtkBuilder *builder = data; ++ GtkWidget *chooser; ++ GtkWidget *toplevel; ++ GtkWidget *treeview; ++ GtkListStore *active_sources; ++ ++ g_debug ("add an input source"); ++ ++ toplevel = gtk_widget_get_toplevel (WID ("region_notebook")); ++ treeview = WID ("active_input_sources"); ++ active_sources = GTK_LIST_STORE (tree_view_get_actual_model (GTK_TREE_VIEW (treeview))); ++ ++ chooser = input_chooser_new (GTK_WINDOW (toplevel), active_sources); ++ g_signal_connect (chooser, "response", ++ G_CALLBACK (chooser_response), builder); ++} ++ ++static void ++remove_selected_input (GtkButton *button, gpointer data) ++{ ++ GtkBuilder *builder = data; ++ GtkTreeModel *model; ++ GtkTreeModel *child_model; ++ GtkTreeIter iter; ++ GtkTreeIter child_iter; ++ GtkTreePath *path; ++ ++ g_debug ("remove selected input source"); ++ ++ if (get_selected_iter (builder, &model, &iter) == FALSE) ++ return; ++ ++ path = gtk_tree_model_get_path (model, &iter); ++ ++ child_model = gtk_tree_model_filter_get_model (GTK_TREE_MODEL_FILTER (model)); ++ gtk_tree_model_filter_convert_iter_to_child_iter (GTK_TREE_MODEL_FILTER (model), ++ &child_iter, ++ &iter); ++ gtk_list_store_remove (GTK_LIST_STORE (child_model), &child_iter); ++ ++ if (!gtk_tree_model_get_iter (model, &iter, path)) ++ gtk_tree_path_prev (path); ++ ++ set_selected_path (builder, path); ++ ++ gtk_tree_path_free (path); ++ ++ update_button_sensitivity (builder); ++ update_configuration (child_model); ++} ++ ++static void ++move_selected_input_up (GtkButton *button, gpointer data) ++{ ++ GtkBuilder *builder = data; ++ GtkTreeModel *model; ++ GtkTreeModel *child_model; ++ GtkTreeIter iter, prev; ++ GtkTreeIter child_iter, child_prev; ++ GtkTreePath *path; ++ ++ g_debug ("move selected input source up"); ++ ++ if (!get_selected_iter (builder, &model, &iter)) ++ return; ++ ++ prev = iter; ++ if (!gtk_tree_model_iter_previous (model, &prev)) ++ return; ++ ++ path = gtk_tree_model_get_path (model, &prev); ++ ++ child_model = gtk_tree_model_filter_get_model (GTK_TREE_MODEL_FILTER (model)); ++ gtk_tree_model_filter_convert_iter_to_child_iter (GTK_TREE_MODEL_FILTER (model), ++ &child_iter, ++ &iter); ++ gtk_tree_model_filter_convert_iter_to_child_iter (GTK_TREE_MODEL_FILTER (model), ++ &child_prev, ++ &prev); ++ gtk_list_store_swap (GTK_LIST_STORE (child_model), &child_iter, &child_prev); ++ ++ set_selected_path (builder, path); ++ gtk_tree_path_free (path); ++ ++ update_button_sensitivity (builder); ++ update_configuration (child_model); ++} ++ ++static void ++move_selected_input_down (GtkButton *button, gpointer data) ++{ ++ GtkBuilder *builder = data; ++ GtkTreeModel *model; ++ GtkTreeModel *child_model; ++ GtkTreeIter iter, next; ++ GtkTreeIter child_iter, child_next; ++ GtkTreePath *path; ++ ++ g_debug ("move selected input source down"); ++ ++ if (!get_selected_iter (builder, &model, &iter)) ++ return; ++ ++ next = iter; ++ if (!gtk_tree_model_iter_next (model, &next)) ++ return; ++ ++ path = gtk_tree_model_get_path (model, &next); ++ ++ child_model = gtk_tree_model_filter_get_model (GTK_TREE_MODEL_FILTER (model)); ++ gtk_tree_model_filter_convert_iter_to_child_iter (GTK_TREE_MODEL_FILTER (model), ++ &child_iter, ++ &iter); ++ gtk_tree_model_filter_convert_iter_to_child_iter (GTK_TREE_MODEL_FILTER (model), ++ &child_next, ++ &next); ++ gtk_list_store_swap (GTK_LIST_STORE (child_model), &child_iter, &child_next); ++ ++ set_selected_path (builder, path); ++ gtk_tree_path_free (path); ++ ++ update_button_sensitivity (builder); ++ update_configuration (child_model); ++} ++ ++static void ++show_selected_layout (GtkButton *button, gpointer data) ++{ ++ GtkBuilder *builder = data; ++ GtkTreeModel *model; ++ GtkTreeIter iter; ++ gchar *type; ++ gchar *id; ++ gchar *kbd_viewer_args; ++ const gchar *xkb_layout; ++ const gchar *xkb_variant; ++ ++ g_debug ("show selected layout"); ++ ++ if (!get_selected_iter (builder, &model, &iter)) ++ return; ++ ++ gtk_tree_model_get (model, &iter, ++ TYPE_COLUMN, &type, ++ ID_COLUMN, &id, ++ -1); ++ ++ if (g_str_equal (type, INPUT_SOURCE_TYPE_XKB)) ++ { ++ gnome_xkb_info_get_layout_info (xkb_info, id, NULL, NULL, &xkb_layout, &xkb_variant); ++ ++ if (!xkb_layout || !xkb_layout[0]) ++ { ++ g_warning ("Couldn't find XKB input source '%s'", id); ++ goto exit; ++ } ++ } ++ else if (g_str_equal (type, INPUT_SOURCE_TYPE_IBUS)) ++ { ++#ifdef HAVE_IBUS ++ IBusEngineDesc *engine_desc = NULL; ++ ++ if (ibus_engines) ++ engine_desc = g_hash_table_lookup (ibus_engines, id); ++ ++ if (engine_desc) ++ { ++ xkb_layout = ibus_engine_desc_get_layout (engine_desc); ++ xkb_variant = ""; ++ } ++ else ++ { ++ g_warning ("Couldn't find IBus input source '%s'", id); ++ goto exit; ++ } ++#else ++ g_warning ("IBus input source type specified but IBus support was not compiled"); ++ goto exit; ++#endif ++ } ++ else ++ { ++ g_warning ("Unknown input source type '%s'", type); ++ goto exit; ++ } ++ ++ if (xkb_variant[0]) ++ kbd_viewer_args = g_strdup_printf ("gkbd-keyboard-display -l \"%s\t%s\"", ++ xkb_layout, xkb_variant); ++ else ++ kbd_viewer_args = g_strdup_printf ("gkbd-keyboard-display -l %s", ++ xkb_layout); ++ ++ g_spawn_command_line_async (kbd_viewer_args, NULL); ++ ++ g_free (kbd_viewer_args); ++ exit: ++ g_free (type); ++ g_free (id); ++} ++ ++static void ++show_selected_settings (GtkButton *button, gpointer data) ++{ ++ GtkBuilder *builder = data; ++ GtkTreeModel *model; ++ GtkTreeIter iter; ++ GdkAppLaunchContext *ctx; ++ GDesktopAppInfo *app_info; ++ gchar *id; ++ GError *error = NULL; ++ ++ g_debug ("show selected layout"); ++ ++ if (!get_selected_iter (builder, &model, &iter)) ++ return; ++ ++ gtk_tree_model_get (model, &iter, SETUP_COLUMN, &app_info, -1); ++ ++ if (!app_info) ++ return; ++ ++ ctx = gdk_display_get_app_launch_context (gdk_display_get_default ()); ++ gdk_app_launch_context_set_timestamp (ctx, gtk_get_current_event_time ()); ++ ++ gtk_tree_model_get (model, &iter, ID_COLUMN, &id, -1); ++ g_app_launch_context_setenv (G_APP_LAUNCH_CONTEXT (ctx), ++ "IBUS_ENGINE_NAME", ++ id); ++ g_free (id); ++ ++ if (!g_app_info_launch (G_APP_INFO (app_info), NULL, G_APP_LAUNCH_CONTEXT (ctx), &error)) ++ { ++ g_warning ("Failed to launch input source setup: %s", error->message); ++ g_error_free (error); ++ } ++ ++ g_object_unref (ctx); ++ g_object_unref (app_info); ++} ++ ++static gboolean ++go_to_shortcuts (GtkLinkButton *button, ++ CcRegionPanel *panel) ++{ ++ gchar *argv[3]; ++ argv[0] = "cinnamon-settings"; ++ argv[1] = "keyboard"; ++ argv[3] = NULL; ++ g_spawn_async(NULL, argv, NULL, G_SPAWN_SEARCH_PATH, NULL, NULL, NULL, NULL); ++ return TRUE; ++} ++ ++static void ++input_sources_changed (GSettings *settings, ++ gchar *key, ++ GtkBuilder *builder) ++{ ++ GtkWidget *treeview; ++ GtkTreeModel *store; ++ GtkTreePath *path; ++ GtkTreeIter iter; ++ GtkTreeModel *model; ++ ++ treeview = WID("active_input_sources"); ++ store = tree_view_get_actual_model (GTK_TREE_VIEW (treeview)); ++ ++ if (get_selected_iter (builder, &model, &iter)) ++ path = gtk_tree_model_get_path (model, &iter); ++ else ++ path = NULL; ++ ++ gtk_list_store_clear (GTK_LIST_STORE (store)); ++ populate_with_active_sources (GTK_LIST_STORE (store)); ++ ++ if (path) ++ { ++ set_selected_path (builder, path); ++ gtk_tree_path_free (path); ++ } ++} ++ ++static void ++update_shortcut_label (GtkWidget *widget, ++ const char *value) ++{ ++ char *text; ++ guint accel_key, *keycode; ++ GdkModifierType mods; ++ ++ if (value == NULL || *value == '\0') ++ { ++ gtk_label_set_text (GTK_LABEL (widget), "\342\200\224"); ++ return; ++ } ++ gtk_accelerator_parse_with_keycode (value, &accel_key, &keycode, &mods); ++ if (accel_key == 0 && keycode == NULL && mods == 0) ++ { ++ gtk_label_set_text (GTK_LABEL (widget), "\342\200\224"); ++ g_warning ("Failed to parse keyboard shortcut: '%s'", value); ++ return; ++ } ++ ++ text = gtk_accelerator_get_label_with_keycode (gtk_widget_get_display (widget), accel_key, *keycode, mods); ++ g_free (keycode); ++ gtk_label_set_text (GTK_LABEL (widget), text); ++ g_free (text); ++} ++ ++static void ++update_shortcuts (GtkBuilder *builder) ++{ ++ char *previous, *next; ++ GSettings *settings; ++ ++ settings = g_settings_new ("org.cinnamon.settings-daemon.plugins.media-keys"); ++ ++ previous = g_settings_get_string (settings, "switch-input-source-backward"); ++ next = g_settings_get_string (settings, "switch-input-source"); ++ ++ update_shortcut_label (WID ("prev-source-shortcut-label"), previous); ++ update_shortcut_label (WID ("next-source-shortcut-label"), next); ++ ++ g_free (previous); ++ g_free (next); ++} ++ ++static gboolean ++active_sources_visible_func (GtkTreeModel *model, ++ GtkTreeIter *iter, ++ gpointer data) ++{ ++ gchar *display_name; ++ ++ gtk_tree_model_get (model, iter, NAME_COLUMN, &display_name, -1); ++ ++ if (!display_name) ++ return FALSE; ++ ++ g_free (display_name); ++ ++ return TRUE; ++} ++ ++void ++setup_input_tabs (GtkBuilder *builder, ++ CcRegionPanel *panel) ++{ ++ GtkWidget *treeview; ++ GtkTreeViewColumn *column; ++ GtkCellRenderer *cell; ++ GtkListStore *store; ++ GtkTreeModel *filtered_store; ++ GtkTreeSelection *selection; ++ ++ /* set up the list of active inputs */ ++ treeview = WID("active_input_sources"); ++ column = gtk_tree_view_column_new (); ++ cell = gtk_cell_renderer_text_new (); ++ gtk_tree_view_column_pack_start (column, cell, TRUE); ++ gtk_tree_view_column_add_attribute (column, cell, "text", NAME_COLUMN); ++ gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), column); ++ ++ store = gtk_list_store_new (N_COLUMNS, ++ G_TYPE_STRING, ++ G_TYPE_STRING, ++ G_TYPE_STRING, ++ G_TYPE_DESKTOP_APP_INFO); ++ ++ gtk_tree_view_set_model (GTK_TREE_VIEW (treeview), GTK_TREE_MODEL (store)); ++ ++ input_sources_settings = g_settings_new (GNOME_DESKTOP_INPUT_SOURCES_DIR); ++ g_settings_delay (input_sources_settings); ++ g_object_weak_ref (G_OBJECT (builder), (GWeakNotify) g_object_unref, input_sources_settings); ++ ++ if (!xkb_info) ++ xkb_info = gnome_xkb_info_new (); ++ ++#ifdef HAVE_IBUS ++ ibus_init (); ++ shell_name_watch_id = g_bus_watch_name (G_BUS_TYPE_SESSION, ++ "org.Cinnamon", ++ G_BUS_NAME_WATCHER_FLAGS_NONE, ++ on_shell_appeared, ++ NULL, ++ builder, ++ NULL); ++ g_object_weak_ref (G_OBJECT (builder), (GWeakNotify) clear_ibus, NULL); ++#endif ++ ++ populate_with_active_sources (store); ++ ++ selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview)); ++ g_signal_connect_swapped (selection, "changed", ++ G_CALLBACK (update_button_sensitivity), builder); ++ ++ /* Some input source types might have their info loaded ++ * asynchronously. In that case we don't want to show them ++ * immediately so we use a filter model on top of the real model ++ * which mirrors the GSettings key. */ ++ filtered_store = gtk_tree_model_filter_new (GTK_TREE_MODEL (store), NULL); ++ gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER (filtered_store), ++ active_sources_visible_func, ++ NULL, ++ NULL); ++ gtk_tree_view_set_model (GTK_TREE_VIEW (treeview), filtered_store); ++ ++ /* set up the buttons */ ++ g_signal_connect (WID("input_source_add"), "clicked", ++ G_CALLBACK (add_input), builder); ++ g_signal_connect (WID("input_source_remove"), "clicked", ++ G_CALLBACK (remove_selected_input), builder); ++ g_signal_connect (WID("input_source_move_up"), "clicked", ++ G_CALLBACK (move_selected_input_up), builder); ++ g_signal_connect (WID("input_source_move_down"), "clicked", ++ G_CALLBACK (move_selected_input_down), builder); ++ g_signal_connect (WID("input_source_show"), "clicked", ++ G_CALLBACK (show_selected_layout), builder); ++ g_signal_connect (WID("input_source_settings"), "clicked", ++ G_CALLBACK (show_selected_settings), builder); ++ ++ /* use an em dash is no shortcut */ ++ update_shortcuts (builder); ++ ++ g_signal_connect (WID("jump-to-shortcuts"), "activate-link", ++ G_CALLBACK (go_to_shortcuts), panel); ++ ++ g_signal_connect (G_OBJECT (input_sources_settings), ++ "changed::" KEY_INPUT_SOURCES, ++ G_CALLBACK (input_sources_changed), ++ builder); ++} ++ ++static void ++filter_clear (GtkEntry *entry, ++ GtkEntryIconPosition icon_pos, ++ GdkEvent *event, ++ gpointer user_data) ++{ ++ gtk_entry_set_text (entry, ""); ++} ++ ++static gchar **search_pattern_list; ++ ++static void ++filter_changed (GtkBuilder *builder) ++{ ++ GtkTreeModelFilter *filtered_model; ++ GtkTreeView *tree_view; ++ GtkTreeSelection *selection; ++ GtkTreeIter selected_iter; ++ GtkWidget *filter_entry; ++ const gchar *pattern; ++ gchar *upattern; ++ ++ filter_entry = WID ("input_source_filter"); ++ pattern = gtk_entry_get_text (GTK_ENTRY (filter_entry)); ++ upattern = g_utf8_strup (pattern, -1); ++ if (!g_strcmp0 (pattern, "")) ++ g_object_set (G_OBJECT (filter_entry), ++ "secondary-icon-name", "edit-find-symbolic", ++ "secondary-icon-activatable", FALSE, ++ "secondary-icon-sensitive", FALSE, ++ NULL); ++ else ++ g_object_set (G_OBJECT (filter_entry), ++ "secondary-icon-name", "edit-clear-symbolic", ++ "secondary-icon-activatable", TRUE, ++ "secondary-icon-sensitive", TRUE, ++ NULL); ++ ++ if (search_pattern_list != NULL) ++ g_strfreev (search_pattern_list); ++ ++ search_pattern_list = g_strsplit (upattern, " ", -1); ++ g_free (upattern); ++ ++ filtered_model = GTK_TREE_MODEL_FILTER (gtk_builder_get_object (builder, "filtered_input_source_model")); ++ gtk_tree_model_filter_refilter (filtered_model); ++ ++ tree_view = GTK_TREE_VIEW (WID ("filtered_input_source_list")); ++ selection = gtk_tree_view_get_selection (tree_view); ++ if (gtk_tree_selection_get_selected (selection, NULL, &selected_iter)) ++ { ++ GtkTreePath *path = gtk_tree_model_get_path (GTK_TREE_MODEL (filtered_model), ++ &selected_iter); ++ gtk_tree_view_scroll_to_cell (tree_view, path, NULL, TRUE, 0.5, 0.5); ++ gtk_tree_path_free (path); ++ } ++ else ++ { ++ GtkTreeIter iter; ++ if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (filtered_model), &iter)) ++ gtk_tree_selection_select_iter (selection, &iter); ++ } ++} ++ ++static void ++selection_changed (GtkTreeSelection *selection, ++ GtkBuilder *builder) ++{ ++ gtk_widget_set_sensitive (WID ("ok-button"), ++ gtk_tree_selection_get_selected (selection, NULL, NULL)); ++} ++ ++static void ++row_activated (GtkTreeView *tree_view, ++ GtkTreePath *path, ++ GtkTreeViewColumn *column, ++ GtkBuilder *builder) ++{ ++ GtkWidget *add_button; ++ GtkWidget *dialog; ++ ++ add_button = WID ("ok-button"); ++ dialog = WID ("input_source_chooser"); ++ if (gtk_widget_is_sensitive (add_button)) ++ gtk_dialog_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK); ++} ++ ++static void ++entry_activated (GtkBuilder *builder, ++ gpointer data) ++{ ++ row_activated (NULL, NULL, NULL, builder); ++} ++ ++static gboolean ++filter_func (GtkTreeModel *model, ++ GtkTreeIter *iter, ++ gpointer data) ++{ ++ gchar *name = NULL; ++ gchar **pattern; ++ gboolean rv = TRUE; ++ ++ if (search_pattern_list == NULL || search_pattern_list[0] == NULL) ++ return TRUE; ++ ++ gtk_tree_model_get (model, iter, ++ NAME_COLUMN, &name, ++ -1); ++ ++ pattern = search_pattern_list; ++ do { ++ gboolean is_pattern_found = FALSE; ++ gchar *udesc = g_utf8_strup (name, -1); ++ if (udesc != NULL && g_strstr_len (udesc, -1, *pattern)) ++ { ++ is_pattern_found = TRUE; ++ } ++ g_free (udesc); ++ ++ if (!is_pattern_found) ++ { ++ rv = FALSE; ++ break; ++ } ++ ++ } while (*++pattern != NULL); ++ ++ g_free (name); ++ ++ return rv; ++} ++ ++static GtkWidget * ++input_chooser_new (GtkWindow *main_window, ++ GtkListStore *active_sources) ++{ ++ GtkBuilder *builder; ++ GtkWidget *chooser; ++ GtkWidget *filtered_list; ++ GtkWidget *filter_entry; ++ GtkTreeViewColumn *visible_column; ++ GtkTreeSelection *selection; ++ GtkListStore *model; ++ GtkTreeModelFilter *filtered_model; ++ GtkTreeIter iter; ++ ++ builder = gtk_builder_new (); ++ gtk_builder_set_translation_domain (builder, GETTEXT_PACKAGE); ++ gtk_builder_add_from_file (builder, ++ CINNAMONCC_UI_DIR "/cinnamon-region-panel-input-chooser.ui", ++ NULL); ++ chooser = WID ("input_source_chooser"); ++ input_chooser = chooser; ++ g_object_add_weak_pointer (G_OBJECT (chooser), (gpointer *) &input_chooser); ++ g_object_set_data_full (G_OBJECT (chooser), "builder", builder, g_object_unref); ++ ++ filtered_list = WID ("filtered_input_source_list"); ++ filter_entry = WID ("input_source_filter"); ++ ++ g_object_set_data (G_OBJECT (chooser), ++ "filtered_input_source_list", filtered_list); ++ visible_column = ++ gtk_tree_view_column_new_with_attributes ("Input Sources", ++ gtk_cell_renderer_text_new (), ++ "text", NAME_COLUMN, ++ NULL); ++ ++ gtk_window_set_transient_for (GTK_WINDOW (chooser), main_window); ++ ++ gtk_tree_view_append_column (GTK_TREE_VIEW (filtered_list), ++ visible_column); ++ /* We handle searching ourselves, thank you. */ ++ gtk_tree_view_set_enable_search (GTK_TREE_VIEW (filtered_list), FALSE); ++ gtk_tree_view_set_search_column (GTK_TREE_VIEW (filtered_list), -1); ++ ++ g_signal_connect_swapped (G_OBJECT (filter_entry), "activate", ++ G_CALLBACK (entry_activated), builder); ++ g_signal_connect_swapped (G_OBJECT (filter_entry), "notify::text", ++ G_CALLBACK (filter_changed), builder); ++ ++ g_signal_connect (G_OBJECT (filter_entry), "icon-release", ++ G_CALLBACK (filter_clear), NULL); ++ ++ filtered_model = GTK_TREE_MODEL_FILTER (gtk_builder_get_object (builder, "filtered_input_source_model")); ++ model = GTK_LIST_STORE (gtk_builder_get_object (builder, "input_source_model")); ++ ++ populate_model (model, active_sources); ++ ++ gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (model), ++ NAME_COLUMN, GTK_SORT_ASCENDING); ++ ++ gtk_tree_model_filter_set_visible_func (filtered_model, ++ filter_func, ++ NULL, NULL); ++ ++ selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (filtered_list)); ++ ++ g_signal_connect (G_OBJECT (selection), "changed", ++ G_CALLBACK (selection_changed), builder); ++ ++ if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (filtered_model), &iter)) ++ gtk_tree_selection_select_iter (selection, &iter); ++ ++ g_signal_connect (G_OBJECT (filtered_list), "row-activated", ++ G_CALLBACK (row_activated), builder); ++ ++ gtk_widget_grab_focus (filter_entry); ++ ++ gtk_widget_show (chooser); ++ ++ return chooser; ++} ++ ++static gboolean ++input_chooser_get_selected (GtkWidget *dialog, ++ GtkTreeModel **model, ++ GtkTreeIter *iter) ++{ ++ GtkWidget *tv; ++ GtkTreeSelection *selection; ++ ++ tv = g_object_get_data (G_OBJECT (dialog), "filtered_input_source_list"); ++ selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (tv)); ++ ++ return gtk_tree_selection_get_selected (selection, model, iter); ++} +diff -uNrp a/panels/region/cinnamon-region-panel-input-chooser.ui b/panels/region/cinnamon-region-panel-input-chooser.ui +--- a/panels/region/cinnamon-region-panel-input-chooser.ui 1970-01-01 01:00:00.000000000 +0100 ++++ b/panels/region/cinnamon-region-panel-input-chooser.ui 2013-09-21 13:24:15.339949536 +0100 +@@ -0,0 +1,157 @@ ++<?xml version="1.0" encoding="UTF-8"?> ++<interface> ++ <requires lib="gtk+" version="2.16"/> ++ <object class="GtkListStore" id="input_source_model"> ++ <columns> ++ <!-- display name --> ++ <column type="gchararray"/> ++ <!-- input source type --> ++ <column type="gchararray"/> ++ <!-- type specific identifier --> ++ <column type="gchararray"/> ++ </columns> ++ </object> ++ <object class="GtkTreeModelFilter" id="filtered_input_source_model"> ++ <property name="child_model">input_source_model</property> ++ </object> ++ <object class="GtkDialog" id="input_source_chooser"> ++ <property name="visible">False</property> ++ <property name="can_focus">False</property> ++ <property name="border_width">5</property> ++ <property name="title" translatable="yes">Choose an input source</property> ++ <property name="modal">True</property> ++ <property name="window_position">center-on-parent</property> ++ <property name="type_hint">dialog</property> ++ <child internal-child="vbox"> ++ <object class="GtkBox" id="dialog-vbox3"> ++ <property name="visible">True</property> ++ <property name="can_focus">False</property> ++ <property name="orientation">vertical</property> ++ <property name="spacing">2</property> ++ <child internal-child="action_area"> ++ <object class="GtkButtonBox" id="hbtnBox"> ++ <property name="visible">True</property> ++ <property name="can_focus">False</property> ++ <property name="layout_style">end</property> ++ <child> ++ <object class="GtkButton" id="cancel-button"> ++ <property name="label">gtk-cancel</property> ++ <property name="visible">True</property> ++ <property name="can_focus">True</property> ++ <property name="can_default">True</property> ++ <property name="receives_default">False</property> ++ <property name="use_action_appearance">False</property> ++ <property name="use_stock">True</property> ++ </object> ++ <packing> ++ <property name="expand">False</property> ++ <property name="fill">False</property> ++ <property name="pack_type">end</property> ++ <property name="position">1</property> ++ </packing> ++ </child> ++ <child> ++ <object class="GtkButton" id="ok-button"> ++ <property name="label">gtk-add</property> ++ <property name="visible">True</property> ++ <property name="can_focus">True</property> ++ <property name="can_default">True</property> ++ <property name="receives_default">False</property> ++ <property name="use_action_appearance">False</property> ++ <property name="use_stock">True</property> ++ </object> ++ <packing> ++ <property name="expand">False</property> ++ <property name="fill">False</property> ++ <property name="pack_type">end</property> ++ <property name="position">2</property> ++ </packing> ++ </child> ++ </object> ++ </child> ++ <child> ++ <object class="GtkVBox" id="vbox40"> ++ <property name="visible">True</property> ++ <property name="can_focus">False</property> ++ <property name="border_width">5</property> ++ <property name="spacing">6</property> ++ <child> ++ <object class="GtkVBox" id="vbox1"> ++ <property name="visible">True</property> ++ <property name="can_focus">False</property> ++ <property name="spacing">6</property> ++ <child> ++ <object class="GtkLabel" id="label1"> ++ <property name="visible">True</property> ++ <property name="can_focus">False</property> ++ <property name="xalign">0</property> ++ <property name="label" translatable="yes">Select an input source to add</property> ++ </object> ++ <packing> ++ <property name="expand">False</property> ++ <property name="fill">False</property> ++ <property name="position">0</property> ++ </packing> ++ </child> ++ <child> ++ <object class="GtkScrolledWindow" id="scrolledwindow1"> ++ <property name="visible">True</property> ++ <property name="can_focus">True</property> ++ <property name="hscrollbar_policy">never</property> ++ <property name="shadow_type">etched-in</property> ++ <property name="min_content_width">450</property> ++ <property name="min_content_height">250</property> ++ <child> ++ <object class="GtkTreeView" id="filtered_input_source_list"> ++ <property name="visible">True</property> ++ <property name="can_focus">True</property> ++ <property name="model">filtered_input_source_model</property> ++ <property name="headers_visible">False</property> ++ <property name="search_column">0</property> ++ </object> ++ </child> ++ </object> ++ <packing> ++ <property name="expand">True</property> ++ <property name="fill">True</property> ++ <property name="position">1</property> ++ </packing> ++ </child> ++ </object> ++ <packing> ++ <property name="expand">True</property> ++ <property name="fill">True</property> ++ <property name="position">0</property> ++ </packing> ++ </child> ++ <child> ++ <object class="GtkEntry" id="input_source_filter"> ++ <property name="visible">True</property> ++ <property name="can_focus">True</property> ++ <property name="invisible_char">•</property> ++ <property name="secondary-icon-name">edit-find-symbolic</property> ++ <property name="secondary-icon-activatable">False</property> ++ <property name="secondary-icon-sensitive">False</property> ++ </object> ++ <packing> ++ <property name="expand">False</property> ++ <property name="fill">False</property> ++ <property name="pack_type">end</property> ++ <property name="position">1</property> ++ </packing> ++ </child> ++ </object> ++ <packing> ++ <property name="expand">True</property> ++ <property name="fill">True</property> ++ <property name="position">1</property> ++ </packing> ++ </child> ++ </object> ++ </child> ++ <action-widgets> ++ <action-widget response="-5">ok-button</action-widget> ++ <action-widget response="-6">cancel-button</action-widget> ++ </action-widgets> ++ </object> ++</interface> +diff -uNrp a/panels/region/cinnamon-region-panel-input.h b/panels/region/cinnamon-region-panel-input.h +--- a/panels/region/cinnamon-region-panel-input.h 1970-01-01 01:00:00.000000000 +0100 ++++ b/panels/region/cinnamon-region-panel-input.h 2013-09-21 13:24:15.339949536 +0100 +@@ -0,0 +1,36 @@ ++/* cinnamon-region-panel-input.h ++ * Copyright (C) 2011 Red Hat, Inc. ++ * ++ * Written by Matthias Clasen ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2, or (at your option) ++ * any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA ++ * 02110-1335, USA. ++ */ ++ ++#ifndef __CINNAMON_KEYBOARD_PROPERTY_INPUT_H ++#define __CINNAMON_KEYBOARD_PROPERTY_INPUT_H ++ ++#include <gtk/gtk.h> ++ ++#include "cc-region-panel.h" ++ ++G_BEGIN_DECLS ++ ++void setup_input_tabs (GtkBuilder *builder, ++ CcRegionPanel *self); ++ ++G_END_DECLS ++ ++#endif /* __CINNAMON_KEYBOARD_PROPERTY_INPUT_H */ +diff -uNrp a/panels/region/cinnamon-region-panel-lang.c b/panels/region/cinnamon-region-panel-lang.c +--- a/panels/region/cinnamon-region-panel-lang.c 2013-08-25 14:40:14.000000000 +0100 ++++ b/panels/region/cinnamon-region-panel-lang.c 2013-09-21 13:24:15.340949500 +0100 +@@ -24,7 +24,7 @@ + #endif + + #include <string.h> +-#include <glib/gi18n-lib.h> ++#include <glib/gi18n.h> + + #include "cinnamon-region-panel-lang.h" + #include "cinnamon-region-panel-formats.h" +diff -uNrp a/panels/region/cinnamon-region-panel-lang.h b/panels/region/cinnamon-region-panel-lang.h +--- a/panels/region/cinnamon-region-panel-lang.h 2013-08-25 14:40:14.000000000 +0100 ++++ b/panels/region/cinnamon-region-panel-lang.h 2013-09-21 13:24:15.340949500 +0100 +@@ -19,8 +19,8 @@ + * 02110-1335, USA. + */ + +-#ifndef __GNOME_KEYBOARD_PROPERTY_LANG_H +-#define __GNOME_KEYBOARD_PROPERTY_LANG_H ++#ifndef __CINNAMON_KEYBOARD_PROPERTY_LANG_H ++#define __CINNAMON_KEYBOARD_PROPERTY_LANG_H + + #include <gtk/gtk.h> + +@@ -29,4 +29,4 @@ G_BEGIN_DECLS + void setup_language (GtkBuilder *builder); + + G_END_DECLS +-#endif /* __GNOME_KEYBOARD_PROPERTY_LANG_H */ ++#endif /* __CINNAMON_KEYBOARD_PROPERTY_LANG_H */ +diff -uNrp a/panels/region/cinnamon-region-panel-layout-chooser.ui b/panels/region/cinnamon-region-panel-layout-chooser.ui +--- a/panels/region/cinnamon-region-panel-layout-chooser.ui 2013-08-25 14:40:14.000000000 +0100 ++++ b/panels/region/cinnamon-region-panel-layout-chooser.ui 1970-01-01 01:00:00.000000000 +0100 +@@ -1,180 +0,0 @@ +-<?xml version="1.0" encoding="UTF-8"?> +-<interface> +- <requires lib="gtk+" version="2.16"/> +- <object class="GtkListStore" id="layout_list_model"> +- <columns> +- <!-- column-name sort_order --> +- <column type="gchararray"/> +- <!-- column-name visible --> +- <column type="gchararray"/> +- <!-- column-name xkb_id --> +- <column type="gchararray"/> +- <!-- column-name country_desc --> +- <column type="gchararray"/> +- <!-- column-name language_desc --> +- <column type="gchararray"/> +- </columns> +- </object> +- <object class="GtkTreeModelFilter" id="filtered_layout_list_model"> +- <property name="child_model">layout_list_model</property> +- </object> +- <object class="GtkDialog" id="xkb_layout_chooser"> +- <property name="visible">False</property> +- <property name="can_focus">False</property> +- <property name="border_width">5</property> +- <property name="title" translatable="yes">Choose a Layout</property> +- <property name="modal">True</property> +- <property name="window_position">center-on-parent</property> +- <property name="type_hint">dialog</property> +- <child internal-child="vbox"> +- <object class="GtkBox" id="dialog-vbox3"> +- <property name="visible">True</property> +- <property name="can_focus">False</property> +- <property name="orientation">vertical</property> +- <property name="spacing">2</property> +- <child internal-child="action_area"> +- <object class="GtkButtonBox" id="hbtnBox"> +- <property name="visible">True</property> +- <property name="can_focus">False</property> +- <property name="layout_style">end</property> +- <child> +- <object class="GtkButton" id="btnPreview"> +- <property name="label" translatable="yes">Preview</property> +- <property name="visible">True</property> +- <property name="can_focus">True</property> +- <property name="receives_default">True</property> +- <property name="use_action_appearance">False</property> +- </object> +- <packing> +- <property name="expand">False</property> +- <property name="fill">False</property> +- <property name="position">0</property> +- <property name="secondary">True</property> +- </packing> +- </child> +- <child> +- <object class="GtkButton" id="btnCancel"> +- <property name="label">gtk-cancel</property> +- <property name="visible">True</property> +- <property name="can_focus">True</property> +- <property name="can_default">True</property> +- <property name="receives_default">False</property> +- <property name="use_action_appearance">False</property> +- <property name="use_stock">True</property> +- </object> +- <packing> +- <property name="expand">False</property> +- <property name="fill">False</property> +- <property name="pack_type">end</property> +- <property name="position">1</property> +- </packing> +- </child> +- <child> +- <object class="GtkButton" id="btnOk"> +- <property name="label">gtk-add</property> +- <property name="visible">True</property> +- <property name="can_focus">True</property> +- <property name="can_default">True</property> +- <property name="receives_default">False</property> +- <property name="use_action_appearance">False</property> +- <property name="use_stock">True</property> +- </object> +- <packing> +- <property name="expand">False</property> +- <property name="fill">False</property> +- <property name="pack_type">end</property> +- <property name="position">2</property> +- </packing> +- </child> +- </object> +- </child> +- <child> +- <object class="GtkVBox" id="vbox40"> +- <property name="visible">True</property> +- <property name="can_focus">False</property> +- <property name="border_width">5</property> +- <property name="spacing">6</property> +- <child> +- <object class="GtkVBox" id="vbox1"> +- <property name="visible">True</property> +- <property name="can_focus">False</property> +- <property name="spacing">6</property> +- <child> +- <object class="GtkLabel" id="label1"> +- <property name="visible">True</property> +- <property name="can_focus">False</property> +- <property name="xalign">0</property> +- <property name="label" translatable="yes">Select an input source to add</property> +- </object> +- <packing> +- <property name="expand">False</property> +- <property name="fill">False</property> +- <property name="position">0</property> +- </packing> +- </child> +- <child> +- <object class="GtkScrolledWindow" id="scrolledwindow1"> +- <property name="visible">True</property> +- <property name="can_focus">True</property> +- <property name="hscrollbar_policy">never</property> +- <property name="shadow_type">etched-in</property> +- <property name="min_content_width">450</property> +- <property name="min_content_height">250</property> +- <child> +- <object class="GtkTreeView" id="xkb_filtered_layouts_list"> +- <property name="visible">True</property> +- <property name="can_focus">True</property> +- <property name="model">filtered_layout_list_model</property> +- <property name="headers_visible">False</property> +- <property name="search_column">0</property> +- <child internal-child="selection"> +- <object class="GtkTreeSelection" id="treeview-selection1"/> +- </child> +- </object> +- </child> +- </object> +- <packing> +- <property name="expand">True</property> +- <property name="fill">True</property> +- <property name="position">1</property> +- </packing> +- </child> +- </object> +- <packing> +- <property name="expand">True</property> +- <property name="fill">True</property> +- <property name="position">0</property> +- </packing> +- </child> +- <child> +- <object class="GtkEntry" id="xkb_layout_filter"> +- <property name="visible">True</property> +- <property name="can_focus">True</property> +- <property name="invisible_char">•</property> +- <property name="secondary-icon-name">edit-find-symbolic</property> +- <property name="secondary-icon-activatable">False</property> +- <property name="secondary-icon-sensitive">False</property> +- </object> +- <packing> +- <property name="expand">False</property> +- <property name="fill">False</property> +- <property name="pack_type">end</property> +- <property name="position">1</property> +- </packing> +- </child> +- </object> +- <packing> +- <property name="expand">True</property> +- <property name="fill">True</property> +- <property name="position">1</property> +- </packing> +- </child> +- </object> +- </child> +- <action-widgets> +- <action-widget response="1">btnPreview</action-widget> +- <action-widget response="-5">btnOk</action-widget> +- <action-widget response="-6">btnCancel</action-widget> +- </action-widgets> +- </object> +-</interface> +diff -uNrp a/panels/region/cinnamon-region-panel-options-dialog.ui b/panels/region/cinnamon-region-panel-options-dialog.ui +--- a/panels/region/cinnamon-region-panel-options-dialog.ui 2013-08-25 14:40:14.000000000 +0100 ++++ b/panels/region/cinnamon-region-panel-options-dialog.ui 1970-01-01 01:00:00.000000000 +0100 +@@ -1,79 +0,0 @@ +-<?xml version="1.0" encoding="UTF-8"?> +-<interface> +- <requires lib="gtk+" version="2.16"/> +- <object class="GtkDialog" id="xkb_options_dialog"> +- <property name="can_focus">False</property> +- <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> +- <property name="border_width">5</property> +- <property name="title" translatable="yes">Keyboard Layout Options</property> +- <property name="window_position">center-on-parent</property> +- <property name="default_width">550</property> +- <property name="default_height">400</property> +- <property name="type_hint">dialog</property> +- <child internal-child="vbox"> +- <object class="GtkBox" id="dialog_vbox"> +- <property name="visible">True</property> +- <property name="can_focus">False</property> +- <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> +- <property name="orientation">vertical</property> +- <property name="spacing">2</property> +- <child> +- <object class="GtkScrolledWindow" id="options_scroll"> +- <property name="visible">True</property> +- <property name="can_focus">True</property> +- <property name="border_width">5</property> +- <property name="shadow_type">out</property> +- <child> +- <object class="GtkViewport" id="viewport1"> +- <property name="visible">True</property> +- <property name="can_focus">False</property> +- <property name="shadow_type">none</property> +- <child> +- <object class="GtkVBox" id="options_vbox"> +- <property name="visible">True</property> +- <property name="can_focus">False</property> +- </object> +- </child> +- </object> +- </child> +- </object> +- <packing> +- <property name="expand">False</property> +- <property name="fill">True</property> +- <property name="position">1</property> +- </packing> +- </child> +- <child internal-child="action_area"> +- <object class="GtkButtonBox" id="dialog-action_area4"> +- <property name="visible">True</property> +- <property name="can_focus">False</property> +- <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> +- <property name="layout_style">end</property> +- <child> +- <placeholder/> +- </child> +- <child> +- <object class="GtkButton" id="button2"> +- <property name="label">gtk-close</property> +- <property name="visible">True</property> +- <property name="can_focus">True</property> +- <property name="receives_default">True</property> +- <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> +- <property name="use_action_appearance">False</property> +- <property name="use_stock">True</property> +- </object> +- <packing> +- <property name="expand">False</property> +- <property name="fill">False</property> +- <property name="position">1</property> +- </packing> +- </child> +- </object> +- </child> +- </object> +- </child> +- <action-widgets> +- <action-widget response="-7">button2</action-widget> +- </action-widgets> +- </object> +-</interface> +diff -uNrp a/panels/region/cinnamon-region-panel-system.c b/panels/region/cinnamon-region-panel-system.c +--- a/panels/region/cinnamon-region-panel-system.c 2013-08-25 14:40:14.000000000 +0100 ++++ b/panels/region/cinnamon-region-panel-system.c 2013-09-21 13:24:15.342949428 +0100 +@@ -27,15 +27,18 @@ + + #include <polkit/polkit.h> + +-#include <glib/gi18n-lib.h> ++#include <glib/gi18n.h> ++ ++#define GNOME_DESKTOP_USE_UNSTABLE_API ++#include <libcinnamon-desktop/gnome-xkb-info.h> + +-#include <libgnomekbd/gkbd-keyboard-config.h> + #include "cc-common-language.h" + #include "gdm-languages.h" + #include "cinnamon-region-panel-system.h" +-#include "cinnamon-region-panel-xkb.h" + +-static GSettings *locale_settings, *xkb_settings; ++#define WID(s) GTK_WIDGET(gtk_builder_get_object (dialog, s)) ++ ++static GSettings *locale_settings, *input_sources_settings; + static GDBusProxy *localed_proxy; + static GPermission *localed_permission; + +@@ -72,13 +75,14 @@ update_copy_button (GtkBuilder *dialog) + + button = WID ("copy_settings_button"); + +- /* If the version of localed doesn't include layouts... */ +- if (system_input_source) { ++ if (user_input_source && user_input_source[0]) { + layouts_differ = (g_strcmp0 (user_input_source, system_input_source) != 0); + if (layouts_differ == FALSE) + layouts_differ = (g_strcmp0 (user_input_variants, system_input_variants) != 0); +- } else ++ } else { ++ /* Nothing to copy */ + layouts_differ = FALSE; ++ } + + if (g_strcmp0 (user_lang, system_lang) == 0 && + g_strcmp0 (user_region, system_region) == 0 && +@@ -131,61 +135,67 @@ system_update_language (GtkBuilder *dial + } + + static void +-xkb_settings_changed (GSettings *settings, +- const gchar *key, +- GtkBuilder *dialog) ++input_sources_changed (GSettings *settings, ++ const gchar *key, ++ GtkBuilder *dialog) + { +- guint i; +- GString *disp, *list, *variants; +- GtkWidget *label; +- gchar **layouts; +- +- layouts = g_settings_get_strv (settings, "layouts"); +- if (layouts == NULL) +- return; +- +- label = WID ("user_input_source"); +- disp = g_string_new (""); +- list = g_string_new (""); +- variants = g_string_new (""); +- +- for (i = 0; layouts[i]; i++) { +- gchar *utf_visible; +- char **split; +- gchar *layout, *variant; +- +- utf_visible = xkb_layout_description_utf8 (layouts[i]); +- if (disp->str[0] != '\0') +- g_string_append (disp, ", "); +- g_string_append (disp, utf_visible ? utf_visible : layouts[i]); +- g_free (utf_visible); +- +- split = g_strsplit_set (layouts[i], " \t", 2); +- +- if (split == NULL || split[0] == NULL) +- continue; +- +- layout = split[0]; +- variant = split[1]; +- +- if (list->str[0] != '\0') +- g_string_append (list, ","); +- g_string_append (list, layout); +- +- if (variants->str[0] != '\0') +- g_string_append (variants, ","); +- g_string_append (variants, variant ? variant : ""); +- +- g_strfreev (split); +- } +- g_strfreev (layouts); ++ GString *disp, *list, *variants; ++ GtkWidget *label; ++ GnomeXkbInfo *xkb_info; ++ GVariantIter iter; ++ GVariant *sources; ++ const gchar *type; ++ const gchar *id; ++ ++ sources = g_settings_get_value (input_sources_settings, "sources"); ++ xkb_info = gnome_xkb_info_new (); ++ ++ label = WID ("user_input_source"); ++ disp = g_string_new (""); ++ list = g_string_new (""); ++ variants = g_string_new (""); ++ ++ g_variant_iter_init (&iter, sources); ++ while (g_variant_iter_next (&iter, "(&s&s)", &type, &id)) { ++ /* We can't copy non-XKB layouts to the system yet */ ++ if (g_str_equal (type, "xkb")) { ++ char **split; ++ gchar *layout, *variant; ++ const char *name; ++ ++ gnome_xkb_info_get_layout_info (xkb_info, id, &name, NULL, NULL, NULL); ++ if (disp->str[0] != '\0') ++ g_string_append (disp, ", "); ++ g_string_append (disp, name); ++ ++ split = g_strsplit (id, "+", 2); ++ ++ if (split == NULL || split[0] == NULL) ++ continue; ++ ++ layout = split[0]; ++ variant = split[1]; ++ ++ if (list->str[0] != '\0') { ++ g_string_append (list, ","); ++ g_string_append (variants, ","); ++ } ++ g_string_append (list, layout); ++ g_string_append (variants, variant ? variant : ""); ++ ++ g_strfreev (split); ++ } ++ } ++ g_variant_unref (sources); ++ g_object_unref (xkb_info); + + g_object_set_data_full (G_OBJECT (label), "input_source", g_string_free (list, FALSE), g_free); + g_object_set_data_full (G_OBJECT (label), "input_variants", g_string_free (variants, FALSE), g_free); ++ + gtk_label_set_text (GTK_LABEL (label), disp->str); + g_string_free (disp, TRUE); + +- update_copy_button (dialog); ++ update_copy_button (dialog); + } + + static void +@@ -222,12 +232,13 @@ on_localed_properties_changed (GDBusProx + const gchar **invalidated_properties, + GtkBuilder *dialog) + { +- GVariant *v; ++ GVariant *v, *w; + GtkWidget *label; +- const char *layout; ++ GnomeXkbInfo *xkb_info; + char **layouts; ++ char **variants; + GString *disp; +- guint i; ++ guint i, n; + + if (invalidated_properties != NULL) { + guint i; +@@ -236,6 +247,8 @@ on_localed_properties_changed (GDBusProx + update_property (proxy, "Locale"); + else if (g_str_equal (invalidated_properties[i], "X11Layout")) + update_property (proxy, "X11Layout"); ++ else if (g_str_equal (invalidated_properties[i], "X11Variant")) ++ update_property (proxy, "X11Variant"); + } + } + +@@ -290,29 +303,56 @@ on_localed_properties_changed (GDBusProx + label = WID ("system_input_source"); + v = g_dbus_proxy_get_cached_property (proxy, "X11Layout"); + if (v) { +- layout = g_variant_get_string (v, NULL); +- g_object_set_data_full (G_OBJECT (label), "input_source", g_strdup (layout), g_free); +- } else { ++ layouts = g_strsplit (g_variant_get_string (v, NULL), ",", -1); ++ g_object_set_data_full (G_OBJECT (label), "input_source", ++ g_variant_dup_string (v, NULL), g_free); ++ g_variant_unref (v); ++ } else { + g_object_set_data_full (G_OBJECT (label), "input_source", NULL, g_free); + update_copy_button (dialog); + return; + } + +- disp = g_string_new (""); +- layouts = g_strsplit (layout, ",", -1); +- for (i = 0; layouts[i]; i++) { +- gchar *utf_visible; +- +- utf_visible = xkb_layout_description_utf8 (layouts[i]); +- if (disp->str[0] != '\0') +- disp = g_string_append (disp, ", "); +- disp = g_string_append (disp, utf_visible ? utf_visible : layouts[i]); +- g_free (utf_visible); +- } ++ w = g_dbus_proxy_get_cached_property (proxy, "X11Variant"); ++ if (w) { ++ variants = g_strsplit (g_variant_get_string (w, NULL), ",", -1); ++ g_object_set_data_full (G_OBJECT (label), "input_variants", ++ g_variant_dup_string (w, NULL), g_free); ++ g_variant_unref (w); ++ } else { ++ variants = NULL; ++ g_object_set_data_full (G_OBJECT (label), "input_variants", NULL, g_free); ++ } ++ ++ if (variants && variants[0]) ++ n = MIN (g_strv_length (layouts), g_strv_length (variants)); ++ else ++ n = g_strv_length (layouts); ++ ++ xkb_info = gnome_xkb_info_new (); ++ disp = g_string_new (""); ++ for (i = 0; i < n && layouts[i][0]; i++) { ++ const char *name; ++ char *id; ++ ++ if (variants && variants[i] && variants[i][0]) ++ id = g_strdup_printf ("%s+%s", layouts[i], variants[i]); ++ else ++ id = g_strdup (layouts[i]); ++ ++ gnome_xkb_info_get_layout_info (xkb_info, id, &name, NULL, NULL, NULL); ++ if (disp->str[0] != '\0') ++ disp = g_string_append (disp, ", "); ++ disp = g_string_append (disp, name ? name : id); ++ ++ g_free (id); ++ } + gtk_label_set_text (GTK_LABEL (label), disp->str); + g_string_free (disp, TRUE); + +- g_variant_unref (v); ++ g_strfreev (variants); ++ g_strfreev (layouts); ++ g_object_unref (xkb_info); + + update_copy_button (dialog); + } +@@ -386,6 +426,11 @@ copy_settings (GtkButton *button, GtkBui + layout = g_object_get_data (G_OBJECT (label), "input_source"); + variants = g_object_get_data (G_OBJECT (label), "input_variants"); + ++ if (layout == NULL || layout[0] == '\0') { ++ g_debug ("Not calling SetX11Keyboard, as there are no XKB input sources in the user's settings"); ++ return; ++ } ++ + g_dbus_proxy_call (localed_proxy, + "SetX11Keyboard", + g_variant_new ("(ssssbb)", layout, "", variants ? variants : "", "", TRUE, TRUE), +@@ -468,10 +513,10 @@ setup_system (GtkBuilder *dialog) + G_CALLBACK (locale_settings_changed), dialog); + g_object_weak_ref (G_OBJECT (dialog), (GWeakNotify) g_object_unref, locale_settings); + +- xkb_settings = g_settings_new (GKBD_KEYBOARD_SCHEMA); +- g_signal_connect (xkb_settings, "changed::layouts", +- G_CALLBACK (xkb_settings_changed), dialog); +- g_object_weak_ref (G_OBJECT (dialog), (GWeakNotify) g_object_unref, xkb_settings); ++ input_sources_settings = g_settings_new ("org.cinnamon.desktop.input-sources"); ++ g_signal_connect (input_sources_settings, "changed::sources", ++ G_CALLBACK (input_sources_changed), dialog); ++ g_object_weak_ref (G_OBJECT (dialog), (GWeakNotify) g_object_unref, input_sources_settings); + + /* Display user settings */ + language = cc_common_language_get_current_language (); +@@ -480,7 +525,7 @@ setup_system (GtkBuilder *dialog) + + locale_settings_changed (locale_settings, "region", dialog); + +- xkb_settings_changed (xkb_settings, "layouts", dialog); ++ input_sources_changed (input_sources_settings, "sources", dialog); + + bus = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, NULL); + g_dbus_proxy_new (bus, +diff -uNrp a/panels/region/cinnamon-region-panel-system.h b/panels/region/cinnamon-region-panel-system.h +--- a/panels/region/cinnamon-region-panel-system.h 2013-08-25 14:40:14.000000000 +0100 ++++ b/panels/region/cinnamon-region-panel-system.h 2013-09-21 13:24:15.342949428 +0100 +@@ -19,8 +19,8 @@ + * 02110-1335, USA. + */ + +-#ifndef __GNOME_REGION_PANEL_SYSTEM_H +-#define __GNOME_REGION_PANEL_SYSTEM_H ++#ifndef __CINNAMON_REGION_PANEL_SYSTEM_H ++#define __CINNAMON_REGION_PANEL_SYSTEM_H + + #include <gtk/gtk.h> + +diff -uNrp a/panels/region/cinnamon-region-panel.ui b/panels/region/cinnamon-region-panel.ui +--- a/panels/region/cinnamon-region-panel.ui 2013-08-25 14:40:14.000000000 +0100 ++++ b/panels/region/cinnamon-region-panel.ui 2013-09-21 13:24:15.347949247 +0100 +@@ -162,27 +162,17 @@ + <style> + <class name="inline-toolbar"/> + </style> ++ <style> ++ <class name="inline-toolbar"/> ++ </style> + <child> + <object class="GtkToolButton" id="language_add"> ++ <property name="use_action_appearance">False</property> + <property name="visible">True</property> +- <property name="can_focus">False</property> + <property name="label" translatable="yes">Add Language</property> +- <property name="use_underline">True</property> +- <property name="icon_name">list-add-symbolic</property> +- </object> +- <packing> +- <property name="expand">False</property> +- <property name="homogeneous">True</property> +- </packing> +- </child> +- <child> +- <object class="GtkToolButton" id="language_remove"> +- <property name="visible">True</property> +- <property name="sensitive">False</property> + <property name="can_focus">False</property> +- <property name="label" translatable="yes">Remove Language</property> + <property name="use_underline">True</property> +- <property name="icon_name">list-remove-symbolic</property> ++ <property name="icon_name">list-add-symbolic</property> + </object> + <packing> + <property name="expand">False</property> +@@ -198,12 +188,13 @@ + </child> + <child> + <object class="GtkVBox" id="vbox3"> +- <property name="visible">True</property> + <property name="can_focus">False</property> + <child> + <object class="GtkLabel" id="label23"> + <property name="visible">True</property> + <property name="can_focus">False</property> ++ <property name="use_underline">True</property> ++ <property name="label" translatable="yes">Add Language</property> + </object> + <packing> + <property name="expand">True</property> +@@ -212,23 +203,24 @@ + </packing> + </child> + <child> +- <object class="GtkButton" id="get_languages_button"> +- <property name="label" translatable="yes">button</property> ++ <object class="GtkLinkButton" id="linkbutton1"> ++ <property name="label" translatable="yes">Install languages...</property> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="receives_default">True</property> ++ <property name="has_tooltip">True</property> + </object> + <packing> +- <property name="expand">True</property> ++ <property name="expand">False</property> + <property name="fill">True</property> +- <property name="position">13</property> ++ <property name="position">1</property> + </packing> + </child> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> +- <property name="position">2</property> ++ <property name="position">1</property> + </packing> + </child> + </object> +@@ -305,19 +297,19 @@ + </child> + <child> + <object class="GtkToolbar" id="region-toolbar"> +- <property name="visible">True</property> +- <property name="can_focus">False</property> + <property name="toolbar_style">icons</property> + <property name="show_arrow">False</property> + <property name="icon_size">1</property> ++ <property name="visible">True</property> + <style> + <class name="inline-toolbar"/> + </style> + <child> + <object class="GtkToolButton" id="region_add"> ++ <property name="use_action_appearance">False</property> ++ <property name="label" translatable="yes">Add Region</property> + <property name="visible">True</property> + <property name="can_focus">False</property> +- <property name="label" translatable="yes">Add Region</property> + <property name="use_underline">True</property> + <property name="icon_name">list-add-symbolic</property> + </object> +@@ -328,10 +320,11 @@ + </child> + <child> + <object class="GtkToolButton" id="region_remove"> ++ <property name="use_action_appearance">False</property> + <property name="visible">True</property> ++ <property name="label" translatable="yes">Remove Region</property> + <property name="sensitive">False</property> + <property name="can_focus">False</property> +- <property name="label" translatable="yes">Remove Region</property> + <property name="use_underline">True</property> + <property name="icon_name">list-remove-symbolic</property> + </object> +@@ -373,18 +366,6 @@ + <property name="n_rows">9</property> + <property name="n_columns">2</property> + <child> +- <placeholder/> +- </child> +- <child> +- <placeholder/> +- </child> +- <child> +- <placeholder/> +- </child> +- <child> +- <placeholder/> +- </child> +- <child> + <object class="GtkLabel" id="label7"> + <property name="visible">True</property> + <property name="can_focus">False</property> +@@ -626,6 +607,12 @@ + <property name="height">1</property> + </packing> + </child> ++ <child> ++ <placeholder/> ++ </child> ++ <child> ++ <placeholder/> ++ </child> + </object> + <packing> + <property name="position">1</property> +@@ -643,36 +630,43 @@ + </packing> + </child> + <child> +- <object class="GtkVBox" id="vbox1"> ++ <object class="GtkVBox" id="vbox5"> + <property name="visible">True</property> + <property name="can_focus">False</property> +- <property name="border_width">10</property> ++ <property name="border_width">12</property> + <property name="spacing">12</property> + <child> +- <placeholder/> ++ <object class="GtkLabel" id="label24"> ++ <property name="visible">True</property> ++ <property name="can_focus">False</property> ++ <property name="xalign">0</property> ++ <property name="label" translatable="yes">Select keyboards or other input sources</property> ++ </object> ++ <packing> ++ <property name="expand">False</property> ++ <property name="fill">False</property> ++ <property name="position">0</property> ++ </packing> + </child> + <child> +- <object class="GtkHBox" id="hbox2"> ++ <object class="GtkHBox" id="hbox3"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="spacing">12</property> + <child> +- <object class="GtkVBox" id="vbox7"> ++ <object class="GtkVBox" id="vbox6"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <child> +- <object class="GtkScrolledWindow" id="xkb_layouts_swindow"> ++ <object class="GtkScrolledWindow" id="input_sources_swindow"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="shadow_type">in</property> + <child> +- <object class="GtkTreeView" id="xkb_layouts_selected"> ++ <object class="GtkTreeView" id="active_input_sources"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="headers_visible">False</property> +- <child internal-child="selection"> +- <object class="GtkTreeSelection" id="treeview-selection1"/> +- </child> + </object> + </child> + </object> +@@ -683,7 +677,7 @@ + </packing> + </child> + <child> +- <object class="GtkToolbar" id="layouts-toolbar"> ++ <object class="GtkToolbar" id="input-toolbar"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="toolbar_style">icons</property> +@@ -693,70 +687,166 @@ + <class name="inline-toolbar"/> + </style> + <child> +- <object class="GtkToolButton" id="xkb_layouts_add"> ++ <object class="GtkToolItem" id="i_s_ar_item"> + <property name="visible">True</property> +- <property name="can_focus">False</property> +- <property name="label" translatable="yes">Add Layout</property> +- <property name="use_underline">True</property> +- <property name="icon_name">list-add-symbolic</property> ++ <child> ++ <object class="GtkBox" id="i_s_ar_box"> ++ <property name="visible">True</property> ++ <child> ++ <object class="GtkButton" id="input_source_add"> ++ <property name="visible">True</property> ++ <child internal-child="accessible"> ++ <object class="AtkObject" id="i_s_a_a11y"> ++ <property name="accessible-name" translatable="yes">Add Input Source</property> ++ </object> ++ </child> ++ <child> ++ <object class="GtkImage" id="i_s_a_image"> ++ ++ <property name="visible">True</property> ++ <property name="icon-name">list-add-symbolic</property> ++ <property name="icon-size">1</property> ++ </object> ++ </child> ++ </object> ++ </child> ++ <child> ++ <object class="GtkButton" id="input_source_remove"> ++ <property name="visible">True</property> ++ <child internal-child="accessible"> ++ <object class="AtkObject" id="i_s_r_a11y"> ++ <property name="accessible-name" translatable="yes">Remove Input Source</property> ++ </object> ++ </child> ++ <child> ++ <object class="GtkImage" id="i_s_r_image"> ++ <property name="visible">True</property> ++ <property name="icon-name">list-remove-symbolic</property> ++ <property name="icon-size">1</property> ++ </object> ++ </child> ++ </object> ++ </child> ++ </object> ++ </child> + </object> +- <packing> +- <property name="expand">False</property> +- <property name="homogeneous">True</property> +- </packing> + </child> ++ + <child> +- <object class="GtkToolButton" id="xkb_layouts_remove"> ++ <object class="GtkSeparatorToolItem" id="sep1"> + <property name="visible">True</property> +- <property name="can_focus">False</property> +- <property name="label" translatable="yes">Remove Layout</property> +- <property name="use_underline">True</property> +- <property name="icon_name">list-remove-symbolic</property> ++ <property name="draw">False</property> + </object> + <packing> +- <property name="expand">False</property> +- <property name="homogeneous">True</property> ++ <property name="expand">True</property> + </packing> + </child> ++ + <child> +- <object class="GtkToolButton" id="xkb_layouts_move_up"> ++ <object class="GtkToolItem" id="i_s_ud_item"> + <property name="visible">True</property> +- <property name="can_focus">False</property> +- <property name="label" translatable="yes">Move Up</property> +- <property name="use_underline">True</property> +- <property name="icon_name">go-up-symbolic</property> ++ <child> ++ <object class="GtkBox" id="i_s_ud_box"> ++ <property name="visible">True</property> ++ <child> ++ <object class="GtkButton" id="input_source_move_up"> ++ <property name="visible">True</property> ++ <child internal-child="accessible"> ++ <object class="AtkObject" id="i_s_u_a11y"> ++ <property name="accessible-name" translatable="yes">Move Input Source Up</property> ++ </object> ++ </child> ++ <child> ++ <object class="GtkImage" id="i_s_u_image"> ++ ++ <property name="visible">True</property> ++ <property name="icon-name">go-up-symbolic</property> ++ <property name="icon-size">1</property> ++ </object> ++ </child> ++ </object> ++ </child> ++ <child> ++ <object class="GtkButton" id="input_source_move_down"> ++ <property name="visible">True</property> ++ <child internal-child="accessible"> ++ <object class="AtkObject" id="i_s_d_a11y"> ++ <property name="accessible-name" translatable="yes">Move Input Source Down</property> ++ </object> ++ </child> ++ <child> ++ <object class="GtkImage" id="i_s_d_image"> ++ <property name="visible">True</property> ++ <property name="icon-name">go-down-symbolic</property> ++ <property name="icon-size">1</property> ++ </object> ++ </child> ++ </object> ++ </child> ++ </object> ++ </child> + </object> +- <packing> +- <property name="expand">False</property> +- <property name="homogeneous">True</property> +- </packing> + </child> ++ + <child> +- <object class="GtkToolButton" id="xkb_layouts_move_down"> ++ <object class="GtkSeparatorToolItem" id="sep2"> + <property name="visible">True</property> +- <property name="can_focus">False</property> +- <property name="label" translatable="yes">Move Down</property> +- <property name="use_underline">True</property> +- <property name="icon_name">go-down-symbolic</property> ++ <property name="draw">False</property> ++ <property name="hexpand">True</property> + </object> + <packing> +- <property name="expand">False</property> +- <property name="homogeneous">True</property> ++ <property name="expand">True</property> + </packing> + </child> ++ + <child> +- <object class="GtkToolButton" id="xkb_layouts_show"> ++ <object class="GtkToolItem" id="i_s_sp_item"> + <property name="visible">True</property> +- <property name="can_focus">False</property> +- <property name="label" translatable="yes">Preview Layout</property> +- <property name="use_underline">True</property> +- <property name="icon_name">input-keyboard-symbolic</property> ++ <child> ++ <object class="GtkBox" id="i_s_sp_box"> ++ <property name="visible">True</property> ++ <child> ++ <object class="GtkButton" id="input_source_settings"> ++ <property name="visible">True</property> ++ <child internal-child="accessible"> ++ <object class="AtkObject" id="i_s_s_a11y"> ++ <property name="accessible-name" translatable="yes">Input Source Settings</property> ++ </object> ++ </child> ++ <child> ++ <object class="GtkImage" id="i_s_s_image"> ++ ++ <property name="visible">True</property> ++ <property name="icon_name">preferences-system-symbolic</property> ++ <property name="icon_size">1</property> ++ <property name="pixel_size">16</property> ++ </object> ++ </child> ++ </object> ++ </child> ++ <child> ++ <object class="GtkButton" id="input_source_show"> ++ <property name="visible">True</property> ++ <child internal-child="accessible"> ++ <object class="AtkObject" id="i_s_p_a11y"> ++ <property name="accessible-name" translatable="yes">Show Keyboard Layout</property> ++ </object> ++ </child> ++ <child> ++ <object class="GtkImage" id="i_s_p_image"> ++ ++ <property name="visible">True</property> ++ <property name="icon_name">input-keyboard-symbolic</property> ++ <property name="icon-size">1</property> ++ </object> ++ </child> ++ </object> ++ </child> ++ </object> ++ </child> + </object> +- <packing> +- <property name="expand">False</property> +- <property name="homogeneous">True</property> +- </packing> + </child> ++ + </object> + <packing> + <property name="expand">False</property> +@@ -772,168 +862,111 @@ + </packing> + </child> + <child> +- <object class="GtkVBox" id="vbox33"> ++ <object class="GtkFrame" id="frame4"> + <property name="visible">True</property> + <property name="can_focus">False</property> +- <property name="spacing">12</property> ++ <property name="label_xalign">0</property> ++ <property name="shadow_type">none</property> + <child> +- <object class="GtkVBox" id="vbox34"> ++ <object class="GtkAlignment" id="alignment3"> + <property name="visible">True</property> + <property name="can_focus">False</property> +- <property name="spacing">6</property> ++ <property name="left_padding">12</property> + <child> +- <object class="GtkRadioButton" id="chk_same_group"> +- <property name="label" translatable="yes">Use the same layout for all windows</property> +- <property name="visible">True</property> +- <property name="can_focus">True</property> +- <property name="receives_default">False</property> +- <property name="xalign">0</property> +- <property name="active">True</property> +- <property name="draw_indicator">True</property> +- </object> +- <packing> +- <property name="expand">True</property> +- <property name="fill">True</property> +- <property name="position">0</property> +- </packing> +- </child> +- <child> +- <object class="GtkRadioButton" id="chk_separate_group_per_window"> +- <property name="label" translatable="yes">Allow different layouts for individual windows</property> +- <property name="visible">True</property> +- <property name="can_focus">True</property> +- <property name="receives_default">False</property> +- <property name="xalign">0</property> +- <property name="active">True</property> +- <property name="draw_indicator">True</property> +- <property name="group">chk_same_group</property> +- </object> +- <packing> +- <property name="expand">True</property> +- <property name="fill">True</property> +- <property name="position">1</property> +- </packing> +- </child> +- <child> +- <object class="GtkAlignment" id="alignment1"> ++ <object class="GtkGrid" id="shortcuts-grid"> + <property name="visible">True</property> + <property name="can_focus">False</property> +- <property name="left_padding">12</property> ++ <property name="margin_top">6</property> ++ <property name="row_spacing">6</property> ++ <property name="column_spacing">6</property> + <child> +- <object class="GtkVBox" id="vbox4"> ++ <object class="GtkLabel" id="prev-source-label"> + <property name="visible">True</property> + <property name="can_focus">False</property> +- <child> +- <object class="GtkRadioButton" id="chk_new_windows_default_layout"> +- <property name="label" translatable="yes">New windows use the default layout</property> +- <property name="visible">True</property> +- <property name="can_focus">True</property> +- <property name="receives_default">False</property> +- <property name="xalign">0</property> +- <property name="active">True</property> +- <property name="draw_indicator">True</property> +- </object> +- <packing> +- <property name="expand">True</property> +- <property name="fill">True</property> +- <property name="position">0</property> +- </packing> +- </child> +- <child> +- <object class="GtkRadioButton" id="chk_new_windows_inherit_layout"> +- <property name="label" translatable="yes">New windows use the previous window's layout</property> +- <property name="visible">True</property> +- <property name="can_focus">True</property> +- <property name="receives_default">False</property> +- <property name="xalign">0</property> +- <property name="active">True</property> +- <property name="draw_indicator">True</property> +- <property name="group">chk_new_windows_default_layout</property> +- </object> +- <packing> +- <property name="expand">True</property> +- <property name="fill">True</property> +- <property name="position">1</property> +- </packing> +- </child> ++ <property name="xalign">0</property> ++ <property name="label" translatable="yes">Switch to previous source</property> + </object> ++ <packing> ++ <property name="left_attach">0</property> ++ <property name="top_attach">0</property> ++ <property name="width">1</property> ++ <property name="height">1</property> ++ </packing> ++ </child> ++ <child> ++ <object class="GtkLabel" id="prev-source-shortcut-label"> ++ <property name="visible">True</property> ++ <property name="can_focus">False</property> ++ <property name="halign">end</property> ++ <property name="hexpand">True</property> ++ <property name="label" translatable="yes">Ctrl+Alt+Space</property> ++ <style><class name="dim-label"/></style> ++ </object> ++ <packing> ++ <property name="left_attach">1</property> ++ <property name="top_attach">0</property> ++ <property name="width">1</property> ++ <property name="height">1</property> ++ </packing> ++ </child> ++ <child> ++ <object class="GtkLabel" id="next-source-label"> ++ <property name="visible">True</property> ++ <property name="can_focus">False</property> ++ <property name="xalign">0</property> ++ <property name="label" translatable="yes">Switch to next source</property> ++ </object> ++ <packing> ++ <property name="left_attach">0</property> ++ <property name="top_attach">1</property> ++ <property name="width">1</property> ++ <property name="height">1</property> ++ </packing> ++ </child> ++ <child> ++ <object class="GtkLabel" id="next-source-shortcut-label"> ++ <property name="visible">True</property> ++ <property name="can_focus">False</property> ++ <property name="halign">end</property> ++ <property name="hexpand">True</property> ++ <property name="label" translatable="yes">Ctrl+Alt+Shift+Space</property> ++ <style><class name="dim-label"/></style> ++ </object> ++ <packing> ++ <property name="left_attach">1</property> ++ <property name="top_attach">1</property> ++ <property name="width">1</property> ++ <property name="height">1</property> ++ </packing> ++ </child> ++ <child> ++ <object class="GtkLinkButton" id="jump-to-shortcuts"> ++ <property name="visible">True</property> ++ <property name="can_focus">True</property> ++ <property name="label" translatable="yes">Shortcut Settings</property> ++ <property name="halign">end</property> ++ </object> ++ <packing> ++ <property name="left_attach">1</property> ++ <property name="top_attach">2</property> ++ <property name="width">1</property> ++ <property name="height">1</property> ++ </packing> + </child> + </object> +- <packing> +- <property name="expand">True</property> +- <property name="fill">True</property> +- <property name="position">2</property> +- </packing> + </child> + </object> +- <packing> +- <property name="expand">False</property> +- <property name="fill">False</property> +- <property name="position">0</property> +- </packing> +- </child> +- <child> +- <object class="GtkLabel" id="label2"> +- <property name="visible">True</property> +- <property name="can_focus">False</property> +- </object> +- <packing> +- <property name="expand">True</property> +- <property name="fill">False</property> +- <property name="position">1</property> +- </packing> + </child> +- <child> +- <object class="GtkHButtonBox" id="hbuttonbox2"> ++ <child type="label"> ++ <object class="GtkLabel" id="shortcuts-frame-label"> + <property name="visible">True</property> + <property name="can_focus">False</property> +- <property name="spacing">6</property> +- <property name="layout_style">end</property> +- <child> +- <object class="GtkButton" id="xkb_layout_options"> +- <property name="label" translatable="yes">_Options...</property> +- <property name="visible">True</property> +- <property name="can_focus">True</property> +- <property name="receives_default">True</property> +- <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> +- <property name="has_tooltip">True</property> +- <property name="tooltip_markup" translatable="yes">View and edit keyboard layout options</property> +- <property name="tooltip_text" translatable="yes">View and edit keyboard layout options</property> +- <property name="use_underline">True</property> +- </object> +- <packing> +- <property name="expand">False</property> +- <property name="fill">False</property> +- <property name="position">0</property> +- </packing> +- </child> +- <child> +- <object class="GtkButton" id="xkb_reset_to_defaults"> +- <property name="label" translatable="yes">Reset to De_faults</property> +- <property name="visible">True</property> +- <property name="can_focus">True</property> +- <property name="receives_default">True</property> +- <property name="has_tooltip">True</property> +- <property name="tooltip_markup" translatable="yes">Replace the current keyboard layout settings with the +-default settings</property> +- <property name="tooltip_text" translatable="yes">Replace the current keyboard layout settings with the +-default settings</property> +- <property name="use_underline">True</property> +- </object> +- <packing> +- <property name="expand">False</property> +- <property name="fill">False</property> +- <property name="pack_type">end</property> +- <property name="position">1</property> +- <property name="secondary">True</property> +- </packing> +- </child> ++ <property name="label" translatable="yes">Shortcuts</property> ++ <property name="use_markup">True</property> ++ <attributes> ++ <attribute name="weight" value="bold"/> ++ </attributes> + </object> +- <packing> +- <property name="expand">False</property> +- <property name="fill">False</property> +- <property name="position">2</property> +- </packing> + </child> + </object> + <packing> +@@ -951,17 +984,17 @@ default settings</property> + </child> + </object> + <packing> +- <property name="position">2</property> ++ <property name="position">3</property> + </packing> + </child> + <child type="tab"> +- <object class="GtkLabel" id="label46"> ++ <object class="GtkLabel" id="label13"> + <property name="visible">True</property> + <property name="can_focus">False</property> +- <property name="label" translatable="yes">Keyboard Layouts</property> ++ <property name="label" translatable="yes">Input Sources</property> + </object> + <packing> +- <property name="position">2</property> ++ <property name="position">3</property> + <property name="tab_fill">False</property> + </packing> + </child> +@@ -974,9 +1007,6 @@ default settings</property> + <property name="column_spacing">12</property> + <property name="row_spacing">12</property> + <child> +- <placeholder/> +- </child> +- <child> + <object class="GtkLabel" id="system-title"> + <property name="visible">True</property> + <property name="can_focus">False</property> +@@ -1051,6 +1081,7 @@ default settings</property> + <property name="bottom_attach">2</property> + <property name="x_padding">3</property> + <property name="y_padding">3</property> ++ <property name="y_options">GTK_FILL</property> + </packing> + </child> + <child> +@@ -1060,6 +1091,7 @@ default settings</property> + <property name="xalign">0</property> + <property name="yalign">0</property> + <property name="wrap">True</property> ++ <property name="width-chars">18</property> + </object> + <packing> + <property name="left_attach">1</property> +@@ -1068,6 +1100,7 @@ default settings</property> + <property name="bottom_attach">2</property> + <property name="x_padding">3</property> + <property name="y_padding">3</property> ++ <property name="y_options">GTK_FILL</property> + </packing> + </child> + <child> +@@ -1178,6 +1211,7 @@ default settings</property> + <property name="bottom_attach">2</property> + <property name="x_padding">3</property> + <property name="y_padding">3</property> ++ <property name="y_options">GTK_FILL</property> + </packing> + </child> + <child> +@@ -1187,6 +1221,7 @@ default settings</property> + <property name="xalign">0</property> + <property name="yalign">0</property> + <property name="wrap">True</property> ++ <property name="width-chars">18</property> + </object> + <packing> + <property name="left_attach">1</property> +@@ -1195,6 +1230,7 @@ default settings</property> + <property name="bottom_attach">2</property> + <property name="x_padding">3</property> + <property name="y_padding">3</property> ++ <property name="y_options">GTK_FILL</property> + </packing> + </child> + <child> +@@ -1254,6 +1290,7 @@ default settings</property> + <child> + <object class="GtkButton" id="copy_settings_button"> + <property name="label" translatable="yes">Copy Settings...</property> ++ <property name="use_action_appearance">False</property> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="receives_default">True</property> +@@ -1269,9 +1306,12 @@ default settings</property> + <property name="y_padding">3</property> + </packing> + </child> ++ <child> ++ <placeholder/> ++ </child> + </object> + <packing> +- <property name="position">3</property> ++ <property name="position">4</property> + </packing> + </child> + <child type="tab"> +@@ -1281,7 +1321,7 @@ default settings</property> + <property name="label" translatable="yes">System</property> + </object> + <packing> +- <property name="position">3</property> ++ <property name="position">4</property> + <property name="tab_fill">False</property> + </packing> + </child> +@@ -1302,4 +1342,11 @@ default settings</property> + </object> + </child> + </object> ++ <object class="GtkSizeGroup" id="system-input-source-sizegroup"> ++ <property name="mode">vertical</property> ++ <widgets> ++ <widget name="user_input_source"/> ++ <widget name="system_input_source"/> ++ </widgets> ++ </object> + </interface> +diff -uNrp a/panels/region/cinnamon-region-panel-xkb.c b/panels/region/cinnamon-region-panel-xkb.c +--- a/panels/region/cinnamon-region-panel-xkb.c 2013-08-25 14:40:14.000000000 +0100 ++++ b/panels/region/cinnamon-region-panel-xkb.c 1970-01-01 01:00:00.000000000 +0100 +@@ -1,190 +0,0 @@ +-/* cinnamon-region-panel-xkb.c +- * Copyright (C) 2003-2007 Sergey V. Udaltsov +- * +- * Written by: Sergey V. Udaltsov <svu@gnome.org> +- * +- * This program is free software; you can redistribute it and/or modify +- * it under the terms of the GNU General Public License as published by +- * the Free Software Foundation; either version 2, or (at your option) +- * any later version. +- * +- * This program is distributed in the hope that it will be useful, +- * but WITHOUT ANY WARRANTY; without even the implied warranty of +- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +- * GNU General Public License for more details. +- * +- * You should have received a copy of the GNU General Public License +- * along with this program; if not, write to the Free Software +- * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA +- * 02110-1335, USA. +- */ +- +-#ifdef HAVE_CONFIG_H +-# include <config.h> +-#endif +- +-#include <string.h> +-#include <gdk/gdkx.h> +-#include <glib/gi18n-lib.h> +- +-#include "cinnamon-region-panel-xkb.h" +- +-#include <libgnomekbd/gkbd-desktop-config.h> +- +-XklEngine *engine; +-XklConfigRegistry *config_registry; +- +-GkbdKeyboardConfig initial_config; +-GkbdDesktopConfig desktop_config; +- +-GSettings *xkb_keyboard_settings; +-GSettings *xkb_desktop_settings; +- +-char * +-xci_desc_to_utf8 (const XklConfigItem * ci) +-{ +- gchar *dd = g_strdup (ci->description); +- gchar *sd = g_strstrip (dd); +- gchar *rv = g_strdup (sd[0] == 0 ? ci->name : sd); +- g_free (dd); +- return rv; +-} +- +-static void +-cleanup_xkb_tabs (GtkBuilder * dialog, +- GObject *where_the_object_wa) +-{ +- gkbd_desktop_config_term (&desktop_config); +- gkbd_keyboard_config_term (&initial_config); +- g_object_unref (G_OBJECT (config_registry)); +- config_registry = NULL; +- /* Don't unref it here, or we'll crash if open the panel again */ +- engine = NULL; +- g_object_unref (G_OBJECT (xkb_keyboard_settings)); +- g_object_unref (G_OBJECT (xkb_desktop_settings)); +- xkb_keyboard_settings = NULL; +- xkb_desktop_settings = NULL; +-} +- +-static void +-reset_to_defaults (GtkWidget * button, GtkBuilder * dialog) +-{ +- GkbdKeyboardConfig empty_kbd_config; +- +- gkbd_keyboard_config_init (&empty_kbd_config, engine); +- gkbd_keyboard_config_save (&empty_kbd_config); +- gkbd_keyboard_config_term (&empty_kbd_config); +- +- g_settings_reset (xkb_desktop_settings, +- GKBD_DESKTOP_CONFIG_KEY_DEFAULT_GROUP); +- +- /* all the rest is g-s-d's business */ +-} +- +-static void +-chk_new_windows_inherit_layout_toggled (GtkWidget * +- chk_new_windows_inherit_layout, +- GtkBuilder * dialog) +-{ +- xkb_save_default_group (gtk_toggle_button_get_active +- (GTK_TOGGLE_BUTTON +- (chk_new_windows_inherit_layout)) ? -1 : +- 0); +-} +- +-void +-setup_xkb_tabs (GtkBuilder * dialog) +-{ +- GtkWidget *widget; +- GtkStyleContext *context; +- GtkWidget *chk_new_windows_inherit_layout; +- +- chk_new_windows_inherit_layout = WID ("chk_new_windows_inherit_layout"); +- +- xkb_desktop_settings = g_settings_new (GKBD_DESKTOP_SCHEMA); +- xkb_keyboard_settings = g_settings_new (GKBD_KEYBOARD_SCHEMA); +- +- engine = +- xkl_engine_get_instance (GDK_DISPLAY_XDISPLAY +- (gdk_display_get_default ())); +- config_registry = xkl_config_registry_get_instance (engine); +- +- gkbd_desktop_config_init (&desktop_config, engine); +- gkbd_desktop_config_load (&desktop_config); +- +- xkl_config_registry_load (config_registry, +- desktop_config.load_extra_items); +- +- gkbd_keyboard_config_init (&initial_config, engine); +- gkbd_keyboard_config_load_from_x_initial (&initial_config, NULL); +- +- /* Set initial state */ +- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (WID ("chk_separate_group_per_window")), +- g_settings_get_boolean (xkb_desktop_settings, +- GKBD_DESKTOP_CONFIG_KEY_GROUP_PER_WINDOW)); +- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (chk_new_windows_inherit_layout), +- xkb_get_default_group () < 0); +- +- g_settings_bind (xkb_desktop_settings, +- GKBD_DESKTOP_CONFIG_KEY_GROUP_PER_WINDOW, +- WID ("chk_separate_group_per_window"), "active", +- G_SETTINGS_BIND_DEFAULT); +- g_settings_bind (xkb_desktop_settings, +- GKBD_DESKTOP_CONFIG_KEY_GROUP_PER_WINDOW, +- WID ("chk_new_windows_inherit_layout"), "sensitive", +- G_SETTINGS_BIND_DEFAULT); +- g_settings_bind (xkb_desktop_settings, +- GKBD_DESKTOP_CONFIG_KEY_GROUP_PER_WINDOW, +- WID ("chk_new_windows_default_layout"), "sensitive", +- G_SETTINGS_BIND_DEFAULT); +- +- xkb_layouts_prepare_selected_tree (dialog); +- xkb_layouts_fill_selected_tree (dialog); +- +- xkb_layouts_register_buttons_handlers (dialog); +- g_signal_connect (G_OBJECT (WID ("xkb_reset_to_defaults")), +- "clicked", G_CALLBACK (reset_to_defaults), +- dialog); +- +- g_signal_connect (G_OBJECT (chk_new_windows_inherit_layout), +- "toggled", +- G_CALLBACK +- (chk_new_windows_inherit_layout_toggled), +- dialog); +- +- g_signal_connect_swapped (G_OBJECT (WID ("xkb_layout_options")), +- "clicked", +- G_CALLBACK (xkb_options_popup_dialog), +- dialog); +- +- xkb_layouts_register_conf_listener (dialog); +- xkb_options_register_conf_listener (dialog); +- +- g_object_weak_ref (G_OBJECT (WID ("region_notebook")), +- (GWeakNotify) cleanup_xkb_tabs, dialog); +- +- enable_disable_restoring (dialog); +- +- /* Setup junction between toolbar and treeview */ +- widget = WID ("xkb_layouts_swindow"); +- context = gtk_widget_get_style_context (widget); +- gtk_style_context_set_junction_sides (context, GTK_JUNCTION_BOTTOM); +- widget = WID ("layouts-toolbar"); +- context = gtk_widget_get_style_context (widget); +- gtk_style_context_set_junction_sides (context, GTK_JUNCTION_TOP); +-} +- +-void +-enable_disable_restoring (GtkBuilder * dialog) +-{ +- GkbdKeyboardConfig gswic; +- gboolean enable; +- +- gkbd_keyboard_config_init (&gswic, engine); +- gkbd_keyboard_config_load (&gswic, NULL); +- +- enable = !gkbd_keyboard_config_equals (&gswic, &initial_config); +- +- gkbd_keyboard_config_term (&gswic); +- gtk_widget_set_sensitive (WID ("xkb_reset_to_defaults"), enable); +-} +diff -uNrp a/panels/region/cinnamon-region-panel-xkb.h b/panels/region/cinnamon-region-panel-xkb.h +--- a/panels/region/cinnamon-region-panel-xkb.h 2013-08-25 14:40:14.000000000 +0100 ++++ b/panels/region/cinnamon-region-panel-xkb.h 1970-01-01 01:00:00.000000000 +0100 +@@ -1,96 +0,0 @@ +-/* cinnamon-region-panel-xkb.h +- * Copyright (C) 2003-2007 Sergey V Udaltsov +- * +- * Written by Sergey V. Udaltsov <svu@gnome.org> +- * +- * This program is free software; you can redistribute it and/or modify +- * it under the terms of the GNU General Public License as published by +- * the Free Software Foundation; either version 2, or (at your option) +- * any later version. +- * +- * This program is distributed in the hope that it will be useful, +- * but WITHOUT ANY WARRANTY; without even the implied warranty of +- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +- * GNU General Public License for more details. +- * +- * You should have received a copy of the GNU General Public License +- * along with this program; if not, write to the Free Software +- * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA +- * 02110-1335, USA. +- */ +- +-#ifndef __GNOME_KEYBOARD_PROPERTY_XKB_H +-#define __GNOME_KEYBOARD_PROPERTY_XKB_H +- +-#include <gtk/gtk.h> +- +-#include "libgnomekbd/gkbd-keyboard-config.h" +-#include "libgnomekbd/gkbd-util.h" +- +-G_BEGIN_DECLS +-#define CWID(s) GTK_WIDGET (gtk_builder_get_object (chooser_dialog, s)) +-#define WID(s) GTK_WIDGET (gtk_builder_get_object (dialog, s)) +-extern XklEngine *engine; +-extern XklConfigRegistry *config_registry; +-extern GSettings *xkb_keyboard_settings; +-extern GSettings *xkb_desktop_settings; +-extern GkbdKeyboardConfig initial_config; +- +-extern void setup_xkb_tabs (GtkBuilder * dialog); +- +-extern void xkb_layouts_fill_selected_tree (GtkBuilder * dialog); +- +-extern void xkb_layouts_register_buttons_handlers (GtkBuilder * dialog); +- +-extern void xkb_layouts_register_conf_listener (GtkBuilder * dialog); +- +-extern void xkb_options_register_conf_listener (GtkBuilder * dialog); +- +-extern void xkb_layouts_prepare_selected_tree (GtkBuilder * dialog); +- +-extern void xkb_options_load_options (GtkBuilder * dialog); +- +-extern void xkb_options_popup_dialog (GtkBuilder * dialog); +- +-extern char *xci_desc_to_utf8 (const XklConfigItem * ci); +- +-extern gchar *xkb_layout_description_utf8 (const gchar * visible); +- +-extern void enable_disable_restoring (GtkBuilder * dialog); +- +-extern void preview_toggled (GtkBuilder * dialog, GtkWidget * button); +- +-extern GtkWidget *xkb_layout_choose (GtkBuilder * dialog); +- +-extern void xkb_layout_chooser_response (GtkDialog *dialog, gint response_id); +- +-extern gchar **xkb_layouts_get_selected_list (void); +- +-extern gchar **xkb_options_get_selected_list (void); +- +-#define xkb_layouts_set_selected_list(list) \ +- g_settings_set_strv (xkb_keyboard_settings, \ +- GKBD_KEYBOARD_CONFIG_KEY_LAYOUTS, \ +- (const gchar *const*)(list)) +- +-#define xkb_options_set_selected_list(list) \ +- g_settings_set_strv (xkb_keyboard_settings, \ +- GKBD_KEYBOARD_CONFIG_KEY_OPTIONS, \ +- (const gchar *const*)(list)) +- +-extern GtkWidget *xkb_layout_preview_create_widget (GtkBuilder * +- chooser_dialog); +- +-extern void xkb_layout_preview_update (GtkBuilder * chooser_dialog); +- +-extern void xkb_layout_preview_set_drawing_layout (GtkWidget * kbdraw, +- const gchar * id); +- +-extern gchar *xkb_layout_chooser_get_selected_id (GtkDialog *dialog); +- +-extern void xkb_save_default_group (gint group_no); +- +-extern gint xkb_get_default_group (void); +- +-G_END_DECLS +-#endif /* __GNOME_KEYBOARD_PROPERTY_XKB_H */ +diff -uNrp a/panels/region/cinnamon-region-panel-xkbltadd.c b/panels/region/cinnamon-region-panel-xkbltadd.c +--- a/panels/region/cinnamon-region-panel-xkbltadd.c 2013-08-25 14:40:14.000000000 +0100 ++++ b/panels/region/cinnamon-region-panel-xkbltadd.c 1970-01-01 01:00:00.000000000 +0100 +@@ -1,495 +0,0 @@ +-/* cinnamon-region-panel-xkbltadd.c +- * Copyright (C) 2007 Sergey V. Udaltsov +- * +- * Written by: Sergey V. Udaltsov <svu@gnome.org> +- * +- * This program is free software; you can redistribute it and/or modify +- * it under the terms of the GNU General Public License as published by +- * the Free Software Foundation; either version 2, or (at your option) +- * any later version. +- * +- * This program is distributed in the hope that it will be useful, +- * but WITHOUT ANY WARRANTY; without even the implied warranty of +- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +- * GNU General Public License for more details. +- * +- * You should have received a copy of the GNU General Public License +- * along with this program; if not, write to the Free Software +- * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA +- * 02110-1335, USA. +- */ +- +-#ifdef HAVE_CONFIG_H +-# include <config.h> +-#endif +- +-#include <string.h> +- +-#include <libgnomekbd/gkbd-keyboard-drawing.h> +-#include <libgnomekbd/gkbd-util.h> +- +-#include "cinnamon-region-panel-xkb.h" +- +-enum { +- COMBO_BOX_MODEL_COL_SORT, +- COMBO_BOX_MODEL_COL_VISIBLE, +- COMBO_BOX_MODEL_COL_XKB_ID, +- COMBO_BOX_MODEL_COL_COUNTRY_DESC, +- COMBO_BOX_MODEL_COL_LANGUAGE_DESC +-}; +- +-static gchar **search_pattern_list = NULL; +- +-static GtkWidget *preview_dialog = NULL; +- +-static GRegex *left_bracket_regex = NULL; +- +-#define RESPONSE_PREVIEW 1 +- +-static void +-xkb_preview_destroy_callback (GtkWidget * widget) +-{ +- preview_dialog = NULL; +-} +- +-static gboolean +-xkb_layout_chooser_selection_dupe (GtkDialog * dialog) +-{ +- gchar *selected_id = +- (gchar *) xkb_layout_chooser_get_selected_id (dialog); +- gchar **layouts_list, **pl; +- gboolean rv = FALSE; +- if (selected_id == NULL) +- return rv; +- layouts_list = pl = xkb_layouts_get_selected_list (); +- while (pl && *pl) { +- if (!g_ascii_strcasecmp (*pl++, selected_id)) { +- rv = TRUE; +- break; +- } +- } +- g_strfreev (layouts_list); +- return rv; +-} +- +-void +-xkb_layout_chooser_response (GtkDialog * dialog, gint response) +-{ +- switch (response) +- case GTK_RESPONSE_OK:{ +- /* Handled by the main code */ +- break; +- case RESPONSE_PREVIEW:{ +- gchar *selected_id = (gchar *) +- xkb_layout_chooser_get_selected_id +- (dialog); +- +- if (selected_id != NULL) { +- if (preview_dialog == NULL) { +- preview_dialog = +- gkbd_keyboard_drawing_dialog_new +- (); +- g_signal_connect (G_OBJECT +- (preview_dialog), +- "destroy", +- G_CALLBACK +- (xkb_preview_destroy_callback), +- NULL); +- /* Put into the separate group to avoid conflict +- with modal parent */ +- gtk_window_group_add_window +- (gtk_window_group_new +- (), +- GTK_WINDOW +- (preview_dialog)); +- }; +- gkbd_keyboard_drawing_dialog_set_layout +- (preview_dialog, +- config_registry, selected_id); +- +- gtk_widget_show_all +- (preview_dialog); +- } +- } +- +- return; +- } +- if (preview_dialog != NULL) { +- gtk_widget_destroy (preview_dialog); +- } +- if (search_pattern_list != NULL) { +- g_strfreev (search_pattern_list); +- search_pattern_list = NULL; +- } +- gtk_widget_destroy (GTK_WIDGET (dialog)); +-} +- +-static gchar * +-xkl_create_description_from_list (const XklConfigItem * item, +- const XklConfigItem * subitem, +- const gchar * prop_name, +- const gchar * +- (*desc_getter) (const gchar * code)) +-{ +- gchar *rv = NULL, *code = NULL; +- gchar **list = NULL; +- const gchar *desc; +- +- if (subitem != NULL) +- list = +- (gchar +- **) (g_object_get_data (G_OBJECT (subitem), +- prop_name)); +- if (list == NULL || *list == 0) +- list = +- (gchar +- **) (g_object_get_data (G_OBJECT (item), prop_name)); +- +- /* First try the parent id as such */ +- desc = desc_getter (item->name); +- if (desc != NULL) { +- rv = g_utf8_strup (desc, -1); +- } else { +- code = g_utf8_strup (item->name, -1); +- desc = desc_getter (code); +- if (desc != NULL) { +- rv = g_utf8_strup (desc, -1); +- } +- g_free (code); +- } +- +- if (list == NULL || *list == 0) +- return rv; +- +- while (*list != 0) { +- code = *list++; +- desc = desc_getter (code); +- if (desc != NULL) { +- gchar *udesc = g_utf8_strup (desc, -1); +- if (rv == NULL) { +- rv = udesc; +- } else { +- gchar *orv = rv; +- rv = g_strdup_printf ("%s %s", rv, udesc); +- g_free (orv); +- g_free (udesc); +- } +- } +- } +- return rv; +-} +- +-static void +-xkl_layout_add_to_list (XklConfigRegistry * config, +- const XklConfigItem * item, +- const XklConfigItem * subitem, +- GtkBuilder * chooser_dialog) +-{ +- GtkListStore *list_store = +- GTK_LIST_STORE (gtk_builder_get_object (chooser_dialog, +- "layout_list_model")); +- GtkTreeIter iter; +- +- gchar *utf_variant_name = +- subitem ? +- xkb_layout_description_utf8 (gkbd_keyboard_config_merge_items +- (item->name, +- subitem->name)) : +- xci_desc_to_utf8 (item); +- +- const gchar *xkb_id = +- subitem ? gkbd_keyboard_config_merge_items (item->name, +- subitem->name) : +- item->name; +- +- gchar *country_desc = +- xkl_create_description_from_list (item, subitem, +- XCI_PROP_COUNTRY_LIST, +- xkl_get_country_name); +- gchar *language_desc = +- xkl_create_description_from_list (item, subitem, +- XCI_PROP_LANGUAGE_LIST, +- xkl_get_language_name); +- +- gchar *tmp = utf_variant_name; +- utf_variant_name = +- g_regex_replace_literal (left_bracket_regex, tmp, -1, 0, +- "<", 0, NULL); +- g_free (tmp); +- +- if (subitem +- && g_object_get_data (G_OBJECT (subitem), +- XCI_PROP_EXTRA_ITEM)) { +- gchar *buf = +- g_strdup_printf ("<i>%s</i>", utf_variant_name); +- gtk_list_store_insert_with_values (list_store, &iter, -1, +- COMBO_BOX_MODEL_COL_SORT, +- utf_variant_name, +- COMBO_BOX_MODEL_COL_VISIBLE, +- buf, +- COMBO_BOX_MODEL_COL_XKB_ID, +- xkb_id, +- COMBO_BOX_MODEL_COL_COUNTRY_DESC, +- country_desc, +- COMBO_BOX_MODEL_COL_LANGUAGE_DESC, +- language_desc, -1); +- g_free (buf); +- } else +- gtk_list_store_insert_with_values (list_store, &iter, +- -1, +- COMBO_BOX_MODEL_COL_SORT, +- utf_variant_name, +- COMBO_BOX_MODEL_COL_VISIBLE, +- utf_variant_name, +- COMBO_BOX_MODEL_COL_XKB_ID, +- xkb_id, +- COMBO_BOX_MODEL_COL_COUNTRY_DESC, +- country_desc, +- COMBO_BOX_MODEL_COL_LANGUAGE_DESC, +- language_desc, -1); +- g_free (utf_variant_name); +- g_free (country_desc); +- g_free (language_desc); +-} +- +-static void +-xkb_layout_filter_clear (GtkEntry * entry, +- GtkEntryIconPosition icon_pos, +- GdkEvent * event, gpointer user_data) +-{ +- gtk_entry_set_text (entry, ""); +-} +- +-static void +-xkb_layout_filter_changed (GtkBuilder * chooser_dialog) +-{ +- GtkTreeModelFilter *filtered_model = +- GTK_TREE_MODEL_FILTER (gtk_builder_get_object (chooser_dialog, +- "filtered_layout_list_model")); +- GtkWidget *xkb_layout_filter = CWID ("xkb_layout_filter"); +- const gchar *pattern = +- gtk_entry_get_text (GTK_ENTRY (xkb_layout_filter)); +- gchar *upattern = g_utf8_strup (pattern, -1); +- +- if (!g_strcmp0 (pattern, "")) { +- g_object_set (G_OBJECT (xkb_layout_filter), +- "secondary-icon-name", "edit-find-symbolic", +- "secondary-icon-activatable", FALSE, +- "secondary-icon-sensitive", FALSE, NULL); +- } else { +- g_object_set (G_OBJECT (xkb_layout_filter), +- "secondary-icon-name", "edit-clear-symbolic", +- "secondary-icon-activatable", TRUE, +- "secondary-icon-sensitive", TRUE, NULL); +- } +- +- if (search_pattern_list != NULL) +- g_strfreev (search_pattern_list); +- +- search_pattern_list = g_strsplit (upattern, " ", -1); +- g_free (upattern); +- +- gtk_tree_model_filter_refilter (filtered_model); +-} +- +-static void +-xkb_layout_chooser_selection_changed (GtkTreeSelection * selection, +- GtkBuilder * chooser_dialog) +-{ +- GList *selected_layouts = +- gtk_tree_selection_get_selected_rows (selection, NULL); +- GtkWidget *add_button = CWID ("btnOk"); +- GtkWidget *preview_button = CWID ("btnPreview"); +- gboolean anything_selected = g_list_length (selected_layouts) == 1; +- gboolean dupe = +- xkb_layout_chooser_selection_dupe (GTK_DIALOG +- (CWID +- ("xkb_layout_chooser"))); +- +- gtk_widget_set_sensitive (add_button, anything_selected && !dupe); +- gtk_widget_set_sensitive (preview_button, anything_selected); +-} +- +-static void +-xkb_layout_chooser_row_activated (GtkTreeView * tree_view, +- GtkTreePath * path, +- GtkTreeViewColumn * column, +- GtkBuilder * chooser_dialog) +-{ +- GtkWidget *add_button = CWID ("btnOk"); +- GtkWidget *dialog = CWID ("xkb_layout_chooser"); +- +- if (gtk_widget_is_sensitive (add_button)) +- gtk_dialog_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK); +-} +- +-static gboolean +-xkb_filter_layouts (GtkTreeModel * model, +- GtkTreeIter * iter, gpointer data) +-{ +- gchar *desc = NULL, *country_desc = NULL, *language_desc = +- NULL, **pattern; +- gboolean rv = TRUE; +- +- if (search_pattern_list == NULL || search_pattern_list[0] == NULL) +- return TRUE; +- +- gtk_tree_model_get (model, iter, +- COMBO_BOX_MODEL_COL_SORT, &desc, +- COMBO_BOX_MODEL_COL_COUNTRY_DESC, +- &country_desc, +- COMBO_BOX_MODEL_COL_LANGUAGE_DESC, +- &language_desc, -1); +- +- pattern = search_pattern_list; +- do { +- gboolean is_pattern_found = FALSE; +- gchar *udesc = g_utf8_strup (desc, -1); +- if (udesc != NULL && g_strstr_len (udesc, -1, *pattern)) { +- is_pattern_found = TRUE; +- } else if (country_desc != NULL +- && g_strstr_len (country_desc, -1, *pattern)) { +- is_pattern_found = TRUE; +- } else if (language_desc != NULL +- && g_strstr_len (language_desc, -1, *pattern)) { +- is_pattern_found = TRUE; +- } +- g_free (udesc); +- +- if (!is_pattern_found) { +- rv = FALSE; +- break; +- } +- +- } while (*++pattern != NULL); +- +- g_free (desc); +- g_free (country_desc); +- g_free (language_desc); +- return rv; +-} +- +-GtkWidget * +-xkb_layout_choose (GtkBuilder * dialog) +-{ +- GtkBuilder *chooser_dialog = gtk_builder_new (); +- GtkWidget *chooser, *xkb_filtered_layouts_list, *xkb_layout_filter; +- GtkTreeViewColumn *visible_column; +- GtkTreeSelection *selection; +- GtkListStore *model; +- GtkTreeModelFilter *filtered_model; +- gtk_builder_set_translation_domain (chooser_dialog, GETTEXT_PACKAGE); +- gtk_builder_add_from_file (chooser_dialog, CINNAMONCC_UI_DIR +- "/cinnamon-region-panel-layout-chooser.ui", +- NULL); +- chooser = CWID ("xkb_layout_chooser"); +- xkb_filtered_layouts_list = CWID ("xkb_filtered_layouts_list"); +- xkb_layout_filter = CWID ("xkb_layout_filter"); +- +- g_object_set_data (G_OBJECT (chooser), "xkb_filtered_layouts_list", +- xkb_filtered_layouts_list); +- visible_column = +- gtk_tree_view_column_new_with_attributes ("Layout", +- gtk_cell_renderer_text_new +- (), "markup", +- COMBO_BOX_MODEL_COL_VISIBLE, +- NULL); +- +- gtk_window_set_transient_for (GTK_WINDOW (chooser), +- GTK_WINDOW +- (gtk_widget_get_toplevel +- (WID ("region_notebook")))); +- +- gtk_tree_view_append_column (GTK_TREE_VIEW +- (xkb_filtered_layouts_list), +- visible_column); +- g_signal_connect_swapped (G_OBJECT (xkb_layout_filter), +- "notify::text", +- G_CALLBACK +- (xkb_layout_filter_changed), +- chooser_dialog); +- +- g_signal_connect (G_OBJECT (xkb_layout_filter), "icon-release", +- G_CALLBACK (xkb_layout_filter_clear), NULL); +- +- selection = +- gtk_tree_view_get_selection (GTK_TREE_VIEW +- (xkb_filtered_layouts_list)); +- +- g_signal_connect (G_OBJECT (selection), +- "changed", +- G_CALLBACK +- (xkb_layout_chooser_selection_changed), +- chooser_dialog); +- +- xkb_layout_chooser_selection_changed (selection, chooser_dialog); +- +- g_signal_connect (G_OBJECT (xkb_filtered_layouts_list), +- "row-activated", +- G_CALLBACK (xkb_layout_chooser_row_activated), +- chooser_dialog); +- +- filtered_model = +- GTK_TREE_MODEL_FILTER (gtk_builder_get_object +- (chooser_dialog, +- "filtered_layout_list_model")); +- model = +- GTK_LIST_STORE (gtk_builder_get_object +- (chooser_dialog, "layout_list_model")); +- +- left_bracket_regex = g_regex_new ("<", 0, 0, NULL); +- +- xkl_config_registry_search_by_pattern (config_registry, +- NULL, +- (TwoConfigItemsProcessFunc) +- (xkl_layout_add_to_list), +- chooser_dialog); +- +- g_regex_unref (left_bracket_regex); +- +- gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (model), +- COMBO_BOX_MODEL_COL_SORT, +- GTK_SORT_ASCENDING); +- +- gtk_tree_model_filter_set_visible_func (filtered_model, +- xkb_filter_layouts, +- NULL, NULL); +- +- gtk_widget_grab_focus (xkb_layout_filter); +- +- gtk_widget_show (chooser); +- +- return chooser; +-} +- +-gchar * +-xkb_layout_chooser_get_selected_id (GtkDialog * dialog) +-{ +- GtkTreeModel *filtered_list_model; +- GtkWidget *xkb_filtered_layouts_list = +- g_object_get_data (G_OBJECT (dialog), +- "xkb_filtered_layouts_list"); +- GtkTreeIter viter; +- gchar *v_id; +- GtkTreeSelection *selection = +- gtk_tree_view_get_selection (GTK_TREE_VIEW +- (xkb_filtered_layouts_list)); +- GList *selected_layouts = +- gtk_tree_selection_get_selected_rows (selection, +- &filtered_list_model); +- +- if (g_list_length (selected_layouts) != 1) +- return NULL; +- +- gtk_tree_model_get_iter (filtered_list_model, +- &viter, +- (GtkTreePath *) (selected_layouts->data)); +- g_list_foreach (selected_layouts, +- (GFunc) gtk_tree_path_free, NULL); +- g_list_free (selected_layouts); +- +- gtk_tree_model_get (filtered_list_model, &viter, +- COMBO_BOX_MODEL_COL_XKB_ID, &v_id, -1); +- +- return v_id; +-} +diff -uNrp a/panels/region/cinnamon-region-panel-xkblt.c b/panels/region/cinnamon-region-panel-xkblt.c +--- a/panels/region/cinnamon-region-panel-xkblt.c 2013-08-25 14:40:14.000000000 +0100 ++++ b/panels/region/cinnamon-region-panel-xkblt.c 1970-01-01 01:00:00.000000000 +0100 +@@ -1,470 +0,0 @@ +-/* cinnamon-region-panel-xkblt.c +- * Copyright (C) 2003-2007 Sergey V. Udaltsov +- * +- * Written by: Sergey V. Udaltsov <svu@gnome.org> +- * +- * This program is free software; you can redistribute it and/or modify +- * it under the terms of the GNU General Public License as published by +- * the Free Software Foundation; either version 2, or (at your option) +- * any later version. +- * +- * This program is distributed in the hope that it will be useful, +- * but WITHOUT ANY WARRANTY; without even the implied warranty of +- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +- * GNU General Public License for more details. +- * +- * You should have received a copy of the GNU General Public License +- * along with this program; if not, write to the Free Software +- * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA +- * 02110-1335, USA. +- */ +- +-#ifdef HAVE_CONFIG_H +-# include <config.h> +-#endif +- +-#include <gdk/gdkx.h> +-#include <glib/gi18n-lib.h> +- +-#include <libgnomekbd/gkbd-desktop-config.h> +-#include <libgnomekbd/gkbd-keyboard-drawing.h> +- +-#include "cinnamon-region-panel-xkb.h" +- +-enum { +- SEL_LAYOUT_TREE_COL_DESCRIPTION, +- SEL_LAYOUT_TREE_COL_ID, +- SEL_LAYOUT_TREE_COL_ENABLED, +- SEL_LAYOUT_N_COLS +-}; +- +-static int idx2select = -1; +-static int max_selected_layouts = -1; +- +-static GtkCellRenderer *text_renderer; +- +-static gboolean disable_buttons_sensibility_update = FALSE; +- +-static gboolean +-get_selected_iter (GtkBuilder *dialog, +- GtkTreeModel **model, +- GtkTreeIter *iter) +-{ +- GtkTreeSelection *selection; +- +- selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (WID ("xkb_layouts_selected"))); +- +- return gtk_tree_selection_get_selected (selection, model, iter); +-} +- +-static void +-set_selected_path (GtkBuilder *dialog, +- GtkTreePath *path) +-{ +- GtkTreeSelection *selection; +- +- selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (WID ("xkb_layouts_selected"))); +- +- gtk_tree_selection_select_path (selection, path); +-} +- +-static gint +-find_selected_layout_idx (GtkBuilder *dialog) +-{ +- GtkTreeIter selected_iter; +- GtkTreeModel *model; +- GtkTreePath *path; +- gint *indices; +- gint rv; +- +- if (!get_selected_iter (dialog, &model, &selected_iter)) +- return -1; +- +- path = gtk_tree_model_get_path (model, &selected_iter); +- if (path == NULL) +- return -1; +- +- indices = gtk_tree_path_get_indices (path); +- rv = indices[0]; +- gtk_tree_path_free (path); +- return rv; +-} +- +-gchar ** +-xkb_layouts_get_selected_list (void) +-{ +- gchar **retval; +- +- retval = g_settings_get_strv (xkb_keyboard_settings, +- GKBD_KEYBOARD_CONFIG_KEY_LAYOUTS); +- if (retval == NULL || retval[0] == NULL) { +- g_strfreev (retval); +- retval = g_strdupv (initial_config.layouts_variants); +- } +- +- return retval; +-} +- +-gint +-xkb_get_default_group () +-{ +- return g_settings_get_int (xkb_desktop_settings, +- GKBD_DESKTOP_CONFIG_KEY_DEFAULT_GROUP); +-} +- +-void +-xkb_save_default_group (gint default_group) +-{ +- g_settings_set_int (xkb_desktop_settings, +- GKBD_DESKTOP_CONFIG_KEY_DEFAULT_GROUP, +- default_group); +-} +- +-static void +-xkb_layouts_enable_disable_buttons (GtkBuilder * dialog) +-{ +- GtkWidget *add_layout_btn = WID ("xkb_layouts_add"); +- GtkWidget *show_layout_btn = WID ("xkb_layouts_show"); +- GtkWidget *del_layout_btn = WID ("xkb_layouts_remove"); +- GtkWidget *selected_layouts_tree = WID ("xkb_layouts_selected"); +- GtkWidget *move_up_layout_btn = WID ("xkb_layouts_move_up"); +- GtkWidget *move_down_layout_btn = WID ("xkb_layouts_move_down"); +- +- GtkTreeSelection *s_selection = +- gtk_tree_view_get_selection (GTK_TREE_VIEW +- (selected_layouts_tree)); +- const int n_selected_selected_layouts = +- gtk_tree_selection_count_selected_rows (s_selection); +- GtkTreeModel *selected_layouts_model = gtk_tree_view_get_model +- (GTK_TREE_VIEW (selected_layouts_tree)); +- const int n_selected_layouts = +- gtk_tree_model_iter_n_children (selected_layouts_model, +- NULL); +- gint sidx = find_selected_layout_idx (dialog); +- +- if (disable_buttons_sensibility_update) +- return; +- +- gtk_widget_set_sensitive (add_layout_btn, +- (n_selected_layouts < +- max_selected_layouts +- || max_selected_layouts == 0)); +- gtk_widget_set_sensitive (del_layout_btn, (n_selected_layouts > 1) +- && (n_selected_selected_layouts > 0)); +- gtk_widget_set_sensitive (show_layout_btn, +- (n_selected_selected_layouts > 0)); +- gtk_widget_set_sensitive (move_up_layout_btn, sidx > 0); +- gtk_widget_set_sensitive (move_down_layout_btn, sidx >= 0 +- && sidx < (n_selected_layouts - 1)); +-} +- +-static void +-update_layouts_list (GtkTreeModel *model, +- GtkBuilder *dialog) +-{ +- gboolean cont; +- GtkTreeIter iter; +- GPtrArray *array; +- +- array = g_ptr_array_new_with_free_func ((GDestroyNotify) g_free); +- cont = gtk_tree_model_get_iter_first (model, &iter); +- while (cont) { +- char *id; +- +- gtk_tree_model_get (model, &iter, +- SEL_LAYOUT_TREE_COL_ID, &id, +- -1); +- g_ptr_array_add (array, id); +- cont = gtk_tree_model_iter_next (model, &iter); +- } +- g_ptr_array_add (array, NULL); +- xkb_layouts_set_selected_list (array->pdata); +- g_ptr_array_free (array, TRUE); +- +- xkb_layouts_enable_disable_buttons (dialog); +-} +- +-static void +-xkb_layouts_drag_end (GtkWidget *widget, +- GdkDragContext *drag_context, +- gpointer user_data) +-{ +- update_layouts_list (gtk_tree_view_get_model (GTK_TREE_VIEW (widget)), +- GTK_BUILDER (user_data)); +-} +- +-void +-xkb_layouts_prepare_selected_tree (GtkBuilder * dialog) +-{ +- GtkListStore *list_store; +- GtkWidget *tree_view = WID ("xkb_layouts_selected"); +- GtkTreeSelection *selection; +- GtkTreeViewColumn *desc_column; +- +- list_store = gtk_list_store_new (SEL_LAYOUT_N_COLS, +- G_TYPE_STRING, G_TYPE_STRING, G_TYPE_BOOLEAN); +- +- text_renderer = GTK_CELL_RENDERER (gtk_cell_renderer_text_new ()); +- +- desc_column = +- gtk_tree_view_column_new_with_attributes (_("Layout"), +- text_renderer, +- "text", +- SEL_LAYOUT_TREE_COL_DESCRIPTION, +- "sensitive", +- SEL_LAYOUT_TREE_COL_ENABLED, +- NULL); +- selection = +- gtk_tree_view_get_selection (GTK_TREE_VIEW (tree_view)); +- +- gtk_tree_view_set_model (GTK_TREE_VIEW (tree_view), +- GTK_TREE_MODEL (list_store)); +- +- gtk_tree_view_column_set_sizing (desc_column, +- GTK_TREE_VIEW_COLUMN_AUTOSIZE); +- gtk_tree_view_column_set_resizable (desc_column, TRUE); +- gtk_tree_view_column_set_expand (desc_column, TRUE); +- +- gtk_tree_view_append_column (GTK_TREE_VIEW (tree_view), +- desc_column); +- +- g_signal_connect_swapped (G_OBJECT (selection), "changed", +- G_CALLBACK +- (xkb_layouts_enable_disable_buttons), +- dialog); +- max_selected_layouts = xkl_engine_get_max_num_groups (engine); +- +- /* Setting up DnD */ +- gtk_tree_view_set_reorderable (GTK_TREE_VIEW (tree_view), TRUE); +- g_signal_connect (G_OBJECT (tree_view), "drag-end", +- G_CALLBACK (xkb_layouts_drag_end), dialog); +-} +- +-gchar * +-xkb_layout_description_utf8 (const gchar * visible) +-{ +- char *l, *sl, *v, *sv; +- if (gkbd_keyboard_config_get_descriptions +- (config_registry, visible, &sl, &l, &sv, &v)) +- visible = +- gkbd_keyboard_config_format_full_description (l, v); +- return g_strstrip (g_strdup (visible)); +-} +- +-void +-xkb_layouts_fill_selected_tree (GtkBuilder * dialog) +-{ +- gchar **layouts = xkb_layouts_get_selected_list (); +- guint i; +- GtkListStore *list_store = +- GTK_LIST_STORE (gtk_tree_view_get_model +- (GTK_TREE_VIEW +- (WID ("xkb_layouts_selected")))); +- +- /* temporarily disable the buttons' status update */ +- disable_buttons_sensibility_update = TRUE; +- +- gtk_list_store_clear (list_store); +- +- for (i = 0; layouts != NULL && layouts[i] != NULL; i++) { +- char *cur_layout = layouts[i]; +- gchar *utf_visible = +- xkb_layout_description_utf8 (cur_layout); +- +- gtk_list_store_insert_with_values (list_store, NULL, G_MAXINT, +- SEL_LAYOUT_TREE_COL_DESCRIPTION, +- utf_visible, +- SEL_LAYOUT_TREE_COL_ID, +- cur_layout, +- SEL_LAYOUT_TREE_COL_ENABLED, +- i < max_selected_layouts, -1); +- g_free (utf_visible); +- } +- +- g_strfreev (layouts); +- +- /* enable the buttons' status update */ +- disable_buttons_sensibility_update = FALSE; +- +- if (idx2select != -1) { +- GtkTreeSelection *selection = +- gtk_tree_view_get_selection ((GTK_TREE_VIEW +- (WID +- ("xkb_layouts_selected")))); +- GtkTreePath *path = +- gtk_tree_path_new_from_indices (idx2select, -1); +- gtk_tree_selection_select_path (selection, path); +- gtk_tree_path_free (path); +- idx2select = -1; +- } else { +- /* if there is nothing to select - just enable/disable the buttons, +- otherwise it would be done by the selection change */ +- xkb_layouts_enable_disable_buttons (dialog); +- } +-} +- +-static void +-add_default_switcher_if_necessary () +-{ +- gchar **layouts_list = xkb_layouts_get_selected_list(); +- gchar **options_list = xkb_options_get_selected_list (); +- gboolean was_appended; +- +- options_list = +- gkbd_keyboard_config_add_default_switch_option_if_necessary +- (layouts_list, options_list, &was_appended); +- if (was_appended) +- xkb_options_set_selected_list (options_list); +- g_strfreev (options_list); +-} +- +-static void +-chooser_response (GtkDialog *chooser, +- int response_id, +- GtkBuilder *dialog) +-{ +- if (response_id == GTK_RESPONSE_OK) { +- char *id, *name; +- GtkListStore *list_store; +- +- list_store = GTK_LIST_STORE (gtk_tree_view_get_model (GTK_TREE_VIEW (WID ("xkb_layouts_selected")))); +- id = xkb_layout_chooser_get_selected_id (chooser); +- name = xkb_layout_description_utf8 (id); +- gtk_list_store_insert_with_values (list_store, NULL, G_MAXINT, +- SEL_LAYOUT_TREE_COL_DESCRIPTION, name, +- SEL_LAYOUT_TREE_COL_ID, id, +- SEL_LAYOUT_TREE_COL_ENABLED, TRUE, +- -1); +- g_free (name); +- add_default_switcher_if_necessary (); +- update_layouts_list (GTK_TREE_MODEL (list_store), dialog); +- } +- +- xkb_layout_chooser_response (chooser, response_id); +-} +- +-static void +-add_selected_layout (GtkWidget * button, GtkBuilder * dialog) +-{ +- GtkWidget *chooser; +- +- chooser = xkb_layout_choose (dialog); +- g_signal_connect (G_OBJECT (chooser), "response", +- G_CALLBACK (chooser_response), dialog); +-} +- +-static void +-show_selected_layout (GtkWidget * button, GtkBuilder * dialog) +-{ +- gint idx = find_selected_layout_idx (dialog); +- +- if (idx != -1) { +- GtkWidget *parent = WID ("region_notebook"); +- GtkWidget *popup = gkbd_keyboard_drawing_dialog_new (); +- gkbd_keyboard_drawing_dialog_set_group (popup, +- config_registry, +- idx); +- gtk_window_set_transient_for (GTK_WINDOW (popup), +- GTK_WINDOW +- (gtk_widget_get_toplevel +- (parent))); +- gtk_widget_show_all (popup); +- } +-} +- +-static void +-remove_selected_layout (GtkWidget * button, GtkBuilder * dialog) +-{ +- GtkTreeModel *model; +- GtkTreeIter iter; +- +- if (get_selected_iter (dialog, &model, &iter) == FALSE) +- return; +- +- gtk_list_store_remove (GTK_LIST_STORE (model), &iter); +- update_layouts_list (model, dialog); +-} +- +-static void +-move_up_selected_layout (GtkWidget * button, GtkBuilder * dialog) +-{ +- GtkTreeModel *model; +- GtkTreeIter iter, prev; +- GtkTreePath *path; +- +- if (get_selected_iter (dialog, &model, &iter) == FALSE) +- return; +- +- prev = iter; +- if (!gtk_tree_model_iter_previous (model, &prev)) +- return; +- +- path = gtk_tree_model_get_path (model, &prev); +- +- gtk_list_store_swap (GTK_LIST_STORE (model), &iter, &prev); +- +- update_layouts_list (model, dialog); +- +- set_selected_path (dialog, path); +- +- gtk_tree_path_free (path); +-} +- +-static void +-move_down_selected_layout (GtkWidget * button, GtkBuilder * dialog) +-{ +- GtkTreeModel *model; +- GtkTreeIter iter, next; +- GtkTreePath *path; +- +- if (get_selected_iter (dialog, &model, &iter) == FALSE) +- return; +- +- next = iter; +- if (!gtk_tree_model_iter_next (model, &next)) +- return; +- +- path = gtk_tree_model_get_path (model, &next); +- +- gtk_list_store_swap (GTK_LIST_STORE (model), &iter, &next); +- +- update_layouts_list (model, dialog); +- +- set_selected_path (dialog, path); +- +- gtk_tree_path_free (path); +-} +- +-void +-xkb_layouts_register_buttons_handlers (GtkBuilder * dialog) +-{ +- g_signal_connect (G_OBJECT (WID ("xkb_layouts_add")), "clicked", +- G_CALLBACK (add_selected_layout), dialog); +- g_signal_connect (G_OBJECT (WID ("xkb_layouts_show")), "clicked", +- G_CALLBACK (show_selected_layout), dialog); +- g_signal_connect (G_OBJECT (WID ("xkb_layouts_remove")), "clicked", +- G_CALLBACK (remove_selected_layout), dialog); +- g_signal_connect (G_OBJECT (WID ("xkb_layouts_move_up")), +- "clicked", G_CALLBACK (move_up_selected_layout), +- dialog); +- g_signal_connect (G_OBJECT (WID ("xkb_layouts_move_down")), +- "clicked", +- G_CALLBACK (move_down_selected_layout), dialog); +-} +- +-static void +-xkb_layouts_update_list (GSettings * settings, +- gchar * key, GtkBuilder * dialog) +-{ +- if (strcmp (key, GKBD_KEYBOARD_CONFIG_KEY_LAYOUTS) == 0) { +- xkb_layouts_fill_selected_tree (dialog); +- enable_disable_restoring (dialog); +- } +-} +- +-void +-xkb_layouts_register_conf_listener (GtkBuilder * dialog) +-{ +- g_signal_connect (xkb_keyboard_settings, "changed", +- G_CALLBACK (xkb_layouts_update_list), dialog); +-} +diff -uNrp a/panels/region/cinnamon-region-panel-xkbot.c b/panels/region/cinnamon-region-panel-xkbot.c +--- a/panels/region/cinnamon-region-panel-xkbot.c 2013-08-25 14:40:14.000000000 +0100 ++++ b/panels/region/cinnamon-region-panel-xkbot.c 1970-01-01 01:00:00.000000000 +0100 +@@ -1,516 +0,0 @@ +-/* cinnamon-region-panel-xkbot.c +- * Copyright (C) 2003-2007 Sergey V. Udaltsov +- * +- * Written by: Sergey V. Udaltsov <svu@gnome.org> +- * John Spray <spray_john@users.sourceforge.net> +- * +- * This program is free software; you can redistribute it and/or modify +- * it under the terms of the GNU General Public License as published by +- * the Free Software Foundation; either version 2, or (at your option) +- * any later version. +- * +- * This program is distributed in the hope that it will be useful, +- * but WITHOUT ANY WARRANTY; without even the implied warranty of +- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +- * GNU General Public License for more details. +- * +- * You should have received a copy of the GNU General Public License +- * along with this program; if not, write to the Free Software +- * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA +- * 02110-1335, USA. +- */ +- +-#ifdef HAVE_CONFIG_H +-# include <config.h> +-#endif +- +-#include <glib/gi18n-lib.h> +-#include <string.h> +- +-#include "cinnamon-region-panel-xkb.h" +- +-static GtkBuilder *chooser_dialog = NULL; +-static const char *current1st_level_id = NULL; +-static GSList *option_checks_list = NULL; +-static GtkWidget *current_none_radio = NULL; +-static GtkWidget *current_expander = NULL; +-static gboolean current_multi_select = FALSE; +-static GSList *current_radio_group = NULL; +- +-#define OPTION_ID_PROP "optionID" +-#define SELCOUNTER_PROP "selectionCounter" +-#define GCONFSTATE_PROP "gconfState" +-#define EXPANDERS_PROP "expandersList" +- +-gchar ** +-xkb_options_get_selected_list (void) +-{ +- gchar **retval; +- +- retval = +- g_settings_get_strv (xkb_keyboard_settings, +- GKBD_KEYBOARD_CONFIG_KEY_OPTIONS); +- if (retval == NULL) { +- retval = g_strdupv (initial_config.options); +- } +- +- return retval; +-} +- +-/* Returns the selection counter of the expander (static current_expander) */ +-static int +-xkb_options_expander_selcounter_get (void) +-{ +- return +- GPOINTER_TO_INT (g_object_get_data +- (G_OBJECT (current_expander), +- SELCOUNTER_PROP)); +-} +- +-/* Increments the selection counter in the expander (static current_expander) +- using the value (can be 0)*/ +-static void +-xkb_options_expander_selcounter_add (int value) +-{ +- g_object_set_data (G_OBJECT (current_expander), SELCOUNTER_PROP, +- GINT_TO_POINTER +- (xkb_options_expander_selcounter_get () +- + value)); +-} +- +-/* Resets the seletion counter in the expander (static current_expander) */ +-static void +-xkb_options_expander_selcounter_reset (void) +-{ +- g_object_set_data (G_OBJECT (current_expander), SELCOUNTER_PROP, +- GINT_TO_POINTER (0)); +-} +- +-/* Formats the expander (static current_expander), based on the selection counter */ +-static void +-xkb_options_expander_highlight (void) +-{ +- char *utf_group_name = +- g_object_get_data (G_OBJECT (current_expander), +- "utfGroupName"); +- int counter = xkb_options_expander_selcounter_get (); +- if (utf_group_name != NULL) { +- gchar *titlemarkup = +- g_strconcat (counter > +- 0 ? "<span weight=\"bold\">" : "<span>", +- utf_group_name, "</span>", NULL); +- gtk_expander_set_label (GTK_EXPANDER (current_expander), +- titlemarkup); +- g_free (titlemarkup); +- } +-} +- +-/* Add optionname from the backend's selection list if it's not +- already in there. */ +-static void +-xkb_options_select (gchar * optionname) +-{ +- gboolean already_selected = FALSE; +- gchar **options_list; +- guint i; +- +- options_list = xkb_options_get_selected_list (); +- for (i = 0; options_list != NULL && options_list[i] != NULL; i++) { +- gchar *option = options_list[i]; +- if (!strcmp (option, optionname)) { +- already_selected = TRUE; +- break; +- } +- } +- +- if (!already_selected) { +- options_list = +- gkbd_strv_append (options_list, g_strdup (optionname)); +- xkb_options_set_selected_list (options_list); +- } +- +- g_strfreev (options_list); +-} +- +-/* Remove all occurences of optionname from the backend's selection list */ +-static void +-xkb_options_deselect (gchar * optionname) +-{ +- gchar **options_list = xkb_options_get_selected_list (); +- if (options_list != NULL) { +- gchar **option = options_list; +- while (*option != NULL) { +- gchar *id = *option; +- if (!strcmp (id, optionname)) { +- gkbd_strv_behead (option); +- } else +- option++; +- } +- xkb_options_set_selected_list (options_list); +- } +- g_strfreev (options_list); +-} +- +-/* Return true if optionname describes a string already in the backend's +- list of selected options */ +-static gboolean +-xkb_options_is_selected (gchar * optionname) +-{ +- gboolean retval = FALSE; +- gchar **options_list = xkb_options_get_selected_list (); +- if (options_list != NULL) { +- gchar **option = options_list; +- while (*option != NULL) { +- if (!strcmp (*option, optionname)) { +- retval = TRUE; +- break; +- } +- option++; +- } +- } +- g_strfreev (options_list); +- return retval; +-} +- +-/* Make sure selected options stay visible when navigating with the keyboard */ +-static gboolean +-option_focused_cb (GtkWidget * widget, GdkEventFocus * event, +- gpointer data) +-{ +- GtkScrolledWindow *win = GTK_SCROLLED_WINDOW (data); +- GtkAllocation alloc; +- GtkAdjustment *adj; +- +- gtk_widget_get_allocation (widget, &alloc); +- adj = gtk_scrolled_window_get_vadjustment (win); +- gtk_adjustment_clamp_page (adj, alloc.y, alloc.y + alloc.height); +- +- return FALSE; +-} +- +-/* Update xkb backend to reflect the new UI state */ +-static void +-option_toggled_cb (GtkWidget * checkbutton, gpointer data) +-{ +- gpointer optionID = +- g_object_get_data (G_OBJECT (checkbutton), OPTION_ID_PROP); +- if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (checkbutton))) +- xkb_options_select (optionID); +- else +- xkb_options_deselect (optionID); +-} +- +-/* Add a check_button or radio_button to control a particular option +- This function makes particular use of the current... variables at +- the top of this file. */ +-static void +-xkb_options_add_option (XklConfigRegistry * config_registry, +- XklConfigItem * config_item, GtkBuilder * dialog) +-{ +- GtkWidget *option_check; +- gchar *utf_option_name = xci_desc_to_utf8 (config_item); +- /* Copy this out because we'll load it into the widget with set_data */ +- gchar *full_option_name = +- g_strdup (gkbd_keyboard_config_merge_items +- (current1st_level_id, config_item->name)); +- gboolean initial_state; +- +- if (current_multi_select) +- option_check = +- gtk_check_button_new_with_label (utf_option_name); +- else { +- if (current_radio_group == NULL) { +- /* The first radio in a group is to be "Default", meaning none of +- the below options are to be included in the selected list. +- This is a HIG-compliant alternative to allowing no +- selection in the group. */ +- option_check = +- gtk_radio_button_new_with_label +- (current_radio_group, _("Default")); +- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON +- (option_check), +- TRUE); +- /* Make option name underscore - +- to enforce its first position in the list */ +- g_object_set_data_full (G_OBJECT (option_check), +- "utfOptionName", +- g_strdup (" "), g_free); +- option_checks_list = +- g_slist_append (option_checks_list, +- option_check); +- current_radio_group = +- gtk_radio_button_get_group (GTK_RADIO_BUTTON +- (option_check)); +- current_none_radio = option_check; +- +- g_signal_connect (option_check, "focus-in-event", +- G_CALLBACK (option_focused_cb), +- WID ("options_scroll")); +- } +- option_check = +- gtk_radio_button_new_with_label (current_radio_group, +- utf_option_name); +- current_radio_group = +- gtk_radio_button_get_group (GTK_RADIO_BUTTON +- (option_check)); +- g_object_set_data (G_OBJECT (option_check), "NoneRadio", +- current_none_radio); +- } +- +- initial_state = xkb_options_is_selected (full_option_name); +- +- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (option_check), +- initial_state); +- +- g_object_set_data_full (G_OBJECT (option_check), OPTION_ID_PROP, +- full_option_name, g_free); +- g_object_set_data_full (G_OBJECT (option_check), "utfOptionName", +- utf_option_name, g_free); +- +- g_signal_connect (option_check, "toggled", +- G_CALLBACK (option_toggled_cb), NULL); +- +- option_checks_list = +- g_slist_append (option_checks_list, option_check); +- +- g_signal_connect (option_check, "focus-in-event", +- G_CALLBACK (option_focused_cb), +- WID ("options_scroll")); +- +- xkb_options_expander_selcounter_add (initial_state); +- g_object_set_data (G_OBJECT (option_check), GCONFSTATE_PROP, +- GINT_TO_POINTER (initial_state)); +-} +- +-static gint +-xkb_option_checks_compare (GtkWidget * chk1, GtkWidget * chk2) +-{ +- const gchar *t1 = +- g_object_get_data (G_OBJECT (chk1), "utfOptionName"); +- const gchar *t2 = +- g_object_get_data (G_OBJECT (chk2), "utfOptionName"); +- return g_utf8_collate (t1, t2); +-} +- +-/* Add a group of options: create title and layout widgets and then +- add widgets for all the options in the group. */ +-static void +-xkb_options_add_group (XklConfigRegistry * config_registry, +- XklConfigItem * config_item, GtkBuilder * dialog) +-{ +- GtkWidget *align, *vbox, *option_check; +- gboolean allow_multiple_selection = +- GPOINTER_TO_INT (g_object_get_data (G_OBJECT (config_item), +- XCI_PROP_ALLOW_MULTIPLE_SELECTION)); +- +- GSList *expanders_list = +- g_object_get_data (G_OBJECT (dialog), EXPANDERS_PROP); +- +- gchar *utf_group_name = xci_desc_to_utf8 (config_item); +- gchar *titlemarkup = +- g_strconcat ("<span>", utf_group_name, "</span>", NULL); +- +- current_expander = gtk_expander_new (titlemarkup); +- gtk_expander_set_use_markup (GTK_EXPANDER (current_expander), +- TRUE); +- g_object_set_data_full (G_OBJECT (current_expander), +- "utfGroupName", utf_group_name, g_free); +- g_object_set_data_full (G_OBJECT (current_expander), "groupId", +- g_strdup (config_item->name), g_free); +- +- g_free (titlemarkup); +- align = gtk_alignment_new (0, 0, 1, 1); +- gtk_alignment_set_padding (GTK_ALIGNMENT (align), 6, 12, 12, 0); +- vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6); +- gtk_box_set_homogeneous (GTK_BOX (vbox), TRUE); +- gtk_container_add (GTK_CONTAINER (align), vbox); +- gtk_container_add (GTK_CONTAINER (current_expander), align); +- +- current_multi_select = (gboolean) allow_multiple_selection; +- current_radio_group = NULL; +- current1st_level_id = config_item->name; +- +- option_checks_list = NULL; +- +- xkl_config_registry_foreach_option (config_registry, +- config_item->name, +- (ConfigItemProcessFunc) +- xkb_options_add_option, +- dialog); +- /* sort it */ +- option_checks_list = +- g_slist_sort (option_checks_list, +- (GCompareFunc) xkb_option_checks_compare); +- while (option_checks_list) { +- option_check = GTK_WIDGET (option_checks_list->data); +- gtk_box_pack_start (GTK_BOX (vbox), option_check, TRUE, +- TRUE, 0); +- option_checks_list = option_checks_list->next; +- } +- /* free it */ +- g_slist_free (option_checks_list); +- option_checks_list = NULL; +- +- xkb_options_expander_highlight (); +- +- expanders_list = g_slist_append (expanders_list, current_expander); +- g_object_set_data (G_OBJECT (dialog), EXPANDERS_PROP, +- expanders_list); +- +- g_signal_connect (current_expander, "focus-in-event", +- G_CALLBACK (option_focused_cb), +- WID ("options_scroll")); +-} +- +-static gint +-xkb_options_expanders_compare (GtkWidget * expander1, +- GtkWidget * expander2) +-{ +- const gchar *t1 = +- g_object_get_data (G_OBJECT (expander1), "utfGroupName"); +- const gchar *t2 = +- g_object_get_data (G_OBJECT (expander2), "utfGroupName"); +- return g_utf8_collate (t1, t2); +-} +- +-/* Create widgets to represent the options made available by the backend */ +-void +-xkb_options_load_options (GtkBuilder * dialog) +-{ +- GtkWidget *opts_vbox = WID ("options_vbox"); +- GtkWidget *dialog_vbox = WID ("dialog_vbox"); +- GtkWidget *options_scroll = WID ("options_scroll"); +- GtkWidget *expander; +- GSList *expanders_list; +- +- current1st_level_id = NULL; +- current_none_radio = NULL; +- current_multi_select = FALSE; +- current_radio_group = NULL; +- +- /* fill the list */ +- xkl_config_registry_foreach_option_group (config_registry, +- (ConfigItemProcessFunc) +- xkb_options_add_group, +- dialog); +- /* sort it */ +- expanders_list = +- g_object_get_data (G_OBJECT (dialog), EXPANDERS_PROP); +- expanders_list = +- g_slist_sort (expanders_list, +- (GCompareFunc) xkb_options_expanders_compare); +- g_object_set_data (G_OBJECT (dialog), EXPANDERS_PROP, +- expanders_list); +- while (expanders_list) { +- expander = GTK_WIDGET (expanders_list->data); +- gtk_box_pack_start (GTK_BOX (opts_vbox), expander, FALSE, +- FALSE, 0); +- expanders_list = expanders_list->next; +- } +- +- /* Somewhere in gtk3 the top vbox in dialog is made non-expandable */ +- gtk_box_set_child_packing (GTK_BOX (dialog_vbox), options_scroll, +- TRUE, TRUE, 0, GTK_PACK_START); +- gtk_widget_show_all (dialog_vbox); +-} +- +-static void +-chooser_response_cb (GtkDialog * dialog, gint response, gpointer data) +-{ +- switch (response) { +- case GTK_RESPONSE_DELETE_EVENT: +- case GTK_RESPONSE_CLOSE: { +- /* just cleanup */ +- GSList *expanders_list = +- g_object_get_data (G_OBJECT (dialog), +- EXPANDERS_PROP); +- g_object_set_data (G_OBJECT (dialog), +- EXPANDERS_PROP, NULL); +- g_slist_free (expanders_list); +- +- gtk_widget_destroy (GTK_WIDGET (dialog)); +- chooser_dialog = NULL; +- } +- break; +- } +-} +- +-/* Create popup dialog */ +-void +-xkb_options_popup_dialog (GtkBuilder * dialog) +-{ +- GtkWidget *chooser; +- +- chooser_dialog = gtk_builder_new (); +- gtk_builder_set_translation_domain (chooser_dialog, GETTEXT_PACKAGE); +- gtk_builder_add_from_file (chooser_dialog, CINNAMONCC_UI_DIR +- "/cinnamon-region-panel-options-dialog.ui", +- NULL); +- +- chooser = CWID ("xkb_options_dialog"); +- gtk_window_set_transient_for (GTK_WINDOW (chooser), +- GTK_WINDOW (gtk_widget_get_toplevel (WID ("region_notebook")))); +- gtk_window_set_modal (GTK_WINDOW (chooser), TRUE); +- xkb_options_load_options (chooser_dialog); +- +- g_signal_connect (chooser, "response", +- G_CALLBACK (chooser_response_cb), dialog); +- gtk_widget_show (chooser); +-} +- +-/* Update selected option counters for a group-bound expander */ +-static void +-xkb_options_update_option_counters (XklConfigRegistry * config_registry, +- XklConfigItem * config_item) +-{ +- gchar *full_option_name = +- g_strdup (gkbd_keyboard_config_merge_items +- (current1st_level_id, config_item->name)); +- gboolean current_state = +- xkb_options_is_selected (full_option_name); +- g_free (full_option_name); +- +- xkb_options_expander_selcounter_add (current_state); +-} +- +-/* Respond to a change in the xkb gconf settings */ +-static void +-xkb_options_update (GSettings * settings, gchar * key, GtkBuilder * dialog) +-{ +- if (!strcmp (key, GKBD_KEYBOARD_CONFIG_KEY_OPTIONS)) { +- /* Updating options is handled by gconf notifies for each widget +- This is here to avoid calling it N_OPTIONS times for each gconf +- change. */ +- enable_disable_restoring (dialog); +- +- if (chooser_dialog != NULL) { +- GSList *expanders_list = +- g_object_get_data (G_OBJECT (chooser_dialog), +- EXPANDERS_PROP); +- while (expanders_list) { +- current_expander = +- GTK_WIDGET (expanders_list->data); +- gchar *group_id = +- g_object_get_data (G_OBJECT +- (current_expander), +- "groupId"); +- current1st_level_id = group_id; +- xkb_options_expander_selcounter_reset (); +- xkl_config_registry_foreach_option +- (config_registry, group_id, +- (ConfigItemProcessFunc) +- xkb_options_update_option_counters, +- current_expander); +- xkb_options_expander_highlight (); +- expanders_list = expanders_list->next; +- } +- } +- } +-} +- +-void +-xkb_options_register_conf_listener (GtkBuilder * dialog) +-{ +- g_signal_connect (xkb_keyboard_settings, "changed", +- G_CALLBACK (xkb_options_update), dialog); +-} +diff -uNrp a/panels/region/cinnamon-region-panel-xkbpv.c b/panels/region/cinnamon-region-panel-xkbpv.c +--- a/panels/region/cinnamon-region-panel-xkbpv.c 2013-08-25 14:40:14.000000000 +0100 ++++ b/panels/region/cinnamon-region-panel-xkbpv.c 1970-01-01 01:00:00.000000000 +0100 +@@ -1,120 +0,0 @@ +-/* cinnamon-region-panel-xkbpv.c +- * Copyright (C) 2003-2007 Sergey V. Udaltsov +- * +- * Written by: Sergey V. Udaltsov <svu@gnome.org> +- * +- * This program is free software; you can redistribute it and/or modify +- * it under the terms of the GNU General Public License as published by +- * the Free Software Foundation; either version 2, or (at your option) +- * any later version. +- * +- * This program is distributed in the hope that it will be useful, +- * but WITHOUT ANY WARRANTY; without even the implied warranty of +- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +- * GNU General Public License for more details. +- * +- * You should have received a copy of the GNU General Public License +- * along with this program; if not, write to the Free Software +- * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA +- * 02110-1335, USA. +- */ +- +-#ifdef HAVE_CONFIG_H +-# include <config.h> +-#endif +- +-#include <libgnomekbd/gkbd-keyboard-drawing.h> +- +-#include "cinnamon-region-panel-xkb.h" +- +-#ifdef HAVE_X11_EXTENSIONS_XKB_H +-#include "X11/XKBlib.h" +-/** +- * BAD STYLE: Taken from xklavier_private_xkb.h +- * Any ideas on architectural improvements are WELCOME +- */ +-extern gboolean xkl_xkb_config_native_prepare (XklEngine * engine, +- const XklConfigRec * data, +- XkbComponentNamesPtr +- component_names); +- +-extern void xkl_xkb_config_native_cleanup (XklEngine * engine, +- XkbComponentNamesPtr +- component_names); +- +-/* */ +-#endif +- +-static GkbdKeyboardDrawingGroupLevel groupsLevels[] = +- { {0, 1}, {0, 3}, {0, 0}, {0, 2} }; +-static GkbdKeyboardDrawingGroupLevel *pGroupsLevels[] = { +- groupsLevels, groupsLevels + 1, groupsLevels + 2, groupsLevels + 3 +-}; +- +-GtkWidget * +-xkb_layout_preview_create_widget (GtkBuilder * chooserDialog) +-{ +- GtkWidget *kbdraw = gkbd_keyboard_drawing_new (); +- +- gkbd_keyboard_drawing_set_groups_levels (GKBD_KEYBOARD_DRAWING +- (kbdraw), pGroupsLevels); +- return kbdraw; +-} +- +-void +-xkb_layout_preview_set_drawing_layout (GtkWidget * kbdraw, +- const gchar * id) +-{ +-#ifdef HAVE_X11_EXTENSIONS_XKB_H +- if (kbdraw != NULL) { +- if (id != NULL) { +- XklConfigRec *data; +- char **p, *layout, *variant; +- XkbComponentNamesRec component_names; +- +- data = xkl_config_rec_new (); +- if (xkl_config_rec_get_from_server (data, engine)) { +- if ((p = data->layouts) != NULL) +- g_strfreev (data->layouts); +- +- if ((p = data->variants) != NULL) +- g_strfreev (data->variants); +- +- data->layouts = g_new0 (char *, 2); +- data->variants = g_new0 (char *, 2); +- if (gkbd_keyboard_config_split_items +- (id, &layout, &variant) +- && variant != NULL) { +- data->layouts[0] = +- (layout == +- NULL) ? NULL : +- g_strdup (layout); +- data->variants[0] = +- (variant == +- NULL) ? NULL : +- g_strdup (variant); +- } else { +- data->layouts[0] = +- (id == +- NULL) ? NULL : g_strdup (id); +- data->variants[0] = NULL; +- } +- +- if (xkl_xkb_config_native_prepare +- (engine, data, &component_names)) { +- gkbd_keyboard_drawing_set_keyboard +- (GKBD_KEYBOARD_DRAWING +- (kbdraw), &component_names); +- +- xkl_xkb_config_native_cleanup +- (engine, &component_names); +- } +- } +- g_object_unref (G_OBJECT (data)); +- } else +- gkbd_keyboard_drawing_set_keyboard +- (GKBD_KEYBOARD_DRAWING (kbdraw), NULL); +- +- } +-#endif +-} +diff -uNrp a/panels/region/.indent.pro b/panels/region/.indent.pro +--- a/panels/region/.indent.pro 1970-01-01 01:00:00.000000000 +0100 ++++ b/panels/region/.indent.pro 2013-08-25 16:50:30.000000000 +0100 +@@ -0,0 +1,2 @@ ++-kr -i8 -pcs -lps -psl ++ +diff -uNrp a/panels/region/Makefile.am b/panels/region/Makefile.am +--- a/panels/region/Makefile.am 2013-08-25 14:40:14.000000000 +0100 ++++ b/panels/region/Makefile.am 2013-09-21 13:24:15.347949247 +0100 +@@ -23,12 +23,9 @@ libregion_la_SOURCES = \ + cinnamon-region-panel-lang.h \ + cinnamon-region-panel-system.c \ + cinnamon-region-panel-system.h \ +- cinnamon-region-panel-xkb.c \ +- cinnamon-region-panel-xkblt.c \ +- cinnamon-region-panel-xkbltadd.c \ +- cinnamon-region-panel-xkbot.c \ +- cinnamon-region-panel-xkbpv.c \ +- cinnamon-region-panel-xkb.h ++ cinnamon-region-panel-input.c \ ++ cinnamon-region-panel-input.h \ ++ $(NULL) + + libregion_la_LIBADD = $(PANEL_LIBS) $(REGION_PANEL_LIBS) $(builddir)/../common/liblanguage.la + +@@ -39,8 +36,8 @@ libregion_la_LDFLAGS = $(PANEL_LDFLAGS) + uidir = $(pkgdatadir)/ui + ui_DATA = \ + cinnamon-region-panel.ui \ +- cinnamon-region-panel-layout-chooser.ui \ +- cinnamon-region-panel-options-dialog.ui ++ cinnamon-region-panel-input-chooser.ui \ ++ $(NULL) + + desktopdir = $(datadir)/applications + Desktop_in_files = cinnamon-region-panel.desktop.in +diff -uNrp a/panels/region/region-module.c b/panels/region/region-module.c +--- a/panels/region/region-module.c 2013-08-25 14:40:14.000000000 +0100 ++++ b/panels/region/region-module.c 2013-09-21 13:24:15.347949247 +0100 +@@ -28,6 +28,7 @@ + void + g_io_module_load (GIOModule * module) + { ++ + /* register the panel */ + cc_region_panel_register (module); + } diff --git a/pkgs/desktops/gnome-3/core/gnome-control-center/default.nix b/pkgs/desktops/gnome-3/core/gnome-control-center/default.nix index ac8b362839c0..1222f03d66e3 100644 --- a/pkgs/desktops/gnome-3/core/gnome-control-center/default.nix +++ b/pkgs/desktops/gnome-3/core/gnome-control-center/default.nix @@ -51,6 +51,8 @@ stdenv.mkDerivation rec { rm $out/share/icons/hicolor/icon-theme.cache ''; + patches = [ ./search_providers_dir.patch ]; + meta = with stdenv.lib; { description = "Single sign-on framework for GNOME"; maintainers = with maintainers; [ lethalman ]; diff --git a/pkgs/desktops/gnome-3/core/gnome-control-center/search_providers_dir.patch b/pkgs/desktops/gnome-3/core/gnome-control-center/search_providers_dir.patch new file mode 100644 index 000000000000..7f5ad970f34e --- /dev/null +++ b/pkgs/desktops/gnome-3/core/gnome-control-center/search_providers_dir.patch @@ -0,0 +1,17 @@ +diff --git a/panels/search/cc-search-panel.c b/panels/search/cc-search-panel.c +index d08e230..3bff4ad 100644 +--- a/panels/search/cc-search-panel.c ++++ b/panels/search/cc-search-panel.c +@@ -574,7 +574,11 @@ populate_search_providers (CcSearchPanel *self) + { + GFile *providers_location; + +- providers_location = g_file_new_for_path (DATADIR "/gnome-shell/search-providers"); ++ const gchar* search_providers_dir = g_getenv ("GNOME_SEARCH_PROVIDERS_DIR"); ++ if (search_providers_dir == NULL) { ++ search_providers_dir = DATADIR "/gnome-shell/search-providers"; ++ } ++ providers_location = g_file_new_for_path (search_providers_dir); + g_file_enumerate_children_async (providers_location, + "standard::type,standard::name,standard::content-type", + G_FILE_QUERY_INFO_NONE, diff --git a/pkgs/development/libraries/webkit/bison26.patch b/pkgs/development/libraries/webkit/bison26.patch deleted file mode 100644 index 95898adeb8a6..000000000000 --- a/pkgs/development/libraries/webkit/bison26.patch +++ /dev/null @@ -1,515 +0,0 @@ -Index: /trunk/Source/WebCore/ChangeLog -=================================================================== ---- /trunk/Source/WebCore/ChangeLog (revision 124098) -+++ /trunk/Source/WebCore/ChangeLog (revision 124099) -@@ -1,2 +1,27 @@ -+2012-07-30 Alexis Menard <alexis.menard@openbossa.org> -+ -+ Build fix with newer bison 2.6. -+ https://bugs.webkit.org/show_bug.cgi?id=92264 -+ -+ Reviewed by Adam Barth. -+ -+ As stated in http://www.gnu.org/software/bison/manual/html_node/Table-of-Symbols.html -+ YYLEX_PARAM and YYPARSE_PARAM are depecreated since version 1.875. So far all Mac OS -+ version I had access to as well as recent Linux runs at least version 2.3 so it's safe -+ to use the replacement of these deprecated macros in favor of %lex-param and %parse-param. -+ As announced http://lists.gnu.org/archive/html/info-gnu/2012-07/msg00011.html with the release -+ of version 2.6 YYLEX_PARAM and YYPARSE_PARAM are not supported anymore. -+ -+ No new tests : build fix and the patch should not trigger any regressions -+ -+ * css/CSSGrammar.y: -+ * css/CSSParser.cpp: -+ * xml/XPathGrammar.y: Refactored a bit to not use an intermediate PARSER define. -+ * xml/XPathParser.cpp: bison 2.6 declare xpathyyparse in the .h file now, i.e. XPathGrammar.h -+ therefore including this file within the namespace {} declarations leads to xpathyyparse being -+ defined part of WebCore::XPath namespaces but the actual implementation of xpathyyparse is in XPathGrammar.cpp -+ (generated) and not implemented within the WebCore::XPath so it lead to linking issues. Last, XPathGrammar.h needs -+ to be included after the other includes as it uses some XPath types. It breaks the style but CSSParser.cpp is doing the same. -+ - 2012-07-30 Sadrul Habib Chowdhury <sadrul@chromium.org> - -Index: /trunk/Source/WebCore/css/CSSParser.cpp -=================================================================== ---- /trunk/Source/WebCore/css/CSSParser.cpp (revision 124098) -+++ /trunk/Source/WebCore/css/CSSParser.cpp (revision 124099) -@@ -115,5 +115,5 @@ - #endif - --extern int cssyyparse(void* parser); -+extern int cssyyparse(WebCore::CSSParser*); - - using namespace std; -Index: /trunk/Source/WebCore/css/CSSGrammar.y -=================================================================== ---- /trunk/Source/WebCore/css/CSSGrammar.y (revision 124098) -+++ /trunk/Source/WebCore/css/CSSGrammar.y (revision 124099) -@@ -54,11 +54,10 @@ - #define YYDEBUG 0 - --// FIXME: Replace with %parse-param { CSSParser* parser } once we can depend on bison 2.x --#define YYPARSE_PARAM parser --#define YYLEX_PARAM parser -- - %} - - %pure_parser -+ -+%parse-param { CSSParser* parser } -+%lex-param { CSSParser* parser } - - %union { -@@ -90,5 +89,5 @@ - %{ - --static inline int cssyyerror(const char*) -+static inline int cssyyerror(void*, const char*) - { - return 1; -Index: /trunk/Source/WebCore/xml/XPathParser.cpp -=================================================================== ---- /trunk/Source/WebCore/xml/XPathParser.cpp (revision 124098) -+++ /trunk/Source/WebCore/xml/XPathParser.cpp (revision 124099) -@@ -33,22 +33,19 @@ - #include "XPathException.h" - #include "XPathNSResolver.h" -+#include "XPathPath.h" - #include "XPathStep.h" - #include <wtf/StdLibExtras.h> - #include <wtf/text/StringHash.h> - --int xpathyyparse(void*); -- -+using namespace WebCore; - using namespace WTF; - using namespace Unicode; -- --namespace WebCore { --namespace XPath { -- --class LocationPath; -- --#include "XPathGrammar.h" -+using namespace XPath; -+ -+extern int xpathyyparse(WebCore::XPath::Parser*); -+#include "XPathGrammar.h" - - Parser* Parser::currentParser = 0; -- -+ - enum XMLCat { NameStart, NameCont, NotPartOfName }; - -@@ -631,4 +628,2 @@ - } - --} --} -Index: /trunk/Source/WebCore/xml/XPathGrammar.y -=================================================================== ---- /trunk/Source/WebCore/xml/XPathGrammar.y (revision 124098) -+++ /trunk/Source/WebCore/xml/XPathGrammar.y (revision 124099) -@@ -35,4 +35,5 @@ - #include "XPathPath.h" - #include "XPathPredicate.h" -+#include "XPathStep.h" - #include "XPathVariableReference.h" - #include <wtf/FastMalloc.h> -@@ -45,6 +46,4 @@ - #define YYDEBUG 0 - #define YYMAXDEPTH 10000 --#define YYPARSE_PARAM parserParameter --#define PARSER static_cast<Parser*>(parserParameter) - - using namespace WebCore; -@@ -54,4 +53,5 @@ - - %pure_parser -+%parse-param { WebCore::XPath::Parser* parser } - - %union -@@ -72,5 +72,5 @@ - - static int xpathyylex(YYSTYPE* yylval) { return Parser::current()->lex(yylval); } --static void xpathyyerror(const char*) { } -+static void xpathyyerror(void*, const char*) { } - - %} -@@ -119,5 +119,5 @@ - OrExpr - { -- PARSER->m_topExpr = $1; -+ parser->m_topExpr = $1; - } - ; -@@ -139,5 +139,5 @@ - { - $$ = new LocationPath; -- PARSER->registerParseNode($$); -+ parser->registerParseNode($$); - } - | -@@ -151,5 +151,5 @@ - $$ = $2; - $$->insertFirstStep($1); -- PARSER->unregisterParseNode($1); -+ parser->unregisterParseNode($1); - } - ; -@@ -160,6 +160,6 @@ - $$ = new LocationPath; - $$->appendStep($1); -- PARSER->unregisterParseNode($1); -- PARSER->registerParseNode($$); -+ parser->unregisterParseNode($1); -+ parser->registerParseNode($$); - } - | -@@ -167,5 +167,5 @@ - { - $$->appendStep($3); -- PARSER->unregisterParseNode($3); -+ parser->unregisterParseNode($3); - } - | -@@ -174,6 +174,6 @@ - $$->appendStep($2); - $$->appendStep($3); -- PARSER->unregisterParseNode($2); -- PARSER->unregisterParseNode($3); -+ parser->unregisterParseNode($2); -+ parser->unregisterParseNode($3); - } - ; -@@ -184,9 +184,9 @@ - if ($2) { - $$ = new Step(Step::ChildAxis, *$1, *$2); -- PARSER->deletePredicateVector($2); -+ parser->deletePredicateVector($2); - } else - $$ = new Step(Step::ChildAxis, *$1); -- PARSER->deleteNodeTest($1); -- PARSER->registerParseNode($$); -+ parser->deleteNodeTest($1); -+ parser->registerParseNode($$); - } - | -@@ -195,6 +195,6 @@ - String localName; - String namespaceURI; -- if (!PARSER->expandQName(*$1, localName, namespaceURI)) { -- PARSER->m_gotNamespaceError = true; -+ if (!parser->expandQName(*$1, localName, namespaceURI)) { -+ parser->m_gotNamespaceError = true; - YYABORT; - } -@@ -202,9 +202,9 @@ - if ($2) { - $$ = new Step(Step::ChildAxis, Step::NodeTest(Step::NodeTest::NameTest, localName, namespaceURI), *$2); -- PARSER->deletePredicateVector($2); -+ parser->deletePredicateVector($2); - } else - $$ = new Step(Step::ChildAxis, Step::NodeTest(Step::NodeTest::NameTest, localName, namespaceURI)); -- PARSER->deleteString($1); -- PARSER->registerParseNode($$); -+ parser->deleteString($1); -+ parser->registerParseNode($$); - } - | -@@ -213,9 +213,9 @@ - if ($3) { - $$ = new Step($1, *$2, *$3); -- PARSER->deletePredicateVector($3); -+ parser->deletePredicateVector($3); - } else - $$ = new Step($1, *$2); -- PARSER->deleteNodeTest($2); -- PARSER->registerParseNode($$); -+ parser->deleteNodeTest($2); -+ parser->registerParseNode($$); - } - | -@@ -224,6 +224,6 @@ - String localName; - String namespaceURI; -- if (!PARSER->expandQName(*$2, localName, namespaceURI)) { -- PARSER->m_gotNamespaceError = true; -+ if (!parser->expandQName(*$2, localName, namespaceURI)) { -+ parser->m_gotNamespaceError = true; - YYABORT; - } -@@ -231,9 +231,9 @@ - if ($3) { - $$ = new Step($1, Step::NodeTest(Step::NodeTest::NameTest, localName, namespaceURI), *$3); -- PARSER->deletePredicateVector($3); -+ parser->deletePredicateVector($3); - } else - $$ = new Step($1, Step::NodeTest(Step::NodeTest::NameTest, localName, namespaceURI)); -- PARSER->deleteString($2); -- PARSER->registerParseNode($$); -+ parser->deleteString($2); -+ parser->registerParseNode($$); - } - | -@@ -260,6 +260,6 @@ - $$ = new Step::NodeTest(Step::NodeTest::CommentNodeTest); - -- PARSER->deleteString($1); -- PARSER->registerNodeTest($$); -+ parser->deleteString($1); -+ parser->registerNodeTest($$); - } - | -@@ -267,6 +267,6 @@ - { - $$ = new Step::NodeTest(Step::NodeTest::ProcessingInstructionNodeTest); -- PARSER->deleteString($1); -- PARSER->registerNodeTest($$); -+ parser->deleteString($1); -+ parser->registerNodeTest($$); - } - | -@@ -274,7 +274,7 @@ - { - $$ = new Step::NodeTest(Step::NodeTest::ProcessingInstructionNodeTest, $3->stripWhiteSpace()); -- PARSER->deleteString($1); -- PARSER->deleteString($3); -- PARSER->registerNodeTest($$); -+ parser->deleteString($1); -+ parser->deleteString($3); -+ parser->registerNodeTest($$); - } - ; -@@ -294,6 +294,6 @@ - $$ = new Vector<Predicate*>; - $$->append(new Predicate($1)); -- PARSER->unregisterParseNode($1); -- PARSER->registerPredicateVector($$); -+ parser->unregisterParseNode($1); -+ parser->registerPredicateVector($$); - } - | -@@ -301,5 +301,5 @@ - { - $$->append(new Predicate($2)); -- PARSER->unregisterParseNode($2); -+ parser->unregisterParseNode($2); - } - ; -@@ -316,5 +316,5 @@ - { - $$ = new Step(Step::DescendantOrSelfAxis, Step::NodeTest(Step::NodeTest::AnyNodeTest)); -- PARSER->registerParseNode($$); -+ parser->registerParseNode($$); - } - ; -@@ -324,5 +324,5 @@ - { - $$ = new Step(Step::SelfAxis, Step::NodeTest(Step::NodeTest::AnyNodeTest)); -- PARSER->registerParseNode($$); -+ parser->registerParseNode($$); - } - | -@@ -330,5 +330,5 @@ - { - $$ = new Step(Step::ParentAxis, Step::NodeTest(Step::NodeTest::AnyNodeTest)); -- PARSER->registerParseNode($$); -+ parser->registerParseNode($$); - } - ; -@@ -338,6 +338,6 @@ - { - $$ = new VariableReference(*$1); -- PARSER->deleteString($1); -- PARSER->registerParseNode($$); -+ parser->deleteString($1); -+ parser->registerParseNode($$); - } - | -@@ -350,6 +350,6 @@ - { - $$ = new StringExpression(*$1); -- PARSER->deleteString($1); -- PARSER->registerParseNode($$); -+ parser->deleteString($1); -+ parser->registerParseNode($$); - } - | -@@ -357,6 +357,6 @@ - { - $$ = new Number($1->toDouble()); -- PARSER->deleteString($1); -- PARSER->registerParseNode($$); -+ parser->deleteString($1); -+ parser->registerParseNode($$); - } - | -@@ -370,6 +370,6 @@ - if (!$$) - YYABORT; -- PARSER->deleteString($1); -- PARSER->registerParseNode($$); -+ parser->deleteString($1); -+ parser->registerParseNode($$); - } - | -@@ -379,7 +379,7 @@ - if (!$$) - YYABORT; -- PARSER->deleteString($1); -- PARSER->deleteExpressionVector($3); -- PARSER->registerParseNode($$); -+ parser->deleteString($1); -+ parser->deleteExpressionVector($3); -+ parser->registerParseNode($$); - } - ; -@@ -390,6 +390,6 @@ - $$ = new Vector<Expression*>; - $$->append($1); -- PARSER->unregisterParseNode($1); -- PARSER->registerExpressionVector($$); -+ parser->unregisterParseNode($1); -+ parser->registerExpressionVector($$); - } - | -@@ -397,5 +397,5 @@ - { - $$->append($3); -- PARSER->unregisterParseNode($3); -+ parser->unregisterParseNode($3); - } - ; -@@ -413,7 +413,7 @@ - $$->addSubExpression($1); - $$->addSubExpression($3); -- PARSER->unregisterParseNode($1); -- PARSER->unregisterParseNode($3); -- PARSER->registerParseNode($$); -+ parser->unregisterParseNode($1); -+ parser->unregisterParseNode($3); -+ parser->registerParseNode($$); - } - ; -@@ -431,7 +431,7 @@ - $3->setAbsolute(true); - $$ = new Path(static_cast<Filter*>($1), $3); -- PARSER->unregisterParseNode($1); -- PARSER->unregisterParseNode($3); -- PARSER->registerParseNode($$); -+ parser->unregisterParseNode($1); -+ parser->unregisterParseNode($3); -+ parser->registerParseNode($$); - } - | -@@ -441,8 +441,8 @@ - $3->setAbsolute(true); - $$ = new Path(static_cast<Filter*>($1), $3); -- PARSER->unregisterParseNode($1); -- PARSER->unregisterParseNode($2); -- PARSER->unregisterParseNode($3); -- PARSER->registerParseNode($$); -+ parser->unregisterParseNode($1); -+ parser->unregisterParseNode($2); -+ parser->unregisterParseNode($3); -+ parser->registerParseNode($$); - } - ; -@@ -454,7 +454,7 @@ - { - $$ = new Filter($1, *$2); -- PARSER->unregisterParseNode($1); -- PARSER->deletePredicateVector($2); -- PARSER->registerParseNode($$); -+ parser->unregisterParseNode($1); -+ parser->deletePredicateVector($2); -+ parser->registerParseNode($$); - } - ; -@@ -466,7 +466,7 @@ - { - $$ = new LogicalOp(LogicalOp::OP_Or, $1, $3); -- PARSER->unregisterParseNode($1); -- PARSER->unregisterParseNode($3); -- PARSER->registerParseNode($$); -+ parser->unregisterParseNode($1); -+ parser->unregisterParseNode($3); -+ parser->registerParseNode($$); - } - ; -@@ -478,7 +478,7 @@ - { - $$ = new LogicalOp(LogicalOp::OP_And, $1, $3); -- PARSER->unregisterParseNode($1); -- PARSER->unregisterParseNode($3); -- PARSER->registerParseNode($$); -+ parser->unregisterParseNode($1); -+ parser->unregisterParseNode($3); -+ parser->registerParseNode($$); - } - ; -@@ -490,7 +490,7 @@ - { - $$ = new EqTestOp($2, $1, $3); -- PARSER->unregisterParseNode($1); -- PARSER->unregisterParseNode($3); -- PARSER->registerParseNode($$); -+ parser->unregisterParseNode($1); -+ parser->unregisterParseNode($3); -+ parser->registerParseNode($$); - } - ; -@@ -502,7 +502,7 @@ - { - $$ = new EqTestOp($2, $1, $3); -- PARSER->unregisterParseNode($1); -- PARSER->unregisterParseNode($3); -- PARSER->registerParseNode($$); -+ parser->unregisterParseNode($1); -+ parser->unregisterParseNode($3); -+ parser->registerParseNode($$); - } - ; -@@ -514,7 +514,7 @@ - { - $$ = new NumericOp(NumericOp::OP_Add, $1, $3); -- PARSER->unregisterParseNode($1); -- PARSER->unregisterParseNode($3); -- PARSER->registerParseNode($$); -+ parser->unregisterParseNode($1); -+ parser->unregisterParseNode($3); -+ parser->registerParseNode($$); - } - | -@@ -522,7 +522,7 @@ - { - $$ = new NumericOp(NumericOp::OP_Sub, $1, $3); -- PARSER->unregisterParseNode($1); -- PARSER->unregisterParseNode($3); -- PARSER->registerParseNode($$); -+ parser->unregisterParseNode($1); -+ parser->unregisterParseNode($3); -+ parser->registerParseNode($$); - } - ; -@@ -534,7 +534,7 @@ - { - $$ = new NumericOp($2, $1, $3); -- PARSER->unregisterParseNode($1); -- PARSER->unregisterParseNode($3); -- PARSER->registerParseNode($$); -+ parser->unregisterParseNode($1); -+ parser->unregisterParseNode($3); -+ parser->registerParseNode($$); - } - ; -@@ -547,6 +547,6 @@ - $$ = new Negative; - $$->addSubExpression($2); -- PARSER->unregisterParseNode($2); -- PARSER->registerParseNode($$); -+ parser->unregisterParseNode($2); -+ parser->registerParseNode($$); - } - ; diff --git a/pkgs/development/libraries/webkit/default.nix b/pkgs/development/libraries/webkit/default.nix deleted file mode 100644 index ef4d259cb029..000000000000 --- a/pkgs/development/libraries/webkit/default.nix +++ /dev/null @@ -1,106 +0,0 @@ -args : with args; -let - s = import ./src-for-default.nix; # 1.8.3 needs newer gtk3, wait for x-updates - version = lib.attrByPath ["version"] s.version args; -in -rec { - src = fetchurl { - url = s.url; - sha256 = s.hash; - }; - - buildInputs = with xlibs; [ - pkgconfig libtool intltool autoconf automake gperf bison flex - gtk3 gtk2 glib atk cairo pango fontconfig freetype libsoup gtkdoc - libjpeg libpng libtiff libxml2 libxslt sqlite icu curl - which libproxy geoclue enchant python ruby perl - mesa libXt libXrender renderproto libXcomposite compositeproto - libXdamage damageproto kbproto - ]; - - propagatedBuildInputs = [ - gstreamer gst_plugins_base gst_ffmpeg gst_plugins_good - ]; - - configureFlags = [ - # "--enable-3D-transforms" # no longer recognized - "--enable-web-sockets" - "--enable-web-timing" - - # https://bugs.webkit.org/show_bug.cgi?id=55294 - "--enable-image-resizer" - - "--enable-geolocation" - - # Not implemented? - # "--enable-web-audio" - - "--enable-mathml" - - #"--enable-wml" - - # https://bugs.webkit.org/show_bug.cgi?id=45110 - #"--enable-indexed-database" - - # Doesn't work in release... - #"--enable-xhtmlmp" - - # "--enable-input-speech" - - #"--enable-file-writer" # no longer recognized - "--enable-blob" - - # https://bugs.webkit.org/show_bug.cgi?id=59430 - # "--enable-directory-upload" - - # https://bugs.webkit.org/show_bug.cgi?id=58443 - # "--enable-file-system" - - "--enable-dependency-tracking" # to fix parallel building - ]; - - # instead of enableParallelBuilding = true; - makeFlags = "-j$NIX_BUILD_CORES"; - - /* doConfigure should be specified separately */ - phaseNames = ["doPatch" "fixConfigure" /* "paranoidFixComments" */ "doConfigure" (doPatchShebangs ".") - "doReplaceUsrBin" "doMakeInstall" "doAddPrograms"]; - - patches = [ ./bison26.patch ]; # http://trac.webkit.org/changeset/124099 - patchFlags = "-p2"; - - #doCheck = true; # tests still have problems - - doReplaceUsrBin = fullDepEntry ('' - for i in $(find . -name '*.pl') $(find . -name '*.pm'); do - sed -e 's@/usr/bin/gcc@gcc@' -i $i - done - '') ["minInit" "doUnpack"]; - - doAddPrograms = fullDepEntry ('' - mkdir -p $out/bin - for i in Programs/.libs/* Programs/*; do - cp $i $out/bin/webkit-program-$(basename $i) || true - done - '') ["minInit" "doMake" "defEnsureDir"]; - - paranoidFixComments = fullDepEntry ('' - sed -re 's@( |^)//.*@/* & */@' -i $(find . -name '*.c' -o -name '*.h') - '') ["minInit" "doUnpack"]; - - # See http://archive.linuxfromscratch.org/mail-archives/blfs-dev/2012-April/022893.html - fixConfigure = fullDepEntry ('' - sed -i -e 's/=GSTREAMER_0_10_REQUIRED_VERSION/=\$GSTREAMER_0_10_REQUIRED_VERSION/' \ - -e 's/=GSTREAMER_0_10_PLUGINS_BASE_REQUIRED_VERSION/=\$GSTREAMER_0_10_PLUGINS_BASE_REQUIRED_VERSION/' \ - configure{,.ac} - '') ["minInit" "doUnpack"]; - - name = s.name; - meta = { - description = "WebKit - a fast and correct HTML renderer"; - maintainers = [stdenv.lib.maintainers.raskin]; - }; - passthru = { - inherit gstreamer gst_plugins_base gst_plugins_good gst_ffmpeg libsoup; - }; -} diff --git a/pkgs/development/libraries/webkit/gtk2.nix b/pkgs/development/libraries/webkit/gtk2.nix deleted file mode 100644 index c2e3b9b06dd6..000000000000 --- a/pkgs/development/libraries/webkit/gtk2.nix +++ /dev/null @@ -1,109 +0,0 @@ - -args : with args; -let - s = import ./src-for-gtk2.nix; - version = lib.attrByPath ["version"] s.version args; -in -rec { - src = fetchurl { - url = s.url; - sha256 = s.hash; - }; - - buildInputs = with xlibs; [ - pkgconfig libtool intltool autoconf automake gperf bison flex - gtk2 glib atk cairo pango fontconfig freetype libsoup gtkdoc - libjpeg libpng libtiff libxml2 libxslt sqlite icu curl - which libproxy geoclue enchant python ruby perl - mesa libXt libXrender renderproto libXcomposite compositeproto - libXdamage damageproto kbproto - ]; - - propagatedBuildInputs = [ - gstreamer gst_plugins_base gst_ffmpeg gst_plugins_good - ]; - - configureFlags = [ - "--with-gtk=2.0" - - # "--enable-3D-transforms" # no longer recognized - "--enable-web-sockets" - "--enable-web-timing" - - # https://bugs.webkit.org/show_bug.cgi?id=55294 - "--enable-image-resizer" - - "--enable-geolocation" - - # Not implemented? - # "--enable-web-audio" - - "--enable-mathml" - - #"--enable-wml" - - # https://bugs.webkit.org/show_bug.cgi?id=45110 - #"--enable-indexed-database" - - # Doesn't work in release... - #"--enable-xhtmlmp" - - # "--enable-input-speech" - - #"--enable-file-writer" # no longer recognized - "--enable-blob" - - # https://bugs.webkit.org/show_bug.cgi?id=59430 - # "--enable-directory-upload" - - # https://bugs.webkit.org/show_bug.cgi?id=58443 - # "--enable-file-system" - - "--enable-dependency-tracking" # to fix parallel building - ]; - - # instead of enableParallelBuilding = true; - makeFlags = "-j$NIX_BUILD_CORES"; - - /* doConfigure should be specified separately */ - phaseNames = ["doPatch" "fixConfigure" /* "paranoidFixComments" */ "doConfigure" (doPatchShebangs ".") - "doReplaceUsrBin" "doMakeInstall" "doAddPrograms"]; - - patches = [ ./bison26.patch ]; # http://trac.webkit.org/changeset/124099 - patchFlags = "-p2"; - - #doCheck = true; # tests still have problems - - doReplaceUsrBin = fullDepEntry ('' - for i in $(find . -name '*.pl') $(find . -name '*.pm'); do - sed -e 's@/usr/bin/gcc@gcc@' -i $i - done - '') ["minInit" "doUnpack"]; - - doAddPrograms = fullDepEntry ('' - mkdir -p $out/bin - for i in Programs/.libs/* Programs/*; do - cp $i $out/bin/webkit-program-$(basename $i) || true - done - '') ["minInit" "doMake" "defEnsureDir"]; - - paranoidFixComments = fullDepEntry ('' - sed -re 's@( |^)//.*@/* & */@' -i $(find . -name '*.c' -o -name '*.h') - '') ["minInit" "doUnpack"]; - - # See http://archive.linuxfromscratch.org/mail-archives/blfs-dev/2012-April/022893.html - fixConfigure = fullDepEntry ('' - sed -i -e 's/=GSTREAMER_0_10_REQUIRED_VERSION/=\$GSTREAMER_0_10_REQUIRED_VERSION/' \ - -e 's/=GSTREAMER_0_10_PLUGINS_BASE_REQUIRED_VERSION/=\$GSTREAMER_0_10_PLUGINS_BASE_REQUIRED_VERSION/' \ - configure{,.ac} - '') ["minInit" "doUnpack"]; - - name = s.name; - meta = { - description = "WebKit - a fast and correct HTML renderer"; - maintainers = [stdenv.lib.maintainers.raskin]; - }; - passthru = { - inherit gstreamer gst_plugins_base gst_plugins_good gst_ffmpeg libsoup; - }; -} diff --git a/pkgs/development/libraries/webkit/src-for-default.nix b/pkgs/development/libraries/webkit/src-for-default.nix deleted file mode 100644 index 65bcd4350960..000000000000 --- a/pkgs/development/libraries/webkit/src-for-default.nix +++ /dev/null @@ -1,10 +0,0 @@ -rec { - version="1.8.1"; - name="webkit-1.8.1"; - hash="0a1v3v8dp2cl332qr51j4fpl0rwpgxbf29hn3zdim9hcniv6l4ls"; - url="http://webkitgtk.org/releases/webkit-1.8.1.tar.xz"; - advertisedUrl="http://webkitgtk.org/releases/webkit-1.8.1.tar.xz"; - - -} - diff --git a/pkgs/development/libraries/webkit/src-for-gtk2.nix b/pkgs/development/libraries/webkit/src-for-gtk2.nix deleted file mode 100644 index 65bcd4350960..000000000000 --- a/pkgs/development/libraries/webkit/src-for-gtk2.nix +++ /dev/null @@ -1,10 +0,0 @@ -rec { - version="1.8.1"; - name="webkit-1.8.1"; - hash="0a1v3v8dp2cl332qr51j4fpl0rwpgxbf29hn3zdim9hcniv6l4ls"; - url="http://webkitgtk.org/releases/webkit-1.8.1.tar.xz"; - advertisedUrl="http://webkitgtk.org/releases/webkit-1.8.1.tar.xz"; - - -} - diff --git a/pkgs/development/libraries/webkit/src-for-svn.nix b/pkgs/development/libraries/webkit/src-for-svn.nix deleted file mode 100644 index f90bafbf6dc3..000000000000 --- a/pkgs/development/libraries/webkit/src-for-svn.nix +++ /dev/null @@ -1,9 +0,0 @@ -rec { - version="r86499"; - name="webkit-r86499"; - hash="04sfwri81x2d9y3z0v7rhrr40vn0bxcbnhb8a0gymqkwa1ngpzmp"; - url="http://builds.nightly.webkit.org/files/trunk/src/WebKit-r86499.tar.bz2"; - advertisedUrl="http://builds.nightly.webkit.org/files/trunk/src/WebKit-r86499.tar.bz2"; - - -} diff --git a/pkgs/development/libraries/webkit/src-info-for-default.nix b/pkgs/development/libraries/webkit/src-info-for-default.nix deleted file mode 100644 index c4e5b8a6fd6e..000000000000 --- a/pkgs/development/libraries/webkit/src-info-for-default.nix +++ /dev/null @@ -1,6 +0,0 @@ -{ - downloadPage = "http://webkitgtk.org/?page=download"; - versionExtractorSedScript = "s/.*-([.0-9]+)[.].*/\\1/"; - versionReferenceCreator = "s/-([.0-9.]+)[.]/-\${version}./"; - baseName = "webkit"; -} diff --git a/pkgs/development/libraries/webkit/src-info-for-svn.nix b/pkgs/development/libraries/webkit/src-info-for-svn.nix deleted file mode 100644 index 994cae544cb2..000000000000 --- a/pkgs/development/libraries/webkit/src-info-for-svn.nix +++ /dev/null @@ -1,6 +0,0 @@ -{ - downloadPage = "http://nightly.webkit.org/"; - versionExtractorSedScript = "s/.*-(r[0-9]+)[.].*/\\1/"; - versionReferenceCreator = "s/-(r[0-9.]+)[.]/-\${version}./"; - baseName = "webkit"; -} diff --git a/pkgs/development/python-modules/virtualenv-change-prefix.patch b/pkgs/development/python-modules/virtualenv-change-prefix.patch index d3e588bd1cd2..958187f982fe 100644 --- a/pkgs/development/python-modules/virtualenv-change-prefix.patch +++ b/pkgs/development/python-modules/virtualenv-change-prefix.patch @@ -1,8 +1,23 @@ -Without this patch `virtualenv --python=python2.7 .` fails with an error because it notices that the python readline.so is not in the same path as python2.7. I assume this is to avoid copying the wrong file on systems where it is possible to find incompatible libraries by accident. Adding "/nix/store" to the prefix fixes this problem. Unfortunately readline is still not available if you just run `virtualenv .`. +Without this patch `virtualenv --python=python2.7 .` fails with an +error because it notices that the python readline.so is not in the +same path as python2.7. I assume this is to avoid copying the wrong +file on systems where it is possible to find incompatible libraries by +accident. Adding "/nix/store" to the prefix fixes this problem. ---- virtualenv-1.8.4/virtualenv.py 2013-01-16 23:43:37.583615220 +0100 -+++ virtualenv-1.8.4/virtualenv.py 2013-01-16 23:44:47.885973431 +0100 -@@ -1135,17 +1135,7 @@ +A sitecustomize.py is created in the virtualenv which makes libraries +from the python specified by the --python argument available to the +virtualenv. For example, this makes readline and sqlite3 available +when a wrapped python is specified. If no --python argument is passed, +it will only add the path to the python used when building +`virtualenv`, which is the unwrapped python, so sqlite3 won't be +available. + + +diff --git a/virtualenv.py b/virtualenv.py +index d3e76a7..cb307fa 100755 +--- a/virtualenv.py ++++ b/virtualenv.py +@@ -1051,17 +1051,7 @@ def path_locations(home_dir): def change_prefix(filename, dst_prefix): @@ -21,7 +36,7 @@ Without this patch `virtualenv --python=python2.7 .` fails with an error because if hasattr(sys, 'real_prefix'): prefixes.append(sys.real_prefix) -@@ -1162,6 +1152,8 @@ +@@ -1078,6 +1068,8 @@ def change_prefix(filename, dst_prefix): if src_prefix != os.sep: # sys.prefix == "/" assert relpath[0] == os.sep relpath = relpath[1:] @@ -30,3 +45,15 @@ Without this patch `virtualenv --python=python2.7 .` fails with an error because return join(dst_prefix, relpath) assert False, "Filename %s does not start with any of these prefixes: %s" % \ (filename, prefixes) +@@ -1190,6 +1182,11 @@ def install_python(home_dir, lib_dir, inc_dir, bin_dir, site_packages, clear, sy + site_filename_dst = change_prefix(site_filename, home_dir) + site_dir = os.path.dirname(site_filename_dst) + writefile(site_filename_dst, SITE_PY) ++ wrapper_path = join(prefix, "lib", py_version, "site-packages") ++ writefile( ++ join(site_dir, 'sitecustomize.py',), ++ "import sys; sys.path.append('%s')" % wrapper_path ++ ) + writefile(join(site_dir, 'orig-prefix.txt'), prefix) + site_packages_filename = join(site_dir, 'no-global-site-packages.txt') + if not site_packages: diff --git a/pkgs/tools/misc/apparix/default.nix b/pkgs/tools/misc/apparix/default.nix new file mode 100644 index 000000000000..693ca27a88d9 --- /dev/null +++ b/pkgs/tools/misc/apparix/default.nix @@ -0,0 +1,20 @@ +{ stdenv, fetchurl }: + +stdenv.mkDerivation rec { + name = "apparix-11-062"; + + src = fetchurl { + url = "http://micans.org/apparix/src/${name}.tar.gz"; + sha256 = "211bb5f67b32ba7c3e044a13e4e79eb998ca017538e9f4b06bc92d5953615235"; + }; + + doCheck = true; + + meta = with stdenv.lib; { + homepage = http://micans.org/apparix; + description = "Add directory bookmarks, distant listing, and distant editing to the command line"; + maintainers = with maintainers; [ lethalman ]; + license = licenses.gpl2; + platforms = platforms.linux; + }; +} diff --git a/pkgs/tools/networking/dnsmasq/default.nix b/pkgs/tools/networking/dnsmasq/default.nix index 0c5dfc6fd748..d8f62913ad50 100644 --- a/pkgs/tools/networking/dnsmasq/default.nix +++ b/pkgs/tools/networking/dnsmasq/default.nix @@ -1,11 +1,11 @@ { stdenv, fetchurl }: stdenv.mkDerivation rec { - name = "dnsmasq-2.68"; + name = "dnsmasq-2.69"; src = fetchurl { url = "http://www.thekelleys.org.uk/dnsmasq/${name}.tar.gz"; - sha256 = "0bvw16i83ybiajskma59zjiqw59vzlcqf8f69k0crwak3zb1j820"; + sha256 = "1zf4d6kjbsn6gwfwvmch1y84q67na1qhh0gyd50ip1vjsmw2l4i7"; }; makeFlags = "DESTDIR= BINDIR=$(out)/bin MANDIR=$(out)/man LOCALEDIR=$(out)/share/locale"; diff --git a/pkgs/top-level/all-packages.nix b/pkgs/top-level/all-packages.nix index 05c07c2c917f..ae947c552b73 100644 --- a/pkgs/top-level/all-packages.nix +++ b/pkgs/top-level/all-packages.nix @@ -270,7 +270,7 @@ let buildFHSChrootEnv = import ../build-support/build-fhs-chrootenv { inherit stdenv glibc glibcLocales gcc coreutils diffutils findutils; inherit gnused gnugrep gnutar gzip bzip2 bashInteractive xz shadow gawk; - inherit less buildEnv; + inherit less su buildEnv; }; dotnetenv = import ../build-support/dotnetenv { @@ -606,6 +606,8 @@ let mcelog = callPackage ../os-specific/linux/mcelog { }; + apparix = callPackage ../tools/misc/apparix { }; + asciidoc = callPackage ../tools/typesetting/asciidoc { inherit (pythonPackages) matplotlib numpy aafigure recursivePthLoader; enableStandardFeatures = false; @@ -5980,28 +5982,7 @@ let wayland = callPackage ../development/libraries/wayland { }; - webkit = - builderDefsPackage ../development/libraries/webkit { - inherit gtk2; # for plugins etc. even with gtk3, see Gentoo ebuild - inherit gtk3 glib atk cairo pango fontconfig freetype; - inherit (gnome) gtkdoc libsoup; - inherit pkgconfig libtool intltool autoconf automake gperf flex - libjpeg libpng libtiff libxml2 libxslt sqlite icu curl - which libproxy geoclue enchant python ruby perl mesa xlibs; - inherit gstreamer gst_plugins_base gst_ffmpeg gst_plugins_good; - bison = bison2; - }; - - webkit_gtk2 = - builderDefsPackage ../development/libraries/webkit/gtk2.nix { - inherit gtk2 glib atk cairo pango fontconfig freetype; - inherit (gnome) gtkdoc libsoup; - inherit pkgconfig libtool intltool autoconf automake gperf flex - libjpeg libpng libtiff libxml2 libxslt sqlite icu curl - which libproxy geoclue enchant python ruby perl mesa xlibs; - inherit gstreamer gst_plugins_base gst_ffmpeg gst_plugins_good; - bison = bison2; - }; + webkit = webkitgtk; webkitgtk = callPackage ../development/libraries/webkitgtk { harfbuzz = harfbuzz.override { @@ -8853,6 +8834,8 @@ let opusTools = callPackage ../applications/audio/opus-tools { }; + pamixer = callPackage ../applications/audio/pamixer { }; + pan = callPackage ../applications/networking/newsreaders/pan { spellChecking = false; }; @@ -9126,8 +9109,7 @@ let }); surf = callPackage ../applications/misc/surf { - libsoup = gnome.libsoup; - webkit = webkit_gtk2; + webkit = webkitgtk2; }; svk = perlPackages.SVK; @@ -9195,6 +9177,14 @@ let inherit (gnome) libIDL; }; + thunderbird-bin = callPackage ../applications/networking/mailreaders/thunderbird-bin { + gconf = pkgs.gnome.GConf; + inherit (pkgs.gnome3) at_spi2_atk; + inherit (pkgs.gnome) libgnome libgnomeui; + inherit (pkgs.xlibs) libX11 libXScrnSaver libXext + libXinerama libXrender libXt; + }; + tig = gitAndTools.tig; timidity = callPackage ../tools/misc/timidity { }; @@ -9248,12 +9238,8 @@ let uwimap = callPackage ../tools/networking/uwimap { }; - uzbl = builderDefsPackage (import ../applications/networking/browsers/uzbl) { - inherit pkgconfig webkit makeWrapper glib_networking python3; - inherit glib pango cairo gdk_pixbuf atk; - inherit (xlibs) libX11 kbproto; - inherit (gnome) libsoup; - gtk = gtk3; + uzbl = callPackage ../applications/networking/browsers/uzbl { + webkit = webkitgtk2; }; vanitygen = callPackage ../applications/misc/vanitygen { }; @@ -9899,8 +9885,10 @@ let cinnamon = recurseIntoAttrs rec { callPackage = newScope pkgs.cinnamon; - inherit (gnome3) gnome_common libgnomekbd; - + inherit (gnome3) gnome_common libgnomekbd gnome-menus; + + cinnamon-control-center = callPackage ../desktops/cinnamon/cinnamon-control-center.nix{ }; + cinnamon-settings-daemon = callPackage ../desktops/cinnamon/cinnamon-settings-daemon.nix{ }; cinnamon-session = callPackage ../desktops/cinnamon/cinnamon-session.nix{ } ; @@ -10364,6 +10352,8 @@ let golly = callPackage ../applications/science/misc/golly { }; + megam = callPackage ../applications/science/misc/megam { }; + root = callPackage ../applications/science/misc/root { }; simgrid = callPackage ../applications/science/misc/simgrid { }; @@ -10686,8 +10676,7 @@ let vimPlugins = callPackage ../misc/vim-plugins { }; vimprobable2 = callPackage ../applications/networking/browsers/vimprobable2 { - inherit (gnome) libsoup; - webkit = webkit_gtk2; + webkit = webkitgtk2; }; vimprobable2Wrapper = wrapFirefox @@ -10695,8 +10684,7 @@ let }; vimb = callPackage ../applications/networking/browsers/vimb { - inherit (gnome) libsoup; - webkit = webkit_gtk2; + webkit = webkitgtk2; }; vimbWrapper = wrapFirefox { diff --git a/pkgs/top-level/python-packages.nix b/pkgs/top-level/python-packages.nix index 0d43dfb4d711..ce019a8464e4 100644 --- a/pkgs/top-level/python-packages.nix +++ b/pkgs/top-level/python-packages.nix @@ -5973,7 +5973,7 @@ rec { }; buildInputs = with pkgs; [ - pkgconfig python gtk2 pygtk libxml2 libxslt libsoup webkit_gtk2 icu + pkgconfig python gtk2 pygtk libxml2 libxslt libsoup webkitgtk2 icu ]; meta = { diff --git a/pkgs/top-level/release-python.nix b/pkgs/top-level/release-python.nix index 8eb08d259834..dfdbb1db8bdf 100644 --- a/pkgs/top-level/release-python.nix +++ b/pkgs/top-level/release-python.nix @@ -1724,7 +1724,6 @@ let wavesurfer = { type = "job"; systems = ["x86_64-linux"]; schedulingPriority = 4; }; wdfs = { type = "job"; systems = ["x86_64-linux"]; schedulingPriority = 4; }; webkit = { type = "job"; systems = ["x86_64-linux"]; schedulingPriority = 4; }; - webkit_gtk2 = { type = "job"; systems = ["x86_64-linux"]; schedulingPriority = 4; }; weechat = { type = "job"; systems = ["x86_64-linux"]; schedulingPriority = 4; }; welkin = { type = "job"; systems = ["x86_64-linux"]; schedulingPriority = 4; }; wesnoth = { type = "job"; systems = ["x86_64-linux"]; schedulingPriority = 4; }; |