Compare commits
84 Commits
fix-render
...
add-more-p
| Author | SHA1 | Date | |
|---|---|---|---|
| 2c355ec966 | |||
| a19bbdc870 | |||
| 8e0b4f05f8 | |||
| 1010b916ef | |||
| c475ed6619 | |||
| 687b260e29 | |||
| ecc46733da | |||
| d6b59d16fd | |||
| a6e220a2ae | |||
| 593946779e | |||
| 537ded4b58 | |||
| 25a6a00f0f | |||
| 8298a1412b | |||
| 47eb25d07f | |||
| 0057c80b2e | |||
| da88831689 | |||
| 7b6c6e51b3 | |||
| 42b2b3b8f6 | |||
| 64680664e3 | |||
| 87dd9b4374 | |||
| c7d5e8d152 | |||
| 4cd15c074e | |||
| 9bfdabdf57 | |||
| 9375bc212b | |||
| 3829b52127 | |||
| f852cab0f9 | |||
| f53babcd68 | |||
| 016c1086e6 | |||
| f7dd4c84b1 | |||
| c1c0cb6b31 | |||
| e5858bf698 | |||
| b8389f6736 | |||
| 6c1c979414 | |||
| 43df82355a | |||
| d8b26040f9 | |||
| bdf29bf57b | |||
| 24358c39a6 | |||
| 504285c08f | |||
| b7eb4026f6 | |||
| ad5e4f58bb | |||
| 3085a10507 | |||
| b5f0aa423b | |||
| 9344a13bed | |||
| c8bc2c424f | |||
| 46fa6d4500 | |||
| 6002774f95 | |||
| f7f208883c | |||
| 5523b00442 | |||
| c81fdb18de | |||
| 778543c719 | |||
| 18b8972029 | |||
| fa31f8eee1 | |||
| 98a2e33d78 | |||
| 58d01bf502 | |||
| 8326bd7016 | |||
| d5f8b0d83b | |||
| e70a898af5 | |||
| df249646bc | |||
| 35ff93258e | |||
| c58d034494 | |||
| 8f1de46381 | |||
| 1846a67e83 | |||
| 35ac14806c | |||
| 4aee4915d9 | |||
| 5eeaa1c693 | |||
| 9b2fcf89e8 | |||
| e801a68f0d | |||
| ffc5628637 | |||
| 306aa89d06 | |||
| 236415cde4 | |||
| d49e0eaa1b | |||
| 107399a531 | |||
| d8f48cc48b | |||
| 2f0beb6d3a | |||
| 3ab3627ffe | |||
| 70895999c2 | |||
| ce311e1bf1 | |||
| 943b2ad9f3 | |||
| f86bbb09f8 | |||
| 7e939c36cc | |||
| c5d2d76ab1 | |||
| 622ba6e38a | |||
| fad06348a7 | |||
| a6ee303123 |
@ -28,4 +28,4 @@ test:
|
||||
dependencies:
|
||||
- build_meson
|
||||
script:
|
||||
- xvfb-run -s -noreset ninja -C _build test
|
||||
- ninja -C _build test
|
||||
|
||||
@ -33,8 +33,8 @@ See `.gitlab-ci.yml`.
|
||||
### Build from git repo
|
||||
|
||||
```
|
||||
$ git clone https://source.puri.sm/Librem5/eekboard.git
|
||||
$ cd eekboard
|
||||
$ git clone https://source.puri.sm/Librem5/squeekboard.git
|
||||
$ cd squeekboard
|
||||
$ mkdir ../build
|
||||
$ meson ../build/
|
||||
$ cd ../build
|
||||
|
||||
@ -1,120 +1,120 @@
|
||||
<?xml version="1.0"?>
|
||||
<geometry version="0.90">
|
||||
<bounds x="0" y="10.000000" width="426.0000" height="296.5853"/>
|
||||
<bounds x="10" y="10" width="410.0000" height="229"/>
|
||||
<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 name="AD01" oref="outline2" />
|
||||
<key name="AD02" oref="outline2" />
|
||||
<key name="AD03" oref="outline2" />
|
||||
<key name="AD04" oref="outline2" />
|
||||
<key name="AD05" oref="outline2" />
|
||||
<key name="AD06" oref="outline2" />
|
||||
<key name="AD07" oref="outline2" />
|
||||
<key name="AD08" oref="outline2" />
|
||||
<key name="AD09" oref="outline2" />
|
||||
<key name="AD10" 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 name="AC01" oref="outline2" />
|
||||
<key name="AC02" oref="outline2" />
|
||||
<key name="AC03" oref="outline2" />
|
||||
<key name="AC04" oref="outline2" />
|
||||
<key name="AC05" oref="outline2" />
|
||||
<key name="AC06" oref="outline2" />
|
||||
<key name="AC07" oref="outline2" />
|
||||
<key name="AC08" oref="outline2" />
|
||||
<key name="AC09" oref="outline2" />
|
||||
<key name="AC10" 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" />
|
||||
<key name="LFSH" oref="altline" />
|
||||
<key name="AB01" oref="outline2" />
|
||||
<key name="AB02" oref="outline2" />
|
||||
<key name="AB03" oref="outline2" />
|
||||
<key name="AB04" oref="outline2" />
|
||||
<key name="AB05" oref="outline2" />
|
||||
<key name="AB06" oref="outline2" />
|
||||
<key name="AB07" oref="outline2" />
|
||||
<key 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" />
|
||||
<key name="I149" oref="altline" />
|
||||
<key name="SPCE" oref="spaceline" />
|
||||
<key name="AB08" oref="outline2" />
|
||||
<key 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"/>
|
||||
<point x="37.46341" y="52"/>
|
||||
<point x="0.000000" y="52"/>
|
||||
</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"/>
|
||||
<point x="48.39024" y="52"/>
|
||||
<point x="0.000000" y="52"/>
|
||||
</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"/>
|
||||
<point x="59.31707" y="52"/>
|
||||
<point x="0.000000" y="52"/>
|
||||
</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"/>
|
||||
<point x="59.31707" y="52"/>
|
||||
<point x="0.000000" y="52"/>
|
||||
</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"/>
|
||||
<point x="68.68292" y="52"/>
|
||||
<point x="0.000000" y="52"/>
|
||||
</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"/>
|
||||
<point x="88.97561" y="52"/>
|
||||
<point x="0.000000" y="52"/>
|
||||
</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"/>
|
||||
<point x="88.97561" y="52"/>
|
||||
<point x="0.000000" y="52"/>
|
||||
</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"/>
|
||||
<point x="109.2682" y="52"/>
|
||||
<point x="0.000000" y="52"/>
|
||||
</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"/>
|
||||
<point x="37.46341" y="52"/>
|
||||
<point x="0.000000" y="52"/>
|
||||
</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"/>
|
||||
<point x="79.60975" y="52"/>
|
||||
<point x="0.000000" y="52"/>
|
||||
</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"/>
|
||||
<point x="150.5853" y="52"/>
|
||||
<point x="0.000000" y="52"/>
|
||||
</outline>
|
||||
</geometry>
|
||||
|
||||
@ -3,37 +3,30 @@
|
||||
<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" />
|
||||
<key name="AD01" oref="outline4" />
|
||||
<key name="AD02" oref="outline4" />
|
||||
<key name="AD03" oref="outline4" />
|
||||
</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 name="AC01" oref="outline4" />
|
||||
<key name="AC02" oref="outline4" />
|
||||
<key name="AC03" oref="outline4" />
|
||||
</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" />
|
||||
<key name="AB01" oref="outline4" />
|
||||
<key name="AB02" oref="outline4" />
|
||||
<key name="AB03" oref="outline4" />
|
||||
</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" />
|
||||
<key name="BKSP" oref="altline" />
|
||||
<key name="AB04" oref="outline4" />
|
||||
<key name="RTRN" oref="altline" />
|
||||
</row>
|
||||
</section>
|
||||
<outline id="outline2" corner-radius="1.000000">
|
||||
@ -1,126 +1,122 @@
|
||||
<?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" />
|
||||
<key name="AD01" oref="outline2" />
|
||||
<key name="AD02" oref="outline2" />
|
||||
<key name="AD03" oref="outline2" />
|
||||
<key name="AD04" oref="outline2" />
|
||||
<key name="AD05" oref="outline2" />
|
||||
<key name="AD06" oref="outline2" />
|
||||
<key name="AD07" oref="outline2" />
|
||||
<key name="AD08" oref="outline2" />
|
||||
<key name="AD09" oref="outline2" />
|
||||
<key name="AD10" oref="outline2" />
|
||||
<key 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" />
|
||||
<key name="AC01" oref="outline2" />
|
||||
<key name="AC02" oref="outline2" />
|
||||
<key name="AC03" oref="outline2" />
|
||||
<key name="AC04" oref="outline2" />
|
||||
<key name="AC05" oref="outline2" />
|
||||
<key name="AC06" oref="outline2" />
|
||||
<key name="AC07" oref="outline2" />
|
||||
<key name="AC08" oref="outline2" />
|
||||
<key name="AC09" oref="outline2" />
|
||||
<key name="AC10" oref="outline2" />
|
||||
<key 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" />
|
||||
<key name="LFSH" oref="altline" />
|
||||
<key name="AB01" oref="outline2" />
|
||||
<key name="AB02" oref="outline2" />
|
||||
<key name="AB03" oref="outline2" />
|
||||
<key name="AB04" oref="outline2" />
|
||||
<key name="AB05" oref="outline2" />
|
||||
<key name="AB06" oref="outline2" />
|
||||
<key name="AB07" oref="outline2" />
|
||||
<key 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" />
|
||||
<key name="I149" oref="altline" />
|
||||
<key name="SPCE" oref="spaceline" />
|
||||
<key name="AB08" oref="outline2" />
|
||||
<key 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"/>
|
||||
<point x="32" y="52"/>
|
||||
<point x="0.000000" y="52"/>
|
||||
</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"/>
|
||||
<point x="48.39024" y="52"/>
|
||||
<point x="0.000000" y="52"/>
|
||||
</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"/>
|
||||
<point x="59.31707" y="52"/>
|
||||
<point x="0.000000" y="52"/>
|
||||
</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"/>
|
||||
<point x="59.31707" y="52"/>
|
||||
<point x="0.000000" y="52"/>
|
||||
</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"/>
|
||||
<point x="68.68292" y="52"/>
|
||||
<point x="0.000000" y="52"/>
|
||||
</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"/>
|
||||
<point x="88.97561" y="52"/>
|
||||
<point x="0.000000" y="52"/>
|
||||
</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"/>
|
||||
<point x="88.97561" y="52"/>
|
||||
<point x="0.000000" y="52"/>
|
||||
</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"/>
|
||||
<point x="109.2682" y="52"/>
|
||||
<point x="0.000000" y="52"/>
|
||||
</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"/>
|
||||
<point x="37.46341" y="52"/>
|
||||
<point x="0.000000" y="52"/>
|
||||
</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"/>
|
||||
<point x="79.60975" y="52"/>
|
||||
<point x="0.000000" y="52"/>
|
||||
</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"/>
|
||||
<point x="150.5853" y="52"/>
|
||||
<point x="0.000000" y="52"/>
|
||||
</outline>
|
||||
</geometry>
|
||||
|
||||
105
data/keyboards/geometry/number-keypad.xml
Normal file
105
data/keyboards/geometry/number-keypad.xml
Normal file
@ -0,0 +1,105 @@
|
||||
<?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 name="AD01" oref="outline2" />
|
||||
<key name="AD02" oref="outline2" />
|
||||
<key name="AD03" oref="outline2" />
|
||||
<key name="AD04" oref="outline2" />
|
||||
<key name="AD05" oref="outline2" />
|
||||
</row>
|
||||
</section>
|
||||
<section angle="0">
|
||||
<row orientation="1">
|
||||
<key name="AC01" oref="outline2" />
|
||||
<key name="AC02" oref="outline2" />
|
||||
<key name="AC03" oref="outline2" />
|
||||
<key name="AC04" oref="outline2" />
|
||||
<key name="AC05" oref="outline2" />
|
||||
</row>
|
||||
</section>
|
||||
<section angle="0">
|
||||
<row orientation="1">
|
||||
<key name="AB01" oref="outline2" />
|
||||
<key name="AB02" oref="outline2" />
|
||||
<key name="AB03" oref="outline2" />
|
||||
<key name="AB04" oref="outline2" />
|
||||
<key name="AB05" oref="outline2" />
|
||||
</row>
|
||||
</section>
|
||||
<section angle="0">
|
||||
<row orientation="1">
|
||||
<key name="BKSP" oref="altline" />
|
||||
<key name="AB06" oref="outline2" />
|
||||
<key name="SPCE" oref="spaceline" />
|
||||
<key 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>
|
||||
105
data/keyboards/geometry/phone-keypad.xml
Normal file
105
data/keyboards/geometry/phone-keypad.xml
Normal file
@ -0,0 +1,105 @@
|
||||
<?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 name="AD01" oref="outline2" />
|
||||
<key name="AD02" oref="outline2" />
|
||||
<key name="AD03" oref="outline2" />
|
||||
<key name="AD04" oref="outline2" />
|
||||
<key name="AD05" oref="outline2" />
|
||||
</row>
|
||||
</section>
|
||||
<section angle="0">
|
||||
<row orientation="1">
|
||||
<key name="AC01" oref="outline2" />
|
||||
<key name="AC02" oref="outline2" />
|
||||
<key name="AC03" oref="outline2" />
|
||||
<key name="AC04" oref="outline2" />
|
||||
<key name="AC05" oref="outline2" />
|
||||
</row>
|
||||
</section>
|
||||
<section angle="0">
|
||||
<row orientation="1">
|
||||
<key name="AB01" oref="outline2" />
|
||||
<key name="AB02" oref="outline2" />
|
||||
<key name="AB03" oref="outline2" />
|
||||
<key name="AB04" oref="outline2" />
|
||||
<key name="AB05" oref="outline2" />
|
||||
</row>
|
||||
</section>
|
||||
<section angle="0">
|
||||
<row orientation="1">
|
||||
<key name="BKSP" oref="altline" />
|
||||
<key name="AB06" oref="outline2" />
|
||||
<key name="SPCE" oref="spaceline" />
|
||||
<key 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>
|
||||
126
data/keyboards/geometry/url.xml
Normal file
126
data/keyboards/geometry/url.xml
Normal file
@ -0,0 +1,126 @@
|
||||
<?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 name="AD01" oref="outline2" />
|
||||
<key name="AD02" oref="outline2" />
|
||||
<key name="AD03" oref="outline2" />
|
||||
<key name="AD04" oref="outline2" />
|
||||
<key name="AD05" oref="outline2" />
|
||||
<key name="AD06" oref="outline2" />
|
||||
<key name="AD07" oref="outline2" />
|
||||
<key name="AD08" oref="outline2" />
|
||||
<key name="AD09" oref="outline2" />
|
||||
<key name="AD10" oref="outline2" />
|
||||
<key name="AE01" oref="outline6" />
|
||||
<key name="AE02" oref="outline2" />
|
||||
<key name="AE03" oref="outline6" />
|
||||
<key name="AE04" oref="outline6" />
|
||||
<key name="AE05" oref="outline6" />
|
||||
<key name="AE06" oref="outline6" />
|
||||
</row>
|
||||
</section>
|
||||
<section angle="0">
|
||||
<row orientation="1">
|
||||
<key name="AC01" oref="outline2" />
|
||||
<key name="AC02" oref="outline2" />
|
||||
<key name="AC03" oref="outline2" />
|
||||
<key name="AC04" oref="outline2" />
|
||||
<key name="AC05" oref="outline2" />
|
||||
<key name="AC06" oref="outline2" />
|
||||
<key name="AC07" oref="outline2" />
|
||||
<key name="AC08" oref="outline2" />
|
||||
<key name="AC09" oref="outline2" />
|
||||
<key name="AC10" oref="outline2" />
|
||||
</row>
|
||||
</section>
|
||||
<section angle="0">
|
||||
<row orientation="1">
|
||||
<key name="LFSH" oref="altline" />
|
||||
<key name="AB01" oref="outline2" />
|
||||
<key name="AB02" oref="outline2" />
|
||||
<key name="AB03" oref="outline2" />
|
||||
<key name="AB04" oref="outline2" />
|
||||
<key name="AB05" oref="outline2" />
|
||||
<key name="AB06" oref="outline2" />
|
||||
<key name="AB07" oref="outline2" />
|
||||
<key name="BKSP" oref="altline" />
|
||||
</row>
|
||||
</section>
|
||||
<section angle="0">
|
||||
<row orientation="1">
|
||||
<key keycode="0" name="ABC123" oref="altline" />
|
||||
<key name="I149" oref="altline" />
|
||||
<key name="SPCE" oref="spaceline" />
|
||||
<key name="AB08" oref="outline2" />
|
||||
<key 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="150.5853" y="0.000000"/>
|
||||
<point x="150.5853" y="52.44877"/>
|
||||
<point x="0.000000" y="52.44877"/>
|
||||
</outline>
|
||||
</geometry>
|
||||
@ -90,8 +90,17 @@
|
||||
longname="Telugu (Inscript)" language="te"/>
|
||||
|
||||
<!-- Common keyboards -->
|
||||
<keyboard id="numbers" name="numbers"
|
||||
geometry="numbers-keypad" symbols="special/numbers"
|
||||
<keyboard id="digits" name="digits"
|
||||
geometry="digits" symbols="special/digits"
|
||||
longname="Digits" language="all"/>
|
||||
<keyboard id="number" name="number"
|
||||
geometry="number-keypad" symbols="special/number"
|
||||
longname="Numeric keypad" language="all"/>
|
||||
<keyboard id="phone" name="phone"
|
||||
geometry="phone-keypad" symbols="special/phone"
|
||||
longname="Phone keypad" language="all"/>
|
||||
<keyboard id="url" name="url"
|
||||
geometry="url" symbols="special/url"
|
||||
longname="Uniform Resource Locator" language="all"/>
|
||||
|
||||
</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" {
|
||||
};
|
||||
};
|
||||
@ -63,8 +63,10 @@
|
||||
<key name="AD11">
|
||||
<symbol keyval="229" label="å">aring</symbol>
|
||||
<symbol keyval="197" label="Å">Aring</symbol>
|
||||
<symbol label="±">U00B1</symbol>
|
||||
<symbol label="§">U00A7</symbol>
|
||||
<symbol label=""></symbol>
|
||||
<symbol label=""></symbol>
|
||||
<!-- Empty labels cause keys to be hidden when the level they are defined
|
||||
for is shown. -->
|
||||
</key>
|
||||
<key name="AC01">
|
||||
<symbol label="a">a</symbol>
|
||||
@ -100,37 +102,37 @@
|
||||
<symbol label="h">h</symbol>
|
||||
<symbol label="H">H</symbol>
|
||||
<symbol label="-">minus</symbol>
|
||||
<symbol label="_">underscore</symbol>
|
||||
<symbol label="^">asciicircum</symbol>
|
||||
</key>
|
||||
<key name="AC07">
|
||||
<symbol label="j">j</symbol>
|
||||
<symbol label="J">J</symbol>
|
||||
<symbol label="+">plus</symbol>
|
||||
<symbol label="=">equal</symbol>
|
||||
<symbol label="_">underscore</symbol>
|
||||
<symbol label="°">degree</symbol>
|
||||
</key>
|
||||
<key name="AC08">
|
||||
<symbol label="k">k</symbol>
|
||||
<symbol label="K">K</symbol>
|
||||
<symbol label="ü">U00FC</symbol>
|
||||
<symbol label="^">asciicircum</symbol>
|
||||
<symbol label="+">plus</symbol>
|
||||
<symbol label="=">equal</symbol>
|
||||
</key>
|
||||
<key name="AC09">
|
||||
<symbol label="l">l</symbol>
|
||||
<symbol label="L">L</symbol>
|
||||
<symbol label="ö">U00F6</symbol>
|
||||
<symbol label="°">degree</symbol>
|
||||
<symbol label="(">parenleft</symbol>
|
||||
<symbol label="{">braceleft</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>
|
||||
<symbol label=")">parenright</symbol>
|
||||
<symbol label="}">braceright</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>
|
||||
<symbol label=""></symbol>
|
||||
<symbol label=""></symbol>
|
||||
</key>
|
||||
<key name="RTRN">
|
||||
<symbol keyval="65293" icon="key-enter">Return</symbol>
|
||||
|
||||
39
data/keyboards/symbols/special/digits.xml
Normal file
39
data/keyboards/symbols/special/digits.xml
Normal file
@ -0,0 +1,39 @@
|
||||
<?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="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="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="0">0</symbol>
|
||||
</key>
|
||||
<key name="RTRN">
|
||||
<symbol keyval="65293" icon="key-enter">Return</symbol>
|
||||
</key>
|
||||
<key name="BKSP">
|
||||
<symbol keyval="65288" icon="edit-clear-symbolic">BackSpace</symbol>
|
||||
</key>
|
||||
</symbols>
|
||||
60
data/keyboards/symbols/special/number.xml
Normal file
60
data/keyboards/symbols/special/number.xml
Normal file
@ -0,0 +1,60 @@
|
||||
<?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=".">period</symbol>
|
||||
</key>
|
||||
<key name="AD05">
|
||||
<symbol label=",">comma</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="/">slash</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>
|
||||
231
data/keyboards/symbols/special/url.xml
Normal file
231
data/keyboards/symbols/special/url.xml
Normal file
@ -0,0 +1,231 @@
|
||||
<?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=""></symbol>
|
||||
<symbol label="1">1</symbol>
|
||||
</key>
|
||||
<key name="AD02">
|
||||
<symbol label="w">w</symbol>
|
||||
<symbol label="W">W</symbol>
|
||||
<symbol label=""></symbol>
|
||||
<symbol label="2">2</symbol>
|
||||
</key>
|
||||
<key name="AD03">
|
||||
<symbol label="e">e</symbol>
|
||||
<symbol label="E">E</symbol>
|
||||
<symbol label=""></symbol>
|
||||
<symbol label="3">3</symbol>
|
||||
</key>
|
||||
<key name="AD04">
|
||||
<symbol label="r">r</symbol>
|
||||
<symbol label="R">R</symbol>
|
||||
<symbol label=""></symbol>
|
||||
<symbol label="4">4</symbol>
|
||||
</key>
|
||||
<key name="AD05">
|
||||
<symbol label="t">t</symbol>
|
||||
<symbol label="T">T</symbol>
|
||||
<symbol label=""></symbol>
|
||||
<symbol label="5">5</symbol>
|
||||
</key>
|
||||
<key name="AD06">
|
||||
<symbol label="y">y</symbol>
|
||||
<symbol label="Y">Y</symbol>
|
||||
<symbol label=""></symbol>
|
||||
<symbol label="6">6</symbol>
|
||||
</key>
|
||||
<key name="AD07">
|
||||
<symbol label="u">u</symbol>
|
||||
<symbol label="U">U</symbol>
|
||||
<symbol label=""></symbol>
|
||||
<symbol label="7">7</symbol>
|
||||
</key>
|
||||
<key name="AD08">
|
||||
<symbol label="i">i</symbol>
|
||||
<symbol label="I">I</symbol>
|
||||
<symbol label=""></symbol>
|
||||
<symbol label="8">8</symbol>
|
||||
</key>
|
||||
<key name="AD09">
|
||||
<symbol label="o">o</symbol>
|
||||
<symbol label="O">O</symbol>
|
||||
<symbol label=""></symbol>
|
||||
<symbol label="9">9</symbol>
|
||||
</key>
|
||||
<key name="AD10">
|
||||
<symbol label="p">p</symbol>
|
||||
<symbol label="P">P</symbol>
|
||||
<symbol label=""></symbol>
|
||||
<symbol label="0">0</symbol>
|
||||
</key>
|
||||
<key name="AC01">
|
||||
<symbol label="a">a</symbol>
|
||||
<symbol label="A">A</symbol>
|
||||
<symbol label="@">at</symbol>
|
||||
<symbol label="~">asciitilde</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="^">asciicircum</symbol>
|
||||
</key>
|
||||
<key name="AC07">
|
||||
<symbol label="j">j</symbol>
|
||||
<symbol label="J">J</symbol>
|
||||
<symbol label="_">underscore</symbol>
|
||||
<symbol label="°">degree</symbol>
|
||||
</key>
|
||||
<key name="AC08">
|
||||
<symbol label="k">k</symbol>
|
||||
<symbol label="K">K</symbol>
|
||||
<symbol label="+">plus</symbol>
|
||||
<symbol label="=">equal</symbol>
|
||||
</key>
|
||||
<key name="AC09">
|
||||
<symbol label="l">l</symbol>
|
||||
<symbol label="L">L</symbol>
|
||||
<symbol label="(">parenleft</symbol>
|
||||
<symbol label="{">braceleft</symbol>
|
||||
</key>
|
||||
<key name="AC10">
|
||||
<symbol label=""></symbol>
|
||||
<symbol label=""></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="123">Shift_L</keysym>
|
||||
<keysym keyval="65505" label="URL">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="URL">show-url</symbol>
|
||||
<symbol label="URL">show-url</symbol>
|
||||
<symbol label="ABC">show-letters</symbol>
|
||||
<symbol label="ABC">show-letters</symbol>
|
||||
</key>
|
||||
<key name="I149">
|
||||
<symbol label="☺" 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>
|
||||
|
||||
<!-- Extra URL mode buttons -->
|
||||
<key name="AE01">
|
||||
<symbol label=""></symbol>
|
||||
<symbol label=""></symbol>
|
||||
<text label="https">https</text>
|
||||
<symbol label=""></symbol>
|
||||
</key>
|
||||
<key name="AE02">
|
||||
<symbol label=""></symbol>
|
||||
<symbol label=""></symbol>
|
||||
<text label="://">://</text>
|
||||
<symbol label=""></symbol>
|
||||
</key>
|
||||
<key name="AE03">
|
||||
<symbol label=""></symbol>
|
||||
<symbol label=""></symbol>
|
||||
<text label="www.">www.</text>
|
||||
<symbol label=""></symbol>
|
||||
</key>
|
||||
<key name="AE04">
|
||||
<symbol label=""></symbol>
|
||||
<symbol label=""></symbol>
|
||||
<text label=".com">.com</text>
|
||||
<symbol label=""></symbol>
|
||||
</key>
|
||||
<key name="AE05">
|
||||
<symbol label=""></symbol>
|
||||
<symbol label=""></symbol>
|
||||
<text label=".org">.org</text>
|
||||
<symbol label=""></symbol>
|
||||
</key>
|
||||
<key name="AE06">
|
||||
<symbol label=""></symbol>
|
||||
<symbol label=""></symbol>
|
||||
<text label=".net">.net</text>
|
||||
<symbol label=""></symbol>
|
||||
</key>
|
||||
|
||||
</symbols>
|
||||
@ -115,6 +115,8 @@
|
||||
<symbol label="{">braceleft</symbol>
|
||||
</key>
|
||||
<key name="AC10">
|
||||
<!-- Empty labels cause keys to be hidden when the level they are defined
|
||||
for is shown. -->
|
||||
<symbol label=""></symbol>
|
||||
<symbol label=""></symbol>
|
||||
<symbol label=")">parenright</symbol>
|
||||
|
||||
@ -2,13 +2,19 @@
|
||||
<gresources>
|
||||
<gresource prefix="/sm/puri/squeekboard">
|
||||
<file compressed="true">style.css</file>
|
||||
|
||||
<!-- Keyboard layouts -->
|
||||
<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/geometry/digits.xml</file>
|
||||
<file compressed="true" preprocess="xml-stripblanks">keyboards/geometry/number-keypad.xml</file>
|
||||
<file compressed="true" preprocess="xml-stripblanks">keyboards/geometry/phone-keypad.xml</file>
|
||||
<file compressed="true" preprocess="xml-stripblanks">keyboards/geometry/url.xml</file>
|
||||
|
||||
<!-- Keyboard definitions -->
|
||||
<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>
|
||||
|
||||
<!-- Natural language keyboards -->
|
||||
<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>
|
||||
@ -38,7 +44,13 @@
|
||||
<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>
|
||||
|
||||
<!-- Special purpose keyboards -->
|
||||
<file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/special/digits.xml</file>
|
||||
<file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/special/number.xml</file>
|
||||
<file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/special/phone.xml</file>
|
||||
<file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/special/url.xml</file>
|
||||
|
||||
<file>icons/key-enter.svg</file>
|
||||
<file>icons/key-shift.svg</file>
|
||||
<file>icons/keyboard-mode-symbolic.svg</file>
|
||||
|
||||
@ -50,7 +50,7 @@ static void
|
||||
eek_container_real_add_child (EekContainer *self,
|
||||
EekElement *child)
|
||||
{
|
||||
EekContainerPrivate *priv = eek_container_get_instance_private (self);
|
||||
EekContainerPrivate *priv = (EekContainerPrivate*)eek_container_get_instance_private (self);
|
||||
|
||||
g_return_if_fail (EEK_IS_ELEMENT(child));
|
||||
g_object_ref (child);
|
||||
|
||||
@ -100,6 +100,7 @@ eek_element_set_property (GObject *object,
|
||||
break;
|
||||
case PROP_LEVEL:
|
||||
eek_element_set_level (element, g_value_get_int (value));
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
|
||||
@ -55,7 +55,8 @@ typedef struct _EekGtkKeyboardPrivate
|
||||
{
|
||||
EekRenderer *renderer;
|
||||
EekKeyboard *keyboard;
|
||||
EekTheme *theme;
|
||||
GtkCssProvider *css_provider;
|
||||
GtkStyleContext *scontext;
|
||||
|
||||
GdkEventSequence *sequence; // unowned reference
|
||||
} EekGtkKeyboardPrivate;
|
||||
@ -66,16 +67,6 @@ static void on_key_pressed (EekKey *key,
|
||||
EekGtkKeyboard *self);
|
||||
static void on_key_released (EekKey *key,
|
||||
EekGtkKeyboard *self);
|
||||
static void on_key_locked (EekKeyboard *keyboard,
|
||||
EekKey *key,
|
||||
gpointer user_data);
|
||||
static void on_key_unlocked (EekKeyboard *keyboard,
|
||||
EekKey *key,
|
||||
gpointer user_data);
|
||||
static void on_symbol_index_changed (EekKeyboard *keyboard,
|
||||
gint group,
|
||||
gint level,
|
||||
gpointer user_data);
|
||||
static void render_pressed_key (GtkWidget *widget,
|
||||
EekKey *key);
|
||||
static void render_locked_key (GtkWidget *widget,
|
||||
@ -109,12 +100,9 @@ eek_gtk_keyboard_real_draw (GtkWidget *self,
|
||||
gtk_widget_get_allocation (self, &allocation);
|
||||
|
||||
if (!priv->renderer) {
|
||||
PangoContext *pcontext;
|
||||
PangoContext *pcontext = gtk_widget_get_pango_context (self);
|
||||
|
||||
pcontext = gtk_widget_get_pango_context (self);
|
||||
priv->renderer = eek_renderer_new (priv->keyboard, pcontext);
|
||||
if (priv->theme)
|
||||
eek_renderer_set_theme (priv->renderer, priv->theme);
|
||||
priv->renderer = eek_renderer_new (priv->keyboard, pcontext, priv->scontext);
|
||||
|
||||
eek_renderer_set_allocation_size (priv->renderer,
|
||||
allocation.width,
|
||||
@ -159,9 +147,11 @@ eek_gtk_keyboard_real_size_allocate (GtkWidget *self,
|
||||
}
|
||||
|
||||
static void depress(EekGtkKeyboard *self,
|
||||
gdouble x, gdouble y, guint32 time) {
|
||||
gdouble x, gdouble y, guint32 time)
|
||||
{
|
||||
EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (self);
|
||||
EekKey *key = eek_renderer_find_key_by_position (priv->renderer, x, y);
|
||||
|
||||
if (key) {
|
||||
eek_keyboard_press_key(priv->keyboard, key, time);
|
||||
on_key_pressed(key, self);
|
||||
@ -172,16 +162,17 @@ static void drag(EekGtkKeyboard *self,
|
||||
gdouble x, gdouble y, guint32 time) {
|
||||
EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (self);
|
||||
EekKey *key = eek_renderer_find_key_by_position (priv->renderer, x, y);
|
||||
GList *list, *head;
|
||||
|
||||
list = eek_keyboard_get_pressed_keys (priv->keyboard);
|
||||
|
||||
if (key) {
|
||||
GList *list, *head;
|
||||
gboolean found = FALSE;
|
||||
|
||||
list = eek_keyboard_get_pressed_keys (priv->keyboard);
|
||||
for (head = list; head; head = g_list_next (head)) {
|
||||
if (head->data == key)
|
||||
if (head->data == key) {
|
||||
found = TRUE;
|
||||
else {
|
||||
} else {
|
||||
eek_keyboard_release_key(priv->keyboard, EEK_KEY(head->data), time);
|
||||
on_key_released(key, self);
|
||||
}
|
||||
@ -192,6 +183,12 @@ static void drag(EekGtkKeyboard *self,
|
||||
eek_keyboard_press_key(priv->keyboard, key, time);
|
||||
on_key_pressed(key, self);
|
||||
}
|
||||
} else {
|
||||
for (head = list; head; head = g_list_next (head)) {
|
||||
eek_keyboard_release_key(priv->keyboard, EEK_KEY(head->data), time);
|
||||
on_key_released(key, self);
|
||||
}
|
||||
g_list_free (list);
|
||||
}
|
||||
}
|
||||
|
||||
@ -332,18 +329,10 @@ eek_gtk_keyboard_set_keyboard (EekGtkKeyboard *self,
|
||||
return;
|
||||
|
||||
if (priv->keyboard) {
|
||||
g_signal_handlers_disconnect_by_data(priv->keyboard, self);
|
||||
g_object_unref (priv->keyboard);
|
||||
}
|
||||
|
||||
priv->keyboard = g_object_ref (keyboard);
|
||||
|
||||
g_signal_connect (priv->keyboard, "key-locked",
|
||||
G_CALLBACK(on_key_locked), self);
|
||||
g_signal_connect (priv->keyboard, "key-unlocked",
|
||||
G_CALLBACK(on_key_unlocked), self);
|
||||
g_signal_connect (priv->keyboard, "symbol-index-changed",
|
||||
G_CALLBACK(on_symbol_index_changed), self);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -379,7 +368,6 @@ eek_gtk_keyboard_dispose (GObject *object)
|
||||
if (priv->keyboard) {
|
||||
GList *list, *head;
|
||||
|
||||
g_signal_handlers_disconnect_by_data(priv->keyboard, self);
|
||||
list = eek_keyboard_get_pressed_keys (priv->keyboard);
|
||||
for (head = list; head; head = g_list_next (head)) {
|
||||
g_log("squeek", G_LOG_LEVEL_DEBUG, "emit EekKey pressed");
|
||||
@ -391,11 +379,6 @@ eek_gtk_keyboard_dispose (GObject *object)
|
||||
priv->keyboard = NULL;
|
||||
}
|
||||
|
||||
if (priv->theme) {
|
||||
g_object_unref (priv->theme);
|
||||
priv->theme = NULL;
|
||||
}
|
||||
|
||||
G_OBJECT_CLASS (eek_gtk_keyboard_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
@ -436,7 +419,20 @@ eek_gtk_keyboard_class_init (EekGtkKeyboardClass *klass)
|
||||
static void
|
||||
eek_gtk_keyboard_init (EekGtkKeyboard *self)
|
||||
{
|
||||
/* void */
|
||||
EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (self);
|
||||
|
||||
/* Create a default CSS provider and load a style sheet */
|
||||
priv->css_provider = gtk_css_provider_new ();
|
||||
gtk_css_provider_load_from_resource (priv->css_provider,
|
||||
"/sm/puri/squeekboard/style.css");
|
||||
|
||||
/* Apply the style to the widget */
|
||||
priv->scontext = gtk_widget_get_style_context (GTK_WIDGET(self));
|
||||
gtk_style_context_add_class (priv->scontext, "keyboard");
|
||||
gtk_style_context_add_provider (priv->scontext,
|
||||
GTK_STYLE_PROVIDER(priv->css_provider),
|
||||
GTK_STYLE_PROVIDER_PRIORITY_USER);
|
||||
gtk_style_context_set_state (priv->scontext, GTK_STATE_FLAG_NORMAL);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -481,25 +477,15 @@ render_pressed_key (GtkWidget *widget,
|
||||
{
|
||||
EekGtkKeyboard *self = EEK_GTK_KEYBOARD (widget);
|
||||
EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (self);
|
||||
EekBounds bounds, large_bounds;
|
||||
|
||||
GdkWindow *window = gtk_widget_get_window (widget);
|
||||
cairo_region_t *region = gdk_window_get_clip_region (window);
|
||||
GdkDrawingContext *context = gdk_window_begin_draw_frame (window, region);
|
||||
cairo_t *cr = gdk_drawing_context_get_cairo_context (context);
|
||||
|
||||
eek_renderer_get_key_bounds (priv->renderer, key, &bounds, TRUE);
|
||||
magnify_bounds (widget, &bounds, &large_bounds, 1.5);
|
||||
|
||||
cairo_save (cr);
|
||||
cairo_translate (cr, bounds.x, bounds.y);
|
||||
eek_renderer_render_key (priv->renderer, cr, key, 1.0, TRUE);
|
||||
cairo_restore (cr);
|
||||
/*
|
||||
cairo_save (cr);
|
||||
cairo_translate (cr, large_bounds.x, large_bounds.y);
|
||||
eek_renderer_render_key (priv->renderer, cr, key, 1.5, TRUE);
|
||||
cairo_restore (cr);
|
||||
*/
|
||||
gdk_window_end_draw_frame (window, context);
|
||||
|
||||
@ -512,16 +498,12 @@ render_locked_key (GtkWidget *widget,
|
||||
{
|
||||
EekGtkKeyboard *self = EEK_GTK_KEYBOARD (widget);
|
||||
EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (self);
|
||||
EekBounds bounds;
|
||||
|
||||
GdkWindow *window = gtk_widget_get_window (widget);
|
||||
cairo_region_t *region = gdk_window_get_clip_region (window);
|
||||
GdkDrawingContext *context = gdk_window_begin_draw_frame (window, region);
|
||||
cairo_t *cr = gdk_drawing_context_get_cairo_context (context);
|
||||
|
||||
eek_renderer_get_key_bounds (priv->renderer, key, &bounds, TRUE);
|
||||
|
||||
cairo_translate (cr, bounds.x, bounds.y);
|
||||
eek_renderer_render_key (priv->renderer, cr, key, 1.0, TRUE);
|
||||
|
||||
gdk_window_end_draw_frame (window, context);
|
||||
@ -535,16 +517,12 @@ render_released_key (GtkWidget *widget,
|
||||
{
|
||||
EekGtkKeyboard *self = EEK_GTK_KEYBOARD (widget);
|
||||
EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (self);
|
||||
EekBounds bounds, large_bounds;
|
||||
|
||||
GdkWindow *window = gtk_widget_get_window (widget);
|
||||
cairo_region_t *region = gdk_window_get_clip_region (window);
|
||||
GdkDrawingContext *context = gdk_window_begin_draw_frame (window, region);
|
||||
cairo_t *cr = gdk_drawing_context_get_cairo_context (context);
|
||||
|
||||
eek_renderer_get_key_bounds (priv->renderer, key, &bounds, TRUE);
|
||||
magnify_bounds (widget, &bounds, &large_bounds, 1.5);
|
||||
|
||||
eek_renderer_render_keyboard (priv->renderer, cr);
|
||||
|
||||
gdk_window_end_draw_frame (window, context);
|
||||
@ -595,57 +573,3 @@ on_key_released (EekKey *key,
|
||||
NULL);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
on_key_locked (EekKeyboard *keyboard,
|
||||
EekKey *key,
|
||||
gpointer user_data)
|
||||
{
|
||||
GtkWidget *widget = user_data;
|
||||
EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (user_data);
|
||||
|
||||
/* renderer may have not been set yet if the widget is a popup */
|
||||
if (!priv->renderer)
|
||||
return;
|
||||
|
||||
render_locked_key (widget, key);
|
||||
gtk_widget_queue_draw (widget);
|
||||
}
|
||||
|
||||
static void
|
||||
on_key_unlocked (EekKeyboard *keyboard,
|
||||
EekKey *key,
|
||||
gpointer user_data)
|
||||
{
|
||||
GtkWidget *widget = user_data;
|
||||
EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (user_data);
|
||||
|
||||
/* renderer may have not been set yet if the widget is a popup */
|
||||
if (!priv->renderer)
|
||||
return;
|
||||
|
||||
render_released_key (widget, key);
|
||||
gtk_widget_queue_draw (GTK_WIDGET(widget));
|
||||
}
|
||||
|
||||
static void
|
||||
on_symbol_index_changed (EekKeyboard *keyboard,
|
||||
gint group,
|
||||
gint level,
|
||||
gpointer user_data)
|
||||
{
|
||||
GtkWidget *widget = user_data;
|
||||
|
||||
gtk_widget_queue_draw (widget);
|
||||
}
|
||||
|
||||
void
|
||||
eek_gtk_keyboard_set_theme (EekGtkKeyboard *keyboard,
|
||||
EekTheme *theme)
|
||||
{
|
||||
g_return_if_fail (EEK_IS_GTK_KEYBOARD(keyboard));
|
||||
g_return_if_fail (EEK_IS_THEME(theme));
|
||||
|
||||
EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (keyboard);
|
||||
priv->theme = g_object_ref (theme);
|
||||
}
|
||||
|
||||
@ -46,8 +46,6 @@ struct _EekGtkKeyboardClass
|
||||
|
||||
GType eek_gtk_keyboard_get_type (void) G_GNUC_CONST;
|
||||
GtkWidget *eek_gtk_keyboard_new (EekKeyboard *keyboard);
|
||||
void eek_gtk_keyboard_set_theme (EekGtkKeyboard *keyboard,
|
||||
EekTheme *theme);
|
||||
|
||||
G_END_DECLS
|
||||
#endif /* EEK_GTK_KEYBOARD_H */
|
||||
|
||||
101
eek/eek-key.c
101
eek/eek-key.c
@ -38,8 +38,6 @@ enum {
|
||||
PROP_0,
|
||||
PROP_KEYCODE,
|
||||
PROP_SYMBOL_MATRIX,
|
||||
PROP_COLUMN,
|
||||
PROP_ROW,
|
||||
PROP_OREF,
|
||||
PROP_LAST
|
||||
};
|
||||
@ -56,8 +54,6 @@ typedef struct _EekKeyPrivate
|
||||
{
|
||||
guint keycode;
|
||||
EekSymbolMatrix *symbol_matrix;
|
||||
gint column;
|
||||
gint row;
|
||||
gulong oref; // UI outline reference
|
||||
gboolean is_pressed;
|
||||
gboolean is_locked;
|
||||
@ -105,8 +101,6 @@ eek_key_set_property (GObject *object,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
EekSymbolMatrix *matrix;
|
||||
gint column, row;
|
||||
|
||||
switch (prop_id) {
|
||||
case PROP_KEYCODE:
|
||||
eek_key_set_keycode (EEK_KEY(object), g_value_get_uint (value));
|
||||
@ -115,14 +109,6 @@ eek_key_set_property (GObject *object,
|
||||
matrix = g_value_get_boxed (value);
|
||||
eek_key_set_symbol_matrix (EEK_KEY(object), matrix);
|
||||
break;
|
||||
case PROP_COLUMN:
|
||||
eek_key_get_index (EEK_KEY(object), &column, &row);
|
||||
eek_key_set_index (EEK_KEY(object), g_value_get_int (value), row);
|
||||
break;
|
||||
case PROP_ROW:
|
||||
eek_key_get_index (EEK_KEY(object), &column, &row);
|
||||
eek_key_set_index (EEK_KEY(object), column, g_value_get_int (value));
|
||||
break;
|
||||
case PROP_OREF:
|
||||
eek_key_set_oref (EEK_KEY(object), g_value_get_uint (value));
|
||||
break;
|
||||
@ -138,8 +124,6 @@ eek_key_get_property (GObject *object,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
gint column, row;
|
||||
|
||||
switch (prop_id) {
|
||||
case PROP_KEYCODE:
|
||||
g_value_set_uint (value, eek_key_get_keycode (EEK_KEY(object)));
|
||||
@ -148,14 +132,6 @@ eek_key_get_property (GObject *object,
|
||||
g_value_set_boxed (value,
|
||||
eek_key_get_symbol_matrix (EEK_KEY(object)));
|
||||
break;
|
||||
case PROP_COLUMN:
|
||||
eek_key_get_index (EEK_KEY(object), &column, &row);
|
||||
g_value_set_int (value, column);
|
||||
break;
|
||||
case PROP_ROW:
|
||||
eek_key_get_index (EEK_KEY(object), &column, &row);
|
||||
g_value_set_int (value, row);
|
||||
break;
|
||||
case PROP_OREF:
|
||||
g_value_set_uint (value, eek_key_get_oref (EEK_KEY(object)));
|
||||
break;
|
||||
@ -203,30 +179,6 @@ eek_key_class_init (EekKeyClass *klass)
|
||||
G_PARAM_READWRITE);
|
||||
g_object_class_install_property (gobject_class, PROP_SYMBOL_MATRIX, pspec);
|
||||
|
||||
/**
|
||||
* EekKey:column:
|
||||
*
|
||||
* The column index of #EekKey in the parent #EekSection.
|
||||
*/
|
||||
pspec = g_param_spec_int ("column",
|
||||
"Column",
|
||||
"Column index of the key in section",
|
||||
-1, G_MAXINT, -1,
|
||||
G_PARAM_READWRITE);
|
||||
g_object_class_install_property (gobject_class, PROP_COLUMN, pspec);
|
||||
|
||||
/**
|
||||
* EekKey:row:
|
||||
*
|
||||
* The row index of #EekKey in the parent #EekSection.
|
||||
*/
|
||||
pspec = g_param_spec_int ("row",
|
||||
"Row",
|
||||
"Row index of the key in section",
|
||||
-1, G_MAXINT, -1,
|
||||
G_PARAM_READWRITE);
|
||||
g_object_class_install_property (gobject_class, PROP_ROW, pspec);
|
||||
|
||||
/**
|
||||
* EekKey:oref:
|
||||
*
|
||||
@ -478,59 +430,6 @@ eek_key_get_symbol_at_index (EekKey *key,
|
||||
level];
|
||||
}
|
||||
|
||||
/**
|
||||
* eek_key_set_index:
|
||||
* @key: an #EekKey
|
||||
* @column: column index of @key in #EekSection
|
||||
* @row: row index of @key in #EekSection
|
||||
*
|
||||
* Set the location of @key in #EekSection with @column and @row.
|
||||
*/
|
||||
void
|
||||
eek_key_set_index (EekKey *key,
|
||||
gint column,
|
||||
gint row)
|
||||
{
|
||||
g_return_if_fail (EEK_IS_KEY(key));
|
||||
g_return_if_fail (0 <= column);
|
||||
g_return_if_fail (0 <= row);
|
||||
|
||||
EekKeyPrivate *priv = eek_key_get_instance_private (key);
|
||||
|
||||
if (priv->column != column) {
|
||||
priv->column = column;
|
||||
g_object_notify (G_OBJECT(key), "column");
|
||||
}
|
||||
if (priv->row != row) {
|
||||
priv->row = row;
|
||||
g_object_notify (G_OBJECT(key), "row");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* eek_key_get_index:
|
||||
* @key: an #EekKey
|
||||
* @column: (allow-none): pointer where the column index of @key in #EekSection will be stored
|
||||
* @row: (allow-none): pointer where the row index of @key in #EekSection will be stored
|
||||
*
|
||||
* Get the location of @key in #EekSection.
|
||||
*/
|
||||
void
|
||||
eek_key_get_index (EekKey *key,
|
||||
gint *column,
|
||||
gint *row)
|
||||
{
|
||||
g_return_if_fail (EEK_IS_KEY(key));
|
||||
g_return_if_fail (column != NULL || row != NULL);
|
||||
|
||||
EekKeyPrivate *priv = eek_key_get_instance_private (key);
|
||||
|
||||
if (column != NULL)
|
||||
*column = priv->column;
|
||||
if (row != NULL)
|
||||
*row = priv->row;
|
||||
}
|
||||
|
||||
/**
|
||||
* eek_key_set_oref:
|
||||
* @key: an #EekKey
|
||||
|
||||
@ -73,13 +73,6 @@ EekSymbol *eek_key_get_symbol_at_index (EekKey *key,
|
||||
gint fallback_group,
|
||||
gint fallback_level);
|
||||
|
||||
void eek_key_set_index (EekKey *key,
|
||||
gint column,
|
||||
gint row);
|
||||
void eek_key_get_index (EekKey *key,
|
||||
gint *column,
|
||||
gint *row);
|
||||
|
||||
void eek_key_set_oref (EekKey *key,
|
||||
guint oref);
|
||||
guint eek_key_get_oref (EekKey *key);
|
||||
|
||||
@ -28,6 +28,7 @@
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include <glib/gprintf.h>
|
||||
|
||||
#include "eek-keyboard.h"
|
||||
#include "eek-marshalers.h"
|
||||
@ -36,6 +37,7 @@
|
||||
#include "eek-symbol.h"
|
||||
#include "eek-enumtypes.h"
|
||||
#include "eekboard/key-emitter.h"
|
||||
#include "keymap.h"
|
||||
|
||||
enum {
|
||||
PROP_0,
|
||||
@ -72,7 +74,11 @@ struct _EekKeyboardPrivate
|
||||
GList *pressed_keys;
|
||||
GList *locked_keys;
|
||||
GArray *outline_array;
|
||||
|
||||
/* Map key names to key objects */
|
||||
GHashTable *names;
|
||||
/* Map characters to symbols and levels */
|
||||
GHashTable *character_map;
|
||||
|
||||
/* modifiers dynamically assigned at run time */
|
||||
EekModifierType num_lock_mask;
|
||||
@ -401,6 +407,7 @@ eek_keyboard_finalize (GObject *object)
|
||||
(GDestroyNotify) eek_modifier_key_free);
|
||||
|
||||
g_hash_table_destroy (priv->names);
|
||||
g_hash_table_destroy (priv->character_map);
|
||||
|
||||
for (i = 0; i < priv->outline_array->len; i++) {
|
||||
EekOutline *outline = &g_array_index (priv->outline_array,
|
||||
@ -529,6 +536,8 @@ eek_keyboard_init (EekKeyboard *self)
|
||||
self->priv->modifier_behavior = EEK_MODIFIER_BEHAVIOR_NONE;
|
||||
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->character_map = g_hash_table_new_full (g_str_hash, g_str_equal,
|
||||
NULL, g_free);
|
||||
eek_element_set_symbol_index (EEK_ELEMENT(self), 0, 0);
|
||||
self->scale = 1.0;
|
||||
}
|
||||
@ -796,3 +805,117 @@ eek_keyboard_get_locked_keys (EekKeyboard *keyboard)
|
||||
g_return_val_if_fail (EEK_IS_KEYBOARD(keyboard), NULL);
|
||||
return g_list_copy (keyboard->priv->locked_keys);
|
||||
}
|
||||
|
||||
/**
|
||||
* eek_keyboard_get_keymap:
|
||||
* @keyboard: an #EekKeyboard
|
||||
*
|
||||
* Get the keymap for the keyboard.
|
||||
* Returns: a string containing the XKB keymap.
|
||||
*/
|
||||
gchar *
|
||||
eek_keyboard_get_keymap(EekKeyboard *keyboard)
|
||||
{
|
||||
/* Start the keycodes and symbols sections with their respective headers. */
|
||||
gchar *keycodes = g_strdup(keymap_keycodes_header);
|
||||
gchar *symbols = g_strdup(keymap_symbols_header);
|
||||
|
||||
/* Iterate over the keys in the name-to-key hash table. */
|
||||
GHashTableIter iter;
|
||||
gpointer key_name, key_ptr;
|
||||
g_hash_table_iter_init(&iter, keyboard->priv->names);
|
||||
|
||||
while (g_hash_table_iter_next(&iter, &key_name, &key_ptr)) {
|
||||
|
||||
gchar *current, *line;
|
||||
EekKey *key = EEK_KEY(key_ptr);
|
||||
int keycode = eek_key_get_keycode(key);
|
||||
|
||||
/* Don't include invalid keycodes in the keymap. */
|
||||
if (keycode == EEK_INVALID_KEYCODE)
|
||||
continue;
|
||||
|
||||
/* Append a key name-to-keycode definition to the keycodes section. */
|
||||
current = keycodes;
|
||||
line = g_strdup_printf(" <%s> = %i;\n", (char *)key_name, keycode);
|
||||
|
||||
keycodes = g_strconcat(current, line, NULL);
|
||||
g_free(line);
|
||||
g_free(current);
|
||||
|
||||
/* Find the symbols associated with the key. */
|
||||
EekSymbolMatrix *matrix = eek_key_get_symbol_matrix(key);
|
||||
EekSymbol *syms[4];
|
||||
int i, j;
|
||||
|
||||
/* Get the symbols for all the levels defined for the key, then
|
||||
pad it out with the first symbol for all levels up to the fourth. */
|
||||
for (i = 0; (i < matrix->num_levels) && (i < 4); ++i)
|
||||
syms[i] = eek_symbol_matrix_get_symbol(matrix, 0, i);
|
||||
|
||||
while (i < 4) {
|
||||
syms[i] = eek_symbol_matrix_get_symbol(matrix, 0, 0);
|
||||
i++;
|
||||
}
|
||||
|
||||
/* The four levels are split into two groups in the keymap.
|
||||
Generate strings for each of these groups, where an empty group is
|
||||
treated specially. */
|
||||
|
||||
gchar *groups[2] = {NULL, NULL};
|
||||
for (i = 0, j = 0; i < 2; ++i, j += 2) {
|
||||
if (syms[j] && syms[j + 1])
|
||||
groups[i] = g_strjoin(", ", eek_symbol_get_name(syms[j]),
|
||||
eek_symbol_get_name(syms[j + 1]),
|
||||
NULL);
|
||||
}
|
||||
|
||||
/* Append a key definition to the symbols section. */
|
||||
current = symbols;
|
||||
line = g_strdup_printf(" key <%s> { [ %s ], [ %s ] };\n",
|
||||
(char *)key_name, groups[0], groups[1]);
|
||||
|
||||
g_free(groups[0]);
|
||||
g_free(groups[1]);
|
||||
|
||||
symbols = g_strconcat(current, line, NULL);
|
||||
g_free(line);
|
||||
g_free(current);
|
||||
}
|
||||
|
||||
/* Assemble the keymap file from the header, sections and footer. */
|
||||
gchar *keymap = g_strconcat(keymap_header,
|
||||
keycodes, " };\n\n",
|
||||
symbols, " };\n\n",
|
||||
keymap_footer, NULL);
|
||||
|
||||
g_free(keycodes);
|
||||
g_free(symbols);
|
||||
return keymap;
|
||||
}
|
||||
|
||||
void
|
||||
eek_keyboard_register_symbol (EekKeyboard *keyboard,
|
||||
EekSymbol *symbol,
|
||||
EekKey *key,
|
||||
guint level)
|
||||
{
|
||||
const gchar *label = eek_symbol_get_label(symbol);
|
||||
|
||||
if (label) {
|
||||
EekKeyPress *key_press = g_malloc0 (sizeof(EekKeyPress));
|
||||
key_press->key = key;
|
||||
key_press->level = level;
|
||||
|
||||
g_hash_table_insert (keyboard->priv->character_map,
|
||||
(gpointer)label,
|
||||
key_press);
|
||||
}
|
||||
}
|
||||
|
||||
EekKeyPress *
|
||||
eek_keyboard_get_key_press (EekKeyboard *keyboard,
|
||||
gchar *ch)
|
||||
{
|
||||
return g_hash_table_lookup (keyboard->priv->character_map, ch);
|
||||
}
|
||||
|
||||
@ -124,6 +124,11 @@ struct _EekModifierKey {
|
||||
};
|
||||
typedef struct _EekModifierKey EekModifierKey;
|
||||
|
||||
struct _EekKeyPress {
|
||||
EekKey *key;
|
||||
guint level;
|
||||
};
|
||||
typedef struct _EekKeyPress EekKeyPress;
|
||||
|
||||
EekKeyboard *eek_keyboard_new (EekboardContextService *manager,
|
||||
EekLayout *layout,
|
||||
@ -195,5 +200,18 @@ void eek_modifier_key_free
|
||||
void eek_keyboard_press_key(EekKeyboard *keyboard, EekKey *key, guint32 timestamp);
|
||||
void eek_keyboard_release_key(EekKeyboard *keyboard, EekKey *key, guint32 timestamp);
|
||||
|
||||
gchar * eek_keyboard_get_keymap
|
||||
(EekKeyboard *keyboard);
|
||||
|
||||
void eek_keyboard_register_symbol
|
||||
(EekKeyboard *keyboard,
|
||||
EekSymbol *symbol,
|
||||
EekKey *key,
|
||||
guint level);
|
||||
|
||||
EekKeyPress * eek_keyboard_get_key_press
|
||||
(EekKeyboard *keyboard,
|
||||
gchar *ch);
|
||||
|
||||
G_END_DECLS
|
||||
#endif /* EEK_KEYBOARD_H */
|
||||
|
||||
122
eek/eek-keysym.c
122
eek/eek-keysym.c
@ -48,15 +48,9 @@
|
||||
#define EEK_KEYSYM_Hyper_L 0xffed
|
||||
#define EEK_KEYSYM_Hyper_R 0xffee
|
||||
|
||||
typedef struct _EekKeysymPrivate
|
||||
{
|
||||
guint xkeysym;
|
||||
} EekKeysymPrivate;
|
||||
|
||||
struct _EekKeysymEntry {
|
||||
guint xkeysym;
|
||||
const gchar *name;
|
||||
EekSymbolCategory category;
|
||||
};
|
||||
|
||||
typedef struct _EekKeysymEntry EekKeysymEntry;
|
||||
@ -65,54 +59,6 @@ typedef struct _EekKeysymEntry EekKeysymEntry;
|
||||
#include "eek-unicode-keysym-entries.h"
|
||||
#include "eek-xkeysym-keysym-entries.h"
|
||||
|
||||
static void eek_serializable_iface_init (EekSerializableIface *iface);
|
||||
|
||||
G_DEFINE_TYPE_EXTENDED (EekKeysym, eek_keysym, EEK_TYPE_SYMBOL,
|
||||
0, /* GTypeFlags */
|
||||
G_ADD_PRIVATE (EekKeysym)
|
||||
G_IMPLEMENT_INTERFACE (EEK_TYPE_SERIALIZABLE,
|
||||
eek_serializable_iface_init))
|
||||
|
||||
static EekSerializableIface *eek_keysym_parent_serializable_iface;
|
||||
|
||||
static void
|
||||
eek_keysym_real_serialize (EekSerializable *self,
|
||||
GVariantBuilder *builder)
|
||||
{
|
||||
EekKeysymPrivate *priv = eek_keysym_get_instance_private (
|
||||
EEK_KEYSYM(self));
|
||||
|
||||
eek_keysym_parent_serializable_iface->serialize (self, builder);
|
||||
|
||||
g_variant_builder_add (builder, "u", priv->xkeysym);
|
||||
}
|
||||
|
||||
static gsize
|
||||
eek_keysym_real_deserialize (EekSerializable *self,
|
||||
GVariant *variant,
|
||||
gsize index)
|
||||
{
|
||||
EekKeysymPrivate *priv = eek_keysym_get_instance_private (
|
||||
EEK_KEYSYM(self));
|
||||
|
||||
index = eek_keysym_parent_serializable_iface->deserialize (self,
|
||||
variant,
|
||||
index);
|
||||
|
||||
g_variant_get_child (variant, index++, "u", &priv->xkeysym);
|
||||
|
||||
return index;
|
||||
}
|
||||
|
||||
static void
|
||||
eek_serializable_iface_init (EekSerializableIface *iface)
|
||||
{
|
||||
eek_keysym_parent_serializable_iface =
|
||||
g_type_interface_peek_parent (iface);
|
||||
|
||||
iface->serialize = eek_keysym_real_serialize;
|
||||
iface->deserialize = eek_keysym_real_deserialize;
|
||||
}
|
||||
|
||||
static gchar *
|
||||
unichar_to_utf8 (gunichar uc)
|
||||
@ -197,18 +143,6 @@ get_modifier_mask (guint xkeysym)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
eek_keysym_class_init (EekKeysymClass *klass)
|
||||
{
|
||||
/* void */
|
||||
}
|
||||
|
||||
static void
|
||||
eek_keysym_init (EekKeysym *self)
|
||||
{
|
||||
/* void */
|
||||
}
|
||||
|
||||
/**
|
||||
* eek_keysym_new_with_modifier:
|
||||
* @xkeysym: an X keysym value
|
||||
@ -217,16 +151,12 @@ eek_keysym_init (EekKeysym *self)
|
||||
* Create an #EekKeysym with given X keysym value @xkeysym and
|
||||
* modifier @modifier_mask.
|
||||
*/
|
||||
EekKeysym *
|
||||
eek_keysym_new_with_modifier (guint xkeysym,
|
||||
EekModifierType modifier_mask)
|
||||
EekSymbol *eek_keysym_new_with_modifier(guint xkeysym,
|
||||
EekModifierType modifier_mask)
|
||||
{
|
||||
EekKeysym *keysym;
|
||||
EekKeysymPrivate *priv;
|
||||
EekKeysymEntry *special_entry, *xkeysym_entry, *unicode_entry,
|
||||
*unichar_entry;
|
||||
gchar *name, *label;
|
||||
EekSymbolCategory category;
|
||||
gunichar uc;
|
||||
|
||||
special_entry =
|
||||
@ -246,23 +176,17 @@ eek_keysym_new_with_modifier (guint xkeysym,
|
||||
unichar_entry = g_slice_new (EekKeysymEntry);
|
||||
unichar_entry->xkeysym = xkeysym;
|
||||
unichar_entry->name = unichar_to_utf8 (uc);
|
||||
unichar_entry->category = EEK_SYMBOL_CATEGORY_LETTER;
|
||||
}
|
||||
|
||||
/* name and category */
|
||||
name = NULL;
|
||||
if (xkeysym_entry) {
|
||||
name = g_strdup (xkeysym_entry->name);
|
||||
category = xkeysym_entry->category;
|
||||
} else if (unichar_entry) {
|
||||
name = g_strdup (unichar_entry->name);
|
||||
category = unichar_entry->category;
|
||||
} else if (unicode_entry) {
|
||||
name = g_strdup (unicode_entry->name);
|
||||
category = unicode_entry->category;
|
||||
} else {
|
||||
name = g_strdup ("");
|
||||
category = EEK_SYMBOL_CATEGORY_UNKNOWN;
|
||||
}
|
||||
|
||||
/* label */
|
||||
@ -275,12 +199,10 @@ eek_keysym_new_with_modifier (guint xkeysym,
|
||||
else
|
||||
label = g_strdup (name);
|
||||
|
||||
keysym = g_object_new (EEK_TYPE_KEYSYM,
|
||||
"name", name,
|
||||
"label", label,
|
||||
"category", category,
|
||||
"modifier-mask", modifier_mask,
|
||||
NULL);
|
||||
EekSymbol *keysym = eek_symbol_new(name);
|
||||
eek_symbol_set_label(keysym, label);
|
||||
eek_symbol_set_modifier_mask(keysym, modifier_mask);
|
||||
|
||||
g_free (name);
|
||||
g_free (label);
|
||||
|
||||
@ -289,8 +211,7 @@ eek_keysym_new_with_modifier (guint xkeysym,
|
||||
g_slice_free (EekKeysymEntry, unichar_entry);
|
||||
}
|
||||
|
||||
priv = eek_keysym_get_instance_private (keysym);
|
||||
priv->xkeysym = xkeysym;
|
||||
keysym->xkeysym = xkeysym;
|
||||
|
||||
return keysym;
|
||||
}
|
||||
@ -301,7 +222,7 @@ eek_keysym_new_with_modifier (guint xkeysym,
|
||||
*
|
||||
* Create an #EekKeysym with given X keysym value @xkeysym.
|
||||
*/
|
||||
EekKeysym *
|
||||
EekSymbol*
|
||||
eek_keysym_new (guint xkeysym)
|
||||
{
|
||||
return eek_keysym_new_with_modifier (xkeysym, get_modifier_mask (xkeysym));
|
||||
@ -313,22 +234,16 @@ eek_keysym_new (guint xkeysym)
|
||||
*
|
||||
* Create an #EekKeysym with an X keysym value looked up by @name.
|
||||
*/
|
||||
EekKeysym *
|
||||
EekSymbol*
|
||||
eek_keysym_new_from_name (const gchar *name)
|
||||
{
|
||||
gint i;
|
||||
|
||||
for (i = 0; i < G_N_ELEMENTS(xkeysym_keysym_entries); i++)
|
||||
for (uint i = 0; i < G_N_ELEMENTS(xkeysym_keysym_entries); i++)
|
||||
if (g_strcmp0 (xkeysym_keysym_entries[i].name, name) == 0)
|
||||
return eek_keysym_new (xkeysym_keysym_entries[i].xkeysym);
|
||||
|
||||
// g_warning ("can't find keysym entry for %s", name);
|
||||
return g_object_new (EEK_TYPE_KEYSYM,
|
||||
"name", name,
|
||||
"label", name,
|
||||
"category", EEK_SYMBOL_CATEGORY_UNKNOWN,
|
||||
"modifier-mask", 0,
|
||||
NULL);
|
||||
EekSymbol *ret = eek_symbol_new(name);
|
||||
eek_symbol_set_label(ret, name);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -338,11 +253,10 @@ eek_keysym_new_from_name (const gchar *name)
|
||||
* Get an X keysym value associated with @keysym
|
||||
*/
|
||||
guint
|
||||
eek_keysym_get_xkeysym (EekKeysym *keysym)
|
||||
eek_keysym_get_xkeysym (EekSymbol *keysym)
|
||||
{
|
||||
EekKeysymPrivate *priv;
|
||||
|
||||
g_assert (EEK_IS_KEYSYM(keysym));
|
||||
priv = eek_keysym_get_instance_private (keysym);
|
||||
return priv->xkeysym;
|
||||
if (keysym->xkeysym == 0) {
|
||||
g_warning("Symbol %s was expected to have a valid keysym", keysym->name);
|
||||
}
|
||||
return keysym->xkeysym;
|
||||
}
|
||||
|
||||
@ -37,20 +37,11 @@ G_BEGIN_DECLS
|
||||
*/
|
||||
#define EEK_INVALID_KEYSYM (0)
|
||||
|
||||
#define EEK_TYPE_KEYSYM (eek_keysym_get_type())
|
||||
G_DECLARE_DERIVABLE_TYPE (EekKeysym, eek_keysym, EEK, KEYSYM, EekSymbol)
|
||||
EekSymbol *eek_keysym_new (guint xkeysym);
|
||||
guint eek_keysym_get_xkeysym (EekSymbol *keysym);
|
||||
|
||||
struct _EekKeysymClass {
|
||||
/*< private >*/
|
||||
EekSymbolClass parent_class;
|
||||
};
|
||||
|
||||
GType eek_keysym_get_type (void) G_GNUC_CONST;
|
||||
EekKeysym *eek_keysym_new (guint xkeysym);
|
||||
guint eek_keysym_get_xkeysym (EekKeysym *keysym);
|
||||
|
||||
EekKeysym *eek_keysym_new_from_name (const gchar *name);
|
||||
EekKeysym *eek_keysym_new_with_modifier (guint xkeysym,
|
||||
EekSymbol *eek_keysym_new_from_name (const gchar *name);
|
||||
EekSymbol *eek_keysym_new_with_modifier (guint xkeysym,
|
||||
EekModifierType modifier_mask);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
@ -129,60 +129,8 @@ eek_layout_place_sections(EekKeyboard *keyboard)
|
||||
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);
|
||||
}
|
||||
|
||||
@ -57,8 +57,6 @@ 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
|
||||
|
||||
@ -33,6 +33,7 @@ enum {
|
||||
PROP_0,
|
||||
PROP_KEYBOARD,
|
||||
PROP_PCONTEXT,
|
||||
PROP_STYLE_CONTEXT,
|
||||
PROP_LAST
|
||||
};
|
||||
|
||||
@ -40,6 +41,9 @@ typedef struct _EekRendererPrivate
|
||||
{
|
||||
EekKeyboard *keyboard;
|
||||
PangoContext *pcontext;
|
||||
GtkCssProvider *css_provider;
|
||||
GtkStyleContext *scontext;
|
||||
GtkStyleContext *key_context;
|
||||
|
||||
EekColor default_foreground_color;
|
||||
EekColor default_background_color;
|
||||
@ -49,6 +53,8 @@ typedef struct _EekRendererPrivate
|
||||
gdouble allocation_height;
|
||||
gdouble scale;
|
||||
gint scale_factor; /* the outputs scale factor */
|
||||
gint origin_x;
|
||||
gint origin_y;
|
||||
|
||||
PangoFontDescription *ascii_font;
|
||||
PangoFontDescription *font;
|
||||
@ -58,7 +64,6 @@ typedef struct _EekRendererPrivate
|
||||
cairo_surface_t *keyboard_surface;
|
||||
gulong symbol_index_changed_handler;
|
||||
|
||||
EekTheme *theme;
|
||||
} EekRendererPrivate;
|
||||
|
||||
G_DEFINE_TYPE_WITH_PRIVATE (EekRenderer, eek_renderer, G_TYPE_OBJECT)
|
||||
@ -66,14 +71,6 @@ G_DEFINE_TYPE_WITH_PRIVATE (EekRenderer, eek_renderer, G_TYPE_OBJECT)
|
||||
static const EekColor DEFAULT_FOREGROUND_COLOR = {0.3, 0.3, 0.3, 1.0};
|
||||
static const EekColor DEFAULT_BACKGROUND_COLOR = {1.0, 1.0, 1.0, 1.0};
|
||||
|
||||
struct _TextProperty {
|
||||
gint category;
|
||||
gboolean ascii;
|
||||
gdouble scale;
|
||||
gboolean ellipses;
|
||||
};
|
||||
typedef struct _TextProperty TextProperty;
|
||||
|
||||
/* eek-keyboard-drawing.c */
|
||||
extern void _eek_rounded_polygon (cairo_t *cr,
|
||||
gdouble radius,
|
||||
@ -105,18 +102,17 @@ create_keyboard_surface_key_callback (EekElement *element,
|
||||
gpointer user_data)
|
||||
{
|
||||
CreateKeyboardSurfaceCallbackData *data = user_data;
|
||||
EekRendererPrivate *priv = eek_renderer_get_instance_private (data->renderer);
|
||||
EekBounds bounds;
|
||||
|
||||
cairo_save (data->cr);
|
||||
|
||||
eek_element_get_bounds (element, &bounds);
|
||||
cairo_translate (data->cr, bounds.x * priv->scale, bounds.y * priv->scale);
|
||||
cairo_translate (data->cr, bounds.x, bounds.y);
|
||||
cairo_rectangle (data->cr,
|
||||
0.0,
|
||||
0.0,
|
||||
bounds.width * priv->scale + 100,
|
||||
bounds.height * priv->scale + 100);
|
||||
bounds.width + 100,
|
||||
bounds.height + 100);
|
||||
cairo_clip (data->cr);
|
||||
render_key (data->renderer, data->cr, EEK_KEY(element), FALSE);
|
||||
|
||||
@ -128,14 +124,13 @@ create_keyboard_surface_section_callback (EekElement *element,
|
||||
gpointer user_data)
|
||||
{
|
||||
CreateKeyboardSurfaceCallbackData *data = user_data;
|
||||
EekRendererPrivate *priv = eek_renderer_get_instance_private (data->renderer);
|
||||
EekBounds bounds;
|
||||
gint angle;
|
||||
|
||||
cairo_save (data->cr);
|
||||
|
||||
eek_element_get_bounds (element, &bounds);
|
||||
cairo_translate (data->cr, bounds.x * priv->scale, bounds.y * priv->scale);
|
||||
cairo_translate (data->cr, bounds.x, bounds.y);
|
||||
|
||||
angle = eek_section_get_angle (EEK_SECTION(element));
|
||||
cairo_rotate (data->cr, angle * G_PI / 180);
|
||||
@ -153,29 +148,24 @@ render_keyboard_surface (EekRenderer *renderer)
|
||||
EekRendererPrivate *priv = eek_renderer_get_instance_private (renderer);
|
||||
EekBounds bounds;
|
||||
CreateKeyboardSurfaceCallbackData data;
|
||||
EekColor foreground, background;
|
||||
EekColor foreground;
|
||||
|
||||
eek_renderer_get_foreground_color (renderer,
|
||||
EEK_ELEMENT(priv->keyboard),
|
||||
&foreground);
|
||||
eek_renderer_get_background_color (renderer,
|
||||
EEK_ELEMENT(priv->keyboard),
|
||||
&background);
|
||||
eek_renderer_get_foreground_color (renderer, priv->scontext, &foreground);
|
||||
|
||||
eek_element_get_bounds (EEK_ELEMENT(priv->keyboard), &bounds);
|
||||
|
||||
data.cr = cairo_create (priv->keyboard_surface);
|
||||
data.renderer = renderer;
|
||||
|
||||
cairo_translate (data.cr, bounds.x * priv->scale, bounds.y * priv->scale);
|
||||
/* Paint the background covering the entire widget area */
|
||||
gtk_render_background (priv->scontext,
|
||||
data.cr,
|
||||
0, 0,
|
||||
priv->allocation_width, priv->allocation_height);
|
||||
|
||||
/* blank background */
|
||||
cairo_set_source_rgba (data.cr,
|
||||
background.red,
|
||||
background.green,
|
||||
background.blue,
|
||||
background.alpha);
|
||||
cairo_paint (data.cr);
|
||||
cairo_save (data.cr);
|
||||
cairo_scale (data.cr, priv->scale, priv->scale);
|
||||
cairo_translate (data.cr, bounds.x, bounds.y);
|
||||
|
||||
cairo_set_source_rgba (data.cr,
|
||||
foreground.red,
|
||||
@ -187,6 +177,8 @@ render_keyboard_surface (EekRenderer *renderer)
|
||||
eek_container_foreach_child (EEK_CONTAINER(priv->keyboard),
|
||||
create_keyboard_surface_section_callback,
|
||||
&data);
|
||||
cairo_restore (data.cr);
|
||||
|
||||
cairo_destroy (data.cr);
|
||||
}
|
||||
|
||||
@ -200,7 +192,6 @@ render_key_outline (EekRenderer *renderer,
|
||||
EekOutline *outline;
|
||||
EekBounds bounds;
|
||||
guint oref;
|
||||
EekThemeNode *theme_node;
|
||||
EekColor foreground, background, gradient_start, gradient_end, border_color;
|
||||
EekGradientType gradient_type;
|
||||
gint border_width;
|
||||
@ -211,213 +202,14 @@ render_key_outline (EekRenderer *renderer,
|
||||
if (outline == NULL)
|
||||
return;
|
||||
|
||||
theme_node = g_object_get_data (G_OBJECT(key),
|
||||
active ?
|
||||
"theme-node-pressed" :
|
||||
"theme-node");
|
||||
if (theme_node) {
|
||||
eek_theme_node_get_foreground_color (theme_node, &foreground);
|
||||
eek_theme_node_get_background_color (theme_node, &background);
|
||||
eek_theme_node_get_background_gradient (theme_node,
|
||||
&gradient_type,
|
||||
&gradient_start,
|
||||
&gradient_end);
|
||||
border_width = eek_theme_node_get_border_width (theme_node,
|
||||
EEK_SIDE_TOP);
|
||||
border_radius = eek_theme_node_get_border_radius (theme_node,
|
||||
EEK_CORNER_TOPLEFT);
|
||||
eek_theme_node_get_border_color (theme_node, EEK_SIDE_TOP,
|
||||
&border_color);
|
||||
} else {
|
||||
foreground = priv->default_foreground_color;
|
||||
background = priv->default_background_color;
|
||||
gradient_type = EEK_GRADIENT_NONE;
|
||||
border_width = (gint)round(priv->border_width);
|
||||
border_radius = -1;
|
||||
border_color.red = ABS(background.red - foreground.red) * 0.7;
|
||||
border_color.green = ABS(background.green - foreground.green) * 0.7;
|
||||
border_color.blue = ABS(background.blue - foreground.blue) * 0.7;
|
||||
border_color.alpha = foreground.alpha;
|
||||
}
|
||||
|
||||
eek_element_get_bounds(EEK_ELEMENT(key), &bounds);
|
||||
outline = eek_outline_copy (outline);
|
||||
gtk_style_context_set_state(priv->key_context,
|
||||
active ? GTK_STATE_FLAG_ACTIVE : GTK_STATE_FLAG_NORMAL);
|
||||
|
||||
for (guint i = 0; i < outline->num_points; i++) {
|
||||
outline->points[i].x *= priv->scale;
|
||||
outline->points[i].y *= priv->scale;
|
||||
}
|
||||
gtk_render_background (priv->key_context,
|
||||
cr, 0, 0, bounds.width, bounds.height);
|
||||
|
||||
cairo_translate (cr,
|
||||
border_width * priv->scale,
|
||||
border_width * priv->scale);
|
||||
|
||||
if (gradient_type != EEK_GRADIENT_NONE) {
|
||||
cairo_pattern_t *pat;
|
||||
gdouble cx, cy;
|
||||
|
||||
switch (gradient_type) {
|
||||
case EEK_GRADIENT_VERTICAL:
|
||||
pat = cairo_pattern_create_linear (0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
bounds.height * priv->scale);
|
||||
break;
|
||||
case EEK_GRADIENT_HORIZONTAL:
|
||||
pat = cairo_pattern_create_linear (0.0,
|
||||
0.0,
|
||||
bounds.width * priv->scale,
|
||||
0.0);
|
||||
break;
|
||||
case EEK_GRADIENT_RADIAL:
|
||||
cx = bounds.width / 2 * priv->scale;
|
||||
cy = bounds.height / 2 * priv->scale;
|
||||
pat = cairo_pattern_create_radial (cx,
|
||||
cy,
|
||||
0,
|
||||
cx,
|
||||
cy,
|
||||
MIN(cx, cy));
|
||||
break;
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
break;
|
||||
}
|
||||
|
||||
cairo_pattern_add_color_stop_rgba (pat,
|
||||
1,
|
||||
gradient_start.red * 0.5,
|
||||
gradient_start.green * 0.5,
|
||||
gradient_start.blue * 0.5,
|
||||
gradient_start.alpha);
|
||||
cairo_pattern_add_color_stop_rgba (pat,
|
||||
0,
|
||||
gradient_end.red,
|
||||
gradient_end.green,
|
||||
gradient_end.blue,
|
||||
gradient_end.alpha);
|
||||
cairo_set_source (cr, pat);
|
||||
cairo_pattern_destroy (pat);
|
||||
} else {
|
||||
cairo_set_source_rgba (cr,
|
||||
background.red,
|
||||
background.green,
|
||||
background.blue,
|
||||
background.alpha);
|
||||
}
|
||||
|
||||
_eek_rounded_polygon (cr,
|
||||
border_radius >= 0 ? border_radius : outline->corner_radius,
|
||||
outline->points,
|
||||
outline->num_points);
|
||||
cairo_fill (cr);
|
||||
|
||||
/* paint the border */
|
||||
cairo_set_line_width (cr, border_width);
|
||||
cairo_set_line_join (cr, CAIRO_LINE_JOIN_ROUND);
|
||||
|
||||
cairo_set_source_rgba (cr,
|
||||
border_color.red,
|
||||
border_color.green,
|
||||
border_color.blue,
|
||||
border_color.alpha);
|
||||
|
||||
_eek_rounded_polygon (cr,
|
||||
border_radius >= 0 ? border_radius : outline->corner_radius,
|
||||
outline->points,
|
||||
outline->num_points);
|
||||
cairo_stroke (cr);
|
||||
|
||||
cairo_translate (cr,
|
||||
-border_width * priv->scale,
|
||||
-border_width * priv->scale);
|
||||
|
||||
eek_outline_free (outline);
|
||||
}
|
||||
|
||||
struct _CalculateFontSizeCallbackData {
|
||||
gdouble size;
|
||||
gboolean ascii;
|
||||
EekRenderer *renderer;
|
||||
const PangoFontDescription *base_font;
|
||||
};
|
||||
typedef struct _CalculateFontSizeCallbackData CalculateFontSizeCallbackData;
|
||||
|
||||
static void
|
||||
calculate_font_size_key_callback (EekElement *element, gpointer user_data)
|
||||
{
|
||||
CalculateFontSizeCallbackData *data = user_data;
|
||||
EekRendererPrivate *priv = eek_renderer_get_instance_private (data->renderer);
|
||||
gdouble sx, sy;
|
||||
PangoFontDescription *font;
|
||||
PangoRectangle extents = { 0, };
|
||||
PangoLayout *layout;
|
||||
gdouble size;
|
||||
EekBounds bounds;
|
||||
const gchar *label = NULL;
|
||||
|
||||
if (data->ascii)
|
||||
label = "M";
|
||||
else {
|
||||
EekSymbol *symbol;
|
||||
|
||||
symbol = eek_key_get_symbol (EEK_KEY(element));
|
||||
if (symbol &&
|
||||
eek_symbol_get_category (symbol) == EEK_SYMBOL_CATEGORY_LETTER)
|
||||
label = eek_symbol_get_label (symbol);
|
||||
if (!label)
|
||||
label = "M";
|
||||
}
|
||||
|
||||
font = pango_font_description_copy (data->base_font);
|
||||
|
||||
eek_element_get_bounds (element, &bounds);
|
||||
size = eek_bounds_long_side (&bounds) * PANGO_SCALE;
|
||||
pango_font_description_set_size (font, size);
|
||||
layout = pango_layout_new (priv->pcontext);
|
||||
pango_layout_set_font_description (layout, font);
|
||||
pango_font_description_free (font);
|
||||
|
||||
pango_layout_set_text (layout, label, -1);
|
||||
|
||||
pango_layout_get_extents (layout, NULL, &extents);
|
||||
g_object_unref (layout);
|
||||
|
||||
sx = sy = 1.0;
|
||||
if (extents.width > bounds.width * PANGO_SCALE)
|
||||
sx = bounds.width * PANGO_SCALE / extents.width;
|
||||
if (extents.height > bounds.height * PANGO_SCALE)
|
||||
sy = bounds.height * PANGO_SCALE / extents.height;
|
||||
|
||||
size *= MIN(sx, sy);
|
||||
if (size < data->size)
|
||||
data->size = size;
|
||||
}
|
||||
|
||||
static void
|
||||
calculate_font_size_section_callback (EekElement *element, gpointer user_data)
|
||||
{
|
||||
eek_container_foreach_child (EEK_CONTAINER(element),
|
||||
calculate_font_size_key_callback,
|
||||
user_data);
|
||||
}
|
||||
|
||||
static gdouble
|
||||
calculate_font_size (EekRenderer *renderer,
|
||||
const PangoFontDescription *base_font,
|
||||
gboolean ascii)
|
||||
{
|
||||
EekRendererPrivate *priv = eek_renderer_get_instance_private (renderer);
|
||||
CalculateFontSizeCallbackData data;
|
||||
|
||||
data.size = G_MAXDOUBLE;
|
||||
data.ascii = ascii;
|
||||
data.renderer = renderer;
|
||||
data.base_font = base_font;
|
||||
eek_container_foreach_child (EEK_CONTAINER(priv->keyboard),
|
||||
calculate_font_size_section_callback,
|
||||
&data);
|
||||
return data.size;
|
||||
gtk_style_context_set_state(priv->key_context, GTK_STATE_FLAG_NORMAL);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -447,8 +239,6 @@ render_key (EekRenderer *self,
|
||||
|
||||
/* render outline */
|
||||
eek_element_get_bounds (EEK_ELEMENT(key), &bounds);
|
||||
bounds.width *= priv->scale;
|
||||
bounds.height *= priv->scale;
|
||||
|
||||
if (active)
|
||||
outline_surface_cache = priv->active_outline_surface_cache;
|
||||
@ -486,19 +276,18 @@ render_key (EekRenderer *self,
|
||||
cairo_set_source_surface (cr, outline_surface, 0.0, 0.0);
|
||||
cairo_paint (cr);
|
||||
|
||||
eek_renderer_get_foreground_color (self, EEK_ELEMENT(key), &foreground);
|
||||
eek_renderer_get_foreground_color (self, priv->key_context, &foreground);
|
||||
/* render icon (if any) */
|
||||
symbol = eek_key_get_symbol_with_fallback (key, 0, 0);
|
||||
if (!symbol)
|
||||
return;
|
||||
|
||||
#define SCALE 0.4
|
||||
if (eek_symbol_get_icon_name (symbol)) {
|
||||
gint scale = priv->scale_factor;
|
||||
cairo_surface_t *icon_surface =
|
||||
eek_renderer_get_icon_surface (self,
|
||||
eek_symbol_get_icon_name (symbol),
|
||||
SCALE * MIN(bounds.width, bounds.height),
|
||||
16 / priv->scale,
|
||||
scale);
|
||||
if (icon_surface) {
|
||||
gint width = cairo_image_surface_get_width (icon_surface);
|
||||
@ -525,7 +314,7 @@ render_key (EekRenderer *self,
|
||||
|
||||
/* render label */
|
||||
layout = pango_cairo_create_layout (cr);
|
||||
eek_renderer_render_key_label (self, layout, key);
|
||||
eek_renderer_real_render_key_label (self, layout, key);
|
||||
pango_layout_get_extents (layout, NULL, &extents);
|
||||
|
||||
cairo_save (cr);
|
||||
@ -545,6 +334,21 @@ render_key (EekRenderer *self,
|
||||
g_object_unref (layout);
|
||||
}
|
||||
|
||||
/**
|
||||
* eek_renderer_apply_transformation_for_key:
|
||||
* @self: The renderer used to render the key
|
||||
* @cr: The Cairo rendering context used for rendering
|
||||
* @key: The key to be transformed
|
||||
* @scale: The factor used to scale the key bounds before rendering
|
||||
* @rotate: Whether to rotate the key by the angle defined for the key's
|
||||
* in its section definition
|
||||
*
|
||||
* Applies a transformation, consisting of scaling and rotation, to the
|
||||
* current rendering context using the bounds for the given key. The scale
|
||||
* factor is separate to the normal scale factor for the keyboard as a whole
|
||||
* and is applied cumulatively. It is typically used to render larger than
|
||||
* normal keys for popups.
|
||||
*/
|
||||
void
|
||||
eek_renderer_apply_transformation_for_key (EekRenderer *self,
|
||||
cairo_t *cr,
|
||||
@ -574,23 +378,6 @@ eek_renderer_apply_transformation_for_key (EekRenderer *self,
|
||||
}
|
||||
}
|
||||
|
||||
static const TextProperty *
|
||||
get_text_property_for_category (EekSymbolCategory category)
|
||||
{
|
||||
static const TextProperty props[EEK_SYMBOL_CATEGORY_LAST] = {
|
||||
{ EEK_SYMBOL_CATEGORY_LETTER, FALSE, 1.0, FALSE },
|
||||
{ EEK_SYMBOL_CATEGORY_FUNCTION, TRUE, 0.5, FALSE },
|
||||
{ EEK_SYMBOL_CATEGORY_KEYNAME, TRUE, 0.5, TRUE }
|
||||
};
|
||||
gint i;
|
||||
|
||||
for (i = 0; i < G_N_ELEMENTS(props); i++)
|
||||
if (props[i].category == category)
|
||||
return &props[i];
|
||||
|
||||
g_return_val_if_reached (NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
eek_renderer_real_render_key_label (EekRenderer *self,
|
||||
PangoLayout *layout,
|
||||
@ -598,10 +385,8 @@ eek_renderer_real_render_key_label (EekRenderer *self,
|
||||
{
|
||||
EekRendererPrivate *priv = eek_renderer_get_instance_private (self);
|
||||
EekSymbol *symbol;
|
||||
EekSymbolCategory category;
|
||||
const gchar *label;
|
||||
EekBounds bounds;
|
||||
const TextProperty *prop;
|
||||
PangoFontDescription *font;
|
||||
PangoLayoutLine *line;
|
||||
gdouble scale;
|
||||
@ -617,35 +402,27 @@ eek_renderer_real_render_key_label (EekRenderer *self,
|
||||
if (!priv->font) {
|
||||
const PangoFontDescription *base_font;
|
||||
gdouble ascii_size, size;
|
||||
EekThemeNode *theme_node;
|
||||
|
||||
theme_node = g_object_get_data (G_OBJECT(key), "theme-node");
|
||||
if (theme_node)
|
||||
base_font = eek_theme_node_get_font (theme_node);
|
||||
else
|
||||
base_font = pango_context_get_font_description (priv->pcontext);
|
||||
ascii_size = calculate_font_size (self, base_font, TRUE);
|
||||
base_font = pango_context_get_font_description (priv->pcontext);
|
||||
// FIXME: Base font size on the same size unit used for button sizing,
|
||||
// and make the default about 1/3 of the current row height
|
||||
ascii_size = 30000.0;
|
||||
priv->ascii_font = pango_font_description_copy (base_font);
|
||||
pango_font_description_set_size (priv->ascii_font, ascii_size);
|
||||
pango_font_description_set_size (priv->ascii_font,
|
||||
(gint)round(ascii_size));
|
||||
|
||||
size = calculate_font_size (self, base_font, FALSE);
|
||||
size = 30000.0;
|
||||
priv->font = pango_font_description_copy (base_font);
|
||||
pango_font_description_set_size (priv->font, size * 0.6);
|
||||
pango_font_description_set_size (priv->font, (gint)round(size * 0.6));
|
||||
}
|
||||
|
||||
eek_element_get_bounds (EEK_ELEMENT(key), &bounds);
|
||||
scale = MIN((bounds.width - priv->border_width) / bounds.width,
|
||||
(bounds.height - priv->border_width) / bounds.height);
|
||||
|
||||
category = eek_symbol_get_category (symbol);
|
||||
prop = get_text_property_for_category (category);
|
||||
|
||||
font = pango_font_description_copy (prop->ascii ?
|
||||
priv->ascii_font :
|
||||
priv->font);
|
||||
font = pango_font_description_copy (priv->font);
|
||||
pango_font_description_set_size (font,
|
||||
pango_font_description_get_size (font) *
|
||||
prop->scale * priv->scale * scale);
|
||||
(gint)round(pango_font_description_get_size (font) * scale));
|
||||
pango_layout_set_font_description (layout, font);
|
||||
pango_font_description_free (font);
|
||||
|
||||
@ -654,9 +431,7 @@ eek_renderer_real_render_key_label (EekRenderer *self,
|
||||
if (line->resolved_dir == PANGO_DIRECTION_RTL)
|
||||
pango_layout_set_alignment (layout, PANGO_ALIGN_RIGHT);
|
||||
pango_layout_set_width (layout,
|
||||
PANGO_SCALE * bounds.width * priv->scale * scale);
|
||||
if (prop->ellipses)
|
||||
pango_layout_set_ellipsize (layout, PANGO_ELLIPSIZE_END);
|
||||
PANGO_SCALE * bounds.width * scale);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -672,6 +447,17 @@ eek_renderer_real_render_key_outline (EekRenderer *self,
|
||||
cairo_restore (cr);
|
||||
}
|
||||
|
||||
/*
|
||||
* eek_renderer_real_render_key:
|
||||
* @self: The renderer used to render the key
|
||||
* @cr: The Cairo rendering context used for rendering
|
||||
* @key: The key to be transformed
|
||||
* @scale: The factor used to scale the key bounds before rendering
|
||||
* @rotate: Whether to rotate the key by the angle defined for the key's
|
||||
* in its section definition
|
||||
*
|
||||
* Renders a key separately from the normal keyboard rendering.
|
||||
*/
|
||||
static void
|
||||
eek_renderer_real_render_key (EekRenderer *self,
|
||||
cairo_t *cr,
|
||||
@ -679,7 +465,18 @@ eek_renderer_real_render_key (EekRenderer *self,
|
||||
gdouble scale,
|
||||
gboolean rotate)
|
||||
{
|
||||
EekRendererPrivate *priv = eek_renderer_get_instance_private (self);
|
||||
EekBounds bounds;
|
||||
|
||||
eek_renderer_get_key_bounds (self, key, &bounds, rotate);
|
||||
|
||||
cairo_save (cr);
|
||||
/* Because this function is called separately from the keyboard rendering
|
||||
function, the transformation for the context needs to be set up */
|
||||
cairo_translate (cr, priv->origin_x, priv->origin_y);
|
||||
cairo_scale (cr, priv->scale, priv->scale);
|
||||
cairo_translate (cr, bounds.x, bounds.y);
|
||||
|
||||
eek_renderer_apply_transformation_for_key (self, cr, key, scale, rotate);
|
||||
render_key (self, cr, key, eek_key_is_pressed (key) || eek_key_is_locked (key));
|
||||
cairo_restore (cr);
|
||||
@ -696,6 +493,10 @@ eek_renderer_real_render_keyboard (EekRenderer *self,
|
||||
g_return_if_fail (priv->allocation_width > 0.0);
|
||||
g_return_if_fail (priv->allocation_height > 0.0);
|
||||
|
||||
cairo_save (cr);
|
||||
|
||||
cairo_translate (cr, priv->origin_x, priv->origin_y);
|
||||
|
||||
if (priv->keyboard_surface)
|
||||
cairo_surface_destroy (priv->keyboard_surface);
|
||||
|
||||
@ -709,6 +510,8 @@ eek_renderer_real_render_keyboard (EekRenderer *self,
|
||||
source = cairo_get_source (cr);
|
||||
cairo_pattern_set_extend (source, CAIRO_EXTEND_PAD);
|
||||
cairo_paint (cr);
|
||||
|
||||
cairo_restore (cr);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -734,6 +537,10 @@ eek_renderer_set_property (GObject *object,
|
||||
priv->pcontext = g_value_get_object (value);
|
||||
g_object_ref (priv->pcontext);
|
||||
break;
|
||||
case PROP_STYLE_CONTEXT:
|
||||
priv->scontext = g_value_get_object (value);
|
||||
g_object_ref (priv->scontext);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
@ -805,7 +612,6 @@ eek_renderer_class_init (EekRendererClass *klass)
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||
GParamSpec *pspec;
|
||||
|
||||
klass->render_key_label = eek_renderer_real_render_key_label;
|
||||
klass->render_key_outline = eek_renderer_real_render_key_outline;
|
||||
klass->render_key = eek_renderer_real_render_key;
|
||||
klass->render_keyboard = eek_renderer_real_render_keyboard;
|
||||
@ -832,6 +638,15 @@ eek_renderer_class_init (EekRendererClass *klass)
|
||||
g_object_class_install_property (gobject_class,
|
||||
PROP_PCONTEXT,
|
||||
pspec);
|
||||
|
||||
pspec = g_param_spec_object ("style-context",
|
||||
"GTK Style Context",
|
||||
"GTK Style Context",
|
||||
GTK_TYPE_STYLE_CONTEXT,
|
||||
G_PARAM_CONSTRUCT_ONLY | G_PARAM_WRITABLE);
|
||||
g_object_class_install_property (gobject_class,
|
||||
PROP_STYLE_CONTEXT,
|
||||
pspec);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -869,6 +684,24 @@ eek_renderer_init (EekRenderer *self)
|
||||
g_str_equal,
|
||||
g_free,
|
||||
(GDestroyNotify)cairo_surface_destroy);
|
||||
|
||||
/* Create a default CSS provider and load a style sheet */
|
||||
priv->css_provider = gtk_css_provider_new ();
|
||||
gtk_css_provider_load_from_resource (priv->css_provider,
|
||||
"/sm/puri/squeekboard/style.css");
|
||||
|
||||
/* Create a style context for keys */
|
||||
priv->key_context = gtk_style_context_new ();
|
||||
gtk_style_context_add_class (priv->key_context, "key");
|
||||
gtk_style_context_add_provider (priv->key_context,
|
||||
GTK_STYLE_PROVIDER(priv->css_provider),
|
||||
GTK_STYLE_PROVIDER_PRIORITY_USER);
|
||||
|
||||
g_autoptr (GtkWidgetPath) path = NULL;
|
||||
path = gtk_widget_path_new ();
|
||||
gtk_widget_path_append_type (path, GTK_TYPE_BUTTON);
|
||||
gtk_style_context_set_path (priv->key_context, path);
|
||||
gtk_style_context_set_state (priv->key_context, GTK_STATE_FLAG_NORMAL);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -900,11 +733,13 @@ on_symbol_index_changed (EekKeyboard *keyboard,
|
||||
|
||||
EekRenderer *
|
||||
eek_renderer_new (EekKeyboard *keyboard,
|
||||
PangoContext *pcontext)
|
||||
PangoContext *pcontext,
|
||||
GtkStyleContext *scontext)
|
||||
{
|
||||
return g_object_new (EEK_TYPE_RENDERER,
|
||||
"keyboard", keyboard,
|
||||
"pango-context", pcontext,
|
||||
"style-context", scontext,
|
||||
NULL);
|
||||
}
|
||||
|
||||
@ -924,23 +759,20 @@ eek_renderer_set_allocation_size (EekRenderer *renderer,
|
||||
priv->allocation_width = width;
|
||||
priv->allocation_height = height;
|
||||
|
||||
/* Calculate a scale factor to use when rendering the keyboard into the
|
||||
available space. */
|
||||
eek_element_get_bounds (EEK_ELEMENT(priv->keyboard), &bounds);
|
||||
|
||||
if (bounds.height * width / bounds.width <= height)
|
||||
scale = width / bounds.width;
|
||||
else if (bounds.width * height / bounds.height <= width)
|
||||
scale = height / bounds.height;
|
||||
else {
|
||||
if (bounds.width * height < bounds.height * width)
|
||||
scale = bounds.width / width;
|
||||
else
|
||||
scale = bounds.height / height;
|
||||
}
|
||||
gdouble w = (bounds.x * 2) + bounds.width;
|
||||
gdouble h = (bounds.y * 2) + bounds.height;
|
||||
|
||||
if (scale != priv->scale) {
|
||||
priv->scale = scale;
|
||||
invalidate (renderer);
|
||||
}
|
||||
scale = MIN(width / w, height / h);
|
||||
|
||||
priv->scale = scale;
|
||||
/* Set the rendering offset in widget coordinates to center the keyboard */
|
||||
priv->origin_x = (width - (scale * w)) / 2;
|
||||
priv->origin_y = (height - (scale * h)) / 2;
|
||||
invalidate (renderer);
|
||||
}
|
||||
|
||||
void
|
||||
@ -956,9 +788,9 @@ eek_renderer_get_size (EekRenderer *renderer,
|
||||
|
||||
eek_element_get_bounds (EEK_ELEMENT(priv->keyboard), &bounds);
|
||||
if (width)
|
||||
*width = bounds.width * priv->scale;
|
||||
*width = bounds.width;
|
||||
if (height)
|
||||
*height = bounds.height * priv->scale;
|
||||
*height = bounds.height;
|
||||
}
|
||||
|
||||
void
|
||||
@ -971,7 +803,6 @@ eek_renderer_get_key_bounds (EekRenderer *renderer,
|
||||
EekBounds section_bounds, keyboard_bounds;
|
||||
gint angle = 0;
|
||||
EekPoint points[4], min, max;
|
||||
gint i;
|
||||
|
||||
g_return_if_fail (EEK_IS_RENDERER(renderer));
|
||||
g_return_if_fail (EEK_IS_KEY(key));
|
||||
@ -989,10 +820,6 @@ eek_renderer_get_key_bounds (EekRenderer *renderer,
|
||||
if (!rotate) {
|
||||
bounds->x += keyboard_bounds.x + section_bounds.x;
|
||||
bounds->y += keyboard_bounds.y + section_bounds.y;
|
||||
bounds->x *= priv->scale;
|
||||
bounds->y *= priv->scale;
|
||||
bounds->width *= priv->scale;
|
||||
bounds->height *= priv->scale;
|
||||
return;
|
||||
}
|
||||
points[0].x = bounds->x;
|
||||
@ -1009,7 +836,7 @@ eek_renderer_get_key_bounds (EekRenderer *renderer,
|
||||
|
||||
min = points[2];
|
||||
max = points[0];
|
||||
for (i = 0; i < G_N_ELEMENTS(points); i++) {
|
||||
for (uint i = 0; i < G_N_ELEMENTS(points); i++) {
|
||||
eek_point_rotate (&points[i], angle);
|
||||
if (points[i].x < min.x)
|
||||
min.x = points[i].x;
|
||||
@ -1024,10 +851,6 @@ eek_renderer_get_key_bounds (EekRenderer *renderer,
|
||||
bounds->y = keyboard_bounds.y + section_bounds.y + min.y;
|
||||
bounds->width = (max.x - min.x);
|
||||
bounds->height = (max.y - min.y);
|
||||
bounds->x *= priv->scale;
|
||||
bounds->y *= priv->scale;
|
||||
bounds->width *= priv->scale;
|
||||
bounds->height *= priv->scale;
|
||||
}
|
||||
|
||||
gdouble
|
||||
@ -1059,18 +882,6 @@ eek_renderer_create_pango_layout (EekRenderer *renderer)
|
||||
return pango_layout_new (priv->pcontext);
|
||||
}
|
||||
|
||||
void
|
||||
eek_renderer_render_key_label (EekRenderer *renderer,
|
||||
PangoLayout *layout,
|
||||
EekKey *key)
|
||||
{
|
||||
g_return_if_fail (EEK_IS_RENDERER(renderer));
|
||||
g_return_if_fail (EEK_IS_KEY(key));
|
||||
|
||||
EEK_RENDERER_GET_CLASS(renderer)->
|
||||
render_key_label (renderer, layout, key);
|
||||
}
|
||||
|
||||
void
|
||||
eek_renderer_render_key_outline (EekRenderer *renderer,
|
||||
cairo_t *cr,
|
||||
@ -1172,64 +983,21 @@ eek_renderer_set_default_background_color (EekRenderer *renderer,
|
||||
|
||||
void
|
||||
eek_renderer_get_foreground_color (EekRenderer *renderer,
|
||||
EekElement *element,
|
||||
GtkStyleContext *context,
|
||||
EekColor *color)
|
||||
{
|
||||
EekThemeNode *theme_node;
|
||||
|
||||
g_return_if_fail (EEK_IS_RENDERER(renderer));
|
||||
g_return_if_fail (color);
|
||||
|
||||
EekRendererPrivate *priv = eek_renderer_get_instance_private (renderer);
|
||||
GtkStateFlags flags = GTK_STATE_FLAG_NORMAL;
|
||||
GdkRGBA gcolor;
|
||||
|
||||
theme_node = g_object_get_data (G_OBJECT(element), "theme-node");
|
||||
if (theme_node)
|
||||
eek_theme_node_get_foreground_color (theme_node, color);
|
||||
else
|
||||
memcpy (color, &priv->default_foreground_color,
|
||||
sizeof(EekColor));
|
||||
}
|
||||
|
||||
void
|
||||
eek_renderer_get_background_color (EekRenderer *renderer,
|
||||
EekElement *element,
|
||||
EekColor *color)
|
||||
{
|
||||
EekThemeNode *theme_node;
|
||||
|
||||
g_return_if_fail (EEK_IS_RENDERER(renderer));
|
||||
g_return_if_fail (color);
|
||||
|
||||
EekRendererPrivate *priv = eek_renderer_get_instance_private (renderer);
|
||||
|
||||
theme_node = g_object_get_data (G_OBJECT(element), "theme-node");
|
||||
if (theme_node)
|
||||
eek_theme_node_get_background_color (theme_node, color);
|
||||
else
|
||||
memcpy (color, &priv->default_background_color,
|
||||
sizeof(EekColor));
|
||||
}
|
||||
|
||||
void
|
||||
eek_renderer_get_background_gradient (EekRenderer *renderer,
|
||||
EekElement *element,
|
||||
EekGradientType *type,
|
||||
EekColor *start,
|
||||
EekColor *end)
|
||||
{
|
||||
EekThemeNode *theme_node;
|
||||
|
||||
g_return_if_fail (EEK_IS_RENDERER(renderer));
|
||||
g_return_if_fail (EEK_IS_ELEMENT(element));
|
||||
g_return_if_fail (type);
|
||||
g_return_if_fail (start);
|
||||
g_return_if_fail (end);
|
||||
|
||||
theme_node = g_object_get_data (G_OBJECT(element), "theme-node");
|
||||
if (theme_node)
|
||||
eek_theme_node_get_background_gradient (theme_node, type, start, end);
|
||||
else
|
||||
*type = EEK_GRADIENT_NONE;
|
||||
gtk_style_context_get_color (context, flags, &gcolor);
|
||||
color->red = gcolor.red;
|
||||
color->green = gcolor.green;
|
||||
color->blue = gcolor.blue;
|
||||
color->alpha = gcolor.alpha;
|
||||
}
|
||||
|
||||
struct _FindKeyByPositionCallbackData {
|
||||
@ -1255,7 +1023,6 @@ find_key_by_position_key_callback (EekElement *element,
|
||||
FindKeyByPositionCallbackData *data = user_data;
|
||||
EekBounds bounds;
|
||||
EekPoint points[4];
|
||||
gint i;
|
||||
gboolean b1, b2, b3;
|
||||
|
||||
eek_element_get_bounds (element, &bounds);
|
||||
@ -1269,14 +1036,10 @@ find_key_by_position_key_callback (EekElement *element,
|
||||
points[3].x = points[0].x;
|
||||
points[3].y = points[2].y;
|
||||
|
||||
EekRendererPrivate *priv = eek_renderer_get_instance_private (data->renderer);
|
||||
|
||||
for (i = 0; i < G_N_ELEMENTS(points); i++) {
|
||||
for (uint i = 0; i < G_N_ELEMENTS(points); i++) {
|
||||
eek_point_rotate (&points[i], data->angle);
|
||||
points[i].x += data->origin.x;
|
||||
points[i].y += data->origin.y;
|
||||
points[i].x *= priv->scale;
|
||||
points[i].y *= priv->scale;
|
||||
}
|
||||
|
||||
b1 = sign (&data->point, &points[0], &points[1]) < 0.0;
|
||||
@ -1285,7 +1048,8 @@ find_key_by_position_key_callback (EekElement *element,
|
||||
|
||||
if (b1 == b2 && b2 == b3) {
|
||||
data->key = EEK_KEY(element);
|
||||
return 0;
|
||||
if (eek_key_has_label(data->key))
|
||||
return 0;
|
||||
}
|
||||
|
||||
b1 = sign (&data->point, &points[2], &points[3]) < 0.0;
|
||||
@ -1294,7 +1058,8 @@ find_key_by_position_key_callback (EekElement *element,
|
||||
|
||||
if (b1 == b2 && b2 == b3) {
|
||||
data->key = EEK_KEY(element);
|
||||
return 0;
|
||||
if (eek_key_has_label(data->key))
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -1;
|
||||
@ -1321,6 +1086,15 @@ find_key_by_position_section_callback (EekElement *element,
|
||||
return data->key ? 0 : -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* eek_renderer_find_key_by_position:
|
||||
* @renderer: The renderer normally used to render the key
|
||||
* @x: The horizontal widget coordinate of the position to test for a key
|
||||
* @y: The vertical widget coordinate of the position to test for a key
|
||||
*
|
||||
* Return value: the key located at the position x, y in widget coordinates, or
|
||||
* NULL if no key can be found at that location
|
||||
**/
|
||||
EekKey *
|
||||
eek_renderer_find_key_by_position (EekRenderer *renderer,
|
||||
gdouble x,
|
||||
@ -1332,19 +1106,22 @@ eek_renderer_find_key_by_position (EekRenderer *renderer,
|
||||
g_return_val_if_fail (EEK_IS_RENDERER(renderer), NULL);
|
||||
|
||||
EekRendererPrivate *priv = eek_renderer_get_instance_private (renderer);
|
||||
|
||||
eek_element_get_bounds (EEK_ELEMENT(priv->keyboard), &bounds);
|
||||
|
||||
if (x < bounds.x * priv->scale ||
|
||||
y < bounds.y * priv->scale ||
|
||||
x > bounds.width * priv->scale ||
|
||||
y > bounds.height * priv->scale)
|
||||
/* Transform from widget coordinates to keyboard coordinates */
|
||||
x = (x - priv->origin_x)/priv->scale - bounds.x;
|
||||
y = (y - priv->origin_y)/priv->scale - bounds.y;
|
||||
|
||||
if (x < 0 ||
|
||||
y < 0 ||
|
||||
x > bounds.width ||
|
||||
y > bounds.height)
|
||||
return NULL;
|
||||
|
||||
data.point.x = x;
|
||||
data.point.y = y;
|
||||
data.origin.x = bounds.x;
|
||||
data.origin.y = bounds.y;
|
||||
data.origin.x = 0;
|
||||
data.origin.y = 0;
|
||||
data.key = NULL;
|
||||
data.renderer = renderer;
|
||||
|
||||
@ -1353,117 +1130,3 @@ eek_renderer_find_key_by_position (EekRenderer *renderer,
|
||||
&data);
|
||||
return data.key;
|
||||
}
|
||||
|
||||
struct _CreateThemeNodeData {
|
||||
EekThemeContext *context;
|
||||
EekThemeNode *parent;
|
||||
EekRenderer *renderer;
|
||||
};
|
||||
typedef struct _CreateThemeNodeData CreateThemeNodeData;
|
||||
|
||||
void
|
||||
create_theme_node_key_callback (EekElement *element,
|
||||
gpointer user_data)
|
||||
{
|
||||
CreateThemeNodeData *data = user_data;
|
||||
EekThemeNode *theme_node;
|
||||
|
||||
EekRendererPrivate *priv = eek_renderer_get_instance_private (data->renderer);
|
||||
|
||||
theme_node = eek_theme_node_new (data->context,
|
||||
data->parent,
|
||||
priv->theme,
|
||||
EEK_TYPE_KEY,
|
||||
eek_element_get_name (element),
|
||||
"key",
|
||||
NULL,
|
||||
NULL);
|
||||
g_object_set_data_full (G_OBJECT(element),
|
||||
"theme-node",
|
||||
theme_node,
|
||||
(GDestroyNotify)g_object_unref);
|
||||
|
||||
theme_node = eek_theme_node_new (data->context,
|
||||
data->parent,
|
||||
priv->theme,
|
||||
EEK_TYPE_KEY,
|
||||
eek_element_get_name (element),
|
||||
"key",
|
||||
"active",
|
||||
NULL);
|
||||
g_object_set_data_full (G_OBJECT(element),
|
||||
"theme-node-pressed",
|
||||
theme_node,
|
||||
(GDestroyNotify)g_object_unref);
|
||||
}
|
||||
|
||||
void
|
||||
create_theme_node_section_callback (EekElement *element,
|
||||
gpointer user_data)
|
||||
{
|
||||
CreateThemeNodeData *data = user_data;
|
||||
EekThemeNode *theme_node, *parent;
|
||||
|
||||
EekRendererPrivate *priv = eek_renderer_get_instance_private (data->renderer);
|
||||
|
||||
theme_node = eek_theme_node_new (data->context,
|
||||
data->parent,
|
||||
priv->theme,
|
||||
EEK_TYPE_SECTION,
|
||||
eek_element_get_name (element),
|
||||
"section",
|
||||
NULL,
|
||||
NULL);
|
||||
g_object_set_data_full (G_OBJECT(element),
|
||||
"theme-node",
|
||||
theme_node,
|
||||
(GDestroyNotify)g_object_unref);
|
||||
|
||||
parent = data->parent;
|
||||
data->parent = theme_node;
|
||||
eek_container_foreach_child (EEK_CONTAINER(element),
|
||||
create_theme_node_key_callback,
|
||||
data);
|
||||
data->parent = parent;
|
||||
}
|
||||
|
||||
void
|
||||
eek_renderer_set_theme (EekRenderer *renderer,
|
||||
EekTheme *theme)
|
||||
{
|
||||
EekThemeContext *theme_context;
|
||||
EekThemeNode *theme_node;
|
||||
CreateThemeNodeData data;
|
||||
|
||||
g_return_if_fail (EEK_IS_RENDERER(renderer));
|
||||
g_return_if_fail (EEK_IS_THEME(theme));
|
||||
|
||||
EekRendererPrivate *priv = eek_renderer_get_instance_private (renderer);
|
||||
|
||||
g_return_if_fail (priv->keyboard);
|
||||
|
||||
if (priv->theme)
|
||||
g_object_unref (priv->theme);
|
||||
priv->theme = g_object_ref (theme);
|
||||
|
||||
theme_context = eek_theme_context_new ();
|
||||
theme_node = eek_theme_node_new (theme_context,
|
||||
NULL,
|
||||
priv->theme,
|
||||
EEK_TYPE_KEYBOARD,
|
||||
"keyboard",
|
||||
"keyboard",
|
||||
NULL,
|
||||
NULL);
|
||||
g_object_set_data_full (G_OBJECT(priv->keyboard),
|
||||
"theme-node",
|
||||
theme_node,
|
||||
(GDestroyNotify)g_object_unref);
|
||||
|
||||
data.context = theme_context;
|
||||
data.parent = theme_node;
|
||||
data.renderer = renderer;
|
||||
eek_container_foreach_child (EEK_CONTAINER(priv->keyboard),
|
||||
create_theme_node_section_callback,
|
||||
&data);
|
||||
}
|
||||
|
||||
@ -25,8 +25,6 @@
|
||||
#include "eek-keyboard.h"
|
||||
#include "eek-keysym.h"
|
||||
#include "eek-types.h"
|
||||
#include "eek-theme.h"
|
||||
#include "eek-theme-context.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
@ -37,10 +35,6 @@ struct _EekRendererClass
|
||||
{
|
||||
GObjectClass parent_class;
|
||||
|
||||
void (* render_key_label) (EekRenderer *self,
|
||||
PangoLayout *layout,
|
||||
EekKey *key);
|
||||
|
||||
void (* render_key_outline) (EekRenderer *self,
|
||||
cairo_t *cr,
|
||||
EekKey *key,
|
||||
@ -68,7 +62,8 @@ struct _EekRendererClass
|
||||
|
||||
GType eek_renderer_get_type (void) G_GNUC_CONST;
|
||||
EekRenderer *eek_renderer_new (EekKeyboard *keyboard,
|
||||
PangoContext *pcontext);
|
||||
PangoContext *pcontext,
|
||||
GtkStyleContext *scontext);
|
||||
void eek_renderer_set_allocation_size
|
||||
(EekRenderer *renderer,
|
||||
gdouble width,
|
||||
@ -120,18 +115,8 @@ void eek_renderer_set_default_background_color
|
||||
const EekColor *color);
|
||||
void eek_renderer_get_foreground_color
|
||||
(EekRenderer *renderer,
|
||||
EekElement *element,
|
||||
GtkStyleContext *context,
|
||||
EekColor *color);
|
||||
void eek_renderer_get_background_color
|
||||
(EekRenderer *renderer,
|
||||
EekElement *element,
|
||||
EekColor *color);
|
||||
void eek_renderer_get_background_gradient
|
||||
(EekRenderer *renderer,
|
||||
EekElement *element,
|
||||
EekGradientType *type,
|
||||
EekColor *start,
|
||||
EekColor *end);
|
||||
void eek_renderer_set_border_width (EekRenderer *renderer,
|
||||
gdouble border_width);
|
||||
EekKey *eek_renderer_find_key_by_position
|
||||
@ -145,8 +130,5 @@ void eek_renderer_apply_transformation_for_key
|
||||
gdouble scale,
|
||||
gboolean rotate);
|
||||
|
||||
void eek_renderer_set_theme (EekRenderer *renderer,
|
||||
EekTheme *theme);
|
||||
|
||||
G_END_DECLS
|
||||
#endif /* EEK_RENDERER_H */
|
||||
|
||||
@ -61,7 +61,7 @@ typedef struct _EekRow EekRow;
|
||||
typedef struct _EekSectionPrivate
|
||||
{
|
||||
gint angle;
|
||||
GSList *rows;
|
||||
EekRow row;
|
||||
EekModifierType modifiers;
|
||||
} EekSectionPrivate;
|
||||
|
||||
@ -70,9 +70,7 @@ G_DEFINE_TYPE_WITH_PRIVATE (EekSection, eek_section, EEK_TYPE_CONTAINER)
|
||||
static gint
|
||||
eek_section_real_get_n_rows (EekSection *self)
|
||||
{
|
||||
EekSectionPrivate *priv = eek_section_get_instance_private (self);
|
||||
|
||||
return g_slist_length (priv->rows);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void
|
||||
@ -80,13 +78,14 @@ eek_section_real_add_row (EekSection *self,
|
||||
gint num_columns,
|
||||
EekOrientation orientation)
|
||||
{
|
||||
EekSectionPrivate *priv = eek_section_get_instance_private (self);
|
||||
EekRow *row;
|
||||
|
||||
EekSectionPrivate *priv = (EekSectionPrivate*)eek_section_get_instance_private (self);
|
||||
priv->row.num_columns = num_columns;
|
||||
priv->row.orientation = orientation;
|
||||
/*
|
||||
row = g_slice_new (EekRow);
|
||||
row->num_columns = num_columns;
|
||||
row->orientation = orientation;
|
||||
priv->rows = g_slist_append (priv->rows, row);
|
||||
priv->rows = g_slist_append (priv->rows, row);*/
|
||||
}
|
||||
|
||||
static void
|
||||
@ -95,15 +94,14 @@ eek_section_real_get_row (EekSection *self,
|
||||
gint *num_columns,
|
||||
EekOrientation *orientation)
|
||||
{
|
||||
EekSectionPrivate *priv = eek_section_get_instance_private (self);
|
||||
EekRow *row;
|
||||
|
||||
row = g_slist_nth_data (priv->rows, index);
|
||||
g_return_if_fail (row);
|
||||
if (num_columns)
|
||||
EekSectionPrivate *priv = (EekSectionPrivate*)eek_section_get_instance_private (self);
|
||||
EekRow *row = &priv->row;
|
||||
if (num_columns) {
|
||||
*num_columns = row->num_columns;
|
||||
if (orientation)
|
||||
}
|
||||
if (orientation) {
|
||||
*orientation = row->orientation;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
@ -123,29 +121,17 @@ on_unlocked (EekKey *key,
|
||||
static EekKey *
|
||||
eek_section_real_create_key (EekSection *self,
|
||||
const gchar *name,
|
||||
gint keycode,
|
||||
gint column_index,
|
||||
gint row_index)
|
||||
gint keycode)
|
||||
{
|
||||
EekKey *key;
|
||||
gint num_rows;
|
||||
EekRow *row;
|
||||
EekSectionPrivate *priv = (EekSectionPrivate*)eek_section_get_instance_private (self);
|
||||
|
||||
num_rows = eek_section_get_n_rows (self);
|
||||
g_return_val_if_fail (0 <= row_index && row_index < num_rows, NULL);
|
||||
EekRow *row = &priv->row;
|
||||
row->num_columns++;
|
||||
|
||||
EekSectionPrivate *priv = eek_section_get_instance_private (self);
|
||||
|
||||
row = g_slist_nth_data (priv->rows, row_index);
|
||||
if (row->num_columns < column_index + 1)
|
||||
row->num_columns = column_index + 1;
|
||||
|
||||
key = g_object_new (EEK_TYPE_KEY,
|
||||
"name", name,
|
||||
"keycode", keycode,
|
||||
"column", column_index,
|
||||
"row", row_index,
|
||||
NULL);
|
||||
EekKey *key = (EekKey*)g_object_new (EEK_TYPE_KEY,
|
||||
"name", name,
|
||||
"keycode", keycode,
|
||||
NULL);
|
||||
g_return_val_if_fail (key, NULL);
|
||||
|
||||
EEK_CONTAINER_GET_CLASS(self)->add_child (EEK_CONTAINER(self),
|
||||
@ -225,12 +211,7 @@ static void
|
||||
eek_section_finalize (GObject *object)
|
||||
{
|
||||
EekSection *self = EEK_SECTION (object);
|
||||
EekSectionPrivate *priv = eek_section_get_instance_private (self);
|
||||
GSList *head;
|
||||
|
||||
for (head = priv->rows; head; head = g_slist_next (head))
|
||||
g_slice_free (EekRow, head->data);
|
||||
g_slist_free (priv->rows);
|
||||
EekSectionPrivate *priv = (EekSectionPrivate*)eek_section_get_instance_private (self);
|
||||
|
||||
G_OBJECT_CLASS (eek_section_parent_class)->finalize (object);
|
||||
}
|
||||
@ -475,16 +456,12 @@ eek_section_get_row (EekSection *section,
|
||||
EekKey *
|
||||
eek_section_create_key (EekSection *section,
|
||||
const gchar *name,
|
||||
gint keycode,
|
||||
gint column,
|
||||
gint row)
|
||||
gint keycode)
|
||||
{
|
||||
g_return_val_if_fail (EEK_IS_SECTION(section), NULL);
|
||||
return EEK_SECTION_GET_CLASS(section)->create_key (section,
|
||||
name,
|
||||
keycode,
|
||||
column,
|
||||
row);
|
||||
keycode);
|
||||
}
|
||||
|
||||
const double keyspacing = 4.0;
|
||||
@ -535,7 +512,8 @@ keycounter (EekElement *element, gpointer user_data)
|
||||
{
|
||||
EekKey *key = EEK_KEY(element);
|
||||
|
||||
/* Skip keys without labels for the current level. */
|
||||
/* Skip keys without labels for the current level. This causes those
|
||||
keys to be hidden in the visible layout. */
|
||||
if (!eek_key_has_label(key))
|
||||
return;
|
||||
|
||||
|
||||
@ -63,9 +63,7 @@ struct _EekSectionClass
|
||||
|
||||
EekKey *(* create_key) (EekSection *self,
|
||||
const gchar *name,
|
||||
gint keycode,
|
||||
gint row,
|
||||
gint column);
|
||||
gint keycode);
|
||||
|
||||
/* signals */
|
||||
void (* key_pressed) (EekSection *self,
|
||||
@ -101,9 +99,7 @@ void eek_section_get_row (EekSection *section,
|
||||
|
||||
EekKey *eek_section_create_key (EekSection *section,
|
||||
const gchar *name,
|
||||
gint keycode,
|
||||
gint column,
|
||||
gint row);
|
||||
gint keycode);
|
||||
|
||||
EekKey *eek_section_find_key_by_keycode (EekSection *section,
|
||||
guint keycode);
|
||||
|
||||
@ -36,10 +36,8 @@ eek_serializable_get_type (void)
|
||||
{
|
||||
static GType iface_type = 0;
|
||||
if (iface_type == 0) {
|
||||
static const GTypeInfo info = {
|
||||
sizeof (EekSerializableIface),
|
||||
NULL,
|
||||
NULL,
|
||||
static GTypeInfo info = {
|
||||
.class_size = sizeof (EekSerializableIface)
|
||||
};
|
||||
iface_type = g_type_register_static (G_TYPE_INTERFACE,
|
||||
"EekSerializable",
|
||||
|
||||
@ -36,24 +36,19 @@ EekSymbolMatrix *
|
||||
eek_symbol_matrix_copy (const EekSymbolMatrix *matrix)
|
||||
{
|
||||
EekSymbolMatrix *retval;
|
||||
gint i, num_symbols = matrix->num_groups * matrix->num_levels;
|
||||
guint num_symbols = matrix->num_groups * matrix->num_levels;
|
||||
|
||||
retval = g_slice_dup (EekSymbolMatrix, matrix);
|
||||
retval->data = g_slice_copy (sizeof (EekSymbol *) * num_symbols,
|
||||
matrix->data);
|
||||
for (i = 0; i < num_symbols; i++)
|
||||
if (retval->data[i])
|
||||
g_object_ref (retval->data[i]);
|
||||
// FIXME: do a deep copy over the data in EekSymbol
|
||||
return retval;
|
||||
}
|
||||
|
||||
void
|
||||
eek_symbol_matrix_free (EekSymbolMatrix *matrix)
|
||||
{
|
||||
gint i, num_symbols = matrix->num_groups * matrix->num_levels;
|
||||
for (i = 0; i < num_symbols; i++)
|
||||
if (matrix->data[i])
|
||||
g_object_unref (matrix->data[i]);
|
||||
guint num_symbols = matrix->num_groups * matrix->num_levels;
|
||||
g_slice_free1 (sizeof (EekSymbol *) * num_symbols, matrix->data);
|
||||
g_slice_free (EekSymbolMatrix, matrix);
|
||||
}
|
||||
@ -79,7 +74,6 @@ eek_symbol_matrix_set_symbol (EekSymbolMatrix *matrix,
|
||||
{
|
||||
g_return_if_fail (group >= 0 && group < matrix->num_groups);
|
||||
g_return_if_fail (level >= 0 && level < matrix->num_levels);
|
||||
g_return_if_fail (EEK_IS_SYMBOL(symbol));
|
||||
matrix->data[group * matrix->num_levels + level] = g_object_ref (symbol);
|
||||
}
|
||||
|
||||
|
||||
414
eek/eek-symbol.c
414
eek/eek-symbol.c
@ -28,270 +28,42 @@
|
||||
#include "config.h"
|
||||
|
||||
#include "eek-symbol.h"
|
||||
#include "eek-serializable.h"
|
||||
#include "eek-enumtypes.h"
|
||||
|
||||
enum {
|
||||
PROP_0,
|
||||
PROP_NAME,
|
||||
PROP_LABEL,
|
||||
PROP_CATEGORY,
|
||||
PROP_MODIFIER_MASK,
|
||||
PROP_ICON_NAME,
|
||||
PROP_TOOLTIP,
|
||||
PROP_LAST
|
||||
};
|
||||
|
||||
typedef struct _EekSymbolPrivate
|
||||
void
|
||||
eek_symbol_destroy (EekSymbol *priv)
|
||||
{
|
||||
gchar *name;
|
||||
gchar *label;
|
||||
EekSymbolCategory category;
|
||||
EekModifierType modifier_mask;
|
||||
gchar *icon_name;
|
||||
gchar *tooltip;
|
||||
} EekSymbolPrivate;
|
||||
|
||||
static void eek_serializable_iface_init (EekSerializableIface *iface);
|
||||
|
||||
G_DEFINE_TYPE_EXTENDED (EekSymbol,
|
||||
eek_symbol,
|
||||
G_TYPE_OBJECT,
|
||||
0, /* GTypeFlags */
|
||||
G_ADD_PRIVATE (EekSymbol)
|
||||
G_IMPLEMENT_INTERFACE (EEK_TYPE_SERIALIZABLE,
|
||||
eek_serializable_iface_init))
|
||||
|
||||
static void
|
||||
eek_symbol_real_serialize (EekSerializable *self,
|
||||
GVariantBuilder *builder)
|
||||
{
|
||||
EekSymbolPrivate *priv = eek_symbol_get_instance_private (EEK_SYMBOL (self));
|
||||
#define NOTNULL(s) ((s) != NULL ? (s) : "")
|
||||
g_variant_builder_add (builder, "s", NOTNULL(priv->name));
|
||||
g_variant_builder_add (builder, "s", NOTNULL(priv->label));
|
||||
g_variant_builder_add (builder, "u", priv->category);
|
||||
g_variant_builder_add (builder, "u", priv->modifier_mask);
|
||||
g_variant_builder_add (builder, "s", NOTNULL(priv->icon_name));
|
||||
g_variant_builder_add (builder, "s", NOTNULL(priv->tooltip));
|
||||
#undef NOTNULL
|
||||
}
|
||||
|
||||
static gsize
|
||||
eek_symbol_real_deserialize (EekSerializable *self,
|
||||
GVariant *variant,
|
||||
gsize index)
|
||||
{
|
||||
EekSymbolPrivate *priv = eek_symbol_get_instance_private (EEK_SYMBOL (self));
|
||||
|
||||
g_variant_get_child (variant, index++, "s", &priv->name);
|
||||
g_variant_get_child (variant, index++, "s", &priv->label);
|
||||
g_variant_get_child (variant, index++, "u", &priv->category);
|
||||
g_variant_get_child (variant, index++, "u", &priv->modifier_mask);
|
||||
g_variant_get_child (variant, index++, "s", &priv->icon_name);
|
||||
g_variant_get_child (variant, index++, "s", &priv->tooltip);
|
||||
|
||||
return index;
|
||||
}
|
||||
|
||||
static void
|
||||
eek_serializable_iface_init (EekSerializableIface *iface)
|
||||
{
|
||||
iface->serialize = eek_symbol_real_serialize;
|
||||
iface->deserialize = eek_symbol_real_deserialize;
|
||||
}
|
||||
|
||||
static void
|
||||
eek_symbol_set_property (GObject *object,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
switch (prop_id) {
|
||||
case PROP_NAME:
|
||||
eek_symbol_set_name (EEK_SYMBOL(object), g_value_get_string (value));
|
||||
break;
|
||||
case PROP_LABEL:
|
||||
eek_symbol_set_label (EEK_SYMBOL(object), g_value_get_string (value));
|
||||
break;
|
||||
case PROP_CATEGORY:
|
||||
eek_symbol_set_category (EEK_SYMBOL(object), g_value_get_enum (value));
|
||||
break;
|
||||
case PROP_MODIFIER_MASK:
|
||||
eek_symbol_set_modifier_mask (EEK_SYMBOL(object),
|
||||
g_value_get_flags (value));
|
||||
break;
|
||||
case PROP_ICON_NAME:
|
||||
eek_symbol_set_icon_name (EEK_SYMBOL(object),
|
||||
g_value_get_string (value));
|
||||
break;
|
||||
case PROP_TOOLTIP:
|
||||
eek_symbol_set_tooltip (EEK_SYMBOL(object),
|
||||
g_value_get_string (value));
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
eek_symbol_get_property (GObject *object,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
switch (prop_id) {
|
||||
case PROP_NAME:
|
||||
g_value_set_string (value, eek_symbol_get_name (EEK_SYMBOL(object)));
|
||||
break;
|
||||
case PROP_LABEL:
|
||||
g_value_set_string (value, eek_symbol_get_label (EEK_SYMBOL(object)));
|
||||
break;
|
||||
case PROP_CATEGORY:
|
||||
g_value_set_enum (value, eek_symbol_get_category (EEK_SYMBOL(object)));
|
||||
break;
|
||||
case PROP_MODIFIER_MASK:
|
||||
g_value_set_flags (value,
|
||||
eek_symbol_get_modifier_mask (EEK_SYMBOL(object)));
|
||||
break;
|
||||
case PROP_ICON_NAME:
|
||||
g_value_set_string (value,
|
||||
eek_symbol_get_icon_name (EEK_SYMBOL(object)));
|
||||
break;
|
||||
case PROP_TOOLTIP:
|
||||
g_value_set_string (value,
|
||||
eek_symbol_get_tooltip (EEK_SYMBOL(object)));
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
eek_symbol_finalize (GObject *object)
|
||||
{
|
||||
EekSymbol *self = EEK_SYMBOL (object);
|
||||
EekSymbolPrivate *priv = eek_symbol_get_instance_private (self);
|
||||
|
||||
g_free (priv->name);
|
||||
g_free (priv->label);
|
||||
g_free (priv->icon_name);
|
||||
g_free (priv->tooltip);
|
||||
G_OBJECT_CLASS (eek_symbol_parent_class)->finalize (object);
|
||||
g_free(priv->text);
|
||||
g_free(priv);
|
||||
}
|
||||
|
||||
static void
|
||||
eek_symbol_class_init (EekSymbolClass *klass)
|
||||
{
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||
GParamSpec *pspec;
|
||||
|
||||
gobject_class->set_property = eek_symbol_set_property;
|
||||
gobject_class->get_property = eek_symbol_get_property;
|
||||
gobject_class->finalize = eek_symbol_finalize;
|
||||
|
||||
pspec = g_param_spec_string ("name",
|
||||
"Name",
|
||||
"Canonical name of the symbol",
|
||||
NULL,
|
||||
G_PARAM_CONSTRUCT | G_PARAM_READWRITE);
|
||||
g_object_class_install_property (gobject_class, PROP_NAME, pspec);
|
||||
|
||||
pspec = g_param_spec_string ("label",
|
||||
"Label",
|
||||
"Text used to display the symbol",
|
||||
NULL,
|
||||
G_PARAM_CONSTRUCT | G_PARAM_READWRITE);
|
||||
g_object_class_install_property (gobject_class, PROP_LABEL, pspec);
|
||||
|
||||
pspec = g_param_spec_enum ("category",
|
||||
"Category",
|
||||
"Category of the symbol",
|
||||
EEK_TYPE_SYMBOL_CATEGORY,
|
||||
EEK_SYMBOL_CATEGORY_UNKNOWN,
|
||||
G_PARAM_CONSTRUCT | G_PARAM_READWRITE);
|
||||
g_object_class_install_property (gobject_class, PROP_CATEGORY, pspec);
|
||||
|
||||
pspec = g_param_spec_flags ("modifier-mask",
|
||||
"Modifier mask",
|
||||
"Modifier mask of the symbol",
|
||||
EEK_TYPE_MODIFIER_TYPE,
|
||||
0,
|
||||
G_PARAM_CONSTRUCT | G_PARAM_READWRITE);
|
||||
g_object_class_install_property (gobject_class, PROP_MODIFIER_MASK, pspec);
|
||||
|
||||
pspec = g_param_spec_string ("icon-name",
|
||||
"Icon name",
|
||||
"Icon name used to render the symbol",
|
||||
NULL,
|
||||
G_PARAM_CONSTRUCT | G_PARAM_READWRITE);
|
||||
g_object_class_install_property (gobject_class, PROP_ICON_NAME, pspec);
|
||||
|
||||
pspec = g_param_spec_string ("tooltip",
|
||||
"Tooltip",
|
||||
"Tooltip text",
|
||||
NULL,
|
||||
G_PARAM_CONSTRUCT | G_PARAM_READWRITE);
|
||||
g_object_class_install_property (gobject_class, PROP_TOOLTIP, pspec);
|
||||
}
|
||||
|
||||
static void
|
||||
eek_symbol_init (EekSymbol *self)
|
||||
{
|
||||
EekSymbolPrivate *priv = eek_symbol_get_instance_private (self);
|
||||
|
||||
priv->category = EEK_SYMBOL_CATEGORY_UNKNOWN;
|
||||
}
|
||||
|
||||
/**
|
||||
* eek_symbol_new:
|
||||
* @name: name of the symbol
|
||||
*
|
||||
* Create a new #EekSymbol with @name.
|
||||
*/
|
||||
EekSymbol *
|
||||
eek_symbol_new (const gchar *name)
|
||||
{
|
||||
return g_object_new (EEK_TYPE_SYMBOL, "name", name, NULL);
|
||||
EekSymbol *self = g_new0(EekSymbol, 1);
|
||||
eek_symbol_set_name(self, name);
|
||||
self->category = EEK_SYMBOL_CATEGORY_UNKNOWN;
|
||||
return self;
|
||||
}
|
||||
|
||||
/**
|
||||
* eek_symbol_set_name:
|
||||
* @symbol: an #EekSymbol
|
||||
* @name: name of the symbol
|
||||
*
|
||||
* Set the name of @symbol to @name.
|
||||
*/
|
||||
void
|
||||
eek_symbol_set_name (EekSymbol *symbol,
|
||||
const gchar *name)
|
||||
{
|
||||
g_return_if_fail (EEK_IS_SYMBOL(symbol));
|
||||
|
||||
EekSymbolPrivate *priv = eek_symbol_get_instance_private (symbol);
|
||||
|
||||
g_free (priv->name);
|
||||
priv->name = g_strdup (name);
|
||||
g_free (symbol->name);
|
||||
symbol->name = g_strdup (name);
|
||||
}
|
||||
|
||||
/**
|
||||
* eek_symbol_get_name:
|
||||
* @symbol: an #EekSymbol
|
||||
*
|
||||
* Get the name of @symbol.
|
||||
*/
|
||||
const gchar *
|
||||
eek_symbol_get_name (EekSymbol *symbol)
|
||||
{
|
||||
g_return_val_if_fail (EEK_IS_SYMBOL(symbol), NULL);
|
||||
|
||||
EekSymbolPrivate *priv = eek_symbol_get_instance_private (symbol);
|
||||
|
||||
if (priv->name == NULL || *priv->name == '\0')
|
||||
if (symbol->name == NULL || *symbol->name == '\0')
|
||||
return NULL;
|
||||
return priv->name;
|
||||
return symbol->name;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -305,12 +77,8 @@ void
|
||||
eek_symbol_set_label (EekSymbol *symbol,
|
||||
const gchar *label)
|
||||
{
|
||||
g_return_if_fail (EEK_IS_SYMBOL(symbol));
|
||||
|
||||
EekSymbolPrivate *priv = eek_symbol_get_instance_private (symbol);
|
||||
|
||||
g_free (priv->label);
|
||||
priv->label = g_strdup (label);
|
||||
g_free (symbol->label);
|
||||
symbol->label = g_strdup (label);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -322,47 +90,9 @@ eek_symbol_set_label (EekSymbol *symbol,
|
||||
const gchar *
|
||||
eek_symbol_get_label (EekSymbol *symbol)
|
||||
{
|
||||
g_return_val_if_fail (EEK_IS_SYMBOL(symbol), NULL);
|
||||
|
||||
EekSymbolPrivate *priv = eek_symbol_get_instance_private (symbol);
|
||||
|
||||
if (priv->label == NULL || *priv->label == '\0')
|
||||
if (symbol->label == NULL || *symbol->label == '\0')
|
||||
return NULL;
|
||||
return priv->label;
|
||||
}
|
||||
|
||||
/**
|
||||
* eek_symbol_set_category:
|
||||
* @symbol: an #EekSymbol
|
||||
* @category: an #EekSymbolCategory
|
||||
*
|
||||
* Set symbol category of @symbol to @category.
|
||||
*/
|
||||
void
|
||||
eek_symbol_set_category (EekSymbol *symbol,
|
||||
EekSymbolCategory category)
|
||||
{
|
||||
g_return_if_fail (EEK_IS_SYMBOL(symbol));
|
||||
|
||||
EekSymbolPrivate *priv = eek_symbol_get_instance_private (symbol);
|
||||
|
||||
priv->category = category;
|
||||
}
|
||||
|
||||
/**
|
||||
* eek_symbol_get_category:
|
||||
* @symbol: an #EekSymbol
|
||||
*
|
||||
* Get symbol category of @symbol.
|
||||
*/
|
||||
EekSymbolCategory
|
||||
eek_symbol_get_category (EekSymbol *symbol)
|
||||
{
|
||||
g_return_val_if_fail (EEK_IS_SYMBOL(symbol), EEK_SYMBOL_CATEGORY_UNKNOWN);
|
||||
|
||||
EekSymbolPrivate *priv = eek_symbol_get_instance_private (symbol);
|
||||
|
||||
return priv->category;
|
||||
return symbol->label;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -376,11 +106,7 @@ void
|
||||
eek_symbol_set_modifier_mask (EekSymbol *symbol,
|
||||
EekModifierType mask)
|
||||
{
|
||||
g_return_if_fail (EEK_IS_SYMBOL(symbol));
|
||||
|
||||
EekSymbolPrivate *priv = eek_symbol_get_instance_private (symbol);
|
||||
|
||||
priv->modifier_mask = mask;
|
||||
symbol->modifier_mask = mask;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -392,131 +118,43 @@ eek_symbol_set_modifier_mask (EekSymbol *symbol,
|
||||
EekModifierType
|
||||
eek_symbol_get_modifier_mask (EekSymbol *symbol)
|
||||
{
|
||||
g_return_val_if_fail (EEK_IS_SYMBOL(symbol), 0);
|
||||
|
||||
EekSymbolPrivate *priv = eek_symbol_get_instance_private (symbol);
|
||||
|
||||
return priv->modifier_mask;
|
||||
return symbol->modifier_mask;
|
||||
}
|
||||
|
||||
/**
|
||||
* eek_symbol_is_modifier:
|
||||
* @symbol: an #EekSymbol
|
||||
*
|
||||
* Check if @symbol is a modifier.
|
||||
* Returns: %TRUE if @symbol is a modifier.
|
||||
*/
|
||||
gboolean
|
||||
eek_symbol_is_modifier (EekSymbol *symbol)
|
||||
{
|
||||
return eek_symbol_get_modifier_mask (symbol) != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* eek_symbol_set_icon_name:
|
||||
* @symbol: an #EekSymbol
|
||||
* @icon_name: icon name of @symbol
|
||||
*
|
||||
* Set the icon name of @symbol to @icon_name.
|
||||
*/
|
||||
void
|
||||
eek_symbol_set_icon_name (EekSymbol *symbol,
|
||||
const gchar *icon_name)
|
||||
{
|
||||
g_return_if_fail (EEK_IS_SYMBOL(symbol));
|
||||
|
||||
EekSymbolPrivate *priv = eek_symbol_get_instance_private (symbol);
|
||||
|
||||
g_free (priv->icon_name);
|
||||
priv->icon_name = g_strdup (icon_name);
|
||||
g_free (symbol->icon_name);
|
||||
symbol->icon_name = g_strdup (icon_name);
|
||||
}
|
||||
|
||||
/**
|
||||
* eek_symbol_get_icon_name:
|
||||
* @symbol: an #EekSymbol
|
||||
*
|
||||
* Get the icon name of @symbol.
|
||||
*/
|
||||
const gchar *
|
||||
eek_symbol_get_icon_name (EekSymbol *symbol)
|
||||
{
|
||||
g_return_val_if_fail (EEK_IS_SYMBOL(symbol), NULL);
|
||||
|
||||
EekSymbolPrivate *priv = eek_symbol_get_instance_private (symbol);
|
||||
|
||||
if (priv->icon_name == NULL || *priv->icon_name == '\0')
|
||||
if (symbol->icon_name == NULL || *symbol->icon_name == '\0')
|
||||
return NULL;
|
||||
return priv->icon_name;
|
||||
return symbol->icon_name;
|
||||
}
|
||||
|
||||
/**
|
||||
* eek_symbol_set_tooltip:
|
||||
* @symbol: an #EekSymbol
|
||||
* @tooltip: icon name of @symbol
|
||||
*
|
||||
* Set the tooltip text of @symbol to @tooltip.
|
||||
*/
|
||||
void
|
||||
eek_symbol_set_tooltip (EekSymbol *symbol,
|
||||
const gchar *tooltip)
|
||||
{
|
||||
g_return_if_fail (EEK_IS_SYMBOL(symbol));
|
||||
|
||||
EekSymbolPrivate *priv = eek_symbol_get_instance_private (symbol);
|
||||
|
||||
g_free (priv->tooltip);
|
||||
priv->tooltip = g_strdup (tooltip);
|
||||
g_free (symbol->tooltip);
|
||||
symbol->tooltip = g_strdup (tooltip);
|
||||
}
|
||||
|
||||
/**
|
||||
* eek_symbol_get_tooltip:
|
||||
* @symbol: an #EekSymbol
|
||||
*
|
||||
* Get the tooltip text of @symbol.
|
||||
*/
|
||||
const gchar *
|
||||
eek_symbol_get_tooltip (EekSymbol *symbol)
|
||||
{
|
||||
g_return_val_if_fail (EEK_IS_SYMBOL(symbol), NULL);
|
||||
|
||||
EekSymbolPrivate *priv = eek_symbol_get_instance_private (symbol);
|
||||
|
||||
if (priv->tooltip == NULL || *priv->tooltip == '\0')
|
||||
if (symbol->tooltip == NULL || *symbol->tooltip == '\0')
|
||||
return NULL;
|
||||
return priv->tooltip;
|
||||
}
|
||||
|
||||
static const struct {
|
||||
EekSymbolCategory category;
|
||||
gchar *name;
|
||||
} category_names[] = {
|
||||
{ EEK_SYMBOL_CATEGORY_LETTER, "letter" },
|
||||
{ EEK_SYMBOL_CATEGORY_FUNCTION, "function" },
|
||||
{ EEK_SYMBOL_CATEGORY_KEYNAME, "keyname" },
|
||||
{ EEK_SYMBOL_CATEGORY_USER0, "user0" },
|
||||
{ EEK_SYMBOL_CATEGORY_USER1, "user1" },
|
||||
{ EEK_SYMBOL_CATEGORY_USER2, "user2" },
|
||||
{ EEK_SYMBOL_CATEGORY_USER3, "user3" },
|
||||
{ EEK_SYMBOL_CATEGORY_USER4, "user4" },
|
||||
{ EEK_SYMBOL_CATEGORY_UNKNOWN, NULL }
|
||||
};
|
||||
|
||||
const gchar *
|
||||
eek_symbol_category_get_name (EekSymbolCategory category)
|
||||
{
|
||||
gint i;
|
||||
for (i = 0; i < G_N_ELEMENTS(category_names); i++)
|
||||
if (category_names[i].category == category)
|
||||
return category_names[i].name;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
EekSymbolCategory
|
||||
eek_symbol_category_from_name (const gchar *name)
|
||||
{
|
||||
gint i;
|
||||
for (i = 0; i < G_N_ELEMENTS(category_names); i++)
|
||||
if (g_strcmp0 (category_names[i].name, name) == 0)
|
||||
return category_names[i].category;
|
||||
return EEK_SYMBOL_CATEGORY_UNKNOWN;
|
||||
return symbol->tooltip;
|
||||
}
|
||||
|
||||
@ -58,20 +58,27 @@ typedef enum {
|
||||
EEK_SYMBOL_CATEGORY_LAST = EEK_SYMBOL_CATEGORY_UNKNOWN
|
||||
} EekSymbolCategory;
|
||||
|
||||
#define EEK_TYPE_SYMBOL (eek_symbol_get_type())
|
||||
G_DECLARE_DERIVABLE_TYPE(EekSymbol, eek_symbol, EEK, SYMBOL, GObject)
|
||||
|
||||
/**
|
||||
* EekSymbolClass:
|
||||
*/
|
||||
struct _EekSymbolClass {
|
||||
/*< private >*/
|
||||
GObjectClass parent_class;
|
||||
};
|
||||
typedef struct _EekSymbol
|
||||
{
|
||||
/// Canonical name of the symbol
|
||||
gchar *name;
|
||||
/// Text used to display the symbol
|
||||
gchar *label;
|
||||
EekSymbolCategory category;
|
||||
EekModifierType modifier_mask;
|
||||
/// Icon name used to render the symbol
|
||||
gchar *icon_name;
|
||||
/// Tooltip text
|
||||
gchar *tooltip;
|
||||
|
||||
GType eek_symbol_get_type (void) G_GNUC_CONST;
|
||||
// May not be present
|
||||
guint xkeysym;
|
||||
gchar *text;
|
||||
} EekSymbol;
|
||||
|
||||
EekSymbol *eek_symbol_new (const gchar *name);
|
||||
void eek_symbol_free (EekSymbol *symbol);
|
||||
void eek_symbol_set_name (EekSymbol *symbol,
|
||||
const gchar *name);
|
||||
const gchar *eek_symbol_get_name (EekSymbol *symbol);
|
||||
|
||||
156
eek/eek-text.c
156
eek/eek-text.c
@ -26,160 +26,18 @@
|
||||
#include "config.h"
|
||||
|
||||
#include "eek-text.h"
|
||||
#include "eek-serializable.h"
|
||||
|
||||
enum {
|
||||
PROP_0,
|
||||
PROP_TEXT,
|
||||
PROP_LAST
|
||||
};
|
||||
|
||||
typedef struct _EekTextPrivate
|
||||
{
|
||||
gchar *text;
|
||||
} EekTextPrivate;
|
||||
|
||||
static void eek_serializable_iface_init (EekSerializableIface *iface);
|
||||
|
||||
G_DEFINE_TYPE_EXTENDED (EekText,
|
||||
eek_text,
|
||||
EEK_TYPE_SYMBOL,
|
||||
0, /* GTypeFlags */
|
||||
G_ADD_PRIVATE (EekText)
|
||||
G_IMPLEMENT_INTERFACE (EEK_TYPE_SERIALIZABLE,
|
||||
eek_serializable_iface_init))
|
||||
|
||||
static EekSerializableIface *eek_text_parent_serializable_iface;
|
||||
|
||||
static void
|
||||
eek_text_real_serialize (EekSerializable *self,
|
||||
GVariantBuilder *builder)
|
||||
{
|
||||
EekTextPrivate *priv = eek_text_get_instance_private (EEK_TEXT (self));
|
||||
|
||||
eek_text_parent_serializable_iface->serialize (self, builder);
|
||||
|
||||
g_variant_builder_add (builder, "s", priv->text);
|
||||
}
|
||||
|
||||
static gsize
|
||||
eek_text_real_deserialize (EekSerializable *self,
|
||||
GVariant *variant,
|
||||
gsize index)
|
||||
{
|
||||
EekTextPrivate *priv = eek_text_get_instance_private (EEK_TEXT (self));
|
||||
|
||||
index = eek_text_parent_serializable_iface->deserialize (self,
|
||||
variant,
|
||||
index);
|
||||
g_variant_get_child (variant, index++, "s", &priv->text);
|
||||
|
||||
return index;
|
||||
}
|
||||
|
||||
static void
|
||||
eek_serializable_iface_init (EekSerializableIface *iface)
|
||||
{
|
||||
eek_text_parent_serializable_iface =
|
||||
g_type_interface_peek_parent (iface);
|
||||
|
||||
iface->serialize = eek_text_real_serialize;
|
||||
iface->deserialize = eek_text_real_deserialize;
|
||||
}
|
||||
|
||||
static void
|
||||
eek_text_set_property (GObject *object,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
EekText *self = EEK_TEXT (object);
|
||||
EekTextPrivate *priv = eek_text_get_instance_private (self);
|
||||
|
||||
switch (prop_id) {
|
||||
case PROP_TEXT:
|
||||
g_free (priv->text);
|
||||
priv->text = g_strdup (g_value_get_string (value));
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
eek_text_get_property (GObject *object,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
EekText *self = EEK_TEXT (object);
|
||||
EekTextPrivate *priv = eek_text_get_instance_private (self);
|
||||
|
||||
switch (prop_id) {
|
||||
case PROP_TEXT:
|
||||
g_value_set_string (value, priv->text);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
eek_text_finalize (GObject *object)
|
||||
{
|
||||
EekText *self = EEK_TEXT (object);
|
||||
EekTextPrivate *priv = eek_text_get_instance_private (self);
|
||||
|
||||
g_free (priv->text);
|
||||
G_OBJECT_CLASS (eek_text_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
eek_text_class_init (EekTextClass *klass)
|
||||
{
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||
GParamSpec *pspec;
|
||||
|
||||
gobject_class->set_property = eek_text_set_property;
|
||||
gobject_class->get_property = eek_text_get_property;
|
||||
gobject_class->finalize = eek_text_finalize;
|
||||
|
||||
pspec = g_param_spec_string ("text",
|
||||
"Text",
|
||||
"Text",
|
||||
NULL,
|
||||
G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE);
|
||||
g_object_class_install_property (gobject_class, PROP_TEXT, pspec);
|
||||
}
|
||||
|
||||
static void
|
||||
eek_text_init (EekText *self)
|
||||
{
|
||||
/* void */
|
||||
}
|
||||
|
||||
EekText *
|
||||
EekSymbol *
|
||||
eek_text_new (const gchar *text)
|
||||
{
|
||||
return g_object_new (EEK_TYPE_TEXT,
|
||||
"label", text,
|
||||
"category", EEK_SYMBOL_CATEGORY_FUNCTION,
|
||||
"text", text,
|
||||
NULL);
|
||||
EekSymbol *ret = eek_symbol_new("");
|
||||
eek_symbol_set_label(ret, text);
|
||||
ret->text = g_strdup (text);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* eek_text_get_text:
|
||||
* @text: an #EekText
|
||||
*
|
||||
* Get a text value associated with @text
|
||||
*/
|
||||
const gchar *
|
||||
eek_text_get_text (EekText *text)
|
||||
eek_text_get_text (EekSymbol *text)
|
||||
{
|
||||
EekTextPrivate *priv = eek_text_get_instance_private (text);
|
||||
|
||||
return priv->text;
|
||||
return text->text;
|
||||
}
|
||||
|
||||
@ -29,17 +29,9 @@
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define EEK_TYPE_TEXT (eek_text_get_type())
|
||||
G_DECLARE_DERIVABLE_TYPE(EekText, eek_text, EEK, TEXT, EekSymbol)
|
||||
|
||||
struct _EekTextClass {
|
||||
/*< private >*/
|
||||
EekSymbolClass parent_class;
|
||||
};
|
||||
|
||||
GType eek_text_get_type (void) G_GNUC_CONST;
|
||||
EekText *eek_text_new (const gchar *text);
|
||||
const gchar *eek_text_get_text (EekText *text);
|
||||
EekSymbol *eek_text_new (const gchar *text);
|
||||
const gchar *eek_text_get_text (EekSymbol *text);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
||||
@ -1,287 +0,0 @@
|
||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; c-basic-offset: 2; -*- */
|
||||
/*
|
||||
* eek-theme-context.c: holds global information about a tree of styled objects
|
||||
*
|
||||
* Copyright 2009, 2010 Red Hat, Inc.
|
||||
* Copyright 2009 Florian Müllner
|
||||
*
|
||||
* This program 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.1 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope 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 program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "eek-theme.h"
|
||||
#include "eek-theme-context.h"
|
||||
|
||||
struct _EekThemeContext {
|
||||
GObject parent;
|
||||
|
||||
double resolution;
|
||||
PangoFontDescription *font;
|
||||
EekThemeNode *root_node;
|
||||
EekTheme *theme;
|
||||
};
|
||||
|
||||
struct _EekThemeContextClass {
|
||||
GObjectClass parent_class;
|
||||
};
|
||||
|
||||
#define DEFAULT_RESOLUTION 96.
|
||||
#define DEFAULT_FONT "sans-serif 10"
|
||||
|
||||
enum
|
||||
{
|
||||
CHANGED,
|
||||
|
||||
LAST_SIGNAL
|
||||
};
|
||||
|
||||
static guint signals[LAST_SIGNAL] = { 0, };
|
||||
|
||||
G_DEFINE_TYPE (EekThemeContext, eek_theme_context, G_TYPE_OBJECT)
|
||||
|
||||
static void
|
||||
eek_theme_context_finalize (GObject *object)
|
||||
{
|
||||
EekThemeContext *context = EEK_THEME_CONTEXT (object);
|
||||
|
||||
if (context->root_node)
|
||||
g_object_unref (context->root_node);
|
||||
if (context->theme)
|
||||
g_object_unref (context->theme);
|
||||
|
||||
pango_font_description_free (context->font);
|
||||
|
||||
G_OBJECT_CLASS (eek_theme_context_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
eek_theme_context_class_init (EekThemeContextClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
object_class->finalize = eek_theme_context_finalize;
|
||||
|
||||
signals[CHANGED] =
|
||||
g_signal_new ("changed",
|
||||
G_TYPE_FROM_CLASS (klass),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
0, /* no default handler slot */
|
||||
NULL, NULL,
|
||||
g_cclosure_marshal_VOID__VOID,
|
||||
G_TYPE_NONE, 0);
|
||||
}
|
||||
|
||||
static void
|
||||
eek_theme_context_init (EekThemeContext *context)
|
||||
{
|
||||
context->resolution = DEFAULT_RESOLUTION;
|
||||
context->font = pango_font_description_from_string (DEFAULT_FONT);
|
||||
}
|
||||
|
||||
/**
|
||||
* eek_theme_context_new:
|
||||
*
|
||||
* Create a new theme context.
|
||||
*/
|
||||
EekThemeContext *
|
||||
eek_theme_context_new (void)
|
||||
{
|
||||
EekThemeContext *context;
|
||||
|
||||
context = g_object_new (EEK_TYPE_THEME_CONTEXT, NULL);
|
||||
|
||||
return context;
|
||||
}
|
||||
|
||||
static void
|
||||
eek_theme_context_changed (EekThemeContext *context)
|
||||
{
|
||||
EekThemeNode *old_root = context->root_node;
|
||||
context->root_node = NULL;
|
||||
|
||||
g_signal_emit (context, signals[CHANGED], 0);
|
||||
|
||||
if (old_root)
|
||||
g_object_unref (old_root);
|
||||
}
|
||||
|
||||
/**
|
||||
* eek_theme_context_set_theme:
|
||||
* @context: an #EekThemeContext
|
||||
* @theme: an #EekTheme
|
||||
*
|
||||
* Sets the default set of theme stylesheets for the context. This theme will
|
||||
* be used for the root node and for nodes descending from it, unless some other
|
||||
* style is explicitely specified.
|
||||
*/
|
||||
void
|
||||
eek_theme_context_set_theme (EekThemeContext *context,
|
||||
EekTheme *theme)
|
||||
{
|
||||
g_return_if_fail (EEK_IS_THEME_CONTEXT (context));
|
||||
g_return_if_fail (theme == NULL || EEK_IS_THEME (theme));
|
||||
|
||||
if (context->theme != theme)
|
||||
{
|
||||
if (context->theme)
|
||||
g_object_unref (context->theme);
|
||||
|
||||
context->theme = theme;
|
||||
|
||||
if (context->theme)
|
||||
g_object_ref (context->theme);
|
||||
|
||||
eek_theme_context_changed (context);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* eek_theme_context_get_theme:
|
||||
* @context: a #EekThemeContext
|
||||
*
|
||||
* Gets the default theme for the context. See eek_theme_context_set_theme()
|
||||
*
|
||||
* Return value: (transfer none): the default theme for the context
|
||||
*/
|
||||
EekTheme *
|
||||
eek_theme_context_get_theme (EekThemeContext *context)
|
||||
{
|
||||
g_return_val_if_fail (EEK_IS_THEME_CONTEXT (context), NULL);
|
||||
|
||||
return context->theme;
|
||||
}
|
||||
|
||||
/**
|
||||
* eek_theme_context_set_resolution:
|
||||
* @context: a #EekThemeContext
|
||||
* @resolution: resolution of the context (number of pixels in an "inch")
|
||||
*
|
||||
* Sets the resolution of the theme context. This is the scale factor
|
||||
* used to convert between points and the length units pt, in, and cm.
|
||||
* This does not necessarily need to correspond to the actual number
|
||||
* resolution of the device. A value of 72. means that points and
|
||||
* pixels are identical. The default value is 96.
|
||||
*/
|
||||
void
|
||||
eek_theme_context_set_resolution (EekThemeContext *context,
|
||||
double resolution)
|
||||
{
|
||||
g_return_if_fail (EEK_IS_THEME_CONTEXT (context));
|
||||
|
||||
if (resolution == context->resolution)
|
||||
return;
|
||||
|
||||
context->resolution = resolution;
|
||||
eek_theme_context_changed (context);
|
||||
}
|
||||
|
||||
/**
|
||||
* eek_theme_context_set_default_resolution:
|
||||
* @context: a #EekThemeContext
|
||||
*
|
||||
* Sets the resolution of the theme context to the default value of 96.
|
||||
* See eek_theme_context_set_resolution().
|
||||
*/
|
||||
void
|
||||
eek_theme_context_set_default_resolution (EekThemeContext *context)
|
||||
{
|
||||
g_return_if_fail (EEK_IS_THEME_CONTEXT (context));
|
||||
|
||||
if (context->resolution == DEFAULT_RESOLUTION)
|
||||
return;
|
||||
|
||||
context->resolution = DEFAULT_RESOLUTION;
|
||||
eek_theme_context_changed (context);
|
||||
}
|
||||
|
||||
/**
|
||||
* eek_theme_context_get_resolution:
|
||||
* @context: a #EekThemeContext
|
||||
*
|
||||
* Gets the current resolution of the theme context.
|
||||
* See eek_theme_context_set_resolution().
|
||||
*
|
||||
* Return value: the resolution (in dots-per-"inch")
|
||||
*/
|
||||
double
|
||||
eek_theme_context_get_resolution (EekThemeContext *context)
|
||||
{
|
||||
g_return_val_if_fail (EEK_IS_THEME_CONTEXT (context), DEFAULT_RESOLUTION);
|
||||
|
||||
return context->resolution;
|
||||
}
|
||||
|
||||
/**
|
||||
* eek_theme_context_set_font:
|
||||
* @context: a #EekThemeContext
|
||||
* @font: the default font for theme context
|
||||
*
|
||||
* Sets the default font for the theme context. This is the font that
|
||||
* is inherited by the root node of the tree of theme nodes. If the
|
||||
* font is not overriden, then this font will be used. If the font is
|
||||
* partially modified (for example, with 'font-size: 110%', then that
|
||||
* modification is based on this font.
|
||||
*/
|
||||
void
|
||||
eek_theme_context_set_font (EekThemeContext *context,
|
||||
const PangoFontDescription *font)
|
||||
{
|
||||
g_return_if_fail (EEK_IS_THEME_CONTEXT (context));
|
||||
g_return_if_fail (font != NULL);
|
||||
|
||||
if (context->font == font ||
|
||||
pango_font_description_equal (context->font, font))
|
||||
return;
|
||||
|
||||
pango_font_description_free (context->font);
|
||||
context->font = pango_font_description_copy (font);
|
||||
eek_theme_context_changed (context);
|
||||
}
|
||||
|
||||
/**
|
||||
* eek_theme_context_get_font:
|
||||
* @context: a #EekThemeContext
|
||||
*
|
||||
* Gets the default font for the theme context. See eek_theme_context_set_font().
|
||||
*
|
||||
* Return value: the default font for the theme context.
|
||||
*/
|
||||
const PangoFontDescription *
|
||||
eek_theme_context_get_font (EekThemeContext *context)
|
||||
{
|
||||
g_return_val_if_fail (EEK_IS_THEME_CONTEXT (context), NULL);
|
||||
|
||||
return context->font;
|
||||
}
|
||||
|
||||
/**
|
||||
* eek_theme_context_get_root_node:
|
||||
* @context: a #EekThemeContext
|
||||
*
|
||||
* Gets the root node of the tree of theme style nodes that associated with this
|
||||
* context. For the node tree associated with a stage, this node represents
|
||||
* styles applied to the stage itself.
|
||||
*
|
||||
* Return value: (transfer none): the root node of the context's style tree
|
||||
*/
|
||||
EekThemeNode *
|
||||
eek_theme_context_get_root_node (EekThemeContext *context)
|
||||
{
|
||||
if (context->root_node == NULL)
|
||||
context->root_node = eek_theme_node_new (context, NULL, context->theme,
|
||||
G_TYPE_NONE, NULL, NULL, NULL, NULL);
|
||||
|
||||
return context->root_node;
|
||||
}
|
||||
@ -1,78 +0,0 @@
|
||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
||||
/*
|
||||
* eek-theme-context.c: holds global information about a tree of styled objects
|
||||
*
|
||||
* Copyright 2009, 2010 Red Hat, Inc.
|
||||
* Copyright 2009 Florian Müllner
|
||||
*
|
||||
* This program 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.1 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope 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 program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __EEK_THEME_CONTEXT_H__
|
||||
#define __EEK_THEME_CONTEXT_H__
|
||||
|
||||
#include <pango/pango.h>
|
||||
#include "eek-theme-node.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
/**
|
||||
* SECTION:eek-theme-context
|
||||
* @short_description: holds global information about a tree of styled objects
|
||||
*
|
||||
* #EekThemeContext is responsible for managing information global to
|
||||
* a tree of styled objects, such as the set of stylesheets or the
|
||||
* default font.
|
||||
*/
|
||||
|
||||
typedef struct _EekThemeContextClass EekThemeContextClass;
|
||||
|
||||
#define EEK_TYPE_THEME_CONTEXT (eek_theme_context_get_type ())
|
||||
#define EEK_THEME_CONTEXT(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), EEK_TYPE_THEME_CONTEXT, EekThemeContext))
|
||||
#define EEK_THEME_CONTEXT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EEK_TYPE_THEME_CONTEXT, EekThemeContextClass))
|
||||
#define EEK_IS_THEME_CONTEXT(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), EEK_TYPE_THEME_CONTEXT))
|
||||
#define EEK_IS_THEME_CONTEXT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EEK_TYPE_THEME_CONTEXT))
|
||||
#define EEK_THEME_CONTEXT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EEK_TYPE_THEME_CONTEXT, EekThemeContextClass))
|
||||
|
||||
GType eek_theme_context_get_type
|
||||
(void) G_GNUC_CONST;
|
||||
|
||||
EekThemeContext *eek_theme_context_new
|
||||
(void);
|
||||
|
||||
void eek_theme_context_set_theme
|
||||
(EekThemeContext *context,
|
||||
EekTheme *theme);
|
||||
EekTheme * eek_theme_context_get_theme
|
||||
(EekThemeContext *context);
|
||||
|
||||
void eek_theme_context_set_resolution
|
||||
(EekThemeContext *context,
|
||||
gdouble resolution);
|
||||
void eek_theme_context_set_default_resolution
|
||||
(EekThemeContext *context);
|
||||
double eek_theme_context_get_resolution
|
||||
(EekThemeContext *context);
|
||||
void eek_theme_context_set_font
|
||||
(EekThemeContext *context,
|
||||
const PangoFontDescription *font);
|
||||
const PangoFontDescription *eek_theme_context_get_font
|
||||
(EekThemeContext *context);
|
||||
|
||||
EekThemeNode * eek_theme_context_get_root_node
|
||||
(EekThemeContext *context);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __EEK_THEME_CONTEXT_H__ */
|
||||
1864
eek/eek-theme-node.c
1864
eek/eek-theme-node.c
File diff suppressed because it is too large
Load Diff
@ -1,141 +0,0 @@
|
||||
/*
|
||||
* 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_THEME_NODE_H__
|
||||
#define __EEK_THEME_NODE_H__
|
||||
|
||||
#include <pango/pango.h>
|
||||
#include "eek-types.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
/**
|
||||
* SECTION:eek-theme-node
|
||||
* @short_description: style information for one node in a tree of
|
||||
* themed objects
|
||||
*
|
||||
* The #EekThemeNode class represents the CSS style information (the
|
||||
* set of CSS properties) for one node in a tree of themed objects. In
|
||||
* typical usage, it represents the style information for a single
|
||||
* #EekElement. A #EekThemeNode is immutable: attributes such as the
|
||||
* CSS classes for the node are passed in at construction. If the
|
||||
* attributes of the node or any parent node change, the node should
|
||||
* be discarded and a new node created. #EekThemeNode has generic
|
||||
* accessors to look up properties by name and specific accessors for
|
||||
* standard CSS properties that add caching and handling of various
|
||||
* details of the CSS specification. #EekThemeNode also has
|
||||
* convenience functions to help in implementing a #EekElement with
|
||||
* borders and padding.
|
||||
*/
|
||||
|
||||
typedef enum {
|
||||
EEK_SIDE_TOP,
|
||||
EEK_SIDE_RIGHT,
|
||||
EEK_SIDE_BOTTOM,
|
||||
EEK_SIDE_LEFT
|
||||
} EekSide;
|
||||
|
||||
typedef enum {
|
||||
EEK_CORNER_TOPLEFT,
|
||||
EEK_CORNER_TOPRIGHT,
|
||||
EEK_CORNER_BOTTOMRIGHT,
|
||||
EEK_CORNER_BOTTOMLEFT
|
||||
} EekCorner;
|
||||
|
||||
#define EEK_TYPE_THEME_NODE (eek_theme_node_get_type())
|
||||
#define EEK_THEME_NODE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EEK_TYPE_THEME_NODE, EekThemeNode))
|
||||
#define EEK_THEME_NODE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EEK_TYPE_THEME_NODE, EekThemeNodeClass))
|
||||
#define EEK_IS_THEME_NODE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EEK_TYPE_THEME_NODE))
|
||||
#define EEK_IS_THEME_NODE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EEK_TYPE_THEME_NODE))
|
||||
#define EEK_THEME_NODE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EEK_TYPE_THEME_NODE, EekThemeNodeClass))
|
||||
|
||||
typedef struct _EekThemeNodeClass EekThemeNodeClass;
|
||||
typedef struct _EekThemeNodePrivate EekThemeNodePrivate;
|
||||
|
||||
GType eek_theme_node_get_type
|
||||
(void) G_GNUC_CONST;
|
||||
|
||||
EekThemeNode *eek_theme_node_new (EekThemeContext *context,
|
||||
EekThemeNode *parent_node,
|
||||
/* can be null */ EekTheme *theme,
|
||||
/* can be null */ GType element_type,
|
||||
const char *element_id,
|
||||
const char *element_class,
|
||||
const char *pseudo_class,
|
||||
const char *inline_style);
|
||||
|
||||
EekThemeNode *eek_theme_node_get_parent
|
||||
(EekThemeNode *node);
|
||||
|
||||
EekTheme *eek_theme_node_get_theme
|
||||
(EekThemeNode *node);
|
||||
|
||||
GType eek_theme_node_get_element_type
|
||||
(EekThemeNode *node);
|
||||
const char *eek_theme_node_get_element_id
|
||||
(EekThemeNode *node);
|
||||
const char *eek_theme_node_get_element_class
|
||||
(EekThemeNode *node);
|
||||
const char *eek_theme_node_get_pseudo_class
|
||||
(EekThemeNode *node);
|
||||
|
||||
/* Generic getters ... these are not cached so are less efficient. The other
|
||||
* reason for adding the more specific version is that we can handle the
|
||||
* details of the actual CSS rules, which can be complicated, especially
|
||||
* for fonts
|
||||
*/
|
||||
void eek_theme_node_get_color
|
||||
(EekThemeNode *node,
|
||||
const char *property_name,
|
||||
EekColor *color);
|
||||
|
||||
/* Specific getters for particular properties: cached
|
||||
*/
|
||||
void eek_theme_node_get_background_color
|
||||
(EekThemeNode *node,
|
||||
EekColor *color);
|
||||
void eek_theme_node_get_foreground_color
|
||||
(EekThemeNode *node,
|
||||
EekColor *color);
|
||||
void eek_theme_node_get_background_gradient
|
||||
(EekThemeNode *node,
|
||||
EekGradientType *type,
|
||||
EekColor *start,
|
||||
EekColor *end);
|
||||
int eek_theme_node_get_border_width
|
||||
(EekThemeNode *node,
|
||||
EekSide side);
|
||||
int eek_theme_node_get_border_radius
|
||||
(EekThemeNode *node,
|
||||
EekCorner corner);
|
||||
void eek_theme_node_get_border_color
|
||||
(EekThemeNode *node,
|
||||
EekSide side,
|
||||
EekColor *color);
|
||||
|
||||
/* Font rule processing is pretty complicated, so we just hardcode it
|
||||
* under the standard font/font-family/font-size/etc names. This means
|
||||
* you can't have multiple separate styled fonts for a single item,
|
||||
* but that should be OK.
|
||||
*/
|
||||
const PangoFontDescription *eek_theme_node_get_font (EekThemeNode *node);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __EEK_THEME_NODE_H__ */
|
||||
@ -1,22 +0,0 @@
|
||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
||||
#ifndef __EEK_THEME_PRIVATE_H__
|
||||
#define __EEK_THEME_PRIVATE_H__
|
||||
|
||||
#include <libcroco/libcroco.h>
|
||||
#include "eek-theme.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
GPtrArray *_eek_theme_get_matched_properties (EekTheme *theme,
|
||||
EekThemeNode *node);
|
||||
|
||||
/* Resolve an URL from the stylesheet to a filename */
|
||||
char *_eek_theme_resolve_url (EekTheme *theme,
|
||||
CRStyleSheet *base_stylesheet,
|
||||
const char *url);
|
||||
|
||||
CRDeclaration *_eek_theme_parse_declaration_list (const char *str);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __EEK_THEME_PRIVATE_H__ */
|
||||
1095
eek/eek-theme.c
1095
eek/eek-theme.c
File diff suppressed because it is too large
Load Diff
@ -1,49 +0,0 @@
|
||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
||||
|
||||
#if !defined(__EEK_H_INSIDE__) && !defined(EEK_COMPILATION)
|
||||
#error "Only <eek/eek.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#ifndef __EEK_THEME_H__
|
||||
#define __EEK_THEME_H__
|
||||
|
||||
#include <glib-object.h>
|
||||
|
||||
#include "eek-types.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
/**
|
||||
* SECTION:EekTheme
|
||||
* @short_description: a set of stylesheets
|
||||
*
|
||||
* #EekTheme holds a set of stylesheets. (The "cascade" of the name
|
||||
* Cascading Stylesheets.) An #EekTheme can be set to apply to all the
|
||||
* keyboard elements.
|
||||
*/
|
||||
|
||||
typedef struct _EekThemeClass EekThemeClass;
|
||||
|
||||
#define EEK_TYPE_THEME (eek_theme_get_type())
|
||||
#define EEK_THEME(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EEK_TYPE_THEME, EekTheme))
|
||||
#define EEK_THEME_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EEK_TYPE_THEME, EekThemeClass))
|
||||
#define EEK_IS_THEME(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EEK_TYPE_THEME))
|
||||
#define EEK_IS_THEME_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EEK_TYPE_THEME))
|
||||
#define EEK_THEME_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EEK_TYPE_THEME, EekThemeClass))
|
||||
|
||||
GType eek_theme_get_type (void) G_GNUC_CONST;
|
||||
|
||||
EekTheme *eek_theme_new (const char *application_stylesheet,
|
||||
const char *theme_stylesheet,
|
||||
const char *default_stylesheet);
|
||||
|
||||
gboolean eek_theme_load_stylesheet (EekTheme *theme,
|
||||
const char *path,
|
||||
GError **error);
|
||||
|
||||
void eek_theme_unload_stylesheet (EekTheme *theme,
|
||||
const char *path);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __EEK_THEME_H__ */
|
||||
@ -139,7 +139,6 @@ typedef struct _EekKey EekKey;
|
||||
typedef struct _EekSection EekSection;
|
||||
typedef struct _EekKeyboard EekKeyboard;
|
||||
typedef struct _EekSymbol EekSymbol;
|
||||
typedef struct _EekKeysym EekKeysym;
|
||||
typedef struct _EekText EekText;
|
||||
typedef struct _EekTheme EekTheme;
|
||||
typedef struct _EekThemeContext EekThemeContext;
|
||||
|
||||
@ -79,10 +79,6 @@ static gboolean parse_symbols (const gchar *path,
|
||||
EekKeyboard *keyboard,
|
||||
GError **error);
|
||||
|
||||
static void scale_keyboard (EekKeyboard *keyboard,
|
||||
gdouble width,
|
||||
gdouble height);
|
||||
|
||||
static gboolean validate (const gchar **valid_path_list,
|
||||
gsize valid_path_list_len,
|
||||
const gchar *element_name,
|
||||
@ -247,6 +243,7 @@ struct _GeometryParseData {
|
||||
gchar *name;
|
||||
EekOutline outline;
|
||||
gchar *oref;
|
||||
gint keycode;
|
||||
|
||||
GHashTable *key_oref_hash;
|
||||
GHashTable *oref_outline_hash;
|
||||
@ -269,6 +266,7 @@ geometry_parse_data_new (EekKeyboard *keyboard)
|
||||
g_str_equal,
|
||||
g_free,
|
||||
(GDestroyNotify)eek_outline_free);
|
||||
data->keycode = 8;
|
||||
return data;
|
||||
}
|
||||
|
||||
@ -396,17 +394,6 @@ geometry_start_element_callback (GMarkupParseContext *pcontext,
|
||||
if (g_strcmp0 (element_name, "key") == 0) {
|
||||
guint keycode;
|
||||
|
||||
attribute = get_attribute (attribute_names, attribute_values,
|
||||
"keycode");
|
||||
if (attribute == NULL) {
|
||||
g_set_error (error,
|
||||
G_MARKUP_ERROR,
|
||||
G_MARKUP_ERROR_MISSING_ATTRIBUTE,
|
||||
"no \"keycode\" attribute for \"key\"");
|
||||
return;
|
||||
}
|
||||
keycode = strtol (attribute, NULL, 10);
|
||||
|
||||
attribute = get_attribute (attribute_names, attribute_values,
|
||||
"name");
|
||||
if (attribute == NULL) {
|
||||
@ -416,12 +403,18 @@ geometry_start_element_callback (GMarkupParseContext *pcontext,
|
||||
"no \"name\" attribute for \"key\"");
|
||||
return;
|
||||
}
|
||||
gchar *name = g_strdup (attribute);
|
||||
|
||||
attribute = get_attribute (attribute_names, attribute_values,
|
||||
"keycode");
|
||||
if (attribute != NULL)
|
||||
keycode = strtol (attribute, NULL, 10);
|
||||
else
|
||||
keycode = data->keycode++;
|
||||
|
||||
data->key = eek_section_create_key (data->section,
|
||||
g_strdup (attribute),
|
||||
keycode,
|
||||
data->num_columns,
|
||||
data->num_rows - 1);
|
||||
name,
|
||||
keycode);
|
||||
|
||||
attribute = get_attribute (attribute_names, attribute_values,
|
||||
"oref");
|
||||
@ -573,7 +566,6 @@ struct _SymbolsParseData {
|
||||
gchar *label;
|
||||
gchar *icon;
|
||||
gchar *tooltip;
|
||||
EekSymbolCategory category;
|
||||
guint keyval;
|
||||
gint groups;
|
||||
};
|
||||
@ -686,13 +678,6 @@ symbols_start_element_callback (GMarkupParseContext *pcontext,
|
||||
"tooltip");
|
||||
if (attribute != NULL)
|
||||
data->tooltip = g_strdup (attribute);
|
||||
|
||||
attribute = get_attribute (attribute_names, attribute_values,
|
||||
"category");
|
||||
if (attribute != NULL)
|
||||
data->category = strtoul (attribute, NULL, 10);
|
||||
else
|
||||
data->category = EEK_SYMBOL_CATEGORY_KEYNAME;
|
||||
}
|
||||
|
||||
out:
|
||||
@ -727,7 +712,6 @@ symbols_end_element_callback (GMarkupParseContext *pcontext,
|
||||
gint levels = num_symbols / data->groups;
|
||||
EekSymbolMatrix *matrix = eek_symbol_matrix_new (data->groups,
|
||||
levels);
|
||||
|
||||
head = data->symbols = g_slist_reverse (data->symbols);
|
||||
for (i = 0; i < num_symbols; i++) {
|
||||
if (head && head->data) {
|
||||
@ -751,21 +735,22 @@ symbols_end_element_callback (GMarkupParseContext *pcontext,
|
||||
EekSymbol *symbol;
|
||||
|
||||
if (g_strcmp0 (element_name, "keysym") == 0) {
|
||||
EekKeysym *keysym;
|
||||
EekSymbol *keysym;
|
||||
if (data->keyval != EEK_INVALID_KEYSYM)
|
||||
keysym = eek_keysym_new (data->keyval);
|
||||
else
|
||||
keysym = eek_keysym_new_from_name (text);
|
||||
symbol = EEK_SYMBOL(keysym);
|
||||
symbol = keysym;
|
||||
} else if (g_strcmp0 (element_name, "text") == 0) {
|
||||
symbol = EEK_SYMBOL(eek_text_new (text));
|
||||
symbol = eek_text_new (text);
|
||||
} else {
|
||||
symbol = eek_symbol_new (text);
|
||||
eek_symbol_set_category (symbol, EEK_SYMBOL_CATEGORY_KEYNAME);
|
||||
}
|
||||
|
||||
if (data->label) {
|
||||
eek_symbol_set_label (symbol, data->label);
|
||||
eek_keyboard_register_symbol (data->keyboard, symbol, data->key,
|
||||
g_slist_length (data->symbols));
|
||||
g_free (data->label);
|
||||
data->label = NULL;
|
||||
}
|
||||
@ -946,11 +931,9 @@ eek_xml_layout_real_create_keyboard (EekboardContextService *manager,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Arrange the sections in the original coordinate system. */
|
||||
eek_layout_place_sections(keyboard);
|
||||
|
||||
/* Fit keyboard in the given width and height. */
|
||||
scale_keyboard (keyboard, initial_width, initial_height);
|
||||
|
||||
/* Use pre-defined modifier mask here. */
|
||||
eek_keyboard_set_num_lock_mask (keyboard, EEK_MOD2_MASK);
|
||||
eek_keyboard_set_alt_gr_mask (keyboard, EEK_BUTTON1_MASK);
|
||||
@ -1360,23 +1343,6 @@ parse_keyboards (const gchar *path, GError **error)
|
||||
return keyboards;
|
||||
}
|
||||
|
||||
static void scale_keyboard (EekKeyboard *keyboard,
|
||||
gdouble width,
|
||||
gdouble height)
|
||||
{
|
||||
gdouble scale;
|
||||
EekBounds bounds;
|
||||
|
||||
eek_element_get_bounds (EEK_ELEMENT(keyboard), &bounds);
|
||||
|
||||
if (width * bounds.height < height * bounds.width)
|
||||
scale = width / bounds.width;
|
||||
else
|
||||
scale = height / bounds.height;
|
||||
|
||||
eek_layout_scale_keyboard(keyboard, scale);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
validate (const gchar **valid_path_list,
|
||||
gsize valid_path_list_len,
|
||||
|
||||
315
eek/eek-xml.c
315
eek/eek-xml.c
@ -1,315 +0,0 @@
|
||||
/*
|
||||
* 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: eek-xml
|
||||
* @title: XML Conversion Utilities
|
||||
* @short_description: #EekKeyboard to XML conversion utilities
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <glib/gprintf.h>
|
||||
|
||||
#include "eek-section.h"
|
||||
#include "eek-key.h"
|
||||
#include "eek-xml.h"
|
||||
#include "eek-keysym.h"
|
||||
#include "eek-text.h"
|
||||
|
||||
#define g_string_append_indent(string, indent) \
|
||||
{ \
|
||||
gint i; \
|
||||
for (i = 0; i < (indent); i++) { \
|
||||
g_string_append (string, " "); \
|
||||
} \
|
||||
}
|
||||
|
||||
void
|
||||
g_string_markup_printf (GString *output, const gchar *format, ...)
|
||||
{
|
||||
gchar *escaped_text;
|
||||
va_list ap;
|
||||
|
||||
va_start (ap, format);
|
||||
escaped_text = g_markup_vprintf_escaped (format, ap);
|
||||
va_end (ap);
|
||||
|
||||
g_string_append (output, escaped_text);
|
||||
g_free (escaped_text);
|
||||
}
|
||||
|
||||
struct _OutputCallbackData {
|
||||
GString *output;
|
||||
gint indent;
|
||||
GHashTable *oref_hash;
|
||||
gint key_serial;
|
||||
};
|
||||
typedef struct _OutputCallbackData OutputCallbackData;
|
||||
|
||||
static void
|
||||
output_bounds (GString *output, EekBounds *bounds)
|
||||
{
|
||||
g_string_markup_printf (output,
|
||||
"<bounds>%lf,%lf,%lf,%lf</bounds>\n",
|
||||
bounds->x,
|
||||
bounds->y,
|
||||
bounds->width,
|
||||
bounds->height);
|
||||
}
|
||||
|
||||
static void
|
||||
output_symbol_attributes (GString *output,
|
||||
EekSymbol *symbol)
|
||||
{
|
||||
if (eek_symbol_get_name (symbol) != NULL)
|
||||
g_string_markup_printf (output, " name=\"%s\"",
|
||||
eek_symbol_get_name (symbol));
|
||||
if (eek_symbol_get_label (symbol) != NULL)
|
||||
g_string_markup_printf (output, " label=\"%s\"",
|
||||
eek_symbol_get_label (symbol));
|
||||
if (eek_symbol_get_category (symbol) != EEK_SYMBOL_CATEGORY_UNKNOWN)
|
||||
g_string_markup_printf (output, " category=\"%s\"",
|
||||
eek_symbol_category_get_name (eek_symbol_get_category (symbol)));
|
||||
}
|
||||
|
||||
static void
|
||||
output_key_callback (EekElement *element, gpointer user_data)
|
||||
{
|
||||
OutputCallbackData *data = user_data;
|
||||
EekBounds bounds;
|
||||
gint i, num_symbols;
|
||||
EekSymbolMatrix *matrix;
|
||||
gint column, row;
|
||||
guint keycode;
|
||||
gchar *id;
|
||||
gulong oref;
|
||||
|
||||
keycode = eek_key_get_keycode (EEK_KEY(element));
|
||||
if (keycode == EEK_INVALID_KEYCODE)
|
||||
id = g_strdup_printf ("key%d", data->key_serial);
|
||||
else
|
||||
id = g_strdup_printf ("keycode%d", keycode);
|
||||
data->key_serial++;
|
||||
|
||||
eek_key_get_index (EEK_KEY(element), &column, &row);
|
||||
g_string_append_indent (data->output, data->indent);
|
||||
if (eek_element_get_name (element))
|
||||
g_string_markup_printf (data->output,
|
||||
"<key id=\"%s\" name=\"%s\" "
|
||||
"column=\"%d\" row=\"%d\">\n",
|
||||
id,
|
||||
eek_element_get_name (element),
|
||||
column,
|
||||
row);
|
||||
else
|
||||
g_string_markup_printf (data->output,
|
||||
"<key id=\"%s\" "
|
||||
"column=\"%d\" row=\"%d\">\n",
|
||||
id,
|
||||
column,
|
||||
row);
|
||||
g_free (id);
|
||||
|
||||
eek_element_get_bounds (element, &bounds);
|
||||
g_string_append_indent (data->output, data->indent + 1);
|
||||
output_bounds (data->output, &bounds);
|
||||
|
||||
oref = eek_key_get_oref (EEK_KEY(element));
|
||||
if (oref != 0) {
|
||||
g_string_append_indent (data->output, data->indent + 1);
|
||||
g_string_markup_printf (data->output,
|
||||
"<oref>outline%u</oref>\n",
|
||||
oref);
|
||||
if (!g_hash_table_lookup (data->oref_hash, (gpointer)oref))
|
||||
g_hash_table_insert (data->oref_hash,
|
||||
(gpointer)oref,
|
||||
(gpointer)TRUE);
|
||||
}
|
||||
|
||||
matrix = eek_key_get_symbol_matrix (EEK_KEY(element));
|
||||
num_symbols = matrix->num_groups * matrix->num_levels;
|
||||
if (num_symbols > 0) {
|
||||
g_string_append_indent (data->output, data->indent + 1);
|
||||
g_string_markup_printf (data->output,
|
||||
"<symbols groups=\"%d\" levels=\"%d\">\n",
|
||||
matrix->num_groups, matrix->num_levels);
|
||||
|
||||
for (i = 0; i < num_symbols; i++) {
|
||||
EekSymbol *symbol = matrix->data[i];
|
||||
|
||||
g_string_append_indent (data->output, data->indent + 2);
|
||||
if (EEK_IS_KEYSYM(symbol)) {
|
||||
guint xkeysym = eek_keysym_get_xkeysym (EEK_KEYSYM(symbol));
|
||||
|
||||
g_string_markup_printf (data->output, "<keysym");
|
||||
output_symbol_attributes (data->output, symbol);
|
||||
if (xkeysym != EEK_INVALID_KEYSYM)
|
||||
g_string_markup_printf (data->output, " keyval=\"%u\"",
|
||||
xkeysym);
|
||||
g_string_markup_printf (data->output, ">%s</keysym>\n",
|
||||
eek_symbol_get_name (symbol));
|
||||
}
|
||||
else if (EEK_IS_TEXT(symbol)) {
|
||||
g_string_markup_printf (data->output, "<text");
|
||||
output_symbol_attributes (data->output, symbol);
|
||||
g_string_markup_printf (data->output,
|
||||
">%s</text>\n",
|
||||
eek_text_get_text (EEK_TEXT(symbol)));
|
||||
}
|
||||
else {
|
||||
g_string_markup_printf (data->output, "<symbol");
|
||||
output_symbol_attributes (data->output, symbol);
|
||||
g_string_markup_printf (data->output,
|
||||
">%s</symbol>\n",
|
||||
eek_symbol_get_name (symbol));
|
||||
}
|
||||
}
|
||||
g_string_append_indent (data->output, data->indent + 1);
|
||||
g_string_markup_printf (data->output, "</symbols>\n");
|
||||
}
|
||||
|
||||
g_string_append_indent (data->output, data->indent);
|
||||
g_string_markup_printf (data->output, "</key>\n");
|
||||
}
|
||||
|
||||
static void
|
||||
output_section_callback (EekElement *element, gpointer user_data)
|
||||
{
|
||||
OutputCallbackData *data = user_data;
|
||||
EekBounds bounds;
|
||||
gint angle, n_rows, i;
|
||||
|
||||
g_string_append_indent (data->output, data->indent);
|
||||
if (eek_element_get_name (element))
|
||||
g_string_markup_printf (data->output, "<section name=\"%s\">\n",
|
||||
eek_element_get_name (element));
|
||||
else
|
||||
g_string_markup_printf (data->output, "<section>\n");
|
||||
|
||||
eek_element_get_bounds (element, &bounds);
|
||||
g_string_append_indent (data->output, data->indent + 1);
|
||||
output_bounds (data->output, &bounds);
|
||||
|
||||
angle = eek_section_get_angle (EEK_SECTION(element));
|
||||
g_string_append_indent (data->output, data->indent + 1);
|
||||
g_string_markup_printf (data->output, "<angle>%d</angle>\n", angle);
|
||||
|
||||
n_rows = eek_section_get_n_rows (EEK_SECTION(element));
|
||||
for (i = 0; i < n_rows; i++) {
|
||||
gint num_columns;
|
||||
EekOrientation orientation;
|
||||
|
||||
eek_section_get_row (EEK_SECTION(element),
|
||||
i,
|
||||
&num_columns,
|
||||
&orientation);
|
||||
g_string_append_indent (data->output, data->indent + 1);
|
||||
g_string_markup_printf (data->output, "<row>\n");
|
||||
g_string_append_indent (data->output, data->indent + 2);
|
||||
g_string_markup_printf (data->output, "<columns>%d</columns>\n",
|
||||
num_columns);
|
||||
g_string_append_indent (data->output, data->indent + 2);
|
||||
g_string_markup_printf (data->output, "<orientation>%d</orientation>\n",
|
||||
orientation);
|
||||
g_string_append_indent (data->output, data->indent + 1);
|
||||
g_string_markup_printf (data->output, "</row>\n");
|
||||
}
|
||||
|
||||
data->indent++;
|
||||
eek_container_foreach_child (EEK_CONTAINER(element),
|
||||
output_key_callback,
|
||||
data);
|
||||
data->indent--;
|
||||
|
||||
g_string_append_indent (data->output, data->indent);
|
||||
g_string_markup_printf (data->output, "</section>\n");
|
||||
}
|
||||
|
||||
/**
|
||||
* eek_keyboard_output:
|
||||
* @keyboard: an #EekKeyboard
|
||||
* @output: a GString
|
||||
* @indent: an integer
|
||||
*
|
||||
* Convert @keyboard into the XML format and store it into @output.
|
||||
*/
|
||||
void
|
||||
eek_keyboard_output (EekKeyboard *keyboard, GString *output, gint indent)
|
||||
{
|
||||
OutputCallbackData data;
|
||||
EekBounds bounds;
|
||||
gulong oref;
|
||||
GHashTableIter iter;
|
||||
|
||||
g_assert (EEK_IS_KEYBOARD(keyboard));
|
||||
|
||||
g_string_append_indent (output, indent);
|
||||
if (eek_element_get_name (EEK_ELEMENT(keyboard)))
|
||||
g_string_markup_printf (output, "<?xml version=\"1.0\"?>\n"
|
||||
"<keyboard version=\"%s\" id=\"%s\">\n",
|
||||
EEK_XML_SCHEMA_VERSION,
|
||||
eek_element_get_name (EEK_ELEMENT(keyboard)));
|
||||
else
|
||||
g_string_markup_printf (output, "<?xml version=\"1.0\"?>\n"
|
||||
"<keyboard version=\"%s\">\n",
|
||||
EEK_XML_SCHEMA_VERSION);
|
||||
|
||||
eek_element_get_bounds (EEK_ELEMENT(keyboard), &bounds);
|
||||
g_string_append_indent (output, indent + 1);
|
||||
output_bounds (output, &bounds);
|
||||
|
||||
data.output = output;
|
||||
data.indent = indent;
|
||||
data.oref_hash = g_hash_table_new (g_direct_hash, g_direct_equal);
|
||||
data.key_serial = 0;
|
||||
|
||||
data.indent++;
|
||||
eek_container_foreach_child (EEK_CONTAINER(keyboard),
|
||||
output_section_callback,
|
||||
&data);
|
||||
data.indent--;
|
||||
|
||||
g_hash_table_iter_init (&iter, data.oref_hash);
|
||||
while (g_hash_table_iter_next (&iter, (gpointer *)&oref, NULL)) {
|
||||
EekOutline *outline;
|
||||
gint j;
|
||||
|
||||
outline = eek_keyboard_get_outline (keyboard, oref);
|
||||
g_string_append_indent (output, indent + 1);
|
||||
g_string_markup_printf (output, "<outline id=\"outline%u\">\n", oref);
|
||||
g_string_append_indent (output, indent + 2);
|
||||
g_string_markup_printf (output, "<corner-radius>%lf</corner-radius>\n",
|
||||
outline->corner_radius);
|
||||
for (j = 0; j < outline->num_points; j++) {
|
||||
g_string_append_indent (output, indent + 2);
|
||||
g_string_markup_printf (output, "<point>%lf,%lf</point>\n",
|
||||
outline->points[j].x,
|
||||
outline->points[j].y);
|
||||
}
|
||||
|
||||
g_string_append_indent (output, indent + 1);
|
||||
g_string_markup_printf (output, "</outline>\n");
|
||||
}
|
||||
g_hash_table_destroy (data.oref_hash);
|
||||
|
||||
g_string_append_indent (output, indent);
|
||||
g_string_markup_printf (output, "</keyboard>\n");
|
||||
}
|
||||
@ -1,39 +0,0 @@
|
||||
/*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#if !defined(__EEK_H_INSIDE__) && !defined(EEK_COMPILATION)
|
||||
#error "Only <eek/eek.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#ifndef EEK_XML_H
|
||||
#define EEK_XML_H 1
|
||||
|
||||
#include <glib-object.h>
|
||||
#include "eek-keyboard.h"
|
||||
#include "eek-xml-layout.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define EEK_XML_SCHEMA_VERSION "0.90"
|
||||
|
||||
void eek_keyboard_output (EekKeyboard *keyboard,
|
||||
GString *output,
|
||||
gint indent);
|
||||
|
||||
G_END_DECLS
|
||||
#endif /* EEK_XML_H */
|
||||
@ -29,9 +29,7 @@
|
||||
#include "eek-symbol.h"
|
||||
#include "eek-keysym.h"
|
||||
#include "eek-text.h"
|
||||
#include "eek-xml.h"
|
||||
#include "eek-serializable.h"
|
||||
#include "eek-theme.h"
|
||||
|
||||
void eek_init (void);
|
||||
|
||||
|
||||
@ -33,7 +33,7 @@ else:
|
||||
|
||||
table = dict()
|
||||
for line in in_stream:
|
||||
match = re.match(r'\s*(0x[0-9A-F]+)\s+(\S*)\s+(\S*)', line, re.I)
|
||||
match = re.match(r'\s*(0x[0-9A-F]+)\s+"(.*)"\s+(\S*)', line, re.I)
|
||||
if match:
|
||||
table[int(match.group(1), 16)] = (match.group(2), match.group(3))
|
||||
|
||||
@ -42,8 +42,8 @@ sys.stdout.write("static const EekKeysymEntry %s[] = {\n" %
|
||||
|
||||
for index, (keysym, (l, c)) in enumerate([(keysym, table[keysym])
|
||||
for keysym in sorted(table.keys())]):
|
||||
sys.stdout.write(" { 0x%X, %s, %s }" %
|
||||
(keysym, l, c))
|
||||
sys.stdout.write(" { 0x%X, \"%s\" }" %
|
||||
(keysym, l))
|
||||
if index < len(table) - 1:
|
||||
sys.stdout.write(",")
|
||||
sys.stdout.write("\n")
|
||||
|
||||
39
eek/keymap.h
Normal file
39
eek/keymap.h
Normal file
@ -0,0 +1,39 @@
|
||||
#include <gdk/gdk.h>
|
||||
#include <xkbcommon/xkbcommon.h>
|
||||
|
||||
gboolean
|
||||
squeek_keymap_get_entries_for_keyval (struct xkb_keymap *xkb_keymap,
|
||||
guint keyval,
|
||||
GdkKeymapKey **keys,
|
||||
guint *n_keys);
|
||||
|
||||
static const char *keymap_header = "xkb_keymap {\n\
|
||||
\n";
|
||||
|
||||
static const char *keymap_keycodes_header = "\
|
||||
xkb_keycodes \"squeekboard\" {\n\n\
|
||||
minimum = 8;\n\
|
||||
maximum = 255;\n\
|
||||
\n";
|
||||
|
||||
static const char *keymap_symbols_header = "\
|
||||
xkb_symbols \"squeekboard\" {\n\
|
||||
\n\
|
||||
name[Group1] = \"Letters\";\n\
|
||||
name[Group2] = \"Numbers/Symbols\";\n\
|
||||
\n";
|
||||
|
||||
static const char *keymap_footer = "\
|
||||
xkb_types \"squeekboard\" {\n\
|
||||
\n\
|
||||
type \"TWO_LEVEL\" {\n\
|
||||
modifiers = Shift;\n\
|
||||
map[Shift] = Level2;\n\
|
||||
level_name[Level1] = \"Base\";\n\
|
||||
level_name[Level2] = \"Shift\";\n\
|
||||
};\n\
|
||||
};\n\
|
||||
\n\
|
||||
xkb_compatibility \"squeekboard\" {\n\
|
||||
};\n\
|
||||
};";
|
||||
@ -27,9 +27,6 @@
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "eekboard/eekboard-context-service.h"
|
||||
#include "keymap.h"
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
@ -37,10 +34,14 @@
|
||||
#include <sys/random.h> // TODO: this is Linux-specific
|
||||
#include <xkbcommon/xkbcommon.h>
|
||||
|
||||
#include <gio/gio.h>
|
||||
|
||||
#include "eekboard/key-emitter.h"
|
||||
#include "wayland.h"
|
||||
//#include "eekboard/eekboard-xklutil.h"
|
||||
//#include "eek/eek-xkl.h"
|
||||
|
||||
#include "eek/eek-xml-layout.h"
|
||||
|
||||
#include "eekboard/eekboard-context-service.h"
|
||||
|
||||
#define CSW 640
|
||||
#define CSH 480
|
||||
@ -85,55 +86,6 @@ struct _EekboardContextServicePrivate {
|
||||
|
||||
G_DEFINE_TYPE_WITH_PRIVATE (EekboardContextService, eekboard_context_service, G_TYPE_OBJECT);
|
||||
|
||||
/*static Display *display = NULL; */
|
||||
gchar *
|
||||
get_keymap_from_resource(const gchar *keyboard_type, gboolean fallback)
|
||||
{
|
||||
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 *
|
||||
eekboard_context_service_real_create_keyboard (EekboardContextService *self,
|
||||
const gchar *keyboard_type)
|
||||
@ -193,13 +145,8 @@ eekboard_context_service_real_create_keyboard (EekboardContextService *self,
|
||||
if (!context) {
|
||||
g_error("No context created");
|
||||
}
|
||||
/*
|
||||
struct xkb_rule_names rules = { 0 };
|
||||
rules.layout = strdup(keyboard_type);
|
||||
*/
|
||||
char *keymap_str = get_keymap_from_resource(keyboard_type, FALSE);
|
||||
if (!keymap_str)
|
||||
keymap_str = get_keymap_from_resource("us", TRUE);
|
||||
|
||||
gchar *keymap_str = eek_keyboard_get_keymap(keyboard);
|
||||
|
||||
struct xkb_keymap *keymap = xkb_keymap_new_from_string(context, keymap_str,
|
||||
XKB_KEYMAP_FORMAT_TEXT_V1, XKB_KEYMAP_COMPILE_NO_FLAGS);
|
||||
@ -357,8 +304,24 @@ settings_update_layout(EekboardContextService *context)
|
||||
|
||||
EekboardContextServicePrivate *priv = EEKBOARD_CONTEXT_SERVICE_GET_PRIVATE(context);
|
||||
|
||||
if (priv->purpose == ZWP_TEXT_INPUT_V3_CONTENT_PURPOSE_PHONE)
|
||||
keyboard_layout = g_strdup("numbers");
|
||||
switch (priv->purpose) {
|
||||
case ZWP_TEXT_INPUT_V3_CONTENT_PURPOSE_DIGITS:
|
||||
case ZWP_TEXT_INPUT_V3_CONTENT_PURPOSE_PIN:
|
||||
keyboard_layout = g_strdup("digits");
|
||||
break;
|
||||
case ZWP_TEXT_INPUT_V3_CONTENT_PURPOSE_NUMBER:
|
||||
keyboard_layout = g_strdup("number");
|
||||
break;
|
||||
case ZWP_TEXT_INPUT_V3_CONTENT_PURPOSE_PHONE:
|
||||
keyboard_layout = g_strdup("phone");
|
||||
break;
|
||||
case ZWP_TEXT_INPUT_V3_CONTENT_PURPOSE_URL:
|
||||
keyboard_layout = g_strdup("url");
|
||||
break;
|
||||
case ZWP_TEXT_INPUT_V3_CONTENT_PURPOSE_NORMAL:
|
||||
default:
|
||||
;
|
||||
}
|
||||
|
||||
// generic part follows
|
||||
static guint keyboard_id = 0;
|
||||
|
||||
@ -35,7 +35,6 @@ enum {
|
||||
ENABLED,
|
||||
DISABLED,
|
||||
DESTROYED,
|
||||
KEY_ACTIVATED,
|
||||
LAST_SIGNAL
|
||||
};
|
||||
|
||||
@ -81,28 +80,6 @@ eekboard_context_real_g_signal (GDBusProxy *self,
|
||||
return;
|
||||
}
|
||||
|
||||
if (g_strcmp0 (signal_name, "KeyActivated") == 0) {
|
||||
guint keycode;
|
||||
GVariant *variant = NULL;
|
||||
guint modifiers = 0;
|
||||
EekSerializable *serializable;
|
||||
|
||||
g_variant_get (parameters, "(uvu)",
|
||||
&keycode, &variant, &modifiers);
|
||||
g_return_if_fail (variant != NULL);
|
||||
|
||||
serializable = eek_serializable_deserialize (variant);
|
||||
g_variant_unref (variant);
|
||||
|
||||
g_return_if_fail (EEK_IS_SYMBOL(serializable));
|
||||
|
||||
g_signal_emit (context, signals[KEY_ACTIVATED], 0,
|
||||
keycode, EEK_SYMBOL(serializable), modifiers);
|
||||
g_object_unref (serializable);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (g_strcmp0 (signal_name, "VisibilityChanged") == 0) {
|
||||
gboolean visible = FALSE;
|
||||
|
||||
@ -149,14 +126,6 @@ eekboard_context_real_destroyed (EekboardContext *self)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
eekboard_context_real_key_activated (EekboardContext *self,
|
||||
guint keycode,
|
||||
EekSymbol *symbol,
|
||||
guint modifiers)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
eekboard_context_get_property (GObject *object,
|
||||
guint prop_id,
|
||||
@ -186,7 +155,6 @@ eekboard_context_class_init (EekboardContextClass *klass)
|
||||
klass->enabled = eekboard_context_real_enabled;
|
||||
klass->disabled = eekboard_context_real_disabled;
|
||||
klass->destroyed = eekboard_context_real_destroyed;
|
||||
klass->key_activated = eekboard_context_real_key_activated;
|
||||
|
||||
proxy_class->g_signal = eekboard_context_real_g_signal;
|
||||
|
||||
@ -240,31 +208,6 @@ eekboard_context_class_init (EekboardContextClass *klass)
|
||||
G_TYPE_NONE,
|
||||
0);
|
||||
|
||||
/**
|
||||
* EekboardContext::key-activated:
|
||||
* @context: an #EekboardContext
|
||||
* @keycode: a keycode
|
||||
* @symbol: an #EekSymbol
|
||||
* @modifiers: modifiers
|
||||
*
|
||||
* The ::key-activated signal is emitted each time a key is
|
||||
* pressed in @context.
|
||||
*/
|
||||
/*
|
||||
signals[KEY_ACTIVATED] =
|
||||
g_signal_new (I_("key-activated"),
|
||||
G_TYPE_FROM_CLASS(gobject_class),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET(EekboardContextClass, key_activated),
|
||||
NULL,
|
||||
NULL,
|
||||
_eekboard_marshal_VOID__UINT_OBJECT_UINT,
|
||||
G_TYPE_NONE,
|
||||
3,
|
||||
G_TYPE_UINT,
|
||||
G_TYPE_OBJECT,
|
||||
G_TYPE_UINT);
|
||||
*/
|
||||
/**
|
||||
* EekboardContext::destroyed:
|
||||
* @context: an #EekboardContext
|
||||
|
||||
@ -47,11 +47,6 @@ struct _EekboardContextClass {
|
||||
void (*disabled) (EekboardContext *self);
|
||||
void (*destroyed) (EekboardContext *self);
|
||||
|
||||
void (*key_activated) (EekboardContext *self,
|
||||
guint keycode,
|
||||
EekSymbol *symbol,
|
||||
guint modifiers);
|
||||
|
||||
/*< private >*/
|
||||
/* padding */
|
||||
gpointer pdummy[24];
|
||||
|
||||
@ -28,12 +28,14 @@
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "eekboard/eekboard-service.h"
|
||||
|
||||
#include "sm.puri.OSK0.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <gio/gio.h>
|
||||
|
||||
#include "eekboard/eekboard-service.h"
|
||||
|
||||
enum {
|
||||
PROP_0,
|
||||
PROP_OBJECT_PATH,
|
||||
|
||||
@ -20,7 +20,6 @@
|
||||
/* This file is responsible for managing keycode data and emitting keycodes. */
|
||||
|
||||
#include "eekboard/key-emitter.h"
|
||||
#include "eekboard/keymap.h"
|
||||
|
||||
#include <gdk/gdk.h>
|
||||
|
||||
@ -39,98 +38,6 @@ typedef struct {
|
||||
} SeatEmitter;
|
||||
|
||||
|
||||
/* The following functions for keyboard mapping change are direct
|
||||
translation of the code in Caribou (in libcaribou/xadapter.vala):
|
||||
|
||||
- get_replaced_keycode (Caribou: get_reserved_keycode)
|
||||
- replace_keycode
|
||||
- get_keycode_from_gdk_keymap (Caribou: best_keycode_keyval_match)
|
||||
*/
|
||||
|
||||
/* Find an unused keycode where a keysym can be assigned. Restricted to Level 1 */
|
||||
static guint
|
||||
get_replaced_keycode (SeatEmitter *client)
|
||||
{
|
||||
guint keycode;
|
||||
return 0; // FIXME: no xkb allocated yet
|
||||
for (keycode = client->xkb->max_key_code;
|
||||
keycode >= client->xkb->min_key_code;
|
||||
--keycode) {
|
||||
guint offset = client->xkb->map->key_sym_map[keycode].offset;
|
||||
if (client->xkb->map->key_sym_map[keycode].kt_index[0] == XkbOneLevelIndex &&
|
||||
client->xkb->map->syms[offset] != NoSymbol) {
|
||||
return keycode;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Replace keysym assigned to KEYCODE to KEYSYM. Both args are used
|
||||
as in-out. If KEYCODE points to 0, this function picks a keycode
|
||||
from the current map and replace the associated keysym to KEYSYM.
|
||||
In that case, the replaced keycode is stored in KEYCODE and the old
|
||||
keysym is stored in KEYSYM. If otherwise (KEYCODE points to
|
||||
non-zero keycode), it simply changes the current map with the
|
||||
specified KEYCODE and KEYSYM. */
|
||||
static gboolean
|
||||
replace_keycode (SeatEmitter *emitter,
|
||||
guint keycode,
|
||||
guint *keysym)
|
||||
{
|
||||
/* GdkDisplay *display = gdk_display_get_default ();
|
||||
Display *xdisplay = GDK_DISPLAY_XDISPLAY (display);
|
||||
guint old_keysym;
|
||||
int keysyms_per_keycode;
|
||||
KeySym *syms;
|
||||
*/
|
||||
return TRUE; // FIXME: no xkb allocated at the moment, pretending all is fine
|
||||
g_return_val_if_fail (emitter->xkb->min_key_code <= keycode &&
|
||||
keycode <= emitter->xkb->max_key_code,
|
||||
FALSE);
|
||||
g_return_val_if_fail (keysym != NULL, FALSE);
|
||||
/*
|
||||
* Update keyboard mapping. Wayland receives keyboard mapping as a string, so XChangeKeyboardMapping needs to translate from the symbol tbale t the string. TODO.
|
||||
*
|
||||
syms = XGetKeyboardMapping (xdisplay, keycode, 1, &keysyms_per_keycode);
|
||||
old_keysym = syms[0];
|
||||
syms[0] = *keysym;
|
||||
XChangeKeyboardMapping (xdisplay, keycode, 1, syms, 1);
|
||||
XSync (xdisplay, False);
|
||||
XFree (syms);
|
||||
*keysym = old_keysym;
|
||||
*/
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
get_keycode_from_gdk_keymap (SeatEmitter *emitter,
|
||||
guint keysym,
|
||||
guint *keycode,
|
||||
guint *modifiers)
|
||||
{
|
||||
GdkKeymapKey *keys, *best_match = NULL;
|
||||
guint n_keys, i;
|
||||
|
||||
if (!squeek_keymap_get_entries_for_keyval (emitter->keymap, keysym, &keys, &n_keys))
|
||||
return FALSE;
|
||||
|
||||
for (i = 0; i < n_keys; i++)
|
||||
if ((guint)keys[i].group == emitter->group)
|
||||
best_match = &keys[i];
|
||||
|
||||
if (!best_match) {
|
||||
g_free (keys);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
*keycode = best_match->keycode;
|
||||
*modifiers = best_match->level == 1 ? EEK_SHIFT_MASK : 0;
|
||||
|
||||
g_free (keys);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
int send_virtual_keyboard_key(
|
||||
struct zwp_virtual_keyboard_v1 *keyboard,
|
||||
unsigned int keycode,
|
||||
@ -141,115 +48,6 @@ int send_virtual_keyboard_key(
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
send_fake_modifiers_events (SeatEmitter *emitter,
|
||||
EekModifierType modifiers,
|
||||
uint32_t timestamp)
|
||||
{
|
||||
(void)timestamp;
|
||||
|
||||
uint32_t proto_modifiers = 0;
|
||||
if (modifiers & EEK_SHIFT_MASK) {
|
||||
proto_modifiers |= 1<<MOD_IDX_SHIFT;
|
||||
}
|
||||
if (modifiers & EEK_CONTROL_MASK) {
|
||||
proto_modifiers |= 1<<MOD_IDX_CTRL;
|
||||
}
|
||||
if (modifiers & EEK_MOD1_MASK) {
|
||||
proto_modifiers |= 1<<MOD_IDX_ALT;
|
||||
}
|
||||
zwp_virtual_keyboard_v1_modifiers(emitter->virtual_keyboard, proto_modifiers, 0, 0, emitter->group);
|
||||
}
|
||||
|
||||
static void
|
||||
send_fake_key_event (SeatEmitter *emitter,
|
||||
guint xkeysym,
|
||||
guint keyboard_modifiers,
|
||||
gboolean pressed,
|
||||
uint32_t timestamp)
|
||||
{
|
||||
EekModifierType modifiers;
|
||||
guint old_keysym = xkeysym;
|
||||
|
||||
g_return_if_fail (xkeysym > 0);
|
||||
|
||||
guint keycode;
|
||||
if (!get_keycode_from_gdk_keymap (emitter, xkeysym, &keycode, &modifiers)) {
|
||||
keycode = get_replaced_keycode (emitter);
|
||||
if (keycode == 0) {
|
||||
g_warning ("no available keycode to replace");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!replace_keycode (emitter, keycode, &old_keysym)) {
|
||||
g_warning ("failed to lookup X keysym %X", xkeysym);
|
||||
return;
|
||||
}
|
||||
}
|
||||
/* Clear level shift modifiers */
|
||||
keyboard_modifiers &= (unsigned)~EEK_SHIFT_MASK;
|
||||
keyboard_modifiers &= (unsigned)~EEK_LOCK_MASK;
|
||||
/* FIXME: may need to remap ISO_Level3_Shift and NumLock */
|
||||
|
||||
modifiers |= keyboard_modifiers;
|
||||
|
||||
send_fake_modifiers_events (emitter, modifiers, timestamp);
|
||||
|
||||
// There's something magical about subtracting/adding 8 to keycodes for some reason
|
||||
send_virtual_keyboard_key (emitter->virtual_keyboard, keycode - 8, (unsigned)pressed, timestamp);
|
||||
send_fake_modifiers_events (emitter, modifiers, timestamp);
|
||||
|
||||
if (old_keysym != xkeysym)
|
||||
replace_keycode (emitter, keycode, &old_keysym);
|
||||
}
|
||||
|
||||
static void
|
||||
send_fake_key_events (SeatEmitter *emitter,
|
||||
EekSymbol *symbol,
|
||||
EekModifierType keyboard_modifiers,
|
||||
gboolean pressed,
|
||||
uint32_t timestamp)
|
||||
{
|
||||
/* Ignore modifier keys */
|
||||
if (eek_symbol_is_modifier (symbol))
|
||||
return;
|
||||
|
||||
/* If symbol is a text, convert chars in it to keysym */
|
||||
if (EEK_IS_TEXT(symbol)) {
|
||||
const gchar *utf8 = eek_text_get_text (EEK_TEXT(symbol));
|
||||
printf("Attempting to send text %s\n", utf8);
|
||||
/* FIXME:
|
||||
glong items_written;
|
||||
gunichar *ucs4 = g_utf8_to_ucs4_fast (utf8, -1, &items_written);
|
||||
gint i;
|
||||
|
||||
for (i = 0; i < items_written; i++) {
|
||||
guint xkeysym;
|
||||
EekKeysym *keysym;
|
||||
gchar *name;
|
||||
|
||||
name = g_strdup_printf ("U%04X", ucs4[i]);
|
||||
xkeysym = XStringToKeysym (name); // TODO: use xkb_get_keysym_from_name
|
||||
g_free (name);
|
||||
|
||||
keysym = eek_keysym_new (xkeysym);
|
||||
send_fake_key_events (client,
|
||||
EEK_SYMBOL(keysym),
|
||||
keyboard_modifiers);
|
||||
}
|
||||
g_free (ucs4);
|
||||
*/
|
||||
return;
|
||||
}
|
||||
|
||||
if (EEK_IS_KEYSYM(symbol)) {
|
||||
guint xkeysym = eek_keysym_get_xkeysym (EEK_KEYSYM(symbol));
|
||||
send_fake_key_event (emitter, xkeysym, keyboard_modifiers, pressed, timestamp);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Finds the first key code for each modifier and saves it in modifier_keycodes */
|
||||
static void
|
||||
update_modifier_info (SeatEmitter *client)
|
||||
@ -286,14 +84,13 @@ update_modifier_info (SeatEmitter *client)
|
||||
|
||||
static void
|
||||
send_fake_key (SeatEmitter *emitter,
|
||||
EekKeyboard *keyboard,
|
||||
guint level,
|
||||
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)
|
||||
@ -304,6 +101,38 @@ send_fake_key (SeatEmitter *emitter,
|
||||
zwp_virtual_keyboard_v1_modifiers(emitter->virtual_keyboard, proto_modifiers, 0, 0, group);
|
||||
}
|
||||
|
||||
static void
|
||||
send_fake_text (SeatEmitter *emitter,
|
||||
EekKeyboard *keyboard,
|
||||
const gchar *text,
|
||||
uint32_t timestamp)
|
||||
{
|
||||
gchar *ptr = (gchar *)text;
|
||||
|
||||
while (*ptr) {
|
||||
gchar buf[7];
|
||||
gunichar c = g_utf8_get_char(ptr);
|
||||
int n = g_unichar_to_utf8(c, buf);
|
||||
*(buf + n) = 0;
|
||||
|
||||
EekKeyPress *key_press = eek_keyboard_get_key_press(keyboard, buf);
|
||||
|
||||
if (key_press) {
|
||||
EekKey *key = key_press->key;
|
||||
|
||||
send_fake_key (emitter, key_press->level, eek_key_get_keycode(key),
|
||||
(key_press->level % 2) == 1 ? EEK_SHIFT_MASK : 0,
|
||||
1, timestamp);
|
||||
|
||||
send_fake_key (emitter, key_press->level, eek_key_get_keycode(key),
|
||||
(key_press->level % 2) == 1 ? EEK_SHIFT_MASK : 0,
|
||||
0, timestamp);
|
||||
}
|
||||
|
||||
ptr = g_utf8_find_next_char(ptr, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
emit_key_activated (EekboardContextService *manager,
|
||||
EekKeyboard *keyboard,
|
||||
@ -344,5 +173,12 @@ emit_key_activated (EekboardContextService *manager,
|
||||
emitter.virtual_keyboard = manager->virtual_keyboard;
|
||||
emitter.keymap = keyboard->keymap;
|
||||
update_modifier_info (&emitter);
|
||||
send_fake_key (&emitter, keyboard, keycode, modifiers, pressed, timestamp);
|
||||
|
||||
const gchar *text = (gchar *)eek_text_get_text(symbol);
|
||||
if (text && pressed) {
|
||||
send_fake_text (&emitter, keyboard, text, timestamp);
|
||||
} else {
|
||||
guint level = eek_element_get_level(EEK_ELEMENT(keyboard));
|
||||
send_fake_key (&emitter, level, keycode, modifiers, pressed, timestamp);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,66 +0,0 @@
|
||||
/* GDK - The GIMP Drawing Kit
|
||||
* Copyright (C) 2000 Red Hat, Inc.
|
||||
* Copyright (C) 2019 Purism, SPC
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
/*
|
||||
* Modified for squeekboard based on GTK
|
||||
*/
|
||||
|
||||
#include "keymap.h"
|
||||
|
||||
gboolean
|
||||
squeek_keymap_get_entries_for_keyval (struct xkb_keymap *xkb_keymap,
|
||||
guint keyval,
|
||||
GdkKeymapKey **keys,
|
||||
guint *n_keys)
|
||||
{
|
||||
GArray *retval;
|
||||
guint keycode;
|
||||
xkb_keycode_t min_keycode, max_keycode;
|
||||
retval = g_array_new (FALSE, FALSE, sizeof (GdkKeymapKey));
|
||||
min_keycode = xkb_keymap_min_keycode (xkb_keymap);
|
||||
max_keycode = xkb_keymap_max_keycode (xkb_keymap);
|
||||
for (keycode = min_keycode; keycode < max_keycode; keycode++)
|
||||
{
|
||||
xkb_layout_index_t num_layouts, layout;
|
||||
num_layouts = xkb_keymap_num_layouts_for_key (xkb_keymap, keycode);
|
||||
for (layout = 0; layout < num_layouts; layout++)
|
||||
{
|
||||
xkb_layout_index_t num_levels, level;
|
||||
num_levels = xkb_keymap_num_levels_for_key (xkb_keymap, keycode, layout);
|
||||
for (level = 0; level < num_levels; level++)
|
||||
{
|
||||
const xkb_keysym_t *syms;
|
||||
gint num_syms, sym;
|
||||
num_syms = xkb_keymap_key_get_syms_by_level (xkb_keymap, keycode, layout, level, &syms);
|
||||
for (sym = 0; sym < num_syms; sym++)
|
||||
{
|
||||
if (syms[sym] == keyval)
|
||||
{
|
||||
GdkKeymapKey key;
|
||||
key.keycode = keycode;
|
||||
key.group = (gint)layout;
|
||||
key.level = (gint)level;
|
||||
g_array_append_val (retval, key);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
*n_keys = retval->len;
|
||||
*keys = (GdkKeymapKey*) g_array_free (retval, FALSE);
|
||||
return TRUE;
|
||||
}
|
||||
@ -1,8 +0,0 @@
|
||||
#include <gdk/gdk.h>
|
||||
#include <xkbcommon/xkbcommon.h>
|
||||
|
||||
gboolean
|
||||
squeek_keymap_get_entries_for_keyval (struct xkb_keymap *xkb_keymap,
|
||||
guint keyval,
|
||||
GdkKeymapKey **keys,
|
||||
guint *n_keys);
|
||||
10
meson.build
10
meson.build
@ -11,6 +11,16 @@ project(
|
||||
]
|
||||
)
|
||||
|
||||
add_project_arguments(
|
||||
[
|
||||
'-Werror=implicit-function-declaration',
|
||||
'-Werror=implicit-fallthrough=3',
|
||||
'-Werror=maybe-uninitialized',
|
||||
'-Werror=missing-field-initializers',
|
||||
],
|
||||
language: 'c'
|
||||
)
|
||||
|
||||
i18n = import('i18n')
|
||||
|
||||
conf_data = configuration_data()
|
||||
|
||||
1350
src/bitflags.rs
Normal file
1350
src/bitflags.rs
Normal file
File diff suppressed because it is too large
Load Diff
@ -5,19 +5,6 @@
|
||||
#include "eekboard/eekboard-context-service.h"
|
||||
|
||||
|
||||
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)
|
||||
{
|
||||
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) {}
|
||||
|
||||
|
||||
static const struct zwp_input_method_v2_listener input_method_listener = {
|
||||
.activate = imservice_handle_input_method_activate,
|
||||
.deactivate = imservice_handle_input_method_deactivate,
|
||||
@ -41,14 +28,16 @@ struct imservice* get_imservice(EekboardContextService *context,
|
||||
return imservice;
|
||||
}
|
||||
|
||||
void imservice_make_visible(EekboardContextService *context,
|
||||
struct zwp_input_method_v2 *im) {
|
||||
(void)im;
|
||||
void imservice_make_visible(EekboardContextService *context) {
|
||||
eekboard_context_service_show_keyboard (context);
|
||||
}
|
||||
|
||||
void imservice_try_hide(EekboardContextService *context,
|
||||
struct zwp_input_method_v2 *im) {
|
||||
(void)im;
|
||||
void imservice_try_hide(EekboardContextService *context) {
|
||||
eekboard_context_service_hide_keyboard (context);
|
||||
}
|
||||
|
||||
/// Declared explicitly because _destroy is inline,
|
||||
/// making it unavailable in Rust
|
||||
void imservice_destroy_im(struct zwp_input_method_v2 *im) {
|
||||
zwp_input_method_v2_destroy(im);
|
||||
}
|
||||
|
||||
@ -4,11 +4,7 @@
|
||||
#include "input-method-unstable-v2-client-protocol.h"
|
||||
#include "eek/eek-types.h"
|
||||
|
||||
struct imservice
|
||||
{
|
||||
struct zwp_input_method_v2 *im;
|
||||
EekboardContextService *ui_manager;
|
||||
};
|
||||
struct imservice;
|
||||
|
||||
struct imservice* get_imservice(EekboardContextService *context,
|
||||
struct zwp_input_method_manager_v2 *manager,
|
||||
@ -22,5 +18,8 @@ void imservice_handle_input_method_deactivate(void *data, struct zwp_input_metho
|
||||
void imservice_handle_surrounding_text(void *data, struct zwp_input_method_v2 *input_method,
|
||||
const char *text, uint32_t cursor, uint32_t anchor);
|
||||
void imservice_handle_commit_state(void *data, struct zwp_input_method_v2 *input_method);
|
||||
void imservice_handle_content_type(void *data, struct zwp_input_method_v2 *input_method, uint32_t hint, uint32_t purpose);
|
||||
void imservice_handle_text_change_cause(void *data, struct zwp_input_method_v2 *input_method, uint32_t cause);
|
||||
void imservice_handle_unavailable(void *data, struct zwp_input_method_v2 *input_method);
|
||||
|
||||
#endif
|
||||
|
||||
228
src/imservice.rs
228
src/imservice.rs
@ -3,6 +3,11 @@ use std::ffi::CString;
|
||||
use std::num::Wrapping;
|
||||
use std::string::String;
|
||||
|
||||
use super::bitflags;
|
||||
|
||||
// Traits
|
||||
use std::convert::TryFrom;
|
||||
|
||||
|
||||
/// Gathers stuff defined in C or called by C
|
||||
pub mod c {
|
||||
@ -18,7 +23,7 @@ pub mod c {
|
||||
}
|
||||
|
||||
// The following defined in C
|
||||
|
||||
|
||||
/// struct zwp_input_method_v2*
|
||||
#[repr(transparent)]
|
||||
pub struct InputMethod(*const c_void);
|
||||
@ -29,8 +34,10 @@ pub mod c {
|
||||
|
||||
#[no_mangle]
|
||||
extern "C" {
|
||||
fn imservice_make_visible(imservice: *const UIManager);
|
||||
fn imservice_try_hide(imservice: *const UIManager);
|
||||
fn imservice_destroy_im(im: *mut c::InputMethod);
|
||||
fn eekboard_context_service_set_hint_purpose(imservice: *const UIManager, hint: u32, purpose: u32);
|
||||
fn eekboard_context_service_show_keyboard(imservice: *const UIManager);
|
||||
fn eekboard_context_service_hide_keyboard(imservice: *const UIManager);
|
||||
}
|
||||
|
||||
// The following defined in Rust. TODO: wrap naked pointers to Rust data inside RefCells to prevent multiple writers
|
||||
@ -54,9 +61,9 @@ pub mod c {
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C"
|
||||
fn imservice_handle_input_method_activate(imservice: *mut IMService,
|
||||
_im: *const InputMethod)
|
||||
im: *const InputMethod)
|
||||
{
|
||||
let imservice = &mut *imservice;
|
||||
let imservice = check_imservice(imservice, im).unwrap();
|
||||
imservice.preedit_string = String::new();
|
||||
imservice.pending = IMProtocolState {
|
||||
active: true,
|
||||
@ -67,9 +74,9 @@ pub mod c {
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C"
|
||||
fn imservice_handle_input_method_deactivate(imservice: *mut IMService,
|
||||
_im: *const InputMethod)
|
||||
im: *const InputMethod)
|
||||
{
|
||||
let imservice = &mut *imservice;
|
||||
let imservice = check_imservice(imservice, im).unwrap();
|
||||
imservice.pending = IMProtocolState {
|
||||
active: false,
|
||||
..imservice.pending.clone()
|
||||
@ -79,23 +86,65 @@ pub mod c {
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C"
|
||||
fn imservice_handle_surrounding_text(imservice: *mut IMService,
|
||||
_im: *const InputMethod,
|
||||
im: *const InputMethod,
|
||||
text: *const c_char, cursor: u32, _anchor: u32)
|
||||
{
|
||||
let imservice = &mut *imservice;
|
||||
let imservice = check_imservice(imservice, im).unwrap();
|
||||
imservice.pending = IMProtocolState {
|
||||
surrounding_text: into_cstring(text).expect("Received invalid string"),
|
||||
surrounding_cursor: cursor,
|
||||
..imservice.pending
|
||||
..imservice.pending.clone()
|
||||
};
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C"
|
||||
fn imservice_handle_content_type(imservice: *mut IMService,
|
||||
im: *const InputMethod,
|
||||
hint: u32, purpose: u32)
|
||||
{
|
||||
let imservice = check_imservice(imservice, im).unwrap();
|
||||
imservice.pending = IMProtocolState {
|
||||
content_hint: {
|
||||
ContentHint::from_bits(hint).unwrap_or_else(|| {
|
||||
eprintln!("Warning: received invalid hint flags");
|
||||
ContentHint::NONE
|
||||
})
|
||||
},
|
||||
content_purpose: {
|
||||
ContentPurpose::try_from(purpose).unwrap_or_else(|_e| {
|
||||
eprintln!("Warning: Received invalid purpose value");
|
||||
ContentPurpose::Normal
|
||||
})
|
||||
},
|
||||
..imservice.pending.clone()
|
||||
};
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C"
|
||||
fn imservice_handle_text_change_cause(imservice: *mut IMService,
|
||||
im: *const InputMethod,
|
||||
cause: u32)
|
||||
{
|
||||
let imservice = check_imservice(imservice, im).unwrap();
|
||||
imservice.pending = IMProtocolState {
|
||||
text_change_cause: {
|
||||
ChangeCause::try_from(cause).unwrap_or_else(|_e| {
|
||||
eprintln!("Warning: received invalid cause value");
|
||||
ChangeCause::InputMethod
|
||||
})
|
||||
},
|
||||
..imservice.pending.clone()
|
||||
};
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C"
|
||||
fn imservice_handle_commit_state(imservice: *mut IMService,
|
||||
_im: *const InputMethod)
|
||||
im: *const InputMethod)
|
||||
{
|
||||
let imservice = &mut *imservice;
|
||||
let imservice = check_imservice(imservice, im).unwrap();
|
||||
let active_changed = imservice.current.active ^ imservice.pending.active;
|
||||
|
||||
imservice.serial += Wrapping(1u32);
|
||||
@ -106,27 +155,174 @@ pub mod c {
|
||||
};
|
||||
if active_changed {
|
||||
if imservice.current.active {
|
||||
imservice_make_visible(imservice.ui_manager);
|
||||
eekboard_context_service_show_keyboard(imservice.ui_manager);
|
||||
eekboard_context_service_set_hint_purpose(
|
||||
imservice.ui_manager,
|
||||
imservice.current.content_hint.bits(),
|
||||
imservice.current.content_purpose.clone() as u32);
|
||||
} else {
|
||||
imservice_try_hide(imservice.ui_manager);
|
||||
eekboard_context_service_hide_keyboard(imservice.ui_manager);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C"
|
||||
fn imservice_handle_unavailable(imservice: *mut IMService,
|
||||
im: *mut InputMethod)
|
||||
{
|
||||
let imservice = check_imservice(imservice, im).unwrap();
|
||||
imservice_destroy_im(im);
|
||||
|
||||
// no need to care about proper double-buffering,
|
||||
// the keyboard is already decommissioned
|
||||
imservice.current.active = false;
|
||||
|
||||
eekboard_context_service_hide_keyboard(imservice.ui_manager);
|
||||
}
|
||||
|
||||
// FIXME: destroy and deallocate
|
||||
|
||||
// Helpers
|
||||
|
||||
/// Convenience method for referencing the IMService raw pointer,
|
||||
/// and for verifying that the input method passed along
|
||||
/// matches the one in the `imservice`.
|
||||
///
|
||||
/// The lifetime of the returned value is 'static,
|
||||
/// due to the fact that the lifetime of a raw pointer is undefined.
|
||||
/// Care must be take
|
||||
/// not to exceed the lifetime of the pointer with the reference,
|
||||
/// especially not to store it.
|
||||
fn check_imservice(imservice: *mut IMService, im: *const InputMethod)
|
||||
-> Result<&'static mut IMService, &'static str>
|
||||
{
|
||||
if imservice.is_null() {
|
||||
return Err("Null imservice pointer");
|
||||
}
|
||||
let imservice: &mut IMService = unsafe { &mut *imservice };
|
||||
if im == imservice.im {
|
||||
Ok(imservice)
|
||||
} else {
|
||||
Err("Imservice doesn't contain the input method")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bitflags!{
|
||||
/// Map to `text_input_unstable_v3.content_hint` values
|
||||
pub struct ContentHint: u32 {
|
||||
const NONE = 0x0;
|
||||
const COMPLETION = 0x1;
|
||||
const SPELLCHECK = 0x2;
|
||||
const AUTO_CAPITALIZATION = 0x4;
|
||||
const LOWERCASE = 0x8;
|
||||
const UPPERCASE = 0x10;
|
||||
const TITLECASE = 0x20;
|
||||
const HIDDEN_TEXT = 0x40;
|
||||
const SENSITIVE_DATA = 0x80;
|
||||
const LATIN = 0x100;
|
||||
const MULTILINE = 0x200;
|
||||
}
|
||||
}
|
||||
|
||||
/// Map to `text_input_unstable_v3.content_purpose` values
|
||||
///
|
||||
/// ```
|
||||
/// assert_eq!(ContentPurpose::Alpha as u32, 0);
|
||||
/// ```
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum ContentPurpose {
|
||||
Normal = 0,
|
||||
Alpha = 1,
|
||||
Digits = 2,
|
||||
Number = 3,
|
||||
Phone = 4,
|
||||
Url = 5,
|
||||
Email = 6,
|
||||
Name = 7,
|
||||
Password = 8,
|
||||
Pin = 9,
|
||||
Date = 10,
|
||||
Time = 11,
|
||||
Datetime = 12,
|
||||
Terminal = 13,
|
||||
}
|
||||
|
||||
impl TryFrom<u32> for ContentPurpose {
|
||||
// There's only one way to fail: number not in protocol,
|
||||
// so no special error type is needed
|
||||
type Error = ();
|
||||
fn try_from(num: u32) -> Result<Self, Self::Error> {
|
||||
use self::ContentPurpose::*;
|
||||
match num {
|
||||
0 => Ok(Normal),
|
||||
1 => Ok(Alpha),
|
||||
2 => Ok(Digits),
|
||||
3 => Ok(Number),
|
||||
4 => Ok(Phone),
|
||||
5 => Ok(Url),
|
||||
6 => Ok(Email),
|
||||
7 => Ok(Name),
|
||||
8 => Ok(Password),
|
||||
9 => Ok(Pin),
|
||||
10 => Ok(Date),
|
||||
11 => Ok(Time),
|
||||
12 => Ok(Datetime),
|
||||
13 => Ok(Terminal),
|
||||
_ => Err(()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Map to `text_input_unstable_v3.change_cause` values
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum ChangeCause {
|
||||
InputMethod = 0,
|
||||
Other = 1,
|
||||
}
|
||||
|
||||
impl TryFrom<u32> for ChangeCause {
|
||||
// There's only one way to fail: number not in protocol,
|
||||
// so no special error type is needed
|
||||
type Error = ();
|
||||
fn try_from(num: u32) -> Result<Self, Self::Error> {
|
||||
match num {
|
||||
0 => Ok(ChangeCause::InputMethod),
|
||||
1 => Ok(ChangeCause::Other),
|
||||
_ => Err(())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Describes the desired state of the input method as requested by the server
|
||||
#[derive(Default, Clone)]
|
||||
#[derive(Clone)]
|
||||
struct IMProtocolState {
|
||||
surrounding_text: CString,
|
||||
surrounding_cursor: u32,
|
||||
content_purpose: ContentPurpose,
|
||||
content_hint: ContentHint,
|
||||
text_change_cause: ChangeCause,
|
||||
active: bool,
|
||||
}
|
||||
|
||||
impl Default for IMProtocolState {
|
||||
fn default() -> IMProtocolState {
|
||||
IMProtocolState {
|
||||
surrounding_text: CString::default(),
|
||||
surrounding_cursor: 0, // TODO: mark that there's no cursor
|
||||
content_hint: ContentHint::NONE,
|
||||
content_purpose: ContentPurpose::Normal,
|
||||
text_change_cause: ChangeCause::InputMethod,
|
||||
active: false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct IMService {
|
||||
/// Owned reference (still created and destroyed in C)
|
||||
im: *const c::InputMethod,
|
||||
pub im: *const c::InputMethod,
|
||||
/// Unowned reference. Be careful, it's shared with C at large
|
||||
ui_manager: *const c::UIManager,
|
||||
|
||||
|
||||
4
src/lib.rs
Normal file
4
src/lib.rs
Normal file
@ -0,0 +1,4 @@
|
||||
#[macro_use]
|
||||
mod bitflags;
|
||||
|
||||
mod imservice;
|
||||
@ -30,9 +30,6 @@ sources = [
|
||||
'../eek/eek-symbol.c',
|
||||
'../eek/eek-symbol-matrix.c',
|
||||
'../eek/eek-text.c',
|
||||
'../eek/eek-theme.c',
|
||||
'../eek/eek-theme-context.c',
|
||||
'../eek/eek-theme-node.c',
|
||||
'../eek/eek-types.c',
|
||||
'../eek/eek-xml-layout.c',
|
||||
'../eek/layersurface.c',
|
||||
@ -40,7 +37,6 @@ sources = [
|
||||
enums,
|
||||
keysym_entries,
|
||||
marshalers,
|
||||
'../eekboard/keymap.c',
|
||||
'../eekboard/key-emitter.c',
|
||||
'../eekboard/eekboard-context-service.c',
|
||||
'../eekboard/eekboard-context.c',
|
||||
@ -70,10 +66,19 @@ deps = [
|
||||
# Replacement for eekboard-server
|
||||
rslib = static_library(
|
||||
'rslib',
|
||||
sources: ['imservice.rs'],
|
||||
sources: ['lib.rs'],
|
||||
rust_crate_type: 'staticlib'
|
||||
)
|
||||
|
||||
rstests = executable(
|
||||
'rstests',
|
||||
sources: ['lib.rs'],
|
||||
rust_args: ['--test'],
|
||||
install: false
|
||||
)
|
||||
|
||||
test('rstests', rstests)
|
||||
|
||||
libsqueekboard = static_library('libsqueekboard',
|
||||
sources,
|
||||
link_with: rslib,
|
||||
|
||||
@ -174,13 +174,6 @@ set_geometry (ServerContextService *context)
|
||||
|
||||
gtk_window_set_decorated (GTK_WINDOW(context->window), FALSE);
|
||||
gtk_window_set_resizable (GTK_WINDOW(context->window), FALSE);
|
||||
} else {
|
||||
gtk_window_resize (GTK_WINDOW(context->window),
|
||||
bounds.width,
|
||||
bounds.height);
|
||||
gtk_window_move (GTK_WINDOW(context->window),
|
||||
MAX(rect.width - 20 - bounds.width, 0),
|
||||
MAX(rect.height - 40 - bounds.height, 0));
|
||||
}
|
||||
}
|
||||
|
||||
@ -236,24 +229,16 @@ static void
|
||||
make_widget (ServerContextService *context)
|
||||
{
|
||||
EekKeyboard *keyboard;
|
||||
EekTheme *theme;
|
||||
|
||||
if (context->widget) {
|
||||
gtk_widget_destroy(context->widget);
|
||||
context->widget = NULL;
|
||||
}
|
||||
|
||||
theme = eek_theme_new ("resource:///sm/puri/squeekboard/style.css",
|
||||
NULL,
|
||||
NULL);
|
||||
|
||||
keyboard = eekboard_context_service_get_keyboard (EEKBOARD_CONTEXT_SERVICE(context));
|
||||
|
||||
context->widget = eek_gtk_keyboard_new (keyboard);
|
||||
|
||||
eek_gtk_keyboard_set_theme (EEK_GTK_KEYBOARD(context->widget), theme);
|
||||
g_clear_object (&theme);
|
||||
|
||||
gtk_widget_set_has_tooltip (context->widget, TRUE);
|
||||
gtk_container_add (GTK_CONTAINER(context->window), context->widget);
|
||||
gtk_widget_show (context->widget);
|
||||
|
||||
@ -19,6 +19,8 @@
|
||||
*/
|
||||
#include "eek/eek.h"
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
static void
|
||||
test_create (void)
|
||||
{
|
||||
@ -30,9 +32,9 @@ test_create (void)
|
||||
section = eek_keyboard_create_section (keyboard);
|
||||
g_assert (EEK_IS_SECTION(section));
|
||||
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, "key0", 1);
|
||||
g_assert (EEK_IS_KEY(key0));
|
||||
key1 = eek_section_create_key (section, "key1", 2, 1, 0);
|
||||
key1 = eek_section_create_key (section, "key1", 2);
|
||||
g_assert (EEK_IS_KEY(key1));
|
||||
}
|
||||
|
||||
|
||||
@ -24,6 +24,7 @@
|
||||
#include "config.h"
|
||||
|
||||
#include "eek/eek.h"
|
||||
#include "eek/eek-xml-layout.h"
|
||||
|
||||
static void
|
||||
test_output_parse (void)
|
||||
@ -47,7 +48,6 @@ int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
g_test_init (&argc, &argv, NULL);
|
||||
gtk_init (&argc, &argv); /* for gdk_x11_display_get_xdisplay() */
|
||||
|
||||
g_test_add_func ("/eek-xml-test/output-parse", test_output_parse);
|
||||
|
||||
|
||||
@ -21,7 +21,8 @@ test_link_args = [
|
||||
|
||||
tests = [
|
||||
'eek-simple-test',
|
||||
'eek-xml-test'
|
||||
'eek-xml-test',
|
||||
'test-keymap-generation'
|
||||
]
|
||||
|
||||
foreach name : tests
|
||||
|
||||
@ -1,181 +0,0 @@
|
||||
<?xml version="1.0"?>
|
||||
<keyboard version="0.90">
|
||||
<bounds>0.000000,0.000000,124.000000,149.000000</bounds>
|
||||
<section name="Keypad">
|
||||
<bounds>10.000000,10.000000,104.000000,129.000000</bounds>
|
||||
<angle>0</angle>
|
||||
<row>
|
||||
<columns>4</columns>
|
||||
<orientation>1</orientation>
|
||||
</row>
|
||||
<row>
|
||||
<columns>4</columns>
|
||||
<orientation>1</orientation>
|
||||
</row>
|
||||
<row>
|
||||
<columns>3</columns>
|
||||
<orientation>1</orientation>
|
||||
</row>
|
||||
<row>
|
||||
<columns>4</columns>
|
||||
<orientation>1</orientation>
|
||||
</row>
|
||||
<row>
|
||||
<columns>2</columns>
|
||||
<orientation>1</orientation>
|
||||
</row>
|
||||
<key id="keycode91" name="KPDL" column="1" row="4">
|
||||
<bounds>54.000000,104.000000,24.000000,24.000000</bounds>
|
||||
<outline-ref>outline0</outline-ref>
|
||||
<symbols groups="1" levels="2">
|
||||
<keysym keyval="65439">KP_Delete</keysym>
|
||||
<keysym keyval="65454">KP_Decimal</keysym>
|
||||
</symbols>
|
||||
</key>
|
||||
<key id="keycode90" name="KP0" column="0" row="4">
|
||||
<bounds>2.000000,104.000000,50.000000,24.000000</bounds>
|
||||
<outline-ref>outline1</outline-ref>
|
||||
<symbols groups="1" levels="2">
|
||||
<keysym keyval="65438">KP_Insert</keysym>
|
||||
<keysym keyval="65456">KP_0</keysym>
|
||||
</symbols>
|
||||
</key>
|
||||
<key id="keycode108" name="KPEN" column="3" row="3">
|
||||
<bounds>80.000000,78.000000,24.000000,50.000000</bounds>
|
||||
<outline-ref>outline2</outline-ref>
|
||||
<symbols groups="1" levels="1">
|
||||
<keysym keyval="65421">KP_Enter</keysym>
|
||||
</symbols>
|
||||
</key>
|
||||
<key id="keycode89" name="KP3" column="2" row="3">
|
||||
<bounds>54.000000,78.000000,24.000000,24.000000</bounds>
|
||||
<outline-ref>outline0</outline-ref>
|
||||
<symbols groups="1" levels="2">
|
||||
<keysym keyval="65435">KP_Next</keysym>
|
||||
<keysym keyval="65459">KP_3</keysym>
|
||||
</symbols>
|
||||
</key>
|
||||
<key id="keycode88" name="KP2" column="1" row="3">
|
||||
<bounds>28.000000,78.000000,24.000000,24.000000</bounds>
|
||||
<outline-ref>outline0</outline-ref>
|
||||
<symbols groups="1" levels="2">
|
||||
<keysym keyval="65433">KP_Down</keysym>
|
||||
<keysym keyval="65458">KP_2</keysym>
|
||||
</symbols>
|
||||
</key>
|
||||
<key id="keycode87" name="KP1" column="0" row="3">
|
||||
<bounds>2.000000,78.000000,24.000000,24.000000</bounds>
|
||||
<outline-ref>outline0</outline-ref>
|
||||
<symbols groups="1" levels="2">
|
||||
<keysym keyval="65436">KP_End</keysym>
|
||||
<keysym keyval="65457">KP_1</keysym>
|
||||
</symbols>
|
||||
</key>
|
||||
<key id="keycode85" name="KP6" column="2" row="2">
|
||||
<bounds>54.000000,53.000000,24.000000,24.000000</bounds>
|
||||
<outline-ref>outline0</outline-ref>
|
||||
<symbols groups="1" levels="2">
|
||||
<keysym keyval="65432">KP_Right</keysym>
|
||||
<keysym keyval="65462">KP_6</keysym>
|
||||
</symbols>
|
||||
</key>
|
||||
<key id="keycode84" name="KP5" column="1" row="2">
|
||||
<bounds>28.000000,53.000000,24.000000,24.000000</bounds>
|
||||
<outline-ref>outline0</outline-ref>
|
||||
<symbols groups="1" levels="2">
|
||||
<keysym keyval="65437">KP_Begin</keysym>
|
||||
<keysym keyval="65461">KP_5</keysym>
|
||||
</symbols>
|
||||
</key>
|
||||
<key id="keycode83" name="KP4" column="0" row="2">
|
||||
<bounds>2.000000,53.000000,24.000000,24.000000</bounds>
|
||||
<outline-ref>outline0</outline-ref>
|
||||
<symbols groups="1" levels="2">
|
||||
<keysym keyval="65430">KP_Left</keysym>
|
||||
<keysym keyval="65460">KP_4</keysym>
|
||||
</symbols>
|
||||
</key>
|
||||
<key id="keycode86" name="KPAD" column="3" row="1">
|
||||
<bounds>80.000000,27.000000,24.000000,50.000000</bounds>
|
||||
<outline-ref>outline2</outline-ref>
|
||||
<symbols groups="1" levels="2">
|
||||
<keysym keyval="65451">KP_Add</keysym>
|
||||
<keysym keyval="269024802"></keysym>
|
||||
</symbols>
|
||||
</key>
|
||||
<key id="keycode81" name="KP9" column="2" row="1">
|
||||
<bounds>54.000000,27.000000,24.000000,24.000000</bounds>
|
||||
<outline-ref>outline0</outline-ref>
|
||||
<symbols groups="1" levels="2">
|
||||
<keysym keyval="65434">KP_Prior</keysym>
|
||||
<keysym keyval="65465">KP_9</keysym>
|
||||
</symbols>
|
||||
</key>
|
||||
<key id="keycode80" name="KP8" column="1" row="1">
|
||||
<bounds>28.000000,27.000000,24.000000,24.000000</bounds>
|
||||
<outline-ref>outline0</outline-ref>
|
||||
<symbols groups="1" levels="2">
|
||||
<keysym keyval="65431">KP_Up</keysym>
|
||||
<keysym keyval="65464">KP_8</keysym>
|
||||
</symbols>
|
||||
</key>
|
||||
<key id="keycode79" name="KP7" column="0" row="1">
|
||||
<bounds>2.000000,27.000000,24.000000,24.000000</bounds>
|
||||
<outline-ref>outline0</outline-ref>
|
||||
<symbols groups="1" levels="2">
|
||||
<keysym keyval="65429">KP_Home</keysym>
|
||||
<keysym keyval="65463">KP_7</keysym>
|
||||
</symbols>
|
||||
</key>
|
||||
<key id="keycode82" name="KPSU" column="3" row="0">
|
||||
<bounds>80.000000,1.000000,24.000000,24.000000</bounds>
|
||||
<outline-ref>outline0</outline-ref>
|
||||
<symbols groups="1" levels="2">
|
||||
<keysym keyval="65453">KP_Subtract</keysym>
|
||||
<keysym keyval="269024803"></keysym>
|
||||
</symbols>
|
||||
</key>
|
||||
<key id="keycode63" name="KPMU" column="2" row="0">
|
||||
<bounds>54.000000,1.000000,24.000000,24.000000</bounds>
|
||||
<outline-ref>outline0</outline-ref>
|
||||
<symbols groups="1" levels="2">
|
||||
<keysym keyval="65450">KP_Multiply</keysym>
|
||||
<keysym keyval="269024801"></keysym>
|
||||
</symbols>
|
||||
</key>
|
||||
<key id="keycode112" name="KPDV" column="1" row="0">
|
||||
<bounds>28.000000,1.000000,24.000000,24.000000</bounds>
|
||||
<outline-ref>outline0</outline-ref>
|
||||
<symbols groups="1" levels="2">
|
||||
<keysym keyval="65455">KP_Divide</keysym>
|
||||
<keysym keyval="269024800"></keysym>
|
||||
</symbols>
|
||||
</key>
|
||||
<key id="keycode77" name="NMLK" column="0" row="0">
|
||||
<bounds>2.000000,1.000000,24.000000,24.000000</bounds>
|
||||
<outline-ref>outline0</outline-ref>
|
||||
<symbols groups="1" levels="2">
|
||||
<keysym keyval="65407">Num_Lock</keysym>
|
||||
<keysym keyval="65273">Pointer_EnableKeys</keysym>
|
||||
</symbols>
|
||||
</key>
|
||||
</section>
|
||||
<outline id="outline0">
|
||||
<point>0.000000,0.000000</point>
|
||||
<point>24.000000,0.000000</point>
|
||||
<point>24.000000,24.000000</point>
|
||||
<point>0.000000,24.000000</point>
|
||||
</outline>
|
||||
<outline id="outline1">
|
||||
<point>0.000000,0.000000</point>
|
||||
<point>50.000000,0.000000</point>
|
||||
<point>50.000000,24.000000</point>
|
||||
<point>0.000000,24.000000</point>
|
||||
</outline>
|
||||
<outline id="outline2">
|
||||
<point>0.000000,0.000000</point>
|
||||
<point>24.000000,0.000000</point>
|
||||
<point>24.000000,50.000000</point>
|
||||
<point>0.000000,50.000000</point>
|
||||
</outline>
|
||||
</keyboard>
|
||||
72
tests/test-keymap-generation.c
Normal file
72
tests/test-keymap-generation.c
Normal file
@ -0,0 +1,72 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2011 Daiki Ueno <ueno@unixuser.org>
|
||||
* Copyright (C) 2010-2011 Red Hat, Inc.
|
||||
* Copyright (C) 2019 Purism SPC
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
/* For gdk_x11_display_get_xdisplay(). See main(). */
|
||||
#include <gtk/gtk.h>
|
||||
#include <xkbcommon/xkbcommon.h>
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "eek/eek.h"
|
||||
#include "eek/eek-xml-layout.h"
|
||||
|
||||
static void
|
||||
test_check_xkb (void)
|
||||
{
|
||||
EekLayout *layout;
|
||||
EekKeyboard *keyboard;
|
||||
GError *error;
|
||||
|
||||
error = NULL;
|
||||
layout = eek_xml_layout_new ("us", &error);
|
||||
g_assert_no_error (error);
|
||||
|
||||
keyboard = eek_keyboard_new (NULL, layout, 640, 480);
|
||||
gchar *keymap_str = eek_keyboard_get_keymap(keyboard);
|
||||
|
||||
struct xkb_context *context = xkb_context_new(XKB_CONTEXT_NO_FLAGS);
|
||||
if (!context) {
|
||||
g_error("No context created");
|
||||
}
|
||||
|
||||
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) {
|
||||
g_error("Bad keymap");
|
||||
}
|
||||
|
||||
g_object_unref (layout);
|
||||
g_object_unref (keyboard);
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
g_test_init (&argc, &argv, NULL);
|
||||
|
||||
g_test_add_func ("/test-keymap-generation/check-xkb", test_check_xkb);
|
||||
|
||||
return g_test_run ();
|
||||
}
|
||||
Reference in New Issue
Block a user