Compare commits
2 Commits
add-more-p
...
click
| Author | SHA1 | Date | |
|---|---|---|---|
| 8c0b55d7f8 | |||
| 72da6d02ae |
9
.gitignore
vendored
9
.gitignore
vendored
@ -1,9 +0,0 @@
|
|||||||
.zanata-cache/
|
|
||||||
_build
|
|
||||||
TAGS
|
|
||||||
tags
|
|
||||||
vgdump
|
|
||||||
*.swp
|
|
||||||
*~
|
|
||||||
\#*#
|
|
||||||
.\#*
|
|
||||||
@ -2,30 +2,16 @@ image: debian:buster
|
|||||||
|
|
||||||
stages:
|
stages:
|
||||||
- build
|
- build
|
||||||
- test
|
|
||||||
|
|
||||||
.tags: &tags
|
|
||||||
tags:
|
|
||||||
- librem5
|
|
||||||
|
|
||||||
before_script:
|
before_script:
|
||||||
- apt-get -y update
|
- apt-get -y update
|
||||||
- apt-get -y build-dep .
|
- apt-get -y build-dep .
|
||||||
|
|
||||||
build_meson:
|
build_meson:
|
||||||
<<: *tags
|
|
||||||
stage: build
|
stage: build
|
||||||
artifacts:
|
tags:
|
||||||
paths:
|
- librem5
|
||||||
- _build
|
|
||||||
script:
|
script:
|
||||||
- meson . _build/ -Ddepdatadir=/usr/share
|
- meson . _build/ -Ddepdatadir=/usr/share
|
||||||
- ninja -C _build install
|
- ninja -C _build install
|
||||||
|
|
||||||
test:
|
|
||||||
<<: *tags
|
|
||||||
stage: test
|
|
||||||
dependencies:
|
|
||||||
- build_meson
|
|
||||||
script:
|
|
||||||
- ninja -C _build test
|
|
||||||
|
|||||||
@ -33,8 +33,8 @@ See `.gitlab-ci.yml`.
|
|||||||
### Build from git repo
|
### Build from git repo
|
||||||
|
|
||||||
```
|
```
|
||||||
$ git clone https://source.puri.sm/Librem5/squeekboard.git
|
$ git clone https://source.puri.sm/Librem5/eekboard.git
|
||||||
$ cd squeekboard
|
$ cd eekboard
|
||||||
$ mkdir ../build
|
$ mkdir ../build
|
||||||
$ meson ../build/
|
$ meson ../build/
|
||||||
$ cd ../build
|
$ cd ../build
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||||
|
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" height="16" width="16"
|
<svg xmlns="http://www.w3.org/2000/svg" height="24" width="24"
|
||||||
version="1.1" viewBox="0 0 24 24">
|
version="1.1" viewBox="0 0 24 24">
|
||||||
|
|
||||||
<path d="M 24,1 L 24,10 C 24,15 20,17 17,17 L 7,17 L 10,20 L 10,23
|
<path d="M 24,1 L 24,10 C 24,15 20,17 17,17 L 7,17 L 10,20 L 10,23
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 388 B After Width: | Height: | Size: 388 B |
@ -1,6 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||||
|
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" height="16" width="16"
|
<svg xmlns="http://www.w3.org/2000/svg" height="24" width="24"
|
||||||
version="1.1" viewBox="0 0 24 24">
|
version="1.1" viewBox="0 0 24 24">
|
||||||
|
|
||||||
<path d="M 12,2 L 22,14 L 16,14 L 16,22 L 8,22 L 8,14 L 2,14 Z"
|
<path d="M 12,2 L 22,14 L 16,14 L 16,22 L 8,22 L 8,14 L 2,14 Z"
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 279 B After Width: | Height: | Size: 279 B |
@ -1,120 +1,119 @@
|
|||||||
<?xml version="1.0"?>
|
<?xml version="1.0"?>
|
||||||
<geometry version="0.90">
|
<geometry version="0.90">
|
||||||
<bounds x="10" y="10" width="410.0000" height="229"/>
|
<bounds x="0" y="10.000000" width="426.0000" height="296.5853"/>
|
||||||
<section angle="0">
|
<section angle="0">
|
||||||
<row orientation="1">
|
<row orientation="1">
|
||||||
<key name="AD01" oref="outline2" />
|
<key keycode="24" name="AD01" oref="outline2" />
|
||||||
<key name="AD02" oref="outline2" />
|
<key keycode="25" name="AD02" oref="outline2" />
|
||||||
<key name="AD03" oref="outline2" />
|
<key keycode="26" name="AD03" oref="outline2" />
|
||||||
<key name="AD04" oref="outline2" />
|
<key keycode="27" name="AD04" oref="outline2" />
|
||||||
<key name="AD05" oref="outline2" />
|
<key keycode="28" name="AD05" oref="outline2" />
|
||||||
<key name="AD06" oref="outline2" />
|
<key keycode="29" name="AD06" oref="outline2" />
|
||||||
<key name="AD07" oref="outline2" />
|
<key keycode="30" name="AD07" oref="outline2" />
|
||||||
<key name="AD08" oref="outline2" />
|
<key keycode="31" name="AD08" oref="outline2" />
|
||||||
<key name="AD09" oref="outline2" />
|
<key keycode="32" name="AD09" oref="outline2" />
|
||||||
<key name="AD10" oref="outline2" />
|
<key keycode="33" name="AD10" oref="outline2" />
|
||||||
</row>
|
</row>
|
||||||
</section>
|
</section>
|
||||||
<section angle="0">
|
<section angle="0">
|
||||||
<row orientation="1">
|
<row orientation="1">
|
||||||
<key name="AC01" oref="outline2" />
|
<key keycode="38" name="AC01" oref="outline2" />
|
||||||
<key name="AC02" oref="outline2" />
|
<key keycode="39" name="AC02" oref="outline2" />
|
||||||
<key name="AC03" oref="outline2" />
|
<key keycode="40" name="AC03" oref="outline2" />
|
||||||
<key name="AC04" oref="outline2" />
|
<key keycode="41" name="AC04" oref="outline2" />
|
||||||
<key name="AC05" oref="outline2" />
|
<key keycode="42" name="AC05" oref="outline2" />
|
||||||
<key name="AC06" oref="outline2" />
|
<key keycode="43" name="AC06" oref="outline2" />
|
||||||
<key name="AC07" oref="outline2" />
|
<key keycode="44" name="AC07" oref="outline2" />
|
||||||
<key name="AC08" oref="outline2" />
|
<key keycode="45" name="AC08" oref="outline2" />
|
||||||
<key name="AC09" oref="outline2" />
|
<key keycode="46" name="AC09" oref="outline2" />
|
||||||
<key name="AC10" oref="outline2" />
|
|
||||||
</row>
|
</row>
|
||||||
</section>
|
</section>
|
||||||
<section angle="0">
|
<section angle="0">
|
||||||
<row orientation="1">
|
<row orientation="1">
|
||||||
<key name="LFSH" oref="altline" />
|
<key keycode="50" name="LFSH" oref="altline" />
|
||||||
<key name="AB01" oref="outline2" />
|
<key keycode="52" name="AB01" oref="outline2" />
|
||||||
<key name="AB02" oref="outline2" />
|
<key keycode="53" name="AB02" oref="outline2" />
|
||||||
<key name="AB03" oref="outline2" />
|
<key keycode="54" name="AB03" oref="outline2" />
|
||||||
<key name="AB04" oref="outline2" />
|
<key keycode="55" name="AB04" oref="outline2" />
|
||||||
<key name="AB05" oref="outline2" />
|
<key keycode="56" name="AB05" oref="outline2" />
|
||||||
<key name="AB06" oref="outline2" />
|
<key keycode="57" name="AB06" oref="outline2" />
|
||||||
<key name="AB07" oref="outline2" />
|
<key keycode="58" name="AB07" oref="outline2" />
|
||||||
<key name="BKSP" oref="altline" />
|
<key keycode="22" name="BKSP" oref="altline" />
|
||||||
</row>
|
</row>
|
||||||
</section>
|
</section>
|
||||||
<section angle="0">
|
<section angle="0">
|
||||||
<row orientation="1">
|
<row orientation="1">
|
||||||
<key keycode="0" name="ABC123" oref="altline" />
|
<key keycode="0" name="ABC123" oref="altline" />
|
||||||
<key name="I149" oref="altline" />
|
<key keycode="150" name="I150" oref="altline" />
|
||||||
<key name="SPCE" oref="spaceline" />
|
<key keycode="65" name="SPCE" oref="spaceline" />
|
||||||
<key name="AB08" oref="outline2" />
|
<key keycode="60" name="AB09" oref="outline2" />
|
||||||
<key name="RTRN" oref="outline7" />
|
<key keycode="36" name="RTRN" oref="outline7" />
|
||||||
</row>
|
</row>
|
||||||
</section>
|
</section>
|
||||||
<outline id="outline2" corner-radius="1.000000">
|
<outline id="outline2" corner-radius="1.000000">
|
||||||
<point x="0.000000" y="0.000000"/>
|
<point x="0.000000" y="0.000000"/>
|
||||||
<point x="37.46341" y="0.000000"/>
|
<point x="37.46341" y="0.000000"/>
|
||||||
<point x="37.46341" y="52"/>
|
<point x="37.46341" y="52.44877"/>
|
||||||
<point x="0.000000" y="52"/>
|
<point x="0.000000" y="52.44877"/>
|
||||||
</outline>
|
</outline>
|
||||||
<outline id="altline" corner-radius="1.000000">
|
<outline id="altline" corner-radius="1.000000">
|
||||||
<point x="0.000000" y="0.000000"/>
|
<point x="0.000000" y="0.000000"/>
|
||||||
<point x="48.39024" y="0.000000"/>
|
<point x="48.39024" y="0.000000"/>
|
||||||
<point x="48.39024" y="52"/>
|
<point x="48.39024" y="52.44877"/>
|
||||||
<point x="0.000000" y="52"/>
|
<point x="0.000000" y="52.44877"/>
|
||||||
</outline>
|
</outline>
|
||||||
<outline id="outline4" corner-radius="1.000000">
|
<outline id="outline4" corner-radius="1.000000">
|
||||||
<point x="0.000000" y="0.000000"/>
|
<point x="0.000000" y="0.000000"/>
|
||||||
<point x="59.31707" y="0.000000"/>
|
<point x="59.31707" y="0.000000"/>
|
||||||
<point x="59.31707" y="52"/>
|
<point x="59.31707" y="52.44877"/>
|
||||||
<point x="0.000000" y="52"/>
|
<point x="0.000000" y="52.44877"/>
|
||||||
</outline>
|
</outline>
|
||||||
<outline id="outline5" corner-radius="1.000000">
|
<outline id="outline5" corner-radius="1.000000">
|
||||||
<point x="0.000000" y="0.000000"/>
|
<point x="0.000000" y="0.000000"/>
|
||||||
<point x="59.31707" y="0.000000"/>
|
<point x="59.31707" y="0.000000"/>
|
||||||
<point x="59.31707" y="52"/>
|
<point x="59.31707" y="52.44877"/>
|
||||||
<point x="0.000000" y="52"/>
|
<point x="0.000000" y="52.44877"/>
|
||||||
</outline>
|
</outline>
|
||||||
<outline id="outline6" corner-radius="1.000000">
|
<outline id="outline6" corner-radius="1.000000">
|
||||||
<point x="0.000000" y="0.000000"/>
|
<point x="0.000000" y="0.000000"/>
|
||||||
<point x="68.68292" y="0.000000"/>
|
<point x="68.68292" y="0.000000"/>
|
||||||
<point x="68.68292" y="52"/>
|
<point x="68.68292" y="52.44877"/>
|
||||||
<point x="0.000000" y="52"/>
|
<point x="0.000000" y="52.44877"/>
|
||||||
</outline>
|
</outline>
|
||||||
<outline id="outline7" corner-radius="1.000000">
|
<outline id="outline7" corner-radius="1.000000">
|
||||||
<point x="0.000000" y="0.000000"/>
|
<point x="0.000000" y="0.000000"/>
|
||||||
<point x="88.97561" y="0.000000"/>
|
<point x="88.97561" y="0.000000"/>
|
||||||
<point x="88.97561" y="52"/>
|
<point x="88.97561" y="52.44877"/>
|
||||||
<point x="0.000000" y="52"/>
|
<point x="0.000000" y="52.44877"/>
|
||||||
</outline>
|
</outline>
|
||||||
<outline id="outline8" corner-radius="1.000000">
|
<outline id="outline8" corner-radius="1.000000">
|
||||||
<point x="0.000000" y="0.000000"/>
|
<point x="0.000000" y="0.000000"/>
|
||||||
<point x="88.97561" y="0.000000"/>
|
<point x="88.97561" y="0.000000"/>
|
||||||
<point x="88.97561" y="52"/>
|
<point x="88.97561" y="52.44877"/>
|
||||||
<point x="0.000000" y="52"/>
|
<point x="0.000000" y="52.44877"/>
|
||||||
</outline>
|
</outline>
|
||||||
<outline id="outline9" corner-radius="1.000000">
|
<outline id="outline9" corner-radius="1.000000">
|
||||||
<point x="0.000000" y="0.000000"/>
|
<point x="0.000000" y="0.000000"/>
|
||||||
<point x="109.2682" y="0.000000"/>
|
<point x="109.2682" y="0.000000"/>
|
||||||
<point x="109.2682" y="52"/>
|
<point x="109.2682" y="52.44877"/>
|
||||||
<point x="0.000000" y="52"/>
|
<point x="0.000000" y="52.44877"/>
|
||||||
</outline>
|
</outline>
|
||||||
<outline id="outline10" corner-radius="1.000000">
|
<outline id="outline10" corner-radius="1.000000">
|
||||||
<point x="0.000000" y="0.000000"/>
|
<point x="0.000000" y="0.000000"/>
|
||||||
<point x="37.46341" y="0.000000"/>
|
<point x="37.46341" y="0.000000"/>
|
||||||
<point x="37.46341" y="52"/>
|
<point x="37.46341" y="52.44877"/>
|
||||||
<point x="0.000000" y="52"/>
|
<point x="0.000000" y="52.44877"/>
|
||||||
</outline>
|
</outline>
|
||||||
<outline id="outline13" corner-radius="1.000000">
|
<outline id="outline13" corner-radius="1.000000">
|
||||||
<point x="0.000000" y="0.000000"/>
|
<point x="0.000000" y="0.000000"/>
|
||||||
<point x="79.60975" y="0.000000"/>
|
<point x="79.60975" y="0.000000"/>
|
||||||
<point x="79.60975" y="52"/>
|
<point x="79.60975" y="52.44877"/>
|
||||||
<point x="0.000000" y="52"/>
|
<point x="0.000000" y="52.44877"/>
|
||||||
</outline>
|
</outline>
|
||||||
<outline id="spaceline" corner-radius="1.000000">
|
<outline id="spaceline" corner-radius="1.000000">
|
||||||
<point x="0.000000" y="0.000000"/>
|
<point x="0.000000" y="0.000000"/>
|
||||||
<point x="150.5853" y="0.000000"/>
|
<point x="150.5853" y="0.000000"/>
|
||||||
<point x="150.5853" y="52"/>
|
<point x="150.5853" y="52.44877"/>
|
||||||
<point x="0.000000" y="52"/>
|
<point x="0.000000" y="52.44877"/>
|
||||||
</outline>
|
</outline>
|
||||||
</geometry>
|
</geometry>
|
||||||
|
|||||||
@ -1,98 +0,0 @@
|
|||||||
<?xml version="1.0"?>
|
|
||||||
<geometry version="0.90">
|
|
||||||
<bounds x="0" y="10.000000" width="426.0000" height="296.5853"/>
|
|
||||||
<section angle="0">
|
|
||||||
<row orientation="1">
|
|
||||||
<key name="AD01" oref="outline4" />
|
|
||||||
<key name="AD02" oref="outline4" />
|
|
||||||
<key name="AD03" oref="outline4" />
|
|
||||||
</row>
|
|
||||||
</section>
|
|
||||||
<section angle="0">
|
|
||||||
<row orientation="1">
|
|
||||||
<key name="AC01" oref="outline4" />
|
|
||||||
<key name="AC02" oref="outline4" />
|
|
||||||
<key name="AC03" oref="outline4" />
|
|
||||||
</row>
|
|
||||||
</section>
|
|
||||||
<section angle="0">
|
|
||||||
<row orientation="1">
|
|
||||||
<key name="AB01" oref="outline4" />
|
|
||||||
<key name="AB02" oref="outline4" />
|
|
||||||
<key name="AB03" oref="outline4" />
|
|
||||||
</row>
|
|
||||||
</section>
|
|
||||||
<section angle="0">
|
|
||||||
<row orientation="1">
|
|
||||||
<key name="BKSP" oref="altline" />
|
|
||||||
<key name="AB04" oref="outline4" />
|
|
||||||
<key name="RTRN" oref="altline" />
|
|
||||||
</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>
|
|
||||||
@ -1,122 +0,0 @@
|
|||||||
<?xml version="1.0"?>
|
|
||||||
<geometry version="0.90">
|
|
||||||
<bounds x="0" y="10.000000" width="426.0000" height="296.5853"/>
|
|
||||||
<section angle="0">
|
|
||||||
<row orientation="1">
|
|
||||||
<key 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 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 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="32" y="0.000000"/>
|
|
||||||
<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"/>
|
|
||||||
<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"/>
|
|
||||||
<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"/>
|
|
||||||
<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"/>
|
|
||||||
<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"/>
|
|
||||||
<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"/>
|
|
||||||
<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"/>
|
|
||||||
<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"/>
|
|
||||||
<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"/>
|
|
||||||
<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"/>
|
|
||||||
<point x="0.000000" y="52"/>
|
|
||||||
</outline>
|
|
||||||
</geometry>
|
|
||||||
@ -1,105 +0,0 @@
|
|||||||
<?xml version="1.0"?>
|
|
||||||
<geometry version="0.90">
|
|
||||||
<bounds x="0" y="10.000000" width="426.0000" height="296.5853"/>
|
|
||||||
<section angle="0">
|
|
||||||
<row orientation="1">
|
|
||||||
<key 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>
|
|
||||||
@ -1,105 +0,0 @@
|
|||||||
<?xml version="1.0"?>
|
|
||||||
<geometry version="0.90">
|
|
||||||
<bounds x="0" y="10.000000" width="426.0000" height="296.5853"/>
|
|
||||||
<section angle="0">
|
|
||||||
<row orientation="1">
|
|
||||||
<key 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>
|
|
||||||
@ -1,126 +0,0 @@
|
|||||||
<?xml version="1.0"?>
|
|
||||||
<geometry version="0.90">
|
|
||||||
<bounds x="0" y="10.000000" width="426.0000" height="296.5853"/>
|
|
||||||
<section angle="0">
|
|
||||||
<row orientation="1">
|
|
||||||
<key 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>
|
|
||||||
@ -24,9 +24,6 @@
|
|||||||
<keyboard id="my" name="my"
|
<keyboard id="my" name="my"
|
||||||
geometry="compact" symbols="my"
|
geometry="compact" symbols="my"
|
||||||
longname="Myanmar" language="my"/>
|
longname="Myanmar" language="my"/>
|
||||||
<keyboard id="nb" name="nb"
|
|
||||||
geometry="extended" symbols="nb"
|
|
||||||
longname="Norwegian" language="nb"/>
|
|
||||||
<keyboard id="ru" name="ru"
|
<keyboard id="ru" name="ru"
|
||||||
geometry="compact" symbols="us"
|
geometry="compact" symbols="us"
|
||||||
longname="Russian" language="ru"/>
|
longname="Russian" language="ru"/>
|
||||||
@ -88,19 +85,4 @@
|
|||||||
<keyboard id="te-inscript" name="te-inscript"
|
<keyboard id="te-inscript" name="te-inscript"
|
||||||
geometry="compact" symbols="te-inscript"
|
geometry="compact" symbols="te-inscript"
|
||||||
longname="Telugu (Inscript)" language="te"/>
|
longname="Telugu (Inscript)" language="te"/>
|
||||||
|
|
||||||
<!-- Common keyboards -->
|
|
||||||
<keyboard id="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>
|
</keyboards>
|
||||||
|
|||||||
@ -1,206 +0,0 @@
|
|||||||
<?xml version='1.0' encoding='ASCII' standalone='yes'?>
|
|
||||||
<symbols version="0.90">
|
|
||||||
<key name="AD01">
|
|
||||||
<symbol label="q">q</symbol>
|
|
||||||
<symbol label="Q">Q</symbol>
|
|
||||||
<symbol label="1">1</symbol>
|
|
||||||
<symbol label="~">asciitilde</symbol>
|
|
||||||
</key>
|
|
||||||
<key name="AD02">
|
|
||||||
<symbol label="w">w</symbol>
|
|
||||||
<symbol label="W">W</symbol>
|
|
||||||
<symbol label="2">2</symbol>
|
|
||||||
<symbol label="`">quoteleft</symbol>
|
|
||||||
</key>
|
|
||||||
<key name="AD03">
|
|
||||||
<symbol label="e">e</symbol>
|
|
||||||
<symbol label="E">E</symbol>
|
|
||||||
<symbol label="3">3</symbol>
|
|
||||||
<symbol label="|">bar</symbol>
|
|
||||||
</key>
|
|
||||||
<key name="AD04">
|
|
||||||
<symbol label="r">r</symbol>
|
|
||||||
<symbol label="R">R</symbol>
|
|
||||||
<symbol label="4">4</symbol>
|
|
||||||
<symbol label="·">U00B7</symbol>
|
|
||||||
</key>
|
|
||||||
<key name="AD05">
|
|
||||||
<symbol label="t">t</symbol>
|
|
||||||
<symbol label="T">T</symbol>
|
|
||||||
<symbol label="5">5</symbol>
|
|
||||||
<symbol label="√">squareroot</symbol>
|
|
||||||
</key>
|
|
||||||
<key name="AD06">
|
|
||||||
<symbol label="y">y</symbol>
|
|
||||||
<symbol label="Y">Y</symbol>
|
|
||||||
<symbol label="6">6</symbol>
|
|
||||||
<symbol label="π">Greek_pi</symbol>
|
|
||||||
</key>
|
|
||||||
<key name="AD07">
|
|
||||||
<symbol label="u">u</symbol>
|
|
||||||
<symbol label="U">U</symbol>
|
|
||||||
<symbol label="7">7</symbol>
|
|
||||||
<symbol label="÷">division</symbol>
|
|
||||||
</key>
|
|
||||||
<key name="AD08">
|
|
||||||
<symbol label="i">i</symbol>
|
|
||||||
<symbol label="I">I</symbol>
|
|
||||||
<symbol label="8">8</symbol>
|
|
||||||
<symbol label="×">multiply</symbol>
|
|
||||||
</key>
|
|
||||||
<key name="AD09">
|
|
||||||
<symbol label="o">o</symbol>
|
|
||||||
<symbol label="O">O</symbol>
|
|
||||||
<symbol label="9">9</symbol>
|
|
||||||
<symbol label="¶">paragraph</symbol>
|
|
||||||
</key>
|
|
||||||
<key name="AD10">
|
|
||||||
<symbol label="p">p</symbol>
|
|
||||||
<symbol label="P">P</symbol>
|
|
||||||
<symbol label="0">0</symbol>
|
|
||||||
<symbol label="△">U25B3</symbol>
|
|
||||||
</key>
|
|
||||||
<key name="AD11">
|
|
||||||
<symbol keyval="229" label="å">aring</symbol>
|
|
||||||
<symbol keyval="197" label="Å">Aring</symbol>
|
|
||||||
<symbol label=""></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>
|
|
||||||
<symbol label="A">A</symbol>
|
|
||||||
<symbol label="@">at</symbol>
|
|
||||||
<symbol label="©">copyright</symbol>
|
|
||||||
</key>
|
|
||||||
<key name="AC02">
|
|
||||||
<symbol label="s">s</symbol>
|
|
||||||
<symbol label="S">S</symbol>
|
|
||||||
<symbol label="#">numbersign</symbol>
|
|
||||||
<symbol label="®">U00AE</symbol>
|
|
||||||
</key>
|
|
||||||
<key name="AC03">
|
|
||||||
<symbol label="d">d</symbol>
|
|
||||||
<symbol label="D">D</symbol>
|
|
||||||
<symbol label="$">dollar</symbol>
|
|
||||||
<symbol label="£">U00A3</symbol>
|
|
||||||
</key>
|
|
||||||
<key name="AC04">
|
|
||||||
<symbol label="f">f</symbol>
|
|
||||||
<symbol label="F">F</symbol>
|
|
||||||
<symbol label="%">percent</symbol>
|
|
||||||
<symbol label="€">EuroSign</symbol>
|
|
||||||
</key>
|
|
||||||
<key name="AC05">
|
|
||||||
<symbol label="g">g</symbol>
|
|
||||||
<symbol label="G">G</symbol>
|
|
||||||
<symbol label="&">ampersand</symbol>
|
|
||||||
<symbol label="¥">U00A5</symbol>
|
|
||||||
</key>
|
|
||||||
<key name="AC06">
|
|
||||||
<symbol label="h">h</symbol>
|
|
||||||
<symbol label="H">H</symbol>
|
|
||||||
<symbol label="-">minus</symbol>
|
|
||||||
<symbol label="^">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 keyval="248" label="ø">oslash</symbol>
|
|
||||||
<symbol keyval="216" label="Ø">Oslash</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=""></symbol>
|
|
||||||
<symbol label=""></symbol>
|
|
||||||
</key>
|
|
||||||
<key name="RTRN">
|
|
||||||
<symbol keyval="65293" icon="key-enter">Return</symbol>
|
|
||||||
</key>
|
|
||||||
<key name="LFSH">
|
|
||||||
<keysym keyval="65505" icon="key-shift">Shift_L</keysym>
|
|
||||||
<keysym keyval="65505" icon="key-shift">Shift_L</keysym>
|
|
||||||
<keysym keyval="65505" label="=/+">Shift_L</keysym>
|
|
||||||
<keysym keyval="65505" label="123">Shift_L</keysym>
|
|
||||||
</key>
|
|
||||||
<key name="AB01">
|
|
||||||
<symbol label="z">z</symbol>
|
|
||||||
<symbol label="Z">Z</symbol>
|
|
||||||
<symbol label=",">comma</symbol>
|
|
||||||
<symbol label="\">backslash</symbol>
|
|
||||||
</key>
|
|
||||||
<key name="AB02">
|
|
||||||
<symbol label="x">x</symbol>
|
|
||||||
<symbol label="X">X</symbol>
|
|
||||||
<symbol label=""">quotedbl</symbol>
|
|
||||||
<symbol label="/">slash</symbol>
|
|
||||||
</key>
|
|
||||||
<key name="AB03">
|
|
||||||
<symbol label="c">c</symbol>
|
|
||||||
<symbol label="C">C</symbol>
|
|
||||||
<symbol label="'">quoteright</symbol>
|
|
||||||
<symbol label="<">less</symbol>
|
|
||||||
</key>
|
|
||||||
<key name="AB04">
|
|
||||||
<symbol label="v">v</symbol>
|
|
||||||
<symbol label="V">V</symbol>
|
|
||||||
<symbol label=":">colon</symbol>
|
|
||||||
<symbol label=">">greater</symbol>
|
|
||||||
</key>
|
|
||||||
<key name="AB05">
|
|
||||||
<symbol label="b">b</symbol>
|
|
||||||
<symbol label="B">B</symbol>
|
|
||||||
<symbol label=";">semicolon</symbol>
|
|
||||||
<symbol label="=">equal</symbol>
|
|
||||||
</key>
|
|
||||||
<key name="AB06">
|
|
||||||
<symbol label="n">n</symbol>
|
|
||||||
<symbol label="N">N</symbol>
|
|
||||||
<symbol label="!">exclam</symbol>
|
|
||||||
<symbol label="[">bracketleft</symbol>
|
|
||||||
</key>
|
|
||||||
<key name="AB07">
|
|
||||||
<symbol label="m">m</symbol>
|
|
||||||
<symbol label="M">M</symbol>
|
|
||||||
<symbol label="?">question</symbol>
|
|
||||||
<symbol label="]">bracketright</symbol>
|
|
||||||
</key>
|
|
||||||
<key name="AB08">
|
|
||||||
<symbol label=".">period</symbol>
|
|
||||||
</key>
|
|
||||||
<key name="ABC123">
|
|
||||||
<symbol label="123">show-numbers</symbol>
|
|
||||||
<symbol label="123">show-numbers</symbol>
|
|
||||||
<symbol label="ABC">show-letters</symbol>
|
|
||||||
<symbol label="ABC">show-letters</symbol>
|
|
||||||
</key>
|
|
||||||
<key name="I149">
|
|
||||||
<symbol icon="keyboard-mode-symbolic" tooltip="Setup">preferences</symbol>
|
|
||||||
</key>
|
|
||||||
<key name="SPCE">
|
|
||||||
<symbol label=" ">space</symbol>
|
|
||||||
</key>
|
|
||||||
<key name="BKSP">
|
|
||||||
<symbol keyval="65288" icon="edit-clear-symbolic">BackSpace</symbol>
|
|
||||||
</key>
|
|
||||||
</symbols>
|
|
||||||
@ -1,39 +0,0 @@
|
|||||||
<?xml version='1.0' encoding='ASCII' standalone='yes'?>
|
|
||||||
<symbols version="0.90">
|
|
||||||
<key name="AD01">
|
|
||||||
<symbol label="1">1</symbol>
|
|
||||||
</key>
|
|
||||||
<key name="AD02">
|
|
||||||
<symbol label="2">2</symbol>
|
|
||||||
</key>
|
|
||||||
<key name="AD03">
|
|
||||||
<symbol label="3">3</symbol>
|
|
||||||
</key>
|
|
||||||
<key name="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>
|
|
||||||
@ -1,60 +0,0 @@
|
|||||||
<?xml version='1.0' encoding='ASCII' standalone='yes'?>
|
|
||||||
<symbols version="0.90">
|
|
||||||
<key name="AD01">
|
|
||||||
<symbol label="1">1</symbol>
|
|
||||||
</key>
|
|
||||||
<key name="AD02">
|
|
||||||
<symbol label="2">2</symbol>
|
|
||||||
</key>
|
|
||||||
<key name="AD03">
|
|
||||||
<symbol label="3">3</symbol>
|
|
||||||
</key>
|
|
||||||
<key name="AD04">
|
|
||||||
<symbol label=".">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>
|
|
||||||
@ -1,60 +0,0 @@
|
|||||||
<?xml version='1.0' encoding='ASCII' standalone='yes'?>
|
|
||||||
<symbols version="0.90">
|
|
||||||
<key name="AD01">
|
|
||||||
<symbol label="1">1</symbol>
|
|
||||||
</key>
|
|
||||||
<key name="AD02">
|
|
||||||
<symbol label="2">2</symbol>
|
|
||||||
</key>
|
|
||||||
<key name="AD03">
|
|
||||||
<symbol label="3">3</symbol>
|
|
||||||
</key>
|
|
||||||
<key name="AD04">
|
|
||||||
<symbol label="(">parenleft</symbol>
|
|
||||||
</key>
|
|
||||||
<key name="AD05">
|
|
||||||
<symbol label=")">parenright</symbol>
|
|
||||||
</key>
|
|
||||||
<key name="AC01">
|
|
||||||
<symbol label="4">4</symbol>
|
|
||||||
</key>
|
|
||||||
<key name="AC02">
|
|
||||||
<symbol label="5">5</symbol>
|
|
||||||
</key>
|
|
||||||
<key name="AC03">
|
|
||||||
<symbol label="6">6</symbol>
|
|
||||||
</key>
|
|
||||||
<key name="AC04">
|
|
||||||
<symbol label="#">numbersign</symbol>
|
|
||||||
</key>
|
|
||||||
<key name="AC05">
|
|
||||||
<symbol label="*">asterisk</symbol>
|
|
||||||
</key>
|
|
||||||
<key name="AB01">
|
|
||||||
<symbol label="7">7</symbol>
|
|
||||||
</key>
|
|
||||||
<key name="AB02">
|
|
||||||
<symbol label="8">8</symbol>
|
|
||||||
</key>
|
|
||||||
<key name="AB03">
|
|
||||||
<symbol label="9">9</symbol>
|
|
||||||
</key>
|
|
||||||
<key name="AB04">
|
|
||||||
<symbol label="+">plus</symbol>
|
|
||||||
</key>
|
|
||||||
<key name="AB05">
|
|
||||||
<symbol label="-">minus</symbol>
|
|
||||||
</key>
|
|
||||||
<key name="AB06">
|
|
||||||
<symbol label="0">0</symbol>
|
|
||||||
</key>
|
|
||||||
<key name="RTRN">
|
|
||||||
<symbol keyval="65293" icon="key-enter">Return</symbol>
|
|
||||||
</key>
|
|
||||||
<key name="SPCE">
|
|
||||||
<symbol label=" ">space</symbol>
|
|
||||||
</key>
|
|
||||||
<key name="BKSP">
|
|
||||||
<symbol keyval="65288" icon="edit-clear-symbolic">BackSpace</symbol>
|
|
||||||
</key>
|
|
||||||
</symbols>
|
|
||||||
@ -1,231 +0,0 @@
|
|||||||
<?xml version='1.0' encoding='ASCII' standalone='yes'?>
|
|
||||||
<symbols version="0.90">
|
|
||||||
<key name="AD01">
|
|
||||||
<symbol label="q">q</symbol>
|
|
||||||
<symbol label="Q">Q</symbol>
|
|
||||||
<symbol label=""></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>
|
|
||||||
@ -1,194 +1,276 @@
|
|||||||
<?xml version='1.0' encoding='ASCII' standalone='yes'?>
|
<?xml version="1.0"?>
|
||||||
<symbols version="0.90">
|
<symbols version="0.90">
|
||||||
<key name="AD01">
|
<key keycode="9" name="ESC">
|
||||||
<symbol label="q">q</symbol>
|
<keysym keyval="65307">Escape</keysym>
|
||||||
<symbol label="Q">Q</symbol>
|
|
||||||
<symbol label="1">1</symbol>
|
|
||||||
<symbol label="~">asciitilde</symbol>
|
|
||||||
</key>
|
</key>
|
||||||
<key name="AD02">
|
<key keycode="67" name="FK01">
|
||||||
<symbol label="w">w</symbol>
|
<keysym keyval="65470">F1</keysym>
|
||||||
<symbol label="W">W</symbol>
|
|
||||||
<symbol label="2">2</symbol>
|
|
||||||
<symbol label="`">quoteleft</symbol>
|
|
||||||
</key>
|
</key>
|
||||||
<key name="AD03">
|
<key keycode="68" name="FK02">
|
||||||
<symbol label="e">e</symbol>
|
<keysym keyval="65471">F2</keysym>
|
||||||
<symbol label="E">E</symbol>
|
|
||||||
<symbol label="3">3</symbol>
|
|
||||||
<symbol label="|">bar</symbol>
|
|
||||||
</key>
|
</key>
|
||||||
<key name="AD04">
|
<key keycode="69" name="FK03">
|
||||||
<symbol label="r">r</symbol>
|
<keysym keyval="65472">F3</keysym>
|
||||||
<symbol label="R">R</symbol>
|
|
||||||
<symbol label="4">4</symbol>
|
|
||||||
<symbol label="·">U00B7</symbol>
|
|
||||||
</key>
|
</key>
|
||||||
<key name="AD05">
|
<key keycode="70" name="FK04">
|
||||||
<symbol label="t">t</symbol>
|
<keysym keyval="65473">F4</keysym>
|
||||||
<symbol label="T">T</symbol>
|
|
||||||
<symbol label="5">5</symbol>
|
|
||||||
<symbol label="√">squareroot</symbol>
|
|
||||||
</key>
|
</key>
|
||||||
<key name="AD06">
|
<key keycode="71" name="FK05">
|
||||||
<symbol label="y">y</symbol>
|
<keysym keyval="65474">F5</keysym>
|
||||||
<symbol label="Y">Y</symbol>
|
|
||||||
<symbol label="6">6</symbol>
|
|
||||||
<symbol label="π">Greek_pi</symbol>
|
|
||||||
</key>
|
</key>
|
||||||
<key name="AD07">
|
<key keycode="72" name="FK06">
|
||||||
<symbol label="u">u</symbol>
|
<keysym keyval="65475">F6</keysym>
|
||||||
<symbol label="U">U</symbol>
|
|
||||||
<symbol label="7">7</symbol>
|
|
||||||
<symbol label="÷">division</symbol>
|
|
||||||
</key>
|
</key>
|
||||||
<key name="AD08">
|
<key keycode="73" name="FK07">
|
||||||
<symbol label="i">i</symbol>
|
<keysym keyval="65476">F7</keysym>
|
||||||
<symbol label="I">I</symbol>
|
|
||||||
<symbol label="8">8</symbol>
|
|
||||||
<symbol label="×">multiply</symbol>
|
|
||||||
</key>
|
</key>
|
||||||
<key name="AD09">
|
<key keycode="74" name="FK08">
|
||||||
<symbol label="o">o</symbol>
|
<keysym keyval="65477">F8</keysym>
|
||||||
<symbol label="O">O</symbol>
|
|
||||||
<symbol label="9">9</symbol>
|
|
||||||
<symbol label="¶">paragraph</symbol>
|
|
||||||
</key>
|
</key>
|
||||||
<key name="AD10">
|
<key keycode="75" name="FK09">
|
||||||
<symbol label="p">p</symbol>
|
<keysym keyval="65478">F9</keysym>
|
||||||
<symbol label="P">P</symbol>
|
|
||||||
<symbol label="0">0</symbol>
|
|
||||||
<symbol label="△">U25B3</symbol>
|
|
||||||
</key>
|
</key>
|
||||||
<key name="AC01">
|
<key keycode="76" name="FK10">
|
||||||
<symbol label="a">a</symbol>
|
<keysym keyval="65479">F10</keysym>
|
||||||
<symbol label="A">A</symbol>
|
|
||||||
<symbol label="@">at</symbol>
|
|
||||||
<symbol label="©">copyright</symbol>
|
|
||||||
</key>
|
</key>
|
||||||
<key name="AC02">
|
<key keycode="95" name="FK11">
|
||||||
<symbol label="s">s</symbol>
|
<keysym keyval="65480">F11</keysym>
|
||||||
<symbol label="S">S</symbol>
|
|
||||||
<symbol label="#">numbersign</symbol>
|
|
||||||
<symbol label="®">U00AE</symbol>
|
|
||||||
</key>
|
</key>
|
||||||
<key name="AC03">
|
<key keycode="96" name="FK12">
|
||||||
<symbol label="d">d</symbol>
|
<keysym keyval="65481">F12</keysym>
|
||||||
<symbol label="D">D</symbol>
|
|
||||||
<symbol label="$">dollar</symbol>
|
|
||||||
<symbol label="£">U00A3</symbol>
|
|
||||||
</key>
|
</key>
|
||||||
<key name="AC04">
|
<key keycode="22" name="BKSP">
|
||||||
<symbol label="f">f</symbol>
|
<keysym keyval="65288" icon="edit-clear-symbolic">backspace</keysym>
|
||||||
<symbol label="F">F</symbol>
|
|
||||||
<symbol label="%">percent</symbol>
|
|
||||||
<symbol label="€">EuroSign</symbol>
|
|
||||||
</key>
|
</key>
|
||||||
<key name="AC05">
|
<key keycode="23" name="TAB">
|
||||||
<symbol label="g">g</symbol>
|
<keysym keyval="65289">Tab</keysym>
|
||||||
<symbol label="G">G</symbol>
|
<keysym keyval="65056">ISO_Left_Tab</keysym>
|
||||||
<symbol label="&">ampersand</symbol>
|
|
||||||
<symbol label="¥">U00A5</symbol>
|
|
||||||
</key>
|
</key>
|
||||||
<key name="AC06">
|
<key keycode="24" name="AD01">
|
||||||
<symbol label="h">h</symbol>
|
<keysym keyval="113">q</keysym>
|
||||||
<symbol label="H">H</symbol>
|
<keysym keyval="81">Q</keysym>
|
||||||
<symbol label="-">minus</symbol>
|
<keysym keyval="49">1</keysym>
|
||||||
<symbol label="^">asciicircum</symbol>
|
<keysym keyval="126">asciitilde</keysym>
|
||||||
</key>
|
</key>
|
||||||
<key name="AC07">
|
<key keycode="25" name="AD02">
|
||||||
<symbol label="j">j</symbol>
|
<keysym keyval="119">w</keysym>
|
||||||
<symbol label="J">J</symbol>
|
<keysym keyval="87">W</keysym>
|
||||||
<symbol label="_">underscore</symbol>
|
<keysym keyval="50">2</keysym>
|
||||||
<symbol label="°">degree</symbol>
|
<keysym keyval="96">quoteleft</keysym>
|
||||||
</key>
|
</key>
|
||||||
<key name="AC08">
|
<key keycode="26" name="AD03">
|
||||||
<symbol label="k">k</symbol>
|
<keysym keyval="101">e</keysym>
|
||||||
<symbol label="K">K</symbol>
|
<keysym keyval="69">E</keysym>
|
||||||
<symbol label="+">plus</symbol>
|
<keysym keyval="51">3</keysym>
|
||||||
<symbol label="=">equal</symbol>
|
<keysym keyval="124">bar</keysym>
|
||||||
</key>
|
</key>
|
||||||
<key name="AC09">
|
<key keycode="27" name="AD04">
|
||||||
<symbol label="l">l</symbol>
|
<keysym keyval="114">r</keysym>
|
||||||
<symbol label="L">L</symbol>
|
<keysym keyval="82">R</keysym>
|
||||||
<symbol label="(">parenleft</symbol>
|
<keysym keyval="52">4</keysym>
|
||||||
<symbol label="{">braceleft</symbol>
|
<keysym keyval="183">middledot</keysym>
|
||||||
</key>
|
</key>
|
||||||
<key name="AC10">
|
<key keycode="28" name="AD05">
|
||||||
<!-- Empty labels cause keys to be hidden when the level they are defined
|
<keysym keyval="116">t</keysym>
|
||||||
for is shown. -->
|
<keysym keyval="84">T</keysym>
|
||||||
<symbol label=""></symbol>
|
<keysym keyval="53">5</keysym>
|
||||||
<symbol label=""></symbol>
|
|
||||||
<symbol label=")">parenright</symbol>
|
|
||||||
<symbol label="}">braceright</symbol>
|
|
||||||
</key>
|
</key>
|
||||||
<key name="RTRN">
|
<key keycode="29" name="AD06">
|
||||||
<symbol keyval="65293" icon="key-enter">Return</symbol>
|
<keysym keyval="121">y</keysym>
|
||||||
|
<keysym keyval="89">Y</keysym>
|
||||||
|
<keysym keyval="54">6</keysym>
|
||||||
</key>
|
</key>
|
||||||
<key name="LFSH">
|
<key keycode="30" name="AD07">
|
||||||
|
<keysym keyval="117">u</keysym>
|
||||||
|
<keysym keyval="85">U</keysym>
|
||||||
|
<keysym keyval="55">7</keysym>
|
||||||
|
</key>
|
||||||
|
<key keycode="31" name="AD08">
|
||||||
|
<keysym keyval="105">i</keysym>
|
||||||
|
<keysym keyval="73">I</keysym>
|
||||||
|
<keysym keyval="56">8</keysym>
|
||||||
|
</key>
|
||||||
|
<key keycode="32" name="AD09">
|
||||||
|
<keysym keyval="111">o</keysym>
|
||||||
|
<keysym keyval="79">O</keysym>
|
||||||
|
<keysym keyval="57">9</keysym>
|
||||||
|
</key>
|
||||||
|
<key keycode="33" name="AD10">
|
||||||
|
<keysym keyval="112">p</keysym>
|
||||||
|
<keysym keyval="80">P</keysym>
|
||||||
|
<keysym keyval="48">0</keysym>
|
||||||
|
</key>
|
||||||
|
<key keycode="34" name="AD11">
|
||||||
|
<keysym keyval="91">bracketleft</keysym>
|
||||||
|
<keysym keyval="123">braceleft</keysym>
|
||||||
|
</key>
|
||||||
|
<key keycode="35" name="AD12">
|
||||||
|
<keysym keyval="93">bracketright</keysym>
|
||||||
|
<keysym keyval="125">braceright</keysym>
|
||||||
|
</key>
|
||||||
|
<key keycode="51" name="BKSL">
|
||||||
|
<keysym keyval="92">backslash</keysym>
|
||||||
|
<keysym keyval="124">bar</keysym>
|
||||||
|
</key>
|
||||||
|
<key keycode="0" name="ABC123">
|
||||||
|
<symbol label="123">show-numbers</symbol>
|
||||||
|
<symbol label="123">show-numbers</symbol>
|
||||||
|
<symbol label="ABC">show-letters</symbol>
|
||||||
|
<symbol label="ABC">show-letters</symbol>
|
||||||
|
</key>
|
||||||
|
<key keycode="38" name="AC01">
|
||||||
|
<keysym keyval="97">a</keysym>
|
||||||
|
<keysym keyval="65">A</keysym>
|
||||||
|
<keysym keyval="64">at</keysym>
|
||||||
|
<keysym keyval="169">copyright</keysym>
|
||||||
|
</key>
|
||||||
|
<key keycode="39" name="AC02">
|
||||||
|
<keysym keyval="115">s</keysym>
|
||||||
|
<keysym keyval="83">S</keysym>
|
||||||
|
<keysym keyval="35">numbersign</keysym>
|
||||||
|
<keysym keyval="174">registeredtrademark</keysym>
|
||||||
|
</key>
|
||||||
|
<key keycode="40" name="AC03">
|
||||||
|
<keysym keyval="100">d</keysym>
|
||||||
|
<keysym keyval="68">D</keysym>
|
||||||
|
<keysym keyval="36">dollar</keysym>
|
||||||
|
<keysym keyval="163">poundsign</keysym>
|
||||||
|
</key>
|
||||||
|
<key keycode="41" name="AC04">
|
||||||
|
<keysym keyval="102">f</keysym>
|
||||||
|
<keysym keyval="70">F</keysym>
|
||||||
|
<keysym keyval="37">percent</keysym>
|
||||||
|
<text>€</text>
|
||||||
|
</key>
|
||||||
|
<key keycode="42" name="AC05">
|
||||||
|
<keysym keyval="103">g</keysym>
|
||||||
|
<keysym keyval="71">G</keysym>
|
||||||
|
<keysym keyval="38">ampersand</keysym>
|
||||||
|
<keysym keyval="165">yensign</keysym>
|
||||||
|
</key>
|
||||||
|
<key keycode="43" name="AC06">
|
||||||
|
<keysym keyval="104">h</keysym>
|
||||||
|
<keysym keyval="72">H</keysym>
|
||||||
|
<keysym keyval="45">minus</keysym>
|
||||||
|
<keysym keyval="94">asciicircum</keysym>
|
||||||
|
</key>
|
||||||
|
<key keycode="44" name="AC07">
|
||||||
|
<keysym keyval="106">j</keysym>
|
||||||
|
<keysym keyval="74">J</keysym>
|
||||||
|
<keysym keyval="43">plus</keysym>
|
||||||
|
<keysym keyval="176">degreesign</keysym>
|
||||||
|
</key>
|
||||||
|
<key keycode="45" name="AC08">
|
||||||
|
<keysym keyval="107">k</keysym>
|
||||||
|
<keysym keyval="75">K</keysym>
|
||||||
|
<keysym keyval="40">parenleft</keysym>
|
||||||
|
<keysym keyval="123">braceleft</keysym>
|
||||||
|
</key>
|
||||||
|
<key keycode="46" name="AC09">
|
||||||
|
<keysym keyval="108">l</keysym>
|
||||||
|
<keysym keyval="76">L</keysym>
|
||||||
|
<keysym keyval="41">parenright</keysym>
|
||||||
|
<keysym keyval="125">braceright</keysym>
|
||||||
|
</key>
|
||||||
|
<key keycode="47" name="AC10">
|
||||||
|
<keysym keyval="59">semicolon</keysym>
|
||||||
|
<keysym keyval="58">colon</keysym>
|
||||||
|
</key>
|
||||||
|
<key keycode="48" name="AC11">
|
||||||
|
<keysym keyval="39">quoteright</keysym>
|
||||||
|
<keysym keyval="34">quotedbl</keysym>
|
||||||
|
</key>
|
||||||
|
<key keycode="36" name="RTRN">
|
||||||
|
<keysym keyval="65293" icon="key-enter">Return</keysym>
|
||||||
|
</key>
|
||||||
|
<key keycode="50" name="LFSH">
|
||||||
<keysym keyval="65505" icon="key-shift">Shift_L</keysym>
|
<keysym keyval="65505" icon="key-shift">Shift_L</keysym>
|
||||||
<keysym keyval="65505" icon="key-shift">Shift_L</keysym>
|
<keysym keyval="65505" icon="key-shift">Shift_L</keysym>
|
||||||
<keysym keyval="65505" label="=/+">Shift_L</keysym>
|
<keysym keyval="65505" label="=/+">Shift_L</keysym>
|
||||||
<keysym keyval="65505" label="123">Shift_L</keysym>
|
<keysym keyval="65505" label="123">Shift_L</keysym>
|
||||||
</key>
|
</key>
|
||||||
<key name="AB01">
|
<key keycode="52" name="AB01">
|
||||||
<symbol label="z">z</symbol>
|
<keysym keyval="122">z</keysym>
|
||||||
<symbol label="Z">Z</symbol>
|
<keysym keyval="90">Z</keysym>
|
||||||
<symbol label=",">comma</symbol>
|
<keysym keyval="44">comma</keysym>
|
||||||
<symbol label="\">backslash</symbol>
|
<keysym keyval="92">backslash</keysym>
|
||||||
</key>
|
</key>
|
||||||
<key name="AB02">
|
<key keycode="53" name="AB02">
|
||||||
<symbol label="x">x</symbol>
|
<keysym keyval="120">x</keysym>
|
||||||
<symbol label="X">X</symbol>
|
<keysym keyval="88">X</keysym>
|
||||||
<symbol label=""">quotedbl</symbol>
|
<keysym keyval="34">quotedbl</keysym>
|
||||||
<symbol label="/">slash</symbol>
|
<keysym keyval="47">slash</keysym>
|
||||||
</key>
|
</key>
|
||||||
<key name="AB03">
|
<key keycode="54" name="AB03">
|
||||||
<symbol label="c">c</symbol>
|
<keysym keyval="99">c</keysym>
|
||||||
<symbol label="C">C</symbol>
|
<keysym keyval="67">C</keysym>
|
||||||
<symbol label="'">quoteright</symbol>
|
<keysym keyval="39">quoteright</keysym>
|
||||||
<symbol label="<">less</symbol>
|
<keysym keyval="60">less</keysym>
|
||||||
</key>
|
</key>
|
||||||
<key name="AB04">
|
<key keycode="55" name="AB04">
|
||||||
<symbol label="v">v</symbol>
|
<keysym keyval="118">v</keysym>
|
||||||
<symbol label="V">V</symbol>
|
<keysym keyval="86">V</keysym>
|
||||||
<symbol label=":">colon</symbol>
|
<keysym keyval="58">colon</keysym>
|
||||||
<symbol label=">">greater</symbol>
|
<keysym keyval="62">greater</keysym>
|
||||||
</key>
|
</key>
|
||||||
<key name="AB05">
|
<key keycode="56" name="AB05">
|
||||||
<symbol label="b">b</symbol>
|
<keysym keyval="98">b</keysym>
|
||||||
<symbol label="B">B</symbol>
|
<keysym keyval="66">B</keysym>
|
||||||
<symbol label=";">semicolon</symbol>
|
<keysym keyval="59">semicolon</keysym>
|
||||||
<symbol label="=">equal</symbol>
|
<keysym keyval="61">equal</keysym>
|
||||||
</key>
|
</key>
|
||||||
<key name="AB06">
|
<key keycode="57" name="AB06">
|
||||||
<symbol label="n">n</symbol>
|
<keysym keyval="110">n</keysym>
|
||||||
<symbol label="N">N</symbol>
|
<keysym keyval="78">N</keysym>
|
||||||
<symbol label="!">exclam</symbol>
|
<keysym keyval="33">exclam</keysym>
|
||||||
<symbol label="[">bracketleft</symbol>
|
<keysym keyval="91">bracketleft</keysym>
|
||||||
</key>
|
</key>
|
||||||
<key name="AB07">
|
<key keycode="58" name="AB07">
|
||||||
<symbol label="m">m</symbol>
|
<keysym keyval="109">m</keysym>
|
||||||
<symbol label="M">M</symbol>
|
<keysym keyval="77">M</keysym>
|
||||||
<symbol label="?">question</symbol>
|
<keysym keyval="63">question</keysym>
|
||||||
<symbol label="]">bracketright</symbol>
|
<keysym keyval="93">bracketright</keysym>
|
||||||
</key>
|
</key>
|
||||||
<key name="AB08">
|
<key keycode="59" name="AB08">
|
||||||
<symbol label=".">period</symbol>
|
<keysym keyval="44">comma</keysym>
|
||||||
|
<keysym keyval="60">less</keysym>
|
||||||
</key>
|
</key>
|
||||||
<key name="ABC123">
|
<key keycode="60" name="AB09">
|
||||||
<symbol label="123">show-numbers</symbol>
|
<keysym keyval="46">period</keysym>
|
||||||
<symbol label="123">show-numbers</symbol>
|
|
||||||
<symbol label="ABC">show-letters</symbol>
|
|
||||||
<symbol label="ABC">show-letters</symbol>
|
|
||||||
</key>
|
</key>
|
||||||
<key name="I149">
|
<key keycode="61" name="AB10">
|
||||||
<symbol label="☺" icon="keyboard-mode-symbolic" tooltip="Setup">preferences</symbol>
|
<keysym keyval="47">slash</keysym>
|
||||||
|
<keysym keyval="63">question</keysym>
|
||||||
</key>
|
</key>
|
||||||
<key name="SPCE">
|
<key keycode="62" name="RTSH">
|
||||||
<symbol label=" ">space</symbol>
|
<keysym keyval="65506">Shift_R</keysym>
|
||||||
</key>
|
</key>
|
||||||
<key name="BKSP">
|
<key keycode="149" name="I149">
|
||||||
<symbol keyval="65288" icon="edit-clear-symbolic">BackSpace</symbol>
|
<symbol label="⌨" icon="input-keyboard-symbolic" tooltip="Change keyboard">cycle-keyboard</symbol>
|
||||||
|
</key>
|
||||||
|
<key keycode="150" name="I150">
|
||||||
|
<symbol label="☺" icon="keyboard-mode-symbolic" tooltip="Setup">preferences</symbol>
|
||||||
|
</key>
|
||||||
|
<key keycode="37" name="LCTL">
|
||||||
|
<keysym keyval="65507">Control_L</keysym>
|
||||||
|
</key>
|
||||||
|
<key keycode="64" name="LALT">
|
||||||
|
<keysym keyval="65513">Alt_L</keysym>
|
||||||
|
<keysym keyval="65511">Meta_L</keysym>
|
||||||
|
</key>
|
||||||
|
<key keycode="65" name="SPCE">
|
||||||
|
<keysym keyval="32">space</keysym>
|
||||||
|
</key>
|
||||||
|
<key keycode="113" name="LEFT">
|
||||||
|
<keysym keyval="65361">Left</keysym>
|
||||||
|
</key>
|
||||||
|
<key keycode="111" name="UP">
|
||||||
|
<keysym keyval="65362">Up</keysym>
|
||||||
|
</key>
|
||||||
|
<key keycode="116" name="DOWN">
|
||||||
|
<keysym keyval="65364">Down</keysym>
|
||||||
|
</key>
|
||||||
|
<key keycode="114" name="RGHT">
|
||||||
|
<keysym keyval="65363">Right</keysym>
|
||||||
</key>
|
</key>
|
||||||
</symbols>
|
</symbols>
|
||||||
|
|||||||
@ -2,19 +2,8 @@
|
|||||||
<gresources>
|
<gresources>
|
||||||
<gresource prefix="/sm/puri/squeekboard">
|
<gresource prefix="/sm/puri/squeekboard">
|
||||||
<file compressed="true">style.css</file>
|
<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/compact.xml</file>
|
||||||
<file compressed="true" preprocess="xml-stripblanks">keyboards/geometry/extended.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" preprocess="xml-stripblanks">keyboards/keyboards.xml</file>
|
||||||
|
|
||||||
<!-- Natural language keyboards -->
|
|
||||||
<file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/ar.xml</file>
|
<file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/ar.xml</file>
|
||||||
<file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/as-inscript.xml</file>
|
<file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/as-inscript.xml</file>
|
||||||
<file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/be.xml</file>
|
<file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/be.xml</file>
|
||||||
@ -32,7 +21,6 @@
|
|||||||
<file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/ml-inscript.xml</file>
|
<file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/ml-inscript.xml</file>
|
||||||
<file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/mr-inscript.xml</file>
|
<file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/mr-inscript.xml</file>
|
||||||
<file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/my.xml</file>
|
<file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/my.xml</file>
|
||||||
<file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/nb.xml</file>
|
|
||||||
<file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/or-inscript.xml</file>
|
<file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/or-inscript.xml</file>
|
||||||
<file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/pa-inscript.xml</file>
|
<file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/pa-inscript.xml</file>
|
||||||
<file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/ru.xml</file>
|
<file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/ru.xml</file>
|
||||||
@ -44,13 +32,6 @@
|
|||||||
<file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/ug.xml</file>
|
<file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/ug.xml</file>
|
||||||
<file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/us.xml</file>
|
<file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/us.xml</file>
|
||||||
<file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/zh-bopomofo.xml</file>
|
<file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/zh-bopomofo.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-enter.svg</file>
|
||||||
<file>icons/key-shift.svg</file>
|
<file>icons/key-shift.svg</file>
|
||||||
<file>icons/keyboard-mode-symbolic.svg</file>
|
<file>icons/keyboard-mode-symbolic.svg</file>
|
||||||
|
|||||||
5
debian/control
vendored
5
debian/control
vendored
@ -11,10 +11,7 @@ Build-Depends:
|
|||||||
libcroco3-dev,
|
libcroco3-dev,
|
||||||
libwayland-dev (>= 1.16),
|
libwayland-dev (>= 1.16),
|
||||||
rustc,
|
rustc,
|
||||||
wayland-protocols (>= 1.14),
|
wayland-protocols (>= 1.14)
|
||||||
# for running the tests
|
|
||||||
xvfb,
|
|
||||||
xauth,
|
|
||||||
Standards-Version: 4.1.3
|
Standards-Version: 4.1.3
|
||||||
Homepage: https://source.puri.sm/Librem5/squeekboard
|
Homepage: https://source.puri.sm/Librem5/squeekboard
|
||||||
|
|
||||||
|
|||||||
@ -26,7 +26,9 @@
|
|||||||
* shall be used to implement #EekKeyboard and #EekSection.
|
* shall be used to implement #EekKeyboard and #EekSection.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
#endif /* HAVE_CONFIG_H */
|
||||||
|
|
||||||
#include "eek-container.h"
|
#include "eek-container.h"
|
||||||
|
|
||||||
@ -50,7 +52,7 @@ static void
|
|||||||
eek_container_real_add_child (EekContainer *self,
|
eek_container_real_add_child (EekContainer *self,
|
||||||
EekElement *child)
|
EekElement *child)
|
||||||
{
|
{
|
||||||
EekContainerPrivate *priv = (EekContainerPrivate*)eek_container_get_instance_private (self);
|
EekContainerPrivate *priv = eek_container_get_instance_private (self);
|
||||||
|
|
||||||
g_return_if_fail (EEK_IS_ELEMENT(child));
|
g_return_if_fail (EEK_IS_ELEMENT(child));
|
||||||
g_object_ref (child);
|
g_object_ref (child);
|
||||||
|
|||||||
@ -26,7 +26,9 @@
|
|||||||
* shall be used to implement #EekKeyboard, #EekSection, or #EekKey.
|
* shall be used to implement #EekKeyboard, #EekSection, or #EekKey.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
#endif /* HAVE_CONFIG_H */
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
@ -100,7 +102,6 @@ eek_element_set_property (GObject *object,
|
|||||||
break;
|
break;
|
||||||
case PROP_LEVEL:
|
case PROP_LEVEL:
|
||||||
eek_element_set_level (element, g_value_get_int (value));
|
eek_element_set_level (element, g_value_get_int (value));
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
break;
|
break;
|
||||||
|
|||||||
@ -25,15 +25,15 @@
|
|||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
#ifdef HAVE_LIBCANBERRA
|
#ifdef HAVE_GSOUND
|
||||||
#include <canberra-gtk.h>
|
#include <gsound.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "eek-gtk-keyboard.h"
|
#include "eek-gtk-keyboard.h"
|
||||||
#include "eek-renderer.h"
|
#include "eek-gtk-renderer.h"
|
||||||
#include "eek-keyboard.h"
|
#include "eek-keyboard.h"
|
||||||
#include "eek-section.h"
|
#include "eek-section.h"
|
||||||
#include "eek-key.h"
|
#include "eek-key.h"
|
||||||
@ -55,8 +55,10 @@ typedef struct _EekGtkKeyboardPrivate
|
|||||||
{
|
{
|
||||||
EekRenderer *renderer;
|
EekRenderer *renderer;
|
||||||
EekKeyboard *keyboard;
|
EekKeyboard *keyboard;
|
||||||
GtkCssProvider *css_provider;
|
EekTheme *theme;
|
||||||
GtkStyleContext *scontext;
|
#ifdef HAVE_GSOUND
|
||||||
|
GSoundContext *sound_ctx;
|
||||||
|
#endif
|
||||||
|
|
||||||
GdkEventSequence *sequence; // unowned reference
|
GdkEventSequence *sequence; // unowned reference
|
||||||
} EekGtkKeyboardPrivate;
|
} EekGtkKeyboardPrivate;
|
||||||
@ -67,6 +69,16 @@ static void on_key_pressed (EekKey *key,
|
|||||||
EekGtkKeyboard *self);
|
EekGtkKeyboard *self);
|
||||||
static void on_key_released (EekKey *key,
|
static void on_key_released (EekKey *key,
|
||||||
EekGtkKeyboard *self);
|
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,
|
static void render_pressed_key (GtkWidget *widget,
|
||||||
EekKey *key);
|
EekKey *key);
|
||||||
static void render_locked_key (GtkWidget *widget,
|
static void render_locked_key (GtkWidget *widget,
|
||||||
@ -100,9 +112,12 @@ eek_gtk_keyboard_real_draw (GtkWidget *self,
|
|||||||
gtk_widget_get_allocation (self, &allocation);
|
gtk_widget_get_allocation (self, &allocation);
|
||||||
|
|
||||||
if (!priv->renderer) {
|
if (!priv->renderer) {
|
||||||
PangoContext *pcontext = gtk_widget_get_pango_context (self);
|
PangoContext *pcontext;
|
||||||
|
|
||||||
priv->renderer = eek_renderer_new (priv->keyboard, pcontext, priv->scontext);
|
pcontext = gtk_widget_get_pango_context (self);
|
||||||
|
priv->renderer = eek_gtk_renderer_new (priv->keyboard, pcontext, self);
|
||||||
|
if (priv->theme)
|
||||||
|
eek_renderer_set_theme (priv->renderer, priv->theme);
|
||||||
|
|
||||||
eek_renderer_set_allocation_size (priv->renderer,
|
eek_renderer_set_allocation_size (priv->renderer,
|
||||||
allocation.width,
|
allocation.width,
|
||||||
@ -147,11 +162,9 @@ eek_gtk_keyboard_real_size_allocate (GtkWidget *self,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void depress(EekGtkKeyboard *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);
|
EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (self);
|
||||||
EekKey *key = eek_renderer_find_key_by_position (priv->renderer, x, y);
|
EekKey *key = eek_renderer_find_key_by_position (priv->renderer, x, y);
|
||||||
|
|
||||||
if (key) {
|
if (key) {
|
||||||
eek_keyboard_press_key(priv->keyboard, key, time);
|
eek_keyboard_press_key(priv->keyboard, key, time);
|
||||||
on_key_pressed(key, self);
|
on_key_pressed(key, self);
|
||||||
@ -162,17 +175,16 @@ static void drag(EekGtkKeyboard *self,
|
|||||||
gdouble x, gdouble y, guint32 time) {
|
gdouble x, gdouble y, guint32 time) {
|
||||||
EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (self);
|
EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (self);
|
||||||
EekKey *key = eek_renderer_find_key_by_position (priv->renderer, x, y);
|
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) {
|
if (key) {
|
||||||
|
GList *list, *head;
|
||||||
gboolean found = FALSE;
|
gboolean found = FALSE;
|
||||||
|
|
||||||
|
list = eek_keyboard_get_pressed_keys (priv->keyboard);
|
||||||
for (head = list; head; head = g_list_next (head)) {
|
for (head = list; head; head = g_list_next (head)) {
|
||||||
if (head->data == key) {
|
if (head->data == key)
|
||||||
found = TRUE;
|
found = TRUE;
|
||||||
} else {
|
else {
|
||||||
eek_keyboard_release_key(priv->keyboard, EEK_KEY(head->data), time);
|
eek_keyboard_release_key(priv->keyboard, EEK_KEY(head->data), time);
|
||||||
on_key_released(key, self);
|
on_key_released(key, self);
|
||||||
}
|
}
|
||||||
@ -183,12 +195,6 @@ static void drag(EekGtkKeyboard *self,
|
|||||||
eek_keyboard_press_key(priv->keyboard, key, time);
|
eek_keyboard_press_key(priv->keyboard, key, time);
|
||||||
on_key_pressed(key, self);
|
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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -329,10 +335,18 @@ eek_gtk_keyboard_set_keyboard (EekGtkKeyboard *self,
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
if (priv->keyboard) {
|
if (priv->keyboard) {
|
||||||
|
g_signal_handlers_disconnect_by_data(priv->keyboard, self);
|
||||||
g_object_unref (priv->keyboard);
|
g_object_unref (priv->keyboard);
|
||||||
}
|
}
|
||||||
|
|
||||||
priv->keyboard = g_object_ref (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
|
static void
|
||||||
@ -368,6 +382,7 @@ eek_gtk_keyboard_dispose (GObject *object)
|
|||||||
if (priv->keyboard) {
|
if (priv->keyboard) {
|
||||||
GList *list, *head;
|
GList *list, *head;
|
||||||
|
|
||||||
|
g_signal_handlers_disconnect_by_data(priv->keyboard, self);
|
||||||
list = eek_keyboard_get_pressed_keys (priv->keyboard);
|
list = eek_keyboard_get_pressed_keys (priv->keyboard);
|
||||||
for (head = list; head; head = g_list_next (head)) {
|
for (head = list; head; head = g_list_next (head)) {
|
||||||
g_log("squeek", G_LOG_LEVEL_DEBUG, "emit EekKey pressed");
|
g_log("squeek", G_LOG_LEVEL_DEBUG, "emit EekKey pressed");
|
||||||
@ -379,6 +394,11 @@ eek_gtk_keyboard_dispose (GObject *object)
|
|||||||
priv->keyboard = NULL;
|
priv->keyboard = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (priv->theme) {
|
||||||
|
g_object_unref (priv->theme);
|
||||||
|
priv->theme = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
G_OBJECT_CLASS (eek_gtk_keyboard_parent_class)->dispose (object);
|
G_OBJECT_CLASS (eek_gtk_keyboard_parent_class)->dispose (object);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -419,20 +439,16 @@ eek_gtk_keyboard_class_init (EekGtkKeyboardClass *klass)
|
|||||||
static void
|
static void
|
||||||
eek_gtk_keyboard_init (EekGtkKeyboard *self)
|
eek_gtk_keyboard_init (EekGtkKeyboard *self)
|
||||||
{
|
{
|
||||||
|
#if HAVE_GSOUND
|
||||||
EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (self);
|
EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (self);
|
||||||
|
GError *err = NULL;
|
||||||
|
|
||||||
/* Create a default CSS provider and load a style sheet */
|
priv->sound_ctx = gsound_context_new(NULL, &err);
|
||||||
priv->css_provider = gtk_css_provider_new ();
|
if (!priv->sound_ctx) {
|
||||||
gtk_css_provider_load_from_resource (priv->css_provider,
|
g_warning ("GSound init failed: %s", err->message);
|
||||||
"/sm/puri/squeekboard/style.css");
|
g_clear_error (&err);
|
||||||
|
}
|
||||||
/* Apply the style to the widget */
|
#endif
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -477,15 +493,25 @@ render_pressed_key (GtkWidget *widget,
|
|||||||
{
|
{
|
||||||
EekGtkKeyboard *self = EEK_GTK_KEYBOARD (widget);
|
EekGtkKeyboard *self = EEK_GTK_KEYBOARD (widget);
|
||||||
EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (self);
|
EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (self);
|
||||||
|
EekBounds bounds, large_bounds;
|
||||||
|
|
||||||
GdkWindow *window = gtk_widget_get_window (widget);
|
GdkWindow *window = gtk_widget_get_window (widget);
|
||||||
cairo_region_t *region = gdk_window_get_clip_region (window);
|
cairo_region_t *region = gdk_window_get_clip_region (window);
|
||||||
GdkDrawingContext *context = gdk_window_begin_draw_frame (window, region);
|
GdkDrawingContext *context = gdk_window_begin_draw_frame (window, region);
|
||||||
cairo_t *cr = gdk_drawing_context_get_cairo_context (context);
|
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);
|
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);
|
eek_renderer_render_key (priv->renderer, cr, key, 1.5, TRUE);
|
||||||
|
cairo_restore (cr);
|
||||||
*/
|
*/
|
||||||
gdk_window_end_draw_frame (window, context);
|
gdk_window_end_draw_frame (window, context);
|
||||||
|
|
||||||
@ -498,12 +524,16 @@ render_locked_key (GtkWidget *widget,
|
|||||||
{
|
{
|
||||||
EekGtkKeyboard *self = EEK_GTK_KEYBOARD (widget);
|
EekGtkKeyboard *self = EEK_GTK_KEYBOARD (widget);
|
||||||
EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (self);
|
EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (self);
|
||||||
|
EekBounds bounds;
|
||||||
|
|
||||||
GdkWindow *window = gtk_widget_get_window (widget);
|
GdkWindow *window = gtk_widget_get_window (widget);
|
||||||
cairo_region_t *region = gdk_window_get_clip_region (window);
|
cairo_region_t *region = gdk_window_get_clip_region (window);
|
||||||
GdkDrawingContext *context = gdk_window_begin_draw_frame (window, region);
|
GdkDrawingContext *context = gdk_window_begin_draw_frame (window, region);
|
||||||
cairo_t *cr = gdk_drawing_context_get_cairo_context (context);
|
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);
|
eek_renderer_render_key (priv->renderer, cr, key, 1.0, TRUE);
|
||||||
|
|
||||||
gdk_window_end_draw_frame (window, context);
|
gdk_window_end_draw_frame (window, context);
|
||||||
@ -517,12 +547,16 @@ render_released_key (GtkWidget *widget,
|
|||||||
{
|
{
|
||||||
EekGtkKeyboard *self = EEK_GTK_KEYBOARD (widget);
|
EekGtkKeyboard *self = EEK_GTK_KEYBOARD (widget);
|
||||||
EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (self);
|
EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (self);
|
||||||
|
EekBounds bounds, large_bounds;
|
||||||
|
|
||||||
GdkWindow *window = gtk_widget_get_window (widget);
|
GdkWindow *window = gtk_widget_get_window (widget);
|
||||||
cairo_region_t *region = gdk_window_get_clip_region (window);
|
cairo_region_t *region = gdk_window_get_clip_region (window);
|
||||||
GdkDrawingContext *context = gdk_window_begin_draw_frame (window, region);
|
GdkDrawingContext *context = gdk_window_begin_draw_frame (window, region);
|
||||||
cairo_t *cr = gdk_drawing_context_get_cairo_context (context);
|
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);
|
eek_renderer_render_keyboard (priv->renderer, cr);
|
||||||
|
|
||||||
gdk_window_end_draw_frame (window, context);
|
gdk_window_end_draw_frame (window, context);
|
||||||
@ -543,12 +577,12 @@ on_key_pressed (EekKey *key,
|
|||||||
render_pressed_key (GTK_WIDGET(self), key);
|
render_pressed_key (GTK_WIDGET(self), key);
|
||||||
gtk_widget_queue_draw (GTK_WIDGET(self));
|
gtk_widget_queue_draw (GTK_WIDGET(self));
|
||||||
|
|
||||||
#if HAVE_LIBCANBERRA
|
#if HAVE_GSOUND
|
||||||
ca_gtk_play_for_widget (widget, 0,
|
g_return_if_fail (GSOUND_IS_CONTEXT (priv->sound_ctx));
|
||||||
CA_PROP_EVENT_ID, "button-pressed",
|
gsound_context_play_simple(priv->sound_ctx, NULL, NULL,
|
||||||
CA_PROP_EVENT_DESCRIPTION, "virtual key pressed",
|
GSOUND_ATTR_EVENT_ID, "button-pressed",
|
||||||
CA_PROP_APPLICATION_ID, "org.fedorahosted.Eekboard",
|
GSOUND_ATTR_EVENT_DESCRIPTION, "Button pressed",
|
||||||
NULL);
|
NULL);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -565,11 +599,65 @@ on_key_released (EekKey *key,
|
|||||||
render_released_key (GTK_WIDGET(self), key);
|
render_released_key (GTK_WIDGET(self), key);
|
||||||
gtk_widget_queue_draw (GTK_WIDGET(self));
|
gtk_widget_queue_draw (GTK_WIDGET(self));
|
||||||
|
|
||||||
#if HAVE_LIBCANBERRA
|
#if HAVE_GSOUND
|
||||||
ca_gtk_play_for_widget (widget, 0,
|
g_return_if_fail (GSOUND_IS_CONTEXT (priv->sound_ctx));
|
||||||
CA_PROP_EVENT_ID, "button-released",
|
gsound_context_play_simple(priv->sound_ctx, NULL, NULL,
|
||||||
CA_PROP_EVENT_DESCRIPTION, "virtual key pressed",
|
GSOUND_ATTR_EVENT_ID, "button-released",
|
||||||
CA_PROP_APPLICATION_ID, "org.fedorahosted.Eekboard",
|
GSOUND_ATTR_EVENT_DESCRIPTION, "Button released",
|
||||||
NULL);
|
NULL);
|
||||||
#endif
|
#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,6 +46,8 @@ struct _EekGtkKeyboardClass
|
|||||||
|
|
||||||
GType eek_gtk_keyboard_get_type (void) G_GNUC_CONST;
|
GType eek_gtk_keyboard_get_type (void) G_GNUC_CONST;
|
||||||
GtkWidget *eek_gtk_keyboard_new (EekKeyboard *keyboard);
|
GtkWidget *eek_gtk_keyboard_new (EekKeyboard *keyboard);
|
||||||
|
void eek_gtk_keyboard_set_theme (EekGtkKeyboard *keyboard,
|
||||||
|
EekTheme *theme);
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
#endif /* EEK_GTK_KEYBOARD_H */
|
#endif /* EEK_GTK_KEYBOARD_H */
|
||||||
|
|||||||
84
eek/eek-gtk-renderer.c
Normal file
84
eek/eek-gtk-renderer.c
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2011 Daiki Ueno <ueno@unixuser.org>
|
||||||
|
* Copyright (C) 2011 Red Hat, Inc.
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2 of
|
||||||
|
* the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||||
|
* 02110-1301 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "config.h"
|
||||||
|
#endif /* HAVE_CONFIG_H */
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include <gdk-pixbuf/gdk-pixbuf.h>
|
||||||
|
|
||||||
|
#include "eek-gtk-renderer.h"
|
||||||
|
#include "eek-key.h"
|
||||||
|
|
||||||
|
G_DEFINE_TYPE (EekGtkRenderer, eek_gtk_renderer, EEK_TYPE_RENDERER);
|
||||||
|
|
||||||
|
static cairo_surface_t *
|
||||||
|
eek_gtk_renderer_real_get_icon_surface (EekRenderer *self,
|
||||||
|
const gchar *icon_name,
|
||||||
|
gint size,
|
||||||
|
gint scale)
|
||||||
|
{
|
||||||
|
GError *error = NULL;
|
||||||
|
cairo_surface_t *surface;
|
||||||
|
|
||||||
|
surface = gtk_icon_theme_load_surface (gtk_icon_theme_get_default (),
|
||||||
|
icon_name,
|
||||||
|
size,
|
||||||
|
scale,
|
||||||
|
NULL,
|
||||||
|
0,
|
||||||
|
&error);
|
||||||
|
if (surface == NULL) {
|
||||||
|
g_warning ("can't get icon surface for %s: %s",
|
||||||
|
icon_name,
|
||||||
|
error->message);
|
||||||
|
g_error_free (error);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return surface;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
eek_gtk_renderer_class_init (EekGtkRendererClass *klass)
|
||||||
|
{
|
||||||
|
EekRendererClass *renderer_class = EEK_RENDERER_CLASS (klass);
|
||||||
|
|
||||||
|
renderer_class->get_icon_surface = eek_gtk_renderer_real_get_icon_surface;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
eek_gtk_renderer_init (EekGtkRenderer *self)
|
||||||
|
{
|
||||||
|
GtkIconTheme *theme = gtk_icon_theme_get_default ();
|
||||||
|
|
||||||
|
gtk_icon_theme_add_resource_path (theme, "/sm/puri/squeekboard/icons");
|
||||||
|
}
|
||||||
|
|
||||||
|
EekRenderer *
|
||||||
|
eek_gtk_renderer_new (EekKeyboard *keyboard,
|
||||||
|
PangoContext *pcontext,
|
||||||
|
GtkWidget *widget)
|
||||||
|
{
|
||||||
|
return g_object_new (EEK_TYPE_GTK_RENDERER,
|
||||||
|
"keyboard", keyboard,
|
||||||
|
"pango-context", pcontext,
|
||||||
|
NULL);
|
||||||
|
}
|
||||||
61
eek/eek-gtk-renderer.h
Normal file
61
eek/eek-gtk-renderer.h
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2010-2011 Daiki Ueno <ueno@unixuser.org>
|
||||||
|
* Copyright (C) 2010-2011 Red Hat, Inc.
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2 of
|
||||||
|
* the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||||
|
* 02110-1301 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef EEK_GTK_RENDERER_H
|
||||||
|
#define EEK_GTK_RENDERER_H 1
|
||||||
|
|
||||||
|
#include <gtk/gtk.h>
|
||||||
|
#include "eek-renderer.h"
|
||||||
|
|
||||||
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
#define EEK_TYPE_GTK_RENDERER (eek_gtk_renderer_get_type())
|
||||||
|
#define EEK_GTK_RENDERER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EEK_TYPE_GTK_RENDERER, EekGtkRenderer))
|
||||||
|
#define EEK_GTK_RENDERER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EEK_TYPE_GTK_RENDERER, EekGtkRendererClass))
|
||||||
|
#define EEK_IS_GTK_RENDERER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EEK_TYPE_GTK_RENDERER))
|
||||||
|
#define EEK_IS_GTK_RENDERER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EEK_TYPE_GTK_RENDERER))
|
||||||
|
#define EEK_GTK_RENDERER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EEK_TYPE_GTK_RENDERER, EekGtkRendererClass))
|
||||||
|
|
||||||
|
typedef struct _EekGtkRenderer EekGtkRenderer;
|
||||||
|
typedef struct _EekGtkRendererClass EekGtkRendererClass;
|
||||||
|
typedef struct _EekGtkRendererPrivate EekGtkRendererPrivate;
|
||||||
|
|
||||||
|
struct _EekGtkRenderer {
|
||||||
|
EekRenderer parent;
|
||||||
|
|
||||||
|
EekGtkRendererPrivate *priv;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct _EekGtkRendererClass
|
||||||
|
{
|
||||||
|
EekRendererClass parent_class;
|
||||||
|
|
||||||
|
/*< private >*/
|
||||||
|
/* padding */
|
||||||
|
gpointer pdummy[24];
|
||||||
|
};
|
||||||
|
|
||||||
|
GType eek_gtk_renderer_get_type (void) G_GNUC_CONST;
|
||||||
|
EekRenderer *eek_gtk_renderer_new (EekKeyboard *keyboard,
|
||||||
|
PangoContext *pcontext,
|
||||||
|
GtkWidget *widget);
|
||||||
|
|
||||||
|
G_END_DECLS
|
||||||
|
#endif /* EEK_GTK_RENDERER_H */
|
||||||
111
eek/eek-key.c
111
eek/eek-key.c
@ -25,7 +25,9 @@
|
|||||||
* The #EekKeyClass class represents a key.
|
* The #EekKeyClass class represents a key.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
#endif /* HAVE_CONFIG_H */
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
@ -38,6 +40,8 @@ enum {
|
|||||||
PROP_0,
|
PROP_0,
|
||||||
PROP_KEYCODE,
|
PROP_KEYCODE,
|
||||||
PROP_SYMBOL_MATRIX,
|
PROP_SYMBOL_MATRIX,
|
||||||
|
PROP_COLUMN,
|
||||||
|
PROP_ROW,
|
||||||
PROP_OREF,
|
PROP_OREF,
|
||||||
PROP_LAST
|
PROP_LAST
|
||||||
};
|
};
|
||||||
@ -54,6 +58,8 @@ typedef struct _EekKeyPrivate
|
|||||||
{
|
{
|
||||||
guint keycode;
|
guint keycode;
|
||||||
EekSymbolMatrix *symbol_matrix;
|
EekSymbolMatrix *symbol_matrix;
|
||||||
|
gint column;
|
||||||
|
gint row;
|
||||||
gulong oref; // UI outline reference
|
gulong oref; // UI outline reference
|
||||||
gboolean is_pressed;
|
gboolean is_pressed;
|
||||||
gboolean is_locked;
|
gboolean is_locked;
|
||||||
@ -101,6 +107,8 @@ eek_key_set_property (GObject *object,
|
|||||||
GParamSpec *pspec)
|
GParamSpec *pspec)
|
||||||
{
|
{
|
||||||
EekSymbolMatrix *matrix;
|
EekSymbolMatrix *matrix;
|
||||||
|
gint column, row;
|
||||||
|
|
||||||
switch (prop_id) {
|
switch (prop_id) {
|
||||||
case PROP_KEYCODE:
|
case PROP_KEYCODE:
|
||||||
eek_key_set_keycode (EEK_KEY(object), g_value_get_uint (value));
|
eek_key_set_keycode (EEK_KEY(object), g_value_get_uint (value));
|
||||||
@ -109,6 +117,14 @@ eek_key_set_property (GObject *object,
|
|||||||
matrix = g_value_get_boxed (value);
|
matrix = g_value_get_boxed (value);
|
||||||
eek_key_set_symbol_matrix (EEK_KEY(object), matrix);
|
eek_key_set_symbol_matrix (EEK_KEY(object), matrix);
|
||||||
break;
|
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:
|
case PROP_OREF:
|
||||||
eek_key_set_oref (EEK_KEY(object), g_value_get_uint (value));
|
eek_key_set_oref (EEK_KEY(object), g_value_get_uint (value));
|
||||||
break;
|
break;
|
||||||
@ -124,6 +140,8 @@ eek_key_get_property (GObject *object,
|
|||||||
GValue *value,
|
GValue *value,
|
||||||
GParamSpec *pspec)
|
GParamSpec *pspec)
|
||||||
{
|
{
|
||||||
|
gint column, row;
|
||||||
|
|
||||||
switch (prop_id) {
|
switch (prop_id) {
|
||||||
case PROP_KEYCODE:
|
case PROP_KEYCODE:
|
||||||
g_value_set_uint (value, eek_key_get_keycode (EEK_KEY(object)));
|
g_value_set_uint (value, eek_key_get_keycode (EEK_KEY(object)));
|
||||||
@ -132,6 +150,14 @@ eek_key_get_property (GObject *object,
|
|||||||
g_value_set_boxed (value,
|
g_value_set_boxed (value,
|
||||||
eek_key_get_symbol_matrix (EEK_KEY(object)));
|
eek_key_get_symbol_matrix (EEK_KEY(object)));
|
||||||
break;
|
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:
|
case PROP_OREF:
|
||||||
g_value_set_uint (value, eek_key_get_oref (EEK_KEY(object)));
|
g_value_set_uint (value, eek_key_get_oref (EEK_KEY(object)));
|
||||||
break;
|
break;
|
||||||
@ -179,6 +205,30 @@ eek_key_class_init (EekKeyClass *klass)
|
|||||||
G_PARAM_READWRITE);
|
G_PARAM_READWRITE);
|
||||||
g_object_class_install_property (gobject_class, PROP_SYMBOL_MATRIX, pspec);
|
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:
|
* EekKey:oref:
|
||||||
*
|
*
|
||||||
@ -430,6 +480,59 @@ eek_key_get_symbol_at_index (EekKey *key,
|
|||||||
level];
|
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:
|
* eek_key_set_oref:
|
||||||
* @key: an #EekKey
|
* @key: an #EekKey
|
||||||
@ -508,11 +611,3 @@ void eek_key_set_pressed(EekKey *key, gboolean value)
|
|||||||
|
|
||||||
priv->is_pressed = value;
|
priv->is_pressed = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
gboolean
|
|
||||||
eek_key_has_label(EekKey *key)
|
|
||||||
{
|
|
||||||
EekSymbol *symbol = eek_key_get_symbol(key);
|
|
||||||
return (eek_symbol_get_label(symbol) != NULL) ||
|
|
||||||
(eek_symbol_get_icon_name(symbol) != NULL);
|
|
||||||
}
|
|
||||||
|
|||||||
@ -73,6 +73,13 @@ EekSymbol *eek_key_get_symbol_at_index (EekKey *key,
|
|||||||
gint fallback_group,
|
gint fallback_group,
|
||||||
gint fallback_level);
|
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,
|
void eek_key_set_oref (EekKey *key,
|
||||||
guint oref);
|
guint oref);
|
||||||
guint eek_key_get_oref (EekKey *key);
|
guint eek_key_get_oref (EekKey *key);
|
||||||
@ -82,7 +89,5 @@ gboolean eek_key_is_locked (EekKey *key);
|
|||||||
void eek_key_set_pressed (EekKey *key,
|
void eek_key_set_pressed (EekKey *key,
|
||||||
gboolean value);
|
gboolean value);
|
||||||
|
|
||||||
gboolean eek_key_has_label (EekKey *key);
|
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
#endif /* EEK_KEY_H */
|
#endif /* EEK_KEY_H */
|
||||||
|
|||||||
@ -17,7 +17,9 @@
|
|||||||
* Boston, MA 02111-1307, USA.
|
* Boston, MA 02111-1307, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
#endif /* HAVE_CONFIG_H */
|
||||||
|
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <pango/pangocairo.h>
|
#include <pango/pangocairo.h>
|
||||||
|
|||||||
@ -27,8 +27,9 @@
|
|||||||
* of one or more sections of the #EekSectionClass class.
|
* of one or more sections of the #EekSectionClass class.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include <glib/gprintf.h>
|
#endif /* HAVE_CONFIG_H */
|
||||||
|
|
||||||
#include "eek-keyboard.h"
|
#include "eek-keyboard.h"
|
||||||
#include "eek-marshalers.h"
|
#include "eek-marshalers.h"
|
||||||
@ -37,7 +38,6 @@
|
|||||||
#include "eek-symbol.h"
|
#include "eek-symbol.h"
|
||||||
#include "eek-enumtypes.h"
|
#include "eek-enumtypes.h"
|
||||||
#include "eekboard/key-emitter.h"
|
#include "eekboard/key-emitter.h"
|
||||||
#include "keymap.h"
|
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
PROP_0,
|
PROP_0,
|
||||||
@ -74,11 +74,7 @@ struct _EekKeyboardPrivate
|
|||||||
GList *pressed_keys;
|
GList *pressed_keys;
|
||||||
GList *locked_keys;
|
GList *locked_keys;
|
||||||
GArray *outline_array;
|
GArray *outline_array;
|
||||||
|
GHashTable *keycodes;
|
||||||
/* Map key names to key objects */
|
|
||||||
GHashTable *names;
|
|
||||||
/* Map characters to symbols and levels */
|
|
||||||
GHashTable *character_map;
|
|
||||||
|
|
||||||
/* modifiers dynamically assigned at run time */
|
/* modifiers dynamically assigned at run time */
|
||||||
EekModifierType num_lock_mask;
|
EekModifierType num_lock_mask;
|
||||||
@ -133,9 +129,9 @@ section_child_added_cb (EekContainer *container,
|
|||||||
EekElement *element,
|
EekElement *element,
|
||||||
EekKeyboard *keyboard)
|
EekKeyboard *keyboard)
|
||||||
{
|
{
|
||||||
const gchar *name = eek_element_get_name(element);
|
guint keycode = eek_key_get_keycode (EEK_KEY(element));
|
||||||
g_hash_table_insert (keyboard->priv->names,
|
g_hash_table_insert (keyboard->priv->keycodes,
|
||||||
(gpointer)name,
|
GUINT_TO_POINTER(keycode),
|
||||||
element);
|
element);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -144,9 +140,9 @@ section_child_removed_cb (EekContainer *container,
|
|||||||
EekElement *element,
|
EekElement *element,
|
||||||
EekKeyboard *keyboard)
|
EekKeyboard *keyboard)
|
||||||
{
|
{
|
||||||
const gchar *name = eek_element_get_name(element);
|
guint keycode = eek_key_get_keycode (EEK_KEY(element));
|
||||||
g_hash_table_remove (keyboard->priv->names,
|
g_hash_table_remove (keyboard->priv->keycodes,
|
||||||
name);
|
GUINT_TO_POINTER(keycode));
|
||||||
}
|
}
|
||||||
|
|
||||||
static EekSection *
|
static EekSection *
|
||||||
@ -225,7 +221,7 @@ set_level_from_modifiers (EekKeyboard *self, EekKey *key)
|
|||||||
gint level = priv->old_level & 2;
|
gint level = priv->old_level & 2;
|
||||||
|
|
||||||
/* Handle non-emitting keys */
|
/* Handle non-emitting keys */
|
||||||
if (key) {
|
if (key && (eek_key_get_keycode(key) == 0)) {
|
||||||
const gchar *name = eek_element_get_name(EEK_ELEMENT(key));
|
const gchar *name = eek_element_get_name(EEK_ELEMENT(key));
|
||||||
if (g_strcmp0(name, "ABC123") == 0)
|
if (g_strcmp0(name, "ABC123") == 0)
|
||||||
level ^= 2;
|
level ^= 2;
|
||||||
@ -268,8 +264,6 @@ set_level_from_modifiers (EekKeyboard *self, EekKey *key)
|
|||||||
|
|
||||||
priv->old_level = level;
|
priv->old_level = level;
|
||||||
eek_element_set_level (EEK_ELEMENT(self), level);
|
eek_element_set_level (EEK_ELEMENT(self), level);
|
||||||
|
|
||||||
eek_layout_update_layout(self);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -406,8 +400,7 @@ eek_keyboard_finalize (GObject *object)
|
|||||||
g_list_free_full (priv->locked_keys,
|
g_list_free_full (priv->locked_keys,
|
||||||
(GDestroyNotify) eek_modifier_key_free);
|
(GDestroyNotify) eek_modifier_key_free);
|
||||||
|
|
||||||
g_hash_table_destroy (priv->names);
|
g_hash_table_destroy (priv->keycodes);
|
||||||
g_hash_table_destroy (priv->character_map);
|
|
||||||
|
|
||||||
for (i = 0; i < priv->outline_array->len; i++) {
|
for (i = 0; i < priv->outline_array->len; i++) {
|
||||||
EekOutline *outline = &g_array_index (priv->outline_array,
|
EekOutline *outline = &g_array_index (priv->outline_array,
|
||||||
@ -535,11 +528,8 @@ eek_keyboard_init (EekKeyboard *self)
|
|||||||
self->priv = EEK_KEYBOARD_GET_PRIVATE(self);
|
self->priv = EEK_KEYBOARD_GET_PRIVATE(self);
|
||||||
self->priv->modifier_behavior = EEK_MODIFIER_BEHAVIOR_NONE;
|
self->priv->modifier_behavior = EEK_MODIFIER_BEHAVIOR_NONE;
|
||||||
self->priv->outline_array = g_array_new (FALSE, TRUE, sizeof (EekOutline));
|
self->priv->outline_array = g_array_new (FALSE, TRUE, sizeof (EekOutline));
|
||||||
self->priv->names = g_hash_table_new (g_str_hash, g_str_equal);
|
self->priv->keycodes = g_hash_table_new (g_direct_hash, g_direct_equal);
|
||||||
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);
|
eek_element_set_symbol_index (EEK_ELEMENT(self), 0, 0);
|
||||||
self->scale = 1.0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -558,20 +548,20 @@ eek_keyboard_create_section (EekKeyboard *keyboard)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* eek_keyboard_find_key_by_name:
|
* eek_keyboard_find_key_by_keycode:
|
||||||
* @keyboard: an #EekKeyboard
|
* @keyboard: an #EekKeyboard
|
||||||
* @name: a key name
|
* @keycode: a keycode
|
||||||
*
|
*
|
||||||
* Find an #EekKey whose name is @name.
|
* Find an #EekKey whose keycode is @keycode.
|
||||||
* Return value: (transfer none): #EekKey whose name is @name
|
* Return value: (transfer none): #EekKey whose keycode is @keycode
|
||||||
*/
|
*/
|
||||||
EekKey *
|
EekKey *
|
||||||
eek_keyboard_find_key_by_name (EekKeyboard *keyboard,
|
eek_keyboard_find_key_by_keycode (EekKeyboard *keyboard,
|
||||||
const gchar *name)
|
guint keycode)
|
||||||
{
|
{
|
||||||
g_return_val_if_fail (EEK_IS_KEYBOARD(keyboard), NULL);
|
g_return_val_if_fail (EEK_IS_KEYBOARD(keyboard), NULL);
|
||||||
return g_hash_table_lookup (keyboard->priv->names,
|
return g_hash_table_lookup (keyboard->priv->keycodes,
|
||||||
name);
|
GUINT_TO_POINTER(keycode));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -805,117 +795,3 @@ eek_keyboard_get_locked_keys (EekKeyboard *keyboard)
|
|||||||
g_return_val_if_fail (EEK_IS_KEYBOARD(keyboard), NULL);
|
g_return_val_if_fail (EEK_IS_KEYBOARD(keyboard), NULL);
|
||||||
return g_list_copy (keyboard->priv->locked_keys);
|
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);
|
|
||||||
}
|
|
||||||
|
|||||||
@ -62,7 +62,6 @@ struct _EekKeyboard
|
|||||||
struct xkb_keymap *keymap;
|
struct xkb_keymap *keymap;
|
||||||
int keymap_fd; // keymap formatted as XKB string
|
int keymap_fd; // keymap formatted as XKB string
|
||||||
size_t keymap_len; // length of the data inside keymap_fd
|
size_t keymap_len; // length of the data inside keymap_fd
|
||||||
double scale;
|
|
||||||
|
|
||||||
EekboardContextService *manager; // unowned reference
|
EekboardContextService *manager; // unowned reference
|
||||||
};
|
};
|
||||||
@ -70,8 +69,8 @@ struct _EekKeyboard
|
|||||||
/**
|
/**
|
||||||
* EekKeyboardClass:
|
* EekKeyboardClass:
|
||||||
* @create_section: virtual function for creating a section
|
* @create_section: virtual function for creating a section
|
||||||
* @find_key_by_name: virtual function for finding a key in the
|
* @find_key_by_keycode: virtual function for finding a key in the
|
||||||
* keyboard by name
|
* keyboard by keycode
|
||||||
* @key_pressed: class handler for #EekKeyboard::key-pressed signal
|
* @key_pressed: class handler for #EekKeyboard::key-pressed signal
|
||||||
* @key_released: class handler for #EekKeyboard::key-released signal
|
* @key_released: class handler for #EekKeyboard::key-released signal
|
||||||
* @key_locked: class handler for #EekKeyboard::key-locked signal
|
* @key_locked: class handler for #EekKeyboard::key-locked signal
|
||||||
@ -90,8 +89,8 @@ struct _EekKeyboardClass
|
|||||||
/*< public >*/
|
/*< public >*/
|
||||||
EekSection *(* create_section) (EekKeyboard *self);
|
EekSection *(* create_section) (EekKeyboard *self);
|
||||||
|
|
||||||
EekKey *(* find_key_by_name) (EekKeyboard *self,
|
EekKey *(* find_key_by_keycode) (EekKeyboard *self,
|
||||||
const gchar *name);
|
guint keycode);
|
||||||
|
|
||||||
/*< private >*/
|
/*< private >*/
|
||||||
/* obsolete members moved to EekElement */
|
/* obsolete members moved to EekElement */
|
||||||
@ -124,11 +123,6 @@ struct _EekModifierKey {
|
|||||||
};
|
};
|
||||||
typedef struct _EekModifierKey EekModifierKey;
|
typedef struct _EekModifierKey EekModifierKey;
|
||||||
|
|
||||||
struct _EekKeyPress {
|
|
||||||
EekKey *key;
|
|
||||||
guint level;
|
|
||||||
};
|
|
||||||
typedef struct _EekKeyPress EekKeyPress;
|
|
||||||
|
|
||||||
EekKeyboard *eek_keyboard_new (EekboardContextService *manager,
|
EekKeyboard *eek_keyboard_new (EekboardContextService *manager,
|
||||||
EekLayout *layout,
|
EekLayout *layout,
|
||||||
@ -161,9 +155,9 @@ EekModifierType eek_keyboard_get_modifiers
|
|||||||
EekSection *eek_keyboard_create_section
|
EekSection *eek_keyboard_create_section
|
||||||
(EekKeyboard *keyboard);
|
(EekKeyboard *keyboard);
|
||||||
|
|
||||||
EekKey *eek_keyboard_find_key_by_name
|
EekKey *eek_keyboard_find_key_by_keycode
|
||||||
(EekKeyboard *keyboard,
|
(EekKeyboard *keyboard,
|
||||||
const gchar *name);
|
guint keycode);
|
||||||
|
|
||||||
guint eek_keyboard_add_outline
|
guint eek_keyboard_add_outline
|
||||||
(EekKeyboard *keyboard,
|
(EekKeyboard *keyboard,
|
||||||
@ -200,18 +194,5 @@ void eek_modifier_key_free
|
|||||||
void eek_keyboard_press_key(EekKeyboard *keyboard, EekKey *key, guint32 timestamp);
|
void eek_keyboard_press_key(EekKeyboard *keyboard, EekKey *key, guint32 timestamp);
|
||||||
void eek_keyboard_release_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
|
G_END_DECLS
|
||||||
#endif /* EEK_KEYBOARD_H */
|
#endif /* EEK_KEYBOARD_H */
|
||||||
|
|||||||
124
eek/eek-keysym.c
124
eek/eek-keysym.c
@ -23,7 +23,9 @@
|
|||||||
* @short_description: an #EekSymbol represents an X keysym
|
* @short_description: an #EekSymbol represents an X keysym
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
#endif /* HAVE_CONFIG_H */
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
@ -48,9 +50,15 @@
|
|||||||
#define EEK_KEYSYM_Hyper_L 0xffed
|
#define EEK_KEYSYM_Hyper_L 0xffed
|
||||||
#define EEK_KEYSYM_Hyper_R 0xffee
|
#define EEK_KEYSYM_Hyper_R 0xffee
|
||||||
|
|
||||||
|
typedef struct _EekKeysymPrivate
|
||||||
|
{
|
||||||
|
guint xkeysym;
|
||||||
|
} EekKeysymPrivate;
|
||||||
|
|
||||||
struct _EekKeysymEntry {
|
struct _EekKeysymEntry {
|
||||||
guint xkeysym;
|
guint xkeysym;
|
||||||
const gchar *name;
|
const gchar *name;
|
||||||
|
EekSymbolCategory category;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct _EekKeysymEntry EekKeysymEntry;
|
typedef struct _EekKeysymEntry EekKeysymEntry;
|
||||||
@ -59,6 +67,54 @@ typedef struct _EekKeysymEntry EekKeysymEntry;
|
|||||||
#include "eek-unicode-keysym-entries.h"
|
#include "eek-unicode-keysym-entries.h"
|
||||||
#include "eek-xkeysym-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 *
|
static gchar *
|
||||||
unichar_to_utf8 (gunichar uc)
|
unichar_to_utf8 (gunichar uc)
|
||||||
@ -143,6 +199,18 @@ get_modifier_mask (guint xkeysym)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
eek_keysym_class_init (EekKeysymClass *klass)
|
||||||
|
{
|
||||||
|
/* void */
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
eek_keysym_init (EekKeysym *self)
|
||||||
|
{
|
||||||
|
/* void */
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* eek_keysym_new_with_modifier:
|
* eek_keysym_new_with_modifier:
|
||||||
* @xkeysym: an X keysym value
|
* @xkeysym: an X keysym value
|
||||||
@ -151,12 +219,16 @@ get_modifier_mask (guint xkeysym)
|
|||||||
* Create an #EekKeysym with given X keysym value @xkeysym and
|
* Create an #EekKeysym with given X keysym value @xkeysym and
|
||||||
* modifier @modifier_mask.
|
* modifier @modifier_mask.
|
||||||
*/
|
*/
|
||||||
EekSymbol *eek_keysym_new_with_modifier(guint xkeysym,
|
EekKeysym *
|
||||||
EekModifierType modifier_mask)
|
eek_keysym_new_with_modifier (guint xkeysym,
|
||||||
|
EekModifierType modifier_mask)
|
||||||
{
|
{
|
||||||
|
EekKeysym *keysym;
|
||||||
|
EekKeysymPrivate *priv;
|
||||||
EekKeysymEntry *special_entry, *xkeysym_entry, *unicode_entry,
|
EekKeysymEntry *special_entry, *xkeysym_entry, *unicode_entry,
|
||||||
*unichar_entry;
|
*unichar_entry;
|
||||||
gchar *name, *label;
|
gchar *name, *label;
|
||||||
|
EekSymbolCategory category;
|
||||||
gunichar uc;
|
gunichar uc;
|
||||||
|
|
||||||
special_entry =
|
special_entry =
|
||||||
@ -176,17 +248,23 @@ EekSymbol *eek_keysym_new_with_modifier(guint xkeysym,
|
|||||||
unichar_entry = g_slice_new (EekKeysymEntry);
|
unichar_entry = g_slice_new (EekKeysymEntry);
|
||||||
unichar_entry->xkeysym = xkeysym;
|
unichar_entry->xkeysym = xkeysym;
|
||||||
unichar_entry->name = unichar_to_utf8 (uc);
|
unichar_entry->name = unichar_to_utf8 (uc);
|
||||||
|
unichar_entry->category = EEK_SYMBOL_CATEGORY_LETTER;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* name and category */
|
||||||
name = NULL;
|
name = NULL;
|
||||||
if (xkeysym_entry) {
|
if (xkeysym_entry) {
|
||||||
name = g_strdup (xkeysym_entry->name);
|
name = g_strdup (xkeysym_entry->name);
|
||||||
|
category = xkeysym_entry->category;
|
||||||
} else if (unichar_entry) {
|
} else if (unichar_entry) {
|
||||||
name = g_strdup (unichar_entry->name);
|
name = g_strdup (unichar_entry->name);
|
||||||
|
category = unichar_entry->category;
|
||||||
} else if (unicode_entry) {
|
} else if (unicode_entry) {
|
||||||
name = g_strdup (unicode_entry->name);
|
name = g_strdup (unicode_entry->name);
|
||||||
|
category = unicode_entry->category;
|
||||||
} else {
|
} else {
|
||||||
name = g_strdup ("");
|
name = g_strdup ("");
|
||||||
|
category = EEK_SYMBOL_CATEGORY_UNKNOWN;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* label */
|
/* label */
|
||||||
@ -199,10 +277,12 @@ EekSymbol *eek_keysym_new_with_modifier(guint xkeysym,
|
|||||||
else
|
else
|
||||||
label = g_strdup (name);
|
label = g_strdup (name);
|
||||||
|
|
||||||
EekSymbol *keysym = eek_symbol_new(name);
|
keysym = g_object_new (EEK_TYPE_KEYSYM,
|
||||||
eek_symbol_set_label(keysym, label);
|
"name", name,
|
||||||
eek_symbol_set_modifier_mask(keysym, modifier_mask);
|
"label", label,
|
||||||
|
"category", category,
|
||||||
|
"modifier-mask", modifier_mask,
|
||||||
|
NULL);
|
||||||
g_free (name);
|
g_free (name);
|
||||||
g_free (label);
|
g_free (label);
|
||||||
|
|
||||||
@ -211,7 +291,8 @@ EekSymbol *eek_keysym_new_with_modifier(guint xkeysym,
|
|||||||
g_slice_free (EekKeysymEntry, unichar_entry);
|
g_slice_free (EekKeysymEntry, unichar_entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
keysym->xkeysym = xkeysym;
|
priv = eek_keysym_get_instance_private (keysym);
|
||||||
|
priv->xkeysym = xkeysym;
|
||||||
|
|
||||||
return keysym;
|
return keysym;
|
||||||
}
|
}
|
||||||
@ -222,7 +303,7 @@ EekSymbol *eek_keysym_new_with_modifier(guint xkeysym,
|
|||||||
*
|
*
|
||||||
* Create an #EekKeysym with given X keysym value @xkeysym.
|
* Create an #EekKeysym with given X keysym value @xkeysym.
|
||||||
*/
|
*/
|
||||||
EekSymbol*
|
EekKeysym *
|
||||||
eek_keysym_new (guint xkeysym)
|
eek_keysym_new (guint xkeysym)
|
||||||
{
|
{
|
||||||
return eek_keysym_new_with_modifier (xkeysym, get_modifier_mask (xkeysym));
|
return eek_keysym_new_with_modifier (xkeysym, get_modifier_mask (xkeysym));
|
||||||
@ -234,16 +315,22 @@ eek_keysym_new (guint xkeysym)
|
|||||||
*
|
*
|
||||||
* Create an #EekKeysym with an X keysym value looked up by @name.
|
* Create an #EekKeysym with an X keysym value looked up by @name.
|
||||||
*/
|
*/
|
||||||
EekSymbol*
|
EekKeysym *
|
||||||
eek_keysym_new_from_name (const gchar *name)
|
eek_keysym_new_from_name (const gchar *name)
|
||||||
{
|
{
|
||||||
for (uint i = 0; i < G_N_ELEMENTS(xkeysym_keysym_entries); i++)
|
gint i;
|
||||||
|
|
||||||
|
for (i = 0; i < G_N_ELEMENTS(xkeysym_keysym_entries); i++)
|
||||||
if (g_strcmp0 (xkeysym_keysym_entries[i].name, name) == 0)
|
if (g_strcmp0 (xkeysym_keysym_entries[i].name, name) == 0)
|
||||||
return eek_keysym_new (xkeysym_keysym_entries[i].xkeysym);
|
return eek_keysym_new (xkeysym_keysym_entries[i].xkeysym);
|
||||||
|
|
||||||
EekSymbol *ret = eek_symbol_new(name);
|
// g_warning ("can't find keysym entry for %s", name);
|
||||||
eek_symbol_set_label(ret, name);
|
return g_object_new (EEK_TYPE_KEYSYM,
|
||||||
return ret;
|
"name", name,
|
||||||
|
"label", name,
|
||||||
|
"category", EEK_SYMBOL_CATEGORY_UNKNOWN,
|
||||||
|
"modifier-mask", 0,
|
||||||
|
NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -253,10 +340,11 @@ eek_keysym_new_from_name (const gchar *name)
|
|||||||
* Get an X keysym value associated with @keysym
|
* Get an X keysym value associated with @keysym
|
||||||
*/
|
*/
|
||||||
guint
|
guint
|
||||||
eek_keysym_get_xkeysym (EekSymbol *keysym)
|
eek_keysym_get_xkeysym (EekKeysym *keysym)
|
||||||
{
|
{
|
||||||
if (keysym->xkeysym == 0) {
|
EekKeysymPrivate *priv;
|
||||||
g_warning("Symbol %s was expected to have a valid keysym", keysym->name);
|
|
||||||
}
|
g_assert (EEK_IS_KEYSYM(keysym));
|
||||||
return keysym->xkeysym;
|
priv = eek_keysym_get_instance_private (keysym);
|
||||||
|
return priv->xkeysym;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -37,11 +37,20 @@ G_BEGIN_DECLS
|
|||||||
*/
|
*/
|
||||||
#define EEK_INVALID_KEYSYM (0)
|
#define EEK_INVALID_KEYSYM (0)
|
||||||
|
|
||||||
EekSymbol *eek_keysym_new (guint xkeysym);
|
#define EEK_TYPE_KEYSYM (eek_keysym_get_type())
|
||||||
guint eek_keysym_get_xkeysym (EekSymbol *keysym);
|
G_DECLARE_DERIVABLE_TYPE (EekKeysym, eek_keysym, EEK, KEYSYM, EekSymbol)
|
||||||
|
|
||||||
EekSymbol *eek_keysym_new_from_name (const gchar *name);
|
struct _EekKeysymClass {
|
||||||
EekSymbol *eek_keysym_new_with_modifier (guint xkeysym,
|
/*< 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,
|
||||||
EekModifierType modifier_mask);
|
EekModifierType modifier_mask);
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|||||||
@ -26,7 +26,9 @@
|
|||||||
* arranges keyboard elements.
|
* arranges keyboard elements.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
#endif /* HAVE_CONFIG_H */
|
||||||
|
|
||||||
#include "eek-layout.h"
|
#include "eek-layout.h"
|
||||||
#include "eek-keyboard.h"
|
#include "eek-keyboard.h"
|
||||||
@ -67,70 +69,3 @@ eek_keyboard_new (EekboardContextService *manager,
|
|||||||
initial_width,
|
initial_width,
|
||||||
initial_height);
|
initial_height);
|
||||||
}
|
}
|
||||||
|
|
||||||
const double section_spacing = 7.0;
|
|
||||||
|
|
||||||
struct place_data {
|
|
||||||
double desired_width;
|
|
||||||
double current_offset;
|
|
||||||
EekKeyboard *keyboard;
|
|
||||||
};
|
|
||||||
|
|
||||||
static void
|
|
||||||
section_placer(EekElement *element, gpointer user_data)
|
|
||||||
{
|
|
||||||
struct place_data *data = (struct place_data*)user_data;
|
|
||||||
|
|
||||||
EekBounds section_bounds = {0};
|
|
||||||
eek_element_get_bounds(element, §ion_bounds);
|
|
||||||
section_bounds.width = data->desired_width;
|
|
||||||
eek_element_set_bounds(element, §ion_bounds);
|
|
||||||
|
|
||||||
// Sections are rows now. Gather up all the keys and adjust their bounds.
|
|
||||||
eek_section_place_keys(EEK_SECTION(element), EEK_KEYBOARD(data->keyboard));
|
|
||||||
|
|
||||||
eek_element_get_bounds(element, §ion_bounds);
|
|
||||||
section_bounds.y = data->current_offset;
|
|
||||||
eek_element_set_bounds(element, §ion_bounds);
|
|
||||||
data->current_offset += section_bounds.height + section_spacing;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
section_counter(EekElement *element, gpointer user_data) {
|
|
||||||
|
|
||||||
double *total_height = user_data;
|
|
||||||
EekBounds section_bounds = {0};
|
|
||||||
eek_element_get_bounds(element, §ion_bounds);
|
|
||||||
*total_height += section_bounds.height + section_spacing;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
eek_layout_place_sections(EekKeyboard *keyboard)
|
|
||||||
{
|
|
||||||
/* Order rows */
|
|
||||||
// This needs to be done after outlines, because outlines define key sizes
|
|
||||||
// TODO: do this only for rows without bounds
|
|
||||||
|
|
||||||
// The keyboard width is given by the user via screen size. The height will be given dynamically.
|
|
||||||
// TODO: calculate max line width beforehand for button centering. Leave keyboard centering to the renderer later
|
|
||||||
EekBounds keyboard_bounds = {0};
|
|
||||||
eek_element_get_bounds(EEK_ELEMENT(keyboard), &keyboard_bounds);
|
|
||||||
|
|
||||||
struct place_data placer_data = {
|
|
||||||
.desired_width = keyboard_bounds.width,
|
|
||||||
.current_offset = 0,
|
|
||||||
.keyboard = keyboard,
|
|
||||||
};
|
|
||||||
eek_container_foreach_child(EEK_CONTAINER(keyboard), section_placer, &placer_data);
|
|
||||||
|
|
||||||
double total_height = 0;
|
|
||||||
eek_container_foreach_child(EEK_CONTAINER(keyboard), section_counter, &total_height);
|
|
||||||
keyboard_bounds.height = total_height;
|
|
||||||
eek_element_set_bounds(EEK_ELEMENT(keyboard), &keyboard_bounds);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
eek_layout_update_layout(EekKeyboard *keyboard)
|
|
||||||
{
|
|
||||||
eek_layout_place_sections(keyboard);
|
|
||||||
}
|
|
||||||
|
|||||||
@ -55,9 +55,5 @@ struct _EekLayoutClass
|
|||||||
|
|
||||||
GType eek_layout_get_type (void) G_GNUC_CONST;
|
GType eek_layout_get_type (void) G_GNUC_CONST;
|
||||||
|
|
||||||
void eek_layout_place_sections(EekKeyboard *keyboard);
|
|
||||||
|
|
||||||
void eek_layout_update_layout(EekKeyboard *keyboard);
|
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
#endif /* EEK_LAYOUT_H */
|
#endif /* EEK_LAYOUT_H */
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@ -25,6 +25,8 @@
|
|||||||
#include "eek-keyboard.h"
|
#include "eek-keyboard.h"
|
||||||
#include "eek-keysym.h"
|
#include "eek-keysym.h"
|
||||||
#include "eek-types.h"
|
#include "eek-types.h"
|
||||||
|
#include "eek-theme.h"
|
||||||
|
#include "eek-theme-context.h"
|
||||||
|
|
||||||
G_BEGIN_DECLS
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
@ -35,6 +37,10 @@ struct _EekRendererClass
|
|||||||
{
|
{
|
||||||
GObjectClass parent_class;
|
GObjectClass parent_class;
|
||||||
|
|
||||||
|
void (* render_key_label) (EekRenderer *self,
|
||||||
|
PangoLayout *layout,
|
||||||
|
EekKey *key);
|
||||||
|
|
||||||
void (* render_key_outline) (EekRenderer *self,
|
void (* render_key_outline) (EekRenderer *self,
|
||||||
cairo_t *cr,
|
cairo_t *cr,
|
||||||
EekKey *key,
|
EekKey *key,
|
||||||
@ -62,8 +68,7 @@ struct _EekRendererClass
|
|||||||
|
|
||||||
GType eek_renderer_get_type (void) G_GNUC_CONST;
|
GType eek_renderer_get_type (void) G_GNUC_CONST;
|
||||||
EekRenderer *eek_renderer_new (EekKeyboard *keyboard,
|
EekRenderer *eek_renderer_new (EekKeyboard *keyboard,
|
||||||
PangoContext *pcontext,
|
PangoContext *pcontext);
|
||||||
GtkStyleContext *scontext);
|
|
||||||
void eek_renderer_set_allocation_size
|
void eek_renderer_set_allocation_size
|
||||||
(EekRenderer *renderer,
|
(EekRenderer *renderer,
|
||||||
gdouble width,
|
gdouble width,
|
||||||
@ -115,8 +120,18 @@ void eek_renderer_set_default_background_color
|
|||||||
const EekColor *color);
|
const EekColor *color);
|
||||||
void eek_renderer_get_foreground_color
|
void eek_renderer_get_foreground_color
|
||||||
(EekRenderer *renderer,
|
(EekRenderer *renderer,
|
||||||
GtkStyleContext *context,
|
EekElement *element,
|
||||||
EekColor *color);
|
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,
|
void eek_renderer_set_border_width (EekRenderer *renderer,
|
||||||
gdouble border_width);
|
gdouble border_width);
|
||||||
EekKey *eek_renderer_find_key_by_position
|
EekKey *eek_renderer_find_key_by_position
|
||||||
@ -130,5 +145,8 @@ void eek_renderer_apply_transformation_for_key
|
|||||||
gdouble scale,
|
gdouble scale,
|
||||||
gboolean rotate);
|
gboolean rotate);
|
||||||
|
|
||||||
|
void eek_renderer_set_theme (EekRenderer *renderer,
|
||||||
|
EekTheme *theme);
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
#endif /* EEK_RENDERER_H */
|
#endif /* EEK_RENDERER_H */
|
||||||
|
|||||||
@ -27,7 +27,9 @@
|
|||||||
* of one or more keys of the #EekKeyClass class.
|
* of one or more keys of the #EekKeyClass class.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
#endif /* HAVE_CONFIG_H */
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
@ -61,7 +63,7 @@ typedef struct _EekRow EekRow;
|
|||||||
typedef struct _EekSectionPrivate
|
typedef struct _EekSectionPrivate
|
||||||
{
|
{
|
||||||
gint angle;
|
gint angle;
|
||||||
EekRow row;
|
GSList *rows;
|
||||||
EekModifierType modifiers;
|
EekModifierType modifiers;
|
||||||
} EekSectionPrivate;
|
} EekSectionPrivate;
|
||||||
|
|
||||||
@ -70,7 +72,9 @@ G_DEFINE_TYPE_WITH_PRIVATE (EekSection, eek_section, EEK_TYPE_CONTAINER)
|
|||||||
static gint
|
static gint
|
||||||
eek_section_real_get_n_rows (EekSection *self)
|
eek_section_real_get_n_rows (EekSection *self)
|
||||||
{
|
{
|
||||||
return 1;
|
EekSectionPrivate *priv = eek_section_get_instance_private (self);
|
||||||
|
|
||||||
|
return g_slist_length (priv->rows);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -78,14 +82,13 @@ eek_section_real_add_row (EekSection *self,
|
|||||||
gint num_columns,
|
gint num_columns,
|
||||||
EekOrientation orientation)
|
EekOrientation orientation)
|
||||||
{
|
{
|
||||||
EekSectionPrivate *priv = (EekSectionPrivate*)eek_section_get_instance_private (self);
|
EekSectionPrivate *priv = eek_section_get_instance_private (self);
|
||||||
priv->row.num_columns = num_columns;
|
EekRow *row;
|
||||||
priv->row.orientation = orientation;
|
|
||||||
/*
|
|
||||||
row = g_slice_new (EekRow);
|
row = g_slice_new (EekRow);
|
||||||
row->num_columns = num_columns;
|
row->num_columns = num_columns;
|
||||||
row->orientation = orientation;
|
row->orientation = orientation;
|
||||||
priv->rows = g_slist_append (priv->rows, row);*/
|
priv->rows = g_slist_append (priv->rows, row);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -94,14 +97,15 @@ eek_section_real_get_row (EekSection *self,
|
|||||||
gint *num_columns,
|
gint *num_columns,
|
||||||
EekOrientation *orientation)
|
EekOrientation *orientation)
|
||||||
{
|
{
|
||||||
EekSectionPrivate *priv = (EekSectionPrivate*)eek_section_get_instance_private (self);
|
EekSectionPrivate *priv = eek_section_get_instance_private (self);
|
||||||
EekRow *row = &priv->row;
|
EekRow *row;
|
||||||
if (num_columns) {
|
|
||||||
|
row = g_slist_nth_data (priv->rows, index);
|
||||||
|
g_return_if_fail (row);
|
||||||
|
if (num_columns)
|
||||||
*num_columns = row->num_columns;
|
*num_columns = row->num_columns;
|
||||||
}
|
if (orientation)
|
||||||
if (orientation) {
|
|
||||||
*orientation = row->orientation;
|
*orientation = row->orientation;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -120,18 +124,28 @@ on_unlocked (EekKey *key,
|
|||||||
|
|
||||||
static EekKey *
|
static EekKey *
|
||||||
eek_section_real_create_key (EekSection *self,
|
eek_section_real_create_key (EekSection *self,
|
||||||
const gchar *name,
|
guint keycode,
|
||||||
gint keycode)
|
gint column_index,
|
||||||
|
gint row_index)
|
||||||
{
|
{
|
||||||
EekSectionPrivate *priv = (EekSectionPrivate*)eek_section_get_instance_private (self);
|
EekKey *key;
|
||||||
|
gint num_rows;
|
||||||
|
EekRow *row;
|
||||||
|
|
||||||
EekRow *row = &priv->row;
|
num_rows = eek_section_get_n_rows (self);
|
||||||
row->num_columns++;
|
g_return_val_if_fail (0 <= row_index && row_index < num_rows, NULL);
|
||||||
|
|
||||||
EekKey *key = (EekKey*)g_object_new (EEK_TYPE_KEY,
|
EekSectionPrivate *priv = eek_section_get_instance_private (self);
|
||||||
"name", name,
|
|
||||||
"keycode", keycode,
|
row = g_slist_nth_data (priv->rows, row_index);
|
||||||
NULL);
|
if (row->num_columns < column_index + 1)
|
||||||
|
row->num_columns = column_index + 1;
|
||||||
|
|
||||||
|
key = g_object_new (EEK_TYPE_KEY,
|
||||||
|
"keycode", keycode,
|
||||||
|
"column", column_index,
|
||||||
|
"row", row_index,
|
||||||
|
NULL);
|
||||||
g_return_val_if_fail (key, NULL);
|
g_return_val_if_fail (key, NULL);
|
||||||
|
|
||||||
EEK_CONTAINER_GET_CLASS(self)->add_child (EEK_CONTAINER(self),
|
EEK_CONTAINER_GET_CLASS(self)->add_child (EEK_CONTAINER(self),
|
||||||
@ -211,7 +225,12 @@ static void
|
|||||||
eek_section_finalize (GObject *object)
|
eek_section_finalize (GObject *object)
|
||||||
{
|
{
|
||||||
EekSection *self = EEK_SECTION (object);
|
EekSection *self = EEK_SECTION (object);
|
||||||
EekSectionPrivate *priv = (EekSectionPrivate*)eek_section_get_instance_private (self);
|
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);
|
||||||
|
|
||||||
G_OBJECT_CLASS (eek_section_parent_class)->finalize (object);
|
G_OBJECT_CLASS (eek_section_parent_class)->finalize (object);
|
||||||
}
|
}
|
||||||
@ -444,7 +463,6 @@ eek_section_get_row (EekSection *section,
|
|||||||
/**
|
/**
|
||||||
* eek_section_create_key:
|
* eek_section_create_key:
|
||||||
* @section: an #EekSection
|
* @section: an #EekSection
|
||||||
* @name: a name
|
|
||||||
* @keycode: a keycode
|
* @keycode: a keycode
|
||||||
* @column: the column index of the key
|
* @column: the column index of the key
|
||||||
* @row: the row index of the key
|
* @row: the row index of the key
|
||||||
@ -455,28 +473,19 @@ eek_section_get_row (EekSection *section,
|
|||||||
*/
|
*/
|
||||||
EekKey *
|
EekKey *
|
||||||
eek_section_create_key (EekSection *section,
|
eek_section_create_key (EekSection *section,
|
||||||
const gchar *name,
|
guint keycode,
|
||||||
gint keycode)
|
gint column,
|
||||||
|
gint row)
|
||||||
{
|
{
|
||||||
g_return_val_if_fail (EEK_IS_SECTION(section), NULL);
|
g_return_val_if_fail (EEK_IS_SECTION(section), NULL);
|
||||||
return EEK_SECTION_GET_CLASS(section)->create_key (section,
|
return EEK_SECTION_GET_CLASS(section)->create_key (section,
|
||||||
name,
|
keycode,
|
||||||
keycode);
|
column,
|
||||||
|
row);
|
||||||
}
|
}
|
||||||
|
|
||||||
const double keyspacing = 4.0;
|
static void keysizer(EekElement *element, gpointer user_data) {
|
||||||
|
|
||||||
struct keys_info {
|
|
||||||
uint count;
|
|
||||||
double total_width;
|
|
||||||
double biggest_height;
|
|
||||||
};
|
|
||||||
|
|
||||||
static void
|
|
||||||
keysizer(EekElement *element, gpointer user_data)
|
|
||||||
{
|
|
||||||
EekKey *key = EEK_KEY(element);
|
EekKey *key = EEK_KEY(element);
|
||||||
|
|
||||||
EekKeyboard *keyboard = EEK_KEYBOARD(user_data);
|
EekKeyboard *keyboard = EEK_KEYBOARD(user_data);
|
||||||
uint oref = eek_key_get_oref (key);
|
uint oref = eek_key_get_oref (key);
|
||||||
EekOutline *outline = eek_keyboard_get_outline (keyboard, oref);
|
EekOutline *outline = eek_keyboard_get_outline (keyboard, oref);
|
||||||
@ -507,16 +516,13 @@ keysizer(EekElement *element, gpointer user_data)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
struct keys_info {
|
||||||
keycounter (EekElement *element, gpointer user_data)
|
uint count;
|
||||||
{
|
double total_width;
|
||||||
EekKey *key = EEK_KEY(element);
|
double biggest_height;
|
||||||
|
};
|
||||||
/* Skip keys without labels for the current level. This causes those
|
|
||||||
keys to be hidden in the visible layout. */
|
|
||||||
if (!eek_key_has_label(key))
|
|
||||||
return;
|
|
||||||
|
|
||||||
|
static void keycounter (EekElement *element, gpointer user_data) {
|
||||||
struct keys_info *data = user_data;
|
struct keys_info *data = user_data;
|
||||||
data->count++;
|
data->count++;
|
||||||
EekBounds key_bounds = {0};
|
EekBounds key_bounds = {0};
|
||||||
@ -527,15 +533,9 @@ keycounter (EekElement *element, gpointer user_data)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
const double keyspacing = 4.0;
|
||||||
keyplacer(EekElement *element, gpointer user_data)
|
|
||||||
{
|
|
||||||
EekKey *key = EEK_KEY(element);
|
|
||||||
|
|
||||||
/* Skip keys without labels for the current level. */
|
|
||||||
if (!eek_key_has_label(key))
|
|
||||||
return;
|
|
||||||
|
|
||||||
|
static void keyplacer(EekElement *element, gpointer user_data) {
|
||||||
double *current_offset = user_data;
|
double *current_offset = user_data;
|
||||||
EekBounds key_bounds = {0};
|
EekBounds key_bounds = {0};
|
||||||
eek_element_get_bounds(element, &key_bounds);
|
eek_element_get_bounds(element, &key_bounds);
|
||||||
@ -545,8 +545,7 @@ keyplacer(EekElement *element, gpointer user_data)
|
|||||||
*current_offset += key_bounds.width + keyspacing;
|
*current_offset += key_bounds.width + keyspacing;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void eek_section_place_keys(EekSection *section, EekKeyboard *keyboard)
|
||||||
eek_section_place_keys(EekSection *section, EekKeyboard *keyboard)
|
|
||||||
{
|
{
|
||||||
eek_container_foreach_child(EEK_CONTAINER(section), keysizer, keyboard);
|
eek_container_foreach_child(EEK_CONTAINER(section), keysizer, keyboard);
|
||||||
|
|
||||||
|
|||||||
@ -62,8 +62,9 @@ struct _EekSectionClass
|
|||||||
EekOrientation *orientation);
|
EekOrientation *orientation);
|
||||||
|
|
||||||
EekKey *(* create_key) (EekSection *self,
|
EekKey *(* create_key) (EekSection *self,
|
||||||
const gchar *name,
|
guint keycode,
|
||||||
gint keycode);
|
gint row,
|
||||||
|
gint column);
|
||||||
|
|
||||||
/* signals */
|
/* signals */
|
||||||
void (* key_pressed) (EekSection *self,
|
void (* key_pressed) (EekSection *self,
|
||||||
@ -98,8 +99,9 @@ void eek_section_get_row (EekSection *section,
|
|||||||
EekOrientation *orientation);
|
EekOrientation *orientation);
|
||||||
|
|
||||||
EekKey *eek_section_create_key (EekSection *section,
|
EekKey *eek_section_create_key (EekSection *section,
|
||||||
const gchar *name,
|
guint keycode,
|
||||||
gint keycode);
|
gint column,
|
||||||
|
gint row);
|
||||||
|
|
||||||
EekKey *eek_section_find_key_by_keycode (EekSection *section,
|
EekKey *eek_section_find_key_by_keycode (EekSection *section,
|
||||||
guint keycode);
|
guint keycode);
|
||||||
|
|||||||
@ -27,7 +27,9 @@
|
|||||||
* method.
|
* method.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
#endif /* HAVE_CONFIG_H */
|
||||||
|
|
||||||
#include "eek-serializable.h"
|
#include "eek-serializable.h"
|
||||||
|
|
||||||
@ -36,8 +38,10 @@ eek_serializable_get_type (void)
|
|||||||
{
|
{
|
||||||
static GType iface_type = 0;
|
static GType iface_type = 0;
|
||||||
if (iface_type == 0) {
|
if (iface_type == 0) {
|
||||||
static GTypeInfo info = {
|
static const GTypeInfo info = {
|
||||||
.class_size = sizeof (EekSerializableIface)
|
sizeof (EekSerializableIface),
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
};
|
};
|
||||||
iface_type = g_type_register_static (G_TYPE_INTERFACE,
|
iface_type = g_type_register_static (G_TYPE_INTERFACE,
|
||||||
"EekSerializable",
|
"EekSerializable",
|
||||||
|
|||||||
@ -36,19 +36,24 @@ EekSymbolMatrix *
|
|||||||
eek_symbol_matrix_copy (const EekSymbolMatrix *matrix)
|
eek_symbol_matrix_copy (const EekSymbolMatrix *matrix)
|
||||||
{
|
{
|
||||||
EekSymbolMatrix *retval;
|
EekSymbolMatrix *retval;
|
||||||
guint num_symbols = matrix->num_groups * matrix->num_levels;
|
gint i, num_symbols = matrix->num_groups * matrix->num_levels;
|
||||||
|
|
||||||
retval = g_slice_dup (EekSymbolMatrix, matrix);
|
retval = g_slice_dup (EekSymbolMatrix, matrix);
|
||||||
retval->data = g_slice_copy (sizeof (EekSymbol *) * num_symbols,
|
retval->data = g_slice_copy (sizeof (EekSymbol *) * num_symbols,
|
||||||
matrix->data);
|
matrix->data);
|
||||||
// FIXME: do a deep copy over the data in EekSymbol
|
for (i = 0; i < num_symbols; i++)
|
||||||
|
if (retval->data[i])
|
||||||
|
g_object_ref (retval->data[i]);
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
eek_symbol_matrix_free (EekSymbolMatrix *matrix)
|
eek_symbol_matrix_free (EekSymbolMatrix *matrix)
|
||||||
{
|
{
|
||||||
guint num_symbols = matrix->num_groups * matrix->num_levels;
|
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]);
|
||||||
g_slice_free1 (sizeof (EekSymbol *) * num_symbols, matrix->data);
|
g_slice_free1 (sizeof (EekSymbol *) * num_symbols, matrix->data);
|
||||||
g_slice_free (EekSymbolMatrix, matrix);
|
g_slice_free (EekSymbolMatrix, matrix);
|
||||||
}
|
}
|
||||||
@ -74,6 +79,7 @@ eek_symbol_matrix_set_symbol (EekSymbolMatrix *matrix,
|
|||||||
{
|
{
|
||||||
g_return_if_fail (group >= 0 && group < matrix->num_groups);
|
g_return_if_fail (group >= 0 && group < matrix->num_groups);
|
||||||
g_return_if_fail (level >= 0 && level < matrix->num_levels);
|
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);
|
matrix->data[group * matrix->num_levels + level] = g_object_ref (symbol);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
416
eek/eek-symbol.c
416
eek/eek-symbol.c
@ -25,45 +25,275 @@
|
|||||||
* The #EekSymbolClass class represents a symbol assigned to a key.
|
* The #EekSymbolClass class represents a symbol assigned to a key.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
#endif /* HAVE_CONFIG_H */
|
||||||
|
|
||||||
#include "eek-symbol.h"
|
#include "eek-symbol.h"
|
||||||
|
#include "eek-serializable.h"
|
||||||
#include "eek-enumtypes.h"
|
#include "eek-enumtypes.h"
|
||||||
|
|
||||||
void
|
enum {
|
||||||
eek_symbol_destroy (EekSymbol *priv)
|
PROP_0,
|
||||||
|
PROP_NAME,
|
||||||
|
PROP_LABEL,
|
||||||
|
PROP_CATEGORY,
|
||||||
|
PROP_MODIFIER_MASK,
|
||||||
|
PROP_ICON_NAME,
|
||||||
|
PROP_TOOLTIP,
|
||||||
|
PROP_LAST
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct _EekSymbolPrivate
|
||||||
{
|
{
|
||||||
|
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->name);
|
||||||
g_free (priv->label);
|
g_free (priv->label);
|
||||||
g_free (priv->icon_name);
|
g_free (priv->icon_name);
|
||||||
g_free (priv->tooltip);
|
g_free (priv->tooltip);
|
||||||
g_free(priv->text);
|
G_OBJECT_CLASS (eek_symbol_parent_class)->finalize (object);
|
||||||
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 *
|
EekSymbol *
|
||||||
eek_symbol_new (const gchar *name)
|
eek_symbol_new (const gchar *name)
|
||||||
{
|
{
|
||||||
EekSymbol *self = g_new0(EekSymbol, 1);
|
return g_object_new (EEK_TYPE_SYMBOL, "name", name, NULL);
|
||||||
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
|
void
|
||||||
eek_symbol_set_name (EekSymbol *symbol,
|
eek_symbol_set_name (EekSymbol *symbol,
|
||||||
const gchar *name)
|
const gchar *name)
|
||||||
{
|
{
|
||||||
g_free (symbol->name);
|
g_return_if_fail (EEK_IS_SYMBOL(symbol));
|
||||||
symbol->name = g_strdup (name);
|
|
||||||
|
EekSymbolPrivate *priv = eek_symbol_get_instance_private (symbol);
|
||||||
|
|
||||||
|
g_free (priv->name);
|
||||||
|
priv->name = g_strdup (name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* eek_symbol_get_name:
|
||||||
|
* @symbol: an #EekSymbol
|
||||||
|
*
|
||||||
|
* Get the name of @symbol.
|
||||||
|
*/
|
||||||
const gchar *
|
const gchar *
|
||||||
eek_symbol_get_name (EekSymbol *symbol)
|
eek_symbol_get_name (EekSymbol *symbol)
|
||||||
{
|
{
|
||||||
if (symbol->name == NULL || *symbol->name == '\0')
|
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')
|
||||||
return NULL;
|
return NULL;
|
||||||
return symbol->name;
|
return priv->name;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -77,8 +307,12 @@ void
|
|||||||
eek_symbol_set_label (EekSymbol *symbol,
|
eek_symbol_set_label (EekSymbol *symbol,
|
||||||
const gchar *label)
|
const gchar *label)
|
||||||
{
|
{
|
||||||
g_free (symbol->label);
|
g_return_if_fail (EEK_IS_SYMBOL(symbol));
|
||||||
symbol->label = g_strdup (label);
|
|
||||||
|
EekSymbolPrivate *priv = eek_symbol_get_instance_private (symbol);
|
||||||
|
|
||||||
|
g_free (priv->label);
|
||||||
|
priv->label = g_strdup (label);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -90,9 +324,47 @@ eek_symbol_set_label (EekSymbol *symbol,
|
|||||||
const gchar *
|
const gchar *
|
||||||
eek_symbol_get_label (EekSymbol *symbol)
|
eek_symbol_get_label (EekSymbol *symbol)
|
||||||
{
|
{
|
||||||
if (symbol->label == NULL || *symbol->label == '\0')
|
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')
|
||||||
return NULL;
|
return NULL;
|
||||||
return symbol->label;
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -106,7 +378,11 @@ void
|
|||||||
eek_symbol_set_modifier_mask (EekSymbol *symbol,
|
eek_symbol_set_modifier_mask (EekSymbol *symbol,
|
||||||
EekModifierType mask)
|
EekModifierType mask)
|
||||||
{
|
{
|
||||||
symbol->modifier_mask = mask;
|
g_return_if_fail (EEK_IS_SYMBOL(symbol));
|
||||||
|
|
||||||
|
EekSymbolPrivate *priv = eek_symbol_get_instance_private (symbol);
|
||||||
|
|
||||||
|
priv->modifier_mask = mask;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -118,43 +394,131 @@ eek_symbol_set_modifier_mask (EekSymbol *symbol,
|
|||||||
EekModifierType
|
EekModifierType
|
||||||
eek_symbol_get_modifier_mask (EekSymbol *symbol)
|
eek_symbol_get_modifier_mask (EekSymbol *symbol)
|
||||||
{
|
{
|
||||||
return symbol->modifier_mask;
|
g_return_val_if_fail (EEK_IS_SYMBOL(symbol), 0);
|
||||||
|
|
||||||
|
EekSymbolPrivate *priv = eek_symbol_get_instance_private (symbol);
|
||||||
|
|
||||||
|
return priv->modifier_mask;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* eek_symbol_is_modifier:
|
||||||
|
* @symbol: an #EekSymbol
|
||||||
|
*
|
||||||
|
* Check if @symbol is a modifier.
|
||||||
|
* Returns: %TRUE if @symbol is a modifier.
|
||||||
|
*/
|
||||||
gboolean
|
gboolean
|
||||||
eek_symbol_is_modifier (EekSymbol *symbol)
|
eek_symbol_is_modifier (EekSymbol *symbol)
|
||||||
{
|
{
|
||||||
return eek_symbol_get_modifier_mask (symbol) != 0;
|
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
|
void
|
||||||
eek_symbol_set_icon_name (EekSymbol *symbol,
|
eek_symbol_set_icon_name (EekSymbol *symbol,
|
||||||
const gchar *icon_name)
|
const gchar *icon_name)
|
||||||
{
|
{
|
||||||
g_free (symbol->icon_name);
|
g_return_if_fail (EEK_IS_SYMBOL(symbol));
|
||||||
symbol->icon_name = g_strdup (icon_name);
|
|
||||||
|
EekSymbolPrivate *priv = eek_symbol_get_instance_private (symbol);
|
||||||
|
|
||||||
|
g_free (priv->icon_name);
|
||||||
|
priv->icon_name = g_strdup (icon_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* eek_symbol_get_icon_name:
|
||||||
|
* @symbol: an #EekSymbol
|
||||||
|
*
|
||||||
|
* Get the icon name of @symbol.
|
||||||
|
*/
|
||||||
const gchar *
|
const gchar *
|
||||||
eek_symbol_get_icon_name (EekSymbol *symbol)
|
eek_symbol_get_icon_name (EekSymbol *symbol)
|
||||||
{
|
{
|
||||||
if (symbol->icon_name == NULL || *symbol->icon_name == '\0')
|
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')
|
||||||
return NULL;
|
return NULL;
|
||||||
return symbol->icon_name;
|
return priv->icon_name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* eek_symbol_set_tooltip:
|
||||||
|
* @symbol: an #EekSymbol
|
||||||
|
* @tooltip: icon name of @symbol
|
||||||
|
*
|
||||||
|
* Set the tooltip text of @symbol to @tooltip.
|
||||||
|
*/
|
||||||
void
|
void
|
||||||
eek_symbol_set_tooltip (EekSymbol *symbol,
|
eek_symbol_set_tooltip (EekSymbol *symbol,
|
||||||
const gchar *tooltip)
|
const gchar *tooltip)
|
||||||
{
|
{
|
||||||
g_free (symbol->tooltip);
|
g_return_if_fail (EEK_IS_SYMBOL(symbol));
|
||||||
symbol->tooltip = g_strdup (tooltip);
|
|
||||||
|
EekSymbolPrivate *priv = eek_symbol_get_instance_private (symbol);
|
||||||
|
|
||||||
|
g_free (priv->tooltip);
|
||||||
|
priv->tooltip = g_strdup (tooltip);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* eek_symbol_get_tooltip:
|
||||||
|
* @symbol: an #EekSymbol
|
||||||
|
*
|
||||||
|
* Get the tooltip text of @symbol.
|
||||||
|
*/
|
||||||
const gchar *
|
const gchar *
|
||||||
eek_symbol_get_tooltip (EekSymbol *symbol)
|
eek_symbol_get_tooltip (EekSymbol *symbol)
|
||||||
{
|
{
|
||||||
if (symbol->tooltip == NULL || *symbol->tooltip == '\0')
|
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')
|
||||||
return NULL;
|
return NULL;
|
||||||
return symbol->tooltip;
|
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;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -58,27 +58,20 @@ typedef enum {
|
|||||||
EEK_SYMBOL_CATEGORY_LAST = EEK_SYMBOL_CATEGORY_UNKNOWN
|
EEK_SYMBOL_CATEGORY_LAST = EEK_SYMBOL_CATEGORY_UNKNOWN
|
||||||
} EekSymbolCategory;
|
} EekSymbolCategory;
|
||||||
|
|
||||||
|
#define EEK_TYPE_SYMBOL (eek_symbol_get_type())
|
||||||
|
G_DECLARE_DERIVABLE_TYPE(EekSymbol, eek_symbol, EEK, SYMBOL, GObject)
|
||||||
|
|
||||||
typedef struct _EekSymbol
|
/**
|
||||||
{
|
* EekSymbolClass:
|
||||||
/// Canonical name of the symbol
|
*/
|
||||||
gchar *name;
|
struct _EekSymbolClass {
|
||||||
/// Text used to display the symbol
|
/*< private >*/
|
||||||
gchar *label;
|
GObjectClass parent_class;
|
||||||
EekSymbolCategory category;
|
};
|
||||||
EekModifierType modifier_mask;
|
|
||||||
/// Icon name used to render the symbol
|
|
||||||
gchar *icon_name;
|
|
||||||
/// Tooltip text
|
|
||||||
gchar *tooltip;
|
|
||||||
|
|
||||||
// May not be present
|
GType eek_symbol_get_type (void) G_GNUC_CONST;
|
||||||
guint xkeysym;
|
|
||||||
gchar *text;
|
|
||||||
} EekSymbol;
|
|
||||||
|
|
||||||
EekSymbol *eek_symbol_new (const gchar *name);
|
EekSymbol *eek_symbol_new (const gchar *name);
|
||||||
void eek_symbol_free (EekSymbol *symbol);
|
|
||||||
void eek_symbol_set_name (EekSymbol *symbol,
|
void eek_symbol_set_name (EekSymbol *symbol,
|
||||||
const gchar *name);
|
const gchar *name);
|
||||||
const gchar *eek_symbol_get_name (EekSymbol *symbol);
|
const gchar *eek_symbol_get_name (EekSymbol *symbol);
|
||||||
|
|||||||
158
eek/eek-text.c
158
eek/eek-text.c
@ -23,21 +23,165 @@
|
|||||||
* @short_description: an #EekText represents a text symbol
|
* @short_description: an #EekText represents a text symbol
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
#endif /* HAVE_CONFIG_H */
|
||||||
|
|
||||||
#include "eek-text.h"
|
#include "eek-text.h"
|
||||||
|
#include "eek-serializable.h"
|
||||||
|
|
||||||
EekSymbol *
|
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 *
|
||||||
eek_text_new (const gchar *text)
|
eek_text_new (const gchar *text)
|
||||||
{
|
{
|
||||||
EekSymbol *ret = eek_symbol_new("");
|
return g_object_new (EEK_TYPE_TEXT,
|
||||||
eek_symbol_set_label(ret, text);
|
"label", text,
|
||||||
ret->text = g_strdup (text);
|
"category", EEK_SYMBOL_CATEGORY_FUNCTION,
|
||||||
return ret;
|
"text", text,
|
||||||
|
NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* eek_text_get_text:
|
||||||
|
* @text: an #EekText
|
||||||
|
*
|
||||||
|
* Get a text value associated with @text
|
||||||
|
*/
|
||||||
const gchar *
|
const gchar *
|
||||||
eek_text_get_text (EekSymbol *text)
|
eek_text_get_text (EekText *text)
|
||||||
{
|
{
|
||||||
return text->text;
|
EekTextPrivate *priv = eek_text_get_instance_private (text);
|
||||||
|
|
||||||
|
return priv->text;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -29,9 +29,17 @@
|
|||||||
|
|
||||||
G_BEGIN_DECLS
|
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;
|
GType eek_text_get_type (void) G_GNUC_CONST;
|
||||||
EekSymbol *eek_text_new (const gchar *text);
|
EekText *eek_text_new (const gchar *text);
|
||||||
const gchar *eek_text_get_text (EekSymbol *text);
|
const gchar *eek_text_get_text (EekText *text);
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
|
|||||||
289
eek/eek-theme-context.c
Normal file
289
eek/eek-theme-context.c
Normal file
@ -0,0 +1,289 @@
|
|||||||
|
/* -*- 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/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "config.h"
|
||||||
|
#endif /* HAVE_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;
|
||||||
|
}
|
||||||
78
eek/eek-theme-context.h
Normal file
78
eek/eek-theme-context.h
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
/* -*- 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__ */
|
||||||
1866
eek/eek-theme-node.c
Normal file
1866
eek/eek-theme-node.c
Normal file
File diff suppressed because it is too large
Load Diff
141
eek/eek-theme-node.h
Normal file
141
eek/eek-theme-node.h
Normal file
@ -0,0 +1,141 @@
|
|||||||
|
/*
|
||||||
|
* 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__ */
|
||||||
22
eek/eek-theme-private.h
Normal file
22
eek/eek-theme-private.h
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
/* -*- 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
Normal file
1095
eek/eek-theme.c
Normal file
File diff suppressed because it is too large
Load Diff
49
eek/eek-theme.h
Normal file
49
eek/eek-theme.h
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
/* -*- 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__ */
|
||||||
@ -24,7 +24,9 @@
|
|||||||
* @short_description: Miscellaneous types used in Libeek
|
* @short_description: Miscellaneous types used in Libeek
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
#endif /* HAVE_CONFIG_H */
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|||||||
@ -139,6 +139,7 @@ typedef struct _EekKey EekKey;
|
|||||||
typedef struct _EekSection EekSection;
|
typedef struct _EekSection EekSection;
|
||||||
typedef struct _EekKeyboard EekKeyboard;
|
typedef struct _EekKeyboard EekKeyboard;
|
||||||
typedef struct _EekSymbol EekSymbol;
|
typedef struct _EekSymbol EekSymbol;
|
||||||
|
typedef struct _EekKeysym EekKeysym;
|
||||||
typedef struct _EekText EekText;
|
typedef struct _EekText EekText;
|
||||||
typedef struct _EekTheme EekTheme;
|
typedef struct _EekTheme EekTheme;
|
||||||
typedef struct _EekThemeContext EekThemeContext;
|
typedef struct _EekThemeContext EekThemeContext;
|
||||||
|
|||||||
@ -21,7 +21,9 @@
|
|||||||
* @short_description: Layout engine which loads layout information from XML
|
* @short_description: Layout engine which loads layout information from XML
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
#endif /* HAVE_CONFIG_H */
|
||||||
|
|
||||||
#include <gio/gio.h> /* GResource */
|
#include <gio/gio.h> /* GResource */
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
@ -79,6 +81,10 @@ static gboolean parse_symbols (const gchar *path,
|
|||||||
EekKeyboard *keyboard,
|
EekKeyboard *keyboard,
|
||||||
GError **error);
|
GError **error);
|
||||||
|
|
||||||
|
static void scale_keyboard (EekKeyboard *keyboard,
|
||||||
|
gdouble width,
|
||||||
|
gdouble height);
|
||||||
|
|
||||||
static gboolean validate (const gchar **valid_path_list,
|
static gboolean validate (const gchar **valid_path_list,
|
||||||
gsize valid_path_list_len,
|
gsize valid_path_list_len,
|
||||||
const gchar *element_name,
|
const gchar *element_name,
|
||||||
@ -243,7 +249,6 @@ struct _GeometryParseData {
|
|||||||
gchar *name;
|
gchar *name;
|
||||||
EekOutline outline;
|
EekOutline outline;
|
||||||
gchar *oref;
|
gchar *oref;
|
||||||
gint keycode;
|
|
||||||
|
|
||||||
GHashTable *key_oref_hash;
|
GHashTable *key_oref_hash;
|
||||||
GHashTable *oref_outline_hash;
|
GHashTable *oref_outline_hash;
|
||||||
@ -266,7 +271,6 @@ geometry_parse_data_new (EekKeyboard *keyboard)
|
|||||||
g_str_equal,
|
g_str_equal,
|
||||||
g_free,
|
g_free,
|
||||||
(GDestroyNotify)eek_outline_free);
|
(GDestroyNotify)eek_outline_free);
|
||||||
data->keycode = 8;
|
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -395,26 +399,25 @@ geometry_start_element_callback (GMarkupParseContext *pcontext,
|
|||||||
guint keycode;
|
guint keycode;
|
||||||
|
|
||||||
attribute = get_attribute (attribute_names, attribute_values,
|
attribute = get_attribute (attribute_names, attribute_values,
|
||||||
"name");
|
"keycode");
|
||||||
if (attribute == NULL) {
|
if (attribute == NULL) {
|
||||||
g_set_error (error,
|
g_set_error (error,
|
||||||
G_MARKUP_ERROR,
|
G_MARKUP_ERROR,
|
||||||
G_MARKUP_ERROR_MISSING_ATTRIBUTE,
|
G_MARKUP_ERROR_MISSING_ATTRIBUTE,
|
||||||
"no \"name\" attribute for \"key\"");
|
"no \"keycode\" attribute for \"key\"");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
gchar *name = g_strdup (attribute);
|
keycode = strtoul (attribute, NULL, 10);
|
||||||
|
|
||||||
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,
|
data->key = eek_section_create_key (data->section,
|
||||||
name,
|
keycode,
|
||||||
keycode);
|
data->num_columns,
|
||||||
|
data->num_rows - 1);
|
||||||
|
|
||||||
|
attribute = get_attribute (attribute_names, attribute_values,
|
||||||
|
"name");
|
||||||
|
if (attribute != NULL)
|
||||||
|
eek_element_set_name (EEK_ELEMENT(data->key), attribute);
|
||||||
|
|
||||||
attribute = get_attribute (attribute_names, attribute_values,
|
attribute = get_attribute (attribute_names, attribute_values,
|
||||||
"oref");
|
"oref");
|
||||||
@ -566,6 +569,7 @@ struct _SymbolsParseData {
|
|||||||
gchar *label;
|
gchar *label;
|
||||||
gchar *icon;
|
gchar *icon;
|
||||||
gchar *tooltip;
|
gchar *tooltip;
|
||||||
|
EekSymbolCategory category;
|
||||||
guint keyval;
|
guint keyval;
|
||||||
gint groups;
|
gint groups;
|
||||||
};
|
};
|
||||||
@ -618,25 +622,28 @@ symbols_start_element_callback (GMarkupParseContext *pcontext,
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
if (g_strcmp0 (element_name, "key") == 0) {
|
if (g_strcmp0 (element_name, "key") == 0) {
|
||||||
|
guint keycode;
|
||||||
|
|
||||||
attribute = get_attribute (attribute_names, attribute_values,
|
attribute = get_attribute (attribute_names, attribute_values,
|
||||||
"name");
|
"keycode");
|
||||||
if (attribute == NULL) {
|
if (attribute == NULL) {
|
||||||
g_set_error (error,
|
g_set_error (error,
|
||||||
G_MARKUP_ERROR,
|
G_MARKUP_ERROR,
|
||||||
G_MARKUP_ERROR_MISSING_ATTRIBUTE,
|
G_MARKUP_ERROR_MISSING_ATTRIBUTE,
|
||||||
"no \"name\" attribute for \"key\"");
|
"no \"keycode\" attribute for \"key\"");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
keycode = strtoul (attribute, NULL, 10);
|
||||||
|
|
||||||
data->key = eek_keyboard_find_key_by_name (data->keyboard,
|
data->key = eek_keyboard_find_key_by_keycode (data->keyboard,
|
||||||
attribute);
|
keycode);
|
||||||
if (data->key == NULL) {
|
/*if (data->key == NULL) {
|
||||||
g_set_error (error,
|
g_set_error (error,
|
||||||
G_MARKUP_ERROR,
|
G_MARKUP_ERROR,
|
||||||
G_MARKUP_ERROR_INVALID_CONTENT,
|
G_MARKUP_ERROR_INVALID_CONTENT,
|
||||||
"no such key %s", attribute);
|
"no such keycode %u", keycode);
|
||||||
}
|
return;
|
||||||
|
}*/
|
||||||
|
|
||||||
attribute = get_attribute (attribute_names, attribute_values,
|
attribute = get_attribute (attribute_names, attribute_values,
|
||||||
"groups");
|
"groups");
|
||||||
@ -678,6 +685,13 @@ symbols_start_element_callback (GMarkupParseContext *pcontext,
|
|||||||
"tooltip");
|
"tooltip");
|
||||||
if (attribute != NULL)
|
if (attribute != NULL)
|
||||||
data->tooltip = g_strdup (attribute);
|
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:
|
out:
|
||||||
@ -712,6 +726,7 @@ symbols_end_element_callback (GMarkupParseContext *pcontext,
|
|||||||
gint levels = num_symbols / data->groups;
|
gint levels = num_symbols / data->groups;
|
||||||
EekSymbolMatrix *matrix = eek_symbol_matrix_new (data->groups,
|
EekSymbolMatrix *matrix = eek_symbol_matrix_new (data->groups,
|
||||||
levels);
|
levels);
|
||||||
|
|
||||||
head = data->symbols = g_slist_reverse (data->symbols);
|
head = data->symbols = g_slist_reverse (data->symbols);
|
||||||
for (i = 0; i < num_symbols; i++) {
|
for (i = 0; i < num_symbols; i++) {
|
||||||
if (head && head->data) {
|
if (head && head->data) {
|
||||||
@ -735,22 +750,21 @@ symbols_end_element_callback (GMarkupParseContext *pcontext,
|
|||||||
EekSymbol *symbol;
|
EekSymbol *symbol;
|
||||||
|
|
||||||
if (g_strcmp0 (element_name, "keysym") == 0) {
|
if (g_strcmp0 (element_name, "keysym") == 0) {
|
||||||
EekSymbol *keysym;
|
EekKeysym *keysym;
|
||||||
if (data->keyval != EEK_INVALID_KEYSYM)
|
if (data->keyval != EEK_INVALID_KEYSYM)
|
||||||
keysym = eek_keysym_new (data->keyval);
|
keysym = eek_keysym_new (data->keyval);
|
||||||
else
|
else
|
||||||
keysym = eek_keysym_new_from_name (text);
|
keysym = eek_keysym_new_from_name (text);
|
||||||
symbol = keysym;
|
symbol = EEK_SYMBOL(keysym);
|
||||||
} else if (g_strcmp0 (element_name, "text") == 0) {
|
} else if (g_strcmp0 (element_name, "text") == 0) {
|
||||||
symbol = eek_text_new (text);
|
symbol = EEK_SYMBOL(eek_text_new (text));
|
||||||
} else {
|
} else {
|
||||||
symbol = eek_symbol_new (text);
|
symbol = eek_symbol_new (text);
|
||||||
|
eek_symbol_set_category (symbol, EEK_SYMBOL_CATEGORY_KEYNAME);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data->label) {
|
if (data->label) {
|
||||||
eek_symbol_set_label (symbol, 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);
|
g_free (data->label);
|
||||||
data->label = NULL;
|
data->label = NULL;
|
||||||
}
|
}
|
||||||
@ -931,8 +945,8 @@ eek_xml_layout_real_create_keyboard (EekboardContextService *manager,
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Arrange the sections in the original coordinate system. */
|
/* Fit keyboard in the given width and hight. */
|
||||||
eek_layout_place_sections(keyboard);
|
scale_keyboard (keyboard, initial_width, initial_height);
|
||||||
|
|
||||||
/* Use pre-defined modifier mask here. */
|
/* Use pre-defined modifier mask here. */
|
||||||
eek_keyboard_set_num_lock_mask (keyboard, EEK_MOD2_MASK);
|
eek_keyboard_set_num_lock_mask (keyboard, EEK_MOD2_MASK);
|
||||||
@ -1124,6 +1138,38 @@ eek_xml_keyboard_desc_free (EekXmlKeyboardDesc *desc)
|
|||||||
g_slice_free (EekXmlKeyboardDesc, desc);
|
g_slice_free (EekXmlKeyboardDesc, desc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct place_data {
|
||||||
|
double desired_width;
|
||||||
|
double current_offset;
|
||||||
|
EekKeyboard *keyboard;
|
||||||
|
};
|
||||||
|
|
||||||
|
const double section_spacing = 7.0;
|
||||||
|
|
||||||
|
static void section_placer(EekElement *element, gpointer user_data) {
|
||||||
|
struct place_data *data = (struct place_data*)user_data;
|
||||||
|
|
||||||
|
EekBounds section_bounds = {0};
|
||||||
|
eek_element_get_bounds(element, §ion_bounds);
|
||||||
|
section_bounds.width = data->desired_width;
|
||||||
|
eek_element_set_bounds(element, §ion_bounds);
|
||||||
|
|
||||||
|
// Sections are rows now. Gather up all the keys and adjust their bounds.
|
||||||
|
eek_section_place_keys(EEK_SECTION(element), EEK_KEYBOARD(data->keyboard));
|
||||||
|
|
||||||
|
eek_element_get_bounds(element, §ion_bounds);
|
||||||
|
section_bounds.y = data->current_offset;
|
||||||
|
eek_element_set_bounds(element, §ion_bounds);
|
||||||
|
data->current_offset += section_bounds.height + section_spacing;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void section_counter(EekElement *element, gpointer user_data) {
|
||||||
|
double *total_height = user_data;
|
||||||
|
EekBounds section_bounds = {0};
|
||||||
|
eek_element_get_bounds(element, §ion_bounds);
|
||||||
|
*total_height += section_bounds.height + section_spacing;
|
||||||
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
parse_geometry (const gchar *path, EekKeyboard *keyboard, GError **error)
|
parse_geometry (const gchar *path, EekKeyboard *keyboard, GError **error)
|
||||||
{
|
{
|
||||||
@ -1178,6 +1224,27 @@ parse_geometry (const gchar *path, EekKeyboard *keyboard, GError **error)
|
|||||||
}
|
}
|
||||||
g_hash_table_destroy (oref_hash);
|
g_hash_table_destroy (oref_hash);
|
||||||
|
|
||||||
|
/* Order rows */
|
||||||
|
// This needs to be done after outlines, because outlines define key sizes
|
||||||
|
// TODO: do this only for rows without bounds
|
||||||
|
|
||||||
|
// The keyboard width is given by the user via screen size. The height will be given dynamically.
|
||||||
|
// TODO: calculate max line width beforehand for button centering. Leave keyboard centering to the renderer later
|
||||||
|
EekBounds keyboard_bounds = {0};
|
||||||
|
eek_element_get_bounds(EEK_ELEMENT(keyboard), &keyboard_bounds);
|
||||||
|
|
||||||
|
struct place_data placer_data = {
|
||||||
|
.desired_width = keyboard_bounds.width,
|
||||||
|
.current_offset = 0,
|
||||||
|
.keyboard = keyboard,
|
||||||
|
};
|
||||||
|
eek_container_foreach_child(EEK_CONTAINER(keyboard), section_placer, &placer_data);
|
||||||
|
|
||||||
|
double total_height = 0;
|
||||||
|
eek_container_foreach_child(EEK_CONTAINER(keyboard), section_counter, &total_height);
|
||||||
|
keyboard_bounds.height = total_height;
|
||||||
|
eek_element_set_bounds(EEK_ELEMENT(keyboard), &keyboard_bounds);
|
||||||
|
|
||||||
geometry_parse_data_free (data);
|
geometry_parse_data_free (data);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
@ -1343,6 +1410,65 @@ parse_keyboards (const gchar *path, GError **error)
|
|||||||
return keyboards;
|
return keyboards;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void scale_bounds_callback (EekElement *element,
|
||||||
|
gpointer user_data);
|
||||||
|
|
||||||
|
static void
|
||||||
|
scale_bounds (EekElement *element,
|
||||||
|
gdouble scale)
|
||||||
|
{
|
||||||
|
EekBounds bounds;
|
||||||
|
|
||||||
|
eek_element_get_bounds (element, &bounds);
|
||||||
|
bounds.x *= scale;
|
||||||
|
bounds.y *= scale;
|
||||||
|
bounds.width *= scale;
|
||||||
|
bounds.height *= scale;
|
||||||
|
eek_element_set_bounds (element, &bounds);
|
||||||
|
|
||||||
|
if (EEK_IS_CONTAINER(element))
|
||||||
|
eek_container_foreach_child (EEK_CONTAINER(element),
|
||||||
|
scale_bounds_callback,
|
||||||
|
&scale);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
scale_bounds_callback (EekElement *element,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
scale_bounds (element, *(gdouble *)user_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void scale_keyboard (EekKeyboard *keyboard,
|
||||||
|
gdouble width,
|
||||||
|
gdouble height)
|
||||||
|
{
|
||||||
|
gdouble scale;
|
||||||
|
EekBounds bounds;
|
||||||
|
gsize n_outlines;
|
||||||
|
guint i;
|
||||||
|
|
||||||
|
eek_element_get_bounds (EEK_ELEMENT(keyboard), &bounds);
|
||||||
|
|
||||||
|
if (width * bounds.height < height * bounds.width)
|
||||||
|
scale = width / bounds.width;
|
||||||
|
else
|
||||||
|
scale = height / bounds.height;
|
||||||
|
|
||||||
|
scale_bounds (EEK_ELEMENT(keyboard), scale);
|
||||||
|
|
||||||
|
n_outlines = eek_keyboard_get_n_outlines (keyboard);
|
||||||
|
for (i = 0; i < n_outlines; i++) {
|
||||||
|
EekOutline *outline = eek_keyboard_get_outline (keyboard, i);
|
||||||
|
gint j;
|
||||||
|
|
||||||
|
for (j = 0; j < outline->num_points; j++) {
|
||||||
|
outline->points[j].x *= scale;
|
||||||
|
outline->points[j].y *= scale;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
validate (const gchar **valid_path_list,
|
validate (const gchar **valid_path_list,
|
||||||
gsize valid_path_list_len,
|
gsize valid_path_list_len,
|
||||||
|
|||||||
317
eek/eek-xml.c
Normal file
317
eek/eek-xml.c
Normal file
@ -0,0 +1,317 @@
|
|||||||
|
/*
|
||||||
|
* 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
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "config.h"
|
||||||
|
#endif /* HAVE_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");
|
||||||
|
}
|
||||||
39
eek/eek-xml.h
Normal file
39
eek/eek-xml.h
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
/*
|
||||||
|
* 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 */
|
||||||
@ -23,7 +23,9 @@
|
|||||||
* @title: Library Initialization
|
* @title: Library Initialization
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
#endif /* HAVE_CONFIG_H */
|
||||||
|
|
||||||
#include "eek.h"
|
#include "eek.h"
|
||||||
|
|
||||||
|
|||||||
@ -29,7 +29,9 @@
|
|||||||
#include "eek-symbol.h"
|
#include "eek-symbol.h"
|
||||||
#include "eek-keysym.h"
|
#include "eek-keysym.h"
|
||||||
#include "eek-text.h"
|
#include "eek-text.h"
|
||||||
|
#include "eek-xml.h"
|
||||||
#include "eek-serializable.h"
|
#include "eek-serializable.h"
|
||||||
|
#include "eek-theme.h"
|
||||||
|
|
||||||
void eek_init (void);
|
void eek_init (void);
|
||||||
|
|
||||||
|
|||||||
@ -33,7 +33,7 @@ else:
|
|||||||
|
|
||||||
table = dict()
|
table = dict()
|
||||||
for line in in_stream:
|
for line in in_stream:
|
||||||
match = re.match(r'\s*(0x[0-9A-F]+)\s+"(.*)"\s+(\S*)', line, re.I)
|
match = re.match(r'\s*(0x[0-9A-F]+)\s+(\S*)\s+(\S*)', line, re.I)
|
||||||
if match:
|
if match:
|
||||||
table[int(match.group(1), 16)] = (match.group(2), match.group(3))
|
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 index, (keysym, (l, c)) in enumerate([(keysym, table[keysym])
|
||||||
for keysym in sorted(table.keys())]):
|
for keysym in sorted(table.keys())]):
|
||||||
sys.stdout.write(" { 0x%X, \"%s\" }" %
|
sys.stdout.write(" { 0x%X, %s, %s }" %
|
||||||
(keysym, l))
|
(keysym, l, c))
|
||||||
if index < len(table) - 1:
|
if index < len(table) - 1:
|
||||||
sys.stdout.write(",")
|
sys.stdout.write(",")
|
||||||
sys.stdout.write("\n")
|
sys.stdout.write("\n")
|
||||||
|
|||||||
39
eek/keymap.h
39
eek/keymap.h
@ -1,39 +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);
|
|
||||||
|
|
||||||
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\
|
|
||||||
};";
|
|
||||||
@ -65,9 +65,9 @@ static void layer_surface_configure(void *data,
|
|||||||
uint32_t height)
|
uint32_t height)
|
||||||
{
|
{
|
||||||
PhoshLayerSurface *self = data;
|
PhoshLayerSurface *self = data;
|
||||||
|
|
||||||
gtk_window_resize (GTK_WINDOW (self), width, height);
|
gtk_window_resize (GTK_WINDOW (self), width, height);
|
||||||
zwlr_layer_surface_v1_ack_configure(surface, serial);
|
zwlr_layer_surface_v1_ack_configure(surface, serial);
|
||||||
|
gtk_widget_show_all (GTK_WIDGET (self));
|
||||||
|
|
||||||
g_signal_emit (self, signals[CONFIGURED], 0);
|
g_signal_emit (self, signals[CONFIGURED], 0);
|
||||||
}
|
}
|
||||||
@ -180,39 +180,22 @@ phosh_layer_surface_get_property (GObject *object,
|
|||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
on_phosh_layer_surface_realized (PhoshLayerSurface *self, gpointer unused)
|
phosh_layer_surface_constructed (GObject *object)
|
||||||
{
|
{
|
||||||
PhoshLayerSurfacePrivate *priv;
|
PhoshLayerSurface *self = PHOSH_LAYER_SURFACE (object);
|
||||||
|
PhoshLayerSurfacePrivate *priv = phosh_layer_surface_get_instance_private (self);
|
||||||
GdkWindow *gdk_window;
|
GdkWindow *gdk_window;
|
||||||
|
|
||||||
g_return_if_fail (PHOSH_IS_LAYER_SURFACE (self));
|
G_OBJECT_CLASS (phosh_layer_surface_parent_class)->constructed (object);
|
||||||
|
|
||||||
priv = phosh_layer_surface_get_instance_private (self);
|
gtk_window_set_decorated (GTK_WINDOW (self), FALSE);
|
||||||
|
/* Realize the window so we can get the GDK window */
|
||||||
|
gtk_widget_realize(GTK_WIDGET (self));
|
||||||
|
|
||||||
gdk_window = gtk_widget_get_window (GTK_WIDGET (self));
|
gdk_window = gtk_widget_get_window (GTK_WIDGET (self));
|
||||||
gdk_wayland_window_set_use_custom_surface (gdk_window);
|
gdk_wayland_window_set_use_custom_surface (gdk_window);
|
||||||
priv->wl_surface = gdk_wayland_window_get_wl_surface (gdk_window);
|
priv->wl_surface = gdk_wayland_window_get_wl_surface (gdk_window);
|
||||||
|
|
||||||
gtk_window_set_decorated (GTK_WINDOW (self), FALSE);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void
|
|
||||||
on_phosh_layer_surface_mapped (PhoshLayerSurface *self, gpointer unused)
|
|
||||||
{
|
|
||||||
PhoshLayerSurfacePrivate *priv;
|
|
||||||
GdkWindow *gdk_window;
|
|
||||||
|
|
||||||
g_return_if_fail (PHOSH_IS_LAYER_SURFACE (self));
|
|
||||||
priv = phosh_layer_surface_get_instance_private (self);
|
|
||||||
|
|
||||||
if (!priv->wl_surface) {
|
|
||||||
gdk_window = gtk_widget_get_window (GTK_WIDGET (self));
|
|
||||||
gdk_wayland_window_set_use_custom_surface (gdk_window);
|
|
||||||
priv->wl_surface = gdk_wayland_window_get_wl_surface (gdk_window);
|
|
||||||
}
|
|
||||||
g_debug ("Mapped %p", priv->wl_surface);
|
|
||||||
|
|
||||||
priv->layer_surface = zwlr_layer_shell_v1_get_layer_surface(priv->layer_shell,
|
priv->layer_surface = zwlr_layer_shell_v1_get_layer_surface(priv->layer_shell,
|
||||||
priv->wl_surface,
|
priv->wl_surface,
|
||||||
priv->wl_output,
|
priv->wl_output,
|
||||||
@ -226,45 +209,8 @@ on_phosh_layer_surface_mapped (PhoshLayerSurface *self, gpointer unused)
|
|||||||
&layer_surface_listener,
|
&layer_surface_listener,
|
||||||
self);
|
self);
|
||||||
wl_surface_commit(priv->wl_surface);
|
wl_surface_commit(priv->wl_surface);
|
||||||
|
|
||||||
/* Process all pending events, otherwise we end up sending ack configure
|
|
||||||
* to a not yet configured surface */
|
|
||||||
wl_display_roundtrip (gdk_wayland_display_get_wl_display (gdk_display_get_default ()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
on_phosh_layer_surface_unmapped (PhoshLayerSurface *self, gpointer unused)
|
|
||||||
{
|
|
||||||
PhoshLayerSurfacePrivate *priv;
|
|
||||||
|
|
||||||
g_return_if_fail (PHOSH_IS_LAYER_SURFACE (self));
|
|
||||||
priv = phosh_layer_surface_get_instance_private (self);
|
|
||||||
|
|
||||||
priv = phosh_layer_surface_get_instance_private (self);
|
|
||||||
if (priv->layer_surface) {
|
|
||||||
zwlr_layer_surface_v1_destroy(priv->layer_surface);
|
|
||||||
priv->layer_surface = NULL;
|
|
||||||
}
|
|
||||||
priv->wl_surface = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
phosh_layer_surface_constructed (GObject *object)
|
|
||||||
{
|
|
||||||
PhoshLayerSurface *self = PHOSH_LAYER_SURFACE (object);
|
|
||||||
|
|
||||||
g_signal_connect (self, "realize",
|
|
||||||
G_CALLBACK (on_phosh_layer_surface_realized),
|
|
||||||
NULL);
|
|
||||||
g_signal_connect (self, "map",
|
|
||||||
G_CALLBACK (on_phosh_layer_surface_mapped),
|
|
||||||
NULL);
|
|
||||||
g_signal_connect (self, "unmap",
|
|
||||||
G_CALLBACK (on_phosh_layer_surface_unmapped),
|
|
||||||
NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
phosh_layer_surface_dispose (GObject *object)
|
phosh_layer_surface_dispose (GObject *object)
|
||||||
{
|
{
|
||||||
@ -406,12 +352,6 @@ phosh_layer_surface_new (gpointer layer_shell,
|
|||||||
"wl-output", wl_output);
|
"wl-output", wl_output);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* phosh_layer_surface_get_surface:
|
|
||||||
*
|
|
||||||
* Get the layer layer surface or #NULL if the window
|
|
||||||
* is not yet realized.
|
|
||||||
*/
|
|
||||||
struct zwlr_layer_surface_v1 *
|
struct zwlr_layer_surface_v1 *
|
||||||
phosh_layer_surface_get_layer_surface(PhoshLayerSurface *self)
|
phosh_layer_surface_get_layer_surface(PhoshLayerSurface *self)
|
||||||
{
|
{
|
||||||
@ -423,12 +363,6 @@ phosh_layer_surface_get_layer_surface(PhoshLayerSurface *self)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* phosh_layer_surface_get_wl_surface:
|
|
||||||
*
|
|
||||||
* Get the layer wayland surface or #NULL if the window
|
|
||||||
* is not yet realized.
|
|
||||||
*/
|
|
||||||
struct wl_surface *
|
struct wl_surface *
|
||||||
phosh_layer_surface_get_wl_surface(PhoshLayerSurface *self)
|
phosh_layer_surface_get_wl_surface(PhoshLayerSurface *self)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -25,7 +25,11 @@
|
|||||||
* implementation of eekboard input context service.
|
* implementation of eekboard input context service.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
#endif /* HAVE_CONFIG_H */
|
||||||
|
|
||||||
|
#include "eekboard/eekboard-context-service.h"
|
||||||
|
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
@ -34,14 +38,10 @@
|
|||||||
#include <sys/random.h> // TODO: this is Linux-specific
|
#include <sys/random.h> // TODO: this is Linux-specific
|
||||||
#include <xkbcommon/xkbcommon.h>
|
#include <xkbcommon/xkbcommon.h>
|
||||||
|
|
||||||
#include <gio/gio.h>
|
|
||||||
|
|
||||||
#include "eekboard/key-emitter.h"
|
#include "eekboard/key-emitter.h"
|
||||||
#include "wayland.h"
|
#include "wayland.h"
|
||||||
|
//#include "eekboard/eekboard-xklutil.h"
|
||||||
#include "eek/eek-xml-layout.h"
|
//#include "eek/eek-xkl.h"
|
||||||
|
|
||||||
#include "eekboard/eekboard-context-service.h"
|
|
||||||
|
|
||||||
#define CSW 640
|
#define CSW 640
|
||||||
#define CSH 480
|
#define CSH 480
|
||||||
@ -80,12 +80,12 @@ struct _EekboardContextServicePrivate {
|
|||||||
gboolean repeat_triggered;
|
gboolean repeat_triggered;
|
||||||
|
|
||||||
GSettings *settings;
|
GSettings *settings;
|
||||||
uint32_t hint;
|
|
||||||
uint32_t purpose;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
G_DEFINE_TYPE_WITH_PRIVATE (EekboardContextService, eekboard_context_service, G_TYPE_OBJECT);
|
G_DEFINE_TYPE_WITH_PRIVATE (EekboardContextService, eekboard_context_service, G_TYPE_OBJECT);
|
||||||
|
|
||||||
|
/*static Display *display = NULL; */
|
||||||
|
|
||||||
static EekKeyboard *
|
static EekKeyboard *
|
||||||
eekboard_context_service_real_create_keyboard (EekboardContextService *self,
|
eekboard_context_service_real_create_keyboard (EekboardContextService *self,
|
||||||
const gchar *keyboard_type)
|
const gchar *keyboard_type)
|
||||||
@ -146,22 +146,17 @@ eekboard_context_service_real_create_keyboard (EekboardContextService *self,
|
|||||||
g_error("No context created");
|
g_error("No context created");
|
||||||
}
|
}
|
||||||
|
|
||||||
gchar *keymap_str = eek_keyboard_get_keymap(keyboard);
|
struct xkb_rule_names rules = { 0 };
|
||||||
|
rules.layout = strdup(keyboard_type);
|
||||||
struct xkb_keymap *keymap = xkb_keymap_new_from_string(context, keymap_str,
|
struct xkb_keymap *keymap = xkb_keymap_new_from_names(context, &rules,
|
||||||
XKB_KEYMAP_FORMAT_TEXT_V1, XKB_KEYMAP_COMPILE_NO_FLAGS);
|
XKB_KEYMAP_COMPILE_NO_FLAGS);
|
||||||
|
|
||||||
free(keymap_str);
|
|
||||||
|
|
||||||
xkb_context_unref(context);
|
xkb_context_unref(context);
|
||||||
if (!keymap) {
|
if (!keymap) {
|
||||||
g_error("Bad keymap");
|
g_error("Bad keymap");
|
||||||
}
|
}
|
||||||
keyboard->keymap = keymap;
|
keyboard->keymap = keymap;
|
||||||
|
char *keymap_str = xkb_keymap_get_as_string(keymap, XKB_KEYMAP_FORMAT_TEXT_V1);
|
||||||
keymap_str = xkb_keymap_get_as_string(keymap, XKB_KEYMAP_FORMAT_TEXT_V1);
|
|
||||||
keyboard->keymap_len = strlen(keymap_str) + 1;
|
keyboard->keymap_len = strlen(keymap_str) + 1;
|
||||||
|
|
||||||
g_autofree char *path = strdup("/eek_keymap-XXXXXX");
|
g_autofree char *path = strdup("/eek_keymap-XXXXXX");
|
||||||
char *r = &path[strlen(path) - 6];
|
char *r = &path[strlen(path) - 6];
|
||||||
getrandom(r, 6, GRND_NONBLOCK);
|
getrandom(r, 6, GRND_NONBLOCK);
|
||||||
@ -217,7 +212,12 @@ eekboard_context_service_set_property (GObject *object,
|
|||||||
context->priv->keyboard = g_value_get_object (value);
|
context->priv->keyboard = g_value_get_object (value);
|
||||||
break;
|
break;
|
||||||
case PROP_VISIBLE:
|
case PROP_VISIBLE:
|
||||||
context->priv->visible = g_value_get_boolean (value);
|
/*if (context->priv->keyboard) {
|
||||||
|
if (g_value_get_boolean (value))
|
||||||
|
eekboard_context_service_show_keyboard (context);
|
||||||
|
else
|
||||||
|
eekboard_context_service_hide_keyboard (context);
|
||||||
|
}*/
|
||||||
break;
|
break;
|
||||||
case PROP_FULLSCREEN:
|
case PROP_FULLSCREEN:
|
||||||
context->priv->fullscreen = g_value_get_boolean (value);
|
context->priv->fullscreen = g_value_get_boolean (value);
|
||||||
@ -289,8 +289,7 @@ settings_get_layout(GSettings *settings, char **type, char **layout)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
settings_update_layout(EekboardContextService *context)
|
settings_update_layout(EekboardContextService *context) {
|
||||||
{
|
|
||||||
g_autofree gchar *keyboard_type = NULL;
|
g_autofree gchar *keyboard_type = NULL;
|
||||||
g_autofree gchar *keyboard_layout = NULL;
|
g_autofree gchar *keyboard_layout = NULL;
|
||||||
settings_get_layout(context->priv->settings, &keyboard_type, &keyboard_layout);
|
settings_get_layout(context->priv->settings, &keyboard_type, &keyboard_layout);
|
||||||
@ -302,27 +301,6 @@ settings_update_layout(EekboardContextService *context)
|
|||||||
keyboard_layout = g_strdup("undefined");
|
keyboard_layout = g_strdup("undefined");
|
||||||
}
|
}
|
||||||
|
|
||||||
EekboardContextServicePrivate *priv = EEKBOARD_CONTEXT_SERVICE_GET_PRIVATE(context);
|
|
||||||
|
|
||||||
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
|
// generic part follows
|
||||||
static guint keyboard_id = 0;
|
static guint keyboard_id = 0;
|
||||||
EekKeyboard *keyboard = g_hash_table_lookup(context->priv->keyboard_hash,
|
EekKeyboard *keyboard = g_hash_table_lookup(context->priv->keyboard_hash,
|
||||||
@ -610,15 +588,3 @@ void eekboard_context_service_set_keymap(EekboardContextService *context,
|
|||||||
WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1,
|
WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1,
|
||||||
keyboard->keymap_fd, keyboard->keymap_len);
|
keyboard->keymap_fd, keyboard->keymap_len);
|
||||||
}
|
}
|
||||||
|
|
||||||
void eekboard_context_service_set_hint_purpose(EekboardContextService *context,
|
|
||||||
uint32_t hint, uint32_t purpose)
|
|
||||||
{
|
|
||||||
EekboardContextServicePrivate *priv = EEKBOARD_CONTEXT_SERVICE_GET_PRIVATE(context);
|
|
||||||
|
|
||||||
if (priv->hint != hint || priv->purpose != purpose) {
|
|
||||||
priv->hint = hint;
|
|
||||||
priv->purpose = purpose;
|
|
||||||
settings_update_layout(context);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@ -25,7 +25,6 @@
|
|||||||
#include <eek/eek.h>
|
#include <eek/eek.h>
|
||||||
|
|
||||||
#include "virtual-keyboard-unstable-v1-client-protocol.h"
|
#include "virtual-keyboard-unstable-v1-client-protocol.h"
|
||||||
#include "text-input-unstable-v3-client-protocol.h"
|
|
||||||
|
|
||||||
G_BEGIN_DECLS
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
@ -105,9 +104,5 @@ gboolean eekboard_context_service_get_fullscreen
|
|||||||
void eekboard_context_service_set_keymap(EekboardContextService *context,
|
void eekboard_context_service_set_keymap(EekboardContextService *context,
|
||||||
const EekKeyboard *keyboard);
|
const EekKeyboard *keyboard);
|
||||||
|
|
||||||
void eekboard_context_service_set_hint_purpose(EekboardContextService *context,
|
|
||||||
uint32_t hint,
|
|
||||||
uint32_t purpose);
|
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
#endif /* EEKBOARD_CONTEXT_SERVICE_H */
|
#endif /* EEKBOARD_CONTEXT_SERVICE_H */
|
||||||
|
|||||||
@ -24,7 +24,9 @@
|
|||||||
* context.
|
* context.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
#endif /* HAVE_CONFIG_H */
|
||||||
|
|
||||||
#include "eekboard/eekboard-context.h"
|
#include "eekboard/eekboard-context.h"
|
||||||
//#include "eekboard/eekboard-marshalers.h"
|
//#include "eekboard/eekboard-marshalers.h"
|
||||||
@ -35,6 +37,7 @@ enum {
|
|||||||
ENABLED,
|
ENABLED,
|
||||||
DISABLED,
|
DISABLED,
|
||||||
DESTROYED,
|
DESTROYED,
|
||||||
|
KEY_ACTIVATED,
|
||||||
LAST_SIGNAL
|
LAST_SIGNAL
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -80,6 +83,28 @@ eekboard_context_real_g_signal (GDBusProxy *self,
|
|||||||
return;
|
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) {
|
if (g_strcmp0 (signal_name, "VisibilityChanged") == 0) {
|
||||||
gboolean visible = FALSE;
|
gboolean visible = FALSE;
|
||||||
|
|
||||||
@ -126,6 +151,14 @@ eekboard_context_real_destroyed (EekboardContext *self)
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
eekboard_context_real_key_activated (EekboardContext *self,
|
||||||
|
guint keycode,
|
||||||
|
EekSymbol *symbol,
|
||||||
|
guint modifiers)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
eekboard_context_get_property (GObject *object,
|
eekboard_context_get_property (GObject *object,
|
||||||
guint prop_id,
|
guint prop_id,
|
||||||
@ -155,6 +188,7 @@ eekboard_context_class_init (EekboardContextClass *klass)
|
|||||||
klass->enabled = eekboard_context_real_enabled;
|
klass->enabled = eekboard_context_real_enabled;
|
||||||
klass->disabled = eekboard_context_real_disabled;
|
klass->disabled = eekboard_context_real_disabled;
|
||||||
klass->destroyed = eekboard_context_real_destroyed;
|
klass->destroyed = eekboard_context_real_destroyed;
|
||||||
|
klass->key_activated = eekboard_context_real_key_activated;
|
||||||
|
|
||||||
proxy_class->g_signal = eekboard_context_real_g_signal;
|
proxy_class->g_signal = eekboard_context_real_g_signal;
|
||||||
|
|
||||||
@ -208,6 +242,31 @@ eekboard_context_class_init (EekboardContextClass *klass)
|
|||||||
G_TYPE_NONE,
|
G_TYPE_NONE,
|
||||||
0);
|
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:
|
* EekboardContext::destroyed:
|
||||||
* @context: an #EekboardContext
|
* @context: an #EekboardContext
|
||||||
|
|||||||
@ -47,6 +47,11 @@ struct _EekboardContextClass {
|
|||||||
void (*disabled) (EekboardContext *self);
|
void (*disabled) (EekboardContext *self);
|
||||||
void (*destroyed) (EekboardContext *self);
|
void (*destroyed) (EekboardContext *self);
|
||||||
|
|
||||||
|
void (*key_activated) (EekboardContext *self,
|
||||||
|
guint keycode,
|
||||||
|
EekSymbol *symbol,
|
||||||
|
guint modifiers);
|
||||||
|
|
||||||
/*< private >*/
|
/*< private >*/
|
||||||
/* padding */
|
/* padding */
|
||||||
gpointer pdummy[24];
|
gpointer pdummy[24];
|
||||||
|
|||||||
@ -26,16 +26,16 @@
|
|||||||
* implementation of eekboard service.
|
* implementation of eekboard service.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
#endif /* HAVE_CONFIG_H */
|
||||||
|
|
||||||
|
#include "eekboard/eekboard-service.h"
|
||||||
|
|
||||||
#include "sm.puri.OSK0.h"
|
#include "sm.puri.OSK0.h"
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
#include <gio/gio.h>
|
|
||||||
|
|
||||||
#include "eekboard/eekboard-service.h"
|
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
PROP_0,
|
PROP_0,
|
||||||
PROP_OBJECT_PATH,
|
PROP_OBJECT_PATH,
|
||||||
|
|||||||
@ -20,6 +20,7 @@
|
|||||||
/* This file is responsible for managing keycode data and emitting keycodes. */
|
/* This file is responsible for managing keycode data and emitting keycodes. */
|
||||||
|
|
||||||
#include "eekboard/key-emitter.h"
|
#include "eekboard/key-emitter.h"
|
||||||
|
#include "eekboard/keymap.h"
|
||||||
|
|
||||||
#include <gdk/gdk.h>
|
#include <gdk/gdk.h>
|
||||||
|
|
||||||
@ -38,6 +39,98 @@ typedef struct {
|
|||||||
} SeatEmitter;
|
} 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(
|
int send_virtual_keyboard_key(
|
||||||
struct zwp_virtual_keyboard_v1 *keyboard,
|
struct zwp_virtual_keyboard_v1 *keyboard,
|
||||||
unsigned int keycode,
|
unsigned int keycode,
|
||||||
@ -48,6 +141,115 @@ int send_virtual_keyboard_key(
|
|||||||
return 0;
|
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 */
|
/* Finds the first key code for each modifier and saves it in modifier_keycodes */
|
||||||
static void
|
static void
|
||||||
update_modifier_info (SeatEmitter *client)
|
update_modifier_info (SeatEmitter *client)
|
||||||
@ -82,57 +284,6 @@ update_modifier_info (SeatEmitter *client)
|
|||||||
}*/
|
}*/
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
send_fake_key (SeatEmitter *emitter,
|
|
||||||
guint level,
|
|
||||||
guint keycode,
|
|
||||||
guint keyboard_modifiers,
|
|
||||||
gboolean pressed,
|
|
||||||
uint32_t timestamp)
|
|
||||||
{
|
|
||||||
uint32_t proto_modifiers = 0;
|
|
||||||
uint32_t group = (level / 2);
|
|
||||||
|
|
||||||
if (keyboard_modifiers & EEK_SHIFT_MASK)
|
|
||||||
proto_modifiers |= 1<<MOD_IDX_SHIFT;
|
|
||||||
|
|
||||||
zwp_virtual_keyboard_v1_modifiers(emitter->virtual_keyboard, proto_modifiers, 0, 0, group);
|
|
||||||
send_virtual_keyboard_key (emitter->virtual_keyboard, keycode - 8, (unsigned)pressed, timestamp);
|
|
||||||
zwp_virtual_keyboard_v1_modifiers(emitter->virtual_keyboard, proto_modifiers, 0, 0, group);
|
|
||||||
}
|
|
||||||
|
|
||||||
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
|
void
|
||||||
emit_key_activated (EekboardContextService *manager,
|
emit_key_activated (EekboardContextService *manager,
|
||||||
EekKeyboard *keyboard,
|
EekKeyboard *keyboard,
|
||||||
@ -173,12 +324,5 @@ emit_key_activated (EekboardContextService *manager,
|
|||||||
emitter.virtual_keyboard = manager->virtual_keyboard;
|
emitter.virtual_keyboard = manager->virtual_keyboard;
|
||||||
emitter.keymap = keyboard->keymap;
|
emitter.keymap = keyboard->keymap;
|
||||||
update_modifier_info (&emitter);
|
update_modifier_info (&emitter);
|
||||||
|
send_fake_key_events (&emitter, symbol, 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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
#include <glib.h>
|
#include <glib.h>
|
||||||
|
#include <X11/XKBlib.h>
|
||||||
|
|
||||||
#include "eek/eek.h"
|
#include "eek/eek.h"
|
||||||
|
|
||||||
|
|||||||
66
eekboard/keymap.c
Normal file
66
eekboard/keymap.c
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
/* 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;
|
||||||
|
}
|
||||||
8
eekboard/keymap.h
Normal file
8
eekboard/keymap.h
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
#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);
|
||||||
23
meson.build
23
meson.build
@ -4,21 +4,7 @@ project(
|
|||||||
version: '1.0.10',
|
version: '1.0.10',
|
||||||
license: 'GPLv3',
|
license: 'GPLv3',
|
||||||
meson_version: '>=0.49.0',
|
meson_version: '>=0.49.0',
|
||||||
default_options: [
|
default_options: [ 'warning_level=1', 'buildtype=debugoptimized', 'c_std=gnu11' ],
|
||||||
'warning_level=1',
|
|
||||||
'buildtype=debugoptimized',
|
|
||||||
'c_std=gnu11'
|
|
||||||
]
|
|
||||||
)
|
|
||||||
|
|
||||||
add_project_arguments(
|
|
||||||
[
|
|
||||||
'-Werror=implicit-function-declaration',
|
|
||||||
'-Werror=implicit-fallthrough=3',
|
|
||||||
'-Werror=maybe-uninitialized',
|
|
||||||
'-Werror=missing-field-initializers',
|
|
||||||
],
|
|
||||||
language: 'c'
|
|
||||||
)
|
)
|
||||||
|
|
||||||
i18n = import('i18n')
|
i18n = import('i18n')
|
||||||
@ -42,11 +28,17 @@ else
|
|||||||
endif
|
endif
|
||||||
dbusdir = join_paths(depdatadir, 'dbus-1/interfaces')
|
dbusdir = join_paths(depdatadir, 'dbus-1/interfaces')
|
||||||
|
|
||||||
|
gsound_dep = dependency('gsound', required : false)
|
||||||
|
if gsound_dep.found()
|
||||||
|
conf_data.set10('HAVE_GSOUND', true)
|
||||||
|
endif
|
||||||
|
|
||||||
summary = [
|
summary = [
|
||||||
'',
|
'',
|
||||||
'------------------',
|
'------------------',
|
||||||
'squeekboard @0@'.format(meson.project_version()),
|
'squeekboard @0@'.format(meson.project_version()),
|
||||||
'',
|
'',
|
||||||
|
' gsound: @0@'.format(conf_data.get('HAVE_GSOUND', false)),
|
||||||
'------------------',
|
'------------------',
|
||||||
''
|
''
|
||||||
]
|
]
|
||||||
@ -57,4 +49,3 @@ subdir('protocols')
|
|||||||
subdir('eek')
|
subdir('eek')
|
||||||
subdir('src')
|
subdir('src')
|
||||||
subdir('po')
|
subdir('po')
|
||||||
subdir('tests')
|
|
||||||
|
|||||||
@ -1,8 +1 @@
|
|||||||
option('depdatadir',
|
option('depdatadir', type : 'string', value : '', description : 'System data path. Will be searched for definitions instead of datadir when provided')
|
||||||
type : 'string',
|
|
||||||
value : '',
|
|
||||||
description : 'System data path. Will be searched for definitions instead of datadir when provided')
|
|
||||||
|
|
||||||
option('tests',
|
|
||||||
type: 'boolean', value: true,
|
|
||||||
description: 'Whether to compile unit tests')
|
|
||||||
|
|||||||
@ -14,7 +14,6 @@ wl_protos = [
|
|||||||
'wlr-layer-shell-unstable-v1.xml',
|
'wlr-layer-shell-unstable-v1.xml',
|
||||||
'virtual-keyboard-unstable-v1.xml',
|
'virtual-keyboard-unstable-v1.xml',
|
||||||
'input-method-unstable-v2.xml',
|
'input-method-unstable-v2.xml',
|
||||||
'text-input-unstable-v3.xml'
|
|
||||||
]
|
]
|
||||||
wl_proto_sources = []
|
wl_proto_sources = []
|
||||||
foreach proto: wl_protos
|
foreach proto: wl_protos
|
||||||
|
|||||||
@ -1,441 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
|
|
||||||
<protocol name="text_input_unstable_v3">
|
|
||||||
<copyright>
|
|
||||||
Copyright © 2012, 2013 Intel Corporation
|
|
||||||
Copyright © 2015, 2016 Jan Arne Petersen
|
|
||||||
Copyright © 2017, 2018 Red Hat, Inc.
|
|
||||||
Copyright © 2018 Purism SPC
|
|
||||||
|
|
||||||
Permission to use, copy, modify, distribute, and sell this
|
|
||||||
software and its documentation for any purpose is hereby granted
|
|
||||||
without fee, provided that the above copyright notice appear in
|
|
||||||
all copies and that both that copyright notice and this permission
|
|
||||||
notice appear in supporting documentation, and that the name of
|
|
||||||
the copyright holders not be used in advertising or publicity
|
|
||||||
pertaining to distribution of the software without specific,
|
|
||||||
written prior permission. The copyright holders make no
|
|
||||||
representations about the suitability of this software for any
|
|
||||||
purpose. It is provided "as is" without express or implied
|
|
||||||
warranty.
|
|
||||||
|
|
||||||
THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
|
|
||||||
SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
|
||||||
FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
|
||||||
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
||||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
|
|
||||||
AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
|
|
||||||
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
|
|
||||||
THIS SOFTWARE.
|
|
||||||
</copyright>
|
|
||||||
|
|
||||||
<description summary="Protocol for composing text">
|
|
||||||
This protocol allows compositors to act as input methods and to send text
|
|
||||||
to applications. A text input object is used to manage state of what are
|
|
||||||
typically text entry fields in the application.
|
|
||||||
|
|
||||||
This document adheres to the RFC 2119 when using words like "must",
|
|
||||||
"should", "may", etc.
|
|
||||||
|
|
||||||
Warning! The protocol described in this file is experimental and
|
|
||||||
backward incompatible changes may be made. Backward compatible changes
|
|
||||||
may be added together with the corresponding interface version bump.
|
|
||||||
Backward incompatible changes are done by bumping the version number in
|
|
||||||
the protocol and interface names and resetting the interface version.
|
|
||||||
Once the protocol is to be declared stable, the 'z' prefix and the
|
|
||||||
version number in the protocol and interface names are removed and the
|
|
||||||
interface version number is reset.
|
|
||||||
</description>
|
|
||||||
|
|
||||||
<interface name="zwp_text_input_v3" version="1">
|
|
||||||
<description summary="text input">
|
|
||||||
The zwp_text_input_v3 interface represents text input and input methods
|
|
||||||
associated with a seat. It provides enter/leave events to follow the
|
|
||||||
text input focus for a seat.
|
|
||||||
|
|
||||||
Requests are used to enable/disable the text-input object and set
|
|
||||||
state information like surrounding and selected text or the content type.
|
|
||||||
The information about the entered text is sent to the text-input object
|
|
||||||
via the preedit_string and commit_string events.
|
|
||||||
|
|
||||||
Text is valid UTF-8 encoded, indices and lengths are in bytes. Indices
|
|
||||||
must not point to middle bytes inside a code point: they must either
|
|
||||||
point to the first byte of a code point or to the end of the buffer.
|
|
||||||
Lengths must be measured between two valid indices.
|
|
||||||
|
|
||||||
Focus moving throughout surfaces will result in the emission of
|
|
||||||
zwp_text_input_v3.enter and zwp_text_input_v3.leave events. The focused
|
|
||||||
surface must commit zwp_text_input_v3.enable and
|
|
||||||
zwp_text_input_v3.disable requests as the keyboard focus moves across
|
|
||||||
editable and non-editable elements of the UI. Those two requests are not
|
|
||||||
expected to be paired with each other, the compositor must be able to
|
|
||||||
handle consecutive series of the same request.
|
|
||||||
|
|
||||||
State is sent by the state requests (set_surrounding_text,
|
|
||||||
set_content_type and set_cursor_rectangle) and a commit request. After an
|
|
||||||
enter event or disable request all state information is invalidated and
|
|
||||||
needs to be resent by the client.
|
|
||||||
</description>
|
|
||||||
|
|
||||||
<request name="destroy" type="destructor">
|
|
||||||
<description summary="Destroy the wp_text_input">
|
|
||||||
Destroy the wp_text_input object. Also disables all surfaces enabled
|
|
||||||
through this wp_text_input object.
|
|
||||||
</description>
|
|
||||||
</request>
|
|
||||||
|
|
||||||
<request name="enable">
|
|
||||||
<description summary="Request text input to be enabled">
|
|
||||||
Requests text input on the surface previously obtained from the enter
|
|
||||||
event.
|
|
||||||
|
|
||||||
This request must be issued every time the active text input changes
|
|
||||||
to a new one, including within the current surface. Use
|
|
||||||
zwp_text_input_v3.disable when there is no longer any input focus on
|
|
||||||
the current surface.
|
|
||||||
|
|
||||||
This request resets all state associated with previous enable, disable,
|
|
||||||
set_surrounding_text, set_text_change_cause, set_content_type, and
|
|
||||||
set_cursor_rectangle requests, as well as the state associated with
|
|
||||||
preedit_string, commit_string, and delete_surrounding_text events.
|
|
||||||
|
|
||||||
The set_surrounding_text, set_content_type and set_cursor_rectangle
|
|
||||||
requests must follow if the text input supports the necessary
|
|
||||||
functionality.
|
|
||||||
|
|
||||||
State set with this request is double-buffered. It will get applied on
|
|
||||||
the next zwp_text_input_v3.commit request, and stay valid until the
|
|
||||||
next committed enable or disable request.
|
|
||||||
|
|
||||||
The changes must be applied by the compositor after issuing a
|
|
||||||
zwp_text_input_v3.commit request.
|
|
||||||
</description>
|
|
||||||
</request>
|
|
||||||
|
|
||||||
<request name="disable">
|
|
||||||
<description summary="Disable text input on a surface">
|
|
||||||
Explicitly disable text input on the current surface (typically when
|
|
||||||
there is no focus on any text entry inside the surface).
|
|
||||||
|
|
||||||
State set with this request is double-buffered. It will get applied on
|
|
||||||
the next zwp_text_input_v3.commit request.
|
|
||||||
</description>
|
|
||||||
</request>
|
|
||||||
|
|
||||||
<request name="set_surrounding_text">
|
|
||||||
<description summary="sets the surrounding text">
|
|
||||||
Sets the surrounding plain text around the input, excluding the preedit
|
|
||||||
text.
|
|
||||||
|
|
||||||
The client should notify the compositor of any changes in any of the
|
|
||||||
values carried with this request, including changes caused by handling
|
|
||||||
incoming text-input events as well as changes caused by other
|
|
||||||
mechanisms like keyboard typing.
|
|
||||||
|
|
||||||
If the client is unaware of the text around the cursor, it should not
|
|
||||||
issue this request, to signify lack of support to the compositor.
|
|
||||||
|
|
||||||
Text is UTF-8 encoded, and should include the cursor position, the
|
|
||||||
complete selection and additional characters before and after them.
|
|
||||||
There is a maximum length of wayland messages, so text can not be
|
|
||||||
longer than 4000 bytes.
|
|
||||||
|
|
||||||
Cursor is the byte offset of the cursor within text buffer.
|
|
||||||
|
|
||||||
Anchor is the byte offset of the selection anchor within text buffer.
|
|
||||||
If there is no selected text, anchor is the same as cursor.
|
|
||||||
|
|
||||||
If any preedit text is present, it is replaced with a cursor for the
|
|
||||||
purpose of this event.
|
|
||||||
|
|
||||||
Values set with this request are double-buffered. They will get applied
|
|
||||||
on the next zwp_text_input_v3.commit request, and stay valid until the
|
|
||||||
next committed enable or disable request.
|
|
||||||
|
|
||||||
The initial state for affected fields is empty, meaning that the text
|
|
||||||
input does not support sending surrounding text. If the empty values
|
|
||||||
get applied, subsequent attempts to change them may have no effect.
|
|
||||||
</description>
|
|
||||||
<arg name="text" type="string"/>
|
|
||||||
<arg name="cursor" type="int"/>
|
|
||||||
<arg name="anchor" type="int"/>
|
|
||||||
</request>
|
|
||||||
|
|
||||||
<enum name="change_cause">
|
|
||||||
<description summary="text change reason">
|
|
||||||
Reason for the change of surrounding text or cursor posision.
|
|
||||||
</description>
|
|
||||||
<entry name="input_method" value="0" summary="input method caused the change"/>
|
|
||||||
<entry name="other" value="1" summary="something else than the input method caused the change"/>
|
|
||||||
</enum>
|
|
||||||
|
|
||||||
<request name="set_text_change_cause">
|
|
||||||
<description summary="indicates the cause of surrounding text change">
|
|
||||||
Tells the compositor why the text surrounding the cursor changed.
|
|
||||||
|
|
||||||
Whenever the client detects an external change in text, cursor, or
|
|
||||||
anchor posision, it must issue this request to the compositor. This
|
|
||||||
request is intended to give the input method a chance to update the
|
|
||||||
preedit text in an appropriate way, e.g. by removing it when the user
|
|
||||||
starts typing with a keyboard.
|
|
||||||
|
|
||||||
cause describes the source of the change.
|
|
||||||
|
|
||||||
The value set with this request is double-buffered. It must be applied
|
|
||||||
and reset to initial at the next zwp_text_input_v3.commit request.
|
|
||||||
|
|
||||||
The initial value of cause is input_method.
|
|
||||||
</description>
|
|
||||||
<arg name="cause" type="uint" enum="change_cause"/>
|
|
||||||
</request>
|
|
||||||
|
|
||||||
<enum name="content_hint" bitfield="true">
|
|
||||||
<description summary="content hint">
|
|
||||||
Content hint is a bitmask to allow to modify the behavior of the text
|
|
||||||
input.
|
|
||||||
</description>
|
|
||||||
<entry name="none" value="0x0" summary="no special behavior"/>
|
|
||||||
<entry name="completion" value="0x1" summary="suggest word completions"/>
|
|
||||||
<entry name="spellcheck" value="0x2" summary="suggest word corrections"/>
|
|
||||||
<entry name="auto_capitalization" value="0x4" summary="switch to uppercase letters at the start of a sentence"/>
|
|
||||||
<entry name="lowercase" value="0x8" summary="prefer lowercase letters"/>
|
|
||||||
<entry name="uppercase" value="0x10" summary="prefer uppercase letters"/>
|
|
||||||
<entry name="titlecase" value="0x20" summary="prefer casing for titles and headings (can be language dependent)"/>
|
|
||||||
<entry name="hidden_text" value="0x40" summary="characters should be hidden"/>
|
|
||||||
<entry name="sensitive_data" value="0x80" summary="typed text should not be stored"/>
|
|
||||||
<entry name="latin" value="0x100" summary="just Latin characters should be entered"/>
|
|
||||||
<entry name="multiline" value="0x200" summary="the text input is multiline"/>
|
|
||||||
</enum>
|
|
||||||
|
|
||||||
<enum name="content_purpose">
|
|
||||||
<description summary="content purpose">
|
|
||||||
The content purpose allows to specify the primary purpose of a text
|
|
||||||
input.
|
|
||||||
|
|
||||||
This allows an input method to show special purpose input panels with
|
|
||||||
extra characters or to disallow some characters.
|
|
||||||
</description>
|
|
||||||
<entry name="normal" value="0" summary="default input, allowing all characters"/>
|
|
||||||
<entry name="alpha" value="1" summary="allow only alphabetic characters"/>
|
|
||||||
<entry name="digits" value="2" summary="allow only digits"/>
|
|
||||||
<entry name="number" value="3" summary="input a number (including decimal separator and sign)"/>
|
|
||||||
<entry name="phone" value="4" summary="input a phone number"/>
|
|
||||||
<entry name="url" value="5" summary="input an URL"/>
|
|
||||||
<entry name="email" value="6" summary="input an email address"/>
|
|
||||||
<entry name="name" value="7" summary="input a name of a person"/>
|
|
||||||
<entry name="password" value="8" summary="input a password (combine with sensitive_data hint)"/>
|
|
||||||
<entry name="pin" value="9" summary="input is a numeric password (combine with sensitive_data hint)"/>
|
|
||||||
<entry name="date" value="10" summary="input a date"/>
|
|
||||||
<entry name="time" value="11" summary="input a time"/>
|
|
||||||
<entry name="datetime" value="12" summary="input a date and time"/>
|
|
||||||
<entry name="terminal" value="13" summary="input for a terminal"/>
|
|
||||||
</enum>
|
|
||||||
|
|
||||||
<request name="set_content_type">
|
|
||||||
<description summary="set content purpose and hint">
|
|
||||||
Sets the content purpose and content hint. While the purpose is the
|
|
||||||
basic purpose of an input field, the hint flags allow to modify some of
|
|
||||||
the behavior.
|
|
||||||
|
|
||||||
Values set with this request are double-buffered. They will get applied
|
|
||||||
on the next zwp_text_input_v3.commit request.
|
|
||||||
Subsequent attempts to update them may have no effect. The values
|
|
||||||
remain valid until the next committed enable or disable request.
|
|
||||||
|
|
||||||
The initial value for hint is none, and the initial value for purpose
|
|
||||||
is normal.
|
|
||||||
</description>
|
|
||||||
<arg name="hint" type="uint" enum="content_hint"/>
|
|
||||||
<arg name="purpose" type="uint" enum="content_purpose"/>
|
|
||||||
</request>
|
|
||||||
|
|
||||||
<request name="set_cursor_rectangle">
|
|
||||||
<description summary="set cursor position">
|
|
||||||
Marks an area around the cursor as a x, y, width, height rectangle in
|
|
||||||
surface local coordinates.
|
|
||||||
|
|
||||||
Allows the compositor to put a window with word suggestions near the
|
|
||||||
cursor, without obstructing the text being input.
|
|
||||||
|
|
||||||
If the client is unaware of the position of edited text, it should not
|
|
||||||
issue this request, to signify lack of support to the compositor.
|
|
||||||
|
|
||||||
Values set with this request are double-buffered. They will get applied
|
|
||||||
on the next zwp_text_input_v3.commit request, and stay valid until the
|
|
||||||
next committed enable or disable request.
|
|
||||||
|
|
||||||
The initial values describing a cursor rectangle are empty. That means
|
|
||||||
the text input does not support describing the cursor area. If the
|
|
||||||
empty values get applied, subsequent attempts to change them may have
|
|
||||||
no effect.
|
|
||||||
</description>
|
|
||||||
<arg name="x" type="int"/>
|
|
||||||
<arg name="y" type="int"/>
|
|
||||||
<arg name="width" type="int"/>
|
|
||||||
<arg name="height" type="int"/>
|
|
||||||
</request>
|
|
||||||
|
|
||||||
<request name="commit">
|
|
||||||
<description summary="commit state">
|
|
||||||
Atomically applies state changes recently sent to the compositor.
|
|
||||||
|
|
||||||
The commit request establishes and updates the state of the client, and
|
|
||||||
must be issued after any changes to apply them.
|
|
||||||
|
|
||||||
Text input state (enabled status, content purpose, content hint,
|
|
||||||
surrounding text and change cause, cursor rectangle) is conceptually
|
|
||||||
double-buffered within the context of a text input, i.e. between a
|
|
||||||
committed enable request and the following committed enable or disable
|
|
||||||
request.
|
|
||||||
|
|
||||||
Protocol requests modify the pending state, as opposed to the current
|
|
||||||
state in use by the input method. A commit request atomically applies
|
|
||||||
all pending state, replacing the current state. After commit, the new
|
|
||||||
pending state is as documented for each related request.
|
|
||||||
|
|
||||||
Requests are applied in the order of arrival.
|
|
||||||
|
|
||||||
Neither current nor pending state are modified unless noted otherwise.
|
|
||||||
|
|
||||||
The compositor must count the number of commit requests coming from
|
|
||||||
each zwp_text_input_v3 object and use the count as the serial in done
|
|
||||||
events.
|
|
||||||
</description>
|
|
||||||
</request>
|
|
||||||
|
|
||||||
<event name="enter">
|
|
||||||
<description summary="enter event">
|
|
||||||
Notification that this seat's text-input focus is on a certain surface.
|
|
||||||
|
|
||||||
When the seat has the keyboard capability the text-input focus follows
|
|
||||||
the keyboard focus. This event sets the current surface for the
|
|
||||||
text-input object.
|
|
||||||
</description>
|
|
||||||
<arg name="surface" type="object" interface="wl_surface"/>
|
|
||||||
</event>
|
|
||||||
|
|
||||||
<event name="leave">
|
|
||||||
<description summary="leave event">
|
|
||||||
Notification that this seat's text-input focus is no longer on a
|
|
||||||
certain surface. The client should reset any preedit string previously
|
|
||||||
set.
|
|
||||||
|
|
||||||
The leave notification clears the current surface. It is sent before
|
|
||||||
the enter notification for the new focus.
|
|
||||||
|
|
||||||
When the seat has the keyboard capability the text-input focus follows
|
|
||||||
the keyboard focus.
|
|
||||||
</description>
|
|
||||||
<arg name="surface" type="object" interface="wl_surface"/>
|
|
||||||
</event>
|
|
||||||
|
|
||||||
<event name="preedit_string">
|
|
||||||
<description summary="pre-edit">
|
|
||||||
Notify when a new composing text (pre-edit) should be set at the
|
|
||||||
current cursor position. Any previously set composing text must be
|
|
||||||
removed. Any previously existing selected text must be removed.
|
|
||||||
|
|
||||||
The argument text contains the pre-edit string buffer.
|
|
||||||
|
|
||||||
The parameters cursor_begin and cursor_end are counted in bytes
|
|
||||||
relative to the beginning of the submitted text buffer. Cursor should
|
|
||||||
be hidden when both are equal to -1.
|
|
||||||
|
|
||||||
They could be represented by the client as a line if both values are
|
|
||||||
the same, or as a text highlight otherwise.
|
|
||||||
|
|
||||||
Values set with this event are double-buffered. They must be applied
|
|
||||||
and reset to initial on the next zwp_text_input_v3.done event.
|
|
||||||
|
|
||||||
The initial value of text is an empty string, and cursor_begin,
|
|
||||||
cursor_end and cursor_hidden are all 0.
|
|
||||||
</description>
|
|
||||||
<arg name="text" type="string" allow-null="true"/>
|
|
||||||
<arg name="cursor_begin" type="int"/>
|
|
||||||
<arg name="cursor_end" type="int"/>
|
|
||||||
</event>
|
|
||||||
|
|
||||||
<event name="commit_string">
|
|
||||||
<description summary="text commit">
|
|
||||||
Notify when text should be inserted into the editor widget. The text to
|
|
||||||
commit could be either just a single character after a key press or the
|
|
||||||
result of some composing (pre-edit).
|
|
||||||
|
|
||||||
Values set with this event are double-buffered. They must be applied
|
|
||||||
and reset to initial on the next zwp_text_input_v3.done event.
|
|
||||||
|
|
||||||
The initial value of text is an empty string.
|
|
||||||
</description>
|
|
||||||
<arg name="text" type="string" allow-null="true"/>
|
|
||||||
</event>
|
|
||||||
|
|
||||||
<event name="delete_surrounding_text">
|
|
||||||
<description summary="delete surrounding text">
|
|
||||||
Notify when the text around the current cursor position should be
|
|
||||||
deleted.
|
|
||||||
|
|
||||||
Before_length and after_length are the number of bytes before and after
|
|
||||||
the current cursor index (excluding the selection) to delete.
|
|
||||||
|
|
||||||
If a preedit text is present, in effect before_length is counted from
|
|
||||||
the beginning of it, and after_length from its end (see done event
|
|
||||||
sequence).
|
|
||||||
|
|
||||||
Values set with this event are double-buffered. They must be applied
|
|
||||||
and reset to initial on the next zwp_text_input_v3.done event.
|
|
||||||
|
|
||||||
The initial values of both before_length and after_length are 0.
|
|
||||||
</description>
|
|
||||||
<arg name="before_length" type="uint" summary="length of text before current cursor position"/>
|
|
||||||
<arg name="after_length" type="uint" summary="length of text after current cursor position"/>
|
|
||||||
</event>
|
|
||||||
|
|
||||||
<event name="done">
|
|
||||||
<description summary="apply changes">
|
|
||||||
Instruct the application to apply changes to state requested by the
|
|
||||||
preedit_string, commit_string and delete_surrounding_text events. The
|
|
||||||
state relating to these events is double-buffered, and each one
|
|
||||||
modifies the pending state. This event replaces the current state with
|
|
||||||
the pending state.
|
|
||||||
|
|
||||||
The application must proceed by evaluating the changes in the following
|
|
||||||
order:
|
|
||||||
|
|
||||||
1. Replace existing preedit string with the cursor.
|
|
||||||
2. Delete requested surrounding text.
|
|
||||||
3. Insert commit string with the cursor at its end.
|
|
||||||
4. Calculate surrounding text to send.
|
|
||||||
5. Insert new preedit text in cursor position.
|
|
||||||
6. Place cursor inside preedit text.
|
|
||||||
|
|
||||||
The serial number reflects the last state of the zwp_text_input_v3
|
|
||||||
object known to the compositor. The value of the serial argument must
|
|
||||||
be equal to the number of commit requests already issued on that object.
|
|
||||||
When the client receives a done event with a serial different than the
|
|
||||||
number of past commit requests, it must proceed as normal, except it
|
|
||||||
should not change the current state of the zwp_text_input_v3 object.
|
|
||||||
</description>
|
|
||||||
<arg name="serial" type="uint"/>
|
|
||||||
</event>
|
|
||||||
</interface>
|
|
||||||
|
|
||||||
<interface name="zwp_text_input_manager_v3" version="1">
|
|
||||||
<description summary="text input manager">
|
|
||||||
A factory for text-input objects. This object is a global singleton.
|
|
||||||
</description>
|
|
||||||
|
|
||||||
<request name="destroy" type="destructor">
|
|
||||||
<description summary="Destroy the wp_text_input_manager">
|
|
||||||
Destroy the wp_text_input_manager object.
|
|
||||||
</description>
|
|
||||||
</request>
|
|
||||||
|
|
||||||
<request name="get_text_input">
|
|
||||||
<description summary="create a new text input object">
|
|
||||||
Creates a new text-input object for a given seat.
|
|
||||||
</description>
|
|
||||||
<arg name="id" type="new_id" interface="zwp_text_input_v3"/>
|
|
||||||
<arg name="seat" type="object" interface="wl_seat"/>
|
|
||||||
</request>
|
|
||||||
</interface>
|
|
||||||
</protocol>
|
|
||||||
1350
src/bitflags.rs
1350
src/bitflags.rs
File diff suppressed because it is too large
Load Diff
@ -2,3 +2,5 @@
|
|||||||
* Autogenerated by the Meson build system.
|
* Autogenerated by the Meson build system.
|
||||||
* Do not edit, your changes will be lost.
|
* Do not edit, your changes will be lost.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#mesondefine HAVE_GSOUND
|
||||||
|
|||||||
@ -5,6 +5,11 @@
|
|||||||
#include "eekboard/eekboard-context-service.h"
|
#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) {}
|
||||||
|
void imservice_handle_unavailable(void *data, struct zwp_input_method_v2 *input_method) {}
|
||||||
|
|
||||||
|
|
||||||
static const struct zwp_input_method_v2_listener input_method_listener = {
|
static const struct zwp_input_method_v2_listener input_method_listener = {
|
||||||
.activate = imservice_handle_input_method_activate,
|
.activate = imservice_handle_input_method_activate,
|
||||||
.deactivate = imservice_handle_input_method_deactivate,
|
.deactivate = imservice_handle_input_method_deactivate,
|
||||||
@ -20,24 +25,19 @@ struct imservice* get_imservice(EekboardContextService *context,
|
|||||||
struct wl_seat *seat) {
|
struct wl_seat *seat) {
|
||||||
struct zwp_input_method_v2 *im = zwp_input_method_manager_v2_get_input_method(manager, seat);
|
struct zwp_input_method_v2 *im = zwp_input_method_manager_v2_get_input_method(manager, seat);
|
||||||
struct imservice *imservice = imservice_new(im, context);
|
struct imservice *imservice = imservice_new(im, context);
|
||||||
|
zwp_input_method_v2_add_listener(im,
|
||||||
/* Add a listener, passing the imservice instance to make it available to
|
&input_method_listener, imservice);
|
||||||
callbacks. */
|
|
||||||
zwp_input_method_v2_add_listener(im, &input_method_listener, imservice);
|
|
||||||
|
|
||||||
return imservice;
|
return imservice;
|
||||||
}
|
}
|
||||||
|
|
||||||
void imservice_make_visible(EekboardContextService *context) {
|
void imservice_make_visible(EekboardContextService *context,
|
||||||
|
struct zwp_input_method_v2 *im) {
|
||||||
|
(void)im;
|
||||||
eekboard_context_service_show_keyboard (context);
|
eekboard_context_service_show_keyboard (context);
|
||||||
}
|
}
|
||||||
|
|
||||||
void imservice_try_hide(EekboardContextService *context) {
|
void imservice_try_hide(EekboardContextService *context,
|
||||||
|
struct zwp_input_method_v2 *im) {
|
||||||
|
(void)im;
|
||||||
eekboard_context_service_hide_keyboard (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);
|
|
||||||
}
|
|
||||||
|
|||||||
@ -18,8 +18,5 @@ 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,
|
void imservice_handle_surrounding_text(void *data, struct zwp_input_method_v2 *input_method,
|
||||||
const char *text, uint32_t cursor, uint32_t anchor);
|
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_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
|
#endif
|
||||||
|
|||||||
226
src/imservice.rs
226
src/imservice.rs
@ -3,11 +3,6 @@ use std::ffi::CString;
|
|||||||
use std::num::Wrapping;
|
use std::num::Wrapping;
|
||||||
use std::string::String;
|
use std::string::String;
|
||||||
|
|
||||||
use super::bitflags;
|
|
||||||
|
|
||||||
// Traits
|
|
||||||
use std::convert::TryFrom;
|
|
||||||
|
|
||||||
|
|
||||||
/// Gathers stuff defined in C or called by C
|
/// Gathers stuff defined in C or called by C
|
||||||
pub mod c {
|
pub mod c {
|
||||||
@ -34,10 +29,8 @@ pub mod c {
|
|||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
extern "C" {
|
extern "C" {
|
||||||
fn imservice_destroy_im(im: *mut c::InputMethod);
|
fn imservice_make_visible(imservice: *const UIManager);
|
||||||
fn eekboard_context_service_set_hint_purpose(imservice: *const UIManager, hint: u32, purpose: u32);
|
fn imservice_try_hide(imservice: *const UIManager);
|
||||||
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
|
// The following defined in Rust. TODO: wrap naked pointers to Rust data inside RefCells to prevent multiple writers
|
||||||
@ -61,9 +54,9 @@ pub mod c {
|
|||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe extern "C"
|
pub unsafe extern "C"
|
||||||
fn imservice_handle_input_method_activate(imservice: *mut IMService,
|
fn imservice_handle_input_method_activate(imservice: *mut IMService,
|
||||||
im: *const InputMethod)
|
_im: *const InputMethod)
|
||||||
{
|
{
|
||||||
let imservice = check_imservice(imservice, im).unwrap();
|
let imservice = &mut *imservice;
|
||||||
imservice.preedit_string = String::new();
|
imservice.preedit_string = String::new();
|
||||||
imservice.pending = IMProtocolState {
|
imservice.pending = IMProtocolState {
|
||||||
active: true,
|
active: true,
|
||||||
@ -74,9 +67,9 @@ pub mod c {
|
|||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe extern "C"
|
pub unsafe extern "C"
|
||||||
fn imservice_handle_input_method_deactivate(imservice: *mut IMService,
|
fn imservice_handle_input_method_deactivate(imservice: *mut IMService,
|
||||||
im: *const InputMethod)
|
_im: *const InputMethod)
|
||||||
{
|
{
|
||||||
let imservice = check_imservice(imservice, im).unwrap();
|
let imservice = &mut *imservice;
|
||||||
imservice.pending = IMProtocolState {
|
imservice.pending = IMProtocolState {
|
||||||
active: false,
|
active: false,
|
||||||
..imservice.pending.clone()
|
..imservice.pending.clone()
|
||||||
@ -86,65 +79,23 @@ pub mod c {
|
|||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe extern "C"
|
pub unsafe extern "C"
|
||||||
fn imservice_handle_surrounding_text(imservice: *mut IMService,
|
fn imservice_handle_surrounding_text(imservice: *mut IMService,
|
||||||
im: *const InputMethod,
|
_im: *const InputMethod,
|
||||||
text: *const c_char, cursor: u32, _anchor: u32)
|
text: *const c_char, cursor: u32, _anchor: u32)
|
||||||
{
|
{
|
||||||
let imservice = check_imservice(imservice, im).unwrap();
|
let imservice = &mut *imservice;
|
||||||
imservice.pending = IMProtocolState {
|
imservice.pending = IMProtocolState {
|
||||||
surrounding_text: into_cstring(text).expect("Received invalid string"),
|
surrounding_text: into_cstring(text).expect("Received invalid string"),
|
||||||
surrounding_cursor: cursor,
|
surrounding_cursor: cursor,
|
||||||
..imservice.pending.clone()
|
..imservice.pending
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
#[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]
|
#[no_mangle]
|
||||||
pub unsafe extern "C"
|
pub unsafe extern "C"
|
||||||
fn imservice_handle_commit_state(imservice: *mut IMService,
|
fn imservice_handle_commit_state(imservice: *mut IMService,
|
||||||
im: *const InputMethod)
|
_im: *const InputMethod)
|
||||||
{
|
{
|
||||||
let imservice = check_imservice(imservice, im).unwrap();
|
let imservice = &mut *imservice;
|
||||||
let active_changed = imservice.current.active ^ imservice.pending.active;
|
let active_changed = imservice.current.active ^ imservice.pending.active;
|
||||||
|
|
||||||
imservice.serial += Wrapping(1u32);
|
imservice.serial += Wrapping(1u32);
|
||||||
@ -155,174 +106,27 @@ pub mod c {
|
|||||||
};
|
};
|
||||||
if active_changed {
|
if active_changed {
|
||||||
if imservice.current.active {
|
if imservice.current.active {
|
||||||
eekboard_context_service_show_keyboard(imservice.ui_manager);
|
imservice_make_visible(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 {
|
} else {
|
||||||
eekboard_context_service_hide_keyboard(imservice.ui_manager);
|
imservice_try_hide(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
|
// 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
|
/// Describes the desired state of the input method as requested by the server
|
||||||
#[derive(Clone)]
|
#[derive(Default, Clone)]
|
||||||
struct IMProtocolState {
|
struct IMProtocolState {
|
||||||
surrounding_text: CString,
|
surrounding_text: CString,
|
||||||
surrounding_cursor: u32,
|
surrounding_cursor: u32,
|
||||||
content_purpose: ContentPurpose,
|
|
||||||
content_hint: ContentHint,
|
|
||||||
text_change_cause: ChangeCause,
|
|
||||||
active: bool,
|
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 {
|
pub struct IMService {
|
||||||
/// Owned reference (still created and destroyed in C)
|
/// Owned reference (still created and destroyed in C)
|
||||||
pub im: *const c::InputMethod,
|
im: *const c::InputMethod,
|
||||||
/// Unowned reference. Be careful, it's shared with C at large
|
/// Unowned reference. Be careful, it's shared with C at large
|
||||||
ui_manager: *const c::UIManager,
|
ui_manager: *const c::UIManager,
|
||||||
|
|
||||||
|
|||||||
@ -1,4 +0,0 @@
|
|||||||
#[macro_use]
|
|
||||||
mod bitflags;
|
|
||||||
|
|
||||||
mod imservice;
|
|
||||||
@ -4,21 +4,19 @@ dbus_src = gnome.gdbus_codegen(
|
|||||||
join_paths(meson.source_root() / 'data' / 'dbus', 'sm.puri.OSK0.xml')
|
join_paths(meson.source_root() / 'data' / 'dbus', 'sm.puri.OSK0.xml')
|
||||||
)
|
)
|
||||||
|
|
||||||
config_h = configure_file(
|
config_h = configure_file(input: 'config.h.in', output: 'config.h',configuration: conf_data)
|
||||||
input: 'config.h.in',
|
|
||||||
output: 'config.h',
|
|
||||||
configuration: conf_data
|
|
||||||
)
|
|
||||||
|
|
||||||
sources = [
|
sources = [
|
||||||
config_h,
|
config_h,
|
||||||
'imservice.c',
|
'imservice.c',
|
||||||
'server-context-service.c',
|
'server-context-service.c',
|
||||||
|
'server-main.c',
|
||||||
'wayland.c',
|
'wayland.c',
|
||||||
'../eek/eek.c',
|
'../eek/eek.c',
|
||||||
'../eek/eek-container.c',
|
'../eek/eek-container.c',
|
||||||
'../eek/eek-element.c',
|
'../eek/eek-element.c',
|
||||||
'../eek/eek-gtk-keyboard.c',
|
'../eek/eek-gtk-keyboard.c',
|
||||||
|
'../eek/eek-gtk-renderer.c',
|
||||||
'../eek/eek-key.c',
|
'../eek/eek-key.c',
|
||||||
'../eek/eek-keyboard.c',
|
'../eek/eek-keyboard.c',
|
||||||
'../eek/eek-keyboard-drawing.c',
|
'../eek/eek-keyboard-drawing.c',
|
||||||
@ -30,6 +28,9 @@ sources = [
|
|||||||
'../eek/eek-symbol.c',
|
'../eek/eek-symbol.c',
|
||||||
'../eek/eek-symbol-matrix.c',
|
'../eek/eek-symbol-matrix.c',
|
||||||
'../eek/eek-text.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-types.c',
|
||||||
'../eek/eek-xml-layout.c',
|
'../eek/eek-xml-layout.c',
|
||||||
'../eek/layersurface.c',
|
'../eek/layersurface.c',
|
||||||
@ -37,6 +38,7 @@ sources = [
|
|||||||
enums,
|
enums,
|
||||||
keysym_entries,
|
keysym_entries,
|
||||||
marshalers,
|
marshalers,
|
||||||
|
'../eekboard/keymap.c',
|
||||||
'../eekboard/key-emitter.c',
|
'../eekboard/key-emitter.c',
|
||||||
'../eekboard/eekboard-context-service.c',
|
'../eekboard/eekboard-context-service.c',
|
||||||
'../eekboard/eekboard-context.c',
|
'../eekboard/eekboard-context.c',
|
||||||
@ -61,43 +63,21 @@ deps = [
|
|||||||
cc.find_library('dl'),
|
cc.find_library('dl'),
|
||||||
cc.find_library('pthread'),
|
cc.find_library('pthread'),
|
||||||
# dependency('libxklavier'), # FIXME remove
|
# dependency('libxklavier'), # FIXME remove
|
||||||
|
gsound_dep,
|
||||||
]
|
]
|
||||||
|
|
||||||
# Replacement for eekboard-server
|
# Replacement for eekboard-server
|
||||||
rslib = static_library(
|
rslib = static_library(
|
||||||
'rslib',
|
'rslib',
|
||||||
sources: ['lib.rs'],
|
sources: ['imservice.rs'],
|
||||||
rust_crate_type: 'staticlib'
|
rust_crate_type: 'staticlib'
|
||||||
)
|
)
|
||||||
|
|
||||||
rstests = executable(
|
squeekboard = executable('squeekboard',
|
||||||
'rstests',
|
|
||||||
sources: ['lib.rs'],
|
|
||||||
rust_args: ['--test'],
|
|
||||||
install: false
|
|
||||||
)
|
|
||||||
|
|
||||||
test('rstests', rstests)
|
|
||||||
|
|
||||||
libsqueekboard = static_library('libsqueekboard',
|
|
||||||
sources,
|
sources,
|
||||||
link_with: rslib,
|
link_with: rslib,
|
||||||
include_directories: [include_directories('..'), include_directories('../eek')],
|
include_directories: [include_directories('..'), include_directories('../eek')],
|
||||||
dependencies: deps,
|
dependencies: deps,
|
||||||
c_args: [
|
|
||||||
'-DTHEMESDIR="' + pkgdatadir + '/themes"',
|
|
||||||
'-DKEYBOARDSDIR="' + pkgdatadir + '/keyboards"',
|
|
||||||
'-DEEKBOARD_COMPILATION=1',
|
|
||||||
'-DEEK_COMPILATION=1'],
|
|
||||||
)
|
|
||||||
|
|
||||||
squeekboard = executable('squeekboard',
|
|
||||||
'server-main.c',
|
|
||||||
wl_proto_sources,
|
|
||||||
squeekboard_resources,
|
|
||||||
link_with: libsqueekboard,
|
|
||||||
include_directories: [include_directories('..'), include_directories('../eek')],
|
|
||||||
dependencies: deps,
|
|
||||||
install: true,
|
install: true,
|
||||||
c_args: [
|
c_args: [
|
||||||
'-DTHEMESDIR="' + pkgdatadir + '/themes"',
|
'-DTHEMESDIR="' + pkgdatadir + '/themes"',
|
||||||
@ -105,3 +85,4 @@ squeekboard = executable('squeekboard',
|
|||||||
'-DEEKBOARD_COMPILATION=1',
|
'-DEEKBOARD_COMPILATION=1',
|
||||||
'-DEEK_COMPILATION=1'],
|
'-DEEK_COMPILATION=1'],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@ -15,11 +15,15 @@
|
|||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
#endif /* HAVE_CONFIG_H */
|
||||||
|
|
||||||
#include <gtk/gtk.h>
|
#include <gtk/gtk.h>
|
||||||
#include <glib/gi18n.h>
|
#include <glib/gi18n.h>
|
||||||
|
|
||||||
|
#include <gdk/gdkx.h>
|
||||||
|
|
||||||
#include "eek/eek-gtk.h"
|
#include "eek/eek-gtk.h"
|
||||||
#include "eek/layersurface.h"
|
#include "eek/layersurface.h"
|
||||||
#include "wayland.h"
|
#include "wayland.h"
|
||||||
@ -38,9 +42,13 @@ typedef struct _ServerContextServiceClass ServerContextServiceClass;
|
|||||||
struct _ServerContextService {
|
struct _ServerContextService {
|
||||||
EekboardContextService parent;
|
EekboardContextService parent;
|
||||||
|
|
||||||
|
gboolean was_visible;
|
||||||
|
|
||||||
GtkWidget *window;
|
GtkWidget *window;
|
||||||
GtkWidget *widget;
|
GtkWidget *widget;
|
||||||
|
|
||||||
|
gulong notify_visible_handler;
|
||||||
|
|
||||||
gdouble size_constraint_landscape[2];
|
gdouble size_constraint_landscape[2];
|
||||||
gdouble size_constraint_portrait[2];
|
gdouble size_constraint_portrait[2];
|
||||||
};
|
};
|
||||||
@ -51,7 +59,10 @@ struct _ServerContextServiceClass {
|
|||||||
|
|
||||||
G_DEFINE_TYPE (ServerContextService, server_context_service, EEKBOARD_TYPE_CONTEXT_SERVICE);
|
G_DEFINE_TYPE (ServerContextService, server_context_service, EEKBOARD_TYPE_CONTEXT_SERVICE);
|
||||||
|
|
||||||
|
static void update_widget (ServerContextService *context);
|
||||||
static void set_geometry (ServerContextService *context);
|
static void set_geometry (ServerContextService *context);
|
||||||
|
static void set_dock (GtkWidget *widget,
|
||||||
|
GtkAllocation *allocation);
|
||||||
|
|
||||||
static void
|
static void
|
||||||
on_monitors_changed (GdkScreen *screen,
|
on_monitors_changed (GdkScreen *screen,
|
||||||
@ -75,9 +86,6 @@ on_destroy (GtkWidget *widget, gpointer user_data)
|
|||||||
eekboard_context_service_destroy (EEKBOARD_CONTEXT_SERVICE (context));
|
eekboard_context_service_destroy (EEKBOARD_CONTEXT_SERVICE (context));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
make_widget (ServerContextService *context);
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
on_notify_keyboard (GObject *object,
|
on_notify_keyboard (GObject *object,
|
||||||
GParamSpec *spec,
|
GParamSpec *spec,
|
||||||
@ -96,16 +104,22 @@ on_notify_keyboard (GObject *object,
|
|||||||
eekboard_context_service_set_keymap(EEKBOARD_CONTEXT_SERVICE(context),
|
eekboard_context_service_set_keymap(EEKBOARD_CONTEXT_SERVICE(context),
|
||||||
keyboard);
|
keyboard);
|
||||||
|
|
||||||
/* Recreate the keyboard widget to keep in sync with the keymap. */
|
if (context->window) {
|
||||||
if (context->window)
|
if (keyboard == NULL) {
|
||||||
make_widget(context);
|
gtk_widget_hide (context->window);
|
||||||
|
g_clear_pointer (&context->widget, gtk_widget_destroy);
|
||||||
gboolean visible;
|
} else {
|
||||||
g_object_get (context, "visible", &visible, NULL);
|
gboolean was_visible = gtk_widget_get_visible (context->window);
|
||||||
|
/* avoid to send KeyboardVisibilityChanged */
|
||||||
if (visible) {
|
g_signal_handler_block (context->window,
|
||||||
eekboard_context_service_hide_keyboard(EEKBOARD_CONTEXT_SERVICE(context));
|
context->notify_visible_handler);
|
||||||
eekboard_context_service_show_keyboard(EEKBOARD_CONTEXT_SERVICE(context));
|
update_widget (context);
|
||||||
|
if (was_visible) {
|
||||||
|
gtk_widget_show_all (context->window);
|
||||||
|
}
|
||||||
|
g_signal_handler_unblock (context->window,
|
||||||
|
context->notify_visible_handler);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -119,20 +133,81 @@ on_notify_fullscreen (GObject *object,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
on_notify_map (GObject *object,
|
on_notify_visible (GObject *object,
|
||||||
ServerContextService *context)
|
GParamSpec *spec,
|
||||||
|
ServerContextService *context)
|
||||||
{
|
{
|
||||||
g_object_set (context, "visible", TRUE, NULL);
|
gboolean visible;
|
||||||
}
|
|
||||||
|
|
||||||
|
g_object_get (object, "visible", &visible, NULL);
|
||||||
|
g_object_set (context, "visible", visible, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
on_notify_unmap (GObject *object,
|
set_dock (GtkWidget *widget, GtkAllocation *allocation)
|
||||||
ServerContextService *context)
|
|
||||||
{
|
{
|
||||||
g_object_set (context, "visible", FALSE, NULL);
|
#ifdef HAVE_XDOCK
|
||||||
|
GdkWindow *window = gtk_widget_get_window (widget);
|
||||||
|
long vals[12];
|
||||||
|
|
||||||
|
/* set window type to dock */
|
||||||
|
gdk_window_set_type_hint (window, GDK_WINDOW_TYPE_HINT_DOCK);
|
||||||
|
|
||||||
|
vals[0] = 0;
|
||||||
|
vals[1] = 0;
|
||||||
|
vals[2] = 0;
|
||||||
|
vals[3] = allocation->height;
|
||||||
|
vals[4] = 0;
|
||||||
|
vals[5] = 0;
|
||||||
|
vals[6] = 0;
|
||||||
|
vals[7] = 0;
|
||||||
|
vals[8] = 0;
|
||||||
|
vals[9] = 0;
|
||||||
|
vals[10] = allocation->x;
|
||||||
|
vals[11] = allocation->x + allocation->width;
|
||||||
|
|
||||||
|
XChangeProperty (GDK_WINDOW_XDISPLAY (window),
|
||||||
|
GDK_WINDOW_XID (window),
|
||||||
|
XInternAtom (GDK_WINDOW_XDISPLAY (window),
|
||||||
|
"_NET_WM_STRUT_PARTIAL", False),
|
||||||
|
XA_CARDINAL, 32, PropModeReplace,
|
||||||
|
(guchar *)vals, 12);
|
||||||
|
#endif /* HAVE_XDOCK */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
on_realize_set_dock (GtkWidget *widget,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
GtkAllocation allocation;
|
||||||
|
|
||||||
|
gtk_widget_get_allocation (widget, &allocation);
|
||||||
|
set_dock (widget, &allocation);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
on_size_allocate_set_dock (GtkWidget *widget,
|
||||||
|
GdkRectangle *allocation,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
if (gtk_widget_get_realized (widget))
|
||||||
|
set_dock (widget, allocation);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
on_realize_set_non_maximizable (GtkWidget *widget,
|
||||||
|
ServerContextService *context)
|
||||||
|
{
|
||||||
|
|
||||||
|
g_assert (context && context->window == widget);
|
||||||
|
|
||||||
|
/* make the window not maximizable */
|
||||||
|
gdk_window_set_functions (gtk_widget_get_window (widget),
|
||||||
|
GDK_FUNC_RESIZE |
|
||||||
|
GDK_FUNC_MOVE |
|
||||||
|
GDK_FUNC_MINIMIZE |
|
||||||
|
GDK_FUNC_CLOSE);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
set_geometry (ServerContextService *context)
|
set_geometry (ServerContextService *context)
|
||||||
@ -149,6 +224,13 @@ set_geometry (ServerContextService *context)
|
|||||||
gdk_monitor_get_geometry (monitor, &rect);
|
gdk_monitor_get_geometry (monitor, &rect);
|
||||||
eek_element_get_bounds (EEK_ELEMENT(keyboard), &bounds);
|
eek_element_get_bounds (EEK_ELEMENT(keyboard), &bounds);
|
||||||
|
|
||||||
|
g_signal_handlers_disconnect_by_func (context->window,
|
||||||
|
on_realize_set_dock,
|
||||||
|
context);
|
||||||
|
g_signal_handlers_disconnect_by_func (context->window,
|
||||||
|
on_realize_set_non_maximizable,
|
||||||
|
context);
|
||||||
|
|
||||||
if (eekboard_context_service_get_fullscreen (EEKBOARD_CONTEXT_SERVICE(context))) {
|
if (eekboard_context_service_get_fullscreen (EEKBOARD_CONTEXT_SERVICE(context))) {
|
||||||
gint width = rect.width;
|
gint width = rect.width;
|
||||||
gint height = rect.height;
|
gint height = rect.height;
|
||||||
@ -174,6 +256,22 @@ set_geometry (ServerContextService *context)
|
|||||||
|
|
||||||
gtk_window_set_decorated (GTK_WINDOW(context->window), FALSE);
|
gtk_window_set_decorated (GTK_WINDOW(context->window), FALSE);
|
||||||
gtk_window_set_resizable (GTK_WINDOW(context->window), FALSE);
|
gtk_window_set_resizable (GTK_WINDOW(context->window), FALSE);
|
||||||
|
g_signal_connect_after (context->window, "realize",
|
||||||
|
G_CALLBACK(on_realize_set_dock),
|
||||||
|
context);
|
||||||
|
g_signal_connect_after (context->window, "size-allocate",
|
||||||
|
G_CALLBACK(on_size_allocate_set_dock),
|
||||||
|
context);
|
||||||
|
} else {
|
||||||
|
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));
|
||||||
|
g_signal_connect_after (context->window, "realize",
|
||||||
|
G_CALLBACK(on_realize_set_non_maximizable),
|
||||||
|
context);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -195,15 +293,18 @@ make_window (ServerContextService *context)
|
|||||||
"layer", ZWLR_LAYER_SHELL_V1_LAYER_TOP,
|
"layer", ZWLR_LAYER_SHELL_V1_LAYER_TOP,
|
||||||
"kbd-interactivity", FALSE,
|
"kbd-interactivity", FALSE,
|
||||||
"exclusive-zone", KEYBOARD_HEIGHT,
|
"exclusive-zone", KEYBOARD_HEIGHT,
|
||||||
"namespace", "osk",
|
//"namespace", "phosh home",
|
||||||
NULL
|
NULL
|
||||||
);
|
);
|
||||||
|
|
||||||
g_object_connect (context->window,
|
g_signal_connect (context->window, "destroy",
|
||||||
"signal::destroy", G_CALLBACK(on_destroy), context,
|
G_CALLBACK(on_destroy),
|
||||||
"signal::map", G_CALLBACK(on_notify_map), context,
|
context);
|
||||||
"signal::unmap", G_CALLBACK(on_notify_unmap), context,
|
|
||||||
NULL);
|
context->notify_visible_handler =
|
||||||
|
g_signal_connect (context->window, "notify::visible",
|
||||||
|
G_CALLBACK(on_notify_visible),
|
||||||
|
context);
|
||||||
|
|
||||||
// The properties below are just to make hacking easier.
|
// The properties below are just to make hacking easier.
|
||||||
// The way we use layer-shell overrides some,
|
// The way we use layer-shell overrides some,
|
||||||
@ -221,27 +322,33 @@ make_window (ServerContextService *context)
|
|||||||
static void
|
static void
|
||||||
destroy_window (ServerContextService *context)
|
destroy_window (ServerContextService *context)
|
||||||
{
|
{
|
||||||
gtk_widget_destroy (GTK_WIDGET (context->window));
|
|
||||||
context->window = NULL;
|
context->window = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
make_widget (ServerContextService *context)
|
update_widget (ServerContextService *context)
|
||||||
{
|
{
|
||||||
EekKeyboard *keyboard;
|
EekKeyboard *keyboard;
|
||||||
|
EekTheme *theme;
|
||||||
|
|
||||||
if (context->widget) {
|
if (context->widget) {
|
||||||
gtk_widget_destroy(context->widget);
|
gtk_widget_destroy (context->widget);
|
||||||
context->widget = NULL;
|
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));
|
keyboard = eekboard_context_service_get_keyboard (EEKBOARD_CONTEXT_SERVICE(context));
|
||||||
|
|
||||||
context->widget = eek_gtk_keyboard_new (keyboard);
|
context->widget = eek_gtk_keyboard_new (keyboard);
|
||||||
|
|
||||||
|
eek_gtk_keyboard_set_theme (EEK_GTK_KEYBOARD(context->widget), theme);
|
||||||
|
g_clear_object (&theme);
|
||||||
|
|
||||||
gtk_widget_set_has_tooltip (context->widget, TRUE);
|
gtk_widget_set_has_tooltip (context->widget, TRUE);
|
||||||
gtk_container_add (GTK_CONTAINER(context->window), context->widget);
|
gtk_container_add (GTK_CONTAINER(context->window), context->widget);
|
||||||
gtk_widget_show (context->widget);
|
|
||||||
set_geometry (context);
|
set_geometry (context);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -250,14 +357,11 @@ server_context_service_real_show_keyboard (EekboardContextService *_context)
|
|||||||
{
|
{
|
||||||
ServerContextService *context = SERVER_CONTEXT_SERVICE(_context);
|
ServerContextService *context = SERVER_CONTEXT_SERVICE(_context);
|
||||||
|
|
||||||
if (!context->window)
|
make_window (context);
|
||||||
make_window (context);
|
update_widget (context);
|
||||||
if (!context->widget)
|
|
||||||
make_widget (context);
|
|
||||||
|
|
||||||
EEKBOARD_CONTEXT_SERVICE_CLASS (server_context_service_parent_class)->
|
EEKBOARD_CONTEXT_SERVICE_CLASS (server_context_service_parent_class)->
|
||||||
show_keyboard (_context);
|
show_keyboard (_context);
|
||||||
gtk_widget_show (context->window);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -266,11 +370,34 @@ server_context_service_real_hide_keyboard (EekboardContextService *_context)
|
|||||||
ServerContextService *context = SERVER_CONTEXT_SERVICE(_context);
|
ServerContextService *context = SERVER_CONTEXT_SERVICE(_context);
|
||||||
|
|
||||||
gtk_widget_hide (context->window);
|
gtk_widget_hide (context->window);
|
||||||
|
g_clear_pointer (&context->widget, gtk_widget_destroy);
|
||||||
|
|
||||||
|
destroy_window (context);
|
||||||
|
|
||||||
EEKBOARD_CONTEXT_SERVICE_CLASS (server_context_service_parent_class)->
|
EEKBOARD_CONTEXT_SERVICE_CLASS (server_context_service_parent_class)->
|
||||||
hide_keyboard (_context);
|
hide_keyboard (_context);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
server_context_service_real_enabled (EekboardContextService *_context)
|
||||||
|
{
|
||||||
|
ServerContextService *context = SERVER_CONTEXT_SERVICE(_context);
|
||||||
|
|
||||||
|
if (context->was_visible && context->window)
|
||||||
|
gtk_widget_show_all (context->window);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
server_context_service_real_disabled (EekboardContextService *_context)
|
||||||
|
{
|
||||||
|
ServerContextService *context = SERVER_CONTEXT_SERVICE(_context);
|
||||||
|
|
||||||
|
if (context->window) {
|
||||||
|
context->was_visible = gtk_widget_get_visible (context->window);
|
||||||
|
gtk_widget_hide (context->window);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
server_context_service_real_destroyed (EekboardContextService *_context)
|
server_context_service_real_destroyed (EekboardContextService *_context)
|
||||||
{
|
{
|
||||||
@ -310,7 +437,7 @@ server_context_service_dispose (GObject *object)
|
|||||||
{
|
{
|
||||||
ServerContextService *context = SERVER_CONTEXT_SERVICE(object);
|
ServerContextService *context = SERVER_CONTEXT_SERVICE(object);
|
||||||
|
|
||||||
destroy_window (context);
|
g_clear_pointer (&context->window, gtk_widget_destroy);
|
||||||
context->widget = NULL;
|
context->widget = NULL;
|
||||||
|
|
||||||
G_OBJECT_CLASS (server_context_service_parent_class)->dispose (object);
|
G_OBJECT_CLASS (server_context_service_parent_class)->dispose (object);
|
||||||
@ -325,6 +452,8 @@ server_context_service_class_init (ServerContextServiceClass *klass)
|
|||||||
|
|
||||||
context_class->show_keyboard = server_context_service_real_show_keyboard;
|
context_class->show_keyboard = server_context_service_real_show_keyboard;
|
||||||
context_class->hide_keyboard = server_context_service_real_hide_keyboard;
|
context_class->hide_keyboard = server_context_service_real_hide_keyboard;
|
||||||
|
context_class->enabled = server_context_service_real_enabled;
|
||||||
|
context_class->disabled = server_context_service_real_disabled;
|
||||||
context_class->destroyed = server_context_service_real_destroyed;
|
context_class->destroyed = server_context_service_real_destroyed;
|
||||||
|
|
||||||
gobject_class->set_property = server_context_service_set_property;
|
gobject_class->set_property = server_context_service_set_property;
|
||||||
|
|||||||
@ -23,7 +23,13 @@
|
|||||||
#include <gtk/gtk.h>
|
#include <gtk/gtk.h>
|
||||||
#include <glib/gi18n.h>
|
#include <glib/gi18n.h>
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
#endif /* HAVE_CONFIG_H */
|
||||||
|
|
||||||
|
#if HAVE_CLUTTER_GTK
|
||||||
|
#include <clutter-gtk/clutter-gtk.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "eekboard/eekboard-service.h"
|
#include "eekboard/eekboard-service.h"
|
||||||
#include "eek/eek.h"
|
#include "eek/eek.h"
|
||||||
|
|||||||
@ -19,8 +19,6 @@
|
|||||||
*/
|
*/
|
||||||
#include "eek/eek.h"
|
#include "eek/eek.h"
|
||||||
|
|
||||||
#include <gtk/gtk.h>
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
test_create (void)
|
test_create (void)
|
||||||
{
|
{
|
||||||
@ -32,15 +30,16 @@ test_create (void)
|
|||||||
section = eek_keyboard_create_section (keyboard);
|
section = eek_keyboard_create_section (keyboard);
|
||||||
g_assert (EEK_IS_SECTION(section));
|
g_assert (EEK_IS_SECTION(section));
|
||||||
eek_section_add_row (section, 2, EEK_ORIENTATION_HORIZONTAL);
|
eek_section_add_row (section, 2, EEK_ORIENTATION_HORIZONTAL);
|
||||||
key0 = eek_section_create_key (section, "key0", 1);
|
key0 = eek_section_create_key (section, 1, 0, 0);
|
||||||
g_assert (EEK_IS_KEY(key0));
|
g_assert (EEK_IS_KEY(key0));
|
||||||
key1 = eek_section_create_key (section, "key1", 2);
|
key1 = eek_section_create_key (section, 2, 1, 0);
|
||||||
g_assert (EEK_IS_KEY(key1));
|
g_assert (EEK_IS_KEY(key1));
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
main (int argc, char **argv)
|
main (int argc, char **argv)
|
||||||
{
|
{
|
||||||
|
g_type_init ();
|
||||||
g_test_init (&argc, &argv, NULL);
|
g_test_init (&argc, &argv, NULL);
|
||||||
g_test_add_func ("/eek-simple-test/create", test_create);
|
g_test_add_func ("/eek-simple-test/create", test_create);
|
||||||
return g_test_run ();
|
return g_test_run ();
|
||||||
|
|||||||
@ -21,10 +21,11 @@
|
|||||||
/* For gdk_x11_display_get_xdisplay(). See main(). */
|
/* For gdk_x11_display_get_xdisplay(). See main(). */
|
||||||
#include <gtk/gtk.h>
|
#include <gtk/gtk.h>
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
#endif /* HAVE_CONFIG_H */
|
||||||
|
|
||||||
#include "eek/eek.h"
|
#include "eek/eek.h"
|
||||||
#include "eek/eek-xml-layout.h"
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
test_output_parse (void)
|
test_output_parse (void)
|
||||||
@ -37,9 +38,7 @@ test_output_parse (void)
|
|||||||
layout = eek_xml_layout_new ("us", &error);
|
layout = eek_xml_layout_new ("us", &error);
|
||||||
g_assert_no_error (error);
|
g_assert_no_error (error);
|
||||||
|
|
||||||
/* We don't need the context service to parse an XML file, so we can pass
|
keyboard = eek_keyboard_new (layout, 640, 480);
|
||||||
NULL when creating a keyboard. */
|
|
||||||
keyboard = eek_keyboard_new (NULL, layout, 640, 480);
|
|
||||||
g_object_unref (layout);
|
g_object_unref (layout);
|
||||||
g_object_unref (keyboard);
|
g_object_unref (keyboard);
|
||||||
}
|
}
|
||||||
@ -47,7 +46,9 @@ test_output_parse (void)
|
|||||||
int
|
int
|
||||||
main (int argc, char **argv)
|
main (int argc, char **argv)
|
||||||
{
|
{
|
||||||
|
g_type_init ();
|
||||||
g_test_init (&argc, &argv, NULL);
|
g_test_init (&argc, &argv, NULL);
|
||||||
|
gtk_init (&argc, &argv); /* for gdk_x11_display_get_xdisplay() */
|
||||||
|
|
||||||
g_test_add_func ("/eek-xml-test/output-parse", test_output_parse);
|
g_test_add_func ("/eek-xml-test/output-parse", test_output_parse);
|
||||||
|
|
||||||
|
|||||||
@ -1,50 +0,0 @@
|
|||||||
if get_option('tests')
|
|
||||||
|
|
||||||
test_env = [
|
|
||||||
'G_TEST_SRCDIR=@0@'.format(meson.current_source_dir()),
|
|
||||||
'G_TEST_BUILDDIR=@0@'.format(meson.current_build_dir()),
|
|
||||||
'G_DEBUG=gc-friendly,fatal-warnings',
|
|
||||||
'GSETTINGS_BACKEND=memory',
|
|
||||||
'MALLOC_CHECK_=2'
|
|
||||||
]
|
|
||||||
|
|
||||||
test_cflags = [
|
|
||||||
'-I@0@/../src'.format(meson.current_source_dir()),
|
|
||||||
'-I@0@/../src'.format(meson.current_build_dir()),
|
|
||||||
'-DEEK_COMPILATION',
|
|
||||||
'-DEEKBOARD_COMPILATION'
|
|
||||||
]
|
|
||||||
|
|
||||||
test_link_args = [
|
|
||||||
'-fPIC',
|
|
||||||
]
|
|
||||||
|
|
||||||
tests = [
|
|
||||||
'eek-simple-test',
|
|
||||||
'eek-xml-test',
|
|
||||||
'test-keymap-generation'
|
|
||||||
]
|
|
||||||
|
|
||||||
foreach name : tests
|
|
||||||
|
|
||||||
test_sources = [name + '.c']
|
|
||||||
|
|
||||||
t = executable(
|
|
||||||
name,
|
|
||||||
test_sources,
|
|
||||||
squeekboard_resources,
|
|
||||||
link_with: libsqueekboard,
|
|
||||||
c_args : test_cflags,
|
|
||||||
link_args: test_link_args,
|
|
||||||
dependencies: deps, # from src/meson.build
|
|
||||||
include_directories: [
|
|
||||||
include_directories('..'),
|
|
||||||
include_directories('../eek')
|
|
||||||
]
|
|
||||||
)
|
|
||||||
|
|
||||||
test(name, t, env: test_env)
|
|
||||||
|
|
||||||
endforeach
|
|
||||||
|
|
||||||
endif
|
|
||||||
181
tests/test-keyboard.xml
Normal file
181
tests/test-keyboard.xml
Normal file
@ -0,0 +1,181 @@
|
|||||||
|
<?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>
|
||||||
@ -1,72 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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