Compare commits
	
		
			7 Commits
		
	
	
		
			v1.2.1
			...
			add-more-p
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 2c355ec966 | |||
| a19bbdc870 | |||
| 8e0b4f05f8 | |||
| 1010b916ef | |||
| c475ed6619 | |||
| 687b260e29 | |||
| ecc46733da | 
@ -9,10 +9,6 @@ stages:
 | 
			
		||||
    - librem5
 | 
			
		||||
 | 
			
		||||
before_script:
 | 
			
		||||
  - apt-get -y update
 | 
			
		||||
  - apt-get -y install wget ca-certificates gnupg
 | 
			
		||||
  - echo "deb http://ci.puri.sm/ scratch librem5" > /etc/apt/sources.list.d/ci.list
 | 
			
		||||
  - wget -O- https://ci.puri.sm/ci-repo.key | apt-key add -
 | 
			
		||||
  - apt-get -y update
 | 
			
		||||
  - apt-get -y build-dep .
 | 
			
		||||
 | 
			
		||||
@ -26,26 +22,6 @@ build_meson:
 | 
			
		||||
    - meson . _build/ -Ddepdatadir=/usr/share
 | 
			
		||||
    - ninja -C _build install
 | 
			
		||||
 | 
			
		||||
build_deb:
 | 
			
		||||
    <<: *tags
 | 
			
		||||
    stage: build
 | 
			
		||||
    artifacts:
 | 
			
		||||
      paths:
 | 
			
		||||
        - "*.deb"
 | 
			
		||||
    script:
 | 
			
		||||
        - apt-get -y install devscripts
 | 
			
		||||
        - debuild -i -us -uc -b
 | 
			
		||||
        - cp ../*.deb .
 | 
			
		||||
 | 
			
		||||
test_lintian:
 | 
			
		||||
    <<: *tags
 | 
			
		||||
    stage: test
 | 
			
		||||
    dependencies:
 | 
			
		||||
        - build_deb
 | 
			
		||||
    script:
 | 
			
		||||
        - apt-get -y install lintian
 | 
			
		||||
        - lintian *.deb
 | 
			
		||||
 | 
			
		||||
test:
 | 
			
		||||
  <<: *tags
 | 
			
		||||
  stage: test
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										162
									
								
								Cargo.lock
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										162
									
								
								Cargo.lock
									
									
									
										generated
									
									
									
								
							@ -1,162 +0,0 @@
 | 
			
		||||
# This file is automatically @generated by Cargo.
 | 
			
		||||
# It is not intended for manual editing.
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "bitflags"
 | 
			
		||||
version = "1.0.4"
 | 
			
		||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "dtoa"
 | 
			
		||||
version = "0.4.4"
 | 
			
		||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "libc"
 | 
			
		||||
version = "0.2.62"
 | 
			
		||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "linked-hash-map"
 | 
			
		||||
version = "0.5.2"
 | 
			
		||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "maplit"
 | 
			
		||||
version = "1.0.2"
 | 
			
		||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "memmap"
 | 
			
		||||
version = "0.7.0"
 | 
			
		||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
			
		||||
dependencies = [
 | 
			
		||||
 "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)",
 | 
			
		||||
 "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "proc-macro2"
 | 
			
		||||
version = "1.0.4"
 | 
			
		||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
			
		||||
dependencies = [
 | 
			
		||||
 "unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "quote"
 | 
			
		||||
version = "1.0.2"
 | 
			
		||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
			
		||||
dependencies = [
 | 
			
		||||
 "proc-macro2 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "rs"
 | 
			
		||||
version = "0.1.0"
 | 
			
		||||
dependencies = [
 | 
			
		||||
 "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
 | 
			
		||||
 "maplit 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
 | 
			
		||||
 "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)",
 | 
			
		||||
 "serde_yaml 0.8.9 (registry+https://github.com/rust-lang/crates.io-index)",
 | 
			
		||||
 "xkbcommon 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "serde"
 | 
			
		||||
version = "1.0.101"
 | 
			
		||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
			
		||||
dependencies = [
 | 
			
		||||
 "serde_derive 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)",
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "serde_derive"
 | 
			
		||||
version = "1.0.101"
 | 
			
		||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
			
		||||
dependencies = [
 | 
			
		||||
 "proc-macro2 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
 | 
			
		||||
 "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
 | 
			
		||||
 "syn 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "serde_yaml"
 | 
			
		||||
version = "0.8.9"
 | 
			
		||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
			
		||||
dependencies = [
 | 
			
		||||
 "dtoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)",
 | 
			
		||||
 "linked-hash-map 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
 | 
			
		||||
 "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)",
 | 
			
		||||
 "yaml-rust 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "syn"
 | 
			
		||||
version = "1.0.5"
 | 
			
		||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
			
		||||
dependencies = [
 | 
			
		||||
 "proc-macro2 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
 | 
			
		||||
 "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
 | 
			
		||||
 "unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "unicode-xid"
 | 
			
		||||
version = "0.2.0"
 | 
			
		||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "winapi"
 | 
			
		||||
version = "0.3.8"
 | 
			
		||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
			
		||||
dependencies = [
 | 
			
		||||
 "winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
 | 
			
		||||
 "winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "winapi-i686-pc-windows-gnu"
 | 
			
		||||
version = "0.4.0"
 | 
			
		||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "winapi-x86_64-pc-windows-gnu"
 | 
			
		||||
version = "0.4.0"
 | 
			
		||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "xkbcommon"
 | 
			
		||||
version = "0.4.0"
 | 
			
		||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
			
		||||
dependencies = [
 | 
			
		||||
 "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)",
 | 
			
		||||
 "memmap 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "yaml-rust"
 | 
			
		||||
version = "0.4.3"
 | 
			
		||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
			
		||||
dependencies = [
 | 
			
		||||
 "linked-hash-map 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
[metadata]
 | 
			
		||||
"checksum bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "228047a76f468627ca71776ecdebd732a3423081fcf5125585bcd7c49886ce12"
 | 
			
		||||
"checksum dtoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "ea57b42383d091c85abcc2706240b94ab2a8fa1fc81c10ff23c4de06e2a90b5e"
 | 
			
		||||
"checksum libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)" = "34fcd2c08d2f832f376f4173a231990fa5aef4e99fb569867318a227ef4c06ba"
 | 
			
		||||
"checksum linked-hash-map 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "ae91b68aebc4ddb91978b11a1b02ddd8602a05ec19002801c5666000e05e0f83"
 | 
			
		||||
"checksum maplit 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "3e2e65a1a2e43cfcb47a895c4c8b10d1f4a61097f9f254f183aee60cad9c651d"
 | 
			
		||||
"checksum memmap 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6585fd95e7bb50d6cc31e20d4cf9afb4e2ba16c5846fc76793f11218da9c475b"
 | 
			
		||||
"checksum proc-macro2 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "afdc77cc74ec70ed262262942ebb7dac3d479e9e5cfa2da1841c0806f6cdabcc"
 | 
			
		||||
"checksum quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "053a8c8bcc71fcce321828dc897a98ab9760bef03a4fc36693c231e5b3216cfe"
 | 
			
		||||
"checksum serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)" = "9796c9b7ba2ffe7a9ce53c2287dfc48080f4b2b362fcc245a259b3a7201119dd"
 | 
			
		||||
"checksum serde_derive 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)" = "4b133a43a1ecd55d4086bd5b4dc6c1751c68b1bfbeba7a5040442022c7e7c02e"
 | 
			
		||||
"checksum serde_yaml 0.8.9 (registry+https://github.com/rust-lang/crates.io-index)" = "38b08a9a90e5260fe01c6480ec7c811606df6d3a660415808c3c3fa8ed95b582"
 | 
			
		||||
"checksum syn 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "66850e97125af79138385e9b88339cbcd037e3f28ceab8c5ad98e64f0f1f80bf"
 | 
			
		||||
"checksum unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c"
 | 
			
		||||
"checksum winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "8093091eeb260906a183e6ae1abdba2ef5ef2257a21801128899c3fc699229c6"
 | 
			
		||||
"checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
 | 
			
		||||
"checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
 | 
			
		||||
"checksum xkbcommon 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fda0ea5f7ddabd51deeeda7799bee06274112f577da7dd3d954b8eda731b2fce"
 | 
			
		||||
"checksum yaml-rust 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "65923dd1784f44da1d2c3dbbc5e822045628c590ba72123e1c73d3c230c4434d"
 | 
			
		||||
							
								
								
									
										15
									
								
								Cargo.toml
									
									
									
									
									
								
							
							
						
						
									
										15
									
								
								Cargo.toml
									
									
									
									
									
								
							@ -1,15 +0,0 @@
 | 
			
		||||
[package]
 | 
			
		||||
name = "rs"
 | 
			
		||||
version = "0.1.0"
 | 
			
		||||
 | 
			
		||||
[dependencies]
 | 
			
		||||
bitflags = "1.0.*"
 | 
			
		||||
maplit = "1.0.*"
 | 
			
		||||
serde = { version = "1.0.*", features = ["derive"] }
 | 
			
		||||
serde_yaml = "0.8.*"
 | 
			
		||||
xkbcommon = { version = "0.4.*", features = ["wayland"] }
 | 
			
		||||
 | 
			
		||||
[lib]
 | 
			
		||||
name = "rs"
 | 
			
		||||
path = "src/lib.rs"
 | 
			
		||||
crate-type = ["staticlib", "rlib"]
 | 
			
		||||
							
								
								
									
										58
									
								
								HACKING.md
									
									
									
									
									
								
							
							
						
						
									
										58
									
								
								HACKING.md
									
									
									
									
									
								
							@ -1,58 +0,0 @@
 | 
			
		||||
Hacking
 | 
			
		||||
=======
 | 
			
		||||
 | 
			
		||||
This document describes the standards for modifying and maintaining the *squeekboard* project.
 | 
			
		||||
 | 
			
		||||
Testing
 | 
			
		||||
-------
 | 
			
		||||
 | 
			
		||||
Most common testing is done in CI. Occasionally, and for each release, do perform manual tests to make sure that
 | 
			
		||||
 | 
			
		||||
- the application draws correctly
 | 
			
		||||
- it shows when relevant
 | 
			
		||||
- it changes layouts
 | 
			
		||||
- it changes levels
 | 
			
		||||
 | 
			
		||||
Testing with an application:
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
python3 tests/entry.py
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
Testing visibility:
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
$ busctl call --user sm.puri.OSK0 /sm/puri/OSK0 sm.puri.OSK0 SetVisible b true
 | 
			
		||||
$ busctl call --user sm.puri.OSK0 /sm/puri/OSK0 sm.puri.OSK0 SetVisible b false
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
Testing layouts:
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
$ gsettings set org.gnome.desktop.input-sources sources "[('xkb', 'us'), ('xkb', 'ua')]"
 | 
			
		||||
$ gsettings set org.gnome.desktop.input-sources current 1
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
Maintenance
 | 
			
		||||
-----------
 | 
			
		||||
 | 
			
		||||
Squeekboard uses Rust & Cargo for some of its dependencies.
 | 
			
		||||
 | 
			
		||||
Use the `cargo.sh` script for maintaining the Cargo part of the build. The script takes the usual Cargo commands, after the first 2 positionsl arguments: source directory, and output artifact. So, `cargo test` becomes:
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
cd build_dir
 | 
			
		||||
sh /source_path/cargo.sh '' test
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
### Cargo dependencies
 | 
			
		||||
 | 
			
		||||
Dependencies must be specified in `Cargo.toml` with 2 numbers: "major.minor". Since bugfix version number is meant to not affect the interface, this allows for safe updates.
 | 
			
		||||
 | 
			
		||||
`Cargo.lock` is used for remembering the revisions of all Rust dependencies. It should be updated often, preferably with each bugfix revision, and in a commit on its own:
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
cd build_dir
 | 
			
		||||
sh /source_path/cargo.sh '' update
 | 
			
		||||
ninja test
 | 
			
		||||
```
 | 
			
		||||
							
								
								
									
										29
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										29
									
								
								README.md
									
									
									
									
									
								
							@ -3,18 +3,14 @@
 | 
			
		||||
 | 
			
		||||
*Squeekboard* is a virtual keyboard supporting Wayland, built primarily for the *Librem 5* phone.
 | 
			
		||||
 | 
			
		||||
It squeaks because some Rust got inside.
 | 
			
		||||
 | 
			
		||||
Features
 | 
			
		||||
--------
 | 
			
		||||
 | 
			
		||||
### Present
 | 
			
		||||
 | 
			
		||||
- GTK3
 | 
			
		||||
- Custom yaml-defined keyboards
 | 
			
		||||
- Custom xml-defined keyboards
 | 
			
		||||
- DBus interface to show and hide
 | 
			
		||||
- Use Wayland input method protocol to show and hide
 | 
			
		||||
- Use Wayland virtual keyboard protocol
 | 
			
		||||
 | 
			
		||||
### Temporarily dropped
 | 
			
		||||
 | 
			
		||||
@ -22,6 +18,8 @@ Features
 | 
			
		||||
 | 
			
		||||
### TODO
 | 
			
		||||
 | 
			
		||||
- Use Wayland virtual keyboard protocol
 | 
			
		||||
- Use Wayland text input protocol
 | 
			
		||||
- Use Wayland input method protocol
 | 
			
		||||
- Pick up DBus interface files from /usr/share
 | 
			
		||||
 | 
			
		||||
@ -40,20 +38,31 @@ $ cd squeekboard
 | 
			
		||||
$ mkdir ../build
 | 
			
		||||
$ meson ../build/
 | 
			
		||||
$ cd ../build
 | 
			
		||||
$ ninja test
 | 
			
		||||
$ ninja install
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
For development, alter the `meson` call:
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
$ meson ../build/ --prefix=../install
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
and don't skip `ninja install` before running. The last step is necessary in order to find the keyboard definition files.
 | 
			
		||||
 | 
			
		||||
Running
 | 
			
		||||
-------
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
$ phoc # if no compatible Wayland compositor is running yet
 | 
			
		||||
$ rootston
 | 
			
		||||
$ cd ../build/
 | 
			
		||||
$ src/squeekboard
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
Developing
 | 
			
		||||
----------
 | 
			
		||||
### Testing
 | 
			
		||||
 | 
			
		||||
See `HACKING.md`
 | 
			
		||||
```
 | 
			
		||||
$ busctl call --user sm.puri.OSK0 /sm/puri/OSK0 sm.puri.OSK0 SetVisible b true
 | 
			
		||||
$ busctl call --user sm.puri.OSK0 /sm/puri/OSK0 sm.puri.OSK0 SetVisible b false
 | 
			
		||||
$ gsettings set org.gnome.desktop.input-sources sources "[('xkb', 'us'), ('xkb', 'ua')]"
 | 
			
		||||
$ gsettings set org.gnome.desktop.input-sources current 1
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										1
									
								
								bindings/vala/Eek-0.90.metadata
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								bindings/vala/Eek-0.90.metadata
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1 @@
 | 
			
		||||
Eek cheader_filename="eek/eek.h"
 | 
			
		||||
							
								
								
									
										1
									
								
								bindings/vala/EekGtk-0.90.metadata
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								bindings/vala/EekGtk-0.90.metadata
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1 @@
 | 
			
		||||
EekGtk cheader_filename="eek/eek-gtk.h"
 | 
			
		||||
							
								
								
									
										1
									
								
								bindings/vala/EekXkl-0.90.metadata
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								bindings/vala/EekXkl-0.90.metadata
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1 @@
 | 
			
		||||
EekXkl cheader_filename="eek/eek-xkl.h"
 | 
			
		||||
							
								
								
									
										1
									
								
								bindings/vala/eek-0.90.deps
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								bindings/vala/eek-0.90.deps
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1 @@
 | 
			
		||||
gio-2.0
 | 
			
		||||
							
								
								
									
										1
									
								
								bindings/vala/eek-gtk-0.90.deps
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								bindings/vala/eek-gtk-0.90.deps
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1 @@
 | 
			
		||||
eek-0.90
 | 
			
		||||
							
								
								
									
										2
									
								
								bindings/vala/eek-xkl-0.90.deps
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								bindings/vala/eek-xkl-0.90.deps
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,2 @@
 | 
			
		||||
eek-0.90
 | 
			
		||||
x11
 | 
			
		||||
							
								
								
									
										24
									
								
								cargo.sh
									
									
									
									
									
								
							
							
						
						
									
										24
									
								
								cargo.sh
									
									
									
									
									
								
							@ -1,24 +0,0 @@
 | 
			
		||||
#!/bin/sh
 | 
			
		||||
 | 
			
		||||
# This script manages Cargo operations
 | 
			
		||||
# while keeping the artifact directory within the build tree
 | 
			
		||||
# instead of the source tree
 | 
			
		||||
 | 
			
		||||
set -e
 | 
			
		||||
 | 
			
		||||
SCRIPT_PATH="$(realpath "$0")"
 | 
			
		||||
SOURCE_DIR="$(dirname "$SCRIPT_PATH")"
 | 
			
		||||
 | 
			
		||||
CARGO_TARGET_DIR="$(pwd)"
 | 
			
		||||
export CARGO_TARGET_DIR
 | 
			
		||||
if [ -n "${1}" ]; then
 | 
			
		||||
    OUT_PATH="$(realpath "$1")"
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
cd "$SOURCE_DIR"
 | 
			
		||||
shift
 | 
			
		||||
cargo "$@"
 | 
			
		||||
 | 
			
		||||
if [ -n "${OUT_PATH}" ]; then
 | 
			
		||||
    cp "${CARGO_TARGET_DIR}"/debug/librs.a "${OUT_PATH}"
 | 
			
		||||
fi
 | 
			
		||||
@ -1,197 +0,0 @@
 | 
			
		||||
# Greek layout created by Antonis Tsolomitis
 | 
			
		||||
# University of the Aegean, Department of Mathematics, atsol@aegean.gr
 | 
			
		||||
# Sep 2019
 | 
			
		||||
---
 | 
			
		||||
row_spacing: 11.33
 | 
			
		||||
button_spacing: 4.67
 | 
			
		||||
 | 
			
		||||
bounds: { x: 0, y: 6.33, width: 426, height: 250 }
 | 
			
		||||
 | 
			
		||||
outlines:
 | 
			
		||||
    default:
 | 
			
		||||
        bounds: { x: 0, y: 0, width: 32, height: 52 }
 | 
			
		||||
    altline:
 | 
			
		||||
        bounds: { x: 0, y: 0, width: 48.39024, height: 52 }
 | 
			
		||||
    outline7:
 | 
			
		||||
        bounds: { x: 0, y: 0, width: 88.97561, height: 52 }
 | 
			
		||||
    spaceline:
 | 
			
		||||
        bounds: { x: 0, y: 0, width: 150.5853, height: 52 }
 | 
			
		||||
 | 
			
		||||
views:
 | 
			
		||||
    base:
 | 
			
		||||
        - "; ς ε ρ τ υ θ ι ο π !"
 | 
			
		||||
        - "α σ δ φ γ η ξ κ λ show_accented"
 | 
			
		||||
        - "Shift_L ζ χ ψ ω β ν μ , BackSpace"
 | 
			
		||||
        - "show_numbers preferences space . Return"
 | 
			
		||||
    upper:
 | 
			
		||||
        - ": EuroSign Ε Ρ Τ Υ Θ Ι Ο Π"
 | 
			
		||||
        - "Α Σ Δ Φ Γ Η Ξ Κ Λ show_accented"
 | 
			
		||||
        - "Shift_L Ζ Χ Ψ Ω Β Ν Μ · BackSpace"
 | 
			
		||||
        - "show_numbers preferences space « » Return"
 | 
			
		||||
    accented:
 | 
			
		||||
        - "ά έ ή ί ό ύ ώ ϊ ϋ ΐ"
 | 
			
		||||
        - "ΰ Ά Έ Ή Ί Ό Ύ Ώ Ϊ show_base"
 | 
			
		||||
        - "Ϋ Ϗ ϐ ϑ ϕ ϖ ϗ – — BackSpace"
 | 
			
		||||
        - "show_numbers preferences space quoteleft quoteright Return"
 | 
			
		||||
    numbers:
 | 
			
		||||
        - "1 2 3 4 5 6 7 8 9 0"
 | 
			
		||||
        - "at numbersign dollar percent ampersand minus underscore plus parenleft parenright"
 | 
			
		||||
        - "show_symbols comma quotedbl quoteright colon semicolon exclam question BackSpace"
 | 
			
		||||
        - "show_letters preferences space period Return"
 | 
			
		||||
    symbols:
 | 
			
		||||
        - "asciitilde quoteleft bar U00B7 squareroot Greek_pi Greek_tau division multiply paragraph"
 | 
			
		||||
        - "copyright U00AE U00A3 EuroSign U00A5 asciicircum degree asterisk braceleft braceright"
 | 
			
		||||
        - "show_numbers backslash slash less greater equal bracketleft bracketright  BackSpace"
 | 
			
		||||
        - "show_letters preferences space period Return"
 | 
			
		||||
buttons:
 | 
			
		||||
    Shift_L:
 | 
			
		||||
        action:
 | 
			
		||||
            locking:
 | 
			
		||||
                lock_view: "upper"
 | 
			
		||||
                unlock_view: "base"
 | 
			
		||||
        outline: "altline"
 | 
			
		||||
        icon: "key-shift"
 | 
			
		||||
    BackSpace:
 | 
			
		||||
        outline: "altline"
 | 
			
		||||
        icon: "edit-clear-symbolic"
 | 
			
		||||
    preferences:
 | 
			
		||||
        action: "show_prefs"
 | 
			
		||||
        outline: "altline"
 | 
			
		||||
        icon: "keyboard-mode-symbolic"
 | 
			
		||||
    show_numbers:
 | 
			
		||||
        action:
 | 
			
		||||
            set_view: "numbers"
 | 
			
		||||
        outline: "altline"
 | 
			
		||||
        label: "123"
 | 
			
		||||
    show_letters:
 | 
			
		||||
        action:
 | 
			
		||||
            set_view: "base"
 | 
			
		||||
        outline: "altline"
 | 
			
		||||
        label: "ΑΒΓ"
 | 
			
		||||
    show_symbols:
 | 
			
		||||
        action:
 | 
			
		||||
            set_view: "symbols"
 | 
			
		||||
        outline: "altline"
 | 
			
		||||
        label: "*/="
 | 
			
		||||
    show_accented:
 | 
			
		||||
        action:
 | 
			
		||||
            locking:
 | 
			
		||||
                lock_view: "accented"
 | 
			
		||||
                unlock_view: "base"
 | 
			
		||||
        outline: "altline"
 | 
			
		||||
        label: "άΐ"
 | 
			
		||||
    show_base:
 | 
			
		||||
        action:
 | 
			
		||||
            set_view: "base"
 | 
			
		||||
        outline: "altline"
 | 
			
		||||
        label: "αι"
 | 
			
		||||
    period:
 | 
			
		||||
        outline: altline
 | 
			
		||||
        label: "."
 | 
			
		||||
    space:
 | 
			
		||||
        outline: spaceline
 | 
			
		||||
        label: " "
 | 
			
		||||
    Return:
 | 
			
		||||
        outline: outline7
 | 
			
		||||
        icon: "key-enter"
 | 
			
		||||
    aring:
 | 
			
		||||
        label: "å"
 | 
			
		||||
    Aring:
 | 
			
		||||
        label: "Å"
 | 
			
		||||
    oslash:
 | 
			
		||||
        label: "ø"
 | 
			
		||||
    Oslash:
 | 
			
		||||
        label: "Ø"
 | 
			
		||||
    ae:
 | 
			
		||||
        label: "æ"
 | 
			
		||||
    AE:
 | 
			
		||||
        label: "Æ"
 | 
			
		||||
    asterisk:
 | 
			
		||||
        label: "*"
 | 
			
		||||
    asciitilde:
 | 
			
		||||
        label: "~"
 | 
			
		||||
    quoteleft:
 | 
			
		||||
        label: "`"
 | 
			
		||||
    bar:
 | 
			
		||||
        label: "|"
 | 
			
		||||
    U00B7:
 | 
			
		||||
        label: "·"
 | 
			
		||||
    squareroot:
 | 
			
		||||
        label: "√"
 | 
			
		||||
    Greek_pi:
 | 
			
		||||
        label: "π"
 | 
			
		||||
    division:
 | 
			
		||||
        label: "÷"
 | 
			
		||||
    multiply:
 | 
			
		||||
        label: "×"
 | 
			
		||||
    paragraph:
 | 
			
		||||
        label: "¶"
 | 
			
		||||
    Greek_tau:
 | 
			
		||||
        label: "τ"
 | 
			
		||||
    copyright:
 | 
			
		||||
        label: "©"
 | 
			
		||||
    numbersign:
 | 
			
		||||
        label: "#"
 | 
			
		||||
    U00AE:
 | 
			
		||||
        label: "®"
 | 
			
		||||
    at:
 | 
			
		||||
        label: "@"
 | 
			
		||||
    dollar:
 | 
			
		||||
        label: "$"
 | 
			
		||||
    U00A3:
 | 
			
		||||
        label: "£"
 | 
			
		||||
    percent:
 | 
			
		||||
        label: "%"
 | 
			
		||||
    EuroSign:
 | 
			
		||||
        label: "€"
 | 
			
		||||
    ampersand:
 | 
			
		||||
        label: "&"
 | 
			
		||||
    U00A5:
 | 
			
		||||
        label: "¥"
 | 
			
		||||
    minus:
 | 
			
		||||
        label: "-"
 | 
			
		||||
    asciicircum:
 | 
			
		||||
        label: "^"
 | 
			
		||||
    underscore:
 | 
			
		||||
        label: "_"
 | 
			
		||||
    degree:
 | 
			
		||||
        label: "°"
 | 
			
		||||
    plus:
 | 
			
		||||
        label: "+"
 | 
			
		||||
    equal:
 | 
			
		||||
        label: "="
 | 
			
		||||
    parenleft:
 | 
			
		||||
        label: "("
 | 
			
		||||
    parenright:
 | 
			
		||||
        label: ")"
 | 
			
		||||
    braceleft:
 | 
			
		||||
        label: "{"
 | 
			
		||||
    braceright:
 | 
			
		||||
        label: "}"
 | 
			
		||||
    comma:
 | 
			
		||||
        label: ","
 | 
			
		||||
    backslash:
 | 
			
		||||
        label: "\\"
 | 
			
		||||
    slash:
 | 
			
		||||
        label: "/"
 | 
			
		||||
    quotedbl:
 | 
			
		||||
        label: "\""
 | 
			
		||||
    quoteright:
 | 
			
		||||
        label: "'"
 | 
			
		||||
    less:
 | 
			
		||||
        label: "<"
 | 
			
		||||
    greater:
 | 
			
		||||
        label: ">"
 | 
			
		||||
    colon:
 | 
			
		||||
        label: ":"
 | 
			
		||||
    semicolon:
 | 
			
		||||
        label: ";"
 | 
			
		||||
    exclam:
 | 
			
		||||
        label: "!"
 | 
			
		||||
    question:
 | 
			
		||||
        label: "?"
 | 
			
		||||
    bracketleft:
 | 
			
		||||
        label: "["
 | 
			
		||||
    bracketright:
 | 
			
		||||
        label: "]"
 | 
			
		||||
 | 
			
		||||
@ -1,96 +0,0 @@
 | 
			
		||||
---
 | 
			
		||||
row_spacing: 11.33
 | 
			
		||||
button_spacing: 4.67
 | 
			
		||||
 | 
			
		||||
bounds: { x: 0, y: 1, width: 360, height: 198 }
 | 
			
		||||
 | 
			
		||||
outlines:
 | 
			
		||||
    default:
 | 
			
		||||
        bounds: { x: 0, y: 0, width: 30.67, height: 40.67 }
 | 
			
		||||
    altline:
 | 
			
		||||
        bounds: { x: 0, y: 0, width: 48, height: 40.67 }
 | 
			
		||||
    wide:
 | 
			
		||||
        bounds: { x: 0, y: 0, width: 57.33, height: 40.67 }
 | 
			
		||||
    spaceline:
 | 
			
		||||
        bounds: { x: 0, y: 0, width: 95.00, height: 40.67 }
 | 
			
		||||
    special:
 | 
			
		||||
        bounds: { x: 0, y: 0, width: 39.33, height: 40.67 }
 | 
			
		||||
 | 
			
		||||
views:
 | 
			
		||||
    base:
 | 
			
		||||
        - "q w e r t y u i o p"
 | 
			
		||||
        - "a s d f g h j k l ñ"
 | 
			
		||||
        - "Shift_L   z x c v b n m  BackSpace"
 | 
			
		||||
        - "show_numbers show_eschars preferences         space        ? period Return"
 | 
			
		||||
    upper:
 | 
			
		||||
        - "Q W E R T Y U I O P"
 | 
			
		||||
        - "A S D F G H J K L Ñ"
 | 
			
		||||
        - "Shift_L   Z X C V B N M  BackSpace"
 | 
			
		||||
        - "show_numbers show_eschars preferences         space        ¿ period Return"
 | 
			
		||||
    numbers:
 | 
			
		||||
        - "1 2 3 4 5 6 7 8 9 0"
 | 
			
		||||
        - "@ # € % & - _ + ( )"
 | 
			
		||||
        - "show_symbols   , \" ' colon ; ! = BackSpace"
 | 
			
		||||
        - "show_letters show_eschars preferences         space        ? period Return"
 | 
			
		||||
    symbols:
 | 
			
		||||
        - "~ ` | · √ π τ ÷ × ¶"
 | 
			
		||||
        - "© ® £ $ ¥ ^ ° * { }"
 | 
			
		||||
        - "show_numbers   \\ / < > = [ ]  BackSpace"
 | 
			
		||||
        - "show_letters show_eschars preferences         space        ? period Return"
 | 
			
		||||
    eschars:
 | 
			
		||||
        - "á é í ó ú Á É Í Ó Ú"
 | 
			
		||||
        - "à è ì ò ù À È Ì Ò Ù"
 | 
			
		||||
        - "show_numbers ü ç ï Ü Ç Ï ¡  BackSpace"
 | 
			
		||||
        - "show_letters show_eschars preferences         space        « » Return"
 | 
			
		||||
 | 
			
		||||
buttons:
 | 
			
		||||
    Shift_L:
 | 
			
		||||
        action:
 | 
			
		||||
            locking:
 | 
			
		||||
                lock_view: "upper"
 | 
			
		||||
                unlock_view: "base"
 | 
			
		||||
        outline: "altline"
 | 
			
		||||
        icon: "key-shift"
 | 
			
		||||
    BackSpace:
 | 
			
		||||
        outline: "altline"
 | 
			
		||||
        icon: "edit-clear-symbolic"
 | 
			
		||||
    preferences:
 | 
			
		||||
        action: "show_prefs"
 | 
			
		||||
        outline: "default"
 | 
			
		||||
        icon: "keyboard-mode-symbolic"
 | 
			
		||||
    show_numbers:
 | 
			
		||||
        action:
 | 
			
		||||
            set_view: "numbers"
 | 
			
		||||
        outline: "altline"
 | 
			
		||||
        label: "123"
 | 
			
		||||
    show_letters:
 | 
			
		||||
        action:
 | 
			
		||||
            set_view: "base"
 | 
			
		||||
        outline: "altline"
 | 
			
		||||
        label: "abc"
 | 
			
		||||
    show_symbols:
 | 
			
		||||
        action:
 | 
			
		||||
            set_view: "symbols"
 | 
			
		||||
        outline: "altline"
 | 
			
		||||
        label: "*/="
 | 
			
		||||
    show_eschars:
 | 
			
		||||
        action:
 | 
			
		||||
            locking:
 | 
			
		||||
                lock_view: "eschars"
 | 
			
		||||
                unlock_view: "base"
 | 
			
		||||
        outline: "altline"
 | 
			
		||||
        label: "áÁ"
 | 
			
		||||
 | 
			
		||||
    period:
 | 
			
		||||
        outline: "default"
 | 
			
		||||
        label: "."
 | 
			
		||||
    space:
 | 
			
		||||
        outline: "spaceline"
 | 
			
		||||
        label: " "
 | 
			
		||||
    Return:
 | 
			
		||||
        outline: "altline"
 | 
			
		||||
        icon: "key-enter"
 | 
			
		||||
    colon:
 | 
			
		||||
        label: ":"
 | 
			
		||||
    "\"":
 | 
			
		||||
        keysym: "quotedbl"
 | 
			
		||||
							
								
								
									
										120
									
								
								data/keyboards/geometry/compact.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										120
									
								
								data/keyboards/geometry/compact.xml
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,120 @@
 | 
			
		||||
<?xml version="1.0"?>
 | 
			
		||||
<geometry version="0.90">
 | 
			
		||||
  <bounds x="10" y="10" width="410.0000" height="229"/>
 | 
			
		||||
  <section angle="0">
 | 
			
		||||
    <row orientation="1">
 | 
			
		||||
      <key name="AD01" oref="outline2" />
 | 
			
		||||
      <key name="AD02" oref="outline2" />
 | 
			
		||||
      <key name="AD03" oref="outline2" />
 | 
			
		||||
      <key name="AD04" oref="outline2" />
 | 
			
		||||
      <key name="AD05" oref="outline2" />
 | 
			
		||||
      <key name="AD06" oref="outline2" />
 | 
			
		||||
      <key name="AD07" oref="outline2" />
 | 
			
		||||
      <key name="AD08" oref="outline2" />
 | 
			
		||||
      <key name="AD09" oref="outline2" />
 | 
			
		||||
      <key name="AD10" oref="outline2" />
 | 
			
		||||
    </row>
 | 
			
		||||
  </section>
 | 
			
		||||
  <section angle="0">
 | 
			
		||||
    <row orientation="1">
 | 
			
		||||
      <key name="AC01" oref="outline2" />
 | 
			
		||||
      <key name="AC02" oref="outline2" />
 | 
			
		||||
      <key name="AC03" oref="outline2" />
 | 
			
		||||
      <key name="AC04" oref="outline2" />
 | 
			
		||||
      <key name="AC05" oref="outline2" />
 | 
			
		||||
      <key name="AC06" oref="outline2" />
 | 
			
		||||
      <key name="AC07" oref="outline2" />
 | 
			
		||||
      <key name="AC08" oref="outline2" />
 | 
			
		||||
      <key name="AC09" oref="outline2" />
 | 
			
		||||
      <key name="AC10" oref="outline2" />
 | 
			
		||||
    </row>
 | 
			
		||||
  </section>
 | 
			
		||||
  <section angle="0">
 | 
			
		||||
    <row orientation="1">
 | 
			
		||||
      <key name="LFSH" oref="altline" />
 | 
			
		||||
      <key name="AB01" oref="outline2" />
 | 
			
		||||
      <key name="AB02" oref="outline2" />
 | 
			
		||||
      <key name="AB03" oref="outline2" />
 | 
			
		||||
      <key name="AB04" oref="outline2" />
 | 
			
		||||
      <key name="AB05" oref="outline2" />
 | 
			
		||||
      <key name="AB06" oref="outline2" />
 | 
			
		||||
      <key name="AB07" oref="outline2" />
 | 
			
		||||
      <key name="BKSP" oref="altline" />
 | 
			
		||||
    </row>
 | 
			
		||||
  </section>
 | 
			
		||||
  <section angle="0">
 | 
			
		||||
    <row orientation="1">
 | 
			
		||||
      <key keycode="0" name="ABC123" oref="altline" />
 | 
			
		||||
      <key name="I149" oref="altline" />
 | 
			
		||||
      <key name="SPCE" oref="spaceline" />
 | 
			
		||||
      <key name="AB08" oref="outline2" />
 | 
			
		||||
      <key name="RTRN" oref="outline7" />
 | 
			
		||||
    </row>
 | 
			
		||||
  </section>
 | 
			
		||||
  <outline id="outline2" corner-radius="1.000000">
 | 
			
		||||
    <point x="0.000000" y="0.000000"/>
 | 
			
		||||
    <point x="37.46341" y="0.000000"/>
 | 
			
		||||
    <point x="37.46341" y="52"/>
 | 
			
		||||
    <point x="0.000000" y="52"/>
 | 
			
		||||
  </outline>
 | 
			
		||||
  <outline id="altline" corner-radius="1.000000">
 | 
			
		||||
    <point x="0.000000" y="0.000000"/>
 | 
			
		||||
    <point x="48.39024" y="0.000000"/>
 | 
			
		||||
    <point x="48.39024" y="52"/>
 | 
			
		||||
    <point x="0.000000" y="52"/>
 | 
			
		||||
  </outline>
 | 
			
		||||
  <outline id="outline4" corner-radius="1.000000">
 | 
			
		||||
    <point x="0.000000" y="0.000000"/>
 | 
			
		||||
    <point x="59.31707" y="0.000000"/>
 | 
			
		||||
    <point x="59.31707" y="52"/>
 | 
			
		||||
    <point x="0.000000" y="52"/>
 | 
			
		||||
  </outline>
 | 
			
		||||
  <outline id="outline5" corner-radius="1.000000">
 | 
			
		||||
    <point x="0.000000" y="0.000000"/>
 | 
			
		||||
    <point x="59.31707" y="0.000000"/>
 | 
			
		||||
    <point x="59.31707" y="52"/>
 | 
			
		||||
    <point x="0.000000" y="52"/>
 | 
			
		||||
  </outline>
 | 
			
		||||
  <outline id="outline6" corner-radius="1.000000">
 | 
			
		||||
    <point x="0.000000" y="0.000000"/>
 | 
			
		||||
    <point x="68.68292" y="0.000000"/>
 | 
			
		||||
    <point x="68.68292" y="52"/>
 | 
			
		||||
    <point x="0.000000" y="52"/>
 | 
			
		||||
  </outline>
 | 
			
		||||
  <outline id="outline7" corner-radius="1.000000">
 | 
			
		||||
    <point x="0.000000" y="0.000000"/>
 | 
			
		||||
    <point x="88.97561" y="0.000000"/>
 | 
			
		||||
    <point x="88.97561" y="52"/>
 | 
			
		||||
    <point x="0.000000" y="52"/>
 | 
			
		||||
  </outline>
 | 
			
		||||
  <outline id="outline8" corner-radius="1.000000">
 | 
			
		||||
    <point x="0.000000" y="0.000000"/>
 | 
			
		||||
    <point x="88.97561" y="0.000000"/>
 | 
			
		||||
    <point x="88.97561" y="52"/>
 | 
			
		||||
    <point x="0.000000" y="52"/>
 | 
			
		||||
  </outline>
 | 
			
		||||
  <outline id="outline9" corner-radius="1.000000">
 | 
			
		||||
    <point x="0.000000" y="0.000000"/>
 | 
			
		||||
    <point x="109.2682" y="0.000000"/>
 | 
			
		||||
    <point x="109.2682" y="52"/>
 | 
			
		||||
    <point x="0.000000" y="52"/>
 | 
			
		||||
  </outline>
 | 
			
		||||
  <outline id="outline10" corner-radius="1.000000">
 | 
			
		||||
    <point x="0.000000" y="0.000000"/>
 | 
			
		||||
    <point x="37.46341" y="0.000000"/>
 | 
			
		||||
    <point x="37.46341" y="52"/>
 | 
			
		||||
    <point x="0.000000" y="52"/>
 | 
			
		||||
  </outline>
 | 
			
		||||
  <outline id="outline13" corner-radius="1.000000">
 | 
			
		||||
    <point x="0.000000" y="0.000000"/>
 | 
			
		||||
    <point x="79.60975" y="0.000000"/>
 | 
			
		||||
    <point x="79.60975" y="52"/>
 | 
			
		||||
    <point x="0.000000" y="52"/>
 | 
			
		||||
  </outline>
 | 
			
		||||
  <outline id="spaceline" corner-radius="1.000000">
 | 
			
		||||
    <point x="0.000000" y="0.000000"/>
 | 
			
		||||
    <point x="150.5853" y="0.000000"/>
 | 
			
		||||
    <point x="150.5853" y="52"/>
 | 
			
		||||
    <point x="0.000000" y="52"/>
 | 
			
		||||
  </outline>
 | 
			
		||||
</geometry>
 | 
			
		||||
							
								
								
									
										98
									
								
								data/keyboards/geometry/digits.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										98
									
								
								data/keyboards/geometry/digits.xml
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,98 @@
 | 
			
		||||
<?xml version="1.0"?>
 | 
			
		||||
<geometry version="0.90">
 | 
			
		||||
  <bounds x="0" y="10.000000" width="426.0000" height="296.5853"/>
 | 
			
		||||
  <section angle="0">
 | 
			
		||||
    <row orientation="1">
 | 
			
		||||
      <key name="AD01" oref="outline4" />
 | 
			
		||||
      <key name="AD02" oref="outline4" />
 | 
			
		||||
      <key name="AD03" oref="outline4" />
 | 
			
		||||
    </row>
 | 
			
		||||
  </section>
 | 
			
		||||
  <section angle="0">
 | 
			
		||||
    <row orientation="1">
 | 
			
		||||
      <key name="AC01" oref="outline4" />
 | 
			
		||||
      <key name="AC02" oref="outline4" />
 | 
			
		||||
      <key name="AC03" oref="outline4" />
 | 
			
		||||
    </row>
 | 
			
		||||
  </section>
 | 
			
		||||
  <section angle="0">
 | 
			
		||||
    <row orientation="1">
 | 
			
		||||
      <key name="AB01" oref="outline4" />
 | 
			
		||||
      <key name="AB02" oref="outline4" />
 | 
			
		||||
      <key name="AB03" oref="outline4" />
 | 
			
		||||
    </row>
 | 
			
		||||
  </section>
 | 
			
		||||
  <section angle="0">
 | 
			
		||||
    <row orientation="1">
 | 
			
		||||
      <key name="BKSP" oref="altline" />
 | 
			
		||||
      <key name="AB04" oref="outline4" />
 | 
			
		||||
      <key name="RTRN" oref="altline" />
 | 
			
		||||
    </row>
 | 
			
		||||
  </section>
 | 
			
		||||
  <outline id="outline2" corner-radius="1.000000">
 | 
			
		||||
    <point x="0.000000" y="0.000000"/>
 | 
			
		||||
    <point x="37.46341" y="0.000000"/>
 | 
			
		||||
    <point x="37.46341" y="52.44877"/>
 | 
			
		||||
    <point x="0.000000" y="52.44877"/>
 | 
			
		||||
  </outline>
 | 
			
		||||
  <outline id="altline" corner-radius="1.000000">
 | 
			
		||||
    <point x="0.000000" y="0.000000"/>
 | 
			
		||||
    <point x="48.39024" y="0.000000"/>
 | 
			
		||||
    <point x="48.39024" y="52.44877"/>
 | 
			
		||||
    <point x="0.000000" y="52.44877"/>
 | 
			
		||||
  </outline>
 | 
			
		||||
  <outline id="outline4" corner-radius="1.000000">
 | 
			
		||||
    <point x="0.000000" y="0.000000"/>
 | 
			
		||||
    <point x="59.31707" y="0.000000"/>
 | 
			
		||||
    <point x="59.31707" y="52.44877"/>
 | 
			
		||||
    <point x="0.000000" y="52.44877"/>
 | 
			
		||||
  </outline>
 | 
			
		||||
  <outline id="outline5" corner-radius="1.000000">
 | 
			
		||||
    <point x="0.000000" y="0.000000"/>
 | 
			
		||||
    <point x="59.31707" y="0.000000"/>
 | 
			
		||||
    <point x="59.31707" y="52.44877"/>
 | 
			
		||||
    <point x="0.000000" y="52.44877"/>
 | 
			
		||||
  </outline>
 | 
			
		||||
  <outline id="outline6" corner-radius="1.000000">
 | 
			
		||||
    <point x="0.000000" y="0.000000"/>
 | 
			
		||||
    <point x="68.68292" y="0.000000"/>
 | 
			
		||||
    <point x="68.68292" y="52.44877"/>
 | 
			
		||||
    <point x="0.000000" y="52.44877"/>
 | 
			
		||||
  </outline>
 | 
			
		||||
  <outline id="outline7" corner-radius="1.000000">
 | 
			
		||||
    <point x="0.000000" y="0.000000"/>
 | 
			
		||||
    <point x="88.97561" y="0.000000"/>
 | 
			
		||||
    <point x="88.97561" y="52.44877"/>
 | 
			
		||||
    <point x="0.000000" y="52.44877"/>
 | 
			
		||||
  </outline>
 | 
			
		||||
  <outline id="outline8" corner-radius="1.000000">
 | 
			
		||||
    <point x="0.000000" y="0.000000"/>
 | 
			
		||||
    <point x="88.97561" y="0.000000"/>
 | 
			
		||||
    <point x="88.97561" y="52.44877"/>
 | 
			
		||||
    <point x="0.000000" y="52.44877"/>
 | 
			
		||||
  </outline>
 | 
			
		||||
  <outline id="outline9" corner-radius="1.000000">
 | 
			
		||||
    <point x="0.000000" y="0.000000"/>
 | 
			
		||||
    <point x="109.2682" y="0.000000"/>
 | 
			
		||||
    <point x="109.2682" y="52.44877"/>
 | 
			
		||||
    <point x="0.000000" y="52.44877"/>
 | 
			
		||||
  </outline>
 | 
			
		||||
  <outline id="outline10" corner-radius="1.000000">
 | 
			
		||||
    <point x="0.000000" y="0.000000"/>
 | 
			
		||||
    <point x="37.46341" y="0.000000"/>
 | 
			
		||||
    <point x="37.46341" y="52.44877"/>
 | 
			
		||||
    <point x="0.000000" y="52.44877"/>
 | 
			
		||||
  </outline>
 | 
			
		||||
  <outline id="outline13" corner-radius="1.000000">
 | 
			
		||||
    <point x="0.000000" y="0.000000"/>
 | 
			
		||||
    <point x="79.60975" y="0.000000"/>
 | 
			
		||||
    <point x="79.60975" y="52.44877"/>
 | 
			
		||||
    <point x="0.000000" y="52.44877"/>
 | 
			
		||||
  </outline>
 | 
			
		||||
  <outline id="spaceline" corner-radius="1.000000">
 | 
			
		||||
    <point x="0.000000" y="0.000000"/>
 | 
			
		||||
    <point x="120.5853" y="0.000000"/>
 | 
			
		||||
    <point x="120.5853" y="52.44877"/>
 | 
			
		||||
    <point x="0.000000" y="52.44877"/>
 | 
			
		||||
  </outline>
 | 
			
		||||
</geometry>
 | 
			
		||||
							
								
								
									
										122
									
								
								data/keyboards/geometry/extended.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										122
									
								
								data/keyboards/geometry/extended.xml
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,122 @@
 | 
			
		||||
<?xml version="1.0"?>
 | 
			
		||||
<geometry version="0.90">
 | 
			
		||||
  <bounds x="0" y="10.000000" width="426.0000" height="296.5853"/>
 | 
			
		||||
  <section angle="0">
 | 
			
		||||
    <row orientation="1">
 | 
			
		||||
      <key name="AD01" oref="outline2" />
 | 
			
		||||
      <key name="AD02" oref="outline2" />
 | 
			
		||||
      <key name="AD03" oref="outline2" />
 | 
			
		||||
      <key name="AD04" oref="outline2" />
 | 
			
		||||
      <key name="AD05" oref="outline2" />
 | 
			
		||||
      <key name="AD06" oref="outline2" />
 | 
			
		||||
      <key name="AD07" oref="outline2" />
 | 
			
		||||
      <key name="AD08" oref="outline2" />
 | 
			
		||||
      <key name="AD09" oref="outline2" />
 | 
			
		||||
      <key name="AD10" oref="outline2" />
 | 
			
		||||
      <key name="AD11" oref="outline2" />
 | 
			
		||||
    </row>
 | 
			
		||||
  </section>
 | 
			
		||||
  <section angle="0">
 | 
			
		||||
    <row orientation="1">
 | 
			
		||||
      <key name="AC01" oref="outline2" />
 | 
			
		||||
      <key name="AC02" oref="outline2" />
 | 
			
		||||
      <key name="AC03" oref="outline2" />
 | 
			
		||||
      <key name="AC04" oref="outline2" />
 | 
			
		||||
      <key name="AC05" oref="outline2" />
 | 
			
		||||
      <key name="AC06" oref="outline2" />
 | 
			
		||||
      <key name="AC07" oref="outline2" />
 | 
			
		||||
      <key name="AC08" oref="outline2" />
 | 
			
		||||
      <key name="AC09" oref="outline2" />
 | 
			
		||||
      <key name="AC10" oref="outline2" />
 | 
			
		||||
      <key name="AC11" oref="outline2" />
 | 
			
		||||
    </row>
 | 
			
		||||
  </section>
 | 
			
		||||
  <section angle="0">
 | 
			
		||||
    <row orientation="1">
 | 
			
		||||
      <key name="LFSH" oref="altline" />
 | 
			
		||||
      <key name="AB01" oref="outline2" />
 | 
			
		||||
      <key name="AB02" oref="outline2" />
 | 
			
		||||
      <key name="AB03" oref="outline2" />
 | 
			
		||||
      <key name="AB04" oref="outline2" />
 | 
			
		||||
      <key name="AB05" oref="outline2" />
 | 
			
		||||
      <key name="AB06" oref="outline2" />
 | 
			
		||||
      <key name="AB07" oref="outline2" />
 | 
			
		||||
      <key name="BKSP" oref="altline" />
 | 
			
		||||
    </row>
 | 
			
		||||
  </section>
 | 
			
		||||
  <section angle="0">
 | 
			
		||||
    <row orientation="1">
 | 
			
		||||
      <key keycode="0" name="ABC123" oref="altline" />
 | 
			
		||||
      <key name="I149" oref="altline" />
 | 
			
		||||
      <key name="SPCE" oref="spaceline" />
 | 
			
		||||
      <key name="AB08" oref="outline2" />
 | 
			
		||||
      <key name="RTRN" oref="outline7" />
 | 
			
		||||
    </row>
 | 
			
		||||
  </section>
 | 
			
		||||
  <outline id="outline2" corner-radius="1.000000">
 | 
			
		||||
    <point x="0.000000" y="0.000000"/>
 | 
			
		||||
    <point x="32" y="0.000000"/>
 | 
			
		||||
    <point x="32" y="52"/>
 | 
			
		||||
    <point x="0.000000" y="52"/>
 | 
			
		||||
  </outline>
 | 
			
		||||
  <outline id="altline" corner-radius="1.000000">
 | 
			
		||||
    <point x="0.000000" y="0.000000"/>
 | 
			
		||||
    <point x="48.39024" y="0.000000"/>
 | 
			
		||||
    <point x="48.39024" y="52"/>
 | 
			
		||||
    <point x="0.000000" y="52"/>
 | 
			
		||||
  </outline>
 | 
			
		||||
  <outline id="outline4" corner-radius="1.000000">
 | 
			
		||||
    <point x="0.000000" y="0.000000"/>
 | 
			
		||||
    <point x="59.31707" y="0.000000"/>
 | 
			
		||||
    <point x="59.31707" y="52"/>
 | 
			
		||||
    <point x="0.000000" y="52"/>
 | 
			
		||||
  </outline>
 | 
			
		||||
  <outline id="outline5" corner-radius="1.000000">
 | 
			
		||||
    <point x="0.000000" y="0.000000"/>
 | 
			
		||||
    <point x="59.31707" y="0.000000"/>
 | 
			
		||||
    <point x="59.31707" y="52"/>
 | 
			
		||||
    <point x="0.000000" y="52"/>
 | 
			
		||||
  </outline>
 | 
			
		||||
  <outline id="outline6" corner-radius="1.000000">
 | 
			
		||||
    <point x="0.000000" y="0.000000"/>
 | 
			
		||||
    <point x="68.68292" y="0.000000"/>
 | 
			
		||||
    <point x="68.68292" y="52"/>
 | 
			
		||||
    <point x="0.000000" y="52"/>
 | 
			
		||||
  </outline>
 | 
			
		||||
  <outline id="outline7" corner-radius="1.000000">
 | 
			
		||||
    <point x="0.000000" y="0.000000"/>
 | 
			
		||||
    <point x="88.97561" y="0.000000"/>
 | 
			
		||||
    <point x="88.97561" y="52"/>
 | 
			
		||||
    <point x="0.000000" y="52"/>
 | 
			
		||||
  </outline>
 | 
			
		||||
  <outline id="outline8" corner-radius="1.000000">
 | 
			
		||||
    <point x="0.000000" y="0.000000"/>
 | 
			
		||||
    <point x="88.97561" y="0.000000"/>
 | 
			
		||||
    <point x="88.97561" y="52"/>
 | 
			
		||||
    <point x="0.000000" y="52"/>
 | 
			
		||||
  </outline>
 | 
			
		||||
  <outline id="outline9" corner-radius="1.000000">
 | 
			
		||||
    <point x="0.000000" y="0.000000"/>
 | 
			
		||||
    <point x="109.2682" y="0.000000"/>
 | 
			
		||||
    <point x="109.2682" y="52"/>
 | 
			
		||||
    <point x="0.000000" y="52"/>
 | 
			
		||||
  </outline>
 | 
			
		||||
  <outline id="outline10" corner-radius="1.000000">
 | 
			
		||||
    <point x="0.000000" y="0.000000"/>
 | 
			
		||||
    <point x="37.46341" y="0.000000"/>
 | 
			
		||||
    <point x="37.46341" y="52"/>
 | 
			
		||||
    <point x="0.000000" y="52"/>
 | 
			
		||||
  </outline>
 | 
			
		||||
  <outline id="outline13" corner-radius="1.000000">
 | 
			
		||||
    <point x="0.000000" y="0.000000"/>
 | 
			
		||||
    <point x="79.60975" y="0.000000"/>
 | 
			
		||||
    <point x="79.60975" y="52"/>
 | 
			
		||||
    <point x="0.000000" y="52"/>
 | 
			
		||||
  </outline>
 | 
			
		||||
  <outline id="spaceline" corner-radius="1.000000">
 | 
			
		||||
    <point x="0.000000" y="0.000000"/>
 | 
			
		||||
    <point x="150.5853" y="0.000000"/>
 | 
			
		||||
    <point x="150.5853" y="52"/>
 | 
			
		||||
    <point x="0.000000" y="52"/>
 | 
			
		||||
  </outline>
 | 
			
		||||
</geometry>
 | 
			
		||||
							
								
								
									
										105
									
								
								data/keyboards/geometry/number-keypad.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										105
									
								
								data/keyboards/geometry/number-keypad.xml
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,105 @@
 | 
			
		||||
<?xml version="1.0"?>
 | 
			
		||||
<geometry version="0.90">
 | 
			
		||||
  <bounds x="0" y="10.000000" width="426.0000" height="296.5853"/>
 | 
			
		||||
  <section angle="0">
 | 
			
		||||
    <row orientation="1">
 | 
			
		||||
      <key name="AD01" oref="outline2" />
 | 
			
		||||
      <key name="AD02" oref="outline2" />
 | 
			
		||||
      <key name="AD03" oref="outline2" />
 | 
			
		||||
      <key name="AD04" oref="outline2" />
 | 
			
		||||
      <key name="AD05" oref="outline2" />
 | 
			
		||||
    </row>
 | 
			
		||||
  </section>
 | 
			
		||||
  <section angle="0">
 | 
			
		||||
    <row orientation="1">
 | 
			
		||||
      <key name="AC01" oref="outline2" />
 | 
			
		||||
      <key name="AC02" oref="outline2" />
 | 
			
		||||
      <key name="AC03" oref="outline2" />
 | 
			
		||||
      <key name="AC04" oref="outline2" />
 | 
			
		||||
      <key name="AC05" oref="outline2" />
 | 
			
		||||
    </row>
 | 
			
		||||
  </section>
 | 
			
		||||
  <section angle="0">
 | 
			
		||||
    <row orientation="1">
 | 
			
		||||
      <key name="AB01" oref="outline2" />
 | 
			
		||||
      <key name="AB02" oref="outline2" />
 | 
			
		||||
      <key name="AB03" oref="outline2" />
 | 
			
		||||
      <key name="AB04" oref="outline2" />
 | 
			
		||||
      <key name="AB05" oref="outline2" />
 | 
			
		||||
    </row>
 | 
			
		||||
  </section>
 | 
			
		||||
  <section angle="0">
 | 
			
		||||
    <row orientation="1">
 | 
			
		||||
      <key name="BKSP" oref="altline" />
 | 
			
		||||
      <key name="AB06" oref="outline2" />
 | 
			
		||||
      <key name="SPCE" oref="spaceline" />
 | 
			
		||||
      <key name="RTRN" oref="outline7" />
 | 
			
		||||
    </row>
 | 
			
		||||
  </section>
 | 
			
		||||
  <outline id="outline2" corner-radius="1.000000">
 | 
			
		||||
    <point x="0.000000" y="0.000000"/>
 | 
			
		||||
    <point x="37.46341" y="0.000000"/>
 | 
			
		||||
    <point x="37.46341" y="52.44877"/>
 | 
			
		||||
    <point x="0.000000" y="52.44877"/>
 | 
			
		||||
  </outline>
 | 
			
		||||
  <outline id="altline" corner-radius="1.000000">
 | 
			
		||||
    <point x="0.000000" y="0.000000"/>
 | 
			
		||||
    <point x="48.39024" y="0.000000"/>
 | 
			
		||||
    <point x="48.39024" y="52.44877"/>
 | 
			
		||||
    <point x="0.000000" y="52.44877"/>
 | 
			
		||||
  </outline>
 | 
			
		||||
  <outline id="outline4" corner-radius="1.000000">
 | 
			
		||||
    <point x="0.000000" y="0.000000"/>
 | 
			
		||||
    <point x="59.31707" y="0.000000"/>
 | 
			
		||||
    <point x="59.31707" y="52.44877"/>
 | 
			
		||||
    <point x="0.000000" y="52.44877"/>
 | 
			
		||||
  </outline>
 | 
			
		||||
  <outline id="outline5" corner-radius="1.000000">
 | 
			
		||||
    <point x="0.000000" y="0.000000"/>
 | 
			
		||||
    <point x="59.31707" y="0.000000"/>
 | 
			
		||||
    <point x="59.31707" y="52.44877"/>
 | 
			
		||||
    <point x="0.000000" y="52.44877"/>
 | 
			
		||||
  </outline>
 | 
			
		||||
  <outline id="outline6" corner-radius="1.000000">
 | 
			
		||||
    <point x="0.000000" y="0.000000"/>
 | 
			
		||||
    <point x="68.68292" y="0.000000"/>
 | 
			
		||||
    <point x="68.68292" y="52.44877"/>
 | 
			
		||||
    <point x="0.000000" y="52.44877"/>
 | 
			
		||||
  </outline>
 | 
			
		||||
  <outline id="outline7" corner-radius="1.000000">
 | 
			
		||||
    <point x="0.000000" y="0.000000"/>
 | 
			
		||||
    <point x="88.97561" y="0.000000"/>
 | 
			
		||||
    <point x="88.97561" y="52.44877"/>
 | 
			
		||||
    <point x="0.000000" y="52.44877"/>
 | 
			
		||||
  </outline>
 | 
			
		||||
  <outline id="outline8" corner-radius="1.000000">
 | 
			
		||||
    <point x="0.000000" y="0.000000"/>
 | 
			
		||||
    <point x="88.97561" y="0.000000"/>
 | 
			
		||||
    <point x="88.97561" y="52.44877"/>
 | 
			
		||||
    <point x="0.000000" y="52.44877"/>
 | 
			
		||||
  </outline>
 | 
			
		||||
  <outline id="outline9" corner-radius="1.000000">
 | 
			
		||||
    <point x="0.000000" y="0.000000"/>
 | 
			
		||||
    <point x="109.2682" y="0.000000"/>
 | 
			
		||||
    <point x="109.2682" y="52.44877"/>
 | 
			
		||||
    <point x="0.000000" y="52.44877"/>
 | 
			
		||||
  </outline>
 | 
			
		||||
  <outline id="outline10" corner-radius="1.000000">
 | 
			
		||||
    <point x="0.000000" y="0.000000"/>
 | 
			
		||||
    <point x="37.46341" y="0.000000"/>
 | 
			
		||||
    <point x="37.46341" y="52.44877"/>
 | 
			
		||||
    <point x="0.000000" y="52.44877"/>
 | 
			
		||||
  </outline>
 | 
			
		||||
  <outline id="outline13" corner-radius="1.000000">
 | 
			
		||||
    <point x="0.000000" y="0.000000"/>
 | 
			
		||||
    <point x="79.60975" y="0.000000"/>
 | 
			
		||||
    <point x="79.60975" y="52.44877"/>
 | 
			
		||||
    <point x="0.000000" y="52.44877"/>
 | 
			
		||||
  </outline>
 | 
			
		||||
  <outline id="spaceline" corner-radius="1.000000">
 | 
			
		||||
    <point x="0.000000" y="0.000000"/>
 | 
			
		||||
    <point x="120.5853" y="0.000000"/>
 | 
			
		||||
    <point x="120.5853" y="52.44877"/>
 | 
			
		||||
    <point x="0.000000" y="52.44877"/>
 | 
			
		||||
  </outline>
 | 
			
		||||
</geometry>
 | 
			
		||||
							
								
								
									
										105
									
								
								data/keyboards/geometry/phone-keypad.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										105
									
								
								data/keyboards/geometry/phone-keypad.xml
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,105 @@
 | 
			
		||||
<?xml version="1.0"?>
 | 
			
		||||
<geometry version="0.90">
 | 
			
		||||
  <bounds x="0" y="10.000000" width="426.0000" height="296.5853"/>
 | 
			
		||||
  <section angle="0">
 | 
			
		||||
    <row orientation="1">
 | 
			
		||||
      <key name="AD01" oref="outline2" />
 | 
			
		||||
      <key name="AD02" oref="outline2" />
 | 
			
		||||
      <key name="AD03" oref="outline2" />
 | 
			
		||||
      <key name="AD04" oref="outline2" />
 | 
			
		||||
      <key name="AD05" oref="outline2" />
 | 
			
		||||
    </row>
 | 
			
		||||
  </section>
 | 
			
		||||
  <section angle="0">
 | 
			
		||||
    <row orientation="1">
 | 
			
		||||
      <key name="AC01" oref="outline2" />
 | 
			
		||||
      <key name="AC02" oref="outline2" />
 | 
			
		||||
      <key name="AC03" oref="outline2" />
 | 
			
		||||
      <key name="AC04" oref="outline2" />
 | 
			
		||||
      <key name="AC05" oref="outline2" />
 | 
			
		||||
    </row>
 | 
			
		||||
  </section>
 | 
			
		||||
  <section angle="0">
 | 
			
		||||
    <row orientation="1">
 | 
			
		||||
      <key name="AB01" oref="outline2" />
 | 
			
		||||
      <key name="AB02" oref="outline2" />
 | 
			
		||||
      <key name="AB03" oref="outline2" />
 | 
			
		||||
      <key name="AB04" oref="outline2" />
 | 
			
		||||
      <key name="AB05" oref="outline2" />
 | 
			
		||||
    </row>
 | 
			
		||||
  </section>
 | 
			
		||||
  <section angle="0">
 | 
			
		||||
    <row orientation="1">
 | 
			
		||||
      <key name="BKSP" oref="altline" />
 | 
			
		||||
      <key name="AB06" oref="outline2" />
 | 
			
		||||
      <key name="SPCE" oref="spaceline" />
 | 
			
		||||
      <key name="RTRN" oref="outline7" />
 | 
			
		||||
    </row>
 | 
			
		||||
  </section>
 | 
			
		||||
  <outline id="outline2" corner-radius="1.000000">
 | 
			
		||||
    <point x="0.000000" y="0.000000"/>
 | 
			
		||||
    <point x="37.46341" y="0.000000"/>
 | 
			
		||||
    <point x="37.46341" y="52.44877"/>
 | 
			
		||||
    <point x="0.000000" y="52.44877"/>
 | 
			
		||||
  </outline>
 | 
			
		||||
  <outline id="altline" corner-radius="1.000000">
 | 
			
		||||
    <point x="0.000000" y="0.000000"/>
 | 
			
		||||
    <point x="48.39024" y="0.000000"/>
 | 
			
		||||
    <point x="48.39024" y="52.44877"/>
 | 
			
		||||
    <point x="0.000000" y="52.44877"/>
 | 
			
		||||
  </outline>
 | 
			
		||||
  <outline id="outline4" corner-radius="1.000000">
 | 
			
		||||
    <point x="0.000000" y="0.000000"/>
 | 
			
		||||
    <point x="59.31707" y="0.000000"/>
 | 
			
		||||
    <point x="59.31707" y="52.44877"/>
 | 
			
		||||
    <point x="0.000000" y="52.44877"/>
 | 
			
		||||
  </outline>
 | 
			
		||||
  <outline id="outline5" corner-radius="1.000000">
 | 
			
		||||
    <point x="0.000000" y="0.000000"/>
 | 
			
		||||
    <point x="59.31707" y="0.000000"/>
 | 
			
		||||
    <point x="59.31707" y="52.44877"/>
 | 
			
		||||
    <point x="0.000000" y="52.44877"/>
 | 
			
		||||
  </outline>
 | 
			
		||||
  <outline id="outline6" corner-radius="1.000000">
 | 
			
		||||
    <point x="0.000000" y="0.000000"/>
 | 
			
		||||
    <point x="68.68292" y="0.000000"/>
 | 
			
		||||
    <point x="68.68292" y="52.44877"/>
 | 
			
		||||
    <point x="0.000000" y="52.44877"/>
 | 
			
		||||
  </outline>
 | 
			
		||||
  <outline id="outline7" corner-radius="1.000000">
 | 
			
		||||
    <point x="0.000000" y="0.000000"/>
 | 
			
		||||
    <point x="88.97561" y="0.000000"/>
 | 
			
		||||
    <point x="88.97561" y="52.44877"/>
 | 
			
		||||
    <point x="0.000000" y="52.44877"/>
 | 
			
		||||
  </outline>
 | 
			
		||||
  <outline id="outline8" corner-radius="1.000000">
 | 
			
		||||
    <point x="0.000000" y="0.000000"/>
 | 
			
		||||
    <point x="88.97561" y="0.000000"/>
 | 
			
		||||
    <point x="88.97561" y="52.44877"/>
 | 
			
		||||
    <point x="0.000000" y="52.44877"/>
 | 
			
		||||
  </outline>
 | 
			
		||||
  <outline id="outline9" corner-radius="1.000000">
 | 
			
		||||
    <point x="0.000000" y="0.000000"/>
 | 
			
		||||
    <point x="109.2682" y="0.000000"/>
 | 
			
		||||
    <point x="109.2682" y="52.44877"/>
 | 
			
		||||
    <point x="0.000000" y="52.44877"/>
 | 
			
		||||
  </outline>
 | 
			
		||||
  <outline id="outline10" corner-radius="1.000000">
 | 
			
		||||
    <point x="0.000000" y="0.000000"/>
 | 
			
		||||
    <point x="37.46341" y="0.000000"/>
 | 
			
		||||
    <point x="37.46341" y="52.44877"/>
 | 
			
		||||
    <point x="0.000000" y="52.44877"/>
 | 
			
		||||
  </outline>
 | 
			
		||||
  <outline id="outline13" corner-radius="1.000000">
 | 
			
		||||
    <point x="0.000000" y="0.000000"/>
 | 
			
		||||
    <point x="79.60975" y="0.000000"/>
 | 
			
		||||
    <point x="79.60975" y="52.44877"/>
 | 
			
		||||
    <point x="0.000000" y="52.44877"/>
 | 
			
		||||
  </outline>
 | 
			
		||||
  <outline id="spaceline" corner-radius="1.000000">
 | 
			
		||||
    <point x="0.000000" y="0.000000"/>
 | 
			
		||||
    <point x="120.5853" y="0.000000"/>
 | 
			
		||||
    <point x="120.5853" y="52.44877"/>
 | 
			
		||||
    <point x="0.000000" y="52.44877"/>
 | 
			
		||||
  </outline>
 | 
			
		||||
</geometry>
 | 
			
		||||
							
								
								
									
										126
									
								
								data/keyboards/geometry/url.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										126
									
								
								data/keyboards/geometry/url.xml
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,126 @@
 | 
			
		||||
<?xml version="1.0"?>
 | 
			
		||||
<geometry version="0.90">
 | 
			
		||||
  <bounds x="0" y="10.000000" width="426.0000" height="296.5853"/>
 | 
			
		||||
  <section angle="0">
 | 
			
		||||
    <row orientation="1">
 | 
			
		||||
      <key name="AD01" oref="outline2" />
 | 
			
		||||
      <key name="AD02" oref="outline2" />
 | 
			
		||||
      <key name="AD03" oref="outline2" />
 | 
			
		||||
      <key name="AD04" oref="outline2" />
 | 
			
		||||
      <key name="AD05" oref="outline2" />
 | 
			
		||||
      <key name="AD06" oref="outline2" />
 | 
			
		||||
      <key name="AD07" oref="outline2" />
 | 
			
		||||
      <key name="AD08" oref="outline2" />
 | 
			
		||||
      <key name="AD09" oref="outline2" />
 | 
			
		||||
      <key name="AD10" oref="outline2" />
 | 
			
		||||
      <key name="AE01" oref="outline6" />
 | 
			
		||||
      <key name="AE02" oref="outline2" />
 | 
			
		||||
      <key name="AE03" oref="outline6" />
 | 
			
		||||
      <key name="AE04" oref="outline6" />
 | 
			
		||||
      <key name="AE05" oref="outline6" />
 | 
			
		||||
      <key name="AE06" oref="outline6" />
 | 
			
		||||
    </row>
 | 
			
		||||
  </section>
 | 
			
		||||
  <section angle="0">
 | 
			
		||||
    <row orientation="1">
 | 
			
		||||
      <key name="AC01" oref="outline2" />
 | 
			
		||||
      <key name="AC02" oref="outline2" />
 | 
			
		||||
      <key name="AC03" oref="outline2" />
 | 
			
		||||
      <key name="AC04" oref="outline2" />
 | 
			
		||||
      <key name="AC05" oref="outline2" />
 | 
			
		||||
      <key name="AC06" oref="outline2" />
 | 
			
		||||
      <key name="AC07" oref="outline2" />
 | 
			
		||||
      <key name="AC08" oref="outline2" />
 | 
			
		||||
      <key name="AC09" oref="outline2" />
 | 
			
		||||
      <key name="AC10" oref="outline2" />
 | 
			
		||||
    </row>
 | 
			
		||||
  </section>
 | 
			
		||||
  <section angle="0">
 | 
			
		||||
    <row orientation="1">
 | 
			
		||||
      <key name="LFSH" oref="altline" />
 | 
			
		||||
      <key name="AB01" oref="outline2" />
 | 
			
		||||
      <key name="AB02" oref="outline2" />
 | 
			
		||||
      <key name="AB03" oref="outline2" />
 | 
			
		||||
      <key name="AB04" oref="outline2" />
 | 
			
		||||
      <key name="AB05" oref="outline2" />
 | 
			
		||||
      <key name="AB06" oref="outline2" />
 | 
			
		||||
      <key name="AB07" oref="outline2" />
 | 
			
		||||
      <key name="BKSP" oref="altline" />
 | 
			
		||||
    </row>
 | 
			
		||||
  </section>
 | 
			
		||||
  <section angle="0">
 | 
			
		||||
    <row orientation="1">
 | 
			
		||||
      <key keycode="0" name="ABC123" oref="altline" />
 | 
			
		||||
      <key name="I149" oref="altline" />
 | 
			
		||||
      <key name="SPCE" oref="spaceline" />
 | 
			
		||||
      <key name="AB08" oref="outline2" />
 | 
			
		||||
      <key name="RTRN" oref="outline7" />
 | 
			
		||||
    </row>
 | 
			
		||||
  </section>
 | 
			
		||||
  <outline id="outline2" corner-radius="1.000000">
 | 
			
		||||
    <point x="0.000000" y="0.000000"/>
 | 
			
		||||
    <point x="37.46341" y="0.000000"/>
 | 
			
		||||
    <point x="37.46341" y="52.44877"/>
 | 
			
		||||
    <point x="0.000000" y="52.44877"/>
 | 
			
		||||
  </outline>
 | 
			
		||||
  <outline id="altline" corner-radius="1.000000">
 | 
			
		||||
    <point x="0.000000" y="0.000000"/>
 | 
			
		||||
    <point x="48.39024" y="0.000000"/>
 | 
			
		||||
    <point x="48.39024" y="52.44877"/>
 | 
			
		||||
    <point x="0.000000" y="52.44877"/>
 | 
			
		||||
  </outline>
 | 
			
		||||
  <outline id="outline4" corner-radius="1.000000">
 | 
			
		||||
    <point x="0.000000" y="0.000000"/>
 | 
			
		||||
    <point x="59.31707" y="0.000000"/>
 | 
			
		||||
    <point x="59.31707" y="52.44877"/>
 | 
			
		||||
    <point x="0.000000" y="52.44877"/>
 | 
			
		||||
  </outline>
 | 
			
		||||
  <outline id="outline5" corner-radius="1.000000">
 | 
			
		||||
    <point x="0.000000" y="0.000000"/>
 | 
			
		||||
    <point x="59.31707" y="0.000000"/>
 | 
			
		||||
    <point x="59.31707" y="52.44877"/>
 | 
			
		||||
    <point x="0.000000" y="52.44877"/>
 | 
			
		||||
  </outline>
 | 
			
		||||
  <outline id="outline6" corner-radius="1.000000">
 | 
			
		||||
    <point x="0.000000" y="0.000000"/>
 | 
			
		||||
    <point x="68.68292" y="0.000000"/>
 | 
			
		||||
    <point x="68.68292" y="52.44877"/>
 | 
			
		||||
    <point x="0.000000" y="52.44877"/>
 | 
			
		||||
  </outline>
 | 
			
		||||
  <outline id="outline7" corner-radius="1.000000">
 | 
			
		||||
    <point x="0.000000" y="0.000000"/>
 | 
			
		||||
    <point x="88.97561" y="0.000000"/>
 | 
			
		||||
    <point x="88.97561" y="52.44877"/>
 | 
			
		||||
    <point x="0.000000" y="52.44877"/>
 | 
			
		||||
  </outline>
 | 
			
		||||
  <outline id="outline8" corner-radius="1.000000">
 | 
			
		||||
    <point x="0.000000" y="0.000000"/>
 | 
			
		||||
    <point x="88.97561" y="0.000000"/>
 | 
			
		||||
    <point x="88.97561" y="52.44877"/>
 | 
			
		||||
    <point x="0.000000" y="52.44877"/>
 | 
			
		||||
  </outline>
 | 
			
		||||
  <outline id="outline9" corner-radius="1.000000">
 | 
			
		||||
    <point x="0.000000" y="0.000000"/>
 | 
			
		||||
    <point x="109.2682" y="0.000000"/>
 | 
			
		||||
    <point x="109.2682" y="52.44877"/>
 | 
			
		||||
    <point x="0.000000" y="52.44877"/>
 | 
			
		||||
  </outline>
 | 
			
		||||
  <outline id="outline10" corner-radius="1.000000">
 | 
			
		||||
    <point x="0.000000" y="0.000000"/>
 | 
			
		||||
    <point x="37.46341" y="0.000000"/>
 | 
			
		||||
    <point x="37.46341" y="52.44877"/>
 | 
			
		||||
    <point x="0.000000" y="52.44877"/>
 | 
			
		||||
  </outline>
 | 
			
		||||
  <outline id="outline13" corner-radius="1.000000">
 | 
			
		||||
    <point x="0.000000" y="0.000000"/>
 | 
			
		||||
    <point x="79.60975" y="0.000000"/>
 | 
			
		||||
    <point x="79.60975" y="52.44877"/>
 | 
			
		||||
    <point x="0.000000" y="52.44877"/>
 | 
			
		||||
  </outline>
 | 
			
		||||
  <outline id="spaceline" corner-radius="1.000000">
 | 
			
		||||
    <point x="0.000000" y="0.000000"/>
 | 
			
		||||
    <point x="150.5853" y="0.000000"/>
 | 
			
		||||
    <point x="150.5853" y="52.44877"/>
 | 
			
		||||
    <point x="0.000000" y="52.44877"/>
 | 
			
		||||
  </outline>
 | 
			
		||||
</geometry>
 | 
			
		||||
@ -1,98 +0,0 @@
 | 
			
		||||
---
 | 
			
		||||
row_spacing: 11.33
 | 
			
		||||
button_spacing: 4.67
 | 
			
		||||
 | 
			
		||||
bounds: { x: 0, y: 1, width: 360, height: 198 }
 | 
			
		||||
 | 
			
		||||
outlines:
 | 
			
		||||
    default:
 | 
			
		||||
        bounds: { x: 0, y: 0, width: 30.67, height: 40.67 }
 | 
			
		||||
    altline:
 | 
			
		||||
        bounds: { x: 0, y: 0, width: 48, height: 40.67 }
 | 
			
		||||
    wide:
 | 
			
		||||
        bounds: { x: 0, y: 0, width: 57.33, height: 40.67 }
 | 
			
		||||
    spaceline:
 | 
			
		||||
        bounds: { x: 0, y: 0, width: 95.00, height: 40.67 }
 | 
			
		||||
    special:
 | 
			
		||||
        bounds: { x: 0, y: 0, width: 39.33, height: 40.67 }
 | 
			
		||||
 | 
			
		||||
views:
 | 
			
		||||
    base:
 | 
			
		||||
        - "q w e r t y u i o p"
 | 
			
		||||
        - "a s d f g h j k l n"
 | 
			
		||||
        - "Shift_L   z x c v b n m  BackSpace"
 | 
			
		||||
        - "show_numbers show_eschar preferences         space        ? period Return"
 | 
			
		||||
    upper:
 | 
			
		||||
        - "Q W E R T Y U I O P"
 | 
			
		||||
        - "A S D F G H J K L Ñ"
 | 
			
		||||
        - "Shift_L   Z X C V B N M  BackSpace"
 | 
			
		||||
        - "show_numbers show_eschar preferences         space        ? period Return"
 | 
			
		||||
    numbers:
 | 
			
		||||
        - "1 2 3 4 5 6 7 8 9 0"
 | 
			
		||||
        - "@ # € % & - _ + ( )"
 | 
			
		||||
        - "show_symbols   , \" ' colon ; ! ?  BackSpace"
 | 
			
		||||
        - "show_letters show_eschar preferences         space        ? period Return"
 | 
			
		||||
    symbols:
 | 
			
		||||
        - "~ ` | · √ π τ ÷ × ¶"
 | 
			
		||||
        - "© ® £ $ ¥ ^ ° * { }"
 | 
			
		||||
        - "show_numbers_from_symbols   \\ / < > = [ ]  BackSpace"
 | 
			
		||||
        - "show_letters show_eschar preferences         space        ? period Return"
 | 
			
		||||
    eschar:
 | 
			
		||||
        - "á é í ó ú Á É Í Ó Ú"
 | 
			
		||||
        - "à è ì ò « » ù ! { }"
 | 
			
		||||
        - "show_numbers_from_symbols   \\ / < > = [ ]  BackSpace"
 | 
			
		||||
        - "show_letters show_symbols preferences         space        ? period Return"
 | 
			
		||||
 | 
			
		||||
buttons:
 | 
			
		||||
    Shift_L:
 | 
			
		||||
        action:
 | 
			
		||||
            locking:
 | 
			
		||||
                lock_view: "upper"
 | 
			
		||||
                unlock_view: "base"
 | 
			
		||||
        outline: "altline"
 | 
			
		||||
        icon: "key-shift"
 | 
			
		||||
    BackSpace:
 | 
			
		||||
        outline: "altline"
 | 
			
		||||
        icon: "edit-clear-symbolic"
 | 
			
		||||
    preferences:
 | 
			
		||||
        action: "show_prefs"
 | 
			
		||||
        outline: "default"
 | 
			
		||||
        icon: "keyboard-mode-symbolic"
 | 
			
		||||
    show_numbers:
 | 
			
		||||
        action:
 | 
			
		||||
            set_view: "numbers"
 | 
			
		||||
        outline: "altline"
 | 
			
		||||
        label: "123"
 | 
			
		||||
    show_numbers_from_symbols:
 | 
			
		||||
        action:
 | 
			
		||||
            set_view: "numbers"
 | 
			
		||||
        outline: "altline"
 | 
			
		||||
        label: "123"
 | 
			
		||||
    show_letters:
 | 
			
		||||
        action:
 | 
			
		||||
            set_view: "base"
 | 
			
		||||
        outline: "altline"
 | 
			
		||||
        label: "ABC"
 | 
			
		||||
    show_symbols:
 | 
			
		||||
        action:
 | 
			
		||||
            set_view: "symbols"
 | 
			
		||||
        outline: "altline"
 | 
			
		||||
        label: "*/="
 | 
			
		||||
    show_eschar:
 | 
			
		||||
        action:
 | 
			
		||||
            set_view: "eschar"
 | 
			
		||||
        outline: "altline"
 | 
			
		||||
        label: "àè"
 | 
			
		||||
    period:
 | 
			
		||||
        outline: "default"
 | 
			
		||||
        label: "."
 | 
			
		||||
    space:
 | 
			
		||||
        outline: "spaceline"
 | 
			
		||||
        label: " "
 | 
			
		||||
    Return:
 | 
			
		||||
        outline: "altline"
 | 
			
		||||
        icon: "key-enter"
 | 
			
		||||
    colon:
 | 
			
		||||
        label: ":"
 | 
			
		||||
    "\"":
 | 
			
		||||
        keysym: "quotedbl"
 | 
			
		||||
							
								
								
									
										106
									
								
								data/keyboards/keyboards.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										106
									
								
								data/keyboards/keyboards.xml
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,106 @@
 | 
			
		||||
<?xml version="1.0"?>
 | 
			
		||||
<keyboards version="0.90">
 | 
			
		||||
  <keyboard id="ar" name="ar"
 | 
			
		||||
	    geometry="compact" symbols="ar"
 | 
			
		||||
	    longname="Arabic" language="ar"/>
 | 
			
		||||
  <keyboard id="be" name="be"
 | 
			
		||||
	    geometry="compact" symbols="be"
 | 
			
		||||
	    longname="Belarusian" language="be"/>
 | 
			
		||||
  <keyboard id="fa" name="fa"
 | 
			
		||||
	    geometry="compact" symbols="fa"
 | 
			
		||||
	    longname="Farsi (ISIRI 2901-1994)" language="fa"/>
 | 
			
		||||
  <keyboard id="he" name="he"
 | 
			
		||||
	    geometry="compact" symbols="he"
 | 
			
		||||
	    longname="Hebrew" language="he"/>
 | 
			
		||||
  <keyboard id="ja" name="ja"
 | 
			
		||||
	    geometry="compact" symbols="ja-kana"
 | 
			
		||||
	    longname="Japanese (Kana)" language="ja"/>
 | 
			
		||||
  <keyboard id="kk" name="kk"
 | 
			
		||||
	    geometry="compact" symbols="kk"
 | 
			
		||||
	    longname="Kazakh" language="kk"/>
 | 
			
		||||
  <keyboard id="ks" name="ks"
 | 
			
		||||
	    geometry="compact" symbols="ks"
 | 
			
		||||
	    longname="Kashmiri" language="ks"/>
 | 
			
		||||
  <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"/>
 | 
			
		||||
  <keyboard id="th" name="th"
 | 
			
		||||
	    geometry="compact" symbols="th"
 | 
			
		||||
	    longname="Thai" language="th"/>
 | 
			
		||||
  <keyboard id="ua" name="ua"
 | 
			
		||||
	    geometry="compact" symbols="ua"
 | 
			
		||||
	    longname="Ukrainian" language="ua"/>
 | 
			
		||||
  <keyboard id="ug" name="ug"
 | 
			
		||||
	    geometry="compact" symbols="ug"
 | 
			
		||||
	    longname="Uyghur" language="ug"/>
 | 
			
		||||
  <keyboard id="us" name="us"
 | 
			
		||||
	    geometry="compact" symbols="us"
 | 
			
		||||
	    longname="US" language="en"/>
 | 
			
		||||
  <keyboard id="zh-bopomofo" name="zh-bopomofo"
 | 
			
		||||
	    geometry="compact" symbols="zh-bopomofo"
 | 
			
		||||
	    longname="Chinese (Bopomofo)" language="zh"/>
 | 
			
		||||
  <!-- Indic Inscript keyboards converted from m17n-lib -->
 | 
			
		||||
  <keyboard id="as-inscript" name="as-inscript"
 | 
			
		||||
	    geometry="compact" symbols="as-inscript"
 | 
			
		||||
	    longname="Assamese (Inscript)" language="as"/>
 | 
			
		||||
  <keyboard id="bn-inscript" name="bn-inscript"
 | 
			
		||||
	    geometry="compact" symbols="bn-inscript"
 | 
			
		||||
	    longname="Bengali (Inscript)" language="bn"/>
 | 
			
		||||
  <keyboard id="gu-inscript" name="gu-inscript"
 | 
			
		||||
	    geometry="compact" symbols="gu-inscript"
 | 
			
		||||
	    longname="Gujarati (Inscript)" language="gu"/>
 | 
			
		||||
  <keyboard id="hi-inscript" name="hi-inscript"
 | 
			
		||||
	    geometry="compact" symbols="hi-inscript"
 | 
			
		||||
	    longname="Hindi (Inscript)" language="hi"/>
 | 
			
		||||
  <keyboard id="kn-inscript" name="kn-inscript"
 | 
			
		||||
	    geometry="compact" symbols="kn-inscript"
 | 
			
		||||
	    longname="Kannada (Inscript)" language="kn"/>
 | 
			
		||||
  <keyboard id="ks-inscript" name="ks-inscript"
 | 
			
		||||
	    geometry="compact" symbols="ks-inscript"
 | 
			
		||||
	    longname="Kashmiri Devanagari (Inscript)" language="ks"/>
 | 
			
		||||
  <keyboard id="mai-inscript" name="mai-inscript"
 | 
			
		||||
	    geometry="compact" symbols="mai-inscript"
 | 
			
		||||
	    longname="Maithili (Inscript)" language="mai"/>
 | 
			
		||||
  <keyboard id="ml-inscript" name="ml-inscript"
 | 
			
		||||
	    geometry="compact" symbols="ml-inscript"
 | 
			
		||||
	    longname="Malayalam (Inscript)" language="ml-inscript"/>
 | 
			
		||||
  <keyboard id="mr-inscript" name="mr-inscript"
 | 
			
		||||
	    geometry="compact" symbols="mr-inscript"
 | 
			
		||||
	    longname="Marathi (Inscript)" language="mr"/>
 | 
			
		||||
  <keyboard id="or-inscript" name="or-inscript"
 | 
			
		||||
	    geometry="compact" symbols="or-inscript"
 | 
			
		||||
	    longname="Oriya (Inscript)" language="or"/>
 | 
			
		||||
  <keyboard id="pa-inscript" name="pa-inscript"
 | 
			
		||||
	    geometry="compact" symbols="pa-inscript"
 | 
			
		||||
	    longname="Punjabi (Inscript)" language="pa"/>
 | 
			
		||||
  <keyboard id="sd-inscript" name="sd-inscript"
 | 
			
		||||
	    geometry="compact" symbols="sd-inscript"
 | 
			
		||||
	    longname="Sindhi (Inscript)" language="sd"/>
 | 
			
		||||
  <keyboard id="ta-inscript" name="ta-inscript"
 | 
			
		||||
	    geometry="compact" symbols="ta-inscript"
 | 
			
		||||
	    longname="Tamil (Inscript)" language="ta"/>
 | 
			
		||||
  <keyboard id="te-inscript" name="te-inscript"
 | 
			
		||||
	    geometry="compact" symbols="te-inscript"
 | 
			
		||||
	    longname="Telugu (Inscript)" language="te"/>
 | 
			
		||||
 | 
			
		||||
  <!-- Common keyboards -->
 | 
			
		||||
  <keyboard id="digits" name="digits"
 | 
			
		||||
	    geometry="digits" symbols="special/digits"
 | 
			
		||||
	    longname="Digits" language="all"/>
 | 
			
		||||
  <keyboard id="number" name="number"
 | 
			
		||||
	    geometry="number-keypad" symbols="special/number"
 | 
			
		||||
	    longname="Numeric keypad" language="all"/>
 | 
			
		||||
  <keyboard id="phone" name="phone"
 | 
			
		||||
	    geometry="phone-keypad" symbols="special/phone"
 | 
			
		||||
	    longname="Phone keypad" language="all"/>
 | 
			
		||||
  <keyboard id="url" name="url"
 | 
			
		||||
	    geometry="url" symbols="special/url"
 | 
			
		||||
	    longname="Uniform Resource Locator" language="all"/>
 | 
			
		||||
 | 
			
		||||
</keyboards>
 | 
			
		||||
@ -1,178 +0,0 @@
 | 
			
		||||
---
 | 
			
		||||
row_spacing: 11.33
 | 
			
		||||
button_spacing: 4.67
 | 
			
		||||
 | 
			
		||||
bounds: { x: 0, y: 6.33, width: 426, height: 250 }
 | 
			
		||||
 | 
			
		||||
outlines:
 | 
			
		||||
    default:
 | 
			
		||||
        bounds: { x: 0, y: 0, width: 32, height: 52 }
 | 
			
		||||
    altline:
 | 
			
		||||
        bounds: { x: 0, y: 0, width: 48.39024, height: 52 }
 | 
			
		||||
    outline7:
 | 
			
		||||
        bounds: { x: 0, y: 0, width: 88.97561, height: 52 }
 | 
			
		||||
    spaceline:
 | 
			
		||||
        bounds: { x: 0, y: 0, width: 150.5853, height: 52 }
 | 
			
		||||
 | 
			
		||||
views:
 | 
			
		||||
    base:
 | 
			
		||||
        - "q w e r t y u i o p aring"
 | 
			
		||||
        - "a s d f g h j k l oslash ae"
 | 
			
		||||
        - "Shift_L   z x c v b n m  BackSpace"
 | 
			
		||||
        - "show_numbers preferences         space        period    Return"
 | 
			
		||||
    upper:
 | 
			
		||||
        - "Q W E R T Y U I O P Aring"
 | 
			
		||||
        - "A S D F G H J K L Oslash AE"
 | 
			
		||||
        - "Shift_L   Z X C V B N M  BackSpace"
 | 
			
		||||
        - "show_numbers preferences         space        period    Return"
 | 
			
		||||
    numbers:
 | 
			
		||||
        - "1 2 3 4 5 6 7 8 9 0"
 | 
			
		||||
        - "at numbersign dollar percent ampersand minus underscore plus parenleft parenright"
 | 
			
		||||
        - "show_symbols   comma quotedbl quoteright colon semicolon exclam question  BackSpace"
 | 
			
		||||
        - "show_letters preferences         space        period    Return"
 | 
			
		||||
    symbols:
 | 
			
		||||
        - "asciitilde quoteleft bar U00B7 squareroot Greek_pi Greek_tau division multiply paragraph"
 | 
			
		||||
        - "copyright U00AE U00A3 EuroSign U00A5 asciicircum degree asterisk braceleft braceright"
 | 
			
		||||
        - "show_numbers   backslash slash less greater equal bracketleft bracketright  BackSpace"
 | 
			
		||||
        - "show_letters preferences         space        period    Return"
 | 
			
		||||
 | 
			
		||||
buttons:
 | 
			
		||||
    Shift_L:
 | 
			
		||||
        action:
 | 
			
		||||
            locking:
 | 
			
		||||
                lock_view: "upper"
 | 
			
		||||
                unlock_view: "base"
 | 
			
		||||
        outline: "altline"
 | 
			
		||||
        icon: "key-shift"
 | 
			
		||||
    BackSpace:
 | 
			
		||||
        outline: "altline"
 | 
			
		||||
        icon: "edit-clear-symbolic"
 | 
			
		||||
    preferences:
 | 
			
		||||
        action: "show_prefs"
 | 
			
		||||
        outline: "altline"
 | 
			
		||||
        icon: "keyboard-mode-symbolic"
 | 
			
		||||
    show_numbers:
 | 
			
		||||
        action:
 | 
			
		||||
            set_view: "numbers"
 | 
			
		||||
        outline: "altline"
 | 
			
		||||
        label: "123"
 | 
			
		||||
    show_letters:
 | 
			
		||||
        action:
 | 
			
		||||
            set_view: "base"
 | 
			
		||||
        outline: "altline"
 | 
			
		||||
        label: "ABC"
 | 
			
		||||
    show_symbols:
 | 
			
		||||
        action:
 | 
			
		||||
            set_view: "symbols"
 | 
			
		||||
        outline: "altline"
 | 
			
		||||
        label: "*/="
 | 
			
		||||
    period:
 | 
			
		||||
        outline: altline
 | 
			
		||||
        label: "."
 | 
			
		||||
    space:
 | 
			
		||||
        outline: spaceline
 | 
			
		||||
        label: " "
 | 
			
		||||
    Return:
 | 
			
		||||
        outline: outline7
 | 
			
		||||
        icon: "key-enter"
 | 
			
		||||
    aring:
 | 
			
		||||
        label: "å"
 | 
			
		||||
    Aring:
 | 
			
		||||
        label: "Å"
 | 
			
		||||
    oslash:
 | 
			
		||||
        label: "ø"
 | 
			
		||||
    Oslash:
 | 
			
		||||
        label: "Ø"
 | 
			
		||||
    ae:
 | 
			
		||||
        label: "æ"
 | 
			
		||||
    AE:
 | 
			
		||||
        label: "Æ"
 | 
			
		||||
    asterisk:
 | 
			
		||||
        label: "*"
 | 
			
		||||
    asciitilde:
 | 
			
		||||
        label: "~"
 | 
			
		||||
    quoteleft:
 | 
			
		||||
        label: "`"
 | 
			
		||||
    bar:
 | 
			
		||||
        label: "|"
 | 
			
		||||
    U00B7:
 | 
			
		||||
        label: "·"
 | 
			
		||||
    squareroot:
 | 
			
		||||
        label: "√"
 | 
			
		||||
    Greek_pi:
 | 
			
		||||
        label: "π"
 | 
			
		||||
    division:
 | 
			
		||||
        label: "÷"
 | 
			
		||||
    multiply:
 | 
			
		||||
        label: "×"
 | 
			
		||||
    paragraph:
 | 
			
		||||
        label: "¶"
 | 
			
		||||
    Greek_tau:
 | 
			
		||||
        label: "τ"
 | 
			
		||||
    copyright:
 | 
			
		||||
        label: "©"
 | 
			
		||||
    numbersign:
 | 
			
		||||
        label: "#"
 | 
			
		||||
    U00AE:
 | 
			
		||||
        label: "®"
 | 
			
		||||
    at:
 | 
			
		||||
        label: "@"
 | 
			
		||||
    dollar:
 | 
			
		||||
        label: "$"
 | 
			
		||||
    U00A3:
 | 
			
		||||
        label: "£"
 | 
			
		||||
    percent:
 | 
			
		||||
        label: "%"
 | 
			
		||||
    EuroSign:
 | 
			
		||||
        label: "€"
 | 
			
		||||
    ampersand:
 | 
			
		||||
        label: "&"
 | 
			
		||||
    U00A5:
 | 
			
		||||
        label: "¥"
 | 
			
		||||
    minus:
 | 
			
		||||
        label: "-"
 | 
			
		||||
    asciicircum:
 | 
			
		||||
        label: "^"
 | 
			
		||||
    underscore:
 | 
			
		||||
        label: "_"
 | 
			
		||||
    degree:
 | 
			
		||||
        label: "°"
 | 
			
		||||
    plus:
 | 
			
		||||
        label: "+"
 | 
			
		||||
    equal:
 | 
			
		||||
        label: "="
 | 
			
		||||
    parenleft:
 | 
			
		||||
        label: "("
 | 
			
		||||
    parenright:
 | 
			
		||||
        label: ")"
 | 
			
		||||
    braceleft:
 | 
			
		||||
        label: "{"
 | 
			
		||||
    braceright:
 | 
			
		||||
        label: "}"
 | 
			
		||||
    comma:
 | 
			
		||||
        label: ","
 | 
			
		||||
    backslash:
 | 
			
		||||
        label: "\\"
 | 
			
		||||
    slash:
 | 
			
		||||
        label: "/"
 | 
			
		||||
    quotedbl:
 | 
			
		||||
        label: "\""
 | 
			
		||||
    quoteright:
 | 
			
		||||
        label: "'"
 | 
			
		||||
    less:
 | 
			
		||||
        label: "<"
 | 
			
		||||
    greater:
 | 
			
		||||
        label: ">"
 | 
			
		||||
    colon:
 | 
			
		||||
        label: ":"
 | 
			
		||||
    semicolon:
 | 
			
		||||
        label: ";"
 | 
			
		||||
    exclam:
 | 
			
		||||
        label: "!"
 | 
			
		||||
    question:
 | 
			
		||||
        label: "?"
 | 
			
		||||
    bracketleft:
 | 
			
		||||
        label: "["
 | 
			
		||||
    bracketright:
 | 
			
		||||
        label: "]"
 | 
			
		||||
 | 
			
		||||
@ -1,46 +0,0 @@
 | 
			
		||||
---
 | 
			
		||||
row_spacing: 11.33
 | 
			
		||||
button_spacing: 4.67
 | 
			
		||||
 | 
			
		||||
bounds: { x: 0, y: 6.33, width: 410, height: 250 }
 | 
			
		||||
 | 
			
		||||
outlines:
 | 
			
		||||
    default:
 | 
			
		||||
        bounds: { x: 0, y: 0, width: 37.46341, height: 52 }
 | 
			
		||||
    altline:
 | 
			
		||||
        bounds: { x: 0, y: 0, width: 48.39024, height: 52 }
 | 
			
		||||
    outline7:
 | 
			
		||||
        bounds: { x: 0, y: 0, width: 88.97561, height: 52 }
 | 
			
		||||
    spaceline:
 | 
			
		||||
        bounds: { x: 0, y: 0, width: 120.5853, height: 52 }
 | 
			
		||||
 | 
			
		||||
views:
 | 
			
		||||
    base:
 | 
			
		||||
        - "1 2 3 parenleft parenright"
 | 
			
		||||
        - "4 5 6 numbersign asterisk"
 | 
			
		||||
        - "7 8 9 plus minus"
 | 
			
		||||
        - "BackSpace 0 space Return"
 | 
			
		||||
 | 
			
		||||
buttons:
 | 
			
		||||
    BackSpace:
 | 
			
		||||
        outline: "altline"
 | 
			
		||||
        icon: "edit-clear-symbolic"
 | 
			
		||||
    space:
 | 
			
		||||
        outline: spaceline
 | 
			
		||||
        label: " "
 | 
			
		||||
    Return:
 | 
			
		||||
        outline: outline7
 | 
			
		||||
        icon: "key-enter"
 | 
			
		||||
    asterisk:
 | 
			
		||||
        label: "*"
 | 
			
		||||
    numbersign:
 | 
			
		||||
        label: "#"
 | 
			
		||||
    minus:
 | 
			
		||||
        label: "-"
 | 
			
		||||
    plus:
 | 
			
		||||
        label: "+"
 | 
			
		||||
    parenleft:
 | 
			
		||||
        label: "("
 | 
			
		||||
    parenright:
 | 
			
		||||
        label: ")"
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										206
									
								
								data/keyboards/symbols/nb.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										206
									
								
								data/keyboards/symbols/nb.xml
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,206 @@
 | 
			
		||||
<?xml version='1.0' encoding='ASCII' standalone='yes'?>
 | 
			
		||||
<symbols version="0.90">
 | 
			
		||||
  <key name="AD01">
 | 
			
		||||
    <symbol label="q">q</symbol>
 | 
			
		||||
    <symbol label="Q">Q</symbol>
 | 
			
		||||
    <symbol label="1">1</symbol>
 | 
			
		||||
    <symbol label="~">asciitilde</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AD02">
 | 
			
		||||
    <symbol label="w">w</symbol>
 | 
			
		||||
    <symbol label="W">W</symbol>
 | 
			
		||||
    <symbol label="2">2</symbol>
 | 
			
		||||
    <symbol label="`">quoteleft</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AD03">
 | 
			
		||||
    <symbol label="e">e</symbol>
 | 
			
		||||
    <symbol label="E">E</symbol>
 | 
			
		||||
    <symbol label="3">3</symbol>
 | 
			
		||||
    <symbol label="|">bar</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AD04">
 | 
			
		||||
    <symbol label="r">r</symbol>
 | 
			
		||||
    <symbol label="R">R</symbol>
 | 
			
		||||
    <symbol label="4">4</symbol>
 | 
			
		||||
    <symbol label="·">U00B7</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AD05">
 | 
			
		||||
    <symbol label="t">t</symbol>
 | 
			
		||||
    <symbol label="T">T</symbol>
 | 
			
		||||
    <symbol label="5">5</symbol>
 | 
			
		||||
    <symbol label="√">squareroot</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AD06">
 | 
			
		||||
    <symbol label="y">y</symbol>
 | 
			
		||||
    <symbol label="Y">Y</symbol>
 | 
			
		||||
    <symbol label="6">6</symbol>
 | 
			
		||||
    <symbol label="π">Greek_pi</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AD07">
 | 
			
		||||
    <symbol label="u">u</symbol>
 | 
			
		||||
    <symbol label="U">U</symbol>
 | 
			
		||||
    <symbol label="7">7</symbol>
 | 
			
		||||
    <symbol label="÷">division</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AD08">
 | 
			
		||||
    <symbol label="i">i</symbol>
 | 
			
		||||
    <symbol label="I">I</symbol>
 | 
			
		||||
    <symbol label="8">8</symbol>
 | 
			
		||||
    <symbol label="×">multiply</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AD09">
 | 
			
		||||
    <symbol label="o">o</symbol>
 | 
			
		||||
    <symbol label="O">O</symbol>
 | 
			
		||||
    <symbol label="9">9</symbol>
 | 
			
		||||
    <symbol label="¶">paragraph</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AD10">
 | 
			
		||||
    <symbol label="p">p</symbol>
 | 
			
		||||
    <symbol label="P">P</symbol>
 | 
			
		||||
    <symbol label="0">0</symbol>
 | 
			
		||||
    <symbol label="△">U25B3</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AD11">
 | 
			
		||||
    <symbol keyval="229" label="å">aring</symbol>
 | 
			
		||||
    <symbol keyval="197" label="Å">Aring</symbol>
 | 
			
		||||
    <symbol label=""></symbol>
 | 
			
		||||
    <symbol label=""></symbol>
 | 
			
		||||
    <!-- Empty labels cause keys to be hidden when the level they are defined
 | 
			
		||||
         for is shown. -->
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AC01">
 | 
			
		||||
    <symbol label="a">a</symbol>
 | 
			
		||||
    <symbol label="A">A</symbol>
 | 
			
		||||
    <symbol label="@">at</symbol>
 | 
			
		||||
    <symbol label="©">copyright</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AC02">
 | 
			
		||||
    <symbol label="s">s</symbol>
 | 
			
		||||
    <symbol label="S">S</symbol>
 | 
			
		||||
    <symbol label="#">numbersign</symbol>
 | 
			
		||||
    <symbol label="®">U00AE</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AC03">
 | 
			
		||||
    <symbol label="d">d</symbol>
 | 
			
		||||
    <symbol label="D">D</symbol>
 | 
			
		||||
    <symbol label="$">dollar</symbol>
 | 
			
		||||
    <symbol label="£">U00A3</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AC04">
 | 
			
		||||
    <symbol label="f">f</symbol>
 | 
			
		||||
    <symbol label="F">F</symbol>
 | 
			
		||||
    <symbol label="%">percent</symbol>
 | 
			
		||||
    <symbol label="€">EuroSign</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AC05">
 | 
			
		||||
    <symbol label="g">g</symbol>
 | 
			
		||||
    <symbol label="G">G</symbol>
 | 
			
		||||
    <symbol label="&">ampersand</symbol>
 | 
			
		||||
    <symbol label="¥">U00A5</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AC06">
 | 
			
		||||
    <symbol label="h">h</symbol>
 | 
			
		||||
    <symbol label="H">H</symbol>
 | 
			
		||||
    <symbol label="-">minus</symbol>
 | 
			
		||||
    <symbol label="^">asciicircum</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AC07">
 | 
			
		||||
    <symbol label="j">j</symbol>
 | 
			
		||||
    <symbol label="J">J</symbol>
 | 
			
		||||
    <symbol label="_">underscore</symbol>
 | 
			
		||||
    <symbol label="°">degree</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AC08">
 | 
			
		||||
    <symbol label="k">k</symbol>
 | 
			
		||||
    <symbol label="K">K</symbol>
 | 
			
		||||
    <symbol label="+">plus</symbol>
 | 
			
		||||
    <symbol label="=">equal</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AC09">
 | 
			
		||||
    <symbol label="l">l</symbol>
 | 
			
		||||
    <symbol label="L">L</symbol>
 | 
			
		||||
    <symbol label="(">parenleft</symbol>
 | 
			
		||||
    <symbol label="{">braceleft</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AC10">
 | 
			
		||||
    <symbol keyval="248" label="ø">oslash</symbol>
 | 
			
		||||
    <symbol keyval="216" label="Ø">Oslash</symbol>
 | 
			
		||||
    <symbol label=")">parenright</symbol>
 | 
			
		||||
    <symbol label="}">braceright</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AC11">
 | 
			
		||||
    <symbol keyval="230" label="æ">ae</symbol>
 | 
			
		||||
    <symbol keyval="198" label="Æ">AE</symbol>
 | 
			
		||||
    <symbol label=""></symbol>
 | 
			
		||||
    <symbol label=""></symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="RTRN">
 | 
			
		||||
    <symbol keyval="65293" icon="key-enter">Return</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="LFSH">
 | 
			
		||||
    <keysym keyval="65505" icon="key-shift">Shift_L</keysym>
 | 
			
		||||
    <keysym keyval="65505" icon="key-shift">Shift_L</keysym>
 | 
			
		||||
    <keysym keyval="65505" label="=/+">Shift_L</keysym>
 | 
			
		||||
    <keysym keyval="65505" label="123">Shift_L</keysym>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AB01">
 | 
			
		||||
    <symbol label="z">z</symbol>
 | 
			
		||||
    <symbol label="Z">Z</symbol>
 | 
			
		||||
    <symbol label=",">comma</symbol>
 | 
			
		||||
    <symbol label="\">backslash</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AB02">
 | 
			
		||||
    <symbol label="x">x</symbol>
 | 
			
		||||
    <symbol label="X">X</symbol>
 | 
			
		||||
    <symbol label=""">quotedbl</symbol>
 | 
			
		||||
    <symbol label="/">slash</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AB03">
 | 
			
		||||
    <symbol label="c">c</symbol>
 | 
			
		||||
    <symbol label="C">C</symbol>
 | 
			
		||||
    <symbol label="'">quoteright</symbol>
 | 
			
		||||
    <symbol label="<">less</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AB04">
 | 
			
		||||
    <symbol label="v">v</symbol>
 | 
			
		||||
    <symbol label="V">V</symbol>
 | 
			
		||||
    <symbol label=":">colon</symbol>
 | 
			
		||||
    <symbol label=">">greater</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AB05">
 | 
			
		||||
    <symbol label="b">b</symbol>
 | 
			
		||||
    <symbol label="B">B</symbol>
 | 
			
		||||
    <symbol label=";">semicolon</symbol>
 | 
			
		||||
    <symbol label="=">equal</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AB06">
 | 
			
		||||
    <symbol label="n">n</symbol>
 | 
			
		||||
    <symbol label="N">N</symbol>
 | 
			
		||||
    <symbol label="!">exclam</symbol>
 | 
			
		||||
    <symbol label="[">bracketleft</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AB07">
 | 
			
		||||
    <symbol label="m">m</symbol>
 | 
			
		||||
    <symbol label="M">M</symbol>
 | 
			
		||||
    <symbol label="?">question</symbol>
 | 
			
		||||
    <symbol label="]">bracketright</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AB08">
 | 
			
		||||
    <symbol label=".">period</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="ABC123">
 | 
			
		||||
    <symbol label="123">show-numbers</symbol>
 | 
			
		||||
    <symbol label="123">show-numbers</symbol>
 | 
			
		||||
    <symbol label="ABC">show-letters</symbol>
 | 
			
		||||
    <symbol label="ABC">show-letters</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="I149">
 | 
			
		||||
    <symbol icon="keyboard-mode-symbolic" tooltip="Setup">preferences</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="SPCE">
 | 
			
		||||
    <symbol label=" ">space</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="BKSP">
 | 
			
		||||
    <symbol keyval="65288" icon="edit-clear-symbolic">BackSpace</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
</symbols>
 | 
			
		||||
							
								
								
									
										39
									
								
								data/keyboards/symbols/special/digits.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								data/keyboards/symbols/special/digits.xml
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,39 @@
 | 
			
		||||
<?xml version='1.0' encoding='ASCII' standalone='yes'?>
 | 
			
		||||
<symbols version="0.90">
 | 
			
		||||
  <key name="AD01">
 | 
			
		||||
    <symbol label="1">1</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AD02">
 | 
			
		||||
    <symbol label="2">2</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AD03">
 | 
			
		||||
    <symbol label="3">3</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AC01">
 | 
			
		||||
    <symbol label="4">4</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AC02">
 | 
			
		||||
    <symbol label="5">5</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AC03">
 | 
			
		||||
    <symbol label="6">6</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AB01">
 | 
			
		||||
    <symbol label="7">7</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AB02">
 | 
			
		||||
    <symbol label="8">8</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AB03">
 | 
			
		||||
    <symbol label="9">9</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AB04">
 | 
			
		||||
    <symbol label="0">0</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="RTRN">
 | 
			
		||||
    <symbol keyval="65293" icon="key-enter">Return</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="BKSP">
 | 
			
		||||
    <symbol keyval="65288" icon="edit-clear-symbolic">BackSpace</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
</symbols>
 | 
			
		||||
							
								
								
									
										60
									
								
								data/keyboards/symbols/special/number.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										60
									
								
								data/keyboards/symbols/special/number.xml
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,60 @@
 | 
			
		||||
<?xml version='1.0' encoding='ASCII' standalone='yes'?>
 | 
			
		||||
<symbols version="0.90">
 | 
			
		||||
  <key name="AD01">
 | 
			
		||||
    <symbol label="1">1</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AD02">
 | 
			
		||||
    <symbol label="2">2</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AD03">
 | 
			
		||||
    <symbol label="3">3</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AD04">
 | 
			
		||||
    <symbol label=".">period</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AD05">
 | 
			
		||||
    <symbol label=",">comma</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AC01">
 | 
			
		||||
    <symbol label="4">4</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AC02">
 | 
			
		||||
    <symbol label="5">5</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AC03">
 | 
			
		||||
    <symbol label="6">6</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AC04">
 | 
			
		||||
    <symbol label="/">slash</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AC05">
 | 
			
		||||
    <symbol label="*">asterisk</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AB01">
 | 
			
		||||
    <symbol label="7">7</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AB02">
 | 
			
		||||
    <symbol label="8">8</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AB03">
 | 
			
		||||
    <symbol label="9">9</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AB04">
 | 
			
		||||
    <symbol label="+">plus</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AB05">
 | 
			
		||||
    <symbol label="-">minus</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AB06">
 | 
			
		||||
    <symbol label="0">0</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="RTRN">
 | 
			
		||||
    <symbol keyval="65293" icon="key-enter">Return</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="SPCE">
 | 
			
		||||
    <symbol label=" ">space</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="BKSP">
 | 
			
		||||
    <symbol keyval="65288" icon="edit-clear-symbolic">BackSpace</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
</symbols>
 | 
			
		||||
							
								
								
									
										60
									
								
								data/keyboards/symbols/special/phone.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										60
									
								
								data/keyboards/symbols/special/phone.xml
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,60 @@
 | 
			
		||||
<?xml version='1.0' encoding='ASCII' standalone='yes'?>
 | 
			
		||||
<symbols version="0.90">
 | 
			
		||||
  <key name="AD01">
 | 
			
		||||
    <symbol label="1">1</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AD02">
 | 
			
		||||
    <symbol label="2">2</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AD03">
 | 
			
		||||
    <symbol label="3">3</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AD04">
 | 
			
		||||
    <symbol label="(">parenleft</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AD05">
 | 
			
		||||
    <symbol label=")">parenright</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AC01">
 | 
			
		||||
    <symbol label="4">4</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AC02">
 | 
			
		||||
    <symbol label="5">5</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AC03">
 | 
			
		||||
    <symbol label="6">6</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AC04">
 | 
			
		||||
    <symbol label="#">numbersign</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AC05">
 | 
			
		||||
    <symbol label="*">asterisk</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AB01">
 | 
			
		||||
    <symbol label="7">7</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AB02">
 | 
			
		||||
    <symbol label="8">8</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AB03">
 | 
			
		||||
    <symbol label="9">9</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AB04">
 | 
			
		||||
    <symbol label="+">plus</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AB05">
 | 
			
		||||
    <symbol label="-">minus</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AB06">
 | 
			
		||||
    <symbol label="0">0</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="RTRN">
 | 
			
		||||
    <symbol keyval="65293" icon="key-enter">Return</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="SPCE">
 | 
			
		||||
    <symbol label=" ">space</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="BKSP">
 | 
			
		||||
    <symbol keyval="65288" icon="edit-clear-symbolic">BackSpace</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
</symbols>
 | 
			
		||||
							
								
								
									
										231
									
								
								data/keyboards/symbols/special/url.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										231
									
								
								data/keyboards/symbols/special/url.xml
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,231 @@
 | 
			
		||||
<?xml version='1.0' encoding='ASCII' standalone='yes'?>
 | 
			
		||||
<symbols version="0.90">
 | 
			
		||||
  <key name="AD01">
 | 
			
		||||
    <symbol label="q">q</symbol>
 | 
			
		||||
    <symbol label="Q">Q</symbol>
 | 
			
		||||
    <symbol label=""></symbol>
 | 
			
		||||
    <symbol label="1">1</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AD02">
 | 
			
		||||
    <symbol label="w">w</symbol>
 | 
			
		||||
    <symbol label="W">W</symbol>
 | 
			
		||||
    <symbol label=""></symbol>
 | 
			
		||||
    <symbol label="2">2</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AD03">
 | 
			
		||||
    <symbol label="e">e</symbol>
 | 
			
		||||
    <symbol label="E">E</symbol>
 | 
			
		||||
    <symbol label=""></symbol>
 | 
			
		||||
    <symbol label="3">3</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AD04">
 | 
			
		||||
    <symbol label="r">r</symbol>
 | 
			
		||||
    <symbol label="R">R</symbol>
 | 
			
		||||
    <symbol label=""></symbol>
 | 
			
		||||
    <symbol label="4">4</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AD05">
 | 
			
		||||
    <symbol label="t">t</symbol>
 | 
			
		||||
    <symbol label="T">T</symbol>
 | 
			
		||||
    <symbol label=""></symbol>
 | 
			
		||||
    <symbol label="5">5</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AD06">
 | 
			
		||||
    <symbol label="y">y</symbol>
 | 
			
		||||
    <symbol label="Y">Y</symbol>
 | 
			
		||||
    <symbol label=""></symbol>
 | 
			
		||||
    <symbol label="6">6</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AD07">
 | 
			
		||||
    <symbol label="u">u</symbol>
 | 
			
		||||
    <symbol label="U">U</symbol>
 | 
			
		||||
    <symbol label=""></symbol>
 | 
			
		||||
    <symbol label="7">7</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AD08">
 | 
			
		||||
    <symbol label="i">i</symbol>
 | 
			
		||||
    <symbol label="I">I</symbol>
 | 
			
		||||
    <symbol label=""></symbol>
 | 
			
		||||
    <symbol label="8">8</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AD09">
 | 
			
		||||
    <symbol label="o">o</symbol>
 | 
			
		||||
    <symbol label="O">O</symbol>
 | 
			
		||||
    <symbol label=""></symbol>
 | 
			
		||||
    <symbol label="9">9</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AD10">
 | 
			
		||||
    <symbol label="p">p</symbol>
 | 
			
		||||
    <symbol label="P">P</symbol>
 | 
			
		||||
    <symbol label=""></symbol>
 | 
			
		||||
    <symbol label="0">0</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AC01">
 | 
			
		||||
    <symbol label="a">a</symbol>
 | 
			
		||||
    <symbol label="A">A</symbol>
 | 
			
		||||
    <symbol label="@">at</symbol>
 | 
			
		||||
    <symbol label="~">asciitilde</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AC02">
 | 
			
		||||
    <symbol label="s">s</symbol>
 | 
			
		||||
    <symbol label="S">S</symbol>
 | 
			
		||||
    <symbol label="#">numbersign</symbol>
 | 
			
		||||
    <symbol label="®">U00AE</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AC03">
 | 
			
		||||
    <symbol label="d">d</symbol>
 | 
			
		||||
    <symbol label="D">D</symbol>
 | 
			
		||||
    <symbol label="$">dollar</symbol>
 | 
			
		||||
    <symbol label="£">U00A3</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AC04">
 | 
			
		||||
    <symbol label="f">f</symbol>
 | 
			
		||||
    <symbol label="F">F</symbol>
 | 
			
		||||
    <symbol label="%">percent</symbol>
 | 
			
		||||
    <symbol label="€">EuroSign</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AC05">
 | 
			
		||||
    <symbol label="g">g</symbol>
 | 
			
		||||
    <symbol label="G">G</symbol>
 | 
			
		||||
    <symbol label="&">ampersand</symbol>
 | 
			
		||||
    <symbol label="¥">U00A5</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AC06">
 | 
			
		||||
    <symbol label="h">h</symbol>
 | 
			
		||||
    <symbol label="H">H</symbol>
 | 
			
		||||
    <symbol label="-">minus</symbol>
 | 
			
		||||
    <symbol label="^">asciicircum</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AC07">
 | 
			
		||||
    <symbol label="j">j</symbol>
 | 
			
		||||
    <symbol label="J">J</symbol>
 | 
			
		||||
    <symbol label="_">underscore</symbol>
 | 
			
		||||
    <symbol label="°">degree</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AC08">
 | 
			
		||||
    <symbol label="k">k</symbol>
 | 
			
		||||
    <symbol label="K">K</symbol>
 | 
			
		||||
    <symbol label="+">plus</symbol>
 | 
			
		||||
    <symbol label="=">equal</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AC09">
 | 
			
		||||
    <symbol label="l">l</symbol>
 | 
			
		||||
    <symbol label="L">L</symbol>
 | 
			
		||||
    <symbol label="(">parenleft</symbol>
 | 
			
		||||
    <symbol label="{">braceleft</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AC10">
 | 
			
		||||
    <symbol label=""></symbol>
 | 
			
		||||
    <symbol label=""></symbol>
 | 
			
		||||
    <symbol label=")">parenright</symbol>
 | 
			
		||||
    <symbol label="}">braceright</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="RTRN">
 | 
			
		||||
    <symbol keyval="65293" icon="key-enter">Return</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="LFSH">
 | 
			
		||||
    <keysym keyval="65505" icon="key-shift">Shift_L</keysym>
 | 
			
		||||
    <keysym keyval="65505" icon="key-shift">Shift_L</keysym>
 | 
			
		||||
    <keysym keyval="65505" label="123">Shift_L</keysym>
 | 
			
		||||
    <keysym keyval="65505" label="URL">Shift_L</keysym>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AB01">
 | 
			
		||||
    <symbol label="z">z</symbol>
 | 
			
		||||
    <symbol label="Z">Z</symbol>
 | 
			
		||||
    <symbol label=",">comma</symbol>
 | 
			
		||||
    <symbol label="\">backslash</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AB02">
 | 
			
		||||
    <symbol label="x">x</symbol>
 | 
			
		||||
    <symbol label="X">X</symbol>
 | 
			
		||||
    <symbol label=""">quotedbl</symbol>
 | 
			
		||||
    <symbol label="/">slash</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AB03">
 | 
			
		||||
    <symbol label="c">c</symbol>
 | 
			
		||||
    <symbol label="C">C</symbol>
 | 
			
		||||
    <symbol label="'">quoteright</symbol>
 | 
			
		||||
    <symbol label="<">less</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AB04">
 | 
			
		||||
    <symbol label="v">v</symbol>
 | 
			
		||||
    <symbol label="V">V</symbol>
 | 
			
		||||
    <symbol label=":">colon</symbol>
 | 
			
		||||
    <symbol label=">">greater</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AB05">
 | 
			
		||||
    <symbol label="b">b</symbol>
 | 
			
		||||
    <symbol label="B">B</symbol>
 | 
			
		||||
    <symbol label=";">semicolon</symbol>
 | 
			
		||||
    <symbol label="=">equal</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AB06">
 | 
			
		||||
    <symbol label="n">n</symbol>
 | 
			
		||||
    <symbol label="N">N</symbol>
 | 
			
		||||
    <symbol label="!">exclam</symbol>
 | 
			
		||||
    <symbol label="[">bracketleft</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AB07">
 | 
			
		||||
    <symbol label="m">m</symbol>
 | 
			
		||||
    <symbol label="M">M</symbol>
 | 
			
		||||
    <symbol label="?">question</symbol>
 | 
			
		||||
    <symbol label="]">bracketright</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AB08">
 | 
			
		||||
    <symbol label=".">period</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="ABC123">
 | 
			
		||||
    <symbol label="URL">show-url</symbol>
 | 
			
		||||
    <symbol label="URL">show-url</symbol>
 | 
			
		||||
    <symbol label="ABC">show-letters</symbol>
 | 
			
		||||
    <symbol label="ABC">show-letters</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="I149">
 | 
			
		||||
    <symbol label="☺" icon="keyboard-mode-symbolic" tooltip="Setup">preferences</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="SPCE">
 | 
			
		||||
    <symbol label=" ">space</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="BKSP">
 | 
			
		||||
    <symbol keyval="65288" icon="edit-clear-symbolic">BackSpace</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
 | 
			
		||||
<!-- Extra URL mode buttons -->
 | 
			
		||||
  <key name="AE01">
 | 
			
		||||
    <symbol label=""></symbol>
 | 
			
		||||
    <symbol label=""></symbol>
 | 
			
		||||
    <text label="https">https</text>
 | 
			
		||||
    <symbol label=""></symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AE02">
 | 
			
		||||
    <symbol label=""></symbol>
 | 
			
		||||
    <symbol label=""></symbol>
 | 
			
		||||
    <text label="://">://</text>
 | 
			
		||||
    <symbol label=""></symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AE03">
 | 
			
		||||
    <symbol label=""></symbol>
 | 
			
		||||
    <symbol label=""></symbol>
 | 
			
		||||
    <text label="www.">www.</text>
 | 
			
		||||
    <symbol label=""></symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AE04">
 | 
			
		||||
    <symbol label=""></symbol>
 | 
			
		||||
    <symbol label=""></symbol>
 | 
			
		||||
    <text label=".com">.com</text>
 | 
			
		||||
    <symbol label=""></symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AE05">
 | 
			
		||||
    <symbol label=""></symbol>
 | 
			
		||||
    <symbol label=""></symbol>
 | 
			
		||||
    <text label=".org">.org</text>
 | 
			
		||||
    <symbol label=""></symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AE06">
 | 
			
		||||
    <symbol label=""></symbol>
 | 
			
		||||
    <symbol label=""></symbol>
 | 
			
		||||
    <text label=".net">.net</text>
 | 
			
		||||
    <symbol label=""></symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
 | 
			
		||||
</symbols>
 | 
			
		||||
							
								
								
									
										194
									
								
								data/keyboards/symbols/us.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										194
									
								
								data/keyboards/symbols/us.xml
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,194 @@
 | 
			
		||||
<?xml version='1.0' encoding='ASCII' standalone='yes'?>
 | 
			
		||||
<symbols version="0.90">
 | 
			
		||||
  <key name="AD01">
 | 
			
		||||
    <symbol label="q">q</symbol>
 | 
			
		||||
    <symbol label="Q">Q</symbol>
 | 
			
		||||
    <symbol label="1">1</symbol>
 | 
			
		||||
    <symbol label="~">asciitilde</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AD02">
 | 
			
		||||
    <symbol label="w">w</symbol>
 | 
			
		||||
    <symbol label="W">W</symbol>
 | 
			
		||||
    <symbol label="2">2</symbol>
 | 
			
		||||
    <symbol label="`">quoteleft</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AD03">
 | 
			
		||||
    <symbol label="e">e</symbol>
 | 
			
		||||
    <symbol label="E">E</symbol>
 | 
			
		||||
    <symbol label="3">3</symbol>
 | 
			
		||||
    <symbol label="|">bar</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AD04">
 | 
			
		||||
    <symbol label="r">r</symbol>
 | 
			
		||||
    <symbol label="R">R</symbol>
 | 
			
		||||
    <symbol label="4">4</symbol>
 | 
			
		||||
    <symbol label="·">U00B7</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AD05">
 | 
			
		||||
    <symbol label="t">t</symbol>
 | 
			
		||||
    <symbol label="T">T</symbol>
 | 
			
		||||
    <symbol label="5">5</symbol>
 | 
			
		||||
    <symbol label="√">squareroot</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AD06">
 | 
			
		||||
    <symbol label="y">y</symbol>
 | 
			
		||||
    <symbol label="Y">Y</symbol>
 | 
			
		||||
    <symbol label="6">6</symbol>
 | 
			
		||||
    <symbol label="π">Greek_pi</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AD07">
 | 
			
		||||
    <symbol label="u">u</symbol>
 | 
			
		||||
    <symbol label="U">U</symbol>
 | 
			
		||||
    <symbol label="7">7</symbol>
 | 
			
		||||
    <symbol label="÷">division</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AD08">
 | 
			
		||||
    <symbol label="i">i</symbol>
 | 
			
		||||
    <symbol label="I">I</symbol>
 | 
			
		||||
    <symbol label="8">8</symbol>
 | 
			
		||||
    <symbol label="×">multiply</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AD09">
 | 
			
		||||
    <symbol label="o">o</symbol>
 | 
			
		||||
    <symbol label="O">O</symbol>
 | 
			
		||||
    <symbol label="9">9</symbol>
 | 
			
		||||
    <symbol label="¶">paragraph</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AD10">
 | 
			
		||||
    <symbol label="p">p</symbol>
 | 
			
		||||
    <symbol label="P">P</symbol>
 | 
			
		||||
    <symbol label="0">0</symbol>
 | 
			
		||||
    <symbol label="△">U25B3</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AC01">
 | 
			
		||||
    <symbol label="a">a</symbol>
 | 
			
		||||
    <symbol label="A">A</symbol>
 | 
			
		||||
    <symbol label="@">at</symbol>
 | 
			
		||||
    <symbol label="©">copyright</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AC02">
 | 
			
		||||
    <symbol label="s">s</symbol>
 | 
			
		||||
    <symbol label="S">S</symbol>
 | 
			
		||||
    <symbol label="#">numbersign</symbol>
 | 
			
		||||
    <symbol label="®">U00AE</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AC03">
 | 
			
		||||
    <symbol label="d">d</symbol>
 | 
			
		||||
    <symbol label="D">D</symbol>
 | 
			
		||||
    <symbol label="$">dollar</symbol>
 | 
			
		||||
    <symbol label="£">U00A3</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AC04">
 | 
			
		||||
    <symbol label="f">f</symbol>
 | 
			
		||||
    <symbol label="F">F</symbol>
 | 
			
		||||
    <symbol label="%">percent</symbol>
 | 
			
		||||
    <symbol label="€">EuroSign</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AC05">
 | 
			
		||||
    <symbol label="g">g</symbol>
 | 
			
		||||
    <symbol label="G">G</symbol>
 | 
			
		||||
    <symbol label="&">ampersand</symbol>
 | 
			
		||||
    <symbol label="¥">U00A5</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AC06">
 | 
			
		||||
    <symbol label="h">h</symbol>
 | 
			
		||||
    <symbol label="H">H</symbol>
 | 
			
		||||
    <symbol label="-">minus</symbol>
 | 
			
		||||
    <symbol label="^">asciicircum</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AC07">
 | 
			
		||||
    <symbol label="j">j</symbol>
 | 
			
		||||
    <symbol label="J">J</symbol>
 | 
			
		||||
    <symbol label="_">underscore</symbol>
 | 
			
		||||
    <symbol label="°">degree</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AC08">
 | 
			
		||||
    <symbol label="k">k</symbol>
 | 
			
		||||
    <symbol label="K">K</symbol>
 | 
			
		||||
    <symbol label="+">plus</symbol>
 | 
			
		||||
    <symbol label="=">equal</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AC09">
 | 
			
		||||
    <symbol label="l">l</symbol>
 | 
			
		||||
    <symbol label="L">L</symbol>
 | 
			
		||||
    <symbol label="(">parenleft</symbol>
 | 
			
		||||
    <symbol label="{">braceleft</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AC10">
 | 
			
		||||
    <!-- Empty labels cause keys to be hidden when the level they are defined
 | 
			
		||||
         for is shown. -->
 | 
			
		||||
    <symbol label=""></symbol>
 | 
			
		||||
    <symbol label=""></symbol>
 | 
			
		||||
    <symbol label=")">parenright</symbol>
 | 
			
		||||
    <symbol label="}">braceright</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="RTRN">
 | 
			
		||||
    <symbol keyval="65293" icon="key-enter">Return</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="LFSH">
 | 
			
		||||
    <keysym keyval="65505" icon="key-shift">Shift_L</keysym>
 | 
			
		||||
    <keysym keyval="65505" icon="key-shift">Shift_L</keysym>
 | 
			
		||||
    <keysym keyval="65505" label="=/+">Shift_L</keysym>
 | 
			
		||||
    <keysym keyval="65505" label="123">Shift_L</keysym>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AB01">
 | 
			
		||||
    <symbol label="z">z</symbol>
 | 
			
		||||
    <symbol label="Z">Z</symbol>
 | 
			
		||||
    <symbol label=",">comma</symbol>
 | 
			
		||||
    <symbol label="\">backslash</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AB02">
 | 
			
		||||
    <symbol label="x">x</symbol>
 | 
			
		||||
    <symbol label="X">X</symbol>
 | 
			
		||||
    <symbol label=""">quotedbl</symbol>
 | 
			
		||||
    <symbol label="/">slash</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AB03">
 | 
			
		||||
    <symbol label="c">c</symbol>
 | 
			
		||||
    <symbol label="C">C</symbol>
 | 
			
		||||
    <symbol label="'">quoteright</symbol>
 | 
			
		||||
    <symbol label="<">less</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AB04">
 | 
			
		||||
    <symbol label="v">v</symbol>
 | 
			
		||||
    <symbol label="V">V</symbol>
 | 
			
		||||
    <symbol label=":">colon</symbol>
 | 
			
		||||
    <symbol label=">">greater</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AB05">
 | 
			
		||||
    <symbol label="b">b</symbol>
 | 
			
		||||
    <symbol label="B">B</symbol>
 | 
			
		||||
    <symbol label=";">semicolon</symbol>
 | 
			
		||||
    <symbol label="=">equal</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AB06">
 | 
			
		||||
    <symbol label="n">n</symbol>
 | 
			
		||||
    <symbol label="N">N</symbol>
 | 
			
		||||
    <symbol label="!">exclam</symbol>
 | 
			
		||||
    <symbol label="[">bracketleft</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AB07">
 | 
			
		||||
    <symbol label="m">m</symbol>
 | 
			
		||||
    <symbol label="M">M</symbol>
 | 
			
		||||
    <symbol label="?">question</symbol>
 | 
			
		||||
    <symbol label="]">bracketright</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AB08">
 | 
			
		||||
    <symbol label=".">period</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="ABC123">
 | 
			
		||||
    <symbol label="123">show-numbers</symbol>
 | 
			
		||||
    <symbol label="123">show-numbers</symbol>
 | 
			
		||||
    <symbol label="ABC">show-letters</symbol>
 | 
			
		||||
    <symbol label="ABC">show-letters</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="I149">
 | 
			
		||||
    <symbol label="☺" icon="keyboard-mode-symbolic" tooltip="Setup">preferences</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="SPCE">
 | 
			
		||||
    <symbol label=" ">space</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="BKSP">
 | 
			
		||||
    <symbol keyval="65288" icon="edit-clear-symbolic">BackSpace</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
</symbols>
 | 
			
		||||
@ -1,88 +0,0 @@
 | 
			
		||||
---
 | 
			
		||||
row_spacing: 11.33
 | 
			
		||||
button_spacing: 4.67
 | 
			
		||||
 | 
			
		||||
bounds: { x: 0, y: 1, width: 360, height: 198 }
 | 
			
		||||
 | 
			
		||||
outlines:
 | 
			
		||||
    default:
 | 
			
		||||
        bounds: { x: 0, y: 0, width: 30.67, height: 40.67 }
 | 
			
		||||
    altline:
 | 
			
		||||
        bounds: { x: 0, y: 0, width: 48, height: 40.67 }
 | 
			
		||||
    wide:
 | 
			
		||||
        bounds: { x: 0, y: 0, width: 57.33, height: 40.67 }
 | 
			
		||||
    spaceline:
 | 
			
		||||
        bounds: { x: 0, y: 0, width: 137.33, height: 40.67 }
 | 
			
		||||
    special:
 | 
			
		||||
        bounds: { x: 0, y: 0, width: 39.33, height: 40.67 }
 | 
			
		||||
 | 
			
		||||
views:
 | 
			
		||||
    base:
 | 
			
		||||
        - "q w e r t y u i o p"
 | 
			
		||||
        - "a s d f g h j k l"
 | 
			
		||||
        - "Shift_L   z x c v b n m  BackSpace"
 | 
			
		||||
        - "show_numbers preferences         space        period Return"
 | 
			
		||||
    upper:
 | 
			
		||||
        - "Q W E R T Y U I O P"
 | 
			
		||||
        - "A S D F G H J K L"
 | 
			
		||||
        - "Shift_L   Z X C V B N M  BackSpace"
 | 
			
		||||
        - "show_numbers preferences         space        period Return"
 | 
			
		||||
    numbers:
 | 
			
		||||
        - "1 2 3 4 5 6 7 8 9 0"
 | 
			
		||||
        - "@ # $ % & - _ + ( )"
 | 
			
		||||
        - "show_symbols   , \" ' colon ; ! ?  BackSpace"
 | 
			
		||||
        - "show_letters preferences         space        period Return"
 | 
			
		||||
    symbols:
 | 
			
		||||
        - "~ ` | · √ π τ ÷ × ¶"
 | 
			
		||||
        - "© ® £ € ¥ ^ ° * { }"
 | 
			
		||||
        - "show_numbers_from_symbols   \\ / < > = [ ]  BackSpace"
 | 
			
		||||
        - "show_letters preferences         space        period Return"
 | 
			
		||||
 | 
			
		||||
buttons:
 | 
			
		||||
    Shift_L:
 | 
			
		||||
        action:
 | 
			
		||||
            locking:
 | 
			
		||||
                lock_view: "upper"
 | 
			
		||||
                unlock_view: "base"
 | 
			
		||||
        outline: "altline"
 | 
			
		||||
        icon: "key-shift"
 | 
			
		||||
    BackSpace:
 | 
			
		||||
        outline: "altline"
 | 
			
		||||
        icon: "edit-clear-symbolic"
 | 
			
		||||
    preferences:
 | 
			
		||||
        action: "show_prefs"
 | 
			
		||||
        outline: "special"
 | 
			
		||||
        icon: "keyboard-mode-symbolic"
 | 
			
		||||
    show_numbers:
 | 
			
		||||
        action:
 | 
			
		||||
            set_view: "numbers"
 | 
			
		||||
        outline: "wide"
 | 
			
		||||
        label: "123"
 | 
			
		||||
    show_numbers_from_symbols:
 | 
			
		||||
        action:
 | 
			
		||||
            set_view: "numbers"
 | 
			
		||||
        outline: "altline"
 | 
			
		||||
        label: "123"
 | 
			
		||||
    show_letters:
 | 
			
		||||
        action:
 | 
			
		||||
            set_view: "base"
 | 
			
		||||
        outline: "wide"
 | 
			
		||||
        label: "ABC"
 | 
			
		||||
    show_symbols:
 | 
			
		||||
        action:
 | 
			
		||||
            set_view: "symbols"
 | 
			
		||||
        outline: "altline"
 | 
			
		||||
        label: "*/="
 | 
			
		||||
    period:
 | 
			
		||||
        outline: "special"
 | 
			
		||||
        label: "."
 | 
			
		||||
    space:
 | 
			
		||||
        outline: "spaceline"
 | 
			
		||||
        label: " "
 | 
			
		||||
    Return:
 | 
			
		||||
        outline: "wide"
 | 
			
		||||
        icon: "key-enter"
 | 
			
		||||
    colon:
 | 
			
		||||
        label: ":"
 | 
			
		||||
    "\"":
 | 
			
		||||
        keysym: "quotedbl"
 | 
			
		||||
@ -6,5 +6,4 @@ Exec=squeekboard
 | 
			
		||||
Icon=squeekboard
 | 
			
		||||
Terminal=false
 | 
			
		||||
Type=Application
 | 
			
		||||
NoDisplay=true
 | 
			
		||||
Categories=GTK;Utility;
 | 
			
		||||
 | 
			
		||||
@ -2,6 +2,19 @@
 | 
			
		||||
<gresources>
 | 
			
		||||
  <gresource prefix="/sm/puri/squeekboard">
 | 
			
		||||
   <file compressed="true">style.css</file>
 | 
			
		||||
 | 
			
		||||
<!-- Keyboard layouts -->
 | 
			
		||||
   <file compressed="true" preprocess="xml-stripblanks">keyboards/geometry/compact.xml</file>
 | 
			
		||||
   <file compressed="true" preprocess="xml-stripblanks">keyboards/geometry/extended.xml</file>
 | 
			
		||||
   <file compressed="true" preprocess="xml-stripblanks">keyboards/geometry/digits.xml</file>
 | 
			
		||||
   <file compressed="true" preprocess="xml-stripblanks">keyboards/geometry/number-keypad.xml</file>
 | 
			
		||||
   <file compressed="true" preprocess="xml-stripblanks">keyboards/geometry/phone-keypad.xml</file>
 | 
			
		||||
   <file compressed="true" preprocess="xml-stripblanks">keyboards/geometry/url.xml</file>
 | 
			
		||||
 | 
			
		||||
<!-- Keyboard definitions -->
 | 
			
		||||
   <file compressed="true" preprocess="xml-stripblanks">keyboards/keyboards.xml</file>
 | 
			
		||||
 | 
			
		||||
<!-- Natural language keyboards -->
 | 
			
		||||
   <file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/ar.xml</file>
 | 
			
		||||
   <file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/as-inscript.xml</file>
 | 
			
		||||
   <file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/be.xml</file>
 | 
			
		||||
@ -19,6 +32,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>
 | 
			
		||||
@ -28,7 +42,15 @@
 | 
			
		||||
   <file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/th.xml</file>
 | 
			
		||||
   <file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/ua.xml</file>
 | 
			
		||||
   <file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/ug.xml</file>
 | 
			
		||||
   <file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/us.xml</file>
 | 
			
		||||
   <file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/zh-bopomofo.xml</file>
 | 
			
		||||
 | 
			
		||||
<!-- Special purpose keyboards -->
 | 
			
		||||
   <file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/special/digits.xml</file>
 | 
			
		||||
   <file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/special/number.xml</file>
 | 
			
		||||
   <file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/special/phone.xml</file>
 | 
			
		||||
   <file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/special/url.xml</file>
 | 
			
		||||
 | 
			
		||||
   <file>icons/key-enter.svg</file>
 | 
			
		||||
   <file>icons/key-shift.svg</file>
 | 
			
		||||
   <file>icons/keyboard-mode-symbolic.svg</file>
 | 
			
		||||
 | 
			
		||||
@ -1,41 +1,18 @@
 | 
			
		||||
sq_view {
 | 
			
		||||
.keyboard {
 | 
			
		||||
    background-color: rgba(0, 0, 0, 255);
 | 
			
		||||
    color: #ffffff;
 | 
			
		||||
    font-family: cantarell, sans-serif;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
sq_button {
 | 
			
		||||
.key {
 | 
			
		||||
    color: #deddda;
 | 
			
		||||
    background: #464448;
 | 
			
		||||
    border-style: solid;
 | 
			
		||||
    border-width: 1px;
 | 
			
		||||
    border-width: 0.5px;
 | 
			
		||||
    border-color: #5e5c64;
 | 
			
		||||
    border-radius: 3px;
 | 
			
		||||
    border-radius: 2px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
sq_button:active {
 | 
			
		||||
    background: #545256;
 | 
			
		||||
    border-color: #716e78;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
sq_button.altline,
 | 
			
		||||
sq_button.special,
 | 
			
		||||
sq_button.wide {
 | 
			
		||||
    background: #2b292f;
 | 
			
		||||
    border-color: #3e3a44
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
sq_button.locked {
 | 
			
		||||
    background: #ffffff;
 | 
			
		||||
    color: #2b292f;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#Return {
 | 
			
		||||
    background: #1c71d8;
 | 
			
		||||
    border-color: #1a5fb4
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#Return:active {
 | 
			
		||||
.key:active {
 | 
			
		||||
    background: #1c71d8;
 | 
			
		||||
    border-color: #3584e4;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										12
									
								
								debian/cargo/config
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										12
									
								
								debian/cargo/config
									
									
									
									
										vendored
									
									
								
							@ -1,12 +0,0 @@
 | 
			
		||||
# When modifying this file, consider instead
 | 
			
		||||
# to take advantage of the method that Cargo packagers use
 | 
			
		||||
# to set up all the necessary stuff automatically:
 | 
			
		||||
# https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=907629#30
 | 
			
		||||
 | 
			
		||||
[source.crates-io]
 | 
			
		||||
registry = 'https://github.com/rust-lang/crates.io-index'
 | 
			
		||||
replace-with = 'vendored-sources'
 | 
			
		||||
 | 
			
		||||
[source.vendored-sources]
 | 
			
		||||
directory = '/usr/share/cargo/registry'
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										19
									
								
								debian/changelog
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										19
									
								
								debian/changelog
									
									
									
									
										vendored
									
									
								
							@ -1,22 +1,3 @@
 | 
			
		||||
squeekboard (1.2.1) amber-phone; urgency=medium
 | 
			
		||||
 | 
			
		||||
  * Use different distribution
 | 
			
		||||
 | 
			
		||||
 -- Dorota Czaplejewicz <dorota.czaplejewicz@puri.sm>  Tue, 08 Oct 2019 10:56:10 +0000
 | 
			
		||||
 | 
			
		||||
squeekboard (1.2.0) unstable; urgency=medium
 | 
			
		||||
 | 
			
		||||
  * Use Cargo-based dependencies
 | 
			
		||||
 | 
			
		||||
 -- Dorota Czaplejewicz <dorota.czaplejewicz@puri.sm>  Tue, 24 Sep 2019 10:42:15 +0000
 | 
			
		||||
 | 
			
		||||
squeekboard (1.1.0) unstable; urgency=medium
 | 
			
		||||
 | 
			
		||||
  * Use new keyboard layout format
 | 
			
		||||
 | 
			
		||||
 -- Dorota Czaplejewicz <dorota.czaplejewicz@puri.sm>  Mon, 02 Sep 2019 10:12:02 +0000
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
squeekboard (1.0.10) unstable; urgency=medium
 | 
			
		||||
 | 
			
		||||
  * Use a shared DBus definition
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										9
									
								
								debian/control
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										9
									
								
								debian/control
									
									
									
									
										vendored
									
									
								
							@ -3,19 +3,12 @@ Section: x11
 | 
			
		||||
Priority: optional
 | 
			
		||||
Maintainer: Dorota Czaplejewicz <dorota.czaplejewicz@puri.sm>
 | 
			
		||||
Build-Depends:
 | 
			
		||||
 cargo,
 | 
			
		||||
 debhelper (>= 10),
 | 
			
		||||
 meson (>=0.51.0),
 | 
			
		||||
 ninja-build,
 | 
			
		||||
 meson (>=0.43.0),
 | 
			
		||||
 pkg-config,
 | 
			
		||||
 libglib2.0-dev,
 | 
			
		||||
 libgtk-3-dev,
 | 
			
		||||
 libcroco3-dev,
 | 
			
		||||
 librust-bitflags-1-dev (>= 1.0),
 | 
			
		||||
 librust-maplit-1-dev (>= 1.0),
 | 
			
		||||
 librust-serde-derive-1-dev (>= 1.0),
 | 
			
		||||
 librust-serde-yaml-0.8-dev (>= 0.8),
 | 
			
		||||
 librust-xkbcommon-0.4+wayland-dev (>= 0.4),
 | 
			
		||||
 libwayland-dev (>= 1.16),
 | 
			
		||||
 rustc,
 | 
			
		||||
 wayland-protocols (>= 1.14),
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										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: squeekboard
 | 
			
		||||
Source: https://source.puri.sm/Librem5/squeekboard
 | 
			
		||||
Upstream-Name: evscript
 | 
			
		||||
Source: https://source.puri.sm/david.boddie/evscript
 | 
			
		||||
 | 
			
		||||
Files: *
 | 
			
		||||
Copyright: 2010-2011 Daiki Ueno <ueno@unixuser.org>
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										7
									
								
								debian/rules
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										7
									
								
								debian/rules
									
									
									
									
										vendored
									
									
								
							@ -1,15 +1,8 @@
 | 
			
		||||
#!/usr/bin/make -f
 | 
			
		||||
 | 
			
		||||
export CARGO_HOME = $(CURDIR)/debian/cargo
 | 
			
		||||
export DEB_BUILD_MAINT_OPTIONS = hardening=+all
 | 
			
		||||
 | 
			
		||||
%:
 | 
			
		||||
	dh $@ --builddirectory=_build --buildsystem=meson
 | 
			
		||||
 | 
			
		||||
# The Debian version of linked-hash-map doesn't provide any hash,
 | 
			
		||||
# causing Cargo to refuse to build with a crates.io copy
 | 
			
		||||
build-arch:
 | 
			
		||||
	rm Cargo.lock
 | 
			
		||||
	dh $@ --builddirectory=_build --buildsystem=meson
 | 
			
		||||
 | 
			
		||||
override_dh_autoreconf:
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										2
									
								
								debian/squeekboard.lintian-overrides
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								debian/squeekboard.lintian-overrides
									
									
									
									
										vendored
									
									
								
							@ -1,2 +0,0 @@
 | 
			
		||||
# yaml-rust 0.4.3 shares some roots with libyaml, including the string which lintian checks, creating a false positive
 | 
			
		||||
squeekboard binary: embedded-library usr/bin/squeekboard: libyaml
 | 
			
		||||
							
								
								
									
										232
									
								
								eek/eek-container.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										232
									
								
								eek/eek-container.c
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,232 @@
 | 
			
		||||
/* 
 | 
			
		||||
 * 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.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "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 = (EekContainerPrivate*)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);
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										94
									
								
								eek/eek-container.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										94
									
								
								eek/eek-container.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,94 @@
 | 
			
		||||
/* 
 | 
			
		||||
 * 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 */
 | 
			
		||||
@ -31,23 +31,51 @@
 | 
			
		||||
#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);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -60,9 +88,19 @@ 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));
 | 
			
		||||
        break;
 | 
			
		||||
    default:
 | 
			
		||||
        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 | 
			
		||||
        break;
 | 
			
		||||
@ -79,10 +117,19 @@ 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;
 | 
			
		||||
@ -96,10 +143,26 @@ 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:
 | 
			
		||||
     *
 | 
			
		||||
@ -113,12 +176,149 @@ 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)
 | 
			
		||||
{
 | 
			
		||||
    (void)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;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@ -161,3 +361,211 @@ 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,10 +36,18 @@ 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);
 | 
			
		||||
 | 
			
		||||
@ -51,5 +59,29 @@ 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 */
 | 
			
		||||
 | 
			
		||||
@ -32,13 +32,16 @@
 | 
			
		||||
#include <math.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
#include "eek-gtk-keyboard.h"
 | 
			
		||||
#include "eek-renderer.h"
 | 
			
		||||
#include "eek-keyboard.h"
 | 
			
		||||
 | 
			
		||||
#include "eek-gtk-keyboard.h"
 | 
			
		||||
#include "eek-section.h"
 | 
			
		||||
#include "eek-key.h"
 | 
			
		||||
#include "eek-symbol.h"
 | 
			
		||||
 | 
			
		||||
enum {
 | 
			
		||||
    PROP_0,
 | 
			
		||||
    PROP_KEYBOARD,
 | 
			
		||||
    PROP_LAST
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
@ -51,23 +54,25 @@ enum {
 | 
			
		||||
typedef struct _EekGtkKeyboardPrivate
 | 
			
		||||
{
 | 
			
		||||
    EekRenderer *renderer;
 | 
			
		||||
    LevelKeyboard *keyboard;
 | 
			
		||||
    EekKeyboard *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_button_pressed          (struct squeek_button *button, struct squeek_view *view,
 | 
			
		||||
                                              EekGtkKeyboard *self);
 | 
			
		||||
static void       on_button_released         (const struct squeek_button *button,
 | 
			
		||||
                                              struct squeek_view *view,
 | 
			
		||||
                                              EekGtkKeyboard *self);
 | 
			
		||||
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,
 | 
			
		||||
                                              const struct squeek_button *button);
 | 
			
		||||
static void       on_key_pressed          (EekKey      *key,
 | 
			
		||||
                                           EekGtkKeyboard *self);
 | 
			
		||||
static void       on_key_released         (EekKey      *key,
 | 
			
		||||
                                           EekGtkKeyboard *self);
 | 
			
		||||
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
 | 
			
		||||
eek_gtk_keyboard_real_realize (GtkWidget      *self)
 | 
			
		||||
@ -78,8 +83,7 @@ eek_gtk_keyboard_real_realize (GtkWidget      *self)
 | 
			
		||||
                           GDK_KEY_RELEASE_MASK |
 | 
			
		||||
                           GDK_BUTTON_PRESS_MASK |
 | 
			
		||||
                           GDK_BUTTON_RELEASE_MASK |
 | 
			
		||||
                           GDK_BUTTON_MOTION_MASK |
 | 
			
		||||
                           GDK_TOUCH_MASK);
 | 
			
		||||
                           GDK_BUTTON_MOTION_MASK);
 | 
			
		||||
 | 
			
		||||
    GTK_WIDGET_CLASS (eek_gtk_keyboard_parent_class)->realize (self);
 | 
			
		||||
}
 | 
			
		||||
@ -91,12 +95,14 @@ 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 = gtk_widget_get_pango_context (self);
 | 
			
		||||
 | 
			
		||||
        priv->renderer = eek_renderer_new (priv->keyboard, pcontext);
 | 
			
		||||
        priv->renderer = eek_renderer_new (priv->keyboard, pcontext, priv->scontext);
 | 
			
		||||
 | 
			
		||||
        eek_renderer_set_allocation_size (priv->renderer,
 | 
			
		||||
                                          allocation.width,
 | 
			
		||||
@ -107,27 +113,19 @@ eek_gtk_keyboard_real_draw (GtkWidget *self,
 | 
			
		||||
 | 
			
		||||
    eek_renderer_render_keyboard (priv->renderer, cr);
 | 
			
		||||
 | 
			
		||||
    struct squeek_view *view = squeek_layout_get_current_view(priv->keyboard->layout);
 | 
			
		||||
 | 
			
		||||
    /* redraw pressed key */
 | 
			
		||||
    const GList *list = priv->keyboard->pressed_keys;
 | 
			
		||||
    for (const GList *head = list; head; head = g_list_next (head)) {
 | 
			
		||||
        struct button_place place = squeek_view_find_key(
 | 
			
		||||
            view, head->data
 | 
			
		||||
        );
 | 
			
		||||
        if (place.button)
 | 
			
		||||
            render_pressed_button (self, &place);
 | 
			
		||||
    list = eek_keyboard_get_pressed_keys (priv->keyboard);
 | 
			
		||||
    for (head = list; head; head = g_list_next (head)) {
 | 
			
		||||
        render_pressed_key (self, head->data);
 | 
			
		||||
    }
 | 
			
		||||
    g_list_free (list);
 | 
			
		||||
 | 
			
		||||
    /* redraw locked key */
 | 
			
		||||
    list = priv->keyboard->locked_keys;
 | 
			
		||||
    for (const GList *head = list; head; head = g_list_next (head)) {
 | 
			
		||||
        struct button_place place = squeek_view_find_key(
 | 
			
		||||
            view, ((EekModifierKey *)head->data)->key
 | 
			
		||||
        );
 | 
			
		||||
        if (place.button)
 | 
			
		||||
            render_locked_button (self, &place);
 | 
			
		||||
    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);
 | 
			
		||||
    }
 | 
			
		||||
    g_list_free (list);
 | 
			
		||||
 | 
			
		||||
    return FALSE;
 | 
			
		||||
}
 | 
			
		||||
@ -152,82 +150,56 @@ static void depress(EekGtkKeyboard *self,
 | 
			
		||||
                    gdouble x, gdouble y, guint32 time)
 | 
			
		||||
{
 | 
			
		||||
    EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (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);
 | 
			
		||||
    EekKey *key = eek_renderer_find_key_by_position (priv->renderer, x, y);
 | 
			
		||||
 | 
			
		||||
    if (button) {
 | 
			
		||||
        eek_keyboard_press_key(
 | 
			
		||||
            priv->keyboard,
 | 
			
		||||
            squeek_button_get_key(button),
 | 
			
		||||
            time
 | 
			
		||||
        );
 | 
			
		||||
        on_button_pressed(button, view, self);
 | 
			
		||||
    if (key) {
 | 
			
		||||
        eek_keyboard_press_key(priv->keyboard, key, time);
 | 
			
		||||
        on_key_pressed(key, self);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void drag(EekGtkKeyboard *self,
 | 
			
		||||
                 gdouble x, gdouble y, guint32 time)
 | 
			
		||||
{
 | 
			
		||||
                 gdouble x, gdouble y, guint32 time) {
 | 
			
		||||
    EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (self);
 | 
			
		||||
    struct squeek_view *view = level_keyboard_current(priv->keyboard);
 | 
			
		||||
    struct squeek_button *button = eek_renderer_find_button_by_position (priv->renderer, view, x, y);
 | 
			
		||||
    EekKey *key = eek_renderer_find_key_by_position (priv->renderer, x, y);
 | 
			
		||||
    GList *list, *head;
 | 
			
		||||
 | 
			
		||||
    list = g_list_copy(priv->keyboard->pressed_keys);
 | 
			
		||||
    list = eek_keyboard_get_pressed_keys (priv->keyboard);
 | 
			
		||||
 | 
			
		||||
    if (button) {
 | 
			
		||||
    if (key) {
 | 
			
		||||
        gboolean found = FALSE;
 | 
			
		||||
 | 
			
		||||
        for (head = list; head; head = g_list_next (head)) {
 | 
			
		||||
            struct squeek_key *key = head->data;
 | 
			
		||||
            if (squeek_button_has_key(button, key)) {
 | 
			
		||||
            if (head->data == key) {
 | 
			
		||||
                found = TRUE;
 | 
			
		||||
            } else {
 | 
			
		||||
                eek_keyboard_release_key(priv->keyboard, key, time);
 | 
			
		||||
                // The released handler proceeds to ignore this info...
 | 
			
		||||
                // let's do this for consistency nevertheless
 | 
			
		||||
                struct button_place place = squeek_view_find_key(view, key);
 | 
			
		||||
                on_button_released(place.button, view, self);
 | 
			
		||||
                eek_keyboard_release_key(priv->keyboard, EEK_KEY(head->data), time);
 | 
			
		||||
                on_key_released(key, self);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        g_list_free (list);
 | 
			
		||||
 | 
			
		||||
        if (!found) {
 | 
			
		||||
            eek_keyboard_press_key(
 | 
			
		||||
                priv->keyboard,
 | 
			
		||||
                squeek_button_get_key(button),
 | 
			
		||||
                time
 | 
			
		||||
            );
 | 
			
		||||
 | 
			
		||||
            on_button_pressed(button, view, self);
 | 
			
		||||
            eek_keyboard_press_key(priv->keyboard, key, time);
 | 
			
		||||
            on_key_pressed(key, self);
 | 
			
		||||
        }
 | 
			
		||||
    } else {
 | 
			
		||||
        for (head = list; head; head = g_list_next (head)) {
 | 
			
		||||
            struct squeek_key *key = head->data;
 | 
			
		||||
            eek_keyboard_release_key(priv->keyboard, key, time);
 | 
			
		||||
            // The released handler proceeds to ignore this info...
 | 
			
		||||
            // let's do this for consistency nevertheless
 | 
			
		||||
            struct button_place place = squeek_view_find_key(view, key);
 | 
			
		||||
            on_button_released(place.button, view, self);
 | 
			
		||||
            eek_keyboard_release_key(priv->keyboard, EEK_KEY(head->data), time);
 | 
			
		||||
            on_key_released(key, self);
 | 
			
		||||
        }
 | 
			
		||||
        g_list_free (list);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void release(EekGtkKeyboard *self, guint32 time)
 | 
			
		||||
{
 | 
			
		||||
static void release(EekGtkKeyboard *self, guint32 time) {
 | 
			
		||||
    EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (self);
 | 
			
		||||
 | 
			
		||||
    struct squeek_view *view = level_keyboard_current(priv->keyboard);
 | 
			
		||||
 | 
			
		||||
    GList *list = g_list_copy(priv->keyboard->pressed_keys);
 | 
			
		||||
    GList *list = eek_keyboard_get_pressed_keys (priv->keyboard);
 | 
			
		||||
    for (GList *head = list; head; head = g_list_next (head)) {
 | 
			
		||||
        struct squeek_key *key = head->data;
 | 
			
		||||
        EekKey *key = EEK_KEY(head->data);
 | 
			
		||||
        eek_keyboard_release_key(priv->keyboard, key, time);
 | 
			
		||||
        // The released handler proceeds to ignore this info...
 | 
			
		||||
        // let's do this for consistency nevertheless
 | 
			
		||||
        struct button_place place = squeek_view_find_key(view, key);
 | 
			
		||||
        on_button_released(place.button, view, self);
 | 
			
		||||
        on_key_released(key, self);
 | 
			
		||||
    }
 | 
			
		||||
    g_list_free (list);
 | 
			
		||||
}
 | 
			
		||||
@ -272,27 +244,27 @@ handle_touch_event (GtkWidget     *widget,
 | 
			
		||||
    EekGtkKeyboard        *self = EEK_GTK_KEYBOARD (widget);
 | 
			
		||||
    EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (self);
 | 
			
		||||
 | 
			
		||||
    /* For each new touch, release the previous one and record the new event
 | 
			
		||||
       sequence. */
 | 
			
		||||
    if (event->type == GDK_TOUCH_BEGIN) {
 | 
			
		||||
        release(self, event->time);
 | 
			
		||||
        if (priv->sequence) {
 | 
			
		||||
            // Ignore second and following touch points
 | 
			
		||||
            return FALSE;
 | 
			
		||||
        }
 | 
			
		||||
        priv->sequence = event->sequence;
 | 
			
		||||
        depress(self, event->x, event->y, event->time);
 | 
			
		||||
        return TRUE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* Only allow the latest touch point to be dragged. */
 | 
			
		||||
    if (event->type == GDK_TOUCH_UPDATE && event->sequence == priv->sequence) {
 | 
			
		||||
    if (priv->sequence != event->sequence) {
 | 
			
		||||
        return FALSE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (event->type == GDK_TOUCH_UPDATE) {
 | 
			
		||||
        drag(self, event->x, event->y, event->time);
 | 
			
		||||
    }
 | 
			
		||||
    else if (event->type == GDK_TOUCH_END || event->type == GDK_TOUCH_CANCEL) {
 | 
			
		||||
    if (event->type == GDK_TOUCH_END || event->type == GDK_TOUCH_CANCEL) {
 | 
			
		||||
        // TODO: can the event have different coords than the previous update event?
 | 
			
		||||
        /* Only respond to the release of the latest touch point. Previous
 | 
			
		||||
           touches have already been released. */
 | 
			
		||||
        if (event->sequence == priv->sequence) {
 | 
			
		||||
            release(self, event->time);
 | 
			
		||||
            priv->sequence = NULL;
 | 
			
		||||
        }
 | 
			
		||||
        release(self, event->time);
 | 
			
		||||
        priv->sequence = NULL;
 | 
			
		||||
    }
 | 
			
		||||
    return TRUE;
 | 
			
		||||
}
 | 
			
		||||
@ -304,27 +276,78 @@ eek_gtk_keyboard_real_unmap (GtkWidget *self)
 | 
			
		||||
	    eek_gtk_keyboard_get_instance_private (EEK_GTK_KEYBOARD (self));
 | 
			
		||||
 | 
			
		||||
    if (priv->keyboard) {
 | 
			
		||||
        GList *head;
 | 
			
		||||
        GList *list, *head;
 | 
			
		||||
 | 
			
		||||
        for (head = priv->keyboard->pressed_keys; head; head = g_list_next (head)) {
 | 
			
		||||
            /* Unlike other places where we call this, we don't call
 | 
			
		||||
               on_button_released afterwards since we don't want to queue a
 | 
			
		||||
               redraw. */
 | 
			
		||||
            eek_keyboard_release_key(priv->keyboard, head->data,
 | 
			
		||||
                                        gdk_event_get_time(NULL));
 | 
			
		||||
        /* Make a copy of HEAD before sending "released" signal on
 | 
			
		||||
           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);
 | 
			
		||||
        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");
 | 
			
		||||
        }
 | 
			
		||||
        g_list_free (list);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    GTK_WIDGET_CLASS (eek_gtk_keyboard_parent_class)->unmap (self);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
eek_gtk_keyboard_real_query_tooltip (GtkWidget  *widget,
 | 
			
		||||
                                     gint        x,
 | 
			
		||||
                                     gint        y,
 | 
			
		||||
                                     gboolean    keyboard_tooltip,
 | 
			
		||||
                                     GtkTooltip *tooltip)
 | 
			
		||||
{
 | 
			
		||||
    EekGtkKeyboard        *self = EEK_GTK_KEYBOARD (widget);
 | 
			
		||||
    EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (self);
 | 
			
		||||
 | 
			
		||||
    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);
 | 
			
		||||
        if (text) {
 | 
			
		||||
            gtk_tooltip_set_text (tooltip, text);
 | 
			
		||||
            return TRUE;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    return FALSE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
eek_gtk_keyboard_set_keyboard (EekGtkKeyboard *self,
 | 
			
		||||
                               EekKeyboard    *keyboard)
 | 
			
		||||
{
 | 
			
		||||
    EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (self);
 | 
			
		||||
 | 
			
		||||
    if (priv->keyboard == keyboard)
 | 
			
		||||
        return;
 | 
			
		||||
 | 
			
		||||
    if (priv->keyboard) {
 | 
			
		||||
        g_object_unref (priv->keyboard);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    priv->keyboard = g_object_ref (keyboard);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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;
 | 
			
		||||
@ -340,17 +363,19 @@ eek_gtk_keyboard_dispose (GObject *object)
 | 
			
		||||
    if (priv->renderer) {
 | 
			
		||||
        g_object_unref (priv->renderer);
 | 
			
		||||
        priv->renderer = NULL;
 | 
			
		||||
        priv->renderer = NULL;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (priv->keyboard) {
 | 
			
		||||
        GList *head;
 | 
			
		||||
        GList *list, *head;
 | 
			
		||||
 | 
			
		||||
        for (head = priv->keyboard->pressed_keys; head; head = g_list_next (head)) {
 | 
			
		||||
            eek_keyboard_release_key(priv->keyboard, head->data,
 | 
			
		||||
                                        gdk_event_get_time(NULL));
 | 
			
		||||
        list = eek_keyboard_get_pressed_keys (priv->keyboard);
 | 
			
		||||
        for (head = list; head; head = g_list_next (head)) {
 | 
			
		||||
            g_log("squeek", G_LOG_LEVEL_DEBUG, "emit EekKey pressed");
 | 
			
		||||
            g_signal_emit_by_name (head->data, "released", priv->keyboard);
 | 
			
		||||
        }
 | 
			
		||||
        g_list_free (list);
 | 
			
		||||
 | 
			
		||||
        g_object_unref (priv->keyboard);
 | 
			
		||||
        priv->keyboard = NULL;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -362,6 +387,7 @@ 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;
 | 
			
		||||
@ -373,15 +399,41 @@ eek_gtk_keyboard_class_init (EekGtkKeyboardClass *klass)
 | 
			
		||||
        eek_gtk_keyboard_real_button_release_event;
 | 
			
		||||
    widget_class->motion_notify_event =
 | 
			
		||||
        eek_gtk_keyboard_real_motion_notify_event;
 | 
			
		||||
    widget_class->query_tooltip =
 | 
			
		||||
        eek_gtk_keyboard_real_query_tooltip;
 | 
			
		||||
    widget_class->touch_event = handle_touch_event;
 | 
			
		||||
 | 
			
		||||
    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)
 | 
			
		||||
{}
 | 
			
		||||
{
 | 
			
		||||
    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);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eek_gtk_keyboard_new:
 | 
			
		||||
@ -391,17 +443,37 @@ eek_gtk_keyboard_init (EekGtkKeyboard *self)
 | 
			
		||||
 * Returns: a #GtkWidget
 | 
			
		||||
 */
 | 
			
		||||
GtkWidget *
 | 
			
		||||
eek_gtk_keyboard_new (LevelKeyboard *keyboard)
 | 
			
		||||
eek_gtk_keyboard_new (EekKeyboard *keyboard)
 | 
			
		||||
{
 | 
			
		||||
    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);
 | 
			
		||||
    return g_object_new (EEK_TYPE_GTK_KEYBOARD, "keyboard", keyboard, NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
render_pressed_button (GtkWidget *widget,
 | 
			
		||||
                       struct button_place *place)
 | 
			
		||||
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);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
render_pressed_key (GtkWidget *widget,
 | 
			
		||||
                    EekKey    *key)
 | 
			
		||||
{
 | 
			
		||||
    EekGtkKeyboard        *self = EEK_GTK_KEYBOARD (widget);
 | 
			
		||||
    EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (self);
 | 
			
		||||
@ -411,7 +483,7 @@ render_pressed_button (GtkWidget *widget,
 | 
			
		||||
    GdkDrawingContext *context = gdk_window_begin_draw_frame (window, region);
 | 
			
		||||
    cairo_t           *cr      = gdk_drawing_context_get_cairo_context (context);
 | 
			
		||||
 | 
			
		||||
    eek_renderer_render_button (priv->renderer, cr, place, 1.0, TRUE);
 | 
			
		||||
    eek_renderer_render_key (priv->renderer, cr, key, 1.0, TRUE);
 | 
			
		||||
/*
 | 
			
		||||
    eek_renderer_render_key (priv->renderer, cr, key, 1.5, TRUE);
 | 
			
		||||
*/
 | 
			
		||||
@ -421,7 +493,8 @@ render_pressed_button (GtkWidget *widget,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
render_locked_button (GtkWidget *widget, struct button_place *place)
 | 
			
		||||
render_locked_key (GtkWidget *widget,
 | 
			
		||||
                   EekKey    *key)
 | 
			
		||||
{
 | 
			
		||||
    EekGtkKeyboard        *self = EEK_GTK_KEYBOARD (widget);
 | 
			
		||||
    EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (self);
 | 
			
		||||
@ -431,19 +504,17 @@ render_locked_button (GtkWidget *widget, struct button_place *place)
 | 
			
		||||
    GdkDrawingContext *context = gdk_window_begin_draw_frame (window, region);
 | 
			
		||||
    cairo_t           *cr      = gdk_drawing_context_get_cairo_context (context);
 | 
			
		||||
 | 
			
		||||
    eek_renderer_render_button (priv->renderer, cr, place, 1.0, TRUE);
 | 
			
		||||
    eek_renderer_render_key (priv->renderer, cr, key, 1.0, TRUE);
 | 
			
		||||
 | 
			
		||||
    gdk_window_end_draw_frame (window, context);
 | 
			
		||||
 | 
			
		||||
    cairo_region_destroy (region);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// TODO: does it really redraw the entire keyboard?
 | 
			
		||||
static void
 | 
			
		||||
render_released_button (GtkWidget *widget,
 | 
			
		||||
                        const struct squeek_button *button)
 | 
			
		||||
render_released_key (GtkWidget *widget,
 | 
			
		||||
                     EekKey    *key)
 | 
			
		||||
{
 | 
			
		||||
    (void)button;
 | 
			
		||||
    EekGtkKeyboard        *self = EEK_GTK_KEYBOARD (widget);
 | 
			
		||||
    EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (self);
 | 
			
		||||
 | 
			
		||||
@ -460,9 +531,8 @@ render_released_button (GtkWidget *widget,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
on_button_pressed (struct squeek_button *button,
 | 
			
		||||
                   struct squeek_view *view,
 | 
			
		||||
                   EekGtkKeyboard *self)
 | 
			
		||||
on_key_pressed (EekKey      *key,
 | 
			
		||||
                EekGtkKeyboard *self)
 | 
			
		||||
{
 | 
			
		||||
    EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (self);
 | 
			
		||||
 | 
			
		||||
@ -470,14 +540,7 @@ on_button_pressed (struct squeek_button *button,
 | 
			
		||||
    if (!priv->renderer)
 | 
			
		||||
        return;
 | 
			
		||||
 | 
			
		||||
    struct button_place place = {
 | 
			
		||||
        .button = button,
 | 
			
		||||
        .row = squeek_view_get_row(view, button),
 | 
			
		||||
    };
 | 
			
		||||
    if (!place.row) {
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
    render_pressed_button (GTK_WIDGET(self), &place);
 | 
			
		||||
    render_pressed_key (GTK_WIDGET(self), key);
 | 
			
		||||
    gtk_widget_queue_draw (GTK_WIDGET(self));
 | 
			
		||||
 | 
			
		||||
#if HAVE_LIBCANBERRA
 | 
			
		||||
@ -490,18 +553,16 @@ on_button_pressed (struct squeek_button *button,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
on_button_released (const struct squeek_button *button,
 | 
			
		||||
                    struct squeek_view *view,
 | 
			
		||||
                    EekGtkKeyboard *self)
 | 
			
		||||
on_key_released (EekKey      *key,
 | 
			
		||||
                 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_button (GTK_WIDGET(self), button);
 | 
			
		||||
    render_released_key (GTK_WIDGET(self), key);
 | 
			
		||||
    gtk_widget_queue_draw (GTK_WIDGET(self));
 | 
			
		||||
 | 
			
		||||
#if HAVE_LIBCANBERRA
 | 
			
		||||
 | 
			
		||||
@ -45,7 +45,7 @@ struct _EekGtkKeyboardClass
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
GType      eek_gtk_keyboard_get_type  (void) G_GNUC_CONST;
 | 
			
		||||
GtkWidget *eek_gtk_keyboard_new       (LevelKeyboard *keyboard);
 | 
			
		||||
GtkWidget *eek_gtk_keyboard_new       (EekKeyboard    *keyboard);
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
#endif  /* EEK_GTK_KEYBOARD_H */
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										518
									
								
								eek/eek-key.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										518
									
								
								eek/eek-key.c
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,518 @@
 | 
			
		||||
/* 
 | 
			
		||||
 * 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.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "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_OREF,
 | 
			
		||||
    PROP_LAST
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
enum {
 | 
			
		||||
    LOCKED,
 | 
			
		||||
    UNLOCKED,
 | 
			
		||||
    LAST_SIGNAL
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static guint signals[LAST_SIGNAL] = { 0, };
 | 
			
		||||
 | 
			
		||||
typedef struct _EekKeyPrivate
 | 
			
		||||
{
 | 
			
		||||
    guint keycode;
 | 
			
		||||
    EekSymbolMatrix *symbol_matrix;
 | 
			
		||||
    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;
 | 
			
		||||
    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_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)
 | 
			
		||||
{
 | 
			
		||||
    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_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: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_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;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
gboolean
 | 
			
		||||
eek_key_has_label(EekKey *key)
 | 
			
		||||
{
 | 
			
		||||
    EekSymbol *symbol = eek_key_get_symbol(key);
 | 
			
		||||
    return (eek_symbol_get_label(symbol) != NULL) ||
 | 
			
		||||
           (eek_symbol_get_icon_name(symbol) != NULL);
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										88
									
								
								eek/eek-key.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										88
									
								
								eek/eek-key.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,88 @@
 | 
			
		||||
/* 
 | 
			
		||||
 * 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_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);
 | 
			
		||||
 | 
			
		||||
gboolean         eek_key_has_label           (EekKey          *key);
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
#endif  /* EEK_KEY_H */
 | 
			
		||||
							
								
								
									
										217
									
								
								eek/eek-keyboard-drawing.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										217
									
								
								eek/eek-keyboard-drawing.c
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,217 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2006 Sergey V. Udaltsov <svu@gnome.org>
 | 
			
		||||
 *
 | 
			
		||||
 * 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.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "config.h"
 | 
			
		||||
 | 
			
		||||
#include <math.h>
 | 
			
		||||
#include <pango/pangocairo.h>
 | 
			
		||||
 | 
			
		||||
#include "eek-types.h"
 | 
			
		||||
 | 
			
		||||
static gdouble
 | 
			
		||||
length (gdouble x, gdouble y)
 | 
			
		||||
{
 | 
			
		||||
    return sqrt (x * x + y * y);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gdouble
 | 
			
		||||
point_line_distance (gdouble ax, gdouble ay, gdouble nx, gdouble ny)
 | 
			
		||||
{
 | 
			
		||||
    return ax * nx + ay * ny;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
normal_form (gdouble ax, gdouble ay,
 | 
			
		||||
	     gdouble bx, gdouble by,
 | 
			
		||||
	     gdouble * nx, gdouble * ny, gdouble * d)
 | 
			
		||||
{
 | 
			
		||||
    gdouble l;
 | 
			
		||||
 | 
			
		||||
    *nx = by - ay;
 | 
			
		||||
    *ny = ax - bx;
 | 
			
		||||
 | 
			
		||||
    l = length (*nx, *ny);
 | 
			
		||||
 | 
			
		||||
    *nx /= l;
 | 
			
		||||
    *ny /= l;
 | 
			
		||||
 | 
			
		||||
    *d = point_line_distance (ax, ay, *nx, *ny);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
inverse (gdouble a, gdouble b, gdouble c, gdouble d,
 | 
			
		||||
	 gdouble * e, gdouble * f, gdouble * g, gdouble * h)
 | 
			
		||||
{
 | 
			
		||||
    gdouble det;
 | 
			
		||||
 | 
			
		||||
    det = a * d - b * c;
 | 
			
		||||
 | 
			
		||||
    *e = d / det;
 | 
			
		||||
    *f = -b / det;
 | 
			
		||||
    *g = -c / det;
 | 
			
		||||
    *h = a / det;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
multiply (gdouble a, gdouble b, gdouble c, gdouble d,
 | 
			
		||||
	  gdouble e, gdouble f, gdouble * x, gdouble * y)
 | 
			
		||||
{
 | 
			
		||||
    *x = a * e + b * f;
 | 
			
		||||
    *y = c * e + d * f;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
intersect (gdouble n1x, gdouble n1y, gdouble d1,
 | 
			
		||||
	   gdouble n2x, gdouble n2y, gdouble d2, gdouble * x, gdouble * y)
 | 
			
		||||
{
 | 
			
		||||
    gdouble e, f, g, h;
 | 
			
		||||
 | 
			
		||||
    inverse (n1x, n1y, n2x, n2y, &e, &f, &g, &h);
 | 
			
		||||
    multiply (e, f, g, h, d1, d2, x, y);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* draw an angle from the current point to b and then to c,
 | 
			
		||||
 * with a rounded corner of the given radius.
 | 
			
		||||
 */
 | 
			
		||||
static void
 | 
			
		||||
rounded_corner (cairo_t * cr,
 | 
			
		||||
		gdouble bx, gdouble by,
 | 
			
		||||
		gdouble cx, gdouble cy, gdouble radius)
 | 
			
		||||
{
 | 
			
		||||
    gdouble ax, ay;
 | 
			
		||||
    gdouble n1x, n1y, d1;
 | 
			
		||||
    gdouble n2x, n2y, d2;
 | 
			
		||||
    gdouble pd1, pd2;
 | 
			
		||||
    gdouble ix, iy;
 | 
			
		||||
    gdouble dist1, dist2;
 | 
			
		||||
    gdouble nx, ny, d;
 | 
			
		||||
    gdouble a1x, a1y, c1x, c1y;
 | 
			
		||||
    gdouble phi1, phi2;
 | 
			
		||||
 | 
			
		||||
    cairo_get_current_point (cr, &ax, &ay);
 | 
			
		||||
#ifdef KBDRAW_DEBUG
 | 
			
		||||
    printf ("        current point: (%f, %f), radius %f:\n", ax, ay,
 | 
			
		||||
            radius);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    /* make sure radius is not too large */
 | 
			
		||||
    dist1 = length (bx - ax, by - ay);
 | 
			
		||||
    dist2 = length (cx - bx, cy - by);
 | 
			
		||||
 | 
			
		||||
    radius = MIN (radius, MIN (dist1, dist2));
 | 
			
		||||
 | 
			
		||||
    /* construct normal forms of the lines */
 | 
			
		||||
    normal_form (ax, ay, bx, by, &n1x, &n1y, &d1);
 | 
			
		||||
    normal_form (bx, by, cx, cy, &n2x, &n2y, &d2);
 | 
			
		||||
 | 
			
		||||
    /* find which side of the line a,b the point c is on */
 | 
			
		||||
    if (point_line_distance (cx, cy, n1x, n1y) < d1)
 | 
			
		||||
        pd1 = d1 - radius;
 | 
			
		||||
    else
 | 
			
		||||
        pd1 = d1 + radius;
 | 
			
		||||
 | 
			
		||||
    /* find which side of the line b,c the point a is on */
 | 
			
		||||
    if (point_line_distance (ax, ay, n2x, n2y) < d2)
 | 
			
		||||
        pd2 = d2 - radius;
 | 
			
		||||
    else
 | 
			
		||||
        pd2 = d2 + radius;
 | 
			
		||||
 | 
			
		||||
    /* intersect the parallels to find the center of the arc */
 | 
			
		||||
    intersect (n1x, n1y, pd1, n2x, n2y, pd2, &ix, &iy);
 | 
			
		||||
 | 
			
		||||
    nx = (bx - ax) / dist1;
 | 
			
		||||
    ny = (by - ay) / dist1;
 | 
			
		||||
    d = point_line_distance (ix, iy, nx, ny);
 | 
			
		||||
 | 
			
		||||
    /* a1 is the point on the line a-b where the arc starts */
 | 
			
		||||
    intersect (n1x, n1y, d1, nx, ny, d, &a1x, &a1y);
 | 
			
		||||
 | 
			
		||||
    nx = (cx - bx) / dist2;
 | 
			
		||||
    ny = (cy - by) / dist2;
 | 
			
		||||
    d = point_line_distance (ix, iy, nx, ny);
 | 
			
		||||
 | 
			
		||||
    /* c1 is the point on the line b-c where the arc ends */
 | 
			
		||||
    intersect (n2x, n2y, d2, nx, ny, d, &c1x, &c1y);
 | 
			
		||||
 | 
			
		||||
    /* determine the first angle */
 | 
			
		||||
    if (a1x - ix == 0)
 | 
			
		||||
        phi1 = (a1y - iy > 0) ? M_PI_2 : 3 * M_PI_2;
 | 
			
		||||
    else if (a1x - ix > 0)
 | 
			
		||||
        phi1 = atan ((a1y - iy) / (a1x - ix));
 | 
			
		||||
    else
 | 
			
		||||
        phi1 = M_PI + atan ((a1y - iy) / (a1x - ix));
 | 
			
		||||
 | 
			
		||||
    /* determine the second angle */
 | 
			
		||||
    if (c1x - ix == 0)
 | 
			
		||||
        phi2 = (c1y - iy > 0) ? M_PI_2 : 3 * M_PI_2;
 | 
			
		||||
    else if (c1x - ix > 0)
 | 
			
		||||
        phi2 = atan ((c1y - iy) / (c1x - ix));
 | 
			
		||||
    else
 | 
			
		||||
        phi2 = M_PI + atan ((c1y - iy) / (c1x - ix));
 | 
			
		||||
 | 
			
		||||
    /* compute the difference between phi2 and phi1 mod 2pi */
 | 
			
		||||
    d = phi2 - phi1;
 | 
			
		||||
    while (d < 0)
 | 
			
		||||
        d += 2 * M_PI;
 | 
			
		||||
    while (d > 2 * M_PI)
 | 
			
		||||
        d -= 2 * M_PI;
 | 
			
		||||
 | 
			
		||||
#ifdef KBDRAW_DEBUG
 | 
			
		||||
    printf ("        line 1 to: (%f, %f):\n", a1x, a1y);
 | 
			
		||||
#endif
 | 
			
		||||
    if (!(isnan (a1x) || isnan (a1y)))
 | 
			
		||||
        cairo_line_to (cr, a1x, a1y);
 | 
			
		||||
 | 
			
		||||
    /* pick the short arc from phi1 to phi2 */
 | 
			
		||||
    if (d < M_PI)
 | 
			
		||||
        cairo_arc (cr, ix, iy, radius, phi1, phi2);
 | 
			
		||||
    else
 | 
			
		||||
        cairo_arc_negative (cr, ix, iy, radius, phi1, phi2);
 | 
			
		||||
 | 
			
		||||
#ifdef KBDRAW_DEBUG
 | 
			
		||||
    printf ("        line 2 to: (%f, %f):\n", cx, cy);
 | 
			
		||||
#endif
 | 
			
		||||
    cairo_line_to (cr, cx, cy);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* renamed from rounded_polygon, use EekPoint instead of GdkPoint not
 | 
			
		||||
   to depend on GTK+, and exported */
 | 
			
		||||
void
 | 
			
		||||
_eek_rounded_polygon (cairo_t  *cr,
 | 
			
		||||
                      gdouble   radius,
 | 
			
		||||
                      EekPoint *points,
 | 
			
		||||
                      guint     num_points)
 | 
			
		||||
{
 | 
			
		||||
    cairo_move_to (cr,
 | 
			
		||||
                   (gdouble) (points[num_points - 1].x +
 | 
			
		||||
                              points[0].x) / 2,
 | 
			
		||||
                   (gdouble) (points[num_points - 1].y +
 | 
			
		||||
                              points[0].y) / 2);
 | 
			
		||||
 | 
			
		||||
    for (guint i = 0; i < num_points; i++) {
 | 
			
		||||
        guint j = (i + 1) % num_points;
 | 
			
		||||
        rounded_corner (cr, (gdouble) points[i].x,
 | 
			
		||||
                        (gdouble) points[i].y,
 | 
			
		||||
                        (gdouble) (points[i].x + points[j].x) / 2,
 | 
			
		||||
                        (gdouble) (points[i].y + points[j].y) / 2,
 | 
			
		||||
                        radius);
 | 
			
		||||
    }
 | 
			
		||||
    cairo_close_path (cr);
 | 
			
		||||
}
 | 
			
		||||
@ -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
 | 
			
		||||
@ -30,12 +30,65 @@
 | 
			
		||||
#include "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 "eek-keyboard.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;
 | 
			
		||||
    unsigned int old_level;
 | 
			
		||||
    GList *pressed_keys;
 | 
			
		||||
    GList *locked_keys;
 | 
			
		||||
    GArray *outline_array;
 | 
			
		||||
 | 
			
		||||
    /* Map key names to key objects */
 | 
			
		||||
    GHashTable *names;
 | 
			
		||||
    /* Map characters to symbols and levels */
 | 
			
		||||
    GHashTable *character_map;
 | 
			
		||||
 | 
			
		||||
    /* modifiers dynamically assigned at run time */
 | 
			
		||||
    EekModifierType num_lock_mask;
 | 
			
		||||
    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);
 | 
			
		||||
 | 
			
		||||
EekModifierKey *
 | 
			
		||||
eek_modifier_key_copy (EekModifierKey *modkey)
 | 
			
		||||
@ -46,107 +99,823 @@ eek_modifier_key_copy (EekModifierKey *modkey)
 | 
			
		||||
void
 | 
			
		||||
eek_modifier_key_free (EekModifierKey *modkey)
 | 
			
		||||
{
 | 
			
		||||
    g_object_unref (modkey->key);
 | 
			
		||||
    g_slice_free (EekModifierKey, modkey);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
eek_keyboard_set_key_locked (LevelKeyboard    *keyboard,
 | 
			
		||||
                            struct squeek_key *key)
 | 
			
		||||
static void
 | 
			
		||||
on_key_locked (EekSection  *section,
 | 
			
		||||
                EekKey      *key,
 | 
			
		||||
                EekKeyboard *keyboard)
 | 
			
		||||
{
 | 
			
		||||
    EekModifierKey *modifier_key = g_slice_new (EekModifierKey);
 | 
			
		||||
    modifier_key->modifiers = 0;
 | 
			
		||||
    modifier_key->key = key;
 | 
			
		||||
    keyboard->locked_keys =
 | 
			
		||||
            g_list_prepend (keyboard->locked_keys, modifier_key);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Unlock all locked keys.
 | 
			
		||||
/// All locked keys will unlock at the next keypress (should be called "stuck")
 | 
			
		||||
/// Returns the number of handled keys
 | 
			
		||||
/// TODO: may need to check key type in order to chain locks
 | 
			
		||||
/// before pressing an "emitting" key
 | 
			
		||||
static int unlock_keys(LevelKeyboard *keyboard) {
 | 
			
		||||
    int handled = 0;
 | 
			
		||||
    for (GList *head = keyboard->locked_keys; head; ) {
 | 
			
		||||
        EekModifierKey *modifier_key = head->data;
 | 
			
		||||
        GList *next = g_list_next (head);
 | 
			
		||||
        keyboard->locked_keys =
 | 
			
		||||
                g_list_remove_link (keyboard->locked_keys, head);
 | 
			
		||||
        //squeek_key_set_locked(squeek_button_get_key(modifier_key->button), false);
 | 
			
		||||
 | 
			
		||||
        squeek_layout_set_state_from_press(keyboard->layout, keyboard, modifier_key->key);
 | 
			
		||||
        g_list_free1 (head);
 | 
			
		||||
        head = next;
 | 
			
		||||
        handled++;
 | 
			
		||||
    }
 | 
			
		||||
    return handled;
 | 
			
		||||
    g_signal_emit (keyboard, signals[KEY_LOCKED], 0, key);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
set_level_from_press (LevelKeyboard *keyboard, struct squeek_key *key)
 | 
			
		||||
on_key_unlocked (EekSection  *section,
 | 
			
		||||
                 EekKey      *key,
 | 
			
		||||
                 EekKeyboard *keyboard)
 | 
			
		||||
{
 | 
			
		||||
    // If the currently locked key was already handled in the unlock phase,
 | 
			
		||||
    // then skip
 | 
			
		||||
    if (unlock_keys(keyboard) == 0) {
 | 
			
		||||
        squeek_layout_set_state_from_press(keyboard->layout, keyboard, key);
 | 
			
		||||
    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)
 | 
			
		||||
{
 | 
			
		||||
    const gchar *name = eek_element_get_name(element);
 | 
			
		||||
    g_hash_table_insert (keyboard->priv->names,
 | 
			
		||||
                         (gpointer)name,
 | 
			
		||||
                         element);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
section_child_removed_cb (EekContainer *container,
 | 
			
		||||
                          EekElement   *element,
 | 
			
		||||
                          EekKeyboard  *keyboard)
 | 
			
		||||
{
 | 
			
		||||
    const gchar *name = eek_element_get_name(element);
 | 
			
		||||
    g_hash_table_remove (keyboard->priv->names,
 | 
			
		||||
                         name);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void eek_keyboard_press_key(LevelKeyboard *keyboard, struct squeek_key *key, guint32 timestamp) {
 | 
			
		||||
    squeek_key_set_pressed(key, TRUE);
 | 
			
		||||
    keyboard->pressed_keys = g_list_prepend (keyboard->pressed_keys, key);
 | 
			
		||||
static void
 | 
			
		||||
eek_keyboard_get_property (GObject    *object,
 | 
			
		||||
                           guint       prop_id,
 | 
			
		||||
                           GValue     *value,
 | 
			
		||||
                           GParamSpec *pspec)
 | 
			
		||||
{
 | 
			
		||||
    EekKeyboardPrivate *priv = EEK_KEYBOARD_GET_PRIVATE(object);
 | 
			
		||||
 | 
			
		||||
    // Only take action about setting level *after* the key has taken effect, i.e. on release
 | 
			
		||||
    //set_level_from_press (keyboard, key);
 | 
			
		||||
    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;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
set_level_from_modifiers (EekKeyboard *self, EekKey *key)
 | 
			
		||||
{
 | 
			
		||||
    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;
 | 
			
		||||
 | 
			
		||||
    /* Handle non-emitting keys */
 | 
			
		||||
    if (key) {
 | 
			
		||||
        const gchar *name = eek_element_get_name(EEK_ELEMENT(key));
 | 
			
		||||
        if (g_strcmp0(name, "ABC123") == 0)
 | 
			
		||||
            level ^= 2;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    level |= ((priv->modifiers & EEK_SHIFT_MASK) ? 1 : 0);
 | 
			
		||||
 | 
			
		||||
    switch (priv->old_level) {
 | 
			
		||||
    case VIEW_LETTERS_UPPER:
 | 
			
		||||
    {
 | 
			
		||||
        /* Redirect upper case letters to numbers instead of symbols, clearing
 | 
			
		||||
           the shift modifier to keep the modifiers in sync with the level */
 | 
			
		||||
        if (level == VIEW_SYMBOLS) {
 | 
			
		||||
            level = VIEW_NUMBERS;
 | 
			
		||||
            priv->modifiers &= ~EEK_SHIFT_MASK;
 | 
			
		||||
        }
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
    case VIEW_SYMBOLS:
 | 
			
		||||
    {
 | 
			
		||||
        /* Redirect symbols to lower case letters instead of upper case,
 | 
			
		||||
           clearing the shift modifier to keep the modifiers in sync with the
 | 
			
		||||
           level */
 | 
			
		||||
        if (level == VIEW_LETTERS_UPPER) {
 | 
			
		||||
            level = VIEW_LETTERS_LOWER;
 | 
			
		||||
            priv->modifiers &= ~EEK_SHIFT_MASK;
 | 
			
		||||
        }
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
    case VIEW_LETTERS_LOWER:    /* Direct transitions between views */
 | 
			
		||||
    case VIEW_NUMBERS:
 | 
			
		||||
    default:
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (level == VIEW_NUMBERS || level == VIEW_SYMBOLS)
 | 
			
		||||
        priv->modifier_behavior = EEK_MODIFIER_BEHAVIOR_LOCK;
 | 
			
		||||
    else
 | 
			
		||||
        priv->modifier_behavior = EEK_MODIFIER_BEHAVIOR_LATCH;
 | 
			
		||||
 | 
			
		||||
    priv->old_level = level;
 | 
			
		||||
    eek_element_set_level (EEK_ELEMENT(self), level);
 | 
			
		||||
 | 
			
		||||
    eek_layout_update_layout(self);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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;
 | 
			
		||||
 | 
			
		||||
    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);
 | 
			
		||||
    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);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // "Borrowed" from eek-context-service; doesn't influence the state but forwards the event
 | 
			
		||||
 | 
			
		||||
    guint keycode = squeek_key_get_keycode (key);
 | 
			
		||||
    guint keycode = eek_key_get_keycode (key);
 | 
			
		||||
    EekModifierType modifiers = eek_keyboard_get_modifiers (keyboard);
 | 
			
		||||
 | 
			
		||||
    emit_key_activated(keyboard->manager, keyboard, keycode, TRUE, timestamp);
 | 
			
		||||
    emit_key_activated(keyboard->manager, keyboard, keycode, symbol, modifiers, TRUE, timestamp);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void eek_keyboard_release_key(LevelKeyboard *keyboard,
 | 
			
		||||
                              struct squeek_key *key,
 | 
			
		||||
                              guint32 timestamp) {
 | 
			
		||||
    for (GList *head = keyboard->pressed_keys; head; head = g_list_next (head)) {
 | 
			
		||||
        if (squeek_key_equal(head->data, key)) {
 | 
			
		||||
            keyboard->pressed_keys = g_list_remove_link (keyboard->pressed_keys, head);
 | 
			
		||||
void eek_keyboard_release_key( EekKeyboard *keyboard,
 | 
			
		||||
                               EekKey      *key,
 | 
			
		||||
                               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);
 | 
			
		||||
            g_list_free1 (head);
 | 
			
		||||
            break;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    set_level_from_press (keyboard, key);
 | 
			
		||||
    EekSymbol *symbol = eek_key_get_symbol_with_fallback (key, 0, 0);
 | 
			
		||||
    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);
 | 
			
		||||
 | 
			
		||||
    // "Borrowed" from eek-context-service; doesn't influence the state but forwards the event
 | 
			
		||||
 | 
			
		||||
    guint keycode = squeek_key_get_keycode (key);
 | 
			
		||||
    guint keycode = eek_key_get_keycode (key);
 | 
			
		||||
    guint modifiers = eek_keyboard_get_modifiers (keyboard);
 | 
			
		||||
 | 
			
		||||
    emit_key_activated(keyboard->manager, keyboard, keycode, FALSE, timestamp);
 | 
			
		||||
    emit_key_activated(keyboard->manager, keyboard, keycode, symbol, modifiers, FALSE, timestamp);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void level_keyboard_deinit(LevelKeyboard *self) {
 | 
			
		||||
    squeek_layout_free(self->layout);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void level_keyboard_free(LevelKeyboard *self) {
 | 
			
		||||
    level_keyboard_deinit(self);
 | 
			
		||||
    g_free(self);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void level_keyboard_init(LevelKeyboard *self, struct squeek_layout *layout) {
 | 
			
		||||
    self->layout = layout;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
LevelKeyboard *level_keyboard_new(EekboardContextService *manager, struct squeek_layout *layout) {
 | 
			
		||||
    LevelKeyboard *keyboard = g_new0(LevelKeyboard, 1);
 | 
			
		||||
    level_keyboard_init(keyboard, layout);
 | 
			
		||||
    keyboard->manager = manager;
 | 
			
		||||
    return keyboard;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
struct squeek_view *level_keyboard_current(LevelKeyboard *keyboard)
 | 
			
		||||
static void
 | 
			
		||||
eek_keyboard_dispose (GObject *object)
 | 
			
		||||
{
 | 
			
		||||
    return squeek_layout_get_current_view(keyboard->layout);
 | 
			
		||||
    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->names);
 | 
			
		||||
    g_hash_table_destroy (priv->character_map);
 | 
			
		||||
 | 
			
		||||
    for (i = 0; i < priv->outline_array->len; i++) {
 | 
			
		||||
        EekOutline *outline = &g_array_index (priv->outline_array,
 | 
			
		||||
                                              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);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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->names = g_hash_table_new (g_str_hash, g_str_equal);
 | 
			
		||||
    self->priv->character_map = g_hash_table_new_full (g_str_hash, g_str_equal,
 | 
			
		||||
        NULL, g_free);
 | 
			
		||||
    eek_element_set_symbol_index (EEK_ELEMENT(self), 0, 0);
 | 
			
		||||
    self->scale = 1.0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eek_keyboard_create_section:
 | 
			
		||||
 * @keyboard: an #EekKeyboard
 | 
			
		||||
 *
 | 
			
		||||
 * Create an #EekSection instance and append it to @keyboard.  This
 | 
			
		||||
 * function is rarely called by application but called by #EekLayout
 | 
			
		||||
 * implementation.
 | 
			
		||||
 */
 | 
			
		||||
EekSection *
 | 
			
		||||
eek_keyboard_create_section (EekKeyboard *keyboard)
 | 
			
		||||
{
 | 
			
		||||
    g_return_val_if_fail (EEK_IS_KEYBOARD(keyboard), NULL);
 | 
			
		||||
    return EEK_KEYBOARD_GET_CLASS(keyboard)->create_section (keyboard);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eek_keyboard_find_key_by_name:
 | 
			
		||||
 * @keyboard: an #EekKeyboard
 | 
			
		||||
 * @name: a key name
 | 
			
		||||
 *
 | 
			
		||||
 * Find an #EekKey whose name is @name.
 | 
			
		||||
 * Return value: (transfer none): #EekKey whose name is @name
 | 
			
		||||
 */
 | 
			
		||||
EekKey *
 | 
			
		||||
eek_keyboard_find_key_by_name (EekKeyboard *keyboard,
 | 
			
		||||
                               const gchar *name)
 | 
			
		||||
{
 | 
			
		||||
    g_return_val_if_fail (EEK_IS_KEYBOARD(keyboard), NULL);
 | 
			
		||||
    return g_hash_table_lookup (keyboard->priv->names,
 | 
			
		||||
                                name);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * 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;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eek_keyboard_get_outline:
 | 
			
		||||
 * @keyboard: an #EekKeyboard
 | 
			
		||||
 * @oref: ID of the outline
 | 
			
		||||
 *
 | 
			
		||||
 * Get an outline associated with @oref in @keyboard.
 | 
			
		||||
 * Returns: an #EekOutline, which should not be released
 | 
			
		||||
 */
 | 
			
		||||
EekOutline *
 | 
			
		||||
eek_keyboard_get_outline (EekKeyboard *keyboard,
 | 
			
		||||
                          guint        oref)
 | 
			
		||||
{
 | 
			
		||||
    g_return_val_if_fail (EEK_IS_KEYBOARD(keyboard), NULL);
 | 
			
		||||
 | 
			
		||||
    if (oref > keyboard->priv->outline_array->len)
 | 
			
		||||
        return NULL;
 | 
			
		||||
 | 
			
		||||
    return &g_array_index (keyboard->priv->outline_array, EekOutline, oref);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eek_keyboard_get_n_outlines:
 | 
			
		||||
 * @keyboard: an #EekKeyboard
 | 
			
		||||
 *
 | 
			
		||||
 * Get the number of outlines defined in @keyboard.
 | 
			
		||||
 * Returns: integer
 | 
			
		||||
 */
 | 
			
		||||
gsize
 | 
			
		||||
eek_keyboard_get_n_outlines (EekKeyboard *keyboard)
 | 
			
		||||
{
 | 
			
		||||
    g_return_val_if_fail (EEK_IS_KEYBOARD(keyboard), 0);
 | 
			
		||||
    return keyboard->priv->outline_array->len;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * 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)
 | 
			
		||||
{
 | 
			
		||||
    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);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eek_keyboard_get_keymap:
 | 
			
		||||
 * @keyboard: an #EekKeyboard
 | 
			
		||||
 *
 | 
			
		||||
 * Get the keymap for the keyboard.
 | 
			
		||||
 * Returns: a string containing the XKB keymap.
 | 
			
		||||
 */
 | 
			
		||||
gchar *
 | 
			
		||||
eek_keyboard_get_keymap(EekKeyboard *keyboard)
 | 
			
		||||
{
 | 
			
		||||
    /* Start the keycodes and symbols sections with their respective headers. */
 | 
			
		||||
    gchar *keycodes = g_strdup(keymap_keycodes_header);
 | 
			
		||||
    gchar *symbols = g_strdup(keymap_symbols_header);
 | 
			
		||||
 | 
			
		||||
    /* Iterate over the keys in the name-to-key hash table. */
 | 
			
		||||
    GHashTableIter iter;
 | 
			
		||||
    gpointer key_name, key_ptr;
 | 
			
		||||
    g_hash_table_iter_init(&iter, keyboard->priv->names);
 | 
			
		||||
 | 
			
		||||
    while (g_hash_table_iter_next(&iter, &key_name, &key_ptr)) {
 | 
			
		||||
 | 
			
		||||
        gchar *current, *line;
 | 
			
		||||
        EekKey *key = EEK_KEY(key_ptr);
 | 
			
		||||
        int keycode = eek_key_get_keycode(key);
 | 
			
		||||
 | 
			
		||||
        /* Don't include invalid keycodes in the keymap. */
 | 
			
		||||
        if (keycode == EEK_INVALID_KEYCODE)
 | 
			
		||||
            continue;
 | 
			
		||||
 | 
			
		||||
        /* Append a key name-to-keycode definition to the keycodes section. */
 | 
			
		||||
        current = keycodes;
 | 
			
		||||
        line = g_strdup_printf("        <%s> = %i;\n", (char *)key_name, keycode);
 | 
			
		||||
 | 
			
		||||
        keycodes = g_strconcat(current, line, NULL);
 | 
			
		||||
        g_free(line);
 | 
			
		||||
        g_free(current);
 | 
			
		||||
 | 
			
		||||
        /* Find the symbols associated with the key. */
 | 
			
		||||
        EekSymbolMatrix *matrix = eek_key_get_symbol_matrix(key);
 | 
			
		||||
        EekSymbol *syms[4];
 | 
			
		||||
        int i, j;
 | 
			
		||||
 | 
			
		||||
        /* Get the symbols for all the levels defined for the key, then
 | 
			
		||||
           pad it out with the first symbol for all levels up to the fourth. */
 | 
			
		||||
        for (i = 0; (i < matrix->num_levels) && (i < 4); ++i)
 | 
			
		||||
            syms[i] = eek_symbol_matrix_get_symbol(matrix, 0, i);
 | 
			
		||||
 | 
			
		||||
        while (i < 4) {
 | 
			
		||||
            syms[i] = eek_symbol_matrix_get_symbol(matrix, 0, 0);
 | 
			
		||||
            i++;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /* The four levels are split into two groups in the keymap.
 | 
			
		||||
           Generate strings for each of these groups, where an empty group is
 | 
			
		||||
           treated specially. */
 | 
			
		||||
 | 
			
		||||
        gchar *groups[2] = {NULL, NULL};
 | 
			
		||||
        for (i = 0, j = 0; i < 2; ++i, j += 2) {
 | 
			
		||||
            if (syms[j] && syms[j + 1])
 | 
			
		||||
                groups[i] = g_strjoin(", ", eek_symbol_get_name(syms[j]),
 | 
			
		||||
                                            eek_symbol_get_name(syms[j + 1]),
 | 
			
		||||
                                            NULL);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /* Append a key definition to the symbols section. */
 | 
			
		||||
        current = symbols;
 | 
			
		||||
        line = g_strdup_printf("        key <%s> { [ %s ], [ %s ] };\n",
 | 
			
		||||
                               (char *)key_name, groups[0], groups[1]);
 | 
			
		||||
 | 
			
		||||
        g_free(groups[0]);
 | 
			
		||||
        g_free(groups[1]);
 | 
			
		||||
 | 
			
		||||
        symbols = g_strconcat(current, line, NULL);
 | 
			
		||||
        g_free(line);
 | 
			
		||||
        g_free(current);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* Assemble the keymap file from the header, sections and footer. */
 | 
			
		||||
    gchar *keymap = g_strconcat(keymap_header,
 | 
			
		||||
                                keycodes, "    };\n\n",
 | 
			
		||||
                                symbols, "    };\n\n",
 | 
			
		||||
                                keymap_footer, NULL);
 | 
			
		||||
 | 
			
		||||
    g_free(keycodes);
 | 
			
		||||
    g_free(symbols);
 | 
			
		||||
    return keymap;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
eek_keyboard_register_symbol (EekKeyboard *keyboard,
 | 
			
		||||
                              EekSymbol   *symbol,
 | 
			
		||||
                              EekKey      *key,
 | 
			
		||||
                              guint        level)
 | 
			
		||||
{
 | 
			
		||||
    const gchar *label = eek_symbol_get_label(symbol);
 | 
			
		||||
 | 
			
		||||
    if (label) {
 | 
			
		||||
        EekKeyPress *key_press = g_malloc0 (sizeof(EekKeyPress));
 | 
			
		||||
        key_press->key = key;
 | 
			
		||||
        key_press->level = level;
 | 
			
		||||
 | 
			
		||||
        g_hash_table_insert (keyboard->priv->character_map,
 | 
			
		||||
                             (gpointer)label,
 | 
			
		||||
                             key_press);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
EekKeyPress *
 | 
			
		||||
eek_keyboard_get_key_press (EekKeyboard *keyboard,
 | 
			
		||||
                         gchar       *ch)
 | 
			
		||||
{
 | 
			
		||||
    return g_hash_table_lookup (keyboard->priv->character_map, ch);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -27,56 +27,191 @@
 | 
			
		||||
 | 
			
		||||
#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
 | 
			
		||||
 | 
			
		||||
struct _EekModifierKey {
 | 
			
		||||
    /*< public >*/
 | 
			
		||||
    EekModifierType modifiers;
 | 
			
		||||
    struct squeek_key *key;
 | 
			
		||||
};
 | 
			
		||||
typedef struct _EekModifierKey EekModifierKey;
 | 
			
		||||
#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))
 | 
			
		||||
 | 
			
		||||
/// Keyboard state holder
 | 
			
		||||
struct _LevelKeyboard {
 | 
			
		||||
    struct squeek_layout *layout;
 | 
			
		||||
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
 | 
			
		||||
 | 
			
		||||
    GList *pressed_keys; // struct squeek_key*
 | 
			
		||||
    GList *locked_keys; // struct EekModifierKey*
 | 
			
		||||
 | 
			
		||||
    guint id; // as a key to layout choices
 | 
			
		||||
    double scale;
 | 
			
		||||
 | 
			
		||||
    EekboardContextService *manager; // unowned reference
 | 
			
		||||
};
 | 
			
		||||
typedef struct _LevelKeyboard LevelKeyboard;
 | 
			
		||||
 | 
			
		||||
/// Represents the path to the button within a view
 | 
			
		||||
struct button_place {
 | 
			
		||||
    const struct squeek_row *row;
 | 
			
		||||
    const struct squeek_button *button;
 | 
			
		||||
/**
 | 
			
		||||
 * EekKeyboardClass:
 | 
			
		||||
 * @create_section: virtual function for creating a section
 | 
			
		||||
 * @find_key_by_name: virtual function for finding a key in the
 | 
			
		||||
 * keyboard by name
 | 
			
		||||
 * @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_name)    (EekKeyboard *self,
 | 
			
		||||
                                         const gchar *name);
 | 
			
		||||
 | 
			
		||||
    /*< 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;
 | 
			
		||||
};
 | 
			
		||||
typedef struct _EekModifierKey EekModifierKey;
 | 
			
		||||
 | 
			
		||||
struct _EekKeyPress {
 | 
			
		||||
    EekKey *key;
 | 
			
		||||
    guint level;
 | 
			
		||||
};
 | 
			
		||||
typedef struct _EekKeyPress EekKeyPress;
 | 
			
		||||
 | 
			
		||||
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);
 | 
			
		||||
 | 
			
		||||
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);
 | 
			
		||||
 | 
			
		||||
EekSection         *eek_keyboard_create_section
 | 
			
		||||
                                     (EekKeyboard        *keyboard);
 | 
			
		||||
 | 
			
		||||
EekKey             *eek_keyboard_find_key_by_name
 | 
			
		||||
                                     (EekKeyboard        *keyboard,
 | 
			
		||||
                                      const gchar        *name);
 | 
			
		||||
 | 
			
		||||
guint               eek_keyboard_add_outline
 | 
			
		||||
                                     (EekKeyboard        *keyboard,
 | 
			
		||||
                                      EekOutline         *outline);
 | 
			
		||||
 | 
			
		||||
EekOutline         *eek_keyboard_get_outline
 | 
			
		||||
                                     (EekKeyboard        *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(LevelKeyboard *keyboard, struct squeek_key *key, guint32 timestamp);
 | 
			
		||||
void eek_keyboard_release_key(LevelKeyboard *keyboard, struct squeek_key *key, guint32 timestamp);
 | 
			
		||||
void eek_keyboard_press_key(EekKeyboard *keyboard, EekKey *key, guint32 timestamp);
 | 
			
		||||
void eek_keyboard_release_key(EekKeyboard *keyboard, EekKey *key, guint32 timestamp);
 | 
			
		||||
 | 
			
		||||
gchar *             eek_keyboard_get_keymap
 | 
			
		||||
                                     (LevelKeyboard *keyboard);
 | 
			
		||||
                                     (EekKeyboard        *keyboard);
 | 
			
		||||
 | 
			
		||||
struct squeek_view *level_keyboard_current(LevelKeyboard *keyboard);
 | 
			
		||||
LevelKeyboard *level_keyboard_new(EekboardContextService *manager, struct squeek_layout *layout);
 | 
			
		||||
void level_keyboard_deinit(LevelKeyboard *self);
 | 
			
		||||
void level_keyboard_free(LevelKeyboard *self);
 | 
			
		||||
void                eek_keyboard_register_symbol
 | 
			
		||||
                                     (EekKeyboard        *keyboard,
 | 
			
		||||
                                      EekSymbol          *symbol,
 | 
			
		||||
                                      EekKey             *key,
 | 
			
		||||
                                      guint               level);
 | 
			
		||||
 | 
			
		||||
EekKeyPress *       eek_keyboard_get_key_press
 | 
			
		||||
                                     (EekKeyboard        *keyboard,
 | 
			
		||||
                                      gchar              *ch);
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
#endif  /* EEK_KEYBOARD_H */
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										262
									
								
								eek/eek-keysym.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										262
									
								
								eek/eek-keysym.c
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,262 @@
 | 
			
		||||
/* 
 | 
			
		||||
 * 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-keysym
 | 
			
		||||
 * @short_description: an #EekSymbol represents an X keysym
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "config.h"
 | 
			
		||||
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
 | 
			
		||||
#include "eek-keysym.h"
 | 
			
		||||
#include "eek-serializable.h"
 | 
			
		||||
 | 
			
		||||
/* modifier keys */
 | 
			
		||||
#define EEK_KEYSYM_Shift_L 0xffe1
 | 
			
		||||
#define EEK_KEYSYM_Shift_R 0xffe2
 | 
			
		||||
#define EEK_KEYSYM_ISO_Level3_Shift 0xfe03
 | 
			
		||||
#define EEK_KEYSYM_Caps_Lock 0xffe5
 | 
			
		||||
#define EEK_KEYSYM_Shift_Lock 0xffe6
 | 
			
		||||
#define EEK_KEYSYM_Control_L 0xffe3
 | 
			
		||||
#define EEK_KEYSYM_Control_R 0xffe4
 | 
			
		||||
#define EEK_KEYSYM_Alt_L 0xffe9
 | 
			
		||||
#define EEK_KEYSYM_Alt_R 0xffea
 | 
			
		||||
#define EEK_KEYSYM_Meta_L 0xffe7
 | 
			
		||||
#define EEK_KEYSYM_Meta_R 0xffe8
 | 
			
		||||
#define EEK_KEYSYM_Super_L 0xffeb
 | 
			
		||||
#define EEK_KEYSYM_Super_R 0xffec
 | 
			
		||||
#define EEK_KEYSYM_Hyper_L 0xffed
 | 
			
		||||
#define EEK_KEYSYM_Hyper_R 0xffee
 | 
			
		||||
 | 
			
		||||
struct _EekKeysymEntry {
 | 
			
		||||
    guint xkeysym;
 | 
			
		||||
    const gchar *name;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
typedef struct _EekKeysymEntry EekKeysymEntry;
 | 
			
		||||
 | 
			
		||||
#include "eek-special-keysym-entries.h"
 | 
			
		||||
#include "eek-unicode-keysym-entries.h"
 | 
			
		||||
#include "eek-xkeysym-keysym-entries.h"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
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;
 | 
			
		||||
    }
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * 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.
 | 
			
		||||
 */
 | 
			
		||||
EekSymbol *eek_keysym_new_with_modifier(guint           xkeysym,
 | 
			
		||||
                                        EekModifierType modifier_mask)
 | 
			
		||||
{
 | 
			
		||||
    EekKeysymEntry *special_entry, *xkeysym_entry, *unicode_entry,
 | 
			
		||||
        *unichar_entry;
 | 
			
		||||
    gchar *name, *label;
 | 
			
		||||
    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);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    name = NULL;
 | 
			
		||||
    if (xkeysym_entry) {
 | 
			
		||||
        name = g_strdup (xkeysym_entry->name);
 | 
			
		||||
    } else if (unichar_entry) {
 | 
			
		||||
        name = g_strdup (unichar_entry->name);
 | 
			
		||||
    } else if (unicode_entry) {
 | 
			
		||||
        name = g_strdup (unicode_entry->name);
 | 
			
		||||
    } else {
 | 
			
		||||
        name = g_strdup ("");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* 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);
 | 
			
		||||
 | 
			
		||||
    EekSymbol *keysym = eek_symbol_new(name);
 | 
			
		||||
    eek_symbol_set_label(keysym, label);
 | 
			
		||||
    eek_symbol_set_modifier_mask(keysym, modifier_mask);
 | 
			
		||||
 | 
			
		||||
    g_free (name);
 | 
			
		||||
    g_free (label);
 | 
			
		||||
 | 
			
		||||
    if (unichar_entry) {
 | 
			
		||||
        g_free ((gpointer) unichar_entry->name);
 | 
			
		||||
        g_slice_free (EekKeysymEntry, unichar_entry);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    keysym->xkeysym = xkeysym;
 | 
			
		||||
 | 
			
		||||
    return keysym;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eek_keysym_new:
 | 
			
		||||
 * @xkeysym: an X keysym value
 | 
			
		||||
 *
 | 
			
		||||
 * Create an #EekKeysym with given X keysym value @xkeysym.
 | 
			
		||||
 */
 | 
			
		||||
EekSymbol*
 | 
			
		||||
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.
 | 
			
		||||
 */
 | 
			
		||||
EekSymbol*
 | 
			
		||||
eek_keysym_new_from_name (const gchar *name)
 | 
			
		||||
{
 | 
			
		||||
    for (uint i = 0; i < G_N_ELEMENTS(xkeysym_keysym_entries); i++)
 | 
			
		||||
        if (g_strcmp0 (xkeysym_keysym_entries[i].name, name) == 0)
 | 
			
		||||
            return eek_keysym_new (xkeysym_keysym_entries[i].xkeysym);
 | 
			
		||||
 | 
			
		||||
    EekSymbol *ret = eek_symbol_new(name);
 | 
			
		||||
    eek_symbol_set_label(ret, name);
 | 
			
		||||
    return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eek_keysym_get_xkeysym:
 | 
			
		||||
 * @keysym: an #EekKeysym
 | 
			
		||||
 *
 | 
			
		||||
 * Get an X keysym value associated with @keysym
 | 
			
		||||
 */
 | 
			
		||||
guint
 | 
			
		||||
eek_keysym_get_xkeysym (EekSymbol *keysym)
 | 
			
		||||
{
 | 
			
		||||
    if (keysym->xkeysym == 0) {
 | 
			
		||||
        g_warning("Symbol %s was expected to have a valid keysym", keysym->name);
 | 
			
		||||
    }
 | 
			
		||||
    return keysym->xkeysym;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										49
									
								
								eek/eek-keysym.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										49
									
								
								eek/eek-keysym.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,49 @@
 | 
			
		||||
/* 
 | 
			
		||||
 * 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_KEYSYM_H
 | 
			
		||||
#define EEK_KEYSYM_H 1
 | 
			
		||||
 | 
			
		||||
#include <X11/XKBlib.h>
 | 
			
		||||
#include "eek-symbol.h"
 | 
			
		||||
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * EEK_INVALID_KEYSYM:
 | 
			
		||||
 *
 | 
			
		||||
 * Pseudo keysym used for error reporting.
 | 
			
		||||
 */
 | 
			
		||||
#define EEK_INVALID_KEYSYM (0)
 | 
			
		||||
 | 
			
		||||
EekSymbol *eek_keysym_new               (guint           xkeysym);
 | 
			
		||||
guint      eek_keysym_get_xkeysym       (EekSymbol      *keysym);
 | 
			
		||||
 | 
			
		||||
EekSymbol *eek_keysym_new_from_name     (const gchar    *name);
 | 
			
		||||
EekSymbol *eek_keysym_new_with_modifier (guint           xkeysym,
 | 
			
		||||
                                         EekModifierType modifier_mask);
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
 | 
			
		||||
#endif  /* EEK_KEYSYM_H */
 | 
			
		||||
@ -31,7 +31,6 @@
 | 
			
		||||
#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)
 | 
			
		||||
 | 
			
		||||
@ -45,3 +44,93 @@ void
 | 
			
		||||
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)
 | 
			
		||||
{
 | 
			
		||||
    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);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const double section_spacing = 7.0;
 | 
			
		||||
 | 
			
		||||
struct place_data {
 | 
			
		||||
    double desired_width;
 | 
			
		||||
    double current_offset;
 | 
			
		||||
    EekKeyboard *keyboard;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
section_placer(EekElement *element, gpointer user_data)
 | 
			
		||||
{
 | 
			
		||||
    struct place_data *data = (struct place_data*)user_data;
 | 
			
		||||
 | 
			
		||||
    EekBounds section_bounds = {0};
 | 
			
		||||
    eek_element_get_bounds(element, §ion_bounds);
 | 
			
		||||
    section_bounds.width = data->desired_width;
 | 
			
		||||
    eek_element_set_bounds(element, §ion_bounds);
 | 
			
		||||
 | 
			
		||||
    // Sections are rows now. Gather up all the keys and adjust their bounds.
 | 
			
		||||
    eek_section_place_keys(EEK_SECTION(element), EEK_KEYBOARD(data->keyboard));
 | 
			
		||||
 | 
			
		||||
    eek_element_get_bounds(element, §ion_bounds);
 | 
			
		||||
    section_bounds.y = data->current_offset;
 | 
			
		||||
    eek_element_set_bounds(element, §ion_bounds);
 | 
			
		||||
    data->current_offset += section_bounds.height + section_spacing;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
section_counter(EekElement *element, gpointer user_data) {
 | 
			
		||||
 | 
			
		||||
    double *total_height = user_data;
 | 
			
		||||
    EekBounds section_bounds = {0};
 | 
			
		||||
    eek_element_get_bounds(element, §ion_bounds);
 | 
			
		||||
    *total_height += section_bounds.height + section_spacing;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
eek_layout_place_sections(EekKeyboard *keyboard)
 | 
			
		||||
{
 | 
			
		||||
    /* Order rows */
 | 
			
		||||
    // This needs to be done after outlines, because outlines define key sizes
 | 
			
		||||
    // TODO: do this only for rows without bounds
 | 
			
		||||
 | 
			
		||||
    // The keyboard width is given by the user via screen size. The height will be given dynamically.
 | 
			
		||||
    // TODO: calculate max line width beforehand for button centering. Leave keyboard centering to the renderer later
 | 
			
		||||
    EekBounds keyboard_bounds = {0};
 | 
			
		||||
    eek_element_get_bounds(EEK_ELEMENT(keyboard), &keyboard_bounds);
 | 
			
		||||
 | 
			
		||||
    struct place_data placer_data = {
 | 
			
		||||
        .desired_width = keyboard_bounds.width,
 | 
			
		||||
        .current_offset = 0,
 | 
			
		||||
        .keyboard = keyboard,
 | 
			
		||||
    };
 | 
			
		||||
    eek_container_foreach_child(EEK_CONTAINER(keyboard), section_placer, &placer_data);
 | 
			
		||||
 | 
			
		||||
    double total_height = 0;
 | 
			
		||||
    eek_container_foreach_child(EEK_CONTAINER(keyboard), section_counter, &total_height);
 | 
			
		||||
    keyboard_bounds.height = total_height;
 | 
			
		||||
    eek_element_set_bounds(EEK_ELEMENT(keyboard), &keyboard_bounds);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
eek_layout_update_layout(EekKeyboard *keyboard)
 | 
			
		||||
{
 | 
			
		||||
    eek_layout_place_sections(keyboard);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -27,7 +27,6 @@
 | 
			
		||||
 | 
			
		||||
#include <glib-object.h>
 | 
			
		||||
#include "eek-types.h"
 | 
			
		||||
#include "src/layout.h"
 | 
			
		||||
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
@ -44,7 +43,7 @@ struct _EekLayoutClass
 | 
			
		||||
    GObjectClass parent_class;
 | 
			
		||||
 | 
			
		||||
    /*< public >*/
 | 
			
		||||
    LevelKeyboard* (* create_keyboard) (EekboardContextService *manager,
 | 
			
		||||
    EekKeyboard* (* create_keyboard) (EekboardContextService *manager,
 | 
			
		||||
                                      EekLayout *self,
 | 
			
		||||
                                      gdouble    initial_width,
 | 
			
		||||
                                      gdouble    initial_height);
 | 
			
		||||
@ -56,5 +55,9 @@ struct _EekLayoutClass
 | 
			
		||||
 | 
			
		||||
GType        eek_layout_get_type  (void) G_GNUC_CONST;
 | 
			
		||||
 | 
			
		||||
void         eek_layout_place_sections(EekKeyboard *keyboard);
 | 
			
		||||
 | 
			
		||||
void         eek_layout_update_layout(EekKeyboard *keyboard);
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
#endif  /* EEK_LAYOUT_H */
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										1
									
								
								eek/eek-marshalers.list
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								eek/eek-marshalers.list
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1 @@
 | 
			
		||||
VOID:INT,INT
 | 
			
		||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@ -21,10 +21,9 @@
 | 
			
		||||
#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"
 | 
			
		||||
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
@ -36,9 +35,15 @@ struct _EekRendererClass
 | 
			
		||||
{
 | 
			
		||||
    GObjectClass parent_class;
 | 
			
		||||
 | 
			
		||||
    void             (* render_button)         (EekRenderer *self,
 | 
			
		||||
    void             (* render_key_outline) (EekRenderer *self,
 | 
			
		||||
                                             cairo_t     *cr,
 | 
			
		||||
                                             struct button_place *place,
 | 
			
		||||
                                             EekKey      *key,
 | 
			
		||||
                                             gdouble      scale,
 | 
			
		||||
                                             gboolean     rotate);
 | 
			
		||||
 | 
			
		||||
    void             (* render_key)         (EekRenderer *self,
 | 
			
		||||
                                             cairo_t     *cr,
 | 
			
		||||
                                             EekKey      *key,
 | 
			
		||||
                                             gdouble      scale,
 | 
			
		||||
                                             gboolean     rotate);
 | 
			
		||||
 | 
			
		||||
@ -56,8 +61,9 @@ struct _EekRendererClass
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
GType            eek_renderer_get_type         (void) G_GNUC_CONST;
 | 
			
		||||
EekRenderer     *eek_renderer_new              (LevelKeyboard     *keyboard,
 | 
			
		||||
                                                PangoContext    *pcontext);
 | 
			
		||||
EekRenderer     *eek_renderer_new              (EekKeyboard     *keyboard,
 | 
			
		||||
                                                PangoContext    *pcontext,
 | 
			
		||||
                                                GtkStyleContext *scontext);
 | 
			
		||||
void             eek_renderer_set_allocation_size
 | 
			
		||||
                                               (EekRenderer     *renderer,
 | 
			
		||||
                                                gdouble          width,
 | 
			
		||||
@ -65,8 +71,8 @@ void             eek_renderer_set_allocation_size
 | 
			
		||||
void             eek_renderer_get_size         (EekRenderer     *renderer,
 | 
			
		||||
                                                gdouble         *width,
 | 
			
		||||
                                                gdouble         *height);
 | 
			
		||||
void             eek_renderer_get_button_bounds   (EekRenderer     *renderer,
 | 
			
		||||
                                                struct button_place *button,
 | 
			
		||||
void             eek_renderer_get_key_bounds   (EekRenderer     *renderer,
 | 
			
		||||
                                                EekKey          *key,
 | 
			
		||||
                                                EekBounds       *bounds,
 | 
			
		||||
                                                gboolean         rotate);
 | 
			
		||||
 | 
			
		||||
@ -76,9 +82,20 @@ void             eek_renderer_set_scale_factor (EekRenderer     *renderer,
 | 
			
		||||
 | 
			
		||||
PangoLayout     *eek_renderer_create_pango_layout
 | 
			
		||||
                                               (EekRenderer     *renderer);
 | 
			
		||||
void             eek_renderer_render_button       (EekRenderer     *renderer,
 | 
			
		||||
void             eek_renderer_render_key_label (EekRenderer     *renderer,
 | 
			
		||||
                                                PangoLayout     *layout,
 | 
			
		||||
                                                EekKey          *key);
 | 
			
		||||
 | 
			
		||||
void             eek_renderer_render_key_outline
 | 
			
		||||
                                               (EekRenderer     *renderer,
 | 
			
		||||
                                                cairo_t         *cr,
 | 
			
		||||
                                                struct button_place *place,
 | 
			
		||||
                                                EekKey          *key,
 | 
			
		||||
                                                gdouble          scale,
 | 
			
		||||
                                                gboolean         rotate);
 | 
			
		||||
 | 
			
		||||
void             eek_renderer_render_key       (EekRenderer     *renderer,
 | 
			
		||||
                                                cairo_t         *cr,
 | 
			
		||||
                                                EekKey          *key,
 | 
			
		||||
                                                gdouble          scale,
 | 
			
		||||
                                                gboolean         rotate);
 | 
			
		||||
 | 
			
		||||
@ -102,12 +119,14 @@ void             eek_renderer_get_foreground_color
 | 
			
		||||
                                                EekColor        *color);
 | 
			
		||||
void             eek_renderer_set_border_width (EekRenderer     *renderer,
 | 
			
		||||
                                                gdouble          border_width);
 | 
			
		||||
struct squeek_button *eek_renderer_find_button_by_position(EekRenderer     *renderer, struct squeek_view *view,
 | 
			
		||||
EekKey          *eek_renderer_find_key_by_position
 | 
			
		||||
                                               (EekRenderer     *renderer,
 | 
			
		||||
                                                gdouble          x,
 | 
			
		||||
                                                gdouble          y);
 | 
			
		||||
void             eek_renderer_apply_transformation_for_button
 | 
			
		||||
void             eek_renderer_apply_transformation_for_key
 | 
			
		||||
                                               (EekRenderer     *renderer,
 | 
			
		||||
                                                cairo_t         *cr, struct button_place *place,
 | 
			
		||||
                                                cairo_t         *cr,
 | 
			
		||||
                                                EekKey          *key,
 | 
			
		||||
                                                gdouble          scale,
 | 
			
		||||
                                                gboolean         rotate);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										563
									
								
								eek/eek-section.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										563
									
								
								eek/eek-section.c
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,563 @@
 | 
			
		||||
/*
 | 
			
		||||
 * 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-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.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "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;
 | 
			
		||||
    EekRow row;
 | 
			
		||||
    EekModifierType modifiers;
 | 
			
		||||
} EekSectionPrivate;
 | 
			
		||||
 | 
			
		||||
G_DEFINE_TYPE_WITH_PRIVATE (EekSection, eek_section, EEK_TYPE_CONTAINER)
 | 
			
		||||
 | 
			
		||||
static gint
 | 
			
		||||
eek_section_real_get_n_rows (EekSection *self)
 | 
			
		||||
{
 | 
			
		||||
return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
eek_section_real_add_row (EekSection    *self,
 | 
			
		||||
                          gint           num_columns,
 | 
			
		||||
                          EekOrientation orientation)
 | 
			
		||||
{
 | 
			
		||||
    EekSectionPrivate *priv = (EekSectionPrivate*)eek_section_get_instance_private (self);
 | 
			
		||||
    priv->row.num_columns = num_columns;
 | 
			
		||||
    priv->row.orientation = orientation;
 | 
			
		||||
/*
 | 
			
		||||
    row = g_slice_new (EekRow);
 | 
			
		||||
    row->num_columns = num_columns;
 | 
			
		||||
    row->orientation = orientation;
 | 
			
		||||
    priv->rows = g_slist_append (priv->rows, row);*/
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
eek_section_real_get_row (EekSection     *self,
 | 
			
		||||
                          gint            index,
 | 
			
		||||
                          gint           *num_columns,
 | 
			
		||||
                          EekOrientation *orientation)
 | 
			
		||||
{
 | 
			
		||||
    EekSectionPrivate *priv = (EekSectionPrivate*)eek_section_get_instance_private (self);
 | 
			
		||||
    EekRow *row = &priv->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,
 | 
			
		||||
                             const gchar *name,
 | 
			
		||||
                             gint        keycode)
 | 
			
		||||
{
 | 
			
		||||
    EekSectionPrivate *priv = (EekSectionPrivate*)eek_section_get_instance_private (self);
 | 
			
		||||
 | 
			
		||||
    EekRow *row = &priv->row;
 | 
			
		||||
    row->num_columns++;
 | 
			
		||||
 | 
			
		||||
    EekKey *key = (EekKey*)g_object_new (EEK_TYPE_KEY,
 | 
			
		||||
                                         "name", name,
 | 
			
		||||
                                         "keycode", keycode,
 | 
			
		||||
                                         NULL);
 | 
			
		||||
    g_return_val_if_fail (key, NULL);
 | 
			
		||||
 | 
			
		||||
    EEK_CONTAINER_GET_CLASS(self)->add_child (EEK_CONTAINER(self),
 | 
			
		||||
                                              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 = (EekSectionPrivate*)eek_section_get_instance_private (self);
 | 
			
		||||
 | 
			
		||||
    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
 | 
			
		||||
 * @name: a name
 | 
			
		||||
 * @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,
 | 
			
		||||
                        const gchar *name,
 | 
			
		||||
                        gint        keycode)
 | 
			
		||||
{
 | 
			
		||||
    g_return_val_if_fail (EEK_IS_SECTION(section), NULL);
 | 
			
		||||
    return EEK_SECTION_GET_CLASS(section)->create_key (section,
 | 
			
		||||
                                                       name,
 | 
			
		||||
                                                       keycode);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const double keyspacing = 4.0;
 | 
			
		||||
 | 
			
		||||
struct keys_info {
 | 
			
		||||
    uint count;
 | 
			
		||||
    double total_width;
 | 
			
		||||
    double biggest_height;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
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);
 | 
			
		||||
    if (outline && outline->num_points > 0) {
 | 
			
		||||
        double minx = outline->points[0].x;
 | 
			
		||||
        double maxx = minx;
 | 
			
		||||
        double miny = outline->points[0].y;
 | 
			
		||||
        double maxy = miny;
 | 
			
		||||
        for (uint i = 1; i < outline->num_points; i++) {
 | 
			
		||||
            EekPoint p = outline->points[i];
 | 
			
		||||
            if (p.x < minx) {
 | 
			
		||||
                minx = p.x;
 | 
			
		||||
            } else if (p.x > maxx) {
 | 
			
		||||
                maxx = p.x;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (p.y < miny) {
 | 
			
		||||
                miny = p.y;
 | 
			
		||||
            } else if (p.y > maxy) {
 | 
			
		||||
                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);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
keycounter (EekElement *element, gpointer user_data)
 | 
			
		||||
{
 | 
			
		||||
    EekKey *key = EEK_KEY(element);
 | 
			
		||||
 | 
			
		||||
    /* Skip keys without labels for the current level. This causes those
 | 
			
		||||
       keys to be hidden in the visible layout. */
 | 
			
		||||
    if (!eek_key_has_label(key))
 | 
			
		||||
        return;
 | 
			
		||||
 | 
			
		||||
    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;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
keyplacer(EekElement *element, gpointer user_data)
 | 
			
		||||
{
 | 
			
		||||
    EekKey *key = EEK_KEY(element);
 | 
			
		||||
 | 
			
		||||
    /* Skip keys without labels for the current level. */
 | 
			
		||||
    if (!eek_key_has_label(key))
 | 
			
		||||
        return;
 | 
			
		||||
 | 
			
		||||
    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);
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										110
									
								
								eek/eek-section.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										110
									
								
								eek/eek-section.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,110 @@
 | 
			
		||||
/* 
 | 
			
		||||
 * 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_SECTION_H
 | 
			
		||||
#define EEK_SECTION_H 1
 | 
			
		||||
 | 
			
		||||
#include <glib-object.h>
 | 
			
		||||
#include "eek-container.h"
 | 
			
		||||
#include "eek-types.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,
 | 
			
		||||
                                     const gchar    *name,
 | 
			
		||||
                                     gint            keycode);
 | 
			
		||||
 | 
			
		||||
    /* 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,
 | 
			
		||||
                                          const gchar    *name,
 | 
			
		||||
                                          gint            keycode);
 | 
			
		||||
 | 
			
		||||
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 */
 | 
			
		||||
							
								
								
									
										89
									
								
								eek/eek-serializable.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										89
									
								
								eek/eek-serializable.c
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,89 @@
 | 
			
		||||
/*
 | 
			
		||||
 * 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.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "config.h"
 | 
			
		||||
 | 
			
		||||
#include "eek-serializable.h"
 | 
			
		||||
 | 
			
		||||
GType
 | 
			
		||||
eek_serializable_get_type (void)
 | 
			
		||||
{
 | 
			
		||||
    static GType iface_type = 0;
 | 
			
		||||
    if (iface_type == 0) {
 | 
			
		||||
        static GTypeInfo info = {
 | 
			
		||||
            .class_size = sizeof (EekSerializableIface)
 | 
			
		||||
        };
 | 
			
		||||
        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;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										66
									
								
								eek/eek-serializable.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										66
									
								
								eek/eek-serializable.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,66 @@
 | 
			
		||||
/* 
 | 
			
		||||
 * 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 */
 | 
			
		||||
							
								
								
									
										99
									
								
								eek/eek-symbol-matrix.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										99
									
								
								eek/eek-symbol-matrix.c
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,99 @@
 | 
			
		||||
/* 
 | 
			
		||||
 * 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;
 | 
			
		||||
    guint num_symbols = matrix->num_groups * matrix->num_levels;
 | 
			
		||||
 | 
			
		||||
    retval = g_slice_dup (EekSymbolMatrix, matrix);
 | 
			
		||||
    retval->data = g_slice_copy (sizeof (EekSymbol *) * num_symbols,
 | 
			
		||||
                                 matrix->data);
 | 
			
		||||
    // FIXME: do a deep copy over the data in EekSymbol
 | 
			
		||||
    return retval;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
eek_symbol_matrix_free (EekSymbolMatrix *matrix)
 | 
			
		||||
{
 | 
			
		||||
    guint num_symbols = matrix->num_groups * matrix->num_levels;
 | 
			
		||||
    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);
 | 
			
		||||
    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];
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										62
									
								
								eek/eek-symbol-matrix.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										62
									
								
								eek/eek-symbol-matrix.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,62 @@
 | 
			
		||||
/* 
 | 
			
		||||
 * 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 */
 | 
			
		||||
@ -30,15 +30,42 @@
 | 
			
		||||
#include "eek-symbol.h"
 | 
			
		||||
#include "eek-enumtypes.h"
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
eek_symbol_destroy (EekSymbol *priv)
 | 
			
		||||
{
 | 
			
		||||
    g_free (priv->name);
 | 
			
		||||
    g_free (priv->label);
 | 
			
		||||
    g_free (priv->icon_name);
 | 
			
		||||
    g_free (priv->tooltip);
 | 
			
		||||
    g_free(priv->text);
 | 
			
		||||
    g_free(priv);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
EekSymbol *
 | 
			
		||||
eek_symbol_new (const gchar *name)
 | 
			
		||||
{
 | 
			
		||||
    EekSymbol *self = g_new0(EekSymbol, 1);
 | 
			
		||||
    self->name = g_strdup (name);
 | 
			
		||||
    eek_symbol_set_name(self, name);
 | 
			
		||||
    self->category = EEK_SYMBOL_CATEGORY_UNKNOWN;
 | 
			
		||||
    return self;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
eek_symbol_set_name (EekSymbol   *symbol,
 | 
			
		||||
                     const gchar *name)
 | 
			
		||||
{
 | 
			
		||||
    g_free (symbol->name);
 | 
			
		||||
    symbol->name = g_strdup (name);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const gchar *
 | 
			
		||||
eek_symbol_get_name (EekSymbol *symbol)
 | 
			
		||||
{
 | 
			
		||||
    if (symbol->name == NULL || *symbol->name == '\0')
 | 
			
		||||
        return NULL;
 | 
			
		||||
    return symbol->name;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eek_symbol_set_label:
 | 
			
		||||
 * @symbol: an #EekSymbol
 | 
			
		||||
@ -54,6 +81,20 @@ eek_symbol_set_label (EekSymbol   *symbol,
 | 
			
		||||
    symbol->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)
 | 
			
		||||
{
 | 
			
		||||
    if (symbol->label == NULL || *symbol->label == '\0')
 | 
			
		||||
        return NULL;
 | 
			
		||||
    return symbol->label;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eek_symbol_set_modifier_mask:
 | 
			
		||||
 * @symbol: an #EekSymbol
 | 
			
		||||
@ -77,10 +118,15 @@ eek_symbol_set_modifier_mask (EekSymbol      *symbol,
 | 
			
		||||
EekModifierType
 | 
			
		||||
eek_symbol_get_modifier_mask (EekSymbol *symbol)
 | 
			
		||||
{
 | 
			
		||||
    return 0;
 | 
			
		||||
    return symbol->modifier_mask;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
gboolean
 | 
			
		||||
eek_symbol_is_modifier (EekSymbol *symbol)
 | 
			
		||||
{
 | 
			
		||||
    return eek_symbol_get_modifier_mask (symbol) != 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
eek_symbol_set_icon_name (EekSymbol   *symbol,
 | 
			
		||||
                          const gchar *icon_name)
 | 
			
		||||
@ -92,7 +138,9 @@ eek_symbol_set_icon_name (EekSymbol   *symbol,
 | 
			
		||||
const gchar *
 | 
			
		||||
eek_symbol_get_icon_name (EekSymbol *symbol)
 | 
			
		||||
{
 | 
			
		||||
    return NULL;
 | 
			
		||||
    if (symbol->icon_name == NULL || *symbol->icon_name == '\0')
 | 
			
		||||
        return NULL;
 | 
			
		||||
    return symbol->icon_name;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
@ -106,7 +154,6 @@ eek_symbol_set_tooltip (EekSymbol   *symbol,
 | 
			
		||||
const gchar *
 | 
			
		||||
eek_symbol_get_tooltip (EekSymbol *symbol)
 | 
			
		||||
{
 | 
			
		||||
    return NULL;
 | 
			
		||||
    if (symbol->tooltip == NULL || *symbol->tooltip == '\0')
 | 
			
		||||
        return NULL;
 | 
			
		||||
    return symbol->tooltip;
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										107
									
								
								eek/eek-symbol.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										107
									
								
								eek/eek-symbol.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,107 @@
 | 
			
		||||
/* 
 | 
			
		||||
 * 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;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
typedef struct _EekSymbol
 | 
			
		||||
{
 | 
			
		||||
    /// Canonical name of the symbol
 | 
			
		||||
    gchar *name;
 | 
			
		||||
    /// Text used to display the symbol
 | 
			
		||||
    gchar *label;
 | 
			
		||||
    EekSymbolCategory category;
 | 
			
		||||
    EekModifierType modifier_mask;
 | 
			
		||||
    /// Icon name used to render the symbol
 | 
			
		||||
    gchar *icon_name;
 | 
			
		||||
    /// Tooltip text
 | 
			
		||||
    gchar *tooltip;
 | 
			
		||||
 | 
			
		||||
    // May not be present
 | 
			
		||||
    guint xkeysym;
 | 
			
		||||
    gchar *text;
 | 
			
		||||
} EekSymbol;
 | 
			
		||||
 | 
			
		||||
EekSymbol        *eek_symbol_new                (const gchar      *name);
 | 
			
		||||
void              eek_symbol_free               (EekSymbol        *symbol);
 | 
			
		||||
void              eek_symbol_set_name           (EekSymbol        *symbol,
 | 
			
		||||
                                                 const gchar      *name);
 | 
			
		||||
const gchar      *eek_symbol_get_name           (EekSymbol        *symbol);
 | 
			
		||||
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 */
 | 
			
		||||
							
								
								
									
										43
									
								
								eek/eek-text.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								eek/eek-text.c
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,43 @@
 | 
			
		||||
/* 
 | 
			
		||||
 * 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
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "config.h"
 | 
			
		||||
 | 
			
		||||
#include "eek-text.h"
 | 
			
		||||
 | 
			
		||||
EekSymbol *
 | 
			
		||||
eek_text_new (const gchar *text)
 | 
			
		||||
{
 | 
			
		||||
    EekSymbol *ret = eek_symbol_new("");
 | 
			
		||||
    eek_symbol_set_label(ret, text);
 | 
			
		||||
    ret->text = g_strdup (text);
 | 
			
		||||
    return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const gchar *
 | 
			
		||||
eek_text_get_text (EekSymbol *text)
 | 
			
		||||
{
 | 
			
		||||
    return text->text;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										38
									
								
								eek/eek-text.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								eek/eek-text.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,38 @@
 | 
			
		||||
/* 
 | 
			
		||||
 * 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
 | 
			
		||||
 | 
			
		||||
GType        eek_text_get_type (void) G_GNUC_CONST;
 | 
			
		||||
EekSymbol   *eek_text_new      (const gchar *text);
 | 
			
		||||
const gchar *eek_text_get_text (EekSymbol   *text);
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
 | 
			
		||||
#endif  /* EEK_TEXT_H */
 | 
			
		||||
@ -134,6 +134,10 @@ 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 _EekText EekText;
 | 
			
		||||
typedef struct _EekTheme EekTheme;
 | 
			
		||||
@ -146,7 +150,6 @@ typedef struct _EekOutline EekOutline;
 | 
			
		||||
typedef struct _EekColor EekColor;
 | 
			
		||||
 | 
			
		||||
typedef struct _EekboardContextService EekboardContextService;
 | 
			
		||||
typedef struct _LevelKeyboard LevelKeyboard;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * EekPoint:
 | 
			
		||||
@ -191,6 +194,12 @@ 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
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										1412
									
								
								eek/eek-xml-layout.c
									
									
									
									
									
								
							
							
						
						
									
										1412
									
								
								eek/eek-xml-layout.c
									
									
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@ -23,11 +23,44 @@
 | 
			
		||||
#ifndef EEK_XML_LAYOUT_H
 | 
			
		||||
#define EEK_XML_LAYOUT_H 1
 | 
			
		||||
 | 
			
		||||
#include "eek-types.h"
 | 
			
		||||
#include <gio/gio.h>
 | 
			
		||||
#include "eek-layout.h"
 | 
			
		||||
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
LevelKeyboard *
 | 
			
		||||
eek_xml_layout_real_create_keyboard (const char *keyboard_type,
 | 
			
		||||
                                     EekboardContextService *manager);
 | 
			
		||||
 | 
			
		||||
#define EEK_TYPE_XML_LAYOUT (eek_xml_layout_get_type())
 | 
			
		||||
G_DECLARE_DERIVABLE_TYPE (EekXmlLayout, eek_xml_layout, EEK, XML_LAYOUT, EekLayout)
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * EekXmlLayoutClass:
 | 
			
		||||
 */
 | 
			
		||||
struct _EekXmlLayoutClass
 | 
			
		||||
{
 | 
			
		||||
    /*< private >*/
 | 
			
		||||
    EekLayoutClass parent_class;
 | 
			
		||||
 | 
			
		||||
    /* padding */
 | 
			
		||||
    gpointer pdummy[24];
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct _EekXmlKeyboardDesc
 | 
			
		||||
{
 | 
			
		||||
    gchar *id;
 | 
			
		||||
    gchar *name;
 | 
			
		||||
    gchar *geometry;
 | 
			
		||||
    gchar *symbols;
 | 
			
		||||
    gchar *language;
 | 
			
		||||
    gchar *longname;
 | 
			
		||||
};
 | 
			
		||||
typedef struct _EekXmlKeyboardDesc EekXmlKeyboardDesc;
 | 
			
		||||
 | 
			
		||||
GType               eek_xml_layout_get_type    (void) G_GNUC_CONST;
 | 
			
		||||
EekLayout          *eek_xml_layout_new         (const gchar        *id,
 | 
			
		||||
                                                GError            **error);
 | 
			
		||||
GList              *eek_xml_list_keyboards     (void);
 | 
			
		||||
 | 
			
		||||
EekXmlKeyboardDesc *eek_xml_keyboard_desc_copy (EekXmlKeyboardDesc *desc);
 | 
			
		||||
void                eek_xml_keyboard_desc_free (EekXmlKeyboardDesc *desc);
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
#endif  /* EEK_XML_LAYOUT_H */
 | 
			
		||||
 | 
			
		||||
@ -23,7 +23,13 @@
 | 
			
		||||
#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-serializable.h"
 | 
			
		||||
 | 
			
		||||
void eek_init (void);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										50
									
								
								eek/gen-keysym-entries.py
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										50
									
								
								eek/gen-keysym-entries.py
									
									
									
									
									
										Executable file
									
								
							@ -0,0 +1,50 @@
 | 
			
		||||
#!/usr/bin/env python3
 | 
			
		||||
 | 
			
		||||
# Copyright (C) 2010-2011 Daiki Ueno <ueno@unixuser.org>
 | 
			
		||||
# Copyright (C) 2010-2011 Red Hat, Inc.
 | 
			
		||||
# Copyright (C) 2019      Purism, SPC
 | 
			
		||||
 | 
			
		||||
# This library is free software; you can redistribute it and/or
 | 
			
		||||
# modify it under the terms of the GNU Lesser General Public License
 | 
			
		||||
# as published by the Free Software Foundation; either version 2 of
 | 
			
		||||
# the License, or (at your option) any later version.
 | 
			
		||||
 | 
			
		||||
# This library is distributed in the hope that it will be useful, but
 | 
			
		||||
# WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
			
		||||
# Lesser General Public License for more details.
 | 
			
		||||
 | 
			
		||||
# You should have received a copy of the GNU Lesser General Public
 | 
			
		||||
# License along with this library; if not, write to the Free Software
 | 
			
		||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 | 
			
		||||
# 02110-1301 USA
 | 
			
		||||
 | 
			
		||||
import sys
 | 
			
		||||
import re
 | 
			
		||||
 | 
			
		||||
if len(sys.argv) > 3:
 | 
			
		||||
    print("Usage: %s TABLE-NAME [INPUT_FILE]" % sys.argv[0], file=sys.stderr)
 | 
			
		||||
    sys.exit(-1)
 | 
			
		||||
 | 
			
		||||
if len(sys.argv) < 3:
 | 
			
		||||
    in_stream = sys.stdin
 | 
			
		||||
else:
 | 
			
		||||
    in_stream = open(sys.argv[2])
 | 
			
		||||
 | 
			
		||||
table = dict()
 | 
			
		||||
for line in in_stream:
 | 
			
		||||
    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))
 | 
			
		||||
 | 
			
		||||
sys.stdout.write("static const EekKeysymEntry %s[] = {\n" %
 | 
			
		||||
                 sys.argv[1])
 | 
			
		||||
 | 
			
		||||
for index, (keysym, (l, c)) in enumerate([(keysym, table[keysym])
 | 
			
		||||
                                          for keysym in sorted(table.keys())]):
 | 
			
		||||
    sys.stdout.write("    { 0x%X, \"%s\" }" %
 | 
			
		||||
                     (keysym, l))
 | 
			
		||||
    if index < len(table) - 1:
 | 
			
		||||
        sys.stdout.write(",")
 | 
			
		||||
    sys.stdout.write("\n")
 | 
			
		||||
sys.stdout.write("};\n")
 | 
			
		||||
							
								
								
									
										31
									
								
								eek/keymap.h
									
									
									
									
									
								
							
							
						
						
									
										31
									
								
								eek/keymap.h
									
									
									
									
									
								
							@ -6,3 +6,34 @@ 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\
 | 
			
		||||
};";
 | 
			
		||||
 | 
			
		||||
@ -1,8 +1,44 @@
 | 
			
		||||
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@'],
 | 
			
		||||
  capture: true,
 | 
			
		||||
  output: 'eek-@BASENAME@.h',
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
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'),
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										62
									
								
								eek/special-keysym-entries.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										62
									
								
								eek/special-keysym-entries.txt
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,62 @@
 | 
			
		||||
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
 | 
			
		||||
							
								
								
									
										826
									
								
								eek/unicode-keysym-entries.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										826
									
								
								eek/unicode-keysym-entries.txt
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,826 @@
 | 
			
		||||
# 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 
 | 
			
		||||
							
								
								
									
										1306
									
								
								eek/xkeysym-keysym-entries.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1306
									
								
								eek/xkeysym-keysym-entries.txt
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@ -29,7 +29,6 @@
 | 
			
		||||
 | 
			
		||||
#include <fcntl.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#define _XOPEN_SOURCE 500
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <sys/mman.h>
 | 
			
		||||
#include <sys/random.h> // TODO: this is Linux-specific
 | 
			
		||||
@ -51,6 +50,7 @@ enum {
 | 
			
		||||
    PROP_0, // Magic: without this, keyboard is not useable in g_object_notify
 | 
			
		||||
    PROP_KEYBOARD,
 | 
			
		||||
    PROP_VISIBLE,
 | 
			
		||||
    PROP_FULLSCREEN,
 | 
			
		||||
    PROP_LAST
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
@ -69,11 +69,13 @@ static guint signals[LAST_SIGNAL] = { 0, };
 | 
			
		||||
struct _EekboardContextServicePrivate {
 | 
			
		||||
    gboolean enabled;
 | 
			
		||||
    gboolean visible;
 | 
			
		||||
    gboolean fullscreen;
 | 
			
		||||
 | 
			
		||||
    LevelKeyboard *keyboard; // currently used keyboard
 | 
			
		||||
    EekKeyboard *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;
 | 
			
		||||
 | 
			
		||||
@ -84,29 +86,77 @@ struct _EekboardContextServicePrivate {
 | 
			
		||||
 | 
			
		||||
G_DEFINE_TYPE_WITH_PRIVATE (EekboardContextService, eekboard_context_service, G_TYPE_OBJECT);
 | 
			
		||||
 | 
			
		||||
static LevelKeyboard *
 | 
			
		||||
static EekKeyboard *
 | 
			
		||||
eekboard_context_service_real_create_keyboard (EekboardContextService *self,
 | 
			
		||||
                                               const gchar            *keyboard_type)
 | 
			
		||||
{
 | 
			
		||||
    LevelKeyboard *keyboard = eek_xml_layout_real_create_keyboard(keyboard_type, self);
 | 
			
		||||
    EekKeyboard *keyboard;
 | 
			
		||||
    EekLayout *layout;
 | 
			
		||||
    GError *error;
 | 
			
		||||
 | 
			
		||||
    if (g_str_has_prefix (keyboard_type, "xkb:")) {
 | 
			
		||||
        /* TODO: Depends on xklavier
 | 
			
		||||
        XklConfigRec *rec =
 | 
			
		||||
            eekboard_xkl_config_rec_from_string (&keyboard_type[4]);
 | 
			
		||||
 | 
			
		||||
        if (display == NULL)
 | 
			
		||||
            //display = XOpenDisplay (NULL);
 | 
			
		||||
            return NULL; // FIXME: replace with wl display
 | 
			
		||||
 | 
			
		||||
        error = NULL;
 | 
			
		||||
        layout = eek_xkl_layout_new (display, &error);
 | 
			
		||||
        if (layout == NULL) {
 | 
			
		||||
            g_warning ("can't create keyboard %s: %s",
 | 
			
		||||
                       keyboard_type, error->message);
 | 
			
		||||
            g_error_free (error);
 | 
			
		||||
            return NULL;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (!eek_xkl_layout_set_config (EEK_XKL_LAYOUT(layout), rec)) {
 | 
			
		||||
            g_object_unref (layout);
 | 
			
		||||
            return NULL;
 | 
			
		||||
        }
 | 
			
		||||
        */
 | 
			
		||||
        return NULL;
 | 
			
		||||
    } else {
 | 
			
		||||
        error = NULL;
 | 
			
		||||
        layout = eek_xml_layout_new (keyboard_type, &error);
 | 
			
		||||
        if (layout == NULL) {
 | 
			
		||||
            g_warning ("can't create keyboard %s: %s",
 | 
			
		||||
                       keyboard_type, error->message);
 | 
			
		||||
            g_error_free (error);
 | 
			
		||||
            keyboard_type = "us";
 | 
			
		||||
            error = NULL;
 | 
			
		||||
            layout = eek_xml_layout_new (keyboard_type, &error);
 | 
			
		||||
            if (layout == NULL) {
 | 
			
		||||
                g_error ("failed to create fallback layout: %s", error->message);
 | 
			
		||||
                g_error_free (error);
 | 
			
		||||
                return NULL;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    keyboard = eek_keyboard_new (self, layout, CSW, CSH);
 | 
			
		||||
    if (!keyboard) {
 | 
			
		||||
        g_error("Failed to create a keyboard");
 | 
			
		||||
    }
 | 
			
		||||
    g_object_unref (layout);
 | 
			
		||||
 | 
			
		||||
    struct xkb_context *context = xkb_context_new(XKB_CONTEXT_NO_FLAGS);
 | 
			
		||||
    if (!context) {
 | 
			
		||||
        g_error("No context created");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const gchar *keymap_str = squeek_layout_get_keymap(keyboard->layout);
 | 
			
		||||
    gchar *keymap_str = eek_keyboard_get_keymap(keyboard);
 | 
			
		||||
 | 
			
		||||
    struct xkb_keymap *keymap = xkb_keymap_new_from_string(context, keymap_str,
 | 
			
		||||
        XKB_KEYMAP_FORMAT_TEXT_V1, XKB_KEYMAP_COMPILE_NO_FLAGS);
 | 
			
		||||
 | 
			
		||||
    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;
 | 
			
		||||
 | 
			
		||||
    keymap_str = xkb_keymap_get_as_string(keymap, XKB_KEYMAP_FORMAT_TEXT_V1);
 | 
			
		||||
@ -115,7 +165,7 @@ eekboard_context_service_real_create_keyboard (EekboardContextService *self,
 | 
			
		||||
    g_autofree char *path = strdup("/eek_keymap-XXXXXX");
 | 
			
		||||
    char *r = &path[strlen(path) - 6];
 | 
			
		||||
    getrandom(r, 6, GRND_NONBLOCK);
 | 
			
		||||
    for (unsigned i = 0; i < 6; i++) {
 | 
			
		||||
    for (uint i = 0; i < 6; i++) {
 | 
			
		||||
        r[i] = (r[i] & 0b1111111) | 0b1000000; // A-z
 | 
			
		||||
        r[i] = r[i] > 'z' ? '?' : r[i]; // The randomizer doesn't need to be good...
 | 
			
		||||
    }
 | 
			
		||||
@ -133,8 +183,9 @@ eekboard_context_service_real_create_keyboard (EekboardContextService *self,
 | 
			
		||||
    if ((void*)ptr == (void*)-1) {
 | 
			
		||||
        g_error("Failed to set up mmap");
 | 
			
		||||
    }
 | 
			
		||||
    strncpy(ptr, keymap_str, keyboard->keymap_len);
 | 
			
		||||
    strcpy(ptr, keymap_str);
 | 
			
		||||
    munmap(ptr, keyboard->keymap_len);
 | 
			
		||||
    free(keymap_str);
 | 
			
		||||
 | 
			
		||||
    return keyboard;
 | 
			
		||||
}
 | 
			
		||||
@ -168,6 +219,9 @@ eekboard_context_service_set_property (GObject      *object,
 | 
			
		||||
    case PROP_VISIBLE:
 | 
			
		||||
        context->priv->visible = g_value_get_boolean (value);
 | 
			
		||||
        break;
 | 
			
		||||
    case PROP_FULLSCREEN:
 | 
			
		||||
        context->priv->fullscreen = g_value_get_boolean (value);
 | 
			
		||||
        break;
 | 
			
		||||
    default:
 | 
			
		||||
        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 | 
			
		||||
        break;
 | 
			
		||||
@ -189,6 +243,9 @@ eekboard_context_service_get_property (GObject    *object,
 | 
			
		||||
    case PROP_VISIBLE:
 | 
			
		||||
        g_value_set_boolean (value, context->priv->visible);
 | 
			
		||||
        break;
 | 
			
		||||
    case PROP_FULLSCREEN:
 | 
			
		||||
        g_value_set_boolean (value, context->priv->fullscreen);
 | 
			
		||||
        break;
 | 
			
		||||
    default:
 | 
			
		||||
        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 | 
			
		||||
        break;
 | 
			
		||||
@ -248,26 +305,41 @@ settings_update_layout(EekboardContextService *context)
 | 
			
		||||
    EekboardContextServicePrivate *priv = EEKBOARD_CONTEXT_SERVICE_GET_PRIVATE(context);
 | 
			
		||||
 | 
			
		||||
    switch (priv->purpose) {
 | 
			
		||||
    case ZWP_TEXT_INPUT_V3_CONTENT_PURPOSE_DIGITS:
 | 
			
		||||
    case ZWP_TEXT_INPUT_V3_CONTENT_PURPOSE_PIN:
 | 
			
		||||
        keyboard_layout = g_strdup("digits");
 | 
			
		||||
        break;
 | 
			
		||||
    case ZWP_TEXT_INPUT_V3_CONTENT_PURPOSE_NUMBER:
 | 
			
		||||
    case ZWP_TEXT_INPUT_V3_CONTENT_PURPOSE_PHONE:
 | 
			
		||||
        keyboard_layout = g_strdup("number");
 | 
			
		||||
        break;
 | 
			
		||||
    case ZWP_TEXT_INPUT_V3_CONTENT_PURPOSE_PHONE:
 | 
			
		||||
        keyboard_layout = g_strdup("phone");
 | 
			
		||||
        break;
 | 
			
		||||
    case ZWP_TEXT_INPUT_V3_CONTENT_PURPOSE_URL:
 | 
			
		||||
        keyboard_layout = g_strdup("url");
 | 
			
		||||
        break;
 | 
			
		||||
    case ZWP_TEXT_INPUT_V3_CONTENT_PURPOSE_NORMAL:
 | 
			
		||||
    default:
 | 
			
		||||
        ;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // generic part follows
 | 
			
		||||
    static guint keyboard_id = 0;
 | 
			
		||||
    LevelKeyboard *keyboard = g_hash_table_lookup(context->priv->keyboard_hash,
 | 
			
		||||
    EekKeyboard *keyboard = g_hash_table_lookup(context->priv->keyboard_hash,
 | 
			
		||||
                                                GUINT_TO_POINTER(keyboard_id));
 | 
			
		||||
    // create a keyboard
 | 
			
		||||
    if (!keyboard) {
 | 
			
		||||
        keyboard = eekboard_context_service_real_create_keyboard(context, keyboard_layout);
 | 
			
		||||
        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);
 | 
			
		||||
 | 
			
		||||
        g_hash_table_insert (context->priv->keyboard_hash,
 | 
			
		||||
                             GUINT_TO_POINTER(keyboard_id),
 | 
			
		||||
                             keyboard);
 | 
			
		||||
        keyboard->id = keyboard_id;
 | 
			
		||||
        g_object_set_data (G_OBJECT(keyboard),
 | 
			
		||||
                           "keyboard-id",
 | 
			
		||||
                           GUINT_TO_POINTER(keyboard_id));
 | 
			
		||||
        keyboard_id++;
 | 
			
		||||
    }
 | 
			
		||||
    // set as current
 | 
			
		||||
@ -308,6 +380,7 @@ 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;
 | 
			
		||||
 | 
			
		||||
@ -372,9 +445,10 @@ eekboard_context_service_class_init (EekboardContextServiceClass *klass)
 | 
			
		||||
     *
 | 
			
		||||
     * An #EekKeyboard currently active in this context.
 | 
			
		||||
     */
 | 
			
		||||
    pspec = g_param_spec_pointer("keyboard",
 | 
			
		||||
    pspec = g_param_spec_object ("keyboard",
 | 
			
		||||
                                 "Keyboard",
 | 
			
		||||
                                 "Keyboard",
 | 
			
		||||
                                 EEK_TYPE_KEYBOARD,
 | 
			
		||||
                                 G_PARAM_READWRITE);
 | 
			
		||||
    g_object_class_install_property (gobject_class,
 | 
			
		||||
                                     PROP_KEYBOARD,
 | 
			
		||||
@ -393,6 +467,20 @@ eekboard_context_service_class_init (EekboardContextServiceClass *klass)
 | 
			
		||||
    g_object_class_install_property (gobject_class,
 | 
			
		||||
                                     PROP_VISIBLE,
 | 
			
		||||
                                     pspec);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * EekboardContextService:fullscreen:
 | 
			
		||||
     *
 | 
			
		||||
     * Flag to indicate if keyboard is rendered in fullscreen mode.
 | 
			
		||||
     */
 | 
			
		||||
    pspec = g_param_spec_boolean ("fullscreen",
 | 
			
		||||
                                  "Fullscreen",
 | 
			
		||||
                                  "Fullscreen",
 | 
			
		||||
                                  FALSE,
 | 
			
		||||
                                  G_PARAM_READWRITE);
 | 
			
		||||
    g_object_class_install_property (gobject_class,
 | 
			
		||||
                                     PROP_FULLSCREEN,
 | 
			
		||||
                                     pspec);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
@ -496,14 +584,27 @@ eekboard_context_service_destroy (EekboardContextService *context)
 | 
			
		||||
 * Get keyboard currently active in @context.
 | 
			
		||||
 * Returns: (transfer none): an #EekKeyboard
 | 
			
		||||
 */
 | 
			
		||||
LevelKeyboard *
 | 
			
		||||
EekKeyboard *
 | 
			
		||||
eekboard_context_service_get_keyboard (EekboardContextService *context)
 | 
			
		||||
{
 | 
			
		||||
    return context->priv->keyboard;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eekboard_context_service_get_fullscreen:
 | 
			
		||||
 * @context: an #EekboardContextService
 | 
			
		||||
 *
 | 
			
		||||
 * Check if keyboard is rendered in fullscreen mode in @context.
 | 
			
		||||
 * Returns: %TRUE or %FALSE
 | 
			
		||||
 */
 | 
			
		||||
gboolean
 | 
			
		||||
eekboard_context_service_get_fullscreen (EekboardContextService *context)
 | 
			
		||||
{
 | 
			
		||||
    return context->priv->fullscreen;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void eekboard_context_service_set_keymap(EekboardContextService *context,
 | 
			
		||||
                                         const LevelKeyboard *keyboard)
 | 
			
		||||
                                         const EekKeyboard *keyboard)
 | 
			
		||||
{
 | 
			
		||||
    zwp_virtual_keyboard_v1_keymap(context->virtual_keyboard,
 | 
			
		||||
        WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1,
 | 
			
		||||
 | 
			
		||||
@ -73,7 +73,7 @@ struct _EekboardContextServiceClass {
 | 
			
		||||
    GObjectClass parent_class;
 | 
			
		||||
 | 
			
		||||
    /*< public >*/
 | 
			
		||||
    struct squeek_view *(*create_keyboard)    (EekboardContextService *self,
 | 
			
		||||
    EekKeyboard *(*create_keyboard)    (EekboardContextService *self,
 | 
			
		||||
                                        const gchar            *keyboard_type);
 | 
			
		||||
    void         (*show_keyboard)      (EekboardContextService *self);
 | 
			
		||||
    void         (*hide_keyboard)      (EekboardContextService *self);
 | 
			
		||||
@ -97,10 +97,13 @@ void          eekboard_context_service_show_keyboard
 | 
			
		||||
void          eekboard_context_service_hide_keyboard
 | 
			
		||||
                                              (EekboardContextService *context);
 | 
			
		||||
void          eekboard_context_service_destroy (EekboardContextService *context);
 | 
			
		||||
LevelKeyboard *eekboard_context_service_get_keyboard(EekboardContextService *context);
 | 
			
		||||
EekKeyboard  *eekboard_context_service_get_keyboard
 | 
			
		||||
                                              (EekboardContextService *context);
 | 
			
		||||
gboolean      eekboard_context_service_get_fullscreen
 | 
			
		||||
                                              (EekboardContextService *context);
 | 
			
		||||
 | 
			
		||||
void eekboard_context_service_set_keymap(EekboardContextService *context,
 | 
			
		||||
                                         const LevelKeyboard *keyboard);
 | 
			
		||||
                                         const EekKeyboard *keyboard);
 | 
			
		||||
 | 
			
		||||
void eekboard_context_service_set_hint_purpose(EekboardContextService *context,
 | 
			
		||||
                                               uint32_t hint,
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										654
									
								
								eekboard/eekboard-context.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										654
									
								
								eekboard/eekboard-context.c
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,654 @@
 | 
			
		||||
/* 
 | 
			
		||||
 * 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/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * SECTION:eekboard-context
 | 
			
		||||
 * @short_description: client interface of eekboard input context service
 | 
			
		||||
 *
 | 
			
		||||
 * The #EekboardContext class provides a client access to remote input
 | 
			
		||||
 * context.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "config.h"
 | 
			
		||||
 | 
			
		||||
#include "eekboard/eekboard-context.h"
 | 
			
		||||
//#include "eekboard/eekboard-marshalers.h"
 | 
			
		||||
 | 
			
		||||
#define I_(string) g_intern_static_string (string)
 | 
			
		||||
 | 
			
		||||
enum {
 | 
			
		||||
    ENABLED,
 | 
			
		||||
    DISABLED,
 | 
			
		||||
    DESTROYED,
 | 
			
		||||
    LAST_SIGNAL
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static guint signals[LAST_SIGNAL] = { 0, };
 | 
			
		||||
 | 
			
		||||
enum {
 | 
			
		||||
    PROP_0,
 | 
			
		||||
    PROP_VISIBLE,
 | 
			
		||||
    PROP_LAST
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
typedef struct _EekboardContextPrivate
 | 
			
		||||
{
 | 
			
		||||
    gboolean visible;
 | 
			
		||||
    gboolean enabled;
 | 
			
		||||
    gboolean fullscreen;
 | 
			
		||||
    gint group;
 | 
			
		||||
} EekboardContextPrivate;
 | 
			
		||||
 | 
			
		||||
G_DEFINE_TYPE_WITH_PRIVATE (EekboardContext, eekboard_context, G_TYPE_DBUS_PROXY)
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
eekboard_context_real_g_signal (GDBusProxy  *self,
 | 
			
		||||
                                const gchar *sender_name,
 | 
			
		||||
                                const gchar *signal_name,
 | 
			
		||||
                                GVariant    *parameters)
 | 
			
		||||
{
 | 
			
		||||
    EekboardContext *context = EEKBOARD_CONTEXT (self);
 | 
			
		||||
    EekboardContextPrivate *priv = eekboard_context_get_instance_private (context);
 | 
			
		||||
 | 
			
		||||
    if (g_strcmp0 (signal_name, "Enabled") == 0) {
 | 
			
		||||
        g_signal_emit (context, signals[ENABLED], 0);
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (g_strcmp0 (signal_name, "Disabled") == 0) {
 | 
			
		||||
        g_signal_emit (context, signals[DISABLED], 0);
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (g_strcmp0 (signal_name, "Destroyed") == 0) {
 | 
			
		||||
        g_signal_emit (context, signals[DESTROYED], 0);
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (g_strcmp0 (signal_name, "VisibilityChanged") == 0) {
 | 
			
		||||
        gboolean visible = FALSE;
 | 
			
		||||
 | 
			
		||||
        g_variant_get (parameters, "(b)", &visible);
 | 
			
		||||
        if (visible != priv->visible) {
 | 
			
		||||
            priv->visible = visible;
 | 
			
		||||
            g_object_notify (G_OBJECT(context), "visible");
 | 
			
		||||
        }
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (g_strcmp0 (signal_name, "GroupChanged") == 0) {
 | 
			
		||||
        gint group = 0;
 | 
			
		||||
 | 
			
		||||
        g_variant_get (parameters, "(i)", &group);
 | 
			
		||||
        if (group != priv->group) {
 | 
			
		||||
            priv->group = group;
 | 
			
		||||
            /* g_object_notify (G_OBJECT(context), "group"); */
 | 
			
		||||
        }
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    g_return_if_reached ();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
eekboard_context_real_enabled (EekboardContext *self)
 | 
			
		||||
{
 | 
			
		||||
    EekboardContextPrivate *priv = eekboard_context_get_instance_private (self);
 | 
			
		||||
 | 
			
		||||
    priv->enabled = TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
eekboard_context_real_disabled (EekboardContext *self)
 | 
			
		||||
{
 | 
			
		||||
    EekboardContextPrivate *priv = eekboard_context_get_instance_private (self);
 | 
			
		||||
 | 
			
		||||
    priv->enabled = FALSE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
eekboard_context_real_destroyed (EekboardContext *self)
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
eekboard_context_get_property (GObject    *object,
 | 
			
		||||
                               guint       prop_id,
 | 
			
		||||
                               GValue     *value,
 | 
			
		||||
                               GParamSpec *pspec)
 | 
			
		||||
{
 | 
			
		||||
    EekboardContext *context = EEKBOARD_CONTEXT(object);
 | 
			
		||||
    EekboardContextPrivate *priv = eekboard_context_get_instance_private (context);
 | 
			
		||||
 | 
			
		||||
    switch (prop_id) {
 | 
			
		||||
    case PROP_VISIBLE:
 | 
			
		||||
        g_value_set_boolean (value, priv->visible);
 | 
			
		||||
        break;
 | 
			
		||||
    default:
 | 
			
		||||
        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
eekboard_context_class_init (EekboardContextClass *klass)
 | 
			
		||||
{
 | 
			
		||||
    GDBusProxyClass *proxy_class = G_DBUS_PROXY_CLASS (klass);
 | 
			
		||||
    GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
 | 
			
		||||
    GParamSpec        *pspec;
 | 
			
		||||
 | 
			
		||||
    klass->enabled = eekboard_context_real_enabled;
 | 
			
		||||
    klass->disabled = eekboard_context_real_disabled;
 | 
			
		||||
    klass->destroyed = eekboard_context_real_destroyed;
 | 
			
		||||
 | 
			
		||||
    proxy_class->g_signal = eekboard_context_real_g_signal;
 | 
			
		||||
 | 
			
		||||
    gobject_class->get_property = eekboard_context_get_property;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * EekboardContext:visible:
 | 
			
		||||
     *
 | 
			
		||||
     * Flag to indicate if keyboard is visible or not.
 | 
			
		||||
     */
 | 
			
		||||
    pspec = g_param_spec_boolean ("visible",
 | 
			
		||||
                                  "visible",
 | 
			
		||||
                                  "Flag that indicates if keyboard is visible",
 | 
			
		||||
                                  FALSE,
 | 
			
		||||
                                  G_PARAM_READABLE);
 | 
			
		||||
    g_object_class_install_property (gobject_class,
 | 
			
		||||
                                     PROP_VISIBLE,
 | 
			
		||||
                                     pspec);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * EekboardContext::enabled:
 | 
			
		||||
     * @context: an #EekboardContext
 | 
			
		||||
     *
 | 
			
		||||
     * Emitted when @context is enabled.
 | 
			
		||||
     */
 | 
			
		||||
    signals[ENABLED] =
 | 
			
		||||
        g_signal_new (I_("enabled"),
 | 
			
		||||
                      G_TYPE_FROM_CLASS(gobject_class),
 | 
			
		||||
                      G_SIGNAL_RUN_LAST,
 | 
			
		||||
                      G_STRUCT_OFFSET(EekboardContextClass, enabled),
 | 
			
		||||
                      NULL,
 | 
			
		||||
                      NULL,
 | 
			
		||||
                      g_cclosure_marshal_VOID__VOID,
 | 
			
		||||
                      G_TYPE_NONE,
 | 
			
		||||
                      0);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * EekboardContext::disabled:
 | 
			
		||||
     * @context: an #EekboardContext
 | 
			
		||||
     *
 | 
			
		||||
     * The ::disabled signal is emitted each time @context is disabled.
 | 
			
		||||
     */
 | 
			
		||||
    signals[DISABLED] =
 | 
			
		||||
        g_signal_new (I_("disabled"),
 | 
			
		||||
                      G_TYPE_FROM_CLASS(gobject_class),
 | 
			
		||||
                      G_SIGNAL_RUN_LAST,
 | 
			
		||||
                      G_STRUCT_OFFSET(EekboardContextClass, disabled),
 | 
			
		||||
                      NULL,
 | 
			
		||||
                      NULL,
 | 
			
		||||
                      g_cclosure_marshal_VOID__VOID,
 | 
			
		||||
                      G_TYPE_NONE,
 | 
			
		||||
                      0);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * EekboardContext::destroyed:
 | 
			
		||||
     * @context: an #EekboardContext
 | 
			
		||||
     *
 | 
			
		||||
     * 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(EekboardContextClass, destroyed),
 | 
			
		||||
                      NULL,
 | 
			
		||||
                      NULL,
 | 
			
		||||
                      g_cclosure_marshal_VOID__VOID,
 | 
			
		||||
                      G_TYPE_NONE,
 | 
			
		||||
                      0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
eekboard_context_init (EekboardContext *self)
 | 
			
		||||
{
 | 
			
		||||
    /* void */
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
context_name_vanished_callback (GDBusConnection *connection,
 | 
			
		||||
                                const gchar     *name,
 | 
			
		||||
                                gpointer         user_data)
 | 
			
		||||
{
 | 
			
		||||
    EekboardContext *context = user_data;
 | 
			
		||||
    g_signal_emit (context, signals[DESTROYED], 0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eekboard_context_new:
 | 
			
		||||
 * @connection: a #GDBusConnection
 | 
			
		||||
 * @object_path: object path
 | 
			
		||||
 * @cancellable: a #GCancellable
 | 
			
		||||
 *
 | 
			
		||||
 * Create a D-Bus proxy of an input context maintained by
 | 
			
		||||
 * eekboard-server.  This function is seldom called from applications
 | 
			
		||||
 * since eekboard_server_create_context() calls it implicitly.
 | 
			
		||||
 */
 | 
			
		||||
EekboardContext *
 | 
			
		||||
eekboard_context_new (GDBusConnection *connection,
 | 
			
		||||
                      const gchar     *object_path,
 | 
			
		||||
                      GCancellable    *cancellable)
 | 
			
		||||
{
 | 
			
		||||
    GInitable *initable;
 | 
			
		||||
    GError *error;
 | 
			
		||||
 | 
			
		||||
    g_return_val_if_fail (object_path != NULL, NULL);
 | 
			
		||||
    g_return_val_if_fail (G_IS_DBUS_CONNECTION(connection), NULL);
 | 
			
		||||
 | 
			
		||||
    error = NULL;
 | 
			
		||||
    initable =
 | 
			
		||||
        g_initable_new (EEKBOARD_TYPE_CONTEXT,
 | 
			
		||||
                        cancellable,
 | 
			
		||||
                        &error,
 | 
			
		||||
                        "g-name", "org.fedorahosted.Eekboard",
 | 
			
		||||
                        "g-connection", connection,
 | 
			
		||||
                        "g-interface-name", "org.fedorahosted.Eekboard.Context",
 | 
			
		||||
                        "g-object-path", object_path,
 | 
			
		||||
                        NULL);
 | 
			
		||||
    if (initable != NULL) {
 | 
			
		||||
        EekboardContext *context = EEKBOARD_CONTEXT (initable);
 | 
			
		||||
        gchar *name_owner = g_dbus_proxy_get_name_owner (G_DBUS_PROXY(context));
 | 
			
		||||
 | 
			
		||||
        if (name_owner == NULL) {
 | 
			
		||||
            g_object_unref (context);
 | 
			
		||||
            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,
 | 
			
		||||
                                        context_name_vanished_callback,
 | 
			
		||||
                                        context,
 | 
			
		||||
                                        NULL);
 | 
			
		||||
        g_free (name_owner);
 | 
			
		||||
 | 
			
		||||
        return context;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    g_warning ("can't create context client: %s", error->message);
 | 
			
		||||
    g_error_free (error);
 | 
			
		||||
 | 
			
		||||
    return NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
context_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_context_add_keyboard:
 | 
			
		||||
 * @context: an #EekboardContext
 | 
			
		||||
 * @keyboard: a string representing keyboard
 | 
			
		||||
 * @cancellable: a #GCancellable
 | 
			
		||||
 *
 | 
			
		||||
 * Register @keyboard in @context.
 | 
			
		||||
 */
 | 
			
		||||
guint
 | 
			
		||||
eekboard_context_add_keyboard (EekboardContext *context,
 | 
			
		||||
                               const gchar     *keyboard,
 | 
			
		||||
                               GCancellable    *cancellable)
 | 
			
		||||
{
 | 
			
		||||
    GVariant *result;
 | 
			
		||||
    GError *error;
 | 
			
		||||
 | 
			
		||||
    g_return_val_if_fail (EEKBOARD_IS_CONTEXT(context), 0);
 | 
			
		||||
 | 
			
		||||
    error = NULL;
 | 
			
		||||
    result = g_dbus_proxy_call_sync (G_DBUS_PROXY(context),
 | 
			
		||||
                                     "AddKeyboard",
 | 
			
		||||
                                     g_variant_new ("(s)", keyboard),
 | 
			
		||||
                                     G_DBUS_CALL_FLAGS_NONE,
 | 
			
		||||
                                     -1,
 | 
			
		||||
                                     cancellable,
 | 
			
		||||
                                     &error);
 | 
			
		||||
 | 
			
		||||
    if (result) {
 | 
			
		||||
        guint keyboard_id;
 | 
			
		||||
 | 
			
		||||
        g_variant_get (result, "(u)", &keyboard_id);
 | 
			
		||||
        g_variant_unref (result);
 | 
			
		||||
 | 
			
		||||
        return keyboard_id;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    g_warning ("error in AddKeyboard call: %s", error->message);
 | 
			
		||||
    g_error_free (error);
 | 
			
		||||
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eekboard_context_remove_keyboard:
 | 
			
		||||
 * @context: an #EekboardContext
 | 
			
		||||
 * @keyboard_id: keyboard ID
 | 
			
		||||
 * @cancellable: a #GCancellable
 | 
			
		||||
 *
 | 
			
		||||
 * Unregister the keyboard with @keyboard_id in @context.
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
eekboard_context_remove_keyboard (EekboardContext *context,
 | 
			
		||||
                                  guint            keyboard_id,
 | 
			
		||||
                                  GCancellable    *cancellable)
 | 
			
		||||
{
 | 
			
		||||
    g_return_if_fail (EEKBOARD_IS_CONTEXT(context));
 | 
			
		||||
 | 
			
		||||
    g_dbus_proxy_call (G_DBUS_PROXY(context),
 | 
			
		||||
                       "RemoveKeyboard",
 | 
			
		||||
                       g_variant_new ("(u)", keyboard_id),
 | 
			
		||||
                       G_DBUS_CALL_FLAGS_NONE,
 | 
			
		||||
                       -1,
 | 
			
		||||
                       cancellable,
 | 
			
		||||
                       context_async_ready_callback,
 | 
			
		||||
                       NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eekboard_context_set_keyboard:
 | 
			
		||||
 * @context: an #EekboardContext
 | 
			
		||||
 * @keyboard_id: keyboard ID
 | 
			
		||||
 * @cancellable: a #GCancellable
 | 
			
		||||
 *
 | 
			
		||||
 * Select a keyboard with ID @keyboard_id in @context.
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
eekboard_context_set_keyboard (EekboardContext *context,
 | 
			
		||||
                               guint            keyboard_id,
 | 
			
		||||
                               GCancellable    *cancellable)
 | 
			
		||||
{
 | 
			
		||||
    g_return_if_fail (EEKBOARD_IS_CONTEXT(context));
 | 
			
		||||
 | 
			
		||||
    g_dbus_proxy_call (G_DBUS_PROXY(context),
 | 
			
		||||
                       "SetKeyboard",
 | 
			
		||||
                       g_variant_new ("(u)", keyboard_id),
 | 
			
		||||
                       G_DBUS_CALL_FLAGS_NONE,
 | 
			
		||||
                       -1,
 | 
			
		||||
                       cancellable,
 | 
			
		||||
                       context_async_ready_callback,
 | 
			
		||||
                       NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eekboard_context_set_group:
 | 
			
		||||
 * @context: an #EekboardContext
 | 
			
		||||
 * @group: group number
 | 
			
		||||
 * @cancellable: a #GCancellable
 | 
			
		||||
 *
 | 
			
		||||
 * Set the keyboard group of @context.
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
eekboard_context_set_group (EekboardContext *context,
 | 
			
		||||
                            gint             group,
 | 
			
		||||
                            GCancellable    *cancellable)
 | 
			
		||||
{
 | 
			
		||||
    g_return_if_fail (EEKBOARD_IS_CONTEXT(context));
 | 
			
		||||
 | 
			
		||||
    EekboardContextPrivate *priv = eekboard_context_get_instance_private (context);
 | 
			
		||||
 | 
			
		||||
    if (priv->group != group) {
 | 
			
		||||
        g_dbus_proxy_call (G_DBUS_PROXY(context),
 | 
			
		||||
                           "SetGroup",
 | 
			
		||||
                           g_variant_new ("(i)", group),
 | 
			
		||||
                           G_DBUS_CALL_FLAGS_NONE,
 | 
			
		||||
                           -1,
 | 
			
		||||
                           cancellable,
 | 
			
		||||
                           context_async_ready_callback,
 | 
			
		||||
                           NULL);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eekboard_context_get_group:
 | 
			
		||||
 * @context: an #EekboardContext
 | 
			
		||||
 * @cancellable: a #GCancellable
 | 
			
		||||
 *
 | 
			
		||||
 * Get the keyboard group of @context.
 | 
			
		||||
 */
 | 
			
		||||
gint
 | 
			
		||||
eekboard_context_get_group (EekboardContext *context,
 | 
			
		||||
                            GCancellable    *cancellable)
 | 
			
		||||
{
 | 
			
		||||
    g_return_val_if_fail (EEKBOARD_IS_CONTEXT(context), 0);
 | 
			
		||||
 | 
			
		||||
    EekboardContextPrivate *priv = eekboard_context_get_instance_private (context);
 | 
			
		||||
 | 
			
		||||
    return priv->group;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eekboard_context_show_keyboard:
 | 
			
		||||
 * @context: an #EekboardContext
 | 
			
		||||
 * @cancellable: a #GCancellable
 | 
			
		||||
 *
 | 
			
		||||
 * Request eekboard-server to show a keyboard set by
 | 
			
		||||
 * eekboard_context_set_keyboard().
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
eekboard_context_show_keyboard (EekboardContext *context,
 | 
			
		||||
                                GCancellable    *cancellable)
 | 
			
		||||
{
 | 
			
		||||
    g_return_if_fail (EEKBOARD_IS_CONTEXT(context));
 | 
			
		||||
 | 
			
		||||
    EekboardContextPrivate *priv = eekboard_context_get_instance_private (context);
 | 
			
		||||
 | 
			
		||||
    if (priv->enabled) {
 | 
			
		||||
        g_dbus_proxy_call (G_DBUS_PROXY(context),
 | 
			
		||||
                           "ShowKeyboard",
 | 
			
		||||
                           NULL,
 | 
			
		||||
                           G_DBUS_CALL_FLAGS_NONE,
 | 
			
		||||
                           -1,
 | 
			
		||||
                           cancellable,
 | 
			
		||||
                           context_async_ready_callback,
 | 
			
		||||
                           NULL);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eekboard_context_hide_keyboard:
 | 
			
		||||
 * @context: an #EekboardContext
 | 
			
		||||
 * @cancellable: a #GCancellable
 | 
			
		||||
 *
 | 
			
		||||
 * Request eekboard-server to hide a keyboard.
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
eekboard_context_hide_keyboard (EekboardContext *context,
 | 
			
		||||
                                GCancellable    *cancellable)
 | 
			
		||||
{
 | 
			
		||||
    g_return_if_fail (EEKBOARD_IS_CONTEXT(context));
 | 
			
		||||
 | 
			
		||||
    EekboardContextPrivate *priv = eekboard_context_get_instance_private (context);
 | 
			
		||||
 | 
			
		||||
    if (priv->enabled) {
 | 
			
		||||
        g_dbus_proxy_call (G_DBUS_PROXY(context),
 | 
			
		||||
                           "HideKeyboard",
 | 
			
		||||
                           NULL,
 | 
			
		||||
                           G_DBUS_CALL_FLAGS_NONE,
 | 
			
		||||
                           -1,
 | 
			
		||||
                           cancellable,
 | 
			
		||||
                           context_async_ready_callback,
 | 
			
		||||
                           NULL);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eekboard_context_press_keycode:
 | 
			
		||||
 * @context: an #EekboardContext
 | 
			
		||||
 * @keycode: keycode number
 | 
			
		||||
 * @cancellable: a #GCancellable
 | 
			
		||||
 *
 | 
			
		||||
 * Tell eekboard-server that a key identified by @keycode is pressed.
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
eekboard_context_press_keycode (EekboardContext *context,
 | 
			
		||||
                                guint            keycode,
 | 
			
		||||
                                GCancellable    *cancellable)
 | 
			
		||||
{
 | 
			
		||||
    g_return_if_fail (EEKBOARD_IS_CONTEXT(context));
 | 
			
		||||
 | 
			
		||||
    EekboardContextPrivate *priv = eekboard_context_get_instance_private (context);
 | 
			
		||||
 | 
			
		||||
    if (priv->enabled) {
 | 
			
		||||
        g_dbus_proxy_call (G_DBUS_PROXY(context),
 | 
			
		||||
                           "PressKeycode",
 | 
			
		||||
                           g_variant_new ("(u)", keycode),
 | 
			
		||||
                           G_DBUS_CALL_FLAGS_NONE,
 | 
			
		||||
                           -1,
 | 
			
		||||
                           cancellable,
 | 
			
		||||
                           context_async_ready_callback,
 | 
			
		||||
                           NULL);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eekboard_context_release_keycode:
 | 
			
		||||
 * @context: an #EekboardContext
 | 
			
		||||
 * @keycode: keycode number
 | 
			
		||||
 * @cancellable: a #GCancellable
 | 
			
		||||
 *
 | 
			
		||||
 * Tell eekboard-server that a key identified by @keycode is released.
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
eekboard_context_release_keycode (EekboardContext *context,
 | 
			
		||||
                                  guint            keycode,
 | 
			
		||||
                                  GCancellable    *cancellable)
 | 
			
		||||
{
 | 
			
		||||
    g_return_if_fail (EEKBOARD_IS_CONTEXT(context));
 | 
			
		||||
 | 
			
		||||
    EekboardContextPrivate *priv = eekboard_context_get_instance_private (context);
 | 
			
		||||
 | 
			
		||||
    if (priv->enabled) {
 | 
			
		||||
        g_dbus_proxy_call (G_DBUS_PROXY(context),
 | 
			
		||||
                           "ReleaseKeycode",
 | 
			
		||||
                           g_variant_new ("(u)", keycode),
 | 
			
		||||
                           G_DBUS_CALL_FLAGS_NONE,
 | 
			
		||||
                           -1,
 | 
			
		||||
                           cancellable,
 | 
			
		||||
                           context_async_ready_callback,
 | 
			
		||||
                           NULL);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eekboard_context_is_visible:
 | 
			
		||||
 * @context: an #EekboardContext
 | 
			
		||||
 *
 | 
			
		||||
 * Check if keyboard is visible.
 | 
			
		||||
 */
 | 
			
		||||
gboolean
 | 
			
		||||
eekboard_context_is_visible (EekboardContext *context)
 | 
			
		||||
{
 | 
			
		||||
    g_return_val_if_fail (EEKBOARD_IS_CONTEXT(context), FALSE);
 | 
			
		||||
 | 
			
		||||
    EekboardContextPrivate *priv = eekboard_context_get_instance_private (context);
 | 
			
		||||
 | 
			
		||||
    return priv->enabled && priv->visible;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eekboard_context_set_enabled:
 | 
			
		||||
 * @context: an #EekboardContext
 | 
			
		||||
 * @enabled: flag to indicate if @context is enabled
 | 
			
		||||
 *
 | 
			
		||||
 * Set @context enabled or disabled.  This function is seldom called
 | 
			
		||||
 * since the flag is set via D-Bus signal #EekboardContext::enabled
 | 
			
		||||
 * and #EekboardContext::disabled.
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
eekboard_context_set_enabled (EekboardContext *context,
 | 
			
		||||
                              gboolean         enabled)
 | 
			
		||||
{
 | 
			
		||||
    g_return_if_fail (EEKBOARD_IS_CONTEXT(context));
 | 
			
		||||
 | 
			
		||||
    EekboardContextPrivate *priv = eekboard_context_get_instance_private (context);
 | 
			
		||||
 | 
			
		||||
    priv->enabled = enabled;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eekboard_context_is_enabled:
 | 
			
		||||
 * @context: an #EekboardContext
 | 
			
		||||
 *
 | 
			
		||||
 * Check if @context is enabled.
 | 
			
		||||
 */
 | 
			
		||||
gboolean
 | 
			
		||||
eekboard_context_is_enabled (EekboardContext *context)
 | 
			
		||||
{
 | 
			
		||||
    g_return_val_if_fail (EEKBOARD_IS_CONTEXT(context), FALSE);
 | 
			
		||||
 | 
			
		||||
    EekboardContextPrivate *priv = eekboard_context_get_instance_private (context);
 | 
			
		||||
 | 
			
		||||
    return priv->enabled;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eekboard_context_set_fullscreen:
 | 
			
		||||
 * @context: an #EekboardContext
 | 
			
		||||
 * @fullscreen: a flag to indicate fullscreen mode
 | 
			
		||||
 * @cancellable: a #GCancellable
 | 
			
		||||
 *
 | 
			
		||||
 * Set the fullscreen mode of @context.
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
eekboard_context_set_fullscreen (EekboardContext *context,
 | 
			
		||||
                                 gboolean         fullscreen,
 | 
			
		||||
                                 GCancellable    *cancellable)
 | 
			
		||||
{
 | 
			
		||||
    g_return_if_fail (EEKBOARD_IS_CONTEXT(context));
 | 
			
		||||
 | 
			
		||||
    EekboardContextPrivate *priv = eekboard_context_get_instance_private (context);
 | 
			
		||||
 | 
			
		||||
    if (priv->fullscreen != fullscreen) {
 | 
			
		||||
        g_dbus_proxy_call (G_DBUS_PROXY(context),
 | 
			
		||||
                           "SetFullscreen",
 | 
			
		||||
                           g_variant_new ("(b)", fullscreen),
 | 
			
		||||
                           G_DBUS_CALL_FLAGS_NONE,
 | 
			
		||||
                           -1,
 | 
			
		||||
                           cancellable,
 | 
			
		||||
                           context_async_ready_callback,
 | 
			
		||||
                           NULL);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										94
									
								
								eekboard/eekboard-context.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										94
									
								
								eekboard/eekboard-context.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,94 @@
 | 
			
		||||
/* 
 | 
			
		||||
 * 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/>.
 | 
			
		||||
 */
 | 
			
		||||
#if !defined(__EEKBOARD_CLIENT_H_INSIDE__) && !defined(EEKBOARD_COMPILATION)
 | 
			
		||||
#error "Only <eekboard/eekboard-client.h> can be included directly."
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef EEKBOARD_CONTEXT_H
 | 
			
		||||
#define EEKBOARD_CONTEXT_H 1
 | 
			
		||||
 | 
			
		||||
#include <gio/gio.h>
 | 
			
		||||
#include "eek/eek.h"
 | 
			
		||||
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
#define EEKBOARD_TYPE_CONTEXT (eekboard_context_get_type())
 | 
			
		||||
G_DECLARE_DERIVABLE_TYPE (EekboardContext, eekboard_context, EEKBOARD, CONTEXT, GDBusProxy)
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * EekboardContextClass:
 | 
			
		||||
 * @enabled: class handler for #EekboardContext::enabled signal
 | 
			
		||||
 * @disabled: class handler for #EekboardContext::disabled signal
 | 
			
		||||
 * @key_pressed: class handler for #EekboardContext::key-pressed signal
 | 
			
		||||
 * @destroyed: class handler for #EekboardContext::destroyed signal
 | 
			
		||||
 */
 | 
			
		||||
struct _EekboardContextClass {
 | 
			
		||||
    /*< private >*/
 | 
			
		||||
    GDBusProxyClass parent_class;
 | 
			
		||||
 | 
			
		||||
    /*< public >*/
 | 
			
		||||
    /* signals */
 | 
			
		||||
    void (*enabled)       (EekboardContext *self);
 | 
			
		||||
    void (*disabled)      (EekboardContext *self);
 | 
			
		||||
    void (*destroyed)     (EekboardContext *self);
 | 
			
		||||
 | 
			
		||||
    /*< private >*/
 | 
			
		||||
    /* padding */
 | 
			
		||||
    gpointer pdummy[24];
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
GType            eekboard_context_get_type       (void) G_GNUC_CONST;
 | 
			
		||||
 | 
			
		||||
EekboardContext *eekboard_context_new            (GDBusConnection *connection,
 | 
			
		||||
                                                  const gchar     *object_path,
 | 
			
		||||
                                                  GCancellable    *cancellable);
 | 
			
		||||
guint            eekboard_context_add_keyboard   (EekboardContext *context,
 | 
			
		||||
                                                  const gchar     *keyboard,
 | 
			
		||||
                                                  GCancellable    *cancellable);
 | 
			
		||||
void             eekboard_context_remove_keyboard (EekboardContext *context,
 | 
			
		||||
                                                   guint            keyboard_id,
 | 
			
		||||
                                                   GCancellable    *cancellable);
 | 
			
		||||
void             eekboard_context_set_keyboard   (EekboardContext *context,
 | 
			
		||||
                                                  guint            keyboard_id,
 | 
			
		||||
                                                  GCancellable    *cancellable);
 | 
			
		||||
void             eekboard_context_show_keyboard  (EekboardContext *context,
 | 
			
		||||
                                                  GCancellable    *cancellable);
 | 
			
		||||
void             eekboard_context_hide_keyboard  (EekboardContext *context,
 | 
			
		||||
                                                  GCancellable    *cancellable);
 | 
			
		||||
void             eekboard_context_set_group      (EekboardContext *context,
 | 
			
		||||
                                                  gint             group,
 | 
			
		||||
                                                  GCancellable    *cancellable);
 | 
			
		||||
gint             eekboard_context_get_group      (EekboardContext *context,
 | 
			
		||||
                                                  GCancellable    *cancellable);
 | 
			
		||||
void             eekboard_context_press_keycode  (EekboardContext *context,
 | 
			
		||||
                                                  guint            keycode,
 | 
			
		||||
                                                  GCancellable    *cancellable);
 | 
			
		||||
void             eekboard_context_release_keycode (EekboardContext *context,
 | 
			
		||||
                                                   guint            keycode,
 | 
			
		||||
                                                   GCancellable    *cancellable);
 | 
			
		||||
gboolean         eekboard_context_is_visible
 | 
			
		||||
                                                 (EekboardContext *context);
 | 
			
		||||
void             eekboard_context_set_enabled    (EekboardContext *context,
 | 
			
		||||
                                                  gboolean         enabled);
 | 
			
		||||
gboolean         eekboard_context_is_enabled     (EekboardContext *context);
 | 
			
		||||
void             eekboard_context_set_fullscreen (EekboardContext *context,
 | 
			
		||||
                                                  gboolean         fullscreen,
 | 
			
		||||
                                                  GCancellable    *cancellable);
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
#endif  /* EEKBOARD_CONTEXT_H */
 | 
			
		||||
@ -22,7 +22,6 @@
 | 
			
		||||
#include "eekboard/key-emitter.h"
 | 
			
		||||
 | 
			
		||||
#include <gdk/gdk.h>
 | 
			
		||||
#include <X11/XKBlib.h>
 | 
			
		||||
 | 
			
		||||
#include "eekboard/eekboard-context-service.h"
 | 
			
		||||
 | 
			
		||||
@ -85,20 +84,61 @@ update_modifier_info (SeatEmitter *client)
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
send_fake_key (SeatEmitter *emitter,
 | 
			
		||||
               LevelKeyboard *keyboard,
 | 
			
		||||
               guint    level,
 | 
			
		||||
               guint    keycode,
 | 
			
		||||
               guint    keyboard_modifiers,
 | 
			
		||||
               gboolean pressed,
 | 
			
		||||
               uint32_t timestamp)
 | 
			
		||||
{
 | 
			
		||||
    zwp_virtual_keyboard_v1_modifiers(emitter->virtual_keyboard, 0, 0, 0, 0);
 | 
			
		||||
    uint32_t proto_modifiers = 0;
 | 
			
		||||
    uint32_t group = (level / 2);
 | 
			
		||||
 | 
			
		||||
    if (keyboard_modifiers & EEK_SHIFT_MASK)
 | 
			
		||||
        proto_modifiers |= 1<<MOD_IDX_SHIFT;
 | 
			
		||||
 | 
			
		||||
    zwp_virtual_keyboard_v1_modifiers(emitter->virtual_keyboard, proto_modifiers, 0, 0, group);
 | 
			
		||||
    send_virtual_keyboard_key (emitter->virtual_keyboard, keycode - 8, (unsigned)pressed, timestamp);
 | 
			
		||||
    zwp_virtual_keyboard_v1_modifiers(emitter->virtual_keyboard, 0, 0, 0, 0);
 | 
			
		||||
    zwp_virtual_keyboard_v1_modifiers(emitter->virtual_keyboard, proto_modifiers, 0, 0, group);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
send_fake_text (SeatEmitter *emitter,
 | 
			
		||||
                EekKeyboard *keyboard,
 | 
			
		||||
                const gchar *text,
 | 
			
		||||
                uint32_t timestamp)
 | 
			
		||||
{
 | 
			
		||||
    gchar *ptr = (gchar *)text;
 | 
			
		||||
 | 
			
		||||
    while (*ptr) {
 | 
			
		||||
        gchar buf[7];
 | 
			
		||||
        gunichar c = g_utf8_get_char(ptr);
 | 
			
		||||
        int n = g_unichar_to_utf8(c, buf);
 | 
			
		||||
        *(buf + n) = 0;
 | 
			
		||||
 | 
			
		||||
        EekKeyPress *key_press = eek_keyboard_get_key_press(keyboard, buf);
 | 
			
		||||
 | 
			
		||||
        if (key_press) {
 | 
			
		||||
            EekKey *key = key_press->key;
 | 
			
		||||
 | 
			
		||||
            send_fake_key (emitter, key_press->level, eek_key_get_keycode(key),
 | 
			
		||||
                           (key_press->level % 2) == 1 ? EEK_SHIFT_MASK : 0,
 | 
			
		||||
                           1, timestamp);
 | 
			
		||||
 | 
			
		||||
            send_fake_key (emitter, key_press->level, eek_key_get_keycode(key),
 | 
			
		||||
                           (key_press->level % 2) == 1 ? EEK_SHIFT_MASK : 0,
 | 
			
		||||
                           0, timestamp);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        ptr = g_utf8_find_next_char(ptr, NULL);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
emit_key_activated (EekboardContextService *manager,
 | 
			
		||||
                    LevelKeyboard     *keyboard,
 | 
			
		||||
                    EekKeyboard     *keyboard,
 | 
			
		||||
                    guint            keycode,
 | 
			
		||||
                    EekSymbol       *symbol,
 | 
			
		||||
                    EekModifierType  modifiers,
 | 
			
		||||
                    gboolean pressed,
 | 
			
		||||
                    uint32_t timestamp)
 | 
			
		||||
{
 | 
			
		||||
@ -133,5 +173,12 @@ emit_key_activated (EekboardContextService *manager,
 | 
			
		||||
    emitter.virtual_keyboard = manager->virtual_keyboard;
 | 
			
		||||
    emitter.keymap = keyboard->keymap;
 | 
			
		||||
    update_modifier_info (&emitter);
 | 
			
		||||
    send_fake_key (&emitter, keyboard, keycode, pressed, timestamp);
 | 
			
		||||
 | 
			
		||||
    const gchar *text = (gchar *)eek_text_get_text(symbol);
 | 
			
		||||
    if (text && pressed) {
 | 
			
		||||
        send_fake_text (&emitter, keyboard, text, timestamp);
 | 
			
		||||
    } else {
 | 
			
		||||
        guint level = eek_element_get_level(EEK_ELEMENT(keyboard));
 | 
			
		||||
        send_fake_key (&emitter, level, keycode, modifiers, pressed, timestamp);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -39,7 +39,9 @@ enum mod_indices {
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
emit_key_activated (EekboardContextService *manager, LevelKeyboard *keyboard,
 | 
			
		||||
emit_key_activated (EekboardContextService *manager, EekKeyboard *keyboard,
 | 
			
		||||
                    guint            keycode,
 | 
			
		||||
                    EekSymbol       *symbol,
 | 
			
		||||
                    guint            modifiers,
 | 
			
		||||
                    gboolean pressed, uint32_t timestamp);
 | 
			
		||||
#endif // KEYEMITTER_H
 | 
			
		||||
 | 
			
		||||
@ -1,29 +0,0 @@
 | 
			
		||||
extern crate rs;
 | 
			
		||||
extern crate xkbcommon;
 | 
			
		||||
 | 
			
		||||
use std::env;
 | 
			
		||||
 | 
			
		||||
use rs::data::{ Layout, LoadError };
 | 
			
		||||
 | 
			
		||||
use xkbcommon::xkb;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
fn check_layout(name: &str) {
 | 
			
		||||
    let layout = Layout::from_resource(name)
 | 
			
		||||
        .and_then(|layout| layout.build().map_err(LoadError::BadKeyMap))
 | 
			
		||||
        .expect("layout broken");
 | 
			
		||||
    
 | 
			
		||||
    let context = xkb::Context::new(xkb::CONTEXT_NO_FLAGS);
 | 
			
		||||
    xkb::Keymap::new_from_string(
 | 
			
		||||
        &context,
 | 
			
		||||
        layout.keymap_str
 | 
			
		||||
            .clone()
 | 
			
		||||
            .into_string().expect("Failed to decode keymap string"),
 | 
			
		||||
        xkb::KEYMAP_FORMAT_TEXT_V1,
 | 
			
		||||
        xkb::KEYMAP_COMPILE_NO_FLAGS,
 | 
			
		||||
    ).expect("Failed to create keymap");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn main() -> () {
 | 
			
		||||
    check_layout(env::args().nth(1).expect("No argument given").as_str());
 | 
			
		||||
}
 | 
			
		||||
@ -1,9 +1,9 @@
 | 
			
		||||
project(
 | 
			
		||||
    'squeekboard',
 | 
			
		||||
    'c', 'rust',
 | 
			
		||||
    version: '1.2.1',
 | 
			
		||||
    version: '1.0.10',
 | 
			
		||||
    license: 'GPLv3',
 | 
			
		||||
    meson_version: '>=0.51.0',
 | 
			
		||||
    meson_version: '>=0.49.0',
 | 
			
		||||
    default_options: [
 | 
			
		||||
        'warning_level=1',
 | 
			
		||||
        'buildtype=debugoptimized',
 | 
			
		||||
@ -17,7 +17,6 @@ add_project_arguments(
 | 
			
		||||
    '-Werror=implicit-fallthrough=3',
 | 
			
		||||
    '-Werror=maybe-uninitialized',
 | 
			
		||||
    '-Werror=missing-field-initializers',
 | 
			
		||||
    '-Werror=incompatible-pointer-types',
 | 
			
		||||
  ],
 | 
			
		||||
  language: 'c'
 | 
			
		||||
)
 | 
			
		||||
@ -53,9 +52,6 @@ summary = [
 | 
			
		||||
]
 | 
			
		||||
message('\n'.join(summary))
 | 
			
		||||
 | 
			
		||||
cargo = find_program('cargo')
 | 
			
		||||
cargo_script = find_program('cargo.sh')
 | 
			
		||||
 | 
			
		||||
subdir('data')
 | 
			
		||||
subdir('protocols')
 | 
			
		||||
subdir('eek')
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										1350
									
								
								src/bitflags.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1350
									
								
								src/bitflags.rs
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										698
									
								
								src/data.rs
									
									
									
									
									
								
							
							
						
						
									
										698
									
								
								src/data.rs
									
									
									
									
									
								
							@ -1,698 +0,0 @@
 | 
			
		||||
/**! The parsing of the data files for layouts */
 | 
			
		||||
 | 
			
		||||
use std::cell::RefCell;
 | 
			
		||||
use std::collections::{ HashMap, HashSet };
 | 
			
		||||
use std::env;
 | 
			
		||||
use std::ffi::CString;
 | 
			
		||||
use std::fmt;
 | 
			
		||||
use std::fs;
 | 
			
		||||
use std::io;
 | 
			
		||||
use std::path::PathBuf;
 | 
			
		||||
use std::rc::Rc;
 | 
			
		||||
use std::vec::Vec;
 | 
			
		||||
 | 
			
		||||
use xkbcommon::xkb;
 | 
			
		||||
 | 
			
		||||
use ::keyboard::{
 | 
			
		||||
    KeyState,
 | 
			
		||||
    generate_keymap, generate_keycodes, FormattingError
 | 
			
		||||
};
 | 
			
		||||
use ::resources;
 | 
			
		||||
use ::util::c::as_str;
 | 
			
		||||
use ::xdg;
 | 
			
		||||
 | 
			
		||||
// traits, derives
 | 
			
		||||
use std::io::BufReader;
 | 
			
		||||
use std::iter::FromIterator;
 | 
			
		||||
 | 
			
		||||
use serde::Deserialize;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/// Gathers stuff defined in C or called by C
 | 
			
		||||
pub mod c {
 | 
			
		||||
    use super::*;
 | 
			
		||||
    use std::os::raw::c_char;
 | 
			
		||||
    
 | 
			
		||||
    #[no_mangle]
 | 
			
		||||
    pub extern "C"
 | 
			
		||||
    fn squeek_load_layout(name: *const c_char) -> *mut ::layout::Layout {
 | 
			
		||||
        let name = as_str(&name)
 | 
			
		||||
            .expect("Bad layout name")
 | 
			
		||||
            .expect("Empty layout name");
 | 
			
		||||
 | 
			
		||||
        let layout = load_layout_with_fallback(name);
 | 
			
		||||
        Box::into_raw(Box::new(layout))
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const FALLBACK_LAYOUT_NAME: &str = "us";
 | 
			
		||||
 | 
			
		||||
#[derive(Debug)]
 | 
			
		||||
pub enum LoadError {
 | 
			
		||||
    BadData(Error),
 | 
			
		||||
    MissingResource,
 | 
			
		||||
    BadResource(serde_yaml::Error),
 | 
			
		||||
    BadKeyMap(FormattingError),
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl fmt::Display for LoadError {
 | 
			
		||||
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
 | 
			
		||||
        use self::LoadError::*;
 | 
			
		||||
        match self {
 | 
			
		||||
            BadData(e) => write!(f, "Bad data: {}", e),
 | 
			
		||||
            MissingResource => write!(f, "Missing resource"),
 | 
			
		||||
            BadResource(e) => write!(f, "Bad resource: {}", e),
 | 
			
		||||
            BadKeyMap(e) => write!(f, "Bad key map: {}", e),
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[derive(Debug, PartialEq)]
 | 
			
		||||
enum DataSource {
 | 
			
		||||
    File(PathBuf),
 | 
			
		||||
    Resource(String),
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl fmt::Display for DataSource {
 | 
			
		||||
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
 | 
			
		||||
        match self {
 | 
			
		||||
            DataSource::File(path) => write!(f, "Path: {:?}", path.display()),
 | 
			
		||||
            DataSource::Resource(name) => write!(f, "Resource: {}", name),
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Tries to load the layout from the first place where it's present.
 | 
			
		||||
/// If the layout exists, but is broken, fallback is activated.
 | 
			
		||||
fn load_layout(
 | 
			
		||||
    name: &str,
 | 
			
		||||
    keyboards_path: Option<PathBuf>,
 | 
			
		||||
) -> (
 | 
			
		||||
    Result<::layout::Layout, LoadError>, // last attempted
 | 
			
		||||
    DataSource, // last attempt source
 | 
			
		||||
    Option<(LoadError, DataSource)>, // first attempt source
 | 
			
		||||
) {
 | 
			
		||||
    let path = keyboards_path.map(|path|
 | 
			
		||||
        path.join(name).with_extension("yaml")
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    let layout = match path {
 | 
			
		||||
        Some(path) => Some((
 | 
			
		||||
            Layout::from_file(path.clone())
 | 
			
		||||
                .map_err(LoadError::BadData)
 | 
			
		||||
                .and_then(|layout|
 | 
			
		||||
                    layout.build().map_err(LoadError::BadKeyMap)
 | 
			
		||||
                ),
 | 
			
		||||
            DataSource::File(path),
 | 
			
		||||
        )),
 | 
			
		||||
        None => None, // No env var, not an error
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    let (failed_attempt, layout) = match layout {
 | 
			
		||||
        Some((Ok(layout), path)) => (None, Some((layout, path))),
 | 
			
		||||
        Some((Err(e), path)) => (Some((e, path)), None),
 | 
			
		||||
        None => (None, None),
 | 
			
		||||
    };
 | 
			
		||||
    
 | 
			
		||||
    let (layout, source) = match layout {
 | 
			
		||||
        Some((layout, path)) => (Ok(layout), path),
 | 
			
		||||
        None => (
 | 
			
		||||
            Layout::from_resource(name)
 | 
			
		||||
                .and_then(|layout|
 | 
			
		||||
                    layout.build().map_err(LoadError::BadKeyMap)
 | 
			
		||||
                ),
 | 
			
		||||
            DataSource::Resource(name.into()),
 | 
			
		||||
        ),
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    (layout, source, failed_attempt)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn log_attempt_info(attempt: Option<(LoadError, DataSource)>) {
 | 
			
		||||
    match attempt {
 | 
			
		||||
        Some((
 | 
			
		||||
            LoadError::BadData(Error::Missing(_e)),
 | 
			
		||||
            DataSource::File(_file)
 | 
			
		||||
        )) => {
 | 
			
		||||
            // Missing file, not to worry. TODO: print in debug logging level
 | 
			
		||||
        }
 | 
			
		||||
        Some((e, source)) => {
 | 
			
		||||
            eprintln!(
 | 
			
		||||
                "Failed to load layout from {}: {}, trying builtin",
 | 
			
		||||
                source, e
 | 
			
		||||
            );
 | 
			
		||||
        },
 | 
			
		||||
        _ => {}
 | 
			
		||||
    };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn load_layout_with_fallback(
 | 
			
		||||
    name: &str
 | 
			
		||||
) -> ::layout::Layout {
 | 
			
		||||
    let path = env::var_os("SQUEEKBOARD_KEYBOARDSDIR")
 | 
			
		||||
        .map(PathBuf::from)
 | 
			
		||||
        .or_else(|| xdg::data_path("squeekboard/keyboards"));
 | 
			
		||||
    
 | 
			
		||||
    let (layout, source, attempt) = load_layout(name, path.clone());
 | 
			
		||||
 | 
			
		||||
    log_attempt_info(attempt);
 | 
			
		||||
    
 | 
			
		||||
    let (layout, source, attempt) = match (layout, source) {
 | 
			
		||||
        (Err(e), source) => {
 | 
			
		||||
            eprintln!(
 | 
			
		||||
                "Failed to load layout from {}: {}, using fallback",
 | 
			
		||||
                source, e
 | 
			
		||||
            );
 | 
			
		||||
            load_layout(FALLBACK_LAYOUT_NAME, path)
 | 
			
		||||
        },
 | 
			
		||||
        (res, source) => (res, source, None),
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    log_attempt_info(attempt);
 | 
			
		||||
 | 
			
		||||
    match (layout, source) {
 | 
			
		||||
        (Err(e), source) => {
 | 
			
		||||
            panic!(
 | 
			
		||||
                format!("Failed to load hardcoded layout from {}: {:?}",
 | 
			
		||||
                    source, e
 | 
			
		||||
                )
 | 
			
		||||
            );
 | 
			
		||||
        },
 | 
			
		||||
        (Ok(layout), source) => {
 | 
			
		||||
            eprintln!("Loaded layout from {}", source);
 | 
			
		||||
            layout
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// The root element describing an entire keyboard
 | 
			
		||||
#[derive(Debug, Deserialize, PartialEq)]
 | 
			
		||||
#[serde(deny_unknown_fields)]
 | 
			
		||||
pub struct Layout {
 | 
			
		||||
    row_spacing: f64,
 | 
			
		||||
    button_spacing: f64,
 | 
			
		||||
    bounds: Bounds,
 | 
			
		||||
    views: HashMap<String, Vec<ButtonIds>>,
 | 
			
		||||
    #[serde(default)] 
 | 
			
		||||
    buttons: HashMap<String, ButtonMeta>,
 | 
			
		||||
    outlines: HashMap<String, Outline>
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[derive(Debug, Clone, Deserialize, PartialEq)]
 | 
			
		||||
#[serde(deny_unknown_fields)]
 | 
			
		||||
struct Bounds {
 | 
			
		||||
    x: f64,
 | 
			
		||||
    y: f64,
 | 
			
		||||
    width: f64,
 | 
			
		||||
    height: f64,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Buttons are embedded in a single string
 | 
			
		||||
type ButtonIds = String;
 | 
			
		||||
 | 
			
		||||
#[derive(Debug, Default, Deserialize, PartialEq)]
 | 
			
		||||
#[serde(deny_unknown_fields)]
 | 
			
		||||
struct ButtonMeta {
 | 
			
		||||
    /// Action other than keysym (conflicts with keysym)
 | 
			
		||||
    action: Option<Action>,
 | 
			
		||||
    /// The name of the outline. If not present, will be "default"
 | 
			
		||||
    outline: Option<String>,
 | 
			
		||||
    /// FIXME: start using it
 | 
			
		||||
    keysym: Option<String>,
 | 
			
		||||
    /// If not present, will be derived from the button ID
 | 
			
		||||
    label: Option<String>,
 | 
			
		||||
    /// Conflicts with label
 | 
			
		||||
    icon: Option<String>,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[derive(Debug, Deserialize, PartialEq)]
 | 
			
		||||
#[serde(deny_unknown_fields)]
 | 
			
		||||
enum Action {
 | 
			
		||||
    #[serde(rename="locking")]
 | 
			
		||||
    Locking { lock_view: String, unlock_view: String },
 | 
			
		||||
    #[serde(rename="set_view")]
 | 
			
		||||
    SetView(String),
 | 
			
		||||
    #[serde(rename="show_prefs")]
 | 
			
		||||
    ShowPrefs,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[derive(Debug, Clone, Deserialize, PartialEq)]
 | 
			
		||||
#[serde(deny_unknown_fields)]
 | 
			
		||||
struct Outline {
 | 
			
		||||
    bounds: Bounds,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Errors encountered loading the layout into yaml
 | 
			
		||||
#[derive(Debug)]
 | 
			
		||||
pub enum Error {
 | 
			
		||||
    Yaml(serde_yaml::Error),
 | 
			
		||||
    Io(io::Error),
 | 
			
		||||
    /// The file was missing.
 | 
			
		||||
    /// It's distinct from Io in order to make it matchable
 | 
			
		||||
    /// without calling io::Error::kind()
 | 
			
		||||
    Missing(io::Error),
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl fmt::Display for Error {
 | 
			
		||||
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
 | 
			
		||||
        match self {
 | 
			
		||||
            Error::Yaml(e) => write!(f, "YAML: {}", e),
 | 
			
		||||
            Error::Io(e) => write!(f, "IO: {}", e),
 | 
			
		||||
            Error::Missing(e) => write!(f, "Missing: {}", e),
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl From<io::Error> for Error {
 | 
			
		||||
    fn from(e: io::Error) -> Self {
 | 
			
		||||
        let kind = e.kind();
 | 
			
		||||
        match kind {
 | 
			
		||||
            io::ErrorKind::NotFound => Error::Missing(e),
 | 
			
		||||
            _ => Error::Io(e),
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl Layout {
 | 
			
		||||
    pub fn from_resource(name: &str) -> Result<Layout, LoadError> {
 | 
			
		||||
        let data = resources::get_keyboard(name)
 | 
			
		||||
                    .ok_or(LoadError::MissingResource)?;
 | 
			
		||||
        serde_yaml::from_str(data)
 | 
			
		||||
                    .map_err(LoadError::BadResource)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fn from_file(path: PathBuf) -> Result<Layout, Error> {
 | 
			
		||||
        let infile = BufReader::new(
 | 
			
		||||
            fs::OpenOptions::new()
 | 
			
		||||
                .read(true)
 | 
			
		||||
                .open(&path)?
 | 
			
		||||
        );
 | 
			
		||||
        serde_yaml::from_reader(infile).map_err(Error::Yaml)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn build(self) -> Result<::layout::Layout, FormattingError> {
 | 
			
		||||
        let button_names = self.views.values()
 | 
			
		||||
            .flat_map(|rows| {
 | 
			
		||||
                rows.iter()
 | 
			
		||||
                    .flat_map(|row| row.split_ascii_whitespace())
 | 
			
		||||
            });
 | 
			
		||||
        
 | 
			
		||||
        let button_names: HashSet<&str>
 | 
			
		||||
            = HashSet::from_iter(button_names);
 | 
			
		||||
 | 
			
		||||
        let keycodes = generate_keycodes(
 | 
			
		||||
            button_names.iter()
 | 
			
		||||
                .map(|name| *name)
 | 
			
		||||
                .filter(|name| {
 | 
			
		||||
                    match self.buttons.get(*name) {
 | 
			
		||||
                        // buttons with defined action can't emit keysyms
 | 
			
		||||
                        // and so don't need keycodes
 | 
			
		||||
                        Some(ButtonMeta { action: Some(_), .. }) => false,
 | 
			
		||||
                        _ => true,
 | 
			
		||||
                    }
 | 
			
		||||
                })
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
        let button_states = button_names.iter().map(|name| {(
 | 
			
		||||
            String::from(*name),
 | 
			
		||||
            Rc::new(RefCell::new(KeyState {
 | 
			
		||||
                pressed: false,
 | 
			
		||||
                locked: false,
 | 
			
		||||
                keycode: keycodes.get(*name).map(|k| *k),
 | 
			
		||||
                symbol: create_symbol(
 | 
			
		||||
                    &self.buttons,
 | 
			
		||||
                    name,
 | 
			
		||||
                    self.views.keys().collect()
 | 
			
		||||
                ),
 | 
			
		||||
            }))
 | 
			
		||||
        )});
 | 
			
		||||
 | 
			
		||||
        let button_states =
 | 
			
		||||
            HashMap::<String, Rc<RefCell<KeyState>>>::from_iter(
 | 
			
		||||
                button_states
 | 
			
		||||
            );
 | 
			
		||||
 | 
			
		||||
        // TODO: generate from symbols
 | 
			
		||||
        let keymap_str = generate_keymap(&button_states)?;
 | 
			
		||||
 | 
			
		||||
        let views = HashMap::from_iter(
 | 
			
		||||
            self.views.iter().map(|(name, view)| {(
 | 
			
		||||
                name.clone(),
 | 
			
		||||
                Box::new(::layout::View {
 | 
			
		||||
                    bounds: ::layout::c::Bounds {
 | 
			
		||||
                        x: self.bounds.x,
 | 
			
		||||
                        y: self.bounds.y,
 | 
			
		||||
                        width: self.bounds.width,
 | 
			
		||||
                        height: self.bounds.height,
 | 
			
		||||
                    },
 | 
			
		||||
                    spacing: ::layout::Spacing {
 | 
			
		||||
                        row: self.row_spacing,
 | 
			
		||||
                        button: self.button_spacing,
 | 
			
		||||
                    },
 | 
			
		||||
                    rows: view.iter().map(|row| {
 | 
			
		||||
                        Box::new(::layout::Row {
 | 
			
		||||
                            angle: 0,
 | 
			
		||||
                            bounds: None,
 | 
			
		||||
                            buttons: row.split_ascii_whitespace().map(|name| {
 | 
			
		||||
                                Box::new(create_button(
 | 
			
		||||
                                    &self.buttons,
 | 
			
		||||
                                    &self.outlines,
 | 
			
		||||
                                    name,
 | 
			
		||||
                                    button_states.get(name.into())
 | 
			
		||||
                                        .expect("Button state not created")
 | 
			
		||||
                                        .clone()
 | 
			
		||||
                                ))
 | 
			
		||||
                            }).collect(),
 | 
			
		||||
                        })
 | 
			
		||||
                    }).collect(),
 | 
			
		||||
                })
 | 
			
		||||
            )})
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
        Ok(::layout::Layout {
 | 
			
		||||
            current_view: "base".into(),
 | 
			
		||||
            views: views,
 | 
			
		||||
            keymap_str: {
 | 
			
		||||
                CString::new(keymap_str)
 | 
			
		||||
                    .expect("Invalid keymap string generated")
 | 
			
		||||
            },
 | 
			
		||||
        })
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn create_symbol(
 | 
			
		||||
    button_info: &HashMap<String, ButtonMeta>,
 | 
			
		||||
    name: &str,
 | 
			
		||||
    view_names: Vec<&String>,
 | 
			
		||||
) -> ::symbol::Symbol {
 | 
			
		||||
    let default_meta = ButtonMeta::default();
 | 
			
		||||
    let symbol_meta = button_info.get(name)
 | 
			
		||||
        .unwrap_or(&default_meta);
 | 
			
		||||
    
 | 
			
		||||
    fn filter_view_name(
 | 
			
		||||
        button_name: &str,
 | 
			
		||||
        view_name: String,
 | 
			
		||||
        view_names: &Vec<&String>
 | 
			
		||||
    ) -> String {
 | 
			
		||||
        if view_names.contains(&&view_name) {
 | 
			
		||||
            view_name
 | 
			
		||||
        } else {
 | 
			
		||||
            eprintln!(
 | 
			
		||||
                "Button {} switches to missing view {}",
 | 
			
		||||
                button_name,
 | 
			
		||||
                view_name
 | 
			
		||||
            );
 | 
			
		||||
            "base".into()
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    fn keysym_valid(name: &str) -> bool {
 | 
			
		||||
        xkb::keysym_from_name(name, xkb::KEYSYM_NO_FLAGS) != xkb::KEY_NoSymbol
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    let keysym = match &symbol_meta.action {
 | 
			
		||||
        Some(_) => None,
 | 
			
		||||
        None => Some(match &symbol_meta.keysym {
 | 
			
		||||
            Some(keysym) => match keysym_valid(keysym.as_str()) {
 | 
			
		||||
                true => keysym.clone(),
 | 
			
		||||
                false => {
 | 
			
		||||
                    eprintln!("Keysym name invalid: {}", keysym);
 | 
			
		||||
                    "space".into() // placeholder
 | 
			
		||||
                },
 | 
			
		||||
            },
 | 
			
		||||
            None => match keysym_valid(name) {
 | 
			
		||||
                true => String::from(name),
 | 
			
		||||
                false => match name.chars().count() {
 | 
			
		||||
                    1 => format!("U{:04X}", name.chars().next().unwrap() as u32),
 | 
			
		||||
                    // If the name is longer than 1 char,
 | 
			
		||||
                    // then it's not a single Unicode char,
 | 
			
		||||
                    // but was trying to be an identifier
 | 
			
		||||
                    _ => {
 | 
			
		||||
                        eprintln!(
 | 
			
		||||
                            "Could not derive a valid keysym for key {}",
 | 
			
		||||
                            name
 | 
			
		||||
                        );
 | 
			
		||||
                        "space".into() // placeholder
 | 
			
		||||
                    }
 | 
			
		||||
                },
 | 
			
		||||
            },
 | 
			
		||||
        }),
 | 
			
		||||
    };
 | 
			
		||||
    
 | 
			
		||||
    match &symbol_meta.action {
 | 
			
		||||
        Some(Action::SetView(view_name)) => ::symbol::Symbol {
 | 
			
		||||
            action: ::symbol::Action::SetLevel(
 | 
			
		||||
                filter_view_name(name, view_name.clone(), &view_names)
 | 
			
		||||
            ),
 | 
			
		||||
        },
 | 
			
		||||
        Some(Action::Locking { lock_view, unlock_view }) => ::symbol::Symbol {
 | 
			
		||||
            action: ::symbol::Action::LockLevel {
 | 
			
		||||
                lock: filter_view_name(name, lock_view.clone(), &view_names),
 | 
			
		||||
                unlock: filter_view_name(
 | 
			
		||||
                    name,
 | 
			
		||||
                    unlock_view.clone(),
 | 
			
		||||
                    &view_names
 | 
			
		||||
                ),
 | 
			
		||||
            },
 | 
			
		||||
        },
 | 
			
		||||
        Some(Action::ShowPrefs) => ::symbol::Symbol {
 | 
			
		||||
            action: ::symbol::Action::Submit {
 | 
			
		||||
                text: None,
 | 
			
		||||
                keys: Vec::new(),
 | 
			
		||||
            },
 | 
			
		||||
        },
 | 
			
		||||
        None => ::symbol::Symbol {
 | 
			
		||||
            action: ::symbol::Action::Submit {
 | 
			
		||||
                text: None,
 | 
			
		||||
                keys: vec!(
 | 
			
		||||
                    ::symbol::KeySym(keysym.unwrap()),
 | 
			
		||||
                ),
 | 
			
		||||
            },
 | 
			
		||||
        },
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// TODO: Since this will receive user-provided data,
 | 
			
		||||
/// all .expect() on them should be turned into soft fails
 | 
			
		||||
fn create_button(
 | 
			
		||||
    button_info: &HashMap<String, ButtonMeta>,
 | 
			
		||||
    outlines: &HashMap<String, Outline>,
 | 
			
		||||
    name: &str,
 | 
			
		||||
    state: Rc<RefCell<KeyState>>,
 | 
			
		||||
) -> ::layout::Button {
 | 
			
		||||
    let cname = CString::new(name.clone())
 | 
			
		||||
        .expect("Bad name");
 | 
			
		||||
    // don't remove, because multiple buttons with the same name are allowed
 | 
			
		||||
    let default_meta = ButtonMeta::default();
 | 
			
		||||
    let button_meta = button_info.get(name)
 | 
			
		||||
        .unwrap_or(&default_meta);
 | 
			
		||||
 | 
			
		||||
    // TODO: move conversion to the C/Rust boundary
 | 
			
		||||
    let label = if let Some(label) = &button_meta.label {
 | 
			
		||||
        ::layout::Label::Text(CString::new(label.as_str())
 | 
			
		||||
            .expect("Bad label"))
 | 
			
		||||
    } else if let Some(icon) = &button_meta.icon {
 | 
			
		||||
        ::layout::Label::IconName(CString::new(icon.as_str())
 | 
			
		||||
            .expect("Bad icon"))
 | 
			
		||||
    } else {
 | 
			
		||||
        ::layout::Label::Text(cname.clone())
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    let outline_name = match &button_meta.outline {
 | 
			
		||||
        Some(outline) => {
 | 
			
		||||
            if outlines.contains_key(outline) {
 | 
			
		||||
                outline.clone()
 | 
			
		||||
            } else {
 | 
			
		||||
                eprintln!("Outline named {} does not exist! Using default for button {}", outline, name);
 | 
			
		||||
                "default".into()
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        None => "default".into(),
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    let outline = outlines.get(&outline_name)
 | 
			
		||||
        .map(|outline| (*outline).clone())
 | 
			
		||||
        .unwrap_or_else(|| {
 | 
			
		||||
            eprintln!("No default outline defied Using 1x1!");
 | 
			
		||||
            Outline {
 | 
			
		||||
                bounds: Bounds { x: 0f64, y: 0f64, width: 1f64, height: 1f64 },
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
    ::layout::Button {
 | 
			
		||||
        name: cname,
 | 
			
		||||
        outline_name: CString::new(outline_name).expect("Bad outline"),
 | 
			
		||||
        // TODO: do layout before creating buttons
 | 
			
		||||
        bounds: ::layout::c::Bounds {
 | 
			
		||||
            x: outline.bounds.x,
 | 
			
		||||
            y: outline.bounds.y,
 | 
			
		||||
            width: outline.bounds.width,
 | 
			
		||||
            height: outline.bounds.height,
 | 
			
		||||
        },
 | 
			
		||||
        label: label,
 | 
			
		||||
        state: state,
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[cfg(test)]
 | 
			
		||||
mod tests {
 | 
			
		||||
    use super::*;
 | 
			
		||||
    
 | 
			
		||||
    use std::error::Error as ErrorTrait;
 | 
			
		||||
 | 
			
		||||
    #[test]
 | 
			
		||||
    fn test_parse_path() {
 | 
			
		||||
        assert_eq!(
 | 
			
		||||
            Layout::from_file(PathBuf::from("tests/layout.yaml")).unwrap(),
 | 
			
		||||
            Layout {
 | 
			
		||||
                row_spacing: 0f64,
 | 
			
		||||
                button_spacing: 0f64,
 | 
			
		||||
                bounds: Bounds { x: 0f64, y: 0f64, width: 0f64, height: 0f64 },
 | 
			
		||||
                views: hashmap!(
 | 
			
		||||
                    "base".into() => vec!("test".into()),
 | 
			
		||||
                ),
 | 
			
		||||
                buttons: hashmap!{
 | 
			
		||||
                    "test".into() => ButtonMeta {
 | 
			
		||||
                        icon: None,
 | 
			
		||||
                        keysym: None,
 | 
			
		||||
                        action: None,
 | 
			
		||||
                        label: Some("test".into()),
 | 
			
		||||
                        outline: None,
 | 
			
		||||
                    }
 | 
			
		||||
                },
 | 
			
		||||
                outlines: hashmap!{
 | 
			
		||||
                    "default".into() => Outline {
 | 
			
		||||
                        bounds: Bounds {
 | 
			
		||||
                            x: 0f64, y: 0f64, width: 0f64, height: 0f64
 | 
			
		||||
                        }, 
 | 
			
		||||
                    }
 | 
			
		||||
                },
 | 
			
		||||
            }
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// Check if the default protection works
 | 
			
		||||
    #[test]
 | 
			
		||||
    fn test_empty_views() {
 | 
			
		||||
        let out = Layout::from_file(PathBuf::from("tests/layout2.yaml"));
 | 
			
		||||
        match out {
 | 
			
		||||
            Ok(_) => assert!(false, "Data mistakenly accepted"),
 | 
			
		||||
            Err(e) => {
 | 
			
		||||
                let mut handled = false;
 | 
			
		||||
                if let Error::Yaml(ye) = &e {
 | 
			
		||||
                    handled = ye.description() == "missing field `views`";
 | 
			
		||||
                };
 | 
			
		||||
                if !handled {
 | 
			
		||||
                    println!("Unexpected error {:?}", e);
 | 
			
		||||
                    assert!(false)
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    #[test]
 | 
			
		||||
    fn test_extra_field() {
 | 
			
		||||
        let out = Layout::from_file(PathBuf::from("tests/layout3.yaml"));
 | 
			
		||||
        match out {
 | 
			
		||||
            Ok(_) => assert!(false, "Data mistakenly accepted"),
 | 
			
		||||
            Err(e) => {
 | 
			
		||||
                let mut handled = false;
 | 
			
		||||
                if let Error::Yaml(ye) = &e {
 | 
			
		||||
                    handled = ye.description()
 | 
			
		||||
                        .starts_with("unknown field `bad_field`");
 | 
			
		||||
                };
 | 
			
		||||
                if !handled {
 | 
			
		||||
                    println!("Unexpected error {:?}", e);
 | 
			
		||||
                    assert!(false)
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    #[test]
 | 
			
		||||
    fn test_layout_punctuation() {
 | 
			
		||||
        let out = Layout::from_file(PathBuf::from("tests/layout_key1.yaml"))
 | 
			
		||||
            .unwrap()
 | 
			
		||||
            .build()
 | 
			
		||||
            .unwrap();
 | 
			
		||||
        assert_eq!(
 | 
			
		||||
            out.views["base"]
 | 
			
		||||
                .rows[0]
 | 
			
		||||
                .buttons[0]
 | 
			
		||||
                .label,
 | 
			
		||||
            ::layout::Label::Text(CString::new("test").unwrap())
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    #[test]
 | 
			
		||||
    fn test_layout_unicode() {
 | 
			
		||||
        let out = Layout::from_file(PathBuf::from("tests/layout_key2.yaml"))
 | 
			
		||||
            .unwrap()
 | 
			
		||||
            .build()
 | 
			
		||||
            .unwrap();
 | 
			
		||||
        assert_eq!(
 | 
			
		||||
            out.views["base"]
 | 
			
		||||
                .rows[0]
 | 
			
		||||
                .buttons[0]
 | 
			
		||||
                .label,
 | 
			
		||||
            ::layout::Label::Text(CString::new("test").unwrap())
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    #[test]
 | 
			
		||||
    fn parsing_fallback() {
 | 
			
		||||
        assert!(Layout::from_resource(FALLBACK_LAYOUT_NAME)
 | 
			
		||||
            .and_then(|layout| layout.build().map_err(LoadError::BadKeyMap))
 | 
			
		||||
            .is_ok()
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    /// First fallback should be to builtin, not to FALLBACK_LAYOUT_NAME
 | 
			
		||||
    #[test]
 | 
			
		||||
    fn fallbacks_order() {
 | 
			
		||||
        let (layout, source, _failure) = load_layout(
 | 
			
		||||
            "nb",
 | 
			
		||||
            Some(PathBuf::from("tests"))
 | 
			
		||||
        );
 | 
			
		||||
        
 | 
			
		||||
        assert_eq!(
 | 
			
		||||
            source,
 | 
			
		||||
            load_layout("nb", None).1
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    #[test]
 | 
			
		||||
    fn unicode_keysym() {
 | 
			
		||||
        let keysym = xkb::keysym_from_name(
 | 
			
		||||
            format!("U{:X}", "å".chars().next().unwrap() as u32).as_str(),
 | 
			
		||||
            xkb::KEYSYM_NO_FLAGS,
 | 
			
		||||
        );
 | 
			
		||||
        let keysym = xkb::keysym_to_utf8(keysym);
 | 
			
		||||
        assert_eq!(keysym, "å\0");
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    #[test]
 | 
			
		||||
    fn test_key_unicode() {
 | 
			
		||||
        assert_eq!(
 | 
			
		||||
            create_symbol(
 | 
			
		||||
                &hashmap!{
 | 
			
		||||
                    ".".into() => ButtonMeta {
 | 
			
		||||
                        icon: None,
 | 
			
		||||
                        keysym: None,
 | 
			
		||||
                        action: None,
 | 
			
		||||
                        label: Some("test".into()),
 | 
			
		||||
                        outline: None,
 | 
			
		||||
                    }
 | 
			
		||||
                },
 | 
			
		||||
                ".",
 | 
			
		||||
                Vec::new()
 | 
			
		||||
            ),
 | 
			
		||||
            ::symbol::Symbol {
 | 
			
		||||
                action: ::symbol::Action::Submit {
 | 
			
		||||
                    text: None,
 | 
			
		||||
                    keys: vec!(::symbol::KeySym("U002E".into())),
 | 
			
		||||
                },
 | 
			
		||||
            }
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										146
									
								
								src/float_ord.rs
									
									
									
									
									
								
							
							
						
						
									
										146
									
								
								src/float_ord.rs
									
									
									
									
									
								
							@ -1,146 +0,0 @@
 | 
			
		||||
//! 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
 | 
			
		||||
 * 
 | 
			
		||||
 * This version drops any dependency on rand.
 | 
			
		||||
 * Caution: Don't pull the version from crates.io
 | 
			
		||||
 * before making sure rand is optional.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
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
 | 
			
		||||
///
 | 
			
		||||
/// ```
 | 
			
		||||
/// use rs::float_ord;
 | 
			
		||||
/// 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());
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -3,7 +3,7 @@ use std::ffi::CString;
 | 
			
		||||
use std::num::Wrapping;
 | 
			
		||||
use std::string::String;
 | 
			
		||||
 | 
			
		||||
use ::util::c::into_cstring;
 | 
			
		||||
use super::bitflags;
 | 
			
		||||
 | 
			
		||||
// Traits
 | 
			
		||||
use std::convert::TryFrom;
 | 
			
		||||
@ -13,8 +13,15 @@ use std::convert::TryFrom;
 | 
			
		||||
pub mod c {
 | 
			
		||||
    use super::*;
 | 
			
		||||
    
 | 
			
		||||
    use std::ffi::CStr;
 | 
			
		||||
    use std::os::raw::{c_char, c_void};
 | 
			
		||||
 | 
			
		||||
    
 | 
			
		||||
    fn into_cstring(s: *const c_char) -> Result<CString, std::ffi::NulError> {
 | 
			
		||||
        CString::new(
 | 
			
		||||
            unsafe {CStr::from_ptr(s)}.to_bytes()
 | 
			
		||||
        )
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    // The following defined in C
 | 
			
		||||
        
 | 
			
		||||
    /// struct zwp_input_method_v2*
 | 
			
		||||
@ -84,9 +91,7 @@ pub mod c {
 | 
			
		||||
    {
 | 
			
		||||
        let imservice = check_imservice(imservice, im).unwrap();
 | 
			
		||||
        imservice.pending = IMProtocolState {
 | 
			
		||||
            surrounding_text: into_cstring(text)
 | 
			
		||||
                .expect("Received invalid string")
 | 
			
		||||
                .expect("Received null string"),
 | 
			
		||||
            surrounding_text: into_cstring(text).expect("Received invalid string"),
 | 
			
		||||
            surrounding_cursor: cursor,
 | 
			
		||||
            ..imservice.pending.clone()
 | 
			
		||||
        };
 | 
			
		||||
@ -225,8 +230,7 @@ bitflags!{
 | 
			
		||||
/// Map to `text_input_unstable_v3.content_purpose` values
 | 
			
		||||
///
 | 
			
		||||
/// ```
 | 
			
		||||
/// use rs::imservice::ContentPurpose;
 | 
			
		||||
/// assert_eq!(ContentPurpose::Alpha as u32, 1);
 | 
			
		||||
/// assert_eq!(ContentPurpose::Alpha as u32, 0);
 | 
			
		||||
/// ```
 | 
			
		||||
#[derive(Debug, Clone)]
 | 
			
		||||
pub enum ContentPurpose {
 | 
			
		||||
 | 
			
		||||
@ -1,26 +0,0 @@
 | 
			
		||||
#ifndef __KEYBOARD_H
 | 
			
		||||
#define __KEYBOARD_H
 | 
			
		||||
 | 
			
		||||
#include "stdbool.h"
 | 
			
		||||
#include "inttypes.h"
 | 
			
		||||
 | 
			
		||||
struct squeek_key;
 | 
			
		||||
 | 
			
		||||
struct squeek_key *squeek_key_new(uint32_t keycode);
 | 
			
		||||
void squeek_key_free(struct squeek_key *key);
 | 
			
		||||
void squeek_key_add_symbol(struct squeek_key* key,
 | 
			
		||||
                           const char *element_name,
 | 
			
		||||
                           const char *text, uint32_t keyval,
 | 
			
		||||
                           const char *label, const char *icon,
 | 
			
		||||
                           const char *tooltip);
 | 
			
		||||
uint32_t squeek_key_is_pressed(struct squeek_key *key);
 | 
			
		||||
void squeek_key_set_pressed(struct squeek_key *key, uint32_t pressed);
 | 
			
		||||
uint32_t squeek_key_is_locked(struct squeek_key *key);
 | 
			
		||||
void squeek_key_set_locked(struct squeek_key *key, uint32_t pressed);
 | 
			
		||||
uint32_t squeek_key_get_keycode(struct squeek_key *key);
 | 
			
		||||
void squeek_key_set_keycode(struct squeek_key *key, uint32_t keycode);
 | 
			
		||||
uint32_t squeek_key_equal(struct squeek_key* key, struct squeek_key* key1);
 | 
			
		||||
 | 
			
		||||
struct squeek_symbol *squeek_key_get_symbol(struct squeek_key* key);
 | 
			
		||||
const char* squeek_key_to_keymap_entry(const char *key_name, struct squeek_key *key);
 | 
			
		||||
#endif
 | 
			
		||||
							
								
								
									
										259
									
								
								src/keyboard.rs
									
									
									
									
									
								
							
							
						
						
									
										259
									
								
								src/keyboard.rs
									
									
									
									
									
								
							@ -1,259 +0,0 @@
 | 
			
		||||
/*! State of the emulated keyboard and keys */
 | 
			
		||||
 | 
			
		||||
use std::cell::RefCell;
 | 
			
		||||
use std::collections::HashMap;
 | 
			
		||||
use std::fmt;
 | 
			
		||||
use std::io;
 | 
			
		||||
use std::rc::Rc;
 | 
			
		||||
use std::string::FromUtf8Error;
 | 
			
		||||
    
 | 
			
		||||
use ::symbol::{ Symbol, Action };
 | 
			
		||||
 | 
			
		||||
use std::io::Write;
 | 
			
		||||
use std::iter::{ FromIterator, IntoIterator };
 | 
			
		||||
 | 
			
		||||
/// Gathers stuff defined in C or called by C
 | 
			
		||||
pub mod c {
 | 
			
		||||
    use super::*;
 | 
			
		||||
    use ::util::c;
 | 
			
		||||
    use ::util::c::as_cstr;
 | 
			
		||||
    
 | 
			
		||||
    use std::ffi::CString;
 | 
			
		||||
    use std::os::raw::c_char;
 | 
			
		||||
 | 
			
		||||
    pub type CKeyState = c::Wrapped<KeyState>;
 | 
			
		||||
 | 
			
		||||
    // The following defined in Rust. TODO: wrap naked pointers to Rust data inside RefCells to prevent multiple writers
 | 
			
		||||
 | 
			
		||||
    #[no_mangle]
 | 
			
		||||
    pub extern "C"
 | 
			
		||||
    fn squeek_key_free(key: CKeyState) {
 | 
			
		||||
        unsafe { key.unwrap() }; // reference dropped
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    /// Compares pointers to the data
 | 
			
		||||
    #[no_mangle]
 | 
			
		||||
    pub extern "C"
 | 
			
		||||
    fn squeek_key_equal(key: CKeyState, key2: CKeyState) -> u32 {
 | 
			
		||||
        return Rc::ptr_eq(&key.clone_ref(), &key2.clone_ref()) as u32
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    #[no_mangle]
 | 
			
		||||
    pub extern "C"
 | 
			
		||||
    fn squeek_key_is_pressed(key: CKeyState) -> u32 {
 | 
			
		||||
        //let key = unsafe { Rc::from_raw(key.0) };
 | 
			
		||||
        return key.to_owned().pressed as u32;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    #[no_mangle]
 | 
			
		||||
    pub extern "C"
 | 
			
		||||
    fn squeek_key_set_pressed(key: CKeyState, pressed: u32) {
 | 
			
		||||
        let key = key.clone_ref();
 | 
			
		||||
        let mut key = key.borrow_mut();
 | 
			
		||||
        key.pressed = pressed != 0;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    #[no_mangle]
 | 
			
		||||
    pub extern "C"
 | 
			
		||||
    fn squeek_key_is_locked(key: CKeyState) -> u32 {
 | 
			
		||||
        return key.to_owned().locked as u32;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    #[no_mangle]
 | 
			
		||||
    pub extern "C"
 | 
			
		||||
    fn squeek_key_set_locked(key: CKeyState, locked: u32) {
 | 
			
		||||
        let key = key.clone_ref();
 | 
			
		||||
        let mut key = key.borrow_mut();
 | 
			
		||||
        key.locked = locked != 0;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    #[no_mangle]
 | 
			
		||||
    pub extern "C"
 | 
			
		||||
    fn squeek_key_get_keycode(key: CKeyState) -> u32 {
 | 
			
		||||
        return key.to_owned().keycode.unwrap_or(0u32);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    #[no_mangle]
 | 
			
		||||
    pub extern "C"
 | 
			
		||||
    fn squeek_key_to_keymap_entry(
 | 
			
		||||
        key_name: *const c_char,
 | 
			
		||||
        key: CKeyState,
 | 
			
		||||
    ) -> *const c_char {
 | 
			
		||||
        let key_name = as_cstr(&key_name)
 | 
			
		||||
            .expect("Missing key name")
 | 
			
		||||
            .to_str()
 | 
			
		||||
            .expect("Bad key name");
 | 
			
		||||
 | 
			
		||||
        let symbol_name = match key.to_owned().symbol.action {
 | 
			
		||||
            Action::Submit { text: Some(text), .. } => {
 | 
			
		||||
                Some(
 | 
			
		||||
                    text.clone()
 | 
			
		||||
                        .into_string().expect("Bad symbol")
 | 
			
		||||
                )
 | 
			
		||||
            },
 | 
			
		||||
            _ => None,
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        let inner = match symbol_name {
 | 
			
		||||
            Some(name) => format!("[ {} ]", name),
 | 
			
		||||
            _ => format!("[ ]"),
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        CString::new(format!("        key <{}> {{ {} }};\n", key_name, inner))
 | 
			
		||||
            .expect("Couldn't convert string")
 | 
			
		||||
            .into_raw()
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    #[no_mangle]
 | 
			
		||||
    pub extern "C"
 | 
			
		||||
    fn squeek_key_get_action_name(
 | 
			
		||||
        key_name: *const c_char,
 | 
			
		||||
        key: CKeyState,
 | 
			
		||||
    ) -> *const c_char {
 | 
			
		||||
        let key_name = as_cstr(&key_name)
 | 
			
		||||
            .expect("Missing key name")
 | 
			
		||||
            .to_str()
 | 
			
		||||
            .expect("Bad key name");
 | 
			
		||||
 | 
			
		||||
        let symbol_name = match key.to_owned().symbol.action {
 | 
			
		||||
            Action::Submit { text: Some(text), .. } => {
 | 
			
		||||
                Some(
 | 
			
		||||
                    text.clone()
 | 
			
		||||
                        .into_string().expect("Bad symbol text")
 | 
			
		||||
                )
 | 
			
		||||
            },
 | 
			
		||||
            _ => None
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        let inner = match symbol_name {
 | 
			
		||||
            Some(name) => format!("[ {} ]", name),
 | 
			
		||||
            _ => format!("[ ]"),
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        CString::new(format!("        key <{}> {{ {} }};\n", key_name, inner))
 | 
			
		||||
            .expect("Couldn't convert string")
 | 
			
		||||
            .into_raw()
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[derive(Debug, Clone)]
 | 
			
		||||
pub struct KeyState {
 | 
			
		||||
    pub pressed: bool,
 | 
			
		||||
    pub locked: bool,
 | 
			
		||||
    pub keycode: Option<u32>,
 | 
			
		||||
    pub symbol: Symbol,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Generates a mapping where each key gets a keycode, starting from 8
 | 
			
		||||
pub fn generate_keycodes<'a, C: IntoIterator<Item=&'a str>>(
 | 
			
		||||
    key_names: C
 | 
			
		||||
) -> HashMap<String, u32> {
 | 
			
		||||
    HashMap::from_iter(
 | 
			
		||||
        key_names.into_iter()
 | 
			
		||||
            .map(|name| String::from(name))
 | 
			
		||||
            .zip(8..)
 | 
			
		||||
    )
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[derive(Debug)]
 | 
			
		||||
pub enum FormattingError {
 | 
			
		||||
    Utf(FromUtf8Error),
 | 
			
		||||
    Format(io::Error),
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl fmt::Display for FormattingError {
 | 
			
		||||
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
 | 
			
		||||
        match self {
 | 
			
		||||
            FormattingError::Utf(e) => write!(f, "UTF: {}", e),
 | 
			
		||||
            FormattingError::Format(e) => write!(f, "Format: {}", e),
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl From<io::Error> for FormattingError {
 | 
			
		||||
    fn from(e: io::Error) -> Self {
 | 
			
		||||
        FormattingError::Format(e)
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Generates a de-facto single level keymap. TODO: actually drop second level
 | 
			
		||||
pub fn generate_keymap(
 | 
			
		||||
    keystates: &HashMap::<String, Rc<RefCell<KeyState>>>
 | 
			
		||||
) -> Result<String, FormattingError> {
 | 
			
		||||
    let mut buf: Vec<u8> = Vec::new();
 | 
			
		||||
    writeln!(
 | 
			
		||||
        buf,
 | 
			
		||||
        "xkb_keymap {{
 | 
			
		||||
 | 
			
		||||
    xkb_keycodes \"squeekboard\" {{
 | 
			
		||||
        minimum = 8;
 | 
			
		||||
        maximum = 255;"
 | 
			
		||||
    )?;
 | 
			
		||||
    
 | 
			
		||||
    for (name, state) in keystates.iter() {
 | 
			
		||||
        let state = state.borrow();
 | 
			
		||||
        if let ::symbol::Action::Submit { text: _, keys } = &state.symbol.action {
 | 
			
		||||
            match keys.len() {
 | 
			
		||||
                0 => eprintln!("Key {} has no keysyms", name),
 | 
			
		||||
                a => {
 | 
			
		||||
                    // TODO: don't ignore any keysyms
 | 
			
		||||
                    if a > 1 {
 | 
			
		||||
                        eprintln!("Key {} multiple keysyms", name);
 | 
			
		||||
                    }
 | 
			
		||||
                    write!(
 | 
			
		||||
                        buf,
 | 
			
		||||
                        "
 | 
			
		||||
        <{}> = {};",
 | 
			
		||||
                        keys[0].0,
 | 
			
		||||
                        state.keycode.unwrap()
 | 
			
		||||
                    )?;
 | 
			
		||||
                },
 | 
			
		||||
            };
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    writeln!(
 | 
			
		||||
        buf,
 | 
			
		||||
        "
 | 
			
		||||
    }};
 | 
			
		||||
    
 | 
			
		||||
    xkb_symbols \"squeekboard\" {{
 | 
			
		||||
 | 
			
		||||
        name[Group1] = \"Letters\";
 | 
			
		||||
        name[Group2] = \"Numbers/Symbols\";"
 | 
			
		||||
    )?;
 | 
			
		||||
    
 | 
			
		||||
    for (name, state) in keystates.iter() {
 | 
			
		||||
        if let ::symbol::Action::Submit { text: _, keys } = &state.borrow().symbol.action {
 | 
			
		||||
            if let Some(keysym) = keys.iter().next() {
 | 
			
		||||
                write!(
 | 
			
		||||
                    buf,
 | 
			
		||||
                    "
 | 
			
		||||
        key <{}> {{ [ {0} ] }};",
 | 
			
		||||
                    keysym.0,
 | 
			
		||||
                )?;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    writeln!(
 | 
			
		||||
        buf,
 | 
			
		||||
        "
 | 
			
		||||
    }};
 | 
			
		||||
 | 
			
		||||
    xkb_types \"squeekboard\" {{
 | 
			
		||||
 | 
			
		||||
	type \"TWO_LEVEL\" {{
 | 
			
		||||
            modifiers = Shift;
 | 
			
		||||
            map[Shift] = Level2;
 | 
			
		||||
            level_name[Level1] = \"Base\";
 | 
			
		||||
            level_name[Level2] = \"Shift\";
 | 
			
		||||
	}};
 | 
			
		||||
    }};
 | 
			
		||||
 | 
			
		||||
    xkb_compatibility \"squeekboard\" {{
 | 
			
		||||
    }};
 | 
			
		||||
}};"
 | 
			
		||||
    )?;
 | 
			
		||||
    
 | 
			
		||||
    String::from_utf8(buf).map_err(FormattingError::Utf)
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										65
									
								
								src/layout.h
									
									
									
									
									
								
							
							
						
						
									
										65
									
								
								src/layout.h
									
									
									
									
									
								
							@ -1,65 +0,0 @@
 | 
			
		||||
#ifndef __LAYOUT_H
 | 
			
		||||
#define __LAYOUT_H
 | 
			
		||||
 | 
			
		||||
#include <inttypes.h>
 | 
			
		||||
#include <glib.h>
 | 
			
		||||
#include "eek/eek-element.h"
 | 
			
		||||
#include "src/keyboard.h"
 | 
			
		||||
 | 
			
		||||
struct squeek_button;
 | 
			
		||||
struct squeek_row;
 | 
			
		||||
struct squeek_view;
 | 
			
		||||
struct squeek_layout;
 | 
			
		||||
 | 
			
		||||
int32_t squeek_row_get_angle(const struct squeek_row*);
 | 
			
		||||
 | 
			
		||||
EekBounds squeek_row_get_bounds(const struct squeek_row*);
 | 
			
		||||
 | 
			
		||||
uint32_t squeek_row_contains(struct squeek_row*, struct squeek_button *button);
 | 
			
		||||
 | 
			
		||||
struct button_place squeek_view_find_key(struct squeek_view*, struct squeek_key *state);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
typedef void (*ButtonCallback) (struct squeek_button *button, gpointer user_data);
 | 
			
		||||
void squeek_row_foreach(struct squeek_row*,
 | 
			
		||||
                            ButtonCallback   callback,
 | 
			
		||||
                            gpointer      user_data);
 | 
			
		||||
 | 
			
		||||
void squeek_row_free(struct squeek_row*);
 | 
			
		||||
 | 
			
		||||
uint32_t squeek_button_get_oref(const struct squeek_button*);
 | 
			
		||||
EekBounds squeek_button_get_bounds(const struct squeek_button*);
 | 
			
		||||
const char *squeek_button_get_label(const struct squeek_button*);
 | 
			
		||||
const char *squeek_button_get_icon_name(const struct squeek_button*);
 | 
			
		||||
const char *squeek_button_get_name(const struct squeek_button*);
 | 
			
		||||
const char *squeek_button_get_outline_name(const struct squeek_button*);
 | 
			
		||||
 | 
			
		||||
struct squeek_key *squeek_button_get_key(const struct squeek_button*);
 | 
			
		||||
uint32_t *squeek_button_has_key(const struct squeek_button* button,
 | 
			
		||||
                                const struct squeek_key *key);
 | 
			
		||||
void squeek_button_print(const struct squeek_button* button);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
EekBounds squeek_view_get_bounds(const struct squeek_view*);
 | 
			
		||||
 | 
			
		||||
typedef void (*RowCallback) (struct squeek_row *row, gpointer user_data);
 | 
			
		||||
void squeek_view_foreach(struct squeek_view*,
 | 
			
		||||
                            RowCallback   callback,
 | 
			
		||||
                            gpointer      user_data);
 | 
			
		||||
 | 
			
		||||
struct squeek_row *squeek_view_get_row(struct squeek_view *view,
 | 
			
		||||
                                       struct squeek_button *button);
 | 
			
		||||
 | 
			
		||||
struct squeek_button *squeek_view_find_button_by_position(struct squeek_view *view, EekPoint point);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
squeek_layout_place_contents(struct squeek_layout*);
 | 
			
		||||
struct squeek_view *squeek_layout_get_current_view(struct squeek_layout*);
 | 
			
		||||
void squeek_layout_set_state_from_press(struct squeek_layout* layout, LevelKeyboard *keyboard, struct squeek_key* key);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
struct squeek_layout *squeek_load_layout(const char *type);
 | 
			
		||||
const char *squeek_layout_get_keymap(const struct squeek_layout*);
 | 
			
		||||
void squeek_layout_free(struct squeek_layout*);
 | 
			
		||||
#endif
 | 
			
		||||
							
								
								
									
										803
									
								
								src/layout.rs
									
									
									
									
									
								
							
							
						
						
									
										803
									
								
								src/layout.rs
									
									
									
									
									
								
							@ -1,803 +0,0 @@
 | 
			
		||||
/*!
 | 
			
		||||
 * Layout-related data.
 | 
			
		||||
 * 
 | 
			
		||||
 * The `View` contains `Row`s and each `Row` contains `Button`s.
 | 
			
		||||
 * They carry data relevant to their positioning only,
 | 
			
		||||
 * except the Button, which also carries some data
 | 
			
		||||
 * about its appearance and function.
 | 
			
		||||
 * 
 | 
			
		||||
 * The layout is determined bottom-up, by measuring `Button` sizes,
 | 
			
		||||
 * deriving `Row` sizes from them, and then centering them within the `View`.
 | 
			
		||||
 * 
 | 
			
		||||
 * That makes the `View` position immutable,
 | 
			
		||||
 * and therefore different than the other positions.
 | 
			
		||||
 * 
 | 
			
		||||
 * Note that it might be a better idea
 | 
			
		||||
 * to make `View` position depend on its contents,
 | 
			
		||||
 * and let the renderer scale and center it within the widget.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
use std::cell::RefCell;
 | 
			
		||||
use std::collections::HashMap;
 | 
			
		||||
use std::ffi::CString;
 | 
			
		||||
use std::rc::Rc;
 | 
			
		||||
use std::vec::Vec;
 | 
			
		||||
 | 
			
		||||
use ::keyboard::*;
 | 
			
		||||
use ::float_ord::FloatOrd;
 | 
			
		||||
use ::symbol::*;
 | 
			
		||||
 | 
			
		||||
/// Gathers stuff defined in C or called by C
 | 
			
		||||
pub mod c {
 | 
			
		||||
    use super::*;
 | 
			
		||||
 | 
			
		||||
    use std::ffi::CStr;
 | 
			
		||||
    use std::os::raw::{ c_char, c_void };
 | 
			
		||||
    use std::ptr;
 | 
			
		||||
 | 
			
		||||
    // The following defined in C
 | 
			
		||||
 | 
			
		||||
    #[repr(transparent)]
 | 
			
		||||
    pub struct UserData(*const c_void);
 | 
			
		||||
 | 
			
		||||
    /// Defined in eek-types.h
 | 
			
		||||
    #[repr(C)]
 | 
			
		||||
    #[derive(Clone, Debug)]
 | 
			
		||||
    pub struct Point {
 | 
			
		||||
        pub x: f64,
 | 
			
		||||
        pub y: f64,
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// Defined in eek-types.h
 | 
			
		||||
    #[repr(C)]
 | 
			
		||||
    #[derive(Clone, Debug)]
 | 
			
		||||
    pub struct Bounds {
 | 
			
		||||
        pub x: f64,
 | 
			
		||||
        pub y: f64,
 | 
			
		||||
        pub width: f64,
 | 
			
		||||
        pub height: f64
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    type ButtonCallback = unsafe extern "C" fn(button: *mut ::layout::Button, data: *mut UserData);
 | 
			
		||||
    type RowCallback = unsafe extern "C" fn(row: *mut ::layout::Row, data: *mut UserData);
 | 
			
		||||
 | 
			
		||||
    // The following defined in Rust. TODO: wrap naked pointers to Rust data inside RefCells to prevent multiple writers
 | 
			
		||||
 | 
			
		||||
    #[no_mangle]
 | 
			
		||||
    pub extern "C"
 | 
			
		||||
    fn squeek_view_get_bounds(view: *const ::layout::View) -> Bounds {
 | 
			
		||||
        unsafe { &*view }.bounds.clone()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    #[no_mangle]
 | 
			
		||||
    pub extern "C"
 | 
			
		||||
    fn squeek_view_foreach(
 | 
			
		||||
        view: *mut ::layout::View,
 | 
			
		||||
        callback: RowCallback,
 | 
			
		||||
        data: *mut UserData,
 | 
			
		||||
    ) {
 | 
			
		||||
        let view = unsafe { &mut *view };
 | 
			
		||||
        for row in view.rows.iter_mut() {
 | 
			
		||||
            let row = row.as_mut() as *mut ::layout::Row;
 | 
			
		||||
            unsafe { callback(row, data) };
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    #[no_mangle]
 | 
			
		||||
    pub extern "C"
 | 
			
		||||
    fn squeek_row_get_angle(row: *const ::layout::Row) -> i32 {
 | 
			
		||||
        let row = unsafe { &*row };
 | 
			
		||||
        row.angle
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    #[no_mangle]
 | 
			
		||||
    pub extern "C"
 | 
			
		||||
    fn squeek_row_get_bounds(row: *const ::layout::Row) -> Bounds {
 | 
			
		||||
        let row = unsafe { &*row };
 | 
			
		||||
        match &row.bounds {
 | 
			
		||||
            Some(bounds) => bounds.clone(),
 | 
			
		||||
            None => panic!("Row doesn't have any bounds yet"),
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// Set bounds by consuming the value
 | 
			
		||||
    #[no_mangle]
 | 
			
		||||
    pub extern "C"
 | 
			
		||||
    fn squeek_row_set_bounds(row: *mut ::layout::Row, bounds: Bounds) {
 | 
			
		||||
        let row = unsafe { &mut *row };
 | 
			
		||||
        row.bounds = Some(bounds);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    #[no_mangle]
 | 
			
		||||
    pub extern "C"
 | 
			
		||||
    fn squeek_row_foreach(
 | 
			
		||||
        row: *mut ::layout::Row,
 | 
			
		||||
        callback: ButtonCallback,
 | 
			
		||||
        data: *mut UserData,
 | 
			
		||||
    ) {
 | 
			
		||||
        let row = unsafe { &mut *row };
 | 
			
		||||
        for button in row.buttons.iter_mut() {
 | 
			
		||||
            let button = button.as_mut() as *mut ::layout::Button;
 | 
			
		||||
            unsafe { callback(button, data) };
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    #[no_mangle]
 | 
			
		||||
    pub extern "C"
 | 
			
		||||
    fn squeek_row_free(row: *mut ::layout::Row) {
 | 
			
		||||
        unsafe { Box::from_raw(row) }; // gets dropped
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    #[no_mangle]
 | 
			
		||||
    pub extern "C"
 | 
			
		||||
    fn squeek_button_get_bounds(button: *const ::layout::Button) -> Bounds {
 | 
			
		||||
        let button = unsafe { &*button };
 | 
			
		||||
        button.bounds.clone()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// Borrow a new reference to key state. Doesn't need freeing
 | 
			
		||||
    #[no_mangle]
 | 
			
		||||
    pub extern "C"
 | 
			
		||||
    fn squeek_button_get_key(
 | 
			
		||||
        button: *const ::layout::Button
 | 
			
		||||
    ) -> ::keyboard::c::CKeyState {
 | 
			
		||||
        let button = unsafe { &*button };
 | 
			
		||||
        ::keyboard::c::CKeyState::wrap(button.state.clone())
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    /// Really should just return the label
 | 
			
		||||
    #[no_mangle]
 | 
			
		||||
    pub extern "C"
 | 
			
		||||
    fn squeek_button_get_symbol(
 | 
			
		||||
        button: *const ::layout::Button,
 | 
			
		||||
    ) -> *const Symbol {
 | 
			
		||||
        let button = unsafe { &*button };
 | 
			
		||||
        let state = button.state.borrow();
 | 
			
		||||
        &state.symbol as *const Symbol
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    #[no_mangle]
 | 
			
		||||
    pub extern "C"
 | 
			
		||||
    fn squeek_button_get_label(
 | 
			
		||||
        button: *const ::layout::Button
 | 
			
		||||
    ) -> *const c_char {
 | 
			
		||||
        let button = unsafe { &*button };
 | 
			
		||||
        match &button.label {
 | 
			
		||||
            Label::Text(text) => text.as_ptr(),
 | 
			
		||||
            // returning static strings to C is a bit cumbersome
 | 
			
		||||
            Label::IconName(_) => unsafe {
 | 
			
		||||
                // CStr doesn't allocate anything, so it only points to
 | 
			
		||||
                // the 'static str, avoiding a memory leak
 | 
			
		||||
                CStr::from_bytes_with_nul_unchecked(b"icon\0")
 | 
			
		||||
            }.as_ptr(),
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    #[no_mangle]
 | 
			
		||||
    pub extern "C"
 | 
			
		||||
    fn squeek_button_get_icon_name(button: *const Button) -> *const c_char {
 | 
			
		||||
        let button = unsafe { &*button };
 | 
			
		||||
        match &button.label {
 | 
			
		||||
            Label::Text(_) => ptr::null(),
 | 
			
		||||
            Label::IconName(name) => name.as_ptr(),
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    #[no_mangle]
 | 
			
		||||
    pub extern "C"
 | 
			
		||||
    fn squeek_button_get_name(button: *const Button) -> *const c_char {
 | 
			
		||||
        let button = unsafe { &*button };
 | 
			
		||||
        button.name.as_ptr()
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    #[no_mangle]
 | 
			
		||||
    pub extern "C"
 | 
			
		||||
    fn squeek_button_get_outline_name(button: *const Button) -> *const c_char {
 | 
			
		||||
        let button = unsafe { &*button };
 | 
			
		||||
        button.outline_name.as_ptr()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    #[no_mangle]
 | 
			
		||||
    pub extern "C"
 | 
			
		||||
    fn squeek_button_has_key(
 | 
			
		||||
        button: *const ::layout::Button,
 | 
			
		||||
        state: ::keyboard::c::CKeyState,
 | 
			
		||||
    ) -> u32 {
 | 
			
		||||
        let button = unsafe { &*button };
 | 
			
		||||
        let state = state.clone_ref();
 | 
			
		||||
        let equal = Rc::ptr_eq(&button.state, &state);
 | 
			
		||||
        equal as u32
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    #[no_mangle]
 | 
			
		||||
    pub extern "C"
 | 
			
		||||
    fn squeek_button_print(button: *const ::layout::Button) {
 | 
			
		||||
        let button = unsafe { &*button };
 | 
			
		||||
        println!("{:?}", button);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    #[no_mangle]
 | 
			
		||||
    pub extern "C"
 | 
			
		||||
    fn squeek_layout_get_current_view(layout: *const Layout) -> *const View {
 | 
			
		||||
        let layout = unsafe { &*layout };
 | 
			
		||||
        let view_name = layout.current_view.clone();
 | 
			
		||||
        layout.views.get(&view_name)
 | 
			
		||||
            .expect("Current view doesn't exist")
 | 
			
		||||
            .as_ref() as *const View
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    #[no_mangle]
 | 
			
		||||
    pub extern "C"
 | 
			
		||||
    fn squeek_layout_get_keymap(layout: *const Layout) -> *const c_char {
 | 
			
		||||
        let layout = unsafe { &*layout };
 | 
			
		||||
        layout.keymap_str.as_ptr()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    #[no_mangle]
 | 
			
		||||
    pub extern "C"
 | 
			
		||||
    fn squeek_layout_free(layout: *mut Layout) {
 | 
			
		||||
        unsafe { Box::from_raw(layout) };
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    
 | 
			
		||||
    /// Entry points for more complex procedures and algoithms which span multiple modules
 | 
			
		||||
    pub mod procedures {
 | 
			
		||||
        use super::*;
 | 
			
		||||
 | 
			
		||||
        #[repr(C)]
 | 
			
		||||
        #[derive(PartialEq, Debug)]
 | 
			
		||||
        pub struct ButtonPlace {
 | 
			
		||||
            row: *const Row,
 | 
			
		||||
            button: *const Button,
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        #[repr(transparent)]
 | 
			
		||||
        pub struct LevelKeyboard(*const c_void);
 | 
			
		||||
 | 
			
		||||
        #[no_mangle]
 | 
			
		||||
        extern "C" {
 | 
			
		||||
            /// Checks if point falls within bounds,
 | 
			
		||||
            /// which are relative to origin and rotated by angle (I think)
 | 
			
		||||
            pub fn eek_are_bounds_inside (bounds: Bounds,
 | 
			
		||||
                point: Point,
 | 
			
		||||
                origin: Point,
 | 
			
		||||
                angle: i32
 | 
			
		||||
            ) -> u32;
 | 
			
		||||
            
 | 
			
		||||
            pub fn eek_keyboard_set_key_locked(
 | 
			
		||||
                keyboard: *mut LevelKeyboard,
 | 
			
		||||
                key: ::keyboard::c::CKeyState,
 | 
			
		||||
            );
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        #[no_mangle]
 | 
			
		||||
        pub extern "C"
 | 
			
		||||
        fn squeek_layout_set_state_from_press(
 | 
			
		||||
            layout: *mut Layout,
 | 
			
		||||
            keyboard: *mut LevelKeyboard,
 | 
			
		||||
            key: ::keyboard::c::CKeyState,
 | 
			
		||||
        ) {
 | 
			
		||||
            let layout = unsafe { &mut *layout };
 | 
			
		||||
 | 
			
		||||
            let view_name = match key.to_owned().symbol.action {
 | 
			
		||||
                ::symbol::Action::SetLevel(name) => {
 | 
			
		||||
                    Some(name.clone())
 | 
			
		||||
                },
 | 
			
		||||
                ::symbol::Action::LockLevel { lock, unlock } => {
 | 
			
		||||
                    let locked = {
 | 
			
		||||
                        let key = key.clone_ref();
 | 
			
		||||
                        let mut key = key.borrow_mut();
 | 
			
		||||
                        key.locked ^= true;
 | 
			
		||||
                        key.locked
 | 
			
		||||
                    };
 | 
			
		||||
 | 
			
		||||
                    if locked {
 | 
			
		||||
                        unsafe {
 | 
			
		||||
                            eek_keyboard_set_key_locked(
 | 
			
		||||
                                keyboard,
 | 
			
		||||
                                key
 | 
			
		||||
                            )
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    Some(if locked { lock } else { unlock }.clone())
 | 
			
		||||
                },
 | 
			
		||||
                _ => None,
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            if let Some(view_name) = view_name {
 | 
			
		||||
                if let Err(_e) = layout.set_view(view_name.clone()) {
 | 
			
		||||
                    eprintln!("No such view: {}, ignoring switch", view_name)
 | 
			
		||||
                };
 | 
			
		||||
            };
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// Places each button in order, starting from 0 on the left,
 | 
			
		||||
        /// keeping the spacing.
 | 
			
		||||
        /// Sizes each button according to outline dimensions.
 | 
			
		||||
        /// Places each row in order, starting from 0 on the top,
 | 
			
		||||
        /// keeping the spacing.
 | 
			
		||||
        /// Sets button and row sizes according to their contents.
 | 
			
		||||
        #[no_mangle]
 | 
			
		||||
        pub extern "C"
 | 
			
		||||
        fn squeek_layout_place_contents(
 | 
			
		||||
            layout: *mut Layout,
 | 
			
		||||
        ) {
 | 
			
		||||
            let layout = unsafe { &mut *layout };
 | 
			
		||||
            for view in layout.views.values_mut() {
 | 
			
		||||
                let sizes: Vec<Vec<Bounds>> = view.rows.iter().map(|row| {
 | 
			
		||||
                    row.buttons.iter()
 | 
			
		||||
                        .map(|button| button.bounds.clone())
 | 
			
		||||
                        .collect()
 | 
			
		||||
                }).collect();
 | 
			
		||||
                let spacing = view.spacing.clone();
 | 
			
		||||
                view.place_buttons_with_sizes(sizes, spacing);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        fn squeek_row_contains(row: &Row, needle: *const Button) -> bool {
 | 
			
		||||
            row.buttons.iter().position(
 | 
			
		||||
                // TODO: wrap Button properly in Rc; this comparison is unreliable
 | 
			
		||||
                |button| button.as_ref() as *const ::layout::Button == needle
 | 
			
		||||
            ).is_some()
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        #[no_mangle]
 | 
			
		||||
        pub extern "C"
 | 
			
		||||
        fn squeek_view_get_row(
 | 
			
		||||
            view: *mut View,
 | 
			
		||||
            needle: *const ::layout::Button,
 | 
			
		||||
        ) -> *mut Row {
 | 
			
		||||
            let view = unsafe { &mut *view };
 | 
			
		||||
            let result = view.rows.iter_mut().find(|row| {
 | 
			
		||||
                squeek_row_contains(row, needle)
 | 
			
		||||
            });
 | 
			
		||||
            match result {
 | 
			
		||||
                Some(row) => row.as_mut() as *mut Row,
 | 
			
		||||
                None => ptr::null_mut(),
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        #[no_mangle]
 | 
			
		||||
        pub extern "C"
 | 
			
		||||
        fn squeek_view_find_key(
 | 
			
		||||
            view: *const View,
 | 
			
		||||
            needle: ::keyboard::c::CKeyState,
 | 
			
		||||
        ) -> ButtonPlace {
 | 
			
		||||
            let view = unsafe { &*view };
 | 
			
		||||
            let state = needle.clone_ref();
 | 
			
		||||
            
 | 
			
		||||
            let paths = ::layout::procedures::find_key_paths(view, &state);
 | 
			
		||||
 | 
			
		||||
            // Can only return 1 entry back to C
 | 
			
		||||
            let (row, button) = match paths.get(0) {
 | 
			
		||||
                Some((row, button)) => (
 | 
			
		||||
                    row.as_ref() as *const Row,
 | 
			
		||||
                    button.as_ref() as *const Button,
 | 
			
		||||
                ),
 | 
			
		||||
                None => ( ptr::null(), ptr::null() ),
 | 
			
		||||
            };
 | 
			
		||||
            ButtonPlace { row, button }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        #[no_mangle]
 | 
			
		||||
        pub extern "C"
 | 
			
		||||
        fn squeek_view_find_button_by_position(
 | 
			
		||||
            view: *mut View, point: Point
 | 
			
		||||
        ) -> *mut Button {
 | 
			
		||||
            let view = unsafe { &mut *view };
 | 
			
		||||
            let result = view.find_button_by_position(point);
 | 
			
		||||
            match result {
 | 
			
		||||
                Some(button) => button.as_mut() as *mut Button,
 | 
			
		||||
                None => ptr::null_mut(),
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        #[cfg(test)]
 | 
			
		||||
        mod test {
 | 
			
		||||
            use super::*;
 | 
			
		||||
 | 
			
		||||
            use super::super::test::*;
 | 
			
		||||
 | 
			
		||||
            #[test]
 | 
			
		||||
            fn row_has_button() {
 | 
			
		||||
                let state = make_state();
 | 
			
		||||
                let button = make_button_with_state(
 | 
			
		||||
                    "test".into(),
 | 
			
		||||
                    state.clone()
 | 
			
		||||
                );
 | 
			
		||||
                let button_ptr = button_as_raw(&button);
 | 
			
		||||
                let mut row = Row::new(0);
 | 
			
		||||
                row.buttons.push(button);
 | 
			
		||||
                assert_eq!(squeek_row_contains(&row, button_ptr), true);
 | 
			
		||||
                let shared_button = make_button_with_state(
 | 
			
		||||
                    "test2".into(),
 | 
			
		||||
                    state
 | 
			
		||||
                );
 | 
			
		||||
                let shared_button_ptr = button_as_raw(&shared_button);
 | 
			
		||||
                row.buttons.push(shared_button);
 | 
			
		||||
                assert_eq!(squeek_row_contains(&row, shared_button_ptr), true);
 | 
			
		||||
                let row = Row::new(0);
 | 
			
		||||
                assert_eq!(squeek_row_contains(&row, button_ptr), false);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            #[test]
 | 
			
		||||
            fn view_has_button() {
 | 
			
		||||
                let state = make_state();
 | 
			
		||||
                let state_clone = ::keyboard::c::CKeyState::wrap(state.clone());
 | 
			
		||||
 | 
			
		||||
                let button = make_button_with_state("1".into(), state);
 | 
			
		||||
                let button_ptr = button.as_ref() as *const Button;
 | 
			
		||||
                
 | 
			
		||||
                let row = Box::new(Row {
 | 
			
		||||
                    buttons: vec!(button),
 | 
			
		||||
                    angle: 0,
 | 
			
		||||
                    bounds: None
 | 
			
		||||
                });
 | 
			
		||||
                let row_ptr = row.as_ref() as *const Row;
 | 
			
		||||
 | 
			
		||||
                let view = View {
 | 
			
		||||
                    bounds: Bounds {
 | 
			
		||||
                        x: 0f64, y: 0f64,
 | 
			
		||||
                        width: 0f64, height: 0f64
 | 
			
		||||
                    },
 | 
			
		||||
                    spacing: Spacing {
 | 
			
		||||
                        button: 0f64,
 | 
			
		||||
                        row: 0f64,
 | 
			
		||||
                    },
 | 
			
		||||
                    rows: vec!(row),
 | 
			
		||||
                };
 | 
			
		||||
 | 
			
		||||
                assert_eq!(
 | 
			
		||||
                    squeek_view_find_key(
 | 
			
		||||
                        &view as *const View,
 | 
			
		||||
                        state_clone.clone(),
 | 
			
		||||
                    ),
 | 
			
		||||
                    ButtonPlace {
 | 
			
		||||
                        row: row_ptr,
 | 
			
		||||
                        button: button_ptr,
 | 
			
		||||
                    }
 | 
			
		||||
                );
 | 
			
		||||
 | 
			
		||||
                let view = View {
 | 
			
		||||
                    bounds: Bounds {
 | 
			
		||||
                        x: 0f64, y: 0f64,
 | 
			
		||||
                        width: 0f64, height: 0f64
 | 
			
		||||
                    },
 | 
			
		||||
                    spacing: Spacing {
 | 
			
		||||
                        button: 0f64,
 | 
			
		||||
                        row: 0f64,
 | 
			
		||||
                    },
 | 
			
		||||
                    rows: Vec::new(),
 | 
			
		||||
                };
 | 
			
		||||
                assert_eq!(
 | 
			
		||||
                    squeek_view_find_key(
 | 
			
		||||
                        &view as *const View,
 | 
			
		||||
                        state_clone.clone()
 | 
			
		||||
                    ),
 | 
			
		||||
                    ButtonPlace {
 | 
			
		||||
                        row: ptr::null(),
 | 
			
		||||
                        button: ptr::null(),
 | 
			
		||||
                    }
 | 
			
		||||
                );
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    #[cfg(test)]
 | 
			
		||||
    mod test {
 | 
			
		||||
        use super::*;
 | 
			
		||||
        
 | 
			
		||||
        use ::keyboard::c::CKeyState;
 | 
			
		||||
 | 
			
		||||
        pub fn make_state() -> Rc<RefCell<::keyboard::KeyState>> {
 | 
			
		||||
            Rc::new(RefCell::new(::keyboard::KeyState {
 | 
			
		||||
                pressed: false,
 | 
			
		||||
                locked: false,
 | 
			
		||||
                keycode: None,
 | 
			
		||||
                symbol: Symbol {
 | 
			
		||||
                    action: Action::SetLevel("default".into()),
 | 
			
		||||
                }
 | 
			
		||||
            }))
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        pub fn make_button_with_state(
 | 
			
		||||
            name: String,
 | 
			
		||||
            state: Rc<RefCell<::keyboard::KeyState>>,
 | 
			
		||||
        ) -> Box<Button> {
 | 
			
		||||
            Box::new(Button {
 | 
			
		||||
                name: CString::new(name.clone()).unwrap(),
 | 
			
		||||
                bounds: c::Bounds {
 | 
			
		||||
                    x: 0f64, y: 0f64, width: 0f64, height: 0f64
 | 
			
		||||
                },
 | 
			
		||||
                outline_name: CString::new("test").unwrap(),
 | 
			
		||||
                label: Label::Text(CString::new(name).unwrap()),
 | 
			
		||||
                state: state,
 | 
			
		||||
            })
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        pub fn button_as_raw(button: &Box<Button>) -> *const Button {
 | 
			
		||||
            button.as_ref() as *const Button
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        #[test]
 | 
			
		||||
        fn button_has_key() {
 | 
			
		||||
            let state = make_state();
 | 
			
		||||
            let button = make_button_with_state("1".into(), state.clone());
 | 
			
		||||
            assert_eq!(
 | 
			
		||||
                squeek_button_has_key(
 | 
			
		||||
                    button_as_raw(&button),
 | 
			
		||||
                    CKeyState::wrap(state.clone())
 | 
			
		||||
                ),
 | 
			
		||||
                1
 | 
			
		||||
            );
 | 
			
		||||
            let other_state = make_state();
 | 
			
		||||
            let other_button = make_button_with_state("1".into(), other_state);
 | 
			
		||||
            assert_eq!(
 | 
			
		||||
                squeek_button_has_key(
 | 
			
		||||
                    button_as_raw(&other_button),
 | 
			
		||||
                    CKeyState::wrap(state.clone())
 | 
			
		||||
                ),
 | 
			
		||||
                0
 | 
			
		||||
            );
 | 
			
		||||
            let orphan_state = CKeyState::wrap(make_state());
 | 
			
		||||
            assert_eq!(
 | 
			
		||||
                squeek_button_has_key(button_as_raw(&button), orphan_state),
 | 
			
		||||
                0
 | 
			
		||||
            );
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[derive(Debug)]
 | 
			
		||||
pub struct Size {
 | 
			
		||||
    pub width: f64,
 | 
			
		||||
    pub height: f64,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[derive(Debug, Clone, PartialEq)]
 | 
			
		||||
pub enum Label {
 | 
			
		||||
    /// Text used to display the symbol
 | 
			
		||||
    Text(CString),
 | 
			
		||||
    /// Icon name used to render the symbol
 | 
			
		||||
    IconName(CString),
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// The graphical representation of a button
 | 
			
		||||
#[derive(Clone, Debug)]
 | 
			
		||||
pub struct Button {
 | 
			
		||||
    /// ID string, e.g. for CSS 
 | 
			
		||||
    pub name: CString,
 | 
			
		||||
    /// Label to display to the user
 | 
			
		||||
    pub label: Label,
 | 
			
		||||
    /// TODO: position the buttons before they get initial bounds
 | 
			
		||||
    /// Position relative to some origin (i.e. parent/row)
 | 
			
		||||
    pub bounds: c::Bounds,
 | 
			
		||||
    /// The name of the visual class applied
 | 
			
		||||
    pub outline_name: CString,
 | 
			
		||||
    /// current state, shared with other buttons
 | 
			
		||||
    pub state: Rc<RefCell<KeyState>>,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// The graphical representation of a row of buttons
 | 
			
		||||
pub struct Row {
 | 
			
		||||
    pub buttons: Vec<Box<Button>>,
 | 
			
		||||
    /// Angle is not really used anywhere...
 | 
			
		||||
    pub angle: i32,
 | 
			
		||||
    /// Position relative to some origin (i.e. parent/view origin)
 | 
			
		||||
    pub bounds: Option<c::Bounds>,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl Row {
 | 
			
		||||
    fn new(angle: i32) -> Row {
 | 
			
		||||
        Row {
 | 
			
		||||
            buttons: Vec::new(),
 | 
			
		||||
            angle: angle,
 | 
			
		||||
            bounds: None,
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    fn last(positions: &Vec<c::Bounds>) -> Option<&c::Bounds> {
 | 
			
		||||
        let len = positions.len();
 | 
			
		||||
        match len {
 | 
			
		||||
            0 => None,
 | 
			
		||||
            l => Some(&positions[l - 1])
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    fn calculate_button_positions(outlines: Vec<c::Bounds>, button_spacing: f64)
 | 
			
		||||
        -> Vec<c::Bounds>
 | 
			
		||||
    {
 | 
			
		||||
        let mut x_offset = 0f64;
 | 
			
		||||
        outlines.iter().map(|outline| {
 | 
			
		||||
            x_offset += outline.x; // account for offset outlines
 | 
			
		||||
            let position = c::Bounds {
 | 
			
		||||
                x: x_offset,
 | 
			
		||||
                ..outline.clone()
 | 
			
		||||
            };
 | 
			
		||||
            x_offset += outline.width + button_spacing;
 | 
			
		||||
            position
 | 
			
		||||
        }).collect()
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    fn calculate_row_size(positions: &Vec<c::Bounds>) -> Size {
 | 
			
		||||
        let max_height = positions.iter().map(
 | 
			
		||||
            |bounds| FloatOrd(bounds.height)
 | 
			
		||||
        ).max()
 | 
			
		||||
            .unwrap_or(FloatOrd(0f64))
 | 
			
		||||
            .0;
 | 
			
		||||
        
 | 
			
		||||
        let total_width = match Row::last(positions) {
 | 
			
		||||
            Some(position) => position.x + position.width,
 | 
			
		||||
            None => 0f64,
 | 
			
		||||
        };
 | 
			
		||||
        Size { width: total_width, height: max_height }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// Finds the first button that covers the specified point
 | 
			
		||||
    /// relative to row's position's origin
 | 
			
		||||
    fn find_button_by_position(&mut self, point: c::Point)
 | 
			
		||||
        -> Option<&mut Box<Button>>
 | 
			
		||||
    {
 | 
			
		||||
        let row_bounds = self.bounds.as_ref().expect("Missing bounds on row");
 | 
			
		||||
        let origin = c::Point {
 | 
			
		||||
            x: row_bounds.x,
 | 
			
		||||
            y: row_bounds.y,
 | 
			
		||||
        };
 | 
			
		||||
        let angle = self.angle;
 | 
			
		||||
        self.buttons.iter_mut().find(|button| {
 | 
			
		||||
            let bounds = button.bounds.clone();
 | 
			
		||||
            let point = point.clone();
 | 
			
		||||
            let origin = origin.clone();
 | 
			
		||||
            procedures::is_point_inside(bounds, point, origin, angle)
 | 
			
		||||
        })
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[derive(Clone, Debug)]
 | 
			
		||||
pub struct Spacing {
 | 
			
		||||
    pub row: f64,
 | 
			
		||||
    pub button: f64,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub struct View {
 | 
			
		||||
    /// Position relative to keyboard origin
 | 
			
		||||
    pub bounds: c::Bounds,
 | 
			
		||||
    pub spacing: Spacing,
 | 
			
		||||
    pub rows: Vec<Box<Row>>,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl View {
 | 
			
		||||
    /// Determines the positions of rows based on their sizes
 | 
			
		||||
    /// Each row will be centered horizontally
 | 
			
		||||
    /// The collection of rows will not be altered vertically
 | 
			
		||||
    /// (TODO: maybe make view bounds a constraint,
 | 
			
		||||
    /// and derive a scaling factor that lets contents fit into view)
 | 
			
		||||
    /// (or TODO: blow up view bounds to match contents
 | 
			
		||||
    /// and then scale the entire thing)
 | 
			
		||||
    fn calculate_row_positions(&self, sizes: Vec<Size>, row_spacing: f64)
 | 
			
		||||
        -> Vec<c::Bounds>
 | 
			
		||||
    {
 | 
			
		||||
        let mut y_offset = self.bounds.y;
 | 
			
		||||
        sizes.into_iter().map(|size| {
 | 
			
		||||
            let position = c::Bounds {
 | 
			
		||||
                x: (self.bounds.width - size.width) / 2f64,
 | 
			
		||||
                y: y_offset,
 | 
			
		||||
                width: size.width,
 | 
			
		||||
                height: size.height,
 | 
			
		||||
            };
 | 
			
		||||
            y_offset += size.height + row_spacing;
 | 
			
		||||
            position
 | 
			
		||||
        }).collect()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// Uses button outline information to place all buttons and rows inside.
 | 
			
		||||
    /// The view itself will not be affected by the sizes
 | 
			
		||||
    fn place_buttons_with_sizes(
 | 
			
		||||
        &mut self,
 | 
			
		||||
        button_outlines: Vec<Vec<c::Bounds>>,
 | 
			
		||||
        spacing: Spacing,
 | 
			
		||||
    ) {
 | 
			
		||||
        // Determine all positions
 | 
			
		||||
        let button_positions: Vec<_>
 | 
			
		||||
            = button_outlines.into_iter()
 | 
			
		||||
                .map(|outlines| {
 | 
			
		||||
                    Row::calculate_button_positions(outlines, spacing.button)
 | 
			
		||||
                })
 | 
			
		||||
                .collect();
 | 
			
		||||
        
 | 
			
		||||
        let row_sizes = button_positions.iter()
 | 
			
		||||
            .map(Row::calculate_row_size)
 | 
			
		||||
            .collect();
 | 
			
		||||
 | 
			
		||||
        let row_positions
 | 
			
		||||
            = self.calculate_row_positions(row_sizes, spacing.row);
 | 
			
		||||
 | 
			
		||||
        // Apply all positions
 | 
			
		||||
        for ((mut row, row_position), button_positions)
 | 
			
		||||
            in self.rows.iter_mut()
 | 
			
		||||
                .zip(row_positions)
 | 
			
		||||
                .zip(button_positions) {
 | 
			
		||||
            row.bounds = Some(row_position);
 | 
			
		||||
            for (mut button, button_position)
 | 
			
		||||
                in row.buttons.iter_mut()
 | 
			
		||||
                    .zip(button_positions) {
 | 
			
		||||
                button.bounds = button_position;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// Finds the first button that covers the specified point
 | 
			
		||||
    /// relative to view's position's origin
 | 
			
		||||
    fn find_button_by_position(&mut self, point: c::Point)
 | 
			
		||||
        -> Option<&mut Box<Button>>
 | 
			
		||||
    {
 | 
			
		||||
        // make point relative to the inside of the view,
 | 
			
		||||
        // which is the origin of all rows
 | 
			
		||||
        let point = c::Point {
 | 
			
		||||
            x: point.x - self.bounds.x,
 | 
			
		||||
            y: point.y - self.bounds.y,
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        self.rows.iter_mut().find_map(
 | 
			
		||||
            |row| row.find_button_by_position(point.clone())
 | 
			
		||||
        )
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub struct Layout {
 | 
			
		||||
    pub current_view: String,
 | 
			
		||||
    pub views: HashMap<String, Box<View>>,
 | 
			
		||||
    // TODO: move to ::keyboard::Keyboard
 | 
			
		||||
    pub keymap_str: CString,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
struct NoSuchView;
 | 
			
		||||
 | 
			
		||||
impl Layout {
 | 
			
		||||
    fn set_view(&mut self, view: String) -> Result<(), NoSuchView> {
 | 
			
		||||
        if self.views.contains_key(&view) {
 | 
			
		||||
            self.current_view = view;
 | 
			
		||||
            Ok(())
 | 
			
		||||
        } else {
 | 
			
		||||
            Err(NoSuchView)
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
mod procedures {
 | 
			
		||||
    use super::*;
 | 
			
		||||
    
 | 
			
		||||
    type Path<'v> = (&'v Box<Row>, &'v Box<Button>);
 | 
			
		||||
 | 
			
		||||
    /// Finds all `(row, button)` paths that refer to the specified key `state`
 | 
			
		||||
    pub fn find_key_paths<'v, 's>(
 | 
			
		||||
        view: &'v View,
 | 
			
		||||
        state: &'s Rc<RefCell<KeyState>>
 | 
			
		||||
    ) -> Vec<Path<'v>> {
 | 
			
		||||
        view.rows.iter().flat_map(|row| {
 | 
			
		||||
            let row_paths: Vec<Path> = row.buttons.iter().filter_map(|button| {
 | 
			
		||||
                if Rc::ptr_eq(&button.state, state) {
 | 
			
		||||
                    Some((row, button))
 | 
			
		||||
                } else {
 | 
			
		||||
                    None
 | 
			
		||||
                }
 | 
			
		||||
            }).collect(); // collecting not to let row references outlive the function
 | 
			
		||||
            row_paths.into_iter()
 | 
			
		||||
        }).collect()
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    /// Checks if point is inside bounds which are rotated by angle.
 | 
			
		||||
    /// FIXME: what's origin about?
 | 
			
		||||
    pub fn is_point_inside(
 | 
			
		||||
        bounds: c::Bounds,
 | 
			
		||||
        point: c::Point,
 | 
			
		||||
        origin: c::Point,
 | 
			
		||||
        angle: i32
 | 
			
		||||
    ) -> bool {
 | 
			
		||||
        (unsafe {
 | 
			
		||||
            c::procedures::eek_are_bounds_inside(bounds, point, origin, angle)
 | 
			
		||||
        }) == 1
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										16
									
								
								src/lib.rs
									
									
									
									
									
								
							
							
						
						
									
										16
									
								
								src/lib.rs
									
									
									
									
									
								
							@ -1,16 +1,4 @@
 | 
			
		||||
#[macro_use]
 | 
			
		||||
extern crate bitflags;
 | 
			
		||||
#[macro_use]
 | 
			
		||||
extern crate maplit;
 | 
			
		||||
extern crate serde;
 | 
			
		||||
extern crate xkbcommon;
 | 
			
		||||
mod bitflags;
 | 
			
		||||
 | 
			
		||||
pub mod data;
 | 
			
		||||
pub mod float_ord;
 | 
			
		||||
pub mod imservice;
 | 
			
		||||
mod keyboard;
 | 
			
		||||
mod layout;
 | 
			
		||||
mod resources;
 | 
			
		||||
mod symbol;
 | 
			
		||||
mod util;
 | 
			
		||||
mod xdg;
 | 
			
		||||
mod imservice;
 | 
			
		||||
 | 
			
		||||
@ -16,18 +16,30 @@ sources = [
 | 
			
		||||
  'server-context-service.c',
 | 
			
		||||
  'wayland.c',
 | 
			
		||||
  '../eek/eek.c',
 | 
			
		||||
  '../eek/eek-container.c',
 | 
			
		||||
  '../eek/eek-element.c',
 | 
			
		||||
  '../eek/eek-gtk-keyboard.c',
 | 
			
		||||
  '../eek/eek-key.c',
 | 
			
		||||
  '../eek/eek-keyboard.c',
 | 
			
		||||
  '../eek/eek-keyboard-drawing.c',
 | 
			
		||||
  '../eek/eek-keysym.c',
 | 
			
		||||
  '../eek/eek-layout.c',
 | 
			
		||||
  '../eek/eek-renderer.c',
 | 
			
		||||
  '../eek/eek-section.c',
 | 
			
		||||
  '../eek/eek-serializable.c',
 | 
			
		||||
  '../eek/eek-symbol.c',
 | 
			
		||||
  '../eek/eek-symbol-matrix.c',
 | 
			
		||||
  '../eek/eek-text.c',
 | 
			
		||||
  '../eek/eek-types.c',
 | 
			
		||||
  '../eek/eek-xml-layout.c',
 | 
			
		||||
  '../eek/layersurface.c',
 | 
			
		||||
  dbus_src,
 | 
			
		||||
  enums,
 | 
			
		||||
  keysym_entries,
 | 
			
		||||
  marshalers,
 | 
			
		||||
  '../eekboard/key-emitter.c',
 | 
			
		||||
  '../eekboard/eekboard-context-service.c',
 | 
			
		||||
  '../eekboard/eekboard-context.c',
 | 
			
		||||
  '../eekboard/eekboard-service.c',
 | 
			
		||||
  #  '../eekboard/eekboard-xklutil.c',
 | 
			
		||||
  squeekboard_resources,
 | 
			
		||||
@ -51,41 +63,25 @@ deps = [
 | 
			
		||||
#  dependency('libxklavier'), # FIXME remove
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
rslibs = custom_target(
 | 
			
		||||
    'rslibs',
 | 
			
		||||
    build_by_default: true,
 | 
			
		||||
    build_always_stale: true,
 | 
			
		||||
    output: ['librs.a'],
 | 
			
		||||
    install: false,
 | 
			
		||||
    console: true,
 | 
			
		||||
    command: [cargo_script, '@OUTPUT@', 'build']
 | 
			
		||||
# Replacement for eekboard-server
 | 
			
		||||
rslib = static_library(
 | 
			
		||||
  'rslib',
 | 
			
		||||
  sources: ['lib.rs'],
 | 
			
		||||
  rust_crate_type: 'staticlib'
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
build_rstests = custom_target(
 | 
			
		||||
    'build_rstests',
 | 
			
		||||
    build_by_default: false,
 | 
			
		||||
    # HACK: this target needs to build before all the tests,
 | 
			
		||||
    # but it doesn't produce anything stable.
 | 
			
		||||
    # Declaring build_by_default with some random but irrelevant output
 | 
			
		||||
    # ensures that it's always built as it should
 | 
			
		||||
    build_always_stale: true,
 | 
			
		||||
    output: ['src'],
 | 
			
		||||
    install: false,
 | 
			
		||||
    console: true,
 | 
			
		||||
    command: [cargo_script, '', 'build', '--tests'],
 | 
			
		||||
    depends: rslibs, # no point building tests if the code itself fails
 | 
			
		||||
rstests = executable(
 | 
			
		||||
  'rstests',
 | 
			
		||||
  sources: ['lib.rs'],
 | 
			
		||||
  rust_args: ['--test'],
 | 
			
		||||
  install: false
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
test(
 | 
			
		||||
    'rstest',
 | 
			
		||||
    cargo_script,
 | 
			
		||||
    args: ['', 'test'],
 | 
			
		||||
    depends: build_rstests,
 | 
			
		||||
)
 | 
			
		||||
test('rstests', rstests)
 | 
			
		||||
 | 
			
		||||
libsqueekboard = static_library('libsqueekboard',
 | 
			
		||||
  sources,
 | 
			
		||||
  link_with: [rslibs],
 | 
			
		||||
  link_with: rslib,
 | 
			
		||||
  include_directories: [include_directories('..'), include_directories('../eek')],
 | 
			
		||||
  dependencies: deps,
 | 
			
		||||
  c_args: [
 | 
			
		||||
 | 
			
		||||
@ -1,27 +0,0 @@
 | 
			
		||||
/*! Statically linked resources.
 | 
			
		||||
 * This could be done using GResource, but that would need additional work.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
const KEYBOARDS: &[(*const str, *const str)] = &[
 | 
			
		||||
    ("us", include_str!("../data/keyboards/us.yaml")),
 | 
			
		||||
    ("el", include_str!("../data/keyboards/el.yaml")),
 | 
			
		||||
    ("es", include_str!("../data/keyboards/es.yaml")),
 | 
			
		||||
    ("it", include_str!("../data/keyboards/it.yaml")),
 | 
			
		||||
    ("nb", include_str!("../data/keyboards/nb.yaml")),
 | 
			
		||||
    ("number", include_str!("../data/keyboards/number.yaml")),
 | 
			
		||||
];
 | 
			
		||||
 | 
			
		||||
pub fn get_keyboard(needle: &str) -> Option<&'static str> {
 | 
			
		||||
    // Need to dereference in unsafe code
 | 
			
		||||
    // comparing *const str to &str will compare pointers
 | 
			
		||||
    KEYBOARDS.iter()
 | 
			
		||||
        .find(|(name, _)| {
 | 
			
		||||
            let name: *const str = *name;
 | 
			
		||||
            (unsafe { &*name }) == needle
 | 
			
		||||
        })
 | 
			
		||||
        .map(|(_, value)| {
 | 
			
		||||
            let value: *const str = *value;
 | 
			
		||||
            unsafe { &*value }
 | 
			
		||||
        })
 | 
			
		||||
}
 | 
			
		||||
@ -40,7 +40,6 @@ struct _ServerContextService {
 | 
			
		||||
 | 
			
		||||
    GtkWidget *window;
 | 
			
		||||
    GtkWidget *widget;
 | 
			
		||||
    guint hiding;
 | 
			
		||||
 | 
			
		||||
    gdouble size_constraint_landscape[2];
 | 
			
		||||
    gdouble size_constraint_portrait[2];
 | 
			
		||||
@ -52,6 +51,17 @@ struct _ServerContextServiceClass {
 | 
			
		||||
 | 
			
		||||
G_DEFINE_TYPE (ServerContextService, server_context_service, EEKBOARD_TYPE_CONTEXT_SERVICE);
 | 
			
		||||
 | 
			
		||||
static void set_geometry  (ServerContextService *context);
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
on_monitors_changed (GdkScreen            *screen,
 | 
			
		||||
                     ServerContextService *context)
 | 
			
		||||
 | 
			
		||||
{
 | 
			
		||||
    if (context->window)
 | 
			
		||||
        set_geometry (context);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
on_destroy (GtkWidget *widget, gpointer user_data)
 | 
			
		||||
{
 | 
			
		||||
@ -73,7 +83,9 @@ on_notify_keyboard (GObject              *object,
 | 
			
		||||
                    GParamSpec           *spec,
 | 
			
		||||
                    ServerContextService *context)
 | 
			
		||||
{
 | 
			
		||||
    const LevelKeyboard *keyboard = eekboard_context_service_get_keyboard (EEKBOARD_CONTEXT_SERVICE(context));
 | 
			
		||||
    const EekKeyboard *keyboard;
 | 
			
		||||
 | 
			
		||||
    keyboard = eekboard_context_service_get_keyboard (EEKBOARD_CONTEXT_SERVICE(context));
 | 
			
		||||
 | 
			
		||||
    if (!keyboard)
 | 
			
		||||
        g_error("Programmer error: keyboard layout was unset!");
 | 
			
		||||
@ -97,6 +109,15 @@ on_notify_keyboard (GObject              *object,
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
on_notify_fullscreen (GObject              *object,
 | 
			
		||||
                      GParamSpec           *spec,
 | 
			
		||||
                      ServerContextService *context)
 | 
			
		||||
{
 | 
			
		||||
    if (context->window)
 | 
			
		||||
        set_geometry (context);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
on_notify_map (GObject    *object,
 | 
			
		||||
               ServerContextService *context)
 | 
			
		||||
@ -112,6 +133,50 @@ on_notify_unmap (GObject    *object,
 | 
			
		||||
    g_object_set (context, "visible", FALSE, NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
set_geometry (ServerContextService *context)
 | 
			
		||||
{
 | 
			
		||||
    GdkScreen   *screen   = gdk_screen_get_default ();
 | 
			
		||||
    GdkWindow   *root     = gdk_screen_get_root_window (screen);
 | 
			
		||||
    GdkDisplay  *display  = gdk_display_get_default ();
 | 
			
		||||
    GdkMonitor  *monitor  = gdk_display_get_monitor_at_window (display, root);
 | 
			
		||||
    EekKeyboard *keyboard = eekboard_context_service_get_keyboard (EEKBOARD_CONTEXT_SERVICE(context));
 | 
			
		||||
 | 
			
		||||
    GdkRectangle rect;
 | 
			
		||||
    EekBounds bounds;
 | 
			
		||||
 | 
			
		||||
    gdk_monitor_get_geometry (monitor, &rect);
 | 
			
		||||
    eek_element_get_bounds (EEK_ELEMENT(keyboard), &bounds);
 | 
			
		||||
 | 
			
		||||
    if (eekboard_context_service_get_fullscreen (EEKBOARD_CONTEXT_SERVICE(context))) {
 | 
			
		||||
        gint width  = rect.width;
 | 
			
		||||
        gint height = rect.height;
 | 
			
		||||
 | 
			
		||||
        if (width > height) {
 | 
			
		||||
            width  *= context->size_constraint_landscape[0];
 | 
			
		||||
            height *= context->size_constraint_landscape[1];
 | 
			
		||||
        } else {
 | 
			
		||||
            width  *= context->size_constraint_portrait[0];
 | 
			
		||||
            height *= context->size_constraint_portrait[1];
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (width * bounds.height > height * bounds.width)
 | 
			
		||||
            width = (height / bounds.height) * bounds.width;
 | 
			
		||||
        else
 | 
			
		||||
            height = (width / bounds.width) * bounds.height;
 | 
			
		||||
 | 
			
		||||
        gtk_window_resize (GTK_WINDOW(context->widget), width, height);
 | 
			
		||||
 | 
			
		||||
        gtk_window_move (GTK_WINDOW(context->window),
 | 
			
		||||
                         (rect.width - width) / 2,
 | 
			
		||||
                         rect.height - height);
 | 
			
		||||
 | 
			
		||||
        gtk_window_set_decorated (GTK_WINDOW(context->window), FALSE);
 | 
			
		||||
        gtk_window_set_resizable (GTK_WINDOW(context->window), FALSE);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#define KEYBOARD_HEIGHT 210
 | 
			
		||||
static void
 | 
			
		||||
make_window (ServerContextService *context)
 | 
			
		||||
@ -163,18 +228,21 @@ destroy_window (ServerContextService *context)
 | 
			
		||||
static void
 | 
			
		||||
make_widget (ServerContextService *context)
 | 
			
		||||
{
 | 
			
		||||
    EekKeyboard *keyboard;
 | 
			
		||||
 | 
			
		||||
    if (context->widget) {
 | 
			
		||||
        gtk_widget_destroy(context->widget);
 | 
			
		||||
        context->widget = NULL;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    LevelKeyboard *keyboard = eekboard_context_service_get_keyboard (EEKBOARD_CONTEXT_SERVICE(context));
 | 
			
		||||
    keyboard = eekboard_context_service_get_keyboard (EEKBOARD_CONTEXT_SERVICE(context));
 | 
			
		||||
 | 
			
		||||
    context->widget = eek_gtk_keyboard_new (keyboard);
 | 
			
		||||
 | 
			
		||||
    gtk_widget_set_has_tooltip (context->widget, TRUE);
 | 
			
		||||
    gtk_container_add (GTK_CONTAINER(context->window), context->widget);
 | 
			
		||||
    gtk_widget_show (context->widget);
 | 
			
		||||
    set_geometry (context);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
@ -182,11 +250,6 @@ server_context_service_real_show_keyboard (EekboardContextService *_context)
 | 
			
		||||
{
 | 
			
		||||
    ServerContextService *context = SERVER_CONTEXT_SERVICE(_context);
 | 
			
		||||
 | 
			
		||||
    if (context->hiding) {
 | 
			
		||||
	    g_source_remove (context->hiding);
 | 
			
		||||
	    context->hiding = 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (!context->window)
 | 
			
		||||
        make_window (context);
 | 
			
		||||
    if (!context->widget)
 | 
			
		||||
@ -197,22 +260,12 @@ server_context_service_real_show_keyboard (EekboardContextService *_context)
 | 
			
		||||
    gtk_widget_show (context->window);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
on_hide (ServerContextService *context)
 | 
			
		||||
{
 | 
			
		||||
    gtk_widget_hide (context->window);
 | 
			
		||||
    context->hiding = 0;
 | 
			
		||||
 | 
			
		||||
    return G_SOURCE_REMOVE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
server_context_service_real_hide_keyboard (EekboardContextService *_context)
 | 
			
		||||
{
 | 
			
		||||
    ServerContextService *context = SERVER_CONTEXT_SERVICE(_context);
 | 
			
		||||
 | 
			
		||||
    if (!context->hiding)
 | 
			
		||||
	context->hiding = g_timeout_add (200, (GSourceFunc) on_hide, context);
 | 
			
		||||
    gtk_widget_hide (context->window);
 | 
			
		||||
 | 
			
		||||
    EEKBOARD_CONTEXT_SERVICE_CLASS (server_context_service_parent_class)->
 | 
			
		||||
        hide_keyboard (_context);
 | 
			
		||||
@ -301,10 +354,21 @@ server_context_service_class_init (ServerContextServiceClass *klass)
 | 
			
		||||
static void
 | 
			
		||||
server_context_service_init (ServerContextService *context)
 | 
			
		||||
{
 | 
			
		||||
    GdkScreen *screen = gdk_screen_get_default ();
 | 
			
		||||
 | 
			
		||||
    g_signal_connect (screen,
 | 
			
		||||
                      "monitors-changed",
 | 
			
		||||
                      G_CALLBACK(on_monitors_changed),
 | 
			
		||||
                      context);
 | 
			
		||||
    g_signal_connect (context,
 | 
			
		||||
                      "notify::keyboard",
 | 
			
		||||
                      G_CALLBACK(on_notify_keyboard),
 | 
			
		||||
                      context);
 | 
			
		||||
 | 
			
		||||
    g_signal_connect (context,
 | 
			
		||||
                      "notify::fullscreen",
 | 
			
		||||
                      G_CALLBACK(on_notify_fullscreen),
 | 
			
		||||
                      context);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
EekboardContextService *
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										51
									
								
								src/server-context.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										51
									
								
								src/server-context.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,51 @@
 | 
			
		||||
/* 
 | 
			
		||||
 * 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 SERVER_CONTEXT_H
 | 
			
		||||
#define SERVER_CONTEXT_H 1
 | 
			
		||||
 | 
			
		||||
#include <gio/gio.h>
 | 
			
		||||
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
#define SERVER_CONTEXT_PATH "/org/fedorahosted/Eekboard/Context_%d"
 | 
			
		||||
#define SERVER_CONTEXT_INTERFACE "org.fedorahosted.Eekboard.Context"
 | 
			
		||||
 | 
			
		||||
#define SERVER_TYPE_CONTEXT (server_context_get_type())
 | 
			
		||||
#define SERVER_CONTEXT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SERVER_TYPE_CONTEXT, ServerContext))
 | 
			
		||||
#define SERVER_CONTEXT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SERVER_TYPE_CONTEXT, ServerContextClass))
 | 
			
		||||
#define SERVER_IS_CONTEXT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SERVER_TYPE_CONTEXT))
 | 
			
		||||
#define SERVER_IS_CONTEXT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SERVER_TYPE_CONTEXT))
 | 
			
		||||
#define SERVER_CONTEXT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SERVER_TYPE_CONTEXT, ServerContextClass))
 | 
			
		||||
 | 
			
		||||
typedef struct _ServerContext ServerContext;
 | 
			
		||||
 | 
			
		||||
ServerContext *server_context_new         (const gchar     *object_path,
 | 
			
		||||
                                           GDBusConnection *connection);
 | 
			
		||||
void           server_context_set_enabled (ServerContext   *context,
 | 
			
		||||
                                           gboolean         enabled);
 | 
			
		||||
void           server_context_set_client_connection
 | 
			
		||||
                                          (ServerContext   *context,
 | 
			
		||||
                                           const gchar     *client_connection);
 | 
			
		||||
const gchar   *server_context_get_client_connection
 | 
			
		||||
                                          (ServerContext   *context);
 | 
			
		||||
void           server_context_set_client_name
 | 
			
		||||
                                          (ServerContext   *context,
 | 
			
		||||
                                           const gchar     *client_name);
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
#endif  /* SERVER_CONTEXT_H */
 | 
			
		||||
@ -1,46 +0,0 @@
 | 
			
		||||
/*! The symbol object, defining actions that the key can do when activated */
 | 
			
		||||
 | 
			
		||||
use std::ffi::CString;
 | 
			
		||||
 | 
			
		||||
/// Name of the keysym
 | 
			
		||||
#[derive(Debug, Clone, PartialEq)]
 | 
			
		||||
pub struct KeySym(pub String);
 | 
			
		||||
 | 
			
		||||
/// Use to switch layouts
 | 
			
		||||
type Level = String;
 | 
			
		||||
 | 
			
		||||
/// Use to send modified keypresses
 | 
			
		||||
#[derive(Debug, Clone, PartialEq)]
 | 
			
		||||
pub enum Modifier {
 | 
			
		||||
    Control,
 | 
			
		||||
    Alt,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Action to perform on the keypress and, in reverse, on keyrelease
 | 
			
		||||
#[derive(Debug, Clone, PartialEq)]
 | 
			
		||||
pub enum Action {
 | 
			
		||||
    /// Switch to this view
 | 
			
		||||
    SetLevel(Level),
 | 
			
		||||
    /// Switch to a view and latch
 | 
			
		||||
    LockLevel {
 | 
			
		||||
        lock: Level,
 | 
			
		||||
        /// When unlocked by pressing it or emitting a key
 | 
			
		||||
        unlock: Level,
 | 
			
		||||
    },
 | 
			
		||||
    /// Set this modifier TODO: release?
 | 
			
		||||
    SetModifier(Modifier),
 | 
			
		||||
    /// Submit some text
 | 
			
		||||
    Submit {
 | 
			
		||||
        /// Text to submit with input-method
 | 
			
		||||
        text: Option<CString>,
 | 
			
		||||
        /// The key events this symbol submits when submitting text is not possible
 | 
			
		||||
        keys: Vec<KeySym>,
 | 
			
		||||
    },
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Contains a static description of a particular key's actions
 | 
			
		||||
#[derive(Debug, Clone, PartialEq)]
 | 
			
		||||
pub struct Symbol {
 | 
			
		||||
    /// The action that this key performs
 | 
			
		||||
    pub action: Action,
 | 
			
		||||
}
 | 
			
		||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user