Compare commits
268 Commits
update-deb
...
layouts
| Author | SHA1 | Date | |
|---|---|---|---|
| 0e2def7069 | |||
| aa5e1d87dd | |||
| 0a0f7a09a4 | |||
| 9ef38ecf30 | |||
| 4a61ab269b | |||
| 531a87825c | |||
| 4b5bb2a507 | |||
| 1a5f7dd907 | |||
| d38c030ee6 | |||
| 2042ddf08e | |||
| 1cf242a9df | |||
| 9aa0f14494 | |||
| a9c7d688fd | |||
| d2e5cdef4e | |||
| 607f5ed877 | |||
| bd63ae5615 | |||
| 79b66f81ec | |||
| e1c57fa9f0 | |||
| a64bff6aab | |||
| 4e9a8e4afe | |||
| c9a580dc07 | |||
| f479a36dbe | |||
| a7e7e8fb74 | |||
| e56f1c6392 | |||
| 7caf2ef86d | |||
| 86b72d2723 | |||
| c4b3a0aaaa | |||
| de9c93610b | |||
| 7a06ac1ee7 | |||
| f50f8e95b1 | |||
| 2e201b67a7 | |||
| 524040cf00 | |||
| 77d4f45d13 | |||
| 0d33179727 | |||
| 4f8de42598 | |||
| 3689727fc1 | |||
| fffd82b9be | |||
| 6fc351d2e8 | |||
| 5630cf31f1 | |||
| 0c83101b3f | |||
| fc683de434 | |||
| b70afbe9eb | |||
| 996f681e5c | |||
| eb118d67fc | |||
| 725b36ba79 | |||
| 1471a61993 | |||
| 94a76eedfd | |||
| 8566257a01 | |||
| f60917e466 | |||
| 407ec97672 | |||
| 636ed0267d | |||
| 3154125ce0 | |||
| 62496aa18e | |||
| 0b98c2cbe6 | |||
| bc82b59e47 | |||
| 277393387c | |||
| 007ff5c366 | |||
| 699e785340 | |||
| 6081dc240a | |||
| b2e9216920 | |||
| 7972cb17cd | |||
| 73d2505c89 | |||
| bdde8a127e | |||
| 8cf39394c5 | |||
| ecf6957a6e | |||
| d858005a68 | |||
| 6309fa8a48 | |||
| fb8e2ec4e7 | |||
| 91d7cc1118 | |||
| a072755cee | |||
| 1cfec4de50 | |||
| cc3f2315a7 | |||
| f745223796 | |||
| 25a2e95890 | |||
| f371b14e89 | |||
| 0b6935e50c | |||
| fb93e25833 | |||
| ad86cb531a | |||
| 53b89aae45 | |||
| b76e43679e | |||
| 077ca8fad2 | |||
| 377521c108 | |||
| 23d5f18d4a | |||
| c8adb45ab5 | |||
| 18163e3ecc | |||
| a18beca50c | |||
| 04b721aed9 | |||
| 45f9353164 | |||
| 5abe6ed6be | |||
| 38f81e45f4 | |||
| c1482c2377 | |||
| 6bbd8f6006 | |||
| cbdd72a4b6 | |||
| f7d30b0df3 | |||
| 3e35b7441e | |||
| 754e79103a | |||
| d6b59d16fd | |||
| a6e220a2ae | |||
| 0b59262e95 | |||
| 593946779e | |||
| 537ded4b58 | |||
| 25a6a00f0f | |||
| 8298a1412b | |||
| 47eb25d07f | |||
| 0057c80b2e | |||
| da88831689 | |||
| 7b6c6e51b3 | |||
| 42b2b3b8f6 | |||
| 64680664e3 | |||
| 87dd9b4374 | |||
| c7d5e8d152 | |||
| 4cd15c074e | |||
| 9bfdabdf57 | |||
| 9375bc212b | |||
| 3829b52127 | |||
| f852cab0f9 | |||
| f53babcd68 | |||
| 016c1086e6 | |||
| f7dd4c84b1 | |||
| c1c0cb6b31 | |||
| e5858bf698 | |||
| b8389f6736 | |||
| 6c1c979414 | |||
| 43df82355a | |||
| d8b26040f9 | |||
| bdf29bf57b | |||
| 24358c39a6 | |||
| 504285c08f | |||
| b7eb4026f6 | |||
| ad5e4f58bb | |||
| 3085a10507 | |||
| b5f0aa423b | |||
| 9344a13bed | |||
| c8bc2c424f | |||
| 46fa6d4500 | |||
| 6002774f95 | |||
| f7f208883c | |||
| 5523b00442 | |||
| c81fdb18de | |||
| 778543c719 | |||
| 18b8972029 | |||
| fa31f8eee1 | |||
| 98a2e33d78 | |||
| 58d01bf502 | |||
| 8326bd7016 | |||
| d5f8b0d83b | |||
| e70a898af5 | |||
| df249646bc | |||
| 35ff93258e | |||
| c58d034494 | |||
| 8f1de46381 | |||
| 1846a67e83 | |||
| 35ac14806c | |||
| 4aee4915d9 | |||
| 5eeaa1c693 | |||
| 9b2fcf89e8 | |||
| e801a68f0d | |||
| ffc5628637 | |||
| 306aa89d06 | |||
| 236415cde4 | |||
| d49e0eaa1b | |||
| 107399a531 | |||
| 99a7786dc3 | |||
| d8f48cc48b | |||
| 2f0beb6d3a | |||
| 3ab3627ffe | |||
| 70895999c2 | |||
| ce311e1bf1 | |||
| e9cf572a3c | |||
| 943b2ad9f3 | |||
| f86bbb09f8 | |||
| 1246776328 | |||
| ea15f69e73 | |||
| 2e22bb5431 | |||
| a9a6e1d2b5 | |||
| 7e939c36cc | |||
| c5d2d76ab1 | |||
| 622ba6e38a | |||
| fad06348a7 | |||
| a6ee303123 | |||
| 4b66add65f | |||
| 79dce7c4c3 | |||
| aff71e0e33 | |||
| 9b10f56ba6 | |||
| 2391947b34 | |||
| e903150971 | |||
| 7495ec9bbb | |||
| e25d5a84b2 | |||
| 88ade4df1b | |||
| 00c3903672 | |||
| c801b17ba0 | |||
| 9ec8d62f3f | |||
| b1edcfcb1b | |||
| 54b0f59935 | |||
| 531b09f296 | |||
| e5b6d66d60 | |||
| a045810af6 | |||
| d68a8fef9a | |||
| 9162d4291f | |||
| 93d7699aa7 | |||
| 6eb63f6a4c | |||
| f6d4ca0387 | |||
| 7b41466a77 | |||
| 18c25084db | |||
| a5875402ef | |||
| f3ed1ba247 | |||
| 633d69baca | |||
| dbc8cc14bc | |||
| c65583b911 | |||
| 3d518b5757 | |||
| bfa72d7f61 | |||
| 373713ba54 | |||
| 068c325ee2 | |||
| 3b076e5e64 | |||
| 07d6e3a0f2 | |||
| 7690ef9a1a | |||
| 9974c385e5 | |||
| 8dafad80b1 | |||
| 93e9b2dde9 | |||
| c3a54595ea | |||
| 95ef52fe42 | |||
| c638c40a09 | |||
| 83d48d24ce | |||
| d807e43929 | |||
| 0a112be956 | |||
| 078efa2a6e | |||
| 5827827008 | |||
| 9c61d8de72 | |||
| f72ddc8129 | |||
| 7e9c3b40bb | |||
| a8371af9c0 | |||
| 4e11d071d9 | |||
| a7140705c4 | |||
| 69986132b4 | |||
| 3c97a3a592 | |||
| 268dda4da0 | |||
| 45f58a97b9 | |||
| bdbbaf6099 | |||
| 839968dc84 | |||
| fbdc5f4a93 | |||
| e5648a82a3 | |||
| 38133d326b | |||
| cc00fcb5c9 | |||
| 53f7a14717 | |||
| 922495ca06 | |||
| e5e2e08ff4 | |||
| c7c410210b | |||
| cb7c214aa0 | |||
| 6f5f49729c | |||
| 94c9442de1 | |||
| 8c044d0852 | |||
| 1f0cc0a5f3 | |||
| 5693ce3df7 | |||
| bcf04ab11e | |||
| 086f6bd772 | |||
| d0fa444a0e | |||
| cd81aeb286 | |||
| 7db33bc92e | |||
| fb6c501e44 | |||
| ce7b398f7b | |||
| 4d8d3a8109 | |||
| a183cf8b63 | |||
| f834edcf94 | |||
| 17802a9408 | |||
| ac1aad881c | |||
| 928110a92d | |||
| f6479fafe2 | |||
| 62b1c2ba84 |
9
.gitignore
vendored
Normal file
9
.gitignore
vendored
Normal file
@ -0,0 +1,9 @@
|
||||
.zanata-cache/
|
||||
_build
|
||||
TAGS
|
||||
tags
|
||||
vgdump
|
||||
*.swp
|
||||
*~
|
||||
\#*#
|
||||
.\#*
|
||||
@ -2,16 +2,30 @@ image: debian:buster
|
||||
|
||||
stages:
|
||||
- build
|
||||
- test
|
||||
|
||||
.tags: &tags
|
||||
tags:
|
||||
- librem5
|
||||
|
||||
before_script:
|
||||
- apt-get -y update
|
||||
- apt-get -y build-dep .
|
||||
|
||||
build_meson:
|
||||
<<: *tags
|
||||
stage: build
|
||||
tags:
|
||||
- librem5
|
||||
artifacts:
|
||||
paths:
|
||||
- _build
|
||||
script:
|
||||
- meson . _build/ -Ddepdatadir=/usr/share
|
||||
- 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
|
||||
|
||||
```
|
||||
$ git clone https://source.puri.sm/Librem5/eekboard.git
|
||||
$ cd eekboard
|
||||
$ git clone https://source.puri.sm/Librem5/squeekboard.git
|
||||
$ cd squeekboard
|
||||
$ mkdir ../build
|
||||
$ meson ../build/
|
||||
$ cd ../build
|
||||
|
||||
20
autogen.sh
20
autogen.sh
@ -1,20 +0,0 @@
|
||||
#!/bin/sh
|
||||
# Run this to generate all the initial makefiles, etc.
|
||||
|
||||
srcdir=`dirname $0`
|
||||
test -z "$srcdir" && srcdir=.
|
||||
|
||||
PKG_NAME="eekboard"
|
||||
|
||||
(test -f $srcdir/configure.ac \
|
||||
&& test -f $srcdir/README.md ) || {
|
||||
echo -n "**Error**: Directory "\`$srcdir\'" does not look like the"
|
||||
echo " top-level $PKG_NAME directory"
|
||||
exit 1
|
||||
}
|
||||
|
||||
ACLOCAL_FLAGS="$ACLOCAL_FLAGS -I m4"
|
||||
REQUIRED_AUTOMAKE_VERSION=1.10
|
||||
REQUIRED_AUTOCONF_VERSION=2.60
|
||||
|
||||
. gnome-autogen.sh
|
||||
@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
|
||||
<svg xmlns="http://www.w3.org/2000/svg" height="24" width="24"
|
||||
<svg xmlns="http://www.w3.org/2000/svg" height="16" width="16"
|
||||
version="1.1" viewBox="0 0 24 24">
|
||||
|
||||
<path d="M 24,1 L 24,10 C 24,15 20,17 17,17 L 7,17 L 10,20 L 10,23
|
||||
|
||||
|
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"?>
|
||||
|
||||
<svg xmlns="http://www.w3.org/2000/svg" height="24" width="24"
|
||||
<svg xmlns="http://www.w3.org/2000/svg" height="16" width="16"
|
||||
version="1.1" viewBox="0 0 24 24">
|
||||
|
||||
<path d="M 12,2 L 22,14 L 16,14 L 16,22 L 8,22 L 8,14 L 2,14 Z"
|
||||
|
||||
|
Before Width: | Height: | Size: 279 B After Width: | Height: | Size: 279 B |
52
data/icons/keyboard-mode-symbolic.svg
Normal file
52
data/icons/keyboard-mode-symbolic.svg
Normal file
@ -0,0 +1,52 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
id="svg4043"
|
||||
version="1.1"
|
||||
viewBox="0 0 4.2333331 4.2333093"
|
||||
height="4.2333093mm"
|
||||
width="4.2333331mm">
|
||||
<defs
|
||||
id="defs4037" />
|
||||
<metadata
|
||||
id="metadata4040">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
transform="translate(-86.329776,-68.097636)"
|
||||
id="layer1">
|
||||
<g
|
||||
style="stroke-width:1.00004983;fill:#2e3436;fill-opacity:1"
|
||||
transform="matrix(0.99990029,0,0,1,-7.1823833,-1.8799927)"
|
||||
id="g842">
|
||||
<g
|
||||
style="stroke-width:1.00004983;fill:#2e3436;fill-opacity:1"
|
||||
id="g836">
|
||||
<path
|
||||
id="path5166"
|
||||
d="m 95.636719,69.978516 c -1.165869,0 -2.115235,0.949365 -2.115235,2.115234 0,1.165869 0.949366,2.117188 2.115235,2.117188 1.165869,0 2.117187,-0.951319 2.117187,-2.117188 0,-1.165869 -0.951318,-2.115234 -2.117187,-2.115234 z m 0,0.529296 c 0.879886,0 1.58789,0.706052 1.58789,1.585938 0,0.879886 -0.708004,1.587891 -1.58789,1.587891 -0.879886,0 -1.585938,-0.708005 -1.585938,-1.587891 0,-0.879886 0.706052,-1.585937 1.585938,-1.585938 z"
|
||||
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#2e3436;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.52919304;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" />
|
||||
</g>
|
||||
<path
|
||||
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#2e3436;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.26459652;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
|
||||
d="m 95.636719,70.109375 c -0.144398,0 -0.27248,0.07793 -0.373047,0.189453 -0.100567,0.111521 -0.18209,0.261405 -0.25,0.439453 -0.135821,0.356096 -0.214844,0.830395 -0.214844,1.355469 0,0.525074 0.07902,1.001326 0.214844,1.357422 0.06791,0.178048 0.149433,0.327932 0.25,0.439453 0.100567,0.111521 0.228649,0.1875 0.373047,0.1875 0.144397,0 0.27248,-0.07598 0.373047,-0.1875 0.100566,-0.111521 0.182089,-0.261405 0.25,-0.439453 0.135821,-0.356096 0.216797,-0.832348 0.216796,-1.357422 0,-0.525074 -0.08097,-0.999373 -0.216796,-1.355469 -0.06791,-0.178048 -0.149434,-0.327932 -0.25,-0.439453 -0.100567,-0.111521 -0.22865,-0.189453 -0.373047,-0.189453 z m 0,0.265625 c 0.05067,0 0.109272,0.02564 0.177734,0.101562 0.06846,0.07592 0.139293,0.198356 0.199219,0.355469 0.119851,0.314227 0.197266,0.763915 0.197266,1.261719 0,0.497804 -0.07742,0.949446 -0.197266,1.263672 -0.05993,0.157113 -0.130756,0.279549 -0.199219,0.355469 -0.06846,0.07592 -0.12706,0.101562 -0.177734,0.101562 -0.05067,0 -0.107319,-0.02564 -0.175781,-0.101562 -0.06846,-0.07592 -0.139294,-0.198356 -0.199219,-0.355469 C 95.141867,73.043196 95.0625,72.591554 95.0625,72.09375 c 0,-0.497804 0.07937,-0.947492 0.199219,-1.261719 0.05993,-0.157113 0.130756,-0.279549 0.199219,-0.355469 C 95.5294,70.400643 95.586045,70.375 95.636719,70.375 Z"
|
||||
id="circle5168" />
|
||||
<path
|
||||
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#2e3436;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.26459652;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
|
||||
d="m 93.697266,71.962891 v 0.263671 h 3.96875 v -0.263671 z"
|
||||
id="path5170" />
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 6.6 KiB |
@ -1,119 +1,64 @@
|
||||
<?xml version="1.0"?>
|
||||
<geometry version="0.90">
|
||||
<bounds x="0" y="10.000000" width="426.0000" height="296.5853"/>
|
||||
<section angle="0">
|
||||
<row orientation="1">
|
||||
<key keycode="24" name="AD01" oref="outline2" />
|
||||
<key keycode="25" name="AD02" oref="outline2" />
|
||||
<key keycode="26" name="AD03" oref="outline2" />
|
||||
<key keycode="27" name="AD04" oref="outline2" />
|
||||
<key keycode="28" name="AD05" oref="outline2" />
|
||||
<key keycode="29" name="AD06" oref="outline2" />
|
||||
<key keycode="30" name="AD07" oref="outline2" />
|
||||
<key keycode="31" name="AD08" oref="outline2" />
|
||||
<key keycode="32" name="AD09" oref="outline2" />
|
||||
<key keycode="33" name="AD10" oref="outline2" />
|
||||
</row>
|
||||
</section>
|
||||
<section angle="0">
|
||||
<row orientation="1">
|
||||
<key keycode="38" name="AC01" oref="outline2" />
|
||||
<key keycode="39" name="AC02" oref="outline2" />
|
||||
<key keycode="40" name="AC03" oref="outline2" />
|
||||
<key keycode="41" name="AC04" oref="outline2" />
|
||||
<key keycode="42" name="AC05" oref="outline2" />
|
||||
<key keycode="43" name="AC06" oref="outline2" />
|
||||
<key keycode="44" name="AC07" oref="outline2" />
|
||||
<key keycode="45" name="AC08" oref="outline2" />
|
||||
<key keycode="46" name="AC09" oref="outline2" />
|
||||
</row>
|
||||
</section>
|
||||
<section angle="0">
|
||||
<row orientation="1">
|
||||
<key keycode="50" name="LFSH" oref="altline" />
|
||||
<key keycode="52" name="AB01" oref="outline2" />
|
||||
<key keycode="53" name="AB02" oref="outline2" />
|
||||
<key keycode="54" name="AB03" oref="outline2" />
|
||||
<key keycode="55" name="AB04" oref="outline2" />
|
||||
<key keycode="56" name="AB05" oref="outline2" />
|
||||
<key keycode="57" name="AB06" oref="outline2" />
|
||||
<key keycode="58" name="AB07" oref="outline2" />
|
||||
<key keycode="22" name="BKSP" oref="altline" />
|
||||
</row>
|
||||
</section>
|
||||
<section angle="0">
|
||||
<row orientation="1">
|
||||
<key keycode="0" name="ABC123" oref="altline" />
|
||||
<key keycode="150" name="I150" oref="altline" />
|
||||
<key keycode="65" name="SPCE" oref="spaceline" />
|
||||
<key keycode="60" name="AB09" oref="outline2" />
|
||||
<key keycode="36" name="RTRN" oref="outline7" />
|
||||
</row>
|
||||
</section>
|
||||
<outline id="outline2" corner-radius="1.000000">
|
||||
<bounds x="10" y="10" width="410.0000" height="229"/>
|
||||
|
||||
<outline id="default" corner-radius="1.000000">
|
||||
<point x="0.000000" y="0.000000"/>
|
||||
<point x="37.46341" y="0.000000"/>
|
||||
<point x="37.46341" y="52.44877"/>
|
||||
<point x="0.000000" y="52.44877"/>
|
||||
<point x="37.46341" y="52"/>
|
||||
<point x="0.000000" y="52"/>
|
||||
</outline>
|
||||
<outline id="altline" corner-radius="1.000000">
|
||||
<point x="0.000000" y="0.000000"/>
|
||||
<point x="48.39024" y="0.000000"/>
|
||||
<point x="48.39024" y="52.44877"/>
|
||||
<point x="0.000000" y="52.44877"/>
|
||||
</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"/>
|
||||
<point x="48.39024" y="52"/>
|
||||
<point x="0.000000" y="52"/>
|
||||
</outline>
|
||||
<outline id="outline7" corner-radius="1.000000">
|
||||
<point x="0.000000" y="0.000000"/>
|
||||
<point x="88.97561" y="0.000000"/>
|
||||
<point x="88.97561" y="52.44877"/>
|
||||
<point x="0.000000" y="52.44877"/>
|
||||
</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"/>
|
||||
<point x="88.97561" y="52"/>
|
||||
<point x="0.000000" y="52"/>
|
||||
</outline>
|
||||
<outline id="spaceline" corner-radius="1.000000">
|
||||
<point x="0.000000" y="0.000000"/>
|
||||
<point x="150.5853" y="0.000000"/>
|
||||
<point x="150.5853" y="52.44877"/>
|
||||
<point x="0.000000" y="52.44877"/>
|
||||
<point x="150.5853" y="52"/>
|
||||
<point x="0.000000" y="52"/>
|
||||
</outline>
|
||||
|
||||
<button name="Shift_L" oref="altline" />
|
||||
<button name="BackSpace" oref="altline" />
|
||||
<button name="preferences" oref="altline" />
|
||||
<button name="show_numbers" oref="altline" keycode="0" />
|
||||
<button name="show_letters" oref="altline" keycode="0" />
|
||||
<button name="show_symbols" oref="altline" keycode="0" />
|
||||
<button name="period" oref="altline" />
|
||||
<button name="space" oref="spaceline" />
|
||||
<button name="Return" oref="outline7" />
|
||||
|
||||
<view>
|
||||
<section angle="0">q w e r t y u i o p</section>
|
||||
<section angle="0">a s d f g h j k l</section>
|
||||
<section angle="0"> Shift_L z x c v b n m BackSpace </section>
|
||||
<section angle="0"> show_numbers preferences space period Return </section>
|
||||
</view>
|
||||
<view>
|
||||
<section angle="0">Q W E R T Y U I O P</section>
|
||||
<section angle="0">A S D F G H J K L</section>
|
||||
<section angle="0"> Shift_L Z X C V B N M BackSpace </section>
|
||||
<section angle="0"> show_numbers preferences space period Return </section>
|
||||
</view>
|
||||
<view>
|
||||
<section angle="0">1 2 3 4 5 6 7 8 9 0</section>
|
||||
<section angle="0">at numbersign dollar percent ampersand minus underscore plus parenleft parenright</section>
|
||||
<section angle="0"> show_symbols comma quotedbl quoteright colon semicolon exclam question BackSpace </section>
|
||||
<section angle="0"> show_letters preferences space period Return </section>
|
||||
</view>
|
||||
<view>
|
||||
<section angle="0">asciitilde quoteleft bar U00B7 squareroot Greek_pi Greek_tau division multiply paragraph</section>
|
||||
<section angle="0">copyright U00AE U00A3 EuroSign U00A5 asciicircum degree asterisk braceleft braceright</section>
|
||||
<section angle="0"> show_numbers backslash slash less greater equal bracketleft bracketright BackSpace </section>
|
||||
<section angle="0"> show_letters preferences space period Return </section>
|
||||
</view>
|
||||
</geometry>
|
||||
|
||||
105
data/keyboards/geometry/extended.xml
Normal file
105
data/keyboards/geometry/extended.xml
Normal file
@ -0,0 +1,105 @@
|
||||
<?xml version="1.0"?>
|
||||
<geometry version="0.90">
|
||||
<bounds x="0" y="10.000000" width="426.0000" height="296.5853"/>
|
||||
|
||||
<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>
|
||||
|
||||
<button name="Shift_L" oref="altline" />
|
||||
<button name="BackSpace" oref="altline" />
|
||||
<button name="preferences" oref="altline" />
|
||||
<button name="show_numbers" oref="altline" keycode="0" />
|
||||
<button name="show_letters" oref="altline" keycode="0" />
|
||||
<button name="show_symbols" oref="altline" keycode="0" />
|
||||
<button name="space" oref="spaceline" />
|
||||
<button name="return" oref="outline7" />
|
||||
|
||||
<view>
|
||||
<section angle="0">q w e r t y u i o p aring</section>
|
||||
<section angle="0">a s d f g h j k l oslash ae</section>
|
||||
<section angle="0"> Shift_L z x c v b n m BackSpace </section>
|
||||
<section angle="0"> show_numbers preferences space period Return </section>
|
||||
</view>
|
||||
<view>
|
||||
<section angle="0">Q W E R T Y U I O P Aring</section>
|
||||
<section angle="0">A S D F G H J K L Oslash AE</section>
|
||||
<section angle="0"> Shift_L Z X C V B N M BackSpace </section>
|
||||
<section angle="0"> show_numbers preferences space period Return </section>
|
||||
</view>
|
||||
<view>
|
||||
<section angle="0">1 2 3 4 5 6 7 8 9 0</section>
|
||||
<section angle="0">at numbersign dollar percent ampersand minus underscore plus parenleft parenright</section>
|
||||
<section angle="0"> show_symbols comma quotedbl quoteright colon semicolon exclam question BackSpace </section>
|
||||
<section angle="0"> show_letters preferences space period Return </section>
|
||||
</view>
|
||||
<view>
|
||||
<section angle="0">asciitilde quoteleft bar U00B7 squareroot Greek_pi Greek_tau division multiply paragraph</section>
|
||||
<section angle="0">copyright U00AE U00A3 EuroSign U00A5 asciicircum degree asterisk braceleft braceright</section>
|
||||
<section angle="0"> show_numbers backslash slash less greater equal bracketleft bracketright BackSpace </section>
|
||||
<section angle="0"> show_letters preferences space period Return </section>
|
||||
</view>
|
||||
</geometry>
|
||||
40
data/keyboards/geometry/number-keypad.xml
Normal file
40
data/keyboards/geometry/number-keypad.xml
Normal file
@ -0,0 +1,40 @@
|
||||
<?xml version="1.0"?>
|
||||
<geometry version="0.90">
|
||||
<bounds x="0" y="10.000000" width="426.0000" height="296.5853"/>
|
||||
|
||||
<outline id="default" 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="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="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>
|
||||
|
||||
<button name="BackSpace" oref="altline" />
|
||||
<button name="space" oref="spaceline" />
|
||||
<button name="Return" oref="outline7" />
|
||||
|
||||
<view>
|
||||
<section angle="0">1 2 3 parenleft parenright</section>
|
||||
<section angle="0">4 5 6 numbersign asterisk</section>
|
||||
<section angle="0">7 8 9 plus minus</section>
|
||||
<section angle="0">BackSpace 0 space Return</section>
|
||||
</view>
|
||||
</geometry>
|
||||
@ -24,6 +24,9 @@
|
||||
<keyboard id="my" name="my"
|
||||
geometry="compact" symbols="my"
|
||||
longname="Myanmar" language="my"/>
|
||||
<keyboard id="nb" name="nb"
|
||||
geometry="extended" symbols="nb"
|
||||
longname="Norwegian" language="nb"/>
|
||||
<keyboard id="ru" name="ru"
|
||||
geometry="compact" symbols="us"
|
||||
longname="Russian" language="ru"/>
|
||||
@ -85,4 +88,13 @@
|
||||
<keyboard id="te-inscript" name="te-inscript"
|
||||
geometry="compact" symbols="te-inscript"
|
||||
longname="Telugu (Inscript)" language="te"/>
|
||||
|
||||
<!-- Common keyboards -->
|
||||
<keyboard id="number" name="number"
|
||||
geometry="number-keypad" symbols="special/number"
|
||||
longname="Numeric keypad" language="all"/>
|
||||
<keyboard id="phone" name="phone"
|
||||
geometry="number-keypad" symbols="special/number"
|
||||
longname="Phone keypad" language="all"/>
|
||||
|
||||
</keyboards>
|
||||
|
||||
132
data/keyboards/symbols/nb.xml
Normal file
132
data/keyboards/symbols/nb.xml
Normal file
@ -0,0 +1,132 @@
|
||||
<?xml version='1.0' encoding='UTF-8' standalone='yes'?>
|
||||
<symbols version="0.90">
|
||||
<symbol label="*">asterisk</symbol>
|
||||
<symbol label="+/=">show_symbols</symbol>
|
||||
<symbol label="τ">Greek_tau</symbol>
|
||||
<symbol label="å">aring</symbol>
|
||||
<symbol label="ø">oslash</symbol>
|
||||
<symbol label="æ">ae</symbol>
|
||||
<symbol label="Å">Aring</symbol>
|
||||
<symbol label="Ø">Oslash</symbol>
|
||||
<symbol label="Æ">AE</symbol>
|
||||
<symbol label="q">q</symbol>
|
||||
<symbol label="Q">Q</symbol>
|
||||
<symbol label="1">1</symbol>
|
||||
<symbol label="~">asciitilde</symbol>
|
||||
<symbol label="w">w</symbol>
|
||||
<symbol label="W">W</symbol>
|
||||
<symbol label="2">2</symbol>
|
||||
<symbol label="`">quoteleft</symbol>
|
||||
<symbol label="e">e</symbol>
|
||||
<symbol label="E">E</symbol>
|
||||
<symbol label="3">3</symbol>
|
||||
<symbol label="|">bar</symbol>
|
||||
<symbol label="r">r</symbol>
|
||||
<symbol label="R">R</symbol>
|
||||
<symbol label="4">4</symbol>
|
||||
<symbol label="·">U00B7</symbol>
|
||||
<symbol label="t">t</symbol>
|
||||
<symbol label="T">T</symbol>
|
||||
<symbol label="5">5</symbol>
|
||||
<symbol label="√">squareroot</symbol>
|
||||
<symbol label="y">y</symbol>
|
||||
<symbol label="Y">Y</symbol>
|
||||
<symbol label="6">6</symbol>
|
||||
<symbol label="π">Greek_pi</symbol>
|
||||
<symbol label="u">u</symbol>
|
||||
<symbol label="U">U</symbol>
|
||||
<symbol label="7">7</symbol>
|
||||
<symbol label="÷">division</symbol>
|
||||
<symbol label="i">i</symbol>
|
||||
<symbol label="I">I</symbol>
|
||||
<symbol label="8">8</symbol>
|
||||
<symbol label="×">multiply</symbol>
|
||||
<symbol label="o">o</symbol>
|
||||
<symbol label="O">O</symbol>
|
||||
<symbol label="9">9</symbol>
|
||||
<symbol label="¶">paragraph</symbol>
|
||||
<symbol label="p">p</symbol>
|
||||
<symbol label="P">P</symbol>
|
||||
<symbol label="0">0</symbol>
|
||||
<symbol label="△">U25B3</symbol>
|
||||
<symbol keyval="229" label="å">aring</symbol>
|
||||
<symbol keyval="197" label="Å">Aring</symbol>
|
||||
<symbol label="a">a</symbol>
|
||||
<symbol label="A">A</symbol>
|
||||
<symbol label="@">at</symbol>
|
||||
<symbol label="©">copyright</symbol>
|
||||
<symbol label="s">s</symbol>
|
||||
<symbol label="S">S</symbol>
|
||||
<symbol label="#">numbersign</symbol>
|
||||
<symbol label="®">U00AE</symbol>
|
||||
<symbol label="d">d</symbol>
|
||||
<symbol label="D">D</symbol>
|
||||
<symbol label="$">dollar</symbol>
|
||||
<symbol label="£">U00A3</symbol>
|
||||
<symbol label="f">f</symbol>
|
||||
<symbol label="F">F</symbol>
|
||||
<symbol label="%">percent</symbol>
|
||||
<symbol label="€">EuroSign</symbol>
|
||||
<symbol label="g">g</symbol>
|
||||
<symbol label="G">G</symbol>
|
||||
<symbol label="&">ampersand</symbol>
|
||||
<symbol label="¥">U00A5</symbol>
|
||||
<symbol label="h">h</symbol>
|
||||
<symbol label="H">H</symbol>
|
||||
<symbol label="-">minus</symbol>
|
||||
<symbol label="^">asciicircum</symbol>
|
||||
<symbol label="j">j</symbol>
|
||||
<symbol label="J">J</symbol>
|
||||
<symbol label="_">underscore</symbol>
|
||||
<symbol label="°">degree</symbol>
|
||||
<symbol label="k">k</symbol>
|
||||
<symbol label="K">K</symbol>
|
||||
<symbol label="+">plus</symbol>
|
||||
<symbol label="=">equal</symbol>
|
||||
<symbol label="l">l</symbol>
|
||||
<symbol label="L">L</symbol>
|
||||
<symbol label="(">parenleft</symbol>
|
||||
<symbol label="{">braceleft</symbol>
|
||||
<symbol keyval="248" label="ø">oslash</symbol>
|
||||
<symbol keyval="216" label="Ø">Oslash</symbol>
|
||||
<symbol label=")">parenright</symbol>
|
||||
<symbol label="}">braceright</symbol>
|
||||
<symbol keyval="230" label="æ">ae</symbol>
|
||||
<symbol keyval="198" label="Æ">AE</symbol>
|
||||
<symbol keyval="65293" icon="key-enter">Return</symbol>
|
||||
<symbol keyval="65505" icon="key-shift">Shift_L</symbol>
|
||||
<symbol label="z">z</symbol>
|
||||
<symbol label="Z">Z</symbol>
|
||||
<symbol label=",">comma</symbol>
|
||||
<symbol label="\">backslash</symbol>
|
||||
<symbol label="x">x</symbol>
|
||||
<symbol label="X">X</symbol>
|
||||
<symbol label=""">quotedbl</symbol>
|
||||
<symbol label="/">slash</symbol>
|
||||
<symbol label="c">c</symbol>
|
||||
<symbol label="C">C</symbol>
|
||||
<symbol label="'">quoteright</symbol>
|
||||
<symbol label="<">less</symbol>
|
||||
<symbol label="v">v</symbol>
|
||||
<symbol label="V">V</symbol>
|
||||
<symbol label=":">colon</symbol>
|
||||
<symbol label=">">greater</symbol>
|
||||
<symbol label="b">b</symbol>
|
||||
<symbol label="B">B</symbol>
|
||||
<symbol label=";">semicolon</symbol>
|
||||
<symbol label="=">equal</symbol>
|
||||
<symbol label="n">n</symbol>
|
||||
<symbol label="N">N</symbol>
|
||||
<symbol label="!">exclam</symbol>
|
||||
<symbol label="[">bracketleft</symbol>
|
||||
<symbol label="m">m</symbol>
|
||||
<symbol label="M">M</symbol>
|
||||
<symbol label="?">question</symbol>
|
||||
<symbol label="]">bracketright</symbol>
|
||||
<symbol label=".">period</symbol>
|
||||
<symbol label="123">show_numbers</symbol>
|
||||
<symbol label="ABC">show_letters</symbol>
|
||||
<symbol label="☺" icon="keyboard-mode-symbolic" tooltip="Setup">preferences</symbol>
|
||||
<symbol label=" ">space</symbol>
|
||||
<symbol keyval="65288" icon="edit-clear-symbolic">BackSpace</symbol>
|
||||
</symbols>
|
||||
22
data/keyboards/symbols/special/number.xml
Normal file
22
data/keyboards/symbols/special/number.xml
Normal file
@ -0,0 +1,22 @@
|
||||
<?xml version='1.0' encoding='ASCII' standalone='yes'?>
|
||||
<symbols version="0.90">
|
||||
<symbol label="1">1</symbol>
|
||||
<symbol label="2">2</symbol>
|
||||
<symbol label="3">3</symbol>
|
||||
<symbol label="(">parenleft</symbol>
|
||||
<symbol label=")">parenright</symbol>
|
||||
<symbol label="4">4</symbol>
|
||||
<symbol label="5">5</symbol>
|
||||
<symbol label="6">6</symbol>
|
||||
<symbol label="#">numbersign</symbol>
|
||||
<symbol label="*">asterisk</symbol>
|
||||
<symbol label="7">7</symbol>
|
||||
<symbol label="8">8</symbol>
|
||||
<symbol label="9">9</symbol>
|
||||
<symbol label="+">plus</symbol>
|
||||
<symbol label="-">minus</symbol>
|
||||
<symbol label="0">0</symbol>
|
||||
<symbol keyval="65293" icon="key-enter">Return</symbol>
|
||||
<symbol label=" ">space</symbol>
|
||||
<symbol keyval="65288" icon="edit-clear-symbolic">BackSpace</symbol>
|
||||
</symbols>
|
||||
@ -1,276 +1,118 @@
|
||||
<?xml version="1.0"?>
|
||||
<?xml version='1.0' encoding='ASCII' standalone='yes'?>
|
||||
<symbols version="0.90">
|
||||
<key keycode="9" name="ESC">
|
||||
<keysym keyval="65307">Escape</keysym>
|
||||
</key>
|
||||
<key keycode="67" name="FK01">
|
||||
<keysym keyval="65470">F1</keysym>
|
||||
</key>
|
||||
<key keycode="68" name="FK02">
|
||||
<keysym keyval="65471">F2</keysym>
|
||||
</key>
|
||||
<key keycode="69" name="FK03">
|
||||
<keysym keyval="65472">F3</keysym>
|
||||
</key>
|
||||
<key keycode="70" name="FK04">
|
||||
<keysym keyval="65473">F4</keysym>
|
||||
</key>
|
||||
<key keycode="71" name="FK05">
|
||||
<keysym keyval="65474">F5</keysym>
|
||||
</key>
|
||||
<key keycode="72" name="FK06">
|
||||
<keysym keyval="65475">F6</keysym>
|
||||
</key>
|
||||
<key keycode="73" name="FK07">
|
||||
<keysym keyval="65476">F7</keysym>
|
||||
</key>
|
||||
<key keycode="74" name="FK08">
|
||||
<keysym keyval="65477">F8</keysym>
|
||||
</key>
|
||||
<key keycode="75" name="FK09">
|
||||
<keysym keyval="65478">F9</keysym>
|
||||
</key>
|
||||
<key keycode="76" name="FK10">
|
||||
<keysym keyval="65479">F10</keysym>
|
||||
</key>
|
||||
<key keycode="95" name="FK11">
|
||||
<keysym keyval="65480">F11</keysym>
|
||||
</key>
|
||||
<key keycode="96" name="FK12">
|
||||
<keysym keyval="65481">F12</keysym>
|
||||
</key>
|
||||
<key keycode="22" name="BKSP">
|
||||
<keysym keyval="65288" icon="edit-clear-symbolic">backspace</keysym>
|
||||
</key>
|
||||
<key keycode="23" name="TAB">
|
||||
<keysym keyval="65289">Tab</keysym>
|
||||
<keysym keyval="65056">ISO_Left_Tab</keysym>
|
||||
</key>
|
||||
<key keycode="24" name="AD01">
|
||||
<keysym keyval="113">q</keysym>
|
||||
<keysym keyval="81">Q</keysym>
|
||||
<keysym keyval="49">1</keysym>
|
||||
<keysym keyval="126">asciitilde</keysym>
|
||||
</key>
|
||||
<key keycode="25" name="AD02">
|
||||
<keysym keyval="119">w</keysym>
|
||||
<keysym keyval="87">W</keysym>
|
||||
<keysym keyval="50">2</keysym>
|
||||
<keysym keyval="96">quoteleft</keysym>
|
||||
</key>
|
||||
<key keycode="26" name="AD03">
|
||||
<keysym keyval="101">e</keysym>
|
||||
<keysym keyval="69">E</keysym>
|
||||
<keysym keyval="51">3</keysym>
|
||||
<keysym keyval="124">bar</keysym>
|
||||
</key>
|
||||
<key keycode="27" name="AD04">
|
||||
<keysym keyval="114">r</keysym>
|
||||
<keysym keyval="82">R</keysym>
|
||||
<keysym keyval="52">4</keysym>
|
||||
<keysym keyval="183">middledot</keysym>
|
||||
</key>
|
||||
<key keycode="28" name="AD05">
|
||||
<keysym keyval="116">t</keysym>
|
||||
<keysym keyval="84">T</keysym>
|
||||
<keysym keyval="53">5</keysym>
|
||||
</key>
|
||||
<key keycode="29" name="AD06">
|
||||
<keysym keyval="121">y</keysym>
|
||||
<keysym keyval="89">Y</keysym>
|
||||
<keysym keyval="54">6</keysym>
|
||||
</key>
|
||||
<key keycode="30" name="AD07">
|
||||
<keysym keyval="117">u</keysym>
|
||||
<keysym keyval="85">U</keysym>
|
||||
<keysym keyval="55">7</keysym>
|
||||
</key>
|
||||
<key keycode="31" name="AD08">
|
||||
<keysym keyval="105">i</keysym>
|
||||
<keysym keyval="73">I</keysym>
|
||||
<keysym keyval="56">8</keysym>
|
||||
</key>
|
||||
<key keycode="32" name="AD09">
|
||||
<keysym keyval="111">o</keysym>
|
||||
<keysym keyval="79">O</keysym>
|
||||
<keysym keyval="57">9</keysym>
|
||||
</key>
|
||||
<key keycode="33" name="AD10">
|
||||
<keysym keyval="112">p</keysym>
|
||||
<keysym keyval="80">P</keysym>
|
||||
<keysym keyval="48">0</keysym>
|
||||
</key>
|
||||
<key keycode="34" name="AD11">
|
||||
<keysym keyval="91">bracketleft</keysym>
|
||||
<keysym keyval="123">braceleft</keysym>
|
||||
</key>
|
||||
<key keycode="35" name="AD12">
|
||||
<keysym keyval="93">bracketright</keysym>
|
||||
<keysym keyval="125">braceright</keysym>
|
||||
</key>
|
||||
<key keycode="51" name="BKSL">
|
||||
<keysym keyval="92">backslash</keysym>
|
||||
<keysym keyval="124">bar</keysym>
|
||||
</key>
|
||||
<key keycode="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" label="=/+">Shift_L</keysym>
|
||||
<keysym keyval="65505" label="123">Shift_L</keysym>
|
||||
</key>
|
||||
<key keycode="52" name="AB01">
|
||||
<keysym keyval="122">z</keysym>
|
||||
<keysym keyval="90">Z</keysym>
|
||||
<keysym keyval="44">comma</keysym>
|
||||
<keysym keyval="92">backslash</keysym>
|
||||
</key>
|
||||
<key keycode="53" name="AB02">
|
||||
<keysym keyval="120">x</keysym>
|
||||
<keysym keyval="88">X</keysym>
|
||||
<keysym keyval="34">quotedbl</keysym>
|
||||
<keysym keyval="47">slash</keysym>
|
||||
</key>
|
||||
<key keycode="54" name="AB03">
|
||||
<keysym keyval="99">c</keysym>
|
||||
<keysym keyval="67">C</keysym>
|
||||
<keysym keyval="39">quoteright</keysym>
|
||||
<keysym keyval="60">less</keysym>
|
||||
</key>
|
||||
<key keycode="55" name="AB04">
|
||||
<keysym keyval="118">v</keysym>
|
||||
<keysym keyval="86">V</keysym>
|
||||
<keysym keyval="58">colon</keysym>
|
||||
<keysym keyval="62">greater</keysym>
|
||||
</key>
|
||||
<key keycode="56" name="AB05">
|
||||
<keysym keyval="98">b</keysym>
|
||||
<keysym keyval="66">B</keysym>
|
||||
<keysym keyval="59">semicolon</keysym>
|
||||
<keysym keyval="61">equal</keysym>
|
||||
</key>
|
||||
<key keycode="57" name="AB06">
|
||||
<keysym keyval="110">n</keysym>
|
||||
<keysym keyval="78">N</keysym>
|
||||
<keysym keyval="33">exclam</keysym>
|
||||
<keysym keyval="91">bracketleft</keysym>
|
||||
</key>
|
||||
<key keycode="58" name="AB07">
|
||||
<keysym keyval="109">m</keysym>
|
||||
<keysym keyval="77">M</keysym>
|
||||
<keysym keyval="63">question</keysym>
|
||||
<keysym keyval="93">bracketright</keysym>
|
||||
</key>
|
||||
<key keycode="59" name="AB08">
|
||||
<keysym keyval="44">comma</keysym>
|
||||
<keysym keyval="60">less</keysym>
|
||||
</key>
|
||||
<key keycode="60" name="AB09">
|
||||
<keysym keyval="46">period</keysym>
|
||||
</key>
|
||||
<key keycode="61" name="AB10">
|
||||
<keysym keyval="47">slash</keysym>
|
||||
<keysym keyval="63">question</keysym>
|
||||
</key>
|
||||
<key keycode="62" name="RTSH">
|
||||
<keysym keyval="65506">Shift_R</keysym>
|
||||
</key>
|
||||
<key keycode="149" name="I149">
|
||||
<symbol label="⌨" icon="input-keyboard-symbolic" tooltip="Change keyboard">cycle-keyboard</symbol>
|
||||
</key>
|
||||
<key keycode="150" name="I150">
|
||||
<symbol label="☺" icon="preferences-system-symbolic" tooltip="Setup">preferences</symbol>
|
||||
</key>
|
||||
<key keycode="37" name="LCTL">
|
||||
<keysym keyval="65507">Control_L</keysym>
|
||||
</key>
|
||||
<key keycode="64" name="LALT">
|
||||
<keysym keyval="65513">Alt_L</keysym>
|
||||
<keysym keyval="65511">Meta_L</keysym>
|
||||
</key>
|
||||
<key keycode="65" name="SPCE">
|
||||
<keysym keyval="32">space</keysym>
|
||||
</key>
|
||||
<key keycode="113" name="LEFT">
|
||||
<keysym keyval="65361">Left</keysym>
|
||||
</key>
|
||||
<key keycode="111" name="UP">
|
||||
<keysym keyval="65362">Up</keysym>
|
||||
</key>
|
||||
<key keycode="116" name="DOWN">
|
||||
<keysym keyval="65364">Down</keysym>
|
||||
</key>
|
||||
<key keycode="114" name="RGHT">
|
||||
<keysym keyval="65363">Right</keysym>
|
||||
</key>
|
||||
<symbol label="*">asterisk</symbol>
|
||||
<symbol label="+/=">show_symbols</symbol>
|
||||
<symbol label="q">q</symbol>
|
||||
<symbol label="Q">Q</symbol>
|
||||
<symbol label="1">1</symbol>
|
||||
<symbol label="~">asciitilde</symbol>
|
||||
<symbol label="w">w</symbol>
|
||||
<symbol label="W">W</symbol>
|
||||
<symbol label="2">2</symbol>
|
||||
<symbol label="`">quoteleft</symbol>
|
||||
<symbol label="e">e</symbol>
|
||||
<symbol label="E">E</symbol>
|
||||
<symbol label="3">3</symbol>
|
||||
<symbol label="|">bar</symbol>
|
||||
<symbol label="r">r</symbol>
|
||||
<symbol label="R">R</symbol>
|
||||
<symbol label="4">4</symbol>
|
||||
<symbol label="·">U00B7</symbol>
|
||||
<symbol label="t">t</symbol>
|
||||
<symbol label="T">T</symbol>
|
||||
<symbol label="5">5</symbol>
|
||||
<symbol label="√">squareroot</symbol>
|
||||
<symbol label="y">y</symbol>
|
||||
<symbol label="Y">Y</symbol>
|
||||
<symbol label="6">6</symbol>
|
||||
<symbol label="π">Greek_pi</symbol>
|
||||
<symbol label="u">u</symbol>
|
||||
<symbol label="U">U</symbol>
|
||||
<symbol label="7">7</symbol>
|
||||
<symbol label="÷">division</symbol>
|
||||
<symbol label="i">i</symbol>
|
||||
<symbol label="I">I</symbol>
|
||||
<symbol label="8">8</symbol>
|
||||
<symbol label="×">multiply</symbol>
|
||||
<symbol label="o">o</symbol>
|
||||
<symbol label="O">O</symbol>
|
||||
<symbol label="9">9</symbol>
|
||||
<symbol label="¶">paragraph</symbol>
|
||||
<symbol label="p">p</symbol>
|
||||
<symbol label="P">P</symbol>
|
||||
<symbol label="0">0</symbol>
|
||||
<symbol label="τ">Greek_tau</symbol>
|
||||
<symbol label="a">a</symbol>
|
||||
<symbol label="A">A</symbol>
|
||||
<symbol label="@">at</symbol>
|
||||
<symbol label="©">copyright</symbol>
|
||||
<symbol label="s">s</symbol>
|
||||
<symbol label="S">S</symbol>
|
||||
<symbol label="#">numbersign</symbol>
|
||||
<symbol label="®">U00AE</symbol>
|
||||
<symbol label="d">d</symbol>
|
||||
<symbol label="D">D</symbol>
|
||||
<symbol label="$">dollar</symbol>
|
||||
<symbol label="£">U00A3</symbol>
|
||||
<symbol label="f">f</symbol>
|
||||
<symbol label="F">F</symbol>
|
||||
<symbol label="%">percent</symbol>
|
||||
<symbol label="€">EuroSign</symbol>
|
||||
<symbol label="g">g</symbol>
|
||||
<symbol label="G">G</symbol>
|
||||
<symbol label="&">ampersand</symbol>
|
||||
<symbol label="¥">U00A5</symbol>
|
||||
<symbol label="h">h</symbol>
|
||||
<symbol label="H">H</symbol>
|
||||
<symbol label="-">minus</symbol>
|
||||
<symbol label="^">asciicircum</symbol>
|
||||
<symbol label="j">j</symbol>
|
||||
<symbol label="J">J</symbol>
|
||||
<symbol label="_">underscore</symbol>
|
||||
<symbol label="°">degree</symbol>
|
||||
<symbol label="k">k</symbol>
|
||||
<symbol label="K">K</symbol>
|
||||
<symbol label="+">plus</symbol>
|
||||
<symbol label="=">equal</symbol>
|
||||
<symbol label="l">l</symbol>
|
||||
<symbol label="L">L</symbol>
|
||||
<symbol label="(">parenleft</symbol>
|
||||
<symbol label="{">braceleft</symbol>
|
||||
<symbol label=")">parenright</symbol>
|
||||
<symbol label="}">braceright</symbol>
|
||||
<symbol keyval="65293" icon="key-enter">Return</symbol>
|
||||
<symbol keyval="65505" icon="key-shift">Shift_L</symbol>
|
||||
<symbol label="z">z</symbol>
|
||||
<symbol label="Z">Z</symbol>
|
||||
<symbol label=",">comma</symbol>
|
||||
<symbol label="\">backslash</symbol>
|
||||
<symbol label="x">x</symbol>
|
||||
<symbol label="X">X</symbol>
|
||||
<symbol label=""">quotedbl</symbol>
|
||||
<symbol label="/">slash</symbol>
|
||||
<symbol label="c">c</symbol>
|
||||
<symbol label="C">C</symbol>
|
||||
<symbol label="'">quoteright</symbol>
|
||||
<symbol label="<">less</symbol>
|
||||
<symbol label="v">v</symbol>
|
||||
<symbol label="V">V</symbol>
|
||||
<symbol label=":">colon</symbol>
|
||||
<symbol label=">">greater</symbol>
|
||||
<symbol label="b">b</symbol>
|
||||
<symbol label="B">B</symbol>
|
||||
<symbol label=";">semicolon</symbol>
|
||||
<symbol label="n">n</symbol>
|
||||
<symbol label="N">N</symbol>
|
||||
<symbol label="!">exclam</symbol>
|
||||
<symbol label="[">bracketleft</symbol>
|
||||
<symbol label="m">m</symbol>
|
||||
<symbol label="M">M</symbol>
|
||||
<symbol label="?">question</symbol>
|
||||
<symbol label="]">bracketright</symbol>
|
||||
<symbol label=".">period</symbol>
|
||||
<symbol label="123">show_numbers</symbol>
|
||||
<symbol label="ABC">show_letters</symbol>
|
||||
<symbol label="☺" icon="keyboard-mode-symbolic" tooltip="Setup">preferences</symbol>
|
||||
<symbol label=" ">space</symbol>
|
||||
<symbol keyval="65288" icon="edit-clear-symbolic">BackSpace</symbol>
|
||||
</symbols>
|
||||
|
||||
@ -3,6 +3,8 @@
|
||||
<gresource prefix="/sm/puri/squeekboard">
|
||||
<file compressed="true">style.css</file>
|
||||
<file compressed="true" preprocess="xml-stripblanks">keyboards/geometry/compact.xml</file>
|
||||
<file compressed="true" preprocess="xml-stripblanks">keyboards/geometry/extended.xml</file>
|
||||
<file compressed="true" preprocess="xml-stripblanks">keyboards/geometry/number-keypad.xml</file>
|
||||
<file compressed="true" preprocess="xml-stripblanks">keyboards/keyboards.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>
|
||||
@ -21,6 +23,7 @@
|
||||
<file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/ml-inscript.xml</file>
|
||||
<file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/mr-inscript.xml</file>
|
||||
<file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/my.xml</file>
|
||||
<file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/nb.xml</file>
|
||||
<file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/or-inscript.xml</file>
|
||||
<file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/pa-inscript.xml</file>
|
||||
<file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/ru.xml</file>
|
||||
@ -32,7 +35,9 @@
|
||||
<file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/ug.xml</file>
|
||||
<file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/us.xml</file>
|
||||
<file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/zh-bopomofo.xml</file>
|
||||
<file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/special/number.xml</file>
|
||||
<file>icons/key-enter.svg</file>
|
||||
<file>icons/key-shift.svg</file>
|
||||
<file>icons/keyboard-mode-symbolic.svg</file>
|
||||
</gresource>
|
||||
</gresources>
|
||||
|
||||
@ -7,7 +7,8 @@
|
||||
.key {
|
||||
color: #deddda;
|
||||
background: #464448;
|
||||
border-width: 0.5px;
|
||||
border-style: solid;
|
||||
border-width: 1px;
|
||||
border-color: #5e5c64;
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
5
debian/control
vendored
5
debian/control
vendored
@ -11,7 +11,10 @@ Build-Depends:
|
||||
libcroco3-dev,
|
||||
libwayland-dev (>= 1.16),
|
||||
rustc,
|
||||
wayland-protocols (>= 1.14)
|
||||
wayland-protocols (>= 1.14),
|
||||
# for running the tests
|
||||
xvfb,
|
||||
xauth,
|
||||
Standards-Version: 4.1.3
|
||||
Homepage: https://source.puri.sm/Librem5/squeekboard
|
||||
|
||||
|
||||
4
debian/copyright
vendored
4
debian/copyright
vendored
@ -1,6 +1,6 @@
|
||||
Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
|
||||
Upstream-Name: evscript
|
||||
Source: https://source.puri.sm/david.boddie/evscript
|
||||
Upstream-Name: squeekboard
|
||||
Source: https://source.puri.sm/Librem5/squeekboard
|
||||
|
||||
Files: *
|
||||
Copyright: 2010-2011 Daiki Ueno <ueno@unixuser.org>
|
||||
|
||||
@ -1,234 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2011 Daiki Ueno <ueno@unixuser.org>
|
||||
* Copyright (C) 2010-2011 Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public License
|
||||
* as published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
* 02110-1301 USA
|
||||
*/
|
||||
|
||||
/**
|
||||
* SECTION:eek-container
|
||||
* @short_description: Base class of a keyboard container
|
||||
*
|
||||
* The #EekContainerClass class represents a keyboard container, which
|
||||
* shall be used to implement #EekKeyboard and #EekSection.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
|
||||
#include "eek-container.h"
|
||||
|
||||
enum {
|
||||
CHILD_ADDED,
|
||||
CHILD_REMOVED,
|
||||
LAST_SIGNAL
|
||||
};
|
||||
|
||||
static guint signals[LAST_SIGNAL] = { 0, };
|
||||
|
||||
typedef struct _EekContainerPrivate
|
||||
{
|
||||
GList *head;
|
||||
GList *last;
|
||||
} EekContainerPrivate;
|
||||
|
||||
G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (EekContainer, eek_container, EEK_TYPE_ELEMENT)
|
||||
|
||||
static void
|
||||
eek_container_real_add_child (EekContainer *self,
|
||||
EekElement *child)
|
||||
{
|
||||
EekContainerPrivate *priv = eek_container_get_instance_private (self);
|
||||
|
||||
g_return_if_fail (EEK_IS_ELEMENT(child));
|
||||
g_object_ref (child);
|
||||
|
||||
if (!priv->head) {
|
||||
priv->head = priv->last = g_list_prepend (priv->head, child);
|
||||
} else {
|
||||
priv->last->next = g_list_prepend (priv->last->next, child);
|
||||
priv->last = priv->last->next;
|
||||
}
|
||||
eek_element_set_parent (child, EEK_ELEMENT(self));
|
||||
g_signal_emit (self, signals[CHILD_ADDED], 0, child);
|
||||
}
|
||||
|
||||
static void
|
||||
eek_container_real_remove_child (EekContainer *self,
|
||||
EekElement *child)
|
||||
{
|
||||
EekContainerPrivate *priv = eek_container_get_instance_private (self);
|
||||
GList *head;
|
||||
|
||||
g_return_if_fail (EEK_IS_ELEMENT(child));
|
||||
head = g_list_find (priv->head, child);
|
||||
g_return_if_fail (head);
|
||||
g_object_unref (child);
|
||||
if (head == priv->last)
|
||||
priv->last = g_list_previous (priv->last);
|
||||
priv->head = g_list_remove_link (priv->head, head);
|
||||
eek_element_set_parent (child, NULL);
|
||||
g_signal_emit (self, signals[CHILD_REMOVED], 0, child);
|
||||
}
|
||||
|
||||
static void
|
||||
eek_container_real_foreach_child (EekContainer *self,
|
||||
EekCallback callback,
|
||||
gpointer user_data)
|
||||
{
|
||||
EekContainerPrivate *priv = eek_container_get_instance_private (self);
|
||||
GList *head;
|
||||
|
||||
for (head = priv->head; head; head = g_list_next (head))
|
||||
(*callback) (EEK_ELEMENT(head->data), user_data);
|
||||
}
|
||||
|
||||
static EekElement *
|
||||
eek_container_real_find (EekContainer *self,
|
||||
EekCompareFunc func,
|
||||
gpointer user_data)
|
||||
{
|
||||
EekContainerPrivate *priv = eek_container_get_instance_private (self);
|
||||
GList *head;
|
||||
|
||||
head = g_list_find_custom (priv->head, user_data, (GCompareFunc)func);
|
||||
if (head)
|
||||
return head->data;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
eek_container_dispose (GObject *object)
|
||||
{
|
||||
EekContainer *self = EEK_CONTAINER (object);
|
||||
EekContainerPrivate *priv = eek_container_get_instance_private (self);
|
||||
GList *head;
|
||||
|
||||
for (head = priv->head; head; head = priv->head) {
|
||||
g_object_unref (head->data);
|
||||
priv->head = g_list_next (head);
|
||||
g_list_free1 (head);
|
||||
}
|
||||
G_OBJECT_CLASS(eek_container_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
eek_container_class_init (EekContainerClass *klass)
|
||||
{
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
klass->add_child = eek_container_real_add_child;
|
||||
klass->remove_child = eek_container_real_remove_child;
|
||||
klass->foreach_child = eek_container_real_foreach_child;
|
||||
klass->find = eek_container_real_find;
|
||||
|
||||
/* signals */
|
||||
klass->child_added = NULL;
|
||||
klass->child_removed = NULL;
|
||||
|
||||
gobject_class->dispose = eek_container_dispose;
|
||||
|
||||
/**
|
||||
* EekContainer::child-added:
|
||||
* @container: an #EekContainer
|
||||
* @element: an #EekElement
|
||||
*
|
||||
* The ::child-added signal is emitted each time an element is
|
||||
* added to @container.
|
||||
*/
|
||||
signals[CHILD_ADDED] =
|
||||
g_signal_new (I_("child-added"),
|
||||
G_TYPE_FROM_CLASS(gobject_class),
|
||||
G_SIGNAL_RUN_FIRST,
|
||||
G_STRUCT_OFFSET(EekContainerClass, child_added),
|
||||
NULL, NULL,
|
||||
g_cclosure_marshal_VOID__OBJECT,
|
||||
G_TYPE_NONE, 1,
|
||||
EEK_TYPE_ELEMENT);
|
||||
|
||||
/**
|
||||
* EekContainer::child-removed:
|
||||
* @container: an #EekContainer
|
||||
* @element: an #EekElement
|
||||
*
|
||||
* The ::child-removed signal is emitted each time an element is
|
||||
* removed from @container.
|
||||
*/
|
||||
signals[CHILD_REMOVED] =
|
||||
g_signal_new (I_("child-removed"),
|
||||
G_TYPE_FROM_CLASS(gobject_class),
|
||||
G_SIGNAL_RUN_FIRST,
|
||||
G_STRUCT_OFFSET(EekContainerClass, child_removed),
|
||||
NULL,
|
||||
NULL,
|
||||
g_cclosure_marshal_VOID__OBJECT,
|
||||
G_TYPE_NONE, 1,
|
||||
EEK_TYPE_ELEMENT);
|
||||
}
|
||||
|
||||
static void
|
||||
eek_container_init (EekContainer *self)
|
||||
{
|
||||
/* void */
|
||||
}
|
||||
|
||||
/**
|
||||
* eek_container_foreach_child:
|
||||
* @container: an #EekContainer
|
||||
* @callback: (scope call): an #EekCallback
|
||||
* @user_data: additional data passed to @callback
|
||||
*
|
||||
* Enumerate children of @container and run @callback with each child.
|
||||
*/
|
||||
void
|
||||
eek_container_foreach_child (EekContainer *container,
|
||||
EekCallback callback,
|
||||
gpointer user_data)
|
||||
{
|
||||
g_return_if_fail (EEK_IS_CONTAINER(container));
|
||||
EEK_CONTAINER_GET_CLASS(container)->foreach_child (container,
|
||||
callback,
|
||||
user_data);
|
||||
}
|
||||
|
||||
/**
|
||||
* eek_container_find:
|
||||
* @container: an #EekContainer
|
||||
* @func: function to be used to compare two children
|
||||
* @user_data: additional data passed to @func
|
||||
*
|
||||
* Find a child which matches the criteria supplied as @func, in @container.
|
||||
* Returns: an #EekElement or NULL on failure
|
||||
*/
|
||||
EekElement *
|
||||
eek_container_find (EekContainer *container,
|
||||
EekCompareFunc func,
|
||||
gpointer user_data)
|
||||
{
|
||||
g_return_val_if_fail (EEK_IS_CONTAINER(container), NULL);
|
||||
return EEK_CONTAINER_GET_CLASS(container)->find (container,
|
||||
func,
|
||||
user_data);
|
||||
}
|
||||
|
||||
void
|
||||
eek_container_add_child (EekContainer *container, EekElement *element)
|
||||
{
|
||||
g_return_if_fail (EEK_IS_CONTAINER(container));
|
||||
g_return_if_fail (EEK_IS_ELEMENT(element));
|
||||
return EEK_CONTAINER_GET_CLASS(container)->add_child (container, element);
|
||||
}
|
||||
@ -1,94 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2011 Daiki Ueno <ueno@unixuser.org>
|
||||
* Copyright (C) 2010-2011 Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public License
|
||||
* as published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
* 02110-1301 USA
|
||||
*/
|
||||
|
||||
#if !defined(__EEK_H_INSIDE__) && !defined(EEK_COMPILATION)
|
||||
#error "Only <eek/eek.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#ifndef EEK_CONTAINER_H
|
||||
#define EEK_CONTAINER_H 1
|
||||
|
||||
#include "eek-element.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define EEK_TYPE_CONTAINER (eek_container_get_type())
|
||||
G_DECLARE_DERIVABLE_TYPE (EekContainer, eek_container, EEK, CONTAINER, EekElement)
|
||||
|
||||
/**
|
||||
* EekCallback:
|
||||
* @element: an #EekElement
|
||||
* @user_data: user-supplied data
|
||||
*
|
||||
* The type of the callback function used for iterating over the
|
||||
* children of a container, see eek_container_foreach_child().
|
||||
*/
|
||||
typedef void (*EekCallback) (EekElement *element, gpointer user_data);
|
||||
typedef gint (*EekCompareFunc) (EekElement *element, gpointer user_data);
|
||||
|
||||
/**
|
||||
* EekContainerClass:
|
||||
* @foreach_child: virtual function for iterating over the container's children
|
||||
* @find: virtual function for looking up a child
|
||||
* @child_added: class handler for #EekContainer::child-added
|
||||
* @child_removed: class handler for #EekContainer::child-added
|
||||
*/
|
||||
struct _EekContainerClass
|
||||
{
|
||||
/*< private >*/
|
||||
EekElementClass parent_class;
|
||||
|
||||
void (* add_child) (EekContainer *self,
|
||||
EekElement *element);
|
||||
|
||||
void (* remove_child) (EekContainer *self,
|
||||
EekElement *element);
|
||||
|
||||
/*< public >*/
|
||||
void (* foreach_child) (EekContainer *self,
|
||||
EekCallback callback,
|
||||
gpointer user_data);
|
||||
EekElement *(* find) (EekContainer *self,
|
||||
EekCompareFunc func,
|
||||
gpointer data);
|
||||
|
||||
/* signals */
|
||||
void (* child_added) (EekContainer *self,
|
||||
EekElement *element);
|
||||
void (* child_removed) (EekContainer *self,
|
||||
EekElement *element);
|
||||
/*< private >*/
|
||||
/* padding */
|
||||
gpointer pdummy[24];
|
||||
};
|
||||
|
||||
GType eek_container_get_type (void) G_GNUC_CONST;
|
||||
|
||||
void eek_container_foreach_child (EekContainer *container,
|
||||
EekCallback callback,
|
||||
gpointer user_data);
|
||||
EekElement *eek_container_find (EekContainer *container,
|
||||
EekCompareFunc func,
|
||||
gpointer user_data);
|
||||
void eek_container_add_child (EekContainer *container,
|
||||
EekElement *element);
|
||||
|
||||
G_END_DECLS
|
||||
#endif /* EEK_CONTAINER_H */
|
||||
@ -26,58 +26,28 @@
|
||||
* shall be used to implement #EekKeyboard, #EekSection, or #EekKey.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "eek-element.h"
|
||||
#include "eek-container.h"
|
||||
#include "eek-marshalers.h"
|
||||
|
||||
enum {
|
||||
PROP_0,
|
||||
PROP_NAME,
|
||||
PROP_BOUNDS,
|
||||
PROP_GROUP,
|
||||
PROP_LEVEL,
|
||||
PROP_LAST
|
||||
};
|
||||
|
||||
enum {
|
||||
SYMBOL_INDEX_CHANGED,
|
||||
LAST_SIGNAL
|
||||
};
|
||||
|
||||
static guint signals[LAST_SIGNAL] = { 0, };
|
||||
|
||||
typedef struct _EekElementPrivate
|
||||
{
|
||||
gchar *name;
|
||||
EekBounds bounds;
|
||||
EekElement *parent;
|
||||
gint group;
|
||||
gint level;
|
||||
} EekElementPrivate;
|
||||
|
||||
G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (EekElement, eek_element, G_TYPE_OBJECT)
|
||||
|
||||
static void
|
||||
eek_element_real_symbol_index_changed (EekElement *self,
|
||||
gint group,
|
||||
gint level)
|
||||
{
|
||||
// g_debug ("symbol-index-changed");
|
||||
}
|
||||
|
||||
static void
|
||||
eek_element_finalize (GObject *object)
|
||||
{
|
||||
EekElement *self = EEK_ELEMENT (object);
|
||||
EekElementPrivate *priv = eek_element_get_instance_private (self);
|
||||
|
||||
g_free (priv->name);
|
||||
G_OBJECT_CLASS (eek_element_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
@ -90,18 +60,9 @@ eek_element_set_property (GObject *object,
|
||||
EekElement *element = EEK_ELEMENT(object);
|
||||
|
||||
switch (prop_id) {
|
||||
case PROP_NAME:
|
||||
eek_element_set_name (element,
|
||||
g_value_dup_string (value));
|
||||
break;
|
||||
case PROP_BOUNDS:
|
||||
eek_element_set_bounds (element, g_value_get_boxed (value));
|
||||
break;
|
||||
case PROP_GROUP:
|
||||
eek_element_set_group (element, g_value_get_int (value));
|
||||
break;
|
||||
case PROP_LEVEL:
|
||||
eek_element_set_level (element, g_value_get_int (value));
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
@ -118,19 +79,10 @@ eek_element_get_property (GObject *object,
|
||||
EekBounds bounds;
|
||||
|
||||
switch (prop_id) {
|
||||
case PROP_NAME:
|
||||
g_value_set_string (value, eek_element_get_name (element));
|
||||
break;
|
||||
case PROP_BOUNDS:
|
||||
eek_element_get_bounds (element, &bounds);
|
||||
g_value_set_boxed (value, &bounds);
|
||||
break;
|
||||
case PROP_GROUP:
|
||||
g_value_set_int (value, eek_element_get_group (element));
|
||||
break;
|
||||
case PROP_LEVEL:
|
||||
g_value_set_int (value, eek_element_get_level (element));
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
@ -144,26 +96,10 @@ eek_element_class_init (EekElementClass *klass)
|
||||
GParamSpec *pspec;
|
||||
|
||||
/* signals */
|
||||
klass->symbol_index_changed = eek_element_real_symbol_index_changed;
|
||||
|
||||
gobject_class->set_property = eek_element_set_property;
|
||||
gobject_class->get_property = eek_element_get_property;
|
||||
gobject_class->finalize = eek_element_finalize;
|
||||
|
||||
/**
|
||||
* EekElement:name:
|
||||
*
|
||||
* The name of #EekElement.
|
||||
*/
|
||||
pspec = g_param_spec_string ("name",
|
||||
"Name",
|
||||
"Name",
|
||||
NULL,
|
||||
G_PARAM_READWRITE);
|
||||
g_object_class_install_property (gobject_class,
|
||||
PROP_NAME,
|
||||
pspec);
|
||||
|
||||
/**
|
||||
* EekElement:bounds:
|
||||
*
|
||||
@ -177,149 +113,12 @@ eek_element_class_init (EekElementClass *klass)
|
||||
g_object_class_install_property (gobject_class,
|
||||
PROP_BOUNDS,
|
||||
pspec);
|
||||
|
||||
/**
|
||||
* EekElement:group:
|
||||
*
|
||||
* The group value of the symbol index of #EekElement.
|
||||
*/
|
||||
pspec = g_param_spec_int ("group",
|
||||
"Group",
|
||||
"Group value of the symbol index",
|
||||
-1, G_MAXINT, -1,
|
||||
G_PARAM_READWRITE);
|
||||
g_object_class_install_property (gobject_class,
|
||||
PROP_GROUP,
|
||||
pspec);
|
||||
|
||||
/**
|
||||
* EekElement:level:
|
||||
*
|
||||
* The level value of the symbol index of #EekElement.
|
||||
*/
|
||||
pspec = g_param_spec_int ("level",
|
||||
"Level",
|
||||
"Level value of the symbol index",
|
||||
-1, G_MAXINT, -1,
|
||||
G_PARAM_READWRITE);
|
||||
g_object_class_install_property (gobject_class,
|
||||
PROP_LEVEL,
|
||||
pspec);
|
||||
|
||||
/**
|
||||
* EekElement::symbol-index-changed:
|
||||
* @element: an #EekElement
|
||||
* @group: row index of the symbol matrix of keys on @element
|
||||
* @level: column index of the symbol matrix of keys on @element
|
||||
*
|
||||
* The ::symbol-index-changed signal is emitted each time the
|
||||
* global configuration of group/level index changes.
|
||||
*/
|
||||
signals[SYMBOL_INDEX_CHANGED] =
|
||||
g_signal_new (I_("symbol-index-changed"),
|
||||
G_TYPE_FROM_CLASS(gobject_class),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET(EekElementClass, symbol_index_changed),
|
||||
NULL,
|
||||
NULL,
|
||||
_eek_marshal_VOID__INT_INT,
|
||||
G_TYPE_NONE,
|
||||
2,
|
||||
G_TYPE_INT,
|
||||
G_TYPE_INT);
|
||||
}
|
||||
|
||||
static void
|
||||
eek_element_init (EekElement *self)
|
||||
{
|
||||
EekElementPrivate *priv = eek_element_get_instance_private (self);
|
||||
|
||||
priv->group = -1;
|
||||
priv->level = -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* eek_element_set_parent:
|
||||
* @element: an #EekElement
|
||||
* @parent: (allow-none): an #EekElement or %NULL
|
||||
*
|
||||
* Set the parent of @element to @parent.
|
||||
*/
|
||||
void
|
||||
eek_element_set_parent (EekElement *element,
|
||||
EekElement *parent)
|
||||
{
|
||||
g_return_if_fail (EEK_IS_ELEMENT(element));
|
||||
g_return_if_fail (parent == NULL || EEK_IS_ELEMENT(parent));
|
||||
|
||||
EekElementPrivate *priv = eek_element_get_instance_private (element);
|
||||
|
||||
if (priv->parent == parent)
|
||||
return;
|
||||
|
||||
if (priv->parent != NULL) {
|
||||
/* release self-reference acquired when setting parent */
|
||||
g_object_unref (element);
|
||||
}
|
||||
|
||||
if (parent != NULL) {
|
||||
g_object_ref (element);
|
||||
}
|
||||
|
||||
priv->parent = parent;
|
||||
}
|
||||
|
||||
/**
|
||||
* eek_element_get_parent:
|
||||
* @element: an #EekElement
|
||||
*
|
||||
* Get the parent of @element.
|
||||
* Returns: an #EekElement if the parent is set
|
||||
*/
|
||||
EekElement *
|
||||
eek_element_get_parent (EekElement *element)
|
||||
{
|
||||
g_return_val_if_fail (EEK_IS_ELEMENT(element), NULL);
|
||||
|
||||
EekElementPrivate *priv = eek_element_get_instance_private (element);
|
||||
|
||||
return priv->parent;
|
||||
}
|
||||
|
||||
/**
|
||||
* eek_element_set_name:
|
||||
* @element: an #EekElement
|
||||
* @name: name of @element
|
||||
*
|
||||
* Set the name of @element to @name.
|
||||
*/
|
||||
void
|
||||
eek_element_set_name (EekElement *element,
|
||||
const gchar *name)
|
||||
{
|
||||
g_return_if_fail (EEK_IS_ELEMENT(element));
|
||||
|
||||
EekElementPrivate *priv = eek_element_get_instance_private (element);
|
||||
|
||||
g_free (priv->name);
|
||||
priv->name = g_strdup (name);
|
||||
}
|
||||
|
||||
/**
|
||||
* eek_element_get_name:
|
||||
* @element: an #EekElement
|
||||
*
|
||||
* Get the name of @element.
|
||||
* Returns: the name of @element or NULL when the name is not set
|
||||
*/
|
||||
const gchar *
|
||||
eek_element_get_name (EekElement *element)
|
||||
{
|
||||
g_return_val_if_fail (EEK_IS_ELEMENT(element), NULL);
|
||||
|
||||
EekElementPrivate *priv = eek_element_get_instance_private (element);
|
||||
|
||||
return priv->name;
|
||||
(void)self;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -362,211 +161,3 @@ eek_element_get_bounds (EekElement *element,
|
||||
|
||||
memcpy (bounds, &priv->bounds, sizeof(EekBounds));
|
||||
}
|
||||
|
||||
/**
|
||||
* eek_element_get_absolute_position:
|
||||
* @element: an #EekElement
|
||||
* @x: pointer where the X coordinate of @element will be stored
|
||||
* @y: pointer where the Y coordinate of @element will be stored
|
||||
*
|
||||
* Compute the absolute position of @element.
|
||||
*/
|
||||
void
|
||||
eek_element_get_absolute_position (EekElement *element,
|
||||
gdouble *x,
|
||||
gdouble *y)
|
||||
{
|
||||
EekBounds bounds;
|
||||
gdouble ax = 0.0, ay = 0.0;
|
||||
|
||||
do {
|
||||
eek_element_get_bounds (element, &bounds);
|
||||
ax += bounds.x;
|
||||
ay += bounds.y;
|
||||
} while ((element = eek_element_get_parent (element)) != NULL);
|
||||
*x = ax;
|
||||
*y = ay;
|
||||
}
|
||||
|
||||
/**
|
||||
* eek_element_set_position:
|
||||
* @element: an #EekElement
|
||||
* @x: X coordinate of top left corner
|
||||
* @y: Y coordinate of top left corner
|
||||
*
|
||||
* Set the relative position of @element.
|
||||
*/
|
||||
void
|
||||
eek_element_set_position (EekElement *element,
|
||||
gdouble x,
|
||||
gdouble y)
|
||||
{
|
||||
EekBounds bounds;
|
||||
|
||||
eek_element_get_bounds (element, &bounds);
|
||||
bounds.x = x;
|
||||
bounds.y = y;
|
||||
eek_element_set_bounds (element, &bounds);
|
||||
}
|
||||
|
||||
/**
|
||||
* eek_element_set_size:
|
||||
* @element: an #EekElement
|
||||
* @width: width of @element
|
||||
* @height: height of @element
|
||||
*
|
||||
* Set the size of @element.
|
||||
*/
|
||||
void
|
||||
eek_element_set_size (EekElement *element,
|
||||
gdouble width,
|
||||
gdouble height)
|
||||
{
|
||||
EekBounds bounds;
|
||||
|
||||
eek_element_get_bounds (element, &bounds);
|
||||
bounds.width = width;
|
||||
bounds.height = height;
|
||||
eek_element_set_bounds (element, &bounds);
|
||||
}
|
||||
|
||||
/**
|
||||
* eek_element_set_symbol_index:
|
||||
* @element: an #EekElement
|
||||
* @group: row index of the symbol matrix
|
||||
* @level: column index of the symbol matrix
|
||||
*
|
||||
* Set the default index of the symbol matrices of @element. The
|
||||
* setting affects the child, if child does not have the index set, as
|
||||
* well as this element. To unset, pass -1 as group/level.
|
||||
*/
|
||||
void
|
||||
eek_element_set_symbol_index (EekElement *element,
|
||||
gint group,
|
||||
gint level)
|
||||
{
|
||||
gboolean emit_signal;
|
||||
|
||||
g_return_if_fail (EEK_IS_ELEMENT(element));
|
||||
|
||||
emit_signal = group != eek_element_get_group (element) ||
|
||||
level != eek_element_get_level (element);
|
||||
|
||||
eek_element_set_group (element, group);
|
||||
eek_element_set_level (element, level);
|
||||
|
||||
if (emit_signal)
|
||||
g_signal_emit (element, signals[SYMBOL_INDEX_CHANGED], 0, group, level);
|
||||
}
|
||||
|
||||
/**
|
||||
* eek_element_get_symbol_index:
|
||||
* @element: an #EekElement
|
||||
* @group: a pointer where the group value of the symbol index will be stored
|
||||
* @level: a pointer where the level value of the symbol index will be stored
|
||||
*
|
||||
* Get the default index of the symbol matrices of @element.
|
||||
* If the index is not set, -1 will be returned.
|
||||
*/
|
||||
void
|
||||
eek_element_get_symbol_index (EekElement *element,
|
||||
gint *group,
|
||||
gint *level)
|
||||
{
|
||||
g_return_if_fail (EEK_IS_ELEMENT(element));
|
||||
g_return_if_fail (group != NULL || level != NULL);
|
||||
if (group != NULL)
|
||||
*group = eek_element_get_group (element);
|
||||
if (level != NULL)
|
||||
*level = eek_element_get_level (element);
|
||||
}
|
||||
|
||||
/**
|
||||
* eek_element_set_group:
|
||||
* @element: an #EekElement
|
||||
* @group: group index of @element
|
||||
*
|
||||
* Set the group value of the default symbol index of @element. To
|
||||
* unset, pass -1 as @group.
|
||||
*
|
||||
* See also: eek_element_set_symbol_index()
|
||||
*/
|
||||
void
|
||||
eek_element_set_group (EekElement *element,
|
||||
gint group)
|
||||
{
|
||||
g_return_if_fail (EEK_IS_ELEMENT(element));
|
||||
|
||||
EekElementPrivate *priv = eek_element_get_instance_private (element);
|
||||
|
||||
if (priv->group != group) {
|
||||
priv->group = group;
|
||||
g_object_notify (G_OBJECT(element), "group");
|
||||
g_signal_emit (element, signals[SYMBOL_INDEX_CHANGED], 0,
|
||||
group, priv->level);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* eek_element_set_level:
|
||||
* @element: an #EekElement
|
||||
* @level: level index of @element
|
||||
*
|
||||
* Set the level value of the default symbol index of @element. To
|
||||
* unset, pass -1 as @level.
|
||||
*
|
||||
* See also: eek_element_set_symbol_index()
|
||||
*/
|
||||
void
|
||||
eek_element_set_level (EekElement *element,
|
||||
gint level)
|
||||
{
|
||||
g_return_if_fail (EEK_IS_ELEMENT(element));
|
||||
|
||||
EekElementPrivate *priv = eek_element_get_instance_private (element);
|
||||
|
||||
if (priv->level != level) {
|
||||
priv->level = level;
|
||||
g_object_notify (G_OBJECT(element), "level");
|
||||
g_signal_emit (element, signals[SYMBOL_INDEX_CHANGED], 0,
|
||||
priv->group, level);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* eek_element_get_group:
|
||||
* @element: an #EekElement
|
||||
*
|
||||
* Return the group value of the default symbol index of @element.
|
||||
* If the value is not set, -1 will be returned.
|
||||
*
|
||||
* See also: eek_element_get_symbol_index()
|
||||
*/
|
||||
gint
|
||||
eek_element_get_group (EekElement *element)
|
||||
{
|
||||
g_return_val_if_fail (EEK_IS_ELEMENT(element), -1);
|
||||
|
||||
EekElementPrivate *priv = eek_element_get_instance_private (element);
|
||||
|
||||
return priv->group;
|
||||
}
|
||||
|
||||
/**
|
||||
* eek_element_get_level:
|
||||
* @element: an #EekElement
|
||||
*
|
||||
* Return the level value of the default symbol index of @element.
|
||||
* If the value is not set, -1 will be returned.
|
||||
*
|
||||
* See also: eek_element_get_symbol_index()
|
||||
*/
|
||||
gint
|
||||
eek_element_get_level (EekElement *element)
|
||||
{
|
||||
g_return_val_if_fail (EEK_IS_ELEMENT(element), -1);
|
||||
|
||||
EekElementPrivate *priv = eek_element_get_instance_private (element);
|
||||
|
||||
return priv->level;
|
||||
}
|
||||
|
||||
@ -36,18 +36,10 @@ struct _EekElementClass
|
||||
{
|
||||
/*< private >*/
|
||||
GObjectClass parent_class;
|
||||
|
||||
/* signals */
|
||||
void (* symbol_index_changed) (EekElement *self,
|
||||
gint group,
|
||||
gint level);
|
||||
};
|
||||
|
||||
GType eek_element_get_type (void) G_GNUC_CONST;
|
||||
|
||||
void eek_element_set_parent (EekElement *element,
|
||||
EekElement *parent);
|
||||
EekElement *eek_element_get_parent (EekElement *element);
|
||||
void eek_element_set_name (EekElement *element,
|
||||
const gchar *name);
|
||||
|
||||
@ -59,29 +51,5 @@ void eek_element_set_bounds (EekElement *element,
|
||||
void eek_element_get_bounds (EekElement *element,
|
||||
EekBounds *bounds);
|
||||
|
||||
void eek_element_set_position (EekElement *element,
|
||||
gdouble x,
|
||||
gdouble y);
|
||||
void eek_element_set_size (EekElement *element,
|
||||
gdouble width,
|
||||
gdouble height);
|
||||
|
||||
void eek_element_get_absolute_position (EekElement *element,
|
||||
gdouble *x,
|
||||
gdouble *y);
|
||||
|
||||
void eek_element_set_symbol_index (EekElement *element,
|
||||
gint group,
|
||||
gint level);
|
||||
void eek_element_get_symbol_index (EekElement *element,
|
||||
gint *group,
|
||||
gint *level);
|
||||
void eek_element_set_group (EekElement *element,
|
||||
gint group);
|
||||
void eek_element_set_level (EekElement *element,
|
||||
gint level);
|
||||
gint eek_element_get_group (EekElement *element);
|
||||
gint eek_element_get_level (EekElement *element);
|
||||
|
||||
G_END_DECLS
|
||||
#endif /* EEK_ELEMENT_H */
|
||||
|
||||
@ -23,9 +23,7 @@
|
||||
* @short_description: a #GtkWidget displaying #EekKeyboard
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
|
||||
#ifdef HAVE_LIBCANBERRA
|
||||
#include <canberra-gtk.h>
|
||||
@ -34,16 +32,14 @@
|
||||
#include <math.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "eek-gtk-keyboard.h"
|
||||
#include "eek-gtk-renderer.h"
|
||||
#include "eek-renderer.h"
|
||||
#include "eek-keyboard.h"
|
||||
#include "eek-section.h"
|
||||
#include "eek-key.h"
|
||||
#include "eek-symbol.h"
|
||||
#include "src/symbol.h"
|
||||
|
||||
#include "eek-gtk-keyboard.h"
|
||||
|
||||
enum {
|
||||
PROP_0,
|
||||
PROP_KEYBOARD,
|
||||
PROP_LAST
|
||||
};
|
||||
|
||||
@ -56,37 +52,25 @@ enum {
|
||||
typedef struct _EekGtkKeyboardPrivate
|
||||
{
|
||||
EekRenderer *renderer;
|
||||
EekKeyboard *keyboard;
|
||||
gulong key_locked_handler;
|
||||
gulong key_unlocked_handler;
|
||||
gulong symbol_index_changed_handler;
|
||||
EekTheme *theme;
|
||||
LevelKeyboard *keyboard;
|
||||
GtkCssProvider *css_provider;
|
||||
GtkStyleContext *scontext;
|
||||
|
||||
GdkEventSequence *sequence; // unowned reference
|
||||
} EekGtkKeyboardPrivate;
|
||||
|
||||
G_DEFINE_TYPE_WITH_PRIVATE (EekGtkKeyboard, eek_gtk_keyboard, GTK_TYPE_DRAWING_AREA)
|
||||
|
||||
static void on_key_pressed (EekKey *key,
|
||||
static void on_button_pressed (struct squeek_button *button, struct squeek_view *view,
|
||||
EekGtkKeyboard *self);
|
||||
static void on_key_released (EekKey *key,
|
||||
static void on_button_released (struct squeek_button *button,
|
||||
struct squeek_view *view,
|
||||
EekGtkKeyboard *self);
|
||||
static void on_key_locked (EekKeyboard *keyboard,
|
||||
EekKey *key,
|
||||
gpointer user_data);
|
||||
static void on_key_unlocked (EekKeyboard *keyboard,
|
||||
EekKey *key,
|
||||
gpointer user_data);
|
||||
static void on_symbol_index_changed (EekKeyboard *keyboard,
|
||||
gint group,
|
||||
gint level,
|
||||
gpointer user_data);
|
||||
static void render_pressed_key (GtkWidget *widget,
|
||||
EekKey *key);
|
||||
static void render_locked_key (GtkWidget *widget,
|
||||
EekKey *key);
|
||||
static void render_released_key (GtkWidget *widget,
|
||||
EekKey *key);
|
||||
static void render_pressed_button (GtkWidget *widget, struct button_place *place);
|
||||
static void render_locked_button (GtkWidget *widget,
|
||||
struct button_place *place);
|
||||
static void render_released_button (GtkWidget *widget,
|
||||
struct squeek_button *button);
|
||||
|
||||
static void
|
||||
eek_gtk_keyboard_real_realize (GtkWidget *self)
|
||||
@ -109,38 +93,45 @@ eek_gtk_keyboard_real_draw (GtkWidget *self,
|
||||
EekGtkKeyboardPrivate *priv =
|
||||
eek_gtk_keyboard_get_instance_private (EEK_GTK_KEYBOARD (self));
|
||||
GtkAllocation allocation;
|
||||
GList *list, *head;
|
||||
|
||||
gtk_widget_get_allocation (self, &allocation);
|
||||
|
||||
if (!priv->renderer) {
|
||||
PangoContext *pcontext;
|
||||
PangoContext *pcontext = gtk_widget_get_pango_context (self);
|
||||
|
||||
pcontext = gtk_widget_get_pango_context (self);
|
||||
priv->renderer = eek_gtk_renderer_new (priv->keyboard, pcontext, self);
|
||||
if (priv->theme)
|
||||
eek_renderer_set_theme (priv->renderer, priv->theme);
|
||||
priv->renderer = eek_renderer_new (priv->keyboard, pcontext, priv->scontext);
|
||||
|
||||
eek_renderer_set_allocation_size (priv->renderer,
|
||||
allocation.width,
|
||||
allocation.height);
|
||||
eek_renderer_set_scale_factor (priv->renderer,
|
||||
gtk_widget_get_scale_factor (self));
|
||||
}
|
||||
|
||||
eek_renderer_render_keyboard (priv->renderer, cr);
|
||||
|
||||
struct squeek_view *view = priv->keyboard->views[priv->keyboard->level];
|
||||
|
||||
/* redraw pressed key */
|
||||
list = eek_keyboard_get_pressed_keys (priv->keyboard);
|
||||
for (head = list; head; head = g_list_next (head)) {
|
||||
render_pressed_key (self, head->data);
|
||||
const GList *list = priv->keyboard->pressed_buttons;
|
||||
for (const GList *head = list; head; head = g_list_next (head)) {
|
||||
struct button_place place = squeek_view_find_key(
|
||||
view, squeek_button_get_key(head->data)
|
||||
);
|
||||
if (place.button)
|
||||
render_pressed_button (self, &place);
|
||||
}
|
||||
g_list_free (list);
|
||||
|
||||
/* redraw locked key */
|
||||
list = eek_keyboard_get_locked_keys (priv->keyboard);
|
||||
for (head = list; head; head = g_list_next (head)) {
|
||||
render_locked_key (self, ((EekModifierKey *)head->data)->key);
|
||||
list = priv->keyboard->locked_buttons;
|
||||
for (const GList *head = list; head; head = g_list_next (head)) {
|
||||
struct button_place place = squeek_view_find_key(
|
||||
view, squeek_button_get_key(
|
||||
((EekModifierKey *)head->data)->button
|
||||
)
|
||||
);
|
||||
if (place.button)
|
||||
render_locked_button (self, &place);
|
||||
}
|
||||
g_list_free (list);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
@ -162,50 +153,63 @@ eek_gtk_keyboard_real_size_allocate (GtkWidget *self,
|
||||
}
|
||||
|
||||
static void depress(EekGtkKeyboard *self,
|
||||
gdouble x, gdouble y, guint32 time) {
|
||||
gdouble x, gdouble y, guint32 time)
|
||||
{
|
||||
EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (self);
|
||||
EekKey *key = eek_renderer_find_key_by_position (priv->renderer, x, y);
|
||||
if (key) {
|
||||
eek_keyboard_press_key(priv->keyboard, key, time);
|
||||
on_key_pressed(key, self);
|
||||
struct squeek_view *view = level_keyboard_current(priv->keyboard);
|
||||
struct squeek_button *button = eek_renderer_find_button_by_position (priv->renderer, view, x, y);
|
||||
|
||||
if (button) {
|
||||
eek_keyboard_press_button(priv->keyboard, button, time);
|
||||
on_button_pressed(button, view, self);
|
||||
}
|
||||
}
|
||||
|
||||
static void drag(EekGtkKeyboard *self,
|
||||
gdouble x, gdouble y, guint32 time) {
|
||||
EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (self);
|
||||
EekKey *key = eek_renderer_find_key_by_position (priv->renderer, x, y);
|
||||
struct squeek_view *view = level_keyboard_current(priv->keyboard);
|
||||
struct squeek_button *button = eek_renderer_find_button_by_position (priv->renderer, view, x, y);
|
||||
GList *list, *head;
|
||||
|
||||
if (key) {
|
||||
GList *list, *head;
|
||||
list = g_list_copy(priv->keyboard->pressed_buttons);
|
||||
|
||||
if (button) {
|
||||
gboolean found = FALSE;
|
||||
|
||||
list = eek_keyboard_get_pressed_keys (priv->keyboard);
|
||||
for (head = list; head; head = g_list_next (head)) {
|
||||
if (head->data == key)
|
||||
if (head->data == button) {
|
||||
found = TRUE;
|
||||
else {
|
||||
eek_keyboard_release_key(priv->keyboard, EEK_KEY(head->data), time);
|
||||
on_key_released(key, self);
|
||||
} else {
|
||||
eek_keyboard_release_button(priv->keyboard, head->data, time);
|
||||
on_button_released(button, view, self);
|
||||
}
|
||||
}
|
||||
g_list_free (list);
|
||||
|
||||
if (!found) {
|
||||
eek_keyboard_press_key(priv->keyboard, key, time);
|
||||
on_key_pressed(key, self);
|
||||
eek_keyboard_press_button(priv->keyboard, button, time);
|
||||
on_button_pressed(button, view, self);
|
||||
}
|
||||
} else {
|
||||
for (head = list; head; head = g_list_next (head)) {
|
||||
eek_keyboard_release_button(priv->keyboard, head->data, time);
|
||||
on_button_released(head->data, view, self);
|
||||
}
|
||||
g_list_free (list);
|
||||
}
|
||||
}
|
||||
|
||||
static void release(EekGtkKeyboard *self, guint32 time) {
|
||||
EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (self);
|
||||
|
||||
GList *list = eek_keyboard_get_pressed_keys (priv->keyboard);
|
||||
struct squeek_view *view = level_keyboard_current(priv->keyboard);
|
||||
|
||||
GList *list = g_list_copy(priv->keyboard->pressed_buttons);
|
||||
for (GList *head = list; head; head = g_list_next (head)) {
|
||||
EekKey *key = EEK_KEY(head->data);
|
||||
eek_keyboard_release_key(priv->keyboard, key, time);
|
||||
on_key_released(key, self);
|
||||
struct squeek_button *button = head->data;
|
||||
eek_keyboard_release_button(priv->keyboard, button, time);
|
||||
on_button_released(button, view, self);
|
||||
}
|
||||
g_list_free (list);
|
||||
}
|
||||
@ -288,7 +292,7 @@ eek_gtk_keyboard_real_unmap (GtkWidget *self)
|
||||
elements, so that the default handler of
|
||||
EekKeyboard::key-released signal can remove elements from its
|
||||
internal copy */
|
||||
list = eek_keyboard_get_pressed_keys (priv->keyboard);
|
||||
list = g_list_copy(priv->keyboard->pressed_buttons);
|
||||
for (head = list; head; head = g_list_next (head)) {
|
||||
g_log("squeek", G_LOG_LEVEL_DEBUG, "emit EekKey released");
|
||||
g_signal_emit_by_name (head->data, "released");
|
||||
@ -308,15 +312,15 @@ eek_gtk_keyboard_real_query_tooltip (GtkWidget *widget,
|
||||
{
|
||||
EekGtkKeyboard *self = EEK_GTK_KEYBOARD (widget);
|
||||
EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (self);
|
||||
struct squeek_view *view = level_keyboard_current(priv->keyboard);
|
||||
|
||||
EekKey *key;
|
||||
|
||||
key = eek_renderer_find_key_by_position (priv->renderer,
|
||||
(gdouble)x,
|
||||
(gdouble)y);
|
||||
if (key) {
|
||||
EekSymbol *symbol = eek_key_get_symbol (key);
|
||||
const gchar *text = eek_symbol_get_tooltip (symbol);
|
||||
struct squeek_button *button = eek_renderer_find_button_by_position (priv->renderer,
|
||||
view,
|
||||
(gdouble)x,
|
||||
(gdouble)y);
|
||||
if (button) {
|
||||
//struct squeek_symbol *symbol = eek_key_get_symbol_at_index(key, 0, priv->keyboard->level);
|
||||
const gchar *text = NULL; // FIXME
|
||||
if (text) {
|
||||
gtk_tooltip_set_text (tooltip, text);
|
||||
return TRUE;
|
||||
@ -325,37 +329,13 @@ eek_gtk_keyboard_real_query_tooltip (GtkWidget *widget,
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
eek_gtk_keyboard_set_keyboard (EekGtkKeyboard *self,
|
||||
EekKeyboard *keyboard)
|
||||
{
|
||||
EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (self);
|
||||
priv->keyboard = g_object_ref (keyboard);
|
||||
|
||||
priv->key_locked_handler =
|
||||
g_signal_connect (priv->keyboard, "key-locked",
|
||||
G_CALLBACK(on_key_locked), self);
|
||||
priv->key_unlocked_handler =
|
||||
g_signal_connect (priv->keyboard, "key-unlocked",
|
||||
G_CALLBACK(on_key_unlocked), self);
|
||||
priv->symbol_index_changed_handler =
|
||||
g_signal_connect (priv->keyboard, "symbol-index-changed",
|
||||
G_CALLBACK(on_symbol_index_changed), self);
|
||||
}
|
||||
|
||||
static void
|
||||
eek_gtk_keyboard_set_property (GObject *object,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
EekKeyboard *keyboard;
|
||||
|
||||
switch (prop_id) {
|
||||
case PROP_KEYBOARD:
|
||||
keyboard = g_value_get_object (value);
|
||||
eek_gtk_keyboard_set_keyboard (EEK_GTK_KEYBOARD(object), keyboard);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
@ -374,37 +354,18 @@ eek_gtk_keyboard_dispose (GObject *object)
|
||||
}
|
||||
|
||||
if (priv->keyboard) {
|
||||
if (g_signal_handler_is_connected (priv->keyboard,
|
||||
priv->key_locked_handler))
|
||||
g_signal_handler_disconnect (priv->keyboard,
|
||||
priv->key_locked_handler);
|
||||
if (g_signal_handler_is_connected (priv->keyboard,
|
||||
priv->key_unlocked_handler))
|
||||
g_signal_handler_disconnect (priv->keyboard,
|
||||
priv->key_unlocked_handler);
|
||||
if (g_signal_handler_is_connected (priv->keyboard,
|
||||
priv->symbol_index_changed_handler))
|
||||
g_signal_handler_disconnect (priv->keyboard,
|
||||
priv->symbol_index_changed_handler);
|
||||
|
||||
GList *list, *head;
|
||||
|
||||
list = eek_keyboard_get_pressed_keys (priv->keyboard);
|
||||
list = g_list_copy(priv->keyboard->pressed_buttons);
|
||||
for (head = list; head; head = g_list_next (head)) {
|
||||
g_log("squeek", G_LOG_LEVEL_DEBUG, "emit EekKey pressed");
|
||||
g_signal_emit_by_name (head->data, "released", priv->keyboard);
|
||||
g_signal_emit_by_name (head->data, "released", level_keyboard_current(priv->keyboard));
|
||||
}
|
||||
g_list_free (list);
|
||||
|
||||
g_object_unref (priv->keyboard);
|
||||
priv->keyboard = NULL;
|
||||
}
|
||||
|
||||
if (priv->theme) {
|
||||
g_object_unref (priv->theme);
|
||||
priv->theme = NULL;
|
||||
}
|
||||
|
||||
G_OBJECT_CLASS (eek_gtk_keyboard_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
@ -413,7 +374,6 @@ eek_gtk_keyboard_class_init (EekGtkKeyboardClass *klass)
|
||||
{
|
||||
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||
GParamSpec *pspec;
|
||||
|
||||
widget_class->realize = eek_gtk_keyboard_real_realize;
|
||||
widget_class->unmap = eek_gtk_keyboard_real_unmap;
|
||||
@ -431,21 +391,25 @@ eek_gtk_keyboard_class_init (EekGtkKeyboardClass *klass)
|
||||
|
||||
gobject_class->set_property = eek_gtk_keyboard_set_property;
|
||||
gobject_class->dispose = eek_gtk_keyboard_dispose;
|
||||
|
||||
pspec = g_param_spec_object ("keyboard",
|
||||
"Keyboard",
|
||||
"Keyboard",
|
||||
EEK_TYPE_KEYBOARD,
|
||||
G_PARAM_CONSTRUCT_ONLY | G_PARAM_WRITABLE);
|
||||
g_object_class_install_property (gobject_class,
|
||||
PROP_KEYBOARD,
|
||||
pspec);
|
||||
}
|
||||
|
||||
static void
|
||||
eek_gtk_keyboard_init (EekGtkKeyboard *self)
|
||||
{
|
||||
/* void */
|
||||
EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (self);
|
||||
|
||||
/* Create a default CSS provider and load a style sheet */
|
||||
priv->css_provider = gtk_css_provider_new ();
|
||||
gtk_css_provider_load_from_resource (priv->css_provider,
|
||||
"/sm/puri/squeekboard/style.css");
|
||||
|
||||
/* Apply the style to the widget */
|
||||
priv->scontext = gtk_widget_get_style_context (GTK_WIDGET(self));
|
||||
gtk_style_context_add_class (priv->scontext, "keyboard");
|
||||
gtk_style_context_add_provider (priv->scontext,
|
||||
GTK_STYLE_PROVIDER(priv->css_provider),
|
||||
GTK_STYLE_PROVIDER_PRIORITY_USER);
|
||||
gtk_style_context_set_state (priv->scontext, GTK_STATE_FLAG_NORMAL);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -456,179 +420,76 @@ eek_gtk_keyboard_init (EekGtkKeyboard *self)
|
||||
* Returns: a #GtkWidget
|
||||
*/
|
||||
GtkWidget *
|
||||
eek_gtk_keyboard_new (EekKeyboard *keyboard)
|
||||
eek_gtk_keyboard_new (LevelKeyboard *keyboard)
|
||||
{
|
||||
return g_object_new (EEK_TYPE_GTK_KEYBOARD, "keyboard", keyboard, NULL);
|
||||
EekGtkKeyboard *ret = EEK_GTK_KEYBOARD(g_object_new (EEK_TYPE_GTK_KEYBOARD, NULL));
|
||||
EekGtkKeyboardPrivate *priv = (EekGtkKeyboardPrivate*)eek_gtk_keyboard_get_instance_private (ret);
|
||||
priv->keyboard = keyboard;
|
||||
return GTK_WIDGET(ret);
|
||||
}
|
||||
|
||||
static void
|
||||
magnify_bounds (GtkWidget *self,
|
||||
EekBounds *bounds,
|
||||
EekBounds *large_bounds,
|
||||
gdouble scale)
|
||||
{
|
||||
GtkAllocation allocation;
|
||||
gdouble x, y;
|
||||
|
||||
g_assert (scale >= 1.0);
|
||||
|
||||
gtk_widget_get_allocation (self, &allocation);
|
||||
|
||||
large_bounds->width = bounds->width * scale;
|
||||
large_bounds->height = bounds->height * scale;
|
||||
|
||||
x = bounds->x - (large_bounds->width - bounds->width) / 2;
|
||||
y = bounds->y - large_bounds->height;
|
||||
|
||||
large_bounds->x = CLAMP(x, 0, allocation.width - large_bounds->width);
|
||||
large_bounds->y = CLAMP(y, 0, allocation.height - large_bounds->height);
|
||||
}
|
||||
|
||||
/*
|
||||
* Alleviate the asymmetry between drawing a pressed key and a released key,
|
||||
* and consistently draw to the exact same area.
|
||||
*
|
||||
* By saving the dirty rectangle we can limit drawing of the backbuffer to
|
||||
* the screen as well, eg gdk_window_invalidate_rect() instead of
|
||||
* gtk_widget_queue_draw() which redraws the entire widget.
|
||||
*
|
||||
* b1 is mandatory, b2 is optional
|
||||
*/
|
||||
static GdkRectangle
|
||||
clip_bounds_to_dirty_rectangle (cairo_t *cr, EekBounds *b1, EekBounds *b2)
|
||||
{
|
||||
if (b2)
|
||||
cairo_rectangle (cr, b2->x, b2->y, b2->width, b2->height);
|
||||
|
||||
cairo_rectangle (cr, b1->x, b1->y, b1->width, b1->height);
|
||||
cairo_clip (cr);
|
||||
|
||||
/*
|
||||
* save the clipped region to a bounding box so we can limit
|
||||
* the drawing of the backbuffer to the screen to the same area
|
||||
*/
|
||||
cairo_rectangle_t bbox;
|
||||
|
||||
cairo_clip_extents (cr, &bbox.x, &bbox.y, &bbox.width, &bbox.height);
|
||||
|
||||
/* convert double to int, making sure r strictly covers bbox to avoid
|
||||
* artefacts. floor() is unnecessary, ceil() is not */
|
||||
GdkRectangle r = {
|
||||
floor (bbox.x),
|
||||
floor (bbox.y),
|
||||
ceil (bbox.width),
|
||||
ceil (bbox.height)
|
||||
};
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
static void
|
||||
render_pressed_key (GtkWidget *widget,
|
||||
EekKey *key)
|
||||
render_pressed_button (GtkWidget *widget,
|
||||
struct button_place *place)
|
||||
{
|
||||
EekGtkKeyboard *self = EEK_GTK_KEYBOARD (widget);
|
||||
EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (self);
|
||||
EekBounds bounds, large_bounds;
|
||||
|
||||
GdkWindow *window = gtk_widget_get_window (widget);
|
||||
cairo_region_t *region = gdk_window_get_clip_region (window);
|
||||
GdkDrawingContext *context = gdk_window_begin_draw_frame (window, region);
|
||||
cairo_t *cr = gdk_drawing_context_get_cairo_context (context);
|
||||
|
||||
eek_renderer_get_key_bounds (priv->renderer, key, &bounds, TRUE);
|
||||
magnify_bounds (widget, &bounds, &large_bounds, 1.5);
|
||||
|
||||
/*
|
||||
* clip to limit drawing to backbuffer and save clip region to dirty_rect
|
||||
* to limit redrawing of the backbuffer to the same area
|
||||
*/
|
||||
GdkRectangle dirty_rect = clip_bounds_to_dirty_rectangle (cr, &bounds, &large_bounds);
|
||||
|
||||
cairo_save (cr);
|
||||
cairo_translate (cr, bounds.x, bounds.y);
|
||||
eek_renderer_render_key (priv->renderer, cr, key, 1.0, TRUE);
|
||||
cairo_restore (cr);
|
||||
eek_renderer_render_button (priv->renderer, cr, place, 1.0, TRUE);
|
||||
/*
|
||||
cairo_save (cr);
|
||||
cairo_translate (cr, large_bounds.x, large_bounds.y);
|
||||
eek_renderer_render_key (priv->renderer, cr, key, 1.5, TRUE);
|
||||
cairo_restore (cr);
|
||||
*/
|
||||
gdk_window_end_draw_frame (window, context);
|
||||
|
||||
cairo_region_destroy (region);
|
||||
|
||||
/* force immediate drawing of the backbuffer to the screen */
|
||||
gdk_window_invalidate_rect (window, &dirty_rect, FALSE);
|
||||
}
|
||||
|
||||
static void
|
||||
render_locked_key (GtkWidget *widget,
|
||||
EekKey *key)
|
||||
render_locked_button (GtkWidget *widget, struct button_place *place)
|
||||
{
|
||||
EekGtkKeyboard *self = EEK_GTK_KEYBOARD (widget);
|
||||
EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (self);
|
||||
EekBounds bounds;
|
||||
|
||||
GdkWindow *window = gtk_widget_get_window (widget);
|
||||
cairo_region_t *region = gdk_window_get_clip_region (window);
|
||||
GdkDrawingContext *context = gdk_window_begin_draw_frame (window, region);
|
||||
cairo_t *cr = gdk_drawing_context_get_cairo_context (context);
|
||||
|
||||
eek_renderer_get_key_bounds (priv->renderer, key, &bounds, TRUE);
|
||||
|
||||
/*
|
||||
* clip to limit drawing to backbuffer and save clip region to dirty_rect
|
||||
* to limit redrawing of the backbuffer to the same area
|
||||
*/
|
||||
GdkRectangle dirty_rect = clip_bounds_to_dirty_rectangle (cr, &bounds, NULL);
|
||||
|
||||
cairo_translate (cr, bounds.x, bounds.y);
|
||||
eek_renderer_render_key (priv->renderer, cr, key, 1.0, TRUE);
|
||||
eek_renderer_render_button (priv->renderer, cr, place, 1.0, TRUE);
|
||||
|
||||
gdk_window_end_draw_frame (window, context);
|
||||
|
||||
cairo_region_destroy (region);
|
||||
|
||||
/* force immediate drawing of the backbuffer to the screen */
|
||||
gdk_window_invalidate_rect (window, &dirty_rect, FALSE);
|
||||
}
|
||||
|
||||
static void
|
||||
render_released_key (GtkWidget *widget,
|
||||
EekKey *key)
|
||||
render_released_button (GtkWidget *widget,
|
||||
struct squeek_button *button)
|
||||
{
|
||||
(void)button;
|
||||
EekGtkKeyboard *self = EEK_GTK_KEYBOARD (widget);
|
||||
EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (self);
|
||||
EekBounds bounds, large_bounds;
|
||||
|
||||
GdkWindow *window = gtk_widget_get_window (widget);
|
||||
cairo_region_t *region = gdk_window_get_clip_region (window);
|
||||
GdkDrawingContext *context = gdk_window_begin_draw_frame (window, region);
|
||||
cairo_t *cr = gdk_drawing_context_get_cairo_context (context);
|
||||
|
||||
eek_renderer_get_key_bounds (priv->renderer, key, &bounds, TRUE);
|
||||
magnify_bounds (widget, &bounds, &large_bounds, 1.5);
|
||||
|
||||
/*
|
||||
* clip to limit drawing to backbuffer and save clip region to dirty_rect
|
||||
* to limit redrawing of the backbuffer to the same area
|
||||
*/
|
||||
GdkRectangle dirty_rect = clip_bounds_to_dirty_rectangle(cr, &bounds, &large_bounds);
|
||||
|
||||
eek_renderer_render_keyboard (priv->renderer, cr);
|
||||
|
||||
gdk_window_end_draw_frame (window, context);
|
||||
|
||||
cairo_region_destroy (region);
|
||||
|
||||
/* force immediate drawing of the backbuffer to the screen */
|
||||
gdk_window_invalidate_rect (window, &dirty_rect, FALSE);
|
||||
}
|
||||
|
||||
static void
|
||||
on_key_pressed (EekKey *key,
|
||||
on_button_pressed (struct squeek_button *button,
|
||||
struct squeek_view *view,
|
||||
EekGtkKeyboard *self)
|
||||
{
|
||||
EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (self);
|
||||
@ -637,7 +498,15 @@ on_key_pressed (EekKey *key,
|
||||
if (!priv->renderer)
|
||||
return;
|
||||
|
||||
render_pressed_key (GTK_WIDGET(self), key);
|
||||
struct button_place place = {
|
||||
.button = button,
|
||||
.row = squeek_view_get_row(view, button),
|
||||
};
|
||||
if (!place.row) {
|
||||
return;
|
||||
}
|
||||
render_pressed_button (GTK_WIDGET(self), &place);
|
||||
gtk_widget_queue_draw (GTK_WIDGET(self));
|
||||
|
||||
#if HAVE_LIBCANBERRA
|
||||
ca_gtk_play_for_widget (widget, 0,
|
||||
@ -649,16 +518,19 @@ on_key_pressed (EekKey *key,
|
||||
}
|
||||
|
||||
static void
|
||||
on_key_released (EekKey *key,
|
||||
on_button_released (struct squeek_button *button,
|
||||
struct squeek_view *view,
|
||||
EekGtkKeyboard *self)
|
||||
{
|
||||
(void)view;
|
||||
EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (self);
|
||||
|
||||
/* renderer may have not been set yet if the widget is a popup */
|
||||
if (!priv->renderer)
|
||||
return;
|
||||
|
||||
render_released_key (GTK_WIDGET(self), key);
|
||||
render_released_button (GTK_WIDGET(self), button);
|
||||
gtk_widget_queue_draw (GTK_WIDGET(self));
|
||||
|
||||
#if HAVE_LIBCANBERRA
|
||||
ca_gtk_play_for_widget (widget, 0,
|
||||
@ -668,55 +540,3 @@ on_key_released (EekKey *key,
|
||||
NULL);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
on_key_locked (EekKeyboard *keyboard,
|
||||
EekKey *key,
|
||||
gpointer user_data)
|
||||
{
|
||||
GtkWidget *widget = user_data;
|
||||
EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (user_data);
|
||||
|
||||
/* renderer may have not been set yet if the widget is a popup */
|
||||
if (!priv->renderer)
|
||||
return;
|
||||
|
||||
render_locked_key (widget, key);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
@ -45,9 +45,7 @@ struct _EekGtkKeyboardClass
|
||||
};
|
||||
|
||||
GType eek_gtk_keyboard_get_type (void) G_GNUC_CONST;
|
||||
GtkWidget *eek_gtk_keyboard_new (EekKeyboard *keyboard);
|
||||
void eek_gtk_keyboard_set_theme (EekGtkKeyboard *keyboard,
|
||||
EekTheme *theme);
|
||||
GtkWidget *eek_gtk_keyboard_new (LevelKeyboard *keyboard);
|
||||
|
||||
G_END_DECLS
|
||||
#endif /* EEK_GTK_KEYBOARD_H */
|
||||
|
||||
@ -1,118 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2011 Daiki Ueno <ueno@unixuser.org>
|
||||
* Copyright (C) 2011 Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public License
|
||||
* as published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
* 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
|
||||
#include <string.h>
|
||||
#include <gdk-pixbuf/gdk-pixbuf.h>
|
||||
|
||||
#include "eek-gtk-renderer.h"
|
||||
#include "eek-key.h"
|
||||
|
||||
G_DEFINE_TYPE (EekGtkRenderer, eek_gtk_renderer, EEK_TYPE_RENDERER);
|
||||
|
||||
static cairo_surface_t *
|
||||
pixbuf_to_cairo_surface (GdkPixbuf *pixbuf)
|
||||
{
|
||||
cairo_surface_t *dummy_surface;
|
||||
cairo_pattern_t *pattern;
|
||||
cairo_surface_t *surface;
|
||||
cairo_t *cr;
|
||||
|
||||
dummy_surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 1, 1);
|
||||
|
||||
cr = cairo_create (dummy_surface);
|
||||
gdk_cairo_set_source_pixbuf (cr, pixbuf, 0, 0);
|
||||
pattern = cairo_get_source (cr);
|
||||
cairo_pattern_get_surface (pattern, &surface);
|
||||
cairo_surface_reference (surface);
|
||||
cairo_destroy (cr);
|
||||
cairo_surface_destroy (dummy_surface);
|
||||
|
||||
return surface;
|
||||
}
|
||||
|
||||
static cairo_surface_t *
|
||||
eek_gtk_renderer_real_get_icon_surface (EekRenderer *self,
|
||||
const gchar *icon_name,
|
||||
gint size)
|
||||
{
|
||||
GdkPixbuf *pixbuf;
|
||||
GError *error = NULL;
|
||||
cairo_surface_t *surface;
|
||||
|
||||
gchar *path = g_strconcat("/sm/puri/squeekboard/icons/", icon_name, ".svg", NULL);
|
||||
|
||||
pixbuf = gdk_pixbuf_new_from_resource_at_scale (path, size, size,
|
||||
TRUE, &error);
|
||||
|
||||
if (pixbuf != NULL)
|
||||
goto found;
|
||||
else {
|
||||
g_warning ("can't get icon pixbuf for %s: %s", path, error->message);
|
||||
g_error_free (error);
|
||||
error = NULL;
|
||||
}
|
||||
g_free(path);
|
||||
|
||||
pixbuf = gtk_icon_theme_load_icon (gtk_icon_theme_get_default (),
|
||||
icon_name,
|
||||
size,
|
||||
0,
|
||||
&error);
|
||||
if (pixbuf == NULL) {
|
||||
g_warning ("can't get icon pixbuf for %s: %s",
|
||||
icon_name,
|
||||
error->message);
|
||||
g_error_free (error);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
found:
|
||||
surface = pixbuf_to_cairo_surface (pixbuf);
|
||||
g_object_unref (pixbuf);
|
||||
return surface;
|
||||
}
|
||||
|
||||
static void
|
||||
eek_gtk_renderer_class_init (EekGtkRendererClass *klass)
|
||||
{
|
||||
EekRendererClass *renderer_class = EEK_RENDERER_CLASS (klass);
|
||||
|
||||
renderer_class->get_icon_surface = eek_gtk_renderer_real_get_icon_surface;
|
||||
}
|
||||
|
||||
static void
|
||||
eek_gtk_renderer_init (EekGtkRenderer *self)
|
||||
{
|
||||
}
|
||||
|
||||
EekRenderer *
|
||||
eek_gtk_renderer_new (EekKeyboard *keyboard,
|
||||
PangoContext *pcontext,
|
||||
GtkWidget *widget)
|
||||
{
|
||||
return g_object_new (EEK_TYPE_GTK_RENDERER,
|
||||
"keyboard", keyboard,
|
||||
"pango-context", pcontext,
|
||||
NULL);
|
||||
}
|
||||
@ -1,61 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2011 Daiki Ueno <ueno@unixuser.org>
|
||||
* Copyright (C) 2010-2011 Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public License
|
||||
* as published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
* 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef EEK_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 */
|
||||
613
eek/eek-key.c
613
eek/eek-key.c
@ -1,613 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2011 Daiki Ueno <ueno@unixuser.org>
|
||||
* Copyright (C) 2010-2011 Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public License
|
||||
* as published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
* 02110-1301 USA
|
||||
*/
|
||||
|
||||
/**
|
||||
* SECTION:eek-key
|
||||
* @short_description: Base class of a key
|
||||
*
|
||||
* The #EekKeyClass class represents a key.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "eek-key.h"
|
||||
#include "eek-section.h"
|
||||
#include "eek-keyboard.h"
|
||||
#include "eek-symbol.h"
|
||||
|
||||
enum {
|
||||
PROP_0,
|
||||
PROP_KEYCODE,
|
||||
PROP_SYMBOL_MATRIX,
|
||||
PROP_COLUMN,
|
||||
PROP_ROW,
|
||||
PROP_OREF,
|
||||
PROP_LAST
|
||||
};
|
||||
|
||||
enum {
|
||||
LOCKED,
|
||||
UNLOCKED,
|
||||
LAST_SIGNAL
|
||||
};
|
||||
|
||||
static guint signals[LAST_SIGNAL] = { 0, };
|
||||
|
||||
typedef struct _EekKeyPrivate
|
||||
{
|
||||
guint keycode;
|
||||
EekSymbolMatrix *symbol_matrix;
|
||||
gint column;
|
||||
gint row;
|
||||
gulong oref; // UI outline reference
|
||||
gboolean is_pressed;
|
||||
gboolean is_locked;
|
||||
} EekKeyPrivate;
|
||||
|
||||
G_DEFINE_TYPE_WITH_PRIVATE (EekKey, eek_key, EEK_TYPE_ELEMENT)
|
||||
|
||||
static void
|
||||
eek_key_real_locked (EekKey *self)
|
||||
{
|
||||
EekKeyPrivate *priv = eek_key_get_instance_private (self);
|
||||
|
||||
priv->is_locked = TRUE;
|
||||
#if DEBUG
|
||||
g_debug ("locked %X", eek_key_get_keycode (self));
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
eek_key_real_unlocked (EekKey *self)
|
||||
{
|
||||
EekKeyPrivate *priv = eek_key_get_instance_private (self);
|
||||
|
||||
priv->is_locked = FALSE;
|
||||
#if DEBUG
|
||||
g_debug ("unlocked %X", eek_key_get_keycode (self));
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
eek_key_finalize (GObject *object)
|
||||
{
|
||||
EekKey *self = EEK_KEY (object);
|
||||
EekKeyPrivate *priv = eek_key_get_instance_private (self);
|
||||
|
||||
eek_symbol_matrix_free (priv->symbol_matrix);
|
||||
|
||||
G_OBJECT_CLASS (eek_key_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
eek_key_set_property (GObject *object,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
EekSymbolMatrix *matrix;
|
||||
gint column, row;
|
||||
|
||||
switch (prop_id) {
|
||||
case PROP_KEYCODE:
|
||||
eek_key_set_keycode (EEK_KEY(object), g_value_get_uint (value));
|
||||
break;
|
||||
case PROP_SYMBOL_MATRIX:
|
||||
matrix = g_value_get_boxed (value);
|
||||
eek_key_set_symbol_matrix (EEK_KEY(object), matrix);
|
||||
break;
|
||||
case PROP_COLUMN:
|
||||
eek_key_get_index (EEK_KEY(object), &column, &row);
|
||||
eek_key_set_index (EEK_KEY(object), g_value_get_int (value), row);
|
||||
break;
|
||||
case PROP_ROW:
|
||||
eek_key_get_index (EEK_KEY(object), &column, &row);
|
||||
eek_key_set_index (EEK_KEY(object), column, g_value_get_int (value));
|
||||
break;
|
||||
case PROP_OREF:
|
||||
eek_key_set_oref (EEK_KEY(object), g_value_get_uint (value));
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
eek_key_get_property (GObject *object,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
gint column, row;
|
||||
|
||||
switch (prop_id) {
|
||||
case PROP_KEYCODE:
|
||||
g_value_set_uint (value, eek_key_get_keycode (EEK_KEY(object)));
|
||||
break;
|
||||
case PROP_SYMBOL_MATRIX:
|
||||
g_value_set_boxed (value,
|
||||
eek_key_get_symbol_matrix (EEK_KEY(object)));
|
||||
break;
|
||||
case PROP_COLUMN:
|
||||
eek_key_get_index (EEK_KEY(object), &column, &row);
|
||||
g_value_set_int (value, column);
|
||||
break;
|
||||
case PROP_ROW:
|
||||
eek_key_get_index (EEK_KEY(object), &column, &row);
|
||||
g_value_set_int (value, row);
|
||||
break;
|
||||
case PROP_OREF:
|
||||
g_value_set_uint (value, eek_key_get_oref (EEK_KEY(object)));
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
eek_key_class_init (EekKeyClass *klass)
|
||||
{
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||
GParamSpec *pspec;
|
||||
|
||||
gobject_class->set_property = eek_key_set_property;
|
||||
gobject_class->get_property = eek_key_get_property;
|
||||
gobject_class->finalize = eek_key_finalize;
|
||||
|
||||
/* signals */
|
||||
klass->locked = eek_key_real_locked;
|
||||
klass->unlocked = eek_key_real_unlocked;
|
||||
|
||||
/**
|
||||
* EekKey:keycode:
|
||||
*
|
||||
* The keycode of #EekKey.
|
||||
*/
|
||||
pspec = g_param_spec_uint ("keycode",
|
||||
"Keycode",
|
||||
"Keycode of the key",
|
||||
0, G_MAXUINT, 0,
|
||||
G_PARAM_READWRITE);
|
||||
g_object_class_install_property (gobject_class, PROP_KEYCODE, pspec);
|
||||
|
||||
/**
|
||||
* EekKey:symbol-matrix:
|
||||
*
|
||||
* The symbol matrix of #EekKey.
|
||||
*/
|
||||
pspec = g_param_spec_boxed ("symbol-matrix",
|
||||
"Symbol matrix",
|
||||
"Symbol matrix of the key",
|
||||
EEK_TYPE_SYMBOL_MATRIX,
|
||||
G_PARAM_READWRITE);
|
||||
g_object_class_install_property (gobject_class, PROP_SYMBOL_MATRIX, pspec);
|
||||
|
||||
/**
|
||||
* EekKey:column:
|
||||
*
|
||||
* The column index of #EekKey in the parent #EekSection.
|
||||
*/
|
||||
pspec = g_param_spec_int ("column",
|
||||
"Column",
|
||||
"Column index of the key in section",
|
||||
-1, G_MAXINT, -1,
|
||||
G_PARAM_READWRITE);
|
||||
g_object_class_install_property (gobject_class, PROP_COLUMN, pspec);
|
||||
|
||||
/**
|
||||
* EekKey:row:
|
||||
*
|
||||
* The row index of #EekKey in the parent #EekSection.
|
||||
*/
|
||||
pspec = g_param_spec_int ("row",
|
||||
"Row",
|
||||
"Row index of the key in section",
|
||||
-1, G_MAXINT, -1,
|
||||
G_PARAM_READWRITE);
|
||||
g_object_class_install_property (gobject_class, PROP_ROW, pspec);
|
||||
|
||||
/**
|
||||
* EekKey:oref:
|
||||
*
|
||||
* The outline id of #EekKey.
|
||||
*/
|
||||
pspec = g_param_spec_ulong ("oref",
|
||||
"Oref",
|
||||
"Outline id of the key",
|
||||
0, G_MAXULONG, 0,
|
||||
G_PARAM_READWRITE);
|
||||
g_object_class_install_property (gobject_class, PROP_OREF, pspec);
|
||||
|
||||
/**
|
||||
* EekKey::locked:
|
||||
* @key: an #EekKey
|
||||
*
|
||||
* The ::locked signal is emitted each time @key is shifted to
|
||||
* the locked state. The class handler runs before signal
|
||||
* handlers to allow signal handlers to read the status of @key
|
||||
* with eek_key_is_locked().
|
||||
*/
|
||||
signals[LOCKED] =
|
||||
g_signal_new (I_("locked"),
|
||||
G_TYPE_FROM_CLASS(gobject_class),
|
||||
G_SIGNAL_RUN_FIRST,
|
||||
G_STRUCT_OFFSET(EekKeyClass, locked),
|
||||
NULL,
|
||||
NULL,
|
||||
g_cclosure_marshal_VOID__VOID,
|
||||
G_TYPE_NONE, 0);
|
||||
|
||||
/**
|
||||
* EekKey::unlocked:
|
||||
* @key: an #EekKey
|
||||
*
|
||||
* The ::unlocked signal is emitted each time @key is shifted to
|
||||
* the unlocked state.
|
||||
*/
|
||||
signals[UNLOCKED] =
|
||||
g_signal_new (I_("unlocked"),
|
||||
G_TYPE_FROM_CLASS(gobject_class),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET(EekKeyClass, unlocked),
|
||||
NULL,
|
||||
NULL,
|
||||
g_cclosure_marshal_VOID__VOID,
|
||||
G_TYPE_NONE, 0);
|
||||
}
|
||||
|
||||
static void
|
||||
eek_key_init (EekKey *self)
|
||||
{
|
||||
EekKeyPrivate *priv = eek_key_get_instance_private (self);
|
||||
priv->symbol_matrix = eek_symbol_matrix_new (0, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* eek_key_set_keycode:
|
||||
* @key: an #EekKey
|
||||
* @keycode: keycode
|
||||
*
|
||||
* Set the keycode of @key to @keycode. Since typically the keycode
|
||||
* value is used to find a key in a keyboard by calling
|
||||
* eek_keyboard_find_key_by_keycode, it is not necessarily the same as
|
||||
* the X keycode but it should be unique in the keyboard @key belongs
|
||||
* to.
|
||||
*/
|
||||
void
|
||||
eek_key_set_keycode (EekKey *key,
|
||||
guint keycode)
|
||||
{
|
||||
g_return_if_fail (EEK_IS_KEY (key));
|
||||
|
||||
EekKeyPrivate *priv = eek_key_get_instance_private (key);
|
||||
|
||||
priv->keycode = keycode;
|
||||
}
|
||||
|
||||
/**
|
||||
* eek_key_get_keycode:
|
||||
* @key: an #EekKey
|
||||
*
|
||||
* Get keycode of @key.
|
||||
* Returns: keycode or %EEK_INVALID_KEYCODE on failure
|
||||
*/
|
||||
guint
|
||||
eek_key_get_keycode (EekKey *key)
|
||||
{
|
||||
g_return_val_if_fail (EEK_IS_KEY (key), EEK_INVALID_KEYCODE);
|
||||
|
||||
EekKeyPrivate *priv = eek_key_get_instance_private (key);
|
||||
|
||||
return priv->keycode;
|
||||
}
|
||||
|
||||
/**
|
||||
* eek_key_set_symbol_matrix:
|
||||
* @key: an #EekKey
|
||||
* @matrix: an #EekSymbolMatrix
|
||||
*
|
||||
* Set the symbol matrix of @key to @matrix.
|
||||
*/
|
||||
void
|
||||
eek_key_set_symbol_matrix (EekKey *key,
|
||||
EekSymbolMatrix *matrix)
|
||||
{
|
||||
g_return_if_fail (EEK_IS_KEY(key));
|
||||
|
||||
EekKeyPrivate *priv = eek_key_get_instance_private (key);
|
||||
|
||||
eek_symbol_matrix_free (priv->symbol_matrix);
|
||||
priv->symbol_matrix = eek_symbol_matrix_copy (matrix);
|
||||
}
|
||||
|
||||
/**
|
||||
* eek_key_get_symbol_matrix:
|
||||
* @key: an #EekKey
|
||||
*
|
||||
* Get the symbol matrix of @key.
|
||||
* Returns: (transfer none): #EekSymbolMatrix or %NULL
|
||||
*/
|
||||
EekSymbolMatrix *
|
||||
eek_key_get_symbol_matrix (EekKey *key)
|
||||
{
|
||||
g_return_val_if_fail (EEK_IS_KEY(key), NULL);
|
||||
|
||||
EekKeyPrivate *priv = eek_key_get_instance_private (key);
|
||||
|
||||
return priv->symbol_matrix;
|
||||
}
|
||||
|
||||
/**
|
||||
* eek_key_get_symbol:
|
||||
* @key: an #EekKey
|
||||
*
|
||||
* Get the current symbol of @key.
|
||||
* Return value: (transfer none): the current #EekSymbol or %NULL on failure
|
||||
*/
|
||||
EekSymbol *
|
||||
eek_key_get_symbol (EekKey *key)
|
||||
{
|
||||
return eek_key_get_symbol_with_fallback (key, 0, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* eek_key_get_symbol_with_fallback:
|
||||
* @key: an #EekKey
|
||||
* @fallback_group: fallback group index
|
||||
* @fallback_level: fallback level index
|
||||
*
|
||||
* Get the current symbol of @key.
|
||||
* Return value: (transfer none): the current #EekSymbol or %NULL on failure
|
||||
*/
|
||||
EekSymbol *
|
||||
eek_key_get_symbol_with_fallback (EekKey *key,
|
||||
gint fallback_group,
|
||||
gint fallback_level)
|
||||
{
|
||||
gint group, level;
|
||||
|
||||
g_return_val_if_fail (EEK_IS_KEY (key), NULL);
|
||||
g_return_val_if_fail (fallback_group >= 0, NULL);
|
||||
g_return_val_if_fail (fallback_level >= 0, NULL);
|
||||
|
||||
eek_element_get_symbol_index (EEK_ELEMENT(key), &group, &level);
|
||||
|
||||
if (group < 0 || level < 0) {
|
||||
EekElement *section;
|
||||
|
||||
section = eek_element_get_parent (EEK_ELEMENT(key));
|
||||
g_return_val_if_fail (EEK_IS_SECTION (section), NULL);
|
||||
|
||||
if (group < 0)
|
||||
group = eek_element_get_group (section);
|
||||
|
||||
if (level < 0)
|
||||
level = eek_element_get_level (section);
|
||||
|
||||
if (group < 0 || level < 0) {
|
||||
EekElement *keyboard;
|
||||
|
||||
keyboard = eek_element_get_parent (section);
|
||||
g_return_val_if_fail (EEK_IS_KEYBOARD (keyboard), NULL);
|
||||
|
||||
if (group < 0)
|
||||
group = eek_element_get_group (keyboard);
|
||||
if (level < 0)
|
||||
level = eek_element_get_level (keyboard);
|
||||
}
|
||||
}
|
||||
|
||||
return eek_key_get_symbol_at_index (key,
|
||||
group,
|
||||
level,
|
||||
fallback_group,
|
||||
fallback_level);
|
||||
}
|
||||
|
||||
/**
|
||||
* eek_key_get_symbol_at_index:
|
||||
* @key: an #EekKey
|
||||
* @group: group index of the symbol matrix
|
||||
* @level: level index of the symbol matrix
|
||||
* @fallback_group: fallback group index
|
||||
* @fallback_level: fallback level index
|
||||
*
|
||||
* Get the symbol at (@group, @level) in the symbol matrix of @key.
|
||||
* Return value: (transfer none): an #EekSymbol at (@group, @level), or %NULL
|
||||
*/
|
||||
EekSymbol *
|
||||
eek_key_get_symbol_at_index (EekKey *key,
|
||||
gint group,
|
||||
gint level,
|
||||
gint fallback_group,
|
||||
gint fallback_level)
|
||||
{
|
||||
EekKeyPrivate *priv = eek_key_get_instance_private (key);
|
||||
gint num_symbols;
|
||||
|
||||
g_return_val_if_fail (fallback_group >= 0, NULL);
|
||||
g_return_val_if_fail (fallback_level >= 0, NULL);
|
||||
|
||||
if (group < 0)
|
||||
group = fallback_group;
|
||||
if (level < 0)
|
||||
level = fallback_level;
|
||||
|
||||
if (!priv->symbol_matrix)
|
||||
return NULL;
|
||||
|
||||
num_symbols = priv->symbol_matrix->num_groups *
|
||||
priv->symbol_matrix->num_levels;
|
||||
if (num_symbols == 0)
|
||||
return NULL;
|
||||
|
||||
if (group >= priv->symbol_matrix->num_groups) {
|
||||
if (fallback_group < 0)
|
||||
return NULL;
|
||||
group = fallback_group;
|
||||
}
|
||||
|
||||
if (level >= priv->symbol_matrix->num_levels) {
|
||||
if (fallback_level < 0)
|
||||
return NULL;
|
||||
level = fallback_level;
|
||||
}
|
||||
|
||||
return priv->symbol_matrix->data[group * priv->symbol_matrix->num_levels +
|
||||
level];
|
||||
}
|
||||
|
||||
/**
|
||||
* eek_key_set_index:
|
||||
* @key: an #EekKey
|
||||
* @column: column index of @key in #EekSection
|
||||
* @row: row index of @key in #EekSection
|
||||
*
|
||||
* Set the location of @key in #EekSection with @column and @row.
|
||||
*/
|
||||
void
|
||||
eek_key_set_index (EekKey *key,
|
||||
gint column,
|
||||
gint row)
|
||||
{
|
||||
g_return_if_fail (EEK_IS_KEY(key));
|
||||
g_return_if_fail (0 <= column);
|
||||
g_return_if_fail (0 <= row);
|
||||
|
||||
EekKeyPrivate *priv = eek_key_get_instance_private (key);
|
||||
|
||||
if (priv->column != column) {
|
||||
priv->column = column;
|
||||
g_object_notify (G_OBJECT(key), "column");
|
||||
}
|
||||
if (priv->row != row) {
|
||||
priv->row = row;
|
||||
g_object_notify (G_OBJECT(key), "row");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* eek_key_get_index:
|
||||
* @key: an #EekKey
|
||||
* @column: (allow-none): pointer where the column index of @key in #EekSection will be stored
|
||||
* @row: (allow-none): pointer where the row index of @key in #EekSection will be stored
|
||||
*
|
||||
* Get the location of @key in #EekSection.
|
||||
*/
|
||||
void
|
||||
eek_key_get_index (EekKey *key,
|
||||
gint *column,
|
||||
gint *row)
|
||||
{
|
||||
g_return_if_fail (EEK_IS_KEY(key));
|
||||
g_return_if_fail (column != NULL || row != NULL);
|
||||
|
||||
EekKeyPrivate *priv = eek_key_get_instance_private (key);
|
||||
|
||||
if (column != NULL)
|
||||
*column = priv->column;
|
||||
if (row != NULL)
|
||||
*row = priv->row;
|
||||
}
|
||||
|
||||
/**
|
||||
* eek_key_set_oref:
|
||||
* @key: an #EekKey
|
||||
* @oref: outline id of @key
|
||||
*
|
||||
* Set the outline id of @key to @oref.
|
||||
*/
|
||||
void
|
||||
eek_key_set_oref (EekKey *key,
|
||||
guint oref)
|
||||
{
|
||||
g_return_if_fail (EEK_IS_KEY(key));
|
||||
|
||||
EekKeyPrivate *priv = eek_key_get_instance_private (key);
|
||||
|
||||
if (priv->oref != oref) {
|
||||
priv->oref = oref;
|
||||
g_object_notify (G_OBJECT(key), "oref");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* eek_key_get_oref:
|
||||
* @key: an #EekKey
|
||||
*
|
||||
* Get the outline id of @key.
|
||||
* Returns: unsigned integer
|
||||
*/
|
||||
guint
|
||||
eek_key_get_oref (EekKey *key)
|
||||
{
|
||||
g_return_val_if_fail (EEK_IS_KEY (key), 0);
|
||||
|
||||
EekKeyPrivate *priv = eek_key_get_instance_private (key);
|
||||
|
||||
return priv->oref;
|
||||
}
|
||||
|
||||
/**
|
||||
* eek_key_is_pressed:
|
||||
* @key: an #EekKey
|
||||
*
|
||||
* Return %TRUE if key is marked as pressed.
|
||||
*/
|
||||
gboolean
|
||||
eek_key_is_pressed (EekKey *key)
|
||||
{
|
||||
g_return_val_if_fail (EEK_IS_KEY(key), FALSE);
|
||||
|
||||
EekKeyPrivate *priv = eek_key_get_instance_private (key);
|
||||
|
||||
return priv->is_pressed;
|
||||
}
|
||||
|
||||
/**
|
||||
* eek_key_is_locked:
|
||||
* @key: an #EekKey
|
||||
*
|
||||
* Return %TRUE if key is marked as locked.
|
||||
*/
|
||||
gboolean
|
||||
eek_key_is_locked (EekKey *key)
|
||||
{
|
||||
g_return_val_if_fail (EEK_IS_KEY(key), FALSE);
|
||||
|
||||
EekKeyPrivate *priv = eek_key_get_instance_private (key);
|
||||
|
||||
return priv->is_locked;
|
||||
}
|
||||
|
||||
void eek_key_set_pressed(EekKey *key, gboolean value)
|
||||
{
|
||||
g_return_if_fail (EEK_IS_KEY(key));
|
||||
|
||||
EekKeyPrivate *priv = eek_key_get_instance_private (key);
|
||||
|
||||
priv->is_pressed = value;
|
||||
}
|
||||
@ -1,93 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2011 Daiki Ueno <ueno@unixuser.org>
|
||||
* Copyright (C) 2010-2011 Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public License
|
||||
* as published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
* 02110-1301 USA
|
||||
*/
|
||||
|
||||
#if !defined(__EEK_H_INSIDE__) && !defined(EEK_COMPILATION)
|
||||
#error "Only <eek/eek.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#ifndef EEK_KEY_H
|
||||
#define EEK_KEY_H 1
|
||||
|
||||
#include "eek-element.h"
|
||||
#include "eek-symbol-matrix.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define EEK_TYPE_KEY (eek_key_get_type())
|
||||
G_DECLARE_DERIVABLE_TYPE(EekKey, eek_key, EEK, KEY, EekElement)
|
||||
|
||||
/**
|
||||
* EekKeyClass:
|
||||
* @pressed: class handler for #EekKey::pressed signal
|
||||
* @released: class handler for #EekKey::released signal
|
||||
* @locked: class handler for #EekKey::locked signal
|
||||
* @unlocked: class handler for #EekKey::unlocked signal
|
||||
* @cancelled: class handler for #EekKey::cancelled signal
|
||||
* @is_pressed: virtual function for getting whether the key is pressed
|
||||
* @is_locked: virtual function for getting whether the key is locked
|
||||
*/
|
||||
struct _EekKeyClass
|
||||
{
|
||||
/*< private >*/
|
||||
EekElementClass parent_class;
|
||||
|
||||
/*< public >*/
|
||||
/* signals */
|
||||
void (* locked) (EekKey *key);
|
||||
void (* unlocked) (EekKey *key);
|
||||
};
|
||||
|
||||
GType eek_key_get_type (void) G_GNUC_CONST;
|
||||
|
||||
void eek_key_set_keycode (EekKey *key,
|
||||
guint keycode);
|
||||
guint eek_key_get_keycode (EekKey *key);
|
||||
void eek_key_set_symbol_matrix (EekKey *key,
|
||||
EekSymbolMatrix *matrix);
|
||||
EekSymbolMatrix *eek_key_get_symbol_matrix (EekKey *key);
|
||||
EekSymbol *eek_key_get_symbol (EekKey *key);
|
||||
EekSymbol *eek_key_get_symbol_with_fallback
|
||||
(EekKey *key,
|
||||
gint fallback_group,
|
||||
gint fallback_level);
|
||||
EekSymbol *eek_key_get_symbol_at_index (EekKey *key,
|
||||
gint group,
|
||||
gint level,
|
||||
gint fallback_group,
|
||||
gint fallback_level);
|
||||
|
||||
void eek_key_set_index (EekKey *key,
|
||||
gint column,
|
||||
gint row);
|
||||
void eek_key_get_index (EekKey *key,
|
||||
gint *column,
|
||||
gint *row);
|
||||
|
||||
void eek_key_set_oref (EekKey *key,
|
||||
guint oref);
|
||||
guint eek_key_get_oref (EekKey *key);
|
||||
|
||||
gboolean eek_key_is_pressed (EekKey *key);
|
||||
gboolean eek_key_is_locked (EekKey *key);
|
||||
void eek_key_set_pressed (EekKey *key,
|
||||
gboolean value);
|
||||
|
||||
G_END_DECLS
|
||||
#endif /* EEK_KEY_H */
|
||||
@ -17,9 +17,7 @@
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
|
||||
#include <math.h>
|
||||
#include <pango/pangocairo.h>
|
||||
|
||||
@ -1,17 +1,17 @@
|
||||
/*
|
||||
/*
|
||||
* 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
|
||||
@ -27,64 +27,16 @@
|
||||
* of one or more sections of the #EekSectionClass class.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
#include <glib/gprintf.h>
|
||||
|
||||
#include "eek-keyboard.h"
|
||||
#include "eek-marshalers.h"
|
||||
#include "eek-section.h"
|
||||
#include "eek-key.h"
|
||||
#include "eek-symbol.h"
|
||||
#include "eek-enumtypes.h"
|
||||
#include "eekboard/key-emitter.h"
|
||||
#include "keymap.h"
|
||||
#include "src/keyboard.h"
|
||||
#include "src/symbol.h"
|
||||
|
||||
enum {
|
||||
PROP_0,
|
||||
PROP_LAYOUT,
|
||||
PROP_MODIFIER_BEHAVIOR,
|
||||
PROP_LAST
|
||||
};
|
||||
|
||||
enum {
|
||||
KEY_RELEASED,
|
||||
KEY_LOCKED,
|
||||
KEY_UNLOCKED,
|
||||
LAST_SIGNAL
|
||||
};
|
||||
|
||||
enum {
|
||||
VIEW_LETTERS_LOWER,
|
||||
VIEW_LETTERS_UPPER,
|
||||
VIEW_NUMBERS,
|
||||
VIEW_SYMBOLS
|
||||
};
|
||||
|
||||
static guint signals[LAST_SIGNAL] = { 0, };
|
||||
|
||||
#define EEK_KEYBOARD_GET_PRIVATE(obj) \
|
||||
(G_TYPE_INSTANCE_GET_PRIVATE ((obj), EEK_TYPE_KEYBOARD, EekKeyboardPrivate))
|
||||
|
||||
struct _EekKeyboardPrivate
|
||||
{
|
||||
EekLayout *layout;
|
||||
EekModifierBehavior modifier_behavior;
|
||||
EekModifierType modifiers;
|
||||
EekModifierType old_level;
|
||||
GList *pressed_keys;
|
||||
GList *locked_keys;
|
||||
GArray *outline_array;
|
||||
GHashTable *keycodes;
|
||||
|
||||
/* modifiers dynamically assigned at run time */
|
||||
EekModifierType num_lock_mask;
|
||||
EekModifierType alt_gr_mask;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE_WITH_PRIVATE (EekKeyboard, eek_keyboard, EEK_TYPE_CONTAINER);
|
||||
|
||||
G_DEFINE_BOXED_TYPE(EekModifierKey, eek_modifier_key,
|
||||
eek_modifier_key_copy, eek_modifier_key_free);
|
||||
#include "eek-keyboard.h"
|
||||
|
||||
EekModifierKey *
|
||||
eek_modifier_key_copy (EekModifierKey *modkey)
|
||||
@ -95,583 +47,162 @@ eek_modifier_key_copy (EekModifierKey *modkey)
|
||||
void
|
||||
eek_modifier_key_free (EekModifierKey *modkey)
|
||||
{
|
||||
g_object_unref (modkey->key);
|
||||
g_slice_free (EekModifierKey, modkey);
|
||||
}
|
||||
|
||||
static void
|
||||
on_key_locked (EekSection *section,
|
||||
EekKey *key,
|
||||
EekKeyboard *keyboard)
|
||||
/// Updates the state of locked keys based on the key that was activated
|
||||
/// FIXME: make independent of what the key are named,
|
||||
/// and instead refer to the contained symbols
|
||||
static guint
|
||||
set_key_states (LevelKeyboard *keyboard,
|
||||
struct squeek_button *button,
|
||||
guint new_level)
|
||||
{
|
||||
g_signal_emit (keyboard, signals[KEY_LOCKED], 0, key);
|
||||
}
|
||||
|
||||
static void
|
||||
on_key_unlocked (EekSection *section,
|
||||
EekKey *key,
|
||||
EekKeyboard *keyboard)
|
||||
{
|
||||
g_signal_emit (keyboard, signals[KEY_UNLOCKED], 0, key);
|
||||
}
|
||||
|
||||
static void
|
||||
on_symbol_index_changed (EekSection *section,
|
||||
gint group,
|
||||
gint level,
|
||||
EekKeyboard *keyboard)
|
||||
{
|
||||
g_signal_emit_by_name (keyboard, "symbol-index-changed", group, level);
|
||||
}
|
||||
|
||||
static void
|
||||
section_child_added_cb (EekContainer *container,
|
||||
EekElement *element,
|
||||
EekKeyboard *keyboard)
|
||||
{
|
||||
guint keycode = eek_key_get_keycode (EEK_KEY(element));
|
||||
g_hash_table_insert (keyboard->priv->keycodes,
|
||||
GUINT_TO_POINTER(keycode),
|
||||
element);
|
||||
}
|
||||
|
||||
static void
|
||||
section_child_removed_cb (EekContainer *container,
|
||||
EekElement *element,
|
||||
EekKeyboard *keyboard)
|
||||
{
|
||||
guint keycode = eek_key_get_keycode (EEK_KEY(element));
|
||||
g_hash_table_remove (keyboard->priv->keycodes,
|
||||
GUINT_TO_POINTER(keycode));
|
||||
}
|
||||
|
||||
static EekSection *
|
||||
eek_keyboard_real_create_section (EekKeyboard *self)
|
||||
{
|
||||
EekSection *section;
|
||||
|
||||
section = g_object_new (EEK_TYPE_SECTION, NULL);
|
||||
g_return_val_if_fail (section, NULL);
|
||||
|
||||
g_signal_connect (G_OBJECT(section), "child-added",
|
||||
G_CALLBACK(section_child_added_cb), self);
|
||||
|
||||
g_signal_connect (G_OBJECT(section), "child-removed",
|
||||
G_CALLBACK(section_child_removed_cb), self);
|
||||
|
||||
EEK_CONTAINER_GET_CLASS(self)->add_child (EEK_CONTAINER(self),
|
||||
EEK_ELEMENT(section));
|
||||
return section;
|
||||
}
|
||||
|
||||
static void
|
||||
eek_keyboard_set_property (GObject *object,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
EekKeyboardPrivate *priv = EEK_KEYBOARD_GET_PRIVATE(object);
|
||||
|
||||
switch (prop_id) {
|
||||
case PROP_LAYOUT:
|
||||
priv->layout = g_value_get_object (value);
|
||||
if (priv->layout)
|
||||
g_object_ref (priv->layout);
|
||||
break;
|
||||
case PROP_MODIFIER_BEHAVIOR:
|
||||
eek_keyboard_set_modifier_behavior (EEK_KEYBOARD(object),
|
||||
g_value_get_enum (value));
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
struct squeek_key *key = squeek_button_get_key(button);
|
||||
// Keys locking rules hardcoded for the time being...
|
||||
const gchar *name = squeek_symbol_get_name(squeek_key_get_symbol(key));
|
||||
// Lock the shift whenever it's pressed on the baselevel
|
||||
// TODO: need to lock shift on the destination level
|
||||
if (g_strcmp0(name, "Shift_L") == 0 && keyboard->level == 0) {
|
||||
EekModifierKey *modifier_key = g_slice_new (EekModifierKey);
|
||||
modifier_key->modifiers = 0;
|
||||
modifier_key->button = button;
|
||||
keyboard->locked_buttons =
|
||||
g_list_prepend (keyboard->locked_buttons, modifier_key);
|
||||
squeek_key_set_locked(key, true);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
eek_keyboard_get_property (GObject *object,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
EekKeyboardPrivate *priv = EEK_KEYBOARD_GET_PRIVATE(object);
|
||||
|
||||
switch (prop_id) {
|
||||
case PROP_LAYOUT:
|
||||
g_value_set_object (value, priv->layout);
|
||||
break;
|
||||
case PROP_MODIFIER_BEHAVIOR:
|
||||
g_value_set_enum (value,
|
||||
eek_keyboard_get_modifier_behavior (EEK_KEYBOARD(object)));
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
if (keyboard->level == 1) {
|
||||
// Only shift is locked in this state, unlock on any key press
|
||||
for (GList *head = keyboard->locked_buttons; head; ) {
|
||||
EekModifierKey *modifier_key = head->data;
|
||||
GList *next = g_list_next (head);
|
||||
keyboard->locked_buttons =
|
||||
g_list_remove_link (keyboard->locked_buttons, head);
|
||||
squeek_key_set_locked(squeek_button_get_key(modifier_key->button), false);
|
||||
g_list_free1 (head);
|
||||
head = next;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
return new_level;
|
||||
}
|
||||
|
||||
// FIXME: unhardcode, parse some user information as to which key triggers which view (level)
|
||||
static void
|
||||
set_level_from_modifiers (EekKeyboard *self, EekKey *key)
|
||||
set_level_from_press (LevelKeyboard *keyboard, struct squeek_button *button)
|
||||
{
|
||||
EekKeyboardPrivate *priv = EEK_KEYBOARD_GET_PRIVATE(self);
|
||||
|
||||
/* The levels are: 0 Letters, 1 Upper case letters, 2 Numbers, 3 Symbols */
|
||||
|
||||
/* Use the numbers/letters bit from the old level */
|
||||
gint level = priv->old_level & 2;
|
||||
|
||||
guint level = keyboard->level;
|
||||
/* Handle non-emitting keys */
|
||||
if (key && (eek_key_get_keycode(key) == 0)) {
|
||||
const gchar *name = eek_element_get_name(EEK_ELEMENT(key));
|
||||
if (g_strcmp0(name, "ABC123") == 0)
|
||||
level ^= 2;
|
||||
}
|
||||
|
||||
level |= ((priv->modifiers & EEK_SHIFT_MASK) ? 1 : 0);
|
||||
|
||||
switch (priv->old_level) {
|
||||
case VIEW_LETTERS_UPPER:
|
||||
{
|
||||
/* Redirect upper case letters to numbers instead of symbols, clearing
|
||||
the shift modifier to keep the modifiers in sync with the level */
|
||||
if (level == VIEW_SYMBOLS) {
|
||||
level = VIEW_NUMBERS;
|
||||
priv->modifiers &= ~EEK_SHIFT_MASK;
|
||||
if (button) {
|
||||
const gchar *name = squeek_symbol_get_name(squeek_key_get_symbol(squeek_button_get_key(button)));
|
||||
if (g_strcmp0(name, "show_numbers") == 0) {
|
||||
level = 2;
|
||||
} else if (g_strcmp0(name, "show_letters") == 0) {
|
||||
level = 0;
|
||||
} else if (g_strcmp0(name, "show_symbols") == 0) {
|
||||
level = 3;
|
||||
} else if (g_strcmp0(name, "Shift_L") == 0) {
|
||||
level ^= 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case VIEW_SYMBOLS:
|
||||
{
|
||||
/* Redirect symbols to lower case letters instead of upper case,
|
||||
clearing the shift modifier to keep the modifiers in sync with the
|
||||
level */
|
||||
if (level == VIEW_LETTERS_UPPER) {
|
||||
level = VIEW_LETTERS_LOWER;
|
||||
priv->modifiers &= ~EEK_SHIFT_MASK;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case VIEW_LETTERS_LOWER: /* Direct transitions between views */
|
||||
case VIEW_NUMBERS:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (level == VIEW_NUMBERS || level == VIEW_SYMBOLS)
|
||||
priv->modifier_behavior = EEK_MODIFIER_BEHAVIOR_LOCK;
|
||||
else if (level == VIEW_LETTERS_UPPER)
|
||||
priv->modifier_behavior = EEK_MODIFIER_BEHAVIOR_LATCH;
|
||||
keyboard->level = set_key_states(keyboard, button, level);
|
||||
|
||||
priv->old_level = level;
|
||||
eek_element_set_level (EEK_ELEMENT(self), level);
|
||||
eek_layout_update_layout(keyboard);
|
||||
}
|
||||
|
||||
static void
|
||||
set_modifiers_with_key (EekKeyboard *self,
|
||||
EekKey *key,
|
||||
EekModifierType modifiers)
|
||||
{
|
||||
EekKeyboardPrivate *priv = EEK_KEYBOARD_GET_PRIVATE(self);
|
||||
EekModifierType enabled = (priv->modifiers ^ modifiers) & modifiers;
|
||||
EekModifierType disabled = (priv->modifiers ^ modifiers) & priv->modifiers;
|
||||
void eek_keyboard_press_button(LevelKeyboard *keyboard, struct squeek_button *button, guint32 timestamp) {
|
||||
struct squeek_key *key = squeek_button_get_key(button);
|
||||
squeek_key_set_pressed(key, TRUE);
|
||||
keyboard->pressed_buttons = g_list_prepend (keyboard->pressed_buttons, button);
|
||||
|
||||
if (enabled != 0) {
|
||||
if (priv->modifier_behavior != EEK_MODIFIER_BEHAVIOR_NONE) {
|
||||
EekModifierKey *modifier_key = g_slice_new (EekModifierKey);
|
||||
modifier_key->modifiers = enabled;
|
||||
modifier_key->key = g_object_ref (key);
|
||||
priv->locked_keys =
|
||||
g_list_prepend (priv->locked_keys, modifier_key);
|
||||
g_signal_emit_by_name (modifier_key->key, "locked");
|
||||
}
|
||||
} else {
|
||||
if (priv->modifier_behavior != EEK_MODIFIER_BEHAVIOR_NONE) {
|
||||
GList *head;
|
||||
for (head = priv->locked_keys; head; ) {
|
||||
EekModifierKey *modifier_key = head->data;
|
||||
if (modifier_key->modifiers & disabled) {
|
||||
GList *next = g_list_next (head);
|
||||
priv->locked_keys =
|
||||
g_list_remove_link (priv->locked_keys, head);
|
||||
g_signal_emit_by_name (modifier_key->key, "unlocked");
|
||||
g_list_free1 (head);
|
||||
head = next;
|
||||
} else
|
||||
head = g_list_next (head);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
priv->modifiers = modifiers;
|
||||
}
|
||||
|
||||
void eek_keyboard_press_key(EekKeyboard *keyboard, EekKey *key, guint32 timestamp) {
|
||||
EekKeyboardPrivate *priv = EEK_KEYBOARD_GET_PRIVATE(keyboard);
|
||||
|
||||
eek_key_set_pressed(key, TRUE);
|
||||
priv->pressed_keys = g_list_prepend (priv->pressed_keys, key);
|
||||
|
||||
EekSymbol *symbol = eek_key_get_symbol_with_fallback (key, 0, 0);
|
||||
struct squeek_symbol *symbol = squeek_key_get_symbol(key);
|
||||
if (!symbol)
|
||||
return;
|
||||
|
||||
EekModifierType modifier = eek_symbol_get_modifier_mask (symbol);
|
||||
if (priv->modifier_behavior == EEK_MODIFIER_BEHAVIOR_NONE) {
|
||||
set_modifiers_with_key (keyboard, key, priv->modifiers | modifier);
|
||||
set_level_from_modifiers (keyboard, key);
|
||||
}
|
||||
// Only take action about setting level *after* the key has taken effect, i.e. on release
|
||||
//set_level_from_press (keyboard, key);
|
||||
|
||||
// "Borrowed" from eek-context-service; doesn't influence the state but forwards the event
|
||||
|
||||
guint keycode = eek_key_get_keycode (key);
|
||||
EekModifierType modifiers = eek_keyboard_get_modifiers (keyboard);
|
||||
guint keycode = squeek_key_get_keycode (key);
|
||||
|
||||
emit_key_activated(keyboard->manager, keyboard, keycode, symbol, modifiers, TRUE, timestamp);
|
||||
emit_key_activated(keyboard->manager, keyboard, keycode, TRUE, timestamp);
|
||||
}
|
||||
|
||||
void eek_keyboard_release_key( EekKeyboard *keyboard,
|
||||
EekKey *key,
|
||||
void eek_keyboard_release_button(LevelKeyboard *keyboard,
|
||||
struct squeek_button *button,
|
||||
guint32 timestamp) {
|
||||
EekKeyboardPrivate *priv = EEK_KEYBOARD_GET_PRIVATE(keyboard);
|
||||
|
||||
for (GList *head = priv->pressed_keys; head; head = g_list_next (head)) {
|
||||
if (head->data == key) {
|
||||
priv->pressed_keys = g_list_remove_link (priv->pressed_keys, head);
|
||||
for (GList *head = keyboard->pressed_buttons; head; head = g_list_next (head)) {
|
||||
if (head->data == button) {
|
||||
keyboard->pressed_buttons = g_list_remove_link (keyboard->pressed_buttons, head);
|
||||
g_list_free1 (head);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
EekSymbol *symbol = eek_key_get_symbol_with_fallback (key, 0, 0);
|
||||
struct squeek_symbol *symbol = squeek_button_get_symbol(button);
|
||||
if (!symbol)
|
||||
return;
|
||||
|
||||
EekModifierType modifier = eek_symbol_get_modifier_mask (symbol);
|
||||
|
||||
if (!symbol)
|
||||
return;
|
||||
|
||||
modifier = eek_symbol_get_modifier_mask (symbol);
|
||||
switch (priv->modifier_behavior) {
|
||||
case EEK_MODIFIER_BEHAVIOR_NONE:
|
||||
set_modifiers_with_key (keyboard, key, priv->modifiers & ~modifier);
|
||||
break;
|
||||
case EEK_MODIFIER_BEHAVIOR_LOCK:
|
||||
priv->modifiers ^= modifier;
|
||||
break;
|
||||
case EEK_MODIFIER_BEHAVIOR_LATCH:
|
||||
if (modifier)
|
||||
set_modifiers_with_key (keyboard, key, priv->modifiers ^ modifier);
|
||||
else
|
||||
set_modifiers_with_key (keyboard, key,
|
||||
(priv->modifiers ^ modifier) & modifier);
|
||||
break;
|
||||
}
|
||||
set_level_from_modifiers (keyboard, key);
|
||||
set_level_from_press (keyboard, button);
|
||||
|
||||
// "Borrowed" from eek-context-service; doesn't influence the state but forwards the event
|
||||
|
||||
guint keycode = eek_key_get_keycode (key);
|
||||
guint modifiers = eek_keyboard_get_modifiers (keyboard);
|
||||
guint keycode = squeek_key_get_keycode (squeek_button_get_key(button));
|
||||
|
||||
emit_key_activated(keyboard->manager, keyboard, keycode, symbol, modifiers, FALSE, timestamp);
|
||||
emit_key_activated(keyboard->manager, keyboard, keycode, FALSE, timestamp);
|
||||
}
|
||||
|
||||
static void
|
||||
eek_keyboard_dispose (GObject *object)
|
||||
{
|
||||
EekKeyboardPrivate *priv = EEK_KEYBOARD_GET_PRIVATE(object);
|
||||
|
||||
if (priv->layout) {
|
||||
g_object_unref (priv->layout);
|
||||
priv->layout = NULL;
|
||||
}
|
||||
|
||||
G_OBJECT_CLASS (eek_keyboard_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
eek_keyboard_finalize (GObject *object)
|
||||
{
|
||||
EekKeyboardPrivate *priv = EEK_KEYBOARD_GET_PRIVATE(object);
|
||||
guint i;
|
||||
|
||||
g_list_free (priv->pressed_keys);
|
||||
g_list_free_full (priv->locked_keys,
|
||||
(GDestroyNotify) eek_modifier_key_free);
|
||||
|
||||
g_hash_table_destroy (priv->keycodes);
|
||||
|
||||
for (i = 0; i < priv->outline_array->len; i++) {
|
||||
EekOutline *outline = &g_array_index (priv->outline_array,
|
||||
void level_keyboard_deinit(LevelKeyboard *self) {
|
||||
g_hash_table_destroy (self->names);
|
||||
for (guint i = 0; i < self->outline_array->len; i++) {
|
||||
EekOutline *outline = &g_array_index (self->outline_array,
|
||||
EekOutline,
|
||||
i);
|
||||
g_slice_free1 (sizeof (EekPoint) * outline->num_points,
|
||||
outline->points);
|
||||
}
|
||||
g_array_free (priv->outline_array, TRUE);
|
||||
|
||||
G_OBJECT_CLASS (eek_keyboard_parent_class)->finalize (object);
|
||||
g_array_free (self->outline_array, TRUE);
|
||||
for (guint i = 0; i < 4; i++) {
|
||||
// free self->view[i];
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
eek_keyboard_real_child_added (EekContainer *self,
|
||||
EekElement *element)
|
||||
{
|
||||
g_signal_connect (element, "key-locked",
|
||||
G_CALLBACK(on_key_locked), self);
|
||||
g_signal_connect (element, "key-unlocked",
|
||||
G_CALLBACK(on_key_unlocked), self);
|
||||
g_signal_connect (element, "symbol-index-changed",
|
||||
G_CALLBACK(on_symbol_index_changed), self);
|
||||
void level_keyboard_free(LevelKeyboard *self) {
|
||||
level_keyboard_deinit(self);
|
||||
g_free(self);
|
||||
}
|
||||
|
||||
static void
|
||||
eek_keyboard_real_child_removed (EekContainer *self,
|
||||
EekElement *element)
|
||||
{
|
||||
g_signal_handlers_disconnect_by_func (element, on_key_locked, self);
|
||||
g_signal_handlers_disconnect_by_func (element, on_key_unlocked, self);
|
||||
void level_keyboard_init(LevelKeyboard *self) {
|
||||
self->outline_array = g_array_new (FALSE, TRUE, sizeof (EekOutline));
|
||||
}
|
||||
|
||||
static void
|
||||
eek_keyboard_class_init (EekKeyboardClass *klass)
|
||||
{
|
||||
EekContainerClass *container_class = EEK_CONTAINER_CLASS (klass);
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||
GParamSpec *pspec;
|
||||
|
||||
klass->create_section = eek_keyboard_real_create_section;
|
||||
|
||||
/* signals */
|
||||
container_class->child_added = eek_keyboard_real_child_added;
|
||||
container_class->child_removed = eek_keyboard_real_child_removed;
|
||||
|
||||
gobject_class->get_property = eek_keyboard_get_property;
|
||||
gobject_class->set_property = eek_keyboard_set_property;
|
||||
gobject_class->dispose = eek_keyboard_dispose;
|
||||
gobject_class->finalize = eek_keyboard_finalize;
|
||||
|
||||
/**
|
||||
* EekKeyboard:layout:
|
||||
*
|
||||
* The layout used to create this #EekKeyboard.
|
||||
*/
|
||||
pspec = g_param_spec_object ("layout",
|
||||
"Layout",
|
||||
"Layout used to create the keyboard",
|
||||
EEK_TYPE_LAYOUT,
|
||||
G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE);
|
||||
g_object_class_install_property (gobject_class,
|
||||
PROP_LAYOUT,
|
||||
pspec);
|
||||
|
||||
/**
|
||||
* EekKeyboard:modifier-behavior:
|
||||
*
|
||||
* The modifier handling mode of #EekKeyboard.
|
||||
*/
|
||||
pspec = g_param_spec_enum ("modifier-behavior",
|
||||
"Modifier behavior",
|
||||
"Modifier handling mode of the keyboard",
|
||||
EEK_TYPE_MODIFIER_BEHAVIOR,
|
||||
EEK_MODIFIER_BEHAVIOR_NONE,
|
||||
G_PARAM_READWRITE);
|
||||
g_object_class_install_property (gobject_class,
|
||||
PROP_MODIFIER_BEHAVIOR,
|
||||
pspec);
|
||||
|
||||
/**
|
||||
* EekKeyboard::key-locked:
|
||||
* @keyboard: an #EekKeyboard
|
||||
* @key: an #EekKey
|
||||
*
|
||||
* The ::key-locked signal is emitted each time a key in @keyboard
|
||||
* is shifted to the locked state.
|
||||
*/
|
||||
signals[KEY_LOCKED] =
|
||||
g_signal_new (I_("key-locked"),
|
||||
G_TYPE_FROM_CLASS(gobject_class),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET(EekKeyboardClass, key_locked),
|
||||
NULL,
|
||||
NULL,
|
||||
g_cclosure_marshal_VOID__OBJECT,
|
||||
G_TYPE_NONE,
|
||||
1,
|
||||
EEK_TYPE_KEY);
|
||||
|
||||
/**
|
||||
* EekKeyboard::key-unlocked:
|
||||
* @keyboard: an #EekKeyboard
|
||||
* @key: an #EekKey
|
||||
*
|
||||
* The ::key-unlocked signal is emitted each time a key in @keyboard
|
||||
* is shifted to the unlocked state.
|
||||
*/
|
||||
signals[KEY_UNLOCKED] =
|
||||
g_signal_new (I_("key-unlocked"),
|
||||
G_TYPE_FROM_CLASS(gobject_class),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET(EekKeyboardClass, key_unlocked),
|
||||
NULL,
|
||||
NULL,
|
||||
g_cclosure_marshal_VOID__OBJECT,
|
||||
G_TYPE_NONE,
|
||||
1,
|
||||
EEK_TYPE_KEY);
|
||||
}
|
||||
|
||||
static void
|
||||
eek_keyboard_init (EekKeyboard *self)
|
||||
{
|
||||
self->priv = EEK_KEYBOARD_GET_PRIVATE(self);
|
||||
self->priv->modifier_behavior = EEK_MODIFIER_BEHAVIOR_NONE;
|
||||
self->priv->outline_array = g_array_new (FALSE, TRUE, sizeof (EekOutline));
|
||||
self->priv->keycodes = g_hash_table_new (g_direct_hash, g_direct_equal);
|
||||
eek_element_set_symbol_index (EEK_ELEMENT(self), 0, 0);
|
||||
LevelKeyboard *level_keyboard_new(EekboardContextService *manager, struct squeek_view *views[4], GHashTable *name_button_hash) {
|
||||
LevelKeyboard *keyboard = g_new0(LevelKeyboard, 1);
|
||||
level_keyboard_init(keyboard);
|
||||
for (uint i = 0; i < 4; i++) {
|
||||
keyboard->views[i] = views[i];
|
||||
}
|
||||
keyboard->manager = manager;
|
||||
keyboard->names = name_button_hash;
|
||||
return keyboard;
|
||||
}
|
||||
|
||||
/**
|
||||
* eek_keyboard_create_section:
|
||||
* eek_keyboard_find_key_by_name:
|
||||
* @keyboard: an #EekKeyboard
|
||||
* @name: a key name
|
||||
*
|
||||
* Create an #EekSection instance and append it to @keyboard. This
|
||||
* function is rarely called by application but called by #EekLayout
|
||||
* implementation.
|
||||
* Find an #EekKey whose name is @name.
|
||||
* Return value: (transfer none): #EekKey whose name is @name
|
||||
*/
|
||||
EekSection *
|
||||
eek_keyboard_create_section (EekKeyboard *keyboard)
|
||||
struct squeek_button*
|
||||
eek_keyboard_find_button_by_name (LevelKeyboard *keyboard,
|
||||
const gchar *name)
|
||||
{
|
||||
g_return_val_if_fail (EEK_IS_KEYBOARD(keyboard), NULL);
|
||||
return EEK_KEYBOARD_GET_CLASS(keyboard)->create_section (keyboard);
|
||||
}
|
||||
|
||||
/**
|
||||
* eek_keyboard_find_key_by_keycode:
|
||||
* @keyboard: an #EekKeyboard
|
||||
* @keycode: a keycode
|
||||
*
|
||||
* Find an #EekKey whose keycode is @keycode.
|
||||
* Return value: (transfer none): #EekKey whose keycode is @keycode
|
||||
*/
|
||||
EekKey *
|
||||
eek_keyboard_find_key_by_keycode (EekKeyboard *keyboard,
|
||||
guint keycode)
|
||||
{
|
||||
g_return_val_if_fail (EEK_IS_KEYBOARD(keyboard), NULL);
|
||||
return g_hash_table_lookup (keyboard->priv->keycodes,
|
||||
GUINT_TO_POINTER(keycode));
|
||||
}
|
||||
|
||||
/**
|
||||
* eek_keyboard_get_layout:
|
||||
* @keyboard: an #EekKeyboard
|
||||
*
|
||||
* Get the layout used to create @keyboard.
|
||||
* Returns: an #EekLayout
|
||||
*/
|
||||
EekLayout *
|
||||
eek_keyboard_get_layout (EekKeyboard *keyboard)
|
||||
{
|
||||
g_return_val_if_fail (EEK_IS_KEYBOARD(keyboard), NULL);
|
||||
return keyboard->priv->layout;
|
||||
}
|
||||
|
||||
/**
|
||||
* eek_keyboard_get_size:
|
||||
* @keyboard: an #EekKeyboard
|
||||
* @width: width of @keyboard
|
||||
* @height: height of @keyboard
|
||||
*
|
||||
* Get the size of @keyboard.
|
||||
*/
|
||||
void
|
||||
eek_keyboard_get_size (EekKeyboard *keyboard,
|
||||
gdouble *width,
|
||||
gdouble *height)
|
||||
{
|
||||
EekBounds bounds;
|
||||
|
||||
eek_element_get_bounds (EEK_ELEMENT(keyboard), &bounds);
|
||||
*width = bounds.width;
|
||||
*height = bounds.height;
|
||||
}
|
||||
|
||||
/**
|
||||
* eek_keyboard_set_modifier_behavior:
|
||||
* @keyboard: an #EekKeyboard
|
||||
* @modifier_behavior: modifier behavior of @keyboard
|
||||
*
|
||||
* Set the modifier handling mode of @keyboard.
|
||||
*/
|
||||
void
|
||||
eek_keyboard_set_modifier_behavior (EekKeyboard *keyboard,
|
||||
EekModifierBehavior modifier_behavior)
|
||||
{
|
||||
g_return_if_fail (EEK_IS_KEYBOARD(keyboard));
|
||||
keyboard->priv->modifier_behavior = modifier_behavior;
|
||||
}
|
||||
|
||||
/**
|
||||
* eek_keyboard_get_modifier_behavior:
|
||||
* @keyboard: an #EekKeyboard
|
||||
*
|
||||
* Get the modifier handling mode of @keyboard.
|
||||
* Returns: #EekModifierBehavior
|
||||
*/
|
||||
EekModifierBehavior
|
||||
eek_keyboard_get_modifier_behavior (EekKeyboard *keyboard)
|
||||
{
|
||||
g_return_val_if_fail (EEK_IS_KEYBOARD(keyboard), 0);
|
||||
return keyboard->priv->modifier_behavior;
|
||||
}
|
||||
|
||||
void
|
||||
eek_keyboard_set_modifiers (EekKeyboard *keyboard,
|
||||
EekModifierType modifiers)
|
||||
{
|
||||
g_return_if_fail (EEK_IS_KEYBOARD(keyboard));
|
||||
keyboard->priv->modifiers = modifiers;
|
||||
set_level_from_modifiers (keyboard, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* eek_keyboard_get_modifiers:
|
||||
* @keyboard: an #EekKeyboard
|
||||
*
|
||||
* Get the current modifier status of @keyboard.
|
||||
* Returns: #EekModifierType
|
||||
*/
|
||||
EekModifierType
|
||||
eek_keyboard_get_modifiers (EekKeyboard *keyboard)
|
||||
{
|
||||
g_return_val_if_fail (EEK_IS_KEYBOARD(keyboard), 0);
|
||||
return keyboard->priv->modifiers;
|
||||
}
|
||||
|
||||
/**
|
||||
* eek_keyboard_add_outline:
|
||||
* @keyboard: an #EekKeyboard
|
||||
* @outline: an #EekOutline
|
||||
*
|
||||
* Register an outline of @keyboard.
|
||||
* Returns: an unsigned integer ID of the registered outline, for
|
||||
* later reference
|
||||
*/
|
||||
guint
|
||||
eek_keyboard_add_outline (EekKeyboard *keyboard,
|
||||
EekOutline *outline)
|
||||
{
|
||||
EekOutline *_outline;
|
||||
|
||||
g_return_val_if_fail (EEK_IS_KEYBOARD(keyboard), 0);
|
||||
|
||||
_outline = eek_outline_copy (outline);
|
||||
g_array_append_val (keyboard->priv->outline_array, *_outline);
|
||||
/* don't use eek_outline_free here, so as to keep _outline->points */
|
||||
g_slice_free (EekOutline, _outline);
|
||||
return keyboard->priv->outline_array->len - 1;
|
||||
return g_hash_table_lookup (keyboard->names, name);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -683,115 +214,76 @@ eek_keyboard_add_outline (EekKeyboard *keyboard,
|
||||
* Returns: an #EekOutline, which should not be released
|
||||
*/
|
||||
EekOutline *
|
||||
eek_keyboard_get_outline (EekKeyboard *keyboard,
|
||||
level_keyboard_get_outline (LevelKeyboard *keyboard,
|
||||
guint oref)
|
||||
{
|
||||
g_return_val_if_fail (EEK_IS_KEYBOARD(keyboard), NULL);
|
||||
|
||||
if (oref > keyboard->priv->outline_array->len)
|
||||
if (oref > keyboard->outline_array->len)
|
||||
return NULL;
|
||||
|
||||
return &g_array_index (keyboard->priv->outline_array, EekOutline, oref);
|
||||
return &g_array_index (keyboard->outline_array, EekOutline, oref);
|
||||
}
|
||||
|
||||
/**
|
||||
* eek_keyboard_get_n_outlines:
|
||||
* eek_keyboard_get_keymap:
|
||||
* @keyboard: an #EekKeyboard
|
||||
*
|
||||
* Get the number of outlines defined in @keyboard.
|
||||
* Returns: integer
|
||||
* Get the keymap for the keyboard.
|
||||
* Returns: a string containing the XKB keymap.
|
||||
*/
|
||||
gsize
|
||||
eek_keyboard_get_n_outlines (EekKeyboard *keyboard)
|
||||
gchar *
|
||||
eek_keyboard_get_keymap(LevelKeyboard *keyboard)
|
||||
{
|
||||
g_return_val_if_fail (EEK_IS_KEYBOARD(keyboard), 0);
|
||||
return keyboard->priv->outline_array->len;
|
||||
/* 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;
|
||||
gchar *button_name;
|
||||
gpointer button_ptr;
|
||||
g_hash_table_iter_init(&iter, keyboard->names);
|
||||
|
||||
while (g_hash_table_iter_next(&iter, (gpointer)&button_name, &button_ptr)) {
|
||||
|
||||
gchar *current, *line;
|
||||
struct squeek_button *button = button_ptr;
|
||||
struct squeek_key *key = squeek_button_get_key(button);
|
||||
guint keycode = squeek_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 *)button_name, keycode);
|
||||
|
||||
keycodes = g_strconcat(current, line, NULL);
|
||||
g_free(line);
|
||||
g_free(current);
|
||||
|
||||
// FIXME: free
|
||||
const char *key_str = squeek_key_to_keymap_entry(
|
||||
(char*)button_name,
|
||||
key
|
||||
);
|
||||
current = symbols;
|
||||
symbols = g_strconcat(current, key_str, NULL);
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* eek_keyboard_set_num_lock_mask:
|
||||
* @keyboard: an #EekKeyboard
|
||||
* @num_lock_mask: an #EekModifierType
|
||||
*
|
||||
* Set modifier mask used as Num_Lock.
|
||||
*/
|
||||
void
|
||||
eek_keyboard_set_num_lock_mask (EekKeyboard *keyboard,
|
||||
EekModifierType num_lock_mask)
|
||||
struct squeek_view *level_keyboard_current(LevelKeyboard *keyboard)
|
||||
{
|
||||
g_return_if_fail (EEK_IS_KEYBOARD(keyboard));
|
||||
keyboard->priv->num_lock_mask = num_lock_mask;
|
||||
}
|
||||
|
||||
/**
|
||||
* eek_keyboard_get_num_lock_mask:
|
||||
* @keyboard: an #EekKeyboard
|
||||
*
|
||||
* Get modifier mask used as Num_Lock.
|
||||
* Returns: an #EekModifierType
|
||||
*/
|
||||
EekModifierType
|
||||
eek_keyboard_get_num_lock_mask (EekKeyboard *keyboard)
|
||||
{
|
||||
g_return_val_if_fail (EEK_IS_KEYBOARD(keyboard), 0);
|
||||
return keyboard->priv->num_lock_mask;
|
||||
}
|
||||
|
||||
/**
|
||||
* eek_keyboard_set_alt_gr_mask:
|
||||
* @keyboard: an #EekKeyboard
|
||||
* @alt_gr_mask: an #EekModifierType
|
||||
*
|
||||
* Set modifier mask used as Alt_Gr.
|
||||
*/
|
||||
void
|
||||
eek_keyboard_set_alt_gr_mask (EekKeyboard *keyboard,
|
||||
EekModifierType alt_gr_mask)
|
||||
{
|
||||
g_return_if_fail (EEK_IS_KEYBOARD(keyboard));
|
||||
keyboard->priv->alt_gr_mask = alt_gr_mask;
|
||||
}
|
||||
|
||||
/**
|
||||
* eek_keyboard_get_alt_gr_mask:
|
||||
* @keyboard: an #EekKeyboard
|
||||
*
|
||||
* Get modifier mask used as Alt_Gr.
|
||||
* Returns: an #EekModifierType
|
||||
*/
|
||||
EekModifierType
|
||||
eek_keyboard_get_alt_gr_mask (EekKeyboard *keyboard)
|
||||
{
|
||||
g_return_val_if_fail (EEK_IS_KEYBOARD(keyboard), 0);
|
||||
return keyboard->priv->alt_gr_mask;
|
||||
}
|
||||
|
||||
/**
|
||||
* eek_keyboard_get_pressed_keys:
|
||||
* @keyboard: an #EekKeyboard
|
||||
*
|
||||
* Get pressed keys.
|
||||
* Returns: (transfer container) (element-type EekKey): A list of
|
||||
* pressed keys.
|
||||
*/
|
||||
GList *
|
||||
eek_keyboard_get_pressed_keys (EekKeyboard *keyboard)
|
||||
{
|
||||
g_return_val_if_fail (EEK_IS_KEYBOARD(keyboard), NULL);
|
||||
return g_list_copy (keyboard->priv->pressed_keys);
|
||||
}
|
||||
|
||||
/**
|
||||
* eek_keyboard_get_locked_keys:
|
||||
* @keyboard: an #EekKeyboard
|
||||
*
|
||||
* Get locked keys.
|
||||
* Returns: (transfer container) (element-type Eek.ModifierKey): A list
|
||||
* of locked keys.
|
||||
*/
|
||||
GList *
|
||||
eek_keyboard_get_locked_keys (EekKeyboard *keyboard)
|
||||
{
|
||||
g_return_val_if_fail (EEK_IS_KEYBOARD(keyboard), NULL);
|
||||
return g_list_copy (keyboard->priv->locked_keys);
|
||||
return keyboard->views[keyboard->level];
|
||||
}
|
||||
|
||||
@ -27,172 +27,67 @@
|
||||
|
||||
#include <glib-object.h>
|
||||
#include <xkbcommon/xkbcommon.h>
|
||||
#include "eek-container.h"
|
||||
#include "eek-types.h"
|
||||
#include "eek-layout.h"
|
||||
#include "src/layout.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define EEK_TYPE_KEYBOARD (eek_keyboard_get_type())
|
||||
#define EEK_KEYBOARD(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EEK_TYPE_KEYBOARD, EekKeyboard))
|
||||
#define EEK_KEYBOARD_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EEK_TYPE_KEYBOARD, EekKeyboardClass))
|
||||
#define EEK_IS_KEYBOARD(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EEK_TYPE_KEYBOARD))
|
||||
#define EEK_IS_KEYBOARD_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EEK_TYPE_KEYBOARD))
|
||||
#define EEK_KEYBOARD_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EEK_TYPE_KEYBOARD, EekKeyboardClass))
|
||||
|
||||
typedef struct _EekKeyboardClass EekKeyboardClass;
|
||||
typedef struct _EekKeyboardPrivate EekKeyboardPrivate;
|
||||
|
||||
/**
|
||||
* EekKeyboard:
|
||||
*
|
||||
* Contains the state of the physical keyboard.
|
||||
*
|
||||
* Is also a graphical element...
|
||||
*
|
||||
* The #EekKeyboard structure contains only private data and should
|
||||
* only be accessed using the provided API.
|
||||
*/
|
||||
struct _EekKeyboard
|
||||
{
|
||||
/*< private >*/
|
||||
EekContainer parent;
|
||||
|
||||
EekKeyboardPrivate *priv;
|
||||
struct xkb_keymap *keymap;
|
||||
int keymap_fd; // keymap formatted as XKB string
|
||||
size_t keymap_len; // length of the data inside keymap_fd
|
||||
|
||||
EekboardContextService *manager; // unowned reference
|
||||
};
|
||||
|
||||
/**
|
||||
* EekKeyboardClass:
|
||||
* @create_section: virtual function for creating a section
|
||||
* @find_key_by_keycode: virtual function for finding a key in the
|
||||
* keyboard by keycode
|
||||
* @key_pressed: class handler for #EekKeyboard::key-pressed signal
|
||||
* @key_released: class handler for #EekKeyboard::key-released signal
|
||||
* @key_locked: class handler for #EekKeyboard::key-locked signal
|
||||
* @key_unlocked: class handler for #EekKeyboard::key-unlocked signal
|
||||
* @key_cancelled: class handler for #EekKeyboard::key-cancelled signal
|
||||
*/
|
||||
struct _EekKeyboardClass
|
||||
{
|
||||
/*< private >*/
|
||||
EekContainerClass parent_class;
|
||||
|
||||
/* obsolete members moved to EekElement */
|
||||
gpointer set_symbol_index;
|
||||
gpointer get_symbol_index;
|
||||
|
||||
/*< public >*/
|
||||
EekSection *(* create_section) (EekKeyboard *self);
|
||||
|
||||
EekKey *(* find_key_by_keycode) (EekKeyboard *self,
|
||||
guint keycode);
|
||||
|
||||
/*< private >*/
|
||||
/* obsolete members moved to EekElement */
|
||||
gpointer symbol_index_changed;
|
||||
|
||||
/*< public >*/
|
||||
/* signals */
|
||||
void (* key_locked) (EekKeyboard *self,
|
||||
EekKey *key);
|
||||
void (* key_unlocked) (EekKeyboard *self,
|
||||
EekKey *key);
|
||||
|
||||
/*< private >*/
|
||||
/* padding */
|
||||
gpointer pdummy[21];
|
||||
};
|
||||
|
||||
/**
|
||||
* EekModifierKey:
|
||||
* @modifiers: an #EekModifierType which @key triggers
|
||||
* @key: an #EekKey
|
||||
*
|
||||
* Entry which associates modifier mask to a key. This is returned by
|
||||
* eek_keyboard_get_locked_keys().
|
||||
*/
|
||||
struct _EekModifierKey {
|
||||
/*< public >*/
|
||||
EekModifierType modifiers;
|
||||
EekKey *key;
|
||||
struct squeek_button *button;
|
||||
};
|
||||
typedef struct _EekModifierKey EekModifierKey;
|
||||
|
||||
/// Keyboard state holder
|
||||
struct _LevelKeyboard {
|
||||
struct squeek_view *views[4];
|
||||
guint level;
|
||||
struct xkb_keymap *keymap;
|
||||
int keymap_fd; // keymap formatted as XKB string
|
||||
size_t keymap_len; // length of the data inside keymap_fd
|
||||
GArray *outline_array;
|
||||
|
||||
EekKeyboard *eek_keyboard_new (EekboardContextService *manager,
|
||||
EekLayout *layout,
|
||||
gdouble initial_width,
|
||||
gdouble initial_height);
|
||||
GType eek_keyboard_get_type
|
||||
(void) G_GNUC_CONST;
|
||||
EekLayout *eek_keyboard_get_layout
|
||||
(EekKeyboard *keyboard);
|
||||
void eek_keyboard_get_size
|
||||
(EekKeyboard *keyboard,
|
||||
gdouble *width,
|
||||
gdouble *height);
|
||||
void eek_keyboard_set_size
|
||||
(EekKeyboard *keyboard,
|
||||
gdouble width,
|
||||
gdouble height);
|
||||
GList *pressed_buttons; // struct squeek_button*
|
||||
GList *locked_buttons; // struct squeek_button*
|
||||
|
||||
void eek_keyboard_set_modifier_behavior
|
||||
(EekKeyboard *keyboard,
|
||||
EekModifierBehavior modifier_behavior);
|
||||
EekModifierBehavior eek_keyboard_get_modifier_behavior
|
||||
(EekKeyboard *keyboard);
|
||||
void eek_keyboard_set_modifiers
|
||||
(EekKeyboard *keyboard,
|
||||
EekModifierType modifiers);
|
||||
EekModifierType eek_keyboard_get_modifiers
|
||||
(EekKeyboard *keyboard);
|
||||
/* Map button names to button objects: */
|
||||
GHashTable *names;
|
||||
|
||||
EekSection *eek_keyboard_create_section
|
||||
(EekKeyboard *keyboard);
|
||||
guint id; // as a key to layout choices
|
||||
|
||||
EekKey *eek_keyboard_find_key_by_keycode
|
||||
(EekKeyboard *keyboard,
|
||||
guint keycode);
|
||||
EekboardContextService *manager; // unowned reference
|
||||
};
|
||||
typedef struct _LevelKeyboard LevelKeyboard;
|
||||
|
||||
guint eek_keyboard_add_outline
|
||||
(EekKeyboard *keyboard,
|
||||
EekOutline *outline);
|
||||
struct squeek_button *eek_keyboard_find_button_by_name(LevelKeyboard *keyboard,
|
||||
const gchar *name);
|
||||
|
||||
EekOutline *eek_keyboard_get_outline
|
||||
(EekKeyboard *keyboard,
|
||||
/// Represents the path to the button within a view
|
||||
struct button_place {
|
||||
const struct squeek_row *row;
|
||||
const struct squeek_button *button;
|
||||
};
|
||||
|
||||
EekOutline *level_keyboard_get_outline
|
||||
(LevelKeyboard *keyboard,
|
||||
guint oref);
|
||||
gsize eek_keyboard_get_n_outlines
|
||||
(EekKeyboard *keyboard);
|
||||
|
||||
void eek_keyboard_set_num_lock_mask
|
||||
(EekKeyboard *keyboard,
|
||||
EekModifierType num_lock_mask);
|
||||
EekModifierType eek_keyboard_get_num_lock_mask
|
||||
(EekKeyboard *keyboard);
|
||||
|
||||
void eek_keyboard_set_alt_gr_mask
|
||||
(EekKeyboard *keyboard,
|
||||
EekModifierType alt_gr_mask);
|
||||
EekModifierType eek_keyboard_get_alt_gr_mask
|
||||
(EekKeyboard *keyboard);
|
||||
|
||||
GList *eek_keyboard_get_pressed_keys
|
||||
(EekKeyboard *keyboard);
|
||||
GList *eek_keyboard_get_locked_keys
|
||||
(EekKeyboard *keyboard);
|
||||
|
||||
EekModifierKey *eek_modifier_key_copy
|
||||
(EekModifierKey *modkey);
|
||||
void eek_modifier_key_free
|
||||
(EekModifierKey *modkey);
|
||||
|
||||
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_press_button(LevelKeyboard *keyboard, struct squeek_button *button, guint32 timestamp);
|
||||
void eek_keyboard_release_button(LevelKeyboard *keyboard, struct squeek_button *button, guint32 timestamp);
|
||||
|
||||
gchar * eek_keyboard_get_keymap
|
||||
(LevelKeyboard *keyboard);
|
||||
|
||||
struct squeek_view *level_keyboard_current(LevelKeyboard *keyboard);
|
||||
LevelKeyboard *level_keyboard_new(EekboardContextService *manager, struct squeek_view *views[], GHashTable *name_button_hash);
|
||||
void level_keyboard_deinit(LevelKeyboard *self);
|
||||
void level_keyboard_free(LevelKeyboard *self);
|
||||
|
||||
G_END_DECLS
|
||||
#endif /* EEK_KEYBOARD_H */
|
||||
|
||||
297
eek/eek-keysym.c
297
eek/eek-keysym.c
@ -23,15 +23,9 @@
|
||||
* @short_description: an #EekSymbol represents an X keysym
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "eek-keysym.h"
|
||||
#include "eek-serializable.h"
|
||||
|
||||
/* modifier keys */
|
||||
#define EEK_KEYSYM_Shift_L 0xffe1
|
||||
@ -50,301 +44,22 @@
|
||||
#define EEK_KEYSYM_Hyper_L 0xffed
|
||||
#define EEK_KEYSYM_Hyper_R 0xffee
|
||||
|
||||
typedef struct _EekKeysymPrivate
|
||||
{
|
||||
guint xkeysym;
|
||||
} EekKeysymPrivate;
|
||||
|
||||
struct _EekKeysymEntry {
|
||||
guint xkeysym;
|
||||
const gchar *name;
|
||||
EekSymbolCategory category;
|
||||
};
|
||||
|
||||
typedef struct _EekKeysymEntry EekKeysymEntry;
|
||||
|
||||
#include "eek-special-keysym-entries.h"
|
||||
#include "eek-unicode-keysym-entries.h"
|
||||
#include "eek-xkeysym-keysym-entries.h"
|
||||
|
||||
static void eek_serializable_iface_init (EekSerializableIface *iface);
|
||||
|
||||
G_DEFINE_TYPE_EXTENDED (EekKeysym, eek_keysym, EEK_TYPE_SYMBOL,
|
||||
0, /* GTypeFlags */
|
||||
G_ADD_PRIVATE (EekKeysym)
|
||||
G_IMPLEMENT_INTERFACE (EEK_TYPE_SERIALIZABLE,
|
||||
eek_serializable_iface_init))
|
||||
|
||||
static EekSerializableIface *eek_keysym_parent_serializable_iface;
|
||||
|
||||
static void
|
||||
eek_keysym_real_serialize (EekSerializable *self,
|
||||
GVariantBuilder *builder)
|
||||
guint32
|
||||
eek_keysym_from_name (const gchar *name)
|
||||
{
|
||||
EekKeysymPrivate *priv = eek_keysym_get_instance_private (
|
||||
EEK_KEYSYM(self));
|
||||
|
||||
eek_keysym_parent_serializable_iface->serialize (self, builder);
|
||||
|
||||
g_variant_builder_add (builder, "u", priv->xkeysym);
|
||||
}
|
||||
|
||||
static gsize
|
||||
eek_keysym_real_deserialize (EekSerializable *self,
|
||||
GVariant *variant,
|
||||
gsize index)
|
||||
{
|
||||
EekKeysymPrivate *priv = eek_keysym_get_instance_private (
|
||||
EEK_KEYSYM(self));
|
||||
|
||||
index = eek_keysym_parent_serializable_iface->deserialize (self,
|
||||
variant,
|
||||
index);
|
||||
|
||||
g_variant_get_child (variant, index++, "u", &priv->xkeysym);
|
||||
|
||||
return index;
|
||||
}
|
||||
|
||||
static void
|
||||
eek_serializable_iface_init (EekSerializableIface *iface)
|
||||
{
|
||||
eek_keysym_parent_serializable_iface =
|
||||
g_type_interface_peek_parent (iface);
|
||||
|
||||
iface->serialize = eek_keysym_real_serialize;
|
||||
iface->deserialize = eek_keysym_real_deserialize;
|
||||
}
|
||||
|
||||
static gchar *
|
||||
unichar_to_utf8 (gunichar uc)
|
||||
{
|
||||
if (g_unichar_isgraph (uc)) {
|
||||
gchar *buf;
|
||||
gint len;
|
||||
|
||||
len = g_unichar_to_utf8 (uc, NULL);
|
||||
buf = g_malloc0 (len + 1);
|
||||
g_unichar_to_utf8 (uc, buf);
|
||||
return buf;
|
||||
}
|
||||
return g_strdup ("");
|
||||
}
|
||||
|
||||
static int
|
||||
keysym_entry_compare_by_xkeysym (const void *key0, const void *key1)
|
||||
{
|
||||
const EekKeysymEntry *entry0 = key0, *entry1 = key1;
|
||||
return (gint) (entry0->xkeysym - entry1->xkeysym);
|
||||
}
|
||||
|
||||
static EekKeysymEntry *
|
||||
find_keysym_entry_by_xkeysym (guint xkeysym,
|
||||
const EekKeysymEntry *entries,
|
||||
gint num_entries)
|
||||
{
|
||||
EekKeysymEntry key;
|
||||
|
||||
key.xkeysym = xkeysym;
|
||||
return bsearch (&key, entries, num_entries, sizeof (EekKeysymEntry),
|
||||
keysym_entry_compare_by_xkeysym);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
get_unichar (guint xkeysym, gunichar *uc) {
|
||||
/* Check for Latin-1 characters (1:1 mapping) */
|
||||
if ((xkeysym >= 0x0020 && xkeysym <= 0x007e) ||
|
||||
(xkeysym >= 0x00a0 && xkeysym <= 0x00ff)) {
|
||||
*uc = xkeysym;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* Also check for directly encoded 24-bit UCS characters:
|
||||
*/
|
||||
if ((xkeysym & 0xff000000) == 0x01000000) {
|
||||
*uc = xkeysym & 0x00ffffff;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
G_INLINE_FUNC EekModifierType
|
||||
get_modifier_mask (guint xkeysym)
|
||||
{
|
||||
switch (xkeysym) {
|
||||
case EEK_KEYSYM_Shift_L:
|
||||
case EEK_KEYSYM_Shift_R:
|
||||
case EEK_KEYSYM_Caps_Lock:
|
||||
case EEK_KEYSYM_Shift_Lock:
|
||||
return EEK_SHIFT_MASK;
|
||||
case EEK_KEYSYM_ISO_Level3_Shift:
|
||||
return EEK_BUTTON1_MASK;
|
||||
case EEK_KEYSYM_Control_L:
|
||||
case EEK_KEYSYM_Control_R:
|
||||
return EEK_CONTROL_MASK;
|
||||
case EEK_KEYSYM_Alt_L:
|
||||
case EEK_KEYSYM_Alt_R:
|
||||
return EEK_MOD1_MASK;
|
||||
case EEK_KEYSYM_Meta_L:
|
||||
case EEK_KEYSYM_Meta_R:
|
||||
return EEK_META_MASK;
|
||||
case EEK_KEYSYM_Super_L:
|
||||
case EEK_KEYSYM_Super_R:
|
||||
return EEK_SUPER_MASK;
|
||||
case EEK_KEYSYM_Hyper_L:
|
||||
case EEK_KEYSYM_Hyper_R:
|
||||
return EEK_HYPER_MASK;
|
||||
for (uint i = 0; i < G_N_ELEMENTS(xkeysym_keysym_entries); i++) {
|
||||
if (g_strcmp0 (xkeysym_keysym_entries[i].name, name) == 0) {
|
||||
return xkeysym_keysym_entries[i].xkeysym;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
eek_keysym_class_init (EekKeysymClass *klass)
|
||||
{
|
||||
/* void */
|
||||
}
|
||||
|
||||
static void
|
||||
eek_keysym_init (EekKeysym *self)
|
||||
{
|
||||
/* void */
|
||||
}
|
||||
|
||||
/**
|
||||
* eek_keysym_new_with_modifier:
|
||||
* @xkeysym: an X keysym value
|
||||
* @modifier_mask: modifier assigned to @xkeysym
|
||||
*
|
||||
* Create an #EekKeysym with given X keysym value @xkeysym and
|
||||
* modifier @modifier_mask.
|
||||
*/
|
||||
EekKeysym *
|
||||
eek_keysym_new_with_modifier (guint xkeysym,
|
||||
EekModifierType modifier_mask)
|
||||
{
|
||||
EekKeysym *keysym;
|
||||
EekKeysymPrivate *priv;
|
||||
EekKeysymEntry *special_entry, *xkeysym_entry, *unicode_entry,
|
||||
*unichar_entry;
|
||||
gchar *name, *label;
|
||||
EekSymbolCategory category;
|
||||
gunichar uc;
|
||||
|
||||
special_entry =
|
||||
find_keysym_entry_by_xkeysym (xkeysym,
|
||||
special_keysym_entries,
|
||||
G_N_ELEMENTS(special_keysym_entries));
|
||||
xkeysym_entry =
|
||||
find_keysym_entry_by_xkeysym (xkeysym,
|
||||
xkeysym_keysym_entries,
|
||||
G_N_ELEMENTS(xkeysym_keysym_entries));
|
||||
unicode_entry =
|
||||
find_keysym_entry_by_xkeysym (xkeysym,
|
||||
unicode_keysym_entries,
|
||||
G_N_ELEMENTS(unicode_keysym_entries));
|
||||
unichar_entry = NULL;
|
||||
if (get_unichar (xkeysym, &uc)) {
|
||||
unichar_entry = g_slice_new (EekKeysymEntry);
|
||||
unichar_entry->xkeysym = xkeysym;
|
||||
unichar_entry->name = unichar_to_utf8 (uc);
|
||||
unichar_entry->category = EEK_SYMBOL_CATEGORY_LETTER;
|
||||
}
|
||||
|
||||
/* name and category */
|
||||
name = NULL;
|
||||
if (xkeysym_entry) {
|
||||
name = g_strdup (xkeysym_entry->name);
|
||||
category = xkeysym_entry->category;
|
||||
} else if (unichar_entry) {
|
||||
name = g_strdup (unichar_entry->name);
|
||||
category = unichar_entry->category;
|
||||
} else if (unicode_entry) {
|
||||
name = g_strdup (unicode_entry->name);
|
||||
category = unicode_entry->category;
|
||||
} else {
|
||||
name = g_strdup ("");
|
||||
category = EEK_SYMBOL_CATEGORY_UNKNOWN;
|
||||
}
|
||||
|
||||
/* label */
|
||||
if (special_entry)
|
||||
label = g_strdup (special_entry->name);
|
||||
else if (unichar_entry)
|
||||
label = g_strdup (unichar_entry->name);
|
||||
else if (unicode_entry)
|
||||
label = g_strdup (unicode_entry->name);
|
||||
else
|
||||
label = g_strdup (name);
|
||||
|
||||
keysym = g_object_new (EEK_TYPE_KEYSYM,
|
||||
"name", name,
|
||||
"label", label,
|
||||
"category", category,
|
||||
"modifier-mask", modifier_mask,
|
||||
NULL);
|
||||
g_free (name);
|
||||
g_free (label);
|
||||
|
||||
if (unichar_entry) {
|
||||
g_free ((gpointer) unichar_entry->name);
|
||||
g_slice_free (EekKeysymEntry, unichar_entry);
|
||||
}
|
||||
|
||||
priv = eek_keysym_get_instance_private (keysym);
|
||||
priv->xkeysym = xkeysym;
|
||||
|
||||
return keysym;
|
||||
}
|
||||
|
||||
/**
|
||||
* eek_keysym_new:
|
||||
* @xkeysym: an X keysym value
|
||||
*
|
||||
* Create an #EekKeysym with given X keysym value @xkeysym.
|
||||
*/
|
||||
EekKeysym *
|
||||
eek_keysym_new (guint xkeysym)
|
||||
{
|
||||
return eek_keysym_new_with_modifier (xkeysym, get_modifier_mask (xkeysym));
|
||||
}
|
||||
|
||||
/**
|
||||
* eek_keysym_new_from_name:
|
||||
* @name: an X keysym name
|
||||
*
|
||||
* Create an #EekKeysym with an X keysym value looked up by @name.
|
||||
*/
|
||||
EekKeysym *
|
||||
eek_keysym_new_from_name (const gchar *name)
|
||||
{
|
||||
gint i;
|
||||
|
||||
for (i = 0; i < G_N_ELEMENTS(xkeysym_keysym_entries); i++)
|
||||
if (g_strcmp0 (xkeysym_keysym_entries[i].name, name) == 0)
|
||||
return eek_keysym_new (xkeysym_keysym_entries[i].xkeysym);
|
||||
|
||||
// g_warning ("can't find keysym entry for %s", name);
|
||||
return g_object_new (EEK_TYPE_KEYSYM,
|
||||
"name", name,
|
||||
"label", name,
|
||||
"category", EEK_SYMBOL_CATEGORY_UNKNOWN,
|
||||
"modifier-mask", 0,
|
||||
NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* eek_keysym_get_xkeysym:
|
||||
* @keysym: an #EekKeysym
|
||||
*
|
||||
* Get an X keysym value associated with @keysym
|
||||
*/
|
||||
guint
|
||||
eek_keysym_get_xkeysym (EekKeysym *keysym)
|
||||
{
|
||||
EekKeysymPrivate *priv;
|
||||
|
||||
g_assert (EEK_IS_KEYSYM(keysym));
|
||||
priv = eek_keysym_get_instance_private (keysym);
|
||||
return priv->xkeysym;
|
||||
}
|
||||
|
||||
@ -25,34 +25,8 @@
|
||||
#ifndef EEK_KEYSYM_H
|
||||
#define EEK_KEYSYM_H 1
|
||||
|
||||
#include <X11/XKBlib.h>
|
||||
#include "eek-symbol.h"
|
||||
#include "glib.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
/**
|
||||
* EEK_INVALID_KEYSYM:
|
||||
*
|
||||
* Pseudo keysym used for error reporting.
|
||||
*/
|
||||
#define EEK_INVALID_KEYSYM (0)
|
||||
|
||||
#define EEK_TYPE_KEYSYM (eek_keysym_get_type())
|
||||
G_DECLARE_DERIVABLE_TYPE (EekKeysym, eek_keysym, EEK, KEYSYM, EekSymbol)
|
||||
|
||||
struct _EekKeysymClass {
|
||||
/*< private >*/
|
||||
EekSymbolClass parent_class;
|
||||
};
|
||||
|
||||
GType eek_keysym_get_type (void) G_GNUC_CONST;
|
||||
EekKeysym *eek_keysym_new (guint xkeysym);
|
||||
guint eek_keysym_get_xkeysym (EekKeysym *keysym);
|
||||
|
||||
EekKeysym *eek_keysym_new_from_name (const gchar *name);
|
||||
EekKeysym *eek_keysym_new_with_modifier (guint xkeysym,
|
||||
EekModifierType modifier_mask);
|
||||
|
||||
G_END_DECLS
|
||||
guint32 eek_keysym_from_name (const gchar *name);
|
||||
|
||||
#endif /* EEK_KEYSYM_H */
|
||||
|
||||
@ -26,13 +26,12 @@
|
||||
* arranges keyboard elements.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
|
||||
#include "eek-layout.h"
|
||||
#include "eek-keyboard.h"
|
||||
#include "eekboard/eekboard-context-service.h"
|
||||
#include "eek-xml-layout.h"
|
||||
|
||||
G_DEFINE_ABSTRACT_TYPE (EekLayout, eek_layout, G_TYPE_OBJECT)
|
||||
|
||||
@ -47,25 +46,8 @@ eek_layout_init (EekLayout *self)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* eek_keyboard_new:
|
||||
* @layout: an #EekLayout
|
||||
* @initial_width: initial width of the keyboard
|
||||
* @initial_height: initial height of the keyboard
|
||||
*
|
||||
* Create a new #EekKeyboard based on @layout.
|
||||
*/
|
||||
EekKeyboard *
|
||||
eek_keyboard_new (EekboardContextService *manager,
|
||||
EekLayout *layout,
|
||||
gdouble initial_width,
|
||||
gdouble initial_height)
|
||||
void
|
||||
eek_layout_update_layout(LevelKeyboard *keyboard)
|
||||
{
|
||||
g_assert (EEK_IS_LAYOUT(layout));
|
||||
g_assert (EEK_LAYOUT_GET_CLASS(layout)->create_keyboard);
|
||||
|
||||
return EEK_LAYOUT_GET_CLASS(layout)->create_keyboard (manager,
|
||||
layout,
|
||||
initial_width,
|
||||
initial_height);
|
||||
squeek_view_place_contents(level_keyboard_current(keyboard), keyboard);
|
||||
}
|
||||
|
||||
@ -27,6 +27,7 @@
|
||||
|
||||
#include <glib-object.h>
|
||||
#include "eek-types.h"
|
||||
#include "src/layout.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
@ -43,7 +44,7 @@ struct _EekLayoutClass
|
||||
GObjectClass parent_class;
|
||||
|
||||
/*< public >*/
|
||||
EekKeyboard* (* create_keyboard) (EekboardContextService *manager,
|
||||
LevelKeyboard* (* create_keyboard) (EekboardContextService *manager,
|
||||
EekLayout *self,
|
||||
gdouble initial_width,
|
||||
gdouble initial_height);
|
||||
@ -55,5 +56,14 @@ struct _EekLayoutClass
|
||||
|
||||
GType eek_layout_get_type (void) G_GNUC_CONST;
|
||||
|
||||
void eek_layout_place_rows(LevelKeyboard *keyboard, struct squeek_view *level);
|
||||
|
||||
void eek_layout_update_layout(LevelKeyboard *keyboard);
|
||||
|
||||
|
||||
LevelKeyboard *
|
||||
level_keyboard_from_layout (EekLayout *layout,
|
||||
gdouble initial_width,
|
||||
gdouble initial_height);
|
||||
G_END_DECLS
|
||||
#endif /* EEK_LAYOUT_H */
|
||||
|
||||
@ -1 +0,0 @@
|
||||
VOID:INT,INT
|
||||
1118
eek/eek-renderer.c
1118
eek/eek-renderer.c
File diff suppressed because it is too large
Load Diff
@ -21,12 +21,11 @@
|
||||
#ifndef EEK_RENDERER_H
|
||||
#define EEK_RENDERER_H 1
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
#include <pango/pangocairo.h>
|
||||
|
||||
#include "eek-keyboard.h"
|
||||
#include "eek-keysym.h"
|
||||
#include "eek-types.h"
|
||||
#include "eek-theme.h"
|
||||
#include "eek-theme-context.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
@ -37,19 +36,9 @@ struct _EekRendererClass
|
||||
{
|
||||
GObjectClass parent_class;
|
||||
|
||||
void (* render_key_label) (EekRenderer *self,
|
||||
PangoLayout *layout,
|
||||
EekKey *key);
|
||||
|
||||
void (* render_key_outline) (EekRenderer *self,
|
||||
void (* render_button) (EekRenderer *self,
|
||||
cairo_t *cr,
|
||||
EekKey *key,
|
||||
gdouble scale,
|
||||
gboolean rotate);
|
||||
|
||||
void (* render_key) (EekRenderer *self,
|
||||
cairo_t *cr,
|
||||
EekKey *key,
|
||||
struct button_place *place,
|
||||
gdouble scale,
|
||||
gboolean rotate);
|
||||
|
||||
@ -58,7 +47,8 @@ struct _EekRendererClass
|
||||
|
||||
cairo_surface_t *(* get_icon_surface) (EekRenderer *self,
|
||||
const gchar *icon_name,
|
||||
gint size);
|
||||
gint size,
|
||||
gint scale);
|
||||
|
||||
/*< private >*/
|
||||
/* padding */
|
||||
@ -66,8 +56,9 @@ struct _EekRendererClass
|
||||
};
|
||||
|
||||
GType eek_renderer_get_type (void) G_GNUC_CONST;
|
||||
EekRenderer *eek_renderer_new (EekKeyboard *keyboard,
|
||||
PangoContext *pcontext);
|
||||
EekRenderer *eek_renderer_new (LevelKeyboard *keyboard,
|
||||
PangoContext *pcontext,
|
||||
GtkStyleContext *scontext);
|
||||
void eek_renderer_set_allocation_size
|
||||
(EekRenderer *renderer,
|
||||
gdouble width,
|
||||
@ -75,35 +66,27 @@ void eek_renderer_set_allocation_size
|
||||
void eek_renderer_get_size (EekRenderer *renderer,
|
||||
gdouble *width,
|
||||
gdouble *height);
|
||||
void eek_renderer_get_key_bounds (EekRenderer *renderer,
|
||||
EekKey *key,
|
||||
void eek_renderer_get_button_bounds (EekRenderer *renderer,
|
||||
struct button_place *button,
|
||||
EekBounds *bounds,
|
||||
gboolean rotate);
|
||||
|
||||
gdouble eek_renderer_get_scale (EekRenderer *renderer);
|
||||
void eek_renderer_set_scale_factor (EekRenderer *renderer,
|
||||
gint scale);
|
||||
|
||||
PangoLayout *eek_renderer_create_pango_layout
|
||||
(EekRenderer *renderer);
|
||||
void eek_renderer_render_key_label (EekRenderer *renderer,
|
||||
PangoLayout *layout,
|
||||
EekKey *key);
|
||||
|
||||
void eek_renderer_render_key_outline
|
||||
(EekRenderer *renderer,
|
||||
void eek_renderer_render_button (EekRenderer *renderer,
|
||||
cairo_t *cr,
|
||||
EekKey *key,
|
||||
gdouble scale,
|
||||
gboolean rotate);
|
||||
|
||||
void eek_renderer_render_key (EekRenderer *renderer,
|
||||
cairo_t *cr,
|
||||
EekKey *key,
|
||||
struct button_place *place,
|
||||
gdouble scale,
|
||||
gboolean rotate);
|
||||
|
||||
cairo_surface_t *eek_renderer_get_icon_surface (EekRenderer *renderer,
|
||||
const gchar *icon_name,
|
||||
gint size);
|
||||
gint size,
|
||||
gint scale);
|
||||
|
||||
void eek_renderer_render_keyboard (EekRenderer *renderer,
|
||||
cairo_t *cr);
|
||||
@ -116,33 +99,18 @@ void eek_renderer_set_default_background_color
|
||||
const EekColor *color);
|
||||
void eek_renderer_get_foreground_color
|
||||
(EekRenderer *renderer,
|
||||
EekElement *element,
|
||||
GtkStyleContext *context,
|
||||
EekColor *color);
|
||||
void eek_renderer_get_background_color
|
||||
(EekRenderer *renderer,
|
||||
EekElement *element,
|
||||
EekColor *color);
|
||||
void eek_renderer_get_background_gradient
|
||||
(EekRenderer *renderer,
|
||||
EekElement *element,
|
||||
EekGradientType *type,
|
||||
EekColor *start,
|
||||
EekColor *end);
|
||||
void eek_renderer_set_border_width (EekRenderer *renderer,
|
||||
gdouble border_width);
|
||||
EekKey *eek_renderer_find_key_by_position
|
||||
(EekRenderer *renderer,
|
||||
struct squeek_button *eek_renderer_find_button_by_position(EekRenderer *renderer, struct squeek_view *view,
|
||||
gdouble x,
|
||||
gdouble y);
|
||||
void eek_renderer_apply_transformation_for_key
|
||||
void eek_renderer_apply_transformation_for_button
|
||||
(EekRenderer *renderer,
|
||||
cairo_t *cr,
|
||||
EekKey *key,
|
||||
cairo_t *cr, struct button_place *place,
|
||||
gdouble scale,
|
||||
gboolean rotate);
|
||||
|
||||
void eek_renderer_set_theme (EekRenderer *renderer,
|
||||
EekTheme *theme);
|
||||
|
||||
G_END_DECLS
|
||||
#endif /* EEK_RENDERER_H */
|
||||
|
||||
@ -18,477 +18,12 @@
|
||||
* 02110-1301 USA
|
||||
*/
|
||||
|
||||
/**
|
||||
* SECTION:eek-section
|
||||
* @short_description: Base class of a section
|
||||
* @see_also: #EekKey
|
||||
*
|
||||
* The #EekSectionClass class represents a section, which consists
|
||||
* of one or more keys of the #EekKeyClass class.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "eek-keyboard.h"
|
||||
#include "eek-section.h"
|
||||
#include "eek-key.h"
|
||||
#include "eek-symbol.h"
|
||||
|
||||
enum {
|
||||
PROP_0,
|
||||
PROP_ANGLE,
|
||||
PROP_LAST
|
||||
};
|
||||
|
||||
enum {
|
||||
KEY_LOCKED,
|
||||
KEY_UNLOCKED,
|
||||
LAST_SIGNAL
|
||||
};
|
||||
|
||||
static guint signals[LAST_SIGNAL] = { 0, };
|
||||
|
||||
struct _EekRow
|
||||
{
|
||||
gint num_columns;
|
||||
EekOrientation orientation;
|
||||
};
|
||||
|
||||
typedef struct _EekRow EekRow;
|
||||
|
||||
typedef struct _EekSectionPrivate
|
||||
{
|
||||
gint angle;
|
||||
GSList *rows;
|
||||
EekModifierType modifiers;
|
||||
} EekSectionPrivate;
|
||||
|
||||
G_DEFINE_TYPE_WITH_PRIVATE (EekSection, eek_section, EEK_TYPE_CONTAINER)
|
||||
|
||||
static gint
|
||||
eek_section_real_get_n_rows (EekSection *self)
|
||||
{
|
||||
EekSectionPrivate *priv = eek_section_get_instance_private (self);
|
||||
|
||||
return g_slist_length (priv->rows);
|
||||
}
|
||||
|
||||
static void
|
||||
eek_section_real_add_row (EekSection *self,
|
||||
gint num_columns,
|
||||
EekOrientation orientation)
|
||||
{
|
||||
EekSectionPrivate *priv = eek_section_get_instance_private (self);
|
||||
EekRow *row;
|
||||
|
||||
row = g_slice_new (EekRow);
|
||||
row->num_columns = num_columns;
|
||||
row->orientation = orientation;
|
||||
priv->rows = g_slist_append (priv->rows, row);
|
||||
}
|
||||
|
||||
static void
|
||||
eek_section_real_get_row (EekSection *self,
|
||||
gint index,
|
||||
gint *num_columns,
|
||||
EekOrientation *orientation)
|
||||
{
|
||||
EekSectionPrivate *priv = eek_section_get_instance_private (self);
|
||||
EekRow *row;
|
||||
|
||||
row = g_slist_nth_data (priv->rows, index);
|
||||
g_return_if_fail (row);
|
||||
if (num_columns)
|
||||
*num_columns = row->num_columns;
|
||||
if (orientation)
|
||||
*orientation = row->orientation;
|
||||
}
|
||||
|
||||
static void
|
||||
on_locked (EekKey *key,
|
||||
EekSection *section)
|
||||
{
|
||||
g_signal_emit (section, signals[KEY_LOCKED], 0, key);
|
||||
}
|
||||
|
||||
static void
|
||||
on_unlocked (EekKey *key,
|
||||
EekSection *section)
|
||||
{
|
||||
g_signal_emit (section, signals[KEY_UNLOCKED], 0, key);
|
||||
}
|
||||
|
||||
static EekKey *
|
||||
eek_section_real_create_key (EekSection *self,
|
||||
guint keycode,
|
||||
gint column_index,
|
||||
gint row_index)
|
||||
{
|
||||
EekKey *key;
|
||||
gint num_rows;
|
||||
EekRow *row;
|
||||
|
||||
num_rows = eek_section_get_n_rows (self);
|
||||
g_return_val_if_fail (0 <= row_index && row_index < num_rows, NULL);
|
||||
|
||||
EekSectionPrivate *priv = eek_section_get_instance_private (self);
|
||||
|
||||
row = g_slist_nth_data (priv->rows, row_index);
|
||||
if (row->num_columns < column_index + 1)
|
||||
row->num_columns = column_index + 1;
|
||||
|
||||
key = g_object_new (EEK_TYPE_KEY,
|
||||
"keycode", keycode,
|
||||
"column", column_index,
|
||||
"row", row_index,
|
||||
NULL);
|
||||
g_return_val_if_fail (key, NULL);
|
||||
|
||||
EEK_CONTAINER_GET_CLASS(self)->add_child (EEK_CONTAINER(self),
|
||||
EEK_ELEMENT(key));
|
||||
|
||||
return key;
|
||||
}
|
||||
|
||||
static void
|
||||
set_level_from_modifiers (EekSection *self)
|
||||
{
|
||||
EekSectionPrivate *priv = eek_section_get_instance_private (self);
|
||||
EekKeyboard *keyboard;
|
||||
EekModifierType num_lock_mask;
|
||||
gint level = -1;
|
||||
|
||||
keyboard = EEK_KEYBOARD(eek_element_get_parent (EEK_ELEMENT(self)));
|
||||
num_lock_mask = eek_keyboard_get_num_lock_mask (keyboard);
|
||||
if (priv->modifiers & num_lock_mask)
|
||||
level = 1;
|
||||
eek_element_set_level (EEK_ELEMENT(self), level);
|
||||
}
|
||||
|
||||
static void
|
||||
eek_section_real_key_pressed (EekSection *self, EekKey *key)
|
||||
{
|
||||
EekSectionPrivate *priv = eek_section_get_instance_private (self);
|
||||
EekSymbol *symbol;
|
||||
EekKeyboard *keyboard;
|
||||
EekModifierBehavior behavior;
|
||||
EekModifierType modifier;
|
||||
|
||||
symbol = eek_key_get_symbol_with_fallback (key, 0, 0);
|
||||
if (!symbol)
|
||||
return;
|
||||
|
||||
keyboard = EEK_KEYBOARD(eek_element_get_parent (EEK_ELEMENT(self)));
|
||||
behavior = eek_keyboard_get_modifier_behavior (keyboard);
|
||||
modifier = eek_symbol_get_modifier_mask (symbol);
|
||||
if (behavior == EEK_MODIFIER_BEHAVIOR_NONE) {
|
||||
priv->modifiers |= modifier;
|
||||
set_level_from_modifiers (self);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
eek_section_real_key_released (EekSection *self, EekKey *key)
|
||||
{
|
||||
EekSectionPrivate *priv = eek_section_get_instance_private (self);
|
||||
EekSymbol *symbol;
|
||||
EekKeyboard *keyboard;
|
||||
EekModifierBehavior behavior;
|
||||
EekModifierType modifier;
|
||||
|
||||
symbol = eek_key_get_symbol_with_fallback (key, 0, 0);
|
||||
if (!symbol)
|
||||
return;
|
||||
|
||||
keyboard = EEK_KEYBOARD(eek_element_get_parent (EEK_ELEMENT(self)));
|
||||
behavior = eek_keyboard_get_modifier_behavior (keyboard);
|
||||
modifier = eek_symbol_get_modifier_mask (symbol);
|
||||
switch (behavior) {
|
||||
case EEK_MODIFIER_BEHAVIOR_NONE:
|
||||
priv->modifiers &= ~modifier;
|
||||
break;
|
||||
case EEK_MODIFIER_BEHAVIOR_LOCK:
|
||||
priv->modifiers ^= modifier;
|
||||
break;
|
||||
case EEK_MODIFIER_BEHAVIOR_LATCH:
|
||||
priv->modifiers = (priv->modifiers ^ modifier) & modifier;
|
||||
break;
|
||||
}
|
||||
set_level_from_modifiers (self);
|
||||
}
|
||||
|
||||
static void
|
||||
eek_section_finalize (GObject *object)
|
||||
{
|
||||
EekSection *self = EEK_SECTION (object);
|
||||
EekSectionPrivate *priv = eek_section_get_instance_private (self);
|
||||
GSList *head;
|
||||
|
||||
for (head = priv->rows; head; head = g_slist_next (head))
|
||||
g_slice_free (EekRow, head->data);
|
||||
g_slist_free (priv->rows);
|
||||
|
||||
G_OBJECT_CLASS (eek_section_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
eek_section_set_property (GObject *object,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
switch (prop_id) {
|
||||
case PROP_ANGLE:
|
||||
eek_section_set_angle (EEK_SECTION(object),
|
||||
g_value_get_int (value));
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
eek_section_get_property (GObject *object,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
switch (prop_id) {
|
||||
case PROP_ANGLE:
|
||||
g_value_set_int (value, eek_section_get_angle (EEK_SECTION(object)));
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
eek_section_real_child_added (EekContainer *self,
|
||||
EekElement *element)
|
||||
{
|
||||
g_signal_connect (element, "locked", G_CALLBACK(on_locked), self);
|
||||
g_signal_connect (element, "unlocked", G_CALLBACK(on_unlocked), self);
|
||||
}
|
||||
|
||||
static void
|
||||
eek_section_real_child_removed (EekContainer *self,
|
||||
EekElement *element)
|
||||
{
|
||||
g_signal_handlers_disconnect_by_func (element, on_locked, self);
|
||||
g_signal_handlers_disconnect_by_func (element, on_unlocked, self);
|
||||
}
|
||||
|
||||
static void
|
||||
eek_section_class_init (EekSectionClass *klass)
|
||||
{
|
||||
EekContainerClass *container_class = EEK_CONTAINER_CLASS (klass);
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||
GParamSpec *pspec;
|
||||
|
||||
klass->get_n_rows = eek_section_real_get_n_rows;
|
||||
klass->add_row = eek_section_real_add_row;
|
||||
klass->get_row = eek_section_real_get_row;
|
||||
klass->create_key = eek_section_real_create_key;
|
||||
|
||||
/* signals */
|
||||
klass->key_pressed = eek_section_real_key_pressed;
|
||||
klass->key_released = eek_section_real_key_released;
|
||||
|
||||
container_class->child_added = eek_section_real_child_added;
|
||||
container_class->child_removed = eek_section_real_child_removed;
|
||||
|
||||
gobject_class->set_property = eek_section_set_property;
|
||||
gobject_class->get_property = eek_section_get_property;
|
||||
gobject_class->finalize = eek_section_finalize;
|
||||
|
||||
/**
|
||||
* EekSection:angle:
|
||||
*
|
||||
* The rotation angle of #EekSection.
|
||||
*/
|
||||
pspec = g_param_spec_int ("angle",
|
||||
"Angle",
|
||||
"Rotation angle of the section",
|
||||
-360, 360, 0,
|
||||
G_PARAM_READWRITE);
|
||||
g_object_class_install_property (gobject_class,
|
||||
PROP_ANGLE,
|
||||
pspec);
|
||||
|
||||
/**
|
||||
* EekSection::key-locked:
|
||||
* @section: an #EekSection
|
||||
* @key: an #EekKey
|
||||
*
|
||||
* The ::key-locked signal is emitted each time a key in @section
|
||||
* is shifted to the locked state.
|
||||
*/
|
||||
signals[KEY_LOCKED] =
|
||||
g_signal_new (I_("key-locked"),
|
||||
G_TYPE_FROM_CLASS(gobject_class),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET(EekSectionClass, key_locked),
|
||||
NULL,
|
||||
NULL,
|
||||
g_cclosure_marshal_VOID__OBJECT,
|
||||
G_TYPE_NONE,
|
||||
1,
|
||||
EEK_TYPE_KEY);
|
||||
|
||||
/**
|
||||
* EekSection::key-unlocked:
|
||||
* @section: an #EekSection
|
||||
* @key: an #EekKey
|
||||
*
|
||||
* The ::key-unlocked signal is emitted each time a key in @section
|
||||
* is shifted to the unlocked state.
|
||||
*/
|
||||
signals[KEY_UNLOCKED] =
|
||||
g_signal_new (I_("key-unlocked"),
|
||||
G_TYPE_FROM_CLASS(gobject_class),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET(EekSectionClass, key_unlocked),
|
||||
NULL,
|
||||
NULL,
|
||||
g_cclosure_marshal_VOID__OBJECT,
|
||||
G_TYPE_NONE,
|
||||
1,
|
||||
EEK_TYPE_KEY);
|
||||
}
|
||||
|
||||
static void
|
||||
eek_section_init (EekSection *self)
|
||||
{
|
||||
/* void */
|
||||
}
|
||||
|
||||
/**
|
||||
* eek_section_set_angle:
|
||||
* @section: an #EekSection
|
||||
* @angle: rotation angle
|
||||
*
|
||||
* Set rotation angle of @section to @angle.
|
||||
*/
|
||||
void
|
||||
eek_section_set_angle (EekSection *section,
|
||||
gint angle)
|
||||
{
|
||||
g_return_if_fail (EEK_IS_SECTION(section));
|
||||
|
||||
EekSectionPrivate *priv = eek_section_get_instance_private (section);
|
||||
|
||||
if (priv->angle != angle) {
|
||||
priv->angle = angle;
|
||||
g_object_notify (G_OBJECT(section), "angle");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* eek_section_get_angle:
|
||||
* @section: an #EekSection
|
||||
*
|
||||
* Get rotation angle of @section.
|
||||
*/
|
||||
gint
|
||||
eek_section_get_angle (EekSection *section)
|
||||
{
|
||||
g_return_val_if_fail (EEK_IS_SECTION(section), -1);
|
||||
|
||||
EekSectionPrivate *priv = eek_section_get_instance_private (section);
|
||||
|
||||
return priv->angle;
|
||||
}
|
||||
|
||||
/**
|
||||
* eek_section_get_n_rows:
|
||||
* @section: an #EekSection
|
||||
*
|
||||
* Get the number of rows in @section.
|
||||
*/
|
||||
gint
|
||||
eek_section_get_n_rows (EekSection *section)
|
||||
{
|
||||
g_return_val_if_fail (EEK_IS_SECTION(section), -1);
|
||||
return EEK_SECTION_GET_CLASS(section)->get_n_rows (section);
|
||||
}
|
||||
|
||||
/**
|
||||
* eek_section_add_row:
|
||||
* @section: an #EekSection
|
||||
* @num_columns: the number of column in the row
|
||||
* @orientation: #EekOrientation of the row
|
||||
*
|
||||
* Add a row which has @num_columns columns and whose orientation is
|
||||
* @orientation to @section.
|
||||
*/
|
||||
void
|
||||
eek_section_add_row (EekSection *section,
|
||||
gint num_columns,
|
||||
EekOrientation orientation)
|
||||
{
|
||||
g_return_if_fail (EEK_IS_SECTION(section));
|
||||
EEK_SECTION_GET_CLASS(section)->add_row (section,
|
||||
num_columns,
|
||||
orientation);
|
||||
}
|
||||
|
||||
/**
|
||||
* eek_section_get_row:
|
||||
* @section: an #EekSection
|
||||
* @index: the index of row
|
||||
* @num_columns: pointer where the number of column in the row will be stored
|
||||
* @orientation: pointer where #EekOrientation of the row will be stored
|
||||
*
|
||||
* Get the information about the @index-th row in @section.
|
||||
*/
|
||||
void
|
||||
eek_section_get_row (EekSection *section,
|
||||
gint index,
|
||||
gint *num_columns,
|
||||
EekOrientation *orientation)
|
||||
{
|
||||
g_return_if_fail (EEK_IS_SECTION(section));
|
||||
EEK_SECTION_GET_CLASS(section)->get_row (section,
|
||||
index,
|
||||
num_columns,
|
||||
orientation);
|
||||
}
|
||||
|
||||
/**
|
||||
* eek_section_create_key:
|
||||
* @section: an #EekSection
|
||||
* @keycode: a keycode
|
||||
* @column: the column index of the key
|
||||
* @row: the row index of the key
|
||||
*
|
||||
* Create an #EekKey instance and append it to @section. This
|
||||
* function is rarely called by application but called by #EekLayout
|
||||
* implementation.
|
||||
*/
|
||||
EekKey *
|
||||
eek_section_create_key (EekSection *section,
|
||||
guint keycode,
|
||||
gint column,
|
||||
gint row)
|
||||
{
|
||||
g_return_val_if_fail (EEK_IS_SECTION(section), NULL);
|
||||
return EEK_SECTION_GET_CLASS(section)->create_key (section,
|
||||
keycode,
|
||||
column,
|
||||
row);
|
||||
}
|
||||
|
||||
static void keysizer(EekElement *element, gpointer user_data) {
|
||||
EekKey *key = EEK_KEY(element);
|
||||
EekKeyboard *keyboard = EEK_KEYBOARD(user_data);
|
||||
uint oref = eek_key_get_oref (key);
|
||||
EekOutline *outline = eek_keyboard_get_outline (keyboard, oref);
|
||||
EekBounds eek_get_outline_size(LevelKeyboard *keyboard, uint32_t oref) {
|
||||
EekOutline *outline = level_keyboard_get_outline (keyboard, oref);
|
||||
if (outline && outline->num_points > 0) {
|
||||
double minx = outline->points[0].x;
|
||||
double maxx = minx;
|
||||
@ -508,55 +43,14 @@ static void keysizer(EekElement *element, gpointer user_data) {
|
||||
maxy = p.y;
|
||||
}
|
||||
}
|
||||
EekBounds key_bounds = {0};
|
||||
eek_element_get_bounds(element, &key_bounds);
|
||||
key_bounds.height = maxy - miny;
|
||||
key_bounds.width = maxx - minx;
|
||||
eek_element_set_bounds(element, &key_bounds);
|
||||
EekBounds key_bounds = {
|
||||
.height = maxy - miny,
|
||||
.width = maxx - minx,
|
||||
.x = 0,
|
||||
.y = 0,
|
||||
};
|
||||
return key_bounds;
|
||||
}
|
||||
}
|
||||
|
||||
struct keys_info {
|
||||
uint count;
|
||||
double total_width;
|
||||
double biggest_height;
|
||||
};
|
||||
|
||||
static void keycounter (EekElement *element, gpointer user_data) {
|
||||
struct keys_info *data = user_data;
|
||||
data->count++;
|
||||
EekBounds key_bounds = {0};
|
||||
eek_element_get_bounds(element, &key_bounds);
|
||||
data->total_width += key_bounds.width;
|
||||
if (key_bounds.height > data->biggest_height) {
|
||||
data->biggest_height = key_bounds.height;
|
||||
}
|
||||
}
|
||||
|
||||
const double keyspacing = 4.0;
|
||||
|
||||
static void keyplacer(EekElement *element, gpointer user_data) {
|
||||
double *current_offset = user_data;
|
||||
EekBounds key_bounds = {0};
|
||||
eek_element_get_bounds(element, &key_bounds);
|
||||
key_bounds.x = *current_offset;
|
||||
key_bounds.y = 0;
|
||||
eek_element_set_bounds(element, &key_bounds);
|
||||
*current_offset += key_bounds.width + keyspacing;
|
||||
}
|
||||
|
||||
void eek_section_place_keys(EekSection *section, EekKeyboard *keyboard)
|
||||
{
|
||||
eek_container_foreach_child(EEK_CONTAINER(section), keysizer, keyboard);
|
||||
|
||||
struct keys_info keyinfo = {0};
|
||||
eek_container_foreach_child(EEK_CONTAINER(section), keycounter, &keyinfo);
|
||||
EekBounds section_bounds = {0};
|
||||
eek_element_get_bounds(EEK_ELEMENT(section), §ion_bounds);
|
||||
|
||||
double key_offset = (section_bounds.width - (keyinfo.total_width + (keyinfo.count - 1) * keyspacing)) / 2;
|
||||
eek_container_foreach_child(EEK_CONTAINER(section), keyplacer, &key_offset);
|
||||
|
||||
section_bounds.height = keyinfo.biggest_height;
|
||||
eek_element_set_bounds(EEK_ELEMENT(section), §ion_bounds);
|
||||
EekBounds bounds = {0, 0, 0, 0};
|
||||
return bounds;
|
||||
}
|
||||
|
||||
@ -25,88 +25,10 @@
|
||||
#ifndef EEK_SECTION_H
|
||||
#define EEK_SECTION_H 1
|
||||
|
||||
/* Contains row-related functions that couldn't be done in Rust easily. */
|
||||
|
||||
#include <glib-object.h>
|
||||
#include "eek-container.h"
|
||||
#include "eek-types.h"
|
||||
#include "eek-keyboard.h"
|
||||
#include "src/layout.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define EEK_TYPE_SECTION (eek_section_get_type())
|
||||
G_DECLARE_DERIVABLE_TYPE(EekSection, eek_section, EEK, SECTION, EekContainer)
|
||||
|
||||
/**
|
||||
* EekSectionClass:
|
||||
* @get_n_rows: virtual function for getting the number of rows in the section
|
||||
* @add_row: virtual function for adding a new row to the section
|
||||
* @get_row: virtual function for accessing a row in the section
|
||||
* @create_key: virtual function for creating key in the section
|
||||
* @key_pressed: class handler for #EekSection::key-pressed signal
|
||||
* @key_released: class handler for #EekSection::key-released signal
|
||||
* @key_locked: class handler for #EekSection::key-locked signal
|
||||
* @key_unlocked: class handler for #EekSection::key-unlocked signal
|
||||
* @key_cancelled: class handler for #EekSection::key-cancelled signal
|
||||
*/
|
||||
struct _EekSectionClass
|
||||
{
|
||||
/*< private >*/
|
||||
EekContainerClass parent_class;
|
||||
|
||||
/*< public >*/
|
||||
gint (* get_n_rows) (EekSection *self);
|
||||
void (* add_row) (EekSection *self,
|
||||
gint num_columns,
|
||||
EekOrientation orientation);
|
||||
void (* get_row) (EekSection *self,
|
||||
gint index,
|
||||
gint *num_columns,
|
||||
EekOrientation *orientation);
|
||||
|
||||
EekKey *(* create_key) (EekSection *self,
|
||||
guint keycode,
|
||||
gint row,
|
||||
gint column);
|
||||
|
||||
/* signals */
|
||||
void (* key_pressed) (EekSection *self,
|
||||
EekKey *key);
|
||||
void (* key_released) (EekSection *self,
|
||||
EekKey *key);
|
||||
void (* key_locked) (EekSection *self,
|
||||
EekKey *key);
|
||||
void (* key_unlocked) (EekSection *self,
|
||||
EekKey *key);
|
||||
void (* key_cancelled) (EekSection *self,
|
||||
EekKey *key);
|
||||
|
||||
/*< private >*/
|
||||
/* padding */
|
||||
gpointer pdummy[19];
|
||||
};
|
||||
|
||||
GType eek_section_get_type (void) G_GNUC_CONST;
|
||||
|
||||
void eek_section_set_angle (EekSection *section,
|
||||
gint angle);
|
||||
gint eek_section_get_angle (EekSection *section);
|
||||
|
||||
gint eek_section_get_n_rows (EekSection *section);
|
||||
void eek_section_add_row (EekSection *section,
|
||||
gint num_columns,
|
||||
EekOrientation orientation);
|
||||
void eek_section_get_row (EekSection *section,
|
||||
gint index,
|
||||
gint *num_columns,
|
||||
EekOrientation *orientation);
|
||||
|
||||
EekKey *eek_section_create_key (EekSection *section,
|
||||
guint keycode,
|
||||
gint column,
|
||||
gint row);
|
||||
|
||||
EekKey *eek_section_find_key_by_keycode (EekSection *section,
|
||||
guint keycode);
|
||||
|
||||
void eek_section_place_keys (EekSection *section, EekKeyboard *keyboard);
|
||||
|
||||
G_END_DECLS
|
||||
#endif /* EEK_SECTION_H */
|
||||
|
||||
@ -1,93 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2008-2010 Peng Huang <shawn.p.huang@gmail.com>
|
||||
* Copyright (C) 2008-2010 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., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/**
|
||||
* SECTION:eek-serializable
|
||||
* @short_description: Interface which provides object serialization
|
||||
* into #GVariant
|
||||
*
|
||||
* The #EekSerializableIface interface defines serialize/deserialize
|
||||
* method.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
|
||||
#include "eek-serializable.h"
|
||||
|
||||
GType
|
||||
eek_serializable_get_type (void)
|
||||
{
|
||||
static GType iface_type = 0;
|
||||
if (iface_type == 0) {
|
||||
static const GTypeInfo info = {
|
||||
sizeof (EekSerializableIface),
|
||||
NULL,
|
||||
NULL,
|
||||
};
|
||||
iface_type = g_type_register_static (G_TYPE_INTERFACE,
|
||||
"EekSerializable",
|
||||
&info, 0);
|
||||
}
|
||||
return iface_type;
|
||||
}
|
||||
|
||||
GVariant *
|
||||
eek_serializable_serialize (EekSerializable *object)
|
||||
{
|
||||
GVariantBuilder builder;
|
||||
|
||||
g_return_val_if_fail (EEK_IS_SERIALIZABLE (object), FALSE);
|
||||
|
||||
g_variant_builder_init (&builder, G_VARIANT_TYPE_TUPLE);
|
||||
g_variant_builder_add (&builder, "s", g_type_name (G_OBJECT_TYPE (object)));
|
||||
EEK_SERIALIZABLE_GET_IFACE (object)->serialize (object, &builder);
|
||||
|
||||
return g_variant_builder_end (&builder);
|
||||
}
|
||||
|
||||
EekSerializable *
|
||||
eek_serializable_deserialize (GVariant *variant)
|
||||
{
|
||||
gchar *type_name = NULL;
|
||||
GType type;
|
||||
EekSerializable *object;
|
||||
gsize index = 0;
|
||||
|
||||
g_return_val_if_fail (variant != NULL, NULL);
|
||||
|
||||
g_variant_get_child (variant, index++, "&s", &type_name);
|
||||
type = g_type_from_name (type_name);
|
||||
|
||||
g_return_val_if_fail (g_type_is_a (type, EEK_TYPE_SERIALIZABLE), NULL);
|
||||
|
||||
object = g_object_new (type, NULL);
|
||||
|
||||
index = EEK_SERIALIZABLE_GET_IFACE (object)->deserialize (object,
|
||||
variant,
|
||||
index);
|
||||
if (index < 0) {
|
||||
g_object_unref (object);
|
||||
g_return_val_if_reached (NULL);
|
||||
}
|
||||
|
||||
return object;
|
||||
}
|
||||
@ -1,66 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2011 Daiki Ueno <ueno@unixuser.org>
|
||||
* Copyright (C) 2011 Red Hat, Inc.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#if !defined(__EEK_H_INSIDE__) && !defined(EEK_COMPILATION)
|
||||
#error "Only <eek/eek.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#ifndef EEK_SERIALIZABLE_H
|
||||
#define EEK_SERIALIZABLE_H 1
|
||||
|
||||
#include <glib-object.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define EEK_TYPE_SERIALIZABLE (eek_serializable_get_type())
|
||||
#define EEK_SERIALIZABLE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EEK_TYPE_SERIALIZABLE, EekSerializable))
|
||||
#define EEK_IS_SERIALIZABLE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EEK_TYPE_SERIALIZABLE))
|
||||
#define EEK_SERIALIZABLE_GET_IFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), EEK_TYPE_SERIALIZABLE, EekSerializableIface))
|
||||
|
||||
typedef struct _EekSerializable EekSerializable;
|
||||
typedef struct _EekSerializableIface EekSerializableIface;
|
||||
|
||||
/**
|
||||
* EekSerializableIface:
|
||||
*
|
||||
* @serialize: virtual function for serializing object into #GVariant
|
||||
* @deserialize: virtual function for deserializing object from #GVariant
|
||||
*/
|
||||
struct _EekSerializableIface
|
||||
{
|
||||
/*< private >*/
|
||||
GTypeInterface parent_iface;
|
||||
|
||||
void (* serialize) (EekSerializable *object,
|
||||
GVariantBuilder *builder);
|
||||
gsize (* deserialize) (EekSerializable *object,
|
||||
GVariant *variant,
|
||||
gsize index);
|
||||
|
||||
/*< private >*/
|
||||
/* padding */
|
||||
gpointer pdummy[24];
|
||||
};
|
||||
|
||||
GType eek_serializable_get_type (void);
|
||||
|
||||
GVariant *eek_serializable_serialize (EekSerializable *object);
|
||||
EekSerializable *eek_serializable_deserialize (GVariant *variant);
|
||||
|
||||
G_END_DECLS
|
||||
#endif /* EEK_SERIALIZABLE_H */
|
||||
@ -1,105 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2011 Daiki Ueno <ueno@unixuser.org>
|
||||
* Copyright (C) 2011 Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public License
|
||||
* as published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
* 02110-1301 USA
|
||||
*/
|
||||
#include "eek-symbol-matrix.h"
|
||||
|
||||
EekSymbolMatrix *
|
||||
eek_symbol_matrix_new (gint num_groups,
|
||||
gint num_levels)
|
||||
{
|
||||
EekSymbolMatrix *matrix = g_slice_new (EekSymbolMatrix);
|
||||
|
||||
matrix->num_groups = num_groups;
|
||||
matrix->num_levels = num_levels;
|
||||
matrix->data = g_slice_alloc0 (sizeof (EekSymbol *) *
|
||||
num_groups * num_levels);
|
||||
return matrix;
|
||||
}
|
||||
|
||||
EekSymbolMatrix *
|
||||
eek_symbol_matrix_copy (const EekSymbolMatrix *matrix)
|
||||
{
|
||||
EekSymbolMatrix *retval;
|
||||
gint i, num_symbols = matrix->num_groups * matrix->num_levels;
|
||||
|
||||
retval = g_slice_dup (EekSymbolMatrix, matrix);
|
||||
retval->data = g_slice_copy (sizeof (EekSymbol *) * num_symbols,
|
||||
matrix->data);
|
||||
for (i = 0; i < num_symbols; i++)
|
||||
if (retval->data[i])
|
||||
g_object_ref (retval->data[i]);
|
||||
return retval;
|
||||
}
|
||||
|
||||
void
|
||||
eek_symbol_matrix_free (EekSymbolMatrix *matrix)
|
||||
{
|
||||
gint i, num_symbols = matrix->num_groups * matrix->num_levels;
|
||||
for (i = 0; i < num_symbols; i++)
|
||||
if (matrix->data[i])
|
||||
g_object_unref (matrix->data[i]);
|
||||
g_slice_free1 (sizeof (EekSymbol *) * num_symbols, matrix->data);
|
||||
g_slice_free (EekSymbolMatrix, matrix);
|
||||
}
|
||||
|
||||
GType
|
||||
eek_symbol_matrix_get_type (void)
|
||||
{
|
||||
static GType our_type = 0;
|
||||
|
||||
if (our_type == 0)
|
||||
our_type =
|
||||
g_boxed_type_register_static ("EekSymbolMatrix",
|
||||
(GBoxedCopyFunc)eek_symbol_matrix_copy,
|
||||
(GBoxedFreeFunc)eek_symbol_matrix_free);
|
||||
return our_type;
|
||||
}
|
||||
|
||||
void
|
||||
eek_symbol_matrix_set_symbol (EekSymbolMatrix *matrix,
|
||||
gint group,
|
||||
gint level,
|
||||
EekSymbol *symbol)
|
||||
{
|
||||
g_return_if_fail (group >= 0 && group < matrix->num_groups);
|
||||
g_return_if_fail (level >= 0 && level < matrix->num_levels);
|
||||
g_return_if_fail (EEK_IS_SYMBOL(symbol));
|
||||
matrix->data[group * matrix->num_levels + level] = g_object_ref (symbol);
|
||||
}
|
||||
|
||||
/**
|
||||
* eek_symbol_matrix_get_symbol:
|
||||
* @matrix: an #EekSymbolMatrix
|
||||
* @group: group index of @matrix
|
||||
* @level: level index of @matrix
|
||||
*
|
||||
* Get an #EekSymbol stored in the cell selected by (@group, @level)
|
||||
* in @matrix.
|
||||
*
|
||||
* Return value: (transfer none): an #EekSymbol.
|
||||
*/
|
||||
EekSymbol *
|
||||
eek_symbol_matrix_get_symbol (EekSymbolMatrix *matrix,
|
||||
gint group,
|
||||
gint level)
|
||||
{
|
||||
g_return_val_if_fail (group >= 0 && group < matrix->num_groups, NULL);
|
||||
g_return_val_if_fail (level >= 0 && level < matrix->num_levels, NULL);
|
||||
return matrix->data[group * matrix->num_levels + level];
|
||||
}
|
||||
@ -1,62 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2011 Daiki Ueno <ueno@unixuser.org>
|
||||
* Copyright (C) 2011 Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public License
|
||||
* as published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
* 02110-1301 USA
|
||||
*/
|
||||
#ifndef EEK_SYMBOL_MATRIX_H
|
||||
#define EEK_SYMBOL_MATRIX_H 1
|
||||
|
||||
#include "eek-symbol.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
/**
|
||||
* EekSymbolMatrix:
|
||||
* @data: array of symbols
|
||||
* @num_groups: the number of groups (rows)
|
||||
* @num_levels: the number of levels (columns)
|
||||
*
|
||||
* Symbol matrix of a key.
|
||||
*/
|
||||
struct _EekSymbolMatrix
|
||||
{
|
||||
/*< public >*/
|
||||
gint num_groups;
|
||||
gint num_levels;
|
||||
EekSymbol **data;
|
||||
};
|
||||
|
||||
#define EEK_TYPE_SYMBOL_MATRIX (eek_symbol_matrix_get_type ())
|
||||
GType eek_symbol_matrix_get_type (void) G_GNUC_CONST;
|
||||
EekSymbolMatrix *eek_symbol_matrix_new (gint num_groups,
|
||||
gint num_levels);
|
||||
EekSymbolMatrix *eek_symbol_matrix_copy (const EekSymbolMatrix *matrix);
|
||||
void eek_symbol_matrix_free (EekSymbolMatrix *matrix);
|
||||
|
||||
void eek_symbol_matrix_set_symbol
|
||||
(EekSymbolMatrix *matrix,
|
||||
gint group,
|
||||
gint level,
|
||||
EekSymbol *symbol);
|
||||
EekSymbol *eek_symbol_matrix_get_symbol
|
||||
(EekSymbolMatrix *matrix,
|
||||
gint group,
|
||||
gint level);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* EEK_SYMBOL_MATRIX_H */
|
||||
445
eek/eek-symbol.c
445
eek/eek-symbol.c
@ -25,275 +25,18 @@
|
||||
* The #EekSymbolClass class represents a symbol assigned to a key.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
|
||||
#include "eek-symbol.h"
|
||||
#include "eek-serializable.h"
|
||||
#include "eek-enumtypes.h"
|
||||
|
||||
enum {
|
||||
PROP_0,
|
||||
PROP_NAME,
|
||||
PROP_LABEL,
|
||||
PROP_CATEGORY,
|
||||
PROP_MODIFIER_MASK,
|
||||
PROP_ICON_NAME,
|
||||
PROP_TOOLTIP,
|
||||
PROP_LAST
|
||||
};
|
||||
|
||||
typedef struct _EekSymbolPrivate
|
||||
{
|
||||
gchar *name;
|
||||
gchar *label;
|
||||
EekSymbolCategory category;
|
||||
EekModifierType modifier_mask;
|
||||
gchar *icon_name;
|
||||
gchar *tooltip;
|
||||
} EekSymbolPrivate;
|
||||
|
||||
static void eek_serializable_iface_init (EekSerializableIface *iface);
|
||||
|
||||
G_DEFINE_TYPE_EXTENDED (EekSymbol,
|
||||
eek_symbol,
|
||||
G_TYPE_OBJECT,
|
||||
0, /* GTypeFlags */
|
||||
G_ADD_PRIVATE (EekSymbol)
|
||||
G_IMPLEMENT_INTERFACE (EEK_TYPE_SERIALIZABLE,
|
||||
eek_serializable_iface_init))
|
||||
|
||||
static void
|
||||
eek_symbol_real_serialize (EekSerializable *self,
|
||||
GVariantBuilder *builder)
|
||||
{
|
||||
EekSymbolPrivate *priv = eek_symbol_get_instance_private (EEK_SYMBOL (self));
|
||||
#define NOTNULL(s) ((s) != NULL ? (s) : "")
|
||||
g_variant_builder_add (builder, "s", NOTNULL(priv->name));
|
||||
g_variant_builder_add (builder, "s", NOTNULL(priv->label));
|
||||
g_variant_builder_add (builder, "u", priv->category);
|
||||
g_variant_builder_add (builder, "u", priv->modifier_mask);
|
||||
g_variant_builder_add (builder, "s", NOTNULL(priv->icon_name));
|
||||
g_variant_builder_add (builder, "s", NOTNULL(priv->tooltip));
|
||||
#undef NOTNULL
|
||||
}
|
||||
|
||||
static gsize
|
||||
eek_symbol_real_deserialize (EekSerializable *self,
|
||||
GVariant *variant,
|
||||
gsize index)
|
||||
{
|
||||
EekSymbolPrivate *priv = eek_symbol_get_instance_private (EEK_SYMBOL (self));
|
||||
|
||||
g_variant_get_child (variant, index++, "s", &priv->name);
|
||||
g_variant_get_child (variant, index++, "s", &priv->label);
|
||||
g_variant_get_child (variant, index++, "u", &priv->category);
|
||||
g_variant_get_child (variant, index++, "u", &priv->modifier_mask);
|
||||
g_variant_get_child (variant, index++, "s", &priv->icon_name);
|
||||
g_variant_get_child (variant, index++, "s", &priv->tooltip);
|
||||
|
||||
return index;
|
||||
}
|
||||
|
||||
static void
|
||||
eek_serializable_iface_init (EekSerializableIface *iface)
|
||||
{
|
||||
iface->serialize = eek_symbol_real_serialize;
|
||||
iface->deserialize = eek_symbol_real_deserialize;
|
||||
}
|
||||
|
||||
static void
|
||||
eek_symbol_set_property (GObject *object,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
switch (prop_id) {
|
||||
case PROP_NAME:
|
||||
eek_symbol_set_name (EEK_SYMBOL(object), g_value_get_string (value));
|
||||
break;
|
||||
case PROP_LABEL:
|
||||
eek_symbol_set_label (EEK_SYMBOL(object), g_value_get_string (value));
|
||||
break;
|
||||
case PROP_CATEGORY:
|
||||
eek_symbol_set_category (EEK_SYMBOL(object), g_value_get_enum (value));
|
||||
break;
|
||||
case PROP_MODIFIER_MASK:
|
||||
eek_symbol_set_modifier_mask (EEK_SYMBOL(object),
|
||||
g_value_get_flags (value));
|
||||
break;
|
||||
case PROP_ICON_NAME:
|
||||
eek_symbol_set_icon_name (EEK_SYMBOL(object),
|
||||
g_value_get_string (value));
|
||||
break;
|
||||
case PROP_TOOLTIP:
|
||||
eek_symbol_set_tooltip (EEK_SYMBOL(object),
|
||||
g_value_get_string (value));
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
eek_symbol_get_property (GObject *object,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
switch (prop_id) {
|
||||
case PROP_NAME:
|
||||
g_value_set_string (value, eek_symbol_get_name (EEK_SYMBOL(object)));
|
||||
break;
|
||||
case PROP_LABEL:
|
||||
g_value_set_string (value, eek_symbol_get_label (EEK_SYMBOL(object)));
|
||||
break;
|
||||
case PROP_CATEGORY:
|
||||
g_value_set_enum (value, eek_symbol_get_category (EEK_SYMBOL(object)));
|
||||
break;
|
||||
case PROP_MODIFIER_MASK:
|
||||
g_value_set_flags (value,
|
||||
eek_symbol_get_modifier_mask (EEK_SYMBOL(object)));
|
||||
break;
|
||||
case PROP_ICON_NAME:
|
||||
g_value_set_string (value,
|
||||
eek_symbol_get_icon_name (EEK_SYMBOL(object)));
|
||||
break;
|
||||
case PROP_TOOLTIP:
|
||||
g_value_set_string (value,
|
||||
eek_symbol_get_tooltip (EEK_SYMBOL(object)));
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
eek_symbol_finalize (GObject *object)
|
||||
{
|
||||
EekSymbol *self = EEK_SYMBOL (object);
|
||||
EekSymbolPrivate *priv = eek_symbol_get_instance_private (self);
|
||||
|
||||
g_free (priv->name);
|
||||
g_free (priv->label);
|
||||
g_free (priv->icon_name);
|
||||
g_free (priv->tooltip);
|
||||
G_OBJECT_CLASS (eek_symbol_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
eek_symbol_class_init (EekSymbolClass *klass)
|
||||
{
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||
GParamSpec *pspec;
|
||||
|
||||
gobject_class->set_property = eek_symbol_set_property;
|
||||
gobject_class->get_property = eek_symbol_get_property;
|
||||
gobject_class->finalize = eek_symbol_finalize;
|
||||
|
||||
pspec = g_param_spec_string ("name",
|
||||
"Name",
|
||||
"Canonical name of the symbol",
|
||||
NULL,
|
||||
G_PARAM_CONSTRUCT | G_PARAM_READWRITE);
|
||||
g_object_class_install_property (gobject_class, PROP_NAME, pspec);
|
||||
|
||||
pspec = g_param_spec_string ("label",
|
||||
"Label",
|
||||
"Text used to display the symbol",
|
||||
NULL,
|
||||
G_PARAM_CONSTRUCT | G_PARAM_READWRITE);
|
||||
g_object_class_install_property (gobject_class, PROP_LABEL, pspec);
|
||||
|
||||
pspec = g_param_spec_enum ("category",
|
||||
"Category",
|
||||
"Category of the symbol",
|
||||
EEK_TYPE_SYMBOL_CATEGORY,
|
||||
EEK_SYMBOL_CATEGORY_UNKNOWN,
|
||||
G_PARAM_CONSTRUCT | G_PARAM_READWRITE);
|
||||
g_object_class_install_property (gobject_class, PROP_CATEGORY, pspec);
|
||||
|
||||
pspec = g_param_spec_flags ("modifier-mask",
|
||||
"Modifier mask",
|
||||
"Modifier mask of the symbol",
|
||||
EEK_TYPE_MODIFIER_TYPE,
|
||||
0,
|
||||
G_PARAM_CONSTRUCT | G_PARAM_READWRITE);
|
||||
g_object_class_install_property (gobject_class, PROP_MODIFIER_MASK, pspec);
|
||||
|
||||
pspec = g_param_spec_string ("icon-name",
|
||||
"Icon name",
|
||||
"Icon name used to render the symbol",
|
||||
NULL,
|
||||
G_PARAM_CONSTRUCT | G_PARAM_READWRITE);
|
||||
g_object_class_install_property (gobject_class, PROP_ICON_NAME, pspec);
|
||||
|
||||
pspec = g_param_spec_string ("tooltip",
|
||||
"Tooltip",
|
||||
"Tooltip text",
|
||||
NULL,
|
||||
G_PARAM_CONSTRUCT | G_PARAM_READWRITE);
|
||||
g_object_class_install_property (gobject_class, PROP_TOOLTIP, pspec);
|
||||
}
|
||||
|
||||
static void
|
||||
eek_symbol_init (EekSymbol *self)
|
||||
{
|
||||
EekSymbolPrivate *priv = eek_symbol_get_instance_private (self);
|
||||
|
||||
priv->category = EEK_SYMBOL_CATEGORY_UNKNOWN;
|
||||
}
|
||||
|
||||
/**
|
||||
* eek_symbol_new:
|
||||
* @name: name of the symbol
|
||||
*
|
||||
* Create a new #EekSymbol with @name.
|
||||
*/
|
||||
EekSymbol *
|
||||
eek_symbol_new (const gchar *name)
|
||||
{
|
||||
return g_object_new (EEK_TYPE_SYMBOL, "name", name, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* eek_symbol_set_name:
|
||||
* @symbol: an #EekSymbol
|
||||
* @name: name of the symbol
|
||||
*
|
||||
* Set the name of @symbol to @name.
|
||||
*/
|
||||
void
|
||||
eek_symbol_set_name (EekSymbol *symbol,
|
||||
const gchar *name)
|
||||
{
|
||||
g_return_if_fail (EEK_IS_SYMBOL(symbol));
|
||||
|
||||
EekSymbolPrivate *priv = eek_symbol_get_instance_private (symbol);
|
||||
|
||||
g_free (priv->name);
|
||||
priv->name = g_strdup (name);
|
||||
}
|
||||
|
||||
/**
|
||||
* eek_symbol_get_name:
|
||||
* @symbol: an #EekSymbol
|
||||
*
|
||||
* Get the name of @symbol.
|
||||
*/
|
||||
const gchar *
|
||||
eek_symbol_get_name (EekSymbol *symbol)
|
||||
{
|
||||
g_return_val_if_fail (EEK_IS_SYMBOL(symbol), NULL);
|
||||
|
||||
EekSymbolPrivate *priv = eek_symbol_get_instance_private (symbol);
|
||||
|
||||
if (priv->name == NULL || *priv->name == '\0')
|
||||
return NULL;
|
||||
return priv->name;
|
||||
EekSymbol *self = g_new0(EekSymbol, 1);
|
||||
self->name = g_strdup (name);
|
||||
self->category = EEK_SYMBOL_CATEGORY_UNKNOWN;
|
||||
return self;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -307,64 +50,8 @@ void
|
||||
eek_symbol_set_label (EekSymbol *symbol,
|
||||
const gchar *label)
|
||||
{
|
||||
g_return_if_fail (EEK_IS_SYMBOL(symbol));
|
||||
|
||||
EekSymbolPrivate *priv = eek_symbol_get_instance_private (symbol);
|
||||
|
||||
g_free (priv->label);
|
||||
priv->label = g_strdup (label);
|
||||
}
|
||||
|
||||
/**
|
||||
* eek_symbol_get_label:
|
||||
* @symbol: an #EekSymbol
|
||||
*
|
||||
* Get the label text of @symbol.
|
||||
*/
|
||||
const gchar *
|
||||
eek_symbol_get_label (EekSymbol *symbol)
|
||||
{
|
||||
g_return_val_if_fail (EEK_IS_SYMBOL(symbol), NULL);
|
||||
|
||||
EekSymbolPrivate *priv = eek_symbol_get_instance_private (symbol);
|
||||
|
||||
if (priv->label == NULL || *priv->label == '\0')
|
||||
return NULL;
|
||||
return priv->label;
|
||||
}
|
||||
|
||||
/**
|
||||
* eek_symbol_set_category:
|
||||
* @symbol: an #EekSymbol
|
||||
* @category: an #EekSymbolCategory
|
||||
*
|
||||
* Set symbol category of @symbol to @category.
|
||||
*/
|
||||
void
|
||||
eek_symbol_set_category (EekSymbol *symbol,
|
||||
EekSymbolCategory category)
|
||||
{
|
||||
g_return_if_fail (EEK_IS_SYMBOL(symbol));
|
||||
|
||||
EekSymbolPrivate *priv = eek_symbol_get_instance_private (symbol);
|
||||
|
||||
priv->category = category;
|
||||
}
|
||||
|
||||
/**
|
||||
* eek_symbol_get_category:
|
||||
* @symbol: an #EekSymbol
|
||||
*
|
||||
* Get symbol category of @symbol.
|
||||
*/
|
||||
EekSymbolCategory
|
||||
eek_symbol_get_category (EekSymbol *symbol)
|
||||
{
|
||||
g_return_val_if_fail (EEK_IS_SYMBOL(symbol), EEK_SYMBOL_CATEGORY_UNKNOWN);
|
||||
|
||||
EekSymbolPrivate *priv = eek_symbol_get_instance_private (symbol);
|
||||
|
||||
return priv->category;
|
||||
g_free (symbol->label);
|
||||
symbol->label = g_strdup (label);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -378,11 +65,7 @@ void
|
||||
eek_symbol_set_modifier_mask (EekSymbol *symbol,
|
||||
EekModifierType mask)
|
||||
{
|
||||
g_return_if_fail (EEK_IS_SYMBOL(symbol));
|
||||
|
||||
EekSymbolPrivate *priv = eek_symbol_get_instance_private (symbol);
|
||||
|
||||
priv->modifier_mask = mask;
|
||||
symbol->modifier_mask = mask;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -394,131 +77,37 @@ eek_symbol_set_modifier_mask (EekSymbol *symbol,
|
||||
EekModifierType
|
||||
eek_symbol_get_modifier_mask (EekSymbol *symbol)
|
||||
{
|
||||
g_return_val_if_fail (EEK_IS_SYMBOL(symbol), 0);
|
||||
|
||||
EekSymbolPrivate *priv = eek_symbol_get_instance_private (symbol);
|
||||
|
||||
return priv->modifier_mask;
|
||||
return 0;
|
||||
return symbol->modifier_mask;
|
||||
}
|
||||
|
||||
/**
|
||||
* eek_symbol_is_modifier:
|
||||
* @symbol: an #EekSymbol
|
||||
*
|
||||
* Check if @symbol is a modifier.
|
||||
* Returns: %TRUE if @symbol is a modifier.
|
||||
*/
|
||||
gboolean
|
||||
eek_symbol_is_modifier (EekSymbol *symbol)
|
||||
{
|
||||
return eek_symbol_get_modifier_mask (symbol) != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* eek_symbol_set_icon_name:
|
||||
* @symbol: an #EekSymbol
|
||||
* @icon_name: icon name of @symbol
|
||||
*
|
||||
* Set the icon name of @symbol to @icon_name.
|
||||
*/
|
||||
void
|
||||
eek_symbol_set_icon_name (EekSymbol *symbol,
|
||||
const gchar *icon_name)
|
||||
{
|
||||
g_return_if_fail (EEK_IS_SYMBOL(symbol));
|
||||
|
||||
EekSymbolPrivate *priv = eek_symbol_get_instance_private (symbol);
|
||||
|
||||
g_free (priv->icon_name);
|
||||
priv->icon_name = g_strdup (icon_name);
|
||||
g_free (symbol->icon_name);
|
||||
symbol->icon_name = g_strdup (icon_name);
|
||||
}
|
||||
|
||||
/**
|
||||
* eek_symbol_get_icon_name:
|
||||
* @symbol: an #EekSymbol
|
||||
*
|
||||
* Get the icon name of @symbol.
|
||||
*/
|
||||
const gchar *
|
||||
eek_symbol_get_icon_name (EekSymbol *symbol)
|
||||
{
|
||||
g_return_val_if_fail (EEK_IS_SYMBOL(symbol), NULL);
|
||||
|
||||
EekSymbolPrivate *priv = eek_symbol_get_instance_private (symbol);
|
||||
|
||||
if (priv->icon_name == NULL || *priv->icon_name == '\0')
|
||||
return NULL;
|
||||
return priv->icon_name;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* eek_symbol_set_tooltip:
|
||||
* @symbol: an #EekSymbol
|
||||
* @tooltip: icon name of @symbol
|
||||
*
|
||||
* Set the tooltip text of @symbol to @tooltip.
|
||||
*/
|
||||
void
|
||||
eek_symbol_set_tooltip (EekSymbol *symbol,
|
||||
const gchar *tooltip)
|
||||
{
|
||||
g_return_if_fail (EEK_IS_SYMBOL(symbol));
|
||||
|
||||
EekSymbolPrivate *priv = eek_symbol_get_instance_private (symbol);
|
||||
|
||||
g_free (priv->tooltip);
|
||||
priv->tooltip = g_strdup (tooltip);
|
||||
g_free (symbol->tooltip);
|
||||
symbol->tooltip = g_strdup (tooltip);
|
||||
}
|
||||
|
||||
/**
|
||||
* eek_symbol_get_tooltip:
|
||||
* @symbol: an #EekSymbol
|
||||
*
|
||||
* Get the tooltip text of @symbol.
|
||||
*/
|
||||
const gchar *
|
||||
eek_symbol_get_tooltip (EekSymbol *symbol)
|
||||
{
|
||||
g_return_val_if_fail (EEK_IS_SYMBOL(symbol), NULL);
|
||||
|
||||
EekSymbolPrivate *priv = eek_symbol_get_instance_private (symbol);
|
||||
|
||||
if (priv->tooltip == NULL || *priv->tooltip == '\0')
|
||||
return NULL;
|
||||
return priv->tooltip;
|
||||
}
|
||||
|
||||
static const struct {
|
||||
EekSymbolCategory category;
|
||||
gchar *name;
|
||||
} category_names[] = {
|
||||
{ EEK_SYMBOL_CATEGORY_LETTER, "letter" },
|
||||
{ EEK_SYMBOL_CATEGORY_FUNCTION, "function" },
|
||||
{ EEK_SYMBOL_CATEGORY_KEYNAME, "keyname" },
|
||||
{ EEK_SYMBOL_CATEGORY_USER0, "user0" },
|
||||
{ EEK_SYMBOL_CATEGORY_USER1, "user1" },
|
||||
{ EEK_SYMBOL_CATEGORY_USER2, "user2" },
|
||||
{ EEK_SYMBOL_CATEGORY_USER3, "user3" },
|
||||
{ EEK_SYMBOL_CATEGORY_USER4, "user4" },
|
||||
{ EEK_SYMBOL_CATEGORY_UNKNOWN, NULL }
|
||||
};
|
||||
|
||||
const gchar *
|
||||
eek_symbol_category_get_name (EekSymbolCategory category)
|
||||
{
|
||||
gint i;
|
||||
for (i = 0; i < G_N_ELEMENTS(category_names); i++)
|
||||
if (category_names[i].category == category)
|
||||
return category_names[i].name;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
EekSymbolCategory
|
||||
eek_symbol_category_from_name (const gchar *name)
|
||||
{
|
||||
gint i;
|
||||
for (i = 0; i < G_N_ELEMENTS(category_names); i++)
|
||||
if (g_strcmp0 (category_names[i].name, name) == 0)
|
||||
return category_names[i].category;
|
||||
return EEK_SYMBOL_CATEGORY_UNKNOWN;
|
||||
if (symbol->tooltip == NULL || *symbol->tooltip == '\0')
|
||||
return NULL;
|
||||
return symbol->tooltip;
|
||||
}
|
||||
|
||||
100
eek/eek-symbol.h
100
eek/eek-symbol.h
@ -1,100 +0,0 @@
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#if !defined(__EEK_H_INSIDE__) && !defined(EEK_COMPILATION)
|
||||
#error "Only <eek/eek.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#ifndef EEK_SYMBOL_H
|
||||
#define EEK_SYMBOL_H 1
|
||||
|
||||
#include "eek-types.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
/**
|
||||
* EekSymbolCategory:
|
||||
* @EEK_SYMBOL_CATEGORY_LETTER: the symbol represents an alphabet letter
|
||||
* @EEK_SYMBOL_CATEGORY_FUNCTION: the symbol represents a function
|
||||
* @EEK_SYMBOL_CATEGORY_KEYNAME: the symbol does not have meaning but
|
||||
* have a name
|
||||
* @EEK_SYMBOL_CATEGORY_USER0: reserved for future use
|
||||
* @EEK_SYMBOL_CATEGORY_USER1: reserved for future use
|
||||
* @EEK_SYMBOL_CATEGORY_USER2: reserved for future use
|
||||
* @EEK_SYMBOL_CATEGORY_USER3: reserved for future use
|
||||
* @EEK_SYMBOL_CATEGORY_USER4: reserved for future use
|
||||
* @EEK_SYMBOL_CATEGORY_UNKNOWN: used for error reporting
|
||||
* @EEK_SYMBOL_CATEGORY_LAST: the last symbol category
|
||||
*
|
||||
* Category of the key symbols.
|
||||
*/
|
||||
typedef enum {
|
||||
EEK_SYMBOL_CATEGORY_LETTER,
|
||||
EEK_SYMBOL_CATEGORY_FUNCTION,
|
||||
EEK_SYMBOL_CATEGORY_KEYNAME,
|
||||
EEK_SYMBOL_CATEGORY_USER0,
|
||||
EEK_SYMBOL_CATEGORY_USER1,
|
||||
EEK_SYMBOL_CATEGORY_USER2,
|
||||
EEK_SYMBOL_CATEGORY_USER3,
|
||||
EEK_SYMBOL_CATEGORY_USER4,
|
||||
EEK_SYMBOL_CATEGORY_UNKNOWN,
|
||||
EEK_SYMBOL_CATEGORY_LAST = EEK_SYMBOL_CATEGORY_UNKNOWN
|
||||
} EekSymbolCategory;
|
||||
|
||||
#define EEK_TYPE_SYMBOL (eek_symbol_get_type())
|
||||
G_DECLARE_DERIVABLE_TYPE(EekSymbol, eek_symbol, EEK, SYMBOL, GObject)
|
||||
|
||||
/**
|
||||
* EekSymbolClass:
|
||||
*/
|
||||
struct _EekSymbolClass {
|
||||
/*< private >*/
|
||||
GObjectClass parent_class;
|
||||
};
|
||||
|
||||
GType eek_symbol_get_type (void) G_GNUC_CONST;
|
||||
|
||||
EekSymbol *eek_symbol_new (const gchar *name);
|
||||
void eek_symbol_set_name (EekSymbol *symbol,
|
||||
const gchar *name);
|
||||
const gchar *eek_symbol_get_name (EekSymbol *symbol);
|
||||
void eek_symbol_set_label (EekSymbol *symbol,
|
||||
const gchar *label);
|
||||
const gchar *eek_symbol_get_label (EekSymbol *symbol);
|
||||
void eek_symbol_set_category (EekSymbol *symbol,
|
||||
EekSymbolCategory category);
|
||||
EekSymbolCategory eek_symbol_get_category (EekSymbol *symbol);
|
||||
EekModifierType eek_symbol_get_modifier_mask (EekSymbol *symbol);
|
||||
void eek_symbol_set_modifier_mask (EekSymbol *symbol,
|
||||
EekModifierType mask);
|
||||
gboolean eek_symbol_is_modifier (EekSymbol *symbol);
|
||||
void eek_symbol_set_icon_name (EekSymbol *symbol,
|
||||
const gchar *icon_name);
|
||||
const gchar *eek_symbol_get_icon_name (EekSymbol *symbol);
|
||||
void eek_symbol_set_tooltip (EekSymbol *symbol,
|
||||
const gchar *tooltip);
|
||||
const gchar * eek_symbol_get_tooltip (EekSymbol *symbol);
|
||||
|
||||
const gchar *eek_symbol_category_get_name (EekSymbolCategory category);
|
||||
EekSymbolCategory eek_symbol_category_from_name (const gchar *name);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* EEK_SYMBOL_H */
|
||||
187
eek/eek-text.c
187
eek/eek-text.c
@ -1,187 +0,0 @@
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
/**
|
||||
* SECTION:eek-text
|
||||
* @short_description: an #EekText represents a text symbol
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
|
||||
#include "eek-text.h"
|
||||
#include "eek-serializable.h"
|
||||
|
||||
enum {
|
||||
PROP_0,
|
||||
PROP_TEXT,
|
||||
PROP_LAST
|
||||
};
|
||||
|
||||
typedef struct _EekTextPrivate
|
||||
{
|
||||
gchar *text;
|
||||
} EekTextPrivate;
|
||||
|
||||
static void eek_serializable_iface_init (EekSerializableIface *iface);
|
||||
|
||||
G_DEFINE_TYPE_EXTENDED (EekText,
|
||||
eek_text,
|
||||
EEK_TYPE_SYMBOL,
|
||||
0, /* GTypeFlags */
|
||||
G_ADD_PRIVATE (EekText)
|
||||
G_IMPLEMENT_INTERFACE (EEK_TYPE_SERIALIZABLE,
|
||||
eek_serializable_iface_init))
|
||||
|
||||
static EekSerializableIface *eek_text_parent_serializable_iface;
|
||||
|
||||
static void
|
||||
eek_text_real_serialize (EekSerializable *self,
|
||||
GVariantBuilder *builder)
|
||||
{
|
||||
EekTextPrivate *priv = eek_text_get_instance_private (EEK_TEXT (self));
|
||||
|
||||
eek_text_parent_serializable_iface->serialize (self, builder);
|
||||
|
||||
g_variant_builder_add (builder, "s", priv->text);
|
||||
}
|
||||
|
||||
static gsize
|
||||
eek_text_real_deserialize (EekSerializable *self,
|
||||
GVariant *variant,
|
||||
gsize index)
|
||||
{
|
||||
EekTextPrivate *priv = eek_text_get_instance_private (EEK_TEXT (self));
|
||||
|
||||
index = eek_text_parent_serializable_iface->deserialize (self,
|
||||
variant,
|
||||
index);
|
||||
g_variant_get_child (variant, index++, "s", &priv->text);
|
||||
|
||||
return index;
|
||||
}
|
||||
|
||||
static void
|
||||
eek_serializable_iface_init (EekSerializableIface *iface)
|
||||
{
|
||||
eek_text_parent_serializable_iface =
|
||||
g_type_interface_peek_parent (iface);
|
||||
|
||||
iface->serialize = eek_text_real_serialize;
|
||||
iface->deserialize = eek_text_real_deserialize;
|
||||
}
|
||||
|
||||
static void
|
||||
eek_text_set_property (GObject *object,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
EekText *self = EEK_TEXT (object);
|
||||
EekTextPrivate *priv = eek_text_get_instance_private (self);
|
||||
|
||||
switch (prop_id) {
|
||||
case PROP_TEXT:
|
||||
g_free (priv->text);
|
||||
priv->text = g_strdup (g_value_get_string (value));
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
eek_text_get_property (GObject *object,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
EekText *self = EEK_TEXT (object);
|
||||
EekTextPrivate *priv = eek_text_get_instance_private (self);
|
||||
|
||||
switch (prop_id) {
|
||||
case PROP_TEXT:
|
||||
g_value_set_string (value, priv->text);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
eek_text_finalize (GObject *object)
|
||||
{
|
||||
EekText *self = EEK_TEXT (object);
|
||||
EekTextPrivate *priv = eek_text_get_instance_private (self);
|
||||
|
||||
g_free (priv->text);
|
||||
G_OBJECT_CLASS (eek_text_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
eek_text_class_init (EekTextClass *klass)
|
||||
{
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||
GParamSpec *pspec;
|
||||
|
||||
gobject_class->set_property = eek_text_set_property;
|
||||
gobject_class->get_property = eek_text_get_property;
|
||||
gobject_class->finalize = eek_text_finalize;
|
||||
|
||||
pspec = g_param_spec_string ("text",
|
||||
"Text",
|
||||
"Text",
|
||||
NULL,
|
||||
G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE);
|
||||
g_object_class_install_property (gobject_class, PROP_TEXT, pspec);
|
||||
}
|
||||
|
||||
static void
|
||||
eek_text_init (EekText *self)
|
||||
{
|
||||
/* void */
|
||||
}
|
||||
|
||||
EekText *
|
||||
eek_text_new (const gchar *text)
|
||||
{
|
||||
return g_object_new (EEK_TYPE_TEXT,
|
||||
"label", text,
|
||||
"category", EEK_SYMBOL_CATEGORY_FUNCTION,
|
||||
"text", text,
|
||||
NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* eek_text_get_text:
|
||||
* @text: an #EekText
|
||||
*
|
||||
* Get a text value associated with @text
|
||||
*/
|
||||
const gchar *
|
||||
eek_text_get_text (EekText *text)
|
||||
{
|
||||
EekTextPrivate *priv = eek_text_get_instance_private (text);
|
||||
|
||||
return priv->text;
|
||||
}
|
||||
@ -1,46 +0,0 @@
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#if !defined(__EEK_H_INSIDE__) && !defined(EEK_COMPILATION)
|
||||
#error "Only <eek/eek.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#ifndef EEK_TEXT_H
|
||||
#define EEK_TEXT_H 1
|
||||
|
||||
#include "eek-symbol.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define EEK_TYPE_TEXT (eek_text_get_type())
|
||||
G_DECLARE_DERIVABLE_TYPE(EekText, eek_text, EEK, TEXT, EekSymbol)
|
||||
|
||||
struct _EekTextClass {
|
||||
/*< private >*/
|
||||
EekSymbolClass parent_class;
|
||||
};
|
||||
|
||||
GType eek_text_get_type (void) G_GNUC_CONST;
|
||||
EekText *eek_text_new (const gchar *text);
|
||||
const gchar *eek_text_get_text (EekText *text);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* EEK_TEXT_H */
|
||||
@ -1,289 +0,0 @@
|
||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; c-basic-offset: 2; -*- */
|
||||
/*
|
||||
* eek-theme-context.c: holds global information about a tree of styled objects
|
||||
*
|
||||
* Copyright 2009, 2010 Red Hat, Inc.
|
||||
* Copyright 2009 Florian Müllner
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation, either version 2.1 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT ANY
|
||||
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#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;
|
||||
}
|
||||
@ -1,78 +0,0 @@
|
||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
||||
/*
|
||||
* eek-theme-context.c: holds global information about a tree of styled objects
|
||||
*
|
||||
* Copyright 2009, 2010 Red Hat, Inc.
|
||||
* Copyright 2009 Florian Müllner
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation, either version 2.1 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT ANY
|
||||
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __EEK_THEME_CONTEXT_H__
|
||||
#define __EEK_THEME_CONTEXT_H__
|
||||
|
||||
#include <pango/pango.h>
|
||||
#include "eek-theme-node.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
/**
|
||||
* SECTION:eek-theme-context
|
||||
* @short_description: holds global information about a tree of styled objects
|
||||
*
|
||||
* #EekThemeContext is responsible for managing information global to
|
||||
* a tree of styled objects, such as the set of stylesheets or the
|
||||
* default font.
|
||||
*/
|
||||
|
||||
typedef struct _EekThemeContextClass EekThemeContextClass;
|
||||
|
||||
#define EEK_TYPE_THEME_CONTEXT (eek_theme_context_get_type ())
|
||||
#define EEK_THEME_CONTEXT(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), EEK_TYPE_THEME_CONTEXT, EekThemeContext))
|
||||
#define EEK_THEME_CONTEXT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EEK_TYPE_THEME_CONTEXT, EekThemeContextClass))
|
||||
#define EEK_IS_THEME_CONTEXT(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), EEK_TYPE_THEME_CONTEXT))
|
||||
#define EEK_IS_THEME_CONTEXT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EEK_TYPE_THEME_CONTEXT))
|
||||
#define EEK_THEME_CONTEXT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EEK_TYPE_THEME_CONTEXT, EekThemeContextClass))
|
||||
|
||||
GType eek_theme_context_get_type
|
||||
(void) G_GNUC_CONST;
|
||||
|
||||
EekThemeContext *eek_theme_context_new
|
||||
(void);
|
||||
|
||||
void eek_theme_context_set_theme
|
||||
(EekThemeContext *context,
|
||||
EekTheme *theme);
|
||||
EekTheme * eek_theme_context_get_theme
|
||||
(EekThemeContext *context);
|
||||
|
||||
void eek_theme_context_set_resolution
|
||||
(EekThemeContext *context,
|
||||
gdouble resolution);
|
||||
void eek_theme_context_set_default_resolution
|
||||
(EekThemeContext *context);
|
||||
double eek_theme_context_get_resolution
|
||||
(EekThemeContext *context);
|
||||
void eek_theme_context_set_font
|
||||
(EekThemeContext *context,
|
||||
const PangoFontDescription *font);
|
||||
const PangoFontDescription *eek_theme_context_get_font
|
||||
(EekThemeContext *context);
|
||||
|
||||
EekThemeNode * eek_theme_context_get_root_node
|
||||
(EekThemeContext *context);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __EEK_THEME_CONTEXT_H__ */
|
||||
1866
eek/eek-theme-node.c
1866
eek/eek-theme-node.c
File diff suppressed because it is too large
Load Diff
@ -1,141 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2011 Daiki Ueno <ueno@unixuser.org>
|
||||
* Copyright (C) 2010-2011 Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public License
|
||||
* as published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
* 02110-1301 USA
|
||||
*/
|
||||
#ifndef __EEK_THEME_NODE_H__
|
||||
#define __EEK_THEME_NODE_H__
|
||||
|
||||
#include <pango/pango.h>
|
||||
#include "eek-types.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
/**
|
||||
* SECTION:eek-theme-node
|
||||
* @short_description: style information for one node in a tree of
|
||||
* themed objects
|
||||
*
|
||||
* The #EekThemeNode class represents the CSS style information (the
|
||||
* set of CSS properties) for one node in a tree of themed objects. In
|
||||
* typical usage, it represents the style information for a single
|
||||
* #EekElement. A #EekThemeNode is immutable: attributes such as the
|
||||
* CSS classes for the node are passed in at construction. If the
|
||||
* attributes of the node or any parent node change, the node should
|
||||
* be discarded and a new node created. #EekThemeNode has generic
|
||||
* accessors to look up properties by name and specific accessors for
|
||||
* standard CSS properties that add caching and handling of various
|
||||
* details of the CSS specification. #EekThemeNode also has
|
||||
* convenience functions to help in implementing a #EekElement with
|
||||
* borders and padding.
|
||||
*/
|
||||
|
||||
typedef enum {
|
||||
EEK_SIDE_TOP,
|
||||
EEK_SIDE_RIGHT,
|
||||
EEK_SIDE_BOTTOM,
|
||||
EEK_SIDE_LEFT
|
||||
} EekSide;
|
||||
|
||||
typedef enum {
|
||||
EEK_CORNER_TOPLEFT,
|
||||
EEK_CORNER_TOPRIGHT,
|
||||
EEK_CORNER_BOTTOMRIGHT,
|
||||
EEK_CORNER_BOTTOMLEFT
|
||||
} EekCorner;
|
||||
|
||||
#define EEK_TYPE_THEME_NODE (eek_theme_node_get_type())
|
||||
#define EEK_THEME_NODE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EEK_TYPE_THEME_NODE, EekThemeNode))
|
||||
#define EEK_THEME_NODE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EEK_TYPE_THEME_NODE, EekThemeNodeClass))
|
||||
#define EEK_IS_THEME_NODE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EEK_TYPE_THEME_NODE))
|
||||
#define EEK_IS_THEME_NODE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EEK_TYPE_THEME_NODE))
|
||||
#define EEK_THEME_NODE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EEK_TYPE_THEME_NODE, EekThemeNodeClass))
|
||||
|
||||
typedef struct _EekThemeNodeClass EekThemeNodeClass;
|
||||
typedef struct _EekThemeNodePrivate EekThemeNodePrivate;
|
||||
|
||||
GType eek_theme_node_get_type
|
||||
(void) G_GNUC_CONST;
|
||||
|
||||
EekThemeNode *eek_theme_node_new (EekThemeContext *context,
|
||||
EekThemeNode *parent_node,
|
||||
/* can be null */ EekTheme *theme,
|
||||
/* can be null */ GType element_type,
|
||||
const char *element_id,
|
||||
const char *element_class,
|
||||
const char *pseudo_class,
|
||||
const char *inline_style);
|
||||
|
||||
EekThemeNode *eek_theme_node_get_parent
|
||||
(EekThemeNode *node);
|
||||
|
||||
EekTheme *eek_theme_node_get_theme
|
||||
(EekThemeNode *node);
|
||||
|
||||
GType eek_theme_node_get_element_type
|
||||
(EekThemeNode *node);
|
||||
const char *eek_theme_node_get_element_id
|
||||
(EekThemeNode *node);
|
||||
const char *eek_theme_node_get_element_class
|
||||
(EekThemeNode *node);
|
||||
const char *eek_theme_node_get_pseudo_class
|
||||
(EekThemeNode *node);
|
||||
|
||||
/* Generic getters ... these are not cached so are less efficient. The other
|
||||
* reason for adding the more specific version is that we can handle the
|
||||
* details of the actual CSS rules, which can be complicated, especially
|
||||
* for fonts
|
||||
*/
|
||||
void eek_theme_node_get_color
|
||||
(EekThemeNode *node,
|
||||
const char *property_name,
|
||||
EekColor *color);
|
||||
|
||||
/* Specific getters for particular properties: cached
|
||||
*/
|
||||
void eek_theme_node_get_background_color
|
||||
(EekThemeNode *node,
|
||||
EekColor *color);
|
||||
void eek_theme_node_get_foreground_color
|
||||
(EekThemeNode *node,
|
||||
EekColor *color);
|
||||
void eek_theme_node_get_background_gradient
|
||||
(EekThemeNode *node,
|
||||
EekGradientType *type,
|
||||
EekColor *start,
|
||||
EekColor *end);
|
||||
int eek_theme_node_get_border_width
|
||||
(EekThemeNode *node,
|
||||
EekSide side);
|
||||
int eek_theme_node_get_border_radius
|
||||
(EekThemeNode *node,
|
||||
EekCorner corner);
|
||||
void eek_theme_node_get_border_color
|
||||
(EekThemeNode *node,
|
||||
EekSide side,
|
||||
EekColor *color);
|
||||
|
||||
/* Font rule processing is pretty complicated, so we just hardcode it
|
||||
* under the standard font/font-family/font-size/etc names. This means
|
||||
* you can't have multiple separate styled fonts for a single item,
|
||||
* but that should be OK.
|
||||
*/
|
||||
const PangoFontDescription *eek_theme_node_get_font (EekThemeNode *node);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __EEK_THEME_NODE_H__ */
|
||||
@ -1,22 +0,0 @@
|
||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
||||
#ifndef __EEK_THEME_PRIVATE_H__
|
||||
#define __EEK_THEME_PRIVATE_H__
|
||||
|
||||
#include <libcroco/libcroco.h>
|
||||
#include "eek-theme.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
GPtrArray *_eek_theme_get_matched_properties (EekTheme *theme,
|
||||
EekThemeNode *node);
|
||||
|
||||
/* Resolve an URL from the stylesheet to a filename */
|
||||
char *_eek_theme_resolve_url (EekTheme *theme,
|
||||
CRStyleSheet *base_stylesheet,
|
||||
const char *url);
|
||||
|
||||
CRDeclaration *_eek_theme_parse_declaration_list (const char *str);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __EEK_THEME_PRIVATE_H__ */
|
||||
1095
eek/eek-theme.c
1095
eek/eek-theme.c
File diff suppressed because it is too large
Load Diff
@ -1,49 +0,0 @@
|
||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
||||
|
||||
#if !defined(__EEK_H_INSIDE__) && !defined(EEK_COMPILATION)
|
||||
#error "Only <eek/eek.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#ifndef __EEK_THEME_H__
|
||||
#define __EEK_THEME_H__
|
||||
|
||||
#include <glib-object.h>
|
||||
|
||||
#include "eek-types.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
/**
|
||||
* SECTION:EekTheme
|
||||
* @short_description: a set of stylesheets
|
||||
*
|
||||
* #EekTheme holds a set of stylesheets. (The "cascade" of the name
|
||||
* Cascading Stylesheets.) An #EekTheme can be set to apply to all the
|
||||
* keyboard elements.
|
||||
*/
|
||||
|
||||
typedef struct _EekThemeClass EekThemeClass;
|
||||
|
||||
#define EEK_TYPE_THEME (eek_theme_get_type())
|
||||
#define EEK_THEME(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EEK_TYPE_THEME, EekTheme))
|
||||
#define EEK_THEME_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EEK_TYPE_THEME, EekThemeClass))
|
||||
#define EEK_IS_THEME(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EEK_TYPE_THEME))
|
||||
#define EEK_IS_THEME_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EEK_TYPE_THEME))
|
||||
#define EEK_THEME_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EEK_TYPE_THEME, EekThemeClass))
|
||||
|
||||
GType eek_theme_get_type (void) G_GNUC_CONST;
|
||||
|
||||
EekTheme *eek_theme_new (const char *application_stylesheet,
|
||||
const char *theme_stylesheet,
|
||||
const char *default_stylesheet);
|
||||
|
||||
gboolean eek_theme_load_stylesheet (EekTheme *theme,
|
||||
const char *path,
|
||||
GError **error);
|
||||
|
||||
void eek_theme_unload_stylesheet (EekTheme *theme,
|
||||
const char *path);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __EEK_THEME_H__ */
|
||||
@ -24,9 +24,7 @@
|
||||
* @short_description: Miscellaneous types used in Libeek
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
|
||||
@ -134,12 +134,7 @@ typedef enum
|
||||
#define EEK_INVALID_KEYCODE (0)
|
||||
|
||||
typedef struct _EekElement EekElement;
|
||||
typedef struct _EekContainer EekContainer;
|
||||
typedef struct _EekKey EekKey;
|
||||
typedef struct _EekSection EekSection;
|
||||
typedef struct _EekKeyboard EekKeyboard;
|
||||
typedef struct _EekSymbol EekSymbol;
|
||||
typedef struct _EekKeysym EekKeysym;
|
||||
typedef struct _EekText EekText;
|
||||
typedef struct _EekTheme EekTheme;
|
||||
typedef struct _EekThemeContext EekThemeContext;
|
||||
@ -151,6 +146,7 @@ typedef struct _EekOutline EekOutline;
|
||||
typedef struct _EekColor EekColor;
|
||||
|
||||
typedef struct _EekboardContextService EekboardContextService;
|
||||
typedef struct _LevelKeyboard LevelKeyboard;
|
||||
|
||||
/**
|
||||
* EekPoint:
|
||||
@ -195,12 +191,6 @@ GType eek_bounds_get_type (void) G_GNUC_CONST;
|
||||
EekBounds *eek_bounds_copy (const EekBounds *bounds);
|
||||
void eek_bounds_free (EekBounds *bounds);
|
||||
|
||||
G_INLINE_FUNC gdouble
|
||||
eek_bounds_long_side (EekBounds *bounds)
|
||||
{
|
||||
return bounds->width > bounds->height ? bounds->width : bounds->height;
|
||||
}
|
||||
|
||||
/**
|
||||
* EekOutline:
|
||||
* @corner_radius: radius of corners of rounded polygon
|
||||
|
||||
@ -1,30 +0,0 @@
|
||||
# Copyright (C) 2010-2011 Daiki Ueno <ueno@unixuser.org>
|
||||
# Copyright (C) 2010-2011 Red Hat, Inc.
|
||||
|
||||
# This library is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU Lesser General Public License
|
||||
# as published by the Free Software Foundation; either version 2 of
|
||||
# the License, or (at your option) any later version.
|
||||
|
||||
# This library is distributed in the hope that it will be useful, but
|
||||
# WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
# Lesser General Public License for more details.
|
||||
|
||||
# You should have received a copy of the GNU Lesser General Public
|
||||
# License along with this library; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
# 02110-1301 USA
|
||||
|
||||
prefix=@prefix@
|
||||
exec_prefix=@exec_prefix@
|
||||
libdir=@libdir@
|
||||
includedir=@includedir@
|
||||
|
||||
Name: libeek-xkb
|
||||
Description: A Library to Create Keyboard-like UI (XKB Support)
|
||||
URL: http://fedorahosted.org/eekboard/
|
||||
Version: @VERSION@
|
||||
Requires: eek-@EEK_API_VERSION@ gtk+-x11-@GTK_API_VERSION@
|
||||
Libs: -L${libdir} -leek-xkb
|
||||
Cflags: -I${includedir}/eek-@EEK_API_VERSION@
|
||||
@ -1,684 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2006 Sergey V. Udaltsov <svu@gnome.org>
|
||||
* Copyright (C) 2010-2011 Daiki Ueno <ueno@unixuser.org>
|
||||
* Copyright (C) 2010-2011 Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public License
|
||||
* as published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
* 02110-1301 USA
|
||||
*/
|
||||
|
||||
/**
|
||||
* SECTION:eek-xkb-layout
|
||||
* @short_description: Layout engine using XKB configuration
|
||||
*
|
||||
* The #EekXkbLayout inherits #EekLayout class and arranges keyboard
|
||||
* elements using XKB.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
|
||||
#include "eek-xkb-layout.h"
|
||||
|
||||
#include <X11/keysym.h>
|
||||
#include <X11/extensions/XKBgeom.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
#include <gio/gio.h>
|
||||
|
||||
#include "eek-keyboard.h"
|
||||
#include "eek-section.h"
|
||||
#include "eek-key.h"
|
||||
#include "eek-keysym.h"
|
||||
|
||||
#define XKB_COMPONENT_MASK (XkbGBN_GeometryMask | \
|
||||
XkbGBN_KeyNamesMask | \
|
||||
XkbGBN_OtherNamesMask | \
|
||||
XkbGBN_SymbolsMask | \
|
||||
XkbGBN_IndicatorMapMask)
|
||||
|
||||
static void initable_iface_init (GInitableIface *initable_iface);
|
||||
|
||||
enum {
|
||||
PROP_0,
|
||||
PROP_DISPLAY,
|
||||
PROP_LAST
|
||||
};
|
||||
|
||||
typedef struct _EekXkbLayoutPrivate
|
||||
{
|
||||
/* Configuration names that should synch'ed to the symbolic names
|
||||
in priv->xkb->names. Since we use GLib's memory allocator,
|
||||
don't store any address returned from the X server here. */
|
||||
XkbComponentNamesRec names;
|
||||
|
||||
Display *display;
|
||||
|
||||
/* Actual XKB configuration of DISPLAY. */
|
||||
XkbDescRec *xkb;
|
||||
|
||||
/* Hash table to cache orefs by shape address. */
|
||||
GHashTable *shape_oref_hash;
|
||||
|
||||
gint scale_numerator;
|
||||
gint scale_denominator;
|
||||
} EekXkbLayoutPrivate;
|
||||
|
||||
G_DEFINE_TYPE_EXTENDED (EekXkbLayout, eek_xkb_layout, EEK_TYPE_LAYOUT,
|
||||
0, /* GTypeFlags */
|
||||
G_ADD_PRIVATE(EekXkbLayout)
|
||||
G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE,
|
||||
initable_iface_init))
|
||||
|
||||
static guint find_keycode (EekXkbLayout *layout,
|
||||
gchar *key_name);
|
||||
|
||||
static gboolean get_keyboard_from_server (EekXkbLayout *layout,
|
||||
GError **error);
|
||||
|
||||
static gboolean get_names_from_server (EekXkbLayout *layout,
|
||||
GError **error);
|
||||
|
||||
static void setup_scaling (EekXkbLayout *layout,
|
||||
gdouble width,
|
||||
gdouble height);
|
||||
|
||||
G_INLINE_FUNC gint
|
||||
xkb_to_pixmap_coord (EekXkbLayout *layout,
|
||||
gint n)
|
||||
{
|
||||
EekXkbLayoutPrivate *priv = eek_xkb_layout_get_instance_private (layout);
|
||||
return n * priv->scale_numerator / priv->scale_denominator;
|
||||
}
|
||||
|
||||
G_INLINE_FUNC gdouble
|
||||
xkb_to_pixmap_double (EekXkbLayout *layout,
|
||||
gdouble d)
|
||||
{
|
||||
EekXkbLayoutPrivate *priv = eek_xkb_layout_get_instance_private (layout);
|
||||
return d * priv->scale_numerator / priv->scale_denominator;
|
||||
}
|
||||
|
||||
static void
|
||||
create_key (EekXkbLayout *layout,
|
||||
EekKeyboard *keyboard,
|
||||
EekSection *section,
|
||||
gint column,
|
||||
gint row,
|
||||
gdouble x,
|
||||
gdouble y,
|
||||
XkbKeyRec *xkbkey)
|
||||
{
|
||||
XkbGeometryRec *xkbgeometry;
|
||||
XkbBoundsRec *xkbbounds;
|
||||
XkbShapeRec *xkbshape;
|
||||
XkbOutlineRec *xkboutline;
|
||||
EekXkbLayoutPrivate *priv = eek_xkb_layout_get_instance_private (layout);
|
||||
EekKey *key;
|
||||
EekBounds bounds;
|
||||
EekSymbolMatrix *matrix = NULL;
|
||||
gchar name[XkbKeyNameLength + 1];
|
||||
KeyCode keycode;
|
||||
gint num_groups, num_levels;
|
||||
guint oref;
|
||||
gpointer v;
|
||||
|
||||
xkbgeometry = priv->xkb->geom;
|
||||
xkbshape = &xkbgeometry->shapes[xkbkey->shape_ndx];
|
||||
if (g_hash_table_lookup_extended (priv->shape_oref_hash, xkbshape,
|
||||
NULL, &v)) {
|
||||
oref = GPOINTER_TO_UINT(v);
|
||||
} else {
|
||||
EekOutline *outline;
|
||||
|
||||
xkboutline = xkbshape->primary == NULL ? &xkbshape->outlines[0] :
|
||||
xkbshape->primary;
|
||||
|
||||
outline = g_slice_new (EekOutline);
|
||||
outline->corner_radius = xkb_to_pixmap_coord(layout,
|
||||
xkboutline->corner_radius);
|
||||
|
||||
if (xkboutline->num_points <= 2) { /* rectangular */
|
||||
gdouble x1, y1, x2, y2;
|
||||
|
||||
outline->num_points = 4;
|
||||
outline->points = g_slice_alloc0 (sizeof (EekPoint) *
|
||||
outline->num_points);
|
||||
if (xkboutline->num_points == 1) {
|
||||
x1 = xkb_to_pixmap_coord(layout, xkbshape->bounds.x1);
|
||||
y1 = xkb_to_pixmap_coord(layout, xkbshape->bounds.y1);
|
||||
x2 = xkb_to_pixmap_coord(layout, xkboutline->points[0].x);
|
||||
y2 = xkb_to_pixmap_coord(layout, xkboutline->points[0].y);
|
||||
} else {
|
||||
x1 = xkb_to_pixmap_coord(layout, xkboutline->points[0].x);
|
||||
y1 = xkb_to_pixmap_coord(layout, xkboutline->points[0].y);
|
||||
x2 = xkb_to_pixmap_coord(layout, xkboutline->points[1].x);
|
||||
y2 = xkb_to_pixmap_coord(layout, xkboutline->points[1].y);
|
||||
}
|
||||
outline->points[0].x = outline->points[3].x = x1;
|
||||
outline->points[0].y = outline->points[1].y = y1;
|
||||
outline->points[1].x = outline->points[2].x = x2;
|
||||
outline->points[2].y = outline->points[3].y = y2;
|
||||
} else { /* polygon */
|
||||
gint i;
|
||||
|
||||
outline->num_points = xkboutline->num_points;
|
||||
outline->points = g_new0 (EekPoint, outline->num_points);
|
||||
for (i = 0; i < xkboutline->num_points; i++) {
|
||||
outline->points[i].x =
|
||||
xkb_to_pixmap_coord(layout, xkboutline->points[i].x);
|
||||
outline->points[i].y =
|
||||
xkb_to_pixmap_coord(layout, xkboutline->points[i].y);
|
||||
}
|
||||
}
|
||||
oref = eek_keyboard_add_outline (keyboard, outline);
|
||||
eek_outline_free (outline);
|
||||
g_hash_table_insert (priv->shape_oref_hash, xkbshape,
|
||||
GUINT_TO_POINTER(oref));
|
||||
}
|
||||
|
||||
memset (name, 0, sizeof name);
|
||||
memcpy (name, xkbkey->name.name, sizeof name - 1);
|
||||
|
||||
xkbbounds = &xkbgeometry->shapes[xkbkey->shape_ndx].bounds;
|
||||
bounds.x = xkb_to_pixmap_coord(layout, xkbbounds->x1 + x);
|
||||
bounds.y = xkb_to_pixmap_coord(layout, xkbbounds->y1 + y);
|
||||
bounds.width = xkb_to_pixmap_coord(layout, xkbbounds->x2 - xkbbounds->x1);
|
||||
bounds.height = xkb_to_pixmap_coord(layout, xkbbounds->y2 - xkbbounds->y1);
|
||||
|
||||
keycode = find_keycode (layout, name);
|
||||
if (keycode == EEK_INVALID_KEYCODE) {
|
||||
num_groups = num_levels = 0;
|
||||
matrix = eek_symbol_matrix_new (0, 0);
|
||||
} else {
|
||||
KeySym keysym;
|
||||
gint i, j;
|
||||
|
||||
num_groups = XkbKeyNumGroups (priv->xkb, keycode);
|
||||
num_levels = XkbKeyGroupsWidth (priv->xkb, keycode);
|
||||
matrix = eek_symbol_matrix_new (num_groups, num_levels);
|
||||
for (i = 0; i < num_groups; i++)
|
||||
for (j = 0; j < num_levels; j++) {
|
||||
EekModifierType modifier;
|
||||
|
||||
keysym = XkbKeySymEntry (priv->xkb, keycode, j, i);
|
||||
modifier = XkbKeysymToModifiers (priv->display, keysym);
|
||||
matrix->data[i * num_levels + j] =
|
||||
EEK_SYMBOL(eek_keysym_new_with_modifier (keysym,
|
||||
modifier));
|
||||
}
|
||||
}
|
||||
|
||||
key = eek_section_create_key (section, keycode, column, row);
|
||||
eek_element_set_name (EEK_ELEMENT(key), name);
|
||||
eek_element_set_bounds (EEK_ELEMENT(key), &bounds);
|
||||
eek_key_set_symbol_matrix (key, matrix);
|
||||
eek_symbol_matrix_free (matrix);
|
||||
eek_key_set_oref (key, oref);
|
||||
}
|
||||
|
||||
static void
|
||||
create_section (EekXkbLayout *layout,
|
||||
EekKeyboard *keyboard,
|
||||
XkbSectionRec *xkbsection)
|
||||
{
|
||||
XkbGeometryRec *xkbgeometry;
|
||||
EekXkbLayoutPrivate *priv = eek_xkb_layout_get_instance_private (layout);
|
||||
EekSection *section;
|
||||
EekBounds bounds;
|
||||
gchar *name;
|
||||
gfloat left, top;
|
||||
gint i, j;
|
||||
|
||||
bounds.x = xkb_to_pixmap_coord(layout, xkbsection->left);
|
||||
bounds.y = xkb_to_pixmap_coord(layout, xkbsection->top);
|
||||
bounds.width = xkb_to_pixmap_coord(layout, xkbsection->width);
|
||||
bounds.height = xkb_to_pixmap_coord(layout, xkbsection->height);
|
||||
|
||||
xkbgeometry = priv->xkb->geom;
|
||||
section = eek_keyboard_create_section (keyboard);
|
||||
name = XGetAtomName (priv->display, xkbsection->name);
|
||||
eek_element_set_name (EEK_ELEMENT(section), name);
|
||||
XFree (name);
|
||||
eek_element_set_bounds (EEK_ELEMENT(section), &bounds);
|
||||
eek_section_set_angle (section,
|
||||
/* angle is in tenth of degree */
|
||||
xkbsection->angle / 10);
|
||||
|
||||
for (i = 0; i < xkbsection->num_rows; i++) {
|
||||
XkbRowRec *xkbrow;
|
||||
|
||||
xkbrow = &xkbsection->rows[i];
|
||||
left = xkbrow->left;
|
||||
top = xkbrow->top;
|
||||
eek_section_add_row (section,
|
||||
xkbrow->num_keys,
|
||||
xkbrow->vertical ?
|
||||
EEK_ORIENTATION_VERTICAL :
|
||||
EEK_ORIENTATION_HORIZONTAL);
|
||||
for (j = 0; j < xkbrow->num_keys; j++) {
|
||||
XkbKeyRec *xkbkey;
|
||||
XkbBoundsRec *xkbbounds;
|
||||
|
||||
xkbkey = &xkbrow->keys[j];
|
||||
if (xkbrow->vertical)
|
||||
top += xkbkey->gap;
|
||||
else
|
||||
left += xkbkey->gap;
|
||||
create_key (layout, keyboard, section, j, i, left, top, xkbkey);
|
||||
xkbbounds = &xkbgeometry->shapes[xkbkey->shape_ndx].bounds;
|
||||
if (xkbrow->vertical)
|
||||
top += xkbbounds->y2 - xkbbounds->y1;
|
||||
else
|
||||
left += xkbbounds->x2 - xkbbounds->x1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
create_keyboard (EekXkbLayout *layout, EekKeyboard *keyboard)
|
||||
{
|
||||
EekXkbLayoutPrivate *priv = eek_xkb_layout_get_instance_private (layout);
|
||||
XkbGeometryRec *xkbgeometry;
|
||||
EekBounds bounds;
|
||||
gint i;
|
||||
|
||||
g_return_if_fail (priv->xkb);
|
||||
g_return_if_fail (priv->xkb->geom);
|
||||
|
||||
xkbgeometry = priv->xkb->geom;
|
||||
|
||||
eek_element_get_bounds (EEK_ELEMENT(keyboard), &bounds);
|
||||
setup_scaling (EEK_XKB_LAYOUT(layout), bounds.width, bounds.height);
|
||||
|
||||
bounds.x = bounds.y = 0;
|
||||
bounds.width = xkb_to_pixmap_coord(layout, xkbgeometry->width_mm);
|
||||
bounds.height = xkb_to_pixmap_coord(layout, xkbgeometry->height_mm);
|
||||
|
||||
for (i = 0; i < xkbgeometry->num_sections; i++) {
|
||||
XkbSectionRec *xkbsection;
|
||||
|
||||
xkbsection = &xkbgeometry->sections[i];
|
||||
create_section (layout, keyboard, xkbsection);
|
||||
}
|
||||
eek_element_set_bounds (EEK_ELEMENT(keyboard), &bounds);
|
||||
}
|
||||
|
||||
static EekKeyboard *
|
||||
eek_xkb_layout_real_create_keyboard (EekboardContextService *manager,
|
||||
EekLayout *self,
|
||||
gdouble initial_width,
|
||||
gdouble initial_height)
|
||||
{
|
||||
EekKeyboard *keyboard = g_object_new (EEK_TYPE_KEYBOARD, "layout", self, NULL);
|
||||
keyboard->manager = manager;
|
||||
|
||||
EekBounds bounds = {
|
||||
.x = 0.0,
|
||||
.y = 0.0,
|
||||
.width = initial_width,
|
||||
.height = initial_height
|
||||
};
|
||||
eek_element_set_bounds (EEK_ELEMENT(keyboard), &bounds);
|
||||
|
||||
/* resolve modifiers dynamically assigned at run time */
|
||||
EekXkbLayoutPrivate *priv = eek_xkb_layout_get_instance_private (
|
||||
EEK_XKB_LAYOUT(self));
|
||||
eek_keyboard_set_num_lock_mask (keyboard,
|
||||
XkbKeysymToModifiers (priv->display,
|
||||
XK_Num_Lock));
|
||||
eek_keyboard_set_alt_gr_mask (keyboard,
|
||||
XkbKeysymToModifiers (priv->display,
|
||||
XK_ISO_Level3_Shift));
|
||||
|
||||
if (priv->shape_oref_hash)
|
||||
g_hash_table_destroy (priv->shape_oref_hash);
|
||||
|
||||
priv->shape_oref_hash = g_hash_table_new (g_direct_hash, g_direct_equal);
|
||||
create_keyboard (EEK_XKB_LAYOUT(self), keyboard);
|
||||
g_hash_table_destroy (priv->shape_oref_hash);
|
||||
|
||||
return keyboard;
|
||||
}
|
||||
|
||||
static void
|
||||
eek_xkb_layout_finalize (GObject *object)
|
||||
{
|
||||
EekXkbLayoutPrivate *priv = eek_xkb_layout_get_instance_private (
|
||||
EEK_XKB_LAYOUT (object));
|
||||
|
||||
g_free (priv->names.keycodes);
|
||||
g_free (priv->names.geometry);
|
||||
g_free (priv->names.symbols);
|
||||
XkbFreeKeyboard (priv->xkb, 0, TRUE); /* free_all = TRUE */
|
||||
G_OBJECT_CLASS (eek_xkb_layout_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
eek_xkb_layout_set_property (GObject *object,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
EekXkbLayout *layout = EEK_XKB_LAYOUT (object);
|
||||
EekXkbLayoutPrivate *priv = eek_xkb_layout_get_instance_private (layout);
|
||||
|
||||
switch (prop_id) {
|
||||
case PROP_DISPLAY:
|
||||
priv->display = g_value_get_pointer (value);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
eek_xkb_layout_get_property (GObject *object,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
EekXkbLayout *layout = EEK_XKB_LAYOUT (object);
|
||||
EekXkbLayoutPrivate *priv = eek_xkb_layout_get_instance_private (layout);
|
||||
|
||||
switch (prop_id) {
|
||||
case PROP_DISPLAY:
|
||||
g_value_set_pointer (value, priv->display);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
eek_xkb_layout_class_init (EekXkbLayoutClass *klass)
|
||||
{
|
||||
EekLayoutClass *layout_class = EEK_LAYOUT_CLASS (klass);
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||
GParamSpec *pspec;
|
||||
|
||||
layout_class->create_keyboard = eek_xkb_layout_real_create_keyboard;
|
||||
|
||||
gobject_class->finalize = eek_xkb_layout_finalize;
|
||||
gobject_class->set_property = eek_xkb_layout_set_property;
|
||||
gobject_class->get_property = eek_xkb_layout_get_property;
|
||||
|
||||
pspec = g_param_spec_pointer ("display",
|
||||
"Display",
|
||||
"X Display",
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_CONSTRUCT_ONLY);
|
||||
g_object_class_install_property (gobject_class, PROP_DISPLAY, pspec);
|
||||
}
|
||||
|
||||
static void
|
||||
eek_xkb_layout_init (EekXkbLayout *self)
|
||||
{
|
||||
/* void */
|
||||
}
|
||||
|
||||
static gboolean
|
||||
get_names_from_server (EekXkbLayout *layout,
|
||||
GError **error)
|
||||
{
|
||||
EekXkbLayoutPrivate *priv = eek_xkb_layout_get_instance_private (layout);
|
||||
gchar *name;
|
||||
|
||||
XkbGetNames (priv->display, XkbAllNamesMask, priv->xkb);
|
||||
|
||||
if (priv->xkb->names->keycodes <= 0)
|
||||
g_warning ("XKB keycodes setting is not loaded properly");
|
||||
else {
|
||||
name = XGetAtomName (priv->display, priv->xkb->names->keycodes);
|
||||
if (!name)
|
||||
g_warning ("Can't get the name of keycodes");
|
||||
else if (!priv->names.keycodes ||
|
||||
g_strcmp0 (name, priv->names.keycodes)) {
|
||||
g_free (priv->names.keycodes);
|
||||
priv->names.keycodes = g_strdup (name);
|
||||
XFree (name);
|
||||
}
|
||||
}
|
||||
|
||||
if (priv->xkb->names->geometry <= 0)
|
||||
g_warning ("XKB geometry setting is not loaded");
|
||||
else {
|
||||
name = XGetAtomName (priv->display, priv->xkb->names->geometry);
|
||||
if (!name)
|
||||
g_warning ("Can't get the name of geometry");
|
||||
else if (!priv->names.geometry ||
|
||||
g_strcmp0 (name, priv->names.geometry)) {
|
||||
g_free (priv->names.geometry);
|
||||
priv->names.geometry = g_strdup (name);
|
||||
XFree (name);
|
||||
}
|
||||
}
|
||||
|
||||
if (priv->xkb->names->symbols <= 0)
|
||||
g_warning ("XKB symbols setting is not loaded");
|
||||
else {
|
||||
name = XGetAtomName (priv->display, priv->xkb->names->symbols);
|
||||
if (!name)
|
||||
g_warning ("Can't get the name of symbols");
|
||||
else if (!priv->names.symbols ||
|
||||
g_strcmp0 (name, priv->names.symbols)) {
|
||||
g_free (priv->names.symbols);
|
||||
priv->names.symbols = g_strdup (name);
|
||||
XFree (name);
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* eek_xkb_layout_new:
|
||||
*
|
||||
* Create a new #EekXkbLayout.
|
||||
*/
|
||||
EekLayout *
|
||||
eek_xkb_layout_new (Display *display,
|
||||
GError **error)
|
||||
{
|
||||
return (EekLayout *) g_initable_new (EEK_TYPE_XKB_LAYOUT,
|
||||
NULL,
|
||||
error,
|
||||
"display", display,
|
||||
NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* eek_xkb_layout_set_names: (skip)
|
||||
* @layout: an #EekXkbLayout
|
||||
* @names: XKB component names
|
||||
* @error: a #GError
|
||||
*
|
||||
* Set the XKB component names to @layout.
|
||||
* Returns: %TRUE if the component names are successfully set, %FALSE otherwise
|
||||
*/
|
||||
gboolean
|
||||
eek_xkb_layout_set_names (EekXkbLayout *layout,
|
||||
XkbComponentNamesRec *names,
|
||||
GError **error)
|
||||
{
|
||||
EekXkbLayoutPrivate *priv = eek_xkb_layout_get_instance_private (layout);
|
||||
|
||||
if (g_strcmp0 (names->keycodes, priv->names.keycodes)) {
|
||||
g_free (priv->names.keycodes);
|
||||
priv->names.keycodes = g_strdup (names->keycodes);
|
||||
}
|
||||
|
||||
if (g_strcmp0 (names->geometry, priv->names.geometry)) {
|
||||
g_free (priv->names.geometry);
|
||||
priv->names.geometry = g_strdup (names->geometry);
|
||||
}
|
||||
|
||||
if (g_strcmp0 (names->symbols, priv->names.symbols)) {
|
||||
g_free (priv->names.symbols);
|
||||
priv->names.symbols = g_strdup (names->symbols);
|
||||
}
|
||||
|
||||
return get_keyboard_from_server (layout, error);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
get_keyboard_from_server (EekXkbLayout *layout,
|
||||
GError **error)
|
||||
{
|
||||
EekXkbLayoutPrivate *priv = eek_xkb_layout_get_instance_private (layout);
|
||||
|
||||
if (priv->xkb) {
|
||||
XkbFreeKeyboard (priv->xkb, 0, True);
|
||||
priv->xkb = NULL;
|
||||
}
|
||||
|
||||
if (priv->names.keycodes && priv->names.geometry && priv->names.symbols) {
|
||||
priv->xkb = XkbGetKeyboardByName (priv->display,
|
||||
XkbUseCoreKbd,
|
||||
&priv->names,
|
||||
0,
|
||||
XKB_COMPONENT_MASK,
|
||||
False);
|
||||
} else {
|
||||
priv->xkb = XkbGetKeyboard (priv->display,
|
||||
XKB_COMPONENT_MASK,
|
||||
XkbUseCoreKbd);
|
||||
if (!get_names_from_server (layout, error)) {
|
||||
XkbFreeKeyboard (priv->xkb, 0, True);
|
||||
priv->xkb = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (priv->xkb == NULL) {
|
||||
g_set_error (error,
|
||||
EEK_ERROR,
|
||||
EEK_ERROR_LAYOUT_ERROR,
|
||||
"can't get keyboard from server");
|
||||
g_free (priv->names.keycodes);
|
||||
priv->names.keycodes = NULL;
|
||||
g_free (priv->names.geometry);
|
||||
priv->names.geometry = NULL;
|
||||
g_free (priv->names.symbols);
|
||||
priv->names.symbols = NULL;
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
static guint
|
||||
find_keycode (EekXkbLayout *layout, gchar *key_name)
|
||||
{
|
||||
#define KEYSYM_NAME_MAX_LENGTH 4
|
||||
guint keycode;
|
||||
gint i, j;
|
||||
XkbKeyNamePtr pkey;
|
||||
XkbKeyAliasPtr palias;
|
||||
guint is_name_matched;
|
||||
gchar *src, *dst;
|
||||
EekXkbLayoutPrivate *priv = eek_xkb_layout_get_instance_private (layout);
|
||||
|
||||
if (!priv->xkb)
|
||||
return EEK_INVALID_KEYCODE;
|
||||
|
||||
pkey = priv->xkb->names->keys + priv->xkb->min_key_code;
|
||||
for (keycode = priv->xkb->min_key_code;
|
||||
keycode <= priv->xkb->max_key_code; keycode++) {
|
||||
is_name_matched = 1;
|
||||
src = key_name;
|
||||
dst = pkey->name;
|
||||
for (i = KEYSYM_NAME_MAX_LENGTH; --i >= 0;) {
|
||||
if ('\0' == *src)
|
||||
break;
|
||||
if (*src++ != *dst++) {
|
||||
is_name_matched = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (is_name_matched)
|
||||
return keycode;
|
||||
pkey++;
|
||||
}
|
||||
|
||||
palias = priv->xkb->names->key_aliases;
|
||||
for (j = priv->xkb->names->num_key_aliases; --j >= 0;) {
|
||||
is_name_matched = 1;
|
||||
src = key_name;
|
||||
dst = palias->alias;
|
||||
for (i = KEYSYM_NAME_MAX_LENGTH; --i >= 0;) {
|
||||
if ('\0' == *src)
|
||||
break;
|
||||
if (*src++ != *dst++) {
|
||||
is_name_matched = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (is_name_matched) {
|
||||
keycode = find_keycode (layout, palias->real);
|
||||
return keycode;
|
||||
}
|
||||
palias++;
|
||||
}
|
||||
|
||||
return EEK_INVALID_KEYCODE;
|
||||
}
|
||||
|
||||
static void
|
||||
setup_scaling (EekXkbLayout *layout,
|
||||
gdouble width,
|
||||
gdouble height)
|
||||
{
|
||||
EekXkbLayoutPrivate *priv = eek_xkb_layout_get_instance_private (layout);
|
||||
|
||||
g_return_if_fail (priv->xkb);
|
||||
|
||||
g_return_if_fail (priv->xkb->geom->width_mm > 0);
|
||||
g_return_if_fail (priv->xkb->geom->height_mm > 0);
|
||||
|
||||
if (width * priv->xkb->geom->height_mm <
|
||||
height * priv->xkb->geom->width_mm) {
|
||||
priv->scale_numerator = width;
|
||||
priv->scale_denominator = priv->xkb->geom->width_mm;
|
||||
} else {
|
||||
priv->scale_numerator = height;
|
||||
priv->scale_denominator = priv->xkb->geom->height_mm;
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
initable_init (GInitable *initable,
|
||||
GCancellable *cancellable,
|
||||
GError **error)
|
||||
{
|
||||
EekXkbLayout *layout = EEK_XKB_LAYOUT (initable);
|
||||
|
||||
if (!get_keyboard_from_server (layout, error))
|
||||
return FALSE;
|
||||
|
||||
if (!get_names_from_server (layout, error))
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
initable_iface_init (GInitableIface *initable_iface)
|
||||
{
|
||||
initable_iface->init = initable_init;
|
||||
}
|
||||
@ -1,55 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2011 Daiki Ueno <ueno@unixuser.org>
|
||||
* Copyright (C) 2010-2011 Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public License
|
||||
* as published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
* 02110-1301 USA
|
||||
*/
|
||||
|
||||
#if !defined(__EEK_H_INSIDE__) && !defined(EEK_COMPILATION)
|
||||
#error "Only <eek/eek-xkb.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#ifndef EEK_XKB_LAYOUT_H
|
||||
#define EEK_XKB_LAYOUT_H 1
|
||||
|
||||
#include <X11/XKBlib.h>
|
||||
#include "eek-layout.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define EEK_TYPE_XKB_LAYOUT (eek_xkb_layout_get_type())
|
||||
G_DECLARE_DERIVABLE_TYPE (EekXkbLayout, eek_xkb_layout, EEK, XKB_LAYOUT, EekLayout)
|
||||
|
||||
struct _EekXkbLayoutClass
|
||||
{
|
||||
/*< private >*/
|
||||
EekLayoutClass parent_class;
|
||||
|
||||
/*< private >*/
|
||||
/* padding */
|
||||
gpointer pdummy[24];
|
||||
};
|
||||
|
||||
GType eek_xkb_layout_get_type (void) G_GNUC_CONST;
|
||||
EekLayout *eek_xkb_layout_new (Display *display,
|
||||
GError **error);
|
||||
|
||||
gboolean eek_xkb_layout_set_names (EekXkbLayout *layout,
|
||||
XkbComponentNamesRec *names,
|
||||
GError **error);
|
||||
|
||||
G_END_DECLS
|
||||
#endif /* #ifndef EEK_XKB_LAYOUT_H */
|
||||
@ -1,26 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2011 Daiki Ueno <ueno@unixuser.org>
|
||||
* Copyright (C) 2010-2011 Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public License
|
||||
* as published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
* 02110-1301 USA
|
||||
*/
|
||||
#ifndef EEK_XKB_H
|
||||
#define EEK_XKB_H 1
|
||||
|
||||
#include "eek.h"
|
||||
#include "eek-xkb-layout.h"
|
||||
|
||||
#endif /* EEK_XKB_H */
|
||||
@ -1,30 +0,0 @@
|
||||
# Copyright (C) 2010-2011 Daiki Ueno <ueno@unixuser.org>
|
||||
# Copyright (C) 2010-2011 Red Hat, Inc.
|
||||
|
||||
# This library is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU Lesser General Public License
|
||||
# as published by the Free Software Foundation; either version 2 of
|
||||
# the License, or (at your option) any later version.
|
||||
|
||||
# This library is distributed in the hope that it will be useful, but
|
||||
# WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
# Lesser General Public License for more details.
|
||||
|
||||
# You should have received a copy of the GNU Lesser General Public
|
||||
# License along with this library; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
# 02110-1301 USA
|
||||
|
||||
prefix=@prefix@
|
||||
exec_prefix=@exec_prefix@
|
||||
libdir=@libdir@
|
||||
includedir=@includedir@
|
||||
|
||||
Name: libeek-xkl
|
||||
Description: A Library to Create Keyboard-like UI (Libxklavier Support)
|
||||
URL: http://fedorahosted.org/eekboard/
|
||||
Version: @VERSION@
|
||||
Requires: eek-@EEK_API_VERSION@ libxklavier
|
||||
Libs: -L${libdir} -leek-xkl
|
||||
Cflags: -I${includedir}/eek-@EEK_API_VERSION@
|
||||
@ -1,662 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2011 Daiki Ueno <ueno@unixuser.org>
|
||||
* Copyright (C) 2010-2011 Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public License
|
||||
* as published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
* 02110-1301 USA
|
||||
*/
|
||||
|
||||
/**
|
||||
* SECTION:eek-xkl-layout
|
||||
* @short_description: Layout engine using Libxklavier configuration
|
||||
*
|
||||
* The #EekXklLayout is a simple wrapper around #EekXkbLayout class
|
||||
* to use Libxklavier configuration.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
|
||||
#include <libxklavier/xklavier.h>
|
||||
#include <gio/gio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "eek-xkl-layout.h"
|
||||
|
||||
#define noKBDRAW_DEBUG
|
||||
|
||||
static GInitableIface *parent_initable_iface;
|
||||
|
||||
static void initable_iface_init (GInitableIface *initable_iface);
|
||||
|
||||
enum {
|
||||
PROP_0,
|
||||
PROP_MODEL,
|
||||
PROP_LAYOUTS,
|
||||
PROP_VARIANTS,
|
||||
PROP_OPTIONS,
|
||||
PROP_LAST
|
||||
};
|
||||
|
||||
typedef struct _EekXklLayoutPrivate
|
||||
{
|
||||
XklEngine *engine;
|
||||
XklConfigRec *config;
|
||||
} EekXklLayoutPrivate;
|
||||
|
||||
G_DEFINE_TYPE_EXTENDED (EekXklLayout, eek_xkl_layout, EEK_TYPE_XKB_LAYOUT,
|
||||
0, /* GTypeFlags */
|
||||
G_ADD_PRIVATE (EekXklLayout)
|
||||
G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE,
|
||||
initable_iface_init))
|
||||
|
||||
/* from gnome-keyboard-properties-xkbpv.c:
|
||||
* BAD STYLE: Taken from xklavier_private_xkb.h
|
||||
* Any ideas on architectural improvements are WELCOME
|
||||
*/
|
||||
extern gboolean xkl_xkb_config_native_prepare (XklEngine * engine,
|
||||
const XklConfigRec * data,
|
||||
XkbComponentNamesPtr
|
||||
component_names);
|
||||
|
||||
extern void xkl_xkb_config_native_cleanup (XklEngine * engine,
|
||||
XkbComponentNamesPtr
|
||||
component_names);
|
||||
|
||||
static gboolean set_xkb_component_names (EekXklLayout *layout,
|
||||
XklConfigRec *config);
|
||||
|
||||
static void
|
||||
eek_xkl_layout_dispose (GObject *object)
|
||||
{
|
||||
EekXklLayoutPrivate *priv = eek_xkl_layout_get_instance_private (
|
||||
EEK_XKL_LAYOUT (object));
|
||||
|
||||
if (priv->config) {
|
||||
g_object_unref (priv->config);
|
||||
priv->config = NULL;
|
||||
}
|
||||
|
||||
G_OBJECT_CLASS (eek_xkl_layout_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
eek_xkl_layout_set_property (GObject *object,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
EekXklLayout *layout = EEK_XKL_LAYOUT(object);
|
||||
|
||||
switch (prop_id) {
|
||||
case PROP_MODEL:
|
||||
eek_xkl_layout_set_model (layout, g_value_get_string (value));
|
||||
break;
|
||||
case PROP_LAYOUTS:
|
||||
eek_xkl_layout_set_layouts (layout, g_value_get_boxed (value));
|
||||
break;
|
||||
case PROP_VARIANTS:
|
||||
eek_xkl_layout_set_variants (layout, g_value_get_boxed (value));
|
||||
break;
|
||||
case PROP_OPTIONS:
|
||||
eek_xkl_layout_set_options (layout, g_value_get_boxed (value));
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
eek_xkl_layout_get_property (GObject *object,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
EekXklLayout *layout = EEK_XKL_LAYOUT(object);
|
||||
|
||||
switch (prop_id) {
|
||||
case PROP_MODEL:
|
||||
g_value_set_string (value,
|
||||
eek_xkl_layout_get_model (layout));
|
||||
break;
|
||||
case PROP_LAYOUTS:
|
||||
g_value_set_boxed (value,
|
||||
eek_xkl_layout_get_layouts (layout));
|
||||
break;
|
||||
case PROP_VARIANTS:
|
||||
g_value_set_boxed (value,
|
||||
eek_xkl_layout_get_variants (layout));
|
||||
break;
|
||||
case PROP_OPTIONS:
|
||||
g_value_set_boxed (value,
|
||||
eek_xkl_layout_get_options (layout));
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
eek_xkl_layout_class_init (EekXklLayoutClass *klass)
|
||||
{
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||
GParamSpec *pspec;
|
||||
|
||||
gobject_class->dispose = eek_xkl_layout_dispose;
|
||||
gobject_class->set_property = eek_xkl_layout_set_property;
|
||||
gobject_class->get_property = eek_xkl_layout_get_property;
|
||||
|
||||
/**
|
||||
* EekXklLayout:model:
|
||||
*
|
||||
* The libxklavier model name of #EekXklLayout.
|
||||
*/
|
||||
pspec = g_param_spec_string ("model",
|
||||
"Model",
|
||||
"Libxklavier model",
|
||||
NULL,
|
||||
G_PARAM_READWRITE);
|
||||
g_object_class_install_property (gobject_class, PROP_MODEL, pspec);
|
||||
|
||||
/**
|
||||
* EekXklLayout:layouts:
|
||||
*
|
||||
* The libxklavier layout names of #EekXklLayout.
|
||||
*/
|
||||
pspec = g_param_spec_boxed ("layouts",
|
||||
"Layouts",
|
||||
"Libxklavier layouts",
|
||||
G_TYPE_STRV,
|
||||
G_PARAM_READWRITE);
|
||||
g_object_class_install_property (gobject_class, PROP_LAYOUTS, pspec);
|
||||
|
||||
/**
|
||||
* EekXklLayout:variants:
|
||||
*
|
||||
* The libxklavier variant names of #EekXklLayout.
|
||||
*/
|
||||
pspec = g_param_spec_boxed ("variants",
|
||||
"Variants",
|
||||
"Libxklavier variants",
|
||||
G_TYPE_STRV,
|
||||
G_PARAM_READWRITE);
|
||||
g_object_class_install_property (gobject_class, PROP_VARIANTS, pspec);
|
||||
|
||||
/**
|
||||
* EekXklLayout:options:
|
||||
*
|
||||
* The libxklavier option names of #EekXklLayout.
|
||||
*/
|
||||
pspec = g_param_spec_boxed ("options",
|
||||
"Options",
|
||||
"Libxklavier options",
|
||||
G_TYPE_STRV,
|
||||
G_PARAM_READWRITE);
|
||||
g_object_class_install_property (gobject_class, PROP_OPTIONS, pspec);
|
||||
}
|
||||
|
||||
static void
|
||||
eek_xkl_layout_init (EekXklLayout *self)
|
||||
{
|
||||
/* void */
|
||||
}
|
||||
|
||||
/**
|
||||
* eek_xkl_layout_new:
|
||||
*
|
||||
* Create a new #EekXklLayout.
|
||||
*/
|
||||
EekLayout *
|
||||
eek_xkl_layout_new (Display *display, GError **error)
|
||||
{
|
||||
return (EekLayout *) g_initable_new (EEK_TYPE_XKL_LAYOUT,
|
||||
NULL,
|
||||
error,
|
||||
"display", display,
|
||||
NULL);
|
||||
}
|
||||
|
||||
G_INLINE_FUNC void
|
||||
merge_xkl_config_rec (XklConfigRec *dst, XklConfigRec *src)
|
||||
{
|
||||
if (src->model) {
|
||||
g_free (dst->model);
|
||||
dst->model = g_strdup (src->model);
|
||||
}
|
||||
if (src->layouts) {
|
||||
g_strfreev (dst->layouts);
|
||||
dst->layouts = g_strdupv (src->layouts);
|
||||
}
|
||||
if (src->variants) {
|
||||
g_strfreev (dst->variants);
|
||||
dst->variants = g_strdupv (src->variants);
|
||||
}
|
||||
if (src->options) {
|
||||
g_strfreev (dst->options);
|
||||
dst->options = g_strdupv (src->options);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* eek_xkl_layout_set_config: (skip)
|
||||
* @layout: an #EekXklLayout
|
||||
* @config: Libxklavier configuration
|
||||
*
|
||||
* Reconfigure @layout with @config.
|
||||
* Returns: %TRUE if the current layout changed, %FALSE otherwise
|
||||
*/
|
||||
gboolean
|
||||
eek_xkl_layout_set_config (EekXklLayout *layout,
|
||||
XklConfigRec *config)
|
||||
{
|
||||
EekXklLayoutPrivate *priv = eek_xkl_layout_get_instance_private (layout);
|
||||
XklConfigRec *c;
|
||||
gboolean retval;
|
||||
|
||||
g_return_val_if_fail (priv, FALSE);
|
||||
c = xkl_config_rec_new ();
|
||||
merge_xkl_config_rec (c, priv->config);
|
||||
merge_xkl_config_rec (c, config);
|
||||
retval = set_xkb_component_names (layout, c);
|
||||
g_object_unref (c);
|
||||
merge_xkl_config_rec (priv->config, config);
|
||||
return retval;
|
||||
}
|
||||
|
||||
/**
|
||||
* eek_xkl_layout_set_config_full:
|
||||
* @layout: an #EekXklLayout
|
||||
* @model: Libxklavier model name
|
||||
* @layouts: Libxklavier layouts
|
||||
* @variants: Libxklavier variants
|
||||
* @options: Libxklavier options
|
||||
*
|
||||
* Reconfigure @layout with @model, @layouts, @variants, and @options.
|
||||
* This function is merely a wrapper around
|
||||
* eek_xkl_layout_set_config() to avoid passing a pointer of
|
||||
* XklConfigRec, which is not currently available in the
|
||||
* gobject-introspection repository.
|
||||
*
|
||||
* Returns: %TRUE if the current layout changed, %FALSE otherwise
|
||||
* Since: 0.0.2
|
||||
*/
|
||||
gboolean
|
||||
eek_xkl_layout_set_config_full (EekXklLayout *layout,
|
||||
gchar *model,
|
||||
gchar **layouts,
|
||||
gchar **variants,
|
||||
gchar **options)
|
||||
{
|
||||
XklConfigRec *config;
|
||||
gboolean retval;
|
||||
|
||||
config = xkl_config_rec_new ();
|
||||
config->model = g_strdup (model);
|
||||
config->layouts = g_strdupv (layouts);
|
||||
config->variants = g_strdupv (variants);
|
||||
config->options = g_strdupv (options);
|
||||
retval = eek_xkl_layout_set_config (layout, config);
|
||||
g_object_unref (config);
|
||||
return retval;
|
||||
}
|
||||
|
||||
/**
|
||||
* eek_xkl_layout_set_model:
|
||||
* @layout: an #EekXklLayout
|
||||
* @model: model name
|
||||
*
|
||||
* Set the model name of @layout configuration (in the Libxklavier terminology).
|
||||
* Returns: %TRUE if the current layout changed, %FALSE otherwise
|
||||
*/
|
||||
gboolean
|
||||
eek_xkl_layout_set_model (EekXklLayout *layout,
|
||||
const gchar *model)
|
||||
{
|
||||
EekXklLayoutPrivate *priv = eek_xkl_layout_get_instance_private (layout);
|
||||
XklConfigRec *config;
|
||||
gboolean retval;
|
||||
|
||||
g_return_val_if_fail (priv, FALSE);
|
||||
config = xkl_config_rec_new ();
|
||||
/* config->model will be freed on g_object_unref (config) */
|
||||
if (model)
|
||||
config->model = g_strdup (model);
|
||||
else
|
||||
config->model = NULL;
|
||||
retval = eek_xkl_layout_set_config (layout, config);
|
||||
g_object_unref (config);
|
||||
return retval;
|
||||
}
|
||||
|
||||
/**
|
||||
* eek_xkl_layout_set_layouts:
|
||||
* @layout: an #EekXklLayout
|
||||
* @layouts: layout names
|
||||
*
|
||||
* Set the layout names of @layout (in the Libxklavier terminology).
|
||||
* Returns: %TRUE if the current layout changed, %FALSE otherwise
|
||||
*/
|
||||
gboolean
|
||||
eek_xkl_layout_set_layouts (EekXklLayout *layout,
|
||||
gchar **layouts)
|
||||
{
|
||||
EekXklLayoutPrivate *priv = eek_xkl_layout_get_instance_private (layout);
|
||||
XklConfigRec *config;
|
||||
gboolean retval;
|
||||
|
||||
g_return_val_if_fail (priv, FALSE);
|
||||
config = xkl_config_rec_new ();
|
||||
/* config->layouts will be freed on g_object_unref (config) */
|
||||
if (layouts)
|
||||
config->layouts = g_strdupv (layouts);
|
||||
else
|
||||
config->layouts = layouts;
|
||||
retval = eek_xkl_layout_set_config (layout, config);
|
||||
g_object_unref (config);
|
||||
return retval;
|
||||
}
|
||||
|
||||
/**
|
||||
* eek_xkl_layout_set_variants:
|
||||
* @layout: an #EekXklLayout
|
||||
* @variants: variant names
|
||||
*
|
||||
* Set the variant names of @layout (in the Libxklavier terminology).
|
||||
* Returns: %TRUE if the current layout changed, %FALSE otherwise
|
||||
*/
|
||||
gboolean
|
||||
eek_xkl_layout_set_variants (EekXklLayout *layout,
|
||||
gchar **variants)
|
||||
{
|
||||
EekXklLayoutPrivate *priv = eek_xkl_layout_get_instance_private (layout);
|
||||
XklConfigRec *config;
|
||||
gboolean retval;
|
||||
|
||||
g_return_val_if_fail (priv, FALSE);
|
||||
config = xkl_config_rec_new ();
|
||||
/* config->variants will be freed on g_object_unref (config) */
|
||||
if (variants)
|
||||
config->variants = g_strdupv (variants);
|
||||
else
|
||||
config->variants = NULL;
|
||||
retval = eek_xkl_layout_set_config (layout, config);
|
||||
g_object_unref (config);
|
||||
return retval;
|
||||
}
|
||||
|
||||
/**
|
||||
* eek_xkl_layout_set_options:
|
||||
* @layout: an #EekXklLayout
|
||||
* @options: option names
|
||||
*
|
||||
* Set the option names of @layout (in the Libxklavier terminology).
|
||||
* Returns: %TRUE if the current layout changed, %FALSE otherwise
|
||||
*/
|
||||
gboolean
|
||||
eek_xkl_layout_set_options (EekXklLayout *layout,
|
||||
gchar **options)
|
||||
{
|
||||
EekXklLayoutPrivate *priv = eek_xkl_layout_get_instance_private (layout);
|
||||
XklConfigRec *config;
|
||||
gboolean retval;
|
||||
|
||||
g_return_val_if_fail (priv, FALSE);
|
||||
config = xkl_config_rec_new ();
|
||||
/* config->options will be freed on g_object_unref (config) */
|
||||
if (options)
|
||||
config->options = options;
|
||||
else
|
||||
config->options = NULL;
|
||||
retval = eek_xkl_layout_set_config (layout, config);
|
||||
g_object_unref (config);
|
||||
return retval;
|
||||
}
|
||||
|
||||
/**
|
||||
* eek_xkl_layout_enable_option:
|
||||
* @layout: an #EekXklLayout
|
||||
* @option: option name
|
||||
*
|
||||
* Set the option of @layout (in the Libxklavier terminology).
|
||||
* Returns: %TRUE if the current layout changed, %FALSE otherwise
|
||||
*/
|
||||
gboolean
|
||||
eek_xkl_layout_enable_option (EekXklLayout *layout,
|
||||
const gchar *option)
|
||||
{
|
||||
gchar **options, **_options;
|
||||
gint i, j;
|
||||
|
||||
options = eek_xkl_layout_get_options (layout);
|
||||
for (i = 0; options && options[i]; i++)
|
||||
if (g_strcmp0 (options[i], option) == 0)
|
||||
return TRUE;
|
||||
_options = g_new0 (gchar *, (i + 2));
|
||||
for (j = 0; j < i; j++)
|
||||
_options[j] = g_strdup (options[j]);
|
||||
_options[i] = g_strdup (option);
|
||||
/* eek_xkl_layout_set_options() will free _options and its elements. */
|
||||
return eek_xkl_layout_set_options (layout, _options);
|
||||
}
|
||||
|
||||
/**
|
||||
* eek_xkl_layout_disable_option:
|
||||
* @layout: an #EekXklLayout
|
||||
* @option: option name
|
||||
*
|
||||
* Unset the option of @layout (in the Libxklavier terminology).
|
||||
* Returns: %TRUE if the current layout changed, %FALSE otherwise
|
||||
*/
|
||||
gboolean
|
||||
eek_xkl_layout_disable_option (EekXklLayout *layout,
|
||||
const gchar *option)
|
||||
{
|
||||
gchar **options, **_options;
|
||||
gint i, j, k;
|
||||
|
||||
options = eek_xkl_layout_get_options (layout);
|
||||
if (!options)
|
||||
return TRUE;
|
||||
for (i = 0, k = 0; options[i]; i++)
|
||||
if (g_strcmp0 (options[i], option) == 0)
|
||||
k = i;
|
||||
if (options[k] == NULL)
|
||||
return TRUE;
|
||||
_options = g_new0 (gchar *, i);
|
||||
for (j = 0; j < k; j++)
|
||||
_options[j] = g_strdup (options[j]);
|
||||
for (j = k + 1; j < i; j++)
|
||||
_options[j] = g_strdup (options[j]);
|
||||
/* eek_xkl_layout_set_options() will free _options and its elements. */
|
||||
return eek_xkl_layout_set_options (layout, _options);
|
||||
}
|
||||
|
||||
/**
|
||||
* eek_xkl_layout_get_model:
|
||||
* @layout: an #EekXklLayout
|
||||
*
|
||||
* Get the model name of @layout configuration (in the Libxklavier terminology).
|
||||
*/
|
||||
gchar *
|
||||
eek_xkl_layout_get_model (EekXklLayout *layout)
|
||||
{
|
||||
EekXklLayoutPrivate *priv = eek_xkl_layout_get_instance_private (layout);
|
||||
|
||||
g_return_val_if_fail (priv, NULL);
|
||||
return g_strdup (priv->config->model);
|
||||
}
|
||||
|
||||
/**
|
||||
* eek_xkl_layout_get_layouts:
|
||||
* @layout: an #EekXklLayout
|
||||
*
|
||||
* Get the layout names of @layout configuration (in the Libxklavier
|
||||
* terminology).
|
||||
*/
|
||||
gchar **
|
||||
eek_xkl_layout_get_layouts (EekXklLayout *layout)
|
||||
{
|
||||
EekXklLayoutPrivate *priv = eek_xkl_layout_get_instance_private (layout);
|
||||
|
||||
g_return_val_if_fail (priv, NULL);
|
||||
return g_strdupv (priv->config->layouts);
|
||||
}
|
||||
|
||||
/**
|
||||
* eek_xkl_layout_get_variants:
|
||||
* @layout: an #EekXklLayout
|
||||
*
|
||||
* Get the variant names of @layout configuration (in the Libxklavier
|
||||
* terminology).
|
||||
*/
|
||||
gchar **
|
||||
eek_xkl_layout_get_variants (EekXklLayout *layout)
|
||||
{
|
||||
EekXklLayoutPrivate *priv = eek_xkl_layout_get_instance_private (layout);
|
||||
|
||||
g_return_val_if_fail (priv, NULL);
|
||||
return g_strdupv (priv->config->variants);
|
||||
}
|
||||
|
||||
/**
|
||||
* eek_xkl_layout_get_options:
|
||||
* @layout: an #EekXklLayout
|
||||
*
|
||||
* Get the option names of @layout configuration (in the Libxklavier
|
||||
* terminology).
|
||||
*/
|
||||
gchar **
|
||||
eek_xkl_layout_get_options (EekXklLayout *layout)
|
||||
{
|
||||
EekXklLayoutPrivate *priv = eek_xkl_layout_get_instance_private (layout);
|
||||
|
||||
g_return_val_if_fail (priv, NULL);
|
||||
return g_strdupv (priv->config->options);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
set_xkb_component_names (EekXklLayout *layout, XklConfigRec *config)
|
||||
{
|
||||
EekXklLayoutPrivate *priv = eek_xkl_layout_get_instance_private (layout);
|
||||
XkbComponentNamesRec names;
|
||||
gboolean retval = FALSE;
|
||||
|
||||
#if DEBUG
|
||||
if (config->layouts) {
|
||||
gint i;
|
||||
|
||||
fprintf (stderr, "layout = ");
|
||||
for (i = 0; config->layouts[i] != NULL; i++)
|
||||
fprintf (stderr, "\"%s\" ", config->layouts[i]);
|
||||
fputc ('\n', stderr);
|
||||
} else
|
||||
fprintf (stderr, "layouts = NULL\n");
|
||||
if (config->variants) {
|
||||
gint i;
|
||||
|
||||
fprintf (stderr, "variant = ");
|
||||
for (i = 0; config->variants[i]; i++)
|
||||
fprintf (stderr, "\"%s\" ", config->variants[i]);
|
||||
fputc ('\n', stderr);
|
||||
} else
|
||||
fprintf (stderr, "variants = NULL\n");
|
||||
if (config->options) {
|
||||
gint i;
|
||||
|
||||
fprintf (stderr, "option = ");
|
||||
for (i = 0; config->options[i]; i++)
|
||||
fprintf (stderr, "\"%s\" ", config->options[i]);
|
||||
fputc ('\n', stderr);
|
||||
} else
|
||||
fprintf (stderr, "options = NULL\n");
|
||||
#endif
|
||||
|
||||
if (xkl_xkb_config_native_prepare (priv->engine, config, &names)) {
|
||||
GError *error = NULL;
|
||||
retval = eek_xkb_layout_set_names (EEK_XKB_LAYOUT(layout),
|
||||
&names,
|
||||
&error);
|
||||
if (!retval)
|
||||
g_warning ("can't set XKB layout");
|
||||
xkl_xkb_config_native_cleanup (priv->engine, &names);
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
/**
|
||||
* eek_xkl_layout_get_option:
|
||||
* @layout: an #EekXklLayout
|
||||
* @option: option name
|
||||
*
|
||||
* Tell if the option of @layout (in the Libxklavier terminology) is set.
|
||||
* Returns: %TRUE if the option is set, %FALSE otherwise
|
||||
*/
|
||||
gboolean
|
||||
eek_xkl_layout_get_option (EekXklLayout *layout,
|
||||
const gchar *option)
|
||||
{
|
||||
gchar **options;
|
||||
gint i;
|
||||
|
||||
options = eek_xkl_layout_get_options (layout);
|
||||
for (i = 0; options && options[i]; i++)
|
||||
if (g_strcmp0 (options[i], option) == 0)
|
||||
return TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
initable_init (GInitable *initable,
|
||||
GCancellable *cancellable,
|
||||
GError **error)
|
||||
{
|
||||
EekXklLayout *layout = EEK_XKL_LAYOUT (initable);
|
||||
EekXklLayoutPrivate *priv = eek_xkl_layout_get_instance_private (layout);
|
||||
Display *display;
|
||||
|
||||
if (!parent_initable_iface->init (initable, cancellable, error))
|
||||
return FALSE;
|
||||
|
||||
priv->config = xkl_config_rec_new ();
|
||||
|
||||
g_object_get (G_OBJECT (initable),
|
||||
"display", &display,
|
||||
NULL);
|
||||
|
||||
priv->engine = xkl_engine_get_instance (display);
|
||||
|
||||
if (!xkl_config_rec_get_from_server (priv->config,
|
||||
priv->engine)) {
|
||||
g_set_error (error,
|
||||
EEK_ERROR,
|
||||
EEK_ERROR_LAYOUT_ERROR,
|
||||
"can't load libxklavier configuration");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
set_xkb_component_names (layout, priv->config);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
initable_iface_init (GInitableIface *initable_iface)
|
||||
{
|
||||
parent_initable_iface = g_type_interface_peek_parent (initable_iface);
|
||||
initable_iface->init = initable_init;
|
||||
}
|
||||
|
||||
@ -1,81 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2011 Daiki Ueno <ueno@unixuser.org>
|
||||
* Copyright (C) 2010-2011 Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public License
|
||||
* as published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
* 02110-1301 USA
|
||||
*/
|
||||
|
||||
#if !defined(__EEK_H_INSIDE__) && !defined(EEK_COMPILATION)
|
||||
#error "Only <eek/eek-xkl.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#ifndef EEK_XKL_LAYOUT_H
|
||||
#define EEK_XKL_LAYOUT_H 1
|
||||
|
||||
#include <libxklavier/xklavier.h>
|
||||
#include "eek-xkb-layout.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define EEK_TYPE_XKL_LAYOUT (eek_xkl_layout_get_type())
|
||||
G_DECLARE_DERIVABLE_TYPE (EekXklLayout, eek_xkl_layout, EEK, XKL_LAYOUT, EekLayout)
|
||||
|
||||
struct _EekXklLayoutClass
|
||||
{
|
||||
/*< private >*/
|
||||
EekXkbLayoutClass parent_class;
|
||||
|
||||
/*< private >*/
|
||||
/* padding */
|
||||
gpointer pdummy[24];
|
||||
};
|
||||
|
||||
GType eek_xkl_layout_get_type (void) G_GNUC_CONST;
|
||||
|
||||
EekLayout *eek_xkl_layout_new (Display *display,
|
||||
GError **error);
|
||||
|
||||
gboolean eek_xkl_layout_set_config (EekXklLayout *layout,
|
||||
XklConfigRec *config);
|
||||
|
||||
gboolean eek_xkl_layout_set_config_full (EekXklLayout *layout,
|
||||
gchar *model,
|
||||
gchar **layouts,
|
||||
gchar **variants,
|
||||
gchar **options);
|
||||
|
||||
gboolean eek_xkl_layout_set_model (EekXklLayout *layout,
|
||||
const gchar *model);
|
||||
gboolean eek_xkl_layout_set_layouts (EekXklLayout *layout,
|
||||
gchar **layouts);
|
||||
gboolean eek_xkl_layout_set_variants (EekXklLayout *layout,
|
||||
gchar **variants);
|
||||
gboolean eek_xkl_layout_set_options (EekXklLayout *layout,
|
||||
gchar **options);
|
||||
gboolean eek_xkl_layout_enable_option (EekXklLayout *layout,
|
||||
const gchar *option);
|
||||
gboolean eek_xkl_layout_disable_option (EekXklLayout *layout,
|
||||
const gchar *option);
|
||||
|
||||
gchar *eek_xkl_layout_get_model (EekXklLayout *layout);
|
||||
gchar **eek_xkl_layout_get_layouts (EekXklLayout *layout);
|
||||
gchar **eek_xkl_layout_get_variants (EekXklLayout *layout);
|
||||
gchar **eek_xkl_layout_get_options (EekXklLayout *layout);
|
||||
gboolean eek_xkl_layout_get_option (EekXklLayout *layout,
|
||||
const gchar *option);
|
||||
|
||||
G_END_DECLS
|
||||
#endif /* #ifndef EEK_XKL_LAYOUT_H */
|
||||
@ -1,26 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2011 Daiki Ueno <ueno@unixuser.org>
|
||||
* Copyright (C) 2010-2011 Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public License
|
||||
* as published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
* 02110-1301 USA
|
||||
*/
|
||||
#ifndef EEK_XKL_H
|
||||
#define EEK_XKL_H 1
|
||||
|
||||
#include "eek.h"
|
||||
#include "eek-xkl-layout.h"
|
||||
|
||||
#endif /* EEK_XKL_H */
|
||||
@ -21,23 +21,20 @@
|
||||
* @short_description: Layout engine which loads layout information from XML
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
|
||||
#include <gio/gio.h> /* GResource */
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "eek-xml-layout.h"
|
||||
#include "eek-keyboard.h"
|
||||
#include "eek-section.h"
|
||||
#include "eek-key.h"
|
||||
#include "eek-keysym.h"
|
||||
#include "eek-text.h"
|
||||
#include "src/keyboard.h"
|
||||
#include "src/symbol.h"
|
||||
|
||||
#include "squeekboard-resources.h"
|
||||
|
||||
#include "eek-xml-layout.h"
|
||||
|
||||
enum {
|
||||
PROP_0,
|
||||
PROP_ID,
|
||||
@ -54,8 +51,8 @@ typedef struct _EekXmlLayoutPrivate
|
||||
} EekXmlLayoutPrivate;
|
||||
|
||||
G_DEFINE_TYPE_EXTENDED (EekXmlLayout, eek_xml_layout, EEK_TYPE_LAYOUT,
|
||||
0, /* GTypeFlags */
|
||||
G_ADD_PRIVATE(EekXmlLayout)
|
||||
0, /* GTypeFlags */
|
||||
G_ADD_PRIVATE(EekXmlLayout)
|
||||
G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE,
|
||||
initable_iface_init))
|
||||
|
||||
@ -69,22 +66,18 @@ static GList *parse_prerequisites
|
||||
(const gchar *path,
|
||||
GError **error);
|
||||
static gboolean parse_geometry (const gchar *path,
|
||||
EekKeyboard *keyboard,
|
||||
struct squeek_view **views, GArray *outline_array, GHashTable *name_button_hash,
|
||||
GError **error);
|
||||
static gboolean parse_symbols_with_prerequisites
|
||||
(const gchar *keyboards_dir,
|
||||
const gchar *name,
|
||||
EekKeyboard *keyboard,
|
||||
LevelKeyboard *keyboard,
|
||||
GList **loaded,
|
||||
GError **error);
|
||||
static gboolean parse_symbols (const gchar *path,
|
||||
EekKeyboard *keyboard,
|
||||
LevelKeyboard *keyboard,
|
||||
GError **error);
|
||||
|
||||
static void scale_keyboard (EekKeyboard *keyboard,
|
||||
gdouble width,
|
||||
gdouble height);
|
||||
|
||||
static gboolean validate (const gchar **valid_path_list,
|
||||
gsize valid_path_list_len,
|
||||
const gchar *element_name,
|
||||
@ -238,60 +231,68 @@ struct _GeometryParseData {
|
||||
GSList *element_stack;
|
||||
|
||||
EekBounds bounds;
|
||||
EekKeyboard *keyboard;
|
||||
EekSection *section;
|
||||
EekKey *key;
|
||||
gint num_columns;
|
||||
struct squeek_view **views;
|
||||
guint view_idx;
|
||||
struct squeek_row *row;
|
||||
gint num_rows;
|
||||
EekOrientation orientation;
|
||||
gdouble corner_radius;
|
||||
GSList *points;
|
||||
gchar *name;
|
||||
EekOutline outline;
|
||||
gchar *oref;
|
||||
gchar *outline_id;
|
||||
guint keycode;
|
||||
|
||||
GHashTable *key_oref_hash;
|
||||
GHashTable *oref_outline_hash;
|
||||
GString *text;
|
||||
|
||||
GArray *outline_array;
|
||||
|
||||
GHashTable *name_button_hash; // char* -> struct squeek_button*
|
||||
GHashTable *keyname_oref_hash; // char* -> guint
|
||||
GHashTable *outlineid_oref_hash; // char* -> guint
|
||||
};
|
||||
typedef struct _GeometryParseData GeometryParseData;
|
||||
|
||||
static GeometryParseData *
|
||||
geometry_parse_data_new (EekKeyboard *keyboard)
|
||||
geometry_parse_data_new (struct squeek_view **views, GHashTable *name_button_hash, GArray *outline_array)
|
||||
{
|
||||
GeometryParseData *data = g_slice_new0 (GeometryParseData);
|
||||
|
||||
data->keyboard = g_object_ref (keyboard);
|
||||
data->key_oref_hash =
|
||||
g_hash_table_new_full (g_direct_hash,
|
||||
g_direct_equal,
|
||||
NULL,
|
||||
g_free);
|
||||
data->oref_outline_hash =
|
||||
data->views = views;
|
||||
data->outline_array = outline_array;
|
||||
data->keyname_oref_hash =
|
||||
g_hash_table_new_full (g_str_hash,
|
||||
g_str_equal,
|
||||
g_free,
|
||||
(GDestroyNotify)eek_outline_free);
|
||||
NULL);
|
||||
data->outlineid_oref_hash =
|
||||
g_hash_table_new_full (g_str_hash,
|
||||
g_str_equal,
|
||||
g_free,
|
||||
NULL);
|
||||
|
||||
data->name_button_hash = name_button_hash;
|
||||
data->text = g_string_sized_new (BUFSIZE);
|
||||
data->keycode = 8;
|
||||
return data;
|
||||
}
|
||||
|
||||
static void
|
||||
geometry_parse_data_free (GeometryParseData *data)
|
||||
{
|
||||
g_object_unref (data->keyboard);
|
||||
g_hash_table_destroy (data->key_oref_hash);
|
||||
g_hash_table_destroy (data->oref_outline_hash);
|
||||
g_hash_table_destroy (data->keyname_oref_hash);
|
||||
g_hash_table_destroy (data->outlineid_oref_hash);
|
||||
g_string_free (data->text, TRUE);
|
||||
g_slice_free (GeometryParseData, data);
|
||||
}
|
||||
|
||||
static const gchar *geometry_valid_path_list[] = {
|
||||
"geometry",
|
||||
"button/geometry",
|
||||
"bounds/geometry",
|
||||
"section/geometry",
|
||||
"view/geometry",
|
||||
"section/view/geometry",
|
||||
"outline/geometry",
|
||||
"bounds/section/geometry",
|
||||
"row/section/geometry",
|
||||
"key/row/section/geometry",
|
||||
"bounds/key/row/section/geometry",
|
||||
"point/outline/geometry",
|
||||
};
|
||||
|
||||
@ -359,80 +360,67 @@ geometry_start_element_callback (GMarkupParseContext *pcontext,
|
||||
return;
|
||||
}
|
||||
bounds.height = g_strtod (attribute, NULL);
|
||||
|
||||
if (g_strcmp0 (data->element_stack->data, "geometry") == 0)
|
||||
eek_element_set_bounds (EEK_ELEMENT(data->keyboard), &bounds);
|
||||
data->bounds = bounds;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (g_strcmp0 (element_name, "view") == 0) {
|
||||
/* Create an empty keyboard to which geometry and symbols
|
||||
information are applied. */
|
||||
struct squeek_view *view = squeek_view_new(data->bounds);
|
||||
data->views[data->view_idx] = view;
|
||||
}
|
||||
|
||||
if (g_strcmp0 (element_name, "section") == 0) {
|
||||
data->section = eek_keyboard_create_section (data->keyboard);
|
||||
attribute = get_attribute (attribute_names, attribute_values,
|
||||
"id");
|
||||
if (attribute != NULL)
|
||||
eek_element_set_name (EEK_ELEMENT(data->section), attribute);
|
||||
gint angle = 0;
|
||||
attribute = get_attribute (attribute_names, attribute_values,
|
||||
"angle");
|
||||
if (attribute != NULL) {
|
||||
gint angle;
|
||||
angle = strtol (attribute, NULL, 10);
|
||||
eek_section_set_angle (data->section, angle);
|
||||
}
|
||||
data->row = squeek_view_create_row(data->views[data->view_idx], angle);
|
||||
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (g_strcmp0 (element_name, "row") == 0) {
|
||||
attribute = get_attribute (attribute_names, attribute_values,
|
||||
"orientation");
|
||||
if (attribute != NULL)
|
||||
data->orientation = strtol (attribute, NULL, 10);
|
||||
|
||||
eek_section_add_row (data->section,
|
||||
data->num_columns,
|
||||
data->orientation);
|
||||
|
||||
data->num_rows++;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (g_strcmp0 (element_name, "key") == 0) {
|
||||
guint keycode;
|
||||
|
||||
attribute = get_attribute (attribute_names, attribute_values,
|
||||
"keycode");
|
||||
if (attribute == NULL) {
|
||||
g_set_error (error,
|
||||
G_MARKUP_ERROR,
|
||||
G_MARKUP_ERROR_MISSING_ATTRIBUTE,
|
||||
"no \"keycode\" attribute for \"key\"");
|
||||
return;
|
||||
}
|
||||
keycode = strtoul (attribute, NULL, 10);
|
||||
|
||||
data->key = eek_section_create_key (data->section,
|
||||
keycode,
|
||||
data->num_columns,
|
||||
data->num_rows - 1);
|
||||
|
||||
attribute = get_attribute (attribute_names, attribute_values,
|
||||
if (g_strcmp0 (element_name, "button") == 0) {
|
||||
const gchar *base_name = 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,
|
||||
"oref");
|
||||
if (attribute == NULL) {
|
||||
if (base_name == NULL) {
|
||||
g_set_error (error,
|
||||
G_MARKUP_ERROR,
|
||||
G_MARKUP_ERROR_MISSING_ATTRIBUTE,
|
||||
"no \"oref\" attribute for \"key\"");
|
||||
"no \"name\" attribute for \"button\"");
|
||||
return;
|
||||
}
|
||||
g_hash_table_insert (data->key_oref_hash,
|
||||
data->key,
|
||||
g_strdup (attribute));
|
||||
|
||||
data->num_columns++;
|
||||
const gchar *oref_name = get_attribute (attribute_names, attribute_values,
|
||||
"oref");
|
||||
if (oref_name == NULL) {
|
||||
oref_name = "default";
|
||||
}
|
||||
const gchar *keycode_name = get_attribute (attribute_names, attribute_values,
|
||||
"keycode");
|
||||
|
||||
guint oref = GPOINTER_TO_UINT(g_hash_table_lookup(data->outlineid_oref_hash,
|
||||
oref_name));
|
||||
const gchar *name = base_name;
|
||||
g_hash_table_insert (data->keyname_oref_hash,
|
||||
g_strdup(name),
|
||||
GUINT_TO_POINTER(oref));
|
||||
|
||||
struct squeek_button *button = g_hash_table_lookup(data->name_button_hash, name);
|
||||
// never gets used! this section gets executed before any buttons get defined
|
||||
if (button) {
|
||||
if (keycode_name != NULL) {
|
||||
// This sets the keycode for all buttons,
|
||||
// since they share state
|
||||
// TODO: get rid of this in the parser;
|
||||
// this belongs after keymap is defined
|
||||
struct squeek_key *key = squeek_button_get_key(button);
|
||||
squeek_key_set_keycode(key, strtol (keycode_name, NULL, 10));
|
||||
}
|
||||
}
|
||||
|
||||
goto out;
|
||||
}
|
||||
@ -446,7 +434,7 @@ geometry_start_element_callback (GMarkupParseContext *pcontext,
|
||||
"no \"id\" attribute for \"outline\"");
|
||||
return;
|
||||
}
|
||||
data->oref = g_strdup (attribute);
|
||||
data->outline_id = g_strdup (attribute);
|
||||
|
||||
attribute = get_attribute (attribute_names, attribute_values,
|
||||
"corner-radius");
|
||||
@ -491,6 +479,30 @@ geometry_start_element_callback (GMarkupParseContext *pcontext,
|
||||
out:
|
||||
data->element_stack = g_slist_prepend (data->element_stack,
|
||||
g_strdup (element_name));
|
||||
data->text->len = 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* eek_keyboard_add_outline:
|
||||
* @keyboard: an #EekKeyboard
|
||||
* @outline: an #EekOutline
|
||||
*
|
||||
* Register an outline of @keyboard.
|
||||
* Returns: an unsigned integer ID of the registered outline, for
|
||||
* later reference
|
||||
*/
|
||||
static guint
|
||||
add_outline (GArray *outline_array,
|
||||
EekOutline *outline)
|
||||
{
|
||||
EekOutline *_outline;
|
||||
|
||||
_outline = eek_outline_copy (outline);
|
||||
g_array_append_val (outline_array, *_outline);
|
||||
/* don't use eek_outline_free here, so as to keep _outline->points */
|
||||
g_slice_free (EekOutline, _outline);
|
||||
return outline_array->len - 1;
|
||||
}
|
||||
|
||||
static void
|
||||
@ -506,23 +518,68 @@ geometry_end_element_callback (GMarkupParseContext *pcontext,
|
||||
data->element_stack = g_slist_next (data->element_stack);
|
||||
g_slist_free1 (head);
|
||||
|
||||
const gchar *text = g_strndup (data->text->str, data->text->len);
|
||||
|
||||
if (g_strcmp0 (element_name, "view") == 0) {
|
||||
data->view_idx++;
|
||||
return;
|
||||
}
|
||||
|
||||
if (g_strcmp0 (element_name, "section") == 0) {
|
||||
data->section = NULL;
|
||||
// Split text on spaces and process each part
|
||||
unsigned head = 0;
|
||||
while (head < strlen(text)) {
|
||||
// Skip to the first non-space character
|
||||
for (; head < strlen(text); head++) {
|
||||
if (text[head] != ' ') {
|
||||
break;
|
||||
}
|
||||
}
|
||||
unsigned start = head;
|
||||
|
||||
// Skip to the first space character
|
||||
for (; head < strlen(text); head++) {
|
||||
if (text[head] == ' ') {
|
||||
break;
|
||||
}
|
||||
}
|
||||
unsigned end = head;
|
||||
|
||||
/// Reached the end
|
||||
if (start == end) {
|
||||
break;
|
||||
}
|
||||
|
||||
gchar *name = g_strndup (&text[start], end - start);
|
||||
struct squeek_button *button = g_hash_table_lookup(data->name_button_hash, name);
|
||||
if (!button) {
|
||||
// Save button name together with its level,
|
||||
// to account for buttons with the same name in multiple levels
|
||||
guint keycode = data->keycode++;
|
||||
|
||||
guint oref = GPOINTER_TO_UINT(g_hash_table_lookup(data->keyname_oref_hash, name));
|
||||
// default value gives idx 0, which is guaranteed to be occupied
|
||||
button = squeek_row_create_button (data->row, keycode, oref);
|
||||
g_hash_table_insert (data->name_button_hash,
|
||||
g_strdup(name),
|
||||
button);
|
||||
} else {
|
||||
struct squeek_button *new_button = squeek_row_create_button_with_state(data->row, button);
|
||||
if (!new_button) {
|
||||
g_set_error (error,
|
||||
G_MARKUP_ERROR,
|
||||
G_MARKUP_ERROR_MISSING_ATTRIBUTE,
|
||||
"Couldn't create a shared button");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
data->row = NULL;
|
||||
data->num_rows = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
if (g_strcmp0 (element_name, "key") == 0) {
|
||||
data->key = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
if (g_strcmp0 (element_name, "row") == 0) {
|
||||
data->num_columns = 0;
|
||||
data->orientation = EEK_ORIENTATION_HORIZONTAL;
|
||||
return;
|
||||
}
|
||||
|
||||
if (g_strcmp0 (element_name, "outline") == 0) {
|
||||
EekOutline *outline = g_slice_new (EekOutline);
|
||||
|
||||
@ -542,19 +599,30 @@ geometry_end_element_callback (GMarkupParseContext *pcontext,
|
||||
g_slist_free (data->points);
|
||||
data->points = NULL;
|
||||
|
||||
g_hash_table_insert (data->oref_outline_hash,
|
||||
g_strdup (data->oref),
|
||||
outline);
|
||||
guint oref = add_outline (data->outline_array, outline);
|
||||
|
||||
g_free (data->oref);
|
||||
g_hash_table_insert (data->outlineid_oref_hash,
|
||||
data->outline_id,
|
||||
GUINT_TO_POINTER(oref));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
geometry_text_callback (GMarkupParseContext *pcontext,
|
||||
const gchar *text,
|
||||
gsize text_len,
|
||||
gpointer user_data,
|
||||
GError **error)
|
||||
{
|
||||
GeometryParseData *data = user_data;
|
||||
g_string_append_len (data->text, text, (gssize)text_len);
|
||||
}
|
||||
|
||||
static const GMarkupParser geometry_parser = {
|
||||
geometry_start_element_callback,
|
||||
geometry_end_element_callback,
|
||||
0,
|
||||
geometry_text_callback,
|
||||
0,
|
||||
0
|
||||
};
|
||||
@ -563,24 +631,22 @@ struct _SymbolsParseData {
|
||||
GSList *element_stack;
|
||||
GString *text;
|
||||
|
||||
EekKeyboard *keyboard;
|
||||
EekKey *key;
|
||||
GSList *symbols;
|
||||
LevelKeyboard *keyboard;
|
||||
struct squeek_view *view;
|
||||
|
||||
gchar *label;
|
||||
gchar *icon;
|
||||
gchar *tooltip;
|
||||
EekSymbolCategory category;
|
||||
guint keyval;
|
||||
gint groups;
|
||||
};
|
||||
typedef struct _SymbolsParseData SymbolsParseData;
|
||||
|
||||
static SymbolsParseData *
|
||||
symbols_parse_data_new (EekKeyboard *keyboard)
|
||||
symbols_parse_data_new (LevelKeyboard *keyboard)
|
||||
{
|
||||
SymbolsParseData *data = g_slice_new0 (SymbolsParseData);
|
||||
|
||||
data->keyboard = g_object_ref (keyboard);
|
||||
data->keyboard = keyboard;
|
||||
data->text = g_string_sized_new (BUFSIZE);
|
||||
return data;
|
||||
}
|
||||
@ -588,19 +654,14 @@ symbols_parse_data_new (EekKeyboard *keyboard)
|
||||
static void
|
||||
symbols_parse_data_free (SymbolsParseData *data)
|
||||
{
|
||||
g_object_unref (data->keyboard);
|
||||
g_string_free (data->text, TRUE);
|
||||
g_slice_free (SymbolsParseData, data);
|
||||
}
|
||||
|
||||
static const gchar *symbols_valid_path_list[] = {
|
||||
"symbols",
|
||||
"symbol/symbols",
|
||||
"include/symbols",
|
||||
"key/symbols",
|
||||
"text/key/symbols",
|
||||
"keysym/key/symbols",
|
||||
"symbol/key/symbols",
|
||||
"invalid/key/symbols",
|
||||
};
|
||||
|
||||
static void
|
||||
@ -621,56 +682,7 @@ symbols_start_element_callback (GMarkupParseContext *pcontext,
|
||||
error))
|
||||
return;
|
||||
|
||||
if (g_strcmp0 (element_name, "key") == 0) {
|
||||
guint keycode;
|
||||
|
||||
attribute = get_attribute (attribute_names, attribute_values,
|
||||
"keycode");
|
||||
if (attribute == NULL) {
|
||||
g_set_error (error,
|
||||
G_MARKUP_ERROR,
|
||||
G_MARKUP_ERROR_MISSING_ATTRIBUTE,
|
||||
"no \"keycode\" attribute for \"key\"");
|
||||
return;
|
||||
}
|
||||
keycode = strtoul (attribute, NULL, 10);
|
||||
|
||||
data->key = eek_keyboard_find_key_by_keycode (data->keyboard,
|
||||
keycode);
|
||||
/*if (data->key == NULL) {
|
||||
g_set_error (error,
|
||||
G_MARKUP_ERROR,
|
||||
G_MARKUP_ERROR_INVALID_CONTENT,
|
||||
"no such keycode %u", keycode);
|
||||
return;
|
||||
}*/
|
||||
|
||||
attribute = get_attribute (attribute_names, attribute_values,
|
||||
"groups");
|
||||
if (attribute != NULL)
|
||||
data->groups = strtol (attribute, NULL, 10);
|
||||
else
|
||||
data->groups = 1;
|
||||
data->symbols = NULL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (g_strcmp0 (element_name, "keysym") == 0) {
|
||||
attribute = get_attribute (attribute_names, attribute_values,
|
||||
"keyval");
|
||||
if (attribute == NULL) {
|
||||
g_set_error (error,
|
||||
G_MARKUP_ERROR,
|
||||
G_MARKUP_ERROR_MISSING_ATTRIBUTE,
|
||||
"no \"keyval\" attribute for \"keysym\"");
|
||||
return;
|
||||
}
|
||||
data->keyval = strtoul (attribute, NULL, 0);
|
||||
}
|
||||
|
||||
if (g_strcmp0 (element_name, "symbol") == 0 ||
|
||||
g_strcmp0 (element_name, "keysym") == 0 ||
|
||||
g_strcmp0 (element_name, "text") == 0) {
|
||||
if (g_strcmp0 (element_name, "symbol") == 0) {
|
||||
attribute = get_attribute (attribute_names, attribute_values,
|
||||
"label");
|
||||
if (attribute != NULL)
|
||||
@ -685,16 +697,8 @@ symbols_start_element_callback (GMarkupParseContext *pcontext,
|
||||
"tooltip");
|
||||
if (attribute != NULL)
|
||||
data->tooltip = g_strdup (attribute);
|
||||
|
||||
attribute = get_attribute (attribute_names, attribute_values,
|
||||
"category");
|
||||
if (attribute != NULL)
|
||||
data->category = strtoul (attribute, NULL, 10);
|
||||
else
|
||||
data->category = EEK_SYMBOL_CATEGORY_KEYNAME;
|
||||
}
|
||||
|
||||
out:
|
||||
data->element_stack = g_slist_prepend (data->element_stack,
|
||||
g_strdup (element_name));
|
||||
data->text->len = 0;
|
||||
@ -709,82 +713,42 @@ symbols_end_element_callback (GMarkupParseContext *pcontext,
|
||||
SymbolsParseData *data = user_data;
|
||||
GSList *head = data->element_stack;
|
||||
gchar *text;
|
||||
gint i;
|
||||
|
||||
g_free (head->data);
|
||||
data->element_stack = g_slist_next (data->element_stack);
|
||||
g_slist_free1 (head);
|
||||
|
||||
// TODO: this could all be moved to text handler
|
||||
text = g_strndup (data->text->str, data->text->len);
|
||||
|
||||
if (g_strcmp0 (element_name, "key") == 0) {
|
||||
if (!data->key) {
|
||||
return;
|
||||
if (g_strcmp0 (element_name, "symbol") == 0) {
|
||||
|
||||
gchar *name = text;
|
||||
struct squeek_button *button = eek_keyboard_find_button_by_name (data->keyboard,
|
||||
name);
|
||||
if (button) {
|
||||
squeek_key_add_symbol(
|
||||
squeek_button_get_key(button),
|
||||
element_name,
|
||||
text,
|
||||
data->keyval,
|
||||
data->label,
|
||||
data->icon,
|
||||
data->tooltip
|
||||
);
|
||||
}
|
||||
|
||||
gint num_symbols = g_slist_length (data->symbols);
|
||||
gint levels = num_symbols / data->groups;
|
||||
EekSymbolMatrix *matrix = eek_symbol_matrix_new (data->groups,
|
||||
levels);
|
||||
|
||||
head = data->symbols = g_slist_reverse (data->symbols);
|
||||
for (i = 0; i < num_symbols; i++) {
|
||||
if (head && head->data) {
|
||||
matrix->data[i] = head->data;
|
||||
head = g_slist_next (head);
|
||||
} else
|
||||
matrix->data[i] = NULL;
|
||||
}
|
||||
g_slist_free (data->symbols);
|
||||
data->symbols = NULL;
|
||||
|
||||
eek_key_set_symbol_matrix (data->key, matrix);
|
||||
eek_symbol_matrix_free (matrix);
|
||||
data->key = NULL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (g_strcmp0 (element_name, "symbol") == 0 ||
|
||||
g_strcmp0 (element_name, "keysym") == 0 ||
|
||||
g_strcmp0 (element_name, "text") == 0) {
|
||||
EekSymbol *symbol;
|
||||
|
||||
if (g_strcmp0 (element_name, "keysym") == 0) {
|
||||
EekKeysym *keysym;
|
||||
if (data->keyval != EEK_INVALID_KEYSYM)
|
||||
keysym = eek_keysym_new (data->keyval);
|
||||
else
|
||||
keysym = eek_keysym_new_from_name (text);
|
||||
symbol = EEK_SYMBOL(keysym);
|
||||
} else if (g_strcmp0 (element_name, "text") == 0) {
|
||||
symbol = EEK_SYMBOL(eek_text_new (text));
|
||||
} else {
|
||||
symbol = eek_symbol_new (text);
|
||||
eek_symbol_set_category (symbol, EEK_SYMBOL_CATEGORY_KEYNAME);
|
||||
}
|
||||
|
||||
if (data->label) {
|
||||
eek_symbol_set_label (symbol, data->label);
|
||||
g_free (data->label);
|
||||
data->label = NULL;
|
||||
}
|
||||
if (data->icon) {
|
||||
eek_symbol_set_icon_name (symbol, data->icon);
|
||||
g_free (data->icon);
|
||||
data->icon = NULL;
|
||||
}
|
||||
if (data->tooltip) {
|
||||
eek_symbol_set_tooltip (symbol, data->tooltip);
|
||||
g_free (data->tooltip);
|
||||
data->tooltip = NULL;
|
||||
}
|
||||
|
||||
data->symbols = g_slist_prepend (data->symbols, symbol);
|
||||
data->keyval = 0;
|
||||
g_free(data->label);
|
||||
data->label = NULL;
|
||||
g_free(data->icon);
|
||||
data->icon = NULL;
|
||||
g_free(data->tooltip);
|
||||
data->tooltip = NULL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (g_strcmp0 (element_name, "invalid") == 0) {
|
||||
data->symbols = g_slist_prepend (data->symbols, NULL);
|
||||
goto out;
|
||||
}
|
||||
|
||||
@ -896,31 +860,37 @@ static const GMarkupParser prerequisites_parser = {
|
||||
0
|
||||
};
|
||||
|
||||
static EekKeyboard *
|
||||
eek_xml_layout_real_create_keyboard (EekboardContextService *manager,
|
||||
EekLayout *self,
|
||||
gdouble initial_width,
|
||||
gdouble initial_height)
|
||||
LevelKeyboard *
|
||||
eek_xml_layout_real_create_keyboard (EekLayout *self,
|
||||
EekboardContextService *manager)
|
||||
{
|
||||
EekXmlLayout *layout = EEK_XML_LAYOUT (self);
|
||||
EekXmlLayoutPrivate *priv = eek_xml_layout_get_instance_private (layout);
|
||||
gboolean retval;
|
||||
|
||||
/* Create an empty keyboard to which geometry and symbols
|
||||
information are applied. */
|
||||
EekKeyboard *keyboard = g_object_new (EEK_TYPE_KEYBOARD, "layout", layout, NULL);
|
||||
keyboard->manager = manager;
|
||||
|
||||
/* Read geometry information. */
|
||||
gchar *filename = g_strdup_printf ("%s.xml", priv->desc->geometry);
|
||||
gchar *path = g_build_filename (priv->keyboards_dir, "geometry", filename, NULL);
|
||||
g_free (filename);
|
||||
|
||||
GArray *outline_array = g_array_new (FALSE, TRUE, sizeof (EekOutline));
|
||||
|
||||
// char* -> struct squeek_button*
|
||||
GHashTable *name_button_hash =
|
||||
g_hash_table_new_full (g_str_hash,
|
||||
g_str_equal,
|
||||
g_free,
|
||||
NULL);
|
||||
// One view for each level
|
||||
struct squeek_view *views[4] = {0};
|
||||
|
||||
GError *error = NULL;
|
||||
retval = parse_geometry (path, keyboard, &error);
|
||||
retval = parse_geometry (path, views, outline_array, name_button_hash, &error);
|
||||
g_free (path);
|
||||
if (!retval) {
|
||||
g_object_unref (keyboard);
|
||||
for (uint i = 0; i < 4; i++) {
|
||||
g_object_unref (views[i]);
|
||||
}
|
||||
g_warning ("can't parse geometry file %s: %s",
|
||||
priv->desc->geometry,
|
||||
error->message);
|
||||
@ -928,6 +898,12 @@ eek_xml_layout_real_create_keyboard (EekboardContextService *manager,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
LevelKeyboard *keyboard = level_keyboard_new(manager, views, name_button_hash);
|
||||
|
||||
keyboard->outline_array = outline_array;
|
||||
// FIXME: are symbols shared betwen views?
|
||||
|
||||
/* Read symbols information. */
|
||||
GList *loaded = NULL;
|
||||
retval = parse_symbols_with_prerequisites (priv->keyboards_dir,
|
||||
@ -937,7 +913,13 @@ eek_xml_layout_real_create_keyboard (EekboardContextService *manager,
|
||||
&error);
|
||||
g_list_free_full (loaded, g_free);
|
||||
if (!retval) {
|
||||
g_object_unref (keyboard);
|
||||
for (uint i = 0; i < 4; i++) {
|
||||
if (views[i]) {
|
||||
g_object_unref(views[i]);
|
||||
views[i] = NULL;
|
||||
}
|
||||
}
|
||||
//g_object_unref (view);
|
||||
g_warning ("can't parse symbols file %s: %s",
|
||||
priv->desc->symbols,
|
||||
error->message);
|
||||
@ -945,12 +927,11 @@ eek_xml_layout_real_create_keyboard (EekboardContextService *manager,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Fit keyboard in the given width and hight. */
|
||||
scale_keyboard (keyboard, initial_width, initial_height);
|
||||
|
||||
/* Use pre-defined modifier mask here. */
|
||||
eek_keyboard_set_num_lock_mask (keyboard, EEK_MOD2_MASK);
|
||||
eek_keyboard_set_alt_gr_mask (keyboard, EEK_BUTTON1_MASK);
|
||||
for (uint i = 0; i < 4; i++) {
|
||||
if (views[i]) {
|
||||
squeek_view_place_contents(views[i], keyboard);
|
||||
}
|
||||
}
|
||||
|
||||
return keyboard;
|
||||
}
|
||||
@ -998,7 +979,7 @@ static void
|
||||
eek_xml_layout_finalize (GObject *object)
|
||||
{
|
||||
EekXmlLayoutPrivate *priv = eek_xml_layout_get_instance_private (
|
||||
EEK_XML_LAYOUT (object));
|
||||
EEK_XML_LAYOUT (object));
|
||||
|
||||
g_free (priv->id);
|
||||
|
||||
@ -1013,21 +994,18 @@ eek_xml_layout_finalize (GObject *object)
|
||||
static void
|
||||
eek_xml_layout_class_init (EekXmlLayoutClass *klass)
|
||||
{
|
||||
EekLayoutClass *layout_class = EEK_LAYOUT_CLASS (klass);
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||
GParamSpec *pspec;
|
||||
|
||||
layout_class->create_keyboard = eek_xml_layout_real_create_keyboard;
|
||||
|
||||
gobject_class->set_property = eek_xml_layout_set_property;
|
||||
gobject_class->get_property = eek_xml_layout_get_property;
|
||||
gobject_class->finalize = eek_xml_layout_finalize;
|
||||
|
||||
pspec = g_param_spec_string ("id",
|
||||
"ID",
|
||||
"ID",
|
||||
NULL,
|
||||
G_PARAM_CONSTRUCT_ONLY |
|
||||
"ID",
|
||||
"ID",
|
||||
NULL,
|
||||
G_PARAM_CONSTRUCT_ONLY |
|
||||
G_PARAM_READWRITE);
|
||||
g_object_class_install_property (gobject_class, PROP_ID, pspec);
|
||||
}
|
||||
@ -1138,46 +1116,11 @@ eek_xml_keyboard_desc_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
|
||||
parse_geometry (const gchar *path, EekKeyboard *keyboard, GError **error)
|
||||
parse_geometry (const gchar *path, struct squeek_view **views, GArray *outline_array, GHashTable *name_button_hash, GError **error)
|
||||
{
|
||||
GeometryParseData *data;
|
||||
GMarkupParseContext *pcontext;
|
||||
GHashTable *oref_hash;
|
||||
GHashTableIter iter;
|
||||
gpointer k, v;
|
||||
GFile *file;
|
||||
GFileInputStream *input;
|
||||
gboolean retval;
|
||||
@ -1191,7 +1134,7 @@ parse_geometry (const gchar *path, EekKeyboard *keyboard, GError **error)
|
||||
if (input == NULL)
|
||||
return FALSE;
|
||||
|
||||
data = geometry_parse_data_new (keyboard);
|
||||
data = geometry_parse_data_new (views, name_button_hash, outline_array);
|
||||
pcontext = g_markup_parse_context_new (&geometry_parser,
|
||||
0,
|
||||
data,
|
||||
@ -1206,44 +1149,29 @@ parse_geometry (const gchar *path, EekKeyboard *keyboard, GError **error)
|
||||
}
|
||||
|
||||
/* Resolve outline references. */
|
||||
/*
|
||||
* GHashTable *oref_hash;
|
||||
GHashTableIter iter;
|
||||
gpointer k, v;
|
||||
|
||||
oref_hash = g_hash_table_new (g_str_hash, g_str_equal);
|
||||
g_hash_table_iter_init (&iter, data->oref_outline_hash);
|
||||
while (g_hash_table_iter_next (&iter, &k, &v)) {
|
||||
EekOutline *outline = v;
|
||||
gulong oref;
|
||||
|
||||
oref = eek_keyboard_add_outline (data->keyboard, outline);
|
||||
oref = add_outline (outline_array, outline);
|
||||
g_hash_table_insert (oref_hash, k, GUINT_TO_POINTER(oref));
|
||||
}
|
||||
}*/
|
||||
|
||||
/*
|
||||
g_hash_table_iter_init (&iter, data->key_oref_hash);
|
||||
while (g_hash_table_iter_next (&iter, &k, &v)) {
|
||||
gpointer oref;
|
||||
if (g_hash_table_lookup_extended (oref_hash, v, NULL, &oref))
|
||||
eek_key_set_oref (EEK_KEY(k), GPOINTER_TO_UINT(oref));
|
||||
}
|
||||
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);
|
||||
}*/
|
||||
// g_hash_table_destroy (oref_hash);
|
||||
|
||||
geometry_parse_data_free (data);
|
||||
return TRUE;
|
||||
@ -1252,7 +1180,7 @@ parse_geometry (const gchar *path, EekKeyboard *keyboard, GError **error)
|
||||
static gboolean
|
||||
parse_symbols_with_prerequisites (const gchar *keyboards_dir,
|
||||
const gchar *name,
|
||||
EekKeyboard *keyboard,
|
||||
LevelKeyboard *keyboard,
|
||||
GList **loaded,
|
||||
GError **error)
|
||||
{
|
||||
@ -1302,7 +1230,7 @@ parse_symbols_with_prerequisites (const gchar *keyboards_dir,
|
||||
}
|
||||
|
||||
static gboolean
|
||||
parse_symbols (const gchar *path, EekKeyboard *keyboard, GError **error)
|
||||
parse_symbols (const gchar *path, LevelKeyboard *keyboard, GError **error)
|
||||
{
|
||||
SymbolsParseData *data;
|
||||
GMarkupParseContext *pcontext;
|
||||
@ -1410,65 +1338,6 @@ parse_keyboards (const gchar *path, GError **error)
|
||||
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
|
||||
validate (const gchar **valid_path_list,
|
||||
gsize valid_path_list_len,
|
||||
@ -1476,7 +1345,7 @@ validate (const gchar **valid_path_list,
|
||||
GSList *element_stack,
|
||||
GError **error)
|
||||
{
|
||||
gint i;
|
||||
guint i;
|
||||
gchar *element_path;
|
||||
GSList *head, *p;
|
||||
GString *string;
|
||||
|
||||
@ -62,5 +62,8 @@ GList *eek_xml_list_keyboards (void);
|
||||
EekXmlKeyboardDesc *eek_xml_keyboard_desc_copy (EekXmlKeyboardDesc *desc);
|
||||
void eek_xml_keyboard_desc_free (EekXmlKeyboardDesc *desc);
|
||||
|
||||
LevelKeyboard *
|
||||
eek_xml_layout_real_create_keyboard (EekLayout *self,
|
||||
EekboardContextService *manager);
|
||||
G_END_DECLS
|
||||
#endif /* EEK_XML_LAYOUT_H */
|
||||
|
||||
317
eek/eek-xml.c
317
eek/eek-xml.c
@ -1,317 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2011 Daiki Ueno <ueno@unixuser.org>
|
||||
* Copyright (C) 2011 Red Hat, Inc.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* SECTION: eek-xml
|
||||
* @title: XML Conversion Utilities
|
||||
* @short_description: #EekKeyboard to XML conversion utilities
|
||||
*/
|
||||
|
||||
#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");
|
||||
}
|
||||
@ -1,39 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2011 Daiki Ueno <ueno@unixuser.org>
|
||||
* Copyright (C) 2011 Red Hat, Inc.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#if !defined(__EEK_H_INSIDE__) && !defined(EEK_COMPILATION)
|
||||
#error "Only <eek/eek.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#ifndef EEK_XML_H
|
||||
#define EEK_XML_H 1
|
||||
|
||||
#include <glib-object.h>
|
||||
#include "eek-keyboard.h"
|
||||
#include "eek-xml-layout.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define EEK_XML_SCHEMA_VERSION "0.90"
|
||||
|
||||
void eek_keyboard_output (EekKeyboard *keyboard,
|
||||
GString *output,
|
||||
gint indent);
|
||||
|
||||
G_END_DECLS
|
||||
#endif /* EEK_XML_H */
|
||||
@ -23,9 +23,7 @@
|
||||
* @title: Library Initialization
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
|
||||
#include "eek.h"
|
||||
|
||||
|
||||
@ -23,15 +23,8 @@
|
||||
#define __EEK_H_INSIDE__ 1
|
||||
|
||||
#include "eek-keyboard.h"
|
||||
#include "eek-section.h"
|
||||
#include "eek-key.h"
|
||||
#include "eek-layout.h"
|
||||
#include "eek-symbol.h"
|
||||
#include "eek-keysym.h"
|
||||
#include "eek-text.h"
|
||||
#include "eek-xml.h"
|
||||
#include "eek-serializable.h"
|
||||
#include "eek-theme.h"
|
||||
|
||||
void eek_init (void);
|
||||
|
||||
|
||||
@ -33,7 +33,7 @@ else:
|
||||
|
||||
table = dict()
|
||||
for line in in_stream:
|
||||
match = re.match(r'\s*(0x[0-9A-F]+)\s+(\S*)\s+(\S*)', line, re.I)
|
||||
match = re.match(r'\s*(0x[0-9A-F]+)\s+"(.*)"\s+(\S*)', line, re.I)
|
||||
if match:
|
||||
table[int(match.group(1), 16)] = (match.group(2), match.group(3))
|
||||
|
||||
@ -42,8 +42,8 @@ sys.stdout.write("static const EekKeysymEntry %s[] = {\n" %
|
||||
|
||||
for index, (keysym, (l, c)) in enumerate([(keysym, table[keysym])
|
||||
for keysym in sorted(table.keys())]):
|
||||
sys.stdout.write(" { 0x%X, %s, %s }" %
|
||||
(keysym, l, c))
|
||||
sys.stdout.write(" { 0x%X, \"%s\" }" %
|
||||
(keysym, l))
|
||||
if index < len(table) - 1:
|
||||
sys.stdout.write(",")
|
||||
sys.stdout.write("\n")
|
||||
|
||||
39
eek/keymap.h
Normal file
39
eek/keymap.h
Normal file
@ -0,0 +1,39 @@
|
||||
#include <gdk/gdk.h>
|
||||
#include <xkbcommon/xkbcommon.h>
|
||||
|
||||
gboolean
|
||||
squeek_keymap_get_entries_for_keyval (struct xkb_keymap *xkb_keymap,
|
||||
guint keyval,
|
||||
GdkKeymapKey **keys,
|
||||
guint *n_keys);
|
||||
|
||||
static const char *keymap_header = "xkb_keymap {\n\
|
||||
\n";
|
||||
|
||||
static const char *keymap_keycodes_header = "\
|
||||
xkb_keycodes \"squeekboard\" {\n\n\
|
||||
minimum = 8;\n\
|
||||
maximum = 255;\n\
|
||||
\n";
|
||||
|
||||
static const char *keymap_symbols_header = "\
|
||||
xkb_symbols \"squeekboard\" {\n\
|
||||
\n\
|
||||
name[Group1] = \"Letters\";\n\
|
||||
name[Group2] = \"Numbers/Symbols\";\n\
|
||||
\n";
|
||||
|
||||
static const char *keymap_footer = "\
|
||||
xkb_types \"squeekboard\" {\n\
|
||||
\n\
|
||||
type \"TWO_LEVEL\" {\n\
|
||||
modifiers = Shift;\n\
|
||||
map[Shift] = Level2;\n\
|
||||
level_name[Level1] = \"Base\";\n\
|
||||
level_name[Level2] = \"Shift\";\n\
|
||||
};\n\
|
||||
};\n\
|
||||
\n\
|
||||
xkb_compatibility \"squeekboard\" {\n\
|
||||
};\n\
|
||||
};";
|
||||
@ -65,9 +65,9 @@ static void layer_surface_configure(void *data,
|
||||
uint32_t height)
|
||||
{
|
||||
PhoshLayerSurface *self = data;
|
||||
|
||||
gtk_window_resize (GTK_WINDOW (self), width, height);
|
||||
zwlr_layer_surface_v1_ack_configure(surface, serial);
|
||||
gtk_widget_show_all (GTK_WIDGET (self));
|
||||
|
||||
g_signal_emit (self, signals[CONFIGURED], 0);
|
||||
}
|
||||
@ -180,22 +180,39 @@ phosh_layer_surface_get_property (GObject *object,
|
||||
|
||||
|
||||
static void
|
||||
phosh_layer_surface_constructed (GObject *object)
|
||||
on_phosh_layer_surface_realized (PhoshLayerSurface *self, gpointer unused)
|
||||
{
|
||||
PhoshLayerSurface *self = PHOSH_LAYER_SURFACE (object);
|
||||
PhoshLayerSurfacePrivate *priv = phosh_layer_surface_get_instance_private (self);
|
||||
PhoshLayerSurfacePrivate *priv;
|
||||
GdkWindow *gdk_window;
|
||||
|
||||
G_OBJECT_CLASS (phosh_layer_surface_parent_class)->constructed (object);
|
||||
g_return_if_fail (PHOSH_IS_LAYER_SURFACE (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));
|
||||
priv = phosh_layer_surface_get_instance_private (self);
|
||||
|
||||
gdk_window = gtk_widget_get_window (GTK_WIDGET (self));
|
||||
gdk_wayland_window_set_use_custom_surface (gdk_window);
|
||||
priv->wl_surface = gdk_wayland_window_get_wl_surface (gdk_window);
|
||||
|
||||
gtk_window_set_decorated (GTK_WINDOW (self), FALSE);
|
||||
}
|
||||
|
||||
|
||||
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->wl_surface,
|
||||
priv->wl_output,
|
||||
@ -209,8 +226,45 @@ phosh_layer_surface_constructed (GObject *object)
|
||||
&layer_surface_listener,
|
||||
self);
|
||||
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
|
||||
phosh_layer_surface_dispose (GObject *object)
|
||||
{
|
||||
@ -352,6 +406,12 @@ phosh_layer_surface_new (gpointer layer_shell,
|
||||
"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 *
|
||||
phosh_layer_surface_get_layer_surface(PhoshLayerSurface *self)
|
||||
{
|
||||
@ -363,6 +423,12 @@ 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 *
|
||||
phosh_layer_surface_get_wl_surface(PhoshLayerSurface *self)
|
||||
{
|
||||
|
||||
@ -1,35 +1,13 @@
|
||||
gnome = import('gnome')
|
||||
|
||||
enum_headers = [
|
||||
'eek-symbol.h',
|
||||
'eek-types.h',
|
||||
]
|
||||
|
||||
enums = gnome.mkenums_simple('eek-enumtypes', sources: enum_headers)
|
||||
|
||||
marshalers = gnome.genmarshal(
|
||||
'eek-marshalers',
|
||||
sources: ['eek-marshalers.list'],
|
||||
prefix: '_eek_marshal',
|
||||
internal: true,
|
||||
)
|
||||
|
||||
python = find_program('python3')
|
||||
|
||||
gen_keysym_entries_special = generator(
|
||||
python,
|
||||
arguments: ['@CURRENT_SOURCE_DIR@/gen-keysym-entries.py', 'special_keysym_entries', '@INPUT@'],
|
||||
capture: true,
|
||||
output: 'eek-@BASENAME@.h',
|
||||
)
|
||||
|
||||
gen_keysym_entries_unicode = generator(
|
||||
python,
|
||||
arguments: ['@CURRENT_SOURCE_DIR@/gen-keysym-entries.py', 'unicode_keysym_entries', '@INPUT@'],
|
||||
capture: true,
|
||||
output: 'eek-@BASENAME@.h',
|
||||
)
|
||||
|
||||
gen_keysym_entries_xkeysym = generator(
|
||||
python,
|
||||
arguments: ['@CURRENT_SOURCE_DIR@/gen-keysym-entries.py', 'xkeysym_keysym_entries', '@INPUT@'],
|
||||
@ -38,7 +16,5 @@ gen_keysym_entries_xkeysym = generator(
|
||||
)
|
||||
|
||||
keysym_entries = [
|
||||
gen_keysym_entries_special.process('./special-keysym-entries.txt'),
|
||||
gen_keysym_entries_unicode.process('./unicode-keysym-entries.txt'),
|
||||
gen_keysym_entries_xkeysym.process('./xkeysym-keysym-entries.txt'),
|
||||
]
|
||||
|
||||
@ -1,62 +0,0 @@
|
||||
0x20 "" EEK_SYMBOL_CATEGORY_LETTER
|
||||
0x8A3 "horiz\nconn" EEK_SYMBOL_CATEGORY_LETTER
|
||||
0xFE50 "ˋ" EEK_SYMBOL_CATEGORY_LETTER
|
||||
0xFE51 "ˊ" EEK_SYMBOL_CATEGORY_LETTER
|
||||
0xFE52 "ˆ" EEK_SYMBOL_CATEGORY_LETTER
|
||||
0xFE53 "~" EEK_SYMBOL_CATEGORY_LETTER
|
||||
0xFE54 "ˉ" EEK_SYMBOL_CATEGORY_LETTER
|
||||
0xFE55 "˘" EEK_SYMBOL_CATEGORY_LETTER
|
||||
0xFE56 "˙" EEK_SYMBOL_CATEGORY_LETTER
|
||||
0xFE57 "¨" EEK_SYMBOL_CATEGORY_LETTER
|
||||
0xFE58 "˚" EEK_SYMBOL_CATEGORY_LETTER
|
||||
0xFE59 "˝" EEK_SYMBOL_CATEGORY_LETTER
|
||||
0xFE5A "ˇ" EEK_SYMBOL_CATEGORY_LETTER
|
||||
0xFE5B "¸" EEK_SYMBOL_CATEGORY_LETTER
|
||||
0xFE5C "˛" EEK_SYMBOL_CATEGORY_LETTER
|
||||
0xFF14 "Scroll\nLock" EEK_SYMBOL_CATEGORY_FUNCTION
|
||||
0xFF20 "Compose" EEK_SYMBOL_CATEGORY_FUNCTION
|
||||
0xFF55 "Page\nUp" EEK_SYMBOL_CATEGORY_FUNCTION
|
||||
0xFF56 "Page\nDown" EEK_SYMBOL_CATEGORY_FUNCTION
|
||||
0xFF7E "AltGr" EEK_SYMBOL_CATEGORY_FUNCTION
|
||||
0xFF7F "Num\nLock" EEK_SYMBOL_CATEGORY_FUNCTION
|
||||
0xFF8D "Enter" EEK_SYMBOL_CATEGORY_FUNCTION
|
||||
0xFF95 "Home" EEK_SYMBOL_CATEGORY_FUNCTION
|
||||
0xFF96 "Left" EEK_SYMBOL_CATEGORY_FUNCTION
|
||||
0xFF97 "Up" EEK_SYMBOL_CATEGORY_FUNCTION
|
||||
0xFF98 "Right" EEK_SYMBOL_CATEGORY_FUNCTION
|
||||
0xFF99 "Down" EEK_SYMBOL_CATEGORY_FUNCTION
|
||||
0xFF9C "End" EEK_SYMBOL_CATEGORY_FUNCTION
|
||||
0xFF9D "Begin" EEK_SYMBOL_CATEGORY_FUNCTION
|
||||
0xFF9E "Ins" EEK_SYMBOL_CATEGORY_FUNCTION
|
||||
0xFF9F "Del" EEK_SYMBOL_CATEGORY_FUNCTION
|
||||
# aliases
|
||||
0xFE03 "123" EEK_SYMBOL_CATEGORY_KEYNAME
|
||||
0xFE04 "⇮" EEK_SYMBOL_CATEGORY_KEYNAME
|
||||
0xFE05 "⇮" EEK_SYMBOL_CATEGORY_KEYNAME
|
||||
0xFE08 "Next" EEK_SYMBOL_CATEGORY_KEYNAME
|
||||
0xFE0A "Prev" EEK_SYMBOL_CATEGORY_KEYNAME
|
||||
0xFF08 "←" EEK_SYMBOL_CATEGORY_KEYNAME
|
||||
0xFF09 "⇥" EEK_SYMBOL_CATEGORY_KEYNAME
|
||||
0xFE20 "⇤" EEK_SYMBOL_CATEGORY_KEYNAME
|
||||
0xFF0D "↵" EEK_SYMBOL_CATEGORY_KEYNAME
|
||||
0xFF1B "Esc" EEK_SYMBOL_CATEGORY_KEYNAME
|
||||
0xFFE1 "⇧" EEK_SYMBOL_CATEGORY_KEYNAME
|
||||
0xFFE2 "⇧" EEK_SYMBOL_CATEGORY_KEYNAME
|
||||
0xFFE3 "Ctrl" EEK_SYMBOL_CATEGORY_KEYNAME
|
||||
0xFFE4 "Ctrl" EEK_SYMBOL_CATEGORY_KEYNAME
|
||||
0xFFE5 "⇪" EEK_SYMBOL_CATEGORY_KEYNAME
|
||||
0xFFE9 "Alt" EEK_SYMBOL_CATEGORY_KEYNAME
|
||||
0xFFEA "Alt" EEK_SYMBOL_CATEGORY_KEYNAME
|
||||
0xFFE7 "Meta" EEK_SYMBOL_CATEGORY_KEYNAME
|
||||
0xFFE8 "Meta" EEK_SYMBOL_CATEGORY_KEYNAME
|
||||
0xFFEB "Super" EEK_SYMBOL_CATEGORY_KEYNAME
|
||||
0xFFEC "Super" EEK_SYMBOL_CATEGORY_KEYNAME
|
||||
0xFFED "Hyper" EEK_SYMBOL_CATEGORY_KEYNAME
|
||||
0xFFEE "Hyper" EEK_SYMBOL_CATEGORY_KEYNAME
|
||||
0xFF2A "半" EEK_SYMBOL_CATEGORY_KEYNAME
|
||||
0xFF21 "漢" EEK_SYMBOL_CATEGORY_KEYNAME
|
||||
0xff51 "⇠" EEK_SYMBOL_CATEGORY_KEYNAME # 1
|
||||
0xff52 "⇡" EEK_SYMBOL_CATEGORY_KEYNAME # 1
|
||||
0xff53 "⇢" EEK_SYMBOL_CATEGORY_KEYNAME # 1
|
||||
0xff54 "⇣" EEK_SYMBOL_CATEGORY_KEYNAME # 1
|
||||
0xff30 "英" EEK_SYMBOL_CATEGORY_KEYNAME
|
||||
@ -1,826 +0,0 @@
|
||||
# This file is derived from gdkkeyuni.c in GTK+. Thanks for the
|
||||
# team. The original comments are below:
|
||||
|
||||
# Modified by the GTK+ Team and others 1997-2000. See the AUTHORS
|
||||
# file for a list of people on the GTK+ Team. See the ChangeLog
|
||||
# files for a list of changes. These files are distributed with
|
||||
# GTK+ at ftp://ftp.gtk.org/pub/gtk/.
|
||||
|
||||
# Thanks to Markus G. Kuhn <mkuhn@acm.org> for the ksysym<->Unicode
|
||||
# mapping functions, from the xterm sources.
|
||||
|
||||
# These tables could be compressed by contiguous ranges, but the
|
||||
# benefit of doing so is smallish. It would save about ~1000 bytes
|
||||
# total.
|
||||
|
||||
0x01a1 "Ą" EEK_SYMBOL_CATEGORY_LETTER # Aogonek Ą LATIN CAPITAL LETTER A WITH OGONEK
|
||||
0x01a2 "˘" EEK_SYMBOL_CATEGORY_LETTER # breve ˘ BREVE
|
||||
0x01a3 "Ł" EEK_SYMBOL_CATEGORY_LETTER # Lstroke Ł LATIN CAPITAL LETTER L WITH STROKE
|
||||
0x01a5 "Ľ" EEK_SYMBOL_CATEGORY_LETTER # Lcaron Ľ LATIN CAPITAL LETTER L WITH CARON
|
||||
0x01a6 "Ś" EEK_SYMBOL_CATEGORY_LETTER # Sacute Ś LATIN CAPITAL LETTER S WITH ACUTE
|
||||
0x01a9 "Š" EEK_SYMBOL_CATEGORY_LETTER # Scaron Š LATIN CAPITAL LETTER S WITH CARON
|
||||
0x01aa "Ş" EEK_SYMBOL_CATEGORY_LETTER # Scedilla Ş LATIN CAPITAL LETTER S WITH CEDILLA
|
||||
0x01ab "Ť" EEK_SYMBOL_CATEGORY_LETTER # Tcaron Ť LATIN CAPITAL LETTER T WITH CARON
|
||||
0x01ac "Ź" EEK_SYMBOL_CATEGORY_LETTER # Zacute Ź LATIN CAPITAL LETTER Z WITH ACUTE
|
||||
0x01ae "Ž" EEK_SYMBOL_CATEGORY_LETTER # Zcaron Ž LATIN CAPITAL LETTER Z WITH CARON
|
||||
0x01af "Ż" EEK_SYMBOL_CATEGORY_LETTER # Zabovedot Ż LATIN CAPITAL LETTER Z WITH DOT ABOVE
|
||||
0x01b1 "ą" EEK_SYMBOL_CATEGORY_LETTER # aogonek ą LATIN SMALL LETTER A WITH OGONEK
|
||||
0x01b2 "˛" EEK_SYMBOL_CATEGORY_LETTER # ogonek ˛ OGONEK
|
||||
0x01b3 "ł" EEK_SYMBOL_CATEGORY_LETTER # lstroke ł LATIN SMALL LETTER L WITH STROKE
|
||||
0x01b5 "ľ" EEK_SYMBOL_CATEGORY_LETTER # lcaron ľ LATIN SMALL LETTER L WITH CARON
|
||||
0x01b6 "ś" EEK_SYMBOL_CATEGORY_LETTER # sacute ś LATIN SMALL LETTER S WITH ACUTE
|
||||
0x01b7 "ˇ" EEK_SYMBOL_CATEGORY_LETTER # caron ˇ CARON
|
||||
0x01b9 "š" EEK_SYMBOL_CATEGORY_LETTER # scaron š LATIN SMALL LETTER S WITH CARON
|
||||
0x01ba "ş" EEK_SYMBOL_CATEGORY_LETTER # scedilla ş LATIN SMALL LETTER S WITH CEDILLA
|
||||
0x01bb "ť" EEK_SYMBOL_CATEGORY_LETTER # tcaron ť LATIN SMALL LETTER T WITH CARON
|
||||
0x01bc "ź" EEK_SYMBOL_CATEGORY_LETTER # zacute ź LATIN SMALL LETTER Z WITH ACUTE
|
||||
0x01bd "˝" EEK_SYMBOL_CATEGORY_LETTER # doubleacute ˝ DOUBLE ACUTE ACCENT
|
||||
0x01be "ž" EEK_SYMBOL_CATEGORY_LETTER # zcaron ž LATIN SMALL LETTER Z WITH CARON
|
||||
0x01bf "ż" EEK_SYMBOL_CATEGORY_LETTER # zabovedot ż LATIN SMALL LETTER Z WITH DOT ABOVE
|
||||
0x01c0 "Ŕ" EEK_SYMBOL_CATEGORY_LETTER # Racute Ŕ LATIN CAPITAL LETTER R WITH ACUTE
|
||||
0x01c3 "Ă" EEK_SYMBOL_CATEGORY_LETTER # Abreve Ă LATIN CAPITAL LETTER A WITH BREVE
|
||||
0x01c5 "Ĺ" EEK_SYMBOL_CATEGORY_LETTER # Lacute Ĺ LATIN CAPITAL LETTER L WITH ACUTE
|
||||
0x01c6 "Ć" EEK_SYMBOL_CATEGORY_LETTER # Cacute Ć LATIN CAPITAL LETTER C WITH ACUTE
|
||||
0x01c8 "Č" EEK_SYMBOL_CATEGORY_LETTER # Ccaron Č LATIN CAPITAL LETTER C WITH CARON
|
||||
0x01ca "Ę" EEK_SYMBOL_CATEGORY_LETTER # Eogonek Ę LATIN CAPITAL LETTER E WITH OGONEK
|
||||
0x01cc "Ě" EEK_SYMBOL_CATEGORY_LETTER # Ecaron Ě LATIN CAPITAL LETTER E WITH CARON
|
||||
0x01cf "Ď" EEK_SYMBOL_CATEGORY_LETTER # Dcaron Ď LATIN CAPITAL LETTER D WITH CARON
|
||||
0x01d0 "Đ" EEK_SYMBOL_CATEGORY_LETTER # Dstroke Đ LATIN CAPITAL LETTER D WITH STROKE
|
||||
0x01d1 "Ń" EEK_SYMBOL_CATEGORY_LETTER # Nacute Ń LATIN CAPITAL LETTER N WITH ACUTE
|
||||
0x01d2 "Ň" EEK_SYMBOL_CATEGORY_LETTER # Ncaron Ň LATIN CAPITAL LETTER N WITH CARON
|
||||
0x01d5 "Ő" EEK_SYMBOL_CATEGORY_LETTER # Odoubleacute Ő LATIN CAPITAL LETTER O WITH DOUBLE ACUTE
|
||||
0x01d8 "Ř" EEK_SYMBOL_CATEGORY_LETTER # Rcaron Ř LATIN CAPITAL LETTER R WITH CARON
|
||||
0x01d9 "Ů" EEK_SYMBOL_CATEGORY_LETTER # Uring Ů LATIN CAPITAL LETTER U WITH RING ABOVE
|
||||
0x01db "Ű" EEK_SYMBOL_CATEGORY_LETTER # Udoubleacute Ű LATIN CAPITAL LETTER U WITH DOUBLE ACUTE
|
||||
0x01de "Ţ" EEK_SYMBOL_CATEGORY_LETTER # Tcedilla Ţ LATIN CAPITAL LETTER T WITH CEDILLA
|
||||
0x01e0 "ŕ" EEK_SYMBOL_CATEGORY_LETTER # racute ŕ LATIN SMALL LETTER R WITH ACUTE
|
||||
0x01e3 "ă" EEK_SYMBOL_CATEGORY_LETTER # abreve ă LATIN SMALL LETTER A WITH BREVE
|
||||
0x01e5 "ĺ" EEK_SYMBOL_CATEGORY_LETTER # lacute ĺ LATIN SMALL LETTER L WITH ACUTE
|
||||
0x01e6 "ć" EEK_SYMBOL_CATEGORY_LETTER # cacute ć LATIN SMALL LETTER C WITH ACUTE
|
||||
0x01e8 "č" EEK_SYMBOL_CATEGORY_LETTER # ccaron č LATIN SMALL LETTER C WITH CARON
|
||||
0x01ea "ę" EEK_SYMBOL_CATEGORY_LETTER # eogonek ę LATIN SMALL LETTER E WITH OGONEK
|
||||
0x01ec "ě" EEK_SYMBOL_CATEGORY_LETTER # ecaron ě LATIN SMALL LETTER E WITH CARON
|
||||
0x01ef "ď" EEK_SYMBOL_CATEGORY_LETTER # dcaron ď LATIN SMALL LETTER D WITH CARON
|
||||
0x01f0 "đ" EEK_SYMBOL_CATEGORY_LETTER # dstroke đ LATIN SMALL LETTER D WITH STROKE
|
||||
0x01f1 "ń" EEK_SYMBOL_CATEGORY_LETTER # nacute ń LATIN SMALL LETTER N WITH ACUTE
|
||||
0x01f2 "ň" EEK_SYMBOL_CATEGORY_LETTER # ncaron ň LATIN SMALL LETTER N WITH CARON
|
||||
0x01f5 "ő" EEK_SYMBOL_CATEGORY_LETTER # odoubleacute ő LATIN SMALL LETTER O WITH DOUBLE ACUTE
|
||||
0x01f8 "ř" EEK_SYMBOL_CATEGORY_LETTER # rcaron ř LATIN SMALL LETTER R WITH CARON
|
||||
0x01f9 "ů" EEK_SYMBOL_CATEGORY_LETTER # uring ů LATIN SMALL LETTER U WITH RING ABOVE
|
||||
0x01fb "ű" EEK_SYMBOL_CATEGORY_LETTER # udoubleacute ű LATIN SMALL LETTER U WITH DOUBLE ACUTE
|
||||
0x01fe "ţ" EEK_SYMBOL_CATEGORY_LETTER # tcedilla ţ LATIN SMALL LETTER T WITH CEDILLA
|
||||
0x01ff "˙" EEK_SYMBOL_CATEGORY_LETTER # abovedot ˙ DOT ABOVE
|
||||
0x02a1 "Ħ" EEK_SYMBOL_CATEGORY_LETTER # Hstroke Ħ LATIN CAPITAL LETTER H WITH STROKE
|
||||
0x02a6 "Ĥ" EEK_SYMBOL_CATEGORY_LETTER # Hcircumflex Ĥ LATIN CAPITAL LETTER H WITH CIRCUMFLEX
|
||||
0x02a9 "İ" EEK_SYMBOL_CATEGORY_LETTER # Iabovedot İ LATIN CAPITAL LETTER I WITH DOT ABOVE
|
||||
0x02ab "Ğ" EEK_SYMBOL_CATEGORY_LETTER # Gbreve Ğ LATIN CAPITAL LETTER G WITH BREVE
|
||||
0x02ac "Ĵ" EEK_SYMBOL_CATEGORY_LETTER # Jcircumflex Ĵ LATIN CAPITAL LETTER J WITH CIRCUMFLEX
|
||||
0x02b1 "ħ" EEK_SYMBOL_CATEGORY_LETTER # hstroke ħ LATIN SMALL LETTER H WITH STROKE
|
||||
0x02b6 "ĥ" EEK_SYMBOL_CATEGORY_LETTER # hcircumflex ĥ LATIN SMALL LETTER H WITH CIRCUMFLEX
|
||||
0x02b9 "ı" EEK_SYMBOL_CATEGORY_LETTER # idotless ı LATIN SMALL LETTER DOTLESS I
|
||||
0x02bb "ğ" EEK_SYMBOL_CATEGORY_LETTER # gbreve ğ LATIN SMALL LETTER G WITH BREVE
|
||||
0x02bc "ĵ" EEK_SYMBOL_CATEGORY_LETTER # jcircumflex ĵ LATIN SMALL LETTER J WITH CIRCUMFLEX
|
||||
0x02c5 "Ċ" EEK_SYMBOL_CATEGORY_LETTER # Cabovedot Ċ LATIN CAPITAL LETTER C WITH DOT ABOVE
|
||||
0x02c6 "Ĉ" EEK_SYMBOL_CATEGORY_LETTER # Ccircumflex Ĉ LATIN CAPITAL LETTER C WITH CIRCUMFLEX
|
||||
0x02d5 "Ġ" EEK_SYMBOL_CATEGORY_LETTER # Gabovedot Ġ LATIN CAPITAL LETTER G WITH DOT ABOVE
|
||||
0x02d8 "Ĝ" EEK_SYMBOL_CATEGORY_LETTER # Gcircumflex Ĝ LATIN CAPITAL LETTER G WITH CIRCUMFLEX
|
||||
0x02dd "Ŭ" EEK_SYMBOL_CATEGORY_LETTER # Ubreve Ŭ LATIN CAPITAL LETTER U WITH BREVE
|
||||
0x02de "Ŝ" EEK_SYMBOL_CATEGORY_LETTER # Scircumflex Ŝ LATIN CAPITAL LETTER S WITH CIRCUMFLEX
|
||||
0x02e5 "ċ" EEK_SYMBOL_CATEGORY_LETTER # cabovedot ċ LATIN SMALL LETTER C WITH DOT ABOVE
|
||||
0x02e6 "ĉ" EEK_SYMBOL_CATEGORY_LETTER # ccircumflex ĉ LATIN SMALL LETTER C WITH CIRCUMFLEX
|
||||
0x02f5 "ġ" EEK_SYMBOL_CATEGORY_LETTER # gabovedot ġ LATIN SMALL LETTER G WITH DOT ABOVE
|
||||
0x02f8 "ĝ" EEK_SYMBOL_CATEGORY_LETTER # gcircumflex ĝ LATIN SMALL LETTER G WITH CIRCUMFLEX
|
||||
0x02fd "ŭ" EEK_SYMBOL_CATEGORY_LETTER # ubreve ŭ LATIN SMALL LETTER U WITH BREVE
|
||||
0x02fe "ŝ" EEK_SYMBOL_CATEGORY_LETTER # scircumflex ŝ LATIN SMALL LETTER S WITH CIRCUMFLEX
|
||||
0x03a2 "ĸ" EEK_SYMBOL_CATEGORY_LETTER # kra ĸ LATIN SMALL LETTER KRA
|
||||
0x03a3 "Ŗ" EEK_SYMBOL_CATEGORY_LETTER # Rcedilla Ŗ LATIN CAPITAL LETTER R WITH CEDILLA
|
||||
0x03a5 "Ĩ" EEK_SYMBOL_CATEGORY_LETTER # Itilde Ĩ LATIN CAPITAL LETTER I WITH TILDE
|
||||
0x03a6 "Ļ" EEK_SYMBOL_CATEGORY_LETTER # Lcedilla Ļ LATIN CAPITAL LETTER L WITH CEDILLA
|
||||
0x03aa "Ē" EEK_SYMBOL_CATEGORY_LETTER # Emacron Ē LATIN CAPITAL LETTER E WITH MACRON
|
||||
0x03ab "Ģ" EEK_SYMBOL_CATEGORY_LETTER # Gcedilla Ģ LATIN CAPITAL LETTER G WITH CEDILLA
|
||||
0x03ac "Ŧ" EEK_SYMBOL_CATEGORY_LETTER # Tslash Ŧ LATIN CAPITAL LETTER T WITH STROKE
|
||||
0x03b3 "ŗ" EEK_SYMBOL_CATEGORY_LETTER # rcedilla ŗ LATIN SMALL LETTER R WITH CEDILLA
|
||||
0x03b5 "ĩ" EEK_SYMBOL_CATEGORY_LETTER # itilde ĩ LATIN SMALL LETTER I WITH TILDE
|
||||
0x03b6 "ļ" EEK_SYMBOL_CATEGORY_LETTER # lcedilla ļ LATIN SMALL LETTER L WITH CEDILLA
|
||||
0x03ba "ē" EEK_SYMBOL_CATEGORY_LETTER # emacron ē LATIN SMALL LETTER E WITH MACRON
|
||||
0x03bb "ģ" EEK_SYMBOL_CATEGORY_LETTER # gcedilla ģ LATIN SMALL LETTER G WITH CEDILLA
|
||||
0x03bc "ŧ" EEK_SYMBOL_CATEGORY_LETTER # tslash ŧ LATIN SMALL LETTER T WITH STROKE
|
||||
0x03bd "Ŋ" EEK_SYMBOL_CATEGORY_LETTER # ENG Ŋ LATIN CAPITAL LETTER ENG
|
||||
0x03bf "ŋ" EEK_SYMBOL_CATEGORY_LETTER # eng ŋ LATIN SMALL LETTER ENG
|
||||
0x03c0 "Ā" EEK_SYMBOL_CATEGORY_LETTER # Amacron Ā LATIN CAPITAL LETTER A WITH MACRON
|
||||
0x03c7 "Į" EEK_SYMBOL_CATEGORY_LETTER # Iogonek Į LATIN CAPITAL LETTER I WITH OGONEK
|
||||
0x03cc "Ė" EEK_SYMBOL_CATEGORY_LETTER # Eabovedot Ė LATIN CAPITAL LETTER E WITH DOT ABOVE
|
||||
0x03cf "Ī" EEK_SYMBOL_CATEGORY_LETTER # Imacron Ī LATIN CAPITAL LETTER I WITH MACRON
|
||||
0x03d1 "Ņ" EEK_SYMBOL_CATEGORY_LETTER # Ncedilla Ņ LATIN CAPITAL LETTER N WITH CEDILLA
|
||||
0x03d2 "Ō" EEK_SYMBOL_CATEGORY_LETTER # Omacron Ō LATIN CAPITAL LETTER O WITH MACRON
|
||||
0x03d3 "Ķ" EEK_SYMBOL_CATEGORY_LETTER # Kcedilla Ķ LATIN CAPITAL LETTER K WITH CEDILLA
|
||||
0x03d9 "Ų" EEK_SYMBOL_CATEGORY_LETTER # Uogonek Ų LATIN CAPITAL LETTER U WITH OGONEK
|
||||
0x03dd "Ũ" EEK_SYMBOL_CATEGORY_LETTER # Utilde Ũ LATIN CAPITAL LETTER U WITH TILDE
|
||||
0x03de "Ū" EEK_SYMBOL_CATEGORY_LETTER # Umacron Ū LATIN CAPITAL LETTER U WITH MACRON
|
||||
0x03e0 "ā" EEK_SYMBOL_CATEGORY_LETTER # amacron ā LATIN SMALL LETTER A WITH MACRON
|
||||
0x03e7 "į" EEK_SYMBOL_CATEGORY_LETTER # iogonek į LATIN SMALL LETTER I WITH OGONEK
|
||||
0x03ec "ė" EEK_SYMBOL_CATEGORY_LETTER # eabovedot ė LATIN SMALL LETTER E WITH DOT ABOVE
|
||||
0x03ef "ī" EEK_SYMBOL_CATEGORY_LETTER # imacron ī LATIN SMALL LETTER I WITH MACRON
|
||||
0x03f1 "ņ" EEK_SYMBOL_CATEGORY_LETTER # ncedilla ņ LATIN SMALL LETTER N WITH CEDILLA
|
||||
0x03f2 "ō" EEK_SYMBOL_CATEGORY_LETTER # omacron ō LATIN SMALL LETTER O WITH MACRON
|
||||
0x03f3 "ķ" EEK_SYMBOL_CATEGORY_LETTER # kcedilla ķ LATIN SMALL LETTER K WITH CEDILLA
|
||||
0x03f9 "ų" EEK_SYMBOL_CATEGORY_LETTER # uogonek ų LATIN SMALL LETTER U WITH OGONEK
|
||||
0x03fd "ũ" EEK_SYMBOL_CATEGORY_LETTER # utilde ũ LATIN SMALL LETTER U WITH TILDE
|
||||
0x03fe "ū" EEK_SYMBOL_CATEGORY_LETTER # umacron ū LATIN SMALL LETTER U WITH MACRON
|
||||
0x047e "‾" EEK_SYMBOL_CATEGORY_LETTER # overline ‾ OVERLINE
|
||||
0x04a1 "。" EEK_SYMBOL_CATEGORY_LETTER # kana_fullstop 。 IDEOGRAPHIC FULL STOP
|
||||
0x04a2 "「" EEK_SYMBOL_CATEGORY_LETTER # kana_openingbracket 「 LEFT CORNER BRACKET
|
||||
0x04a3 "」" EEK_SYMBOL_CATEGORY_LETTER # kana_closingbracket 」 RIGHT CORNER BRACKET
|
||||
0x04a4 "、" EEK_SYMBOL_CATEGORY_LETTER # kana_comma 、 IDEOGRAPHIC COMMA
|
||||
0x04a5 "・" EEK_SYMBOL_CATEGORY_LETTER # kana_conjunctive ・ KATAKANA MIDDLE DOT
|
||||
0x04a6 "ヲ" EEK_SYMBOL_CATEGORY_LETTER # kana_WO ヲ KATAKANA LETTER WO
|
||||
0x04a7 "ァ" EEK_SYMBOL_CATEGORY_LETTER # kana_a ァ KATAKANA LETTER SMALL A
|
||||
0x04a8 "ィ" EEK_SYMBOL_CATEGORY_LETTER # kana_i ィ KATAKANA LETTER SMALL I
|
||||
0x04a9 "ゥ" EEK_SYMBOL_CATEGORY_LETTER # kana_u ゥ KATAKANA LETTER SMALL U
|
||||
0x04aa "ェ" EEK_SYMBOL_CATEGORY_LETTER # kana_e ェ KATAKANA LETTER SMALL E
|
||||
0x04ab "ォ" EEK_SYMBOL_CATEGORY_LETTER # kana_o ォ KATAKANA LETTER SMALL O
|
||||
0x04ac "ャ" EEK_SYMBOL_CATEGORY_LETTER # kana_ya ャ KATAKANA LETTER SMALL YA
|
||||
0x04ad "ュ" EEK_SYMBOL_CATEGORY_LETTER # kana_yu ュ KATAKANA LETTER SMALL YU
|
||||
0x04ae "ョ" EEK_SYMBOL_CATEGORY_LETTER # kana_yo ョ KATAKANA LETTER SMALL YO
|
||||
0x04af "ッ" EEK_SYMBOL_CATEGORY_LETTER # kana_tsu ッ KATAKANA LETTER SMALL TU
|
||||
0x04b0 "ー" EEK_SYMBOL_CATEGORY_LETTER # prolongedsound ー KATAKANA-HIRAGANA PROLONGED SOUND MARK
|
||||
0x04b1 "ア" EEK_SYMBOL_CATEGORY_LETTER # kana_A ア KATAKANA LETTER A
|
||||
0x04b2 "イ" EEK_SYMBOL_CATEGORY_LETTER # kana_I イ KATAKANA LETTER I
|
||||
0x04b3 "ウ" EEK_SYMBOL_CATEGORY_LETTER # kana_U ウ KATAKANA LETTER U
|
||||
0x04b4 "エ" EEK_SYMBOL_CATEGORY_LETTER # kana_E エ KATAKANA LETTER E
|
||||
0x04b5 "オ" EEK_SYMBOL_CATEGORY_LETTER # kana_O オ KATAKANA LETTER O
|
||||
0x04b6 "カ" EEK_SYMBOL_CATEGORY_LETTER # kana_KA カ KATAKANA LETTER KA
|
||||
0x04b7 "キ" EEK_SYMBOL_CATEGORY_LETTER # kana_KI キ KATAKANA LETTER KI
|
||||
0x04b8 "ク" EEK_SYMBOL_CATEGORY_LETTER # kana_KU ク KATAKANA LETTER KU
|
||||
0x04b9 "ケ" EEK_SYMBOL_CATEGORY_LETTER # kana_KE ケ KATAKANA LETTER KE
|
||||
0x04ba "コ" EEK_SYMBOL_CATEGORY_LETTER # kana_KO コ KATAKANA LETTER KO
|
||||
0x04bb "サ" EEK_SYMBOL_CATEGORY_LETTER # kana_SA サ KATAKANA LETTER SA
|
||||
0x04bc "シ" EEK_SYMBOL_CATEGORY_LETTER # kana_SHI シ KATAKANA LETTER SI
|
||||
0x04bd "ス" EEK_SYMBOL_CATEGORY_LETTER # kana_SU ス KATAKANA LETTER SU
|
||||
0x04be "セ" EEK_SYMBOL_CATEGORY_LETTER # kana_SE セ KATAKANA LETTER SE
|
||||
0x04bf "ソ" EEK_SYMBOL_CATEGORY_LETTER # kana_SO ソ KATAKANA LETTER SO
|
||||
0x04c0 "タ" EEK_SYMBOL_CATEGORY_LETTER # kana_TA タ KATAKANA LETTER TA
|
||||
0x04c1 "チ" EEK_SYMBOL_CATEGORY_LETTER # kana_CHI チ KATAKANA LETTER TI
|
||||
0x04c2 "ツ" EEK_SYMBOL_CATEGORY_LETTER # kana_TSU ツ KATAKANA LETTER TU
|
||||
0x04c3 "テ" EEK_SYMBOL_CATEGORY_LETTER # kana_TE テ KATAKANA LETTER TE
|
||||
0x04c4 "ト" EEK_SYMBOL_CATEGORY_LETTER # kana_TO ト KATAKANA LETTER TO
|
||||
0x04c5 "ナ" EEK_SYMBOL_CATEGORY_LETTER # kana_NA ナ KATAKANA LETTER NA
|
||||
0x04c6 "ニ" EEK_SYMBOL_CATEGORY_LETTER # kana_NI ニ KATAKANA LETTER NI
|
||||
0x04c7 "ヌ" EEK_SYMBOL_CATEGORY_LETTER # kana_NU ヌ KATAKANA LETTER NU
|
||||
0x04c8 "ネ" EEK_SYMBOL_CATEGORY_LETTER # kana_NE ネ KATAKANA LETTER NE
|
||||
0x04c9 "ノ" EEK_SYMBOL_CATEGORY_LETTER # kana_NO ノ KATAKANA LETTER NO
|
||||
0x04ca "ハ" EEK_SYMBOL_CATEGORY_LETTER # kana_HA ハ KATAKANA LETTER HA
|
||||
0x04cb "ヒ" EEK_SYMBOL_CATEGORY_LETTER # kana_HI ヒ KATAKANA LETTER HI
|
||||
0x04cc "フ" EEK_SYMBOL_CATEGORY_LETTER # kana_FU フ KATAKANA LETTER HU
|
||||
0x04cd "ヘ" EEK_SYMBOL_CATEGORY_LETTER # kana_HE ヘ KATAKANA LETTER HE
|
||||
0x04ce "ホ" EEK_SYMBOL_CATEGORY_LETTER # kana_HO ホ KATAKANA LETTER HO
|
||||
0x04cf "マ" EEK_SYMBOL_CATEGORY_LETTER # kana_MA マ KATAKANA LETTER MA
|
||||
0x04d0 "ミ" EEK_SYMBOL_CATEGORY_LETTER # kana_MI ミ KATAKANA LETTER MI
|
||||
0x04d1 "ム" EEK_SYMBOL_CATEGORY_LETTER # kana_MU ム KATAKANA LETTER MU
|
||||
0x04d2 "メ" EEK_SYMBOL_CATEGORY_LETTER # kana_ME メ KATAKANA LETTER ME
|
||||
0x04d3 "モ" EEK_SYMBOL_CATEGORY_LETTER # kana_MO モ KATAKANA LETTER MO
|
||||
0x04d4 "ヤ" EEK_SYMBOL_CATEGORY_LETTER # kana_YA ヤ KATAKANA LETTER YA
|
||||
0x04d5 "ユ" EEK_SYMBOL_CATEGORY_LETTER # kana_YU ユ KATAKANA LETTER YU
|
||||
0x04d6 "ヨ" EEK_SYMBOL_CATEGORY_LETTER # kana_YO ヨ KATAKANA LETTER YO
|
||||
0x04d7 "ラ" EEK_SYMBOL_CATEGORY_LETTER # kana_RA ラ KATAKANA LETTER RA
|
||||
0x04d8 "リ" EEK_SYMBOL_CATEGORY_LETTER # kana_RI リ KATAKANA LETTER RI
|
||||
0x04d9 "ル" EEK_SYMBOL_CATEGORY_LETTER # kana_RU ル KATAKANA LETTER RU
|
||||
0x04da "レ" EEK_SYMBOL_CATEGORY_LETTER # kana_RE レ KATAKANA LETTER RE
|
||||
0x04db "ロ" EEK_SYMBOL_CATEGORY_LETTER # kana_RO ロ KATAKANA LETTER RO
|
||||
0x04dc "ワ" EEK_SYMBOL_CATEGORY_LETTER # kana_WA ワ KATAKANA LETTER WA
|
||||
0x04dd "ン" EEK_SYMBOL_CATEGORY_LETTER # kana_N ン KATAKANA LETTER N
|
||||
0x04de "゛" EEK_SYMBOL_CATEGORY_LETTER # voicedsound ゛ KATAKANA-HIRAGANA VOICED SOUND MARK
|
||||
0x04df "゜" EEK_SYMBOL_CATEGORY_LETTER # semivoicedsound ゜ KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK
|
||||
0x05ac "،" EEK_SYMBOL_CATEGORY_LETTER # Arabic_comma ، ARABIC COMMA
|
||||
0x05bb "؛" EEK_SYMBOL_CATEGORY_LETTER # Arabic_semicolon ؛ ARABIC SEMICOLON
|
||||
0x05bf "؟" EEK_SYMBOL_CATEGORY_LETTER # Arabic_question_mark ؟ ARABIC QUESTION MARK
|
||||
0x05c1 "ء" EEK_SYMBOL_CATEGORY_LETTER # Arabic_hamza ء ARABIC LETTER HAMZA
|
||||
0x05c2 "آ" EEK_SYMBOL_CATEGORY_LETTER # Arabic_maddaonalef آ ARABIC LETTER ALEF WITH MADDA ABOVE
|
||||
0x05c3 "أ" EEK_SYMBOL_CATEGORY_LETTER # Arabic_hamzaonalef أ ARABIC LETTER ALEF WITH HAMZA ABOVE
|
||||
0x05c4 "ؤ" EEK_SYMBOL_CATEGORY_LETTER # Arabic_hamzaonwaw ؤ ARABIC LETTER WAW WITH HAMZA ABOVE
|
||||
0x05c5 "إ" EEK_SYMBOL_CATEGORY_LETTER # Arabic_hamzaunderalef إ ARABIC LETTER ALEF WITH HAMZA BELOW
|
||||
0x05c6 "ئ" EEK_SYMBOL_CATEGORY_LETTER # Arabic_hamzaonyeh ئ ARABIC LETTER YEH WITH HAMZA ABOVE
|
||||
0x05c7 "ا" EEK_SYMBOL_CATEGORY_LETTER # Arabic_alef ا ARABIC LETTER ALEF
|
||||
0x05c8 "ب" EEK_SYMBOL_CATEGORY_LETTER # Arabic_beh ب ARABIC LETTER BEH
|
||||
0x05c9 "ة" EEK_SYMBOL_CATEGORY_LETTER # Arabic_tehmarbuta ة ARABIC LETTER TEH MARBUTA
|
||||
0x05ca "ت" EEK_SYMBOL_CATEGORY_LETTER # Arabic_teh ت ARABIC LETTER TEH
|
||||
0x05cb "ث" EEK_SYMBOL_CATEGORY_LETTER # Arabic_theh ث ARABIC LETTER THEH
|
||||
0x05cc "ج" EEK_SYMBOL_CATEGORY_LETTER # Arabic_jeem ج ARABIC LETTER JEEM
|
||||
0x05cd "ح" EEK_SYMBOL_CATEGORY_LETTER # Arabic_hah ح ARABIC LETTER HAH
|
||||
0x05ce "خ" EEK_SYMBOL_CATEGORY_LETTER # Arabic_khah خ ARABIC LETTER KHAH
|
||||
0x05cf "د" EEK_SYMBOL_CATEGORY_LETTER # Arabic_dal د ARABIC LETTER DAL
|
||||
0x05d0 "ذ" EEK_SYMBOL_CATEGORY_LETTER # Arabic_thal ذ ARABIC LETTER THAL
|
||||
0x05d1 "ر" EEK_SYMBOL_CATEGORY_LETTER # Arabic_ra ر ARABIC LETTER REH
|
||||
0x05d2 "ز" EEK_SYMBOL_CATEGORY_LETTER # Arabic_zain ز ARABIC LETTER ZAIN
|
||||
0x05d3 "س" EEK_SYMBOL_CATEGORY_LETTER # Arabic_seen س ARABIC LETTER SEEN
|
||||
0x05d4 "ش" EEK_SYMBOL_CATEGORY_LETTER # Arabic_sheen ش ARABIC LETTER SHEEN
|
||||
0x05d5 "ص" EEK_SYMBOL_CATEGORY_LETTER # Arabic_sad ص ARABIC LETTER SAD
|
||||
0x05d6 "ض" EEK_SYMBOL_CATEGORY_LETTER # Arabic_dad ض ARABIC LETTER DAD
|
||||
0x05d7 "ط" EEK_SYMBOL_CATEGORY_LETTER # Arabic_tah ط ARABIC LETTER TAH
|
||||
0x05d8 "ظ" EEK_SYMBOL_CATEGORY_LETTER # Arabic_zah ظ ARABIC LETTER ZAH
|
||||
0x05d9 "ع" EEK_SYMBOL_CATEGORY_LETTER # Arabic_ain ع ARABIC LETTER AIN
|
||||
0x05da "غ" EEK_SYMBOL_CATEGORY_LETTER # Arabic_ghain غ ARABIC LETTER GHAIN
|
||||
0x05e0 "ـ" EEK_SYMBOL_CATEGORY_LETTER # Arabic_tatweel ـ ARABIC TATWEEL
|
||||
0x05e1 "ف" EEK_SYMBOL_CATEGORY_LETTER # Arabic_feh ف ARABIC LETTER FEH
|
||||
0x05e2 "ق" EEK_SYMBOL_CATEGORY_LETTER # Arabic_qaf ق ARABIC LETTER QAF
|
||||
0x05e3 "ك" EEK_SYMBOL_CATEGORY_LETTER # Arabic_kaf ك ARABIC LETTER KAF
|
||||
0x05e4 "ل" EEK_SYMBOL_CATEGORY_LETTER # Arabic_lam ل ARABIC LETTER LAM
|
||||
0x05e5 "م" EEK_SYMBOL_CATEGORY_LETTER # Arabic_meem م ARABIC LETTER MEEM
|
||||
0x05e6 "ن" EEK_SYMBOL_CATEGORY_LETTER # Arabic_noon ن ARABIC LETTER NOON
|
||||
0x05e7 "ه" EEK_SYMBOL_CATEGORY_LETTER # Arabic_ha ه ARABIC LETTER HEH
|
||||
0x05e8 "و" EEK_SYMBOL_CATEGORY_LETTER # Arabic_waw و ARABIC LETTER WAW
|
||||
0x05e9 "ى" EEK_SYMBOL_CATEGORY_LETTER # Arabic_alefmaksura ى ARABIC LETTER ALEF MAKSURA
|
||||
0x05ea "ي" EEK_SYMBOL_CATEGORY_LETTER # Arabic_yeh ي ARABIC LETTER YEH
|
||||
0x05eb "ً" EEK_SYMBOL_CATEGORY_LETTER # Arabic_fathatan ً ARABIC FATHATAN
|
||||
0x05ec "ٌ" EEK_SYMBOL_CATEGORY_LETTER # Arabic_dammatan ٌ ARABIC DAMMATAN
|
||||
0x05ed "ٍ" EEK_SYMBOL_CATEGORY_LETTER # Arabic_kasratan ٍ ARABIC KASRATAN
|
||||
0x05ee "َ" EEK_SYMBOL_CATEGORY_LETTER # Arabic_fatha َ ARABIC FATHA
|
||||
0x05ef "ُ" EEK_SYMBOL_CATEGORY_LETTER # Arabic_damma ُ ARABIC DAMMA
|
||||
0x05f0 "ِ" EEK_SYMBOL_CATEGORY_LETTER # Arabic_kasra ِ ARABIC KASRA
|
||||
0x05f1 "ّ" EEK_SYMBOL_CATEGORY_LETTER # Arabic_shadda ّ ARABIC SHADDA
|
||||
0x05f2 "ْ" EEK_SYMBOL_CATEGORY_LETTER # Arabic_sukun ْ ARABIC SUKUN
|
||||
0x06a1 "ђ" EEK_SYMBOL_CATEGORY_LETTER # Serbian_dje ђ CYRILLIC SMALL LETTER DJE
|
||||
0x06a2 "ѓ" EEK_SYMBOL_CATEGORY_LETTER # Macedonia_gje ѓ CYRILLIC SMALL LETTER GJE
|
||||
0x06a3 "ё" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_io ё CYRILLIC SMALL LETTER IO
|
||||
0x06a4 "є" EEK_SYMBOL_CATEGORY_LETTER # Ukrainian_ie є CYRILLIC SMALL LETTER UKRAINIAN IE
|
||||
0x06a5 "ѕ" EEK_SYMBOL_CATEGORY_LETTER # Macedonia_dse ѕ CYRILLIC SMALL LETTER DZE
|
||||
0x06a6 "і" EEK_SYMBOL_CATEGORY_LETTER # Ukrainian_i і CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I
|
||||
0x06a7 "ї" EEK_SYMBOL_CATEGORY_LETTER # Ukrainian_yi ї CYRILLIC SMALL LETTER YI
|
||||
0x06a8 "ј" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_je ј CYRILLIC SMALL LETTER JE
|
||||
0x06a9 "љ" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_lje љ CYRILLIC SMALL LETTER LJE
|
||||
0x06aa "њ" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_nje њ CYRILLIC SMALL LETTER NJE
|
||||
0x06ab "ћ" EEK_SYMBOL_CATEGORY_LETTER # Serbian_tshe ћ CYRILLIC SMALL LETTER TSHE
|
||||
0x06ac "ќ" EEK_SYMBOL_CATEGORY_LETTER # Macedonia_kje ќ CYRILLIC SMALL LETTER KJE
|
||||
0x06ad "ґ" EEK_SYMBOL_CATEGORY_LETTER # Ukrainian_ghe_with_upturn ґ CYRILLIC SMALL LETTER GHE WITH UPTURN
|
||||
0x06ae "ў" EEK_SYMBOL_CATEGORY_LETTER # Byelorussian_shortu ў CYRILLIC SMALL LETTER SHORT U
|
||||
0x06af "џ" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_dzhe џ CYRILLIC SMALL LETTER DZHE
|
||||
0x06b0 "№" EEK_SYMBOL_CATEGORY_LETTER # numerosign № NUMERO SIGN
|
||||
0x06b1 "Ђ" EEK_SYMBOL_CATEGORY_LETTER # Serbian_DJE Ђ CYRILLIC CAPITAL LETTER DJE
|
||||
0x06b2 "Ѓ" EEK_SYMBOL_CATEGORY_LETTER # Macedonia_GJE Ѓ CYRILLIC CAPITAL LETTER GJE
|
||||
0x06b3 "Ё" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_IO Ё CYRILLIC CAPITAL LETTER IO
|
||||
0x06b4 "Є" EEK_SYMBOL_CATEGORY_LETTER # Ukrainian_IE Є CYRILLIC CAPITAL LETTER UKRAINIAN IE
|
||||
0x06b5 "Ѕ" EEK_SYMBOL_CATEGORY_LETTER # Macedonia_DSE Ѕ CYRILLIC CAPITAL LETTER DZE
|
||||
0x06b6 "І" EEK_SYMBOL_CATEGORY_LETTER # Ukrainian_I І CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I
|
||||
0x06b7 "Ї" EEK_SYMBOL_CATEGORY_LETTER # Ukrainian_YI Ї CYRILLIC CAPITAL LETTER YI
|
||||
0x06b8 "Ј" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_JE Ј CYRILLIC CAPITAL LETTER JE
|
||||
0x06b9 "Љ" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_LJE Љ CYRILLIC CAPITAL LETTER LJE
|
||||
0x06ba "Њ" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_NJE Њ CYRILLIC CAPITAL LETTER NJE
|
||||
0x06bb "Ћ" EEK_SYMBOL_CATEGORY_LETTER # Serbian_TSHE Ћ CYRILLIC CAPITAL LETTER TSHE
|
||||
0x06bc "Ќ" EEK_SYMBOL_CATEGORY_LETTER # Macedonia_KJE Ќ CYRILLIC CAPITAL LETTER KJE
|
||||
0x06bd "Ґ" EEK_SYMBOL_CATEGORY_LETTER # Ukrainian_GHE_WITH_UPTURN Ґ CYRILLIC CAPITAL LETTER GHE WITH UPTURN
|
||||
0x06be "Ў" EEK_SYMBOL_CATEGORY_LETTER # Byelorussian_SHORTU Ў CYRILLIC CAPITAL LETTER SHORT U
|
||||
0x06bf "Џ" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_DZHE Џ CYRILLIC CAPITAL LETTER DZHE
|
||||
0x06c0 "ю" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_yu ю CYRILLIC SMALL LETTER YU
|
||||
0x06c1 "а" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_a а CYRILLIC SMALL LETTER A
|
||||
0x06c2 "б" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_be б CYRILLIC SMALL LETTER BE
|
||||
0x06c3 "ц" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_tse ц CYRILLIC SMALL LETTER TSE
|
||||
0x06c4 "д" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_de д CYRILLIC SMALL LETTER DE
|
||||
0x06c5 "е" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_ie е CYRILLIC SMALL LETTER IE
|
||||
0x06c6 "ф" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_ef ф CYRILLIC SMALL LETTER EF
|
||||
0x06c7 "г" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_ghe г CYRILLIC SMALL LETTER GHE
|
||||
0x06c8 "х" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_ha х CYRILLIC SMALL LETTER HA
|
||||
0x06c9 "и" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_i и CYRILLIC SMALL LETTER I
|
||||
0x06ca "й" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_shorti й CYRILLIC SMALL LETTER SHORT I
|
||||
0x06cb "к" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_ka к CYRILLIC SMALL LETTER KA
|
||||
0x06cc "л" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_el л CYRILLIC SMALL LETTER EL
|
||||
0x06cd "м" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_em м CYRILLIC SMALL LETTER EM
|
||||
0x06ce "н" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_en н CYRILLIC SMALL LETTER EN
|
||||
0x06cf "о" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_o о CYRILLIC SMALL LETTER O
|
||||
0x06d0 "п" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_pe п CYRILLIC SMALL LETTER PE
|
||||
0x06d1 "я" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_ya я CYRILLIC SMALL LETTER YA
|
||||
0x06d2 "р" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_er р CYRILLIC SMALL LETTER ER
|
||||
0x06d3 "с" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_es с CYRILLIC SMALL LETTER ES
|
||||
0x06d4 "т" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_te т CYRILLIC SMALL LETTER TE
|
||||
0x06d5 "у" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_u у CYRILLIC SMALL LETTER U
|
||||
0x06d6 "ж" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_zhe ж CYRILLIC SMALL LETTER ZHE
|
||||
0x06d7 "в" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_ve в CYRILLIC SMALL LETTER VE
|
||||
0x06d8 "ь" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_softsign ь CYRILLIC SMALL LETTER SOFT SIGN
|
||||
0x06d9 "ы" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_yeru ы CYRILLIC SMALL LETTER YERU
|
||||
0x06da "з" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_ze з CYRILLIC SMALL LETTER ZE
|
||||
0x06db "ш" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_sha ш CYRILLIC SMALL LETTER SHA
|
||||
0x06dc "э" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_e э CYRILLIC SMALL LETTER E
|
||||
0x06dd "щ" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_shcha щ CYRILLIC SMALL LETTER SHCHA
|
||||
0x06de "ч" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_che ч CYRILLIC SMALL LETTER CHE
|
||||
0x06df "ъ" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_hardsign ъ CYRILLIC SMALL LETTER HARD SIGN
|
||||
0x06e0 "Ю" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_YU Ю CYRILLIC CAPITAL LETTER YU
|
||||
0x06e1 "А" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_A А CYRILLIC CAPITAL LETTER A
|
||||
0x06e2 "Б" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_BE Б CYRILLIC CAPITAL LETTER BE
|
||||
0x06e3 "Ц" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_TSE Ц CYRILLIC CAPITAL LETTER TSE
|
||||
0x06e4 "Д" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_DE Д CYRILLIC CAPITAL LETTER DE
|
||||
0x06e5 "Е" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_IE Е CYRILLIC CAPITAL LETTER IE
|
||||
0x06e6 "Ф" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_EF Ф CYRILLIC CAPITAL LETTER EF
|
||||
0x06e7 "Г" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_GHE Г CYRILLIC CAPITAL LETTER GHE
|
||||
0x06e8 "Х" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_HA Х CYRILLIC CAPITAL LETTER HA
|
||||
0x06e9 "И" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_I И CYRILLIC CAPITAL LETTER I
|
||||
0x06ea "Й" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_SHORTI Й CYRILLIC CAPITAL LETTER SHORT I
|
||||
0x06eb "К" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_KA К CYRILLIC CAPITAL LETTER KA
|
||||
0x06ec "Л" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_EL Л CYRILLIC CAPITAL LETTER EL
|
||||
0x06ed "М" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_EM М CYRILLIC CAPITAL LETTER EM
|
||||
0x06ee "Н" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_EN Н CYRILLIC CAPITAL LETTER EN
|
||||
0x06ef "О" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_O О CYRILLIC CAPITAL LETTER O
|
||||
0x06f0 "П" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_PE П CYRILLIC CAPITAL LETTER PE
|
||||
0x06f1 "Я" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_YA Я CYRILLIC CAPITAL LETTER YA
|
||||
0x06f2 "Р" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_ER Р CYRILLIC CAPITAL LETTER ER
|
||||
0x06f3 "С" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_ES С CYRILLIC CAPITAL LETTER ES
|
||||
0x06f4 "Т" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_TE Т CYRILLIC CAPITAL LETTER TE
|
||||
0x06f5 "У" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_U У CYRILLIC CAPITAL LETTER U
|
||||
0x06f6 "Ж" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_ZHE Ж CYRILLIC CAPITAL LETTER ZHE
|
||||
0x06f7 "В" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_VE В CYRILLIC CAPITAL LETTER VE
|
||||
0x06f8 "Ь" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_SOFTSIGN Ь CYRILLIC CAPITAL LETTER SOFT SIGN
|
||||
0x06f9 "Ы" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_YERU Ы CYRILLIC CAPITAL LETTER YERU
|
||||
0x06fa "З" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_ZE З CYRILLIC CAPITAL LETTER ZE
|
||||
0x06fb "Ш" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_SHA Ш CYRILLIC CAPITAL LETTER SHA
|
||||
0x06fc "Э" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_E Э CYRILLIC CAPITAL LETTER E
|
||||
0x06fd "Щ" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_SHCHA Щ CYRILLIC CAPITAL LETTER SHCHA
|
||||
0x06fe "Ч" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_CHE Ч CYRILLIC CAPITAL LETTER CHE
|
||||
0x06ff "Ъ" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_HARDSIGN Ъ CYRILLIC CAPITAL LETTER HARD SIGN
|
||||
0x07a1 "Ά" EEK_SYMBOL_CATEGORY_LETTER # Geek_ALPHAaccent Ά GREEK CAPITAL LETTER ALPHA WITH TONOS
|
||||
0x07a2 "Έ" EEK_SYMBOL_CATEGORY_LETTER # Geek_EPSILONaccent Έ GREEK CAPITAL LETTER EPSILON WITH TONOS
|
||||
0x07a3 "Ή" EEK_SYMBOL_CATEGORY_LETTER # Geek_ETAaccent Ή GREEK CAPITAL LETTER ETA WITH TONOS
|
||||
0x07a4 "Ί" EEK_SYMBOL_CATEGORY_LETTER # Geek_IOTAaccent Ί GREEK CAPITAL LETTER IOTA WITH TONOS
|
||||
0x07a5 "Ϊ" EEK_SYMBOL_CATEGORY_LETTER # Geek_IOTAdieresis Ϊ GREEK CAPITAL LETTER IOTA WITH DIALYTIKA
|
||||
0x07a7 "Ό" EEK_SYMBOL_CATEGORY_LETTER # Geek_OMICRONaccent Ό GREEK CAPITAL LETTER OMICRON WITH TONOS
|
||||
0x07a8 "Ύ" EEK_SYMBOL_CATEGORY_LETTER # Geek_UPSILONaccent Ύ GREEK CAPITAL LETTER UPSILON WITH TONOS
|
||||
0x07a9 "Ϋ" EEK_SYMBOL_CATEGORY_LETTER # Geek_UPSILONdieresis Ϋ GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA
|
||||
0x07ab "Ώ" EEK_SYMBOL_CATEGORY_LETTER # Geek_OMEGAaccent Ώ GREEK CAPITAL LETTER OMEGA WITH TONOS
|
||||
0x07ae "΅" EEK_SYMBOL_CATEGORY_LETTER # Geek_accentdieresis ΅ GREEK DIALYTIKA TONOS
|
||||
0x07af "―" EEK_SYMBOL_CATEGORY_LETTER # Geek_horizbar ― HORIZONTAL BAR
|
||||
0x07b1 "ά" EEK_SYMBOL_CATEGORY_LETTER # Geek_alphaaccent ά GREEK SMALL LETTER ALPHA WITH TONOS
|
||||
0x07b2 "έ" EEK_SYMBOL_CATEGORY_LETTER # Geek_epsilonaccent έ GREEK SMALL LETTER EPSILON WITH TONOS
|
||||
0x07b3 "ή" EEK_SYMBOL_CATEGORY_LETTER # Geek_etaaccent ή GREEK SMALL LETTER ETA WITH TONOS
|
||||
0x07b4 "ί" EEK_SYMBOL_CATEGORY_LETTER # Geek_iotaaccent ί GREEK SMALL LETTER IOTA WITH TONOS
|
||||
0x07b5 "ϊ" EEK_SYMBOL_CATEGORY_LETTER # Geek_iotadieresis ϊ GREEK SMALL LETTER IOTA WITH DIALYTIKA
|
||||
0x07b6 "ΐ" EEK_SYMBOL_CATEGORY_LETTER # Geek_iotaaccentdieresis ΐ GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS
|
||||
0x07b7 "ό" EEK_SYMBOL_CATEGORY_LETTER # Geek_omicronaccent ό GREEK SMALL LETTER OMICRON WITH TONOS
|
||||
0x07b8 "ύ" EEK_SYMBOL_CATEGORY_LETTER # Geek_upsilonaccent ύ GREEK SMALL LETTER UPSILON WITH TONOS
|
||||
0x07b9 "ϋ" EEK_SYMBOL_CATEGORY_LETTER # Geek_upsilondieresis ϋ GREEK SMALL LETTER UPSILON WITH DIALYTIKA
|
||||
0x07ba "ΰ" EEK_SYMBOL_CATEGORY_LETTER # Geek_upsilonaccentdieresis ΰ GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS
|
||||
0x07bb "ώ" EEK_SYMBOL_CATEGORY_LETTER # Geek_omegaaccent ώ GREEK SMALL LETTER OMEGA WITH TONOS
|
||||
0x07c1 "Α" EEK_SYMBOL_CATEGORY_LETTER # Geek_ALPHA Α GREEK CAPITAL LETTER ALPHA
|
||||
0x07c2 "Β" EEK_SYMBOL_CATEGORY_LETTER # Geek_BETA Β GREEK CAPITAL LETTER BETA
|
||||
0x07c3 "Γ" EEK_SYMBOL_CATEGORY_LETTER # Geek_GAMMA Γ GREEK CAPITAL LETTER GAMMA
|
||||
0x07c4 "Δ" EEK_SYMBOL_CATEGORY_LETTER # Geek_DELTA Δ GREEK CAPITAL LETTER DELTA
|
||||
0x07c5 "Ε" EEK_SYMBOL_CATEGORY_LETTER # Geek_EPSILON Ε GREEK CAPITAL LETTER EPSILON
|
||||
0x07c6 "Ζ" EEK_SYMBOL_CATEGORY_LETTER # Geek_ZETA Ζ GREEK CAPITAL LETTER ZETA
|
||||
0x07c7 "Η" EEK_SYMBOL_CATEGORY_LETTER # Geek_ETA Η GREEK CAPITAL LETTER ETA
|
||||
0x07c8 "Θ" EEK_SYMBOL_CATEGORY_LETTER # Geek_THETA Θ GREEK CAPITAL LETTER THETA
|
||||
0x07c9 "Ι" EEK_SYMBOL_CATEGORY_LETTER # Geek_IOTA Ι GREEK CAPITAL LETTER IOTA
|
||||
0x07ca "Κ" EEK_SYMBOL_CATEGORY_LETTER # Geek_KAPPA Κ GREEK CAPITAL LETTER KAPPA
|
||||
0x07cb "Λ" EEK_SYMBOL_CATEGORY_LETTER # Geek_LAMBDA Λ GREEK CAPITAL LETTER LAMDA
|
||||
0x07cc "Μ" EEK_SYMBOL_CATEGORY_LETTER # Geek_MU Μ GREEK CAPITAL LETTER MU
|
||||
0x07cd "Ν" EEK_SYMBOL_CATEGORY_LETTER # Geek_NU Ν GREEK CAPITAL LETTER NU
|
||||
0x07ce "Ξ" EEK_SYMBOL_CATEGORY_LETTER # Geek_XI Ξ GREEK CAPITAL LETTER XI
|
||||
0x07cf "Ο" EEK_SYMBOL_CATEGORY_LETTER # Geek_OMICRON Ο GREEK CAPITAL LETTER OMICRON
|
||||
0x07d0 "Π" EEK_SYMBOL_CATEGORY_LETTER # Geek_PI Π GREEK CAPITAL LETTER PI
|
||||
0x07d1 "Ρ" EEK_SYMBOL_CATEGORY_LETTER # Geek_RHO Ρ GREEK CAPITAL LETTER RHO
|
||||
0x07d2 "Σ" EEK_SYMBOL_CATEGORY_LETTER # Geek_SIGMA Σ GREEK CAPITAL LETTER SIGMA
|
||||
0x07d4 "Τ" EEK_SYMBOL_CATEGORY_LETTER # Geek_TAU Τ GREEK CAPITAL LETTER TAU
|
||||
0x07d5 "Υ" EEK_SYMBOL_CATEGORY_LETTER # Geek_UPSILON Υ GREEK CAPITAL LETTER UPSILON
|
||||
0x07d6 "Φ" EEK_SYMBOL_CATEGORY_LETTER # Geek_PHI Φ GREEK CAPITAL LETTER PHI
|
||||
0x07d7 "Χ" EEK_SYMBOL_CATEGORY_LETTER # Geek_CHI Χ GREEK CAPITAL LETTER CHI
|
||||
0x07d8 "Ψ" EEK_SYMBOL_CATEGORY_LETTER # Geek_PSI Ψ GREEK CAPITAL LETTER PSI
|
||||
0x07d9 "Ω" EEK_SYMBOL_CATEGORY_LETTER # Geek_OMEGA Ω GREEK CAPITAL LETTER OMEGA
|
||||
0x07e1 "α" EEK_SYMBOL_CATEGORY_LETTER # Geek_alpha α GREEK SMALL LETTER ALPHA
|
||||
0x07e2 "β" EEK_SYMBOL_CATEGORY_LETTER # Geek_beta β GREEK SMALL LETTER BETA
|
||||
0x07e3 "γ" EEK_SYMBOL_CATEGORY_LETTER # Geek_gamma γ GREEK SMALL LETTER GAMMA
|
||||
0x07e4 "δ" EEK_SYMBOL_CATEGORY_LETTER # Geek_delta δ GREEK SMALL LETTER DELTA
|
||||
0x07e5 "ε" EEK_SYMBOL_CATEGORY_LETTER # Geek_epsilon ε GREEK SMALL LETTER EPSILON
|
||||
0x07e6 "ζ" EEK_SYMBOL_CATEGORY_LETTER # Geek_zeta ζ GREEK SMALL LETTER ZETA
|
||||
0x07e7 "η" EEK_SYMBOL_CATEGORY_LETTER # Geek_eta η GREEK SMALL LETTER ETA
|
||||
0x07e8 "θ" EEK_SYMBOL_CATEGORY_LETTER # Geek_theta θ GREEK SMALL LETTER THETA
|
||||
0x07e9 "ι" EEK_SYMBOL_CATEGORY_LETTER # Geek_iota ι GREEK SMALL LETTER IOTA
|
||||
0x07ea "κ" EEK_SYMBOL_CATEGORY_LETTER # Geek_kappa κ GREEK SMALL LETTER KAPPA
|
||||
0x07eb "λ" EEK_SYMBOL_CATEGORY_LETTER # Geek_lambda λ GREEK SMALL LETTER LAMDA
|
||||
0x07ec "μ" EEK_SYMBOL_CATEGORY_LETTER # Geek_mu μ GREEK SMALL LETTER MU
|
||||
0x07ed "ν" EEK_SYMBOL_CATEGORY_LETTER # Geek_nu ν GREEK SMALL LETTER NU
|
||||
0x07ee "ξ" EEK_SYMBOL_CATEGORY_LETTER # Geek_xi ξ GREEK SMALL LETTER XI
|
||||
0x07ef "ο" EEK_SYMBOL_CATEGORY_LETTER # Geek_omicron ο GREEK SMALL LETTER OMICRON
|
||||
0x07f0 "π" EEK_SYMBOL_CATEGORY_LETTER # Geek_pi π GREEK SMALL LETTER PI
|
||||
0x07f1 "ρ" EEK_SYMBOL_CATEGORY_LETTER # Geek_rho ρ GREEK SMALL LETTER RHO
|
||||
0x07f2 "σ" EEK_SYMBOL_CATEGORY_LETTER # Geek_sigma σ GREEK SMALL LETTER SIGMA
|
||||
0x07f3 "ς" EEK_SYMBOL_CATEGORY_LETTER # Geek_finalsmallsigma ς GREEK SMALL LETTER FINAL SIGMA
|
||||
0x07f4 "τ" EEK_SYMBOL_CATEGORY_LETTER # Geek_tau τ GREEK SMALL LETTER TAU
|
||||
0x07f5 "υ" EEK_SYMBOL_CATEGORY_LETTER # Geek_upsilon υ GREEK SMALL LETTER UPSILON
|
||||
0x07f6 "φ" EEK_SYMBOL_CATEGORY_LETTER # Geek_phi φ GREEK SMALL LETTER PHI
|
||||
0x07f7 "χ" EEK_SYMBOL_CATEGORY_LETTER # Geek_chi χ GREEK SMALL LETTER CHI
|
||||
0x07f8 "ψ" EEK_SYMBOL_CATEGORY_LETTER # Geek_psi ψ GREEK SMALL LETTER PSI
|
||||
0x07f9 "ω" EEK_SYMBOL_CATEGORY_LETTER # Geek_omega ω GREEK SMALL LETTER OMEGA
|
||||
# 0x08a1 leftradical ? ???
|
||||
# 0x08a2 topleftradical ? ???
|
||||
# 0x08a3 horizconnector ? ???
|
||||
0x08a4 "⌠" EEK_SYMBOL_CATEGORY_LETTER # topintegral ⌠ TOP HALF INTEGRAL
|
||||
0x08a5 "⌡" EEK_SYMBOL_CATEGORY_LETTER # botintegral ⌡ BOTTOM HALF INTEGRAL
|
||||
0x08a6 "│" EEK_SYMBOL_CATEGORY_LETTER # vertconnector │ BOX DRAWINGS LIGHT VERTICAL
|
||||
# 0x08a7 topleftsqbracket ? ???
|
||||
# 0x08a8 botleftsqbracket ? ???
|
||||
# 0x08a9 toprightsqbracket ? ???
|
||||
# 0x08aa botrightsqbracket ? ???
|
||||
# 0x08ab topleftparens ? ???
|
||||
# 0x08ac botleftparens ? ???
|
||||
# 0x08ad toprightparens ? ???
|
||||
# 0x08ae botrightparens ? ???
|
||||
# 0x08af leftmiddlecurlybrace ? ???
|
||||
# 0x08b0 rightmiddlecurlybrace ? ???
|
||||
# 0x08b1 topleftsummation ? ???
|
||||
# 0x08b2 botleftsummation ? ???
|
||||
# 0x08b3 topvertsummationconnector ? ???
|
||||
# 0x08b4 botvertsummationconnector ? ???
|
||||
# 0x08b5 toprightsummation ? ???
|
||||
# 0x08b6 botrightsummation ? ???
|
||||
# 0x08b7 rightmiddlesummation ? ???
|
||||
0x08bc "≤" EEK_SYMBOL_CATEGORY_LETTER # lessthanequal ≤ LESS-THAN OR EQUAL TO
|
||||
0x08bd "≠" EEK_SYMBOL_CATEGORY_LETTER # notequal ≠ NOT EQUAL TO
|
||||
0x08be "≥" EEK_SYMBOL_CATEGORY_LETTER # greaterthanequal ≥ GREATER-THAN OR EQUAL TO
|
||||
0x08bf "∫" EEK_SYMBOL_CATEGORY_LETTER # integral ∫ INTEGRAL
|
||||
0x08c0 "∴" EEK_SYMBOL_CATEGORY_LETTER # therefore ∴ THEREFORE
|
||||
0x08c1 "∝" EEK_SYMBOL_CATEGORY_LETTER # variation ∝ PROPORTIONAL TO
|
||||
0x08c2 "∞" EEK_SYMBOL_CATEGORY_LETTER # infinity ∞ INFINITY
|
||||
0x08c5 "∇" EEK_SYMBOL_CATEGORY_LETTER # nabla ∇ NABLA
|
||||
0x08c8 "≅" EEK_SYMBOL_CATEGORY_LETTER # approximate ≅ APPROXIMATELY EQUAL TO
|
||||
# 0x08c9 similarequal ? ???
|
||||
0x08cd "⇔" EEK_SYMBOL_CATEGORY_LETTER # ifonlyif ⇔ LEFT RIGHT DOUBLE ARROW
|
||||
0x08ce "⇒" EEK_SYMBOL_CATEGORY_LETTER # implies ⇒ RIGHTWARDS DOUBLE ARROW
|
||||
0x08cf "≡" EEK_SYMBOL_CATEGORY_LETTER # identical ≡ IDENTICAL TO
|
||||
0x08d6 "√" EEK_SYMBOL_CATEGORY_LETTER # radical √ SQUARE ROOT
|
||||
0x08da "⊂" EEK_SYMBOL_CATEGORY_LETTER # includedin ⊂ SUBSET OF
|
||||
0x08db "⊃" EEK_SYMBOL_CATEGORY_LETTER # includes ⊃ SUPERSET OF
|
||||
0x08dc "∩" EEK_SYMBOL_CATEGORY_LETTER # intersection ∩ INTERSECTION
|
||||
0x08dd "∪" EEK_SYMBOL_CATEGORY_LETTER # union ∪ UNION
|
||||
0x08de "∧" EEK_SYMBOL_CATEGORY_LETTER # logicaland ∧ LOGICAL AND
|
||||
0x08df "∨" EEK_SYMBOL_CATEGORY_LETTER # logicalor ∨ LOGICAL OR
|
||||
0x08ef "∂" EEK_SYMBOL_CATEGORY_LETTER # partialderivative ∂ PARTIAL DIFFERENTIAL
|
||||
0x08f6 "ƒ" EEK_SYMBOL_CATEGORY_LETTER # function ƒ LATIN SMALL LETTER F WITH HOOK
|
||||
0x08fb "←" EEK_SYMBOL_CATEGORY_LETTER # leftarrow ← LEFTWARDS ARROW
|
||||
0x08fc "↑" EEK_SYMBOL_CATEGORY_LETTER # uparrow ↑ UPWARDS ARROW
|
||||
0x08fd "→" EEK_SYMBOL_CATEGORY_LETTER # rightarrow → RIGHTWARDS ARROW
|
||||
0x08fe "↓" EEK_SYMBOL_CATEGORY_LETTER # downarrow ↓ DOWNWARDS ARROW
|
||||
0x09df "␢" EEK_SYMBOL_CATEGORY_LETTER # blank ␢ BLANK SYMBOL
|
||||
0x09e0 "◆" EEK_SYMBOL_CATEGORY_LETTER # soliddiamond ◆ BLACK DIAMOND
|
||||
0x09e1 "▒" EEK_SYMBOL_CATEGORY_LETTER # checkerboard ▒ MEDIUM SHADE
|
||||
0x09e2 "␉" EEK_SYMBOL_CATEGORY_LETTER # ht ␉ SYMBOL FOR HORIZONTAL TABULATION
|
||||
0x09e3 "␌" EEK_SYMBOL_CATEGORY_LETTER # ff ␌ SYMBOL FOR FORM FEED
|
||||
0x09e4 "␍" EEK_SYMBOL_CATEGORY_LETTER # cr ␍ SYMBOL FOR CARRIAGE RETURN
|
||||
0x09e5 "␊" EEK_SYMBOL_CATEGORY_LETTER # lf ␊ SYMBOL FOR LINE FEED
|
||||
0x09e8 "" EEK_SYMBOL_CATEGORY_LETTER # nl  SYMBOL FOR NEWLINE
|
||||
0x09e9 "␋" EEK_SYMBOL_CATEGORY_LETTER # vt ␋ SYMBOL FOR VERTICAL TABULATION
|
||||
0x09ea "┘" EEK_SYMBOL_CATEGORY_LETTER # lowrightcorner ┘ BOX DRAWINGS LIGHT UP AND LEFT
|
||||
0x09eb "┐" EEK_SYMBOL_CATEGORY_LETTER # uprightcorner ┐ BOX DRAWINGS LIGHT DOWN AND LEFT
|
||||
0x09ec "┌" EEK_SYMBOL_CATEGORY_LETTER # upleftcorner ┌ BOX DRAWINGS LIGHT DOWN AND RIGHT
|
||||
0x09ed "└" EEK_SYMBOL_CATEGORY_LETTER # lowleftcorner └ BOX DRAWINGS LIGHT UP AND RIGHT
|
||||
0x09ee "┼" EEK_SYMBOL_CATEGORY_LETTER # crossinglines ┼ BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL
|
||||
# 0x09ef horizlinescan1 ? ???
|
||||
# 0x09f0 horizlinescan3 ? ???
|
||||
0x09f1 "─" EEK_SYMBOL_CATEGORY_LETTER # horizlinescan5 ─ BOX DRAWINGS LIGHT HORIZONTAL
|
||||
# 0x09f2 horizlinescan7 ? ???
|
||||
# 0x09f3 horizlinescan9 ? ???
|
||||
0x09f4 "├" EEK_SYMBOL_CATEGORY_LETTER # leftt ├ BOX DRAWINGS LIGHT VERTICAL AND RIGHT
|
||||
0x09f5 "┤" EEK_SYMBOL_CATEGORY_LETTER # rightt ┤ BOX DRAWINGS LIGHT VERTICAL AND LEFT
|
||||
0x09f6 "┴" EEK_SYMBOL_CATEGORY_LETTER # bott ┴ BOX DRAWINGS LIGHT UP AND HORIZONTAL
|
||||
0x09f7 "┬" EEK_SYMBOL_CATEGORY_LETTER # topt ┬ BOX DRAWINGS LIGHT DOWN AND HORIZONTAL
|
||||
0x09f8 "│" EEK_SYMBOL_CATEGORY_LETTER # vertbar │ BOX DRAWINGS LIGHT VERTICAL
|
||||
0x0aa1 " " EEK_SYMBOL_CATEGORY_LETTER # emspace EM SPACE
|
||||
0x0aa2 " " EEK_SYMBOL_CATEGORY_LETTER # enspace EN SPACE
|
||||
0x0aa3 " " EEK_SYMBOL_CATEGORY_LETTER # em3space THREE-PER-EM SPACE
|
||||
0x0aa4 " " EEK_SYMBOL_CATEGORY_LETTER # em4space FOUR-PER-EM SPACE
|
||||
0x0aa5 " " EEK_SYMBOL_CATEGORY_LETTER # digitspace FIGURE SPACE
|
||||
0x0aa6 " " EEK_SYMBOL_CATEGORY_LETTER # punctspace PUNCTUATION SPACE
|
||||
0x0aa7 " " EEK_SYMBOL_CATEGORY_LETTER # thinspace THIN SPACE
|
||||
0x0aa8 " " EEK_SYMBOL_CATEGORY_LETTER # hairspace HAIR SPACE
|
||||
0x0aa9 "—" EEK_SYMBOL_CATEGORY_LETTER # emdash — EM DASH
|
||||
0x0aaa "–" EEK_SYMBOL_CATEGORY_LETTER # endash – EN DASH
|
||||
# 0x0aac signifblank ? ???
|
||||
0x0aae "…" EEK_SYMBOL_CATEGORY_LETTER # ellipsis … HORIZONTAL ELLIPSIS
|
||||
# 0x0aaf doubbaselinedot ? ???
|
||||
0x0ab0 "⅓" EEK_SYMBOL_CATEGORY_LETTER # onethird ⅓ VULGAR FRACTION ONE THIRD
|
||||
0x0ab1 "⅔" EEK_SYMBOL_CATEGORY_LETTER # twothirds ⅔ VULGAR FRACTION TWO THIRDS
|
||||
0x0ab2 "⅕" EEK_SYMBOL_CATEGORY_LETTER # onefifth ⅕ VULGAR FRACTION ONE FIFTH
|
||||
0x0ab3 "⅖" EEK_SYMBOL_CATEGORY_LETTER # twofifths ⅖ VULGAR FRACTION TWO FIFTHS
|
||||
0x0ab4 "⅗" EEK_SYMBOL_CATEGORY_LETTER # threefifths ⅗ VULGAR FRACTION THREE FIFTHS
|
||||
0x0ab5 "⅘" EEK_SYMBOL_CATEGORY_LETTER # fourfifths ⅘ VULGAR FRACTION FOUR FIFTHS
|
||||
0x0ab6 "⅙" EEK_SYMBOL_CATEGORY_LETTER # onesixth ⅙ VULGAR FRACTION ONE SIXTH
|
||||
0x0ab7 "⅚" EEK_SYMBOL_CATEGORY_LETTER # fivesixths ⅚ VULGAR FRACTION FIVE SIXTHS
|
||||
0x0ab8 "℅" EEK_SYMBOL_CATEGORY_LETTER # careof ℅ CARE OF
|
||||
0x0abb "‒" EEK_SYMBOL_CATEGORY_LETTER # figdash ‒ FIGURE DASH
|
||||
0x0abc "〈" EEK_SYMBOL_CATEGORY_LETTER # leftanglebracket 〈 LEFT-POINTING ANGLE BRACKET
|
||||
0x0abd "." EEK_SYMBOL_CATEGORY_LETTER # decimalpoint . FULL STOP
|
||||
0x0abe "〉" EEK_SYMBOL_CATEGORY_LETTER # rightanglebracket 〉 RIGHT-POINTING ANGLE BRACKET
|
||||
# 0x0abf marker ? ???
|
||||
0x0ac3 "⅛" EEK_SYMBOL_CATEGORY_LETTER # oneeighth ⅛ VULGAR FRACTION ONE EIGHTH
|
||||
0x0ac4 "⅜" EEK_SYMBOL_CATEGORY_LETTER # threeeighths ⅜ VULGAR FRACTION THREE EIGHTHS
|
||||
0x0ac5 "⅝" EEK_SYMBOL_CATEGORY_LETTER # fiveeighths ⅝ VULGAR FRACTION FIVE EIGHTHS
|
||||
0x0ac6 "⅞" EEK_SYMBOL_CATEGORY_LETTER # seveneighths ⅞ VULGAR FRACTION SEVEN EIGHTHS
|
||||
0x0ac9 "™" EEK_SYMBOL_CATEGORY_LETTER # trademark ™ TRADE MARK SIGN
|
||||
0x0aca "☓" EEK_SYMBOL_CATEGORY_LETTER # signaturemark ☓ SALTIRE
|
||||
# 0x0acb trademarkincircle ? ???
|
||||
0x0acc "◁" EEK_SYMBOL_CATEGORY_LETTER # leftopentriangle ◁ WHITE LEFT-POINTING TRIANGLE
|
||||
0x0acd "▷" EEK_SYMBOL_CATEGORY_LETTER # rightopentriangle ▷ WHITE RIGHT-POINTING TRIANGLE
|
||||
0x0ace "○" EEK_SYMBOL_CATEGORY_LETTER # emopencircle ○ WHITE CIRCLE
|
||||
0x0acf "□" EEK_SYMBOL_CATEGORY_LETTER # emopenrectangle □ WHITE SQUARE
|
||||
0x0ad0 "‘" EEK_SYMBOL_CATEGORY_LETTER # leftsinglequotemark ‘ LEFT SINGLE QUOTATION MARK
|
||||
0x0ad1 "’" EEK_SYMBOL_CATEGORY_LETTER # rightsinglequotemark ’ RIGHT SINGLE QUOTATION MARK
|
||||
0x0ad2 "“" EEK_SYMBOL_CATEGORY_LETTER # leftdoublequotemark “ LEFT DOUBLE QUOTATION MARK
|
||||
0x0ad3 "”" EEK_SYMBOL_CATEGORY_LETTER # rightdoublequotemark ” RIGHT DOUBLE QUOTATION MARK
|
||||
0x0ad4 "℞" EEK_SYMBOL_CATEGORY_LETTER # prescription ℞ PRESCRIPTION TAKE
|
||||
0x0ad6 "′" EEK_SYMBOL_CATEGORY_LETTER # minutes ′ PRIME
|
||||
0x0ad7 "″" EEK_SYMBOL_CATEGORY_LETTER # seconds ″ DOUBLE PRIME
|
||||
0x0ad9 "✝" EEK_SYMBOL_CATEGORY_LETTER # latincross ✝ LATIN CROSS
|
||||
# 0x0ada hexagram ? ???
|
||||
0x0adb "▬" EEK_SYMBOL_CATEGORY_LETTER # filledrectbullet ▬ BLACK RECTANGLE
|
||||
0x0adc "◀" EEK_SYMBOL_CATEGORY_LETTER # filledlefttribullet ◀ BLACK LEFT-POINTING TRIANGLE
|
||||
0x0add "▶" EEK_SYMBOL_CATEGORY_LETTER # filledrighttribullet ▶ BLACK RIGHT-POINTING TRIANGLE
|
||||
0x0ade "●" EEK_SYMBOL_CATEGORY_LETTER # emfilledcircle ● BLACK CIRCLE
|
||||
0x0adf "■" EEK_SYMBOL_CATEGORY_LETTER # emfilledrect ■ BLACK SQUARE
|
||||
0x0ae0 "◦" EEK_SYMBOL_CATEGORY_LETTER # enopencircbullet ◦ WHITE BULLET
|
||||
0x0ae1 "▫" EEK_SYMBOL_CATEGORY_LETTER # enopensquarebullet ▫ WHITE SMALL SQUARE
|
||||
0x0ae2 "▭" EEK_SYMBOL_CATEGORY_LETTER # openrectbullet ▭ WHITE RECTANGLE
|
||||
0x0ae3 "△" EEK_SYMBOL_CATEGORY_LETTER # opentribulletup △ WHITE UP-POINTING TRIANGLE
|
||||
0x0ae4 "▽" EEK_SYMBOL_CATEGORY_LETTER # opentribulletdown ▽ WHITE DOWN-POINTING TRIANGLE
|
||||
0x0ae5 "☆" EEK_SYMBOL_CATEGORY_LETTER # openstar ☆ WHITE STAR
|
||||
0x0ae6 "•" EEK_SYMBOL_CATEGORY_LETTER # enfilledcircbullet • BULLET
|
||||
0x0ae7 "▪" EEK_SYMBOL_CATEGORY_LETTER # enfilledsqbullet ▪ BLACK SMALL SQUARE
|
||||
0x0ae8 "▲" EEK_SYMBOL_CATEGORY_LETTER # filledtribulletup ▲ BLACK UP-POINTING TRIANGLE
|
||||
0x0ae9 "▼" EEK_SYMBOL_CATEGORY_LETTER # filledtribulletdown ▼ BLACK DOWN-POINTING TRIANGLE
|
||||
0x0aea "☜" EEK_SYMBOL_CATEGORY_LETTER # leftpointer ☜ WHITE LEFT POINTING INDEX
|
||||
0x0aeb "☞" EEK_SYMBOL_CATEGORY_LETTER # rightpointer ☞ WHITE RIGHT POINTING INDEX
|
||||
0x0aec "♣" EEK_SYMBOL_CATEGORY_LETTER # club ♣ BLACK CLUB SUIT
|
||||
0x0aed "♦" EEK_SYMBOL_CATEGORY_LETTER # diamond ♦ BLACK DIAMOND SUIT
|
||||
0x0aee "♥" EEK_SYMBOL_CATEGORY_LETTER # heart ♥ BLACK HEART SUIT
|
||||
0x0af0 "✠" EEK_SYMBOL_CATEGORY_LETTER # maltesecross ✠ MALTESE CROSS
|
||||
0x0af1 "†" EEK_SYMBOL_CATEGORY_LETTER # dagger † DAGGER
|
||||
0x0af2 "‡" EEK_SYMBOL_CATEGORY_LETTER # doubledagger ‡ DOUBLE DAGGER
|
||||
0x0af3 "✓" EEK_SYMBOL_CATEGORY_LETTER # checkmark ✓ CHECK MARK
|
||||
0x0af4 "✗" EEK_SYMBOL_CATEGORY_LETTER # ballotcross ✗ BALLOT X
|
||||
0x0af5 "♯" EEK_SYMBOL_CATEGORY_LETTER # musicalsharp ♯ MUSIC SHARP SIGN
|
||||
0x0af6 "♭" EEK_SYMBOL_CATEGORY_LETTER # musicalflat ♭ MUSIC FLAT SIGN
|
||||
0x0af7 "♂" EEK_SYMBOL_CATEGORY_LETTER # malesymbol ♂ MALE SIGN
|
||||
0x0af8 "♀" EEK_SYMBOL_CATEGORY_LETTER # femalesymbol ♀ FEMALE SIGN
|
||||
0x0af9 "☎" EEK_SYMBOL_CATEGORY_LETTER # telephone ☎ BLACK TELEPHONE
|
||||
0x0afa "⌕" EEK_SYMBOL_CATEGORY_LETTER # telephonerecorder ⌕ TELEPHONE RECORDER
|
||||
0x0afb "℗" EEK_SYMBOL_CATEGORY_LETTER # phonographcopyright ℗ SOUND RECORDING COPYRIGHT
|
||||
0x0afc "‸" EEK_SYMBOL_CATEGORY_LETTER # caret ‸ CARET
|
||||
0x0afd "‚" EEK_SYMBOL_CATEGORY_LETTER # singlelowquotemark ‚ SINGLE LOW-9 QUOTATION MARK
|
||||
0x0afe "„" EEK_SYMBOL_CATEGORY_LETTER # doublelowquotemark „ DOUBLE LOW-9 QUOTATION MARK
|
||||
# 0x0aff cursor ? ???
|
||||
0x0ba3 "<" EEK_SYMBOL_CATEGORY_LETTER # leftcaret < LESS-THAN SIGN
|
||||
0x0ba6 ">" EEK_SYMBOL_CATEGORY_LETTER # rightcaret > GREATER-THAN SIGN
|
||||
0x0ba8 "∨" EEK_SYMBOL_CATEGORY_LETTER # downcaret ∨ LOGICAL OR
|
||||
0x0ba9 "∧" EEK_SYMBOL_CATEGORY_LETTER # upcaret ∧ LOGICAL AND
|
||||
0x0bc0 "¯" EEK_SYMBOL_CATEGORY_LETTER # overbar ¯ MACRON
|
||||
0x0bc2 "⊤" EEK_SYMBOL_CATEGORY_LETTER # downtack ⊤ DOWN TACK
|
||||
0x0bc3 "∩" EEK_SYMBOL_CATEGORY_LETTER # upshoe ∩ INTERSECTION
|
||||
0x0bc4 "⌊" EEK_SYMBOL_CATEGORY_LETTER # downstile ⌊ LEFT FLOOR
|
||||
0x0bc6 "_" EEK_SYMBOL_CATEGORY_LETTER # underbar _ LOW LINE
|
||||
0x0bca "∘" EEK_SYMBOL_CATEGORY_LETTER # jot ∘ RING OPERATOR
|
||||
0x0bcc "⎕" EEK_SYMBOL_CATEGORY_LETTER # quad ⎕ APL FUNCTIONAL SYMBOL QUAD (Unicode 3.0)
|
||||
0x0bce "⊥" EEK_SYMBOL_CATEGORY_LETTER # uptack ⊥ UP TACK
|
||||
0x0bcf "○" EEK_SYMBOL_CATEGORY_LETTER # circle ○ WHITE CIRCLE
|
||||
0x0bd3 "⌈" EEK_SYMBOL_CATEGORY_LETTER # upstile ⌈ LEFT CEILING
|
||||
0x0bd6 "∪" EEK_SYMBOL_CATEGORY_LETTER # downshoe ∪ UNION
|
||||
0x0bd8 "⊃" EEK_SYMBOL_CATEGORY_LETTER # rightshoe ⊃ SUPERSET OF
|
||||
0x0bda "⊂" EEK_SYMBOL_CATEGORY_LETTER # leftshoe ⊂ SUBSET OF
|
||||
0x0bdc "⊣" EEK_SYMBOL_CATEGORY_LETTER # lefttack ⊣ LEFT TACK
|
||||
0x0bfc "⊢" EEK_SYMBOL_CATEGORY_LETTER # righttack ⊢ RIGHT TACK
|
||||
0x0cdf "‗" EEK_SYMBOL_CATEGORY_LETTER # hebrew_doublelowline ‗ DOUBLE LOW LINE
|
||||
0x0ce0 "א" EEK_SYMBOL_CATEGORY_LETTER # hebrew_aleph א HEBREW LETTER ALEF
|
||||
0x0ce1 "ב" EEK_SYMBOL_CATEGORY_LETTER # hebrew_bet ב HEBREW LETTER BET
|
||||
0x0ce2 "ג" EEK_SYMBOL_CATEGORY_LETTER # hebrew_gimel ג HEBREW LETTER GIMEL
|
||||
0x0ce3 "ד" EEK_SYMBOL_CATEGORY_LETTER # hebrew_dalet ד HEBREW LETTER DALET
|
||||
0x0ce4 "ה" EEK_SYMBOL_CATEGORY_LETTER # hebrew_he ה HEBREW LETTER HE
|
||||
0x0ce5 "ו" EEK_SYMBOL_CATEGORY_LETTER # hebrew_waw ו HEBREW LETTER VAV
|
||||
0x0ce6 "ז" EEK_SYMBOL_CATEGORY_LETTER # hebrew_zain ז HEBREW LETTER ZAYIN
|
||||
0x0ce7 "ח" EEK_SYMBOL_CATEGORY_LETTER # hebrew_chet ח HEBREW LETTER HET
|
||||
0x0ce8 "ט" EEK_SYMBOL_CATEGORY_LETTER # hebrew_tet ט HEBREW LETTER TET
|
||||
0x0ce9 "י" EEK_SYMBOL_CATEGORY_LETTER # hebrew_yod י HEBREW LETTER YOD
|
||||
0x0cea "ך" EEK_SYMBOL_CATEGORY_LETTER # hebrew_finalkaph ך HEBREW LETTER FINAL KAF
|
||||
0x0ceb "כ" EEK_SYMBOL_CATEGORY_LETTER # hebrew_kaph כ HEBREW LETTER KAF
|
||||
0x0cec "ל" EEK_SYMBOL_CATEGORY_LETTER # hebrew_lamed ל HEBREW LETTER LAMED
|
||||
0x0ced "ם" EEK_SYMBOL_CATEGORY_LETTER # hebrew_finalmem ם HEBREW LETTER FINAL MEM
|
||||
0x0cee "מ" EEK_SYMBOL_CATEGORY_LETTER # hebrew_mem מ HEBREW LETTER MEM
|
||||
0x0cef "ן" EEK_SYMBOL_CATEGORY_LETTER # hebrew_finalnun ן HEBREW LETTER FINAL NUN
|
||||
0x0cf0 "נ" EEK_SYMBOL_CATEGORY_LETTER # hebrew_nun נ HEBREW LETTER NUN
|
||||
0x0cf1 "ס" EEK_SYMBOL_CATEGORY_LETTER # hebrew_samech ס HEBREW LETTER SAMEKH
|
||||
0x0cf2 "ע" EEK_SYMBOL_CATEGORY_LETTER # hebrew_ayin ע HEBREW LETTER AYIN
|
||||
0x0cf3 "ף" EEK_SYMBOL_CATEGORY_LETTER # hebrew_finalpe ף HEBREW LETTER FINAL PE
|
||||
0x0cf4 "פ" EEK_SYMBOL_CATEGORY_LETTER # hebrew_pe פ HEBREW LETTER PE
|
||||
0x0cf5 "ץ" EEK_SYMBOL_CATEGORY_LETTER # hebrew_finalzade ץ HEBREW LETTER FINAL TSADI
|
||||
0x0cf6 "צ" EEK_SYMBOL_CATEGORY_LETTER # hebrew_zade צ HEBREW LETTER TSADI
|
||||
0x0cf7 "ק" EEK_SYMBOL_CATEGORY_LETTER # hebrew_qoph ק HEBREW LETTER QOF
|
||||
0x0cf8 "ר" EEK_SYMBOL_CATEGORY_LETTER # hebrew_resh ר HEBREW LETTER RESH
|
||||
0x0cf9 "ש" EEK_SYMBOL_CATEGORY_LETTER # hebrew_shin ש HEBREW LETTER SHIN
|
||||
0x0cfa "ת" EEK_SYMBOL_CATEGORY_LETTER # hebrew_taw ת HEBREW LETTER TAV
|
||||
0x0da1 "ก" EEK_SYMBOL_CATEGORY_LETTER # Thai_kokai ก THAI CHARACTER KO KAI
|
||||
0x0da2 "ข" EEK_SYMBOL_CATEGORY_LETTER # Thai_khokhai ข THAI CHARACTER KHO KHAI
|
||||
0x0da3 "ฃ" EEK_SYMBOL_CATEGORY_LETTER # Thai_khokhuat ฃ THAI CHARACTER KHO KHUAT
|
||||
0x0da4 "ค" EEK_SYMBOL_CATEGORY_LETTER # Thai_khokhwai ค THAI CHARACTER KHO KHWAI
|
||||
0x0da5 "ฅ" EEK_SYMBOL_CATEGORY_LETTER # Thai_khokhon ฅ THAI CHARACTER KHO KHON
|
||||
0x0da6 "ฆ" EEK_SYMBOL_CATEGORY_LETTER # Thai_khorakhang ฆ THAI CHARACTER KHO RAKHANG
|
||||
0x0da7 "ง" EEK_SYMBOL_CATEGORY_LETTER # Thai_ngongu ง THAI CHARACTER NGO NGU
|
||||
0x0da8 "จ" EEK_SYMBOL_CATEGORY_LETTER # Thai_chochan จ THAI CHARACTER CHO CHAN
|
||||
0x0da9 "ฉ" EEK_SYMBOL_CATEGORY_LETTER # Thai_choching ฉ THAI CHARACTER CHO CHING
|
||||
0x0daa "ช" EEK_SYMBOL_CATEGORY_LETTER # Thai_chochang ช THAI CHARACTER CHO CHANG
|
||||
0x0dab "ซ" EEK_SYMBOL_CATEGORY_LETTER # Thai_soso ซ THAI CHARACTER SO SO
|
||||
0x0dac "ฌ" EEK_SYMBOL_CATEGORY_LETTER # Thai_chochoe ฌ THAI CHARACTER CHO CHOE
|
||||
0x0dad "ญ" EEK_SYMBOL_CATEGORY_LETTER # Thai_yoying ญ THAI CHARACTER YO YING
|
||||
0x0dae "ฎ" EEK_SYMBOL_CATEGORY_LETTER # Thai_dochada ฎ THAI CHARACTER DO CHADA
|
||||
0x0daf "ฏ" EEK_SYMBOL_CATEGORY_LETTER # Thai_topatak ฏ THAI CHARACTER TO PATAK
|
||||
0x0db0 "ฐ" EEK_SYMBOL_CATEGORY_LETTER # Thai_thothan ฐ THAI CHARACTER THO THAN
|
||||
0x0db1 "ฑ" EEK_SYMBOL_CATEGORY_LETTER # Thai_thonangmontho ฑ THAI CHARACTER THO NANGMONTHO
|
||||
0x0db2 "ฒ" EEK_SYMBOL_CATEGORY_LETTER # Thai_thophuthao ฒ THAI CHARACTER THO PHUTHAO
|
||||
0x0db3 "ณ" EEK_SYMBOL_CATEGORY_LETTER # Thai_nonen ณ THAI CHARACTER NO NEN
|
||||
0x0db4 "ด" EEK_SYMBOL_CATEGORY_LETTER # Thai_dodek ด THAI CHARACTER DO DEK
|
||||
0x0db5 "ต" EEK_SYMBOL_CATEGORY_LETTER # Thai_totao ต THAI CHARACTER TO TAO
|
||||
0x0db6 "ถ" EEK_SYMBOL_CATEGORY_LETTER # Thai_thothung ถ THAI CHARACTER THO THUNG
|
||||
0x0db7 "ท" EEK_SYMBOL_CATEGORY_LETTER # Thai_thothahan ท THAI CHARACTER THO THAHAN
|
||||
0x0db8 "ธ" EEK_SYMBOL_CATEGORY_LETTER # Thai_thothong ธ THAI CHARACTER THO THONG
|
||||
0x0db9 "น" EEK_SYMBOL_CATEGORY_LETTER # Thai_nonu น THAI CHARACTER NO NU
|
||||
0x0dba "บ" EEK_SYMBOL_CATEGORY_LETTER # Thai_bobaimai บ THAI CHARACTER BO BAIMAI
|
||||
0x0dbb "ป" EEK_SYMBOL_CATEGORY_LETTER # Thai_popla ป THAI CHARACTER PO PLA
|
||||
0x0dbc "ผ" EEK_SYMBOL_CATEGORY_LETTER # Thai_phophung ผ THAI CHARACTER PHO PHUNG
|
||||
0x0dbd "ฝ" EEK_SYMBOL_CATEGORY_LETTER # Thai_fofa ฝ THAI CHARACTER FO FA
|
||||
0x0dbe "พ" EEK_SYMBOL_CATEGORY_LETTER # Thai_phophan พ THAI CHARACTER PHO PHAN
|
||||
0x0dbf "ฟ" EEK_SYMBOL_CATEGORY_LETTER # Thai_fofan ฟ THAI CHARACTER FO FAN
|
||||
0x0dc0 "ภ" EEK_SYMBOL_CATEGORY_LETTER # Thai_phosamphao ภ THAI CHARACTER PHO SAMPHAO
|
||||
0x0dc1 "ม" EEK_SYMBOL_CATEGORY_LETTER # Thai_moma ม THAI CHARACTER MO MA
|
||||
0x0dc2 "ย" EEK_SYMBOL_CATEGORY_LETTER # Thai_yoyak ย THAI CHARACTER YO YAK
|
||||
0x0dc3 "ร" EEK_SYMBOL_CATEGORY_LETTER # Thai_rorua ร THAI CHARACTER RO RUA
|
||||
0x0dc4 "ฤ" EEK_SYMBOL_CATEGORY_LETTER # Thai_ru ฤ THAI CHARACTER RU
|
||||
0x0dc5 "ล" EEK_SYMBOL_CATEGORY_LETTER # Thai_loling ล THAI CHARACTER LO LING
|
||||
0x0dc6 "ฦ" EEK_SYMBOL_CATEGORY_LETTER # Thai_lu ฦ THAI CHARACTER LU
|
||||
0x0dc7 "ว" EEK_SYMBOL_CATEGORY_LETTER # Thai_wowaen ว THAI CHARACTER WO WAEN
|
||||
0x0dc8 "ศ" EEK_SYMBOL_CATEGORY_LETTER # Thai_sosala ศ THAI CHARACTER SO SALA
|
||||
0x0dc9 "ษ" EEK_SYMBOL_CATEGORY_LETTER # Thai_sorusi ษ THAI CHARACTER SO RUSI
|
||||
0x0dca "ส" EEK_SYMBOL_CATEGORY_LETTER # Thai_sosua ส THAI CHARACTER SO SUA
|
||||
0x0dcb "ห" EEK_SYMBOL_CATEGORY_LETTER # Thai_hohip ห THAI CHARACTER HO HIP
|
||||
0x0dcc "ฬ" EEK_SYMBOL_CATEGORY_LETTER # Thai_lochula ฬ THAI CHARACTER LO CHULA
|
||||
0x0dcd "อ" EEK_SYMBOL_CATEGORY_LETTER # Thai_oang อ THAI CHARACTER O ANG
|
||||
0x0dce "ฮ" EEK_SYMBOL_CATEGORY_LETTER # Thai_honokhuk ฮ THAI CHARACTER HO NOKHUK
|
||||
0x0dcf "ฯ" EEK_SYMBOL_CATEGORY_LETTER # Thai_paiyannoi ฯ THAI CHARACTER PAIYANNOI
|
||||
0x0dd0 "ะ" EEK_SYMBOL_CATEGORY_LETTER # Thai_saraa ะ THAI CHARACTER SARA A
|
||||
0x0dd1 "ั" EEK_SYMBOL_CATEGORY_LETTER # Thai_maihanakat ั THAI CHARACTER MAI HAN-AKAT
|
||||
0x0dd2 "า" EEK_SYMBOL_CATEGORY_LETTER # Thai_saraaa า THAI CHARACTER SARA AA
|
||||
0x0dd3 "ำ" EEK_SYMBOL_CATEGORY_LETTER # Thai_saraam ำ THAI CHARACTER SARA AM
|
||||
0x0dd4 "ิ" EEK_SYMBOL_CATEGORY_LETTER # Thai_sarai ิ THAI CHARACTER SARA I
|
||||
0x0dd5 "ี" EEK_SYMBOL_CATEGORY_LETTER # Thai_saraii ี THAI CHARACTER SARA II
|
||||
0x0dd6 "ึ" EEK_SYMBOL_CATEGORY_LETTER # Thai_saraue ึ THAI CHARACTER SARA UE
|
||||
0x0dd7 "ื" EEK_SYMBOL_CATEGORY_LETTER # Thai_sarauee ื THAI CHARACTER SARA UEE
|
||||
0x0dd8 "ุ" EEK_SYMBOL_CATEGORY_LETTER # Thai_sarau ุ THAI CHARACTER SARA U
|
||||
0x0dd9 "ู" EEK_SYMBOL_CATEGORY_LETTER # Thai_sarauu ู THAI CHARACTER SARA UU
|
||||
0x0dda "ฺ" EEK_SYMBOL_CATEGORY_LETTER # Thai_phinthu ฺ THAI CHARACTER PHINTHU
|
||||
0x0dde "" EEK_SYMBOL_CATEGORY_LETTER # Thai_maihanakat_maitho ???
|
||||
0x0ddf "฿" EEK_SYMBOL_CATEGORY_LETTER # Thai_baht ฿ THAI CURRENCY SYMBOL BAHT
|
||||
0x0de0 "เ" EEK_SYMBOL_CATEGORY_LETTER # Thai_sarae เ THAI CHARACTER SARA E
|
||||
0x0de1 "แ" EEK_SYMBOL_CATEGORY_LETTER # Thai_saraae แ THAI CHARACTER SARA AE
|
||||
0x0de2 "โ" EEK_SYMBOL_CATEGORY_LETTER # Thai_sarao โ THAI CHARACTER SARA O
|
||||
0x0de3 "ใ" EEK_SYMBOL_CATEGORY_LETTER # Thai_saraaimaimuan ใ THAI CHARACTER SARA AI MAIMUAN
|
||||
0x0de4 "ไ" EEK_SYMBOL_CATEGORY_LETTER # Thai_saraaimaimalai ไ THAI CHARACTER SARA AI MAIMALAI
|
||||
0x0de5 "ๅ" EEK_SYMBOL_CATEGORY_LETTER # Thai_lakkhangyao ๅ THAI CHARACTER LAKKHANGYAO
|
||||
0x0de6 "ๆ" EEK_SYMBOL_CATEGORY_LETTER # Thai_maiyamok ๆ THAI CHARACTER MAIYAMOK
|
||||
0x0de7 "็" EEK_SYMBOL_CATEGORY_LETTER # Thai_maitaikhu ็ THAI CHARACTER MAITAIKHU
|
||||
0x0de8 "่" EEK_SYMBOL_CATEGORY_LETTER # Thai_maiek ่ THAI CHARACTER MAI EK
|
||||
0x0de9 "้" EEK_SYMBOL_CATEGORY_LETTER # Thai_maitho ้ THAI CHARACTER MAI THO
|
||||
0x0dea "๊" EEK_SYMBOL_CATEGORY_LETTER # Thai_maitri ๊ THAI CHARACTER MAI TRI
|
||||
0x0deb "๋" EEK_SYMBOL_CATEGORY_LETTER # Thai_maichattawa ๋ THAI CHARACTER MAI CHATTAWA
|
||||
0x0dec "์" EEK_SYMBOL_CATEGORY_LETTER # Thai_thanthakhat ์ THAI CHARACTER THANTHAKHAT
|
||||
0x0ded "ํ" EEK_SYMBOL_CATEGORY_LETTER # Thai_nikhahit ํ THAI CHARACTER NIKHAHIT
|
||||
0x0df0 "๐" EEK_SYMBOL_CATEGORY_LETTER # Thai_leksun ๐ THAI DIGIT ZERO
|
||||
0x0df1 "๑" EEK_SYMBOL_CATEGORY_LETTER # Thai_leknung ๑ THAI DIGIT ONE
|
||||
0x0df2 "๒" EEK_SYMBOL_CATEGORY_LETTER # Thai_leksong ๒ THAI DIGIT TWO
|
||||
0x0df3 "๓" EEK_SYMBOL_CATEGORY_LETTER # Thai_leksam ๓ THAI DIGIT THREE
|
||||
0x0df4 "๔" EEK_SYMBOL_CATEGORY_LETTER # Thai_leksi ๔ THAI DIGIT FOUR
|
||||
0x0df5 "๕" EEK_SYMBOL_CATEGORY_LETTER # Thai_lekha ๕ THAI DIGIT FIVE
|
||||
0x0df6 "๖" EEK_SYMBOL_CATEGORY_LETTER # Thai_lekhok ๖ THAI DIGIT SIX
|
||||
0x0df7 "๗" EEK_SYMBOL_CATEGORY_LETTER # Thai_lekchet ๗ THAI DIGIT SEVEN
|
||||
0x0df8 "๘" EEK_SYMBOL_CATEGORY_LETTER # Thai_lekpaet ๘ THAI DIGIT EIGHT
|
||||
0x0df9 "๙" EEK_SYMBOL_CATEGORY_LETTER # Thai_lekkao ๙ THAI DIGIT NINE
|
||||
0x0ea1 "ㄱ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_Kiyeog ㄱ HANGUL LETTER KIYEOK
|
||||
0x0ea2 "ㄲ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_SsangKiyeog ㄲ HANGUL LETTER SSANGKIYEOK
|
||||
0x0ea3 "ㄳ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_KiyeogSios ㄳ HANGUL LETTER KIYEOK-SIOS
|
||||
0x0ea4 "ㄴ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_Nieun ㄴ HANGUL LETTER NIEUN
|
||||
0x0ea5 "ㄵ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_NieunJieuj ㄵ HANGUL LETTER NIEUN-CIEUC
|
||||
0x0ea6 "ㄶ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_NieunHieuh ㄶ HANGUL LETTER NIEUN-HIEUH
|
||||
0x0ea7 "ㄷ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_Dikeud ㄷ HANGUL LETTER TIKEUT
|
||||
0x0ea8 "ㄸ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_SsangDikeud ㄸ HANGUL LETTER SSANGTIKEUT
|
||||
0x0ea9 "ㄹ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_Rieul ㄹ HANGUL LETTER RIEUL
|
||||
0x0eaa "ㄺ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_RieulKiyeog ㄺ HANGUL LETTER RIEUL-KIYEOK
|
||||
0x0eab "ㄻ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_RieulMieum ㄻ HANGUL LETTER RIEUL-MIEUM
|
||||
0x0eac "ㄼ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_RieulPieub ㄼ HANGUL LETTER RIEUL-PIEUP
|
||||
0x0ead "ㄽ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_RieulSios ㄽ HANGUL LETTER RIEUL-SIOS
|
||||
0x0eae "ㄾ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_RieulTieut ㄾ HANGUL LETTER RIEUL-THIEUTH
|
||||
0x0eaf "ㄿ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_RieulPhieuf ㄿ HANGUL LETTER RIEUL-PHIEUPH
|
||||
0x0eb0 "ㅀ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_RieulHieuh ㅀ HANGUL LETTER RIEUL-HIEUH
|
||||
0x0eb1 "ㅁ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_Mieum ㅁ HANGUL LETTER MIEUM
|
||||
0x0eb2 "ㅂ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_Pieub ㅂ HANGUL LETTER PIEUP
|
||||
0x0eb3 "ㅃ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_SsangPieub ㅃ HANGUL LETTER SSANGPIEUP
|
||||
0x0eb4 "ㅄ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_PieubSios ㅄ HANGUL LETTER PIEUP-SIOS
|
||||
0x0eb5 "ㅅ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_Sios ㅅ HANGUL LETTER SIOS
|
||||
0x0eb6 "ㅆ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_SsangSios ㅆ HANGUL LETTER SSANGSIOS
|
||||
0x0eb7 "ㅇ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_Ieung ㅇ HANGUL LETTER IEUNG
|
||||
0x0eb8 "ㅈ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_Jieuj ㅈ HANGUL LETTER CIEUC
|
||||
0x0eb9 "ㅉ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_SsangJieuj ㅉ HANGUL LETTER SSANGCIEUC
|
||||
0x0eba "ㅊ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_Cieuc ㅊ HANGUL LETTER CHIEUCH
|
||||
0x0ebb "ㅋ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_Khieuq ㅋ HANGUL LETTER KHIEUKH
|
||||
0x0ebc "ㅌ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_Tieut ㅌ HANGUL LETTER THIEUTH
|
||||
0x0ebd "ㅍ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_Phieuf ㅍ HANGUL LETTER PHIEUPH
|
||||
0x0ebe "ㅎ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_Hieuh ㅎ HANGUL LETTER HIEUH
|
||||
0x0ebf "ㅏ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_A ㅏ HANGUL LETTER A
|
||||
0x0ec0 "ㅐ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_AE ㅐ HANGUL LETTER AE
|
||||
0x0ec1 "ㅑ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_YA ㅑ HANGUL LETTER YA
|
||||
0x0ec2 "ㅒ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_YAE ㅒ HANGUL LETTER YAE
|
||||
0x0ec3 "ㅓ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_EO ㅓ HANGUL LETTER EO
|
||||
0x0ec4 "ㅔ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_E ㅔ HANGUL LETTER E
|
||||
0x0ec5 "ㅕ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_YEO ㅕ HANGUL LETTER YEO
|
||||
0x0ec6 "ㅖ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_YE ㅖ HANGUL LETTER YE
|
||||
0x0ec7 "ㅗ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_O ㅗ HANGUL LETTER O
|
||||
0x0ec8 "ㅘ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_WA ㅘ HANGUL LETTER WA
|
||||
0x0ec9 "ㅙ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_WAE ㅙ HANGUL LETTER WAE
|
||||
0x0eca "ㅚ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_OE ㅚ HANGUL LETTER OE
|
||||
0x0ecb "ㅛ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_YO ㅛ HANGUL LETTER YO
|
||||
0x0ecc "ㅜ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_U ㅜ HANGUL LETTER U
|
||||
0x0ecd "ㅝ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_WEO ㅝ HANGUL LETTER WEO
|
||||
0x0ece "ㅞ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_WE ㅞ HANGUL LETTER WE
|
||||
0x0ecf "ㅟ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_WI ㅟ HANGUL LETTER WI
|
||||
0x0ed0 "ㅠ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_YU ㅠ HANGUL LETTER YU
|
||||
0x0ed1 "ㅡ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_EU ㅡ HANGUL LETTER EU
|
||||
0x0ed2 "ㅢ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_YI ㅢ HANGUL LETTER YI
|
||||
0x0ed3 "ㅣ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_I ㅣ HANGUL LETTER I
|
||||
0x0ed4 "ᆨ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_J_Kiyeog ᆨ HANGUL JONGSEONG KIYEOK
|
||||
0x0ed5 "ᆩ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_J_SsangKiyeog ᆩ HANGUL JONGSEONG SSANGKIYEOK
|
||||
0x0ed6 "ᆪ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_J_KiyeogSios ᆪ HANGUL JONGSEONG KIYEOK-SIOS
|
||||
0x0ed7 "ᆫ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_J_Nieun ᆫ HANGUL JONGSEONG NIEUN
|
||||
0x0ed8 "ᆬ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_J_NieunJieuj ᆬ HANGUL JONGSEONG NIEUN-CIEUC
|
||||
0x0ed9 "ᆭ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_J_NieunHieuh ᆭ HANGUL JONGSEONG NIEUN-HIEUH
|
||||
0x0eda "ᆮ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_J_Dikeud ᆮ HANGUL JONGSEONG TIKEUT
|
||||
0x0edb "ᆯ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_J_Rieul ᆯ HANGUL JONGSEONG RIEUL
|
||||
0x0edc "ᆰ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_J_RieulKiyeog ᆰ HANGUL JONGSEONG RIEUL-KIYEOK
|
||||
0x0edd "ᆱ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_J_RieulMieum ᆱ HANGUL JONGSEONG RIEUL-MIEUM
|
||||
0x0ede "ᆲ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_J_RieulPieub ᆲ HANGUL JONGSEONG RIEUL-PIEUP
|
||||
0x0edf "ᆳ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_J_RieulSios ᆳ HANGUL JONGSEONG RIEUL-SIOS
|
||||
0x0ee0 "ᆴ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_J_RieulTieut ᆴ HANGUL JONGSEONG RIEUL-THIEUTH
|
||||
0x0ee1 "ᆵ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_J_RieulPhieuf ᆵ HANGUL JONGSEONG RIEUL-PHIEUPH
|
||||
0x0ee2 "ᆶ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_J_RieulHieuh ᆶ HANGUL JONGSEONG RIEUL-HIEUH
|
||||
0x0ee3 "ᆷ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_J_Mieum ᆷ HANGUL JONGSEONG MIEUM
|
||||
0x0ee4 "ᆸ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_J_Pieub ᆸ HANGUL JONGSEONG PIEUP
|
||||
0x0ee5 "ᆹ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_J_PieubSios ᆹ HANGUL JONGSEONG PIEUP-SIOS
|
||||
0x0ee6 "ᆺ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_J_Sios ᆺ HANGUL JONGSEONG SIOS
|
||||
0x0ee7 "ᆻ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_J_SsangSios ᆻ HANGUL JONGSEONG SSANGSIOS
|
||||
0x0ee8 "ᆼ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_J_Ieung ᆼ HANGUL JONGSEONG IEUNG
|
||||
0x0ee9 "ᆽ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_J_Jieuj ᆽ HANGUL JONGSEONG CIEUC
|
||||
0x0eea "ᆾ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_J_Cieuc ᆾ HANGUL JONGSEONG CHIEUCH
|
||||
0x0eeb "ᆿ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_J_Khieuq ᆿ HANGUL JONGSEONG KHIEUKH
|
||||
0x0eec "ᇀ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_J_Tieut ᇀ HANGUL JONGSEONG THIEUTH
|
||||
0x0eed "ᇁ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_J_Phieuf ᇁ HANGUL JONGSEONG PHIEUPH
|
||||
0x0eee "ᇂ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_J_Hieuh ᇂ HANGUL JONGSEONG HIEUH
|
||||
0x0eef "ㅭ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_RieulYeorinHieuh ㅭ HANGUL LETTER RIEUL-YEORINHIEUH
|
||||
0x0ef0 "ㅱ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_SunkyeongeumMieum ㅱ HANGUL LETTER KAPYEOUNMIEUM
|
||||
0x0ef1 "ㅸ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_SunkyeongeumPieub ㅸ HANGUL LETTER KAPYEOUNPIEUP
|
||||
0x0ef2 "ㅿ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_PanSios ㅿ HANGUL LETTER PANSIOS
|
||||
# 0x0ef3 Hangul_KkogjiDalrinIeung ? ???
|
||||
0x0ef4 "ㆄ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_SunkyeongeumPhieuf ㆄ HANGUL LETTER KAPYEOUNPHIEUPH
|
||||
0x0ef5 "ㆆ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_YeorinHieuh ㆆ HANGUL LETTER YEORINHIEUH
|
||||
0x0ef6 "ㆍ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_AraeA ㆍ HANGUL LETTER ARAEA
|
||||
0x0ef7 "ㆎ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_AraeAE ㆎ HANGUL LETTER ARAEAE
|
||||
0x0ef8 "ᇫ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_J_PanSios ᇫ HANGUL JONGSEONG PANSIOS
|
||||
# 0x0ef9 Hangul_J_KkogjiDalrinIeung ? ???
|
||||
0x0efa "ᇹ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_J_YeorinHieuh ᇹ HANGUL JONGSEONG YEORINHIEUH
|
||||
0x0eff "₩" EEK_SYMBOL_CATEGORY_LETTER # Korean_Won ₩ WON SIGN
|
||||
0x13bc "Œ" EEK_SYMBOL_CATEGORY_LETTER # OE Œ LATIN CAPITAL LIGATURE OE
|
||||
0x13bd "œ" EEK_SYMBOL_CATEGORY_LETTER # oe œ LATIN SMALL LIGATURE OE
|
||||
0x13be "Ÿ" EEK_SYMBOL_CATEGORY_LETTER # Ydiaeresis Ÿ LATIN CAPITAL LETTER Y WITH DIAERESIS
|
||||
0x20a0 "₠" EEK_SYMBOL_CATEGORY_LETTER # EcuSign ₠ EURO-CURRENCY SIGN
|
||||
0x20a1 "₡" EEK_SYMBOL_CATEGORY_LETTER # ColonSign ₡ COLON SIGN
|
||||
0x20a2 "₢" EEK_SYMBOL_CATEGORY_LETTER # CruzeiroSign ₢ CRUZEIRO SIGN
|
||||
0x20a3 "₣" EEK_SYMBOL_CATEGORY_LETTER # FFrancSign ₣ FRENCH FRANC SIGN
|
||||
0x20a4 "₤" EEK_SYMBOL_CATEGORY_LETTER # LiraSign ₤ LIRA SIGN
|
||||
0x20a5 "₥" EEK_SYMBOL_CATEGORY_LETTER # MillSign ₥ MILL SIGN
|
||||
0x20a6 "₦" EEK_SYMBOL_CATEGORY_LETTER # NairaSign ₦ NAIRA SIGN
|
||||
0x20a7 "₧" EEK_SYMBOL_CATEGORY_LETTER # PesetaSign ₧ PESETA SIGN
|
||||
0x20a8 "₨" EEK_SYMBOL_CATEGORY_LETTER # RupeeSign ₨ RUPEE SIGN
|
||||
0x20a9 "₩" EEK_SYMBOL_CATEGORY_LETTER # WonSign ₩ WON SIGN
|
||||
0x20aa "₪" EEK_SYMBOL_CATEGORY_LETTER # NewSheqelSign ₪ NEW SHEQEL SIGN
|
||||
0x20ab "₫" EEK_SYMBOL_CATEGORY_LETTER # DongSign ₫ DONG SIGN
|
||||
0x20ac "€" EEK_SYMBOL_CATEGORY_LETTER # EuroSign € EURO SIGN
|
||||
|
||||
# Following items added to GTK, not in the xterm table
|
||||
|
||||
# Numeric keypad
|
||||
|
||||
# 0xFF80 # Space *
|
||||
0xFFAA "*" EEK_SYMBOL_CATEGORY_LETTER # Multiply *
|
||||
0xFFAB "+" EEK_SYMBOL_CATEGORY_LETTER # Add *
|
||||
0xFFAC "," EEK_SYMBOL_CATEGORY_LETTER # Separator *
|
||||
0xFFAD "-" EEK_SYMBOL_CATEGORY_LETTER # Subtract *
|
||||
0xFFAE "." EEK_SYMBOL_CATEGORY_LETTER # Decimal *
|
||||
0xFFAF "/" EEK_SYMBOL_CATEGORY_LETTER # Divide *
|
||||
0xFFB0 "0" EEK_SYMBOL_CATEGORY_LETTER # 0 *
|
||||
0xFFB1 "1" EEK_SYMBOL_CATEGORY_LETTER # 1 *
|
||||
0xFFB2 "2" EEK_SYMBOL_CATEGORY_LETTER # 2 *
|
||||
0xFFB3 "3" EEK_SYMBOL_CATEGORY_LETTER # 3 *
|
||||
0xFFB4 "4" EEK_SYMBOL_CATEGORY_LETTER # 4 *
|
||||
0xFFB5 "5" EEK_SYMBOL_CATEGORY_LETTER # 5 *
|
||||
0xFFB6 "6" EEK_SYMBOL_CATEGORY_LETTER # 6 *
|
||||
0xFFB7 "7" EEK_SYMBOL_CATEGORY_LETTER # 7 *
|
||||
0xFFB8 "8" EEK_SYMBOL_CATEGORY_LETTER # 8 *
|
||||
0xFFB9 "9" EEK_SYMBOL_CATEGORY_LETTER # 9 *
|
||||
0xFFBD "=" EEK_SYMBOL_CATEGORY_LETTER # Equal *
|
||||
|
||||
# End numeric keypad
|
||||
@ -1,404 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2011 Daiki Ueno <ueno@unixuser.org>
|
||||
* Copyright (C) 2011 Red Hat, Inc.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* SECTION:eekboard-client
|
||||
* @short_description: client interface of eekboard service
|
||||
*
|
||||
* The #EekboardClient class provides a client side access to eekboard-server.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
|
||||
#include "eekboard/eekboard-client.h"
|
||||
|
||||
enum {
|
||||
DESTROYED,
|
||||
LAST_SIGNAL
|
||||
};
|
||||
|
||||
static guint signals[LAST_SIGNAL] = { 0, };
|
||||
|
||||
typedef struct _EekboardClientPrivate
|
||||
{
|
||||
GHashTable *context_hash;
|
||||
} EekboardClientPrivate;
|
||||
|
||||
G_DEFINE_TYPE_WITH_PRIVATE (EekboardClient, eekboard_client, G_TYPE_DBUS_PROXY)
|
||||
|
||||
static void send_destroy_context (EekboardClient *client,
|
||||
EekboardContext *context,
|
||||
GCancellable *cancellable);
|
||||
|
||||
static void
|
||||
eekboard_client_real_destroyed (EekboardClient *self)
|
||||
{
|
||||
EekboardClientPrivate *priv = eekboard_client_get_instance_private (self);
|
||||
|
||||
// g_debug ("eekboard_client_real_destroyed");
|
||||
g_hash_table_remove_all (priv->context_hash);
|
||||
}
|
||||
|
||||
static void
|
||||
eekboard_client_dispose (GObject *object)
|
||||
{
|
||||
EekboardClient *client = EEKBOARD_CLIENT(object);
|
||||
EekboardClientPrivate *priv = eekboard_client_get_instance_private (client);
|
||||
|
||||
if (priv->context_hash) {
|
||||
GHashTableIter iter;
|
||||
gpointer key, value;
|
||||
|
||||
g_hash_table_iter_init (&iter, priv->context_hash);
|
||||
while (g_hash_table_iter_next (&iter, &key, &value)) {
|
||||
send_destroy_context (client, (EekboardContext *)value, NULL);
|
||||
g_hash_table_iter_remove (&iter);
|
||||
}
|
||||
g_hash_table_destroy (priv->context_hash);
|
||||
priv->context_hash = NULL;
|
||||
}
|
||||
|
||||
G_OBJECT_CLASS (eekboard_client_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
eekboard_client_class_init (EekboardClientClass *klass)
|
||||
{
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
klass->destroyed = eekboard_client_real_destroyed;
|
||||
|
||||
gobject_class->dispose = eekboard_client_dispose;
|
||||
|
||||
/**
|
||||
* EekboardClient::destroyed:
|
||||
* @eekboard: an #EekboardClient
|
||||
*
|
||||
* The ::destroyed signal is emitted each time the name of remote
|
||||
* end is vanished.
|
||||
*/
|
||||
signals[DESTROYED] =
|
||||
g_signal_new (I_("destroyed"),
|
||||
G_TYPE_FROM_CLASS(gobject_class),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET(EekboardClientClass, destroyed),
|
||||
NULL,
|
||||
NULL,
|
||||
g_cclosure_marshal_VOID__VOID,
|
||||
G_TYPE_NONE,
|
||||
0);
|
||||
}
|
||||
|
||||
static void
|
||||
eekboard_client_init (EekboardClient *self)
|
||||
{
|
||||
EekboardClientPrivate *priv = eekboard_client_get_instance_private (self);
|
||||
|
||||
priv->context_hash =
|
||||
g_hash_table_new_full (g_str_hash,
|
||||
g_str_equal,
|
||||
(GDestroyNotify)g_free,
|
||||
(GDestroyNotify)g_object_unref);
|
||||
}
|
||||
|
||||
static void
|
||||
eekboard_name_vanished_callback (GDBusConnection *connection,
|
||||
const gchar *name,
|
||||
gpointer user_data)
|
||||
{
|
||||
EekboardClient *client = user_data;
|
||||
g_signal_emit_by_name (client, "destroyed", NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* eekboard_client_new:
|
||||
* @connection: a #GDBusConnection
|
||||
* @cancellable: a #GCancellable
|
||||
*
|
||||
* Create a client.
|
||||
*/
|
||||
EekboardClient *
|
||||
eekboard_client_new (GDBusConnection *connection,
|
||||
GCancellable *cancellable)
|
||||
{
|
||||
GInitable *initable;
|
||||
GError *error;
|
||||
|
||||
g_assert (G_IS_DBUS_CONNECTION(connection));
|
||||
|
||||
error = NULL;
|
||||
initable =
|
||||
g_initable_new (EEKBOARD_TYPE_CLIENT,
|
||||
cancellable,
|
||||
&error,
|
||||
"g-connection", connection,
|
||||
"g-name", "org.fedorahosted.Eekboard",
|
||||
"g-interface-name", "org.fedorahosted.Eekboard",
|
||||
"g-object-path", "/org/fedorahosted/Eekboard",
|
||||
NULL);
|
||||
if (initable != NULL) {
|
||||
EekboardClient *client = EEKBOARD_CLIENT (initable);
|
||||
gchar *name_owner = g_dbus_proxy_get_name_owner (G_DBUS_PROXY(client));
|
||||
if (name_owner == NULL) {
|
||||
g_object_unref (client);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* the vanished callback is called when the server is disconnected */
|
||||
g_bus_watch_name_on_connection (connection,
|
||||
name_owner,
|
||||
G_BUS_NAME_WATCHER_FLAGS_NONE,
|
||||
NULL,
|
||||
eekboard_name_vanished_callback,
|
||||
client,
|
||||
NULL);
|
||||
g_free (name_owner);
|
||||
|
||||
return client;
|
||||
}
|
||||
|
||||
g_warning ("can't create client: %s", error->message);
|
||||
g_error_free (error);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
on_context_destroyed (EekboardContext *context,
|
||||
gpointer user_data)
|
||||
{
|
||||
EekboardClient *client = user_data;
|
||||
EekboardClientPrivate *priv = eekboard_client_get_instance_private (client);
|
||||
|
||||
g_hash_table_remove (priv->context_hash,
|
||||
g_dbus_proxy_get_object_path (G_DBUS_PROXY(context)));
|
||||
}
|
||||
|
||||
/**
|
||||
* eekboard_client_create_context:
|
||||
* @eekboard: an #EekboardClient
|
||||
* @client_name: name of the client
|
||||
* @cancellable: a #GCancellable
|
||||
*
|
||||
* Create a new input context.
|
||||
*
|
||||
* Return value: (transfer full): a newly created #EekboardContext.
|
||||
*/
|
||||
EekboardContext *
|
||||
eekboard_client_create_context (EekboardClient *client,
|
||||
const gchar *client_name,
|
||||
GCancellable *cancellable)
|
||||
{
|
||||
GVariant *variant;
|
||||
const gchar *object_path;
|
||||
EekboardContext *context;
|
||||
GError *error;
|
||||
GDBusConnection *connection;
|
||||
|
||||
g_assert (EEKBOARD_IS_CLIENT(client));
|
||||
g_assert (client_name);
|
||||
|
||||
error = NULL;
|
||||
variant = g_dbus_proxy_call_sync (G_DBUS_PROXY(client),
|
||||
"CreateContext",
|
||||
g_variant_new ("(s)", client_name),
|
||||
G_DBUS_CALL_FLAGS_NONE,
|
||||
-1,
|
||||
cancellable,
|
||||
&error);
|
||||
if (!variant) {
|
||||
g_warning ("failed to call CreateContext: %s", error->message);
|
||||
g_error_free (error);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
g_variant_get (variant, "(&s)", &object_path);
|
||||
connection = g_dbus_proxy_get_connection (G_DBUS_PROXY(client));
|
||||
context = eekboard_context_new (connection, object_path, cancellable);
|
||||
if (!context) {
|
||||
g_variant_unref (variant);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
EekboardClientPrivate *priv = eekboard_client_get_instance_private (client);
|
||||
|
||||
g_hash_table_insert (priv->context_hash,
|
||||
g_strdup (object_path),
|
||||
g_object_ref (context));
|
||||
g_signal_connect (context, "destroyed",
|
||||
G_CALLBACK(on_context_destroyed), client);
|
||||
return context;
|
||||
}
|
||||
|
||||
static void
|
||||
eekboard_async_ready_callback (GObject *source_object,
|
||||
GAsyncResult *res,
|
||||
gpointer user_data)
|
||||
{
|
||||
GError *error = NULL;
|
||||
GVariant *result;
|
||||
|
||||
result = g_dbus_proxy_call_finish (G_DBUS_PROXY(source_object),
|
||||
res,
|
||||
&error);
|
||||
if (result)
|
||||
g_variant_unref (result);
|
||||
else {
|
||||
g_warning ("error in D-Bus proxy call: %s", error->message);
|
||||
g_error_free (error);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* eekboard_client_push_context:
|
||||
* @eekboard: an #EekboardClient
|
||||
* @context: an #EekboardContext
|
||||
* @cancellable: a #GCancellable
|
||||
*
|
||||
* Enable the input context @context and disable the others.
|
||||
*/
|
||||
void
|
||||
eekboard_client_push_context (EekboardClient *client,
|
||||
EekboardContext *context,
|
||||
GCancellable *cancellable)
|
||||
{
|
||||
const gchar *object_path;
|
||||
|
||||
g_return_if_fail (EEKBOARD_IS_CLIENT(client));
|
||||
g_return_if_fail (EEKBOARD_IS_CONTEXT(context));
|
||||
|
||||
EekboardClientPrivate *priv = eekboard_client_get_instance_private (client);
|
||||
|
||||
object_path = g_dbus_proxy_get_object_path (G_DBUS_PROXY(context));
|
||||
|
||||
context = g_hash_table_lookup (priv->context_hash,
|
||||
object_path);
|
||||
if (!context)
|
||||
return;
|
||||
|
||||
eekboard_context_set_enabled (context, TRUE);
|
||||
g_dbus_proxy_call (G_DBUS_PROXY(client),
|
||||
"PushContext",
|
||||
g_variant_new ("(s)", object_path),
|
||||
G_DBUS_CALL_FLAGS_NONE,
|
||||
-1,
|
||||
cancellable,
|
||||
eekboard_async_ready_callback,
|
||||
NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* eekboard_client_pop_context:
|
||||
* @eekboard: an #EekboardClient
|
||||
* @cancellable: a #GCancellable
|
||||
*
|
||||
* Disable the current input context and enable the previous one.
|
||||
*/
|
||||
void
|
||||
eekboard_client_pop_context (EekboardClient *client,
|
||||
GCancellable *cancellable)
|
||||
{
|
||||
g_return_if_fail (EEKBOARD_IS_CLIENT(client));
|
||||
|
||||
g_dbus_proxy_call (G_DBUS_PROXY(client),
|
||||
"PopContext",
|
||||
NULL,
|
||||
G_DBUS_CALL_FLAGS_NONE,
|
||||
-1,
|
||||
cancellable,
|
||||
eekboard_async_ready_callback,
|
||||
NULL);
|
||||
}
|
||||
|
||||
void
|
||||
eekboard_client_show_keyboard (EekboardClient *client,
|
||||
GCancellable *cancellable)
|
||||
{
|
||||
g_return_if_fail (EEKBOARD_IS_CLIENT(client));
|
||||
|
||||
g_dbus_proxy_call (G_DBUS_PROXY(client),
|
||||
"ShowKeyboard",
|
||||
NULL,
|
||||
G_DBUS_CALL_FLAGS_NONE,
|
||||
-1,
|
||||
cancellable,
|
||||
eekboard_async_ready_callback,
|
||||
NULL);
|
||||
}
|
||||
|
||||
void
|
||||
eekboard_client_hide_keyboard (EekboardClient *client,
|
||||
GCancellable *cancellable)
|
||||
{
|
||||
g_return_if_fail (EEKBOARD_IS_CLIENT(client));
|
||||
|
||||
g_dbus_proxy_call (G_DBUS_PROXY(client),
|
||||
"HideKeyboard",
|
||||
NULL,
|
||||
G_DBUS_CALL_FLAGS_NONE,
|
||||
-1,
|
||||
cancellable,
|
||||
eekboard_async_ready_callback,
|
||||
NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
send_destroy_context (EekboardClient *client,
|
||||
EekboardContext *context,
|
||||
GCancellable *cancellable)
|
||||
{
|
||||
const gchar *object_path;
|
||||
|
||||
object_path = g_dbus_proxy_get_object_path (G_DBUS_PROXY(context));
|
||||
|
||||
g_dbus_proxy_call (G_DBUS_PROXY(client),
|
||||
"DestroyContext",
|
||||
g_variant_new ("(s)", object_path),
|
||||
G_DBUS_CALL_FLAGS_NONE,
|
||||
-1,
|
||||
cancellable,
|
||||
eekboard_async_ready_callback,
|
||||
NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* eekboard_client_destroy_context:
|
||||
* @eekboard: an #EekboardClient
|
||||
* @context: an #EekboardContext
|
||||
* @cancellable: a #GCancellable
|
||||
*
|
||||
* Remove @context from @eekboard.
|
||||
*/
|
||||
void
|
||||
eekboard_client_destroy_context (EekboardClient *client,
|
||||
EekboardContext *context,
|
||||
GCancellable *cancellable)
|
||||
{
|
||||
const gchar *object_path;
|
||||
|
||||
g_return_if_fail (EEKBOARD_IS_CLIENT(client));
|
||||
g_return_if_fail (EEKBOARD_IS_CONTEXT(context));
|
||||
|
||||
EekboardClientPrivate *priv = eekboard_client_get_instance_private (client);
|
||||
|
||||
object_path = g_dbus_proxy_get_object_path (G_DBUS_PROXY(context));
|
||||
g_hash_table_remove (priv->context_hash, object_path);
|
||||
|
||||
send_destroy_context (client, context, cancellable);
|
||||
}
|
||||
@ -1,64 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2011 Daiki Ueno <ueno@unixuser.org>
|
||||
* Copyright (C) 2010-2011 Red Hat, Inc.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef EEKBOARD_CLIENT_H
|
||||
#define EEKBOARD_CLIENT_H 1
|
||||
|
||||
#define __EEKBOARD_CLIENT_H_INSIDE__ 1
|
||||
|
||||
#include <gio/gio.h>
|
||||
#include "eekboard/eekboard-context.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define EEKBOARD_TYPE_CLIENT (eekboard_client_get_type())
|
||||
G_DECLARE_DERIVABLE_TYPE (EekboardClient, eekboard_client, EEKBOARD, CLIENT, GDBusProxy)
|
||||
|
||||
struct _EekboardClientClass {
|
||||
/*< private >*/
|
||||
GDBusProxyClass parent_class;
|
||||
|
||||
/* signals */
|
||||
void (* destroyed) (EekboardClient *self);
|
||||
|
||||
/*< private >*/
|
||||
/* padding */
|
||||
gpointer pdummy[23];
|
||||
};
|
||||
|
||||
GType eekboard_client_get_type (void) G_GNUC_CONST;
|
||||
|
||||
EekboardClient *eekboard_client_new (GDBusConnection *connection,
|
||||
GCancellable *cancellable);
|
||||
EekboardContext *eekboard_client_create_context (EekboardClient *eekboard,
|
||||
const gchar *client_name,
|
||||
GCancellable *cancellable);
|
||||
void eekboard_client_push_context (EekboardClient *eekboard,
|
||||
EekboardContext *context,
|
||||
GCancellable *cancellable);
|
||||
void eekboard_client_pop_context (EekboardClient *eekboard,
|
||||
GCancellable *cancellable);
|
||||
void eekboard_client_show_keyboard (EekboardClient *eekboard,
|
||||
GCancellable *cancellable);
|
||||
void eekboard_client_hide_keyboard (EekboardClient *eekboard,
|
||||
GCancellable *cancellable);
|
||||
void eekboard_client_destroy_context (EekboardClient *eekboard,
|
||||
EekboardContext *context,
|
||||
GCancellable *cancellable);
|
||||
|
||||
G_END_DECLS
|
||||
#endif /* EEKBOARD_CLIENT_H */
|
||||
@ -25,11 +25,7 @@
|
||||
* implementation of eekboard input context service.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
|
||||
#include "eekboard/eekboard-context-service.h"
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
@ -38,10 +34,14 @@
|
||||
#include <sys/random.h> // TODO: this is Linux-specific
|
||||
#include <xkbcommon/xkbcommon.h>
|
||||
|
||||
#include <gio/gio.h>
|
||||
|
||||
#include "eekboard/key-emitter.h"
|
||||
#include "wayland.h"
|
||||
//#include "eekboard/eekboard-xklutil.h"
|
||||
//#include "eek/eek-xkl.h"
|
||||
|
||||
#include "eek/eek-xml-layout.h"
|
||||
|
||||
#include "eekboard/eekboard-context-service.h"
|
||||
|
||||
#define CSW 640
|
||||
#define CSH 480
|
||||
@ -71,26 +71,24 @@ struct _EekboardContextServicePrivate {
|
||||
gboolean visible;
|
||||
gboolean fullscreen;
|
||||
|
||||
EekKeyboard *keyboard; // currently used keyboard
|
||||
LevelKeyboard *keyboard; // currently used keyboard
|
||||
GHashTable *keyboard_hash; // a table of available keyboards, per layout
|
||||
|
||||
// TODO: make use of repeating buttons
|
||||
EekKey *repeat_key;
|
||||
guint repeat_timeout_id;
|
||||
gboolean repeat_triggered;
|
||||
|
||||
GSettings *settings;
|
||||
uint32_t hint;
|
||||
uint32_t purpose;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE_WITH_PRIVATE (EekboardContextService, eekboard_context_service, G_TYPE_OBJECT);
|
||||
|
||||
/*static Display *display = NULL; */
|
||||
|
||||
static EekKeyboard *
|
||||
static LevelKeyboard *
|
||||
eekboard_context_service_real_create_keyboard (EekboardContextService *self,
|
||||
const gchar *keyboard_type)
|
||||
{
|
||||
EekKeyboard *keyboard;
|
||||
EekLayout *layout;
|
||||
GError *error;
|
||||
|
||||
@ -135,7 +133,7 @@ eekboard_context_service_real_create_keyboard (EekboardContextService *self,
|
||||
}
|
||||
}
|
||||
}
|
||||
keyboard = eek_keyboard_new (self, layout, CSW, CSH);
|
||||
LevelKeyboard *keyboard = eek_xml_layout_real_create_keyboard(layout, self);
|
||||
if (!keyboard) {
|
||||
g_error("Failed to create a keyboard");
|
||||
}
|
||||
@ -146,17 +144,26 @@ eekboard_context_service_real_create_keyboard (EekboardContextService *self,
|
||||
g_error("No context created");
|
||||
}
|
||||
|
||||
struct xkb_rule_names rules = { 0 };
|
||||
rules.layout = strdup(keyboard_type);
|
||||
struct xkb_keymap *keymap = xkb_keymap_new_from_names(context, &rules,
|
||||
XKB_KEYMAP_COMPILE_NO_FLAGS);
|
||||
gchar *keymap_str = eek_keyboard_get_keymap(keyboard);
|
||||
|
||||
int f = open("maprs.map", O_CREAT | O_WRONLY, 0600);
|
||||
write(f, keymap_str, strlen(keymap_str));
|
||||
close(f);
|
||||
|
||||
struct xkb_keymap *keymap = xkb_keymap_new_from_string(context, keymap_str,
|
||||
XKB_KEYMAP_FORMAT_TEXT_V1, XKB_KEYMAP_COMPILE_NO_FLAGS);
|
||||
|
||||
if (!keymap)
|
||||
g_error("Bad keymap:\n%s", keymap_str);
|
||||
|
||||
free(keymap_str);
|
||||
|
||||
xkb_context_unref(context);
|
||||
if (!keymap) {
|
||||
g_error("Bad 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;
|
||||
|
||||
g_autofree char *path = strdup("/eek_keymap-XXXXXX");
|
||||
char *r = &path[strlen(path) - 6];
|
||||
getrandom(r, 6, GRND_NONBLOCK);
|
||||
@ -212,12 +219,7 @@ eekboard_context_service_set_property (GObject *object,
|
||||
context->priv->keyboard = g_value_get_object (value);
|
||||
break;
|
||||
case PROP_VISIBLE:
|
||||
/*if (context->priv->keyboard) {
|
||||
if (g_value_get_boolean (value))
|
||||
eekboard_context_service_show_keyboard (context);
|
||||
else
|
||||
eekboard_context_service_hide_keyboard (context);
|
||||
}*/
|
||||
context->priv->visible = g_value_get_boolean (value);
|
||||
break;
|
||||
case PROP_FULLSCREEN:
|
||||
context->priv->fullscreen = g_value_get_boolean (value);
|
||||
@ -289,7 +291,8 @@ settings_get_layout(GSettings *settings, char **type, char **layout)
|
||||
}
|
||||
|
||||
static void
|
||||
settings_update_layout(EekboardContextService *context) {
|
||||
settings_update_layout(EekboardContextService *context)
|
||||
{
|
||||
g_autofree gchar *keyboard_type = NULL;
|
||||
g_autofree gchar *keyboard_layout = NULL;
|
||||
settings_get_layout(context->priv->settings, &keyboard_type, &keyboard_layout);
|
||||
@ -301,23 +304,29 @@ settings_update_layout(EekboardContextService *context) {
|
||||
keyboard_layout = g_strdup("undefined");
|
||||
}
|
||||
|
||||
EekboardContextServicePrivate *priv = EEKBOARD_CONTEXT_SERVICE_GET_PRIVATE(context);
|
||||
|
||||
switch (priv->purpose) {
|
||||
case ZWP_TEXT_INPUT_V3_CONTENT_PURPOSE_NUMBER:
|
||||
case ZWP_TEXT_INPUT_V3_CONTENT_PURPOSE_PHONE:
|
||||
keyboard_layout = g_strdup("number");
|
||||
break;
|
||||
default:
|
||||
;
|
||||
}
|
||||
|
||||
// generic part follows
|
||||
static guint keyboard_id = 0;
|
||||
EekKeyboard *keyboard = g_hash_table_lookup(context->priv->keyboard_hash,
|
||||
LevelKeyboard *keyboard = g_hash_table_lookup(context->priv->keyboard_hash,
|
||||
GUINT_TO_POINTER(keyboard_id));
|
||||
// create a keyboard
|
||||
if (!keyboard) {
|
||||
EekboardContextServiceClass *klass = EEKBOARD_CONTEXT_SERVICE_GET_CLASS(context);
|
||||
keyboard = klass->create_keyboard (context, keyboard_layout);
|
||||
eek_keyboard_set_modifier_behavior (keyboard,
|
||||
EEK_MODIFIER_BEHAVIOR_LATCH);
|
||||
keyboard = eekboard_context_service_real_create_keyboard(context, keyboard_layout);
|
||||
|
||||
g_hash_table_insert (context->priv->keyboard_hash,
|
||||
GUINT_TO_POINTER(keyboard_id),
|
||||
keyboard);
|
||||
g_object_set_data (G_OBJECT(keyboard),
|
||||
"keyboard-id",
|
||||
GUINT_TO_POINTER(keyboard_id));
|
||||
keyboard->id = keyboard_id;
|
||||
keyboard_id++;
|
||||
}
|
||||
// set as current
|
||||
@ -358,7 +367,6 @@ eekboard_context_service_class_init (EekboardContextServiceClass *klass)
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||
GParamSpec *pspec;
|
||||
|
||||
klass->create_keyboard = eekboard_context_service_real_create_keyboard;
|
||||
klass->show_keyboard = eekboard_context_service_real_show_keyboard;
|
||||
klass->hide_keyboard = eekboard_context_service_real_hide_keyboard;
|
||||
|
||||
@ -423,10 +431,9 @@ eekboard_context_service_class_init (EekboardContextServiceClass *klass)
|
||||
*
|
||||
* An #EekKeyboard currently active in this context.
|
||||
*/
|
||||
pspec = g_param_spec_object ("keyboard",
|
||||
pspec = g_param_spec_pointer("keyboard",
|
||||
"Keyboard",
|
||||
"Keyboard",
|
||||
EEK_TYPE_KEYBOARD,
|
||||
G_PARAM_READWRITE);
|
||||
g_object_class_install_property (gobject_class,
|
||||
PROP_KEYBOARD,
|
||||
@ -562,7 +569,7 @@ eekboard_context_service_destroy (EekboardContextService *context)
|
||||
* Get keyboard currently active in @context.
|
||||
* Returns: (transfer none): an #EekKeyboard
|
||||
*/
|
||||
EekKeyboard *
|
||||
LevelKeyboard *
|
||||
eekboard_context_service_get_keyboard (EekboardContextService *context)
|
||||
{
|
||||
return context->priv->keyboard;
|
||||
@ -582,9 +589,21 @@ eekboard_context_service_get_fullscreen (EekboardContextService *context)
|
||||
}
|
||||
|
||||
void eekboard_context_service_set_keymap(EekboardContextService *context,
|
||||
const EekKeyboard *keyboard)
|
||||
const LevelKeyboard *keyboard)
|
||||
{
|
||||
zwp_virtual_keyboard_v1_keymap(context->virtual_keyboard,
|
||||
WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1,
|
||||
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,6 +25,7 @@
|
||||
#include <eek/eek.h>
|
||||
|
||||
#include "virtual-keyboard-unstable-v1-client-protocol.h"
|
||||
#include "text-input-unstable-v3-client-protocol.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
@ -72,7 +73,7 @@ struct _EekboardContextServiceClass {
|
||||
GObjectClass parent_class;
|
||||
|
||||
/*< public >*/
|
||||
EekKeyboard *(*create_keyboard) (EekboardContextService *self,
|
||||
struct squeek_view *(*create_keyboard) (EekboardContextService *self,
|
||||
const gchar *keyboard_type);
|
||||
void (*show_keyboard) (EekboardContextService *self);
|
||||
void (*hide_keyboard) (EekboardContextService *self);
|
||||
@ -96,13 +97,16 @@ void eekboard_context_service_show_keyboard
|
||||
void eekboard_context_service_hide_keyboard
|
||||
(EekboardContextService *context);
|
||||
void eekboard_context_service_destroy (EekboardContextService *context);
|
||||
EekKeyboard *eekboard_context_service_get_keyboard
|
||||
(EekboardContextService *context);
|
||||
LevelKeyboard *eekboard_context_service_get_keyboard(EekboardContextService *context);
|
||||
gboolean eekboard_context_service_get_fullscreen
|
||||
(EekboardContextService *context);
|
||||
|
||||
void eekboard_context_service_set_keymap(EekboardContextService *context,
|
||||
const EekKeyboard *keyboard);
|
||||
const LevelKeyboard *keyboard);
|
||||
|
||||
void eekboard_context_service_set_hint_purpose(EekboardContextService *context,
|
||||
uint32_t hint,
|
||||
uint32_t purpose);
|
||||
|
||||
G_END_DECLS
|
||||
#endif /* EEKBOARD_CONTEXT_SERVICE_H */
|
||||
|
||||
@ -24,9 +24,7 @@
|
||||
* context.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
|
||||
#include "eekboard/eekboard-context.h"
|
||||
//#include "eekboard/eekboard-marshalers.h"
|
||||
@ -37,7 +35,6 @@ enum {
|
||||
ENABLED,
|
||||
DISABLED,
|
||||
DESTROYED,
|
||||
KEY_ACTIVATED,
|
||||
LAST_SIGNAL
|
||||
};
|
||||
|
||||
@ -83,28 +80,6 @@ eekboard_context_real_g_signal (GDBusProxy *self,
|
||||
return;
|
||||
}
|
||||
|
||||
if (g_strcmp0 (signal_name, "KeyActivated") == 0) {
|
||||
guint keycode;
|
||||
GVariant *variant = NULL;
|
||||
guint modifiers = 0;
|
||||
EekSerializable *serializable;
|
||||
|
||||
g_variant_get (parameters, "(uvu)",
|
||||
&keycode, &variant, &modifiers);
|
||||
g_return_if_fail (variant != NULL);
|
||||
|
||||
serializable = eek_serializable_deserialize (variant);
|
||||
g_variant_unref (variant);
|
||||
|
||||
g_return_if_fail (EEK_IS_SYMBOL(serializable));
|
||||
|
||||
g_signal_emit (context, signals[KEY_ACTIVATED], 0,
|
||||
keycode, EEK_SYMBOL(serializable), modifiers);
|
||||
g_object_unref (serializable);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (g_strcmp0 (signal_name, "VisibilityChanged") == 0) {
|
||||
gboolean visible = FALSE;
|
||||
|
||||
@ -151,14 +126,6 @@ eekboard_context_real_destroyed (EekboardContext *self)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
eekboard_context_real_key_activated (EekboardContext *self,
|
||||
guint keycode,
|
||||
EekSymbol *symbol,
|
||||
guint modifiers)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
eekboard_context_get_property (GObject *object,
|
||||
guint prop_id,
|
||||
@ -188,7 +155,6 @@ eekboard_context_class_init (EekboardContextClass *klass)
|
||||
klass->enabled = eekboard_context_real_enabled;
|
||||
klass->disabled = eekboard_context_real_disabled;
|
||||
klass->destroyed = eekboard_context_real_destroyed;
|
||||
klass->key_activated = eekboard_context_real_key_activated;
|
||||
|
||||
proxy_class->g_signal = eekboard_context_real_g_signal;
|
||||
|
||||
@ -242,31 +208,6 @@ eekboard_context_class_init (EekboardContextClass *klass)
|
||||
G_TYPE_NONE,
|
||||
0);
|
||||
|
||||
/**
|
||||
* EekboardContext::key-activated:
|
||||
* @context: an #EekboardContext
|
||||
* @keycode: a keycode
|
||||
* @symbol: an #EekSymbol
|
||||
* @modifiers: modifiers
|
||||
*
|
||||
* The ::key-activated signal is emitted each time a key is
|
||||
* pressed in @context.
|
||||
*/
|
||||
/*
|
||||
signals[KEY_ACTIVATED] =
|
||||
g_signal_new (I_("key-activated"),
|
||||
G_TYPE_FROM_CLASS(gobject_class),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET(EekboardContextClass, key_activated),
|
||||
NULL,
|
||||
NULL,
|
||||
_eekboard_marshal_VOID__UINT_OBJECT_UINT,
|
||||
G_TYPE_NONE,
|
||||
3,
|
||||
G_TYPE_UINT,
|
||||
G_TYPE_OBJECT,
|
||||
G_TYPE_UINT);
|
||||
*/
|
||||
/**
|
||||
* EekboardContext::destroyed:
|
||||
* @context: an #EekboardContext
|
||||
|
||||
@ -47,11 +47,6 @@ struct _EekboardContextClass {
|
||||
void (*disabled) (EekboardContext *self);
|
||||
void (*destroyed) (EekboardContext *self);
|
||||
|
||||
void (*key_activated) (EekboardContext *self,
|
||||
guint keycode,
|
||||
EekSymbol *symbol,
|
||||
guint modifiers);
|
||||
|
||||
/*< private >*/
|
||||
/* padding */
|
||||
gpointer pdummy[24];
|
||||
|
||||
@ -26,16 +26,16 @@
|
||||
* implementation of eekboard service.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
|
||||
#include "eekboard/eekboard-service.h"
|
||||
|
||||
#include "sm.puri.OSK0.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <gio/gio.h>
|
||||
|
||||
#include "eekboard/eekboard-service.h"
|
||||
|
||||
enum {
|
||||
PROP_0,
|
||||
PROP_OBJECT_PATH,
|
||||
@ -135,6 +135,11 @@ eekboard_service_dispose (GObject *object)
|
||||
priv->introspection_data = NULL;
|
||||
}
|
||||
|
||||
if (priv->context) {
|
||||
g_signal_handlers_disconnect_by_data (priv->context, service);
|
||||
priv->context = NULL;
|
||||
}
|
||||
|
||||
G_OBJECT_CLASS (eekboard_service_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
@ -166,6 +171,22 @@ handle_set_visible(SmPuriOSK0 *object, GDBusMethodInvocation *invocation,
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void on_visible(EekboardService *service,
|
||||
GParamSpec *pspec,
|
||||
EekboardContextService *context)
|
||||
{
|
||||
gboolean visible;
|
||||
EekboardServicePrivate *priv;
|
||||
|
||||
g_return_if_fail (EEKBOARD_IS_SERVICE (service));
|
||||
g_return_if_fail (EEKBOARD_IS_CONTEXT_SERVICE (context));
|
||||
|
||||
priv = eekboard_service_get_instance_private (service);
|
||||
g_object_get (context, "visible", &visible, NULL);
|
||||
|
||||
sm_puri_osk0_set_visible(priv->dbus_interface, visible);
|
||||
}
|
||||
|
||||
static void
|
||||
eekboard_service_constructed (GObject *object)
|
||||
{
|
||||
@ -173,7 +194,6 @@ eekboard_service_constructed (GObject *object)
|
||||
EekboardServicePrivate *priv = eekboard_service_get_instance_private (service);
|
||||
|
||||
priv->dbus_interface = sm_puri_osk0_skeleton_new();
|
||||
sm_puri_osk0_set_visible(priv->dbus_interface, FALSE); // TODO: use actual value
|
||||
g_signal_connect(priv->dbus_interface, "handle-set-visible",
|
||||
G_CALLBACK(handle_set_visible), service);
|
||||
|
||||
@ -279,5 +299,12 @@ eekboard_service_set_context(EekboardService *service,
|
||||
{
|
||||
EekboardServicePrivate *priv = eekboard_service_get_instance_private (service);
|
||||
|
||||
g_return_if_fail (!priv->context);
|
||||
|
||||
priv->context = context;
|
||||
|
||||
g_signal_connect_swapped (priv->context,
|
||||
"notify::visible",
|
||||
G_CALLBACK(on_visible),
|
||||
service);
|
||||
}
|
||||
|
||||
@ -1,168 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2011 Daiki Ueno <ueno@unixuser.org>
|
||||
* Copyright (C) 2011 Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public License
|
||||
* as published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
* 02110-1301 USA
|
||||
*/
|
||||
#include <string.h>
|
||||
#include "eekboard/eekboard-xklutil.h"
|
||||
|
||||
XklConfigRec *
|
||||
eekboard_xkl_config_rec_from_string (const gchar *layouts)
|
||||
{
|
||||
XklConfigRec *rec;
|
||||
gchar **strv, **l, **v;
|
||||
gint i;
|
||||
|
||||
strv = g_strsplit (layouts, "/", -1);
|
||||
g_return_val_if_fail (g_strv_length (strv) == 3, NULL);
|
||||
|
||||
l = g_strsplit (strv[1], ";", -1);
|
||||
v = g_strdupv (l);
|
||||
for (i = 0; l[i]; i++) {
|
||||
gchar *layout = l[i], *variant = v[i],
|
||||
*variant_start, *variant_end;
|
||||
|
||||
variant_start = strchr (layout, '(');
|
||||
variant_end = strrchr (layout, ')');
|
||||
if (variant_start && variant_end) {
|
||||
*variant_start++ = '\0';
|
||||
g_strlcpy (variant, variant_start,
|
||||
variant_end - variant_start + 1);
|
||||
} else
|
||||
*variant = '\0';
|
||||
}
|
||||
|
||||
rec = xkl_config_rec_new ();
|
||||
rec->model = g_strdup (strv[0]);
|
||||
rec->layouts = l;
|
||||
rec->variants = v;
|
||||
rec->options = g_strsplit (strv[2], ";", -1);
|
||||
g_strfreev (strv);
|
||||
|
||||
return rec;
|
||||
}
|
||||
|
||||
gchar *
|
||||
eekboard_xkl_config_rec_to_string (XklConfigRec *rec)
|
||||
{
|
||||
gchar **strv, **sp, **lp, **vp, *p;
|
||||
gint n_layouts;
|
||||
GString *str;
|
||||
|
||||
n_layouts = g_strv_length (rec->layouts);
|
||||
strv = g_malloc0_n (n_layouts + 2, sizeof (gchar *));
|
||||
for (sp = strv, lp = rec->layouts, vp = rec->variants; *lp; sp++, lp++) {
|
||||
if (*vp != NULL && **vp != '\0')
|
||||
*sp = g_strdup_printf ("%s(%s)", *lp, *vp++);
|
||||
else
|
||||
*sp = g_strdup_printf ("%s", *lp);
|
||||
}
|
||||
|
||||
/* MODEL/L0(V0);L1(V1);...;Ln(Vn)/O0;O1;...;On */
|
||||
str = g_string_new (rec->model);
|
||||
|
||||
g_string_append_c (str, '/');
|
||||
p = g_strjoinv (";", strv);
|
||||
g_strfreev (strv);
|
||||
g_string_append (str, p);
|
||||
g_free (p);
|
||||
|
||||
g_string_append_c (str, '/');
|
||||
p = g_strjoinv (";", rec->options);
|
||||
g_string_append (str, p);
|
||||
g_free (p);
|
||||
|
||||
return g_string_free (str,FALSE);
|
||||
}
|
||||
|
||||
static XklConfigItem *
|
||||
xkl_config_item_copy (const XklConfigItem *item)
|
||||
{
|
||||
XklConfigItem *_item = xkl_config_item_new ();
|
||||
memcpy (_item->name,
|
||||
item->name,
|
||||
sizeof (item->name));
|
||||
memcpy (_item->short_description,
|
||||
item->short_description,
|
||||
sizeof (item->short_description));
|
||||
memcpy (_item->description,
|
||||
item->description,
|
||||
sizeof (item->description));
|
||||
return _item;
|
||||
}
|
||||
|
||||
static void
|
||||
prepend_item (XklConfigRegistry *registry,
|
||||
const XklConfigItem *item,
|
||||
gpointer data)
|
||||
{
|
||||
GSList **list = data;
|
||||
XklConfigItem *_item = xkl_config_item_copy (item);
|
||||
*list = g_slist_prepend (*list, _item);
|
||||
}
|
||||
|
||||
static gint
|
||||
compare_item_by_name (gconstpointer a, gconstpointer b)
|
||||
{
|
||||
const XklConfigItem *ia = a, *ib = b;
|
||||
return g_strcmp0 (ia->name, ib->name);
|
||||
}
|
||||
|
||||
GSList *
|
||||
eekboard_xkl_list_models (XklConfigRegistry *registry)
|
||||
{
|
||||
GSList *list = NULL;
|
||||
xkl_config_registry_foreach_model (registry, prepend_item, &list);
|
||||
return g_slist_sort (list, compare_item_by_name);
|
||||
}
|
||||
|
||||
GSList *
|
||||
eekboard_xkl_list_layouts (XklConfigRegistry *registry)
|
||||
{
|
||||
GSList *list = NULL;
|
||||
xkl_config_registry_foreach_layout (registry, prepend_item, &list);
|
||||
return g_slist_sort (list, compare_item_by_name);
|
||||
}
|
||||
|
||||
GSList *
|
||||
eekboard_xkl_list_option_groups (XklConfigRegistry *registry)
|
||||
{
|
||||
GSList *list = NULL;
|
||||
xkl_config_registry_foreach_option_group (registry, prepend_item, &list);
|
||||
return g_slist_sort (list, compare_item_by_name);
|
||||
}
|
||||
|
||||
GSList *
|
||||
eekboard_xkl_list_layout_variants (XklConfigRegistry *registry,
|
||||
const gchar *layout)
|
||||
{
|
||||
GSList *list = NULL;
|
||||
xkl_config_registry_foreach_layout_variant (registry,
|
||||
layout,
|
||||
prepend_item,
|
||||
&list);
|
||||
return g_slist_sort (list, compare_item_by_name);
|
||||
}
|
||||
|
||||
GSList *
|
||||
eekboard_xkl_list_options (XklConfigRegistry *registry,
|
||||
const gchar *group)
|
||||
{
|
||||
GSList *list = NULL;
|
||||
xkl_config_registry_foreach_option (registry, group, prepend_item, &list);
|
||||
return g_slist_sort (list, compare_item_by_name);
|
||||
}
|
||||
@ -1,39 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2011 Daiki Ueno <ueno@unixuser.org>
|
||||
* Copyright (C) 2011 Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public License
|
||||
* as published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
* 02110-1301 USA
|
||||
*/
|
||||
#ifndef EEKBOARD_XKLUTIL_H
|
||||
#define EEKBOARD_XKLUTIL_H 1
|
||||
|
||||
#include <libxklavier/xklavier.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
XklConfigRec *eekboard_xkl_config_rec_from_string (const gchar *layouts);
|
||||
gchar *eekboard_xkl_config_rec_to_string (XklConfigRec *rec);
|
||||
|
||||
GSList *eekboard_xkl_list_models (XklConfigRegistry *registry);
|
||||
GSList *eekboard_xkl_list_layouts (XklConfigRegistry *registry);
|
||||
GSList *eekboard_xkl_list_option_groups (XklConfigRegistry *registry);
|
||||
GSList *eekboard_xkl_list_layout_variants (XklConfigRegistry *registry,
|
||||
const gchar *layout);
|
||||
GSList *eekboard_xkl_list_options (XklConfigRegistry *registry,
|
||||
const gchar *group);
|
||||
|
||||
G_END_DECLS
|
||||
#endif /* EEKBOARD_XKLUTIL_H */
|
||||
@ -20,9 +20,9 @@
|
||||
/* This file is responsible for managing keycode data and emitting keycodes. */
|
||||
|
||||
#include "eekboard/key-emitter.h"
|
||||
#include "eekboard/keymap.h"
|
||||
|
||||
#include <gdk/gdk.h>
|
||||
#include <X11/XKBlib.h>
|
||||
|
||||
#include "eekboard/eekboard-context-service.h"
|
||||
|
||||
@ -39,98 +39,6 @@ typedef struct {
|
||||
} SeatEmitter;
|
||||
|
||||
|
||||
/* The following functions for keyboard mapping change are direct
|
||||
translation of the code in Caribou (in libcaribou/xadapter.vala):
|
||||
|
||||
- get_replaced_keycode (Caribou: get_reserved_keycode)
|
||||
- replace_keycode
|
||||
- get_keycode_from_gdk_keymap (Caribou: best_keycode_keyval_match)
|
||||
*/
|
||||
|
||||
/* Find an unused keycode where a keysym can be assigned. Restricted to Level 1 */
|
||||
static guint
|
||||
get_replaced_keycode (SeatEmitter *client)
|
||||
{
|
||||
guint keycode;
|
||||
return 0; // FIXME: no xkb allocated yet
|
||||
for (keycode = client->xkb->max_key_code;
|
||||
keycode >= client->xkb->min_key_code;
|
||||
--keycode) {
|
||||
guint offset = client->xkb->map->key_sym_map[keycode].offset;
|
||||
if (client->xkb->map->key_sym_map[keycode].kt_index[0] == XkbOneLevelIndex &&
|
||||
client->xkb->map->syms[offset] != NoSymbol) {
|
||||
return keycode;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Replace keysym assigned to KEYCODE to KEYSYM. Both args are used
|
||||
as in-out. If KEYCODE points to 0, this function picks a keycode
|
||||
from the current map and replace the associated keysym to KEYSYM.
|
||||
In that case, the replaced keycode is stored in KEYCODE and the old
|
||||
keysym is stored in KEYSYM. If otherwise (KEYCODE points to
|
||||
non-zero keycode), it simply changes the current map with the
|
||||
specified KEYCODE and KEYSYM. */
|
||||
static gboolean
|
||||
replace_keycode (SeatEmitter *emitter,
|
||||
guint keycode,
|
||||
guint *keysym)
|
||||
{
|
||||
/* GdkDisplay *display = gdk_display_get_default ();
|
||||
Display *xdisplay = GDK_DISPLAY_XDISPLAY (display);
|
||||
guint old_keysym;
|
||||
int keysyms_per_keycode;
|
||||
KeySym *syms;
|
||||
*/
|
||||
return TRUE; // FIXME: no xkb allocated at the moment, pretending all is fine
|
||||
g_return_val_if_fail (emitter->xkb->min_key_code <= keycode &&
|
||||
keycode <= emitter->xkb->max_key_code,
|
||||
FALSE);
|
||||
g_return_val_if_fail (keysym != NULL, FALSE);
|
||||
/*
|
||||
* Update keyboard mapping. Wayland receives keyboard mapping as a string, so XChangeKeyboardMapping needs to translate from the symbol tbale t the string. TODO.
|
||||
*
|
||||
syms = XGetKeyboardMapping (xdisplay, keycode, 1, &keysyms_per_keycode);
|
||||
old_keysym = syms[0];
|
||||
syms[0] = *keysym;
|
||||
XChangeKeyboardMapping (xdisplay, keycode, 1, syms, 1);
|
||||
XSync (xdisplay, False);
|
||||
XFree (syms);
|
||||
*keysym = old_keysym;
|
||||
*/
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
get_keycode_from_gdk_keymap (SeatEmitter *emitter,
|
||||
guint keysym,
|
||||
guint *keycode,
|
||||
guint *modifiers)
|
||||
{
|
||||
GdkKeymapKey *keys, *best_match = NULL;
|
||||
guint n_keys, i;
|
||||
|
||||
if (!squeek_keymap_get_entries_for_keyval (emitter->keymap, keysym, &keys, &n_keys))
|
||||
return FALSE;
|
||||
|
||||
for (i = 0; i < n_keys; i++)
|
||||
if ((guint)keys[i].group == emitter->group)
|
||||
best_match = &keys[i];
|
||||
|
||||
if (!best_match) {
|
||||
g_free (keys);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
*keycode = best_match->keycode;
|
||||
*modifiers = best_match->level == 1 ? EEK_SHIFT_MASK : 0;
|
||||
|
||||
g_free (keys);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
int send_virtual_keyboard_key(
|
||||
struct zwp_virtual_keyboard_v1 *keyboard,
|
||||
unsigned int keycode,
|
||||
@ -141,115 +49,6 @@ int send_virtual_keyboard_key(
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
send_fake_modifiers_events (SeatEmitter *emitter,
|
||||
EekModifierType modifiers,
|
||||
uint32_t timestamp)
|
||||
{
|
||||
(void)timestamp;
|
||||
|
||||
uint32_t proto_modifiers = 0;
|
||||
if (modifiers & EEK_SHIFT_MASK) {
|
||||
proto_modifiers |= 1<<MOD_IDX_SHIFT;
|
||||
}
|
||||
if (modifiers & EEK_CONTROL_MASK) {
|
||||
proto_modifiers |= 1<<MOD_IDX_CTRL;
|
||||
}
|
||||
if (modifiers & EEK_MOD1_MASK) {
|
||||
proto_modifiers |= 1<<MOD_IDX_ALT;
|
||||
}
|
||||
zwp_virtual_keyboard_v1_modifiers(emitter->virtual_keyboard, proto_modifiers, 0, 0, emitter->group);
|
||||
}
|
||||
|
||||
static void
|
||||
send_fake_key_event (SeatEmitter *emitter,
|
||||
guint xkeysym,
|
||||
guint keyboard_modifiers,
|
||||
gboolean pressed,
|
||||
uint32_t timestamp)
|
||||
{
|
||||
EekModifierType modifiers;
|
||||
guint old_keysym = xkeysym;
|
||||
|
||||
g_return_if_fail (xkeysym > 0);
|
||||
|
||||
guint keycode;
|
||||
if (!get_keycode_from_gdk_keymap (emitter, xkeysym, &keycode, &modifiers)) {
|
||||
keycode = get_replaced_keycode (emitter);
|
||||
if (keycode == 0) {
|
||||
g_warning ("no available keycode to replace");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!replace_keycode (emitter, keycode, &old_keysym)) {
|
||||
g_warning ("failed to lookup X keysym %X", xkeysym);
|
||||
return;
|
||||
}
|
||||
}
|
||||
/* Clear level shift modifiers */
|
||||
keyboard_modifiers &= (unsigned)~EEK_SHIFT_MASK;
|
||||
keyboard_modifiers &= (unsigned)~EEK_LOCK_MASK;
|
||||
/* FIXME: may need to remap ISO_Level3_Shift and NumLock */
|
||||
|
||||
modifiers |= keyboard_modifiers;
|
||||
|
||||
send_fake_modifiers_events (emitter, modifiers, timestamp);
|
||||
|
||||
// There's something magical about subtracting/adding 8 to keycodes for some reason
|
||||
send_virtual_keyboard_key (emitter->virtual_keyboard, keycode - 8, (unsigned)pressed, timestamp);
|
||||
send_fake_modifiers_events (emitter, modifiers, timestamp);
|
||||
|
||||
if (old_keysym != xkeysym)
|
||||
replace_keycode (emitter, keycode, &old_keysym);
|
||||
}
|
||||
|
||||
static void
|
||||
send_fake_key_events (SeatEmitter *emitter,
|
||||
EekSymbol *symbol,
|
||||
EekModifierType keyboard_modifiers,
|
||||
gboolean pressed,
|
||||
uint32_t timestamp)
|
||||
{
|
||||
/* Ignore modifier keys */
|
||||
if (eek_symbol_is_modifier (symbol))
|
||||
return;
|
||||
|
||||
/* If symbol is a text, convert chars in it to keysym */
|
||||
if (EEK_IS_TEXT(symbol)) {
|
||||
const gchar *utf8 = eek_text_get_text (EEK_TEXT(symbol));
|
||||
printf("Attempting to send text %s\n", utf8);
|
||||
/* FIXME:
|
||||
glong items_written;
|
||||
gunichar *ucs4 = g_utf8_to_ucs4_fast (utf8, -1, &items_written);
|
||||
gint i;
|
||||
|
||||
for (i = 0; i < items_written; i++) {
|
||||
guint xkeysym;
|
||||
EekKeysym *keysym;
|
||||
gchar *name;
|
||||
|
||||
name = g_strdup_printf ("U%04X", ucs4[i]);
|
||||
xkeysym = XStringToKeysym (name); // TODO: use xkb_get_keysym_from_name
|
||||
g_free (name);
|
||||
|
||||
keysym = eek_keysym_new (xkeysym);
|
||||
send_fake_key_events (client,
|
||||
EEK_SYMBOL(keysym),
|
||||
keyboard_modifiers);
|
||||
}
|
||||
g_free (ucs4);
|
||||
*/
|
||||
return;
|
||||
}
|
||||
|
||||
if (EEK_IS_KEYSYM(symbol)) {
|
||||
guint xkeysym = eek_keysym_get_xkeysym (EEK_KEYSYM(symbol));
|
||||
send_fake_key_event (emitter, xkeysym, keyboard_modifiers, pressed, timestamp);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Finds the first key code for each modifier and saves it in modifier_keycodes */
|
||||
static void
|
||||
update_modifier_info (SeatEmitter *client)
|
||||
@ -284,12 +83,25 @@ update_modifier_info (SeatEmitter *client)
|
||||
}*/
|
||||
}
|
||||
|
||||
static void
|
||||
send_fake_key (SeatEmitter *emitter,
|
||||
LevelKeyboard *keyboard,
|
||||
guint keycode,
|
||||
gboolean pressed,
|
||||
uint32_t timestamp)
|
||||
{
|
||||
guint level = keyboard->level;
|
||||
uint32_t group = (level / 2);
|
||||
|
||||
zwp_virtual_keyboard_v1_modifiers(emitter->virtual_keyboard, 0, 0, 0, group);
|
||||
send_virtual_keyboard_key (emitter->virtual_keyboard, keycode - 8, (unsigned)pressed, timestamp);
|
||||
zwp_virtual_keyboard_v1_modifiers(emitter->virtual_keyboard, 0, 0, 0, group);
|
||||
}
|
||||
|
||||
void
|
||||
emit_key_activated (EekboardContextService *manager,
|
||||
EekKeyboard *keyboard,
|
||||
LevelKeyboard *keyboard,
|
||||
guint keycode,
|
||||
EekSymbol *symbol,
|
||||
EekModifierType modifiers,
|
||||
gboolean pressed,
|
||||
uint32_t timestamp)
|
||||
{
|
||||
@ -324,5 +136,5 @@ emit_key_activated (EekboardContextService *manager,
|
||||
emitter.virtual_keyboard = manager->virtual_keyboard;
|
||||
emitter.keymap = keyboard->keymap;
|
||||
update_modifier_info (&emitter);
|
||||
send_fake_key_events (&emitter, symbol, modifiers, pressed, timestamp);
|
||||
send_fake_key (&emitter, keyboard, keycode, pressed, timestamp);
|
||||
}
|
||||
|
||||
@ -3,7 +3,6 @@
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <glib.h>
|
||||
#include <X11/XKBlib.h>
|
||||
|
||||
#include "eek/eek.h"
|
||||
|
||||
@ -40,9 +39,7 @@ enum mod_indices {
|
||||
};
|
||||
|
||||
void
|
||||
emit_key_activated (EekboardContextService *manager, EekKeyboard *keyboard,
|
||||
emit_key_activated (EekboardContextService *manager, LevelKeyboard *keyboard,
|
||||
guint keycode,
|
||||
EekSymbol *symbol,
|
||||
guint modifiers,
|
||||
gboolean pressed, uint32_t timestamp);
|
||||
#endif // KEYEMITTER_H
|
||||
|
||||
@ -1,66 +0,0 @@
|
||||
/* GDK - The GIMP Drawing Kit
|
||||
* Copyright (C) 2000 Red Hat, Inc.
|
||||
* Copyright (C) 2019 Purism, SPC
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
/*
|
||||
* Modified for squeekboard based on GTK
|
||||
*/
|
||||
|
||||
#include "keymap.h"
|
||||
|
||||
gboolean
|
||||
squeek_keymap_get_entries_for_keyval (struct xkb_keymap *xkb_keymap,
|
||||
guint keyval,
|
||||
GdkKeymapKey **keys,
|
||||
guint *n_keys)
|
||||
{
|
||||
GArray *retval;
|
||||
guint keycode;
|
||||
xkb_keycode_t min_keycode, max_keycode;
|
||||
retval = g_array_new (FALSE, FALSE, sizeof (GdkKeymapKey));
|
||||
min_keycode = xkb_keymap_min_keycode (xkb_keymap);
|
||||
max_keycode = xkb_keymap_max_keycode (xkb_keymap);
|
||||
for (keycode = min_keycode; keycode < max_keycode; keycode++)
|
||||
{
|
||||
xkb_layout_index_t num_layouts, layout;
|
||||
num_layouts = xkb_keymap_num_layouts_for_key (xkb_keymap, keycode);
|
||||
for (layout = 0; layout < num_layouts; layout++)
|
||||
{
|
||||
xkb_layout_index_t num_levels, level;
|
||||
num_levels = xkb_keymap_num_levels_for_key (xkb_keymap, keycode, layout);
|
||||
for (level = 0; level < num_levels; level++)
|
||||
{
|
||||
const xkb_keysym_t *syms;
|
||||
gint num_syms, sym;
|
||||
num_syms = xkb_keymap_key_get_syms_by_level (xkb_keymap, keycode, layout, level, &syms);
|
||||
for (sym = 0; sym < num_syms; sym++)
|
||||
{
|
||||
if (syms[sym] == keyval)
|
||||
{
|
||||
GdkKeymapKey key;
|
||||
key.keycode = keycode;
|
||||
key.group = (gint)layout;
|
||||
key.level = (gint)level;
|
||||
g_array_append_val (retval, key);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
*n_keys = retval->len;
|
||||
*keys = (GdkKeymapKey*) g_array_free (retval, FALSE);
|
||||
return TRUE;
|
||||
}
|
||||
@ -1,8 +0,0 @@
|
||||
#include <gdk/gdk.h>
|
||||
#include <xkbcommon/xkbcommon.h>
|
||||
|
||||
gboolean
|
||||
squeek_keymap_get_entries_for_keyval (struct xkb_keymap *xkb_keymap,
|
||||
guint keyval,
|
||||
GdkKeymapKey **keys,
|
||||
guint *n_keys);
|
||||
32
meson.build
32
meson.build
@ -3,12 +3,29 @@ project(
|
||||
'c', 'rust',
|
||||
version: '1.0.10',
|
||||
license: 'GPLv3',
|
||||
meson_version: '>=0.43.0',
|
||||
default_options: [ 'warning_level=1', 'buildtype=debugoptimized', 'c_std=gnu11' ],
|
||||
meson_version: '>=0.49.0',
|
||||
default_options: [
|
||||
'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',
|
||||
'-Werror=incompatible-pointer-types',
|
||||
],
|
||||
language: 'c'
|
||||
)
|
||||
|
||||
i18n = import('i18n')
|
||||
|
||||
conf_data = configuration_data()
|
||||
|
||||
if get_option('buildtype').startswith('debug')
|
||||
add_project_arguments('-DDEBUG=1', language : 'c')
|
||||
endif
|
||||
@ -26,8 +43,19 @@ else
|
||||
endif
|
||||
dbusdir = join_paths(depdatadir, 'dbus-1/interfaces')
|
||||
|
||||
summary = [
|
||||
'',
|
||||
'------------------',
|
||||
'squeekboard @0@'.format(meson.project_version()),
|
||||
'',
|
||||
'------------------',
|
||||
''
|
||||
]
|
||||
message('\n'.join(summary))
|
||||
|
||||
subdir('data')
|
||||
subdir('protocols')
|
||||
subdir('eek')
|
||||
subdir('src')
|
||||
subdir('po')
|
||||
subdir('tests')
|
||||
|
||||
@ -1 +1,8 @@
|
||||
option('depdatadir', type : 'string', value : '', description : 'System data path. Will be searched for definitions instead of datadir when provided')
|
||||
option('depdatadir',
|
||||
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,6 +14,7 @@ wl_protos = [
|
||||
'wlr-layer-shell-unstable-v1.xml',
|
||||
'virtual-keyboard-unstable-v1.xml',
|
||||
'input-method-unstable-v2.xml',
|
||||
'text-input-unstable-v3.xml'
|
||||
]
|
||||
wl_proto_sources = []
|
||||
foreach proto: wl_protos
|
||||
|
||||
441
protocols/text-input-unstable-v3.xml
Normal file
441
protocols/text-input-unstable-v3.xml
Normal file
@ -0,0 +1,441 @@
|
||||
<?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
Normal file
1350
src/bitflags.rs
Normal file
File diff suppressed because it is too large
Load Diff
4
src/config.h.in
Normal file
4
src/config.h.in
Normal file
@ -0,0 +1,4 @@
|
||||
/*
|
||||
* Autogenerated by the Meson build system.
|
||||
* Do not edit, your changes will be lost.
|
||||
*/
|
||||
141
src/float_ord.rs
Normal file
141
src/float_ord.rs
Normal file
@ -0,0 +1,141 @@
|
||||
//! Order floating point numbers, into this ordering:
|
||||
//!
|
||||
//! NaN | -Infinity | x < 0 | -0 | +0 | x > 0 | +Infinity | NaN
|
||||
|
||||
/* Adapted from https://github.com/notriddle/rust-float-ord revision e995165f
|
||||
* maintained by Michael Howell <michael@notriddle.com>
|
||||
* licensed under MIT / Apache-2.0 licenses
|
||||
*/
|
||||
|
||||
extern crate core;
|
||||
|
||||
use ::float_ord::core::cmp::{Eq, Ord, Ordering, PartialEq, PartialOrd};
|
||||
use ::float_ord::core::hash::{Hash, Hasher};
|
||||
use ::float_ord::core::mem::transmute;
|
||||
|
||||
/// A wrapper for floats, that implements total equality and ordering
|
||||
/// and hashing.
|
||||
#[derive(Clone, Copy)]
|
||||
pub struct FloatOrd<T>(pub T);
|
||||
|
||||
macro_rules! float_ord_impl {
|
||||
($f:ident, $i:ident, $n:expr) => {
|
||||
impl FloatOrd<$f> {
|
||||
fn convert(self) -> $i {
|
||||
let u = unsafe { transmute::<$f, $i>(self.0) };
|
||||
let bit = 1 << ($n - 1);
|
||||
if u & bit == 0 {
|
||||
u | bit
|
||||
} else {
|
||||
!u
|
||||
}
|
||||
}
|
||||
}
|
||||
impl PartialEq for FloatOrd<$f> {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.convert() == other.convert()
|
||||
}
|
||||
}
|
||||
impl Eq for FloatOrd<$f> {}
|
||||
impl PartialOrd for FloatOrd<$f> {
|
||||
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
|
||||
self.convert().partial_cmp(&other.convert())
|
||||
}
|
||||
}
|
||||
impl Ord for FloatOrd<$f> {
|
||||
fn cmp(&self, other: &Self) -> Ordering {
|
||||
self.convert().cmp(&other.convert())
|
||||
}
|
||||
}
|
||||
impl Hash for FloatOrd<$f> {
|
||||
fn hash<H: Hasher>(&self, state: &mut H) {
|
||||
self.convert().hash(state);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
float_ord_impl!(f32, u32, 32);
|
||||
float_ord_impl!(f64, u64, 64);
|
||||
|
||||
/// Sort a slice of floats.
|
||||
///
|
||||
/// # Allocation behavior
|
||||
///
|
||||
/// This routine uses a quicksort implementation that does not heap allocate.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
/// let mut v = [-5.0, 4.0, 1.0, -3.0, 2.0];
|
||||
///
|
||||
/// float_ord::sort(&mut v);
|
||||
/// assert!(v == [-5.0, -3.0, 1.0, 2.0, 4.0]);
|
||||
/// ```
|
||||
#[allow(dead_code)]
|
||||
pub fn sort<T>(v: &mut [T]) where FloatOrd<T>: Ord {
|
||||
let v_: &mut [FloatOrd<T>] = unsafe { transmute(v) };
|
||||
v_.sort_unstable();
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
extern crate std;
|
||||
|
||||
use self::std::collections::hash_map::DefaultHasher;
|
||||
use self::std::hash::{Hash, Hasher};
|
||||
use super::FloatOrd;
|
||||
|
||||
#[test]
|
||||
fn test_ord() {
|
||||
assert!(FloatOrd(1.0f64) < FloatOrd(2.0f64));
|
||||
assert!(FloatOrd(2.0f32) > FloatOrd(1.0f32));
|
||||
assert!(FloatOrd(1.0f64) == FloatOrd(1.0f64));
|
||||
assert!(FloatOrd(1.0f32) == FloatOrd(1.0f32));
|
||||
assert!(FloatOrd(0.0f64) > FloatOrd(-0.0f64));
|
||||
assert!(FloatOrd(0.0f32) > FloatOrd(-0.0f32));
|
||||
assert!(FloatOrd(::float_ord::core::f64::NAN) == FloatOrd(::float_ord::core::f64::NAN));
|
||||
assert!(FloatOrd(::float_ord::core::f32::NAN) == FloatOrd(::float_ord::core::f32::NAN));
|
||||
assert!(FloatOrd(-::float_ord::core::f64::NAN) < FloatOrd(::float_ord::core::f64::NAN));
|
||||
assert!(FloatOrd(-::float_ord::core::f32::NAN) < FloatOrd(::float_ord::core::f32::NAN));
|
||||
assert!(FloatOrd(-::float_ord::core::f64::INFINITY) < FloatOrd(::float_ord::core::f64::INFINITY));
|
||||
assert!(FloatOrd(-::float_ord::core::f32::INFINITY) < FloatOrd(::float_ord::core::f32::INFINITY));
|
||||
assert!(FloatOrd(::float_ord::core::f64::INFINITY) < FloatOrd(::float_ord::core::f64::NAN));
|
||||
assert!(FloatOrd(::float_ord::core::f32::INFINITY) < FloatOrd(::float_ord::core::f32::NAN));
|
||||
assert!(FloatOrd(-::float_ord::core::f64::NAN) < FloatOrd(::float_ord::core::f64::INFINITY));
|
||||
assert!(FloatOrd(-::float_ord::core::f32::NAN) < FloatOrd(::float_ord::core::f32::INFINITY));
|
||||
}
|
||||
|
||||
fn hash<F: Hash>(f: F) -> u64 {
|
||||
let mut hasher = DefaultHasher::new();
|
||||
f.hash(&mut hasher);
|
||||
hasher.finish()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_hash() {
|
||||
assert_ne!(hash(FloatOrd(0.0f64)), hash(FloatOrd(-0.0f64)));
|
||||
assert_ne!(hash(FloatOrd(0.0f32)), hash(FloatOrd(-0.0f32)));
|
||||
assert_eq!(hash(FloatOrd(-0.0f64)), hash(FloatOrd(-0.0f64)));
|
||||
assert_eq!(hash(FloatOrd(0.0f32)), hash(FloatOrd(0.0f32)));
|
||||
assert_ne!(hash(FloatOrd(::float_ord::core::f64::NAN)), hash(FloatOrd(-::float_ord::core::f64::NAN)));
|
||||
assert_ne!(hash(FloatOrd(::float_ord::core::f32::NAN)), hash(FloatOrd(-::float_ord::core::f32::NAN)));
|
||||
assert_eq!(hash(FloatOrd(::float_ord::core::f64::NAN)), hash(FloatOrd(::float_ord::core::f64::NAN)));
|
||||
assert_eq!(hash(FloatOrd(-::float_ord::core::f32::NAN)), hash(FloatOrd(-::float_ord::core::f32::NAN)));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_sort_nan() {
|
||||
let nan = ::float_ord::core::f64::NAN;
|
||||
let mut v = [-1.0, 5.0, 0.0, -0.0, nan, 1.5, nan, 3.7];
|
||||
super::sort(&mut v);
|
||||
assert!(v[0] == -1.0);
|
||||
assert!(v[1] == 0.0 && v[1].is_sign_negative());
|
||||
assert!(v[2] == 0.0 && !v[2].is_sign_negative());
|
||||
assert!(v[3] == 1.5);
|
||||
assert!(v[4] == 3.7);
|
||||
assert!(v[5] == 5.0);
|
||||
assert!(v[6].is_nan());
|
||||
assert!(v[7].is_nan());
|
||||
}
|
||||
}
|
||||
@ -5,11 +5,6 @@
|
||||
#include "eekboard/eekboard-context-service.h"
|
||||
|
||||
|
||||
void imservice_handle_text_change_cause(void *data, struct zwp_input_method_v2 *input_method, uint32_t cause) {}
|
||||
void imservice_handle_content_type(void *data, struct zwp_input_method_v2 *input_method, uint32_t hint, uint32_t purpose) {}
|
||||
void imservice_handle_unavailable(void *data, struct zwp_input_method_v2 *input_method) {}
|
||||
|
||||
|
||||
static const struct zwp_input_method_v2_listener input_method_listener = {
|
||||
.activate = imservice_handle_input_method_activate,
|
||||
.deactivate = imservice_handle_input_method_deactivate,
|
||||
@ -25,19 +20,24 @@ struct imservice* get_imservice(EekboardContextService *context,
|
||||
struct wl_seat *seat) {
|
||||
struct zwp_input_method_v2 *im = zwp_input_method_manager_v2_get_input_method(manager, seat);
|
||||
struct imservice *imservice = imservice_new(im, context);
|
||||
zwp_input_method_v2_add_listener(im,
|
||||
&input_method_listener, imservice);
|
||||
|
||||
/* Add a listener, passing the imservice instance to make it available to
|
||||
callbacks. */
|
||||
zwp_input_method_v2_add_listener(im, &input_method_listener, imservice);
|
||||
|
||||
return imservice;
|
||||
}
|
||||
|
||||
void imservice_make_visible(EekboardContextService *context,
|
||||
struct zwp_input_method_v2 *im) {
|
||||
(void)im;
|
||||
void imservice_make_visible(EekboardContextService *context) {
|
||||
eekboard_context_service_show_keyboard (context);
|
||||
}
|
||||
|
||||
void imservice_try_hide(EekboardContextService *context,
|
||||
struct zwp_input_method_v2 *im) {
|
||||
(void)im;
|
||||
void imservice_try_hide(EekboardContextService *context) {
|
||||
eekboard_context_service_hide_keyboard (context);
|
||||
}
|
||||
|
||||
/// Declared explicitly because _destroy is inline,
|
||||
/// making it unavailable in Rust
|
||||
void imservice_destroy_im(struct zwp_input_method_v2 *im) {
|
||||
zwp_input_method_v2_destroy(im);
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user