Compare commits
2 Commits
enable-tes
...
silence-wa
| Author | SHA1 | Date | |
|---|---|---|---|
| e09dd2b4dc | |||
| 5235b47827 |
9
.gitignore
vendored
9
.gitignore
vendored
@ -1,9 +0,0 @@
|
|||||||
.zanata-cache/
|
|
||||||
_build
|
|
||||||
TAGS
|
|
||||||
tags
|
|
||||||
vgdump
|
|
||||||
*.swp
|
|
||||||
*~
|
|
||||||
\#*#
|
|
||||||
.\#*
|
|
||||||
@ -2,32 +2,20 @@ image: debian:buster
|
|||||||
|
|
||||||
stages:
|
stages:
|
||||||
- build
|
- build
|
||||||
- test
|
|
||||||
|
|
||||||
.tags: &tags
|
|
||||||
tags:
|
|
||||||
- librem5
|
|
||||||
|
|
||||||
before_script:
|
before_script:
|
||||||
|
- apt-get -y update
|
||||||
|
- apt-get -y install wget gnupg2
|
||||||
|
- echo "deb http://ci.puri.sm/ scratch librem5" > /etc/apt/sources.list.d/ci.list
|
||||||
|
- wget -O- https://ci.puri.sm/ci-repo.key | apt-key add -
|
||||||
- apt-get -y update
|
- apt-get -y update
|
||||||
- apt-get -y build-dep .
|
- apt-get -y build-dep .
|
||||||
|
|
||||||
build_meson:
|
build_meson:
|
||||||
<<: *tags
|
|
||||||
stage: build
|
stage: build
|
||||||
artifacts:
|
tags:
|
||||||
paths:
|
- librem5
|
||||||
- _build
|
|
||||||
script:
|
script:
|
||||||
- meson . _build/ -Ddepdatadir=/usr/share
|
- meson . _build/ -Ddepdatadir=/usr/share
|
||||||
- ninja -C _build install
|
- ninja -C _build install
|
||||||
|
|
||||||
test:
|
|
||||||
<<: *tags
|
|
||||||
stage: test
|
|
||||||
dependencies:
|
|
||||||
- build_meson
|
|
||||||
script:
|
|
||||||
- export LC_ALL=C.UTF-8
|
|
||||||
- ninja -C _build test
|
|
||||||
|
|
||||||
|
|||||||
20
autogen.sh
Executable file
20
autogen.sh
Executable file
@ -0,0 +1,20 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
# Run this to generate all the initial makefiles, etc.
|
||||||
|
|
||||||
|
srcdir=`dirname $0`
|
||||||
|
test -z "$srcdir" && srcdir=.
|
||||||
|
|
||||||
|
PKG_NAME="eekboard"
|
||||||
|
|
||||||
|
(test -f $srcdir/configure.ac \
|
||||||
|
&& test -f $srcdir/README.md ) || {
|
||||||
|
echo -n "**Error**: Directory "\`$srcdir\'" does not look like the"
|
||||||
|
echo " top-level $PKG_NAME directory"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
ACLOCAL_FLAGS="$ACLOCAL_FLAGS -I m4"
|
||||||
|
REQUIRED_AUTOMAKE_VERSION=1.10
|
||||||
|
REQUIRED_AUTOCONF_VERSION=2.60
|
||||||
|
|
||||||
|
. gnome-autogen.sh
|
||||||
@ -1,20 +0,0 @@
|
|||||||
<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
|
|
||||||
"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
|
|
||||||
<node xmlns:doc="http://www.freedesktop.org/dbus/1.0/doc.dtd">
|
|
||||||
<interface name="sm.puri.OSK0">
|
|
||||||
<method name="SetVisible">
|
|
||||||
<arg name="visible" type="b" direction="in"/>
|
|
||||||
<doc:doc><doc:description>
|
|
||||||
Switch keyboard visibility
|
|
||||||
</doc:description></doc:doc>
|
|
||||||
</method>
|
|
||||||
<method name="GetVisible">
|
|
||||||
<arg name="visible" type="b" direction="out"/>
|
|
||||||
<doc:doc><doc:description>
|
|
||||||
Get keyboard visibility
|
|
||||||
</doc:description></doc:doc>
|
|
||||||
</method>
|
|
||||||
<property name="Visible" type="b" access="read">
|
|
||||||
</property>
|
|
||||||
</interface>
|
|
||||||
</node>
|
|
||||||
@ -1,10 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
|
||||||
|
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" height="16" width="16"
|
|
||||||
version="1.1" viewBox="0 0 24 24">
|
|
||||||
|
|
||||||
<path d="M 24,1 L 24,10 C 24,15 20,17 17,17 L 7,17 L 10,20 L 10,23
|
|
||||||
L 7,23 L 0,15 L 7,7 L 10,7 L 10,10 L 7,13 L 17,13
|
|
||||||
C 19,13 20,12 20,10 L 20,1 Z"
|
|
||||||
stroke="none" fill="black" />
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 388 B |
@ -1,8 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
|
||||||
|
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" height="16" width="16"
|
|
||||||
version="1.1" viewBox="0 0 24 24">
|
|
||||||
|
|
||||||
<path d="M 12,2 L 22,14 L 16,14 L 16,22 L 8,22 L 8,14 L 2,14 Z"
|
|
||||||
stroke="none" fill="black" />
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 279 B |
@ -1,52 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
|
||||||
<svg
|
|
||||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
|
||||||
xmlns:cc="http://creativecommons.org/ns#"
|
|
||||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
|
||||||
xmlns:svg="http://www.w3.org/2000/svg"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
id="svg4043"
|
|
||||||
version="1.1"
|
|
||||||
viewBox="0 0 4.2333331 4.2333093"
|
|
||||||
height="4.2333093mm"
|
|
||||||
width="4.2333331mm">
|
|
||||||
<defs
|
|
||||||
id="defs4037" />
|
|
||||||
<metadata
|
|
||||||
id="metadata4040">
|
|
||||||
<rdf:RDF>
|
|
||||||
<cc:Work
|
|
||||||
rdf:about="">
|
|
||||||
<dc:format>image/svg+xml</dc:format>
|
|
||||||
<dc:type
|
|
||||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
|
||||||
<dc:title></dc:title>
|
|
||||||
</cc:Work>
|
|
||||||
</rdf:RDF>
|
|
||||||
</metadata>
|
|
||||||
<g
|
|
||||||
transform="translate(-86.329776,-68.097636)"
|
|
||||||
id="layer1">
|
|
||||||
<g
|
|
||||||
style="stroke-width:1.00004983;fill:#2e3436;fill-opacity:1"
|
|
||||||
transform="matrix(0.99990029,0,0,1,-7.1823833,-1.8799927)"
|
|
||||||
id="g842">
|
|
||||||
<g
|
|
||||||
style="stroke-width:1.00004983;fill:#2e3436;fill-opacity:1"
|
|
||||||
id="g836">
|
|
||||||
<path
|
|
||||||
id="path5166"
|
|
||||||
d="m 95.636719,69.978516 c -1.165869,0 -2.115235,0.949365 -2.115235,2.115234 0,1.165869 0.949366,2.117188 2.115235,2.117188 1.165869,0 2.117187,-0.951319 2.117187,-2.117188 0,-1.165869 -0.951318,-2.115234 -2.117187,-2.115234 z m 0,0.529296 c 0.879886,0 1.58789,0.706052 1.58789,1.585938 0,0.879886 -0.708004,1.587891 -1.58789,1.587891 -0.879886,0 -1.585938,-0.708005 -1.585938,-1.587891 0,-0.879886 0.706052,-1.585937 1.585938,-1.585938 z"
|
|
||||||
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#2e3436;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.52919304;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" />
|
|
||||||
</g>
|
|
||||||
<path
|
|
||||||
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#2e3436;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.26459652;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
|
|
||||||
d="m 95.636719,70.109375 c -0.144398,0 -0.27248,0.07793 -0.373047,0.189453 -0.100567,0.111521 -0.18209,0.261405 -0.25,0.439453 -0.135821,0.356096 -0.214844,0.830395 -0.214844,1.355469 0,0.525074 0.07902,1.001326 0.214844,1.357422 0.06791,0.178048 0.149433,0.327932 0.25,0.439453 0.100567,0.111521 0.228649,0.1875 0.373047,0.1875 0.144397,0 0.27248,-0.07598 0.373047,-0.1875 0.100566,-0.111521 0.182089,-0.261405 0.25,-0.439453 0.135821,-0.356096 0.216797,-0.832348 0.216796,-1.357422 0,-0.525074 -0.08097,-0.999373 -0.216796,-1.355469 -0.06791,-0.178048 -0.149434,-0.327932 -0.25,-0.439453 -0.100567,-0.111521 -0.22865,-0.189453 -0.373047,-0.189453 z m 0,0.265625 c 0.05067,0 0.109272,0.02564 0.177734,0.101562 0.06846,0.07592 0.139293,0.198356 0.199219,0.355469 0.119851,0.314227 0.197266,0.763915 0.197266,1.261719 0,0.497804 -0.07742,0.949446 -0.197266,1.263672 -0.05993,0.157113 -0.130756,0.279549 -0.199219,0.355469 -0.06846,0.07592 -0.12706,0.101562 -0.177734,0.101562 -0.05067,0 -0.107319,-0.02564 -0.175781,-0.101562 -0.06846,-0.07592 -0.139294,-0.198356 -0.199219,-0.355469 C 95.141867,73.043196 95.0625,72.591554 95.0625,72.09375 c 0,-0.497804 0.07937,-0.947492 0.199219,-1.261719 0.05993,-0.157113 0.130756,-0.279549 0.199219,-0.355469 C 95.5294,70.400643 95.586045,70.375 95.636719,70.375 Z"
|
|
||||||
id="circle5168" />
|
|
||||||
<path
|
|
||||||
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#2e3436;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.26459652;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
|
|
||||||
d="m 93.697266,71.962891 v 0.263671 h 3.96875 v -0.263671 z"
|
|
||||||
id="path5170" />
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 6.6 KiB |
@ -1,54 +1,123 @@
|
|||||||
<?xml version="1.0"?>
|
<?xml version="1.0"?>
|
||||||
<geometry version="0.90">
|
<geometry version="0.90">
|
||||||
<bounds x="0" y="10.000000" width="426.0000" height="296.5853"/>
|
<bounds x="0.000000" y="0.000000" width="426.0000" height="296.5853"/>
|
||||||
<section angle="0">
|
<section angle="0">
|
||||||
|
<bounds x="0" y="0" width="608.7804" height="201.3658"/>
|
||||||
<row orientation="1">
|
<row orientation="1">
|
||||||
<key keycode="24" name="AD01" oref="outline2" />
|
<key keycode="24" name="AD01" oref="outline2">
|
||||||
<key keycode="25" name="AD02" oref="outline2" />
|
<bounds x="65.56097" y="42.14634" width="37.46341" height="52.44877"/>
|
||||||
<key keycode="26" name="AD03" oref="outline2" />
|
</key>
|
||||||
<key keycode="27" name="AD04" oref="outline2" />
|
<key keycode="25" name="AD02" oref="outline2">
|
||||||
<key keycode="28" name="AD05" oref="outline2" />
|
<bounds x="106.1463" y="42.14634" width="37.46341" height="37.46341"/>
|
||||||
<key keycode="29" name="AD06" oref="outline2" />
|
</key>
|
||||||
<key keycode="30" name="AD07" oref="outline2" />
|
<key keycode="26" name="AD03" oref="outline2">
|
||||||
<key keycode="31" name="AD08" oref="outline2" />
|
<bounds x="145.1707" y="42.14634" width="37.46341" height="37.46341"/>
|
||||||
<key keycode="32" name="AD09" oref="outline2" />
|
</key>
|
||||||
<key keycode="33" name="AD10" oref="outline2" />
|
<key keycode="27" name="AD04" oref="outline2">
|
||||||
|
<bounds x="185.7560" y="42.14634" width="37.46341" height="37.46341"/>
|
||||||
|
</key>
|
||||||
|
<key keycode="28" name="AD05" oref="outline2">
|
||||||
|
<bounds x="226.3414" y="42.14634" width="37.46341" height="37.46341"/>
|
||||||
|
</key>
|
||||||
|
<key keycode="29" name="AD06" oref="outline2">
|
||||||
|
<bounds x="266.9268" y="42.14634" width="37.46341" height="37.46341"/>
|
||||||
|
</key>
|
||||||
|
<key keycode="30" name="AD07" oref="outline2">
|
||||||
|
<bounds x="307.5121" y="42.14634" width="37.46341" height="37.46341"/>
|
||||||
|
</key>
|
||||||
|
<key keycode="31" name="AD08" oref="outline2">
|
||||||
|
<bounds x="348.0975" y="42.14634" width="37.46341" height="37.46341"/>
|
||||||
|
</key>
|
||||||
|
<key keycode="32" name="AD09" oref="outline2">
|
||||||
|
<bounds x="388.6829" y="42.14634" width="37.46341" height="37.46341"/>
|
||||||
|
</key>
|
||||||
|
<key keycode="33" name="AD10" oref="outline2">
|
||||||
|
<bounds x="429.2682" y="42.14634" width="37.46341" height="37.46341"/>
|
||||||
|
</key>
|
||||||
</row>
|
</row>
|
||||||
</section>
|
</section>
|
||||||
<section angle="0">
|
<section angle="0">
|
||||||
|
<bounds x="0" y="0" width="608.7804" height="201.3658"/>
|
||||||
<row orientation="1">
|
<row orientation="1">
|
||||||
<key keycode="38" name="AC01" oref="outline2" />
|
<key keycode="38" name="AC01" oref="outline2">
|
||||||
<key keycode="39" name="AC02" oref="outline2" />
|
<bounds x="76.48780" y="82.73170" width="37.46341" height="37.46341"/>
|
||||||
<key keycode="40" name="AC03" oref="outline2" />
|
</key>
|
||||||
<key keycode="41" name="AC04" oref="outline2" />
|
<key keycode="39" name="AC02" oref="outline2">
|
||||||
<key keycode="42" name="AC05" oref="outline2" />
|
<bounds x="115.5121" y="82.73170" width="37.46341" height="37.46341"/>
|
||||||
<key keycode="43" name="AC06" oref="outline2" />
|
</key>
|
||||||
<key keycode="44" name="AC07" oref="outline2" />
|
<key keycode="40" name="AC03" oref="outline2">
|
||||||
<key keycode="45" name="AC08" oref="outline2" />
|
<bounds x="156.0975" y="82.73170" width="37.46341" height="37.46341"/>
|
||||||
<key keycode="46" name="AC09" oref="outline2" />
|
</key>
|
||||||
<key keycode="47" name="AC10" oref="outline2" />
|
<key keycode="41" name="AC04" oref="outline2">
|
||||||
|
<bounds x="196.6829" y="82.73170" width="37.46341" height="37.46341"/>
|
||||||
|
</key>
|
||||||
|
<key keycode="42" name="AC05" oref="outline2">
|
||||||
|
<bounds x="237.2682" y="82.73170" width="37.46341" height="37.46341"/>
|
||||||
|
</key>
|
||||||
|
<key keycode="43" name="AC06" oref="outline2">
|
||||||
|
<bounds x="277.8536" y="82.73170" width="37.46341" height="37.46341"/>
|
||||||
|
</key>
|
||||||
|
<key keycode="44" name="AC07" oref="outline2">
|
||||||
|
<bounds x="318.4390" y="82.73170" width="37.46341" height="37.46341"/>
|
||||||
|
</key>
|
||||||
|
<key keycode="45" name="AC08" oref="outline2">
|
||||||
|
<bounds x="359.0243" y="82.73170" width="37.46341" height="37.46341"/>
|
||||||
|
</key>
|
||||||
|
<key keycode="46" name="AC09" oref="outline2">
|
||||||
|
<bounds x="399.6097" y="82.73170" width="37.46341" height="37.46341"/>
|
||||||
|
</key>
|
||||||
</row>
|
</row>
|
||||||
</section>
|
</section>
|
||||||
<section angle="0">
|
<section angle="0">
|
||||||
|
<bounds x="0" y="0" width="608.7804" height="201.3658"/>
|
||||||
<row orientation="1">
|
<row orientation="1">
|
||||||
<key keycode="50" name="LFSH" oref="altline" />
|
<key keycode="50" name="LFSH" oref="altline">
|
||||||
<key keycode="52" name="AB01" oref="outline2" />
|
<bounds x="3.121951" y="121.7560" width="88.97561" height="37.46341"/>
|
||||||
<key keycode="53" name="AB02" oref="outline2" />
|
</key>
|
||||||
<key keycode="54" name="AB03" oref="outline2" />
|
<key keycode="52" name="AB01" oref="outline2">
|
||||||
<key keycode="55" name="AB04" oref="outline2" />
|
<bounds x="95.21951" y="121.7560" width="37.46341" height="37.46341"/>
|
||||||
<key keycode="56" name="AB05" oref="outline2" />
|
</key>
|
||||||
<key keycode="57" name="AB06" oref="outline2" />
|
<key keycode="53" name="AB02" oref="outline2">
|
||||||
<key keycode="58" name="AB07" oref="outline2" />
|
<bounds x="135.8048" y="121.7560" width="37.46341" height="37.46341"/>
|
||||||
<key keycode="22" name="BKSP" oref="altline" />
|
</key>
|
||||||
|
<key keycode="54" name="AB03" oref="outline2">
|
||||||
|
<bounds x="176.3902" y="121.7560" width="37.46341" height="37.46341"/>
|
||||||
|
</key>
|
||||||
|
<key keycode="55" name="AB04" oref="outline2">
|
||||||
|
<bounds x="215.4146" y="121.7560" width="37.46341" height="37.46341"/>
|
||||||
|
</key>
|
||||||
|
<key keycode="56" name="AB05" oref="outline2">
|
||||||
|
<bounds x="256.0000" y="121.7560" width="37.46341" height="37.46341"/>
|
||||||
|
</key>
|
||||||
|
<key keycode="57" name="AB06" oref="outline2">
|
||||||
|
<bounds x="296.5853" y="121.7560" width="37.46341" height="37.46341"/>
|
||||||
|
</key>
|
||||||
|
<key keycode="58" name="AB07" oref="outline2">
|
||||||
|
<bounds x="337.1707" y="121.7560" width="37.46341" height="37.46341"/>
|
||||||
|
</key>
|
||||||
|
<key keycode="22" name="BKSP" oref="altline">
|
||||||
|
<bounds x="529.1707" y="1.560976" width="79.60975" height="37.46341"/>
|
||||||
|
</key>
|
||||||
</row>
|
</row>
|
||||||
</section>
|
</section>
|
||||||
<section angle="0">
|
<section angle="0">
|
||||||
|
<bounds x="0" y="0" width="608.7804" height="201.3658"/>
|
||||||
<row orientation="1">
|
<row orientation="1">
|
||||||
<key keycode="0" name="ABC123" oref="altline" />
|
<key keycode="37" name="LCTL" oref="altline">
|
||||||
<key keycode="149" name="I149" oref="altline" />
|
<bounds x="62.43902" y="162.3414" width="48.39024" height="37.46341"/>
|
||||||
<key keycode="65" name="SPCE" oref="spaceline" />
|
</key>
|
||||||
<key keycode="59" name="AB08" oref="outline2" />
|
<key keycode="66" name="ALTGR" oref="altline">
|
||||||
<key keycode="36" name="RTRN" oref="outline7" />
|
<bounds x="113.9512" y="162.3414" width="48.39024" height="37.46341"/>
|
||||||
|
</key>
|
||||||
|
<key keycode="65" name="SPCE" oref="spaceline">
|
||||||
|
<bounds x="165.4634" y="162.3414" width="217.5853" height="37.46341"/>
|
||||||
|
</key>
|
||||||
|
<key keycode="60" name="AB09" oref="outline2">
|
||||||
|
<bounds x="418.3414" y="121.7560" width="37.46341" height="37.46341"/>
|
||||||
|
</key>
|
||||||
|
<key keycode="36" name="RTRN" oref="outline7">
|
||||||
|
<bounds x="519.8048" y="82.73170" width="88.97561" height="37.46341"/>
|
||||||
|
</key>
|
||||||
</row>
|
</row>
|
||||||
</section>
|
</section>
|
||||||
<outline id="outline2" corner-radius="1.000000">
|
<outline id="outline2" corner-radius="1.000000">
|
||||||
|
|||||||
@ -1,126 +0,0 @@
|
|||||||
<?xml version="1.0"?>
|
|
||||||
<geometry version="0.90">
|
|
||||||
<bounds x="0" y="10.000000" width="426.0000" height="296.5853"/>
|
|
||||||
<!-- Keycodes correspond to those used in /usr/share/X11/xkb/keycodes/evdev.
|
|
||||||
For Squeekboard, the values have no connection to evdev. They are only
|
|
||||||
used as indices into the keymap sent to the compositor. They must have
|
|
||||||
values in the range from 8 to 255. -->
|
|
||||||
<section angle="0">
|
|
||||||
<row orientation="1">
|
|
||||||
<key keycode="24" name="AD01" oref="outline2" />
|
|
||||||
<key keycode="25" name="AD02" oref="outline2" />
|
|
||||||
<key keycode="26" name="AD03" oref="outline2" />
|
|
||||||
<key keycode="27" name="AD04" oref="outline2" />
|
|
||||||
<key keycode="28" name="AD05" oref="outline2" />
|
|
||||||
<key keycode="29" name="AD06" oref="outline2" />
|
|
||||||
<key keycode="30" name="AD07" oref="outline2" />
|
|
||||||
<key keycode="31" name="AD08" oref="outline2" />
|
|
||||||
<key keycode="32" name="AD09" oref="outline2" />
|
|
||||||
<key keycode="33" name="AD10" oref="outline2" />
|
|
||||||
<key keycode="34" name="AD11" oref="outline2" />
|
|
||||||
</row>
|
|
||||||
</section>
|
|
||||||
<section angle="0">
|
|
||||||
<row orientation="1">
|
|
||||||
<key keycode="38" name="AC01" oref="outline2" />
|
|
||||||
<key keycode="39" name="AC02" oref="outline2" />
|
|
||||||
<key keycode="40" name="AC03" oref="outline2" />
|
|
||||||
<key keycode="41" name="AC04" oref="outline2" />
|
|
||||||
<key keycode="42" name="AC05" oref="outline2" />
|
|
||||||
<key keycode="43" name="AC06" oref="outline2" />
|
|
||||||
<key keycode="44" name="AC07" oref="outline2" />
|
|
||||||
<key keycode="45" name="AC08" oref="outline2" />
|
|
||||||
<key keycode="46" name="AC09" oref="outline2" />
|
|
||||||
<key keycode="47" name="AC10" oref="outline2" />
|
|
||||||
<key keycode="48" name="AC11" oref="outline2" />
|
|
||||||
</row>
|
|
||||||
</section>
|
|
||||||
<section angle="0">
|
|
||||||
<row orientation="1">
|
|
||||||
<key keycode="50" name="LFSH" oref="altline" />
|
|
||||||
<key keycode="52" name="AB01" oref="outline2" />
|
|
||||||
<key keycode="53" name="AB02" oref="outline2" />
|
|
||||||
<key keycode="54" name="AB03" oref="outline2" />
|
|
||||||
<key keycode="55" name="AB04" oref="outline2" />
|
|
||||||
<key keycode="56" name="AB05" oref="outline2" />
|
|
||||||
<key keycode="57" name="AB06" oref="outline2" />
|
|
||||||
<key keycode="58" name="AB07" oref="outline2" />
|
|
||||||
<key keycode="22" name="BKSP" oref="altline" />
|
|
||||||
</row>
|
|
||||||
</section>
|
|
||||||
<section angle="0">
|
|
||||||
<row orientation="1">
|
|
||||||
<key keycode="0" name="ABC123" oref="altline" />
|
|
||||||
<key keycode="149" name="I149" oref="altline" />
|
|
||||||
<key keycode="65" name="SPCE" oref="spaceline" />
|
|
||||||
<key keycode="59" name="AB08" oref="outline2" />
|
|
||||||
<key keycode="36" name="RTRN" oref="outline7" />
|
|
||||||
</row>
|
|
||||||
</section>
|
|
||||||
<outline id="outline2" corner-radius="1.000000">
|
|
||||||
<point x="0.000000" y="0.000000"/>
|
|
||||||
<point x="32" y="0.000000"/>
|
|
||||||
<point x="32" y="52.44877"/>
|
|
||||||
<point x="0.000000" y="52.44877"/>
|
|
||||||
</outline>
|
|
||||||
<outline id="altline" corner-radius="1.000000">
|
|
||||||
<point x="0.000000" y="0.000000"/>
|
|
||||||
<point x="48.39024" y="0.000000"/>
|
|
||||||
<point x="48.39024" y="52.44877"/>
|
|
||||||
<point x="0.000000" y="52.44877"/>
|
|
||||||
</outline>
|
|
||||||
<outline id="outline4" corner-radius="1.000000">
|
|
||||||
<point x="0.000000" y="0.000000"/>
|
|
||||||
<point x="59.31707" y="0.000000"/>
|
|
||||||
<point x="59.31707" y="52.44877"/>
|
|
||||||
<point x="0.000000" y="52.44877"/>
|
|
||||||
</outline>
|
|
||||||
<outline id="outline5" corner-radius="1.000000">
|
|
||||||
<point x="0.000000" y="0.000000"/>
|
|
||||||
<point x="59.31707" y="0.000000"/>
|
|
||||||
<point x="59.31707" y="52.44877"/>
|
|
||||||
<point x="0.000000" y="52.44877"/>
|
|
||||||
</outline>
|
|
||||||
<outline id="outline6" corner-radius="1.000000">
|
|
||||||
<point x="0.000000" y="0.000000"/>
|
|
||||||
<point x="68.68292" y="0.000000"/>
|
|
||||||
<point x="68.68292" y="52.44877"/>
|
|
||||||
<point x="0.000000" y="52.44877"/>
|
|
||||||
</outline>
|
|
||||||
<outline id="outline7" corner-radius="1.000000">
|
|
||||||
<point x="0.000000" y="0.000000"/>
|
|
||||||
<point x="88.97561" y="0.000000"/>
|
|
||||||
<point x="88.97561" y="52.44877"/>
|
|
||||||
<point x="0.000000" y="52.44877"/>
|
|
||||||
</outline>
|
|
||||||
<outline id="outline8" corner-radius="1.000000">
|
|
||||||
<point x="0.000000" y="0.000000"/>
|
|
||||||
<point x="88.97561" y="0.000000"/>
|
|
||||||
<point x="88.97561" y="52.44877"/>
|
|
||||||
<point x="0.000000" y="52.44877"/>
|
|
||||||
</outline>
|
|
||||||
<outline id="outline9" corner-radius="1.000000">
|
|
||||||
<point x="0.000000" y="0.000000"/>
|
|
||||||
<point x="109.2682" y="0.000000"/>
|
|
||||||
<point x="109.2682" y="52.44877"/>
|
|
||||||
<point x="0.000000" y="52.44877"/>
|
|
||||||
</outline>
|
|
||||||
<outline id="outline10" corner-radius="1.000000">
|
|
||||||
<point x="0.000000" y="0.000000"/>
|
|
||||||
<point x="37.46341" y="0.000000"/>
|
|
||||||
<point x="37.46341" y="52.44877"/>
|
|
||||||
<point x="0.000000" y="52.44877"/>
|
|
||||||
</outline>
|
|
||||||
<outline id="outline13" corner-radius="1.000000">
|
|
||||||
<point x="0.000000" y="0.000000"/>
|
|
||||||
<point x="79.60975" y="0.000000"/>
|
|
||||||
<point x="79.60975" y="52.44877"/>
|
|
||||||
<point x="0.000000" y="52.44877"/>
|
|
||||||
</outline>
|
|
||||||
<outline id="spaceline" corner-radius="1.000000">
|
|
||||||
<point x="0.000000" y="0.000000"/>
|
|
||||||
<point x="150.5853" y="0.000000"/>
|
|
||||||
<point x="150.5853" y="52.44877"/>
|
|
||||||
<point x="0.000000" y="52.44877"/>
|
|
||||||
</outline>
|
|
||||||
</geometry>
|
|
||||||
@ -1,105 +0,0 @@
|
|||||||
<?xml version="1.0"?>
|
|
||||||
<geometry version="0.90">
|
|
||||||
<bounds x="0" y="10.000000" width="426.0000" height="296.5853"/>
|
|
||||||
<section angle="0">
|
|
||||||
<row orientation="1">
|
|
||||||
<key keycode="24" name="AD01" oref="outline2" />
|
|
||||||
<key keycode="25" name="AD02" oref="outline2" />
|
|
||||||
<key keycode="26" name="AD03" oref="outline2" />
|
|
||||||
<key keycode="27" name="AD04" oref="outline2" />
|
|
||||||
<key keycode="28" name="AD05" oref="outline2" />
|
|
||||||
</row>
|
|
||||||
</section>
|
|
||||||
<section angle="0">
|
|
||||||
<row orientation="1">
|
|
||||||
<key keycode="38" name="AC01" oref="outline2" />
|
|
||||||
<key keycode="39" name="AC02" oref="outline2" />
|
|
||||||
<key keycode="40" name="AC03" oref="outline2" />
|
|
||||||
<key keycode="41" name="AC04" oref="outline2" />
|
|
||||||
<key keycode="42" name="AC05" oref="outline2" />
|
|
||||||
</row>
|
|
||||||
</section>
|
|
||||||
<section angle="0">
|
|
||||||
<row orientation="1">
|
|
||||||
<key keycode="52" name="AB01" oref="outline2" />
|
|
||||||
<key keycode="53" name="AB02" oref="outline2" />
|
|
||||||
<key keycode="54" name="AB03" oref="outline2" />
|
|
||||||
<key keycode="55" name="AB04" oref="outline2" />
|
|
||||||
<key keycode="56" name="AB05" oref="outline2" />
|
|
||||||
</row>
|
|
||||||
</section>
|
|
||||||
<section angle="0">
|
|
||||||
<row orientation="1">
|
|
||||||
<key keycode="22" name="BKSP" oref="altline" />
|
|
||||||
<key keycode="57" name="AB06" oref="outline2" />
|
|
||||||
<key keycode="65" name="SPCE" oref="spaceline" />
|
|
||||||
<key keycode="36" name="RTRN" oref="outline7" />
|
|
||||||
</row>
|
|
||||||
</section>
|
|
||||||
<outline id="outline2" corner-radius="1.000000">
|
|
||||||
<point x="0.000000" y="0.000000"/>
|
|
||||||
<point x="37.46341" y="0.000000"/>
|
|
||||||
<point x="37.46341" y="52.44877"/>
|
|
||||||
<point x="0.000000" y="52.44877"/>
|
|
||||||
</outline>
|
|
||||||
<outline id="altline" corner-radius="1.000000">
|
|
||||||
<point x="0.000000" y="0.000000"/>
|
|
||||||
<point x="48.39024" y="0.000000"/>
|
|
||||||
<point x="48.39024" y="52.44877"/>
|
|
||||||
<point x="0.000000" y="52.44877"/>
|
|
||||||
</outline>
|
|
||||||
<outline id="outline4" corner-radius="1.000000">
|
|
||||||
<point x="0.000000" y="0.000000"/>
|
|
||||||
<point x="59.31707" y="0.000000"/>
|
|
||||||
<point x="59.31707" y="52.44877"/>
|
|
||||||
<point x="0.000000" y="52.44877"/>
|
|
||||||
</outline>
|
|
||||||
<outline id="outline5" corner-radius="1.000000">
|
|
||||||
<point x="0.000000" y="0.000000"/>
|
|
||||||
<point x="59.31707" y="0.000000"/>
|
|
||||||
<point x="59.31707" y="52.44877"/>
|
|
||||||
<point x="0.000000" y="52.44877"/>
|
|
||||||
</outline>
|
|
||||||
<outline id="outline6" corner-radius="1.000000">
|
|
||||||
<point x="0.000000" y="0.000000"/>
|
|
||||||
<point x="68.68292" y="0.000000"/>
|
|
||||||
<point x="68.68292" y="52.44877"/>
|
|
||||||
<point x="0.000000" y="52.44877"/>
|
|
||||||
</outline>
|
|
||||||
<outline id="outline7" corner-radius="1.000000">
|
|
||||||
<point x="0.000000" y="0.000000"/>
|
|
||||||
<point x="88.97561" y="0.000000"/>
|
|
||||||
<point x="88.97561" y="52.44877"/>
|
|
||||||
<point x="0.000000" y="52.44877"/>
|
|
||||||
</outline>
|
|
||||||
<outline id="outline8" corner-radius="1.000000">
|
|
||||||
<point x="0.000000" y="0.000000"/>
|
|
||||||
<point x="88.97561" y="0.000000"/>
|
|
||||||
<point x="88.97561" y="52.44877"/>
|
|
||||||
<point x="0.000000" y="52.44877"/>
|
|
||||||
</outline>
|
|
||||||
<outline id="outline9" corner-radius="1.000000">
|
|
||||||
<point x="0.000000" y="0.000000"/>
|
|
||||||
<point x="109.2682" y="0.000000"/>
|
|
||||||
<point x="109.2682" y="52.44877"/>
|
|
||||||
<point x="0.000000" y="52.44877"/>
|
|
||||||
</outline>
|
|
||||||
<outline id="outline10" corner-radius="1.000000">
|
|
||||||
<point x="0.000000" y="0.000000"/>
|
|
||||||
<point x="37.46341" y="0.000000"/>
|
|
||||||
<point x="37.46341" y="52.44877"/>
|
|
||||||
<point x="0.000000" y="52.44877"/>
|
|
||||||
</outline>
|
|
||||||
<outline id="outline13" corner-radius="1.000000">
|
|
||||||
<point x="0.000000" y="0.000000"/>
|
|
||||||
<point x="79.60975" y="0.000000"/>
|
|
||||||
<point x="79.60975" y="52.44877"/>
|
|
||||||
<point x="0.000000" y="52.44877"/>
|
|
||||||
</outline>
|
|
||||||
<outline id="spaceline" corner-radius="1.000000">
|
|
||||||
<point x="0.000000" y="0.000000"/>
|
|
||||||
<point x="120.5853" y="0.000000"/>
|
|
||||||
<point x="120.5853" y="52.44877"/>
|
|
||||||
<point x="0.000000" y="52.44877"/>
|
|
||||||
</outline>
|
|
||||||
</geometry>
|
|
||||||
@ -24,9 +24,6 @@
|
|||||||
<keyboard id="my" name="my"
|
<keyboard id="my" name="my"
|
||||||
geometry="compact" symbols="my"
|
geometry="compact" symbols="my"
|
||||||
longname="Myanmar" language="my"/>
|
longname="Myanmar" language="my"/>
|
||||||
<keyboard id="nb" name="nb"
|
|
||||||
geometry="extended" symbols="nb"
|
|
||||||
longname="Norwegian" language="nb"/>
|
|
||||||
<keyboard id="ru" name="ru"
|
<keyboard id="ru" name="ru"
|
||||||
geometry="compact" symbols="us"
|
geometry="compact" symbols="us"
|
||||||
longname="Russian" language="ru"/>
|
longname="Russian" language="ru"/>
|
||||||
@ -88,10 +85,4 @@
|
|||||||
<keyboard id="te-inscript" name="te-inscript"
|
<keyboard id="te-inscript" name="te-inscript"
|
||||||
geometry="compact" symbols="te-inscript"
|
geometry="compact" symbols="te-inscript"
|
||||||
longname="Telugu (Inscript)" language="te"/>
|
longname="Telugu (Inscript)" language="te"/>
|
||||||
|
|
||||||
<!-- Common keyboards -->
|
|
||||||
<keyboard id="numbers" name="numbers"
|
|
||||||
geometry="numbers-keypad" symbols="special/numbers"
|
|
||||||
longname="Numeric keypad" language="all"/>
|
|
||||||
|
|
||||||
</keyboards>
|
</keyboards>
|
||||||
|
|||||||
@ -1,308 +0,0 @@
|
|||||||
xkb_keymap {
|
|
||||||
|
|
||||||
xkb_keycodes "squeekboard" {
|
|
||||||
minimum = 8;
|
|
||||||
maximum = 255;
|
|
||||||
<ESC> = 9;
|
|
||||||
<AE01> = 10;
|
|
||||||
<AE02> = 11;
|
|
||||||
<AE03> = 12;
|
|
||||||
<AE04> = 13;
|
|
||||||
<AE05> = 14;
|
|
||||||
<AE06> = 15;
|
|
||||||
<AE07> = 16;
|
|
||||||
<AE08> = 17;
|
|
||||||
<AE09> = 18;
|
|
||||||
<AE10> = 19;
|
|
||||||
<AE11> = 20;
|
|
||||||
<AE12> = 21;
|
|
||||||
<BKSP> = 22;
|
|
||||||
<TAB> = 23;
|
|
||||||
<AD01> = 24;
|
|
||||||
<AD02> = 25;
|
|
||||||
<AD03> = 26;
|
|
||||||
<AD04> = 27;
|
|
||||||
<AD05> = 28;
|
|
||||||
<AD06> = 29;
|
|
||||||
<AD07> = 30;
|
|
||||||
<AD08> = 31;
|
|
||||||
<AD09> = 32;
|
|
||||||
<AD10> = 33;
|
|
||||||
<AD11> = 34;
|
|
||||||
<AD12> = 35;
|
|
||||||
<RTRN> = 36;
|
|
||||||
<LCTL> = 37;
|
|
||||||
<AC01> = 38;
|
|
||||||
<AC02> = 39;
|
|
||||||
<AC03> = 40;
|
|
||||||
<AC04> = 41;
|
|
||||||
<AC05> = 42;
|
|
||||||
<AC06> = 43;
|
|
||||||
<AC07> = 44;
|
|
||||||
<AC08> = 45;
|
|
||||||
<AC09> = 46;
|
|
||||||
<AC10> = 47;
|
|
||||||
<AC11> = 48;
|
|
||||||
<TLDE> = 49;
|
|
||||||
<LFSH> = 50;
|
|
||||||
<BKSL> = 51;
|
|
||||||
<AB01> = 52;
|
|
||||||
<AB02> = 53;
|
|
||||||
<AB03> = 54;
|
|
||||||
<AB04> = 55;
|
|
||||||
<AB05> = 56;
|
|
||||||
<AB06> = 57;
|
|
||||||
<AB07> = 58;
|
|
||||||
<AB08> = 59;
|
|
||||||
<AB09> = 60;
|
|
||||||
<AB10> = 61;
|
|
||||||
<RTSH> = 62;
|
|
||||||
<KPMU> = 63;
|
|
||||||
<LALT> = 64;
|
|
||||||
<SPCE> = 65;
|
|
||||||
<CAPS> = 66;
|
|
||||||
<FK01> = 67;
|
|
||||||
<FK02> = 68;
|
|
||||||
<FK03> = 69;
|
|
||||||
<FK04> = 70;
|
|
||||||
<FK05> = 71;
|
|
||||||
<FK06> = 72;
|
|
||||||
<FK07> = 73;
|
|
||||||
<FK08> = 74;
|
|
||||||
<FK09> = 75;
|
|
||||||
<FK10> = 76;
|
|
||||||
<NMLK> = 77;
|
|
||||||
<SCLK> = 78;
|
|
||||||
<KP7> = 79;
|
|
||||||
<KP8> = 80;
|
|
||||||
<KP9> = 81;
|
|
||||||
<KPSU> = 82;
|
|
||||||
<KP4> = 83;
|
|
||||||
<KP5> = 84;
|
|
||||||
<KP6> = 85;
|
|
||||||
<KPAD> = 86;
|
|
||||||
<KP1> = 87;
|
|
||||||
<KP2> = 88;
|
|
||||||
<KP3> = 89;
|
|
||||||
<KP0> = 90;
|
|
||||||
<KPDL> = 91;
|
|
||||||
<LVL3> = 92;
|
|
||||||
<LSGT> = 94;
|
|
||||||
<FK11> = 95;
|
|
||||||
<FK12> = 96;
|
|
||||||
<AB11> = 97;
|
|
||||||
<KATA> = 98;
|
|
||||||
<HIRA> = 99;
|
|
||||||
<HENK> = 100;
|
|
||||||
<HKTG> = 101;
|
|
||||||
<MUHE> = 102;
|
|
||||||
<JPCM> = 103;
|
|
||||||
<KPEN> = 104;
|
|
||||||
<RCTL> = 105;
|
|
||||||
<KPDV> = 106;
|
|
||||||
<PRSC> = 107;
|
|
||||||
<RALT> = 108;
|
|
||||||
<LNFD> = 109;
|
|
||||||
<HOME> = 110;
|
|
||||||
<UP> = 111;
|
|
||||||
<PGUP> = 112;
|
|
||||||
<LEFT> = 113;
|
|
||||||
<RGHT> = 114;
|
|
||||||
<END> = 115;
|
|
||||||
<DOWN> = 116;
|
|
||||||
<PGDN> = 117;
|
|
||||||
<INS> = 118;
|
|
||||||
<DELE> = 119;
|
|
||||||
<I120> = 120;
|
|
||||||
<MUTE> = 121;
|
|
||||||
<VOL-> = 122;
|
|
||||||
<VOL+> = 123;
|
|
||||||
<POWR> = 124;
|
|
||||||
<KPEQ> = 125;
|
|
||||||
<I126> = 126;
|
|
||||||
<PAUS> = 127;
|
|
||||||
<I128> = 128;
|
|
||||||
<I129> = 129;
|
|
||||||
<HNGL> = 130;
|
|
||||||
<HJCV> = 131;
|
|
||||||
<AE13> = 132;
|
|
||||||
<LWIN> = 133;
|
|
||||||
<RWIN> = 134;
|
|
||||||
<COMP> = 135;
|
|
||||||
<STOP> = 136;
|
|
||||||
<AGAI> = 137;
|
|
||||||
<PROP> = 138;
|
|
||||||
<UNDO> = 139;
|
|
||||||
<FRNT> = 140;
|
|
||||||
<COPY> = 141;
|
|
||||||
<OPEN> = 142;
|
|
||||||
<PAST> = 143;
|
|
||||||
<FIND> = 144;
|
|
||||||
<CUT> = 145;
|
|
||||||
<HELP> = 146;
|
|
||||||
<I147> = 147;
|
|
||||||
<I148> = 148;
|
|
||||||
<I149> = 149;
|
|
||||||
<I150> = 150;
|
|
||||||
<I151> = 151;
|
|
||||||
<I152> = 152;
|
|
||||||
<I153> = 153;
|
|
||||||
<I154> = 154;
|
|
||||||
<I155> = 155;
|
|
||||||
<I156> = 156;
|
|
||||||
<I157> = 157;
|
|
||||||
<I158> = 158;
|
|
||||||
<I159> = 159;
|
|
||||||
<I160> = 160;
|
|
||||||
<I161> = 161;
|
|
||||||
<I162> = 162;
|
|
||||||
<I163> = 163;
|
|
||||||
<I164> = 164;
|
|
||||||
<I165> = 165;
|
|
||||||
<I166> = 166;
|
|
||||||
<I167> = 167;
|
|
||||||
<I168> = 168;
|
|
||||||
<I169> = 169;
|
|
||||||
<I170> = 170;
|
|
||||||
<I171> = 171;
|
|
||||||
<I172> = 172;
|
|
||||||
<I173> = 173;
|
|
||||||
<I174> = 174;
|
|
||||||
<I175> = 175;
|
|
||||||
<I176> = 176;
|
|
||||||
<I177> = 177;
|
|
||||||
<I178> = 178;
|
|
||||||
<I179> = 179;
|
|
||||||
<I180> = 180;
|
|
||||||
<I181> = 181;
|
|
||||||
<I182> = 182;
|
|
||||||
<I183> = 183;
|
|
||||||
<I184> = 184;
|
|
||||||
<I185> = 185;
|
|
||||||
<I186> = 186;
|
|
||||||
<I187> = 187;
|
|
||||||
<I188> = 188;
|
|
||||||
<I189> = 189;
|
|
||||||
<I190> = 190;
|
|
||||||
<FK13> = 191;
|
|
||||||
<FK14> = 192;
|
|
||||||
<FK15> = 193;
|
|
||||||
<FK16> = 194;
|
|
||||||
<FK17> = 195;
|
|
||||||
<FK18> = 196;
|
|
||||||
<FK19> = 197;
|
|
||||||
<FK20> = 198;
|
|
||||||
<FK21> = 199;
|
|
||||||
<FK22> = 200;
|
|
||||||
<FK23> = 201;
|
|
||||||
<FK24> = 202;
|
|
||||||
<MDSW> = 203;
|
|
||||||
<ALT> = 204;
|
|
||||||
<META> = 205;
|
|
||||||
<SUPR> = 206;
|
|
||||||
<HYPR> = 207;
|
|
||||||
<I208> = 208;
|
|
||||||
<I209> = 209;
|
|
||||||
<I210> = 210;
|
|
||||||
<I211> = 211;
|
|
||||||
<I212> = 212;
|
|
||||||
<I213> = 213;
|
|
||||||
<I214> = 214;
|
|
||||||
<I215> = 215;
|
|
||||||
<I216> = 216;
|
|
||||||
<I217> = 217;
|
|
||||||
<I218> = 218;
|
|
||||||
<I219> = 219;
|
|
||||||
<I220> = 220;
|
|
||||||
<I221> = 221;
|
|
||||||
<I222> = 222;
|
|
||||||
<I223> = 223;
|
|
||||||
<I224> = 224;
|
|
||||||
<I225> = 225;
|
|
||||||
<I226> = 226;
|
|
||||||
<I227> = 227;
|
|
||||||
<I228> = 228;
|
|
||||||
<I229> = 229;
|
|
||||||
<I230> = 230;
|
|
||||||
<I231> = 231;
|
|
||||||
<I232> = 232;
|
|
||||||
<I233> = 233;
|
|
||||||
<I234> = 234;
|
|
||||||
<I235> = 235;
|
|
||||||
<I236> = 236;
|
|
||||||
<I237> = 237;
|
|
||||||
<I238> = 238;
|
|
||||||
<I239> = 239;
|
|
||||||
<I240> = 240;
|
|
||||||
<I241> = 241;
|
|
||||||
<I242> = 242;
|
|
||||||
<I243> = 243;
|
|
||||||
<I244> = 244;
|
|
||||||
<I245> = 245;
|
|
||||||
<I246> = 246;
|
|
||||||
<I247> = 247;
|
|
||||||
<I248> = 248;
|
|
||||||
<I249> = 249;
|
|
||||||
<I250> = 250;
|
|
||||||
<I251> = 251;
|
|
||||||
<I252> = 252;
|
|
||||||
<I253> = 253;
|
|
||||||
<I254> = 254;
|
|
||||||
<I255> = 255;
|
|
||||||
};
|
|
||||||
|
|
||||||
xkb_symbols "squeekboard" {
|
|
||||||
|
|
||||||
name[Group1] = "Letters";
|
|
||||||
name[Group2] = "Numbers/Symbols";
|
|
||||||
|
|
||||||
key <AD01> { [ q, Q ], [ 1, asciitilde ] };
|
|
||||||
key <AD02> { [ w, W ], [ 2, quoteleft ] };
|
|
||||||
key <AD03> { [ e, E ], [ 3, bar ] };
|
|
||||||
key <AD04> { [ r, R ], [ 4, U00B7 ] };
|
|
||||||
key <AD05> { [ t, T ], [ 5, squareroot ] };
|
|
||||||
key <AD06> { [ y, Y ], [ 6, Greek_pi ] };
|
|
||||||
key <AD07> { [ u, U ], [ 7, division ] };
|
|
||||||
key <AD08> { [ i, I ], [ 8, multiply ] };
|
|
||||||
key <AD09> { [ o, O ], [ 9, paragraph ] };
|
|
||||||
key <AD10> { [ p, P ], [ 0, U25B3 ] };
|
|
||||||
key <AD11> { [ aring, Aring ], [ U00B1, U00A7 ] };
|
|
||||||
key <AC01> { [ a, A ], [ at, copyright ] };
|
|
||||||
key <AC02> { [ s, S ], [ numbersign, U00AE ] };
|
|
||||||
key <AC03> { [ d, D ], [ dollar, U00A3 ] };
|
|
||||||
key <AC04> { [ f, F ], [ percent, EuroSign ] };
|
|
||||||
key <AC05> { [ g, G ], [ ampersand, U00A5 ] };
|
|
||||||
key <AC06> { [ h, H ], [ minus, underscore ] };
|
|
||||||
key <AC07> { [ j, J ], [ plus, equal ] };
|
|
||||||
key <AC08> { [ k, K ], [ U00FC, asciicircum ] };
|
|
||||||
key <AC09> { [ l, L ], [ U00F6, degree ] };
|
|
||||||
key <AC10> { [ oslash, Oslash ], [ parenleft, braceleft ] };
|
|
||||||
key <AC11> { [ ae, AE ], [ parenright, braceright ] };
|
|
||||||
key <RTRN> { [ Return, Return ], [ Return, Return ] };
|
|
||||||
key <LFSH> { [ Shift_L, Shift_L ], [ Shift_L, Shift_L ] };
|
|
||||||
key <AB01> { [ z, Z ], [ comma, backslash ] };
|
|
||||||
key <AB02> { [ x, X ], [ quotedbl, slash ] };
|
|
||||||
key <AB03> { [ c, C ], [ quoteright, less ] };
|
|
||||||
key <AB04> { [ v, V ], [ colon, greater ] };
|
|
||||||
key <AB05> { [ b, B ], [ semicolon, equal ] };
|
|
||||||
key <AB06> { [ n, N ], [ exclam, bracketleft ] };
|
|
||||||
key <AB07> { [ m, M ], [ question, bracketright ] };
|
|
||||||
key <AB08> { [ period, period ], [ period, period ] };
|
|
||||||
key <I149> { [ preferences, preferences ], [ preferences, preferences ] };
|
|
||||||
key <SPCE> { [ space, space ], [ space, space ] };
|
|
||||||
key <BKSP> { [ BackSpace, BackSpace ], [ BackSpace, BackSpace ] };
|
|
||||||
};
|
|
||||||
|
|
||||||
xkb_types "squeekboard" {
|
|
||||||
|
|
||||||
type "TWO_LEVEL" {
|
|
||||||
modifiers = Shift;
|
|
||||||
map[Shift] = Level2;
|
|
||||||
level_name[Level1] = "Base";
|
|
||||||
level_name[Level2] = "Shift";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
xkb_compatibility "squeekboard" {
|
|
||||||
};
|
|
||||||
};
|
|
||||||
@ -1,292 +0,0 @@
|
|||||||
xkb_keymap {
|
|
||||||
|
|
||||||
xkb_keycodes "squeekboard" {
|
|
||||||
minimum = 8;
|
|
||||||
maximum = 255;
|
|
||||||
<ESC> = 9;
|
|
||||||
<AE01> = 10;
|
|
||||||
<AE02> = 11;
|
|
||||||
<AE03> = 12;
|
|
||||||
<AE04> = 13;
|
|
||||||
<AE05> = 14;
|
|
||||||
<AE06> = 15;
|
|
||||||
<AE07> = 16;
|
|
||||||
<AE08> = 17;
|
|
||||||
<AE09> = 18;
|
|
||||||
<AE10> = 19;
|
|
||||||
<AE11> = 20;
|
|
||||||
<AE12> = 21;
|
|
||||||
<BKSP> = 22;
|
|
||||||
<TAB> = 23;
|
|
||||||
<AD01> = 24;
|
|
||||||
<AD02> = 25;
|
|
||||||
<AD03> = 26;
|
|
||||||
<AD04> = 27;
|
|
||||||
<AD05> = 28;
|
|
||||||
<AD06> = 29;
|
|
||||||
<AD07> = 30;
|
|
||||||
<AD08> = 31;
|
|
||||||
<AD09> = 32;
|
|
||||||
<AD10> = 33;
|
|
||||||
<AD11> = 34;
|
|
||||||
<AD12> = 35;
|
|
||||||
<RTRN> = 36;
|
|
||||||
<LCTL> = 37;
|
|
||||||
<AC01> = 38;
|
|
||||||
<AC02> = 39;
|
|
||||||
<AC03> = 40;
|
|
||||||
<AC04> = 41;
|
|
||||||
<AC05> = 42;
|
|
||||||
<AC06> = 43;
|
|
||||||
<AC07> = 44;
|
|
||||||
<AC08> = 45;
|
|
||||||
<AC09> = 46;
|
|
||||||
<AC10> = 47;
|
|
||||||
<AC11> = 48;
|
|
||||||
<TLDE> = 49;
|
|
||||||
<LFSH> = 50;
|
|
||||||
<BKSL> = 51;
|
|
||||||
<AB01> = 52;
|
|
||||||
<AB02> = 53;
|
|
||||||
<AB03> = 54;
|
|
||||||
<AB04> = 55;
|
|
||||||
<AB05> = 56;
|
|
||||||
<AB06> = 57;
|
|
||||||
<AB07> = 58;
|
|
||||||
<AB08> = 59;
|
|
||||||
<AB09> = 60;
|
|
||||||
<AB10> = 61;
|
|
||||||
<RTSH> = 62;
|
|
||||||
<KPMU> = 63;
|
|
||||||
<LALT> = 64;
|
|
||||||
<SPCE> = 65;
|
|
||||||
<CAPS> = 66;
|
|
||||||
<FK01> = 67;
|
|
||||||
<FK02> = 68;
|
|
||||||
<FK03> = 69;
|
|
||||||
<FK04> = 70;
|
|
||||||
<FK05> = 71;
|
|
||||||
<FK06> = 72;
|
|
||||||
<FK07> = 73;
|
|
||||||
<FK08> = 74;
|
|
||||||
<FK09> = 75;
|
|
||||||
<FK10> = 76;
|
|
||||||
<NMLK> = 77;
|
|
||||||
<SCLK> = 78;
|
|
||||||
<KP7> = 79;
|
|
||||||
<KP8> = 80;
|
|
||||||
<KP9> = 81;
|
|
||||||
<KPSU> = 82;
|
|
||||||
<KP4> = 83;
|
|
||||||
<KP5> = 84;
|
|
||||||
<KP6> = 85;
|
|
||||||
<KPAD> = 86;
|
|
||||||
<KP1> = 87;
|
|
||||||
<KP2> = 88;
|
|
||||||
<KP3> = 89;
|
|
||||||
<KP0> = 90;
|
|
||||||
<KPDL> = 91;
|
|
||||||
<LVL3> = 92;
|
|
||||||
<LSGT> = 94;
|
|
||||||
<FK11> = 95;
|
|
||||||
<FK12> = 96;
|
|
||||||
<AB11> = 97;
|
|
||||||
<KATA> = 98;
|
|
||||||
<HIRA> = 99;
|
|
||||||
<HENK> = 100;
|
|
||||||
<HKTG> = 101;
|
|
||||||
<MUHE> = 102;
|
|
||||||
<JPCM> = 103;
|
|
||||||
<KPEN> = 104;
|
|
||||||
<RCTL> = 105;
|
|
||||||
<KPDV> = 106;
|
|
||||||
<PRSC> = 107;
|
|
||||||
<RALT> = 108;
|
|
||||||
<LNFD> = 109;
|
|
||||||
<HOME> = 110;
|
|
||||||
<UP> = 111;
|
|
||||||
<PGUP> = 112;
|
|
||||||
<LEFT> = 113;
|
|
||||||
<RGHT> = 114;
|
|
||||||
<END> = 115;
|
|
||||||
<DOWN> = 116;
|
|
||||||
<PGDN> = 117;
|
|
||||||
<INS> = 118;
|
|
||||||
<DELE> = 119;
|
|
||||||
<I120> = 120;
|
|
||||||
<MUTE> = 121;
|
|
||||||
<VOL-> = 122;
|
|
||||||
<VOL+> = 123;
|
|
||||||
<POWR> = 124;
|
|
||||||
<KPEQ> = 125;
|
|
||||||
<I126> = 126;
|
|
||||||
<PAUS> = 127;
|
|
||||||
<I128> = 128;
|
|
||||||
<I129> = 129;
|
|
||||||
<HNGL> = 130;
|
|
||||||
<HJCV> = 131;
|
|
||||||
<AE13> = 132;
|
|
||||||
<LWIN> = 133;
|
|
||||||
<RWIN> = 134;
|
|
||||||
<COMP> = 135;
|
|
||||||
<STOP> = 136;
|
|
||||||
<AGAI> = 137;
|
|
||||||
<PROP> = 138;
|
|
||||||
<UNDO> = 139;
|
|
||||||
<FRNT> = 140;
|
|
||||||
<COPY> = 141;
|
|
||||||
<OPEN> = 142;
|
|
||||||
<PAST> = 143;
|
|
||||||
<FIND> = 144;
|
|
||||||
<CUT> = 145;
|
|
||||||
<HELP> = 146;
|
|
||||||
<I147> = 147;
|
|
||||||
<I148> = 148;
|
|
||||||
<I149> = 149;
|
|
||||||
<I150> = 150;
|
|
||||||
<I151> = 151;
|
|
||||||
<I152> = 152;
|
|
||||||
<I153> = 153;
|
|
||||||
<I154> = 154;
|
|
||||||
<I155> = 155;
|
|
||||||
<I156> = 156;
|
|
||||||
<I157> = 157;
|
|
||||||
<I158> = 158;
|
|
||||||
<I159> = 159;
|
|
||||||
<I160> = 160;
|
|
||||||
<I161> = 161;
|
|
||||||
<I162> = 162;
|
|
||||||
<I163> = 163;
|
|
||||||
<I164> = 164;
|
|
||||||
<I165> = 165;
|
|
||||||
<I166> = 166;
|
|
||||||
<I167> = 167;
|
|
||||||
<I168> = 168;
|
|
||||||
<I169> = 169;
|
|
||||||
<I170> = 170;
|
|
||||||
<I171> = 171;
|
|
||||||
<I172> = 172;
|
|
||||||
<I173> = 173;
|
|
||||||
<I174> = 174;
|
|
||||||
<I175> = 175;
|
|
||||||
<I176> = 176;
|
|
||||||
<I177> = 177;
|
|
||||||
<I178> = 178;
|
|
||||||
<I179> = 179;
|
|
||||||
<I180> = 180;
|
|
||||||
<I181> = 181;
|
|
||||||
<I182> = 182;
|
|
||||||
<I183> = 183;
|
|
||||||
<I184> = 184;
|
|
||||||
<I185> = 185;
|
|
||||||
<I186> = 186;
|
|
||||||
<I187> = 187;
|
|
||||||
<I188> = 188;
|
|
||||||
<I189> = 189;
|
|
||||||
<I190> = 190;
|
|
||||||
<FK13> = 191;
|
|
||||||
<FK14> = 192;
|
|
||||||
<FK15> = 193;
|
|
||||||
<FK16> = 194;
|
|
||||||
<FK17> = 195;
|
|
||||||
<FK18> = 196;
|
|
||||||
<FK19> = 197;
|
|
||||||
<FK20> = 198;
|
|
||||||
<FK21> = 199;
|
|
||||||
<FK22> = 200;
|
|
||||||
<FK23> = 201;
|
|
||||||
<FK24> = 202;
|
|
||||||
<MDSW> = 203;
|
|
||||||
<ALT> = 204;
|
|
||||||
<META> = 205;
|
|
||||||
<SUPR> = 206;
|
|
||||||
<HYPR> = 207;
|
|
||||||
<I208> = 208;
|
|
||||||
<I209> = 209;
|
|
||||||
<I210> = 210;
|
|
||||||
<I211> = 211;
|
|
||||||
<I212> = 212;
|
|
||||||
<I213> = 213;
|
|
||||||
<I214> = 214;
|
|
||||||
<I215> = 215;
|
|
||||||
<I216> = 216;
|
|
||||||
<I217> = 217;
|
|
||||||
<I218> = 218;
|
|
||||||
<I219> = 219;
|
|
||||||
<I220> = 220;
|
|
||||||
<I221> = 221;
|
|
||||||
<I222> = 222;
|
|
||||||
<I223> = 223;
|
|
||||||
<I224> = 224;
|
|
||||||
<I225> = 225;
|
|
||||||
<I226> = 226;
|
|
||||||
<I227> = 227;
|
|
||||||
<I228> = 228;
|
|
||||||
<I229> = 229;
|
|
||||||
<I230> = 230;
|
|
||||||
<I231> = 231;
|
|
||||||
<I232> = 232;
|
|
||||||
<I233> = 233;
|
|
||||||
<I234> = 234;
|
|
||||||
<I235> = 235;
|
|
||||||
<I236> = 236;
|
|
||||||
<I237> = 237;
|
|
||||||
<I238> = 238;
|
|
||||||
<I239> = 239;
|
|
||||||
<I240> = 240;
|
|
||||||
<I241> = 241;
|
|
||||||
<I242> = 242;
|
|
||||||
<I243> = 243;
|
|
||||||
<I244> = 244;
|
|
||||||
<I245> = 245;
|
|
||||||
<I246> = 246;
|
|
||||||
<I247> = 247;
|
|
||||||
<I248> = 248;
|
|
||||||
<I249> = 249;
|
|
||||||
<I250> = 250;
|
|
||||||
<I251> = 251;
|
|
||||||
<I252> = 252;
|
|
||||||
<I253> = 253;
|
|
||||||
<I254> = 254;
|
|
||||||
<I255> = 255;
|
|
||||||
};
|
|
||||||
|
|
||||||
xkb_symbols "squeekboard" {
|
|
||||||
|
|
||||||
name[Group1] = "Letters";
|
|
||||||
name[Group2] = "Numbers/Symbols";
|
|
||||||
|
|
||||||
key <AD01> { [ 1, 1 ], [ 1, 1 ] };
|
|
||||||
key <AD02> { [ 2, 2 ], [ 2, 2 ] };
|
|
||||||
key <AD03> { [ 3, 3 ], [ 3, 3 ] };
|
|
||||||
key <AD04> { [ parenleft, parenleft ], [ parenleft, parenleft ] };
|
|
||||||
key <AD05> { [ parenright, parenright ], [ parenright, parenright ] };
|
|
||||||
key <AC01> { [ 4, 4 ], [ 4, 4 ] };
|
|
||||||
key <AC02> { [ 5, 5 ], [ 5, 5 ] };
|
|
||||||
key <AC03> { [ 6, 6 ], [ 6, 6 ] };
|
|
||||||
key <AC04> { [ numbersign, numbersign ], [ numbersign, numbersign ] };
|
|
||||||
key <AC05> { [ asterisk, asterisk ], [ asterisk, asterisk ] };
|
|
||||||
key <AB01> { [ 7, 7 ], [ 7, 7 ] };
|
|
||||||
key <AB02> { [ 8, 8 ], [ 8, 8 ] };
|
|
||||||
key <AB03> { [ 9, 9 ], [ 9, 9 ] };
|
|
||||||
key <AB04> { [ plus, plus ], [ plus, plus ] };
|
|
||||||
key <AB05> { [ minus, minus ], [ minus, minus ] };
|
|
||||||
key <AB06> { [ 0, 0 ], [ 0, 0 ] };
|
|
||||||
key <RTRN> { [ Return, Return ], [ Return, Return ] };
|
|
||||||
key <SPCE> { [ space, space ], [ space, space ] };
|
|
||||||
key <BKSP> { [ BackSpace, BackSpace ], [ BackSpace, BackSpace ] };
|
|
||||||
};
|
|
||||||
|
|
||||||
xkb_types "squeekboard" {
|
|
||||||
|
|
||||||
type "TWO_LEVEL" {
|
|
||||||
modifiers = Shift;
|
|
||||||
map[Shift] = Level2;
|
|
||||||
level_name[Level1] = "Base";
|
|
||||||
level_name[Level2] = "Shift";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
xkb_compatibility "squeekboard" {
|
|
||||||
};
|
|
||||||
};
|
|
||||||
@ -1,306 +0,0 @@
|
|||||||
xkb_keymap {
|
|
||||||
|
|
||||||
xkb_keycodes "squeekboard" {
|
|
||||||
minimum = 8;
|
|
||||||
maximum = 255;
|
|
||||||
<ESC> = 9;
|
|
||||||
<AE01> = 10;
|
|
||||||
<AE02> = 11;
|
|
||||||
<AE03> = 12;
|
|
||||||
<AE04> = 13;
|
|
||||||
<AE05> = 14;
|
|
||||||
<AE06> = 15;
|
|
||||||
<AE07> = 16;
|
|
||||||
<AE08> = 17;
|
|
||||||
<AE09> = 18;
|
|
||||||
<AE10> = 19;
|
|
||||||
<AE11> = 20;
|
|
||||||
<AE12> = 21;
|
|
||||||
<BKSP> = 22;
|
|
||||||
<TAB> = 23;
|
|
||||||
<AD01> = 24;
|
|
||||||
<AD02> = 25;
|
|
||||||
<AD03> = 26;
|
|
||||||
<AD04> = 27;
|
|
||||||
<AD05> = 28;
|
|
||||||
<AD06> = 29;
|
|
||||||
<AD07> = 30;
|
|
||||||
<AD08> = 31;
|
|
||||||
<AD09> = 32;
|
|
||||||
<AD10> = 33;
|
|
||||||
<AD11> = 34;
|
|
||||||
<AD12> = 35;
|
|
||||||
<RTRN> = 36;
|
|
||||||
<LCTL> = 37;
|
|
||||||
<AC01> = 38;
|
|
||||||
<AC02> = 39;
|
|
||||||
<AC03> = 40;
|
|
||||||
<AC04> = 41;
|
|
||||||
<AC05> = 42;
|
|
||||||
<AC06> = 43;
|
|
||||||
<AC07> = 44;
|
|
||||||
<AC08> = 45;
|
|
||||||
<AC09> = 46;
|
|
||||||
<AC10> = 47;
|
|
||||||
<AC11> = 48;
|
|
||||||
<TLDE> = 49;
|
|
||||||
<LFSH> = 50;
|
|
||||||
<BKSL> = 51;
|
|
||||||
<AB01> = 52;
|
|
||||||
<AB02> = 53;
|
|
||||||
<AB03> = 54;
|
|
||||||
<AB04> = 55;
|
|
||||||
<AB05> = 56;
|
|
||||||
<AB06> = 57;
|
|
||||||
<AB07> = 58;
|
|
||||||
<AB08> = 59;
|
|
||||||
<AB09> = 60;
|
|
||||||
<AB10> = 61;
|
|
||||||
<RTSH> = 62;
|
|
||||||
<KPMU> = 63;
|
|
||||||
<LALT> = 64;
|
|
||||||
<SPCE> = 65;
|
|
||||||
<CAPS> = 66;
|
|
||||||
<FK01> = 67;
|
|
||||||
<FK02> = 68;
|
|
||||||
<FK03> = 69;
|
|
||||||
<FK04> = 70;
|
|
||||||
<FK05> = 71;
|
|
||||||
<FK06> = 72;
|
|
||||||
<FK07> = 73;
|
|
||||||
<FK08> = 74;
|
|
||||||
<FK09> = 75;
|
|
||||||
<FK10> = 76;
|
|
||||||
<NMLK> = 77;
|
|
||||||
<SCLK> = 78;
|
|
||||||
<KP7> = 79;
|
|
||||||
<KP8> = 80;
|
|
||||||
<KP9> = 81;
|
|
||||||
<KPSU> = 82;
|
|
||||||
<KP4> = 83;
|
|
||||||
<KP5> = 84;
|
|
||||||
<KP6> = 85;
|
|
||||||
<KPAD> = 86;
|
|
||||||
<KP1> = 87;
|
|
||||||
<KP2> = 88;
|
|
||||||
<KP3> = 89;
|
|
||||||
<KP0> = 90;
|
|
||||||
<KPDL> = 91;
|
|
||||||
<LVL3> = 92;
|
|
||||||
<LSGT> = 94;
|
|
||||||
<FK11> = 95;
|
|
||||||
<FK12> = 96;
|
|
||||||
<AB11> = 97;
|
|
||||||
<KATA> = 98;
|
|
||||||
<HIRA> = 99;
|
|
||||||
<HENK> = 100;
|
|
||||||
<HKTG> = 101;
|
|
||||||
<MUHE> = 102;
|
|
||||||
<JPCM> = 103;
|
|
||||||
<KPEN> = 104;
|
|
||||||
<RCTL> = 105;
|
|
||||||
<KPDV> = 106;
|
|
||||||
<PRSC> = 107;
|
|
||||||
<RALT> = 108;
|
|
||||||
<LNFD> = 109;
|
|
||||||
<HOME> = 110;
|
|
||||||
<UP> = 111;
|
|
||||||
<PGUP> = 112;
|
|
||||||
<LEFT> = 113;
|
|
||||||
<RGHT> = 114;
|
|
||||||
<END> = 115;
|
|
||||||
<DOWN> = 116;
|
|
||||||
<PGDN> = 117;
|
|
||||||
<INS> = 118;
|
|
||||||
<DELE> = 119;
|
|
||||||
<I120> = 120;
|
|
||||||
<MUTE> = 121;
|
|
||||||
<VOL-> = 122;
|
|
||||||
<VOL+> = 123;
|
|
||||||
<POWR> = 124;
|
|
||||||
<KPEQ> = 125;
|
|
||||||
<I126> = 126;
|
|
||||||
<PAUS> = 127;
|
|
||||||
<I128> = 128;
|
|
||||||
<I129> = 129;
|
|
||||||
<HNGL> = 130;
|
|
||||||
<HJCV> = 131;
|
|
||||||
<AE13> = 132;
|
|
||||||
<LWIN> = 133;
|
|
||||||
<RWIN> = 134;
|
|
||||||
<COMP> = 135;
|
|
||||||
<STOP> = 136;
|
|
||||||
<AGAI> = 137;
|
|
||||||
<PROP> = 138;
|
|
||||||
<UNDO> = 139;
|
|
||||||
<FRNT> = 140;
|
|
||||||
<COPY> = 141;
|
|
||||||
<OPEN> = 142;
|
|
||||||
<PAST> = 143;
|
|
||||||
<FIND> = 144;
|
|
||||||
<CUT> = 145;
|
|
||||||
<HELP> = 146;
|
|
||||||
<I147> = 147;
|
|
||||||
<I148> = 148;
|
|
||||||
<I149> = 149;
|
|
||||||
<I150> = 150;
|
|
||||||
<I151> = 151;
|
|
||||||
<I152> = 152;
|
|
||||||
<I153> = 153;
|
|
||||||
<I154> = 154;
|
|
||||||
<I155> = 155;
|
|
||||||
<I156> = 156;
|
|
||||||
<I157> = 157;
|
|
||||||
<I158> = 158;
|
|
||||||
<I159> = 159;
|
|
||||||
<I160> = 160;
|
|
||||||
<I161> = 161;
|
|
||||||
<I162> = 162;
|
|
||||||
<I163> = 163;
|
|
||||||
<I164> = 164;
|
|
||||||
<I165> = 165;
|
|
||||||
<I166> = 166;
|
|
||||||
<I167> = 167;
|
|
||||||
<I168> = 168;
|
|
||||||
<I169> = 169;
|
|
||||||
<I170> = 170;
|
|
||||||
<I171> = 171;
|
|
||||||
<I172> = 172;
|
|
||||||
<I173> = 173;
|
|
||||||
<I174> = 174;
|
|
||||||
<I175> = 175;
|
|
||||||
<I176> = 176;
|
|
||||||
<I177> = 177;
|
|
||||||
<I178> = 178;
|
|
||||||
<I179> = 179;
|
|
||||||
<I180> = 180;
|
|
||||||
<I181> = 181;
|
|
||||||
<I182> = 182;
|
|
||||||
<I183> = 183;
|
|
||||||
<I184> = 184;
|
|
||||||
<I185> = 185;
|
|
||||||
<I186> = 186;
|
|
||||||
<I187> = 187;
|
|
||||||
<I188> = 188;
|
|
||||||
<I189> = 189;
|
|
||||||
<I190> = 190;
|
|
||||||
<FK13> = 191;
|
|
||||||
<FK14> = 192;
|
|
||||||
<FK15> = 193;
|
|
||||||
<FK16> = 194;
|
|
||||||
<FK17> = 195;
|
|
||||||
<FK18> = 196;
|
|
||||||
<FK19> = 197;
|
|
||||||
<FK20> = 198;
|
|
||||||
<FK21> = 199;
|
|
||||||
<FK22> = 200;
|
|
||||||
<FK23> = 201;
|
|
||||||
<FK24> = 202;
|
|
||||||
<MDSW> = 203;
|
|
||||||
<ALT> = 204;
|
|
||||||
<META> = 205;
|
|
||||||
<SUPR> = 206;
|
|
||||||
<HYPR> = 207;
|
|
||||||
<I208> = 208;
|
|
||||||
<I209> = 209;
|
|
||||||
<I210> = 210;
|
|
||||||
<I211> = 211;
|
|
||||||
<I212> = 212;
|
|
||||||
<I213> = 213;
|
|
||||||
<I214> = 214;
|
|
||||||
<I215> = 215;
|
|
||||||
<I216> = 216;
|
|
||||||
<I217> = 217;
|
|
||||||
<I218> = 218;
|
|
||||||
<I219> = 219;
|
|
||||||
<I220> = 220;
|
|
||||||
<I221> = 221;
|
|
||||||
<I222> = 222;
|
|
||||||
<I223> = 223;
|
|
||||||
<I224> = 224;
|
|
||||||
<I225> = 225;
|
|
||||||
<I226> = 226;
|
|
||||||
<I227> = 227;
|
|
||||||
<I228> = 228;
|
|
||||||
<I229> = 229;
|
|
||||||
<I230> = 230;
|
|
||||||
<I231> = 231;
|
|
||||||
<I232> = 232;
|
|
||||||
<I233> = 233;
|
|
||||||
<I234> = 234;
|
|
||||||
<I235> = 235;
|
|
||||||
<I236> = 236;
|
|
||||||
<I237> = 237;
|
|
||||||
<I238> = 238;
|
|
||||||
<I239> = 239;
|
|
||||||
<I240> = 240;
|
|
||||||
<I241> = 241;
|
|
||||||
<I242> = 242;
|
|
||||||
<I243> = 243;
|
|
||||||
<I244> = 244;
|
|
||||||
<I245> = 245;
|
|
||||||
<I246> = 246;
|
|
||||||
<I247> = 247;
|
|
||||||
<I248> = 248;
|
|
||||||
<I249> = 249;
|
|
||||||
<I250> = 250;
|
|
||||||
<I251> = 251;
|
|
||||||
<I252> = 252;
|
|
||||||
<I253> = 253;
|
|
||||||
<I254> = 254;
|
|
||||||
<I255> = 255;
|
|
||||||
};
|
|
||||||
|
|
||||||
xkb_symbols "squeekboard" {
|
|
||||||
|
|
||||||
name[Group1] = "Letters";
|
|
||||||
name[Group2] = "Numbers/Symbols";
|
|
||||||
|
|
||||||
key <AD01> { [ q, Q ], [ 1, asciitilde ] };
|
|
||||||
key <AD02> { [ w, W ], [ 2, quoteleft ] };
|
|
||||||
key <AD03> { [ e, E ], [ 3, bar ] };
|
|
||||||
key <AD04> { [ r, R ], [ 4, U00B7 ] };
|
|
||||||
key <AD05> { [ t, T ], [ 5, squareroot ] };
|
|
||||||
key <AD06> { [ y, Y ], [ 6, Greek_pi ] };
|
|
||||||
key <AD07> { [ u, U ], [ 7, division ] };
|
|
||||||
key <AD08> { [ i, I ], [ 8, multiply ] };
|
|
||||||
key <AD09> { [ o, O ], [ 9, paragraph ] };
|
|
||||||
key <AD10> { [ p, P ], [ 0, U25B3 ] };
|
|
||||||
key <AC01> { [ a, A ], [ at, copyright ] };
|
|
||||||
key <AC02> { [ s, S ], [ numbersign, U00AE ] };
|
|
||||||
key <AC03> { [ d, D ], [ dollar, U00A3 ] };
|
|
||||||
key <AC04> { [ f, F ], [ percent, EuroSign ] };
|
|
||||||
key <AC05> { [ g, G ], [ ampersand, U00A5 ] };
|
|
||||||
key <AC06> { [ h, H ], [ minus, asciicircum ] };
|
|
||||||
key <AC07> { [ j, J ], [ underscore, degree ] };
|
|
||||||
key <AC08> { [ k, K ], [ plus, equal ] };
|
|
||||||
key <AC09> { [ l, L ], [ parenleft, braceleft ] };
|
|
||||||
key <AC10> { [ ], [ parenright, braceright ] };
|
|
||||||
key <RTRN> { [ Return, Return ], [ Return, Return ] };
|
|
||||||
key <LFSH> { [ Shift_L, Shift_L ], [ Shift_L, Shift_L ] };
|
|
||||||
key <AB01> { [ z, Z ], [ comma, backslash ] };
|
|
||||||
key <AB02> { [ x, X ], [ quotedbl, slash ] };
|
|
||||||
key <AB03> { [ c, C ], [ quoteright, less ] };
|
|
||||||
key <AB04> { [ v, V ], [ colon, greater ] };
|
|
||||||
key <AB05> { [ b, B ], [ semicolon, equal ] };
|
|
||||||
key <AB06> { [ n, N ], [ exclam, bracketleft ] };
|
|
||||||
key <AB07> { [ m, M ], [ question, bracketright ] };
|
|
||||||
key <AB08> { [ period, period ], [ period, period ] };
|
|
||||||
key <I149> { [ preferences, preferences ], [ preferences, preferences ] };
|
|
||||||
key <SPCE> { [ space, space ], [ space, space ] };
|
|
||||||
key <BKSP> { [ BackSpace, BackSpace ], [ BackSpace, BackSpace ] };
|
|
||||||
};
|
|
||||||
|
|
||||||
xkb_types "squeekboard" {
|
|
||||||
|
|
||||||
type "TWO_LEVEL" {
|
|
||||||
modifiers = Shift;
|
|
||||||
map[Shift] = Level2;
|
|
||||||
level_name[Level1] = "Base";
|
|
||||||
level_name[Level2] = "Shift";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
xkb_compatibility "squeekboard" {
|
|
||||||
};
|
|
||||||
};
|
|
||||||
@ -1,204 +0,0 @@
|
|||||||
<?xml version='1.0' encoding='ASCII' standalone='yes'?>
|
|
||||||
<symbols version="0.90">
|
|
||||||
<key name="AD01">
|
|
||||||
<symbol label="q">q</symbol>
|
|
||||||
<symbol label="Q">Q</symbol>
|
|
||||||
<symbol label="1">1</symbol>
|
|
||||||
<symbol label="~">asciitilde</symbol>
|
|
||||||
</key>
|
|
||||||
<key name="AD02">
|
|
||||||
<symbol label="w">w</symbol>
|
|
||||||
<symbol label="W">W</symbol>
|
|
||||||
<symbol label="2">2</symbol>
|
|
||||||
<symbol label="`">quoteleft</symbol>
|
|
||||||
</key>
|
|
||||||
<key name="AD03">
|
|
||||||
<symbol label="e">e</symbol>
|
|
||||||
<symbol label="E">E</symbol>
|
|
||||||
<symbol label="3">3</symbol>
|
|
||||||
<symbol label="|">bar</symbol>
|
|
||||||
</key>
|
|
||||||
<key name="AD04">
|
|
||||||
<symbol label="r">r</symbol>
|
|
||||||
<symbol label="R">R</symbol>
|
|
||||||
<symbol label="4">4</symbol>
|
|
||||||
<symbol label="·">U00B7</symbol>
|
|
||||||
</key>
|
|
||||||
<key name="AD05">
|
|
||||||
<symbol label="t">t</symbol>
|
|
||||||
<symbol label="T">T</symbol>
|
|
||||||
<symbol label="5">5</symbol>
|
|
||||||
<symbol label="√">squareroot</symbol>
|
|
||||||
</key>
|
|
||||||
<key name="AD06">
|
|
||||||
<symbol label="y">y</symbol>
|
|
||||||
<symbol label="Y">Y</symbol>
|
|
||||||
<symbol label="6">6</symbol>
|
|
||||||
<symbol label="π">Greek_pi</symbol>
|
|
||||||
</key>
|
|
||||||
<key name="AD07">
|
|
||||||
<symbol label="u">u</symbol>
|
|
||||||
<symbol label="U">U</symbol>
|
|
||||||
<symbol label="7">7</symbol>
|
|
||||||
<symbol label="÷">division</symbol>
|
|
||||||
</key>
|
|
||||||
<key name="AD08">
|
|
||||||
<symbol label="i">i</symbol>
|
|
||||||
<symbol label="I">I</symbol>
|
|
||||||
<symbol label="8">8</symbol>
|
|
||||||
<symbol label="×">multiply</symbol>
|
|
||||||
</key>
|
|
||||||
<key name="AD09">
|
|
||||||
<symbol label="o">o</symbol>
|
|
||||||
<symbol label="O">O</symbol>
|
|
||||||
<symbol label="9">9</symbol>
|
|
||||||
<symbol label="¶">paragraph</symbol>
|
|
||||||
</key>
|
|
||||||
<key name="AD10">
|
|
||||||
<symbol label="p">p</symbol>
|
|
||||||
<symbol label="P">P</symbol>
|
|
||||||
<symbol label="0">0</symbol>
|
|
||||||
<symbol label="△">U25B3</symbol>
|
|
||||||
</key>
|
|
||||||
<key name="AD11">
|
|
||||||
<symbol keyval="229" label="å">aring</symbol>
|
|
||||||
<symbol keyval="197" label="Å">Aring</symbol>
|
|
||||||
<symbol label="±">U00B1</symbol>
|
|
||||||
<symbol label="§">U00A7</symbol>
|
|
||||||
</key>
|
|
||||||
<key name="AC01">
|
|
||||||
<symbol label="a">a</symbol>
|
|
||||||
<symbol label="A">A</symbol>
|
|
||||||
<symbol label="@">at</symbol>
|
|
||||||
<symbol label="©">copyright</symbol>
|
|
||||||
</key>
|
|
||||||
<key name="AC02">
|
|
||||||
<symbol label="s">s</symbol>
|
|
||||||
<symbol label="S">S</symbol>
|
|
||||||
<symbol label="#">numbersign</symbol>
|
|
||||||
<symbol label="®">U00AE</symbol>
|
|
||||||
</key>
|
|
||||||
<key name="AC03">
|
|
||||||
<symbol label="d">d</symbol>
|
|
||||||
<symbol label="D">D</symbol>
|
|
||||||
<symbol label="$">dollar</symbol>
|
|
||||||
<symbol label="£">U00A3</symbol>
|
|
||||||
</key>
|
|
||||||
<key name="AC04">
|
|
||||||
<symbol label="f">f</symbol>
|
|
||||||
<symbol label="F">F</symbol>
|
|
||||||
<symbol label="%">percent</symbol>
|
|
||||||
<symbol label="€">EuroSign</symbol>
|
|
||||||
</key>
|
|
||||||
<key name="AC05">
|
|
||||||
<symbol label="g">g</symbol>
|
|
||||||
<symbol label="G">G</symbol>
|
|
||||||
<symbol label="&">ampersand</symbol>
|
|
||||||
<symbol label="¥">U00A5</symbol>
|
|
||||||
</key>
|
|
||||||
<key name="AC06">
|
|
||||||
<symbol label="h">h</symbol>
|
|
||||||
<symbol label="H">H</symbol>
|
|
||||||
<symbol label="-">minus</symbol>
|
|
||||||
<symbol label="_">underscore</symbol>
|
|
||||||
</key>
|
|
||||||
<key name="AC07">
|
|
||||||
<symbol label="j">j</symbol>
|
|
||||||
<symbol label="J">J</symbol>
|
|
||||||
<symbol label="+">plus</symbol>
|
|
||||||
<symbol label="=">equal</symbol>
|
|
||||||
</key>
|
|
||||||
<key name="AC08">
|
|
||||||
<symbol label="k">k</symbol>
|
|
||||||
<symbol label="K">K</symbol>
|
|
||||||
<symbol label="ü">U00FC</symbol>
|
|
||||||
<symbol label="^">asciicircum</symbol>
|
|
||||||
</key>
|
|
||||||
<key name="AC09">
|
|
||||||
<symbol label="l">l</symbol>
|
|
||||||
<symbol label="L">L</symbol>
|
|
||||||
<symbol label="ö">U00F6</symbol>
|
|
||||||
<symbol label="°">degree</symbol>
|
|
||||||
</key>
|
|
||||||
<key name="AC10">
|
|
||||||
<symbol keyval="248" label="ø">oslash</symbol>
|
|
||||||
<symbol keyval="216" label="Ø">Oslash</symbol>
|
|
||||||
<symbol label="(">parenleft</symbol>
|
|
||||||
<symbol label="{">braceleft</symbol>
|
|
||||||
</key>
|
|
||||||
<key name="AC11">
|
|
||||||
<symbol keyval="230" label="æ">ae</symbol>
|
|
||||||
<symbol keyval="198" label="Æ">AE</symbol>
|
|
||||||
<symbol label=")">parenright</symbol>
|
|
||||||
<symbol label="}">braceright</symbol>
|
|
||||||
</key>
|
|
||||||
<key name="RTRN">
|
|
||||||
<symbol keyval="65293" icon="key-enter">Return</symbol>
|
|
||||||
</key>
|
|
||||||
<key name="LFSH">
|
|
||||||
<keysym keyval="65505" icon="key-shift">Shift_L</keysym>
|
|
||||||
<keysym keyval="65505" icon="key-shift">Shift_L</keysym>
|
|
||||||
<keysym keyval="65505" label="=/+">Shift_L</keysym>
|
|
||||||
<keysym keyval="65505" label="123">Shift_L</keysym>
|
|
||||||
</key>
|
|
||||||
<key name="AB01">
|
|
||||||
<symbol label="z">z</symbol>
|
|
||||||
<symbol label="Z">Z</symbol>
|
|
||||||
<symbol label=",">comma</symbol>
|
|
||||||
<symbol label="\">backslash</symbol>
|
|
||||||
</key>
|
|
||||||
<key name="AB02">
|
|
||||||
<symbol label="x">x</symbol>
|
|
||||||
<symbol label="X">X</symbol>
|
|
||||||
<symbol label=""">quotedbl</symbol>
|
|
||||||
<symbol label="/">slash</symbol>
|
|
||||||
</key>
|
|
||||||
<key name="AB03">
|
|
||||||
<symbol label="c">c</symbol>
|
|
||||||
<symbol label="C">C</symbol>
|
|
||||||
<symbol label="'">quoteright</symbol>
|
|
||||||
<symbol label="<">less</symbol>
|
|
||||||
</key>
|
|
||||||
<key name="AB04">
|
|
||||||
<symbol label="v">v</symbol>
|
|
||||||
<symbol label="V">V</symbol>
|
|
||||||
<symbol label=":">colon</symbol>
|
|
||||||
<symbol label=">">greater</symbol>
|
|
||||||
</key>
|
|
||||||
<key name="AB05">
|
|
||||||
<symbol label="b">b</symbol>
|
|
||||||
<symbol label="B">B</symbol>
|
|
||||||
<symbol label=";">semicolon</symbol>
|
|
||||||
<symbol label="=">equal</symbol>
|
|
||||||
</key>
|
|
||||||
<key name="AB06">
|
|
||||||
<symbol label="n">n</symbol>
|
|
||||||
<symbol label="N">N</symbol>
|
|
||||||
<symbol label="!">exclam</symbol>
|
|
||||||
<symbol label="[">bracketleft</symbol>
|
|
||||||
</key>
|
|
||||||
<key name="AB07">
|
|
||||||
<symbol label="m">m</symbol>
|
|
||||||
<symbol label="M">M</symbol>
|
|
||||||
<symbol label="?">question</symbol>
|
|
||||||
<symbol label="]">bracketright</symbol>
|
|
||||||
</key>
|
|
||||||
<key name="AB08">
|
|
||||||
<symbol label=".">period</symbol>
|
|
||||||
</key>
|
|
||||||
<key name="ABC123">
|
|
||||||
<symbol label="123">show-numbers</symbol>
|
|
||||||
<symbol label="123">show-numbers</symbol>
|
|
||||||
<symbol label="ABC">show-letters</symbol>
|
|
||||||
<symbol label="ABC">show-letters</symbol>
|
|
||||||
</key>
|
|
||||||
<key name="I149">
|
|
||||||
<symbol icon="keyboard-mode-symbolic" tooltip="Setup">preferences</symbol>
|
|
||||||
</key>
|
|
||||||
<key name="SPCE">
|
|
||||||
<symbol label=" ">space</symbol>
|
|
||||||
</key>
|
|
||||||
<key name="BKSP">
|
|
||||||
<symbol keyval="65288" icon="edit-clear-symbolic">BackSpace</symbol>
|
|
||||||
</key>
|
|
||||||
</symbols>
|
|
||||||
@ -1,60 +0,0 @@
|
|||||||
<?xml version='1.0' encoding='ASCII' standalone='yes'?>
|
|
||||||
<symbols version="0.90">
|
|
||||||
<key name="AD01">
|
|
||||||
<symbol label="1">1</symbol>
|
|
||||||
</key>
|
|
||||||
<key name="AD02">
|
|
||||||
<symbol label="2">2</symbol>
|
|
||||||
</key>
|
|
||||||
<key name="AD03">
|
|
||||||
<symbol label="3">3</symbol>
|
|
||||||
</key>
|
|
||||||
<key name="AD04">
|
|
||||||
<symbol label="(">parenleft</symbol>
|
|
||||||
</key>
|
|
||||||
<key name="AD05">
|
|
||||||
<symbol label=")">parenright</symbol>
|
|
||||||
</key>
|
|
||||||
<key name="AC01">
|
|
||||||
<symbol label="4">4</symbol>
|
|
||||||
</key>
|
|
||||||
<key name="AC02">
|
|
||||||
<symbol label="5">5</symbol>
|
|
||||||
</key>
|
|
||||||
<key name="AC03">
|
|
||||||
<symbol label="6">6</symbol>
|
|
||||||
</key>
|
|
||||||
<key name="AC04">
|
|
||||||
<symbol label="#">numbersign</symbol>
|
|
||||||
</key>
|
|
||||||
<key name="AC05">
|
|
||||||
<symbol label="*">asterisk</symbol>
|
|
||||||
</key>
|
|
||||||
<key name="AB01">
|
|
||||||
<symbol label="7">7</symbol>
|
|
||||||
</key>
|
|
||||||
<key name="AB02">
|
|
||||||
<symbol label="8">8</symbol>
|
|
||||||
</key>
|
|
||||||
<key name="AB03">
|
|
||||||
<symbol label="9">9</symbol>
|
|
||||||
</key>
|
|
||||||
<key name="AB04">
|
|
||||||
<symbol label="+">plus</symbol>
|
|
||||||
</key>
|
|
||||||
<key name="AB05">
|
|
||||||
<symbol label="-">minus</symbol>
|
|
||||||
</key>
|
|
||||||
<key name="AB06">
|
|
||||||
<symbol label="0">0</symbol>
|
|
||||||
</key>
|
|
||||||
<key name="RTRN">
|
|
||||||
<symbol keyval="65293" icon="key-enter">Return</symbol>
|
|
||||||
</key>
|
|
||||||
<key name="SPCE">
|
|
||||||
<symbol label=" ">space</symbol>
|
|
||||||
</key>
|
|
||||||
<key name="BKSP">
|
|
||||||
<symbol keyval="65288" icon="edit-clear-symbolic">BackSpace</symbol>
|
|
||||||
</key>
|
|
||||||
</symbols>
|
|
||||||
@ -1,192 +1,304 @@
|
|||||||
<?xml version='1.0' encoding='ASCII' standalone='yes'?>
|
<?xml version="1.0"?>
|
||||||
<symbols version="0.90">
|
<symbols version="0.90">
|
||||||
<key name="AD01">
|
<key keycode="9" name="ESC">
|
||||||
<symbol label="q">q</symbol>
|
<keysym keyval="65307">Escape</keysym>
|
||||||
<symbol label="Q">Q</symbol>
|
|
||||||
<symbol label="1">1</symbol>
|
|
||||||
<symbol label="~">asciitilde</symbol>
|
|
||||||
</key>
|
</key>
|
||||||
<key name="AD02">
|
<key keycode="67" name="FK01">
|
||||||
<symbol label="w">w</symbol>
|
<keysym keyval="65470">F1</keysym>
|
||||||
<symbol label="W">W</symbol>
|
|
||||||
<symbol label="2">2</symbol>
|
|
||||||
<symbol label="`">quoteleft</symbol>
|
|
||||||
</key>
|
</key>
|
||||||
<key name="AD03">
|
<key keycode="68" name="FK02">
|
||||||
<symbol label="e">e</symbol>
|
<keysym keyval="65471">F2</keysym>
|
||||||
<symbol label="E">E</symbol>
|
|
||||||
<symbol label="3">3</symbol>
|
|
||||||
<symbol label="|">bar</symbol>
|
|
||||||
</key>
|
</key>
|
||||||
<key name="AD04">
|
<key keycode="69" name="FK03">
|
||||||
<symbol label="r">r</symbol>
|
<keysym keyval="65472">F3</keysym>
|
||||||
<symbol label="R">R</symbol>
|
|
||||||
<symbol label="4">4</symbol>
|
|
||||||
<symbol label="·">U00B7</symbol>
|
|
||||||
</key>
|
</key>
|
||||||
<key name="AD05">
|
<key keycode="70" name="FK04">
|
||||||
<symbol label="t">t</symbol>
|
<keysym keyval="65473">F4</keysym>
|
||||||
<symbol label="T">T</symbol>
|
|
||||||
<symbol label="5">5</symbol>
|
|
||||||
<symbol label="√">squareroot</symbol>
|
|
||||||
</key>
|
</key>
|
||||||
<key name="AD06">
|
<key keycode="71" name="FK05">
|
||||||
<symbol label="y">y</symbol>
|
<keysym keyval="65474">F5</keysym>
|
||||||
<symbol label="Y">Y</symbol>
|
|
||||||
<symbol label="6">6</symbol>
|
|
||||||
<symbol label="π">Greek_pi</symbol>
|
|
||||||
</key>
|
</key>
|
||||||
<key name="AD07">
|
<key keycode="72" name="FK06">
|
||||||
<symbol label="u">u</symbol>
|
<keysym keyval="65475">F6</keysym>
|
||||||
<symbol label="U">U</symbol>
|
|
||||||
<symbol label="7">7</symbol>
|
|
||||||
<symbol label="÷">division</symbol>
|
|
||||||
</key>
|
</key>
|
||||||
<key name="AD08">
|
<key keycode="73" name="FK07">
|
||||||
<symbol label="i">i</symbol>
|
<keysym keyval="65476">F7</keysym>
|
||||||
<symbol label="I">I</symbol>
|
|
||||||
<symbol label="8">8</symbol>
|
|
||||||
<symbol label="×">multiply</symbol>
|
|
||||||
</key>
|
</key>
|
||||||
<key name="AD09">
|
<key keycode="74" name="FK08">
|
||||||
<symbol label="o">o</symbol>
|
<keysym keyval="65477">F8</keysym>
|
||||||
<symbol label="O">O</symbol>
|
|
||||||
<symbol label="9">9</symbol>
|
|
||||||
<symbol label="¶">paragraph</symbol>
|
|
||||||
</key>
|
</key>
|
||||||
<key name="AD10">
|
<key keycode="75" name="FK09">
|
||||||
<symbol label="p">p</symbol>
|
<keysym keyval="65478">F9</keysym>
|
||||||
<symbol label="P">P</symbol>
|
|
||||||
<symbol label="0">0</symbol>
|
|
||||||
<symbol label="△">U25B3</symbol>
|
|
||||||
</key>
|
</key>
|
||||||
<key name="AC01">
|
<key keycode="76" name="FK10">
|
||||||
<symbol label="a">a</symbol>
|
<keysym keyval="65479">F10</keysym>
|
||||||
<symbol label="A">A</symbol>
|
|
||||||
<symbol label="@">at</symbol>
|
|
||||||
<symbol label="©">copyright</symbol>
|
|
||||||
</key>
|
</key>
|
||||||
<key name="AC02">
|
<key keycode="95" name="FK11">
|
||||||
<symbol label="s">s</symbol>
|
<keysym keyval="65480">F11</keysym>
|
||||||
<symbol label="S">S</symbol>
|
|
||||||
<symbol label="#">numbersign</symbol>
|
|
||||||
<symbol label="®">U00AE</symbol>
|
|
||||||
</key>
|
</key>
|
||||||
<key name="AC03">
|
<key keycode="96" name="FK12">
|
||||||
<symbol label="d">d</symbol>
|
<keysym keyval="65481">F12</keysym>
|
||||||
<symbol label="D">D</symbol>
|
|
||||||
<symbol label="$">dollar</symbol>
|
|
||||||
<symbol label="£">U00A3</symbol>
|
|
||||||
</key>
|
</key>
|
||||||
<key name="AC04">
|
<key keycode="49" name="TLDE">
|
||||||
<symbol label="f">f</symbol>
|
<keysym keyval="96">quoteleft</keysym>
|
||||||
<symbol label="F">F</symbol>
|
<keysym keyval="126">asciitilde</keysym>
|
||||||
<symbol label="%">percent</symbol>
|
|
||||||
<symbol label="€">EuroSign</symbol>
|
|
||||||
</key>
|
</key>
|
||||||
<key name="AC05">
|
<key keycode="10" name="AE01">
|
||||||
<symbol label="g">g</symbol>
|
<keysym keyval="49">1</keysym>
|
||||||
<symbol label="G">G</symbol>
|
<keysym keyval="33">exclam</keysym>
|
||||||
<symbol label="&">ampersand</symbol>
|
|
||||||
<symbol label="¥">U00A5</symbol>
|
|
||||||
</key>
|
</key>
|
||||||
<key name="AC06">
|
<key keycode="11" name="AE02">
|
||||||
<symbol label="h">h</symbol>
|
<keysym keyval="50">2</keysym>
|
||||||
<symbol label="H">H</symbol>
|
<keysym keyval="64">at</keysym>
|
||||||
<symbol label="-">minus</symbol>
|
|
||||||
<symbol label="^">asciicircum</symbol>
|
|
||||||
</key>
|
</key>
|
||||||
<key name="AC07">
|
<key keycode="12" name="AE03">
|
||||||
<symbol label="j">j</symbol>
|
<keysym keyval="51">3</keysym>
|
||||||
<symbol label="J">J</symbol>
|
<keysym keyval="35">numbersign</keysym>
|
||||||
<symbol label="_">underscore</symbol>
|
|
||||||
<symbol label="°">degree</symbol>
|
|
||||||
</key>
|
</key>
|
||||||
<key name="AC08">
|
<key keycode="13" name="AE04">
|
||||||
<symbol label="k">k</symbol>
|
<keysym keyval="52">4</keysym>
|
||||||
<symbol label="K">K</symbol>
|
<keysym keyval="36">dollar</keysym>
|
||||||
<symbol label="+">plus</symbol>
|
|
||||||
<symbol label="=">equal</symbol>
|
|
||||||
</key>
|
</key>
|
||||||
<key name="AC09">
|
<key keycode="14" name="AE05">
|
||||||
<symbol label="l">l</symbol>
|
<keysym keyval="53">5</keysym>
|
||||||
<symbol label="L">L</symbol>
|
<keysym keyval="37">percent</keysym>
|
||||||
<symbol label="(">parenleft</symbol>
|
<keysym keyval="8364">EuroSign</keysym>
|
||||||
<symbol label="{">braceleft</symbol>
|
|
||||||
</key>
|
</key>
|
||||||
<key name="AC10">
|
<key keycode="15" name="AE06">
|
||||||
<symbol label=""></symbol>
|
<keysym keyval="54">6</keysym>
|
||||||
<symbol label=""></symbol>
|
<keysym keyval="94">asciicircum</keysym>
|
||||||
<symbol label=")">parenright</symbol>
|
|
||||||
<symbol label="}">braceright</symbol>
|
|
||||||
</key>
|
</key>
|
||||||
<key name="RTRN">
|
<key keycode="16" name="AE07">
|
||||||
<symbol keyval="65293" icon="key-enter">Return</symbol>
|
<keysym keyval="55">7</keysym>
|
||||||
|
<keysym keyval="38">ampersand</keysym>
|
||||||
</key>
|
</key>
|
||||||
<key name="LFSH">
|
<key keycode="17" name="AE08">
|
||||||
<keysym keyval="65505" icon="key-shift">Shift_L</keysym>
|
<keysym keyval="56">8</keysym>
|
||||||
<keysym keyval="65505" icon="key-shift">Shift_L</keysym>
|
<keysym keyval="42">asterisk</keysym>
|
||||||
<keysym keyval="65505" label="=/+">Shift_L</keysym>
|
|
||||||
<keysym keyval="65505" label="123">Shift_L</keysym>
|
|
||||||
</key>
|
</key>
|
||||||
<key name="AB01">
|
<key keycode="18" name="AE09">
|
||||||
<symbol label="z">z</symbol>
|
<keysym keyval="57">9</keysym>
|
||||||
<symbol label="Z">Z</symbol>
|
<keysym keyval="40">parenleft</keysym>
|
||||||
<symbol label=",">comma</symbol>
|
|
||||||
<symbol label="\">backslash</symbol>
|
|
||||||
</key>
|
</key>
|
||||||
<key name="AB02">
|
<key keycode="19" name="AE10">
|
||||||
<symbol label="x">x</symbol>
|
<keysym keyval="48">0</keysym>
|
||||||
<symbol label="X">X</symbol>
|
<keysym keyval="41">parenright</keysym>
|
||||||
<symbol label=""">quotedbl</symbol>
|
|
||||||
<symbol label="/">slash</symbol>
|
|
||||||
</key>
|
</key>
|
||||||
<key name="AB03">
|
<key keycode="20" name="AE11">
|
||||||
<symbol label="c">c</symbol>
|
<keysym keyval="45">minus</keysym>
|
||||||
<symbol label="C">C</symbol>
|
<keysym keyval="95">underscore</keysym>
|
||||||
<symbol label="'">quoteright</symbol>
|
|
||||||
<symbol label="<">less</symbol>
|
|
||||||
</key>
|
</key>
|
||||||
<key name="AB04">
|
<key keycode="21" name="AE12">
|
||||||
<symbol label="v">v</symbol>
|
<keysym keyval="61">equal</keysym>
|
||||||
<symbol label="V">V</symbol>
|
<keysym keyval="43">plus</keysym>
|
||||||
<symbol label=":">colon</symbol>
|
|
||||||
<symbol label=">">greater</symbol>
|
|
||||||
</key>
|
</key>
|
||||||
<key name="AB05">
|
<key keycode="22" name="BKSP">
|
||||||
<symbol label="b">b</symbol>
|
<keysym keyval="65288">BackSpace</keysym>
|
||||||
<symbol label="B">B</symbol>
|
|
||||||
<symbol label=";">semicolon</symbol>
|
|
||||||
<symbol label="=">equal</symbol>
|
|
||||||
</key>
|
</key>
|
||||||
<key name="AB06">
|
<key keycode="23" name="TAB">
|
||||||
<symbol label="n">n</symbol>
|
<keysym keyval="65289">Tab</keysym>
|
||||||
<symbol label="N">N</symbol>
|
<keysym keyval="65056">ISO_Left_Tab</keysym>
|
||||||
<symbol label="!">exclam</symbol>
|
|
||||||
<symbol label="[">bracketleft</symbol>
|
|
||||||
</key>
|
</key>
|
||||||
<key name="AB07">
|
<key keycode="24" name="AD01">
|
||||||
<symbol label="m">m</symbol>
|
<keysym keyval="113">q</keysym>
|
||||||
<symbol label="M">M</symbol>
|
<keysym keyval="81">Q</keysym>
|
||||||
<symbol label="?">question</symbol>
|
<keysym keyval="49">1</keysym>
|
||||||
<symbol label="]">bracketright</symbol>
|
|
||||||
</key>
|
</key>
|
||||||
<key name="AB08">
|
<key keycode="25" name="AD02">
|
||||||
<symbol label=".">period</symbol>
|
<keysym keyval="119">w</keysym>
|
||||||
|
<keysym keyval="87">W</keysym>
|
||||||
|
<keysym keyval="50">2</keysym>
|
||||||
</key>
|
</key>
|
||||||
<key name="ABC123">
|
<key keycode="26" name="AD03">
|
||||||
<symbol label="123">show-numbers</symbol>
|
<keysym keyval="101">e</keysym>
|
||||||
<symbol label="123">show-numbers</symbol>
|
<keysym keyval="69">E</keysym>
|
||||||
<symbol label="ABC">show-letters</symbol>
|
<keysym keyval="51">3</keysym>
|
||||||
<symbol label="ABC">show-letters</symbol>
|
|
||||||
</key>
|
</key>
|
||||||
<key name="I149">
|
<key keycode="27" name="AD04">
|
||||||
<symbol label="☺" icon="keyboard-mode-symbolic" tooltip="Setup">preferences</symbol>
|
<keysym keyval="114">r</keysym>
|
||||||
|
<keysym keyval="82">R</keysym>
|
||||||
|
<keysym keyval="52">4</keysym>
|
||||||
</key>
|
</key>
|
||||||
<key name="SPCE">
|
<key keycode="28" name="AD05">
|
||||||
<symbol label=" ">space</symbol>
|
<keysym keyval="116">t</keysym>
|
||||||
|
<keysym keyval="84">T</keysym>
|
||||||
|
<keysym keyval="53">5</keysym>
|
||||||
</key>
|
</key>
|
||||||
<key name="BKSP">
|
<key keycode="29" name="AD06">
|
||||||
<symbol keyval="65288" icon="edit-clear-symbolic">BackSpace</symbol>
|
<keysym keyval="121">y</keysym>
|
||||||
|
<keysym keyval="89">Y</keysym>
|
||||||
|
<keysym keyval="54">6</keysym>
|
||||||
|
</key>
|
||||||
|
<key keycode="30" name="AD07">
|
||||||
|
<keysym keyval="117">u</keysym>
|
||||||
|
<keysym keyval="85">U</keysym>
|
||||||
|
<keysym keyval="55">7</keysym>
|
||||||
|
</key>
|
||||||
|
<key keycode="31" name="AD08">
|
||||||
|
<keysym keyval="105">i</keysym>
|
||||||
|
<keysym keyval="73">I</keysym>
|
||||||
|
<keysym keyval="56">8</keysym>
|
||||||
|
</key>
|
||||||
|
<key keycode="32" name="AD09">
|
||||||
|
<keysym keyval="111">o</keysym>
|
||||||
|
<keysym keyval="79">O</keysym>
|
||||||
|
<keysym keyval="57">9</keysym>
|
||||||
|
</key>
|
||||||
|
<key keycode="33" name="AD10">
|
||||||
|
<keysym keyval="112">p</keysym>
|
||||||
|
<keysym keyval="80">P</keysym>
|
||||||
|
<keysym keyval="48">0</keysym>
|
||||||
|
</key>
|
||||||
|
<key keycode="34" name="AD11">
|
||||||
|
<keysym keyval="91">bracketleft</keysym>
|
||||||
|
<keysym keyval="123">braceleft</keysym>
|
||||||
|
</key>
|
||||||
|
<key keycode="35" name="AD12">
|
||||||
|
<keysym keyval="93">bracketright</keysym>
|
||||||
|
<keysym keyval="125">braceright</keysym>
|
||||||
|
</key>
|
||||||
|
<key keycode="51" name="BKSL">
|
||||||
|
<keysym keyval="92">backslash</keysym>
|
||||||
|
<keysym keyval="124">bar</keysym>
|
||||||
|
</key>
|
||||||
|
<key keycode="66" name="ALTGR">
|
||||||
|
<keysym keyval="65027">ISO_Level3_Shift</keysym>
|
||||||
|
</key>
|
||||||
|
<key keycode="38" name="AC01">
|
||||||
|
<keysym keyval="97">a</keysym>
|
||||||
|
<keysym keyval="65">A</keysym>
|
||||||
|
<keysym keyval="64">at</keysym>
|
||||||
|
</key>
|
||||||
|
<key keycode="39" name="AC02">
|
||||||
|
<keysym keyval="115">s</keysym>
|
||||||
|
<keysym keyval="83">S</keysym>
|
||||||
|
<keysym keyval="35">numbersign</keysym>
|
||||||
|
</key>
|
||||||
|
<key keycode="40" name="AC03">
|
||||||
|
<keysym keyval="100">d</keysym>
|
||||||
|
<keysym keyval="68">D</keysym>
|
||||||
|
<keysym keyval="36">dollar</keysym>
|
||||||
|
</key>
|
||||||
|
<key keycode="41" name="AC04">
|
||||||
|
<keysym keyval="102">f</keysym>
|
||||||
|
<keysym keyval="70">F</keysym>
|
||||||
|
<keysym keyval="37">percent</keysym>
|
||||||
|
</key>
|
||||||
|
<key keycode="42" name="AC05">
|
||||||
|
<keysym keyval="103">g</keysym>
|
||||||
|
<keysym keyval="71">G</keysym>
|
||||||
|
<keysym keyval="38">ampersand</keysym>
|
||||||
|
</key>
|
||||||
|
<key keycode="43" name="AC06">
|
||||||
|
<keysym keyval="104">h</keysym>
|
||||||
|
<keysym keyval="72">H</keysym>
|
||||||
|
<keysym keyval="45">minus</keysym>
|
||||||
|
</key>
|
||||||
|
<key keycode="44" name="AC07">
|
||||||
|
<keysym keyval="106">j</keysym>
|
||||||
|
<keysym keyval="74">J</keysym>
|
||||||
|
<keysym keyval="95">underscore</keysym>
|
||||||
|
</key>
|
||||||
|
<key keycode="45" name="AC08">
|
||||||
|
<keysym keyval="107">k</keysym>
|
||||||
|
<keysym keyval="75">K</keysym>
|
||||||
|
<keysym keyval="123">braceleft</keysym>
|
||||||
|
</key>
|
||||||
|
<key keycode="46" name="AC09">
|
||||||
|
<keysym keyval="108">l</keysym>
|
||||||
|
<keysym keyval="76">L</keysym>
|
||||||
|
<keysym keyval="125">braceright</keysym>
|
||||||
|
</key>
|
||||||
|
<key keycode="47" name="AC10">
|
||||||
|
<keysym keyval="59">semicolon</keysym>
|
||||||
|
<keysym keyval="58">colon</keysym>
|
||||||
|
</key>
|
||||||
|
<key keycode="48" name="AC11">
|
||||||
|
<keysym keyval="39">quoteright</keysym>
|
||||||
|
<keysym keyval="34">quotedbl</keysym>
|
||||||
|
</key>
|
||||||
|
<key keycode="36" name="RTRN">
|
||||||
|
<keysym keyval="65293">Return</keysym>
|
||||||
|
</key>
|
||||||
|
<key keycode="50" name="LFSH">
|
||||||
|
<keysym keyval="65505">Shift_L</keysym>
|
||||||
|
</key>
|
||||||
|
<key keycode="52" name="AB01">
|
||||||
|
<keysym keyval="122">z</keysym>
|
||||||
|
<keysym keyval="90">Z</keysym>
|
||||||
|
<keysym keyval="43">plus</keysym>
|
||||||
|
</key>
|
||||||
|
<key keycode="53" name="AB02">
|
||||||
|
<keysym keyval="120">x</keysym>
|
||||||
|
<keysym keyval="88">X</keysym>
|
||||||
|
<keysym keyval="34">quotedbl</keysym>
|
||||||
|
</key>
|
||||||
|
<key keycode="54" name="AB03">
|
||||||
|
<keysym keyval="99">c</keysym>
|
||||||
|
<keysym keyval="67">C</keysym>
|
||||||
|
<keysym keyval="39">quoteright</keysym>
|
||||||
|
</key>
|
||||||
|
<key keycode="55" name="AB04">
|
||||||
|
<keysym keyval="118">v</keysym>
|
||||||
|
<keysym keyval="86">V</keysym>
|
||||||
|
<keysym keyval="58">colon</keysym>
|
||||||
|
</key>
|
||||||
|
<key keycode="56" name="AB05">
|
||||||
|
<keysym keyval="98">b</keysym>
|
||||||
|
<keysym keyval="66">B</keysym>
|
||||||
|
<keysym keyval="59">semicolon</keysym>
|
||||||
|
</key>
|
||||||
|
<key keycode="57" name="AB06">
|
||||||
|
<keysym keyval="110">n</keysym>
|
||||||
|
<keysym keyval="78">N</keysym>
|
||||||
|
<keysym keyval="33">exclam</keysym>
|
||||||
|
</key>
|
||||||
|
<key keycode="58" name="AB07">
|
||||||
|
<keysym keyval="109">m</keysym>
|
||||||
|
<keysym keyval="77">M</keysym>
|
||||||
|
<keysym keyval="63">question</keysym>
|
||||||
|
</key>
|
||||||
|
<key keycode="59" name="AB08">
|
||||||
|
<keysym keyval="44">comma</keysym>
|
||||||
|
<keysym keyval="60">less</keysym>
|
||||||
|
</key>
|
||||||
|
<key keycode="60" name="AB09">
|
||||||
|
<keysym keyval="46">period</keysym>
|
||||||
|
<keysym keyval="62">greater</keysym>
|
||||||
|
</key>
|
||||||
|
<key keycode="61" name="AB10">
|
||||||
|
<keysym keyval="47">slash</keysym>
|
||||||
|
<keysym keyval="63">question</keysym>
|
||||||
|
</key>
|
||||||
|
<key keycode="62" name="RTSH">
|
||||||
|
<keysym keyval="65506">Shift_R</keysym>
|
||||||
|
</key>
|
||||||
|
<key keycode="149" name="I149">
|
||||||
|
<symbol label="⌨" icon="input-keyboard-symbolic" tooltip="Change keyboard">cycle-keyboard</symbol>
|
||||||
|
</key>
|
||||||
|
<key keycode="150" name="I150">
|
||||||
|
<symbol label="☺" icon="preferences-system-symbolic" tooltip="Setup">preferences</symbol>
|
||||||
|
</key>
|
||||||
|
<key keycode="37" name="LCTL">
|
||||||
|
<keysym keyval="65507">Control_L</keysym>
|
||||||
|
</key>
|
||||||
|
<key keycode="64" name="LALT">
|
||||||
|
<keysym keyval="65513">Alt_L</keysym>
|
||||||
|
<keysym keyval="65511">Meta_L</keysym>
|
||||||
|
</key>
|
||||||
|
<key keycode="65" name="SPCE">
|
||||||
|
<keysym keyval="32">space</keysym>
|
||||||
|
</key>
|
||||||
|
<key keycode="113" name="LEFT">
|
||||||
|
<keysym keyval="65361">Left</keysym>
|
||||||
|
</key>
|
||||||
|
<key keycode="111" name="UP">
|
||||||
|
<keysym keyval="65362">Up</keysym>
|
||||||
|
</key>
|
||||||
|
<key keycode="116" name="DOWN">
|
||||||
|
<keysym keyval="65364">Down</keysym>
|
||||||
|
</key>
|
||||||
|
<key keycode="114" name="RGHT">
|
||||||
|
<keysym keyval="65363">Right</keysym>
|
||||||
</key>
|
</key>
|
||||||
</symbols>
|
</symbols>
|
||||||
|
|||||||
@ -1,12 +1,57 @@
|
|||||||
gnome = import('gnome')
|
|
||||||
|
|
||||||
squeekboard_resources = gnome.compile_resources(
|
install_data(
|
||||||
'squeekboard-resources',
|
'themes/default.css',
|
||||||
'squeekboard.gresources.xml',
|
install_dir: pkgdatadir + '/themes',
|
||||||
|
|
||||||
c_name: 'squeekboard',
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
install_data(
|
||||||
|
'keyboards/keyboards.xml',
|
||||||
|
install_dir: pkgdatadir + '/keyboards/',
|
||||||
|
)
|
||||||
|
|
||||||
|
install_data(
|
||||||
|
'keyboards/geometry/compact.xml',
|
||||||
|
install_dir: pkgdatadir + '/keyboards/geometry/',
|
||||||
|
)
|
||||||
|
|
||||||
|
symbols = [
|
||||||
|
'ar.xml',
|
||||||
|
'as-inscript.xml',
|
||||||
|
'be.xml',
|
||||||
|
'bn-inscript.xml',
|
||||||
|
'fa.xml',
|
||||||
|
'gu-inscript.xml',
|
||||||
|
'he.xml',
|
||||||
|
'hi-inscript.xml',
|
||||||
|
'ja-kana.xml',
|
||||||
|
'kk.xml',
|
||||||
|
'kn-inscript.xml',
|
||||||
|
'ks-inscript.xml',
|
||||||
|
'ks.xml',
|
||||||
|
'mai-inscript.xml',
|
||||||
|
'ml-inscript.xml',
|
||||||
|
'mr-inscript.xml',
|
||||||
|
'my.xml',
|
||||||
|
'or-inscript.xml',
|
||||||
|
'pa-inscript.xml',
|
||||||
|
'ru.xml',
|
||||||
|
'sd-inscript.xml',
|
||||||
|
'ta-inscript.xml',
|
||||||
|
'te-inscript.xml',
|
||||||
|
'th.xml',
|
||||||
|
'ua.xml',
|
||||||
|
'ug.xml',
|
||||||
|
'us.xml',
|
||||||
|
'zh-bopomofo.xml',
|
||||||
|
]
|
||||||
|
|
||||||
|
foreach symbol: symbols
|
||||||
|
install_data(
|
||||||
|
'keyboards/symbols/' + symbol,
|
||||||
|
install_dir: pkgdatadir + '/keyboards/symbols/',
|
||||||
|
)
|
||||||
|
endforeach
|
||||||
|
|
||||||
desktop_file = 'sm.puri.Squeekboard.desktop'
|
desktop_file = 'sm.puri.Squeekboard.desktop'
|
||||||
|
|
||||||
i18n.merge_file('desktop',
|
i18n.merge_file('desktop',
|
||||||
|
|||||||
@ -1,46 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<gresources>
|
|
||||||
<gresource prefix="/sm/puri/squeekboard">
|
|
||||||
<file compressed="true">style.css</file>
|
|
||||||
<file compressed="true" preprocess="xml-stripblanks">keyboards/geometry/compact.xml</file>
|
|
||||||
<file compressed="true" preprocess="xml-stripblanks">keyboards/geometry/extended.xml</file>
|
|
||||||
<file compressed="true" preprocess="xml-stripblanks">keyboards/geometry/numbers-keypad.xml</file>
|
|
||||||
<file compressed="true" preprocess="xml-stripblanks">keyboards/keyboards.xml</file>
|
|
||||||
<file compressed="true">keyboards/keymaps/nb.xkb</file>
|
|
||||||
<file compressed="true">keyboards/keymaps/us.xkb</file>
|
|
||||||
<file compressed="true">keyboards/keymaps/numbers.xkb</file>
|
|
||||||
<file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/ar.xml</file>
|
|
||||||
<file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/as-inscript.xml</file>
|
|
||||||
<file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/be.xml</file>
|
|
||||||
<file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/bn-inscript.xml</file>
|
|
||||||
<file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/fa.xml</file>
|
|
||||||
<file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/gu-inscript.xml</file>
|
|
||||||
<file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/he.xml</file>
|
|
||||||
<file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/hi-inscript.xml</file>
|
|
||||||
<file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/ja-kana.xml</file>
|
|
||||||
<file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/kk.xml</file>
|
|
||||||
<file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/kn-inscript.xml</file>
|
|
||||||
<file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/ks-inscript.xml</file>
|
|
||||||
<file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/ks.xml</file>
|
|
||||||
<file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/mai-inscript.xml</file>
|
|
||||||
<file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/ml-inscript.xml</file>
|
|
||||||
<file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/mr-inscript.xml</file>
|
|
||||||
<file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/my.xml</file>
|
|
||||||
<file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/nb.xml</file>
|
|
||||||
<file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/or-inscript.xml</file>
|
|
||||||
<file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/pa-inscript.xml</file>
|
|
||||||
<file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/ru.xml</file>
|
|
||||||
<file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/sd-inscript.xml</file>
|
|
||||||
<file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/ta-inscript.xml</file>
|
|
||||||
<file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/te-inscript.xml</file>
|
|
||||||
<file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/th.xml</file>
|
|
||||||
<file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/ua.xml</file>
|
|
||||||
<file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/ug.xml</file>
|
|
||||||
<file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/us.xml</file>
|
|
||||||
<file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/zh-bopomofo.xml</file>
|
|
||||||
<file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/special/numbers.xml</file>
|
|
||||||
<file>icons/key-enter.svg</file>
|
|
||||||
<file>icons/key-shift.svg</file>
|
|
||||||
<file>icons/keyboard-mode-symbolic.svg</file>
|
|
||||||
</gresource>
|
|
||||||
</gresources>
|
|
||||||
1
debian/control
vendored
1
debian/control
vendored
@ -11,6 +11,7 @@ Build-Depends:
|
|||||||
libcroco3-dev,
|
libcroco3-dev,
|
||||||
libwayland-dev (>= 1.16),
|
libwayland-dev (>= 1.16),
|
||||||
rustc,
|
rustc,
|
||||||
|
virtboard,
|
||||||
wayland-protocols (>= 1.14)
|
wayland-protocols (>= 1.14)
|
||||||
Standards-Version: 4.1.3
|
Standards-Version: 4.1.3
|
||||||
Homepage: https://source.puri.sm/Librem5/squeekboard
|
Homepage: https://source.puri.sm/Librem5/squeekboard
|
||||||
|
|||||||
53
debian/copyright
vendored
53
debian/copyright
vendored
@ -3,58 +3,7 @@ Upstream-Name: evscript
|
|||||||
Source: https://source.puri.sm/david.boddie/evscript
|
Source: https://source.puri.sm/david.boddie/evscript
|
||||||
|
|
||||||
Files: *
|
Files: *
|
||||||
Copyright: 2010-2011 Daiki Ueno <ueno@unixuser.org>
|
Copyright: 2019 Purism SPC
|
||||||
2010-2011 Red Hat, Inc.
|
|
||||||
2019 Purism SPC
|
|
||||||
License: GPL-3+
|
|
||||||
|
|
||||||
Files: eek/layersurface.c
|
|
||||||
src/wayland.c
|
|
||||||
src/key-emitter.c
|
|
||||||
meson.build
|
|
||||||
src/meson.build
|
|
||||||
po/meson.build
|
|
||||||
Copyright: 2018-2019 Purism SPC
|
|
||||||
License: GPL-3+
|
|
||||||
|
|
||||||
Files: eekboard/keymap.c
|
|
||||||
Copyright: 2000 Red Hat, Inc.
|
|
||||||
2019 Purism, SPC
|
|
||||||
License: LGPL-2+
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Lesser General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library 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
|
|
||||||
Lesser General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public
|
|
||||||
License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
Files: protocols/wlr-layer-shell-unstable-v1.xml
|
|
||||||
Copytight: Copyright © 2017 Drew DeVault
|
|
||||||
License: X11
|
|
||||||
Permission to use, copy, modify, distribute, and sell this software and
|
|
||||||
its documentation for any purpose is hereby granted without fee, provided
|
|
||||||
that the above copyright notice appear in all copies and fthat both that
|
|
||||||
copyright notice and this permission notice appear in supporting
|
|
||||||
documentation, and that the name of the copyright holders not be used in
|
|
||||||
advertising or publicity pertaining to distribution of the software
|
|
||||||
without specific, written prior permission. The copyright holders make
|
|
||||||
no representations about the suitability of this software for any
|
|
||||||
purpose. It is provided "as is" without express or implied warranty.
|
|
||||||
.
|
|
||||||
THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
|
|
||||||
SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
|
||||||
FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
|
||||||
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
|
|
||||||
RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
|
|
||||||
CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
|
||||||
CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
||||||
|
|
||||||
License: GPL-3+
|
License: GPL-3+
|
||||||
This package is free software; you can redistribute it and/or modify
|
This package is free software; you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
0
eek/config.h
Normal file
0
eek/config.h
Normal file
@ -26,7 +26,9 @@
|
|||||||
* shall be used to implement #EekKeyboard and #EekSection.
|
* shall be used to implement #EekKeyboard and #EekSection.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
#endif /* HAVE_CONFIG_H */
|
||||||
|
|
||||||
#include "eek-container.h"
|
#include "eek-container.h"
|
||||||
|
|
||||||
|
|||||||
@ -26,7 +26,9 @@
|
|||||||
* shall be used to implement #EekKeyboard, #EekSection, or #EekKey.
|
* shall be used to implement #EekKeyboard, #EekSection, or #EekKey.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
#endif /* HAVE_CONFIG_H */
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
|||||||
@ -23,7 +23,9 @@
|
|||||||
* @short_description: a #GtkWidget displaying #EekKeyboard
|
* @short_description: a #GtkWidget displaying #EekKeyboard
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
#endif /* HAVE_CONFIG_H */
|
||||||
|
|
||||||
#ifdef HAVE_LIBCANBERRA
|
#ifdef HAVE_LIBCANBERRA
|
||||||
#include <canberra-gtk.h>
|
#include <canberra-gtk.h>
|
||||||
@ -33,7 +35,7 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "eek-gtk-keyboard.h"
|
#include "eek-gtk-keyboard.h"
|
||||||
#include "eek-renderer.h"
|
#include "eek-gtk-renderer.h"
|
||||||
#include "eek-keyboard.h"
|
#include "eek-keyboard.h"
|
||||||
#include "eek-section.h"
|
#include "eek-section.h"
|
||||||
#include "eek-key.h"
|
#include "eek-key.h"
|
||||||
@ -55,6 +57,9 @@ typedef struct _EekGtkKeyboardPrivate
|
|||||||
{
|
{
|
||||||
EekRenderer *renderer;
|
EekRenderer *renderer;
|
||||||
EekKeyboard *keyboard;
|
EekKeyboard *keyboard;
|
||||||
|
gulong key_locked_handler;
|
||||||
|
gulong key_unlocked_handler;
|
||||||
|
gulong symbol_index_changed_handler;
|
||||||
EekTheme *theme;
|
EekTheme *theme;
|
||||||
|
|
||||||
GdkEventSequence *sequence; // unowned reference
|
GdkEventSequence *sequence; // unowned reference
|
||||||
@ -112,15 +117,13 @@ eek_gtk_keyboard_real_draw (GtkWidget *self,
|
|||||||
PangoContext *pcontext;
|
PangoContext *pcontext;
|
||||||
|
|
||||||
pcontext = gtk_widget_get_pango_context (self);
|
pcontext = gtk_widget_get_pango_context (self);
|
||||||
priv->renderer = eek_renderer_new (priv->keyboard, pcontext);
|
priv->renderer = eek_gtk_renderer_new (priv->keyboard, pcontext, self);
|
||||||
if (priv->theme)
|
if (priv->theme)
|
||||||
eek_renderer_set_theme (priv->renderer, priv->theme);
|
eek_renderer_set_theme (priv->renderer, priv->theme);
|
||||||
|
|
||||||
eek_renderer_set_allocation_size (priv->renderer,
|
eek_renderer_set_allocation_size (priv->renderer,
|
||||||
allocation.width,
|
allocation.width,
|
||||||
allocation.height);
|
allocation.height);
|
||||||
eek_renderer_set_scale_factor (priv->renderer,
|
|
||||||
gtk_widget_get_scale_factor (self));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
eek_renderer_render_keyboard (priv->renderer, cr);
|
eek_renderer_render_keyboard (priv->renderer, cr);
|
||||||
@ -327,21 +330,15 @@ eek_gtk_keyboard_set_keyboard (EekGtkKeyboard *self,
|
|||||||
EekKeyboard *keyboard)
|
EekKeyboard *keyboard)
|
||||||
{
|
{
|
||||||
EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (self);
|
EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (self);
|
||||||
|
|
||||||
if (priv->keyboard == keyboard)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (priv->keyboard) {
|
|
||||||
g_signal_handlers_disconnect_by_data(priv->keyboard, self);
|
|
||||||
g_object_unref (priv->keyboard);
|
|
||||||
}
|
|
||||||
|
|
||||||
priv->keyboard = g_object_ref (keyboard);
|
priv->keyboard = g_object_ref (keyboard);
|
||||||
|
|
||||||
|
priv->key_locked_handler =
|
||||||
g_signal_connect (priv->keyboard, "key-locked",
|
g_signal_connect (priv->keyboard, "key-locked",
|
||||||
G_CALLBACK(on_key_locked), self);
|
G_CALLBACK(on_key_locked), self);
|
||||||
|
priv->key_unlocked_handler =
|
||||||
g_signal_connect (priv->keyboard, "key-unlocked",
|
g_signal_connect (priv->keyboard, "key-unlocked",
|
||||||
G_CALLBACK(on_key_unlocked), self);
|
G_CALLBACK(on_key_unlocked), self);
|
||||||
|
priv->symbol_index_changed_handler =
|
||||||
g_signal_connect (priv->keyboard, "symbol-index-changed",
|
g_signal_connect (priv->keyboard, "symbol-index-changed",
|
||||||
G_CALLBACK(on_symbol_index_changed), self);
|
G_CALLBACK(on_symbol_index_changed), self);
|
||||||
}
|
}
|
||||||
@ -377,9 +374,21 @@ eek_gtk_keyboard_dispose (GObject *object)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (priv->keyboard) {
|
if (priv->keyboard) {
|
||||||
|
if (g_signal_handler_is_connected (priv->keyboard,
|
||||||
|
priv->key_locked_handler))
|
||||||
|
g_signal_handler_disconnect (priv->keyboard,
|
||||||
|
priv->key_locked_handler);
|
||||||
|
if (g_signal_handler_is_connected (priv->keyboard,
|
||||||
|
priv->key_unlocked_handler))
|
||||||
|
g_signal_handler_disconnect (priv->keyboard,
|
||||||
|
priv->key_unlocked_handler);
|
||||||
|
if (g_signal_handler_is_connected (priv->keyboard,
|
||||||
|
priv->symbol_index_changed_handler))
|
||||||
|
g_signal_handler_disconnect (priv->keyboard,
|
||||||
|
priv->symbol_index_changed_handler);
|
||||||
|
|
||||||
GList *list, *head;
|
GList *list, *head;
|
||||||
|
|
||||||
g_signal_handlers_disconnect_by_data(priv->keyboard, self);
|
|
||||||
list = eek_keyboard_get_pressed_keys (priv->keyboard);
|
list = eek_keyboard_get_pressed_keys (priv->keyboard);
|
||||||
for (head = list; head; head = g_list_next (head)) {
|
for (head = list; head; head = g_list_next (head)) {
|
||||||
g_log("squeek", G_LOG_LEVEL_DEBUG, "emit EekKey pressed");
|
g_log("squeek", G_LOG_LEVEL_DEBUG, "emit EekKey pressed");
|
||||||
@ -475,6 +484,45 @@ magnify_bounds (GtkWidget *self,
|
|||||||
large_bounds->y = CLAMP(y, 0, allocation.height - large_bounds->height);
|
large_bounds->y = CLAMP(y, 0, allocation.height - large_bounds->height);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Alleviate the asymmetry between drawing a pressed key and a released key,
|
||||||
|
* and consistently draw to the exact same area.
|
||||||
|
*
|
||||||
|
* By saving the dirty rectangle we can limit drawing of the backbuffer to
|
||||||
|
* the screen as well, eg gdk_window_invalidate_rect() instead of
|
||||||
|
* gtk_widget_queue_draw() which redraws the entire widget.
|
||||||
|
*
|
||||||
|
* b1 is mandatory, b2 is optional
|
||||||
|
*/
|
||||||
|
static GdkRectangle
|
||||||
|
clip_bounds_to_dirty_rectangle (cairo_t *cr, EekBounds *b1, EekBounds *b2)
|
||||||
|
{
|
||||||
|
if (b2)
|
||||||
|
cairo_rectangle (cr, b2->x, b2->y, b2->width, b2->height);
|
||||||
|
|
||||||
|
cairo_rectangle (cr, b1->x, b1->y, b1->width, b1->height);
|
||||||
|
cairo_clip (cr);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* save the clipped region to a bounding box so we can limit
|
||||||
|
* the drawing of the backbuffer to the screen to the same area
|
||||||
|
*/
|
||||||
|
cairo_rectangle_t bbox;
|
||||||
|
|
||||||
|
cairo_clip_extents (cr, &bbox.x, &bbox.y, &bbox.width, &bbox.height);
|
||||||
|
|
||||||
|
/* convert double to int, making sure r strictly covers bbox to avoid
|
||||||
|
* artefacts. floor() is unnecessary, ceil() is not */
|
||||||
|
GdkRectangle r = {
|
||||||
|
floor (bbox.x),
|
||||||
|
floor (bbox.y),
|
||||||
|
ceil (bbox.width),
|
||||||
|
ceil (bbox.height)
|
||||||
|
};
|
||||||
|
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
render_pressed_key (GtkWidget *widget,
|
render_pressed_key (GtkWidget *widget,
|
||||||
EekKey *key)
|
EekKey *key)
|
||||||
@ -491,19 +539,28 @@ render_pressed_key (GtkWidget *widget,
|
|||||||
eek_renderer_get_key_bounds (priv->renderer, key, &bounds, TRUE);
|
eek_renderer_get_key_bounds (priv->renderer, key, &bounds, TRUE);
|
||||||
magnify_bounds (widget, &bounds, &large_bounds, 1.5);
|
magnify_bounds (widget, &bounds, &large_bounds, 1.5);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* clip to limit drawing to backbuffer and save clip region to dirty_rect
|
||||||
|
* to limit redrawing of the backbuffer to the same area
|
||||||
|
*/
|
||||||
|
GdkRectangle dirty_rect = clip_bounds_to_dirty_rectangle (cr, &bounds, &large_bounds);
|
||||||
|
|
||||||
cairo_save (cr);
|
cairo_save (cr);
|
||||||
cairo_translate (cr, bounds.x, bounds.y);
|
cairo_translate (cr, bounds.x, bounds.y);
|
||||||
eek_renderer_render_key (priv->renderer, cr, key, 1.0, TRUE);
|
eek_renderer_render_key (priv->renderer, cr, key, 1.0, TRUE);
|
||||||
cairo_restore (cr);
|
cairo_restore (cr);
|
||||||
/*
|
|
||||||
cairo_save (cr);
|
cairo_save (cr);
|
||||||
cairo_translate (cr, large_bounds.x, large_bounds.y);
|
cairo_translate (cr, large_bounds.x, large_bounds.y);
|
||||||
eek_renderer_render_key (priv->renderer, cr, key, 1.5, TRUE);
|
eek_renderer_render_key (priv->renderer, cr, key, 1.5, TRUE);
|
||||||
cairo_restore (cr);
|
cairo_restore (cr);
|
||||||
*/
|
|
||||||
gdk_window_end_draw_frame (window, context);
|
gdk_window_end_draw_frame (window, context);
|
||||||
|
|
||||||
cairo_region_destroy (region);
|
cairo_region_destroy (region);
|
||||||
|
|
||||||
|
/* force immediate drawing of the backbuffer to the screen */
|
||||||
|
gdk_window_invalidate_rect (window, &dirty_rect, FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -521,12 +578,21 @@ render_locked_key (GtkWidget *widget,
|
|||||||
|
|
||||||
eek_renderer_get_key_bounds (priv->renderer, key, &bounds, TRUE);
|
eek_renderer_get_key_bounds (priv->renderer, key, &bounds, TRUE);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* clip to limit drawing to backbuffer and save clip region to dirty_rect
|
||||||
|
* to limit redrawing of the backbuffer to the same area
|
||||||
|
*/
|
||||||
|
GdkRectangle dirty_rect = clip_bounds_to_dirty_rectangle (cr, &bounds, NULL);
|
||||||
|
|
||||||
cairo_translate (cr, bounds.x, bounds.y);
|
cairo_translate (cr, bounds.x, bounds.y);
|
||||||
eek_renderer_render_key (priv->renderer, cr, key, 1.0, TRUE);
|
eek_renderer_render_key (priv->renderer, cr, key, 1.0, TRUE);
|
||||||
|
|
||||||
gdk_window_end_draw_frame (window, context);
|
gdk_window_end_draw_frame (window, context);
|
||||||
|
|
||||||
cairo_region_destroy (region);
|
cairo_region_destroy (region);
|
||||||
|
|
||||||
|
/* force immediate drawing of the backbuffer to the screen */
|
||||||
|
gdk_window_invalidate_rect (window, &dirty_rect, FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -545,11 +611,20 @@ render_released_key (GtkWidget *widget,
|
|||||||
eek_renderer_get_key_bounds (priv->renderer, key, &bounds, TRUE);
|
eek_renderer_get_key_bounds (priv->renderer, key, &bounds, TRUE);
|
||||||
magnify_bounds (widget, &bounds, &large_bounds, 1.5);
|
magnify_bounds (widget, &bounds, &large_bounds, 1.5);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* clip to limit drawing to backbuffer and save clip region to dirty_rect
|
||||||
|
* to limit redrawing of the backbuffer to the same area
|
||||||
|
*/
|
||||||
|
GdkRectangle dirty_rect = clip_bounds_to_dirty_rectangle(cr, &bounds, &large_bounds);
|
||||||
|
|
||||||
eek_renderer_render_keyboard (priv->renderer, cr);
|
eek_renderer_render_keyboard (priv->renderer, cr);
|
||||||
|
|
||||||
gdk_window_end_draw_frame (window, context);
|
gdk_window_end_draw_frame (window, context);
|
||||||
|
|
||||||
cairo_region_destroy (region);
|
cairo_region_destroy (region);
|
||||||
|
|
||||||
|
/* force immediate drawing of the backbuffer to the screen */
|
||||||
|
gdk_window_invalidate_rect (window, &dirty_rect, FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -563,7 +638,6 @@ on_key_pressed (EekKey *key,
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
render_pressed_key (GTK_WIDGET(self), key);
|
render_pressed_key (GTK_WIDGET(self), key);
|
||||||
gtk_widget_queue_draw (GTK_WIDGET(self));
|
|
||||||
|
|
||||||
#if HAVE_LIBCANBERRA
|
#if HAVE_LIBCANBERRA
|
||||||
ca_gtk_play_for_widget (widget, 0,
|
ca_gtk_play_for_widget (widget, 0,
|
||||||
@ -585,7 +659,6 @@ on_key_released (EekKey *key,
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
render_released_key (GTK_WIDGET(self), key);
|
render_released_key (GTK_WIDGET(self), key);
|
||||||
gtk_widget_queue_draw (GTK_WIDGET(self));
|
|
||||||
|
|
||||||
#if HAVE_LIBCANBERRA
|
#if HAVE_LIBCANBERRA
|
||||||
ca_gtk_play_for_widget (widget, 0,
|
ca_gtk_play_for_widget (widget, 0,
|
||||||
@ -609,7 +682,6 @@ on_key_locked (EekKeyboard *keyboard,
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
render_locked_key (widget, key);
|
render_locked_key (widget, key);
|
||||||
gtk_widget_queue_draw (widget);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -625,7 +697,6 @@ on_key_unlocked (EekKeyboard *keyboard,
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
render_released_key (widget, key);
|
render_released_key (widget, key);
|
||||||
gtk_widget_queue_draw (GTK_WIDGET(widget));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|||||||
104
eek/eek-gtk-renderer.c
Normal file
104
eek/eek-gtk-renderer.c
Normal file
@ -0,0 +1,104 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2011 Daiki Ueno <ueno@unixuser.org>
|
||||||
|
* Copyright (C) 2011 Red Hat, Inc.
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2 of
|
||||||
|
* the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library 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
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||||
|
* 02110-1301 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "config.h"
|
||||||
|
#endif /* HAVE_CONFIG_H */
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include <gdk-pixbuf/gdk-pixbuf.h>
|
||||||
|
|
||||||
|
#include "eek-gtk-renderer.h"
|
||||||
|
#include "eek-key.h"
|
||||||
|
|
||||||
|
G_DEFINE_TYPE (EekGtkRenderer, eek_gtk_renderer, EEK_TYPE_RENDERER);
|
||||||
|
|
||||||
|
static cairo_surface_t *
|
||||||
|
pixbuf_to_cairo_surface (GdkPixbuf *pixbuf)
|
||||||
|
{
|
||||||
|
cairo_surface_t *dummy_surface;
|
||||||
|
cairo_pattern_t *pattern;
|
||||||
|
cairo_surface_t *surface;
|
||||||
|
cairo_t *cr;
|
||||||
|
|
||||||
|
dummy_surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 1, 1);
|
||||||
|
|
||||||
|
cr = cairo_create (dummy_surface);
|
||||||
|
gdk_cairo_set_source_pixbuf (cr, pixbuf, 0, 0);
|
||||||
|
pattern = cairo_get_source (cr);
|
||||||
|
cairo_pattern_get_surface (pattern, &surface);
|
||||||
|
cairo_surface_reference (surface);
|
||||||
|
cairo_destroy (cr);
|
||||||
|
cairo_surface_destroy (dummy_surface);
|
||||||
|
|
||||||
|
return surface;
|
||||||
|
}
|
||||||
|
|
||||||
|
static cairo_surface_t *
|
||||||
|
eek_gtk_renderer_real_get_icon_surface (EekRenderer *self,
|
||||||
|
const gchar *icon_name,
|
||||||
|
gint size)
|
||||||
|
{
|
||||||
|
GdkPixbuf *pixbuf;
|
||||||
|
GError *error;
|
||||||
|
cairo_surface_t *surface;
|
||||||
|
|
||||||
|
error = NULL;
|
||||||
|
pixbuf = gtk_icon_theme_load_icon (gtk_icon_theme_get_default (),
|
||||||
|
icon_name,
|
||||||
|
size,
|
||||||
|
0,
|
||||||
|
&error);
|
||||||
|
if (pixbuf == NULL) {
|
||||||
|
g_warning ("can't get icon pixbuf for %s: %s",
|
||||||
|
icon_name,
|
||||||
|
error->message);
|
||||||
|
g_error_free (error);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
surface = pixbuf_to_cairo_surface (pixbuf);
|
||||||
|
g_object_unref (pixbuf);
|
||||||
|
return surface;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
eek_gtk_renderer_class_init (EekGtkRendererClass *klass)
|
||||||
|
{
|
||||||
|
EekRendererClass *renderer_class = EEK_RENDERER_CLASS (klass);
|
||||||
|
|
||||||
|
renderer_class->get_icon_surface = eek_gtk_renderer_real_get_icon_surface;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
eek_gtk_renderer_init (EekGtkRenderer *self)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
EekRenderer *
|
||||||
|
eek_gtk_renderer_new (EekKeyboard *keyboard,
|
||||||
|
PangoContext *pcontext,
|
||||||
|
GtkWidget *widget)
|
||||||
|
{
|
||||||
|
return g_object_new (EEK_TYPE_GTK_RENDERER,
|
||||||
|
"keyboard", keyboard,
|
||||||
|
"pango-context", pcontext,
|
||||||
|
NULL);
|
||||||
|
}
|
||||||
61
eek/eek-gtk-renderer.h
Normal file
61
eek/eek-gtk-renderer.h
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2010-2011 Daiki Ueno <ueno@unixuser.org>
|
||||||
|
* Copyright (C) 2010-2011 Red Hat, Inc.
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2 of
|
||||||
|
* the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library 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
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||||
|
* 02110-1301 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef EEK_GTK_RENDERER_H
|
||||||
|
#define EEK_GTK_RENDERER_H 1
|
||||||
|
|
||||||
|
#include <gtk/gtk.h>
|
||||||
|
#include "eek-renderer.h"
|
||||||
|
|
||||||
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
#define EEK_TYPE_GTK_RENDERER (eek_gtk_renderer_get_type())
|
||||||
|
#define EEK_GTK_RENDERER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EEK_TYPE_GTK_RENDERER, EekGtkRenderer))
|
||||||
|
#define EEK_GTK_RENDERER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EEK_TYPE_GTK_RENDERER, EekGtkRendererClass))
|
||||||
|
#define EEK_IS_GTK_RENDERER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EEK_TYPE_GTK_RENDERER))
|
||||||
|
#define EEK_IS_GTK_RENDERER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EEK_TYPE_GTK_RENDERER))
|
||||||
|
#define EEK_GTK_RENDERER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EEK_TYPE_GTK_RENDERER, EekGtkRendererClass))
|
||||||
|
|
||||||
|
typedef struct _EekGtkRenderer EekGtkRenderer;
|
||||||
|
typedef struct _EekGtkRendererClass EekGtkRendererClass;
|
||||||
|
typedef struct _EekGtkRendererPrivate EekGtkRendererPrivate;
|
||||||
|
|
||||||
|
struct _EekGtkRenderer {
|
||||||
|
EekRenderer parent;
|
||||||
|
|
||||||
|
EekGtkRendererPrivate *priv;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct _EekGtkRendererClass
|
||||||
|
{
|
||||||
|
EekRendererClass parent_class;
|
||||||
|
|
||||||
|
/*< private >*/
|
||||||
|
/* padding */
|
||||||
|
gpointer pdummy[24];
|
||||||
|
};
|
||||||
|
|
||||||
|
GType eek_gtk_renderer_get_type (void) G_GNUC_CONST;
|
||||||
|
EekRenderer *eek_gtk_renderer_new (EekKeyboard *keyboard,
|
||||||
|
PangoContext *pcontext,
|
||||||
|
GtkWidget *widget);
|
||||||
|
|
||||||
|
G_END_DECLS
|
||||||
|
#endif /* EEK_GTK_RENDERER_H */
|
||||||
@ -25,7 +25,9 @@
|
|||||||
* The #EekKeyClass class represents a key.
|
* The #EekKeyClass class represents a key.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
#endif /* HAVE_CONFIG_H */
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
@ -609,11 +611,3 @@ void eek_key_set_pressed(EekKey *key, gboolean value)
|
|||||||
|
|
||||||
priv->is_pressed = value;
|
priv->is_pressed = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
gboolean
|
|
||||||
eek_key_has_label(EekKey *key)
|
|
||||||
{
|
|
||||||
EekSymbol *symbol = eek_key_get_symbol(key);
|
|
||||||
return (eek_symbol_get_label(symbol) != NULL) ||
|
|
||||||
(eek_symbol_get_icon_name(symbol) != NULL);
|
|
||||||
}
|
|
||||||
|
|||||||
@ -89,7 +89,5 @@ gboolean eek_key_is_locked (EekKey *key);
|
|||||||
void eek_key_set_pressed (EekKey *key,
|
void eek_key_set_pressed (EekKey *key,
|
||||||
gboolean value);
|
gboolean value);
|
||||||
|
|
||||||
gboolean eek_key_has_label (EekKey *key);
|
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
#endif /* EEK_KEY_H */
|
#endif /* EEK_KEY_H */
|
||||||
|
|||||||
@ -17,7 +17,9 @@
|
|||||||
* Boston, MA 02111-1307, USA.
|
* Boston, MA 02111-1307, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
#endif /* HAVE_CONFIG_H */
|
||||||
|
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <pango/pangocairo.h>
|
#include <pango/pangocairo.h>
|
||||||
|
|||||||
@ -27,7 +27,9 @@
|
|||||||
* of one or more sections of the #EekSectionClass class.
|
* of one or more sections of the #EekSectionClass class.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
#endif /* HAVE_CONFIG_H */
|
||||||
|
|
||||||
#include "eek-keyboard.h"
|
#include "eek-keyboard.h"
|
||||||
#include "eek-marshalers.h"
|
#include "eek-marshalers.h"
|
||||||
@ -51,15 +53,10 @@ enum {
|
|||||||
LAST_SIGNAL
|
LAST_SIGNAL
|
||||||
};
|
};
|
||||||
|
|
||||||
enum {
|
|
||||||
VIEW_LETTERS_LOWER,
|
|
||||||
VIEW_LETTERS_UPPER,
|
|
||||||
VIEW_NUMBERS,
|
|
||||||
VIEW_SYMBOLS
|
|
||||||
};
|
|
||||||
|
|
||||||
static guint signals[LAST_SIGNAL] = { 0, };
|
static guint signals[LAST_SIGNAL] = { 0, };
|
||||||
|
|
||||||
|
G_DEFINE_TYPE (EekKeyboard, eek_keyboard, EEK_TYPE_CONTAINER);
|
||||||
|
|
||||||
#define EEK_KEYBOARD_GET_PRIVATE(obj) \
|
#define EEK_KEYBOARD_GET_PRIVATE(obj) \
|
||||||
(G_TYPE_INSTANCE_GET_PRIVATE ((obj), EEK_TYPE_KEYBOARD, EekKeyboardPrivate))
|
(G_TYPE_INSTANCE_GET_PRIVATE ((obj), EEK_TYPE_KEYBOARD, EekKeyboardPrivate))
|
||||||
|
|
||||||
@ -68,19 +65,16 @@ struct _EekKeyboardPrivate
|
|||||||
EekLayout *layout;
|
EekLayout *layout;
|
||||||
EekModifierBehavior modifier_behavior;
|
EekModifierBehavior modifier_behavior;
|
||||||
EekModifierType modifiers;
|
EekModifierType modifiers;
|
||||||
unsigned int old_level;
|
|
||||||
GList *pressed_keys;
|
GList *pressed_keys;
|
||||||
GList *locked_keys;
|
GList *locked_keys;
|
||||||
GArray *outline_array;
|
GArray *outline_array;
|
||||||
GHashTable *names;
|
GHashTable *keycodes;
|
||||||
|
|
||||||
/* modifiers dynamically assigned at run time */
|
/* modifiers dynamically assigned at run time */
|
||||||
EekModifierType num_lock_mask;
|
EekModifierType num_lock_mask;
|
||||||
EekModifierType alt_gr_mask;
|
EekModifierType alt_gr_mask;
|
||||||
};
|
};
|
||||||
|
|
||||||
G_DEFINE_TYPE_WITH_PRIVATE (EekKeyboard, eek_keyboard, EEK_TYPE_CONTAINER);
|
|
||||||
|
|
||||||
G_DEFINE_BOXED_TYPE(EekModifierKey, eek_modifier_key,
|
G_DEFINE_BOXED_TYPE(EekModifierKey, eek_modifier_key,
|
||||||
eek_modifier_key_copy, eek_modifier_key_free);
|
eek_modifier_key_copy, eek_modifier_key_free);
|
||||||
|
|
||||||
@ -127,9 +121,9 @@ section_child_added_cb (EekContainer *container,
|
|||||||
EekElement *element,
|
EekElement *element,
|
||||||
EekKeyboard *keyboard)
|
EekKeyboard *keyboard)
|
||||||
{
|
{
|
||||||
const gchar *name = eek_element_get_name(element);
|
guint keycode = eek_key_get_keycode (EEK_KEY(element));
|
||||||
g_hash_table_insert (keyboard->priv->names,
|
g_hash_table_insert (keyboard->priv->keycodes,
|
||||||
(gpointer)name,
|
GUINT_TO_POINTER(keycode),
|
||||||
element);
|
element);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -138,9 +132,9 @@ section_child_removed_cb (EekContainer *container,
|
|||||||
EekElement *element,
|
EekElement *element,
|
||||||
EekKeyboard *keyboard)
|
EekKeyboard *keyboard)
|
||||||
{
|
{
|
||||||
const gchar *name = eek_element_get_name(element);
|
guint keycode = eek_key_get_keycode (EEK_KEY(element));
|
||||||
g_hash_table_remove (keyboard->priv->names,
|
g_hash_table_remove (keyboard->priv->keycodes,
|
||||||
name);
|
GUINT_TO_POINTER(keycode));
|
||||||
}
|
}
|
||||||
|
|
||||||
static EekSection *
|
static EekSection *
|
||||||
@ -209,61 +203,16 @@ eek_keyboard_get_property (GObject *object,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
set_level_from_modifiers (EekKeyboard *self, EekKey *key)
|
set_level_from_modifiers (EekKeyboard *self)
|
||||||
{
|
{
|
||||||
EekKeyboardPrivate *priv = EEK_KEYBOARD_GET_PRIVATE(self);
|
EekKeyboardPrivate *priv = EEK_KEYBOARD_GET_PRIVATE(self);
|
||||||
|
gint level = 0;
|
||||||
|
|
||||||
/* The levels are: 0 Letters, 1 Upper case letters, 2 Numbers, 3 Symbols */
|
if (priv->modifiers & priv->alt_gr_mask)
|
||||||
|
level |= 2;
|
||||||
/* Use the numbers/letters bit from the old level */
|
if (priv->modifiers & EEK_SHIFT_MASK)
|
||||||
gint level = priv->old_level & 2;
|
level |= 1;
|
||||||
|
|
||||||
/* Handle non-emitting keys */
|
|
||||||
if (key) {
|
|
||||||
const gchar *name = eek_element_get_name(EEK_ELEMENT(key));
|
|
||||||
if (g_strcmp0(name, "ABC123") == 0)
|
|
||||||
level ^= 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
level |= ((priv->modifiers & EEK_SHIFT_MASK) ? 1 : 0);
|
|
||||||
|
|
||||||
switch (priv->old_level) {
|
|
||||||
case VIEW_LETTERS_UPPER:
|
|
||||||
{
|
|
||||||
/* Redirect upper case letters to numbers instead of symbols, clearing
|
|
||||||
the shift modifier to keep the modifiers in sync with the level */
|
|
||||||
if (level == VIEW_SYMBOLS) {
|
|
||||||
level = VIEW_NUMBERS;
|
|
||||||
priv->modifiers &= ~EEK_SHIFT_MASK;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case VIEW_SYMBOLS:
|
|
||||||
{
|
|
||||||
/* Redirect symbols to lower case letters instead of upper case,
|
|
||||||
clearing the shift modifier to keep the modifiers in sync with the
|
|
||||||
level */
|
|
||||||
if (level == VIEW_LETTERS_UPPER) {
|
|
||||||
level = VIEW_LETTERS_LOWER;
|
|
||||||
priv->modifiers &= ~EEK_SHIFT_MASK;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case VIEW_LETTERS_LOWER: /* Direct transitions between views */
|
|
||||||
case VIEW_NUMBERS:
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (level == VIEW_NUMBERS || level == VIEW_SYMBOLS)
|
|
||||||
priv->modifier_behavior = EEK_MODIFIER_BEHAVIOR_LOCK;
|
|
||||||
else
|
|
||||||
priv->modifier_behavior = EEK_MODIFIER_BEHAVIOR_LATCH;
|
|
||||||
|
|
||||||
priv->old_level = level;
|
|
||||||
eek_element_set_level (EEK_ELEMENT(self), level);
|
eek_element_set_level (EEK_ELEMENT(self), level);
|
||||||
|
|
||||||
eek_layout_update_layout(self);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -318,7 +267,7 @@ void eek_keyboard_press_key(EekKeyboard *keyboard, EekKey *key, guint32 timestam
|
|||||||
EekModifierType modifier = eek_symbol_get_modifier_mask (symbol);
|
EekModifierType modifier = eek_symbol_get_modifier_mask (symbol);
|
||||||
if (priv->modifier_behavior == EEK_MODIFIER_BEHAVIOR_NONE) {
|
if (priv->modifier_behavior == EEK_MODIFIER_BEHAVIOR_NONE) {
|
||||||
set_modifiers_with_key (keyboard, key, priv->modifiers | modifier);
|
set_modifiers_with_key (keyboard, key, priv->modifiers | modifier);
|
||||||
set_level_from_modifiers (keyboard, key);
|
set_level_from_modifiers (keyboard);
|
||||||
}
|
}
|
||||||
|
|
||||||
// "Borrowed" from eek-context-service; doesn't influence the state but forwards the event
|
// "Borrowed" from eek-context-service; doesn't influence the state but forwards the event
|
||||||
@ -367,7 +316,7 @@ void eek_keyboard_release_key( EekKeyboard *keyboard,
|
|||||||
(priv->modifiers ^ modifier) & modifier);
|
(priv->modifiers ^ modifier) & modifier);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
set_level_from_modifiers (keyboard, key);
|
set_level_from_modifiers (keyboard);
|
||||||
|
|
||||||
// "Borrowed" from eek-context-service; doesn't influence the state but forwards the event
|
// "Borrowed" from eek-context-service; doesn't influence the state but forwards the event
|
||||||
|
|
||||||
@ -400,7 +349,7 @@ eek_keyboard_finalize (GObject *object)
|
|||||||
g_list_free_full (priv->locked_keys,
|
g_list_free_full (priv->locked_keys,
|
||||||
(GDestroyNotify) eek_modifier_key_free);
|
(GDestroyNotify) eek_modifier_key_free);
|
||||||
|
|
||||||
g_hash_table_destroy (priv->names);
|
g_hash_table_destroy (priv->keycodes);
|
||||||
|
|
||||||
for (i = 0; i < priv->outline_array->len; i++) {
|
for (i = 0; i < priv->outline_array->len; i++) {
|
||||||
EekOutline *outline = &g_array_index (priv->outline_array,
|
EekOutline *outline = &g_array_index (priv->outline_array,
|
||||||
@ -441,6 +390,9 @@ eek_keyboard_class_init (EekKeyboardClass *klass)
|
|||||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||||
GParamSpec *pspec;
|
GParamSpec *pspec;
|
||||||
|
|
||||||
|
g_type_class_add_private (gobject_class,
|
||||||
|
sizeof (EekKeyboardPrivate));
|
||||||
|
|
||||||
klass->create_section = eek_keyboard_real_create_section;
|
klass->create_section = eek_keyboard_real_create_section;
|
||||||
|
|
||||||
/* signals */
|
/* signals */
|
||||||
@ -528,9 +480,8 @@ eek_keyboard_init (EekKeyboard *self)
|
|||||||
self->priv = EEK_KEYBOARD_GET_PRIVATE(self);
|
self->priv = EEK_KEYBOARD_GET_PRIVATE(self);
|
||||||
self->priv->modifier_behavior = EEK_MODIFIER_BEHAVIOR_NONE;
|
self->priv->modifier_behavior = EEK_MODIFIER_BEHAVIOR_NONE;
|
||||||
self->priv->outline_array = g_array_new (FALSE, TRUE, sizeof (EekOutline));
|
self->priv->outline_array = g_array_new (FALSE, TRUE, sizeof (EekOutline));
|
||||||
self->priv->names = g_hash_table_new (g_str_hash, g_str_equal);
|
self->priv->keycodes = g_hash_table_new (g_direct_hash, g_direct_equal);
|
||||||
eek_element_set_symbol_index (EEK_ELEMENT(self), 0, 0);
|
eek_element_set_symbol_index (EEK_ELEMENT(self), 0, 0);
|
||||||
self->scale = 1.0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -549,20 +500,20 @@ eek_keyboard_create_section (EekKeyboard *keyboard)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* eek_keyboard_find_key_by_name:
|
* eek_keyboard_find_key_by_keycode:
|
||||||
* @keyboard: an #EekKeyboard
|
* @keyboard: an #EekKeyboard
|
||||||
* @name: a key name
|
* @keycode: a keycode
|
||||||
*
|
*
|
||||||
* Find an #EekKey whose name is @name.
|
* Find an #EekKey whose keycode is @keycode.
|
||||||
* Return value: (transfer none): #EekKey whose name is @name
|
* Return value: (transfer none): #EekKey whose keycode is @keycode
|
||||||
*/
|
*/
|
||||||
EekKey *
|
EekKey *
|
||||||
eek_keyboard_find_key_by_name (EekKeyboard *keyboard,
|
eek_keyboard_find_key_by_keycode (EekKeyboard *keyboard,
|
||||||
const gchar *name)
|
guint keycode)
|
||||||
{
|
{
|
||||||
g_return_val_if_fail (EEK_IS_KEYBOARD(keyboard), NULL);
|
g_return_val_if_fail (EEK_IS_KEYBOARD(keyboard), NULL);
|
||||||
return g_hash_table_lookup (keyboard->priv->names,
|
return g_hash_table_lookup (keyboard->priv->keycodes,
|
||||||
name);
|
GUINT_TO_POINTER(keycode));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -634,7 +585,7 @@ eek_keyboard_set_modifiers (EekKeyboard *keyboard,
|
|||||||
{
|
{
|
||||||
g_return_if_fail (EEK_IS_KEYBOARD(keyboard));
|
g_return_if_fail (EEK_IS_KEYBOARD(keyboard));
|
||||||
keyboard->priv->modifiers = modifiers;
|
keyboard->priv->modifiers = modifiers;
|
||||||
set_level_from_modifiers (keyboard, NULL);
|
set_level_from_modifiers (keyboard);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -62,7 +62,6 @@ struct _EekKeyboard
|
|||||||
struct xkb_keymap *keymap;
|
struct xkb_keymap *keymap;
|
||||||
int keymap_fd; // keymap formatted as XKB string
|
int keymap_fd; // keymap formatted as XKB string
|
||||||
size_t keymap_len; // length of the data inside keymap_fd
|
size_t keymap_len; // length of the data inside keymap_fd
|
||||||
double scale;
|
|
||||||
|
|
||||||
EekboardContextService *manager; // unowned reference
|
EekboardContextService *manager; // unowned reference
|
||||||
};
|
};
|
||||||
@ -70,8 +69,8 @@ struct _EekKeyboard
|
|||||||
/**
|
/**
|
||||||
* EekKeyboardClass:
|
* EekKeyboardClass:
|
||||||
* @create_section: virtual function for creating a section
|
* @create_section: virtual function for creating a section
|
||||||
* @find_key_by_name: virtual function for finding a key in the
|
* @find_key_by_keycode: virtual function for finding a key in the
|
||||||
* keyboard by name
|
* keyboard by keycode
|
||||||
* @key_pressed: class handler for #EekKeyboard::key-pressed signal
|
* @key_pressed: class handler for #EekKeyboard::key-pressed signal
|
||||||
* @key_released: class handler for #EekKeyboard::key-released signal
|
* @key_released: class handler for #EekKeyboard::key-released signal
|
||||||
* @key_locked: class handler for #EekKeyboard::key-locked signal
|
* @key_locked: class handler for #EekKeyboard::key-locked signal
|
||||||
@ -90,8 +89,8 @@ struct _EekKeyboardClass
|
|||||||
/*< public >*/
|
/*< public >*/
|
||||||
EekSection *(* create_section) (EekKeyboard *self);
|
EekSection *(* create_section) (EekKeyboard *self);
|
||||||
|
|
||||||
EekKey *(* find_key_by_name) (EekKeyboard *self,
|
EekKey *(* find_key_by_keycode) (EekKeyboard *self,
|
||||||
const gchar *name);
|
guint keycode);
|
||||||
|
|
||||||
/*< private >*/
|
/*< private >*/
|
||||||
/* obsolete members moved to EekElement */
|
/* obsolete members moved to EekElement */
|
||||||
@ -156,9 +155,9 @@ EekModifierType eek_keyboard_get_modifiers
|
|||||||
EekSection *eek_keyboard_create_section
|
EekSection *eek_keyboard_create_section
|
||||||
(EekKeyboard *keyboard);
|
(EekKeyboard *keyboard);
|
||||||
|
|
||||||
EekKey *eek_keyboard_find_key_by_name
|
EekKey *eek_keyboard_find_key_by_keycode
|
||||||
(EekKeyboard *keyboard,
|
(EekKeyboard *keyboard,
|
||||||
const gchar *name);
|
guint keycode);
|
||||||
|
|
||||||
guint eek_keyboard_add_outline
|
guint eek_keyboard_add_outline
|
||||||
(EekKeyboard *keyboard,
|
(EekKeyboard *keyboard,
|
||||||
|
|||||||
@ -23,7 +23,9 @@
|
|||||||
* @short_description: an #EekSymbol represents an X keysym
|
* @short_description: an #EekSymbol represents an X keysym
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
#endif /* HAVE_CONFIG_H */
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|||||||
121
eek/eek-layout.c
121
eek/eek-layout.c
@ -26,7 +26,9 @@
|
|||||||
* arranges keyboard elements.
|
* arranges keyboard elements.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
#endif /* HAVE_CONFIG_H */
|
||||||
|
|
||||||
#include "eek-layout.h"
|
#include "eek-layout.h"
|
||||||
#include "eek-keyboard.h"
|
#include "eek-keyboard.h"
|
||||||
@ -67,122 +69,3 @@ eek_keyboard_new (EekboardContextService *manager,
|
|||||||
initial_width,
|
initial_width,
|
||||||
initial_height);
|
initial_height);
|
||||||
}
|
}
|
||||||
|
|
||||||
const double section_spacing = 7.0;
|
|
||||||
|
|
||||||
struct place_data {
|
|
||||||
double desired_width;
|
|
||||||
double current_offset;
|
|
||||||
EekKeyboard *keyboard;
|
|
||||||
};
|
|
||||||
|
|
||||||
static void
|
|
||||||
section_placer(EekElement *element, gpointer user_data)
|
|
||||||
{
|
|
||||||
struct place_data *data = (struct place_data*)user_data;
|
|
||||||
|
|
||||||
EekBounds section_bounds = {0};
|
|
||||||
eek_element_get_bounds(element, §ion_bounds);
|
|
||||||
section_bounds.width = data->desired_width;
|
|
||||||
eek_element_set_bounds(element, §ion_bounds);
|
|
||||||
|
|
||||||
// Sections are rows now. Gather up all the keys and adjust their bounds.
|
|
||||||
eek_section_place_keys(EEK_SECTION(element), EEK_KEYBOARD(data->keyboard));
|
|
||||||
|
|
||||||
eek_element_get_bounds(element, §ion_bounds);
|
|
||||||
section_bounds.y = data->current_offset;
|
|
||||||
eek_element_set_bounds(element, §ion_bounds);
|
|
||||||
data->current_offset += section_bounds.height + section_spacing;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
section_counter(EekElement *element, gpointer user_data) {
|
|
||||||
|
|
||||||
double *total_height = user_data;
|
|
||||||
EekBounds section_bounds = {0};
|
|
||||||
eek_element_get_bounds(element, §ion_bounds);
|
|
||||||
*total_height += section_bounds.height + section_spacing;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
eek_layout_place_sections(EekKeyboard *keyboard)
|
|
||||||
{
|
|
||||||
/* Order rows */
|
|
||||||
// This needs to be done after outlines, because outlines define key sizes
|
|
||||||
// TODO: do this only for rows without bounds
|
|
||||||
|
|
||||||
// The keyboard width is given by the user via screen size. The height will be given dynamically.
|
|
||||||
// TODO: calculate max line width beforehand for button centering. Leave keyboard centering to the renderer later
|
|
||||||
EekBounds keyboard_bounds = {0};
|
|
||||||
eek_element_get_bounds(EEK_ELEMENT(keyboard), &keyboard_bounds);
|
|
||||||
|
|
||||||
struct place_data placer_data = {
|
|
||||||
.desired_width = keyboard_bounds.width,
|
|
||||||
.current_offset = 0,
|
|
||||||
.keyboard = keyboard,
|
|
||||||
};
|
|
||||||
eek_container_foreach_child(EEK_CONTAINER(keyboard), section_placer, &placer_data);
|
|
||||||
|
|
||||||
double total_height = 0;
|
|
||||||
eek_container_foreach_child(EEK_CONTAINER(keyboard), section_counter, &total_height);
|
|
||||||
keyboard_bounds.height = total_height;
|
|
||||||
eek_element_set_bounds(EEK_ELEMENT(keyboard), &keyboard_bounds);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void scale_bounds_callback (EekElement *element,
|
|
||||||
gpointer user_data);
|
|
||||||
|
|
||||||
static void
|
|
||||||
scale_bounds (EekElement *element,
|
|
||||||
gdouble scale)
|
|
||||||
{
|
|
||||||
EekBounds bounds;
|
|
||||||
|
|
||||||
eek_element_get_bounds (element, &bounds);
|
|
||||||
bounds.x *= scale;
|
|
||||||
bounds.y *= scale;
|
|
||||||
bounds.width *= scale;
|
|
||||||
bounds.height *= scale;
|
|
||||||
eek_element_set_bounds (element, &bounds);
|
|
||||||
|
|
||||||
if (EEK_IS_CONTAINER(element))
|
|
||||||
eek_container_foreach_child (EEK_CONTAINER(element),
|
|
||||||
scale_bounds_callback,
|
|
||||||
&scale);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
scale_bounds_callback (EekElement *element,
|
|
||||||
gpointer user_data)
|
|
||||||
{
|
|
||||||
scale_bounds (element, *(gdouble *)user_data);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
eek_layout_scale_keyboard(EekKeyboard *keyboard, gdouble scale)
|
|
||||||
{
|
|
||||||
gsize n_outlines;
|
|
||||||
|
|
||||||
scale_bounds (EEK_ELEMENT(keyboard), scale);
|
|
||||||
|
|
||||||
n_outlines = eek_keyboard_get_n_outlines (keyboard);
|
|
||||||
for (guint i = 0; i < n_outlines; i++) {
|
|
||||||
EekOutline *outline = eek_keyboard_get_outline (keyboard, i);
|
|
||||||
gint j;
|
|
||||||
|
|
||||||
for (j = 0; j < outline->num_points; j++) {
|
|
||||||
outline->points[j].x *= scale;
|
|
||||||
outline->points[j].y *= scale;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
keyboard->scale = scale;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
eek_layout_update_layout(EekKeyboard *keyboard)
|
|
||||||
{
|
|
||||||
eek_layout_scale_keyboard(keyboard, 1.0 / keyboard->scale);
|
|
||||||
eek_layout_place_sections(keyboard);
|
|
||||||
eek_layout_scale_keyboard(keyboard, 1.0 / keyboard->scale);
|
|
||||||
}
|
|
||||||
|
|||||||
@ -55,11 +55,5 @@ struct _EekLayoutClass
|
|||||||
|
|
||||||
GType eek_layout_get_type (void) G_GNUC_CONST;
|
GType eek_layout_get_type (void) G_GNUC_CONST;
|
||||||
|
|
||||||
void eek_layout_place_sections(EekKeyboard *keyboard);
|
|
||||||
|
|
||||||
void eek_layout_scale_keyboard(EekKeyboard *keyboard, gdouble scale);
|
|
||||||
|
|
||||||
void eek_layout_update_layout(EekKeyboard *keyboard);
|
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
#endif /* EEK_LAYOUT_H */
|
#endif /* EEK_LAYOUT_H */
|
||||||
|
|||||||
@ -18,12 +18,12 @@
|
|||||||
* 02110-1301 USA
|
* 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
#endif /* HAVE_CONFIG_H */
|
||||||
|
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <gdk-pixbuf/gdk-pixbuf.h>
|
|
||||||
#include <gtk/gtk.h>
|
|
||||||
|
|
||||||
#include "eek-key.h"
|
#include "eek-key.h"
|
||||||
#include "eek-section.h"
|
#include "eek-section.h"
|
||||||
@ -48,13 +48,11 @@ typedef struct _EekRendererPrivate
|
|||||||
gdouble allocation_width;
|
gdouble allocation_width;
|
||||||
gdouble allocation_height;
|
gdouble allocation_height;
|
||||||
gdouble scale;
|
gdouble scale;
|
||||||
gint scale_factor; /* the outputs scale factor */
|
|
||||||
|
|
||||||
PangoFontDescription *ascii_font;
|
PangoFontDescription *ascii_font;
|
||||||
PangoFontDescription *font;
|
PangoFontDescription *font;
|
||||||
GHashTable *outline_surface_cache;
|
GHashTable *outline_surface_cache;
|
||||||
GHashTable *active_outline_surface_cache;
|
GHashTable *active_outline_surface_cache;
|
||||||
GHashTable *icons;
|
|
||||||
cairo_surface_t *keyboard_surface;
|
cairo_surface_t *keyboard_surface;
|
||||||
gulong symbol_index_changed_handler;
|
gulong symbol_index_changed_handler;
|
||||||
|
|
||||||
@ -164,14 +162,9 @@ create_keyboard_surface (EekRenderer *renderer)
|
|||||||
&background);
|
&background);
|
||||||
|
|
||||||
eek_element_get_bounds (EEK_ELEMENT(priv->keyboard), &bounds);
|
eek_element_get_bounds (EEK_ELEMENT(priv->keyboard), &bounds);
|
||||||
|
keyboard_surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
|
||||||
/* Create a surface that encompasses the dimensions of the keyboard as well
|
ceil(bounds.width * priv->scale),
|
||||||
as the margin around the edge. */
|
ceil(bounds.height * priv->scale));
|
||||||
keyboard_surface = cairo_image_surface_create (
|
|
||||||
CAIRO_FORMAT_ARGB32,
|
|
||||||
ceil(((bounds.x * 2) + bounds.width) * priv->scale),
|
|
||||||
ceil(((bounds.y * 2) + bounds.height) * priv->scale));
|
|
||||||
|
|
||||||
data.cr = cairo_create (keyboard_surface);
|
data.cr = cairo_create (keyboard_surface);
|
||||||
data.renderer = renderer;
|
data.renderer = renderer;
|
||||||
|
|
||||||
@ -447,9 +440,6 @@ render_key (EekRenderer *self,
|
|||||||
PangoRectangle extents = { 0, };
|
PangoRectangle extents = { 0, };
|
||||||
EekColor foreground;
|
EekColor foreground;
|
||||||
|
|
||||||
if (!eek_key_has_label(key))
|
|
||||||
return;
|
|
||||||
|
|
||||||
oref = eek_key_get_oref (key);
|
oref = eek_key_get_oref (key);
|
||||||
outline = eek_keyboard_get_outline (priv->keyboard, oref);
|
outline = eek_keyboard_get_outline (priv->keyboard, oref);
|
||||||
if (outline == NULL)
|
if (outline == NULL)
|
||||||
@ -469,8 +459,7 @@ render_key (EekRenderer *self,
|
|||||||
if (!outline_surface) {
|
if (!outline_surface) {
|
||||||
cairo_t *cr;
|
cairo_t *cr;
|
||||||
|
|
||||||
// Outline will be drawn on the outside of the button, so the
|
// Outline will be drawn on the outside of the button, so the surface needs to be bigger than the button
|
||||||
// surface needs to be bigger than the button
|
|
||||||
outline_surface =
|
outline_surface =
|
||||||
cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
|
cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
|
||||||
(int)ceil(bounds.width) + 10,
|
(int)ceil(bounds.width) + 10,
|
||||||
@ -496,38 +485,44 @@ render_key (EekRenderer *self,
|
|||||||
cairo_set_source_surface (cr, outline_surface, 0.0, 0.0);
|
cairo_set_source_surface (cr, outline_surface, 0.0, 0.0);
|
||||||
cairo_paint (cr);
|
cairo_paint (cr);
|
||||||
|
|
||||||
eek_renderer_get_foreground_color (self, EEK_ELEMENT(key), &foreground);
|
|
||||||
/* render icon (if any) */
|
/* render icon (if any) */
|
||||||
symbol = eek_key_get_symbol_with_fallback (key, 0, 0);
|
symbol = eek_key_get_symbol_with_fallback (key, 0, 0);
|
||||||
if (!symbol)
|
if (!symbol)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
#define SCALE 0.4
|
|
||||||
if (eek_symbol_get_icon_name (symbol)) {
|
if (eek_symbol_get_icon_name (symbol)) {
|
||||||
gint scale = priv->scale_factor;
|
|
||||||
cairo_surface_t *icon_surface =
|
cairo_surface_t *icon_surface =
|
||||||
eek_renderer_get_icon_surface (self,
|
eek_renderer_get_icon_surface (self,
|
||||||
eek_symbol_get_icon_name (symbol),
|
eek_symbol_get_icon_name (symbol),
|
||||||
SCALE * MIN(bounds.width, bounds.height),
|
MIN(bounds.width, bounds.height) * 0.7);
|
||||||
scale);
|
|
||||||
if (icon_surface) {
|
if (icon_surface) {
|
||||||
gint width = cairo_image_surface_get_width (icon_surface);
|
gint width = cairo_image_surface_get_width (icon_surface);
|
||||||
gint height = cairo_image_surface_get_height (icon_surface);
|
gint height = cairo_image_surface_get_height (icon_surface);
|
||||||
|
gdouble scale;
|
||||||
|
|
||||||
|
if (width < bounds.width && height < bounds.height)
|
||||||
|
scale = 1;
|
||||||
|
else {
|
||||||
|
if (height * bounds.width / width <= bounds.height)
|
||||||
|
scale = bounds.width / width;
|
||||||
|
else if (width * bounds.height / height <= bounds.width)
|
||||||
|
scale = bounds.height / height;
|
||||||
|
else {
|
||||||
|
if (width * bounds.height < height * bounds.width)
|
||||||
|
scale = width / bounds.width;
|
||||||
|
else
|
||||||
|
scale = height / bounds.height;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
cairo_save (cr);
|
cairo_save (cr);
|
||||||
cairo_translate (cr,
|
cairo_translate (cr,
|
||||||
(bounds.width - width / scale) / 2,
|
(bounds.width - width * scale) / 2,
|
||||||
(bounds.height - height / scale) / 2);
|
(bounds.height - height * scale) / 2);
|
||||||
cairo_rectangle (cr, 0, 0, width, height);
|
cairo_rectangle (cr, 0, 0, width, height);
|
||||||
cairo_clip (cr);
|
cairo_clip (cr);
|
||||||
/* Draw the shape of the icon using the foreground color */
|
cairo_set_source_surface (cr, icon_surface, 0.0, 0.0);
|
||||||
cairo_set_source_rgba (cr, foreground.red,
|
cairo_paint (cr);
|
||||||
foreground.green,
|
|
||||||
foreground.blue,
|
|
||||||
foreground.alpha);
|
|
||||||
cairo_mask_surface (cr, icon_surface, 0.0, 0.0);
|
|
||||||
cairo_fill (cr);
|
|
||||||
|
|
||||||
cairo_restore (cr);
|
cairo_restore (cr);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -544,6 +539,7 @@ render_key (EekRenderer *self,
|
|||||||
(bounds.width - extents.width / PANGO_SCALE) / 2,
|
(bounds.width - extents.width / PANGO_SCALE) / 2,
|
||||||
(bounds.height - extents.height / PANGO_SCALE) / 2);
|
(bounds.height - extents.height / PANGO_SCALE) / 2);
|
||||||
|
|
||||||
|
eek_renderer_get_foreground_color (self, EEK_ELEMENT(key), &foreground);
|
||||||
cairo_set_source_rgba (cr,
|
cairo_set_source_rgba (cr,
|
||||||
foreground.red,
|
foreground.red,
|
||||||
foreground.green,
|
foreground.green,
|
||||||
@ -782,8 +778,6 @@ eek_renderer_dispose (GObject *object)
|
|||||||
priv->pcontext = NULL;
|
priv->pcontext = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
g_clear_pointer (&priv->icons, g_hash_table_destroy);
|
|
||||||
|
|
||||||
/* this will release all allocated surfaces and font if any */
|
/* this will release all allocated surfaces and font if any */
|
||||||
invalidate (EEK_RENDERER(object));
|
invalidate (EEK_RENDERER(object));
|
||||||
|
|
||||||
@ -851,7 +845,6 @@ eek_renderer_init (EekRenderer *self)
|
|||||||
priv->allocation_width = 0.0;
|
priv->allocation_width = 0.0;
|
||||||
priv->allocation_height = 0.0;
|
priv->allocation_height = 0.0;
|
||||||
priv->scale = 1.0;
|
priv->scale = 1.0;
|
||||||
priv->scale_factor = 1;
|
|
||||||
priv->font = NULL;
|
priv->font = NULL;
|
||||||
priv->outline_surface_cache =
|
priv->outline_surface_cache =
|
||||||
g_hash_table_new_full (g_direct_hash,
|
g_hash_table_new_full (g_direct_hash,
|
||||||
@ -865,14 +858,6 @@ eek_renderer_init (EekRenderer *self)
|
|||||||
(GDestroyNotify)cairo_surface_destroy);
|
(GDestroyNotify)cairo_surface_destroy);
|
||||||
priv->keyboard_surface = NULL;
|
priv->keyboard_surface = NULL;
|
||||||
priv->symbol_index_changed_handler = 0;
|
priv->symbol_index_changed_handler = 0;
|
||||||
|
|
||||||
GtkIconTheme *theme = gtk_icon_theme_get_default ();
|
|
||||||
|
|
||||||
gtk_icon_theme_add_resource_path (theme, "/sm/puri/squeekboard/icons");
|
|
||||||
priv->icons = g_hash_table_new_full (g_str_hash,
|
|
||||||
g_str_equal,
|
|
||||||
g_free,
|
|
||||||
(GDestroyNotify)cairo_surface_destroy);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -1044,15 +1029,6 @@ eek_renderer_get_scale (EekRenderer *renderer)
|
|||||||
return priv->scale;
|
return priv->scale;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
eek_renderer_set_scale_factor (EekRenderer *renderer, gint scale)
|
|
||||||
{
|
|
||||||
g_return_if_fail (EEK_IS_RENDERER(renderer));
|
|
||||||
|
|
||||||
EekRendererPrivate *priv = eek_renderer_get_instance_private (renderer);
|
|
||||||
priv->scale_factor = scale;
|
|
||||||
}
|
|
||||||
|
|
||||||
PangoLayout *
|
PangoLayout *
|
||||||
eek_renderer_create_pango_layout (EekRenderer *renderer)
|
eek_renderer_create_pango_layout (EekRenderer *renderer)
|
||||||
{
|
{
|
||||||
@ -1096,35 +1072,16 @@ eek_renderer_render_key_outline (EekRenderer *renderer,
|
|||||||
cairo_surface_t *
|
cairo_surface_t *
|
||||||
eek_renderer_get_icon_surface (EekRenderer *renderer,
|
eek_renderer_get_icon_surface (EekRenderer *renderer,
|
||||||
const gchar *icon_name,
|
const gchar *icon_name,
|
||||||
gint size,
|
gint size)
|
||||||
gint scale)
|
|
||||||
{
|
{
|
||||||
GError *error = NULL;
|
EekRendererClass *klass;
|
||||||
cairo_surface_t *surface;
|
|
||||||
|
|
||||||
g_return_val_if_fail (EEK_IS_RENDERER(renderer), NULL);
|
g_return_val_if_fail (EEK_IS_RENDERER(renderer), NULL);
|
||||||
|
|
||||||
EekRendererPrivate *priv = eek_renderer_get_instance_private (renderer);
|
klass = EEK_RENDERER_GET_CLASS(renderer);
|
||||||
|
if (klass->get_icon_surface)
|
||||||
surface = g_hash_table_lookup (priv->icons, icon_name);
|
return klass->get_icon_surface (renderer, icon_name, size);
|
||||||
if (!surface) {
|
|
||||||
surface = gtk_icon_theme_load_surface (gtk_icon_theme_get_default (),
|
|
||||||
icon_name,
|
|
||||||
size,
|
|
||||||
scale,
|
|
||||||
NULL,
|
|
||||||
0,
|
|
||||||
&error);
|
|
||||||
g_hash_table_insert (priv->icons, g_strdup(icon_name), surface);
|
|
||||||
if (surface == NULL) {
|
|
||||||
g_warning ("can't get icon surface for %s: %s",
|
|
||||||
icon_name,
|
|
||||||
error->message);
|
|
||||||
g_error_free (error);
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
|
||||||
}
|
|
||||||
return surface;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|||||||
@ -58,8 +58,7 @@ struct _EekRendererClass
|
|||||||
|
|
||||||
cairo_surface_t *(* get_icon_surface) (EekRenderer *self,
|
cairo_surface_t *(* get_icon_surface) (EekRenderer *self,
|
||||||
const gchar *icon_name,
|
const gchar *icon_name,
|
||||||
gint size,
|
gint size);
|
||||||
gint scale);
|
|
||||||
|
|
||||||
/*< private >*/
|
/*< private >*/
|
||||||
/* padding */
|
/* padding */
|
||||||
@ -82,8 +81,6 @@ void eek_renderer_get_key_bounds (EekRenderer *renderer,
|
|||||||
gboolean rotate);
|
gboolean rotate);
|
||||||
|
|
||||||
gdouble eek_renderer_get_scale (EekRenderer *renderer);
|
gdouble eek_renderer_get_scale (EekRenderer *renderer);
|
||||||
void eek_renderer_set_scale_factor (EekRenderer *renderer,
|
|
||||||
gint scale);
|
|
||||||
|
|
||||||
PangoLayout *eek_renderer_create_pango_layout
|
PangoLayout *eek_renderer_create_pango_layout
|
||||||
(EekRenderer *renderer);
|
(EekRenderer *renderer);
|
||||||
@ -106,8 +103,7 @@ void eek_renderer_render_key (EekRenderer *renderer,
|
|||||||
|
|
||||||
cairo_surface_t *eek_renderer_get_icon_surface (EekRenderer *renderer,
|
cairo_surface_t *eek_renderer_get_icon_surface (EekRenderer *renderer,
|
||||||
const gchar *icon_name,
|
const gchar *icon_name,
|
||||||
gint size,
|
gint size);
|
||||||
gint scale);
|
|
||||||
|
|
||||||
void eek_renderer_render_keyboard (EekRenderer *renderer,
|
void eek_renderer_render_keyboard (EekRenderer *renderer,
|
||||||
cairo_t *cr);
|
cairo_t *cr);
|
||||||
|
|||||||
@ -27,7 +27,9 @@
|
|||||||
* of one or more keys of the #EekKeyClass class.
|
* of one or more keys of the #EekKeyClass class.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
#endif /* HAVE_CONFIG_H */
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
@ -122,8 +124,7 @@ on_unlocked (EekKey *key,
|
|||||||
|
|
||||||
static EekKey *
|
static EekKey *
|
||||||
eek_section_real_create_key (EekSection *self,
|
eek_section_real_create_key (EekSection *self,
|
||||||
const gchar *name,
|
guint keycode,
|
||||||
gint keycode,
|
|
||||||
gint column_index,
|
gint column_index,
|
||||||
gint row_index)
|
gint row_index)
|
||||||
{
|
{
|
||||||
@ -141,7 +142,6 @@ eek_section_real_create_key (EekSection *self,
|
|||||||
row->num_columns = column_index + 1;
|
row->num_columns = column_index + 1;
|
||||||
|
|
||||||
key = g_object_new (EEK_TYPE_KEY,
|
key = g_object_new (EEK_TYPE_KEY,
|
||||||
"name", name,
|
|
||||||
"keycode", keycode,
|
"keycode", keycode,
|
||||||
"column", column_index,
|
"column", column_index,
|
||||||
"row", row_index,
|
"row", row_index,
|
||||||
@ -463,7 +463,6 @@ eek_section_get_row (EekSection *section,
|
|||||||
/**
|
/**
|
||||||
* eek_section_create_key:
|
* eek_section_create_key:
|
||||||
* @section: an #EekSection
|
* @section: an #EekSection
|
||||||
* @name: a name
|
|
||||||
* @keycode: a keycode
|
* @keycode: a keycode
|
||||||
* @column: the column index of the key
|
* @column: the column index of the key
|
||||||
* @row: the row index of the key
|
* @row: the row index of the key
|
||||||
@ -474,32 +473,19 @@ eek_section_get_row (EekSection *section,
|
|||||||
*/
|
*/
|
||||||
EekKey *
|
EekKey *
|
||||||
eek_section_create_key (EekSection *section,
|
eek_section_create_key (EekSection *section,
|
||||||
const gchar *name,
|
guint keycode,
|
||||||
gint keycode,
|
|
||||||
gint column,
|
gint column,
|
||||||
gint row)
|
gint row)
|
||||||
{
|
{
|
||||||
g_return_val_if_fail (EEK_IS_SECTION(section), NULL);
|
g_return_val_if_fail (EEK_IS_SECTION(section), NULL);
|
||||||
return EEK_SECTION_GET_CLASS(section)->create_key (section,
|
return EEK_SECTION_GET_CLASS(section)->create_key (section,
|
||||||
name,
|
|
||||||
keycode,
|
keycode,
|
||||||
column,
|
column,
|
||||||
row);
|
row);
|
||||||
}
|
}
|
||||||
|
|
||||||
const double keyspacing = 4.0;
|
static void keysizer(EekElement *element, gpointer user_data) {
|
||||||
|
|
||||||
struct keys_info {
|
|
||||||
uint count;
|
|
||||||
double total_width;
|
|
||||||
double biggest_height;
|
|
||||||
};
|
|
||||||
|
|
||||||
static void
|
|
||||||
keysizer(EekElement *element, gpointer user_data)
|
|
||||||
{
|
|
||||||
EekKey *key = EEK_KEY(element);
|
EekKey *key = EEK_KEY(element);
|
||||||
|
|
||||||
EekKeyboard *keyboard = EEK_KEYBOARD(user_data);
|
EekKeyboard *keyboard = EEK_KEYBOARD(user_data);
|
||||||
uint oref = eek_key_get_oref (key);
|
uint oref = eek_key_get_oref (key);
|
||||||
EekOutline *outline = eek_keyboard_get_outline (keyboard, oref);
|
EekOutline *outline = eek_keyboard_get_outline (keyboard, oref);
|
||||||
@ -530,15 +516,13 @@ keysizer(EekElement *element, gpointer user_data)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
struct keys_info {
|
||||||
keycounter (EekElement *element, gpointer user_data)
|
uint count;
|
||||||
{
|
double total_width;
|
||||||
EekKey *key = EEK_KEY(element);
|
double biggest_height;
|
||||||
|
};
|
||||||
/* Skip keys without labels for the current level. */
|
|
||||||
if (!eek_key_has_label(key))
|
|
||||||
return;
|
|
||||||
|
|
||||||
|
static void keycounter (EekElement *element, gpointer user_data) {
|
||||||
struct keys_info *data = user_data;
|
struct keys_info *data = user_data;
|
||||||
data->count++;
|
data->count++;
|
||||||
EekBounds key_bounds = {0};
|
EekBounds key_bounds = {0};
|
||||||
@ -549,15 +533,9 @@ keycounter (EekElement *element, gpointer user_data)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
const double keyspacing = 4.0;
|
||||||
keyplacer(EekElement *element, gpointer user_data)
|
|
||||||
{
|
|
||||||
EekKey *key = EEK_KEY(element);
|
|
||||||
|
|
||||||
/* Skip keys without labels for the current level. */
|
|
||||||
if (!eek_key_has_label(key))
|
|
||||||
return;
|
|
||||||
|
|
||||||
|
static void keyplacer(EekElement *element, gpointer user_data) {
|
||||||
double *current_offset = user_data;
|
double *current_offset = user_data;
|
||||||
EekBounds key_bounds = {0};
|
EekBounds key_bounds = {0};
|
||||||
eek_element_get_bounds(element, &key_bounds);
|
eek_element_get_bounds(element, &key_bounds);
|
||||||
@ -567,8 +545,7 @@ keyplacer(EekElement *element, gpointer user_data)
|
|||||||
*current_offset += key_bounds.width + keyspacing;
|
*current_offset += key_bounds.width + keyspacing;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void eek_section_place_keys(EekSection *section, EekKeyboard *keyboard)
|
||||||
eek_section_place_keys(EekSection *section, EekKeyboard *keyboard)
|
|
||||||
{
|
{
|
||||||
eek_container_foreach_child(EEK_CONTAINER(section), keysizer, keyboard);
|
eek_container_foreach_child(EEK_CONTAINER(section), keysizer, keyboard);
|
||||||
|
|
||||||
|
|||||||
@ -62,8 +62,7 @@ struct _EekSectionClass
|
|||||||
EekOrientation *orientation);
|
EekOrientation *orientation);
|
||||||
|
|
||||||
EekKey *(* create_key) (EekSection *self,
|
EekKey *(* create_key) (EekSection *self,
|
||||||
const gchar *name,
|
guint keycode,
|
||||||
gint keycode,
|
|
||||||
gint row,
|
gint row,
|
||||||
gint column);
|
gint column);
|
||||||
|
|
||||||
@ -100,8 +99,7 @@ void eek_section_get_row (EekSection *section,
|
|||||||
EekOrientation *orientation);
|
EekOrientation *orientation);
|
||||||
|
|
||||||
EekKey *eek_section_create_key (EekSection *section,
|
EekKey *eek_section_create_key (EekSection *section,
|
||||||
const gchar *name,
|
guint keycode,
|
||||||
gint keycode,
|
|
||||||
gint column,
|
gint column,
|
||||||
gint row);
|
gint row);
|
||||||
|
|
||||||
|
|||||||
@ -27,7 +27,9 @@
|
|||||||
* method.
|
* method.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
#endif /* HAVE_CONFIG_H */
|
||||||
|
|
||||||
#include "eek-serializable.h"
|
#include "eek-serializable.h"
|
||||||
|
|
||||||
|
|||||||
@ -25,7 +25,9 @@
|
|||||||
* The #EekSymbolClass class represents a symbol assigned to a key.
|
* The #EekSymbolClass class represents a symbol assigned to a key.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
#endif /* HAVE_CONFIG_H */
|
||||||
|
|
||||||
#include "eek-symbol.h"
|
#include "eek-symbol.h"
|
||||||
#include "eek-serializable.h"
|
#include "eek-serializable.h"
|
||||||
|
|||||||
@ -23,7 +23,9 @@
|
|||||||
* @short_description: an #EekText represents a text symbol
|
* @short_description: an #EekText represents a text symbol
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
#endif /* HAVE_CONFIG_H */
|
||||||
|
|
||||||
#include "eek-text.h"
|
#include "eek-text.h"
|
||||||
#include "eek-serializable.h"
|
#include "eek-serializable.h"
|
||||||
|
|||||||
@ -19,7 +19,9 @@
|
|||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
#endif /* HAVE_CONFIG_H */
|
||||||
|
|
||||||
#include "eek-theme.h"
|
#include "eek-theme.h"
|
||||||
#include "eek-theme-context.h"
|
#include "eek-theme-context.h"
|
||||||
|
|||||||
@ -23,7 +23,9 @@
|
|||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
#endif /* HAVE_CONFIG_H */
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
@ -87,6 +89,11 @@ static void eek_theme_node_finalize (GObject *object);
|
|||||||
|
|
||||||
static const EekColor BLACK_COLOR = { 0, 0, 0, 0xff };
|
static const EekColor BLACK_COLOR = { 0, 0, 0, 0xff };
|
||||||
static const EekColor TRANSPARENT_COLOR = { 0, 0, 0, 0 };
|
static const EekColor TRANSPARENT_COLOR = { 0, 0, 0, 0 };
|
||||||
|
#if 0 // ===== REMOVAL NOTICE ==== expires by: 2019-08-20 -Wunused-const-variable =====
|
||||||
|
static const EekColor DEFAULT_SUCCESS_COLOR = { 0x4e, 0x9a, 0x06, 0xff };
|
||||||
|
static const EekColor DEFAULT_WARNING_COLOR = { 0xf5, 0x79, 0x3e, 0xff };
|
||||||
|
static const EekColor DEFAULT_ERROR_COLOR = { 0xcc, 0x00, 0x00, 0xff };
|
||||||
|
#endif // ===== REMOVAL NOTICE ==== expires by: 2019-08-20 -Wunused-const-variable =====
|
||||||
|
|
||||||
static void
|
static void
|
||||||
eek_theme_node_init (EekThemeNode *self)
|
eek_theme_node_init (EekThemeNode *self)
|
||||||
|
|||||||
132
eek/eek-theme.c
132
eek/eek-theme.c
@ -43,7 +43,6 @@
|
|||||||
* Copyright (C) 2003-2004 Dodji Seketeli. All Rights Reserved.
|
* Copyright (C) 2003-2004 Dodji Seketeli. All Rights Reserved.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define G_LOG_DOMAIN "eek-theme"
|
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
@ -167,65 +166,103 @@ eek_theme_class_init (EekThemeClass *klass)
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* This is a workaround for a bug in libcroco < 0.6.2 where
|
||||||
|
* function starting with 'r' (and 'u') are misparsed. We work
|
||||||
|
* around this by exploiting the fact that libcroco is incomformant
|
||||||
|
* with the CSS-spec and case sensitive and pre-convert all
|
||||||
|
* occurrences of rgba to RGBA. Then we make our own parsing
|
||||||
|
* code check for RGBA as well.
|
||||||
|
*/
|
||||||
|
#if LIBCROCO_VERSION_NUMBER < 602
|
||||||
|
static gboolean
|
||||||
|
is_identifier_character (char c)
|
||||||
|
{
|
||||||
|
/* Actual CSS rules allow for unicode > 0x00a1 and escaped
|
||||||
|
* characters, but we'll assume we won't do that in our stylesheets
|
||||||
|
* or at least not next to the string 'rgba'.
|
||||||
|
*/
|
||||||
|
return g_ascii_isalnum(c) || c == '-' || c == '_';
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
convert_rgba_RGBA (char *buf)
|
||||||
|
{
|
||||||
|
char *p;
|
||||||
|
|
||||||
|
p = strstr (buf, "rgba");
|
||||||
|
while (p)
|
||||||
|
{
|
||||||
|
/* Check if this looks like a complete token; this is to
|
||||||
|
* avoiding mangling, say, a selector '.rgba-entry' */
|
||||||
|
if (!((p > buf && is_identifier_character (*(p - 1))) ||
|
||||||
|
(is_identifier_character (*(p + 4)))))
|
||||||
|
memcpy(p, "RGBA", 4);
|
||||||
|
p += 4;
|
||||||
|
p = strstr (p, "rgba");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static CRStyleSheet *
|
||||||
|
parse_stylesheet (const char *filename,
|
||||||
|
GError **error)
|
||||||
|
{
|
||||||
|
enum CRStatus status;
|
||||||
|
char *contents;
|
||||||
|
gsize length;
|
||||||
|
CRStyleSheet *stylesheet = NULL;
|
||||||
|
|
||||||
|
if (filename == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (!g_file_get_contents (filename, &contents, &length, error))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
convert_rgba_RGBA (contents);
|
||||||
|
|
||||||
|
status = cr_om_parser_simply_parse_buf ((const guchar *) contents,
|
||||||
|
length,
|
||||||
|
CR_UTF_8,
|
||||||
|
&stylesheet);
|
||||||
|
g_free (contents);
|
||||||
|
|
||||||
|
if (status != CR_OK)
|
||||||
|
{
|
||||||
|
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
|
||||||
|
"Error parsing stylesheet '%s'; errcode:%d", filename, status);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return stylesheet;
|
||||||
|
}
|
||||||
|
|
||||||
|
CRDeclaration *
|
||||||
|
_eek_theme_parse_declaration_list (const char *str)
|
||||||
|
{
|
||||||
|
char *copy = g_strdup (str);
|
||||||
|
CRDeclaration *result;
|
||||||
|
|
||||||
|
convert_rgba_RGBA (copy);
|
||||||
|
|
||||||
|
result = cr_declaration_parse_list_from_buf ((const guchar *)copy,
|
||||||
|
CR_UTF_8);
|
||||||
|
g_free (copy);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
#else /* LIBCROCO_VERSION_NUMBER >= 602 */
|
||||||
static CRStyleSheet *
|
static CRStyleSheet *
|
||||||
parse_stylesheet (const char *filename,
|
parse_stylesheet (const char *filename,
|
||||||
GError **error)
|
GError **error)
|
||||||
{
|
{
|
||||||
enum CRStatus status;
|
enum CRStatus status;
|
||||||
CRStyleSheet *stylesheet;
|
CRStyleSheet *stylesheet;
|
||||||
g_autoptr (GFileInputStream) stream = NULL;
|
|
||||||
g_autoptr (GFileInfo) info = NULL;
|
|
||||||
g_autoptr (GFile) file = NULL;
|
|
||||||
g_autofree guchar* contents = NULL;
|
|
||||||
goffset size;
|
|
||||||
gsize out = 0;
|
|
||||||
GError *err = NULL;
|
|
||||||
|
|
||||||
if (filename == NULL)
|
if (filename == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
g_debug ("Parsing %s", filename);
|
|
||||||
if (g_strcmp0 (filename, "resource://") > 0) {
|
|
||||||
file = g_file_new_for_uri (filename);
|
|
||||||
stream = g_file_read (file, NULL, &err);
|
|
||||||
if (!stream) {
|
|
||||||
g_warning ("Failed to open %s: %s", filename, err->message);
|
|
||||||
g_clear_error (&err);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
info = g_file_input_stream_query_info (stream,
|
|
||||||
G_FILE_ATTRIBUTE_STANDARD_SIZE,
|
|
||||||
NULL,
|
|
||||||
&err);
|
|
||||||
|
|
||||||
if (!info) {
|
|
||||||
g_warning ("Failed to stat %s: %s", filename, err->message);
|
|
||||||
g_clear_error (&err);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
size = g_file_info_get_size (info);
|
|
||||||
contents = g_malloc0 (size);
|
|
||||||
if (!g_input_stream_read_all (G_INPUT_STREAM (stream),
|
|
||||||
contents,
|
|
||||||
size,
|
|
||||||
&out,
|
|
||||||
NULL,
|
|
||||||
&err)) {
|
|
||||||
g_warning ("Failed to read %s: %s", filename, err->message);
|
|
||||||
g_clear_error (&err);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
status = cr_om_parser_simply_parse_buf (contents,
|
|
||||||
size,
|
|
||||||
CR_UTF_8,
|
|
||||||
&stylesheet);
|
|
||||||
} else {
|
|
||||||
status = cr_om_parser_simply_parse_file ((const guchar *) filename,
|
status = cr_om_parser_simply_parse_file ((const guchar *) filename,
|
||||||
CR_UTF_8,
|
CR_UTF_8,
|
||||||
&stylesheet);
|
&stylesheet);
|
||||||
}
|
|
||||||
|
|
||||||
if (status != CR_OK)
|
if (status != CR_OK)
|
||||||
{
|
{
|
||||||
@ -243,6 +280,7 @@ _eek_theme_parse_declaration_list (const char *str)
|
|||||||
return cr_declaration_parse_list_from_buf ((const guchar *)str,
|
return cr_declaration_parse_list_from_buf ((const guchar *)str,
|
||||||
CR_UTF_8);
|
CR_UTF_8);
|
||||||
}
|
}
|
||||||
|
#endif /* LIBCROCO_VERSION_NUMBER < 602 */
|
||||||
|
|
||||||
/* Just g_warning for now until we have something nicer to do */
|
/* Just g_warning for now until we have something nicer to do */
|
||||||
static CRStyleSheet *
|
static CRStyleSheet *
|
||||||
|
|||||||
@ -24,7 +24,9 @@
|
|||||||
* @short_description: Miscellaneous types used in Libeek
|
* @short_description: Miscellaneous types used in Libeek
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
#endif /* HAVE_CONFIG_H */
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|||||||
30
eek/eek-xkb-0.90.pc.in
Normal file
30
eek/eek-xkb-0.90.pc.in
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
# Copyright (C) 2010-2011 Daiki Ueno <ueno@unixuser.org>
|
||||||
|
# Copyright (C) 2010-2011 Red Hat, Inc.
|
||||||
|
|
||||||
|
# This library is free software; you can redistribute it and/or
|
||||||
|
# modify it under the terms of the GNU Lesser General Public License
|
||||||
|
# as published by the Free Software Foundation; either version 2 of
|
||||||
|
# the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
# This library 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
|
||||||
|
# Lesser General Public License for more details.
|
||||||
|
|
||||||
|
# You should have received a copy of the GNU Lesser General Public
|
||||||
|
# License along with this library; if not, write to the Free Software
|
||||||
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||||
|
# 02110-1301 USA
|
||||||
|
|
||||||
|
prefix=@prefix@
|
||||||
|
exec_prefix=@exec_prefix@
|
||||||
|
libdir=@libdir@
|
||||||
|
includedir=@includedir@
|
||||||
|
|
||||||
|
Name: libeek-xkb
|
||||||
|
Description: A Library to Create Keyboard-like UI (XKB Support)
|
||||||
|
URL: http://fedorahosted.org/eekboard/
|
||||||
|
Version: @VERSION@
|
||||||
|
Requires: eek-@EEK_API_VERSION@ gtk+-x11-@GTK_API_VERSION@
|
||||||
|
Libs: -L${libdir} -leek-xkb
|
||||||
|
Cflags: -I${includedir}/eek-@EEK_API_VERSION@
|
||||||
684
eek/eek-xkb-layout.c
Normal file
684
eek/eek-xkb-layout.c
Normal file
@ -0,0 +1,684 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2006 Sergey V. Udaltsov <svu@gnome.org>
|
||||||
|
* Copyright (C) 2010-2011 Daiki Ueno <ueno@unixuser.org>
|
||||||
|
* Copyright (C) 2010-2011 Red Hat, Inc.
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2 of
|
||||||
|
* the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library 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
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||||
|
* 02110-1301 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SECTION:eek-xkb-layout
|
||||||
|
* @short_description: Layout engine using XKB configuration
|
||||||
|
*
|
||||||
|
* The #EekXkbLayout inherits #EekLayout class and arranges keyboard
|
||||||
|
* elements using XKB.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "config.h"
|
||||||
|
#endif /* HAVE_CONFIG_H */
|
||||||
|
|
||||||
|
#include "eek-xkb-layout.h"
|
||||||
|
|
||||||
|
#include <X11/keysym.h>
|
||||||
|
#include <X11/extensions/XKBgeom.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <gio/gio.h>
|
||||||
|
|
||||||
|
#include "eek-keyboard.h"
|
||||||
|
#include "eek-section.h"
|
||||||
|
#include "eek-key.h"
|
||||||
|
#include "eek-keysym.h"
|
||||||
|
|
||||||
|
#define XKB_COMPONENT_MASK (XkbGBN_GeometryMask | \
|
||||||
|
XkbGBN_KeyNamesMask | \
|
||||||
|
XkbGBN_OtherNamesMask | \
|
||||||
|
XkbGBN_SymbolsMask | \
|
||||||
|
XkbGBN_IndicatorMapMask)
|
||||||
|
|
||||||
|
static void initable_iface_init (GInitableIface *initable_iface);
|
||||||
|
|
||||||
|
enum {
|
||||||
|
PROP_0,
|
||||||
|
PROP_DISPLAY,
|
||||||
|
PROP_LAST
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct _EekXkbLayoutPrivate
|
||||||
|
{
|
||||||
|
/* Configuration names that should synch'ed to the symbolic names
|
||||||
|
in priv->xkb->names. Since we use GLib's memory allocator,
|
||||||
|
don't store any address returned from the X server here. */
|
||||||
|
XkbComponentNamesRec names;
|
||||||
|
|
||||||
|
Display *display;
|
||||||
|
|
||||||
|
/* Actual XKB configuration of DISPLAY. */
|
||||||
|
XkbDescRec *xkb;
|
||||||
|
|
||||||
|
/* Hash table to cache orefs by shape address. */
|
||||||
|
GHashTable *shape_oref_hash;
|
||||||
|
|
||||||
|
gint scale_numerator;
|
||||||
|
gint scale_denominator;
|
||||||
|
} EekXkbLayoutPrivate;
|
||||||
|
|
||||||
|
G_DEFINE_TYPE_EXTENDED (EekXkbLayout, eek_xkb_layout, EEK_TYPE_LAYOUT,
|
||||||
|
0, /* GTypeFlags */
|
||||||
|
G_ADD_PRIVATE(EekXkbLayout)
|
||||||
|
G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE,
|
||||||
|
initable_iface_init))
|
||||||
|
|
||||||
|
static guint find_keycode (EekXkbLayout *layout,
|
||||||
|
gchar *key_name);
|
||||||
|
|
||||||
|
static gboolean get_keyboard_from_server (EekXkbLayout *layout,
|
||||||
|
GError **error);
|
||||||
|
|
||||||
|
static gboolean get_names_from_server (EekXkbLayout *layout,
|
||||||
|
GError **error);
|
||||||
|
|
||||||
|
static void setup_scaling (EekXkbLayout *layout,
|
||||||
|
gdouble width,
|
||||||
|
gdouble height);
|
||||||
|
|
||||||
|
G_INLINE_FUNC gint
|
||||||
|
xkb_to_pixmap_coord (EekXkbLayout *layout,
|
||||||
|
gint n)
|
||||||
|
{
|
||||||
|
EekXkbLayoutPrivate *priv = eek_xkb_layout_get_instance_private (layout);
|
||||||
|
return n * priv->scale_numerator / priv->scale_denominator;
|
||||||
|
}
|
||||||
|
|
||||||
|
G_INLINE_FUNC gdouble
|
||||||
|
xkb_to_pixmap_double (EekXkbLayout *layout,
|
||||||
|
gdouble d)
|
||||||
|
{
|
||||||
|
EekXkbLayoutPrivate *priv = eek_xkb_layout_get_instance_private (layout);
|
||||||
|
return d * priv->scale_numerator / priv->scale_denominator;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
create_key (EekXkbLayout *layout,
|
||||||
|
EekKeyboard *keyboard,
|
||||||
|
EekSection *section,
|
||||||
|
gint column,
|
||||||
|
gint row,
|
||||||
|
gdouble x,
|
||||||
|
gdouble y,
|
||||||
|
XkbKeyRec *xkbkey)
|
||||||
|
{
|
||||||
|
XkbGeometryRec *xkbgeometry;
|
||||||
|
XkbBoundsRec *xkbbounds;
|
||||||
|
XkbShapeRec *xkbshape;
|
||||||
|
XkbOutlineRec *xkboutline;
|
||||||
|
EekXkbLayoutPrivate *priv = eek_xkb_layout_get_instance_private (layout);
|
||||||
|
EekKey *key;
|
||||||
|
EekBounds bounds;
|
||||||
|
EekSymbolMatrix *matrix = NULL;
|
||||||
|
gchar name[XkbKeyNameLength + 1];
|
||||||
|
KeyCode keycode;
|
||||||
|
gint num_groups, num_levels;
|
||||||
|
guint oref;
|
||||||
|
gpointer v;
|
||||||
|
|
||||||
|
xkbgeometry = priv->xkb->geom;
|
||||||
|
xkbshape = &xkbgeometry->shapes[xkbkey->shape_ndx];
|
||||||
|
if (g_hash_table_lookup_extended (priv->shape_oref_hash, xkbshape,
|
||||||
|
NULL, &v)) {
|
||||||
|
oref = GPOINTER_TO_UINT(v);
|
||||||
|
} else {
|
||||||
|
EekOutline *outline;
|
||||||
|
|
||||||
|
xkboutline = xkbshape->primary == NULL ? &xkbshape->outlines[0] :
|
||||||
|
xkbshape->primary;
|
||||||
|
|
||||||
|
outline = g_slice_new (EekOutline);
|
||||||
|
outline->corner_radius = xkb_to_pixmap_coord(layout,
|
||||||
|
xkboutline->corner_radius);
|
||||||
|
|
||||||
|
if (xkboutline->num_points <= 2) { /* rectangular */
|
||||||
|
gdouble x1, y1, x2, y2;
|
||||||
|
|
||||||
|
outline->num_points = 4;
|
||||||
|
outline->points = g_slice_alloc0 (sizeof (EekPoint) *
|
||||||
|
outline->num_points);
|
||||||
|
if (xkboutline->num_points == 1) {
|
||||||
|
x1 = xkb_to_pixmap_coord(layout, xkbshape->bounds.x1);
|
||||||
|
y1 = xkb_to_pixmap_coord(layout, xkbshape->bounds.y1);
|
||||||
|
x2 = xkb_to_pixmap_coord(layout, xkboutline->points[0].x);
|
||||||
|
y2 = xkb_to_pixmap_coord(layout, xkboutline->points[0].y);
|
||||||
|
} else {
|
||||||
|
x1 = xkb_to_pixmap_coord(layout, xkboutline->points[0].x);
|
||||||
|
y1 = xkb_to_pixmap_coord(layout, xkboutline->points[0].y);
|
||||||
|
x2 = xkb_to_pixmap_coord(layout, xkboutline->points[1].x);
|
||||||
|
y2 = xkb_to_pixmap_coord(layout, xkboutline->points[1].y);
|
||||||
|
}
|
||||||
|
outline->points[0].x = outline->points[3].x = x1;
|
||||||
|
outline->points[0].y = outline->points[1].y = y1;
|
||||||
|
outline->points[1].x = outline->points[2].x = x2;
|
||||||
|
outline->points[2].y = outline->points[3].y = y2;
|
||||||
|
} else { /* polygon */
|
||||||
|
gint i;
|
||||||
|
|
||||||
|
outline->num_points = xkboutline->num_points;
|
||||||
|
outline->points = g_new0 (EekPoint, outline->num_points);
|
||||||
|
for (i = 0; i < xkboutline->num_points; i++) {
|
||||||
|
outline->points[i].x =
|
||||||
|
xkb_to_pixmap_coord(layout, xkboutline->points[i].x);
|
||||||
|
outline->points[i].y =
|
||||||
|
xkb_to_pixmap_coord(layout, xkboutline->points[i].y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
oref = eek_keyboard_add_outline (keyboard, outline);
|
||||||
|
eek_outline_free (outline);
|
||||||
|
g_hash_table_insert (priv->shape_oref_hash, xkbshape,
|
||||||
|
GUINT_TO_POINTER(oref));
|
||||||
|
}
|
||||||
|
|
||||||
|
memset (name, 0, sizeof name);
|
||||||
|
memcpy (name, xkbkey->name.name, sizeof name - 1);
|
||||||
|
|
||||||
|
xkbbounds = &xkbgeometry->shapes[xkbkey->shape_ndx].bounds;
|
||||||
|
bounds.x = xkb_to_pixmap_coord(layout, xkbbounds->x1 + x);
|
||||||
|
bounds.y = xkb_to_pixmap_coord(layout, xkbbounds->y1 + y);
|
||||||
|
bounds.width = xkb_to_pixmap_coord(layout, xkbbounds->x2 - xkbbounds->x1);
|
||||||
|
bounds.height = xkb_to_pixmap_coord(layout, xkbbounds->y2 - xkbbounds->y1);
|
||||||
|
|
||||||
|
keycode = find_keycode (layout, name);
|
||||||
|
if (keycode == EEK_INVALID_KEYCODE) {
|
||||||
|
num_groups = num_levels = 0;
|
||||||
|
matrix = eek_symbol_matrix_new (0, 0);
|
||||||
|
} else {
|
||||||
|
KeySym keysym;
|
||||||
|
gint i, j;
|
||||||
|
|
||||||
|
num_groups = XkbKeyNumGroups (priv->xkb, keycode);
|
||||||
|
num_levels = XkbKeyGroupsWidth (priv->xkb, keycode);
|
||||||
|
matrix = eek_symbol_matrix_new (num_groups, num_levels);
|
||||||
|
for (i = 0; i < num_groups; i++)
|
||||||
|
for (j = 0; j < num_levels; j++) {
|
||||||
|
EekModifierType modifier;
|
||||||
|
|
||||||
|
keysym = XkbKeySymEntry (priv->xkb, keycode, j, i);
|
||||||
|
modifier = XkbKeysymToModifiers (priv->display, keysym);
|
||||||
|
matrix->data[i * num_levels + j] =
|
||||||
|
EEK_SYMBOL(eek_keysym_new_with_modifier (keysym,
|
||||||
|
modifier));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
key = eek_section_create_key (section, keycode, column, row);
|
||||||
|
eek_element_set_name (EEK_ELEMENT(key), name);
|
||||||
|
eek_element_set_bounds (EEK_ELEMENT(key), &bounds);
|
||||||
|
eek_key_set_symbol_matrix (key, matrix);
|
||||||
|
eek_symbol_matrix_free (matrix);
|
||||||
|
eek_key_set_oref (key, oref);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
create_section (EekXkbLayout *layout,
|
||||||
|
EekKeyboard *keyboard,
|
||||||
|
XkbSectionRec *xkbsection)
|
||||||
|
{
|
||||||
|
XkbGeometryRec *xkbgeometry;
|
||||||
|
EekXkbLayoutPrivate *priv = eek_xkb_layout_get_instance_private (layout);
|
||||||
|
EekSection *section;
|
||||||
|
EekBounds bounds;
|
||||||
|
gchar *name;
|
||||||
|
gfloat left, top;
|
||||||
|
gint i, j;
|
||||||
|
|
||||||
|
bounds.x = xkb_to_pixmap_coord(layout, xkbsection->left);
|
||||||
|
bounds.y = xkb_to_pixmap_coord(layout, xkbsection->top);
|
||||||
|
bounds.width = xkb_to_pixmap_coord(layout, xkbsection->width);
|
||||||
|
bounds.height = xkb_to_pixmap_coord(layout, xkbsection->height);
|
||||||
|
|
||||||
|
xkbgeometry = priv->xkb->geom;
|
||||||
|
section = eek_keyboard_create_section (keyboard);
|
||||||
|
name = XGetAtomName (priv->display, xkbsection->name);
|
||||||
|
eek_element_set_name (EEK_ELEMENT(section), name);
|
||||||
|
XFree (name);
|
||||||
|
eek_element_set_bounds (EEK_ELEMENT(section), &bounds);
|
||||||
|
eek_section_set_angle (section,
|
||||||
|
/* angle is in tenth of degree */
|
||||||
|
xkbsection->angle / 10);
|
||||||
|
|
||||||
|
for (i = 0; i < xkbsection->num_rows; i++) {
|
||||||
|
XkbRowRec *xkbrow;
|
||||||
|
|
||||||
|
xkbrow = &xkbsection->rows[i];
|
||||||
|
left = xkbrow->left;
|
||||||
|
top = xkbrow->top;
|
||||||
|
eek_section_add_row (section,
|
||||||
|
xkbrow->num_keys,
|
||||||
|
xkbrow->vertical ?
|
||||||
|
EEK_ORIENTATION_VERTICAL :
|
||||||
|
EEK_ORIENTATION_HORIZONTAL);
|
||||||
|
for (j = 0; j < xkbrow->num_keys; j++) {
|
||||||
|
XkbKeyRec *xkbkey;
|
||||||
|
XkbBoundsRec *xkbbounds;
|
||||||
|
|
||||||
|
xkbkey = &xkbrow->keys[j];
|
||||||
|
if (xkbrow->vertical)
|
||||||
|
top += xkbkey->gap;
|
||||||
|
else
|
||||||
|
left += xkbkey->gap;
|
||||||
|
create_key (layout, keyboard, section, j, i, left, top, xkbkey);
|
||||||
|
xkbbounds = &xkbgeometry->shapes[xkbkey->shape_ndx].bounds;
|
||||||
|
if (xkbrow->vertical)
|
||||||
|
top += xkbbounds->y2 - xkbbounds->y1;
|
||||||
|
else
|
||||||
|
left += xkbbounds->x2 - xkbbounds->x1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
create_keyboard (EekXkbLayout *layout, EekKeyboard *keyboard)
|
||||||
|
{
|
||||||
|
EekXkbLayoutPrivate *priv = eek_xkb_layout_get_instance_private (layout);
|
||||||
|
XkbGeometryRec *xkbgeometry;
|
||||||
|
EekBounds bounds;
|
||||||
|
gint i;
|
||||||
|
|
||||||
|
g_return_if_fail (priv->xkb);
|
||||||
|
g_return_if_fail (priv->xkb->geom);
|
||||||
|
|
||||||
|
xkbgeometry = priv->xkb->geom;
|
||||||
|
|
||||||
|
eek_element_get_bounds (EEK_ELEMENT(keyboard), &bounds);
|
||||||
|
setup_scaling (EEK_XKB_LAYOUT(layout), bounds.width, bounds.height);
|
||||||
|
|
||||||
|
bounds.x = bounds.y = 0;
|
||||||
|
bounds.width = xkb_to_pixmap_coord(layout, xkbgeometry->width_mm);
|
||||||
|
bounds.height = xkb_to_pixmap_coord(layout, xkbgeometry->height_mm);
|
||||||
|
|
||||||
|
for (i = 0; i < xkbgeometry->num_sections; i++) {
|
||||||
|
XkbSectionRec *xkbsection;
|
||||||
|
|
||||||
|
xkbsection = &xkbgeometry->sections[i];
|
||||||
|
create_section (layout, keyboard, xkbsection);
|
||||||
|
}
|
||||||
|
eek_element_set_bounds (EEK_ELEMENT(keyboard), &bounds);
|
||||||
|
}
|
||||||
|
|
||||||
|
static EekKeyboard *
|
||||||
|
eek_xkb_layout_real_create_keyboard (EekboardContextService *manager,
|
||||||
|
EekLayout *self,
|
||||||
|
gdouble initial_width,
|
||||||
|
gdouble initial_height)
|
||||||
|
{
|
||||||
|
EekKeyboard *keyboard = g_object_new (EEK_TYPE_KEYBOARD, "layout", self, NULL);
|
||||||
|
keyboard->manager = manager;
|
||||||
|
|
||||||
|
EekBounds bounds = {
|
||||||
|
.x = 0.0,
|
||||||
|
.y = 0.0,
|
||||||
|
.width = initial_width,
|
||||||
|
.height = initial_height
|
||||||
|
};
|
||||||
|
eek_element_set_bounds (EEK_ELEMENT(keyboard), &bounds);
|
||||||
|
|
||||||
|
/* resolve modifiers dynamically assigned at run time */
|
||||||
|
EekXkbLayoutPrivate *priv = eek_xkb_layout_get_instance_private (
|
||||||
|
EEK_XKB_LAYOUT(self));
|
||||||
|
eek_keyboard_set_num_lock_mask (keyboard,
|
||||||
|
XkbKeysymToModifiers (priv->display,
|
||||||
|
XK_Num_Lock));
|
||||||
|
eek_keyboard_set_alt_gr_mask (keyboard,
|
||||||
|
XkbKeysymToModifiers (priv->display,
|
||||||
|
XK_ISO_Level3_Shift));
|
||||||
|
|
||||||
|
if (priv->shape_oref_hash)
|
||||||
|
g_hash_table_destroy (priv->shape_oref_hash);
|
||||||
|
|
||||||
|
priv->shape_oref_hash = g_hash_table_new (g_direct_hash, g_direct_equal);
|
||||||
|
create_keyboard (EEK_XKB_LAYOUT(self), keyboard);
|
||||||
|
g_hash_table_destroy (priv->shape_oref_hash);
|
||||||
|
|
||||||
|
return keyboard;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
eek_xkb_layout_finalize (GObject *object)
|
||||||
|
{
|
||||||
|
EekXkbLayoutPrivate *priv = eek_xkb_layout_get_instance_private (
|
||||||
|
EEK_XKB_LAYOUT (object));
|
||||||
|
|
||||||
|
g_free (priv->names.keycodes);
|
||||||
|
g_free (priv->names.geometry);
|
||||||
|
g_free (priv->names.symbols);
|
||||||
|
XkbFreeKeyboard (priv->xkb, 0, TRUE); /* free_all = TRUE */
|
||||||
|
G_OBJECT_CLASS (eek_xkb_layout_parent_class)->finalize (object);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
eek_xkb_layout_set_property (GObject *object,
|
||||||
|
guint prop_id,
|
||||||
|
const GValue *value,
|
||||||
|
GParamSpec *pspec)
|
||||||
|
{
|
||||||
|
EekXkbLayout *layout = EEK_XKB_LAYOUT (object);
|
||||||
|
EekXkbLayoutPrivate *priv = eek_xkb_layout_get_instance_private (layout);
|
||||||
|
|
||||||
|
switch (prop_id) {
|
||||||
|
case PROP_DISPLAY:
|
||||||
|
priv->display = g_value_get_pointer (value);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
eek_xkb_layout_get_property (GObject *object,
|
||||||
|
guint prop_id,
|
||||||
|
GValue *value,
|
||||||
|
GParamSpec *pspec)
|
||||||
|
{
|
||||||
|
EekXkbLayout *layout = EEK_XKB_LAYOUT (object);
|
||||||
|
EekXkbLayoutPrivate *priv = eek_xkb_layout_get_instance_private (layout);
|
||||||
|
|
||||||
|
switch (prop_id) {
|
||||||
|
case PROP_DISPLAY:
|
||||||
|
g_value_set_pointer (value, priv->display);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
eek_xkb_layout_class_init (EekXkbLayoutClass *klass)
|
||||||
|
{
|
||||||
|
EekLayoutClass *layout_class = EEK_LAYOUT_CLASS (klass);
|
||||||
|
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||||
|
GParamSpec *pspec;
|
||||||
|
|
||||||
|
layout_class->create_keyboard = eek_xkb_layout_real_create_keyboard;
|
||||||
|
|
||||||
|
gobject_class->finalize = eek_xkb_layout_finalize;
|
||||||
|
gobject_class->set_property = eek_xkb_layout_set_property;
|
||||||
|
gobject_class->get_property = eek_xkb_layout_get_property;
|
||||||
|
|
||||||
|
pspec = g_param_spec_pointer ("display",
|
||||||
|
"Display",
|
||||||
|
"X Display",
|
||||||
|
G_PARAM_READWRITE |
|
||||||
|
G_PARAM_CONSTRUCT_ONLY);
|
||||||
|
g_object_class_install_property (gobject_class, PROP_DISPLAY, pspec);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
eek_xkb_layout_init (EekXkbLayout *self)
|
||||||
|
{
|
||||||
|
/* void */
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
get_names_from_server (EekXkbLayout *layout,
|
||||||
|
GError **error)
|
||||||
|
{
|
||||||
|
EekXkbLayoutPrivate *priv = eek_xkb_layout_get_instance_private (layout);
|
||||||
|
gchar *name;
|
||||||
|
|
||||||
|
XkbGetNames (priv->display, XkbAllNamesMask, priv->xkb);
|
||||||
|
|
||||||
|
if (priv->xkb->names->keycodes <= 0)
|
||||||
|
g_warning ("XKB keycodes setting is not loaded properly");
|
||||||
|
else {
|
||||||
|
name = XGetAtomName (priv->display, priv->xkb->names->keycodes);
|
||||||
|
if (!name)
|
||||||
|
g_warning ("Can't get the name of keycodes");
|
||||||
|
else if (!priv->names.keycodes ||
|
||||||
|
g_strcmp0 (name, priv->names.keycodes)) {
|
||||||
|
g_free (priv->names.keycodes);
|
||||||
|
priv->names.keycodes = g_strdup (name);
|
||||||
|
XFree (name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (priv->xkb->names->geometry <= 0)
|
||||||
|
g_warning ("XKB geometry setting is not loaded");
|
||||||
|
else {
|
||||||
|
name = XGetAtomName (priv->display, priv->xkb->names->geometry);
|
||||||
|
if (!name)
|
||||||
|
g_warning ("Can't get the name of geometry");
|
||||||
|
else if (!priv->names.geometry ||
|
||||||
|
g_strcmp0 (name, priv->names.geometry)) {
|
||||||
|
g_free (priv->names.geometry);
|
||||||
|
priv->names.geometry = g_strdup (name);
|
||||||
|
XFree (name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (priv->xkb->names->symbols <= 0)
|
||||||
|
g_warning ("XKB symbols setting is not loaded");
|
||||||
|
else {
|
||||||
|
name = XGetAtomName (priv->display, priv->xkb->names->symbols);
|
||||||
|
if (!name)
|
||||||
|
g_warning ("Can't get the name of symbols");
|
||||||
|
else if (!priv->names.symbols ||
|
||||||
|
g_strcmp0 (name, priv->names.symbols)) {
|
||||||
|
g_free (priv->names.symbols);
|
||||||
|
priv->names.symbols = g_strdup (name);
|
||||||
|
XFree (name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* eek_xkb_layout_new:
|
||||||
|
*
|
||||||
|
* Create a new #EekXkbLayout.
|
||||||
|
*/
|
||||||
|
EekLayout *
|
||||||
|
eek_xkb_layout_new (Display *display,
|
||||||
|
GError **error)
|
||||||
|
{
|
||||||
|
return (EekLayout *) g_initable_new (EEK_TYPE_XKB_LAYOUT,
|
||||||
|
NULL,
|
||||||
|
error,
|
||||||
|
"display", display,
|
||||||
|
NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* eek_xkb_layout_set_names: (skip)
|
||||||
|
* @layout: an #EekXkbLayout
|
||||||
|
* @names: XKB component names
|
||||||
|
* @error: a #GError
|
||||||
|
*
|
||||||
|
* Set the XKB component names to @layout.
|
||||||
|
* Returns: %TRUE if the component names are successfully set, %FALSE otherwise
|
||||||
|
*/
|
||||||
|
gboolean
|
||||||
|
eek_xkb_layout_set_names (EekXkbLayout *layout,
|
||||||
|
XkbComponentNamesRec *names,
|
||||||
|
GError **error)
|
||||||
|
{
|
||||||
|
EekXkbLayoutPrivate *priv = eek_xkb_layout_get_instance_private (layout);
|
||||||
|
|
||||||
|
if (g_strcmp0 (names->keycodes, priv->names.keycodes)) {
|
||||||
|
g_free (priv->names.keycodes);
|
||||||
|
priv->names.keycodes = g_strdup (names->keycodes);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (g_strcmp0 (names->geometry, priv->names.geometry)) {
|
||||||
|
g_free (priv->names.geometry);
|
||||||
|
priv->names.geometry = g_strdup (names->geometry);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (g_strcmp0 (names->symbols, priv->names.symbols)) {
|
||||||
|
g_free (priv->names.symbols);
|
||||||
|
priv->names.symbols = g_strdup (names->symbols);
|
||||||
|
}
|
||||||
|
|
||||||
|
return get_keyboard_from_server (layout, error);
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
get_keyboard_from_server (EekXkbLayout *layout,
|
||||||
|
GError **error)
|
||||||
|
{
|
||||||
|
EekXkbLayoutPrivate *priv = eek_xkb_layout_get_instance_private (layout);
|
||||||
|
|
||||||
|
if (priv->xkb) {
|
||||||
|
XkbFreeKeyboard (priv->xkb, 0, True);
|
||||||
|
priv->xkb = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (priv->names.keycodes && priv->names.geometry && priv->names.symbols) {
|
||||||
|
priv->xkb = XkbGetKeyboardByName (priv->display,
|
||||||
|
XkbUseCoreKbd,
|
||||||
|
&priv->names,
|
||||||
|
0,
|
||||||
|
XKB_COMPONENT_MASK,
|
||||||
|
False);
|
||||||
|
} else {
|
||||||
|
priv->xkb = XkbGetKeyboard (priv->display,
|
||||||
|
XKB_COMPONENT_MASK,
|
||||||
|
XkbUseCoreKbd);
|
||||||
|
if (!get_names_from_server (layout, error)) {
|
||||||
|
XkbFreeKeyboard (priv->xkb, 0, True);
|
||||||
|
priv->xkb = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (priv->xkb == NULL) {
|
||||||
|
g_set_error (error,
|
||||||
|
EEK_ERROR,
|
||||||
|
EEK_ERROR_LAYOUT_ERROR,
|
||||||
|
"can't get keyboard from server");
|
||||||
|
g_free (priv->names.keycodes);
|
||||||
|
priv->names.keycodes = NULL;
|
||||||
|
g_free (priv->names.geometry);
|
||||||
|
priv->names.geometry = NULL;
|
||||||
|
g_free (priv->names.symbols);
|
||||||
|
priv->names.symbols = NULL;
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static guint
|
||||||
|
find_keycode (EekXkbLayout *layout, gchar *key_name)
|
||||||
|
{
|
||||||
|
#define KEYSYM_NAME_MAX_LENGTH 4
|
||||||
|
guint keycode;
|
||||||
|
gint i, j;
|
||||||
|
XkbKeyNamePtr pkey;
|
||||||
|
XkbKeyAliasPtr palias;
|
||||||
|
guint is_name_matched;
|
||||||
|
gchar *src, *dst;
|
||||||
|
EekXkbLayoutPrivate *priv = eek_xkb_layout_get_instance_private (layout);
|
||||||
|
|
||||||
|
if (!priv->xkb)
|
||||||
|
return EEK_INVALID_KEYCODE;
|
||||||
|
|
||||||
|
pkey = priv->xkb->names->keys + priv->xkb->min_key_code;
|
||||||
|
for (keycode = priv->xkb->min_key_code;
|
||||||
|
keycode <= priv->xkb->max_key_code; keycode++) {
|
||||||
|
is_name_matched = 1;
|
||||||
|
src = key_name;
|
||||||
|
dst = pkey->name;
|
||||||
|
for (i = KEYSYM_NAME_MAX_LENGTH; --i >= 0;) {
|
||||||
|
if ('\0' == *src)
|
||||||
|
break;
|
||||||
|
if (*src++ != *dst++) {
|
||||||
|
is_name_matched = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (is_name_matched)
|
||||||
|
return keycode;
|
||||||
|
pkey++;
|
||||||
|
}
|
||||||
|
|
||||||
|
palias = priv->xkb->names->key_aliases;
|
||||||
|
for (j = priv->xkb->names->num_key_aliases; --j >= 0;) {
|
||||||
|
is_name_matched = 1;
|
||||||
|
src = key_name;
|
||||||
|
dst = palias->alias;
|
||||||
|
for (i = KEYSYM_NAME_MAX_LENGTH; --i >= 0;) {
|
||||||
|
if ('\0' == *src)
|
||||||
|
break;
|
||||||
|
if (*src++ != *dst++) {
|
||||||
|
is_name_matched = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_name_matched) {
|
||||||
|
keycode = find_keycode (layout, palias->real);
|
||||||
|
return keycode;
|
||||||
|
}
|
||||||
|
palias++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return EEK_INVALID_KEYCODE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
setup_scaling (EekXkbLayout *layout,
|
||||||
|
gdouble width,
|
||||||
|
gdouble height)
|
||||||
|
{
|
||||||
|
EekXkbLayoutPrivate *priv = eek_xkb_layout_get_instance_private (layout);
|
||||||
|
|
||||||
|
g_return_if_fail (priv->xkb);
|
||||||
|
|
||||||
|
g_return_if_fail (priv->xkb->geom->width_mm > 0);
|
||||||
|
g_return_if_fail (priv->xkb->geom->height_mm > 0);
|
||||||
|
|
||||||
|
if (width * priv->xkb->geom->height_mm <
|
||||||
|
height * priv->xkb->geom->width_mm) {
|
||||||
|
priv->scale_numerator = width;
|
||||||
|
priv->scale_denominator = priv->xkb->geom->width_mm;
|
||||||
|
} else {
|
||||||
|
priv->scale_numerator = height;
|
||||||
|
priv->scale_denominator = priv->xkb->geom->height_mm;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
initable_init (GInitable *initable,
|
||||||
|
GCancellable *cancellable,
|
||||||
|
GError **error)
|
||||||
|
{
|
||||||
|
EekXkbLayout *layout = EEK_XKB_LAYOUT (initable);
|
||||||
|
|
||||||
|
if (!get_keyboard_from_server (layout, error))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
if (!get_names_from_server (layout, error))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
initable_iface_init (GInitableIface *initable_iface)
|
||||||
|
{
|
||||||
|
initable_iface->init = initable_init;
|
||||||
|
}
|
||||||
55
eek/eek-xkb-layout.h
Normal file
55
eek/eek-xkb-layout.h
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2010-2011 Daiki Ueno <ueno@unixuser.org>
|
||||||
|
* Copyright (C) 2010-2011 Red Hat, Inc.
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2 of
|
||||||
|
* the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library 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
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||||
|
* 02110-1301 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if !defined(__EEK_H_INSIDE__) && !defined(EEK_COMPILATION)
|
||||||
|
#error "Only <eek/eek-xkb.h> can be included directly."
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef EEK_XKB_LAYOUT_H
|
||||||
|
#define EEK_XKB_LAYOUT_H 1
|
||||||
|
|
||||||
|
#include <X11/XKBlib.h>
|
||||||
|
#include "eek-layout.h"
|
||||||
|
|
||||||
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
#define EEK_TYPE_XKB_LAYOUT (eek_xkb_layout_get_type())
|
||||||
|
G_DECLARE_DERIVABLE_TYPE (EekXkbLayout, eek_xkb_layout, EEK, XKB_LAYOUT, EekLayout)
|
||||||
|
|
||||||
|
struct _EekXkbLayoutClass
|
||||||
|
{
|
||||||
|
/*< private >*/
|
||||||
|
EekLayoutClass parent_class;
|
||||||
|
|
||||||
|
/*< private >*/
|
||||||
|
/* padding */
|
||||||
|
gpointer pdummy[24];
|
||||||
|
};
|
||||||
|
|
||||||
|
GType eek_xkb_layout_get_type (void) G_GNUC_CONST;
|
||||||
|
EekLayout *eek_xkb_layout_new (Display *display,
|
||||||
|
GError **error);
|
||||||
|
|
||||||
|
gboolean eek_xkb_layout_set_names (EekXkbLayout *layout,
|
||||||
|
XkbComponentNamesRec *names,
|
||||||
|
GError **error);
|
||||||
|
|
||||||
|
G_END_DECLS
|
||||||
|
#endif /* #ifndef EEK_XKB_LAYOUT_H */
|
||||||
26
eek/eek-xkb.h
Normal file
26
eek/eek-xkb.h
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2010-2011 Daiki Ueno <ueno@unixuser.org>
|
||||||
|
* Copyright (C) 2010-2011 Red Hat, Inc.
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2 of
|
||||||
|
* the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library 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
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||||
|
* 02110-1301 USA
|
||||||
|
*/
|
||||||
|
#ifndef EEK_XKB_H
|
||||||
|
#define EEK_XKB_H 1
|
||||||
|
|
||||||
|
#include "eek.h"
|
||||||
|
#include "eek-xkb-layout.h"
|
||||||
|
|
||||||
|
#endif /* EEK_XKB_H */
|
||||||
30
eek/eek-xkl-0.90.pc.in
Normal file
30
eek/eek-xkl-0.90.pc.in
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
# Copyright (C) 2010-2011 Daiki Ueno <ueno@unixuser.org>
|
||||||
|
# Copyright (C) 2010-2011 Red Hat, Inc.
|
||||||
|
|
||||||
|
# This library is free software; you can redistribute it and/or
|
||||||
|
# modify it under the terms of the GNU Lesser General Public License
|
||||||
|
# as published by the Free Software Foundation; either version 2 of
|
||||||
|
# the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
# This library 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
|
||||||
|
# Lesser General Public License for more details.
|
||||||
|
|
||||||
|
# You should have received a copy of the GNU Lesser General Public
|
||||||
|
# License along with this library; if not, write to the Free Software
|
||||||
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||||
|
# 02110-1301 USA
|
||||||
|
|
||||||
|
prefix=@prefix@
|
||||||
|
exec_prefix=@exec_prefix@
|
||||||
|
libdir=@libdir@
|
||||||
|
includedir=@includedir@
|
||||||
|
|
||||||
|
Name: libeek-xkl
|
||||||
|
Description: A Library to Create Keyboard-like UI (Libxklavier Support)
|
||||||
|
URL: http://fedorahosted.org/eekboard/
|
||||||
|
Version: @VERSION@
|
||||||
|
Requires: eek-@EEK_API_VERSION@ libxklavier
|
||||||
|
Libs: -L${libdir} -leek-xkl
|
||||||
|
Cflags: -I${includedir}/eek-@EEK_API_VERSION@
|
||||||
662
eek/eek-xkl-layout.c
Normal file
662
eek/eek-xkl-layout.c
Normal file
@ -0,0 +1,662 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2010-2011 Daiki Ueno <ueno@unixuser.org>
|
||||||
|
* Copyright (C) 2010-2011 Red Hat, Inc.
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2 of
|
||||||
|
* the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library 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
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||||
|
* 02110-1301 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SECTION:eek-xkl-layout
|
||||||
|
* @short_description: Layout engine using Libxklavier configuration
|
||||||
|
*
|
||||||
|
* The #EekXklLayout is a simple wrapper around #EekXkbLayout class
|
||||||
|
* to use Libxklavier configuration.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "config.h"
|
||||||
|
#endif /* HAVE_CONFIG_H */
|
||||||
|
|
||||||
|
#include <libxklavier/xklavier.h>
|
||||||
|
#include <gio/gio.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "eek-xkl-layout.h"
|
||||||
|
|
||||||
|
#define noKBDRAW_DEBUG
|
||||||
|
|
||||||
|
static GInitableIface *parent_initable_iface;
|
||||||
|
|
||||||
|
static void initable_iface_init (GInitableIface *initable_iface);
|
||||||
|
|
||||||
|
enum {
|
||||||
|
PROP_0,
|
||||||
|
PROP_MODEL,
|
||||||
|
PROP_LAYOUTS,
|
||||||
|
PROP_VARIANTS,
|
||||||
|
PROP_OPTIONS,
|
||||||
|
PROP_LAST
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct _EekXklLayoutPrivate
|
||||||
|
{
|
||||||
|
XklEngine *engine;
|
||||||
|
XklConfigRec *config;
|
||||||
|
} EekXklLayoutPrivate;
|
||||||
|
|
||||||
|
G_DEFINE_TYPE_EXTENDED (EekXklLayout, eek_xkl_layout, EEK_TYPE_XKB_LAYOUT,
|
||||||
|
0, /* GTypeFlags */
|
||||||
|
G_ADD_PRIVATE (EekXklLayout)
|
||||||
|
G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE,
|
||||||
|
initable_iface_init))
|
||||||
|
|
||||||
|
/* from gnome-keyboard-properties-xkbpv.c:
|
||||||
|
* 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);
|
||||||
|
|
||||||
|
static gboolean set_xkb_component_names (EekXklLayout *layout,
|
||||||
|
XklConfigRec *config);
|
||||||
|
|
||||||
|
static void
|
||||||
|
eek_xkl_layout_dispose (GObject *object)
|
||||||
|
{
|
||||||
|
EekXklLayoutPrivate *priv = eek_xkl_layout_get_instance_private (
|
||||||
|
EEK_XKL_LAYOUT (object));
|
||||||
|
|
||||||
|
if (priv->config) {
|
||||||
|
g_object_unref (priv->config);
|
||||||
|
priv->config = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
G_OBJECT_CLASS (eek_xkl_layout_parent_class)->dispose (object);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
eek_xkl_layout_set_property (GObject *object,
|
||||||
|
guint prop_id,
|
||||||
|
const GValue *value,
|
||||||
|
GParamSpec *pspec)
|
||||||
|
{
|
||||||
|
EekXklLayout *layout = EEK_XKL_LAYOUT(object);
|
||||||
|
|
||||||
|
switch (prop_id) {
|
||||||
|
case PROP_MODEL:
|
||||||
|
eek_xkl_layout_set_model (layout, g_value_get_string (value));
|
||||||
|
break;
|
||||||
|
case PROP_LAYOUTS:
|
||||||
|
eek_xkl_layout_set_layouts (layout, g_value_get_boxed (value));
|
||||||
|
break;
|
||||||
|
case PROP_VARIANTS:
|
||||||
|
eek_xkl_layout_set_variants (layout, g_value_get_boxed (value));
|
||||||
|
break;
|
||||||
|
case PROP_OPTIONS:
|
||||||
|
eek_xkl_layout_set_options (layout, g_value_get_boxed (value));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
eek_xkl_layout_get_property (GObject *object,
|
||||||
|
guint prop_id,
|
||||||
|
GValue *value,
|
||||||
|
GParamSpec *pspec)
|
||||||
|
{
|
||||||
|
EekXklLayout *layout = EEK_XKL_LAYOUT(object);
|
||||||
|
|
||||||
|
switch (prop_id) {
|
||||||
|
case PROP_MODEL:
|
||||||
|
g_value_set_string (value,
|
||||||
|
eek_xkl_layout_get_model (layout));
|
||||||
|
break;
|
||||||
|
case PROP_LAYOUTS:
|
||||||
|
g_value_set_boxed (value,
|
||||||
|
eek_xkl_layout_get_layouts (layout));
|
||||||
|
break;
|
||||||
|
case PROP_VARIANTS:
|
||||||
|
g_value_set_boxed (value,
|
||||||
|
eek_xkl_layout_get_variants (layout));
|
||||||
|
break;
|
||||||
|
case PROP_OPTIONS:
|
||||||
|
g_value_set_boxed (value,
|
||||||
|
eek_xkl_layout_get_options (layout));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
eek_xkl_layout_class_init (EekXklLayoutClass *klass)
|
||||||
|
{
|
||||||
|
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||||
|
GParamSpec *pspec;
|
||||||
|
|
||||||
|
gobject_class->dispose = eek_xkl_layout_dispose;
|
||||||
|
gobject_class->set_property = eek_xkl_layout_set_property;
|
||||||
|
gobject_class->get_property = eek_xkl_layout_get_property;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* EekXklLayout:model:
|
||||||
|
*
|
||||||
|
* The libxklavier model name of #EekXklLayout.
|
||||||
|
*/
|
||||||
|
pspec = g_param_spec_string ("model",
|
||||||
|
"Model",
|
||||||
|
"Libxklavier model",
|
||||||
|
NULL,
|
||||||
|
G_PARAM_READWRITE);
|
||||||
|
g_object_class_install_property (gobject_class, PROP_MODEL, pspec);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* EekXklLayout:layouts:
|
||||||
|
*
|
||||||
|
* The libxklavier layout names of #EekXklLayout.
|
||||||
|
*/
|
||||||
|
pspec = g_param_spec_boxed ("layouts",
|
||||||
|
"Layouts",
|
||||||
|
"Libxklavier layouts",
|
||||||
|
G_TYPE_STRV,
|
||||||
|
G_PARAM_READWRITE);
|
||||||
|
g_object_class_install_property (gobject_class, PROP_LAYOUTS, pspec);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* EekXklLayout:variants:
|
||||||
|
*
|
||||||
|
* The libxklavier variant names of #EekXklLayout.
|
||||||
|
*/
|
||||||
|
pspec = g_param_spec_boxed ("variants",
|
||||||
|
"Variants",
|
||||||
|
"Libxklavier variants",
|
||||||
|
G_TYPE_STRV,
|
||||||
|
G_PARAM_READWRITE);
|
||||||
|
g_object_class_install_property (gobject_class, PROP_VARIANTS, pspec);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* EekXklLayout:options:
|
||||||
|
*
|
||||||
|
* The libxklavier option names of #EekXklLayout.
|
||||||
|
*/
|
||||||
|
pspec = g_param_spec_boxed ("options",
|
||||||
|
"Options",
|
||||||
|
"Libxklavier options",
|
||||||
|
G_TYPE_STRV,
|
||||||
|
G_PARAM_READWRITE);
|
||||||
|
g_object_class_install_property (gobject_class, PROP_OPTIONS, pspec);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
eek_xkl_layout_init (EekXklLayout *self)
|
||||||
|
{
|
||||||
|
/* void */
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* eek_xkl_layout_new:
|
||||||
|
*
|
||||||
|
* Create a new #EekXklLayout.
|
||||||
|
*/
|
||||||
|
EekLayout *
|
||||||
|
eek_xkl_layout_new (Display *display, GError **error)
|
||||||
|
{
|
||||||
|
return (EekLayout *) g_initable_new (EEK_TYPE_XKL_LAYOUT,
|
||||||
|
NULL,
|
||||||
|
error,
|
||||||
|
"display", display,
|
||||||
|
NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
G_INLINE_FUNC void
|
||||||
|
merge_xkl_config_rec (XklConfigRec *dst, XklConfigRec *src)
|
||||||
|
{
|
||||||
|
if (src->model) {
|
||||||
|
g_free (dst->model);
|
||||||
|
dst->model = g_strdup (src->model);
|
||||||
|
}
|
||||||
|
if (src->layouts) {
|
||||||
|
g_strfreev (dst->layouts);
|
||||||
|
dst->layouts = g_strdupv (src->layouts);
|
||||||
|
}
|
||||||
|
if (src->variants) {
|
||||||
|
g_strfreev (dst->variants);
|
||||||
|
dst->variants = g_strdupv (src->variants);
|
||||||
|
}
|
||||||
|
if (src->options) {
|
||||||
|
g_strfreev (dst->options);
|
||||||
|
dst->options = g_strdupv (src->options);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* eek_xkl_layout_set_config: (skip)
|
||||||
|
* @layout: an #EekXklLayout
|
||||||
|
* @config: Libxklavier configuration
|
||||||
|
*
|
||||||
|
* Reconfigure @layout with @config.
|
||||||
|
* Returns: %TRUE if the current layout changed, %FALSE otherwise
|
||||||
|
*/
|
||||||
|
gboolean
|
||||||
|
eek_xkl_layout_set_config (EekXklLayout *layout,
|
||||||
|
XklConfigRec *config)
|
||||||
|
{
|
||||||
|
EekXklLayoutPrivate *priv = eek_xkl_layout_get_instance_private (layout);
|
||||||
|
XklConfigRec *c;
|
||||||
|
gboolean retval;
|
||||||
|
|
||||||
|
g_return_val_if_fail (priv, FALSE);
|
||||||
|
c = xkl_config_rec_new ();
|
||||||
|
merge_xkl_config_rec (c, priv->config);
|
||||||
|
merge_xkl_config_rec (c, config);
|
||||||
|
retval = set_xkb_component_names (layout, c);
|
||||||
|
g_object_unref (c);
|
||||||
|
merge_xkl_config_rec (priv->config, config);
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* eek_xkl_layout_set_config_full:
|
||||||
|
* @layout: an #EekXklLayout
|
||||||
|
* @model: Libxklavier model name
|
||||||
|
* @layouts: Libxklavier layouts
|
||||||
|
* @variants: Libxklavier variants
|
||||||
|
* @options: Libxklavier options
|
||||||
|
*
|
||||||
|
* Reconfigure @layout with @model, @layouts, @variants, and @options.
|
||||||
|
* This function is merely a wrapper around
|
||||||
|
* eek_xkl_layout_set_config() to avoid passing a pointer of
|
||||||
|
* XklConfigRec, which is not currently available in the
|
||||||
|
* gobject-introspection repository.
|
||||||
|
*
|
||||||
|
* Returns: %TRUE if the current layout changed, %FALSE otherwise
|
||||||
|
* Since: 0.0.2
|
||||||
|
*/
|
||||||
|
gboolean
|
||||||
|
eek_xkl_layout_set_config_full (EekXklLayout *layout,
|
||||||
|
gchar *model,
|
||||||
|
gchar **layouts,
|
||||||
|
gchar **variants,
|
||||||
|
gchar **options)
|
||||||
|
{
|
||||||
|
XklConfigRec *config;
|
||||||
|
gboolean retval;
|
||||||
|
|
||||||
|
config = xkl_config_rec_new ();
|
||||||
|
config->model = g_strdup (model);
|
||||||
|
config->layouts = g_strdupv (layouts);
|
||||||
|
config->variants = g_strdupv (variants);
|
||||||
|
config->options = g_strdupv (options);
|
||||||
|
retval = eek_xkl_layout_set_config (layout, config);
|
||||||
|
g_object_unref (config);
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* eek_xkl_layout_set_model:
|
||||||
|
* @layout: an #EekXklLayout
|
||||||
|
* @model: model name
|
||||||
|
*
|
||||||
|
* Set the model name of @layout configuration (in the Libxklavier terminology).
|
||||||
|
* Returns: %TRUE if the current layout changed, %FALSE otherwise
|
||||||
|
*/
|
||||||
|
gboolean
|
||||||
|
eek_xkl_layout_set_model (EekXklLayout *layout,
|
||||||
|
const gchar *model)
|
||||||
|
{
|
||||||
|
EekXklLayoutPrivate *priv = eek_xkl_layout_get_instance_private (layout);
|
||||||
|
XklConfigRec *config;
|
||||||
|
gboolean retval;
|
||||||
|
|
||||||
|
g_return_val_if_fail (priv, FALSE);
|
||||||
|
config = xkl_config_rec_new ();
|
||||||
|
/* config->model will be freed on g_object_unref (config) */
|
||||||
|
if (model)
|
||||||
|
config->model = g_strdup (model);
|
||||||
|
else
|
||||||
|
config->model = NULL;
|
||||||
|
retval = eek_xkl_layout_set_config (layout, config);
|
||||||
|
g_object_unref (config);
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* eek_xkl_layout_set_layouts:
|
||||||
|
* @layout: an #EekXklLayout
|
||||||
|
* @layouts: layout names
|
||||||
|
*
|
||||||
|
* Set the layout names of @layout (in the Libxklavier terminology).
|
||||||
|
* Returns: %TRUE if the current layout changed, %FALSE otherwise
|
||||||
|
*/
|
||||||
|
gboolean
|
||||||
|
eek_xkl_layout_set_layouts (EekXklLayout *layout,
|
||||||
|
gchar **layouts)
|
||||||
|
{
|
||||||
|
EekXklLayoutPrivate *priv = eek_xkl_layout_get_instance_private (layout);
|
||||||
|
XklConfigRec *config;
|
||||||
|
gboolean retval;
|
||||||
|
|
||||||
|
g_return_val_if_fail (priv, FALSE);
|
||||||
|
config = xkl_config_rec_new ();
|
||||||
|
/* config->layouts will be freed on g_object_unref (config) */
|
||||||
|
if (layouts)
|
||||||
|
config->layouts = g_strdupv (layouts);
|
||||||
|
else
|
||||||
|
config->layouts = layouts;
|
||||||
|
retval = eek_xkl_layout_set_config (layout, config);
|
||||||
|
g_object_unref (config);
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* eek_xkl_layout_set_variants:
|
||||||
|
* @layout: an #EekXklLayout
|
||||||
|
* @variants: variant names
|
||||||
|
*
|
||||||
|
* Set the variant names of @layout (in the Libxklavier terminology).
|
||||||
|
* Returns: %TRUE if the current layout changed, %FALSE otherwise
|
||||||
|
*/
|
||||||
|
gboolean
|
||||||
|
eek_xkl_layout_set_variants (EekXklLayout *layout,
|
||||||
|
gchar **variants)
|
||||||
|
{
|
||||||
|
EekXklLayoutPrivate *priv = eek_xkl_layout_get_instance_private (layout);
|
||||||
|
XklConfigRec *config;
|
||||||
|
gboolean retval;
|
||||||
|
|
||||||
|
g_return_val_if_fail (priv, FALSE);
|
||||||
|
config = xkl_config_rec_new ();
|
||||||
|
/* config->variants will be freed on g_object_unref (config) */
|
||||||
|
if (variants)
|
||||||
|
config->variants = g_strdupv (variants);
|
||||||
|
else
|
||||||
|
config->variants = NULL;
|
||||||
|
retval = eek_xkl_layout_set_config (layout, config);
|
||||||
|
g_object_unref (config);
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* eek_xkl_layout_set_options:
|
||||||
|
* @layout: an #EekXklLayout
|
||||||
|
* @options: option names
|
||||||
|
*
|
||||||
|
* Set the option names of @layout (in the Libxklavier terminology).
|
||||||
|
* Returns: %TRUE if the current layout changed, %FALSE otherwise
|
||||||
|
*/
|
||||||
|
gboolean
|
||||||
|
eek_xkl_layout_set_options (EekXklLayout *layout,
|
||||||
|
gchar **options)
|
||||||
|
{
|
||||||
|
EekXklLayoutPrivate *priv = eek_xkl_layout_get_instance_private (layout);
|
||||||
|
XklConfigRec *config;
|
||||||
|
gboolean retval;
|
||||||
|
|
||||||
|
g_return_val_if_fail (priv, FALSE);
|
||||||
|
config = xkl_config_rec_new ();
|
||||||
|
/* config->options will be freed on g_object_unref (config) */
|
||||||
|
if (options)
|
||||||
|
config->options = options;
|
||||||
|
else
|
||||||
|
config->options = NULL;
|
||||||
|
retval = eek_xkl_layout_set_config (layout, config);
|
||||||
|
g_object_unref (config);
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* eek_xkl_layout_enable_option:
|
||||||
|
* @layout: an #EekXklLayout
|
||||||
|
* @option: option name
|
||||||
|
*
|
||||||
|
* Set the option of @layout (in the Libxklavier terminology).
|
||||||
|
* Returns: %TRUE if the current layout changed, %FALSE otherwise
|
||||||
|
*/
|
||||||
|
gboolean
|
||||||
|
eek_xkl_layout_enable_option (EekXklLayout *layout,
|
||||||
|
const gchar *option)
|
||||||
|
{
|
||||||
|
gchar **options, **_options;
|
||||||
|
gint i, j;
|
||||||
|
|
||||||
|
options = eek_xkl_layout_get_options (layout);
|
||||||
|
for (i = 0; options && options[i]; i++)
|
||||||
|
if (g_strcmp0 (options[i], option) == 0)
|
||||||
|
return TRUE;
|
||||||
|
_options = g_new0 (gchar *, (i + 2));
|
||||||
|
for (j = 0; j < i; j++)
|
||||||
|
_options[j] = g_strdup (options[j]);
|
||||||
|
_options[i] = g_strdup (option);
|
||||||
|
/* eek_xkl_layout_set_options() will free _options and its elements. */
|
||||||
|
return eek_xkl_layout_set_options (layout, _options);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* eek_xkl_layout_disable_option:
|
||||||
|
* @layout: an #EekXklLayout
|
||||||
|
* @option: option name
|
||||||
|
*
|
||||||
|
* Unset the option of @layout (in the Libxklavier terminology).
|
||||||
|
* Returns: %TRUE if the current layout changed, %FALSE otherwise
|
||||||
|
*/
|
||||||
|
gboolean
|
||||||
|
eek_xkl_layout_disable_option (EekXklLayout *layout,
|
||||||
|
const gchar *option)
|
||||||
|
{
|
||||||
|
gchar **options, **_options;
|
||||||
|
gint i, j, k;
|
||||||
|
|
||||||
|
options = eek_xkl_layout_get_options (layout);
|
||||||
|
if (!options)
|
||||||
|
return TRUE;
|
||||||
|
for (i = 0, k = 0; options[i]; i++)
|
||||||
|
if (g_strcmp0 (options[i], option) == 0)
|
||||||
|
k = i;
|
||||||
|
if (options[k] == NULL)
|
||||||
|
return TRUE;
|
||||||
|
_options = g_new0 (gchar *, i);
|
||||||
|
for (j = 0; j < k; j++)
|
||||||
|
_options[j] = g_strdup (options[j]);
|
||||||
|
for (j = k + 1; j < i; j++)
|
||||||
|
_options[j] = g_strdup (options[j]);
|
||||||
|
/* eek_xkl_layout_set_options() will free _options and its elements. */
|
||||||
|
return eek_xkl_layout_set_options (layout, _options);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* eek_xkl_layout_get_model:
|
||||||
|
* @layout: an #EekXklLayout
|
||||||
|
*
|
||||||
|
* Get the model name of @layout configuration (in the Libxklavier terminology).
|
||||||
|
*/
|
||||||
|
gchar *
|
||||||
|
eek_xkl_layout_get_model (EekXklLayout *layout)
|
||||||
|
{
|
||||||
|
EekXklLayoutPrivate *priv = eek_xkl_layout_get_instance_private (layout);
|
||||||
|
|
||||||
|
g_return_val_if_fail (priv, NULL);
|
||||||
|
return g_strdup (priv->config->model);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* eek_xkl_layout_get_layouts:
|
||||||
|
* @layout: an #EekXklLayout
|
||||||
|
*
|
||||||
|
* Get the layout names of @layout configuration (in the Libxklavier
|
||||||
|
* terminology).
|
||||||
|
*/
|
||||||
|
gchar **
|
||||||
|
eek_xkl_layout_get_layouts (EekXklLayout *layout)
|
||||||
|
{
|
||||||
|
EekXklLayoutPrivate *priv = eek_xkl_layout_get_instance_private (layout);
|
||||||
|
|
||||||
|
g_return_val_if_fail (priv, NULL);
|
||||||
|
return g_strdupv (priv->config->layouts);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* eek_xkl_layout_get_variants:
|
||||||
|
* @layout: an #EekXklLayout
|
||||||
|
*
|
||||||
|
* Get the variant names of @layout configuration (in the Libxklavier
|
||||||
|
* terminology).
|
||||||
|
*/
|
||||||
|
gchar **
|
||||||
|
eek_xkl_layout_get_variants (EekXklLayout *layout)
|
||||||
|
{
|
||||||
|
EekXklLayoutPrivate *priv = eek_xkl_layout_get_instance_private (layout);
|
||||||
|
|
||||||
|
g_return_val_if_fail (priv, NULL);
|
||||||
|
return g_strdupv (priv->config->variants);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* eek_xkl_layout_get_options:
|
||||||
|
* @layout: an #EekXklLayout
|
||||||
|
*
|
||||||
|
* Get the option names of @layout configuration (in the Libxklavier
|
||||||
|
* terminology).
|
||||||
|
*/
|
||||||
|
gchar **
|
||||||
|
eek_xkl_layout_get_options (EekXklLayout *layout)
|
||||||
|
{
|
||||||
|
EekXklLayoutPrivate *priv = eek_xkl_layout_get_instance_private (layout);
|
||||||
|
|
||||||
|
g_return_val_if_fail (priv, NULL);
|
||||||
|
return g_strdupv (priv->config->options);
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
set_xkb_component_names (EekXklLayout *layout, XklConfigRec *config)
|
||||||
|
{
|
||||||
|
EekXklLayoutPrivate *priv = eek_xkl_layout_get_instance_private (layout);
|
||||||
|
XkbComponentNamesRec names;
|
||||||
|
gboolean retval = FALSE;
|
||||||
|
|
||||||
|
#if DEBUG
|
||||||
|
if (config->layouts) {
|
||||||
|
gint i;
|
||||||
|
|
||||||
|
fprintf (stderr, "layout = ");
|
||||||
|
for (i = 0; config->layouts[i] != NULL; i++)
|
||||||
|
fprintf (stderr, "\"%s\" ", config->layouts[i]);
|
||||||
|
fputc ('\n', stderr);
|
||||||
|
} else
|
||||||
|
fprintf (stderr, "layouts = NULL\n");
|
||||||
|
if (config->variants) {
|
||||||
|
gint i;
|
||||||
|
|
||||||
|
fprintf (stderr, "variant = ");
|
||||||
|
for (i = 0; config->variants[i]; i++)
|
||||||
|
fprintf (stderr, "\"%s\" ", config->variants[i]);
|
||||||
|
fputc ('\n', stderr);
|
||||||
|
} else
|
||||||
|
fprintf (stderr, "variants = NULL\n");
|
||||||
|
if (config->options) {
|
||||||
|
gint i;
|
||||||
|
|
||||||
|
fprintf (stderr, "option = ");
|
||||||
|
for (i = 0; config->options[i]; i++)
|
||||||
|
fprintf (stderr, "\"%s\" ", config->options[i]);
|
||||||
|
fputc ('\n', stderr);
|
||||||
|
} else
|
||||||
|
fprintf (stderr, "options = NULL\n");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (xkl_xkb_config_native_prepare (priv->engine, config, &names)) {
|
||||||
|
GError *error = NULL;
|
||||||
|
retval = eek_xkb_layout_set_names (EEK_XKB_LAYOUT(layout),
|
||||||
|
&names,
|
||||||
|
&error);
|
||||||
|
if (!retval)
|
||||||
|
g_warning ("can't set XKB layout");
|
||||||
|
xkl_xkb_config_native_cleanup (priv->engine, &names);
|
||||||
|
}
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* eek_xkl_layout_get_option:
|
||||||
|
* @layout: an #EekXklLayout
|
||||||
|
* @option: option name
|
||||||
|
*
|
||||||
|
* Tell if the option of @layout (in the Libxklavier terminology) is set.
|
||||||
|
* Returns: %TRUE if the option is set, %FALSE otherwise
|
||||||
|
*/
|
||||||
|
gboolean
|
||||||
|
eek_xkl_layout_get_option (EekXklLayout *layout,
|
||||||
|
const gchar *option)
|
||||||
|
{
|
||||||
|
gchar **options;
|
||||||
|
gint i;
|
||||||
|
|
||||||
|
options = eek_xkl_layout_get_options (layout);
|
||||||
|
for (i = 0; options && options[i]; i++)
|
||||||
|
if (g_strcmp0 (options[i], option) == 0)
|
||||||
|
return TRUE;
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
initable_init (GInitable *initable,
|
||||||
|
GCancellable *cancellable,
|
||||||
|
GError **error)
|
||||||
|
{
|
||||||
|
EekXklLayout *layout = EEK_XKL_LAYOUT (initable);
|
||||||
|
EekXklLayoutPrivate *priv = eek_xkl_layout_get_instance_private (layout);
|
||||||
|
Display *display;
|
||||||
|
|
||||||
|
if (!parent_initable_iface->init (initable, cancellable, error))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
priv->config = xkl_config_rec_new ();
|
||||||
|
|
||||||
|
g_object_get (G_OBJECT (initable),
|
||||||
|
"display", &display,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
priv->engine = xkl_engine_get_instance (display);
|
||||||
|
|
||||||
|
if (!xkl_config_rec_get_from_server (priv->config,
|
||||||
|
priv->engine)) {
|
||||||
|
g_set_error (error,
|
||||||
|
EEK_ERROR,
|
||||||
|
EEK_ERROR_LAYOUT_ERROR,
|
||||||
|
"can't load libxklavier configuration");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
set_xkb_component_names (layout, priv->config);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
initable_iface_init (GInitableIface *initable_iface)
|
||||||
|
{
|
||||||
|
parent_initable_iface = g_type_interface_peek_parent (initable_iface);
|
||||||
|
initable_iface->init = initable_init;
|
||||||
|
}
|
||||||
|
|
||||||
81
eek/eek-xkl-layout.h
Normal file
81
eek/eek-xkl-layout.h
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2010-2011 Daiki Ueno <ueno@unixuser.org>
|
||||||
|
* Copyright (C) 2010-2011 Red Hat, Inc.
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2 of
|
||||||
|
* the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library 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
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||||
|
* 02110-1301 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if !defined(__EEK_H_INSIDE__) && !defined(EEK_COMPILATION)
|
||||||
|
#error "Only <eek/eek-xkl.h> can be included directly."
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef EEK_XKL_LAYOUT_H
|
||||||
|
#define EEK_XKL_LAYOUT_H 1
|
||||||
|
|
||||||
|
#include <libxklavier/xklavier.h>
|
||||||
|
#include "eek-xkb-layout.h"
|
||||||
|
|
||||||
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
#define EEK_TYPE_XKL_LAYOUT (eek_xkl_layout_get_type())
|
||||||
|
G_DECLARE_DERIVABLE_TYPE (EekXklLayout, eek_xkl_layout, EEK, XKL_LAYOUT, EekLayout)
|
||||||
|
|
||||||
|
struct _EekXklLayoutClass
|
||||||
|
{
|
||||||
|
/*< private >*/
|
||||||
|
EekXkbLayoutClass parent_class;
|
||||||
|
|
||||||
|
/*< private >*/
|
||||||
|
/* padding */
|
||||||
|
gpointer pdummy[24];
|
||||||
|
};
|
||||||
|
|
||||||
|
GType eek_xkl_layout_get_type (void) G_GNUC_CONST;
|
||||||
|
|
||||||
|
EekLayout *eek_xkl_layout_new (Display *display,
|
||||||
|
GError **error);
|
||||||
|
|
||||||
|
gboolean eek_xkl_layout_set_config (EekXklLayout *layout,
|
||||||
|
XklConfigRec *config);
|
||||||
|
|
||||||
|
gboolean eek_xkl_layout_set_config_full (EekXklLayout *layout,
|
||||||
|
gchar *model,
|
||||||
|
gchar **layouts,
|
||||||
|
gchar **variants,
|
||||||
|
gchar **options);
|
||||||
|
|
||||||
|
gboolean eek_xkl_layout_set_model (EekXklLayout *layout,
|
||||||
|
const gchar *model);
|
||||||
|
gboolean eek_xkl_layout_set_layouts (EekXklLayout *layout,
|
||||||
|
gchar **layouts);
|
||||||
|
gboolean eek_xkl_layout_set_variants (EekXklLayout *layout,
|
||||||
|
gchar **variants);
|
||||||
|
gboolean eek_xkl_layout_set_options (EekXklLayout *layout,
|
||||||
|
gchar **options);
|
||||||
|
gboolean eek_xkl_layout_enable_option (EekXklLayout *layout,
|
||||||
|
const gchar *option);
|
||||||
|
gboolean eek_xkl_layout_disable_option (EekXklLayout *layout,
|
||||||
|
const gchar *option);
|
||||||
|
|
||||||
|
gchar *eek_xkl_layout_get_model (EekXklLayout *layout);
|
||||||
|
gchar **eek_xkl_layout_get_layouts (EekXklLayout *layout);
|
||||||
|
gchar **eek_xkl_layout_get_variants (EekXklLayout *layout);
|
||||||
|
gchar **eek_xkl_layout_get_options (EekXklLayout *layout);
|
||||||
|
gboolean eek_xkl_layout_get_option (EekXklLayout *layout,
|
||||||
|
const gchar *option);
|
||||||
|
|
||||||
|
G_END_DECLS
|
||||||
|
#endif /* #ifndef EEK_XKL_LAYOUT_H */
|
||||||
26
eek/eek-xkl.h
Normal file
26
eek/eek-xkl.h
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2010-2011 Daiki Ueno <ueno@unixuser.org>
|
||||||
|
* Copyright (C) 2010-2011 Red Hat, Inc.
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2 of
|
||||||
|
* the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library 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
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||||
|
* 02110-1301 USA
|
||||||
|
*/
|
||||||
|
#ifndef EEK_XKL_H
|
||||||
|
#define EEK_XKL_H 1
|
||||||
|
|
||||||
|
#include "eek.h"
|
||||||
|
#include "eek-xkl-layout.h"
|
||||||
|
|
||||||
|
#endif /* EEK_XKL_H */
|
||||||
@ -21,9 +21,10 @@
|
|||||||
* @short_description: Layout engine which loads layout information from XML
|
* @short_description: Layout engine which loads layout information from XML
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
#endif /* HAVE_CONFIG_H */
|
||||||
|
|
||||||
#include <gio/gio.h> /* GResource */
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
@ -34,8 +35,6 @@
|
|||||||
#include "eek-keysym.h"
|
#include "eek-keysym.h"
|
||||||
#include "eek-text.h"
|
#include "eek-text.h"
|
||||||
|
|
||||||
#include "squeekboard-resources.h"
|
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
PROP_0,
|
PROP_0,
|
||||||
PROP_ID,
|
PROP_ID,
|
||||||
@ -360,6 +359,8 @@ geometry_start_element_callback (GMarkupParseContext *pcontext,
|
|||||||
|
|
||||||
if (g_strcmp0 (data->element_stack->data, "geometry") == 0)
|
if (g_strcmp0 (data->element_stack->data, "geometry") == 0)
|
||||||
eek_element_set_bounds (EEK_ELEMENT(data->keyboard), &bounds);
|
eek_element_set_bounds (EEK_ELEMENT(data->keyboard), &bounds);
|
||||||
|
else if (g_strcmp0 (data->element_stack->data, "section") == 0)
|
||||||
|
eek_element_set_bounds (EEK_ELEMENT(data->section), &bounds);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -405,24 +406,18 @@ geometry_start_element_callback (GMarkupParseContext *pcontext,
|
|||||||
"no \"keycode\" attribute for \"key\"");
|
"no \"keycode\" attribute for \"key\"");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
keycode = strtol (attribute, NULL, 10);
|
keycode = strtoul (attribute, NULL, 10);
|
||||||
|
|
||||||
attribute = get_attribute (attribute_names, attribute_values,
|
|
||||||
"name");
|
|
||||||
if (attribute == NULL) {
|
|
||||||
g_set_error (error,
|
|
||||||
G_MARKUP_ERROR,
|
|
||||||
G_MARKUP_ERROR_MISSING_ATTRIBUTE,
|
|
||||||
"no \"name\" attribute for \"key\"");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
data->key = eek_section_create_key (data->section,
|
data->key = eek_section_create_key (data->section,
|
||||||
g_strdup (attribute),
|
|
||||||
keycode,
|
keycode,
|
||||||
data->num_columns,
|
data->num_columns,
|
||||||
data->num_rows - 1);
|
data->num_rows - 1);
|
||||||
|
|
||||||
|
attribute = get_attribute (attribute_names, attribute_values,
|
||||||
|
"name");
|
||||||
|
if (attribute != NULL)
|
||||||
|
eek_element_set_name (EEK_ELEMENT(data->key), attribute);
|
||||||
|
|
||||||
attribute = get_attribute (attribute_names, attribute_values,
|
attribute = get_attribute (attribute_names, attribute_values,
|
||||||
"oref");
|
"oref");
|
||||||
if (attribute == NULL) {
|
if (attribute == NULL) {
|
||||||
@ -626,25 +621,28 @@ symbols_start_element_callback (GMarkupParseContext *pcontext,
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
if (g_strcmp0 (element_name, "key") == 0) {
|
if (g_strcmp0 (element_name, "key") == 0) {
|
||||||
|
guint keycode;
|
||||||
|
|
||||||
attribute = get_attribute (attribute_names, attribute_values,
|
attribute = get_attribute (attribute_names, attribute_values,
|
||||||
"name");
|
"keycode");
|
||||||
if (attribute == NULL) {
|
if (attribute == NULL) {
|
||||||
g_set_error (error,
|
g_set_error (error,
|
||||||
G_MARKUP_ERROR,
|
G_MARKUP_ERROR,
|
||||||
G_MARKUP_ERROR_MISSING_ATTRIBUTE,
|
G_MARKUP_ERROR_MISSING_ATTRIBUTE,
|
||||||
"no \"name\" attribute for \"key\"");
|
"no \"keycode\" attribute for \"key\"");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
keycode = strtoul (attribute, NULL, 10);
|
||||||
|
|
||||||
data->key = eek_keyboard_find_key_by_name (data->keyboard,
|
data->key = eek_keyboard_find_key_by_keycode (data->keyboard,
|
||||||
attribute);
|
keycode);
|
||||||
if (data->key == NULL) {
|
/*if (data->key == NULL) {
|
||||||
g_set_error (error,
|
g_set_error (error,
|
||||||
G_MARKUP_ERROR,
|
G_MARKUP_ERROR,
|
||||||
G_MARKUP_ERROR_INVALID_CONTENT,
|
G_MARKUP_ERROR_INVALID_CONTENT,
|
||||||
"no such key %s", attribute);
|
"no such keycode %u", keycode);
|
||||||
}
|
return;
|
||||||
|
}*/
|
||||||
|
|
||||||
attribute = get_attribute (attribute_names, attribute_values,
|
attribute = get_attribute (attribute_names, attribute_values,
|
||||||
"groups");
|
"groups");
|
||||||
@ -946,9 +944,7 @@ eek_xml_layout_real_create_keyboard (EekboardContextService *manager,
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
eek_layout_place_sections(keyboard);
|
/* Fit keyboard in the given width and hight. */
|
||||||
|
|
||||||
/* Fit keyboard in the given width and height. */
|
|
||||||
scale_keyboard (keyboard, initial_width, initial_height);
|
scale_keyboard (keyboard, initial_width, initial_height);
|
||||||
|
|
||||||
/* Use pre-defined modifier mask here. */
|
/* Use pre-defined modifier mask here. */
|
||||||
@ -1062,10 +1058,10 @@ initable_init (GInitable *initable,
|
|||||||
gchar *path;
|
gchar *path;
|
||||||
EekXmlKeyboardDesc *desc;
|
EekXmlKeyboardDesc *desc;
|
||||||
|
|
||||||
priv->keyboards_dir = g_strdup ((gchar *) g_getenv ("EEKBOARD_KEYBOARDSDIR"));
|
priv->keyboards_dir = (gchar *) g_getenv ("EEKBOARD_KEYBOARDSDIR");
|
||||||
|
|
||||||
if (priv->keyboards_dir == NULL)
|
if (priv->keyboards_dir == NULL)
|
||||||
priv->keyboards_dir = g_strdup ("resource:///sm/puri/squeekboard/keyboards/");
|
priv->keyboards_dir = KEYBOARDSDIR;
|
||||||
|
priv->keyboards_dir = g_strdup (priv->keyboards_dir);
|
||||||
|
|
||||||
path = g_build_filename (priv->keyboards_dir, "keyboards.xml", NULL);
|
path = g_build_filename (priv->keyboards_dir, "keyboards.xml", NULL);
|
||||||
keyboards = parse_keyboards (path, error);
|
keyboards = parse_keyboards (path, error);
|
||||||
@ -1116,7 +1112,7 @@ eek_xml_list_keyboards (void)
|
|||||||
|
|
||||||
keyboards_dir = g_getenv ("EEKBOARD_KEYBOARDSDIR");
|
keyboards_dir = g_getenv ("EEKBOARD_KEYBOARDSDIR");
|
||||||
if (keyboards_dir == NULL)
|
if (keyboards_dir == NULL)
|
||||||
keyboards_dir = g_strdup ("resource:///sm/puri/squeekboard/keyboards/");
|
keyboards_dir = KEYBOARDSDIR;
|
||||||
path = g_build_filename (keyboards_dir, "keyboards.xml", NULL);
|
path = g_build_filename (keyboards_dir, "keyboards.xml", NULL);
|
||||||
keyboards = parse_keyboards (path, NULL);
|
keyboards = parse_keyboards (path, NULL);
|
||||||
g_free (path);
|
g_free (path);
|
||||||
@ -1141,6 +1137,38 @@ eek_xml_keyboard_desc_free (EekXmlKeyboardDesc *desc)
|
|||||||
g_slice_free (EekXmlKeyboardDesc, desc);
|
g_slice_free (EekXmlKeyboardDesc, desc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct place_data {
|
||||||
|
double desired_width;
|
||||||
|
double current_offset;
|
||||||
|
EekKeyboard *keyboard;
|
||||||
|
};
|
||||||
|
|
||||||
|
const double section_spacing = 7.0;
|
||||||
|
|
||||||
|
static void section_placer(EekElement *element, gpointer user_data) {
|
||||||
|
struct place_data *data = (struct place_data*)user_data;
|
||||||
|
|
||||||
|
EekBounds section_bounds = {0};
|
||||||
|
eek_element_get_bounds(element, §ion_bounds);
|
||||||
|
section_bounds.width = data->desired_width;
|
||||||
|
eek_element_set_bounds(element, §ion_bounds);
|
||||||
|
|
||||||
|
// Sections are rows now. Gather up all the keys and adjust their bounds.
|
||||||
|
eek_section_place_keys(EEK_SECTION(element), EEK_KEYBOARD(data->keyboard));
|
||||||
|
|
||||||
|
eek_element_get_bounds(element, §ion_bounds);
|
||||||
|
section_bounds.y = data->current_offset;
|
||||||
|
eek_element_set_bounds(element, §ion_bounds);
|
||||||
|
data->current_offset += section_bounds.height + section_spacing;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void section_counter(EekElement *element, gpointer user_data) {
|
||||||
|
double *total_height = user_data;
|
||||||
|
EekBounds section_bounds = {0};
|
||||||
|
eek_element_get_bounds(element, §ion_bounds);
|
||||||
|
*total_height += section_bounds.height + section_spacing;
|
||||||
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
parse_geometry (const gchar *path, EekKeyboard *keyboard, GError **error)
|
parse_geometry (const gchar *path, EekKeyboard *keyboard, GError **error)
|
||||||
{
|
{
|
||||||
@ -1153,9 +1181,7 @@ parse_geometry (const gchar *path, EekKeyboard *keyboard, GError **error)
|
|||||||
GFileInputStream *input;
|
GFileInputStream *input;
|
||||||
gboolean retval;
|
gboolean retval;
|
||||||
|
|
||||||
file = g_str_has_prefix (path, "resource://")
|
file = g_file_new_for_path (path);
|
||||||
? g_file_new_for_uri (path)
|
|
||||||
: g_file_new_for_path (path);
|
|
||||||
|
|
||||||
input = g_file_read (file, NULL, error);
|
input = g_file_read (file, NULL, error);
|
||||||
g_object_unref (file);
|
g_object_unref (file);
|
||||||
@ -1195,6 +1221,27 @@ parse_geometry (const gchar *path, EekKeyboard *keyboard, GError **error)
|
|||||||
}
|
}
|
||||||
g_hash_table_destroy (oref_hash);
|
g_hash_table_destroy (oref_hash);
|
||||||
|
|
||||||
|
/* Order rows */
|
||||||
|
// This needs to be done after outlines, because outlines define key sizes
|
||||||
|
// TODO: do this only for rows without bounds
|
||||||
|
|
||||||
|
// The keyboard width is given by the user via screen size. The height will be given dynamically.
|
||||||
|
// TODO: calculate max line width beforehand for button centering. Leave keyboard centering to the renderer later
|
||||||
|
EekBounds keyboard_bounds = {0};
|
||||||
|
eek_element_get_bounds(EEK_ELEMENT(keyboard), &keyboard_bounds);
|
||||||
|
|
||||||
|
struct place_data placer_data = {
|
||||||
|
.desired_width = keyboard_bounds.width,
|
||||||
|
.current_offset = 0,
|
||||||
|
.keyboard = keyboard,
|
||||||
|
};
|
||||||
|
eek_container_foreach_child(EEK_CONTAINER(keyboard), section_placer, &placer_data);
|
||||||
|
|
||||||
|
double total_height = 0;
|
||||||
|
eek_container_foreach_child(EEK_CONTAINER(keyboard), section_counter, &total_height);
|
||||||
|
keyboard_bounds.height = total_height;
|
||||||
|
eek_element_set_bounds(EEK_ELEMENT(keyboard), &keyboard_bounds);
|
||||||
|
|
||||||
geometry_parse_data_free (data);
|
geometry_parse_data_free (data);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
@ -1260,9 +1307,7 @@ parse_symbols (const gchar *path, EekKeyboard *keyboard, GError **error)
|
|||||||
GFileInputStream *input;
|
GFileInputStream *input;
|
||||||
gboolean retval;
|
gboolean retval;
|
||||||
|
|
||||||
file = g_str_has_prefix (path, "resource://")
|
file = g_file_new_for_path (path);
|
||||||
? g_file_new_for_uri (path)
|
|
||||||
: g_file_new_for_path (path);
|
|
||||||
|
|
||||||
input = g_file_read (file, NULL, error);
|
input = g_file_read (file, NULL, error);
|
||||||
g_object_unref (file);
|
g_object_unref (file);
|
||||||
@ -1295,9 +1340,7 @@ parse_prerequisites (const gchar *path, GError **error)
|
|||||||
GList *prerequisites;
|
GList *prerequisites;
|
||||||
gboolean retval;
|
gboolean retval;
|
||||||
|
|
||||||
file = g_str_has_prefix (path, "resource://")
|
file = g_file_new_for_path (path);
|
||||||
? g_file_new_for_uri (path)
|
|
||||||
: g_file_new_for_path (path);
|
|
||||||
|
|
||||||
input = g_file_read (file, NULL, error);
|
input = g_file_read (file, NULL, error);
|
||||||
g_object_unref (file);
|
g_object_unref (file);
|
||||||
@ -1332,9 +1375,7 @@ parse_keyboards (const gchar *path, GError **error)
|
|||||||
GList *keyboards;
|
GList *keyboards;
|
||||||
gboolean retval;
|
gboolean retval;
|
||||||
|
|
||||||
file = g_str_has_prefix (path, "resource://")
|
file = g_file_new_for_path (path);
|
||||||
? g_file_new_for_uri (path)
|
|
||||||
: g_file_new_for_path (path);
|
|
||||||
|
|
||||||
input = g_file_read (file, NULL, error);
|
input = g_file_read (file, NULL, error);
|
||||||
g_object_unref (file);
|
g_object_unref (file);
|
||||||
@ -1360,12 +1401,43 @@ parse_keyboards (const gchar *path, GError **error)
|
|||||||
return keyboards;
|
return keyboards;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void scale_bounds_callback (EekElement *element,
|
||||||
|
gpointer user_data);
|
||||||
|
|
||||||
|
static void
|
||||||
|
scale_bounds (EekElement *element,
|
||||||
|
gdouble scale)
|
||||||
|
{
|
||||||
|
EekBounds bounds;
|
||||||
|
|
||||||
|
eek_element_get_bounds (element, &bounds);
|
||||||
|
bounds.x *= scale;
|
||||||
|
bounds.y *= scale;
|
||||||
|
bounds.width *= scale;
|
||||||
|
bounds.height *= scale;
|
||||||
|
eek_element_set_bounds (element, &bounds);
|
||||||
|
|
||||||
|
if (EEK_IS_CONTAINER(element))
|
||||||
|
eek_container_foreach_child (EEK_CONTAINER(element),
|
||||||
|
scale_bounds_callback,
|
||||||
|
&scale);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
scale_bounds_callback (EekElement *element,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
scale_bounds (element, *(gdouble *)user_data);
|
||||||
|
}
|
||||||
|
|
||||||
static void scale_keyboard (EekKeyboard *keyboard,
|
static void scale_keyboard (EekKeyboard *keyboard,
|
||||||
gdouble width,
|
gdouble width,
|
||||||
gdouble height)
|
gdouble height)
|
||||||
{
|
{
|
||||||
gdouble scale;
|
gdouble scale;
|
||||||
EekBounds bounds;
|
EekBounds bounds;
|
||||||
|
gsize n_outlines;
|
||||||
|
guint i;
|
||||||
|
|
||||||
eek_element_get_bounds (EEK_ELEMENT(keyboard), &bounds);
|
eek_element_get_bounds (EEK_ELEMENT(keyboard), &bounds);
|
||||||
|
|
||||||
@ -1374,7 +1446,18 @@ static void scale_keyboard (EekKeyboard *keyboard,
|
|||||||
else
|
else
|
||||||
scale = height / bounds.height;
|
scale = height / bounds.height;
|
||||||
|
|
||||||
eek_layout_scale_keyboard(keyboard, scale);
|
scale_bounds (EEK_ELEMENT(keyboard), scale);
|
||||||
|
|
||||||
|
n_outlines = eek_keyboard_get_n_outlines (keyboard);
|
||||||
|
for (i = 0; i < n_outlines; i++) {
|
||||||
|
EekOutline *outline = eek_keyboard_get_outline (keyboard, i);
|
||||||
|
gint j;
|
||||||
|
|
||||||
|
for (j = 0; j < outline->num_points; j++) {
|
||||||
|
outline->points[j].x *= scale;
|
||||||
|
outline->points[j].y *= scale;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
|
|||||||
@ -22,7 +22,9 @@
|
|||||||
* @short_description: #EekKeyboard to XML conversion utilities
|
* @short_description: #EekKeyboard to XML conversion utilities
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
#endif /* HAVE_CONFIG_H */
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
|||||||
@ -23,7 +23,9 @@
|
|||||||
* @title: Library Initialization
|
* @title: Library Initialization
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
#endif /* HAVE_CONFIG_H */
|
||||||
|
|
||||||
#include "eek.h"
|
#include "eek.h"
|
||||||
|
|
||||||
|
|||||||
@ -65,9 +65,9 @@ static void layer_surface_configure(void *data,
|
|||||||
uint32_t height)
|
uint32_t height)
|
||||||
{
|
{
|
||||||
PhoshLayerSurface *self = data;
|
PhoshLayerSurface *self = data;
|
||||||
|
|
||||||
gtk_window_resize (GTK_WINDOW (self), width, height);
|
gtk_window_resize (GTK_WINDOW (self), width, height);
|
||||||
zwlr_layer_surface_v1_ack_configure(surface, serial);
|
zwlr_layer_surface_v1_ack_configure(surface, serial);
|
||||||
|
gtk_widget_show_all (GTK_WIDGET (self));
|
||||||
|
|
||||||
g_signal_emit (self, signals[CONFIGURED], 0);
|
g_signal_emit (self, signals[CONFIGURED], 0);
|
||||||
}
|
}
|
||||||
@ -180,38 +180,21 @@ phosh_layer_surface_get_property (GObject *object,
|
|||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
on_phosh_layer_surface_realized (PhoshLayerSurface *self, gpointer unused)
|
phosh_layer_surface_constructed (GObject *object)
|
||||||
{
|
{
|
||||||
PhoshLayerSurfacePrivate *priv;
|
PhoshLayerSurface *self = PHOSH_LAYER_SURFACE (object);
|
||||||
|
PhoshLayerSurfacePrivate *priv = phosh_layer_surface_get_instance_private (self);
|
||||||
GdkWindow *gdk_window;
|
GdkWindow *gdk_window;
|
||||||
|
|
||||||
g_return_if_fail (PHOSH_IS_LAYER_SURFACE (self));
|
G_OBJECT_CLASS (phosh_layer_surface_parent_class)->constructed (object);
|
||||||
|
|
||||||
priv = phosh_layer_surface_get_instance_private (self);
|
|
||||||
|
|
||||||
gdk_window = gtk_widget_get_window (GTK_WIDGET (self));
|
|
||||||
gdk_wayland_window_set_use_custom_surface (gdk_window);
|
|
||||||
priv->wl_surface = gdk_wayland_window_get_wl_surface (gdk_window);
|
|
||||||
|
|
||||||
gtk_window_set_decorated (GTK_WINDOW (self), FALSE);
|
gtk_window_set_decorated (GTK_WINDOW (self), FALSE);
|
||||||
}
|
/* Realize the window so we can get the GDK window */
|
||||||
|
gtk_widget_realize(GTK_WIDGET (self));
|
||||||
|
|
||||||
|
|
||||||
static void
|
|
||||||
on_phosh_layer_surface_mapped (PhoshLayerSurface *self, gpointer unused)
|
|
||||||
{
|
|
||||||
PhoshLayerSurfacePrivate *priv;
|
|
||||||
GdkWindow *gdk_window;
|
|
||||||
|
|
||||||
g_return_if_fail (PHOSH_IS_LAYER_SURFACE (self));
|
|
||||||
priv = phosh_layer_surface_get_instance_private (self);
|
|
||||||
|
|
||||||
if (!priv->wl_surface) {
|
|
||||||
gdk_window = gtk_widget_get_window (GTK_WIDGET (self));
|
gdk_window = gtk_widget_get_window (GTK_WIDGET (self));
|
||||||
gdk_wayland_window_set_use_custom_surface (gdk_window);
|
gdk_wayland_window_set_use_custom_surface (gdk_window);
|
||||||
priv->wl_surface = gdk_wayland_window_get_wl_surface (gdk_window);
|
priv->wl_surface = gdk_wayland_window_get_wl_surface (gdk_window);
|
||||||
}
|
|
||||||
g_debug ("Mapped %p", priv->wl_surface);
|
|
||||||
|
|
||||||
priv->layer_surface = zwlr_layer_shell_v1_get_layer_surface(priv->layer_shell,
|
priv->layer_surface = zwlr_layer_shell_v1_get_layer_surface(priv->layer_shell,
|
||||||
priv->wl_surface,
|
priv->wl_surface,
|
||||||
@ -226,45 +209,8 @@ on_phosh_layer_surface_mapped (PhoshLayerSurface *self, gpointer unused)
|
|||||||
&layer_surface_listener,
|
&layer_surface_listener,
|
||||||
self);
|
self);
|
||||||
wl_surface_commit(priv->wl_surface);
|
wl_surface_commit(priv->wl_surface);
|
||||||
|
|
||||||
/* Process all pending events, otherwise we end up sending ack configure
|
|
||||||
* to a not yet configured surface */
|
|
||||||
wl_display_roundtrip (gdk_wayland_display_get_wl_display (gdk_display_get_default ()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
on_phosh_layer_surface_unmapped (PhoshLayerSurface *self, gpointer unused)
|
|
||||||
{
|
|
||||||
PhoshLayerSurfacePrivate *priv;
|
|
||||||
|
|
||||||
g_return_if_fail (PHOSH_IS_LAYER_SURFACE (self));
|
|
||||||
priv = phosh_layer_surface_get_instance_private (self);
|
|
||||||
|
|
||||||
priv = phosh_layer_surface_get_instance_private (self);
|
|
||||||
if (priv->layer_surface) {
|
|
||||||
zwlr_layer_surface_v1_destroy(priv->layer_surface);
|
|
||||||
priv->layer_surface = NULL;
|
|
||||||
}
|
|
||||||
priv->wl_surface = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
phosh_layer_surface_constructed (GObject *object)
|
|
||||||
{
|
|
||||||
PhoshLayerSurface *self = PHOSH_LAYER_SURFACE (object);
|
|
||||||
|
|
||||||
g_signal_connect (self, "realize",
|
|
||||||
G_CALLBACK (on_phosh_layer_surface_realized),
|
|
||||||
NULL);
|
|
||||||
g_signal_connect (self, "map",
|
|
||||||
G_CALLBACK (on_phosh_layer_surface_mapped),
|
|
||||||
NULL);
|
|
||||||
g_signal_connect (self, "unmap",
|
|
||||||
G_CALLBACK (on_phosh_layer_surface_unmapped),
|
|
||||||
NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
phosh_layer_surface_dispose (GObject *object)
|
phosh_layer_surface_dispose (GObject *object)
|
||||||
{
|
{
|
||||||
@ -406,12 +352,6 @@ phosh_layer_surface_new (gpointer layer_shell,
|
|||||||
"wl-output", wl_output);
|
"wl-output", wl_output);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* phosh_layer_surface_get_surface:
|
|
||||||
*
|
|
||||||
* Get the layer layer surface or #NULL if the window
|
|
||||||
* is not yet realized.
|
|
||||||
*/
|
|
||||||
struct zwlr_layer_surface_v1 *
|
struct zwlr_layer_surface_v1 *
|
||||||
phosh_layer_surface_get_layer_surface(PhoshLayerSurface *self)
|
phosh_layer_surface_get_layer_surface(PhoshLayerSurface *self)
|
||||||
{
|
{
|
||||||
@ -423,12 +363,6 @@ phosh_layer_surface_get_layer_surface(PhoshLayerSurface *self)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* phosh_layer_surface_get_wl_surface:
|
|
||||||
*
|
|
||||||
* Get the layer wayland surface or #NULL if the window
|
|
||||||
* is not yet realized.
|
|
||||||
*/
|
|
||||||
struct wl_surface *
|
struct wl_surface *
|
||||||
phosh_layer_surface_get_wl_surface(PhoshLayerSurface *self)
|
phosh_layer_surface_get_wl_surface(PhoshLayerSurface *self)
|
||||||
{
|
{
|
||||||
|
|||||||
404
eekboard/eekboard-client.c
Normal file
404
eekboard/eekboard-client.c
Normal file
@ -0,0 +1,404 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2011 Daiki Ueno <ueno@unixuser.org>
|
||||||
|
* Copyright (C) 2011 Red Hat, Inc.
|
||||||
|
*
|
||||||
|
* 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 3 of the License, 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, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SECTION:eekboard-client
|
||||||
|
* @short_description: client interface of eekboard service
|
||||||
|
*
|
||||||
|
* The #EekboardClient class provides a client side access to eekboard-server.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "config.h"
|
||||||
|
#endif /* HAVE_CONFIG_H */
|
||||||
|
|
||||||
|
#include "eekboard/eekboard-client.h"
|
||||||
|
|
||||||
|
enum {
|
||||||
|
DESTROYED,
|
||||||
|
LAST_SIGNAL
|
||||||
|
};
|
||||||
|
|
||||||
|
static guint signals[LAST_SIGNAL] = { 0, };
|
||||||
|
|
||||||
|
typedef struct _EekboardClientPrivate
|
||||||
|
{
|
||||||
|
GHashTable *context_hash;
|
||||||
|
} EekboardClientPrivate;
|
||||||
|
|
||||||
|
G_DEFINE_TYPE_WITH_PRIVATE (EekboardClient, eekboard_client, G_TYPE_DBUS_PROXY)
|
||||||
|
|
||||||
|
static void send_destroy_context (EekboardClient *client,
|
||||||
|
EekboardContext *context,
|
||||||
|
GCancellable *cancellable);
|
||||||
|
|
||||||
|
static void
|
||||||
|
eekboard_client_real_destroyed (EekboardClient *self)
|
||||||
|
{
|
||||||
|
EekboardClientPrivate *priv = eekboard_client_get_instance_private (self);
|
||||||
|
|
||||||
|
// g_debug ("eekboard_client_real_destroyed");
|
||||||
|
g_hash_table_remove_all (priv->context_hash);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
eekboard_client_dispose (GObject *object)
|
||||||
|
{
|
||||||
|
EekboardClient *client = EEKBOARD_CLIENT(object);
|
||||||
|
EekboardClientPrivate *priv = eekboard_client_get_instance_private (client);
|
||||||
|
|
||||||
|
if (priv->context_hash) {
|
||||||
|
GHashTableIter iter;
|
||||||
|
gpointer key, value;
|
||||||
|
|
||||||
|
g_hash_table_iter_init (&iter, priv->context_hash);
|
||||||
|
while (g_hash_table_iter_next (&iter, &key, &value)) {
|
||||||
|
send_destroy_context (client, (EekboardContext *)value, NULL);
|
||||||
|
g_hash_table_iter_remove (&iter);
|
||||||
|
}
|
||||||
|
g_hash_table_destroy (priv->context_hash);
|
||||||
|
priv->context_hash = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
G_OBJECT_CLASS (eekboard_client_parent_class)->dispose (object);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
eekboard_client_class_init (EekboardClientClass *klass)
|
||||||
|
{
|
||||||
|
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||||
|
|
||||||
|
klass->destroyed = eekboard_client_real_destroyed;
|
||||||
|
|
||||||
|
gobject_class->dispose = eekboard_client_dispose;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* EekboardClient::destroyed:
|
||||||
|
* @eekboard: an #EekboardClient
|
||||||
|
*
|
||||||
|
* The ::destroyed signal is emitted each time the name of remote
|
||||||
|
* end is vanished.
|
||||||
|
*/
|
||||||
|
signals[DESTROYED] =
|
||||||
|
g_signal_new (I_("destroyed"),
|
||||||
|
G_TYPE_FROM_CLASS(gobject_class),
|
||||||
|
G_SIGNAL_RUN_LAST,
|
||||||
|
G_STRUCT_OFFSET(EekboardClientClass, destroyed),
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
g_cclosure_marshal_VOID__VOID,
|
||||||
|
G_TYPE_NONE,
|
||||||
|
0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
eekboard_client_init (EekboardClient *self)
|
||||||
|
{
|
||||||
|
EekboardClientPrivate *priv = eekboard_client_get_instance_private (self);
|
||||||
|
|
||||||
|
priv->context_hash =
|
||||||
|
g_hash_table_new_full (g_str_hash,
|
||||||
|
g_str_equal,
|
||||||
|
(GDestroyNotify)g_free,
|
||||||
|
(GDestroyNotify)g_object_unref);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
eekboard_name_vanished_callback (GDBusConnection *connection,
|
||||||
|
const gchar *name,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
EekboardClient *client = user_data;
|
||||||
|
g_signal_emit_by_name (client, "destroyed", NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* eekboard_client_new:
|
||||||
|
* @connection: a #GDBusConnection
|
||||||
|
* @cancellable: a #GCancellable
|
||||||
|
*
|
||||||
|
* Create a client.
|
||||||
|
*/
|
||||||
|
EekboardClient *
|
||||||
|
eekboard_client_new (GDBusConnection *connection,
|
||||||
|
GCancellable *cancellable)
|
||||||
|
{
|
||||||
|
GInitable *initable;
|
||||||
|
GError *error;
|
||||||
|
|
||||||
|
g_assert (G_IS_DBUS_CONNECTION(connection));
|
||||||
|
|
||||||
|
error = NULL;
|
||||||
|
initable =
|
||||||
|
g_initable_new (EEKBOARD_TYPE_CLIENT,
|
||||||
|
cancellable,
|
||||||
|
&error,
|
||||||
|
"g-connection", connection,
|
||||||
|
"g-name", "org.fedorahosted.Eekboard",
|
||||||
|
"g-interface-name", "org.fedorahosted.Eekboard",
|
||||||
|
"g-object-path", "/org/fedorahosted/Eekboard",
|
||||||
|
NULL);
|
||||||
|
if (initable != NULL) {
|
||||||
|
EekboardClient *client = EEKBOARD_CLIENT (initable);
|
||||||
|
gchar *name_owner = g_dbus_proxy_get_name_owner (G_DBUS_PROXY(client));
|
||||||
|
if (name_owner == NULL) {
|
||||||
|
g_object_unref (client);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* the vanished callback is called when the server is disconnected */
|
||||||
|
g_bus_watch_name_on_connection (connection,
|
||||||
|
name_owner,
|
||||||
|
G_BUS_NAME_WATCHER_FLAGS_NONE,
|
||||||
|
NULL,
|
||||||
|
eekboard_name_vanished_callback,
|
||||||
|
client,
|
||||||
|
NULL);
|
||||||
|
g_free (name_owner);
|
||||||
|
|
||||||
|
return client;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_warning ("can't create client: %s", error->message);
|
||||||
|
g_error_free (error);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
on_context_destroyed (EekboardContext *context,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
EekboardClient *client = user_data;
|
||||||
|
EekboardClientPrivate *priv = eekboard_client_get_instance_private (client);
|
||||||
|
|
||||||
|
g_hash_table_remove (priv->context_hash,
|
||||||
|
g_dbus_proxy_get_object_path (G_DBUS_PROXY(context)));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* eekboard_client_create_context:
|
||||||
|
* @eekboard: an #EekboardClient
|
||||||
|
* @client_name: name of the client
|
||||||
|
* @cancellable: a #GCancellable
|
||||||
|
*
|
||||||
|
* Create a new input context.
|
||||||
|
*
|
||||||
|
* Return value: (transfer full): a newly created #EekboardContext.
|
||||||
|
*/
|
||||||
|
EekboardContext *
|
||||||
|
eekboard_client_create_context (EekboardClient *client,
|
||||||
|
const gchar *client_name,
|
||||||
|
GCancellable *cancellable)
|
||||||
|
{
|
||||||
|
GVariant *variant;
|
||||||
|
const gchar *object_path;
|
||||||
|
EekboardContext *context;
|
||||||
|
GError *error;
|
||||||
|
GDBusConnection *connection;
|
||||||
|
|
||||||
|
g_assert (EEKBOARD_IS_CLIENT(client));
|
||||||
|
g_assert (client_name);
|
||||||
|
|
||||||
|
error = NULL;
|
||||||
|
variant = g_dbus_proxy_call_sync (G_DBUS_PROXY(client),
|
||||||
|
"CreateContext",
|
||||||
|
g_variant_new ("(s)", client_name),
|
||||||
|
G_DBUS_CALL_FLAGS_NONE,
|
||||||
|
-1,
|
||||||
|
cancellable,
|
||||||
|
&error);
|
||||||
|
if (!variant) {
|
||||||
|
g_warning ("failed to call CreateContext: %s", error->message);
|
||||||
|
g_error_free (error);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_variant_get (variant, "(&s)", &object_path);
|
||||||
|
connection = g_dbus_proxy_get_connection (G_DBUS_PROXY(client));
|
||||||
|
context = eekboard_context_new (connection, object_path, cancellable);
|
||||||
|
if (!context) {
|
||||||
|
g_variant_unref (variant);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
EekboardClientPrivate *priv = eekboard_client_get_instance_private (client);
|
||||||
|
|
||||||
|
g_hash_table_insert (priv->context_hash,
|
||||||
|
g_strdup (object_path),
|
||||||
|
g_object_ref (context));
|
||||||
|
g_signal_connect (context, "destroyed",
|
||||||
|
G_CALLBACK(on_context_destroyed), client);
|
||||||
|
return context;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
eekboard_async_ready_callback (GObject *source_object,
|
||||||
|
GAsyncResult *res,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
GError *error = NULL;
|
||||||
|
GVariant *result;
|
||||||
|
|
||||||
|
result = g_dbus_proxy_call_finish (G_DBUS_PROXY(source_object),
|
||||||
|
res,
|
||||||
|
&error);
|
||||||
|
if (result)
|
||||||
|
g_variant_unref (result);
|
||||||
|
else {
|
||||||
|
g_warning ("error in D-Bus proxy call: %s", error->message);
|
||||||
|
g_error_free (error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* eekboard_client_push_context:
|
||||||
|
* @eekboard: an #EekboardClient
|
||||||
|
* @context: an #EekboardContext
|
||||||
|
* @cancellable: a #GCancellable
|
||||||
|
*
|
||||||
|
* Enable the input context @context and disable the others.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
eekboard_client_push_context (EekboardClient *client,
|
||||||
|
EekboardContext *context,
|
||||||
|
GCancellable *cancellable)
|
||||||
|
{
|
||||||
|
const gchar *object_path;
|
||||||
|
|
||||||
|
g_return_if_fail (EEKBOARD_IS_CLIENT(client));
|
||||||
|
g_return_if_fail (EEKBOARD_IS_CONTEXT(context));
|
||||||
|
|
||||||
|
EekboardClientPrivate *priv = eekboard_client_get_instance_private (client);
|
||||||
|
|
||||||
|
object_path = g_dbus_proxy_get_object_path (G_DBUS_PROXY(context));
|
||||||
|
|
||||||
|
context = g_hash_table_lookup (priv->context_hash,
|
||||||
|
object_path);
|
||||||
|
if (!context)
|
||||||
|
return;
|
||||||
|
|
||||||
|
eekboard_context_set_enabled (context, TRUE);
|
||||||
|
g_dbus_proxy_call (G_DBUS_PROXY(client),
|
||||||
|
"PushContext",
|
||||||
|
g_variant_new ("(s)", object_path),
|
||||||
|
G_DBUS_CALL_FLAGS_NONE,
|
||||||
|
-1,
|
||||||
|
cancellable,
|
||||||
|
eekboard_async_ready_callback,
|
||||||
|
NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* eekboard_client_pop_context:
|
||||||
|
* @eekboard: an #EekboardClient
|
||||||
|
* @cancellable: a #GCancellable
|
||||||
|
*
|
||||||
|
* Disable the current input context and enable the previous one.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
eekboard_client_pop_context (EekboardClient *client,
|
||||||
|
GCancellable *cancellable)
|
||||||
|
{
|
||||||
|
g_return_if_fail (EEKBOARD_IS_CLIENT(client));
|
||||||
|
|
||||||
|
g_dbus_proxy_call (G_DBUS_PROXY(client),
|
||||||
|
"PopContext",
|
||||||
|
NULL,
|
||||||
|
G_DBUS_CALL_FLAGS_NONE,
|
||||||
|
-1,
|
||||||
|
cancellable,
|
||||||
|
eekboard_async_ready_callback,
|
||||||
|
NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
eekboard_client_show_keyboard (EekboardClient *client,
|
||||||
|
GCancellable *cancellable)
|
||||||
|
{
|
||||||
|
g_return_if_fail (EEKBOARD_IS_CLIENT(client));
|
||||||
|
|
||||||
|
g_dbus_proxy_call (G_DBUS_PROXY(client),
|
||||||
|
"ShowKeyboard",
|
||||||
|
NULL,
|
||||||
|
G_DBUS_CALL_FLAGS_NONE,
|
||||||
|
-1,
|
||||||
|
cancellable,
|
||||||
|
eekboard_async_ready_callback,
|
||||||
|
NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
eekboard_client_hide_keyboard (EekboardClient *client,
|
||||||
|
GCancellable *cancellable)
|
||||||
|
{
|
||||||
|
g_return_if_fail (EEKBOARD_IS_CLIENT(client));
|
||||||
|
|
||||||
|
g_dbus_proxy_call (G_DBUS_PROXY(client),
|
||||||
|
"HideKeyboard",
|
||||||
|
NULL,
|
||||||
|
G_DBUS_CALL_FLAGS_NONE,
|
||||||
|
-1,
|
||||||
|
cancellable,
|
||||||
|
eekboard_async_ready_callback,
|
||||||
|
NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
send_destroy_context (EekboardClient *client,
|
||||||
|
EekboardContext *context,
|
||||||
|
GCancellable *cancellable)
|
||||||
|
{
|
||||||
|
const gchar *object_path;
|
||||||
|
|
||||||
|
object_path = g_dbus_proxy_get_object_path (G_DBUS_PROXY(context));
|
||||||
|
|
||||||
|
g_dbus_proxy_call (G_DBUS_PROXY(client),
|
||||||
|
"DestroyContext",
|
||||||
|
g_variant_new ("(s)", object_path),
|
||||||
|
G_DBUS_CALL_FLAGS_NONE,
|
||||||
|
-1,
|
||||||
|
cancellable,
|
||||||
|
eekboard_async_ready_callback,
|
||||||
|
NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* eekboard_client_destroy_context:
|
||||||
|
* @eekboard: an #EekboardClient
|
||||||
|
* @context: an #EekboardContext
|
||||||
|
* @cancellable: a #GCancellable
|
||||||
|
*
|
||||||
|
* Remove @context from @eekboard.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
eekboard_client_destroy_context (EekboardClient *client,
|
||||||
|
EekboardContext *context,
|
||||||
|
GCancellable *cancellable)
|
||||||
|
{
|
||||||
|
const gchar *object_path;
|
||||||
|
|
||||||
|
g_return_if_fail (EEKBOARD_IS_CLIENT(client));
|
||||||
|
g_return_if_fail (EEKBOARD_IS_CONTEXT(context));
|
||||||
|
|
||||||
|
EekboardClientPrivate *priv = eekboard_client_get_instance_private (client);
|
||||||
|
|
||||||
|
object_path = g_dbus_proxy_get_object_path (G_DBUS_PROXY(context));
|
||||||
|
g_hash_table_remove (priv->context_hash, object_path);
|
||||||
|
|
||||||
|
send_destroy_context (client, context, cancellable);
|
||||||
|
}
|
||||||
64
eekboard/eekboard-client.h
Normal file
64
eekboard/eekboard-client.h
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2010-2011 Daiki Ueno <ueno@unixuser.org>
|
||||||
|
* Copyright (C) 2010-2011 Red Hat, Inc.
|
||||||
|
*
|
||||||
|
* 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 3 of the License, 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, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
#ifndef EEKBOARD_CLIENT_H
|
||||||
|
#define EEKBOARD_CLIENT_H 1
|
||||||
|
|
||||||
|
#define __EEKBOARD_CLIENT_H_INSIDE__ 1
|
||||||
|
|
||||||
|
#include <gio/gio.h>
|
||||||
|
#include "eekboard/eekboard-context.h"
|
||||||
|
|
||||||
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
#define EEKBOARD_TYPE_CLIENT (eekboard_client_get_type())
|
||||||
|
G_DECLARE_DERIVABLE_TYPE (EekboardClient, eekboard_client, EEKBOARD, CLIENT, GDBusProxy)
|
||||||
|
|
||||||
|
struct _EekboardClientClass {
|
||||||
|
/*< private >*/
|
||||||
|
GDBusProxyClass parent_class;
|
||||||
|
|
||||||
|
/* signals */
|
||||||
|
void (* destroyed) (EekboardClient *self);
|
||||||
|
|
||||||
|
/*< private >*/
|
||||||
|
/* padding */
|
||||||
|
gpointer pdummy[23];
|
||||||
|
};
|
||||||
|
|
||||||
|
GType eekboard_client_get_type (void) G_GNUC_CONST;
|
||||||
|
|
||||||
|
EekboardClient *eekboard_client_new (GDBusConnection *connection,
|
||||||
|
GCancellable *cancellable);
|
||||||
|
EekboardContext *eekboard_client_create_context (EekboardClient *eekboard,
|
||||||
|
const gchar *client_name,
|
||||||
|
GCancellable *cancellable);
|
||||||
|
void eekboard_client_push_context (EekboardClient *eekboard,
|
||||||
|
EekboardContext *context,
|
||||||
|
GCancellable *cancellable);
|
||||||
|
void eekboard_client_pop_context (EekboardClient *eekboard,
|
||||||
|
GCancellable *cancellable);
|
||||||
|
void eekboard_client_show_keyboard (EekboardClient *eekboard,
|
||||||
|
GCancellable *cancellable);
|
||||||
|
void eekboard_client_hide_keyboard (EekboardClient *eekboard,
|
||||||
|
GCancellable *cancellable);
|
||||||
|
void eekboard_client_destroy_context (EekboardClient *eekboard,
|
||||||
|
EekboardContext *context,
|
||||||
|
GCancellable *cancellable);
|
||||||
|
|
||||||
|
G_END_DECLS
|
||||||
|
#endif /* EEKBOARD_CLIENT_H */
|
||||||
@ -25,10 +25,11 @@
|
|||||||
* implementation of eekboard input context service.
|
* implementation of eekboard input context service.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
#endif /* HAVE_CONFIG_H */
|
||||||
|
|
||||||
#include "eekboard/eekboard-context-service.h"
|
#include "eekboard/eekboard-context-service.h"
|
||||||
#include "keymap.h"
|
|
||||||
|
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
@ -79,60 +80,13 @@ struct _EekboardContextServicePrivate {
|
|||||||
gboolean repeat_triggered;
|
gboolean repeat_triggered;
|
||||||
|
|
||||||
GSettings *settings;
|
GSettings *settings;
|
||||||
uint32_t hint;
|
|
||||||
uint32_t purpose;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
G_DEFINE_TYPE_WITH_PRIVATE (EekboardContextService, eekboard_context_service, G_TYPE_OBJECT);
|
G_DEFINE_TYPE (EekboardContextService, eekboard_context_service, G_TYPE_OBJECT);
|
||||||
|
|
||||||
/*static Display *display = NULL; */
|
#if 0 // ===== REMOVAL NOTICE ==== expires by: 2019-08-20 -Wunused-variable =====
|
||||||
gchar *
|
static Display *display = NULL;
|
||||||
get_keymap_from_resource(const gchar *keyboard_type, gboolean fallback)
|
#endif // ===== REMOVAL NOTICE ==== expires by: 2019-08-20 -Wunused-variable =====
|
||||||
{
|
|
||||||
g_autoptr (GFile) file = NULL;
|
|
||||||
g_autoptr (GFileInfo) info = NULL;
|
|
||||||
g_autoptr (GFileInputStream) stream = NULL;
|
|
||||||
goffset size = 0;
|
|
||||||
gsize bytes_read = 0;
|
|
||||||
g_autofree gchar *contents = NULL;
|
|
||||||
g_autofree gchar *path = NULL;
|
|
||||||
GError *error = NULL;
|
|
||||||
|
|
||||||
if (fallback)
|
|
||||||
g_debug ("falling back to loading a %s keymap", keyboard_type);
|
|
||||||
|
|
||||||
path = g_strconcat ("resource:///sm/puri/squeekboard/keyboards/keymaps/",
|
|
||||||
keyboard_type, ".xkb", NULL);
|
|
||||||
file = g_file_new_for_uri (path);
|
|
||||||
stream = g_file_read (file, NULL, &error);
|
|
||||||
|
|
||||||
if (!stream)
|
|
||||||
goto keymap_error;
|
|
||||||
|
|
||||||
info = g_file_input_stream_query_info (stream,
|
|
||||||
G_FILE_ATTRIBUTE_STANDARD_SIZE,
|
|
||||||
NULL,
|
|
||||||
&error);
|
|
||||||
|
|
||||||
if (!info)
|
|
||||||
goto keymap_error;
|
|
||||||
|
|
||||||
size = g_file_info_get_size (info);
|
|
||||||
contents = g_malloc0 (size);
|
|
||||||
|
|
||||||
if (!g_input_stream_read_all (G_INPUT_STREAM(stream), contents, size,
|
|
||||||
&bytes_read, NULL, &error))
|
|
||||||
goto keymap_error;
|
|
||||||
|
|
||||||
return g_utf8_make_valid (contents, -1);
|
|
||||||
|
|
||||||
keymap_error:
|
|
||||||
if (fallback)
|
|
||||||
g_error ("failed to load keymap from resource: %s", error->message);
|
|
||||||
|
|
||||||
g_error_free (error);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static EekKeyboard *
|
static EekKeyboard *
|
||||||
eekboard_context_service_real_create_keyboard (EekboardContextService *self,
|
eekboard_context_service_real_create_keyboard (EekboardContextService *self,
|
||||||
@ -193,29 +147,18 @@ eekboard_context_service_real_create_keyboard (EekboardContextService *self,
|
|||||||
if (!context) {
|
if (!context) {
|
||||||
g_error("No context created");
|
g_error("No context created");
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
struct xkb_rule_names rules = { 0 };
|
struct xkb_rule_names rules = { 0 };
|
||||||
rules.layout = strdup(keyboard_type);
|
rules.layout = strdup(keyboard_type);
|
||||||
*/
|
struct xkb_keymap *keymap = xkb_keymap_new_from_names(context, &rules,
|
||||||
char *keymap_str = get_keymap_from_resource(keyboard_type, FALSE);
|
XKB_KEYMAP_COMPILE_NO_FLAGS);
|
||||||
if (!keymap_str)
|
|
||||||
keymap_str = get_keymap_from_resource("us", TRUE);
|
|
||||||
|
|
||||||
struct xkb_keymap *keymap = xkb_keymap_new_from_string(context, keymap_str,
|
|
||||||
XKB_KEYMAP_FORMAT_TEXT_V1, XKB_KEYMAP_COMPILE_NO_FLAGS);
|
|
||||||
|
|
||||||
free(keymap_str);
|
|
||||||
|
|
||||||
xkb_context_unref(context);
|
|
||||||
if (!keymap) {
|
if (!keymap) {
|
||||||
g_error("Bad keymap");
|
g_error("Bad keymap");
|
||||||
}
|
}
|
||||||
keyboard->keymap = keymap;
|
keyboard->keymap = keymap;
|
||||||
|
char *keymap_str = xkb_keymap_get_as_string(keymap, XKB_KEYMAP_FORMAT_TEXT_V1);
|
||||||
keymap_str = xkb_keymap_get_as_string(keymap, XKB_KEYMAP_FORMAT_TEXT_V1);
|
|
||||||
keyboard->keymap_len = strlen(keymap_str) + 1;
|
keyboard->keymap_len = strlen(keymap_str) + 1;
|
||||||
|
char *path = strdup("/eek_keymap-XXXXXX");
|
||||||
g_autofree char *path = strdup("/eek_keymap-XXXXXX");
|
|
||||||
char *r = &path[strlen(path) - 6];
|
char *r = &path[strlen(path) - 6];
|
||||||
getrandom(r, 6, GRND_NONBLOCK);
|
getrandom(r, 6, GRND_NONBLOCK);
|
||||||
for (uint i = 0; i < 6; i++) {
|
for (uint i = 0; i < 6; i++) {
|
||||||
@ -270,7 +213,12 @@ eekboard_context_service_set_property (GObject *object,
|
|||||||
context->priv->keyboard = g_value_get_object (value);
|
context->priv->keyboard = g_value_get_object (value);
|
||||||
break;
|
break;
|
||||||
case PROP_VISIBLE:
|
case PROP_VISIBLE:
|
||||||
context->priv->visible = g_value_get_boolean (value);
|
/*if (context->priv->keyboard) {
|
||||||
|
if (g_value_get_boolean (value))
|
||||||
|
eekboard_context_service_show_keyboard (context);
|
||||||
|
else
|
||||||
|
eekboard_context_service_hide_keyboard (context);
|
||||||
|
}*/
|
||||||
break;
|
break;
|
||||||
case PROP_FULLSCREEN:
|
case PROP_FULLSCREEN:
|
||||||
context->priv->fullscreen = g_value_get_boolean (value);
|
context->priv->fullscreen = g_value_get_boolean (value);
|
||||||
@ -338,12 +286,10 @@ settings_get_layout(GSettings *settings, char **type, char **layout)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
g_variant_iter_free(iter);
|
g_variant_iter_free(iter);
|
||||||
g_variant_unref(inputs);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
settings_update_layout(EekboardContextService *context)
|
settings_update_layout(EekboardContextService *context) {
|
||||||
{
|
|
||||||
g_autofree gchar *keyboard_type = NULL;
|
g_autofree gchar *keyboard_type = NULL;
|
||||||
g_autofree gchar *keyboard_layout = NULL;
|
g_autofree gchar *keyboard_layout = NULL;
|
||||||
settings_get_layout(context->priv->settings, &keyboard_type, &keyboard_layout);
|
settings_get_layout(context->priv->settings, &keyboard_type, &keyboard_layout);
|
||||||
@ -355,11 +301,6 @@ settings_update_layout(EekboardContextService *context)
|
|||||||
keyboard_layout = g_strdup("undefined");
|
keyboard_layout = g_strdup("undefined");
|
||||||
}
|
}
|
||||||
|
|
||||||
EekboardContextServicePrivate *priv = EEKBOARD_CONTEXT_SERVICE_GET_PRIVATE(context);
|
|
||||||
|
|
||||||
if (priv->purpose == ZWP_TEXT_INPUT_V3_CONTENT_PURPOSE_PHONE)
|
|
||||||
keyboard_layout = g_strdup("numbers");
|
|
||||||
|
|
||||||
// generic part follows
|
// generic part follows
|
||||||
static guint keyboard_id = 0;
|
static guint keyboard_id = 0;
|
||||||
EekKeyboard *keyboard = g_hash_table_lookup(context->priv->keyboard_hash,
|
EekKeyboard *keyboard = g_hash_table_lookup(context->priv->keyboard_hash,
|
||||||
@ -417,6 +358,9 @@ eekboard_context_service_class_init (EekboardContextServiceClass *klass)
|
|||||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||||
GParamSpec *pspec;
|
GParamSpec *pspec;
|
||||||
|
|
||||||
|
g_type_class_add_private (gobject_class,
|
||||||
|
sizeof (EekboardContextServicePrivate));
|
||||||
|
|
||||||
klass->create_keyboard = eekboard_context_service_real_create_keyboard;
|
klass->create_keyboard = eekboard_context_service_real_create_keyboard;
|
||||||
klass->show_keyboard = eekboard_context_service_real_show_keyboard;
|
klass->show_keyboard = eekboard_context_service_real_show_keyboard;
|
||||||
klass->hide_keyboard = eekboard_context_service_real_hide_keyboard;
|
klass->hide_keyboard = eekboard_context_service_real_hide_keyboard;
|
||||||
@ -541,6 +485,55 @@ eekboard_context_service_init (EekboardContextService *self)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 0 // ===== REMOVAL NOTICE ==== expires by: 2019-08-20 -Wunused-function =====
|
||||||
|
static gboolean on_repeat_timeout (EekboardContextService *context);
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
on_repeat_timeout (EekboardContextService *context)
|
||||||
|
{
|
||||||
|
guint delay = 500; // ms
|
||||||
|
|
||||||
|
// hardcoding; needs to connect to yet another settings path because
|
||||||
|
// org.gnome.desktop.input-sources doesn't control repeating
|
||||||
|
//g_settings_get (context->priv->settings, "repeat-interval", "u", &delay);
|
||||||
|
|
||||||
|
context->priv->repeat_timeout_id =
|
||||||
|
g_timeout_add (delay,
|
||||||
|
(GSourceFunc)on_repeat_timeout,
|
||||||
|
context);
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
#endif // ===== REMOVAL NOTICE ==== expires by: 2019-08-20 -Wunused-function =====
|
||||||
|
|
||||||
|
#if 0 // ===== REMOVAL NOTICE ==== expires by: 2019-08-20 -Wunused-function =====
|
||||||
|
static gboolean
|
||||||
|
on_repeat_timeout_init (EekboardContextService *context)
|
||||||
|
{
|
||||||
|
/* FIXME: clear modifiers for further key repeat; better not
|
||||||
|
depend on modifier behavior is LATCH */
|
||||||
|
eek_keyboard_set_modifiers (context->priv->keyboard, 0);
|
||||||
|
|
||||||
|
/* reschedule repeat timeout only when "repeat" option is set */
|
||||||
|
/* TODO: org.gnome.desktop.input-sources doesn't have repeat info.
|
||||||
|
* In addition, repeat is only useful when the keyboard is not in text
|
||||||
|
* input mode */
|
||||||
|
/*
|
||||||
|
if (g_settings_get_boolean (context->priv->settings, "repeat")) {
|
||||||
|
guint delay;
|
||||||
|
|
||||||
|
g_settings_get (context->priv->settings, "repeat-interval", "u", &delay);
|
||||||
|
context->priv->repeat_timeout_id =
|
||||||
|
g_timeout_add (delay,
|
||||||
|
(GSourceFunc)on_repeat_timeout,
|
||||||
|
context);
|
||||||
|
} else */
|
||||||
|
context->priv->repeat_timeout_id = 0;
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
#endif // ===== REMOVAL NOTICE ==== expires by: 2019-08-20 -Wunused-function =====
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* eekboard_context_service_enable:
|
* eekboard_context_service_enable:
|
||||||
* @context: an #EekboardContextService
|
* @context: an #EekboardContextService
|
||||||
@ -647,15 +640,3 @@ void eekboard_context_service_set_keymap(EekboardContextService *context,
|
|||||||
WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1,
|
WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1,
|
||||||
keyboard->keymap_fd, keyboard->keymap_len);
|
keyboard->keymap_fd, keyboard->keymap_len);
|
||||||
}
|
}
|
||||||
|
|
||||||
void eekboard_context_service_set_hint_purpose(EekboardContextService *context,
|
|
||||||
uint32_t hint, uint32_t purpose)
|
|
||||||
{
|
|
||||||
EekboardContextServicePrivate *priv = EEKBOARD_CONTEXT_SERVICE_GET_PRIVATE(context);
|
|
||||||
|
|
||||||
if (priv->hint != hint || priv->purpose != purpose) {
|
|
||||||
priv->hint = hint;
|
|
||||||
priv->purpose = purpose;
|
|
||||||
settings_update_layout(context);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@ -25,7 +25,6 @@
|
|||||||
#include <eek/eek.h>
|
#include <eek/eek.h>
|
||||||
|
|
||||||
#include "virtual-keyboard-unstable-v1-client-protocol.h"
|
#include "virtual-keyboard-unstable-v1-client-protocol.h"
|
||||||
#include "text-input-unstable-v3-client-protocol.h"
|
|
||||||
|
|
||||||
G_BEGIN_DECLS
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
@ -105,9 +104,5 @@ gboolean eekboard_context_service_get_fullscreen
|
|||||||
void eekboard_context_service_set_keymap(EekboardContextService *context,
|
void eekboard_context_service_set_keymap(EekboardContextService *context,
|
||||||
const EekKeyboard *keyboard);
|
const EekKeyboard *keyboard);
|
||||||
|
|
||||||
void eekboard_context_service_set_hint_purpose(EekboardContextService *context,
|
|
||||||
uint32_t hint,
|
|
||||||
uint32_t purpose);
|
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
#endif /* EEKBOARD_CONTEXT_SERVICE_H */
|
#endif /* EEKBOARD_CONTEXT_SERVICE_H */
|
||||||
|
|||||||
@ -24,7 +24,9 @@
|
|||||||
* context.
|
* context.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
#endif /* HAVE_CONFIG_H */
|
||||||
|
|
||||||
#include "eekboard/eekboard-context.h"
|
#include "eekboard/eekboard-context.h"
|
||||||
//#include "eekboard/eekboard-marshalers.h"
|
//#include "eekboard/eekboard-marshalers.h"
|
||||||
|
|||||||
@ -26,7 +26,9 @@
|
|||||||
* implementation of eekboard service.
|
* implementation of eekboard service.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
#endif /* HAVE_CONFIG_H */
|
||||||
|
|
||||||
#include "eekboard/eekboard-service.h"
|
#include "eekboard/eekboard-service.h"
|
||||||
|
|
||||||
@ -133,11 +135,6 @@ eekboard_service_dispose (GObject *object)
|
|||||||
priv->introspection_data = NULL;
|
priv->introspection_data = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (priv->context) {
|
|
||||||
g_signal_handlers_disconnect_by_data (priv->context, service);
|
|
||||||
priv->context = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
G_OBJECT_CLASS (eekboard_service_parent_class)->dispose (object);
|
G_OBJECT_CLASS (eekboard_service_parent_class)->dispose (object);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -169,22 +166,6 @@ handle_set_visible(SmPuriOSK0 *object, GDBusMethodInvocation *invocation,
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void on_visible(EekboardService *service,
|
|
||||||
GParamSpec *pspec,
|
|
||||||
EekboardContextService *context)
|
|
||||||
{
|
|
||||||
gboolean visible;
|
|
||||||
EekboardServicePrivate *priv;
|
|
||||||
|
|
||||||
g_return_if_fail (EEKBOARD_IS_SERVICE (service));
|
|
||||||
g_return_if_fail (EEKBOARD_IS_CONTEXT_SERVICE (context));
|
|
||||||
|
|
||||||
priv = eekboard_service_get_instance_private (service);
|
|
||||||
g_object_get (context, "visible", &visible, NULL);
|
|
||||||
|
|
||||||
sm_puri_osk0_set_visible(priv->dbus_interface, visible);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
eekboard_service_constructed (GObject *object)
|
eekboard_service_constructed (GObject *object)
|
||||||
{
|
{
|
||||||
@ -192,6 +173,7 @@ eekboard_service_constructed (GObject *object)
|
|||||||
EekboardServicePrivate *priv = eekboard_service_get_instance_private (service);
|
EekboardServicePrivate *priv = eekboard_service_get_instance_private (service);
|
||||||
|
|
||||||
priv->dbus_interface = sm_puri_osk0_skeleton_new();
|
priv->dbus_interface = sm_puri_osk0_skeleton_new();
|
||||||
|
sm_puri_osk0_set_visible(priv->dbus_interface, FALSE); // TODO: use actual value
|
||||||
g_signal_connect(priv->dbus_interface, "handle-set-visible",
|
g_signal_connect(priv->dbus_interface, "handle-set-visible",
|
||||||
G_CALLBACK(handle_set_visible), service);
|
G_CALLBACK(handle_set_visible), service);
|
||||||
|
|
||||||
@ -297,12 +279,5 @@ eekboard_service_set_context(EekboardService *service,
|
|||||||
{
|
{
|
||||||
EekboardServicePrivate *priv = eekboard_service_get_instance_private (service);
|
EekboardServicePrivate *priv = eekboard_service_get_instance_private (service);
|
||||||
|
|
||||||
g_return_if_fail (!priv->context);
|
|
||||||
|
|
||||||
priv->context = context;
|
priv->context = context;
|
||||||
|
|
||||||
g_signal_connect_swapped (priv->context,
|
|
||||||
"notify::visible",
|
|
||||||
G_CALLBACK(on_visible),
|
|
||||||
service);
|
|
||||||
}
|
}
|
||||||
|
|||||||
168
eekboard/eekboard-xklutil.c
Normal file
168
eekboard/eekboard-xklutil.c
Normal file
@ -0,0 +1,168 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2011 Daiki Ueno <ueno@unixuser.org>
|
||||||
|
* Copyright (C) 2011 Red Hat, Inc.
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2 of
|
||||||
|
* the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library 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
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||||
|
* 02110-1301 USA
|
||||||
|
*/
|
||||||
|
#include <string.h>
|
||||||
|
#include "eekboard/eekboard-xklutil.h"
|
||||||
|
|
||||||
|
XklConfigRec *
|
||||||
|
eekboard_xkl_config_rec_from_string (const gchar *layouts)
|
||||||
|
{
|
||||||
|
XklConfigRec *rec;
|
||||||
|
gchar **strv, **l, **v;
|
||||||
|
gint i;
|
||||||
|
|
||||||
|
strv = g_strsplit (layouts, "/", -1);
|
||||||
|
g_return_val_if_fail (g_strv_length (strv) == 3, NULL);
|
||||||
|
|
||||||
|
l = g_strsplit (strv[1], ";", -1);
|
||||||
|
v = g_strdupv (l);
|
||||||
|
for (i = 0; l[i]; i++) {
|
||||||
|
gchar *layout = l[i], *variant = v[i],
|
||||||
|
*variant_start, *variant_end;
|
||||||
|
|
||||||
|
variant_start = strchr (layout, '(');
|
||||||
|
variant_end = strrchr (layout, ')');
|
||||||
|
if (variant_start && variant_end) {
|
||||||
|
*variant_start++ = '\0';
|
||||||
|
g_strlcpy (variant, variant_start,
|
||||||
|
variant_end - variant_start + 1);
|
||||||
|
} else
|
||||||
|
*variant = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
rec = xkl_config_rec_new ();
|
||||||
|
rec->model = g_strdup (strv[0]);
|
||||||
|
rec->layouts = l;
|
||||||
|
rec->variants = v;
|
||||||
|
rec->options = g_strsplit (strv[2], ";", -1);
|
||||||
|
g_strfreev (strv);
|
||||||
|
|
||||||
|
return rec;
|
||||||
|
}
|
||||||
|
|
||||||
|
gchar *
|
||||||
|
eekboard_xkl_config_rec_to_string (XklConfigRec *rec)
|
||||||
|
{
|
||||||
|
gchar **strv, **sp, **lp, **vp, *p;
|
||||||
|
gint n_layouts;
|
||||||
|
GString *str;
|
||||||
|
|
||||||
|
n_layouts = g_strv_length (rec->layouts);
|
||||||
|
strv = g_malloc0_n (n_layouts + 2, sizeof (gchar *));
|
||||||
|
for (sp = strv, lp = rec->layouts, vp = rec->variants; *lp; sp++, lp++) {
|
||||||
|
if (*vp != NULL && **vp != '\0')
|
||||||
|
*sp = g_strdup_printf ("%s(%s)", *lp, *vp++);
|
||||||
|
else
|
||||||
|
*sp = g_strdup_printf ("%s", *lp);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* MODEL/L0(V0);L1(V1);...;Ln(Vn)/O0;O1;...;On */
|
||||||
|
str = g_string_new (rec->model);
|
||||||
|
|
||||||
|
g_string_append_c (str, '/');
|
||||||
|
p = g_strjoinv (";", strv);
|
||||||
|
g_strfreev (strv);
|
||||||
|
g_string_append (str, p);
|
||||||
|
g_free (p);
|
||||||
|
|
||||||
|
g_string_append_c (str, '/');
|
||||||
|
p = g_strjoinv (";", rec->options);
|
||||||
|
g_string_append (str, p);
|
||||||
|
g_free (p);
|
||||||
|
|
||||||
|
return g_string_free (str,FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
static XklConfigItem *
|
||||||
|
xkl_config_item_copy (const XklConfigItem *item)
|
||||||
|
{
|
||||||
|
XklConfigItem *_item = xkl_config_item_new ();
|
||||||
|
memcpy (_item->name,
|
||||||
|
item->name,
|
||||||
|
sizeof (item->name));
|
||||||
|
memcpy (_item->short_description,
|
||||||
|
item->short_description,
|
||||||
|
sizeof (item->short_description));
|
||||||
|
memcpy (_item->description,
|
||||||
|
item->description,
|
||||||
|
sizeof (item->description));
|
||||||
|
return _item;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
prepend_item (XklConfigRegistry *registry,
|
||||||
|
const XklConfigItem *item,
|
||||||
|
gpointer data)
|
||||||
|
{
|
||||||
|
GSList **list = data;
|
||||||
|
XklConfigItem *_item = xkl_config_item_copy (item);
|
||||||
|
*list = g_slist_prepend (*list, _item);
|
||||||
|
}
|
||||||
|
|
||||||
|
static gint
|
||||||
|
compare_item_by_name (gconstpointer a, gconstpointer b)
|
||||||
|
{
|
||||||
|
const XklConfigItem *ia = a, *ib = b;
|
||||||
|
return g_strcmp0 (ia->name, ib->name);
|
||||||
|
}
|
||||||
|
|
||||||
|
GSList *
|
||||||
|
eekboard_xkl_list_models (XklConfigRegistry *registry)
|
||||||
|
{
|
||||||
|
GSList *list = NULL;
|
||||||
|
xkl_config_registry_foreach_model (registry, prepend_item, &list);
|
||||||
|
return g_slist_sort (list, compare_item_by_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
GSList *
|
||||||
|
eekboard_xkl_list_layouts (XklConfigRegistry *registry)
|
||||||
|
{
|
||||||
|
GSList *list = NULL;
|
||||||
|
xkl_config_registry_foreach_layout (registry, prepend_item, &list);
|
||||||
|
return g_slist_sort (list, compare_item_by_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
GSList *
|
||||||
|
eekboard_xkl_list_option_groups (XklConfigRegistry *registry)
|
||||||
|
{
|
||||||
|
GSList *list = NULL;
|
||||||
|
xkl_config_registry_foreach_option_group (registry, prepend_item, &list);
|
||||||
|
return g_slist_sort (list, compare_item_by_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
GSList *
|
||||||
|
eekboard_xkl_list_layout_variants (XklConfigRegistry *registry,
|
||||||
|
const gchar *layout)
|
||||||
|
{
|
||||||
|
GSList *list = NULL;
|
||||||
|
xkl_config_registry_foreach_layout_variant (registry,
|
||||||
|
layout,
|
||||||
|
prepend_item,
|
||||||
|
&list);
|
||||||
|
return g_slist_sort (list, compare_item_by_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
GSList *
|
||||||
|
eekboard_xkl_list_options (XklConfigRegistry *registry,
|
||||||
|
const gchar *group)
|
||||||
|
{
|
||||||
|
GSList *list = NULL;
|
||||||
|
xkl_config_registry_foreach_option (registry, group, prepend_item, &list);
|
||||||
|
return g_slist_sort (list, compare_item_by_name);
|
||||||
|
}
|
||||||
39
eekboard/eekboard-xklutil.h
Normal file
39
eekboard/eekboard-xklutil.h
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2011 Daiki Ueno <ueno@unixuser.org>
|
||||||
|
* Copyright (C) 2011 Red Hat, Inc.
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2 of
|
||||||
|
* the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library 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
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||||
|
* 02110-1301 USA
|
||||||
|
*/
|
||||||
|
#ifndef EEKBOARD_XKLUTIL_H
|
||||||
|
#define EEKBOARD_XKLUTIL_H 1
|
||||||
|
|
||||||
|
#include <libxklavier/xklavier.h>
|
||||||
|
|
||||||
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
XklConfigRec *eekboard_xkl_config_rec_from_string (const gchar *layouts);
|
||||||
|
gchar *eekboard_xkl_config_rec_to_string (XklConfigRec *rec);
|
||||||
|
|
||||||
|
GSList *eekboard_xkl_list_models (XklConfigRegistry *registry);
|
||||||
|
GSList *eekboard_xkl_list_layouts (XklConfigRegistry *registry);
|
||||||
|
GSList *eekboard_xkl_list_option_groups (XklConfigRegistry *registry);
|
||||||
|
GSList *eekboard_xkl_list_layout_variants (XklConfigRegistry *registry,
|
||||||
|
const gchar *layout);
|
||||||
|
GSList *eekboard_xkl_list_options (XklConfigRegistry *registry,
|
||||||
|
const gchar *group);
|
||||||
|
|
||||||
|
G_END_DECLS
|
||||||
|
#endif /* EEKBOARD_XKLUTIL_H */
|
||||||
@ -78,13 +78,15 @@ replace_keycode (SeatEmitter *emitter,
|
|||||||
guint keycode,
|
guint keycode,
|
||||||
guint *keysym)
|
guint *keysym)
|
||||||
{
|
{
|
||||||
/* GdkDisplay *display = gdk_display_get_default ();
|
#if 0 // ===== REMOVAL NOTICE ==== expires by: 2019-08-20 -Wunused-variable =====
|
||||||
Display *xdisplay = GDK_DISPLAY_XDISPLAY (display);
|
GdkDisplay *display = gdk_display_get_default ();
|
||||||
|
//Display *xdisplay = GDK_DISPLAY_XDISPLAY (display);
|
||||||
guint old_keysym;
|
guint old_keysym;
|
||||||
int keysyms_per_keycode;
|
int keysyms_per_keycode;
|
||||||
KeySym *syms;
|
#endif // ===== REMOVAL NOTICE ==== expires by: 2019-08-20 -Wunused-variable =====
|
||||||
*/
|
|
||||||
return TRUE; // FIXME: no xkb allocated at the moment, pretending all is fine
|
return TRUE; // FIXME: no xkb allocated at the moment, pretending all is fine
|
||||||
|
|
||||||
g_return_val_if_fail (emitter->xkb->min_key_code <= keycode &&
|
g_return_val_if_fail (emitter->xkb->min_key_code <= keycode &&
|
||||||
keycode <= emitter->xkb->max_key_code,
|
keycode <= emitter->xkb->max_key_code,
|
||||||
FALSE);
|
FALSE);
|
||||||
@ -284,26 +286,6 @@ update_modifier_info (SeatEmitter *client)
|
|||||||
}*/
|
}*/
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
send_fake_key (SeatEmitter *emitter,
|
|
||||||
EekKeyboard *keyboard,
|
|
||||||
guint keycode,
|
|
||||||
guint keyboard_modifiers,
|
|
||||||
gboolean pressed,
|
|
||||||
uint32_t timestamp)
|
|
||||||
{
|
|
||||||
uint32_t proto_modifiers = 0;
|
|
||||||
guint level = eek_element_get_level(EEK_ELEMENT(keyboard));
|
|
||||||
uint32_t group = (level / 2);
|
|
||||||
|
|
||||||
if (keyboard_modifiers & EEK_SHIFT_MASK)
|
|
||||||
proto_modifiers |= 1<<MOD_IDX_SHIFT;
|
|
||||||
|
|
||||||
zwp_virtual_keyboard_v1_modifiers(emitter->virtual_keyboard, proto_modifiers, 0, 0, group);
|
|
||||||
send_virtual_keyboard_key (emitter->virtual_keyboard, keycode - 8, (unsigned)pressed, timestamp);
|
|
||||||
zwp_virtual_keyboard_v1_modifiers(emitter->virtual_keyboard, proto_modifiers, 0, 0, group);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
emit_key_activated (EekboardContextService *manager,
|
emit_key_activated (EekboardContextService *manager,
|
||||||
EekKeyboard *keyboard,
|
EekKeyboard *keyboard,
|
||||||
@ -344,5 +326,5 @@ emit_key_activated (EekboardContextService *manager,
|
|||||||
emitter.virtual_keyboard = manager->virtual_keyboard;
|
emitter.virtual_keyboard = manager->virtual_keyboard;
|
||||||
emitter.keymap = keyboard->keymap;
|
emitter.keymap = keyboard->keymap;
|
||||||
update_modifier_info (&emitter);
|
update_modifier_info (&emitter);
|
||||||
send_fake_key (&emitter, keyboard, keycode, modifiers, pressed, timestamp);
|
send_fake_key_events (&emitter, symbol, modifiers, pressed, timestamp);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
#include <glib.h>
|
#include <glib.h>
|
||||||
|
#include <X11/XKBlib.h>
|
||||||
|
|
||||||
#include "eek/eek.h"
|
#include "eek/eek.h"
|
||||||
|
|
||||||
|
|||||||
21
meson.build
21
meson.build
@ -3,18 +3,12 @@ project(
|
|||||||
'c', 'rust',
|
'c', 'rust',
|
||||||
version: '1.0.10',
|
version: '1.0.10',
|
||||||
license: 'GPLv3',
|
license: 'GPLv3',
|
||||||
meson_version: '>=0.49.0',
|
meson_version: '>=0.43.0',
|
||||||
default_options: [
|
default_options: [ 'warning_level=1', 'buildtype=debugoptimized', 'c_std=gnu11' ],
|
||||||
'warning_level=1',
|
|
||||||
'buildtype=debugoptimized',
|
|
||||||
'c_std=gnu11'
|
|
||||||
]
|
|
||||||
)
|
)
|
||||||
|
|
||||||
i18n = import('i18n')
|
i18n = import('i18n')
|
||||||
|
|
||||||
conf_data = configuration_data()
|
|
||||||
|
|
||||||
if get_option('buildtype').startswith('debug')
|
if get_option('buildtype').startswith('debug')
|
||||||
add_project_arguments('-DDEBUG=1', language : 'c')
|
add_project_arguments('-DDEBUG=1', language : 'c')
|
||||||
endif
|
endif
|
||||||
@ -32,19 +26,8 @@ else
|
|||||||
endif
|
endif
|
||||||
dbusdir = join_paths(depdatadir, 'dbus-1/interfaces')
|
dbusdir = join_paths(depdatadir, 'dbus-1/interfaces')
|
||||||
|
|
||||||
summary = [
|
|
||||||
'',
|
|
||||||
'------------------',
|
|
||||||
'squeekboard @0@'.format(meson.project_version()),
|
|
||||||
'',
|
|
||||||
'------------------',
|
|
||||||
''
|
|
||||||
]
|
|
||||||
message('\n'.join(summary))
|
|
||||||
|
|
||||||
subdir('data')
|
subdir('data')
|
||||||
subdir('protocols')
|
subdir('protocols')
|
||||||
subdir('eek')
|
subdir('eek')
|
||||||
subdir('src')
|
subdir('src')
|
||||||
subdir('po')
|
subdir('po')
|
||||||
subdir('tests')
|
|
||||||
|
|||||||
@ -1,8 +1 @@
|
|||||||
option('depdatadir',
|
option('depdatadir', type : 'string', value : '', description : 'System data path. Will be searched for definitions instead of datadir when provided')
|
||||||
type : 'string',
|
|
||||||
value : '',
|
|
||||||
description : 'System data path. Will be searched for definitions instead of datadir when provided')
|
|
||||||
|
|
||||||
option('tests',
|
|
||||||
type: 'boolean', value: true,
|
|
||||||
description: 'Whether to compile unit tests')
|
|
||||||
|
|||||||
@ -14,7 +14,6 @@ wl_protos = [
|
|||||||
'wlr-layer-shell-unstable-v1.xml',
|
'wlr-layer-shell-unstable-v1.xml',
|
||||||
'virtual-keyboard-unstable-v1.xml',
|
'virtual-keyboard-unstable-v1.xml',
|
||||||
'input-method-unstable-v2.xml',
|
'input-method-unstable-v2.xml',
|
||||||
'text-input-unstable-v3.xml'
|
|
||||||
]
|
]
|
||||||
wl_proto_sources = []
|
wl_proto_sources = []
|
||||||
foreach proto: wl_protos
|
foreach proto: wl_protos
|
||||||
|
|||||||
@ -1,441 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
|
|
||||||
<protocol name="text_input_unstable_v3">
|
|
||||||
<copyright>
|
|
||||||
Copyright © 2012, 2013 Intel Corporation
|
|
||||||
Copyright © 2015, 2016 Jan Arne Petersen
|
|
||||||
Copyright © 2017, 2018 Red Hat, Inc.
|
|
||||||
Copyright © 2018 Purism SPC
|
|
||||||
|
|
||||||
Permission to use, copy, modify, distribute, and sell this
|
|
||||||
software and its documentation for any purpose is hereby granted
|
|
||||||
without fee, provided that the above copyright notice appear in
|
|
||||||
all copies and that both that copyright notice and this permission
|
|
||||||
notice appear in supporting documentation, and that the name of
|
|
||||||
the copyright holders not be used in advertising or publicity
|
|
||||||
pertaining to distribution of the software without specific,
|
|
||||||
written prior permission. The copyright holders make no
|
|
||||||
representations about the suitability of this software for any
|
|
||||||
purpose. It is provided "as is" without express or implied
|
|
||||||
warranty.
|
|
||||||
|
|
||||||
THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
|
|
||||||
SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
|
||||||
FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
|
||||||
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
||||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
|
|
||||||
AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
|
|
||||||
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
|
|
||||||
THIS SOFTWARE.
|
|
||||||
</copyright>
|
|
||||||
|
|
||||||
<description summary="Protocol for composing text">
|
|
||||||
This protocol allows compositors to act as input methods and to send text
|
|
||||||
to applications. A text input object is used to manage state of what are
|
|
||||||
typically text entry fields in the application.
|
|
||||||
|
|
||||||
This document adheres to the RFC 2119 when using words like "must",
|
|
||||||
"should", "may", etc.
|
|
||||||
|
|
||||||
Warning! The protocol described in this file is experimental and
|
|
||||||
backward incompatible changes may be made. Backward compatible changes
|
|
||||||
may be added together with the corresponding interface version bump.
|
|
||||||
Backward incompatible changes are done by bumping the version number in
|
|
||||||
the protocol and interface names and resetting the interface version.
|
|
||||||
Once the protocol is to be declared stable, the 'z' prefix and the
|
|
||||||
version number in the protocol and interface names are removed and the
|
|
||||||
interface version number is reset.
|
|
||||||
</description>
|
|
||||||
|
|
||||||
<interface name="zwp_text_input_v3" version="1">
|
|
||||||
<description summary="text input">
|
|
||||||
The zwp_text_input_v3 interface represents text input and input methods
|
|
||||||
associated with a seat. It provides enter/leave events to follow the
|
|
||||||
text input focus for a seat.
|
|
||||||
|
|
||||||
Requests are used to enable/disable the text-input object and set
|
|
||||||
state information like surrounding and selected text or the content type.
|
|
||||||
The information about the entered text is sent to the text-input object
|
|
||||||
via the preedit_string and commit_string events.
|
|
||||||
|
|
||||||
Text is valid UTF-8 encoded, indices and lengths are in bytes. Indices
|
|
||||||
must not point to middle bytes inside a code point: they must either
|
|
||||||
point to the first byte of a code point or to the end of the buffer.
|
|
||||||
Lengths must be measured between two valid indices.
|
|
||||||
|
|
||||||
Focus moving throughout surfaces will result in the emission of
|
|
||||||
zwp_text_input_v3.enter and zwp_text_input_v3.leave events. The focused
|
|
||||||
surface must commit zwp_text_input_v3.enable and
|
|
||||||
zwp_text_input_v3.disable requests as the keyboard focus moves across
|
|
||||||
editable and non-editable elements of the UI. Those two requests are not
|
|
||||||
expected to be paired with each other, the compositor must be able to
|
|
||||||
handle consecutive series of the same request.
|
|
||||||
|
|
||||||
State is sent by the state requests (set_surrounding_text,
|
|
||||||
set_content_type and set_cursor_rectangle) and a commit request. After an
|
|
||||||
enter event or disable request all state information is invalidated and
|
|
||||||
needs to be resent by the client.
|
|
||||||
</description>
|
|
||||||
|
|
||||||
<request name="destroy" type="destructor">
|
|
||||||
<description summary="Destroy the wp_text_input">
|
|
||||||
Destroy the wp_text_input object. Also disables all surfaces enabled
|
|
||||||
through this wp_text_input object.
|
|
||||||
</description>
|
|
||||||
</request>
|
|
||||||
|
|
||||||
<request name="enable">
|
|
||||||
<description summary="Request text input to be enabled">
|
|
||||||
Requests text input on the surface previously obtained from the enter
|
|
||||||
event.
|
|
||||||
|
|
||||||
This request must be issued every time the active text input changes
|
|
||||||
to a new one, including within the current surface. Use
|
|
||||||
zwp_text_input_v3.disable when there is no longer any input focus on
|
|
||||||
the current surface.
|
|
||||||
|
|
||||||
This request resets all state associated with previous enable, disable,
|
|
||||||
set_surrounding_text, set_text_change_cause, set_content_type, and
|
|
||||||
set_cursor_rectangle requests, as well as the state associated with
|
|
||||||
preedit_string, commit_string, and delete_surrounding_text events.
|
|
||||||
|
|
||||||
The set_surrounding_text, set_content_type and set_cursor_rectangle
|
|
||||||
requests must follow if the text input supports the necessary
|
|
||||||
functionality.
|
|
||||||
|
|
||||||
State set with this request is double-buffered. It will get applied on
|
|
||||||
the next zwp_text_input_v3.commit request, and stay valid until the
|
|
||||||
next committed enable or disable request.
|
|
||||||
|
|
||||||
The changes must be applied by the compositor after issuing a
|
|
||||||
zwp_text_input_v3.commit request.
|
|
||||||
</description>
|
|
||||||
</request>
|
|
||||||
|
|
||||||
<request name="disable">
|
|
||||||
<description summary="Disable text input on a surface">
|
|
||||||
Explicitly disable text input on the current surface (typically when
|
|
||||||
there is no focus on any text entry inside the surface).
|
|
||||||
|
|
||||||
State set with this request is double-buffered. It will get applied on
|
|
||||||
the next zwp_text_input_v3.commit request.
|
|
||||||
</description>
|
|
||||||
</request>
|
|
||||||
|
|
||||||
<request name="set_surrounding_text">
|
|
||||||
<description summary="sets the surrounding text">
|
|
||||||
Sets the surrounding plain text around the input, excluding the preedit
|
|
||||||
text.
|
|
||||||
|
|
||||||
The client should notify the compositor of any changes in any of the
|
|
||||||
values carried with this request, including changes caused by handling
|
|
||||||
incoming text-input events as well as changes caused by other
|
|
||||||
mechanisms like keyboard typing.
|
|
||||||
|
|
||||||
If the client is unaware of the text around the cursor, it should not
|
|
||||||
issue this request, to signify lack of support to the compositor.
|
|
||||||
|
|
||||||
Text is UTF-8 encoded, and should include the cursor position, the
|
|
||||||
complete selection and additional characters before and after them.
|
|
||||||
There is a maximum length of wayland messages, so text can not be
|
|
||||||
longer than 4000 bytes.
|
|
||||||
|
|
||||||
Cursor is the byte offset of the cursor within text buffer.
|
|
||||||
|
|
||||||
Anchor is the byte offset of the selection anchor within text buffer.
|
|
||||||
If there is no selected text, anchor is the same as cursor.
|
|
||||||
|
|
||||||
If any preedit text is present, it is replaced with a cursor for the
|
|
||||||
purpose of this event.
|
|
||||||
|
|
||||||
Values set with this request are double-buffered. They will get applied
|
|
||||||
on the next zwp_text_input_v3.commit request, and stay valid until the
|
|
||||||
next committed enable or disable request.
|
|
||||||
|
|
||||||
The initial state for affected fields is empty, meaning that the text
|
|
||||||
input does not support sending surrounding text. If the empty values
|
|
||||||
get applied, subsequent attempts to change them may have no effect.
|
|
||||||
</description>
|
|
||||||
<arg name="text" type="string"/>
|
|
||||||
<arg name="cursor" type="int"/>
|
|
||||||
<arg name="anchor" type="int"/>
|
|
||||||
</request>
|
|
||||||
|
|
||||||
<enum name="change_cause">
|
|
||||||
<description summary="text change reason">
|
|
||||||
Reason for the change of surrounding text or cursor posision.
|
|
||||||
</description>
|
|
||||||
<entry name="input_method" value="0" summary="input method caused the change"/>
|
|
||||||
<entry name="other" value="1" summary="something else than the input method caused the change"/>
|
|
||||||
</enum>
|
|
||||||
|
|
||||||
<request name="set_text_change_cause">
|
|
||||||
<description summary="indicates the cause of surrounding text change">
|
|
||||||
Tells the compositor why the text surrounding the cursor changed.
|
|
||||||
|
|
||||||
Whenever the client detects an external change in text, cursor, or
|
|
||||||
anchor posision, it must issue this request to the compositor. This
|
|
||||||
request is intended to give the input method a chance to update the
|
|
||||||
preedit text in an appropriate way, e.g. by removing it when the user
|
|
||||||
starts typing with a keyboard.
|
|
||||||
|
|
||||||
cause describes the source of the change.
|
|
||||||
|
|
||||||
The value set with this request is double-buffered. It must be applied
|
|
||||||
and reset to initial at the next zwp_text_input_v3.commit request.
|
|
||||||
|
|
||||||
The initial value of cause is input_method.
|
|
||||||
</description>
|
|
||||||
<arg name="cause" type="uint" enum="change_cause"/>
|
|
||||||
</request>
|
|
||||||
|
|
||||||
<enum name="content_hint" bitfield="true">
|
|
||||||
<description summary="content hint">
|
|
||||||
Content hint is a bitmask to allow to modify the behavior of the text
|
|
||||||
input.
|
|
||||||
</description>
|
|
||||||
<entry name="none" value="0x0" summary="no special behavior"/>
|
|
||||||
<entry name="completion" value="0x1" summary="suggest word completions"/>
|
|
||||||
<entry name="spellcheck" value="0x2" summary="suggest word corrections"/>
|
|
||||||
<entry name="auto_capitalization" value="0x4" summary="switch to uppercase letters at the start of a sentence"/>
|
|
||||||
<entry name="lowercase" value="0x8" summary="prefer lowercase letters"/>
|
|
||||||
<entry name="uppercase" value="0x10" summary="prefer uppercase letters"/>
|
|
||||||
<entry name="titlecase" value="0x20" summary="prefer casing for titles and headings (can be language dependent)"/>
|
|
||||||
<entry name="hidden_text" value="0x40" summary="characters should be hidden"/>
|
|
||||||
<entry name="sensitive_data" value="0x80" summary="typed text should not be stored"/>
|
|
||||||
<entry name="latin" value="0x100" summary="just Latin characters should be entered"/>
|
|
||||||
<entry name="multiline" value="0x200" summary="the text input is multiline"/>
|
|
||||||
</enum>
|
|
||||||
|
|
||||||
<enum name="content_purpose">
|
|
||||||
<description summary="content purpose">
|
|
||||||
The content purpose allows to specify the primary purpose of a text
|
|
||||||
input.
|
|
||||||
|
|
||||||
This allows an input method to show special purpose input panels with
|
|
||||||
extra characters or to disallow some characters.
|
|
||||||
</description>
|
|
||||||
<entry name="normal" value="0" summary="default input, allowing all characters"/>
|
|
||||||
<entry name="alpha" value="1" summary="allow only alphabetic characters"/>
|
|
||||||
<entry name="digits" value="2" summary="allow only digits"/>
|
|
||||||
<entry name="number" value="3" summary="input a number (including decimal separator and sign)"/>
|
|
||||||
<entry name="phone" value="4" summary="input a phone number"/>
|
|
||||||
<entry name="url" value="5" summary="input an URL"/>
|
|
||||||
<entry name="email" value="6" summary="input an email address"/>
|
|
||||||
<entry name="name" value="7" summary="input a name of a person"/>
|
|
||||||
<entry name="password" value="8" summary="input a password (combine with sensitive_data hint)"/>
|
|
||||||
<entry name="pin" value="9" summary="input is a numeric password (combine with sensitive_data hint)"/>
|
|
||||||
<entry name="date" value="10" summary="input a date"/>
|
|
||||||
<entry name="time" value="11" summary="input a time"/>
|
|
||||||
<entry name="datetime" value="12" summary="input a date and time"/>
|
|
||||||
<entry name="terminal" value="13" summary="input for a terminal"/>
|
|
||||||
</enum>
|
|
||||||
|
|
||||||
<request name="set_content_type">
|
|
||||||
<description summary="set content purpose and hint">
|
|
||||||
Sets the content purpose and content hint. While the purpose is the
|
|
||||||
basic purpose of an input field, the hint flags allow to modify some of
|
|
||||||
the behavior.
|
|
||||||
|
|
||||||
Values set with this request are double-buffered. They will get applied
|
|
||||||
on the next zwp_text_input_v3.commit request.
|
|
||||||
Subsequent attempts to update them may have no effect. The values
|
|
||||||
remain valid until the next committed enable or disable request.
|
|
||||||
|
|
||||||
The initial value for hint is none, and the initial value for purpose
|
|
||||||
is normal.
|
|
||||||
</description>
|
|
||||||
<arg name="hint" type="uint" enum="content_hint"/>
|
|
||||||
<arg name="purpose" type="uint" enum="content_purpose"/>
|
|
||||||
</request>
|
|
||||||
|
|
||||||
<request name="set_cursor_rectangle">
|
|
||||||
<description summary="set cursor position">
|
|
||||||
Marks an area around the cursor as a x, y, width, height rectangle in
|
|
||||||
surface local coordinates.
|
|
||||||
|
|
||||||
Allows the compositor to put a window with word suggestions near the
|
|
||||||
cursor, without obstructing the text being input.
|
|
||||||
|
|
||||||
If the client is unaware of the position of edited text, it should not
|
|
||||||
issue this request, to signify lack of support to the compositor.
|
|
||||||
|
|
||||||
Values set with this request are double-buffered. They will get applied
|
|
||||||
on the next zwp_text_input_v3.commit request, and stay valid until the
|
|
||||||
next committed enable or disable request.
|
|
||||||
|
|
||||||
The initial values describing a cursor rectangle are empty. That means
|
|
||||||
the text input does not support describing the cursor area. If the
|
|
||||||
empty values get applied, subsequent attempts to change them may have
|
|
||||||
no effect.
|
|
||||||
</description>
|
|
||||||
<arg name="x" type="int"/>
|
|
||||||
<arg name="y" type="int"/>
|
|
||||||
<arg name="width" type="int"/>
|
|
||||||
<arg name="height" type="int"/>
|
|
||||||
</request>
|
|
||||||
|
|
||||||
<request name="commit">
|
|
||||||
<description summary="commit state">
|
|
||||||
Atomically applies state changes recently sent to the compositor.
|
|
||||||
|
|
||||||
The commit request establishes and updates the state of the client, and
|
|
||||||
must be issued after any changes to apply them.
|
|
||||||
|
|
||||||
Text input state (enabled status, content purpose, content hint,
|
|
||||||
surrounding text and change cause, cursor rectangle) is conceptually
|
|
||||||
double-buffered within the context of a text input, i.e. between a
|
|
||||||
committed enable request and the following committed enable or disable
|
|
||||||
request.
|
|
||||||
|
|
||||||
Protocol requests modify the pending state, as opposed to the current
|
|
||||||
state in use by the input method. A commit request atomically applies
|
|
||||||
all pending state, replacing the current state. After commit, the new
|
|
||||||
pending state is as documented for each related request.
|
|
||||||
|
|
||||||
Requests are applied in the order of arrival.
|
|
||||||
|
|
||||||
Neither current nor pending state are modified unless noted otherwise.
|
|
||||||
|
|
||||||
The compositor must count the number of commit requests coming from
|
|
||||||
each zwp_text_input_v3 object and use the count as the serial in done
|
|
||||||
events.
|
|
||||||
</description>
|
|
||||||
</request>
|
|
||||||
|
|
||||||
<event name="enter">
|
|
||||||
<description summary="enter event">
|
|
||||||
Notification that this seat's text-input focus is on a certain surface.
|
|
||||||
|
|
||||||
When the seat has the keyboard capability the text-input focus follows
|
|
||||||
the keyboard focus. This event sets the current surface for the
|
|
||||||
text-input object.
|
|
||||||
</description>
|
|
||||||
<arg name="surface" type="object" interface="wl_surface"/>
|
|
||||||
</event>
|
|
||||||
|
|
||||||
<event name="leave">
|
|
||||||
<description summary="leave event">
|
|
||||||
Notification that this seat's text-input focus is no longer on a
|
|
||||||
certain surface. The client should reset any preedit string previously
|
|
||||||
set.
|
|
||||||
|
|
||||||
The leave notification clears the current surface. It is sent before
|
|
||||||
the enter notification for the new focus.
|
|
||||||
|
|
||||||
When the seat has the keyboard capability the text-input focus follows
|
|
||||||
the keyboard focus.
|
|
||||||
</description>
|
|
||||||
<arg name="surface" type="object" interface="wl_surface"/>
|
|
||||||
</event>
|
|
||||||
|
|
||||||
<event name="preedit_string">
|
|
||||||
<description summary="pre-edit">
|
|
||||||
Notify when a new composing text (pre-edit) should be set at the
|
|
||||||
current cursor position. Any previously set composing text must be
|
|
||||||
removed. Any previously existing selected text must be removed.
|
|
||||||
|
|
||||||
The argument text contains the pre-edit string buffer.
|
|
||||||
|
|
||||||
The parameters cursor_begin and cursor_end are counted in bytes
|
|
||||||
relative to the beginning of the submitted text buffer. Cursor should
|
|
||||||
be hidden when both are equal to -1.
|
|
||||||
|
|
||||||
They could be represented by the client as a line if both values are
|
|
||||||
the same, or as a text highlight otherwise.
|
|
||||||
|
|
||||||
Values set with this event are double-buffered. They must be applied
|
|
||||||
and reset to initial on the next zwp_text_input_v3.done event.
|
|
||||||
|
|
||||||
The initial value of text is an empty string, and cursor_begin,
|
|
||||||
cursor_end and cursor_hidden are all 0.
|
|
||||||
</description>
|
|
||||||
<arg name="text" type="string" allow-null="true"/>
|
|
||||||
<arg name="cursor_begin" type="int"/>
|
|
||||||
<arg name="cursor_end" type="int"/>
|
|
||||||
</event>
|
|
||||||
|
|
||||||
<event name="commit_string">
|
|
||||||
<description summary="text commit">
|
|
||||||
Notify when text should be inserted into the editor widget. The text to
|
|
||||||
commit could be either just a single character after a key press or the
|
|
||||||
result of some composing (pre-edit).
|
|
||||||
|
|
||||||
Values set with this event are double-buffered. They must be applied
|
|
||||||
and reset to initial on the next zwp_text_input_v3.done event.
|
|
||||||
|
|
||||||
The initial value of text is an empty string.
|
|
||||||
</description>
|
|
||||||
<arg name="text" type="string" allow-null="true"/>
|
|
||||||
</event>
|
|
||||||
|
|
||||||
<event name="delete_surrounding_text">
|
|
||||||
<description summary="delete surrounding text">
|
|
||||||
Notify when the text around the current cursor position should be
|
|
||||||
deleted.
|
|
||||||
|
|
||||||
Before_length and after_length are the number of bytes before and after
|
|
||||||
the current cursor index (excluding the selection) to delete.
|
|
||||||
|
|
||||||
If a preedit text is present, in effect before_length is counted from
|
|
||||||
the beginning of it, and after_length from its end (see done event
|
|
||||||
sequence).
|
|
||||||
|
|
||||||
Values set with this event are double-buffered. They must be applied
|
|
||||||
and reset to initial on the next zwp_text_input_v3.done event.
|
|
||||||
|
|
||||||
The initial values of both before_length and after_length are 0.
|
|
||||||
</description>
|
|
||||||
<arg name="before_length" type="uint" summary="length of text before current cursor position"/>
|
|
||||||
<arg name="after_length" type="uint" summary="length of text after current cursor position"/>
|
|
||||||
</event>
|
|
||||||
|
|
||||||
<event name="done">
|
|
||||||
<description summary="apply changes">
|
|
||||||
Instruct the application to apply changes to state requested by the
|
|
||||||
preedit_string, commit_string and delete_surrounding_text events. The
|
|
||||||
state relating to these events is double-buffered, and each one
|
|
||||||
modifies the pending state. This event replaces the current state with
|
|
||||||
the pending state.
|
|
||||||
|
|
||||||
The application must proceed by evaluating the changes in the following
|
|
||||||
order:
|
|
||||||
|
|
||||||
1. Replace existing preedit string with the cursor.
|
|
||||||
2. Delete requested surrounding text.
|
|
||||||
3. Insert commit string with the cursor at its end.
|
|
||||||
4. Calculate surrounding text to send.
|
|
||||||
5. Insert new preedit text in cursor position.
|
|
||||||
6. Place cursor inside preedit text.
|
|
||||||
|
|
||||||
The serial number reflects the last state of the zwp_text_input_v3
|
|
||||||
object known to the compositor. The value of the serial argument must
|
|
||||||
be equal to the number of commit requests already issued on that object.
|
|
||||||
When the client receives a done event with a serial different than the
|
|
||||||
number of past commit requests, it must proceed as normal, except it
|
|
||||||
should not change the current state of the zwp_text_input_v3 object.
|
|
||||||
</description>
|
|
||||||
<arg name="serial" type="uint"/>
|
|
||||||
</event>
|
|
||||||
</interface>
|
|
||||||
|
|
||||||
<interface name="zwp_text_input_manager_v3" version="1">
|
|
||||||
<description summary="text input manager">
|
|
||||||
A factory for text-input objects. This object is a global singleton.
|
|
||||||
</description>
|
|
||||||
|
|
||||||
<request name="destroy" type="destructor">
|
|
||||||
<description summary="Destroy the wp_text_input_manager">
|
|
||||||
Destroy the wp_text_input_manager object.
|
|
||||||
</description>
|
|
||||||
</request>
|
|
||||||
|
|
||||||
<request name="get_text_input">
|
|
||||||
<description summary="create a new text input object">
|
|
||||||
Creates a new text-input object for a given seat.
|
|
||||||
</description>
|
|
||||||
<arg name="id" type="new_id" interface="zwp_text_input_v3"/>
|
|
||||||
<arg name="seat" type="object" interface="wl_seat"/>
|
|
||||||
</request>
|
|
||||||
</interface>
|
|
||||||
</protocol>
|
|
||||||
320
src/client-main.c
Normal file
320
src/client-main.c
Normal file
@ -0,0 +1,320 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2010-2011 Daiki Ueno <ueno@unixuser.org>
|
||||||
|
* Copyright (C) 2010-2011 Red Hat, Inc.
|
||||||
|
*
|
||||||
|
* 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 3 of the License, 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, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "config.h"
|
||||||
|
#endif /* HAVE_CONFIG_H */
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#ifdef HAVE_ATSPI
|
||||||
|
#include <dbus/dbus.h>
|
||||||
|
#include <atspi/atspi.h>
|
||||||
|
#endif /* HAVE_ATSPI */
|
||||||
|
#ifdef HAVE_IBUS
|
||||||
|
#include <ibus.h>
|
||||||
|
#endif /* HAVE_IBUS */
|
||||||
|
#include <gtk/gtk.h>
|
||||||
|
#include <glib/gi18n.h>
|
||||||
|
#include "eekboard/eekboard-client.h"
|
||||||
|
#include "client.h"
|
||||||
|
|
||||||
|
static gboolean opt_system = FALSE;
|
||||||
|
static gboolean opt_session = FALSE;
|
||||||
|
static gchar *opt_address = NULL;
|
||||||
|
|
||||||
|
static gboolean opt_focus = FALSE;
|
||||||
|
#ifdef HAVE_ATSPI
|
||||||
|
static gboolean opt_keystroke = FALSE;
|
||||||
|
#endif /* HAVE_ATSPI */
|
||||||
|
|
||||||
|
static gchar *opt_keyboards = NULL;
|
||||||
|
|
||||||
|
static gboolean opt_fullscreen = FALSE;
|
||||||
|
|
||||||
|
static const GOptionEntry options[] = {
|
||||||
|
{"system", 'y', 0, G_OPTION_ARG_NONE, &opt_system,
|
||||||
|
N_("Connect to the system bus")},
|
||||||
|
{"session", 'e', 0, G_OPTION_ARG_NONE, &opt_session,
|
||||||
|
N_("Connect to the session bus")},
|
||||||
|
{"address", 'a', 0, G_OPTION_ARG_STRING, &opt_address,
|
||||||
|
N_("Connect to the given D-Bus address")},
|
||||||
|
#if ENABLE_FOCUS_LISTENER
|
||||||
|
{"listen-focus", 'f', 0, G_OPTION_ARG_NONE, &opt_focus,
|
||||||
|
N_("Listen focus change events")},
|
||||||
|
#endif /* ENABLE_FOCUS_LISTENER */
|
||||||
|
#ifdef HAVE_ATSPI
|
||||||
|
{"listen-keystroke", 's', 0, G_OPTION_ARG_NONE, &opt_keystroke,
|
||||||
|
N_("Listen keystroke events with AT-SPI")},
|
||||||
|
#endif /* HAVE_ATSPI */
|
||||||
|
{"keyboards", 'k', 0, G_OPTION_ARG_STRING, &opt_keyboards,
|
||||||
|
N_("Specify keyboards (comma separated)")},
|
||||||
|
{"fullscreen", 'F', 0, G_OPTION_ARG_NONE, &opt_fullscreen,
|
||||||
|
N_("Create window in fullscreen mode")},
|
||||||
|
{NULL}
|
||||||
|
};
|
||||||
|
|
||||||
|
static void
|
||||||
|
on_context_destroyed (EekboardContext *context,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
gtk_main_quit ();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
on_destroyed (EekboardClient *eekboard,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
gtk_main_quit ();
|
||||||
|
}
|
||||||
|
|
||||||
|
enum FocusListenerType {
|
||||||
|
FOCUS_NONE,
|
||||||
|
FOCUS_ATSPI,
|
||||||
|
FOCUS_IBUS
|
||||||
|
};
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
set_keyboards (SeatEmitter *client,
|
||||||
|
const gchar * const *keyboards)
|
||||||
|
{
|
||||||
|
if (g_strv_length ((gchar **)keyboards) == 0) {
|
||||||
|
if (!client_enable_xkl (client)) {
|
||||||
|
g_printerr ("Can't register xklavier event listeners\n");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (!client_set_keyboards (client, keyboards)) {
|
||||||
|
gchar *str = g_strjoinv (", ", (gchar **)keyboards);
|
||||||
|
g_printerr ("Can't set keyboards \"%s\"\n", str);
|
||||||
|
g_free (str);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
main (int argc, char **argv)
|
||||||
|
{
|
||||||
|
SeatEmitter *client = NULL;
|
||||||
|
EekboardClient *eekboard;
|
||||||
|
EekboardContext *context;
|
||||||
|
GBusType bus_type;
|
||||||
|
GDBusConnection *connection;
|
||||||
|
GError *error;
|
||||||
|
GOptionContext *option_context;
|
||||||
|
gint focus;
|
||||||
|
GSettings *settings = NULL;
|
||||||
|
gchar **keyboards = NULL;
|
||||||
|
gint retval = 0;
|
||||||
|
|
||||||
|
if (!gtk_init_check (&argc, &argv)) {
|
||||||
|
g_printerr ("Can't init GTK\n");
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
eek_init ();
|
||||||
|
|
||||||
|
option_context = g_option_context_new ("eekboard-desktop-client");
|
||||||
|
g_option_context_add_main_entries (option_context, options, NULL);
|
||||||
|
g_option_context_parse (option_context, &argc, &argv, NULL);
|
||||||
|
g_option_context_free (option_context);
|
||||||
|
|
||||||
|
if (opt_system)
|
||||||
|
bus_type = G_BUS_TYPE_SYSTEM;
|
||||||
|
else if (opt_address)
|
||||||
|
bus_type = G_BUS_TYPE_NONE;
|
||||||
|
else
|
||||||
|
bus_type = G_BUS_TYPE_SESSION;
|
||||||
|
|
||||||
|
switch (bus_type) {
|
||||||
|
case G_BUS_TYPE_SYSTEM:
|
||||||
|
error = NULL;
|
||||||
|
connection = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, &error);
|
||||||
|
if (connection == NULL) {
|
||||||
|
g_printerr ("Can't connect to the system bus: %s\n",
|
||||||
|
error->message);
|
||||||
|
g_error_free (error);
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case G_BUS_TYPE_SESSION:
|
||||||
|
error = NULL;
|
||||||
|
connection = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &error);
|
||||||
|
if (connection == NULL) {
|
||||||
|
g_printerr ("Can't connect to the session bus: %s\n",
|
||||||
|
error->message);
|
||||||
|
g_error_free (error);
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case G_BUS_TYPE_NONE:
|
||||||
|
error = NULL;
|
||||||
|
connection = g_dbus_connection_new_for_address_sync (opt_address,
|
||||||
|
0,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
&error);
|
||||||
|
if (connection == NULL) {
|
||||||
|
g_printerr ("Can't connect to the bus at %s: %s\n",
|
||||||
|
opt_address,
|
||||||
|
error->message);
|
||||||
|
g_error_free (error);
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
g_assert_not_reached ();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
client = client_new (connection);
|
||||||
|
g_object_unref (connection);
|
||||||
|
|
||||||
|
if (client == NULL) {
|
||||||
|
g_printerr ("Can't create a client\n");
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
settings = g_settings_new ("org.fedorahosted.eekboard");
|
||||||
|
focus = FOCUS_NONE;
|
||||||
|
if (opt_focus) {
|
||||||
|
gchar *focus_listener = g_settings_get_string (settings,
|
||||||
|
"focus-listener");
|
||||||
|
const struct {
|
||||||
|
const gchar *name;
|
||||||
|
enum FocusListenerType type;
|
||||||
|
} focus_listeners[] = {
|
||||||
|
#ifdef HAVE_ATSPI
|
||||||
|
{ "atspi", FOCUS_ATSPI },
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_IBUS
|
||||||
|
{ "ibus", FOCUS_IBUS },
|
||||||
|
#endif
|
||||||
|
{ NULL }
|
||||||
|
};
|
||||||
|
gint i;
|
||||||
|
|
||||||
|
focus = FOCUS_NONE;
|
||||||
|
for (i = 0; focus_listeners[i].name; i++) {
|
||||||
|
if (g_strcmp0 (focus_listener, focus_listeners[i].name) == 0)
|
||||||
|
focus = focus_listeners[i].type;
|
||||||
|
}
|
||||||
|
if (focus == FOCUS_NONE) {
|
||||||
|
g_printerr ("Unknown focus listener \"%s\". "
|
||||||
|
"Try \"atspi\" or \"ibus\"\n", focus_listener);
|
||||||
|
retval = 1;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef HAVE_ATSPI
|
||||||
|
if (focus == FOCUS_ATSPI || opt_keystroke) {
|
||||||
|
GSettings *desktop_settings =
|
||||||
|
g_settings_new ("org.gnome.desktop.interface");
|
||||||
|
gboolean accessibility_enabled =
|
||||||
|
g_settings_get_boolean (desktop_settings, "toolkit-accessibility");
|
||||||
|
g_object_unref (desktop_settings);
|
||||||
|
|
||||||
|
if (accessibility_enabled) {
|
||||||
|
if (atspi_init () != 0) {
|
||||||
|
g_printerr ("Can't init AT-SPI 2\n");
|
||||||
|
retval = 1;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (focus == FOCUS_ATSPI &&
|
||||||
|
!client_enable_atspi_focus (client)) {
|
||||||
|
g_printerr ("Can't register AT-SPI focus change event listeners\n");
|
||||||
|
retval = 1;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (opt_keystroke &&
|
||||||
|
!client_enable_atspi_keystroke (client)) {
|
||||||
|
g_printerr ("Can't register AT-SPI keystroke event listeners\n");
|
||||||
|
retval = 1;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
g_printerr ("Desktop accessibility support is disabled\n");
|
||||||
|
retval = 1;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif /* HAVE_ATSPI */
|
||||||
|
|
||||||
|
#ifdef HAVE_IBUS
|
||||||
|
if (focus == FOCUS_IBUS) {
|
||||||
|
ibus_init ();
|
||||||
|
|
||||||
|
if (!client_enable_ibus_focus (client)) {
|
||||||
|
g_printerr ("Can't register IBus focus change event listeners\n");
|
||||||
|
retval = 1;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif /* HAVE_IBUS */
|
||||||
|
|
||||||
|
//#ifdef HAVE_XTEST
|
||||||
|
if (!client_enable_xtest (client)) {
|
||||||
|
g_printerr ("Can't init xtest\n");
|
||||||
|
g_object_unref (client);
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
//#endif /* HAVE_XTEST */
|
||||||
|
|
||||||
|
if (!opt_focus) {
|
||||||
|
g_object_get (client, "context", &context, NULL);
|
||||||
|
g_signal_connect (context, "destroyed",
|
||||||
|
G_CALLBACK(on_context_destroyed), NULL);
|
||||||
|
g_object_unref (context);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (opt_fullscreen ||
|
||||||
|
g_settings_get_boolean (settings, "start-fullscreen")) {
|
||||||
|
g_object_get (client, "context", &context, NULL);
|
||||||
|
eekboard_context_set_fullscreen (context, TRUE, NULL);
|
||||||
|
g_object_unref (context);
|
||||||
|
}
|
||||||
|
|
||||||
|
g_object_get (client, "eekboard", &eekboard, NULL);
|
||||||
|
g_signal_connect (eekboard, "destroyed",
|
||||||
|
G_CALLBACK(on_destroyed), NULL);
|
||||||
|
g_object_unref (eekboard);
|
||||||
|
|
||||||
|
if (opt_keyboards != NULL) {
|
||||||
|
keyboards = g_strsplit (opt_keyboards, ",", -1);
|
||||||
|
|
||||||
|
if (!set_keyboards (client, (const gchar * const *)keyboards)) {
|
||||||
|
g_strfreev (keyboards);
|
||||||
|
retval = 1;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
g_strfreev (keyboards);
|
||||||
|
}
|
||||||
|
|
||||||
|
gtk_main ();
|
||||||
|
|
||||||
|
out:
|
||||||
|
if (client)
|
||||||
|
g_object_unref (client);
|
||||||
|
if (settings)
|
||||||
|
g_object_unref (settings);
|
||||||
|
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
1166
src/client.c
Normal file
1166
src/client.c
Normal file
File diff suppressed because it is too large
Load Diff
55
src/client.h
Normal file
55
src/client.h
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2010-2011 Daiki Ueno <ueno@unixuser.org>
|
||||||
|
* Copyright (C) 2010-2011 Red Hat, Inc.
|
||||||
|
*
|
||||||
|
* 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 3 of the License, 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, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
#ifndef CLIENT_H
|
||||||
|
#define CLIENT_H 1
|
||||||
|
|
||||||
|
#include <gio/gio.h>
|
||||||
|
|
||||||
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
#define TYPE_CLIENT (client_get_type())
|
||||||
|
#define CLIENT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_CLIENT, Client))
|
||||||
|
#define CLIENT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_CLIENT, ClientClass))
|
||||||
|
#define IS_CLIENT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_CLIENT))
|
||||||
|
#define IS_CLIENT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_CLIENT))
|
||||||
|
#define CLIENT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TYPE_CLIENT, ClientClass))
|
||||||
|
|
||||||
|
typedef struct _Client SeatEmitter;
|
||||||
|
|
||||||
|
SeatEmitter *client_new (GDBusConnection *connection);
|
||||||
|
|
||||||
|
gboolean client_set_keyboards (SeatEmitter *client,
|
||||||
|
const gchar * const *keyboard);
|
||||||
|
|
||||||
|
gboolean client_enable_xkl (SeatEmitter *client);
|
||||||
|
void client_disable_xkl (SeatEmitter *client);
|
||||||
|
|
||||||
|
gboolean client_enable_atspi_focus (SeatEmitter *client);
|
||||||
|
void client_disable_atspi_focus (SeatEmitter *client);
|
||||||
|
|
||||||
|
gboolean client_enable_atspi_keystroke (SeatEmitter *client);
|
||||||
|
void client_disable_atspi_keystroke (SeatEmitter *client);
|
||||||
|
|
||||||
|
gboolean client_enable_xtest (SeatEmitter *client);
|
||||||
|
void client_disable_xtest (SeatEmitter *client);
|
||||||
|
|
||||||
|
gboolean client_enable_ibus_focus (SeatEmitter *client);
|
||||||
|
void client_disable_ibus_focus (SeatEmitter *client);
|
||||||
|
|
||||||
|
G_END_DECLS
|
||||||
|
#endif /* CLIENT_H */
|
||||||
@ -1,4 +0,0 @@
|
|||||||
/*
|
|
||||||
* Autogenerated by the Meson build system.
|
|
||||||
* Do not edit, your changes will be lost.
|
|
||||||
*/
|
|
||||||
@ -6,15 +6,7 @@
|
|||||||
|
|
||||||
|
|
||||||
void imservice_handle_text_change_cause(void *data, struct zwp_input_method_v2 *input_method, uint32_t cause) {}
|
void imservice_handle_text_change_cause(void *data, struct zwp_input_method_v2 *input_method, uint32_t cause) {}
|
||||||
|
void imservice_handle_content_type(void *data, struct zwp_input_method_v2 *input_method, uint32_t hint, uint32_t purpose) {}
|
||||||
void imservice_handle_content_type(void *data, struct zwp_input_method_v2 *input_method, uint32_t hint, uint32_t purpose)
|
|
||||||
{
|
|
||||||
struct imservice *ims = (struct imservice*)data;
|
|
||||||
EekboardContextService *context = EEKBOARD_CONTEXT_SERVICE(ims->ui_manager);
|
|
||||||
|
|
||||||
eekboard_context_service_set_hint_purpose(context, hint, purpose);
|
|
||||||
}
|
|
||||||
|
|
||||||
void imservice_handle_unavailable(void *data, struct zwp_input_method_v2 *input_method) {}
|
void imservice_handle_unavailable(void *data, struct zwp_input_method_v2 *input_method) {}
|
||||||
|
|
||||||
|
|
||||||
@ -33,11 +25,8 @@ struct imservice* get_imservice(EekboardContextService *context,
|
|||||||
struct wl_seat *seat) {
|
struct wl_seat *seat) {
|
||||||
struct zwp_input_method_v2 *im = zwp_input_method_manager_v2_get_input_method(manager, seat);
|
struct zwp_input_method_v2 *im = zwp_input_method_manager_v2_get_input_method(manager, seat);
|
||||||
struct imservice *imservice = imservice_new(im, context);
|
struct imservice *imservice = imservice_new(im, context);
|
||||||
|
zwp_input_method_v2_add_listener(im,
|
||||||
/* Add a listener, passing the imservice instance to make it available to
|
&input_method_listener, imservice);
|
||||||
callbacks. */
|
|
||||||
zwp_input_method_v2_add_listener(im, &input_method_listener, imservice);
|
|
||||||
|
|
||||||
return imservice;
|
return imservice;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -4,11 +4,7 @@
|
|||||||
#include "input-method-unstable-v2-client-protocol.h"
|
#include "input-method-unstable-v2-client-protocol.h"
|
||||||
#include "eek/eek-types.h"
|
#include "eek/eek-types.h"
|
||||||
|
|
||||||
struct imservice
|
struct imservice;
|
||||||
{
|
|
||||||
struct zwp_input_method_v2 *im;
|
|
||||||
EekboardContextService *ui_manager;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct imservice* get_imservice(EekboardContextService *context,
|
struct imservice* get_imservice(EekboardContextService *context,
|
||||||
struct zwp_input_method_manager_v2 *manager,
|
struct zwp_input_method_manager_v2 *manager,
|
||||||
|
|||||||
@ -1,24 +1,19 @@
|
|||||||
gnome = import('gnome')
|
gnome = import('gnome')
|
||||||
dbus_src = gnome.gdbus_codegen(
|
dbus_src = gnome.gdbus_codegen(
|
||||||
'sm.puri.OSK0',
|
'sm.puri.OSK0',
|
||||||
join_paths(meson.source_root() / 'data' / 'dbus', 'sm.puri.OSK0.xml')
|
join_paths(dbusdir, 'sm.puri.OSK0.xml')
|
||||||
)
|
|
||||||
|
|
||||||
config_h = configure_file(
|
|
||||||
input: 'config.h.in',
|
|
||||||
output: 'config.h',
|
|
||||||
configuration: conf_data
|
|
||||||
)
|
)
|
||||||
|
|
||||||
sources = [
|
sources = [
|
||||||
config_h,
|
|
||||||
'imservice.c',
|
'imservice.c',
|
||||||
'server-context-service.c',
|
'server-context-service.c',
|
||||||
|
'server-main.c',
|
||||||
'wayland.c',
|
'wayland.c',
|
||||||
'../eek/eek.c',
|
'../eek/eek.c',
|
||||||
'../eek/eek-container.c',
|
'../eek/eek-container.c',
|
||||||
'../eek/eek-element.c',
|
'../eek/eek-element.c',
|
||||||
'../eek/eek-gtk-keyboard.c',
|
'../eek/eek-gtk-keyboard.c',
|
||||||
|
'../eek/eek-gtk-renderer.c',
|
||||||
'../eek/eek-key.c',
|
'../eek/eek-key.c',
|
||||||
'../eek/eek-keyboard.c',
|
'../eek/eek-keyboard.c',
|
||||||
'../eek/eek-keyboard-drawing.c',
|
'../eek/eek-keyboard-drawing.c',
|
||||||
@ -45,8 +40,7 @@ sources = [
|
|||||||
'../eekboard/eekboard-context-service.c',
|
'../eekboard/eekboard-context-service.c',
|
||||||
'../eekboard/eekboard-context.c',
|
'../eekboard/eekboard-context.c',
|
||||||
'../eekboard/eekboard-service.c',
|
'../eekboard/eekboard-service.c',
|
||||||
# '../eekboard/eekboard-xklutil.c',
|
# '../eekboard/eekboard-xklutil.c',
|
||||||
squeekboard_resources,
|
|
||||||
wl_proto_sources,
|
wl_proto_sources,
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -74,24 +68,11 @@ rslib = static_library(
|
|||||||
rust_crate_type: 'staticlib'
|
rust_crate_type: 'staticlib'
|
||||||
)
|
)
|
||||||
|
|
||||||
libsqueekboard = static_library('libsqueekboard',
|
squeekboard = executable('squeekboard',
|
||||||
sources,
|
sources,
|
||||||
link_with: rslib,
|
link_with: rslib,
|
||||||
include_directories: [include_directories('..'), include_directories('../eek')],
|
include_directories: [include_directories('..'), include_directories('../eek')],
|
||||||
dependencies: deps,
|
dependencies: deps,
|
||||||
c_args: [
|
|
||||||
'-DTHEMESDIR="' + pkgdatadir + '/themes"',
|
|
||||||
'-DKEYBOARDSDIR="' + pkgdatadir + '/keyboards"',
|
|
||||||
'-DEEKBOARD_COMPILATION=1',
|
|
||||||
'-DEEK_COMPILATION=1'],
|
|
||||||
)
|
|
||||||
|
|
||||||
squeekboard = executable('squeekboard',
|
|
||||||
'server-main.c',
|
|
||||||
wl_proto_sources,
|
|
||||||
link_with: libsqueekboard,
|
|
||||||
include_directories: [include_directories('..'), include_directories('../eek')],
|
|
||||||
dependencies: deps,
|
|
||||||
install: true,
|
install: true,
|
||||||
c_args: [
|
c_args: [
|
||||||
'-DTHEMESDIR="' + pkgdatadir + '/themes"',
|
'-DTHEMESDIR="' + pkgdatadir + '/themes"',
|
||||||
@ -99,3 +80,4 @@ squeekboard = executable('squeekboard',
|
|||||||
'-DEEKBOARD_COMPILATION=1',
|
'-DEEKBOARD_COMPILATION=1',
|
||||||
'-DEEK_COMPILATION=1'],
|
'-DEEK_COMPILATION=1'],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
415
src/preferences-dialog.c
Normal file
415
src/preferences-dialog.c
Normal file
@ -0,0 +1,415 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2011 Daiki Ueno <ueno@unixuser.org>
|
||||||
|
* Copyright (C) 2011 Red Hat, Inc.
|
||||||
|
*
|
||||||
|
* 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 3 of the License, 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, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "config.h"
|
||||||
|
#endif /* HAVE_CONFIG_H */
|
||||||
|
|
||||||
|
#include <gtk/gtk.h>
|
||||||
|
#include "preferences-dialog.h"
|
||||||
|
#include <eek/eek.h>
|
||||||
|
|
||||||
|
struct _PreferencesDialog {
|
||||||
|
GtkWidget *dialog;
|
||||||
|
GtkWidget *repeat_toggle;
|
||||||
|
GtkWidget *repeat_delay_scale;
|
||||||
|
GtkWidget *repeat_speed_scale;
|
||||||
|
GtkWidget *auto_hide_toggle;
|
||||||
|
GtkWidget *auto_hide_delay_scale;
|
||||||
|
GtkWidget *selected_keyboards_treeview;
|
||||||
|
GtkWidget *up_button;
|
||||||
|
GtkWidget *down_button;
|
||||||
|
GtkWidget *add_button;
|
||||||
|
GtkWidget *remove_button;
|
||||||
|
|
||||||
|
GtkWidget *new_keyboard_dialog;
|
||||||
|
GtkWidget *available_keyboards_treeview;
|
||||||
|
|
||||||
|
GList *available_keyboards;
|
||||||
|
GSettings *settings;
|
||||||
|
};
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
get_rate (GValue *value,
|
||||||
|
GVariant *variant,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
int rate;
|
||||||
|
gdouble fraction;
|
||||||
|
|
||||||
|
rate = g_variant_get_uint32 (variant);
|
||||||
|
fraction = 1.0 / ((gdouble) rate / 1000.0);
|
||||||
|
g_value_set_double (value, fraction);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static GVariant *
|
||||||
|
set_rate (const GValue *value,
|
||||||
|
const GVariantType *expected_type,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
gdouble rate;
|
||||||
|
int msecs;
|
||||||
|
|
||||||
|
rate = g_value_get_double (value);
|
||||||
|
msecs = (1 / rate) * 1000;
|
||||||
|
return g_variant_new_uint32 (msecs);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
add_keyboard_to_treeview (GtkTreeView *treeview,
|
||||||
|
const gchar *id,
|
||||||
|
const gchar *longname)
|
||||||
|
{
|
||||||
|
GtkTreeModel *model = gtk_tree_view_get_model (treeview);
|
||||||
|
GtkTreeIter iter;
|
||||||
|
|
||||||
|
if (gtk_tree_model_get_iter_first (model, &iter)) {
|
||||||
|
do {
|
||||||
|
gchar *_id;
|
||||||
|
gtk_tree_model_get (model, &iter, 0, &_id, -1);
|
||||||
|
if (g_strcmp0 (id, _id) == 0) {
|
||||||
|
g_free (_id);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
g_free (_id);
|
||||||
|
} while (gtk_tree_model_iter_next (model, &iter));
|
||||||
|
}
|
||||||
|
|
||||||
|
gtk_list_store_append (GTK_LIST_STORE(model),
|
||||||
|
&iter);
|
||||||
|
gtk_list_store_set (GTK_LIST_STORE(model),
|
||||||
|
&iter,
|
||||||
|
0, id,
|
||||||
|
1, longname,
|
||||||
|
-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
add_keyboard (GtkWidget *button, PreferencesDialog *dialog)
|
||||||
|
{
|
||||||
|
gint retval = gtk_dialog_run (GTK_DIALOG(dialog->new_keyboard_dialog));
|
||||||
|
if (retval == GTK_RESPONSE_OK) {
|
||||||
|
GtkTreeSelection *selection;
|
||||||
|
GtkTreeModel *model;
|
||||||
|
GList *rows, *p;
|
||||||
|
|
||||||
|
selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(dialog->available_keyboards_treeview));
|
||||||
|
rows = gtk_tree_selection_get_selected_rows (selection, &model);
|
||||||
|
for (p = rows; p; p = p->next) {
|
||||||
|
GtkTreeIter iter;
|
||||||
|
if (gtk_tree_model_get_iter (model, &iter, p->data)) {
|
||||||
|
gchar *id, *longname;
|
||||||
|
gtk_tree_model_get (model, &iter, 0, &id, 1, &longname, -1);
|
||||||
|
add_keyboard_to_treeview (GTK_TREE_VIEW(dialog->selected_keyboards_treeview),
|
||||||
|
id,
|
||||||
|
longname);
|
||||||
|
g_free (id);
|
||||||
|
g_free (longname);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
gtk_widget_hide (dialog->new_keyboard_dialog);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
remove_keyboard (GtkWidget *button, PreferencesDialog *dialog)
|
||||||
|
{
|
||||||
|
GtkTreeSelection *selection;
|
||||||
|
GtkTreeModel *model;
|
||||||
|
GList *rows, *p;
|
||||||
|
|
||||||
|
selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(dialog->selected_keyboards_treeview));
|
||||||
|
rows = gtk_tree_selection_get_selected_rows (selection, &model);
|
||||||
|
for (p = rows; p; p = p->next) {
|
||||||
|
GtkTreeIter iter;
|
||||||
|
if (gtk_tree_model_get_iter (model, &iter, p->data))
|
||||||
|
gtk_list_store_remove (GTK_LIST_STORE(model), &iter);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
up_keyboard (GtkWidget *button, PreferencesDialog *dialog)
|
||||||
|
{
|
||||||
|
GtkTreeSelection *selection;
|
||||||
|
GtkTreeModel *model;
|
||||||
|
GtkTreeIter iter;
|
||||||
|
|
||||||
|
selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(dialog->selected_keyboards_treeview));
|
||||||
|
if (gtk_tree_selection_get_selected (selection, &model, &iter)) {
|
||||||
|
GtkTreeIter prev = iter;
|
||||||
|
if (gtk_tree_model_iter_previous (model, &prev))
|
||||||
|
gtk_list_store_swap (GTK_LIST_STORE(model), &iter, &prev);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
down_keyboard (GtkWidget *button, PreferencesDialog *dialog)
|
||||||
|
{
|
||||||
|
GtkTreeSelection *selection;
|
||||||
|
GtkTreeModel *model;
|
||||||
|
GtkTreeIter iter;
|
||||||
|
|
||||||
|
selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(dialog->selected_keyboards_treeview));
|
||||||
|
if (gtk_tree_selection_get_selected (selection, &model, &iter)) {
|
||||||
|
GtkTreeIter next = iter;
|
||||||
|
if (gtk_tree_model_iter_next (model, &next))
|
||||||
|
gtk_list_store_swap (GTK_LIST_STORE(model), &iter, &next);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
selection_changed_cb (GtkTreeSelection *selection, PreferencesDialog *dialog)
|
||||||
|
{
|
||||||
|
gint count = gtk_tree_selection_count_selected_rows (selection);
|
||||||
|
if (count > 0) {
|
||||||
|
gtk_widget_set_sensitive (dialog->remove_button, TRUE);
|
||||||
|
gtk_widget_set_sensitive (dialog->up_button, TRUE);
|
||||||
|
gtk_widget_set_sensitive (dialog->down_button, TRUE);
|
||||||
|
} else {
|
||||||
|
gtk_widget_set_sensitive (dialog->remove_button, FALSE);
|
||||||
|
gtk_widget_set_sensitive (dialog->up_button, FALSE);
|
||||||
|
gtk_widget_set_sensitive (dialog->down_button, FALSE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static gint
|
||||||
|
compare_keyboard_id (const EekXmlKeyboardDesc *desc, const char *id)
|
||||||
|
{
|
||||||
|
return g_strcmp0 (desc->id, id);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
populate_selected_keyboards (PreferencesDialog *dialog)
|
||||||
|
{
|
||||||
|
gchar **strv, **p;
|
||||||
|
|
||||||
|
strv = g_settings_get_strv (dialog->settings, "keyboards");
|
||||||
|
for (p = strv; *p != NULL; p++) {
|
||||||
|
GList *head = g_list_find_custom (dialog->available_keyboards,
|
||||||
|
*p,
|
||||||
|
(GCompareFunc) compare_keyboard_id);
|
||||||
|
if (head == NULL) {
|
||||||
|
g_warning ("unknown keyboard %s", *p);
|
||||||
|
} else {
|
||||||
|
EekXmlKeyboardDesc *desc = head->data;
|
||||||
|
add_keyboard_to_treeview (GTK_TREE_VIEW(dialog->selected_keyboards_treeview),
|
||||||
|
desc->id,
|
||||||
|
desc->longname);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
g_strfreev (strv);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
populate_available_keyboards (PreferencesDialog *dialog)
|
||||||
|
{
|
||||||
|
GList *p;
|
||||||
|
|
||||||
|
for (p = dialog->available_keyboards; p; p = p->next) {
|
||||||
|
EekXmlKeyboardDesc *desc = p->data;
|
||||||
|
add_keyboard_to_treeview (GTK_TREE_VIEW(dialog->available_keyboards_treeview),
|
||||||
|
desc->id,
|
||||||
|
desc->longname);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
save_keyboards (PreferencesDialog *dialog)
|
||||||
|
{
|
||||||
|
GtkTreeModel *model;
|
||||||
|
GtkTreeIter iter;
|
||||||
|
GList *list = NULL, *head;
|
||||||
|
gchar **strv, **p;
|
||||||
|
|
||||||
|
model = gtk_tree_view_get_model (GTK_TREE_VIEW(dialog->selected_keyboards_treeview));
|
||||||
|
if (gtk_tree_model_get_iter_first (model, &iter)) {
|
||||||
|
do {
|
||||||
|
gchar *id;
|
||||||
|
gtk_tree_model_get (model, &iter, 0, &id, -1);
|
||||||
|
list = g_list_prepend (list, id);
|
||||||
|
} while (gtk_tree_model_iter_next (model, &iter));
|
||||||
|
}
|
||||||
|
list = g_list_reverse (list);
|
||||||
|
|
||||||
|
strv = g_new0 (gchar *, g_list_length (list) + 1);
|
||||||
|
for (head = list, p = strv; head; head = head->next, p++) {
|
||||||
|
*p = head->data;
|
||||||
|
}
|
||||||
|
g_settings_set_strv (dialog->settings,
|
||||||
|
"keyboards",
|
||||||
|
(const gchar * const *)strv);
|
||||||
|
g_strfreev (strv);
|
||||||
|
g_list_free (list);
|
||||||
|
}
|
||||||
|
|
||||||
|
PreferencesDialog *
|
||||||
|
preferences_dialog_new (void)
|
||||||
|
{
|
||||||
|
PreferencesDialog *dialog;
|
||||||
|
gchar *ui_path;
|
||||||
|
GtkBuilder *builder;
|
||||||
|
GObject *object;
|
||||||
|
GError *error;
|
||||||
|
GtkListStore *store;
|
||||||
|
GtkCellRenderer *renderer;
|
||||||
|
GtkTreeViewColumn *column;
|
||||||
|
GtkTreeSelection *selection;
|
||||||
|
|
||||||
|
dialog = g_slice_new0 (PreferencesDialog);
|
||||||
|
dialog->settings = g_settings_new ("org.fedorahosted.eekboard");
|
||||||
|
|
||||||
|
builder = gtk_builder_new ();
|
||||||
|
gtk_builder_set_translation_domain (builder, "eekboard");
|
||||||
|
ui_path = g_build_filename (PKGDATADIR,
|
||||||
|
"preferences-dialog.ui",
|
||||||
|
NULL);
|
||||||
|
error = NULL;
|
||||||
|
if (gtk_builder_add_from_file (builder, ui_path, &error) == 0) {
|
||||||
|
g_warning ("can't load %s: %s", ui_path, error->message);
|
||||||
|
g_error_free (error);
|
||||||
|
}
|
||||||
|
g_free (ui_path);
|
||||||
|
|
||||||
|
object = gtk_builder_get_object (builder, "dialog");
|
||||||
|
dialog->dialog = GTK_WIDGET(object);
|
||||||
|
|
||||||
|
object = gtk_builder_get_object (builder, "repeat_toggle");
|
||||||
|
dialog->repeat_toggle = GTK_WIDGET(object);
|
||||||
|
|
||||||
|
g_settings_bind (dialog->settings, "repeat",
|
||||||
|
dialog->repeat_toggle, "active",
|
||||||
|
G_SETTINGS_BIND_DEFAULT);
|
||||||
|
|
||||||
|
object = gtk_builder_get_object (builder, "repeat_delay_scale");
|
||||||
|
dialog->repeat_delay_scale = GTK_WIDGET(object);
|
||||||
|
|
||||||
|
g_settings_bind (dialog->settings, "repeat-delay",
|
||||||
|
gtk_range_get_adjustment (GTK_RANGE (dialog->repeat_delay_scale)), "value",
|
||||||
|
G_SETTINGS_BIND_DEFAULT);
|
||||||
|
|
||||||
|
object = gtk_builder_get_object (builder, "repeat_speed_scale");
|
||||||
|
dialog->repeat_speed_scale = GTK_WIDGET(object);
|
||||||
|
|
||||||
|
g_settings_bind_with_mapping (dialog->settings, "repeat-interval",
|
||||||
|
gtk_range_get_adjustment (GTK_RANGE (gtk_builder_get_object (builder, "repeat_speed_scale"))), "value",
|
||||||
|
G_SETTINGS_BIND_DEFAULT,
|
||||||
|
get_rate, set_rate, NULL, NULL);
|
||||||
|
|
||||||
|
object = gtk_builder_get_object (builder, "auto_hide_toggle");
|
||||||
|
dialog->auto_hide_toggle = GTK_WIDGET(object);
|
||||||
|
|
||||||
|
g_settings_bind (dialog->settings, "auto-hide",
|
||||||
|
dialog->auto_hide_toggle, "active",
|
||||||
|
G_SETTINGS_BIND_DEFAULT);
|
||||||
|
|
||||||
|
object = gtk_builder_get_object (builder, "auto_hide_delay_scale");
|
||||||
|
dialog->auto_hide_delay_scale = GTK_WIDGET(object);
|
||||||
|
|
||||||
|
g_settings_bind (dialog->settings, "auto-hide-delay",
|
||||||
|
gtk_range_get_adjustment (GTK_RANGE (dialog->auto_hide_delay_scale)), "value",
|
||||||
|
G_SETTINGS_BIND_DEFAULT);
|
||||||
|
|
||||||
|
object = gtk_builder_get_object (builder,
|
||||||
|
"selected_keyboards_treeview");
|
||||||
|
dialog->selected_keyboards_treeview = GTK_WIDGET(object);
|
||||||
|
|
||||||
|
selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (object));
|
||||||
|
g_signal_connect (G_OBJECT(selection), "changed",
|
||||||
|
G_CALLBACK(selection_changed_cb), dialog);
|
||||||
|
|
||||||
|
renderer = GTK_CELL_RENDERER(gtk_cell_renderer_text_new ());
|
||||||
|
column = gtk_tree_view_column_new_with_attributes ("Keyboard",
|
||||||
|
renderer,
|
||||||
|
"text",
|
||||||
|
1,
|
||||||
|
NULL);
|
||||||
|
gtk_tree_view_append_column (GTK_TREE_VIEW (object), column);
|
||||||
|
|
||||||
|
object = gtk_builder_get_object (builder, "up_button");
|
||||||
|
dialog->up_button = GTK_WIDGET(object);
|
||||||
|
g_signal_connect (object, "clicked",
|
||||||
|
G_CALLBACK(up_keyboard), dialog);
|
||||||
|
|
||||||
|
object = gtk_builder_get_object (builder, "down_button");
|
||||||
|
dialog->down_button = GTK_WIDGET(object);
|
||||||
|
g_signal_connect (object, "clicked",
|
||||||
|
G_CALLBACK(down_keyboard), dialog);
|
||||||
|
|
||||||
|
object = gtk_builder_get_object (builder, "add_button");
|
||||||
|
dialog->add_button = GTK_WIDGET(object);
|
||||||
|
g_signal_connect (object, "clicked",
|
||||||
|
G_CALLBACK(add_keyboard), dialog);
|
||||||
|
|
||||||
|
object = gtk_builder_get_object (builder, "remove_button");
|
||||||
|
dialog->remove_button = GTK_WIDGET(object);
|
||||||
|
g_signal_connect (object, "clicked",
|
||||||
|
G_CALLBACK(remove_keyboard), dialog);
|
||||||
|
|
||||||
|
object = gtk_builder_get_object (builder, "new_keyboard_dialog");
|
||||||
|
dialog->new_keyboard_dialog = GTK_WIDGET(object);
|
||||||
|
|
||||||
|
object = gtk_builder_get_object (builder,
|
||||||
|
"available_keyboards_treeview");
|
||||||
|
dialog->available_keyboards_treeview = GTK_WIDGET(object);
|
||||||
|
|
||||||
|
renderer = GTK_CELL_RENDERER(gtk_cell_renderer_text_new ());
|
||||||
|
column = gtk_tree_view_column_new_with_attributes ("Keyboard",
|
||||||
|
renderer,
|
||||||
|
"text",
|
||||||
|
1,
|
||||||
|
NULL);
|
||||||
|
gtk_tree_view_append_column (GTK_TREE_VIEW (object), column);
|
||||||
|
|
||||||
|
object = gtk_builder_get_object (builder,
|
||||||
|
"available_keyboards_liststore");
|
||||||
|
store = GTK_LIST_STORE(object);
|
||||||
|
|
||||||
|
gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE(store),
|
||||||
|
1,
|
||||||
|
GTK_SORT_ASCENDING);
|
||||||
|
|
||||||
|
dialog->available_keyboards = eek_xml_list_keyboards ();
|
||||||
|
|
||||||
|
populate_selected_keyboards (dialog);
|
||||||
|
populate_available_keyboards (dialog);
|
||||||
|
|
||||||
|
g_object_unref (builder);
|
||||||
|
|
||||||
|
return dialog;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
preferences_dialog_run (PreferencesDialog *dialog)
|
||||||
|
{
|
||||||
|
gtk_window_present (GTK_WINDOW(dialog->dialog));
|
||||||
|
gtk_dialog_run (GTK_DIALOG(dialog->dialog));
|
||||||
|
save_keyboards (dialog);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
preferences_dialog_free (PreferencesDialog *dialog)
|
||||||
|
{
|
||||||
|
gtk_widget_destroy (dialog->dialog);
|
||||||
|
// gtk_widget_destroy (dialog->new_keyboard_dialog);
|
||||||
|
|
||||||
|
g_object_unref (dialog->settings);
|
||||||
|
g_list_free_full (dialog->available_keyboards,
|
||||||
|
(GDestroyNotify) eek_xml_keyboard_desc_free);
|
||||||
|
|
||||||
|
g_slice_free (PreferencesDialog, dialog);
|
||||||
|
}
|
||||||
32
src/preferences-dialog.h
Normal file
32
src/preferences-dialog.h
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2011 Daiki Ueno <ueno@unixuser.org>
|
||||||
|
* Copyright (C) 2011 Red Hat, Inc.
|
||||||
|
*
|
||||||
|
* 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 3 of the License, 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, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
#ifndef PREFERENCES_DIALOG_H
|
||||||
|
#define PREFERENCES_DIALOG_H 1
|
||||||
|
|
||||||
|
#include <glib-object.h>
|
||||||
|
|
||||||
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
typedef struct _PreferencesDialog PreferencesDialog;
|
||||||
|
|
||||||
|
PreferencesDialog *preferences_dialog_new (void);
|
||||||
|
void preferences_dialog_run (PreferencesDialog *dialog);
|
||||||
|
void preferences_dialog_free (PreferencesDialog *dialog);
|
||||||
|
|
||||||
|
G_END_DECLS
|
||||||
|
#endif /* PREFERENCES_DIALOG_H */
|
||||||
729
src/preferences-dialog.ui
Normal file
729
src/preferences-dialog.ui
Normal file
@ -0,0 +1,729 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<interface>
|
||||||
|
<!-- interface-requires gtk+ 3.0 -->
|
||||||
|
<object class="GtkAction" id="action1">
|
||||||
|
<property name="stock_id">gtk-close</property>
|
||||||
|
</object>
|
||||||
|
<object class="GtkAction" id="action2">
|
||||||
|
<property name="stock_id">gtk-cancel</property>
|
||||||
|
</object>
|
||||||
|
<object class="GtkAction" id="action3">
|
||||||
|
<property name="label" translatable="yes">Select</property>
|
||||||
|
<property name="stock_id">gtk-ok</property>
|
||||||
|
</object>
|
||||||
|
<object class="GtkAdjustment" id="auto_hide_delay_adjustment">
|
||||||
|
<property name="lower">100</property>
|
||||||
|
<property name="upper">2000</property>
|
||||||
|
<property name="value">500</property>
|
||||||
|
<property name="step_increment">10</property>
|
||||||
|
<property name="page_increment">10</property>
|
||||||
|
</object>
|
||||||
|
<object class="GtkListStore" id="available_keyboards_liststore">
|
||||||
|
<columns>
|
||||||
|
<!-- column-name id -->
|
||||||
|
<column type="gchararray"/>
|
||||||
|
<!-- column-name gchararray1 -->
|
||||||
|
<column type="gchararray"/>
|
||||||
|
</columns>
|
||||||
|
</object>
|
||||||
|
<object class="GtkDialog" id="dialog">
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="border_width">5</property>
|
||||||
|
<property name="title" translatable="yes">Keyboard</property>
|
||||||
|
<property name="modal">True</property>
|
||||||
|
<property name="type_hint">dialog</property>
|
||||||
|
<child internal-child="vbox">
|
||||||
|
<object class="GtkBox" id="dialog-vbox4">
|
||||||
|
<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="dialog-action_area5">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="layout_style">end</property>
|
||||||
|
<child>
|
||||||
|
<placeholder/>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<placeholder/>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<placeholder/>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkButton" id="button1">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">True</property>
|
||||||
|
<property name="receives_default">True</property>
|
||||||
|
<property name="related_action">action1</property>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="fill">True</property>
|
||||||
|
<property name="position">3</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="fill">True</property>
|
||||||
|
<property name="pack_type">end</property>
|
||||||
|
<property name="position">0</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkNotebook" id="keyboard_notebook">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">True</property>
|
||||||
|
<property name="border_width">10</property>
|
||||||
|
<child>
|
||||||
|
<object class="GtkVBox" id="general_page">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="border_width">12</property>
|
||||||
|
<property name="spacing">18</property>
|
||||||
|
<child>
|
||||||
|
<object class="GtkVBox" id="vbox22">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="spacing">6</property>
|
||||||
|
<child>
|
||||||
|
<object class="GtkLabel" id="label300">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="xalign">0</property>
|
||||||
|
<property name="label" translatable="yes">Repeat Keys</property>
|
||||||
|
<attributes>
|
||||||
|
<attribute name="weight" value="bold"/>
|
||||||
|
</attributes>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="fill">False</property>
|
||||||
|
<property name="position">0</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkHBox" id="hbox19">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<child>
|
||||||
|
<object class="GtkLabel" id="label43">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="label"> </property>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="fill">False</property>
|
||||||
|
<property name="position">0</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkVBox" id="vbox100">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="spacing">6</property>
|
||||||
|
<child>
|
||||||
|
<object class="GtkCheckButton" id="repeat_toggle">
|
||||||
|
<property name="label" translatable="yes">Key presses _repeat when key is held down</property>
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">True</property>
|
||||||
|
<property name="receives_default">False</property>
|
||||||
|
<property name="use_action_appearance">False</property>
|
||||||
|
<property name="use_underline">True</property>
|
||||||
|
<property name="xalign">0</property>
|
||||||
|
<property name="draw_indicator">True</property>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="fill">False</property>
|
||||||
|
<property name="position">0</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkTable" id="repeat_table">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="n_rows">2</property>
|
||||||
|
<property name="n_columns">4</property>
|
||||||
|
<child>
|
||||||
|
<object class="GtkLabel" id="repeat_speed_label">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="xalign">0</property>
|
||||||
|
<property name="label" translatable="yes">_Speed:</property>
|
||||||
|
<property name="use_underline">True</property>
|
||||||
|
<property name="justify">center</property>
|
||||||
|
<property name="mnemonic_widget">repeat_speed_scale</property>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="top_attach">1</property>
|
||||||
|
<property name="bottom_attach">2</property>
|
||||||
|
<property name="x_options">GTK_SHRINK</property>
|
||||||
|
<property name="y_options"></property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkLabel" id="delay_short_label">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="xalign">1</property>
|
||||||
|
<property name="xpad">10</property>
|
||||||
|
<property name="label" translatable="yes">Short</property>
|
||||||
|
<attributes>
|
||||||
|
<attribute name="style" value="italic"/>
|
||||||
|
<attribute name="scale" value="0.82999999999999996"/>
|
||||||
|
</attributes>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="left_attach">1</property>
|
||||||
|
<property name="right_attach">2</property>
|
||||||
|
<property name="x_options">GTK_SHRINK</property>
|
||||||
|
<property name="y_options"></property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkLabel" id="repeat_slow_label">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="xalign">1</property>
|
||||||
|
<property name="xpad">10</property>
|
||||||
|
<property name="label" translatable="yes">Slow</property>
|
||||||
|
<attributes>
|
||||||
|
<attribute name="style" value="italic"/>
|
||||||
|
<attribute name="scale" value="0.82999999999999996"/>
|
||||||
|
</attributes>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="left_attach">1</property>
|
||||||
|
<property name="right_attach">2</property>
|
||||||
|
<property name="top_attach">1</property>
|
||||||
|
<property name="bottom_attach">2</property>
|
||||||
|
<property name="x_options">GTK_SHRINK</property>
|
||||||
|
<property name="y_options"></property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkHScale" id="repeat_delay_scale">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">True</property>
|
||||||
|
<property name="adjustment">repeat_delay_adjustment</property>
|
||||||
|
<property name="draw_value">False</property>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="left_attach">2</property>
|
||||||
|
<property name="right_attach">3</property>
|
||||||
|
<property name="y_options"></property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkHScale" id="repeat_speed_scale">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">True</property>
|
||||||
|
<property name="adjustment">repeat_speed_adjustment</property>
|
||||||
|
<property name="draw_value">False</property>
|
||||||
|
<child internal-child="accessible">
|
||||||
|
<object class="AtkObject" id="repeat_speed_scale-atkobject">
|
||||||
|
<property name="AtkObject::accessible-description" translatable="yes">Repeat keys speed</property>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="left_attach">2</property>
|
||||||
|
<property name="right_attach">3</property>
|
||||||
|
<property name="top_attach">1</property>
|
||||||
|
<property name="bottom_attach">2</property>
|
||||||
|
<property name="y_options"></property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkLabel" id="delay_long_label">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="xalign">0</property>
|
||||||
|
<property name="label" translatable="yes">Long</property>
|
||||||
|
<attributes>
|
||||||
|
<attribute name="style" value="italic"/>
|
||||||
|
<attribute name="scale" value="0.82999999999999996"/>
|
||||||
|
</attributes>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="left_attach">3</property>
|
||||||
|
<property name="right_attach">4</property>
|
||||||
|
<property name="x_options">GTK_SHRINK</property>
|
||||||
|
<property name="y_options"></property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkLabel" id="repeat_fast_label">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="xalign">0</property>
|
||||||
|
<property name="label" translatable="yes">Fast</property>
|
||||||
|
<attributes>
|
||||||
|
<attribute name="style" value="italic"/>
|
||||||
|
<attribute name="scale" value="0.82999999999999996"/>
|
||||||
|
</attributes>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="left_attach">3</property>
|
||||||
|
<property name="right_attach">4</property>
|
||||||
|
<property name="top_attach">1</property>
|
||||||
|
<property name="bottom_attach">2</property>
|
||||||
|
<property name="x_options">GTK_SHRINK</property>
|
||||||
|
<property name="y_options"></property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkLabel" id="repeat_delay_label">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="xalign">0</property>
|
||||||
|
<property name="label" translatable="yes">_Delay:</property>
|
||||||
|
<property name="use_underline">True</property>
|
||||||
|
<property name="justify">center</property>
|
||||||
|
<property name="mnemonic_widget">repeat_delay_scale</property>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="x_options">GTK_SHRINK</property>
|
||||||
|
<property name="y_options"></property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="fill">False</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>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="fill">False</property>
|
||||||
|
<property name="position">1</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="GtkVBox" id="vbox230">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="spacing">6</property>
|
||||||
|
<child>
|
||||||
|
<object class="GtkLabel" id="label5">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="xalign">0</property>
|
||||||
|
<property name="label" translatable="yes">Focus following</property>
|
||||||
|
<attributes>
|
||||||
|
<attribute name="weight" value="bold"/>
|
||||||
|
</attributes>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="fill">False</property>
|
||||||
|
<property name="position">0</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkHBox" id="hbox20">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<child>
|
||||||
|
<object class="GtkLabel" id="label44">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="label"> </property>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="fill">False</property>
|
||||||
|
<property name="position">0</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkVBox" id="appearances_vbox">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="spacing">6</property>
|
||||||
|
<child>
|
||||||
|
<object class="GtkCheckButton" id="auto_hide_toggle">
|
||||||
|
<property name="label" translatable="yes">Auto hide window when focus is out</property>
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">True</property>
|
||||||
|
<property name="receives_default">False</property>
|
||||||
|
<property name="use_action_appearance">False</property>
|
||||||
|
<property name="use_underline">True</property>
|
||||||
|
<property name="xalign">0</property>
|
||||||
|
<property name="draw_indicator">True</property>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="fill">False</property>
|
||||||
|
<property name="position">0</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkTable" id="table1">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="n_columns">4</property>
|
||||||
|
<child>
|
||||||
|
<object class="GtkLabel" id="auto_hide_delay_label">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="xalign">0</property>
|
||||||
|
<property name="label" translatable="yes">_Delay:</property>
|
||||||
|
<property name="use_underline">True</property>
|
||||||
|
<property name="justify">center</property>
|
||||||
|
<property name="mnemonic_widget">auto_hide_delay_scale</property>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="x_options">GTK_SHRINK</property>
|
||||||
|
<property name="y_options"></property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkLabel" id="auto_hide_delay_short_label">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="xalign">1</property>
|
||||||
|
<property name="xpad">10</property>
|
||||||
|
<property name="label" translatable="yes">Short</property>
|
||||||
|
<attributes>
|
||||||
|
<attribute name="style" value="italic"/>
|
||||||
|
<attribute name="scale" value="0.82999999999999996"/>
|
||||||
|
</attributes>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="left_attach">1</property>
|
||||||
|
<property name="right_attach">2</property>
|
||||||
|
<property name="x_options">GTK_SHRINK</property>
|
||||||
|
<property name="y_options"></property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkHScale" id="auto_hide_delay_scale">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">True</property>
|
||||||
|
<property name="adjustment">auto_hide_delay_adjustment</property>
|
||||||
|
<property name="draw_value">False</property>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="left_attach">2</property>
|
||||||
|
<property name="right_attach">3</property>
|
||||||
|
<property name="y_options"></property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkLabel" id="auto_hide_delay_long_label">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="xalign">0</property>
|
||||||
|
<property name="label" translatable="yes">Long</property>
|
||||||
|
<attributes>
|
||||||
|
<attribute name="style" value="italic"/>
|
||||||
|
<attribute name="scale" value="0.82999999999999996"/>
|
||||||
|
</attributes>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="left_attach">3</property>
|
||||||
|
<property name="right_attach">4</property>
|
||||||
|
<property name="x_options">GTK_SHRINK</property>
|
||||||
|
<property name="y_options"></property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="fill">False</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>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="fill">False</property>
|
||||||
|
<property name="position">1</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="fill">False</property>
|
||||||
|
<property name="position">1</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child type="tab">
|
||||||
|
<object class="GtkLabel" id="label1">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="label" translatable="yes">Typing</property>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="tab_fill">False</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkVBox" id="keyboards_page">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="border_width">12</property>
|
||||||
|
<property name="spacing">18</property>
|
||||||
|
<child>
|
||||||
|
<object class="GtkTreeView" id="selected_keyboards_treeview">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">True</property>
|
||||||
|
<property name="model">selected_keyboards_liststore</property>
|
||||||
|
<property name="headers_visible">False</property>
|
||||||
|
<property name="headers_clickable">False</property>
|
||||||
|
<child internal-child="selection">
|
||||||
|
<object class="GtkTreeSelection" id="treeview-selection2"/>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">True</property>
|
||||||
|
<property name="fill">True</property>
|
||||||
|
<property name="position">0</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkButtonBox" id="buttonbox1">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="spacing">2</property>
|
||||||
|
<property name="layout_style">end</property>
|
||||||
|
<child>
|
||||||
|
<object class="GtkButton" id="up_button">
|
||||||
|
<property name="label">gtk-go-up</property>
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="sensitive">False</property>
|
||||||
|
<property name="can_focus">True</property>
|
||||||
|
<property name="receives_default">True</property>
|
||||||
|
<property name="use_action_appearance">False</property>
|
||||||
|
<property name="use_stock">True</property>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="fill">True</property>
|
||||||
|
<property name="position">0</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkButton" id="down_button">
|
||||||
|
<property name="label">gtk-go-down</property>
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="sensitive">False</property>
|
||||||
|
<property name="can_focus">True</property>
|
||||||
|
<property name="receives_default">True</property>
|
||||||
|
<property name="use_action_appearance">False</property>
|
||||||
|
<property name="use_stock">True</property>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="fill">True</property>
|
||||||
|
<property name="position">1</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkButton" id="add_button">
|
||||||
|
<property name="label">gtk-add</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>
|
||||||
|
<property name="use_stock">True</property>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="fill">True</property>
|
||||||
|
<property name="position">2</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkButton" id="remove_button">
|
||||||
|
<property name="label">gtk-remove</property>
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="sensitive">False</property>
|
||||||
|
<property name="can_focus">True</property>
|
||||||
|
<property name="receives_default">True</property>
|
||||||
|
<property name="use_action_appearance">False</property>
|
||||||
|
<property name="use_stock">True</property>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="fill">True</property>
|
||||||
|
<property name="position">3</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="fill">False</property>
|
||||||
|
<property name="position">1</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="position">1</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child type="tab">
|
||||||
|
<object class="GtkLabel" id="label2">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="label" translatable="yes">Keyboards</property>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="position">1</property>
|
||||||
|
<property name="tab_fill">False</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<placeholder/>
|
||||||
|
</child>
|
||||||
|
<child type="tab">
|
||||||
|
<placeholder/>
|
||||||
|
</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="0">button1</action-widget>
|
||||||
|
</action-widgets>
|
||||||
|
</object>
|
||||||
|
<object class="GtkDialog" id="new_keyboard_dialog">
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="border_width">5</property>
|
||||||
|
<property name="default_height">430</property>
|
||||||
|
<property name="destroy_with_parent">True</property>
|
||||||
|
<property name="type_hint">dialog</property>
|
||||||
|
<property name="transient_for">dialog</property>
|
||||||
|
<child internal-child="vbox">
|
||||||
|
<object class="GtkBox" id="dialog-vbox2">
|
||||||
|
<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="dialog-action_area2">
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="layout_style">end</property>
|
||||||
|
<child>
|
||||||
|
<object class="GtkButton" id="button2">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">True</property>
|
||||||
|
<property name="receives_default">True</property>
|
||||||
|
<property name="related_action">action2</property>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="fill">True</property>
|
||||||
|
<property name="position">0</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkButton" id="button3">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">True</property>
|
||||||
|
<property name="receives_default">True</property>
|
||||||
|
<property name="related_action">action3</property>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="fill">True</property>
|
||||||
|
<property name="position">1</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="fill">True</property>
|
||||||
|
<property name="pack_type">end</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="shadow_type">in</property>
|
||||||
|
<child>
|
||||||
|
<object class="GtkTreeView" id="available_keyboards_treeview">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">True</property>
|
||||||
|
<property name="model">available_keyboards_liststore</property>
|
||||||
|
<property name="headers_visible">False</property>
|
||||||
|
<property name="headers_clickable">False</property>
|
||||||
|
<child internal-child="selection">
|
||||||
|
<object class="GtkTreeSelection" id="treeview-selection3"/>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
</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="0">button2</action-widget>
|
||||||
|
<action-widget response="-5">button3</action-widget>
|
||||||
|
</action-widgets>
|
||||||
|
</object>
|
||||||
|
<object class="GtkAdjustment" id="repeat_delay_adjustment">
|
||||||
|
<property name="lower">100</property>
|
||||||
|
<property name="upper">2000</property>
|
||||||
|
<property name="value">500</property>
|
||||||
|
<property name="step_increment">10</property>
|
||||||
|
<property name="page_increment">10</property>
|
||||||
|
</object>
|
||||||
|
<object class="GtkAdjustment" id="repeat_speed_adjustment">
|
||||||
|
<property name="lower">0.5</property>
|
||||||
|
<property name="upper">50</property>
|
||||||
|
<property name="value">33.299999999999997</property>
|
||||||
|
<property name="step_increment">1</property>
|
||||||
|
<property name="page_increment">1</property>
|
||||||
|
</object>
|
||||||
|
<object class="GtkListStore" id="selected_keyboards_liststore">
|
||||||
|
<columns>
|
||||||
|
<!-- column-name id -->
|
||||||
|
<column type="gchararray"/>
|
||||||
|
<!-- column-name gchararray1 -->
|
||||||
|
<column type="gchararray"/>
|
||||||
|
</columns>
|
||||||
|
</object>
|
||||||
|
</interface>
|
||||||
@ -15,11 +15,15 @@
|
|||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
#endif /* HAVE_CONFIG_H */
|
||||||
|
|
||||||
#include <gtk/gtk.h>
|
#include <gtk/gtk.h>
|
||||||
#include <glib/gi18n.h>
|
#include <glib/gi18n.h>
|
||||||
|
|
||||||
|
#include <gdk/gdkx.h>
|
||||||
|
|
||||||
#include "eek/eek-gtk.h"
|
#include "eek/eek-gtk.h"
|
||||||
#include "eek/layersurface.h"
|
#include "eek/layersurface.h"
|
||||||
#include "wayland.h"
|
#include "wayland.h"
|
||||||
@ -38,9 +42,13 @@ typedef struct _ServerContextServiceClass ServerContextServiceClass;
|
|||||||
struct _ServerContextService {
|
struct _ServerContextService {
|
||||||
EekboardContextService parent;
|
EekboardContextService parent;
|
||||||
|
|
||||||
|
gboolean was_visible;
|
||||||
|
|
||||||
GtkWidget *window;
|
GtkWidget *window;
|
||||||
GtkWidget *widget;
|
GtkWidget *widget;
|
||||||
|
|
||||||
|
gulong notify_visible_handler;
|
||||||
|
|
||||||
gdouble size_constraint_landscape[2];
|
gdouble size_constraint_landscape[2];
|
||||||
gdouble size_constraint_portrait[2];
|
gdouble size_constraint_portrait[2];
|
||||||
};
|
};
|
||||||
@ -51,13 +59,16 @@ struct _ServerContextServiceClass {
|
|||||||
|
|
||||||
G_DEFINE_TYPE (ServerContextService, server_context_service, EEKBOARD_TYPE_CONTEXT_SERVICE);
|
G_DEFINE_TYPE (ServerContextService, server_context_service, EEKBOARD_TYPE_CONTEXT_SERVICE);
|
||||||
|
|
||||||
|
static void update_widget (ServerContextService *context);
|
||||||
static void set_geometry (ServerContextService *context);
|
static void set_geometry (ServerContextService *context);
|
||||||
|
static void set_dock (GtkWidget *widget,
|
||||||
|
GtkAllocation *allocation);
|
||||||
|
|
||||||
static void
|
static void
|
||||||
on_monitors_changed (GdkScreen *screen,
|
on_monitors_changed (GdkScreen *screen,
|
||||||
ServerContextService *context)
|
gpointer user_data)
|
||||||
|
|
||||||
{
|
{
|
||||||
|
ServerContextService *context = user_data;
|
||||||
if (context->window)
|
if (context->window)
|
||||||
set_geometry (context);
|
set_geometry (context);
|
||||||
}
|
}
|
||||||
@ -78,14 +89,16 @@ on_destroy (GtkWidget *widget, gpointer user_data)
|
|||||||
static void
|
static void
|
||||||
on_notify_keyboard (GObject *object,
|
on_notify_keyboard (GObject *object,
|
||||||
GParamSpec *spec,
|
GParamSpec *spec,
|
||||||
ServerContextService *context)
|
gpointer user_data)
|
||||||
{
|
{
|
||||||
|
ServerContextService *context = user_data;
|
||||||
const EekKeyboard *keyboard;
|
const EekKeyboard *keyboard;
|
||||||
|
|
||||||
keyboard = eekboard_context_service_get_keyboard (EEKBOARD_CONTEXT_SERVICE(context));
|
keyboard = eekboard_context_service_get_keyboard (EEKBOARD_CONTEXT_SERVICE(context));
|
||||||
|
|
||||||
if (!keyboard)
|
if (!keyboard) {
|
||||||
g_error("Programmer error: keyboard layout was unset!");
|
g_error("Programmer error: keyboard layout was unset!");
|
||||||
|
}
|
||||||
|
|
||||||
// The keymap will get set even if the window is hidden.
|
// The keymap will get set even if the window is hidden.
|
||||||
// It's not perfect,
|
// It's not perfect,
|
||||||
@ -93,56 +106,139 @@ on_notify_keyboard (GObject *object,
|
|||||||
eekboard_context_service_set_keymap(EEKBOARD_CONTEXT_SERVICE(context),
|
eekboard_context_service_set_keymap(EEKBOARD_CONTEXT_SERVICE(context),
|
||||||
keyboard);
|
keyboard);
|
||||||
|
|
||||||
/* Recreate the keyboard widget to keep in sync with the keymap. */
|
if (context->window) {
|
||||||
gboolean visible;
|
if (keyboard == NULL) {
|
||||||
g_object_get (context, "visible", &visible, NULL);
|
gtk_widget_hide (context->window);
|
||||||
|
gtk_widget_destroy (context->widget);
|
||||||
if (visible) {
|
context->widget = NULL;
|
||||||
eekboard_context_service_hide_keyboard(EEKBOARD_CONTEXT_SERVICE(context));
|
} else {
|
||||||
eekboard_context_service_show_keyboard(EEKBOARD_CONTEXT_SERVICE(context));
|
gboolean was_visible = gtk_widget_get_visible (context->window);
|
||||||
|
/* avoid to send KeyboardVisibilityChanged */
|
||||||
|
g_signal_handler_block (context->window,
|
||||||
|
context->notify_visible_handler);
|
||||||
|
update_widget (context);
|
||||||
|
if (was_visible) {
|
||||||
|
gtk_widget_show_all (context->window);
|
||||||
|
}
|
||||||
|
g_signal_handler_unblock (context->window,
|
||||||
|
context->notify_visible_handler);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
on_notify_fullscreen (GObject *object,
|
on_notify_fullscreen (GObject *object,
|
||||||
GParamSpec *spec,
|
GParamSpec *spec,
|
||||||
ServerContextService *context)
|
gpointer user_data)
|
||||||
{
|
{
|
||||||
|
ServerContextService *context = user_data;
|
||||||
if (context->window)
|
if (context->window)
|
||||||
set_geometry (context);
|
set_geometry (context);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
on_notify_map (GObject *object,
|
on_notify_visible (GObject *object, GParamSpec *spec, gpointer user_data)
|
||||||
ServerContextService *context)
|
|
||||||
{
|
{
|
||||||
g_object_set (context, "visible", TRUE, NULL);
|
ServerContextService *context = user_data;
|
||||||
}
|
gboolean visible;
|
||||||
|
|
||||||
|
g_object_get (object, "visible", &visible, NULL);
|
||||||
|
g_object_set (context, "visible", visible, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
on_notify_unmap (GObject *object,
|
set_dock (GtkWidget *widget, GtkAllocation *allocation)
|
||||||
ServerContextService *context)
|
|
||||||
{
|
{
|
||||||
g_object_set (context, "visible", FALSE, NULL);
|
#ifdef HAVE_XDOCK
|
||||||
|
GdkWindow *window = gtk_widget_get_window (widget);
|
||||||
|
long vals[12];
|
||||||
|
|
||||||
|
/* set window type to dock */
|
||||||
|
gdk_window_set_type_hint (window, GDK_WINDOW_TYPE_HINT_DOCK);
|
||||||
|
|
||||||
|
vals[0] = 0;
|
||||||
|
vals[1] = 0;
|
||||||
|
vals[2] = 0;
|
||||||
|
vals[3] = allocation->height;
|
||||||
|
vals[4] = 0;
|
||||||
|
vals[5] = 0;
|
||||||
|
vals[6] = 0;
|
||||||
|
vals[7] = 0;
|
||||||
|
vals[8] = 0;
|
||||||
|
vals[9] = 0;
|
||||||
|
vals[10] = allocation->x;
|
||||||
|
vals[11] = allocation->x + allocation->width;
|
||||||
|
|
||||||
|
XChangeProperty (GDK_WINDOW_XDISPLAY (window),
|
||||||
|
GDK_WINDOW_XID (window),
|
||||||
|
XInternAtom (GDK_WINDOW_XDISPLAY (window),
|
||||||
|
"_NET_WM_STRUT_PARTIAL", False),
|
||||||
|
XA_CARDINAL, 32, PropModeReplace,
|
||||||
|
(guchar *)vals, 12);
|
||||||
|
#endif /* HAVE_XDOCK */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
on_realize_set_dock (GtkWidget *widget,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
GtkAllocation allocation;
|
||||||
|
|
||||||
|
gtk_widget_get_allocation (widget, &allocation);
|
||||||
|
set_dock (widget, &allocation);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
on_size_allocate_set_dock (GtkWidget *widget,
|
||||||
|
GdkRectangle *allocation,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
if (gtk_widget_get_realized (widget))
|
||||||
|
set_dock (widget, allocation);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
on_realize_set_non_maximizable (GtkWidget *widget,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
ServerContextService *context = user_data;
|
||||||
|
|
||||||
|
g_assert (context && context->window == widget);
|
||||||
|
|
||||||
|
/* make the window not maximizable */
|
||||||
|
gdk_window_set_functions (gtk_widget_get_window (widget),
|
||||||
|
GDK_FUNC_RESIZE |
|
||||||
|
GDK_FUNC_MOVE |
|
||||||
|
GDK_FUNC_MINIMIZE |
|
||||||
|
GDK_FUNC_CLOSE);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
set_geometry (ServerContextService *context)
|
set_geometry (ServerContextService *context)
|
||||||
{
|
{
|
||||||
GdkScreen *screen = gdk_screen_get_default ();
|
GdkScreen *screen;
|
||||||
GdkWindow *root = gdk_screen_get_root_window (screen);
|
GdkDisplay *display;
|
||||||
GdkDisplay *display = gdk_display_get_default ();
|
GdkWindow *root;
|
||||||
GdkMonitor *monitor = gdk_display_get_monitor_at_window (display, root);
|
GdkMonitor *monitor;
|
||||||
EekKeyboard *keyboard = eekboard_context_service_get_keyboard (EEKBOARD_CONTEXT_SERVICE(context));
|
|
||||||
|
|
||||||
GdkRectangle rect;
|
GdkRectangle rect;
|
||||||
|
EekKeyboard *keyboard;
|
||||||
EekBounds bounds;
|
EekBounds bounds;
|
||||||
|
|
||||||
|
screen = gdk_screen_get_default ();
|
||||||
|
root = gdk_screen_get_root_window (screen);
|
||||||
|
display = gdk_display_get_default();
|
||||||
|
monitor = gdk_display_get_monitor_at_window (display, root);
|
||||||
gdk_monitor_get_geometry (monitor, &rect);
|
gdk_monitor_get_geometry (monitor, &rect);
|
||||||
|
keyboard = eekboard_context_service_get_keyboard (EEKBOARD_CONTEXT_SERVICE(context));
|
||||||
eek_element_get_bounds (EEK_ELEMENT(keyboard), &bounds);
|
eek_element_get_bounds (EEK_ELEMENT(keyboard), &bounds);
|
||||||
|
|
||||||
|
g_signal_handlers_disconnect_by_func (context->window,
|
||||||
|
on_realize_set_dock,
|
||||||
|
context);
|
||||||
|
g_signal_handlers_disconnect_by_func (context->window,
|
||||||
|
on_realize_set_non_maximizable,
|
||||||
|
context);
|
||||||
|
|
||||||
if (eekboard_context_service_get_fullscreen (EEKBOARD_CONTEXT_SERVICE(context))) {
|
if (eekboard_context_service_get_fullscreen (EEKBOARD_CONTEXT_SERVICE(context))) {
|
||||||
gint width = rect.width;
|
gint width = rect.width;
|
||||||
gint height = rect.height;
|
gint height = rect.height;
|
||||||
@ -168,6 +264,12 @@ set_geometry (ServerContextService *context)
|
|||||||
|
|
||||||
gtk_window_set_decorated (GTK_WINDOW(context->window), FALSE);
|
gtk_window_set_decorated (GTK_WINDOW(context->window), FALSE);
|
||||||
gtk_window_set_resizable (GTK_WINDOW(context->window), FALSE);
|
gtk_window_set_resizable (GTK_WINDOW(context->window), FALSE);
|
||||||
|
g_signal_connect_after (context->window, "realize",
|
||||||
|
G_CALLBACK(on_realize_set_dock),
|
||||||
|
context);
|
||||||
|
g_signal_connect_after (context->window, "size-allocate",
|
||||||
|
G_CALLBACK(on_size_allocate_set_dock),
|
||||||
|
context);
|
||||||
} else {
|
} else {
|
||||||
gtk_window_resize (GTK_WINDOW(context->window),
|
gtk_window_resize (GTK_WINDOW(context->window),
|
||||||
bounds.width,
|
bounds.width,
|
||||||
@ -175,36 +277,37 @@ set_geometry (ServerContextService *context)
|
|||||||
gtk_window_move (GTK_WINDOW(context->window),
|
gtk_window_move (GTK_WINDOW(context->window),
|
||||||
MAX(rect.width - 20 - bounds.width, 0),
|
MAX(rect.width - 20 - bounds.width, 0),
|
||||||
MAX(rect.height - 40 - bounds.height, 0));
|
MAX(rect.height - 40 - bounds.height, 0));
|
||||||
|
g_signal_connect_after (context->window, "realize",
|
||||||
|
G_CALLBACK(on_realize_set_non_maximizable),
|
||||||
|
context);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#define KEYBOARD_HEIGHT 210
|
|
||||||
static void
|
static void
|
||||||
make_window (ServerContextService *context)
|
make_window (ServerContextService *context) {
|
||||||
{
|
if (context->window) {
|
||||||
if (context->window)
|
|
||||||
g_error("Window already present");
|
g_error("Window already present");
|
||||||
|
return;
|
||||||
context->window = g_object_new (
|
}
|
||||||
|
context->window = GTK_WIDGET(g_object_new (
|
||||||
PHOSH_TYPE_LAYER_SURFACE,
|
PHOSH_TYPE_LAYER_SURFACE,
|
||||||
"layer-shell", squeek_wayland->layer_shell,
|
"layer-shell", squeek_wayland->layer_shell,
|
||||||
"wl-output", g_ptr_array_index(squeek_wayland->outputs, 0), // TODO: select output as needed,
|
"wl-output", g_ptr_array_index(squeek_wayland->outputs, 0), // TODO: select output as needed,
|
||||||
"height", KEYBOARD_HEIGHT,
|
"height", 200,
|
||||||
"anchor", ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM
|
"anchor", ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM
|
||||||
| ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT
|
| ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT
|
||||||
| ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT,
|
| ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT,
|
||||||
"layer", ZWLR_LAYER_SHELL_V1_LAYER_TOP,
|
"layer", ZWLR_LAYER_SHELL_V1_LAYER_TOP,
|
||||||
"kbd-interactivity", FALSE,
|
"kbd-interactivity", FALSE,
|
||||||
"exclusive-zone", KEYBOARD_HEIGHT,
|
"exclusive-zone", 200,
|
||||||
"namespace", "osk",
|
//"namespace", "phosh home",
|
||||||
NULL
|
NULL
|
||||||
);
|
));
|
||||||
|
g_signal_connect (context->window, "destroy",
|
||||||
g_object_connect (context->window,
|
G_CALLBACK(on_destroy), context);
|
||||||
"signal::destroy", G_CALLBACK(on_destroy), context,
|
context->notify_visible_handler =
|
||||||
"signal::map", G_CALLBACK(on_notify_map), context,
|
g_signal_connect (context->window, "notify::visible",
|
||||||
"signal::unmap", G_CALLBACK(on_notify_unmap), context,
|
G_CALLBACK(on_notify_visible), context);
|
||||||
NULL);
|
|
||||||
|
|
||||||
// The properties below are just to make hacking easier.
|
// The properties below are just to make hacking easier.
|
||||||
// The way we use layer-shell overrides some,
|
// The way we use layer-shell overrides some,
|
||||||
@ -220,33 +323,36 @@ make_window (ServerContextService *context)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
destroy_window (ServerContextService *context)
|
destroy_window (ServerContextService *context) {
|
||||||
{
|
|
||||||
gtk_widget_destroy (GTK_WIDGET (context->window));
|
|
||||||
context->window = NULL;
|
context->window = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
make_widget (ServerContextService *context)
|
update_widget (ServerContextService *context)
|
||||||
{
|
{
|
||||||
EekKeyboard *keyboard;
|
EekKeyboard *keyboard;
|
||||||
|
EekBounds bounds;
|
||||||
|
gchar *theme_path;
|
||||||
EekTheme *theme;
|
EekTheme *theme;
|
||||||
|
|
||||||
g_return_if_fail (!context->widget);
|
if (context->widget) {
|
||||||
theme = eek_theme_new ("resource:///sm/puri/squeekboard/style.css",
|
gtk_widget_destroy (context->widget);
|
||||||
NULL,
|
context->widget = NULL;
|
||||||
NULL);
|
}
|
||||||
|
|
||||||
|
theme_path = g_build_filename (THEMESDIR, "default.css", NULL);
|
||||||
|
|
||||||
|
theme = eek_theme_new (theme_path, NULL, NULL);
|
||||||
|
g_free (theme_path);
|
||||||
|
|
||||||
keyboard = eekboard_context_service_get_keyboard (EEKBOARD_CONTEXT_SERVICE(context));
|
keyboard = eekboard_context_service_get_keyboard (EEKBOARD_CONTEXT_SERVICE(context));
|
||||||
|
eek_element_get_bounds (EEK_ELEMENT(keyboard), &bounds);
|
||||||
context->widget = eek_gtk_keyboard_new (keyboard);
|
context->widget = eek_gtk_keyboard_new (keyboard);
|
||||||
|
|
||||||
eek_gtk_keyboard_set_theme (EEK_GTK_KEYBOARD(context->widget), theme);
|
eek_gtk_keyboard_set_theme (EEK_GTK_KEYBOARD(context->widget), theme);
|
||||||
g_clear_object (&theme);
|
g_object_unref (theme);
|
||||||
|
|
||||||
gtk_widget_set_has_tooltip (context->widget, TRUE);
|
gtk_widget_set_has_tooltip (context->widget, TRUE);
|
||||||
gtk_container_add (GTK_CONTAINER(context->window), context->widget);
|
gtk_container_add (GTK_CONTAINER(context->window), context->widget);
|
||||||
gtk_widget_show (context->widget);
|
|
||||||
set_geometry (context);
|
set_geometry (context);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -255,18 +361,11 @@ server_context_service_real_show_keyboard (EekboardContextService *_context)
|
|||||||
{
|
{
|
||||||
ServerContextService *context = SERVER_CONTEXT_SERVICE(_context);
|
ServerContextService *context = SERVER_CONTEXT_SERVICE(_context);
|
||||||
|
|
||||||
if (!context->window)
|
|
||||||
make_window (context);
|
make_window (context);
|
||||||
if (context->widget) {
|
update_widget (context);
|
||||||
gtk_widget_destroy(context->widget);
|
|
||||||
context->widget = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
make_widget (context);
|
|
||||||
|
|
||||||
EEKBOARD_CONTEXT_SERVICE_CLASS (server_context_service_parent_class)->
|
EEKBOARD_CONTEXT_SERVICE_CLASS (server_context_service_parent_class)->
|
||||||
show_keyboard (_context);
|
show_keyboard (_context);
|
||||||
gtk_widget_show (context->window);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -275,11 +374,35 @@ server_context_service_real_hide_keyboard (EekboardContextService *_context)
|
|||||||
ServerContextService *context = SERVER_CONTEXT_SERVICE(_context);
|
ServerContextService *context = SERVER_CONTEXT_SERVICE(_context);
|
||||||
|
|
||||||
gtk_widget_hide (context->window);
|
gtk_widget_hide (context->window);
|
||||||
|
gtk_container_remove(GTK_CONTAINER(context->window), context->widget);
|
||||||
|
context->widget = NULL; // When GTK removes the widget, it doesn't just unlink it, but also frees it
|
||||||
|
destroy_window (context);
|
||||||
|
|
||||||
EEKBOARD_CONTEXT_SERVICE_CLASS (server_context_service_parent_class)->
|
EEKBOARD_CONTEXT_SERVICE_CLASS (server_context_service_parent_class)->
|
||||||
hide_keyboard (_context);
|
hide_keyboard (_context);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
server_context_service_real_enabled (EekboardContextService *_context)
|
||||||
|
{
|
||||||
|
ServerContextService *context = SERVER_CONTEXT_SERVICE(_context);
|
||||||
|
|
||||||
|
if (context->was_visible && context->window)
|
||||||
|
gtk_widget_show_all (context->window);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
server_context_service_real_disabled (EekboardContextService *_context)
|
||||||
|
{
|
||||||
|
ServerContextService *context = SERVER_CONTEXT_SERVICE(_context);
|
||||||
|
|
||||||
|
if (context->window) {
|
||||||
|
context->was_visible =
|
||||||
|
gtk_widget_get_visible (context->window);
|
||||||
|
gtk_widget_hide (context->window);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
server_context_service_real_destroyed (EekboardContextService *_context)
|
server_context_service_real_destroyed (EekboardContextService *_context)
|
||||||
{
|
{
|
||||||
@ -319,8 +442,10 @@ server_context_service_dispose (GObject *object)
|
|||||||
{
|
{
|
||||||
ServerContextService *context = SERVER_CONTEXT_SERVICE(object);
|
ServerContextService *context = SERVER_CONTEXT_SERVICE(object);
|
||||||
|
|
||||||
destroy_window (context);
|
if (context->window) {
|
||||||
context->widget = NULL;
|
gtk_widget_destroy (context->window);
|
||||||
|
context->window = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
G_OBJECT_CLASS (server_context_service_parent_class)->dispose (object);
|
G_OBJECT_CLASS (server_context_service_parent_class)->dispose (object);
|
||||||
}
|
}
|
||||||
@ -334,6 +459,8 @@ server_context_service_class_init (ServerContextServiceClass *klass)
|
|||||||
|
|
||||||
context_class->show_keyboard = server_context_service_real_show_keyboard;
|
context_class->show_keyboard = server_context_service_real_show_keyboard;
|
||||||
context_class->hide_keyboard = server_context_service_real_hide_keyboard;
|
context_class->hide_keyboard = server_context_service_real_hide_keyboard;
|
||||||
|
context_class->enabled = server_context_service_real_enabled;
|
||||||
|
context_class->disabled = server_context_service_real_disabled;
|
||||||
context_class->destroyed = server_context_service_real_destroyed;
|
context_class->destroyed = server_context_service_real_destroyed;
|
||||||
|
|
||||||
gobject_class->set_property = server_context_service_set_property;
|
gobject_class->set_property = server_context_service_set_property;
|
||||||
@ -363,8 +490,9 @@ server_context_service_class_init (ServerContextServiceClass *klass)
|
|||||||
static void
|
static void
|
||||||
server_context_service_init (ServerContextService *context)
|
server_context_service_init (ServerContextService *context)
|
||||||
{
|
{
|
||||||
GdkScreen *screen = gdk_screen_get_default ();
|
GdkScreen *screen;
|
||||||
|
|
||||||
|
screen = gdk_screen_get_default ();
|
||||||
g_signal_connect (screen,
|
g_signal_connect (screen,
|
||||||
"monitors-changed",
|
"monitors-changed",
|
||||||
G_CALLBACK(on_monitors_changed),
|
G_CALLBACK(on_monitors_changed),
|
||||||
@ -373,7 +501,6 @@ server_context_service_init (ServerContextService *context)
|
|||||||
"notify::keyboard",
|
"notify::keyboard",
|
||||||
G_CALLBACK(on_notify_keyboard),
|
G_CALLBACK(on_notify_keyboard),
|
||||||
context);
|
context);
|
||||||
|
|
||||||
g_signal_connect (context,
|
g_signal_connect (context,
|
||||||
"notify::fullscreen",
|
"notify::fullscreen",
|
||||||
G_CALLBACK(on_notify_fullscreen),
|
G_CALLBACK(on_notify_fullscreen),
|
||||||
@ -383,5 +510,6 @@ server_context_service_init (ServerContextService *context)
|
|||||||
EekboardContextService *
|
EekboardContextService *
|
||||||
server_context_service_new ()
|
server_context_service_new ()
|
||||||
{
|
{
|
||||||
return EEKBOARD_CONTEXT_SERVICE(g_object_new (SERVER_TYPE_CONTEXT_SERVICE, NULL));
|
return EEKBOARD_CONTEXT_SERVICE(g_object_new (SERVER_TYPE_CONTEXT_SERVICE,
|
||||||
|
NULL));
|
||||||
}
|
}
|
||||||
|
|||||||
@ -23,7 +23,13 @@
|
|||||||
#include <gtk/gtk.h>
|
#include <gtk/gtk.h>
|
||||||
#include <glib/gi18n.h>
|
#include <glib/gi18n.h>
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
#endif /* HAVE_CONFIG_H */
|
||||||
|
|
||||||
|
#if HAVE_CLUTTER_GTK
|
||||||
|
#include <clutter-gtk/clutter-gtk.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "eekboard/eekboard-service.h"
|
#include "eekboard/eekboard-service.h"
|
||||||
#include "eek/eek.h"
|
#include "eek/eek.h"
|
||||||
|
|||||||
41
src/setup-main.c
Normal file
41
src/setup-main.c
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2012 Daiki Ueno <ueno@unixuser.org>
|
||||||
|
* Copyright (C) 2012 Red Hat, Inc.
|
||||||
|
*
|
||||||
|
* 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 3 of the License, 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, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include <config.h>
|
||||||
|
#endif
|
||||||
|
#include "preferences-dialog.h"
|
||||||
|
#include <gtk/gtk.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
int
|
||||||
|
main (int argc, char **argv)
|
||||||
|
{
|
||||||
|
PreferencesDialog *dialog;
|
||||||
|
|
||||||
|
if (!gtk_init_check (&argc, &argv)) {
|
||||||
|
g_printerr ("Can't init GTK\n");
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
dialog = preferences_dialog_new ();
|
||||||
|
preferences_dialog_run (dialog);
|
||||||
|
preferences_dialog_free (dialog);
|
||||||
|
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
||||||
@ -30,15 +30,16 @@ test_create (void)
|
|||||||
section = eek_keyboard_create_section (keyboard);
|
section = eek_keyboard_create_section (keyboard);
|
||||||
g_assert (EEK_IS_SECTION(section));
|
g_assert (EEK_IS_SECTION(section));
|
||||||
eek_section_add_row (section, 2, EEK_ORIENTATION_HORIZONTAL);
|
eek_section_add_row (section, 2, EEK_ORIENTATION_HORIZONTAL);
|
||||||
key0 = eek_section_create_key (section, "key0", 1, 0, 0);
|
key0 = eek_section_create_key (section, 1, 0, 0);
|
||||||
g_assert (EEK_IS_KEY(key0));
|
g_assert (EEK_IS_KEY(key0));
|
||||||
key1 = eek_section_create_key (section, "key1", 2, 1, 0);
|
key1 = eek_section_create_key (section, 2, 1, 0);
|
||||||
g_assert (EEK_IS_KEY(key1));
|
g_assert (EEK_IS_KEY(key1));
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
main (int argc, char **argv)
|
main (int argc, char **argv)
|
||||||
{
|
{
|
||||||
|
g_type_init ();
|
||||||
g_test_init (&argc, &argv, NULL);
|
g_test_init (&argc, &argv, NULL);
|
||||||
g_test_add_func ("/eek-simple-test/create", test_create);
|
g_test_add_func ("/eek-simple-test/create", test_create);
|
||||||
return g_test_run ();
|
return g_test_run ();
|
||||||
|
|||||||
@ -21,7 +21,9 @@
|
|||||||
/* For gdk_x11_display_get_xdisplay(). See main(). */
|
/* For gdk_x11_display_get_xdisplay(). See main(). */
|
||||||
#include <gtk/gtk.h>
|
#include <gtk/gtk.h>
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
#endif /* HAVE_CONFIG_H */
|
||||||
|
|
||||||
#include "eek/eek.h"
|
#include "eek/eek.h"
|
||||||
|
|
||||||
@ -36,9 +38,7 @@ test_output_parse (void)
|
|||||||
layout = eek_xml_layout_new ("us", &error);
|
layout = eek_xml_layout_new ("us", &error);
|
||||||
g_assert_no_error (error);
|
g_assert_no_error (error);
|
||||||
|
|
||||||
/* We don't need the context service to parse an XML file, so we can pass
|
keyboard = eek_keyboard_new (layout, 640, 480);
|
||||||
NULL when creating a keyboard. */
|
|
||||||
keyboard = eek_keyboard_new (NULL, layout, 640, 480);
|
|
||||||
g_object_unref (layout);
|
g_object_unref (layout);
|
||||||
g_object_unref (keyboard);
|
g_object_unref (keyboard);
|
||||||
}
|
}
|
||||||
@ -46,6 +46,7 @@ test_output_parse (void)
|
|||||||
int
|
int
|
||||||
main (int argc, char **argv)
|
main (int argc, char **argv)
|
||||||
{
|
{
|
||||||
|
g_type_init ();
|
||||||
g_test_init (&argc, &argv, NULL);
|
g_test_init (&argc, &argv, NULL);
|
||||||
gtk_init (&argc, &argv); /* for gdk_x11_display_get_xdisplay() */
|
gtk_init (&argc, &argv); /* for gdk_x11_display_get_xdisplay() */
|
||||||
|
|
||||||
|
|||||||
@ -1,49 +0,0 @@
|
|||||||
if get_option('tests')
|
|
||||||
|
|
||||||
test_env = [
|
|
||||||
'G_TEST_SRCDIR=@0@'.format(meson.current_source_dir()),
|
|
||||||
'G_TEST_BUILDDIR=@0@'.format(meson.current_build_dir()),
|
|
||||||
'G_DEBUG=gc-friendly,fatal-warnings',
|
|
||||||
'GSETTINGS_BACKEND=memory',
|
|
||||||
'MALLOC_CHECK_=2'
|
|
||||||
]
|
|
||||||
|
|
||||||
test_cflags = [
|
|
||||||
'-I@0@/../src'.format(meson.current_source_dir()),
|
|
||||||
'-I@0@/../src'.format(meson.current_build_dir()),
|
|
||||||
'-DEEK_COMPILATION',
|
|
||||||
'-DEEKBOARD_COMPILATION'
|
|
||||||
]
|
|
||||||
|
|
||||||
test_link_args = [
|
|
||||||
'-fPIC',
|
|
||||||
]
|
|
||||||
|
|
||||||
tests = [
|
|
||||||
'eek-simple-test',
|
|
||||||
'eek-xml-test'
|
|
||||||
]
|
|
||||||
|
|
||||||
foreach name : tests
|
|
||||||
|
|
||||||
test_sources = [name + '.c']
|
|
||||||
|
|
||||||
t = executable(
|
|
||||||
name,
|
|
||||||
test_sources,
|
|
||||||
squeekboard_resources,
|
|
||||||
link_with: libsqueekboard,
|
|
||||||
c_args : test_cflags,
|
|
||||||
link_args: test_link_args,
|
|
||||||
dependencies: deps, # from src/meson.build
|
|
||||||
include_directories: [
|
|
||||||
include_directories('..'),
|
|
||||||
include_directories('../eek')
|
|
||||||
]
|
|
||||||
)
|
|
||||||
|
|
||||||
test(name, t, env: test_env)
|
|
||||||
|
|
||||||
endforeach
|
|
||||||
|
|
||||||
endif
|
|
||||||
Reference in New Issue
Block a user