Compare commits
	
		
			2 Commits
		
	
	
		
			v1.2.1
			...
			silence-wa
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| e09dd2b4dc | |||
| 5235b47827 | 
							
								
								
									
										9
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										9
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							@ -1,9 +0,0 @@
 | 
			
		||||
.zanata-cache/
 | 
			
		||||
_build
 | 
			
		||||
TAGS
 | 
			
		||||
tags
 | 
			
		||||
vgdump
 | 
			
		||||
*.swp
 | 
			
		||||
*~
 | 
			
		||||
\#*#
 | 
			
		||||
.\#*
 | 
			
		||||
@ -2,54 +2,20 @@ image: debian:buster
 | 
			
		||||
 | 
			
		||||
stages:
 | 
			
		||||
  - build
 | 
			
		||||
  - test
 | 
			
		||||
 | 
			
		||||
.tags: &tags
 | 
			
		||||
  tags:
 | 
			
		||||
    - librem5
 | 
			
		||||
 | 
			
		||||
before_script:
 | 
			
		||||
  - apt-get -y update
 | 
			
		||||
  - apt-get -y install wget ca-certificates gnupg
 | 
			
		||||
  - apt-get -y install wget gnupg2
 | 
			
		||||
  - echo "deb http://ci.puri.sm/ scratch librem5" > /etc/apt/sources.list.d/ci.list
 | 
			
		||||
  - wget -O- https://ci.puri.sm/ci-repo.key | apt-key add -
 | 
			
		||||
  - apt-get -y update
 | 
			
		||||
  - apt-get -y build-dep .
 | 
			
		||||
 | 
			
		||||
build_meson:
 | 
			
		||||
  <<: *tags
 | 
			
		||||
  stage: build
 | 
			
		||||
  artifacts:
 | 
			
		||||
    paths:
 | 
			
		||||
      - _build
 | 
			
		||||
  tags:
 | 
			
		||||
    - librem5
 | 
			
		||||
  script:
 | 
			
		||||
    - 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
 | 
			
		||||
  dependencies:
 | 
			
		||||
    - build_meson
 | 
			
		||||
  script:
 | 
			
		||||
    - ninja -C _build 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
 | 
			
		||||
```
 | 
			
		||||
							
								
								
									
										33
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										33
									
								
								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
 | 
			
		||||
 | 
			
		||||
@ -35,25 +33,36 @@ See `.gitlab-ci.yml`.
 | 
			
		||||
### Build from git repo
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
$ git clone https://source.puri.sm/Librem5/squeekboard.git
 | 
			
		||||
$ cd squeekboard
 | 
			
		||||
$ git clone https://source.puri.sm/Librem5/eekboard.git
 | 
			
		||||
$ cd eekboard
 | 
			
		||||
$ 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
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										20
									
								
								autogen.sh
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										20
									
								
								autogen.sh
									
									
									
									
									
										Executable file
									
								
							@ -0,0 +1,20 @@
 | 
			
		||||
#!/bin/sh
 | 
			
		||||
# Run this to generate all the initial makefiles, etc.
 | 
			
		||||
 | 
			
		||||
srcdir=`dirname $0`
 | 
			
		||||
test -z "$srcdir" && srcdir=.
 | 
			
		||||
 | 
			
		||||
PKG_NAME="eekboard"
 | 
			
		||||
 | 
			
		||||
(test -f $srcdir/configure.ac \
 | 
			
		||||
  && test -f $srcdir/README.md ) || {
 | 
			
		||||
    echo -n "**Error**: Directory "\`$srcdir\'" does not look like the"
 | 
			
		||||
    echo " top-level $PKG_NAME directory"
 | 
			
		||||
    exit 1
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ACLOCAL_FLAGS="$ACLOCAL_FLAGS -I m4"
 | 
			
		||||
REQUIRED_AUTOMAKE_VERSION=1.10
 | 
			
		||||
REQUIRED_AUTOCONF_VERSION=2.60
 | 
			
		||||
 | 
			
		||||
. gnome-autogen.sh
 | 
			
		||||
							
								
								
									
										1
									
								
								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,20 +0,0 @@
 | 
			
		||||
<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
 | 
			
		||||
"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
 | 
			
		||||
<node xmlns:doc="http://www.freedesktop.org/dbus/1.0/doc.dtd">
 | 
			
		||||
  <interface name="sm.puri.OSK0">
 | 
			
		||||
    <method name="SetVisible">
 | 
			
		||||
      <arg name="visible" type="b" direction="in"/>
 | 
			
		||||
      <doc:doc><doc:description>
 | 
			
		||||
        Switch keyboard visibility
 | 
			
		||||
      </doc:description></doc:doc>
 | 
			
		||||
    </method>
 | 
			
		||||
    <method name="GetVisible">
 | 
			
		||||
      <arg name="visible" type="b" direction="out"/>
 | 
			
		||||
      <doc:doc><doc:description>
 | 
			
		||||
        Get keyboard visibility
 | 
			
		||||
      </doc:description></doc:doc>
 | 
			
		||||
    </method>
 | 
			
		||||
    <property name="Visible" type="b" access="read">
 | 
			
		||||
    </property>
 | 
			
		||||
  </interface>
 | 
			
		||||
</node>
 | 
			
		||||
@ -1,10 +0,0 @@
 | 
			
		||||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
 | 
			
		||||
 | 
			
		||||
<svg xmlns="http://www.w3.org/2000/svg" height="16" width="16"
 | 
			
		||||
     version="1.1" viewBox="0 0 24 24">
 | 
			
		||||
   
 | 
			
		||||
    <path d="M 24,1 L 24,10 C 24,15 20,17 17,17 L 7,17 L 10,20 L 10,23
 | 
			
		||||
             L 7,23 L 0,15 L 7,7 L 10,7 L 10,10 L 7,13 L 17,13
 | 
			
		||||
             C 19,13 20,12 20,10 L 20,1 Z"
 | 
			
		||||
          stroke="none" fill="black" />
 | 
			
		||||
</svg>
 | 
			
		||||
| 
		 Before Width: | Height: | Size: 388 B  | 
@ -1,8 +0,0 @@
 | 
			
		||||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
 | 
			
		||||
 | 
			
		||||
<svg xmlns="http://www.w3.org/2000/svg" height="16" width="16"
 | 
			
		||||
     version="1.1" viewBox="0 0 24 24">
 | 
			
		||||
   
 | 
			
		||||
    <path d="M 12,2 L 22,14 L 16,14 L 16,22 L 8,22 L 8,14 L 2,14 Z"
 | 
			
		||||
          stroke="none" fill="black" />
 | 
			
		||||
</svg>
 | 
			
		||||
| 
		 Before Width: | Height: | Size: 279 B  | 
@ -1,52 +0,0 @@
 | 
			
		||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
 | 
			
		||||
<svg
 | 
			
		||||
   xmlns:dc="http://purl.org/dc/elements/1.1/"
 | 
			
		||||
   xmlns:cc="http://creativecommons.org/ns#"
 | 
			
		||||
   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
 | 
			
		||||
   xmlns:svg="http://www.w3.org/2000/svg"
 | 
			
		||||
   xmlns="http://www.w3.org/2000/svg"
 | 
			
		||||
   id="svg4043"
 | 
			
		||||
   version="1.1"
 | 
			
		||||
   viewBox="0 0 4.2333331 4.2333093"
 | 
			
		||||
   height="4.2333093mm"
 | 
			
		||||
   width="4.2333331mm">
 | 
			
		||||
  <defs
 | 
			
		||||
     id="defs4037" />
 | 
			
		||||
  <metadata
 | 
			
		||||
     id="metadata4040">
 | 
			
		||||
    <rdf:RDF>
 | 
			
		||||
      <cc:Work
 | 
			
		||||
         rdf:about="">
 | 
			
		||||
        <dc:format>image/svg+xml</dc:format>
 | 
			
		||||
        <dc:type
 | 
			
		||||
           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
 | 
			
		||||
        <dc:title></dc:title>
 | 
			
		||||
      </cc:Work>
 | 
			
		||||
    </rdf:RDF>
 | 
			
		||||
  </metadata>
 | 
			
		||||
  <g
 | 
			
		||||
     transform="translate(-86.329776,-68.097636)"
 | 
			
		||||
     id="layer1">
 | 
			
		||||
    <g
 | 
			
		||||
       style="stroke-width:1.00004983;fill:#2e3436;fill-opacity:1"
 | 
			
		||||
       transform="matrix(0.99990029,0,0,1,-7.1823833,-1.8799927)"
 | 
			
		||||
       id="g842">
 | 
			
		||||
      <g
 | 
			
		||||
         style="stroke-width:1.00004983;fill:#2e3436;fill-opacity:1"
 | 
			
		||||
         id="g836">
 | 
			
		||||
        <path
 | 
			
		||||
           id="path5166"
 | 
			
		||||
           d="m 95.636719,69.978516 c -1.165869,0 -2.115235,0.949365 -2.115235,2.115234 0,1.165869 0.949366,2.117188 2.115235,2.117188 1.165869,0 2.117187,-0.951319 2.117187,-2.117188 0,-1.165869 -0.951318,-2.115234 -2.117187,-2.115234 z m 0,0.529296 c 0.879886,0 1.58789,0.706052 1.58789,1.585938 0,0.879886 -0.708004,1.587891 -1.58789,1.587891 -0.879886,0 -1.585938,-0.708005 -1.585938,-1.587891 0,-0.879886 0.706052,-1.585937 1.585938,-1.585938 z"
 | 
			
		||||
           style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#2e3436;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.52919304;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" />
 | 
			
		||||
      </g>
 | 
			
		||||
      <path
 | 
			
		||||
         style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#2e3436;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.26459652;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
 | 
			
		||||
         d="m 95.636719,70.109375 c -0.144398,0 -0.27248,0.07793 -0.373047,0.189453 -0.100567,0.111521 -0.18209,0.261405 -0.25,0.439453 -0.135821,0.356096 -0.214844,0.830395 -0.214844,1.355469 0,0.525074 0.07902,1.001326 0.214844,1.357422 0.06791,0.178048 0.149433,0.327932 0.25,0.439453 0.100567,0.111521 0.228649,0.1875 0.373047,0.1875 0.144397,0 0.27248,-0.07598 0.373047,-0.1875 0.100566,-0.111521 0.182089,-0.261405 0.25,-0.439453 0.135821,-0.356096 0.216797,-0.832348 0.216796,-1.357422 0,-0.525074 -0.08097,-0.999373 -0.216796,-1.355469 -0.06791,-0.178048 -0.149434,-0.327932 -0.25,-0.439453 -0.100567,-0.111521 -0.22865,-0.189453 -0.373047,-0.189453 z m 0,0.265625 c 0.05067,0 0.109272,0.02564 0.177734,0.101562 0.06846,0.07592 0.139293,0.198356 0.199219,0.355469 0.119851,0.314227 0.197266,0.763915 0.197266,1.261719 0,0.497804 -0.07742,0.949446 -0.197266,1.263672 -0.05993,0.157113 -0.130756,0.279549 -0.199219,0.355469 -0.06846,0.07592 -0.12706,0.101562 -0.177734,0.101562 -0.05067,0 -0.107319,-0.02564 -0.175781,-0.101562 -0.06846,-0.07592 -0.139294,-0.198356 -0.199219,-0.355469 C 95.141867,73.043196 95.0625,72.591554 95.0625,72.09375 c 0,-0.497804 0.07937,-0.947492 0.199219,-1.261719 0.05993,-0.157113 0.130756,-0.279549 0.199219,-0.355469 C 95.5294,70.400643 95.586045,70.375 95.636719,70.375 Z"
 | 
			
		||||
         id="circle5168" />
 | 
			
		||||
      <path
 | 
			
		||||
         style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#2e3436;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.26459652;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
 | 
			
		||||
         d="m 93.697266,71.962891 v 0.263671 h 3.96875 v -0.263671 z"
 | 
			
		||||
         id="path5170" />
 | 
			
		||||
    </g>
 | 
			
		||||
  </g>
 | 
			
		||||
</svg>
 | 
			
		||||
| 
		 Before Width: | Height: | Size: 6.6 KiB  | 
@ -1,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"
 | 
			
		||||
							
								
								
									
										189
									
								
								data/keyboards/geometry/compact.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										189
									
								
								data/keyboards/geometry/compact.xml
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,189 @@
 | 
			
		||||
<?xml version="1.0"?>
 | 
			
		||||
<geometry version="0.90">
 | 
			
		||||
  <bounds x="0.000000" y="0.000000" width="426.0000" height="296.5853"/>
 | 
			
		||||
  <section angle="0">
 | 
			
		||||
    <bounds x="0" y="0" width="608.7804" height="201.3658"/>
 | 
			
		||||
    <row orientation="1">
 | 
			
		||||
      <key keycode="24" name="AD01" oref="outline2">
 | 
			
		||||
	<bounds x="65.56097" y="42.14634" width="37.46341" height="52.44877"/>
 | 
			
		||||
      </key>
 | 
			
		||||
      <key keycode="25" name="AD02" oref="outline2">
 | 
			
		||||
	<bounds x="106.1463" y="42.14634" width="37.46341" height="37.46341"/>
 | 
			
		||||
      </key>
 | 
			
		||||
      <key keycode="26" name="AD03" oref="outline2">
 | 
			
		||||
	<bounds x="145.1707" y="42.14634" width="37.46341" height="37.46341"/>
 | 
			
		||||
      </key>
 | 
			
		||||
      <key keycode="27" name="AD04" oref="outline2">
 | 
			
		||||
	<bounds x="185.7560" y="42.14634" width="37.46341" height="37.46341"/>
 | 
			
		||||
      </key>
 | 
			
		||||
      <key keycode="28" name="AD05" oref="outline2">
 | 
			
		||||
	<bounds x="226.3414" y="42.14634" width="37.46341" height="37.46341"/>
 | 
			
		||||
      </key>
 | 
			
		||||
      <key keycode="29" name="AD06" oref="outline2">
 | 
			
		||||
	<bounds x="266.9268" y="42.14634" width="37.46341" height="37.46341"/>
 | 
			
		||||
      </key>
 | 
			
		||||
      <key keycode="30" name="AD07" oref="outline2">
 | 
			
		||||
	<bounds x="307.5121" y="42.14634" width="37.46341" height="37.46341"/>
 | 
			
		||||
      </key>
 | 
			
		||||
      <key keycode="31" name="AD08" oref="outline2">
 | 
			
		||||
	<bounds x="348.0975" y="42.14634" width="37.46341" height="37.46341"/>
 | 
			
		||||
      </key>
 | 
			
		||||
      <key keycode="32" name="AD09" oref="outline2">
 | 
			
		||||
	<bounds x="388.6829" y="42.14634" width="37.46341" height="37.46341"/>
 | 
			
		||||
      </key>
 | 
			
		||||
      <key keycode="33" name="AD10" oref="outline2">
 | 
			
		||||
	<bounds x="429.2682" y="42.14634" width="37.46341" height="37.46341"/>
 | 
			
		||||
      </key>
 | 
			
		||||
    </row>
 | 
			
		||||
  </section>
 | 
			
		||||
  <section angle="0">
 | 
			
		||||
    <bounds x="0" y="0" width="608.7804" height="201.3658"/>
 | 
			
		||||
    <row orientation="1">
 | 
			
		||||
      <key keycode="38" name="AC01" oref="outline2">
 | 
			
		||||
	<bounds x="76.48780" y="82.73170" width="37.46341" height="37.46341"/>
 | 
			
		||||
      </key>
 | 
			
		||||
      <key keycode="39" name="AC02" oref="outline2">
 | 
			
		||||
	<bounds x="115.5121" y="82.73170" width="37.46341" height="37.46341"/>
 | 
			
		||||
      </key>
 | 
			
		||||
      <key keycode="40" name="AC03" oref="outline2">
 | 
			
		||||
	<bounds x="156.0975" y="82.73170" width="37.46341" height="37.46341"/>
 | 
			
		||||
      </key>
 | 
			
		||||
      <key keycode="41" name="AC04" oref="outline2">
 | 
			
		||||
	<bounds x="196.6829" y="82.73170" width="37.46341" height="37.46341"/>
 | 
			
		||||
      </key>
 | 
			
		||||
      <key keycode="42" name="AC05" oref="outline2">
 | 
			
		||||
	<bounds x="237.2682" y="82.73170" width="37.46341" height="37.46341"/>
 | 
			
		||||
      </key>
 | 
			
		||||
      <key keycode="43" name="AC06" oref="outline2">
 | 
			
		||||
	<bounds x="277.8536" y="82.73170" width="37.46341" height="37.46341"/>
 | 
			
		||||
      </key>
 | 
			
		||||
      <key keycode="44" name="AC07" oref="outline2">
 | 
			
		||||
	<bounds x="318.4390" y="82.73170" width="37.46341" height="37.46341"/>
 | 
			
		||||
      </key>
 | 
			
		||||
      <key keycode="45" name="AC08" oref="outline2">
 | 
			
		||||
	<bounds x="359.0243" y="82.73170" width="37.46341" height="37.46341"/>
 | 
			
		||||
      </key>
 | 
			
		||||
      <key keycode="46" name="AC09" oref="outline2">
 | 
			
		||||
	<bounds x="399.6097" y="82.73170" width="37.46341" height="37.46341"/>
 | 
			
		||||
      </key>
 | 
			
		||||
    </row>
 | 
			
		||||
  </section>
 | 
			
		||||
  <section angle="0">
 | 
			
		||||
    <bounds x="0" y="0" width="608.7804" height="201.3658"/>
 | 
			
		||||
    <row orientation="1">
 | 
			
		||||
      <key keycode="50" name="LFSH" oref="altline">
 | 
			
		||||
	<bounds x="3.121951" y="121.7560" width="88.97561" height="37.46341"/>
 | 
			
		||||
      </key>
 | 
			
		||||
      <key keycode="52" name="AB01" oref="outline2">
 | 
			
		||||
	<bounds x="95.21951" y="121.7560" width="37.46341" height="37.46341"/>
 | 
			
		||||
      </key>
 | 
			
		||||
      <key keycode="53" name="AB02" oref="outline2">
 | 
			
		||||
	<bounds x="135.8048" y="121.7560" width="37.46341" height="37.46341"/>
 | 
			
		||||
      </key>
 | 
			
		||||
      <key keycode="54" name="AB03" oref="outline2">
 | 
			
		||||
	<bounds x="176.3902" y="121.7560" width="37.46341" height="37.46341"/>
 | 
			
		||||
      </key>
 | 
			
		||||
      <key keycode="55" name="AB04" oref="outline2">
 | 
			
		||||
	<bounds x="215.4146" y="121.7560" width="37.46341" height="37.46341"/>
 | 
			
		||||
      </key>
 | 
			
		||||
      <key keycode="56" name="AB05" oref="outline2">
 | 
			
		||||
	<bounds x="256.0000" y="121.7560" width="37.46341" height="37.46341"/>
 | 
			
		||||
      </key>
 | 
			
		||||
      <key keycode="57" name="AB06" oref="outline2">
 | 
			
		||||
	<bounds x="296.5853" y="121.7560" width="37.46341" height="37.46341"/>
 | 
			
		||||
      </key>
 | 
			
		||||
      <key keycode="58" name="AB07" oref="outline2">
 | 
			
		||||
	<bounds x="337.1707" y="121.7560" width="37.46341" height="37.46341"/>
 | 
			
		||||
      </key>
 | 
			
		||||
      <key keycode="22" name="BKSP" oref="altline">
 | 
			
		||||
	<bounds x="529.1707" y="1.560976" width="79.60975" height="37.46341"/>
 | 
			
		||||
      </key>
 | 
			
		||||
    </row>
 | 
			
		||||
  </section>
 | 
			
		||||
  <section angle="0">
 | 
			
		||||
    <bounds x="0" y="0" width="608.7804" height="201.3658"/>
 | 
			
		||||
    <row orientation="1">
 | 
			
		||||
      <key keycode="37" name="LCTL" oref="altline">
 | 
			
		||||
	<bounds x="62.43902" y="162.3414" width="48.39024" height="37.46341"/>
 | 
			
		||||
      </key>
 | 
			
		||||
      <key keycode="66" name="ALTGR" oref="altline">
 | 
			
		||||
	<bounds x="113.9512" y="162.3414" width="48.39024" height="37.46341"/>
 | 
			
		||||
      </key>
 | 
			
		||||
      <key keycode="65" name="SPCE" oref="spaceline">
 | 
			
		||||
	<bounds x="165.4634" y="162.3414" width="217.5853" height="37.46341"/>
 | 
			
		||||
      </key>
 | 
			
		||||
      <key keycode="60" name="AB09" oref="outline2">
 | 
			
		||||
       <bounds x="418.3414" y="121.7560" width="37.46341" height="37.46341"/>
 | 
			
		||||
      </key>
 | 
			
		||||
      <key keycode="36" name="RTRN" oref="outline7">
 | 
			
		||||
	<bounds x="519.8048" y="82.73170" width="88.97561" height="37.46341"/>
 | 
			
		||||
      </key>
 | 
			
		||||
    </row>
 | 
			
		||||
  </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"
 | 
			
		||||
							
								
								
									
										88
									
								
								data/keyboards/keyboards.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										88
									
								
								data/keyboards/keyboards.xml
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,88 @@
 | 
			
		||||
<?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="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"/>
 | 
			
		||||
</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: ")"
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										304
									
								
								data/keyboards/symbols/us.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										304
									
								
								data/keyboards/symbols/us.xml
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,304 @@
 | 
			
		||||
<?xml version="1.0"?>
 | 
			
		||||
<symbols version="0.90">
 | 
			
		||||
  <key keycode="9" name="ESC">
 | 
			
		||||
    <keysym keyval="65307">Escape</keysym>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key keycode="67" name="FK01">
 | 
			
		||||
    <keysym keyval="65470">F1</keysym>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key keycode="68" name="FK02">
 | 
			
		||||
    <keysym keyval="65471">F2</keysym>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key keycode="69" name="FK03">
 | 
			
		||||
    <keysym keyval="65472">F3</keysym>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key keycode="70" name="FK04">
 | 
			
		||||
    <keysym keyval="65473">F4</keysym>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key keycode="71" name="FK05">
 | 
			
		||||
    <keysym keyval="65474">F5</keysym>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key keycode="72" name="FK06">
 | 
			
		||||
    <keysym keyval="65475">F6</keysym>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key keycode="73" name="FK07">
 | 
			
		||||
    <keysym keyval="65476">F7</keysym>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key keycode="74" name="FK08">
 | 
			
		||||
    <keysym keyval="65477">F8</keysym>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key keycode="75" name="FK09">
 | 
			
		||||
    <keysym keyval="65478">F9</keysym>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key keycode="76" name="FK10">
 | 
			
		||||
    <keysym keyval="65479">F10</keysym>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key keycode="95" name="FK11">
 | 
			
		||||
    <keysym keyval="65480">F11</keysym>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key keycode="96" name="FK12">
 | 
			
		||||
    <keysym keyval="65481">F12</keysym>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key keycode="49" name="TLDE">
 | 
			
		||||
    <keysym keyval="96">quoteleft</keysym>
 | 
			
		||||
    <keysym keyval="126">asciitilde</keysym>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key keycode="10" name="AE01">
 | 
			
		||||
    <keysym keyval="49">1</keysym>
 | 
			
		||||
    <keysym keyval="33">exclam</keysym>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key keycode="11" name="AE02">
 | 
			
		||||
    <keysym keyval="50">2</keysym>
 | 
			
		||||
    <keysym keyval="64">at</keysym>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key keycode="12" name="AE03">
 | 
			
		||||
    <keysym keyval="51">3</keysym>
 | 
			
		||||
    <keysym keyval="35">numbersign</keysym>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key keycode="13" name="AE04">
 | 
			
		||||
    <keysym keyval="52">4</keysym>
 | 
			
		||||
    <keysym keyval="36">dollar</keysym>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key keycode="14" name="AE05">
 | 
			
		||||
    <keysym keyval="53">5</keysym>
 | 
			
		||||
    <keysym keyval="37">percent</keysym>
 | 
			
		||||
    <keysym keyval="8364">EuroSign</keysym>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key keycode="15" name="AE06">
 | 
			
		||||
    <keysym keyval="54">6</keysym>
 | 
			
		||||
    <keysym keyval="94">asciicircum</keysym>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key keycode="16" name="AE07">
 | 
			
		||||
    <keysym keyval="55">7</keysym>
 | 
			
		||||
    <keysym keyval="38">ampersand</keysym>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key keycode="17" name="AE08">
 | 
			
		||||
    <keysym keyval="56">8</keysym>
 | 
			
		||||
    <keysym keyval="42">asterisk</keysym>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key keycode="18" name="AE09">
 | 
			
		||||
    <keysym keyval="57">9</keysym>
 | 
			
		||||
    <keysym keyval="40">parenleft</keysym>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key keycode="19" name="AE10">
 | 
			
		||||
    <keysym keyval="48">0</keysym>
 | 
			
		||||
    <keysym keyval="41">parenright</keysym>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key keycode="20" name="AE11">
 | 
			
		||||
    <keysym keyval="45">minus</keysym>
 | 
			
		||||
    <keysym keyval="95">underscore</keysym>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key keycode="21" name="AE12">
 | 
			
		||||
    <keysym keyval="61">equal</keysym>
 | 
			
		||||
    <keysym keyval="43">plus</keysym>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key keycode="22" name="BKSP">
 | 
			
		||||
    <keysym keyval="65288">BackSpace</keysym>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key keycode="23" name="TAB">
 | 
			
		||||
    <keysym keyval="65289">Tab</keysym>
 | 
			
		||||
    <keysym keyval="65056">ISO_Left_Tab</keysym>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key keycode="24" name="AD01">
 | 
			
		||||
    <keysym keyval="113">q</keysym>
 | 
			
		||||
    <keysym keyval="81">Q</keysym>
 | 
			
		||||
    <keysym keyval="49">1</keysym>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key keycode="25" name="AD02">
 | 
			
		||||
    <keysym keyval="119">w</keysym>
 | 
			
		||||
    <keysym keyval="87">W</keysym>
 | 
			
		||||
    <keysym keyval="50">2</keysym>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key keycode="26" name="AD03">
 | 
			
		||||
    <keysym keyval="101">e</keysym>
 | 
			
		||||
    <keysym keyval="69">E</keysym>
 | 
			
		||||
    <keysym keyval="51">3</keysym>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key keycode="27" name="AD04">
 | 
			
		||||
    <keysym keyval="114">r</keysym>
 | 
			
		||||
    <keysym keyval="82">R</keysym>
 | 
			
		||||
    <keysym keyval="52">4</keysym>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key keycode="28" name="AD05">
 | 
			
		||||
    <keysym keyval="116">t</keysym>
 | 
			
		||||
    <keysym keyval="84">T</keysym>
 | 
			
		||||
    <keysym keyval="53">5</keysym>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key keycode="29" name="AD06">
 | 
			
		||||
    <keysym keyval="121">y</keysym>
 | 
			
		||||
    <keysym keyval="89">Y</keysym>
 | 
			
		||||
    <keysym keyval="54">6</keysym>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key keycode="30" name="AD07">
 | 
			
		||||
    <keysym keyval="117">u</keysym>
 | 
			
		||||
    <keysym keyval="85">U</keysym>
 | 
			
		||||
    <keysym keyval="55">7</keysym>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key keycode="31" name="AD08">
 | 
			
		||||
    <keysym keyval="105">i</keysym>
 | 
			
		||||
    <keysym keyval="73">I</keysym>
 | 
			
		||||
    <keysym keyval="56">8</keysym>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key keycode="32" name="AD09">
 | 
			
		||||
    <keysym keyval="111">o</keysym>
 | 
			
		||||
    <keysym keyval="79">O</keysym>
 | 
			
		||||
    <keysym keyval="57">9</keysym>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key keycode="33" name="AD10">
 | 
			
		||||
    <keysym keyval="112">p</keysym>
 | 
			
		||||
    <keysym keyval="80">P</keysym>
 | 
			
		||||
    <keysym keyval="48">0</keysym>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key keycode="34" name="AD11">
 | 
			
		||||
    <keysym keyval="91">bracketleft</keysym>
 | 
			
		||||
    <keysym keyval="123">braceleft</keysym>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key keycode="35" name="AD12">
 | 
			
		||||
    <keysym keyval="93">bracketright</keysym>
 | 
			
		||||
    <keysym keyval="125">braceright</keysym>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key keycode="51" name="BKSL">
 | 
			
		||||
    <keysym keyval="92">backslash</keysym>
 | 
			
		||||
    <keysym keyval="124">bar</keysym>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key keycode="66" name="ALTGR">
 | 
			
		||||
    <keysym keyval="65027">ISO_Level3_Shift</keysym>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key keycode="38" name="AC01">
 | 
			
		||||
    <keysym keyval="97">a</keysym>
 | 
			
		||||
    <keysym keyval="65">A</keysym>
 | 
			
		||||
    <keysym keyval="64">at</keysym>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key keycode="39" name="AC02">
 | 
			
		||||
    <keysym keyval="115">s</keysym>
 | 
			
		||||
    <keysym keyval="83">S</keysym>
 | 
			
		||||
    <keysym keyval="35">numbersign</keysym>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key keycode="40" name="AC03">
 | 
			
		||||
    <keysym keyval="100">d</keysym>
 | 
			
		||||
    <keysym keyval="68">D</keysym>
 | 
			
		||||
    <keysym keyval="36">dollar</keysym>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key keycode="41" name="AC04">
 | 
			
		||||
    <keysym keyval="102">f</keysym>
 | 
			
		||||
    <keysym keyval="70">F</keysym>
 | 
			
		||||
    <keysym keyval="37">percent</keysym>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key keycode="42" name="AC05">
 | 
			
		||||
    <keysym keyval="103">g</keysym>
 | 
			
		||||
    <keysym keyval="71">G</keysym>
 | 
			
		||||
    <keysym keyval="38">ampersand</keysym>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key keycode="43" name="AC06">
 | 
			
		||||
    <keysym keyval="104">h</keysym>
 | 
			
		||||
    <keysym keyval="72">H</keysym>
 | 
			
		||||
    <keysym keyval="45">minus</keysym>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key keycode="44" name="AC07">
 | 
			
		||||
    <keysym keyval="106">j</keysym>
 | 
			
		||||
    <keysym keyval="74">J</keysym>
 | 
			
		||||
    <keysym keyval="95">underscore</keysym>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key keycode="45" name="AC08">
 | 
			
		||||
    <keysym keyval="107">k</keysym>
 | 
			
		||||
    <keysym keyval="75">K</keysym>
 | 
			
		||||
    <keysym keyval="123">braceleft</keysym>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key keycode="46" name="AC09">
 | 
			
		||||
    <keysym keyval="108">l</keysym>
 | 
			
		||||
    <keysym keyval="76">L</keysym>
 | 
			
		||||
    <keysym keyval="125">braceright</keysym>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key keycode="47" name="AC10">
 | 
			
		||||
    <keysym keyval="59">semicolon</keysym>
 | 
			
		||||
    <keysym keyval="58">colon</keysym>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key keycode="48" name="AC11">
 | 
			
		||||
    <keysym keyval="39">quoteright</keysym>
 | 
			
		||||
    <keysym keyval="34">quotedbl</keysym>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key keycode="36" name="RTRN">
 | 
			
		||||
    <keysym keyval="65293">Return</keysym>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key keycode="50" name="LFSH">
 | 
			
		||||
    <keysym keyval="65505">Shift_L</keysym>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key keycode="52" name="AB01">
 | 
			
		||||
    <keysym keyval="122">z</keysym>
 | 
			
		||||
    <keysym keyval="90">Z</keysym>
 | 
			
		||||
    <keysym keyval="43">plus</keysym>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key keycode="53" name="AB02">
 | 
			
		||||
    <keysym keyval="120">x</keysym>
 | 
			
		||||
    <keysym keyval="88">X</keysym>
 | 
			
		||||
    <keysym keyval="34">quotedbl</keysym>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key keycode="54" name="AB03">
 | 
			
		||||
    <keysym keyval="99">c</keysym>
 | 
			
		||||
    <keysym keyval="67">C</keysym>
 | 
			
		||||
    <keysym keyval="39">quoteright</keysym>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key keycode="55" name="AB04">
 | 
			
		||||
    <keysym keyval="118">v</keysym>
 | 
			
		||||
    <keysym keyval="86">V</keysym>
 | 
			
		||||
    <keysym keyval="58">colon</keysym>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key keycode="56" name="AB05">
 | 
			
		||||
    <keysym keyval="98">b</keysym>
 | 
			
		||||
    <keysym keyval="66">B</keysym>
 | 
			
		||||
    <keysym keyval="59">semicolon</keysym>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key keycode="57" name="AB06">
 | 
			
		||||
    <keysym keyval="110">n</keysym>
 | 
			
		||||
    <keysym keyval="78">N</keysym>
 | 
			
		||||
    <keysym keyval="33">exclam</keysym>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key keycode="58" name="AB07">
 | 
			
		||||
    <keysym keyval="109">m</keysym>
 | 
			
		||||
    <keysym keyval="77">M</keysym>
 | 
			
		||||
    <keysym keyval="63">question</keysym>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key keycode="59" name="AB08">
 | 
			
		||||
    <keysym keyval="44">comma</keysym>
 | 
			
		||||
    <keysym keyval="60">less</keysym>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key keycode="60" name="AB09">
 | 
			
		||||
    <keysym keyval="46">period</keysym>
 | 
			
		||||
    <keysym keyval="62">greater</keysym>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key keycode="61" name="AB10">
 | 
			
		||||
    <keysym keyval="47">slash</keysym>
 | 
			
		||||
    <keysym keyval="63">question</keysym>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key keycode="62" name="RTSH">
 | 
			
		||||
    <keysym keyval="65506">Shift_R</keysym>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key keycode="149" name="I149">
 | 
			
		||||
    <symbol label="⌨" icon="input-keyboard-symbolic" tooltip="Change keyboard">cycle-keyboard</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key keycode="150" name="I150">
 | 
			
		||||
    <symbol label="☺" icon="preferences-system-symbolic" tooltip="Setup">preferences</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key keycode="37" name="LCTL">
 | 
			
		||||
    <keysym keyval="65507">Control_L</keysym>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key keycode="64" name="LALT">
 | 
			
		||||
    <keysym keyval="65513">Alt_L</keysym>
 | 
			
		||||
    <keysym keyval="65511">Meta_L</keysym>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key keycode="65" name="SPCE">
 | 
			
		||||
    <keysym keyval="32">space</keysym>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key keycode="113" name="LEFT">
 | 
			
		||||
    <keysym keyval="65361">Left</keysym>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key keycode="111" name="UP">
 | 
			
		||||
    <keysym keyval="65362">Up</keysym>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key keycode="116" name="DOWN">
 | 
			
		||||
    <keysym keyval="65364">Down</keysym>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key keycode="114" name="RGHT">
 | 
			
		||||
    <keysym keyval="65363">Right</keysym>
 | 
			
		||||
  </key>
 | 
			
		||||
</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"
 | 
			
		||||
@ -1,12 +1,57 @@
 | 
			
		||||
gnome = import('gnome')
 | 
			
		||||
 | 
			
		||||
squeekboard_resources = gnome.compile_resources(
 | 
			
		||||
   'squeekboard-resources',
 | 
			
		||||
   'squeekboard.gresources.xml',
 | 
			
		||||
 | 
			
		||||
   c_name: 'squeekboard',
 | 
			
		||||
install_data(
 | 
			
		||||
    'themes/default.css',
 | 
			
		||||
    install_dir: pkgdatadir + '/themes',
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
install_data(
 | 
			
		||||
    'keyboards/keyboards.xml',
 | 
			
		||||
    install_dir: pkgdatadir + '/keyboards/',
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
install_data(
 | 
			
		||||
    'keyboards/geometry/compact.xml',
 | 
			
		||||
    install_dir: pkgdatadir + '/keyboards/geometry/',
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
symbols = [
 | 
			
		||||
    'ar.xml',
 | 
			
		||||
    'as-inscript.xml',
 | 
			
		||||
    'be.xml',
 | 
			
		||||
    'bn-inscript.xml',
 | 
			
		||||
    'fa.xml',
 | 
			
		||||
    'gu-inscript.xml',
 | 
			
		||||
    'he.xml',
 | 
			
		||||
    'hi-inscript.xml',
 | 
			
		||||
    'ja-kana.xml',
 | 
			
		||||
    'kk.xml',
 | 
			
		||||
    'kn-inscript.xml',
 | 
			
		||||
    'ks-inscript.xml',
 | 
			
		||||
    'ks.xml',
 | 
			
		||||
    'mai-inscript.xml',
 | 
			
		||||
    'ml-inscript.xml',
 | 
			
		||||
    'mr-inscript.xml',
 | 
			
		||||
    'my.xml',
 | 
			
		||||
    'or-inscript.xml',
 | 
			
		||||
    'pa-inscript.xml',
 | 
			
		||||
    'ru.xml',
 | 
			
		||||
    'sd-inscript.xml',
 | 
			
		||||
    'ta-inscript.xml',
 | 
			
		||||
    'te-inscript.xml',
 | 
			
		||||
    'th.xml',
 | 
			
		||||
    'ua.xml',
 | 
			
		||||
    'ug.xml',
 | 
			
		||||
    'us.xml',
 | 
			
		||||
    'zh-bopomofo.xml',
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
foreach symbol: symbols
 | 
			
		||||
    install_data(
 | 
			
		||||
        'keyboards/symbols/' + symbol,
 | 
			
		||||
        install_dir: pkgdatadir + '/keyboards/symbols/',
 | 
			
		||||
    )
 | 
			
		||||
endforeach
 | 
			
		||||
 | 
			
		||||
desktop_file = 'sm.puri.Squeekboard.desktop'
 | 
			
		||||
 | 
			
		||||
i18n.merge_file('desktop',
 | 
			
		||||
 | 
			
		||||
@ -6,5 +6,4 @@ Exec=squeekboard
 | 
			
		||||
Icon=squeekboard
 | 
			
		||||
Terminal=false
 | 
			
		||||
Type=Application
 | 
			
		||||
NoDisplay=true
 | 
			
		||||
Categories=GTK;Utility;
 | 
			
		||||
 | 
			
		||||
@ -1,36 +0,0 @@
 | 
			
		||||
<?xml version="1.0" encoding="UTF-8"?>
 | 
			
		||||
<gresources>
 | 
			
		||||
  <gresource prefix="/sm/puri/squeekboard">
 | 
			
		||||
   <file compressed="true">style.css</file>
 | 
			
		||||
   <file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/ar.xml</file>
 | 
			
		||||
   <file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/as-inscript.xml</file>
 | 
			
		||||
   <file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/be.xml</file>
 | 
			
		||||
   <file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/bn-inscript.xml</file>
 | 
			
		||||
   <file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/fa.xml</file>
 | 
			
		||||
   <file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/gu-inscript.xml</file>
 | 
			
		||||
   <file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/he.xml</file>
 | 
			
		||||
   <file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/hi-inscript.xml</file>
 | 
			
		||||
   <file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/ja-kana.xml</file>
 | 
			
		||||
   <file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/kk.xml</file>
 | 
			
		||||
   <file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/kn-inscript.xml</file>
 | 
			
		||||
   <file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/ks-inscript.xml</file>
 | 
			
		||||
   <file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/ks.xml</file>
 | 
			
		||||
   <file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/mai-inscript.xml</file>
 | 
			
		||||
   <file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/ml-inscript.xml</file>
 | 
			
		||||
   <file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/mr-inscript.xml</file>
 | 
			
		||||
   <file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/my.xml</file>
 | 
			
		||||
   <file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/or-inscript.xml</file>
 | 
			
		||||
   <file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/pa-inscript.xml</file>
 | 
			
		||||
   <file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/ru.xml</file>
 | 
			
		||||
   <file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/sd-inscript.xml</file>
 | 
			
		||||
   <file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/ta-inscript.xml</file>
 | 
			
		||||
   <file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/te-inscript.xml</file>
 | 
			
		||||
   <file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/th.xml</file>
 | 
			
		||||
   <file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/ua.xml</file>
 | 
			
		||||
   <file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/ug.xml</file>
 | 
			
		||||
   <file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/zh-bopomofo.xml</file>
 | 
			
		||||
   <file>icons/key-enter.svg</file>
 | 
			
		||||
   <file>icons/key-shift.svg</file>
 | 
			
		||||
   <file>icons/keyboard-mode-symbolic.svg</file>
 | 
			
		||||
  </gresource>
 | 
			
		||||
</gresources>
 | 
			
		||||
@ -1,41 +0,0 @@
 | 
			
		||||
sq_view {
 | 
			
		||||
    background-color: rgba(0, 0, 0, 255);
 | 
			
		||||
    color: #ffffff;
 | 
			
		||||
    font-family: cantarell, sans-serif;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
sq_button {
 | 
			
		||||
    color: #deddda;
 | 
			
		||||
    background: #464448;
 | 
			
		||||
    border-style: solid;
 | 
			
		||||
    border-width: 1px;
 | 
			
		||||
    border-color: #5e5c64;
 | 
			
		||||
    border-radius: 3px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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 {
 | 
			
		||||
    background: #1c71d8;
 | 
			
		||||
    border-color: #3584e4;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										18
									
								
								data/themes/default.css
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								data/themes/default.css
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,18 @@
 | 
			
		||||
.keyboard {
 | 
			
		||||
    background-color: rgba(0, 0, 0, 255);
 | 
			
		||||
    color: #ffffff;
 | 
			
		||||
    font-family: cantarell, sans-serif;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.key {
 | 
			
		||||
    color: #deddda;
 | 
			
		||||
    background: #464448;
 | 
			
		||||
    border-width: 0.5px;
 | 
			
		||||
    border-color: #5e5c64;
 | 
			
		||||
    border-radius: 2px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.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
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										15
									
								
								debian/control
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										15
									
								
								debian/control
									
									
									
									
										vendored
									
									
								
							@ -3,25 +3,16 @@ 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),
 | 
			
		||||
# for running the tests
 | 
			
		||||
 xvfb,
 | 
			
		||||
 xauth,
 | 
			
		||||
 virtboard,
 | 
			
		||||
 wayland-protocols (>= 1.14)
 | 
			
		||||
Standards-Version: 4.1.3
 | 
			
		||||
Homepage: https://source.puri.sm/Librem5/squeekboard
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										57
									
								
								debian/copyright
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										57
									
								
								debian/copyright
									
									
									
									
										vendored
									
									
								
							@ -1,60 +1,9 @@
 | 
			
		||||
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>
 | 
			
		||||
           2010-2011 Red Hat, Inc.
 | 
			
		||||
           2019 Purism SPC
 | 
			
		||||
License: GPL-3+
 | 
			
		||||
 | 
			
		||||
Files: eek/layersurface.c
 | 
			
		||||
       src/wayland.c
 | 
			
		||||
       src/key-emitter.c
 | 
			
		||||
       meson.build
 | 
			
		||||
       src/meson.build
 | 
			
		||||
       po/meson.build
 | 
			
		||||
Copyright: 2018-2019 Purism SPC
 | 
			
		||||
License: GPL-3+
 | 
			
		||||
 | 
			
		||||
Files: eekboard/keymap.c
 | 
			
		||||
Copyright: 2000 Red Hat, Inc.
 | 
			
		||||
           2019 Purism, SPC
 | 
			
		||||
License: LGPL-2+
 | 
			
		||||
 This library is free software; you can redistribute it and/or
 | 
			
		||||
 modify it under the terms of the GNU Lesser General Public
 | 
			
		||||
 License as published by the Free Software Foundation; either
 | 
			
		||||
 version 2 of the License, or (at your option) any later version.
 | 
			
		||||
 | 
			
		||||
 This library is distributed in the hope that it will be useful,
 | 
			
		||||
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.         See the GNU
 | 
			
		||||
 Lesser General Public License for more details.
 | 
			
		||||
 | 
			
		||||
 You should have received a copy of the GNU Lesser General Public
 | 
			
		||||
 License along with this library. If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 | 
			
		||||
Files: protocols/wlr-layer-shell-unstable-v1.xml
 | 
			
		||||
Copytight: Copyright © 2017 Drew DeVault
 | 
			
		||||
License: X11
 | 
			
		||||
 Permission to use, copy, modify, distribute, and sell this software and
 | 
			
		||||
 its documentation for any purpose is hereby granted without fee, provided
 | 
			
		||||
 that the above copyright notice appear in all copies and fthat both that
 | 
			
		||||
 copyright notice and this permission notice appear in supporting
 | 
			
		||||
 documentation, and that the name of the copyright holders not be used in
 | 
			
		||||
 advertising or publicity pertaining to distribution of the software
 | 
			
		||||
 without specific, written prior permission.  The copyright holders make
 | 
			
		||||
 no representations about the suitability of this software for any
 | 
			
		||||
 purpose.  It is provided "as is" without express or implied warranty.
 | 
			
		||||
 .
 | 
			
		||||
 THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
 | 
			
		||||
 SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
 | 
			
		||||
 FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
 | 
			
		||||
 SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
 | 
			
		||||
 RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
 | 
			
		||||
 CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
 | 
			
		||||
 CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 | 
			
		||||
 | 
			
		||||
Copyright: 2019 Purism SPC
 | 
			
		||||
License: GPL-3+
 | 
			
		||||
 This package is free software; you can redistribute it and/or modify
 | 
			
		||||
 it under the terms of the GNU General Public License as published by
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										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
 | 
			
		||||
							
								
								
									
										0
									
								
								eek/config.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								eek/config.h
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										234
									
								
								eek/eek-container.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										234
									
								
								eek/eek-container.c
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,234 @@
 | 
			
		||||
/* 
 | 
			
		||||
 * Copyright (C) 2010-2011 Daiki Ueno <ueno@unixuser.org>
 | 
			
		||||
 * Copyright (C) 2010-2011 Red Hat, Inc.
 | 
			
		||||
 * 
 | 
			
		||||
 * This library is free software; you can redistribute it and/or
 | 
			
		||||
 * modify it under the terms of the GNU Lesser General Public License
 | 
			
		||||
 * as published by the Free Software Foundation; either version 2 of
 | 
			
		||||
 * the License, or (at your option) any later version.
 | 
			
		||||
 * 
 | 
			
		||||
 * This library is distributed in the hope that it will be useful, but
 | 
			
		||||
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
			
		||||
 * Lesser General Public License for more details.
 | 
			
		||||
 * 
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General Public
 | 
			
		||||
 * License along with this library; if not, write to the Free Software
 | 
			
		||||
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 | 
			
		||||
 * 02110-1301 USA
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * SECTION:eek-container
 | 
			
		||||
 * @short_description: Base class of a keyboard container
 | 
			
		||||
 *
 | 
			
		||||
 * The #EekContainerClass class represents a keyboard container, which
 | 
			
		||||
 * shall be used to implement #EekKeyboard and #EekSection.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_CONFIG_H
 | 
			
		||||
#include "config.h"
 | 
			
		||||
#endif  /* HAVE_CONFIG_H */
 | 
			
		||||
 | 
			
		||||
#include "eek-container.h"
 | 
			
		||||
 | 
			
		||||
enum {
 | 
			
		||||
    CHILD_ADDED,
 | 
			
		||||
    CHILD_REMOVED,
 | 
			
		||||
    LAST_SIGNAL
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static guint signals[LAST_SIGNAL] = { 0, };
 | 
			
		||||
 | 
			
		||||
typedef struct _EekContainerPrivate
 | 
			
		||||
{
 | 
			
		||||
    GList *head;
 | 
			
		||||
    GList *last;
 | 
			
		||||
} EekContainerPrivate;
 | 
			
		||||
 | 
			
		||||
G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (EekContainer, eek_container, EEK_TYPE_ELEMENT)
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
eek_container_real_add_child (EekContainer *self,
 | 
			
		||||
                              EekElement   *child)
 | 
			
		||||
{
 | 
			
		||||
    EekContainerPrivate *priv = eek_container_get_instance_private (self);
 | 
			
		||||
 | 
			
		||||
    g_return_if_fail (EEK_IS_ELEMENT(child));
 | 
			
		||||
    g_object_ref (child);
 | 
			
		||||
 | 
			
		||||
    if (!priv->head) {
 | 
			
		||||
        priv->head = priv->last = g_list_prepend (priv->head, child);
 | 
			
		||||
    } else {
 | 
			
		||||
        priv->last->next = g_list_prepend (priv->last->next, child);
 | 
			
		||||
        priv->last = priv->last->next;
 | 
			
		||||
    }
 | 
			
		||||
    eek_element_set_parent (child, EEK_ELEMENT(self));
 | 
			
		||||
    g_signal_emit (self, signals[CHILD_ADDED], 0, child);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
eek_container_real_remove_child (EekContainer *self,
 | 
			
		||||
                                 EekElement   *child)
 | 
			
		||||
{
 | 
			
		||||
    EekContainerPrivate *priv = eek_container_get_instance_private (self);
 | 
			
		||||
    GList *head;
 | 
			
		||||
 | 
			
		||||
    g_return_if_fail (EEK_IS_ELEMENT(child));
 | 
			
		||||
    head = g_list_find (priv->head, child);
 | 
			
		||||
    g_return_if_fail (head);
 | 
			
		||||
    g_object_unref (child);
 | 
			
		||||
    if (head == priv->last)
 | 
			
		||||
        priv->last = g_list_previous (priv->last);
 | 
			
		||||
    priv->head = g_list_remove_link (priv->head, head);
 | 
			
		||||
    eek_element_set_parent (child, NULL);
 | 
			
		||||
    g_signal_emit (self, signals[CHILD_REMOVED], 0, child);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
eek_container_real_foreach_child (EekContainer *self,
 | 
			
		||||
                                  EekCallback   callback,
 | 
			
		||||
                                  gpointer      user_data)
 | 
			
		||||
{
 | 
			
		||||
    EekContainerPrivate *priv = eek_container_get_instance_private (self);
 | 
			
		||||
    GList *head;
 | 
			
		||||
 | 
			
		||||
    for (head = priv->head; head; head = g_list_next (head))
 | 
			
		||||
        (*callback) (EEK_ELEMENT(head->data), user_data);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static EekElement *
 | 
			
		||||
eek_container_real_find (EekContainer *self,
 | 
			
		||||
                         EekCompareFunc func,
 | 
			
		||||
                         gpointer user_data)
 | 
			
		||||
{
 | 
			
		||||
    EekContainerPrivate *priv = eek_container_get_instance_private (self);
 | 
			
		||||
    GList *head;
 | 
			
		||||
 | 
			
		||||
    head = g_list_find_custom (priv->head, user_data, (GCompareFunc)func);
 | 
			
		||||
    if (head)
 | 
			
		||||
        return head->data;
 | 
			
		||||
    return NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
eek_container_dispose (GObject *object)
 | 
			
		||||
{
 | 
			
		||||
    EekContainer        *self = EEK_CONTAINER (object);
 | 
			
		||||
    EekContainerPrivate *priv = eek_container_get_instance_private (self);
 | 
			
		||||
    GList *head;
 | 
			
		||||
 | 
			
		||||
    for (head = priv->head; head; head = priv->head) {
 | 
			
		||||
        g_object_unref (head->data);
 | 
			
		||||
        priv->head = g_list_next (head);
 | 
			
		||||
        g_list_free1 (head);
 | 
			
		||||
    }
 | 
			
		||||
    G_OBJECT_CLASS(eek_container_parent_class)->dispose (object);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
eek_container_class_init (EekContainerClass *klass)
 | 
			
		||||
{
 | 
			
		||||
    GObjectClass      *gobject_class = G_OBJECT_CLASS (klass);
 | 
			
		||||
 | 
			
		||||
    klass->add_child = eek_container_real_add_child;
 | 
			
		||||
    klass->remove_child = eek_container_real_remove_child;
 | 
			
		||||
    klass->foreach_child = eek_container_real_foreach_child;
 | 
			
		||||
    klass->find = eek_container_real_find;
 | 
			
		||||
 | 
			
		||||
    /* signals */
 | 
			
		||||
    klass->child_added = NULL;
 | 
			
		||||
    klass->child_removed = NULL;
 | 
			
		||||
 | 
			
		||||
    gobject_class->dispose = eek_container_dispose;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * EekContainer::child-added:
 | 
			
		||||
     * @container: an #EekContainer
 | 
			
		||||
     * @element: an #EekElement
 | 
			
		||||
     *
 | 
			
		||||
     * The ::child-added signal is emitted each time an element is
 | 
			
		||||
     * added to @container.
 | 
			
		||||
     */
 | 
			
		||||
    signals[CHILD_ADDED] =
 | 
			
		||||
        g_signal_new (I_("child-added"),
 | 
			
		||||
                      G_TYPE_FROM_CLASS(gobject_class),
 | 
			
		||||
                      G_SIGNAL_RUN_FIRST,
 | 
			
		||||
                      G_STRUCT_OFFSET(EekContainerClass, child_added),
 | 
			
		||||
                      NULL, NULL,
 | 
			
		||||
                      g_cclosure_marshal_VOID__OBJECT,
 | 
			
		||||
                      G_TYPE_NONE, 1,
 | 
			
		||||
                      EEK_TYPE_ELEMENT);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * EekContainer::child-removed:
 | 
			
		||||
     * @container: an #EekContainer
 | 
			
		||||
     * @element: an #EekElement
 | 
			
		||||
     *
 | 
			
		||||
     * The ::child-removed signal is emitted each time an element is
 | 
			
		||||
     * removed from @container.
 | 
			
		||||
     */
 | 
			
		||||
    signals[CHILD_REMOVED] =
 | 
			
		||||
        g_signal_new (I_("child-removed"),
 | 
			
		||||
                      G_TYPE_FROM_CLASS(gobject_class),
 | 
			
		||||
                      G_SIGNAL_RUN_FIRST,
 | 
			
		||||
                      G_STRUCT_OFFSET(EekContainerClass, child_removed),
 | 
			
		||||
                      NULL,
 | 
			
		||||
                      NULL,
 | 
			
		||||
                      g_cclosure_marshal_VOID__OBJECT,
 | 
			
		||||
                      G_TYPE_NONE, 1,
 | 
			
		||||
                      EEK_TYPE_ELEMENT);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
eek_container_init (EekContainer *self)
 | 
			
		||||
{
 | 
			
		||||
    /* void */
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eek_container_foreach_child:
 | 
			
		||||
 * @container: an #EekContainer
 | 
			
		||||
 * @callback: (scope call): an #EekCallback
 | 
			
		||||
 * @user_data: additional data passed to @callback
 | 
			
		||||
 *
 | 
			
		||||
 * Enumerate children of @container and run @callback with each child.
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
eek_container_foreach_child (EekContainer *container,
 | 
			
		||||
                             EekCallback   callback,
 | 
			
		||||
                             gpointer      user_data)
 | 
			
		||||
{
 | 
			
		||||
    g_return_if_fail (EEK_IS_CONTAINER(container));
 | 
			
		||||
    EEK_CONTAINER_GET_CLASS(container)->foreach_child (container,
 | 
			
		||||
                                                       callback,
 | 
			
		||||
                                                       user_data);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eek_container_find:
 | 
			
		||||
 * @container: an #EekContainer
 | 
			
		||||
 * @func: function to be used to compare two children
 | 
			
		||||
 * @user_data: additional data passed to @func
 | 
			
		||||
 *
 | 
			
		||||
 * Find a child which matches the criteria supplied as @func, in @container.
 | 
			
		||||
 * Returns: an #EekElement or NULL on failure
 | 
			
		||||
 */
 | 
			
		||||
EekElement *
 | 
			
		||||
eek_container_find (EekContainer  *container,
 | 
			
		||||
                    EekCompareFunc func,
 | 
			
		||||
                    gpointer       user_data)
 | 
			
		||||
{
 | 
			
		||||
    g_return_val_if_fail (EEK_IS_CONTAINER(container), NULL);
 | 
			
		||||
    return EEK_CONTAINER_GET_CLASS(container)->find (container,
 | 
			
		||||
                                                     func,
 | 
			
		||||
                                                     user_data);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
eek_container_add_child (EekContainer *container, EekElement *element)
 | 
			
		||||
{
 | 
			
		||||
    g_return_if_fail (EEK_IS_CONTAINER(container));
 | 
			
		||||
    g_return_if_fail (EEK_IS_ELEMENT(element));
 | 
			
		||||
    return EEK_CONTAINER_GET_CLASS(container)->add_child (container, element);
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										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 */
 | 
			
		||||
@ -26,28 +26,58 @@
 | 
			
		||||
 * shall be used to implement #EekKeyboard, #EekSection, or #EekKey.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_CONFIG_H
 | 
			
		||||
#include "config.h"
 | 
			
		||||
#endif  /* HAVE_CONFIG_H */
 | 
			
		||||
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
#include "eek-element.h"
 | 
			
		||||
#include "eek-container.h"
 | 
			
		||||
#include "eek-marshalers.h"
 | 
			
		||||
 | 
			
		||||
enum {
 | 
			
		||||
    PROP_0,
 | 
			
		||||
    PROP_NAME,
 | 
			
		||||
    PROP_BOUNDS,
 | 
			
		||||
    PROP_GROUP,
 | 
			
		||||
    PROP_LEVEL,
 | 
			
		||||
    PROP_LAST
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
enum {
 | 
			
		||||
    SYMBOL_INDEX_CHANGED,
 | 
			
		||||
    LAST_SIGNAL
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static guint signals[LAST_SIGNAL] = { 0, };
 | 
			
		||||
 | 
			
		||||
typedef struct _EekElementPrivate
 | 
			
		||||
{
 | 
			
		||||
    gchar *name;
 | 
			
		||||
    EekBounds bounds;
 | 
			
		||||
    EekElement *parent;
 | 
			
		||||
    gint group;
 | 
			
		||||
    gint level;
 | 
			
		||||
} EekElementPrivate;
 | 
			
		||||
 | 
			
		||||
G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (EekElement, eek_element, G_TYPE_OBJECT)
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
eek_element_real_symbol_index_changed (EekElement *self,
 | 
			
		||||
                                       gint        group,
 | 
			
		||||
                                       gint        level)
 | 
			
		||||
{
 | 
			
		||||
    // g_debug ("symbol-index-changed");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
eek_element_finalize (GObject *object)
 | 
			
		||||
{
 | 
			
		||||
    EekElement        *self = EEK_ELEMENT (object);
 | 
			
		||||
    EekElementPrivate *priv = eek_element_get_instance_private (self);
 | 
			
		||||
 | 
			
		||||
    g_free (priv->name);
 | 
			
		||||
    G_OBJECT_CLASS (eek_element_parent_class)->finalize (object);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -60,9 +90,18 @@ eek_element_set_property (GObject      *object,
 | 
			
		||||
    EekElement *element = EEK_ELEMENT(object);
 | 
			
		||||
 | 
			
		||||
    switch (prop_id) {
 | 
			
		||||
    case PROP_NAME:
 | 
			
		||||
        eek_element_set_name (element,
 | 
			
		||||
                              g_value_dup_string (value));
 | 
			
		||||
        break;
 | 
			
		||||
    case PROP_BOUNDS:
 | 
			
		||||
        eek_element_set_bounds (element, g_value_get_boxed (value));
 | 
			
		||||
        break;
 | 
			
		||||
    case PROP_GROUP:
 | 
			
		||||
        eek_element_set_group (element, g_value_get_int (value));
 | 
			
		||||
        break;
 | 
			
		||||
    case PROP_LEVEL:
 | 
			
		||||
        eek_element_set_level (element, g_value_get_int (value));
 | 
			
		||||
    default:
 | 
			
		||||
        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 | 
			
		||||
        break;
 | 
			
		||||
@ -79,10 +118,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 +144,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 +177,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 +362,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 */
 | 
			
		||||
 | 
			
		||||
@ -23,7 +23,9 @@
 | 
			
		||||
 * @short_description: a #GtkWidget displaying #EekKeyboard
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_CONFIG_H
 | 
			
		||||
#include "config.h"
 | 
			
		||||
#endif  /* HAVE_CONFIG_H */
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_LIBCANBERRA
 | 
			
		||||
#include <canberra-gtk.h>
 | 
			
		||||
@ -32,13 +34,16 @@
 | 
			
		||||
#include <math.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
#include "eek-renderer.h"
 | 
			
		||||
#include "eek-keyboard.h"
 | 
			
		||||
 | 
			
		||||
#include "eek-gtk-keyboard.h"
 | 
			
		||||
#include "eek-gtk-renderer.h"
 | 
			
		||||
#include "eek-keyboard.h"
 | 
			
		||||
#include "eek-section.h"
 | 
			
		||||
#include "eek-key.h"
 | 
			
		||||
#include "eek-symbol.h"
 | 
			
		||||
 | 
			
		||||
enum {
 | 
			
		||||
    PROP_0,
 | 
			
		||||
    PROP_KEYBOARD,
 | 
			
		||||
    PROP_LAST
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
@ -51,23 +56,37 @@ enum {
 | 
			
		||||
typedef struct _EekGtkKeyboardPrivate
 | 
			
		||||
{
 | 
			
		||||
    EekRenderer *renderer;
 | 
			
		||||
    LevelKeyboard *keyboard;
 | 
			
		||||
    EekKeyboard *keyboard;
 | 
			
		||||
    gulong key_locked_handler;
 | 
			
		||||
    gulong key_unlocked_handler;
 | 
			
		||||
    gulong symbol_index_changed_handler;
 | 
			
		||||
    EekTheme *theme;
 | 
			
		||||
 | 
			
		||||
    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       on_key_locked          (EekKeyboard *keyboard,
 | 
			
		||||
                                           EekKey      *key,
 | 
			
		||||
                                           gpointer     user_data);
 | 
			
		||||
static void       on_key_unlocked         (EekKeyboard *keyboard,
 | 
			
		||||
                                           EekKey      *key,
 | 
			
		||||
                                           gpointer     user_data);
 | 
			
		||||
static void       on_symbol_index_changed (EekKeyboard *keyboard,
 | 
			
		||||
                                           gint         group,
 | 
			
		||||
                                           gint         level,
 | 
			
		||||
                                           gpointer     user_data);
 | 
			
		||||
static void       render_pressed_key      (GtkWidget   *widget,
 | 
			
		||||
                                           EekKey      *key);
 | 
			
		||||
static void       render_locked_key       (GtkWidget   *widget,
 | 
			
		||||
                                           EekKey      *key);
 | 
			
		||||
static void       render_released_key     (GtkWidget   *widget,
 | 
			
		||||
                                           EekKey      *key);
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
eek_gtk_keyboard_real_realize (GtkWidget      *self)
 | 
			
		||||
@ -78,8 +97,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,43 +109,38 @@ 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);
 | 
			
		||||
        PangoContext *pcontext;
 | 
			
		||||
 | 
			
		||||
        priv->renderer = eek_renderer_new (priv->keyboard, pcontext);
 | 
			
		||||
        pcontext = gtk_widget_get_pango_context (self);
 | 
			
		||||
        priv->renderer = eek_gtk_renderer_new (priv->keyboard, pcontext, self);
 | 
			
		||||
        if (priv->theme)
 | 
			
		||||
            eek_renderer_set_theme (priv->renderer, priv->theme);
 | 
			
		||||
 | 
			
		||||
        eek_renderer_set_allocation_size (priv->renderer,
 | 
			
		||||
                                          allocation.width,
 | 
			
		||||
                                          allocation.height);
 | 
			
		||||
        eek_renderer_set_scale_factor (priv->renderer,
 | 
			
		||||
                                       gtk_widget_get_scale_factor (self));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    eek_renderer_render_keyboard (priv->renderer, cr);
 | 
			
		||||
 | 
			
		||||
    struct squeek_view *view = 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;
 | 
			
		||||
}
 | 
			
		||||
@ -149,85 +162,50 @@ eek_gtk_keyboard_real_size_allocate (GtkWidget     *self,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void depress(EekGtkKeyboard *self,
 | 
			
		||||
                    gdouble x, gdouble y, guint32 time)
 | 
			
		||||
{
 | 
			
		||||
                    gdouble x, gdouble y, guint32 time) {
 | 
			
		||||
    EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (self);
 | 
			
		||||
    struct squeek_view *view = level_keyboard_current(priv->keyboard);
 | 
			
		||||
    struct squeek_button *button = eek_renderer_find_button_by_position (priv->renderer, view, x, y);
 | 
			
		||||
 | 
			
		||||
    if (button) {
 | 
			
		||||
        eek_keyboard_press_key(
 | 
			
		||||
            priv->keyboard,
 | 
			
		||||
            squeek_button_get_key(button),
 | 
			
		||||
            time
 | 
			
		||||
        );
 | 
			
		||||
        on_button_pressed(button, view, self);
 | 
			
		||||
    EekKey *key = eek_renderer_find_key_by_position (priv->renderer, x, y);
 | 
			
		||||
    if (key) {
 | 
			
		||||
        eek_keyboard_press_key(priv->keyboard, key, time);
 | 
			
		||||
        on_key_pressed(key, self);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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);
 | 
			
		||||
    GList *list, *head;
 | 
			
		||||
    EekKey *key = eek_renderer_find_key_by_position (priv->renderer, x, y);
 | 
			
		||||
 | 
			
		||||
    list = g_list_copy(priv->keyboard->pressed_keys);
 | 
			
		||||
 | 
			
		||||
    if (button) {
 | 
			
		||||
    if (key) {
 | 
			
		||||
        GList *list, *head;
 | 
			
		||||
        gboolean found = FALSE;
 | 
			
		||||
 | 
			
		||||
        list = eek_keyboard_get_pressed_keys (priv->keyboard);
 | 
			
		||||
        for (head = list; head; head = g_list_next (head)) {
 | 
			
		||||
            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);
 | 
			
		||||
            else {
 | 
			
		||||
                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);
 | 
			
		||||
        }
 | 
			
		||||
        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 +250,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 +282,80 @@ 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);
 | 
			
		||||
    priv->keyboard = g_object_ref (keyboard);
 | 
			
		||||
 | 
			
		||||
    priv->key_locked_handler =
 | 
			
		||||
        g_signal_connect (priv->keyboard, "key-locked",
 | 
			
		||||
                          G_CALLBACK(on_key_locked), self);
 | 
			
		||||
    priv->key_unlocked_handler =
 | 
			
		||||
        g_signal_connect (priv->keyboard, "key-unlocked",
 | 
			
		||||
                          G_CALLBACK(on_key_unlocked), self);
 | 
			
		||||
    priv->symbol_index_changed_handler =
 | 
			
		||||
        g_signal_connect (priv->keyboard, "symbol-index-changed",
 | 
			
		||||
                          G_CALLBACK(on_symbol_index_changed), self);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
eek_gtk_keyboard_set_property (GObject      *object,
 | 
			
		||||
                               guint         prop_id,
 | 
			
		||||
                               const GValue *value,
 | 
			
		||||
                               GParamSpec   *pspec)
 | 
			
		||||
{
 | 
			
		||||
    EekKeyboard *keyboard;
 | 
			
		||||
 | 
			
		||||
    switch (prop_id) {
 | 
			
		||||
    case PROP_KEYBOARD:
 | 
			
		||||
        keyboard = g_value_get_object (value);
 | 
			
		||||
        eek_gtk_keyboard_set_keyboard (EEK_GTK_KEYBOARD(object), keyboard);
 | 
			
		||||
        break;
 | 
			
		||||
    default:
 | 
			
		||||
        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 | 
			
		||||
        break;
 | 
			
		||||
@ -340,20 +371,40 @@ 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;
 | 
			
		||||
        if (g_signal_handler_is_connected (priv->keyboard,
 | 
			
		||||
                                           priv->key_locked_handler))
 | 
			
		||||
            g_signal_handler_disconnect (priv->keyboard,
 | 
			
		||||
                                         priv->key_locked_handler);
 | 
			
		||||
        if (g_signal_handler_is_connected (priv->keyboard,
 | 
			
		||||
                                           priv->key_unlocked_handler))
 | 
			
		||||
            g_signal_handler_disconnect (priv->keyboard,
 | 
			
		||||
                                         priv->key_unlocked_handler);
 | 
			
		||||
        if (g_signal_handler_is_connected (priv->keyboard,
 | 
			
		||||
                                           priv->symbol_index_changed_handler))
 | 
			
		||||
            g_signal_handler_disconnect (priv->keyboard,
 | 
			
		||||
                                         priv->symbol_index_changed_handler);
 | 
			
		||||
 | 
			
		||||
        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));
 | 
			
		||||
        GList *list, *head;
 | 
			
		||||
 | 
			
		||||
        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;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (priv->theme) {
 | 
			
		||||
        g_object_unref (priv->theme);
 | 
			
		||||
        priv->theme = NULL;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    G_OBJECT_CLASS (eek_gtk_keyboard_parent_class)->dispose (object);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -362,6 +413,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 +425,28 @@ 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)
 | 
			
		||||
{}
 | 
			
		||||
{
 | 
			
		||||
    /* void */
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eek_gtk_keyboard_new:
 | 
			
		||||
@ -391,78 +456,180 @@ 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)
 | 
			
		||||
{
 | 
			
		||||
    EekGtkKeyboard        *self = EEK_GTK_KEYBOARD (widget);
 | 
			
		||||
    EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (self);
 | 
			
		||||
    GtkAllocation allocation;
 | 
			
		||||
    gdouble x, y;
 | 
			
		||||
 | 
			
		||||
    GdkWindow         *window  = gtk_widget_get_window (widget);
 | 
			
		||||
    cairo_region_t    *region  = gdk_window_get_clip_region (window);
 | 
			
		||||
    GdkDrawingContext *context = gdk_window_begin_draw_frame (window, region);
 | 
			
		||||
    cairo_t           *cr      = gdk_drawing_context_get_cairo_context (context);
 | 
			
		||||
    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);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
    eek_renderer_render_button (priv->renderer, cr, place, 1.0, TRUE);
 | 
			
		||||
/*
 | 
			
		||||
 * Alleviate the asymmetry between drawing a pressed key and a released key,
 | 
			
		||||
 * and consistently draw to the exact same area.
 | 
			
		||||
 *
 | 
			
		||||
 * By saving the dirty rectangle we can limit drawing of the backbuffer to
 | 
			
		||||
 * the screen as well, eg gdk_window_invalidate_rect() instead of
 | 
			
		||||
 * gtk_widget_queue_draw() which redraws the entire widget.
 | 
			
		||||
 *
 | 
			
		||||
 * b1 is mandatory, b2 is optional
 | 
			
		||||
 */
 | 
			
		||||
static GdkRectangle
 | 
			
		||||
clip_bounds_to_dirty_rectangle (cairo_t *cr, EekBounds *b1, EekBounds *b2)
 | 
			
		||||
{
 | 
			
		||||
    if (b2)
 | 
			
		||||
        cairo_rectangle (cr, b2->x, b2->y, b2->width, b2->height);
 | 
			
		||||
 | 
			
		||||
    cairo_rectangle (cr, b1->x, b1->y, b1->width, b1->height);
 | 
			
		||||
    cairo_clip (cr);
 | 
			
		||||
 | 
			
		||||
    /*
 | 
			
		||||
     * save the clipped region to a bounding box so we can limit
 | 
			
		||||
     * the drawing of the backbuffer to the screen to the same area
 | 
			
		||||
     */
 | 
			
		||||
    cairo_rectangle_t bbox;
 | 
			
		||||
 | 
			
		||||
    cairo_clip_extents (cr, &bbox.x, &bbox.y, &bbox.width, &bbox.height);
 | 
			
		||||
 | 
			
		||||
    /* convert double to int, making sure r strictly covers bbox to avoid
 | 
			
		||||
     * artefacts. floor() is unnecessary, ceil() is not */
 | 
			
		||||
    GdkRectangle r = {
 | 
			
		||||
        floor (bbox.x),
 | 
			
		||||
        floor (bbox.y),
 | 
			
		||||
        ceil  (bbox.width),
 | 
			
		||||
        ceil  (bbox.height)
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    return r;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
render_pressed_key (GtkWidget *widget,
 | 
			
		||||
                    EekKey    *key)
 | 
			
		||||
{
 | 
			
		||||
    EekGtkKeyboard        *self = EEK_GTK_KEYBOARD (widget);
 | 
			
		||||
    EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (self);
 | 
			
		||||
    EekBounds bounds, large_bounds;
 | 
			
		||||
 | 
			
		||||
    GdkWindow         *window  = gtk_widget_get_window (widget);
 | 
			
		||||
    cairo_region_t    *region  = gdk_window_get_clip_region (window);
 | 
			
		||||
    GdkDrawingContext *context = gdk_window_begin_draw_frame (window, region);
 | 
			
		||||
    cairo_t           *cr      = gdk_drawing_context_get_cairo_context (context);
 | 
			
		||||
 | 
			
		||||
    eek_renderer_get_key_bounds (priv->renderer, key, &bounds, TRUE);
 | 
			
		||||
    magnify_bounds (widget, &bounds, &large_bounds, 1.5);
 | 
			
		||||
 | 
			
		||||
    /*
 | 
			
		||||
     * clip to limit drawing to backbuffer and save clip region to dirty_rect
 | 
			
		||||
     * to limit redrawing of the backbuffer to the same area
 | 
			
		||||
     */
 | 
			
		||||
    GdkRectangle dirty_rect = clip_bounds_to_dirty_rectangle (cr, &bounds, &large_bounds);
 | 
			
		||||
 | 
			
		||||
    cairo_save (cr);
 | 
			
		||||
    cairo_translate (cr, bounds.x, bounds.y);
 | 
			
		||||
    eek_renderer_render_key (priv->renderer, cr, key, 1.0, TRUE);
 | 
			
		||||
    cairo_restore (cr);
 | 
			
		||||
 | 
			
		||||
    cairo_save (cr);
 | 
			
		||||
    cairo_translate (cr, large_bounds.x, large_bounds.y);
 | 
			
		||||
    eek_renderer_render_key (priv->renderer, cr, key, 1.5, TRUE);
 | 
			
		||||
*/
 | 
			
		||||
    cairo_restore (cr);
 | 
			
		||||
 | 
			
		||||
    gdk_window_end_draw_frame (window, context);
 | 
			
		||||
 | 
			
		||||
    cairo_region_destroy (region);
 | 
			
		||||
 | 
			
		||||
    /* force immediate drawing of the backbuffer to the screen */
 | 
			
		||||
    gdk_window_invalidate_rect (window, &dirty_rect, FALSE);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
render_locked_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);
 | 
			
		||||
    EekBounds bounds;
 | 
			
		||||
 | 
			
		||||
    GdkWindow         *window  = gtk_widget_get_window (widget);
 | 
			
		||||
    cairo_region_t    *region  = gdk_window_get_clip_region (window);
 | 
			
		||||
    GdkDrawingContext *context = gdk_window_begin_draw_frame (window, region);
 | 
			
		||||
    cairo_t           *cr      = gdk_drawing_context_get_cairo_context (context);
 | 
			
		||||
 | 
			
		||||
    eek_renderer_render_button (priv->renderer, cr, place, 1.0, TRUE);
 | 
			
		||||
    eek_renderer_get_key_bounds (priv->renderer, key, &bounds, TRUE);
 | 
			
		||||
 | 
			
		||||
    /*
 | 
			
		||||
     * clip to limit drawing to backbuffer and save clip region to dirty_rect
 | 
			
		||||
     * to limit redrawing of the backbuffer to the same area
 | 
			
		||||
     */
 | 
			
		||||
    GdkRectangle dirty_rect = clip_bounds_to_dirty_rectangle (cr, &bounds, NULL);
 | 
			
		||||
 | 
			
		||||
    cairo_translate (cr, bounds.x, bounds.y);
 | 
			
		||||
    eek_renderer_render_key (priv->renderer, cr, key, 1.0, TRUE);
 | 
			
		||||
 | 
			
		||||
    gdk_window_end_draw_frame (window, context);
 | 
			
		||||
 | 
			
		||||
    cairo_region_destroy (region);
 | 
			
		||||
 | 
			
		||||
    /* force immediate drawing of the backbuffer to the screen */
 | 
			
		||||
    gdk_window_invalidate_rect (window, &dirty_rect, FALSE);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 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);
 | 
			
		||||
    EekBounds bounds, large_bounds;
 | 
			
		||||
 | 
			
		||||
    GdkWindow         *window  = gtk_widget_get_window (widget);
 | 
			
		||||
    cairo_region_t    *region  = gdk_window_get_clip_region (window);
 | 
			
		||||
    GdkDrawingContext *context = gdk_window_begin_draw_frame (window, region);
 | 
			
		||||
    cairo_t           *cr      = gdk_drawing_context_get_cairo_context (context);
 | 
			
		||||
 | 
			
		||||
    eek_renderer_get_key_bounds (priv->renderer, key, &bounds, TRUE);
 | 
			
		||||
    magnify_bounds (widget, &bounds, &large_bounds, 1.5);
 | 
			
		||||
 | 
			
		||||
    /*
 | 
			
		||||
     * clip to limit drawing to backbuffer and save clip region to dirty_rect
 | 
			
		||||
     * to limit redrawing of the backbuffer to the same area
 | 
			
		||||
     */
 | 
			
		||||
    GdkRectangle dirty_rect = clip_bounds_to_dirty_rectangle(cr, &bounds, &large_bounds);
 | 
			
		||||
 | 
			
		||||
    eek_renderer_render_keyboard (priv->renderer, cr);
 | 
			
		||||
 | 
			
		||||
    gdk_window_end_draw_frame (window, context);
 | 
			
		||||
 | 
			
		||||
    cairo_region_destroy (region);
 | 
			
		||||
 | 
			
		||||
    /* force immediate drawing of the backbuffer to the screen */
 | 
			
		||||
    gdk_window_invalidate_rect (window, &dirty_rect, FALSE);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
on_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,15 +637,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);
 | 
			
		||||
    gtk_widget_queue_draw (GTK_WIDGET(self));
 | 
			
		||||
    render_pressed_key (GTK_WIDGET(self), key);
 | 
			
		||||
 | 
			
		||||
#if HAVE_LIBCANBERRA
 | 
			
		||||
    ca_gtk_play_for_widget (widget, 0,
 | 
			
		||||
@ -490,19 +649,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);
 | 
			
		||||
    gtk_widget_queue_draw (GTK_WIDGET(self));
 | 
			
		||||
    render_released_key (GTK_WIDGET(self), key);
 | 
			
		||||
 | 
			
		||||
#if HAVE_LIBCANBERRA
 | 
			
		||||
    ca_gtk_play_for_widget (widget, 0,
 | 
			
		||||
@ -512,3 +668,55 @@ on_button_released (const struct squeek_button *button,
 | 
			
		||||
                            NULL);
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
on_key_locked (EekKeyboard *keyboard,
 | 
			
		||||
               EekKey      *key,
 | 
			
		||||
               gpointer     user_data)
 | 
			
		||||
{
 | 
			
		||||
    GtkWidget *widget = user_data;
 | 
			
		||||
    EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (user_data);
 | 
			
		||||
 | 
			
		||||
    /* renderer may have not been set yet if the widget is a popup */
 | 
			
		||||
    if (!priv->renderer)
 | 
			
		||||
        return;
 | 
			
		||||
 | 
			
		||||
    render_locked_key (widget, key);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
on_key_unlocked (EekKeyboard *keyboard,
 | 
			
		||||
                 EekKey      *key,
 | 
			
		||||
                 gpointer     user_data)
 | 
			
		||||
{
 | 
			
		||||
    GtkWidget *widget = user_data;
 | 
			
		||||
    EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (user_data);
 | 
			
		||||
 | 
			
		||||
    /* renderer may have not been set yet if the widget is a popup */
 | 
			
		||||
    if (!priv->renderer)
 | 
			
		||||
        return;
 | 
			
		||||
 | 
			
		||||
    render_released_key (widget, key);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
on_symbol_index_changed (EekKeyboard *keyboard,
 | 
			
		||||
                         gint         group,
 | 
			
		||||
                         gint         level,
 | 
			
		||||
                         gpointer     user_data)
 | 
			
		||||
{
 | 
			
		||||
    GtkWidget *widget = user_data;
 | 
			
		||||
 | 
			
		||||
    gtk_widget_queue_draw (widget);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
eek_gtk_keyboard_set_theme (EekGtkKeyboard *keyboard,
 | 
			
		||||
                            EekTheme       *theme)
 | 
			
		||||
{
 | 
			
		||||
    g_return_if_fail (EEK_IS_GTK_KEYBOARD(keyboard));
 | 
			
		||||
    g_return_if_fail (EEK_IS_THEME(theme));
 | 
			
		||||
 | 
			
		||||
    EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (keyboard);
 | 
			
		||||
    priv->theme = g_object_ref (theme);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -45,7 +45,9 @@ 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);
 | 
			
		||||
void       eek_gtk_keyboard_set_theme (EekGtkKeyboard *keyboard,
 | 
			
		||||
                                       EekTheme       *theme);
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
#endif  /* EEK_GTK_KEYBOARD_H */
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										104
									
								
								eek/eek-gtk-renderer.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										104
									
								
								eek/eek-gtk-renderer.c
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,104 @@
 | 
			
		||||
/* 
 | 
			
		||||
 * Copyright (C) 2011 Daiki Ueno <ueno@unixuser.org>
 | 
			
		||||
 * Copyright (C) 2011 Red Hat, Inc.
 | 
			
		||||
 * 
 | 
			
		||||
 * This library is free software; you can redistribute it and/or
 | 
			
		||||
 * modify it under the terms of the GNU Lesser General Public License
 | 
			
		||||
 * as published by the Free Software Foundation; either version 2 of
 | 
			
		||||
 * the License, or (at your option) any later version.
 | 
			
		||||
 * 
 | 
			
		||||
 * This library is distributed in the hope that it will be useful, but
 | 
			
		||||
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
			
		||||
 * Lesser General Public License for more details.
 | 
			
		||||
 * 
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General Public
 | 
			
		||||
 * License along with this library; if not, write to the Free Software
 | 
			
		||||
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 | 
			
		||||
 * 02110-1301 USA
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_CONFIG_H
 | 
			
		||||
#include "config.h"
 | 
			
		||||
#endif  /* HAVE_CONFIG_H */
 | 
			
		||||
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <gdk-pixbuf/gdk-pixbuf.h>
 | 
			
		||||
 | 
			
		||||
#include "eek-gtk-renderer.h"
 | 
			
		||||
#include "eek-key.h"
 | 
			
		||||
 | 
			
		||||
G_DEFINE_TYPE (EekGtkRenderer, eek_gtk_renderer, EEK_TYPE_RENDERER);
 | 
			
		||||
 | 
			
		||||
static cairo_surface_t *
 | 
			
		||||
pixbuf_to_cairo_surface (GdkPixbuf *pixbuf)
 | 
			
		||||
{
 | 
			
		||||
  cairo_surface_t *dummy_surface;
 | 
			
		||||
  cairo_pattern_t *pattern;
 | 
			
		||||
  cairo_surface_t *surface;
 | 
			
		||||
  cairo_t *cr;
 | 
			
		||||
 | 
			
		||||
  dummy_surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 1, 1);
 | 
			
		||||
 | 
			
		||||
  cr = cairo_create (dummy_surface);
 | 
			
		||||
  gdk_cairo_set_source_pixbuf (cr, pixbuf, 0, 0);
 | 
			
		||||
  pattern = cairo_get_source (cr);
 | 
			
		||||
  cairo_pattern_get_surface (pattern, &surface);
 | 
			
		||||
  cairo_surface_reference (surface);
 | 
			
		||||
  cairo_destroy (cr);
 | 
			
		||||
  cairo_surface_destroy (dummy_surface);
 | 
			
		||||
 | 
			
		||||
  return surface;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static cairo_surface_t *
 | 
			
		||||
eek_gtk_renderer_real_get_icon_surface (EekRenderer *self,
 | 
			
		||||
                                        const gchar *icon_name,
 | 
			
		||||
                                        gint size)
 | 
			
		||||
{
 | 
			
		||||
    GdkPixbuf *pixbuf;
 | 
			
		||||
    GError *error;
 | 
			
		||||
    cairo_surface_t *surface;
 | 
			
		||||
 | 
			
		||||
    error = NULL;
 | 
			
		||||
    pixbuf = gtk_icon_theme_load_icon (gtk_icon_theme_get_default (),
 | 
			
		||||
                                       icon_name,
 | 
			
		||||
                                       size,
 | 
			
		||||
                                       0,
 | 
			
		||||
                                       &error);
 | 
			
		||||
    if (pixbuf == NULL) {
 | 
			
		||||
        g_warning ("can't get icon pixbuf for %s: %s",
 | 
			
		||||
                   icon_name,
 | 
			
		||||
                   error->message);
 | 
			
		||||
        g_error_free (error);
 | 
			
		||||
        return NULL;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    surface = pixbuf_to_cairo_surface (pixbuf);
 | 
			
		||||
    g_object_unref (pixbuf);
 | 
			
		||||
    return surface;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
eek_gtk_renderer_class_init (EekGtkRendererClass *klass)
 | 
			
		||||
{
 | 
			
		||||
    EekRendererClass *renderer_class = EEK_RENDERER_CLASS (klass);
 | 
			
		||||
 | 
			
		||||
    renderer_class->get_icon_surface = eek_gtk_renderer_real_get_icon_surface;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
eek_gtk_renderer_init (EekGtkRenderer *self)
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
EekRenderer *
 | 
			
		||||
eek_gtk_renderer_new (EekKeyboard  *keyboard,
 | 
			
		||||
                      PangoContext *pcontext,
 | 
			
		||||
                      GtkWidget    *widget)
 | 
			
		||||
{
 | 
			
		||||
    return g_object_new (EEK_TYPE_GTK_RENDERER,
 | 
			
		||||
                         "keyboard", keyboard,
 | 
			
		||||
                         "pango-context", pcontext,
 | 
			
		||||
                         NULL);
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										61
									
								
								eek/eek-gtk-renderer.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										61
									
								
								eek/eek-gtk-renderer.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,61 @@
 | 
			
		||||
/* 
 | 
			
		||||
 * Copyright (C) 2010-2011 Daiki Ueno <ueno@unixuser.org>
 | 
			
		||||
 * Copyright (C) 2010-2011 Red Hat, Inc.
 | 
			
		||||
 * 
 | 
			
		||||
 * This library is free software; you can redistribute it and/or
 | 
			
		||||
 * modify it under the terms of the GNU Lesser General Public License
 | 
			
		||||
 * as published by the Free Software Foundation; either version 2 of
 | 
			
		||||
 * the License, or (at your option) any later version.
 | 
			
		||||
 * 
 | 
			
		||||
 * This library is distributed in the hope that it will be useful, but
 | 
			
		||||
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
			
		||||
 * Lesser General Public License for more details.
 | 
			
		||||
 * 
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General Public
 | 
			
		||||
 * License along with this library; if not, write to the Free Software
 | 
			
		||||
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 | 
			
		||||
 * 02110-1301 USA
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef EEK_GTK_RENDERER_H
 | 
			
		||||
#define EEK_GTK_RENDERER_H 1
 | 
			
		||||
 | 
			
		||||
#include <gtk/gtk.h>
 | 
			
		||||
#include "eek-renderer.h"
 | 
			
		||||
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
#define EEK_TYPE_GTK_RENDERER (eek_gtk_renderer_get_type())
 | 
			
		||||
#define EEK_GTK_RENDERER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EEK_TYPE_GTK_RENDERER, EekGtkRenderer))
 | 
			
		||||
#define EEK_GTK_RENDERER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EEK_TYPE_GTK_RENDERER, EekGtkRendererClass))
 | 
			
		||||
#define EEK_IS_GTK_RENDERER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EEK_TYPE_GTK_RENDERER))
 | 
			
		||||
#define EEK_IS_GTK_RENDERER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EEK_TYPE_GTK_RENDERER))
 | 
			
		||||
#define EEK_GTK_RENDERER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EEK_TYPE_GTK_RENDERER, EekGtkRendererClass))
 | 
			
		||||
 | 
			
		||||
typedef struct _EekGtkRenderer EekGtkRenderer;
 | 
			
		||||
typedef struct _EekGtkRendererClass EekGtkRendererClass;
 | 
			
		||||
typedef struct _EekGtkRendererPrivate EekGtkRendererPrivate;
 | 
			
		||||
 | 
			
		||||
struct _EekGtkRenderer {
 | 
			
		||||
    EekRenderer parent;
 | 
			
		||||
 | 
			
		||||
    EekGtkRendererPrivate *priv;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct _EekGtkRendererClass
 | 
			
		||||
{
 | 
			
		||||
    EekRendererClass parent_class;
 | 
			
		||||
 | 
			
		||||
    /*< private >*/
 | 
			
		||||
    /* padding */
 | 
			
		||||
    gpointer pdummy[24];
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
GType        eek_gtk_renderer_get_type (void) G_GNUC_CONST;
 | 
			
		||||
EekRenderer *eek_gtk_renderer_new      (EekKeyboard  *keyboard,
 | 
			
		||||
                                        PangoContext *pcontext,
 | 
			
		||||
                                        GtkWidget *widget);
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
#endif  /* EEK_GTK_RENDERER_H */
 | 
			
		||||
							
								
								
									
										613
									
								
								eek/eek-key.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										613
									
								
								eek/eek-key.c
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,613 @@
 | 
			
		||||
/* 
 | 
			
		||||
 * Copyright (C) 2010-2011 Daiki Ueno <ueno@unixuser.org>
 | 
			
		||||
 * Copyright (C) 2010-2011 Red Hat, Inc.
 | 
			
		||||
 * 
 | 
			
		||||
 * This library is free software; you can redistribute it and/or
 | 
			
		||||
 * modify it under the terms of the GNU Lesser General Public License
 | 
			
		||||
 * as published by the Free Software Foundation; either version 2 of
 | 
			
		||||
 * the License, or (at your option) any later version.
 | 
			
		||||
 * 
 | 
			
		||||
 * This library is distributed in the hope that it will be useful, but
 | 
			
		||||
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
			
		||||
 * Lesser General Public License for more details.
 | 
			
		||||
 * 
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General Public
 | 
			
		||||
 * License along with this library; if not, write to the Free Software
 | 
			
		||||
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 | 
			
		||||
 * 02110-1301 USA
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * SECTION:eek-key
 | 
			
		||||
 * @short_description: Base class of a key
 | 
			
		||||
 *
 | 
			
		||||
 * The #EekKeyClass class represents a key.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_CONFIG_H
 | 
			
		||||
#include "config.h"
 | 
			
		||||
#endif  /* HAVE_CONFIG_H */
 | 
			
		||||
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
#include "eek-key.h"
 | 
			
		||||
#include "eek-section.h"
 | 
			
		||||
#include "eek-keyboard.h"
 | 
			
		||||
#include "eek-symbol.h"
 | 
			
		||||
 | 
			
		||||
enum {
 | 
			
		||||
    PROP_0,
 | 
			
		||||
    PROP_KEYCODE,
 | 
			
		||||
    PROP_SYMBOL_MATRIX,
 | 
			
		||||
    PROP_COLUMN,
 | 
			
		||||
    PROP_ROW,
 | 
			
		||||
    PROP_OREF,
 | 
			
		||||
    PROP_LAST
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
enum {
 | 
			
		||||
    LOCKED,
 | 
			
		||||
    UNLOCKED,
 | 
			
		||||
    LAST_SIGNAL
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static guint signals[LAST_SIGNAL] = { 0, };
 | 
			
		||||
 | 
			
		||||
typedef struct _EekKeyPrivate
 | 
			
		||||
{
 | 
			
		||||
    guint keycode;
 | 
			
		||||
    EekSymbolMatrix *symbol_matrix;
 | 
			
		||||
    gint column;
 | 
			
		||||
    gint row;
 | 
			
		||||
    gulong oref; // UI outline reference
 | 
			
		||||
    gboolean is_pressed;
 | 
			
		||||
    gboolean is_locked;
 | 
			
		||||
} EekKeyPrivate;
 | 
			
		||||
 | 
			
		||||
G_DEFINE_TYPE_WITH_PRIVATE (EekKey, eek_key, EEK_TYPE_ELEMENT)
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
eek_key_real_locked (EekKey *self)
 | 
			
		||||
{
 | 
			
		||||
    EekKeyPrivate *priv = eek_key_get_instance_private (self);
 | 
			
		||||
 | 
			
		||||
    priv->is_locked = TRUE;
 | 
			
		||||
#if DEBUG
 | 
			
		||||
    g_debug ("locked %X", eek_key_get_keycode (self));
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
eek_key_real_unlocked (EekKey *self)
 | 
			
		||||
{
 | 
			
		||||
    EekKeyPrivate *priv = eek_key_get_instance_private (self);
 | 
			
		||||
 | 
			
		||||
    priv->is_locked = FALSE;
 | 
			
		||||
#if DEBUG
 | 
			
		||||
    g_debug ("unlocked %X", eek_key_get_keycode (self));
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
eek_key_finalize (GObject *object)
 | 
			
		||||
{
 | 
			
		||||
    EekKey        *self = EEK_KEY (object);
 | 
			
		||||
    EekKeyPrivate *priv = eek_key_get_instance_private (self);
 | 
			
		||||
 | 
			
		||||
    eek_symbol_matrix_free (priv->symbol_matrix);
 | 
			
		||||
 | 
			
		||||
    G_OBJECT_CLASS (eek_key_parent_class)->finalize (object);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
eek_key_set_property (GObject      *object,
 | 
			
		||||
                      guint         prop_id,
 | 
			
		||||
                      const GValue *value,
 | 
			
		||||
                      GParamSpec   *pspec)
 | 
			
		||||
{
 | 
			
		||||
    EekSymbolMatrix *matrix;
 | 
			
		||||
    gint column, row;
 | 
			
		||||
 | 
			
		||||
    switch (prop_id) {
 | 
			
		||||
    case PROP_KEYCODE:
 | 
			
		||||
        eek_key_set_keycode (EEK_KEY(object), g_value_get_uint (value));
 | 
			
		||||
        break;
 | 
			
		||||
    case PROP_SYMBOL_MATRIX:
 | 
			
		||||
        matrix = g_value_get_boxed (value);
 | 
			
		||||
        eek_key_set_symbol_matrix (EEK_KEY(object), matrix);
 | 
			
		||||
        break;
 | 
			
		||||
    case PROP_COLUMN:
 | 
			
		||||
        eek_key_get_index (EEK_KEY(object), &column, &row);
 | 
			
		||||
        eek_key_set_index (EEK_KEY(object), g_value_get_int (value), row);
 | 
			
		||||
        break;
 | 
			
		||||
    case PROP_ROW:
 | 
			
		||||
        eek_key_get_index (EEK_KEY(object), &column, &row);
 | 
			
		||||
        eek_key_set_index (EEK_KEY(object), column, g_value_get_int (value));
 | 
			
		||||
        break;
 | 
			
		||||
    case PROP_OREF:
 | 
			
		||||
        eek_key_set_oref (EEK_KEY(object), g_value_get_uint (value));
 | 
			
		||||
        break;
 | 
			
		||||
    default:
 | 
			
		||||
        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
eek_key_get_property (GObject    *object,
 | 
			
		||||
                      guint       prop_id,
 | 
			
		||||
                      GValue     *value,
 | 
			
		||||
                      GParamSpec *pspec)
 | 
			
		||||
{
 | 
			
		||||
    gint column, row;
 | 
			
		||||
 | 
			
		||||
    switch (prop_id) {
 | 
			
		||||
    case PROP_KEYCODE:
 | 
			
		||||
        g_value_set_uint (value, eek_key_get_keycode (EEK_KEY(object)));
 | 
			
		||||
        break;
 | 
			
		||||
    case PROP_SYMBOL_MATRIX:
 | 
			
		||||
        g_value_set_boxed (value,
 | 
			
		||||
                           eek_key_get_symbol_matrix (EEK_KEY(object)));
 | 
			
		||||
        break;
 | 
			
		||||
    case PROP_COLUMN:
 | 
			
		||||
        eek_key_get_index (EEK_KEY(object), &column, &row);
 | 
			
		||||
        g_value_set_int (value, column);
 | 
			
		||||
        break;
 | 
			
		||||
    case PROP_ROW:
 | 
			
		||||
        eek_key_get_index (EEK_KEY(object), &column, &row);
 | 
			
		||||
        g_value_set_int (value, row);
 | 
			
		||||
        break;
 | 
			
		||||
    case PROP_OREF:
 | 
			
		||||
        g_value_set_uint (value, eek_key_get_oref (EEK_KEY(object)));
 | 
			
		||||
        break;
 | 
			
		||||
    default:
 | 
			
		||||
        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
eek_key_class_init (EekKeyClass *klass)
 | 
			
		||||
{
 | 
			
		||||
    GObjectClass      *gobject_class = G_OBJECT_CLASS (klass);
 | 
			
		||||
    GParamSpec        *pspec;
 | 
			
		||||
 | 
			
		||||
    gobject_class->set_property = eek_key_set_property;
 | 
			
		||||
    gobject_class->get_property = eek_key_get_property;
 | 
			
		||||
    gobject_class->finalize     = eek_key_finalize;
 | 
			
		||||
 | 
			
		||||
    /* signals */
 | 
			
		||||
    klass->locked = eek_key_real_locked;
 | 
			
		||||
    klass->unlocked = eek_key_real_unlocked;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * EekKey:keycode:
 | 
			
		||||
     *
 | 
			
		||||
     * The keycode of #EekKey.
 | 
			
		||||
     */
 | 
			
		||||
    pspec = g_param_spec_uint ("keycode",
 | 
			
		||||
                               "Keycode",
 | 
			
		||||
                               "Keycode of the key",
 | 
			
		||||
                               0, G_MAXUINT, 0,
 | 
			
		||||
                               G_PARAM_READWRITE);
 | 
			
		||||
    g_object_class_install_property (gobject_class, PROP_KEYCODE, pspec);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * EekKey:symbol-matrix:
 | 
			
		||||
     *
 | 
			
		||||
     * The symbol matrix of #EekKey.
 | 
			
		||||
     */
 | 
			
		||||
    pspec = g_param_spec_boxed ("symbol-matrix",
 | 
			
		||||
                                "Symbol matrix",
 | 
			
		||||
                                "Symbol matrix of the key",
 | 
			
		||||
                                EEK_TYPE_SYMBOL_MATRIX,
 | 
			
		||||
                                G_PARAM_READWRITE);
 | 
			
		||||
    g_object_class_install_property (gobject_class, PROP_SYMBOL_MATRIX, pspec);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * EekKey:column:
 | 
			
		||||
     *
 | 
			
		||||
     * The column index of #EekKey in the parent #EekSection.
 | 
			
		||||
     */
 | 
			
		||||
    pspec = g_param_spec_int ("column",
 | 
			
		||||
                              "Column",
 | 
			
		||||
                              "Column index of the key in section",
 | 
			
		||||
                              -1, G_MAXINT, -1,
 | 
			
		||||
                              G_PARAM_READWRITE);
 | 
			
		||||
    g_object_class_install_property (gobject_class, PROP_COLUMN, pspec);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * EekKey:row:
 | 
			
		||||
     *
 | 
			
		||||
     * The row index of #EekKey in the parent #EekSection.
 | 
			
		||||
     */
 | 
			
		||||
    pspec = g_param_spec_int ("row",
 | 
			
		||||
                              "Row",
 | 
			
		||||
                              "Row index of the key in section",
 | 
			
		||||
                              -1, G_MAXINT, -1,
 | 
			
		||||
                              G_PARAM_READWRITE);
 | 
			
		||||
    g_object_class_install_property (gobject_class, PROP_ROW, pspec);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * EekKey:oref:
 | 
			
		||||
     *
 | 
			
		||||
     * The outline id of #EekKey.
 | 
			
		||||
     */
 | 
			
		||||
    pspec = g_param_spec_ulong ("oref",
 | 
			
		||||
                                "Oref",
 | 
			
		||||
                                "Outline id of the key",
 | 
			
		||||
                                0, G_MAXULONG, 0,
 | 
			
		||||
                                G_PARAM_READWRITE);
 | 
			
		||||
    g_object_class_install_property (gobject_class, PROP_OREF, pspec);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * EekKey::locked:
 | 
			
		||||
     * @key: an #EekKey
 | 
			
		||||
     *
 | 
			
		||||
     * The ::locked signal is emitted each time @key is shifted to
 | 
			
		||||
     * the locked state.  The class handler runs before signal
 | 
			
		||||
     * handlers to allow signal handlers to read the status of @key
 | 
			
		||||
     * with eek_key_is_locked().
 | 
			
		||||
     */
 | 
			
		||||
    signals[LOCKED] =
 | 
			
		||||
        g_signal_new (I_("locked"),
 | 
			
		||||
                      G_TYPE_FROM_CLASS(gobject_class),
 | 
			
		||||
                      G_SIGNAL_RUN_FIRST,
 | 
			
		||||
                      G_STRUCT_OFFSET(EekKeyClass, locked),
 | 
			
		||||
                      NULL,
 | 
			
		||||
                      NULL,
 | 
			
		||||
                      g_cclosure_marshal_VOID__VOID,
 | 
			
		||||
                      G_TYPE_NONE, 0);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * EekKey::unlocked:
 | 
			
		||||
     * @key: an #EekKey
 | 
			
		||||
     *
 | 
			
		||||
     * The ::unlocked signal is emitted each time @key is shifted to
 | 
			
		||||
     * the unlocked state.
 | 
			
		||||
     */
 | 
			
		||||
   signals[UNLOCKED] =
 | 
			
		||||
        g_signal_new (I_("unlocked"),
 | 
			
		||||
                      G_TYPE_FROM_CLASS(gobject_class),
 | 
			
		||||
                      G_SIGNAL_RUN_LAST,
 | 
			
		||||
                      G_STRUCT_OFFSET(EekKeyClass, unlocked),
 | 
			
		||||
                      NULL,
 | 
			
		||||
                      NULL,
 | 
			
		||||
                      g_cclosure_marshal_VOID__VOID,
 | 
			
		||||
                      G_TYPE_NONE, 0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
eek_key_init (EekKey *self)
 | 
			
		||||
{
 | 
			
		||||
    EekKeyPrivate *priv = eek_key_get_instance_private (self);
 | 
			
		||||
    priv->symbol_matrix = eek_symbol_matrix_new (0, 0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eek_key_set_keycode:
 | 
			
		||||
 * @key: an #EekKey
 | 
			
		||||
 * @keycode: keycode
 | 
			
		||||
 *
 | 
			
		||||
 * Set the keycode of @key to @keycode.  Since typically the keycode
 | 
			
		||||
 * value is used to find a key in a keyboard by calling
 | 
			
		||||
 * eek_keyboard_find_key_by_keycode, it is not necessarily the same as
 | 
			
		||||
 * the X keycode but it should be unique in the keyboard @key belongs
 | 
			
		||||
 * to.
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
eek_key_set_keycode (EekKey *key,
 | 
			
		||||
                     guint   keycode)
 | 
			
		||||
{
 | 
			
		||||
    g_return_if_fail (EEK_IS_KEY (key));
 | 
			
		||||
 | 
			
		||||
    EekKeyPrivate *priv = eek_key_get_instance_private (key);
 | 
			
		||||
 | 
			
		||||
    priv->keycode = keycode;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eek_key_get_keycode:
 | 
			
		||||
 * @key: an #EekKey
 | 
			
		||||
 *
 | 
			
		||||
 * Get keycode of @key.
 | 
			
		||||
 * Returns: keycode or %EEK_INVALID_KEYCODE on failure
 | 
			
		||||
 */
 | 
			
		||||
guint
 | 
			
		||||
eek_key_get_keycode (EekKey *key)
 | 
			
		||||
{
 | 
			
		||||
    g_return_val_if_fail (EEK_IS_KEY (key), EEK_INVALID_KEYCODE);
 | 
			
		||||
 | 
			
		||||
    EekKeyPrivate *priv = eek_key_get_instance_private (key);
 | 
			
		||||
 | 
			
		||||
    return priv->keycode;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eek_key_set_symbol_matrix:
 | 
			
		||||
 * @key: an #EekKey
 | 
			
		||||
 * @matrix: an #EekSymbolMatrix
 | 
			
		||||
 *
 | 
			
		||||
 * Set the symbol matrix of @key to @matrix.
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
eek_key_set_symbol_matrix (EekKey          *key,
 | 
			
		||||
                           EekSymbolMatrix *matrix)
 | 
			
		||||
{
 | 
			
		||||
    g_return_if_fail (EEK_IS_KEY(key));
 | 
			
		||||
 | 
			
		||||
    EekKeyPrivate *priv = eek_key_get_instance_private (key);
 | 
			
		||||
 | 
			
		||||
    eek_symbol_matrix_free (priv->symbol_matrix);
 | 
			
		||||
    priv->symbol_matrix = eek_symbol_matrix_copy (matrix);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eek_key_get_symbol_matrix:
 | 
			
		||||
 * @key: an #EekKey
 | 
			
		||||
 *
 | 
			
		||||
 * Get the symbol matrix of @key.
 | 
			
		||||
 * Returns: (transfer none): #EekSymbolMatrix or %NULL
 | 
			
		||||
 */
 | 
			
		||||
EekSymbolMatrix *
 | 
			
		||||
eek_key_get_symbol_matrix (EekKey *key)
 | 
			
		||||
{
 | 
			
		||||
    g_return_val_if_fail (EEK_IS_KEY(key), NULL);
 | 
			
		||||
 | 
			
		||||
    EekKeyPrivate *priv = eek_key_get_instance_private (key);
 | 
			
		||||
 | 
			
		||||
    return priv->symbol_matrix;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eek_key_get_symbol:
 | 
			
		||||
 * @key: an #EekKey
 | 
			
		||||
 *
 | 
			
		||||
 * Get the current symbol of @key.
 | 
			
		||||
 * Return value: (transfer none): the current #EekSymbol or %NULL on failure
 | 
			
		||||
 */
 | 
			
		||||
EekSymbol *
 | 
			
		||||
eek_key_get_symbol (EekKey *key)
 | 
			
		||||
{
 | 
			
		||||
    return eek_key_get_symbol_with_fallback (key, 0, 0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eek_key_get_symbol_with_fallback:
 | 
			
		||||
 * @key: an #EekKey
 | 
			
		||||
 * @fallback_group: fallback group index
 | 
			
		||||
 * @fallback_level: fallback level index
 | 
			
		||||
 *
 | 
			
		||||
 * Get the current symbol of @key.
 | 
			
		||||
 * Return value: (transfer none): the current #EekSymbol or %NULL on failure
 | 
			
		||||
 */
 | 
			
		||||
EekSymbol *
 | 
			
		||||
eek_key_get_symbol_with_fallback (EekKey *key,
 | 
			
		||||
                                  gint    fallback_group,
 | 
			
		||||
                                  gint    fallback_level)
 | 
			
		||||
{
 | 
			
		||||
    gint group, level;
 | 
			
		||||
 | 
			
		||||
    g_return_val_if_fail (EEK_IS_KEY (key), NULL);
 | 
			
		||||
    g_return_val_if_fail (fallback_group >= 0, NULL);
 | 
			
		||||
    g_return_val_if_fail (fallback_level >= 0, NULL);
 | 
			
		||||
 | 
			
		||||
    eek_element_get_symbol_index (EEK_ELEMENT(key), &group, &level);
 | 
			
		||||
 | 
			
		||||
    if (group < 0 || level < 0) {
 | 
			
		||||
        EekElement *section;
 | 
			
		||||
 | 
			
		||||
        section = eek_element_get_parent (EEK_ELEMENT(key));
 | 
			
		||||
        g_return_val_if_fail (EEK_IS_SECTION (section), NULL);
 | 
			
		||||
 | 
			
		||||
        if (group < 0)
 | 
			
		||||
            group = eek_element_get_group (section);
 | 
			
		||||
 | 
			
		||||
        if (level < 0)
 | 
			
		||||
            level = eek_element_get_level (section);
 | 
			
		||||
 | 
			
		||||
        if (group < 0 || level < 0) {
 | 
			
		||||
            EekElement *keyboard;
 | 
			
		||||
 | 
			
		||||
            keyboard = eek_element_get_parent (section);
 | 
			
		||||
            g_return_val_if_fail (EEK_IS_KEYBOARD (keyboard), NULL);
 | 
			
		||||
 | 
			
		||||
            if (group < 0)
 | 
			
		||||
                group = eek_element_get_group (keyboard);
 | 
			
		||||
            if (level < 0)
 | 
			
		||||
                level = eek_element_get_level (keyboard);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return eek_key_get_symbol_at_index (key,
 | 
			
		||||
                                        group,
 | 
			
		||||
                                        level,
 | 
			
		||||
                                        fallback_group,
 | 
			
		||||
                                        fallback_level);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eek_key_get_symbol_at_index:
 | 
			
		||||
 * @key: an #EekKey
 | 
			
		||||
 * @group: group index of the symbol matrix
 | 
			
		||||
 * @level: level index of the symbol matrix
 | 
			
		||||
 * @fallback_group: fallback group index
 | 
			
		||||
 * @fallback_level: fallback level index
 | 
			
		||||
 *
 | 
			
		||||
 * Get the symbol at (@group, @level) in the symbol matrix of @key.
 | 
			
		||||
 * Return value: (transfer none): an #EekSymbol at (@group, @level), or %NULL
 | 
			
		||||
 */
 | 
			
		||||
EekSymbol *
 | 
			
		||||
eek_key_get_symbol_at_index (EekKey *key,
 | 
			
		||||
                             gint    group,
 | 
			
		||||
                             gint    level,
 | 
			
		||||
                             gint    fallback_group,
 | 
			
		||||
                             gint    fallback_level)
 | 
			
		||||
{
 | 
			
		||||
    EekKeyPrivate *priv = eek_key_get_instance_private (key);
 | 
			
		||||
    gint num_symbols;
 | 
			
		||||
 | 
			
		||||
    g_return_val_if_fail (fallback_group >= 0, NULL);
 | 
			
		||||
    g_return_val_if_fail (fallback_level >= 0, NULL);
 | 
			
		||||
 | 
			
		||||
    if (group < 0)
 | 
			
		||||
        group = fallback_group;
 | 
			
		||||
    if (level < 0)
 | 
			
		||||
        level = fallback_level;
 | 
			
		||||
 | 
			
		||||
    if (!priv->symbol_matrix)
 | 
			
		||||
        return NULL;
 | 
			
		||||
 | 
			
		||||
    num_symbols = priv->symbol_matrix->num_groups *
 | 
			
		||||
        priv->symbol_matrix->num_levels;
 | 
			
		||||
    if (num_symbols == 0)
 | 
			
		||||
        return NULL;
 | 
			
		||||
 | 
			
		||||
    if (group >= priv->symbol_matrix->num_groups) {
 | 
			
		||||
        if (fallback_group < 0)
 | 
			
		||||
            return NULL;
 | 
			
		||||
        group = fallback_group;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (level >= priv->symbol_matrix->num_levels) {
 | 
			
		||||
        if (fallback_level < 0)
 | 
			
		||||
            return NULL;
 | 
			
		||||
        level = fallback_level;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return priv->symbol_matrix->data[group * priv->symbol_matrix->num_levels +
 | 
			
		||||
                                     level];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eek_key_set_index:
 | 
			
		||||
 * @key: an #EekKey
 | 
			
		||||
 * @column: column index of @key in #EekSection
 | 
			
		||||
 * @row: row index of @key in #EekSection
 | 
			
		||||
 *
 | 
			
		||||
 * Set the location of @key in #EekSection with @column and @row.
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
eek_key_set_index (EekKey *key,
 | 
			
		||||
                   gint    column,
 | 
			
		||||
                   gint    row)
 | 
			
		||||
{
 | 
			
		||||
    g_return_if_fail (EEK_IS_KEY(key));
 | 
			
		||||
    g_return_if_fail (0 <= column);
 | 
			
		||||
    g_return_if_fail (0 <= row);
 | 
			
		||||
 | 
			
		||||
    EekKeyPrivate *priv = eek_key_get_instance_private (key);
 | 
			
		||||
 | 
			
		||||
    if (priv->column != column) {
 | 
			
		||||
        priv->column = column;
 | 
			
		||||
        g_object_notify (G_OBJECT(key), "column");
 | 
			
		||||
    }
 | 
			
		||||
    if (priv->row != row) {
 | 
			
		||||
        priv->row = row;
 | 
			
		||||
        g_object_notify (G_OBJECT(key), "row");
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eek_key_get_index:
 | 
			
		||||
 * @key: an #EekKey
 | 
			
		||||
 * @column: (allow-none): pointer where the column index of @key in #EekSection will be stored
 | 
			
		||||
 * @row: (allow-none): pointer where the row index of @key in #EekSection will be stored
 | 
			
		||||
 *
 | 
			
		||||
 * Get the location of @key in #EekSection.
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
eek_key_get_index (EekKey *key,
 | 
			
		||||
                   gint   *column,
 | 
			
		||||
                   gint   *row)
 | 
			
		||||
{
 | 
			
		||||
    g_return_if_fail (EEK_IS_KEY(key));
 | 
			
		||||
    g_return_if_fail (column != NULL || row != NULL);
 | 
			
		||||
 | 
			
		||||
    EekKeyPrivate *priv = eek_key_get_instance_private (key);
 | 
			
		||||
 | 
			
		||||
    if (column != NULL)
 | 
			
		||||
        *column = priv->column;
 | 
			
		||||
    if (row != NULL)
 | 
			
		||||
        *row = priv->row;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eek_key_set_oref:
 | 
			
		||||
 * @key: an #EekKey
 | 
			
		||||
 * @oref: outline id of @key
 | 
			
		||||
 *
 | 
			
		||||
 * Set the outline id of @key to @oref.
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
eek_key_set_oref (EekKey *key,
 | 
			
		||||
                  guint   oref)
 | 
			
		||||
{
 | 
			
		||||
    g_return_if_fail (EEK_IS_KEY(key));
 | 
			
		||||
 | 
			
		||||
    EekKeyPrivate *priv = eek_key_get_instance_private (key);
 | 
			
		||||
 | 
			
		||||
    if (priv->oref != oref) {
 | 
			
		||||
        priv->oref = oref;
 | 
			
		||||
        g_object_notify (G_OBJECT(key), "oref");
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eek_key_get_oref:
 | 
			
		||||
 * @key: an #EekKey
 | 
			
		||||
 *
 | 
			
		||||
 * Get the outline id of @key.
 | 
			
		||||
 * Returns: unsigned integer
 | 
			
		||||
 */
 | 
			
		||||
guint
 | 
			
		||||
eek_key_get_oref (EekKey *key)
 | 
			
		||||
{
 | 
			
		||||
    g_return_val_if_fail (EEK_IS_KEY (key), 0);
 | 
			
		||||
 | 
			
		||||
    EekKeyPrivate *priv = eek_key_get_instance_private (key);
 | 
			
		||||
 | 
			
		||||
    return priv->oref;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eek_key_is_pressed:
 | 
			
		||||
 * @key: an #EekKey
 | 
			
		||||
 *
 | 
			
		||||
 * Return %TRUE if key is marked as pressed.
 | 
			
		||||
 */
 | 
			
		||||
gboolean
 | 
			
		||||
eek_key_is_pressed (EekKey *key)
 | 
			
		||||
{
 | 
			
		||||
    g_return_val_if_fail (EEK_IS_KEY(key), FALSE);
 | 
			
		||||
 | 
			
		||||
    EekKeyPrivate *priv = eek_key_get_instance_private (key);
 | 
			
		||||
 | 
			
		||||
    return priv->is_pressed;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eek_key_is_locked:
 | 
			
		||||
 * @key: an #EekKey
 | 
			
		||||
 *
 | 
			
		||||
 * Return %TRUE if key is marked as locked.
 | 
			
		||||
 */
 | 
			
		||||
gboolean
 | 
			
		||||
eek_key_is_locked (EekKey *key)
 | 
			
		||||
{
 | 
			
		||||
    g_return_val_if_fail (EEK_IS_KEY(key), FALSE);
 | 
			
		||||
 | 
			
		||||
    EekKeyPrivate *priv = eek_key_get_instance_private (key);
 | 
			
		||||
 | 
			
		||||
    return priv->is_locked;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void eek_key_set_pressed(EekKey *key, gboolean value)
 | 
			
		||||
{
 | 
			
		||||
    g_return_if_fail (EEK_IS_KEY(key));
 | 
			
		||||
 | 
			
		||||
    EekKeyPrivate *priv = eek_key_get_instance_private (key);
 | 
			
		||||
 | 
			
		||||
    priv->is_pressed = value;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										93
									
								
								eek/eek-key.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										93
									
								
								eek/eek-key.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,93 @@
 | 
			
		||||
/* 
 | 
			
		||||
 * Copyright (C) 2010-2011 Daiki Ueno <ueno@unixuser.org>
 | 
			
		||||
 * Copyright (C) 2010-2011 Red Hat, Inc.
 | 
			
		||||
 * 
 | 
			
		||||
 * This library is free software; you can redistribute it and/or
 | 
			
		||||
 * modify it under the terms of the GNU Lesser General Public License
 | 
			
		||||
 * as published by the Free Software Foundation; either version 2 of
 | 
			
		||||
 * the License, or (at your option) any later version.
 | 
			
		||||
 * 
 | 
			
		||||
 * This library is distributed in the hope that it will be useful, but
 | 
			
		||||
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
			
		||||
 * Lesser General Public License for more details.
 | 
			
		||||
 * 
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General Public
 | 
			
		||||
 * License along with this library; if not, write to the Free Software
 | 
			
		||||
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 | 
			
		||||
 * 02110-1301 USA
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#if !defined(__EEK_H_INSIDE__) && !defined(EEK_COMPILATION)
 | 
			
		||||
#error "Only <eek/eek.h> can be included directly."
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef EEK_KEY_H
 | 
			
		||||
#define EEK_KEY_H 1
 | 
			
		||||
 | 
			
		||||
#include "eek-element.h"
 | 
			
		||||
#include "eek-symbol-matrix.h"
 | 
			
		||||
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
#define EEK_TYPE_KEY (eek_key_get_type())
 | 
			
		||||
G_DECLARE_DERIVABLE_TYPE(EekKey, eek_key, EEK, KEY, EekElement)
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * EekKeyClass:
 | 
			
		||||
 * @pressed: class handler for #EekKey::pressed signal
 | 
			
		||||
 * @released: class handler for #EekKey::released signal
 | 
			
		||||
 * @locked: class handler for #EekKey::locked signal
 | 
			
		||||
 * @unlocked: class handler for #EekKey::unlocked signal
 | 
			
		||||
 * @cancelled: class handler for #EekKey::cancelled signal
 | 
			
		||||
 * @is_pressed: virtual function for getting whether the key is pressed
 | 
			
		||||
 * @is_locked: virtual function for getting whether the key is locked
 | 
			
		||||
 */
 | 
			
		||||
struct _EekKeyClass
 | 
			
		||||
{
 | 
			
		||||
    /*< private >*/
 | 
			
		||||
    EekElementClass parent_class;
 | 
			
		||||
 | 
			
		||||
    /*< public >*/
 | 
			
		||||
    /* signals */
 | 
			
		||||
    void (* locked)    (EekKey *key);
 | 
			
		||||
    void (* unlocked)  (EekKey *key);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
GType            eek_key_get_type            (void) G_GNUC_CONST;
 | 
			
		||||
 | 
			
		||||
void             eek_key_set_keycode         (EekKey          *key,
 | 
			
		||||
                                              guint            keycode);
 | 
			
		||||
guint            eek_key_get_keycode         (EekKey          *key);
 | 
			
		||||
void             eek_key_set_symbol_matrix   (EekKey          *key,
 | 
			
		||||
                                              EekSymbolMatrix *matrix);
 | 
			
		||||
EekSymbolMatrix *eek_key_get_symbol_matrix   (EekKey          *key);
 | 
			
		||||
EekSymbol       *eek_key_get_symbol          (EekKey          *key);
 | 
			
		||||
EekSymbol       *eek_key_get_symbol_with_fallback
 | 
			
		||||
                                             (EekKey          *key,
 | 
			
		||||
                                              gint             fallback_group,
 | 
			
		||||
                                              gint             fallback_level);
 | 
			
		||||
EekSymbol       *eek_key_get_symbol_at_index (EekKey          *key,
 | 
			
		||||
                                              gint             group,
 | 
			
		||||
                                              gint             level,
 | 
			
		||||
                                              gint             fallback_group,
 | 
			
		||||
                                              gint             fallback_level);
 | 
			
		||||
 | 
			
		||||
void             eek_key_set_index           (EekKey          *key,
 | 
			
		||||
                                              gint             column,
 | 
			
		||||
                                              gint             row);
 | 
			
		||||
void             eek_key_get_index           (EekKey          *key,
 | 
			
		||||
                                              gint            *column,
 | 
			
		||||
                                              gint            *row);
 | 
			
		||||
 | 
			
		||||
void             eek_key_set_oref            (EekKey          *key,
 | 
			
		||||
                                              guint            oref);
 | 
			
		||||
guint            eek_key_get_oref            (EekKey          *key);
 | 
			
		||||
 | 
			
		||||
gboolean         eek_key_is_pressed          (EekKey          *key);
 | 
			
		||||
gboolean         eek_key_is_locked           (EekKey          *key);
 | 
			
		||||
void             eek_key_set_pressed         (EekKey          *key,
 | 
			
		||||
                                              gboolean         value);
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
#endif  /* EEK_KEY_H */
 | 
			
		||||
							
								
								
									
										219
									
								
								eek/eek-keyboard-drawing.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										219
									
								
								eek/eek-keyboard-drawing.c
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,219 @@
 | 
			
		||||
/*
 | 
			
		||||
 * 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.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_CONFIG_H
 | 
			
		||||
#include "config.h"
 | 
			
		||||
#endif  /* HAVE_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
 | 
			
		||||
@ -27,15 +27,56 @@
 | 
			
		||||
 * of one or more sections of the #EekSectionClass class.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_CONFIG_H
 | 
			
		||||
#include "config.h"
 | 
			
		||||
#include <glib/gprintf.h>
 | 
			
		||||
 | 
			
		||||
#include "eek-enumtypes.h"
 | 
			
		||||
#include "eekboard/key-emitter.h"
 | 
			
		||||
#include "keymap.h"
 | 
			
		||||
#include "src/keyboard.h"
 | 
			
		||||
#endif  /* HAVE_CONFIG_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"
 | 
			
		||||
 | 
			
		||||
enum {
 | 
			
		||||
    PROP_0,
 | 
			
		||||
    PROP_LAYOUT,
 | 
			
		||||
    PROP_MODIFIER_BEHAVIOR,
 | 
			
		||||
    PROP_LAST
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
enum {
 | 
			
		||||
    KEY_RELEASED,
 | 
			
		||||
    KEY_LOCKED,
 | 
			
		||||
    KEY_UNLOCKED,
 | 
			
		||||
    LAST_SIGNAL
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static guint signals[LAST_SIGNAL] = { 0, };
 | 
			
		||||
 | 
			
		||||
G_DEFINE_TYPE (EekKeyboard, eek_keyboard, EEK_TYPE_CONTAINER);
 | 
			
		||||
 | 
			
		||||
#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;
 | 
			
		||||
    GList *pressed_keys;
 | 
			
		||||
    GList *locked_keys;
 | 
			
		||||
    GArray *outline_array;
 | 
			
		||||
    GHashTable *keycodes;
 | 
			
		||||
 | 
			
		||||
    /* modifiers dynamically assigned at run time */
 | 
			
		||||
    EekModifierType num_lock_mask;
 | 
			
		||||
    EekModifierType alt_gr_mask;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
G_DEFINE_BOXED_TYPE(EekModifierKey, eek_modifier_key,
 | 
			
		||||
                    eek_modifier_key_copy, eek_modifier_key_free);
 | 
			
		||||
 | 
			
		||||
EekModifierKey *
 | 
			
		||||
eek_modifier_key_copy (EekModifierKey *modkey)
 | 
			
		||||
@ -46,107 +87,663 @@ 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)
 | 
			
		||||
{
 | 
			
		||||
    guint keycode = eek_key_get_keycode (EEK_KEY(element));
 | 
			
		||||
    g_hash_table_insert (keyboard->priv->keycodes,
 | 
			
		||||
                         GUINT_TO_POINTER(keycode),
 | 
			
		||||
                         element);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
section_child_removed_cb (EekContainer *container,
 | 
			
		||||
                          EekElement   *element,
 | 
			
		||||
                          EekKeyboard  *keyboard)
 | 
			
		||||
{
 | 
			
		||||
    guint keycode = eek_key_get_keycode (EEK_KEY(element));
 | 
			
		||||
    g_hash_table_remove (keyboard->priv->keycodes,
 | 
			
		||||
                         GUINT_TO_POINTER(keycode));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static EekSection *
 | 
			
		||||
eek_keyboard_real_create_section (EekKeyboard *self)
 | 
			
		||||
{
 | 
			
		||||
    EekSection *section;
 | 
			
		||||
 | 
			
		||||
    section = g_object_new (EEK_TYPE_SECTION, NULL);
 | 
			
		||||
    g_return_val_if_fail (section, NULL);
 | 
			
		||||
 | 
			
		||||
    g_signal_connect (G_OBJECT(section), "child-added",
 | 
			
		||||
                      G_CALLBACK(section_child_added_cb), self);
 | 
			
		||||
 | 
			
		||||
    g_signal_connect (G_OBJECT(section), "child-removed",
 | 
			
		||||
                      G_CALLBACK(section_child_removed_cb), self);
 | 
			
		||||
 | 
			
		||||
    EEK_CONTAINER_GET_CLASS(self)->add_child (EEK_CONTAINER(self),
 | 
			
		||||
                                              EEK_ELEMENT(section));
 | 
			
		||||
    return section;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
eek_keyboard_set_property (GObject      *object,
 | 
			
		||||
                           guint         prop_id,
 | 
			
		||||
                           const GValue *value,
 | 
			
		||||
                           GParamSpec   *pspec)
 | 
			
		||||
{
 | 
			
		||||
    EekKeyboardPrivate *priv = EEK_KEYBOARD_GET_PRIVATE(object);
 | 
			
		||||
 | 
			
		||||
    switch (prop_id) {
 | 
			
		||||
    case PROP_LAYOUT:
 | 
			
		||||
        priv->layout = g_value_get_object (value);
 | 
			
		||||
        if (priv->layout)
 | 
			
		||||
            g_object_ref (priv->layout);
 | 
			
		||||
        break;
 | 
			
		||||
    case PROP_MODIFIER_BEHAVIOR:
 | 
			
		||||
        eek_keyboard_set_modifier_behavior (EEK_KEYBOARD(object),
 | 
			
		||||
                                            g_value_get_enum (value));
 | 
			
		||||
        break;
 | 
			
		||||
    default:
 | 
			
		||||
        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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)
 | 
			
		||||
{
 | 
			
		||||
    EekKeyboardPrivate *priv = EEK_KEYBOARD_GET_PRIVATE(self);
 | 
			
		||||
    gint level = 0;
 | 
			
		||||
 | 
			
		||||
    if (priv->modifiers & priv->alt_gr_mask)
 | 
			
		||||
        level |= 2;
 | 
			
		||||
    if (priv->modifiers & EEK_SHIFT_MASK)
 | 
			
		||||
        level |= 1;
 | 
			
		||||
    eek_element_set_level (EEK_ELEMENT(self), level);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // "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);
 | 
			
		||||
 | 
			
		||||
    // "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->keycodes);
 | 
			
		||||
 | 
			
		||||
    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;
 | 
			
		||||
 | 
			
		||||
    g_type_class_add_private (gobject_class,
 | 
			
		||||
                              sizeof (EekKeyboardPrivate));
 | 
			
		||||
 | 
			
		||||
    klass->create_section = eek_keyboard_real_create_section;
 | 
			
		||||
 | 
			
		||||
    /* signals */
 | 
			
		||||
    container_class->child_added = eek_keyboard_real_child_added;
 | 
			
		||||
    container_class->child_removed = eek_keyboard_real_child_removed;
 | 
			
		||||
 | 
			
		||||
    gobject_class->get_property = eek_keyboard_get_property;
 | 
			
		||||
    gobject_class->set_property = eek_keyboard_set_property;
 | 
			
		||||
    gobject_class->dispose = eek_keyboard_dispose;
 | 
			
		||||
    gobject_class->finalize = eek_keyboard_finalize;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * EekKeyboard:layout:
 | 
			
		||||
     *
 | 
			
		||||
     * The layout used to create this #EekKeyboard.
 | 
			
		||||
     */
 | 
			
		||||
    pspec = g_param_spec_object ("layout",
 | 
			
		||||
                                 "Layout",
 | 
			
		||||
                                 "Layout used to create the keyboard",
 | 
			
		||||
                                 EEK_TYPE_LAYOUT,
 | 
			
		||||
                                 G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE);
 | 
			
		||||
    g_object_class_install_property (gobject_class,
 | 
			
		||||
                                     PROP_LAYOUT,
 | 
			
		||||
                                     pspec);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * EekKeyboard:modifier-behavior:
 | 
			
		||||
     *
 | 
			
		||||
     * The modifier handling mode of #EekKeyboard.
 | 
			
		||||
     */
 | 
			
		||||
    pspec = g_param_spec_enum ("modifier-behavior",
 | 
			
		||||
                               "Modifier behavior",
 | 
			
		||||
                               "Modifier handling mode of the keyboard",
 | 
			
		||||
                               EEK_TYPE_MODIFIER_BEHAVIOR,
 | 
			
		||||
                               EEK_MODIFIER_BEHAVIOR_NONE,
 | 
			
		||||
                               G_PARAM_READWRITE);
 | 
			
		||||
    g_object_class_install_property (gobject_class,
 | 
			
		||||
                                     PROP_MODIFIER_BEHAVIOR,
 | 
			
		||||
                                     pspec);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * EekKeyboard::key-locked:
 | 
			
		||||
     * @keyboard: an #EekKeyboard
 | 
			
		||||
     * @key: an #EekKey
 | 
			
		||||
     *
 | 
			
		||||
     * The ::key-locked signal is emitted each time a key in @keyboard
 | 
			
		||||
     * is shifted to the locked state.
 | 
			
		||||
     */
 | 
			
		||||
    signals[KEY_LOCKED] =
 | 
			
		||||
        g_signal_new (I_("key-locked"),
 | 
			
		||||
                      G_TYPE_FROM_CLASS(gobject_class),
 | 
			
		||||
                      G_SIGNAL_RUN_LAST,
 | 
			
		||||
                      G_STRUCT_OFFSET(EekKeyboardClass, key_locked),
 | 
			
		||||
                      NULL,
 | 
			
		||||
                      NULL,
 | 
			
		||||
                      g_cclosure_marshal_VOID__OBJECT,
 | 
			
		||||
                      G_TYPE_NONE,
 | 
			
		||||
                      1,
 | 
			
		||||
                      EEK_TYPE_KEY);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * EekKeyboard::key-unlocked:
 | 
			
		||||
     * @keyboard: an #EekKeyboard
 | 
			
		||||
     * @key: an #EekKey
 | 
			
		||||
     *
 | 
			
		||||
     * The ::key-unlocked signal is emitted each time a key in @keyboard
 | 
			
		||||
     * is shifted to the unlocked state.
 | 
			
		||||
     */
 | 
			
		||||
    signals[KEY_UNLOCKED] =
 | 
			
		||||
        g_signal_new (I_("key-unlocked"),
 | 
			
		||||
                      G_TYPE_FROM_CLASS(gobject_class),
 | 
			
		||||
                      G_SIGNAL_RUN_LAST,
 | 
			
		||||
                      G_STRUCT_OFFSET(EekKeyboardClass, key_unlocked),
 | 
			
		||||
                      NULL,
 | 
			
		||||
                      NULL,
 | 
			
		||||
                      g_cclosure_marshal_VOID__OBJECT,
 | 
			
		||||
                      G_TYPE_NONE,
 | 
			
		||||
                      1,
 | 
			
		||||
                      EEK_TYPE_KEY);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
eek_keyboard_init (EekKeyboard *self)
 | 
			
		||||
{
 | 
			
		||||
    self->priv = EEK_KEYBOARD_GET_PRIVATE(self);
 | 
			
		||||
    self->priv->modifier_behavior = EEK_MODIFIER_BEHAVIOR_NONE;
 | 
			
		||||
    self->priv->outline_array = g_array_new (FALSE, TRUE, sizeof (EekOutline));
 | 
			
		||||
    self->priv->keycodes = g_hash_table_new (g_direct_hash, g_direct_equal);
 | 
			
		||||
    eek_element_set_symbol_index (EEK_ELEMENT(self), 0, 0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * 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_keycode:
 | 
			
		||||
 * @keyboard: an #EekKeyboard
 | 
			
		||||
 * @keycode: a keycode
 | 
			
		||||
 *
 | 
			
		||||
 * Find an #EekKey whose keycode is @keycode.
 | 
			
		||||
 * Return value: (transfer none): #EekKey whose keycode is @keycode
 | 
			
		||||
 */
 | 
			
		||||
EekKey *
 | 
			
		||||
eek_keyboard_find_key_by_keycode (EekKeyboard *keyboard,
 | 
			
		||||
                                  guint        keycode)
 | 
			
		||||
{
 | 
			
		||||
    g_return_val_if_fail (EEK_IS_KEYBOARD(keyboard), NULL);
 | 
			
		||||
    return g_hash_table_lookup (keyboard->priv->keycodes,
 | 
			
		||||
                                GUINT_TO_POINTER(keycode));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eek_keyboard_get_layout:
 | 
			
		||||
 * @keyboard: an #EekKeyboard
 | 
			
		||||
 *
 | 
			
		||||
 * Get the layout used to create @keyboard.
 | 
			
		||||
 * Returns: an #EekLayout
 | 
			
		||||
 */
 | 
			
		||||
EekLayout *
 | 
			
		||||
eek_keyboard_get_layout (EekKeyboard *keyboard)
 | 
			
		||||
{
 | 
			
		||||
    g_return_val_if_fail (EEK_IS_KEYBOARD(keyboard), NULL);
 | 
			
		||||
    return keyboard->priv->layout;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eek_keyboard_get_size:
 | 
			
		||||
 * @keyboard: an #EekKeyboard
 | 
			
		||||
 * @width: width of @keyboard
 | 
			
		||||
 * @height: height of @keyboard
 | 
			
		||||
 *
 | 
			
		||||
 * Get the size of @keyboard.
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
eek_keyboard_get_size (EekKeyboard *keyboard,
 | 
			
		||||
                       gdouble     *width,
 | 
			
		||||
                       gdouble     *height)
 | 
			
		||||
{
 | 
			
		||||
    EekBounds bounds;
 | 
			
		||||
 | 
			
		||||
    eek_element_get_bounds (EEK_ELEMENT(keyboard), &bounds);
 | 
			
		||||
    *width = bounds.width;
 | 
			
		||||
    *height = bounds.height;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eek_keyboard_set_modifier_behavior:
 | 
			
		||||
 * @keyboard: an #EekKeyboard
 | 
			
		||||
 * @modifier_behavior: modifier behavior of @keyboard
 | 
			
		||||
 *
 | 
			
		||||
 * Set the modifier handling mode of @keyboard.
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
eek_keyboard_set_modifier_behavior (EekKeyboard        *keyboard,
 | 
			
		||||
                                    EekModifierBehavior modifier_behavior)
 | 
			
		||||
{
 | 
			
		||||
    g_return_if_fail (EEK_IS_KEYBOARD(keyboard));
 | 
			
		||||
    keyboard->priv->modifier_behavior = modifier_behavior;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eek_keyboard_get_modifier_behavior:
 | 
			
		||||
 * @keyboard: an #EekKeyboard
 | 
			
		||||
 *
 | 
			
		||||
 * Get the modifier handling mode of @keyboard.
 | 
			
		||||
 * Returns: #EekModifierBehavior
 | 
			
		||||
 */
 | 
			
		||||
EekModifierBehavior
 | 
			
		||||
eek_keyboard_get_modifier_behavior (EekKeyboard *keyboard)
 | 
			
		||||
{
 | 
			
		||||
    g_return_val_if_fail (EEK_IS_KEYBOARD(keyboard), 0);
 | 
			
		||||
    return keyboard->priv->modifier_behavior;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
eek_keyboard_set_modifiers (EekKeyboard    *keyboard,
 | 
			
		||||
                            EekModifierType modifiers)
 | 
			
		||||
{
 | 
			
		||||
    g_return_if_fail (EEK_IS_KEYBOARD(keyboard));
 | 
			
		||||
    keyboard->priv->modifiers = modifiers;
 | 
			
		||||
    set_level_from_modifiers (keyboard);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * 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);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -27,56 +27,172 @@
 | 
			
		||||
 | 
			
		||||
#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
 | 
			
		||||
 | 
			
		||||
    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_keycode: virtual function for finding a key in the
 | 
			
		||||
 * keyboard by keycode
 | 
			
		||||
 * @key_pressed: class handler for #EekKeyboard::key-pressed signal
 | 
			
		||||
 * @key_released: class handler for #EekKeyboard::key-released signal
 | 
			
		||||
 * @key_locked: class handler for #EekKeyboard::key-locked signal
 | 
			
		||||
 * @key_unlocked: class handler for #EekKeyboard::key-unlocked signal
 | 
			
		||||
 * @key_cancelled: class handler for #EekKeyboard::key-cancelled signal
 | 
			
		||||
 */
 | 
			
		||||
struct _EekKeyboardClass
 | 
			
		||||
{
 | 
			
		||||
    /*< private >*/
 | 
			
		||||
    EekContainerClass parent_class;
 | 
			
		||||
 | 
			
		||||
    /* obsolete members moved to EekElement */
 | 
			
		||||
    gpointer set_symbol_index;
 | 
			
		||||
    gpointer get_symbol_index;
 | 
			
		||||
 | 
			
		||||
    /*< public >*/
 | 
			
		||||
    EekSection *(* create_section)      (EekKeyboard *self);
 | 
			
		||||
 | 
			
		||||
    EekKey     *(* find_key_by_keycode) (EekKeyboard *self,
 | 
			
		||||
                                         guint        keycode);
 | 
			
		||||
 | 
			
		||||
    /*< private >*/
 | 
			
		||||
    /* obsolete members moved to EekElement */
 | 
			
		||||
    gpointer symbol_index_changed;
 | 
			
		||||
 | 
			
		||||
    /*< public >*/
 | 
			
		||||
    /* signals */
 | 
			
		||||
    void        (* key_locked)          (EekKeyboard *self,
 | 
			
		||||
                                         EekKey      *key);
 | 
			
		||||
    void        (* key_unlocked)        (EekKeyboard *self,
 | 
			
		||||
                                         EekKey      *key);
 | 
			
		||||
 | 
			
		||||
    /*< private >*/
 | 
			
		||||
    /* padding */
 | 
			
		||||
    gpointer pdummy[21];
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * EekModifierKey:
 | 
			
		||||
 * @modifiers: an #EekModifierType which @key triggers
 | 
			
		||||
 * @key: an #EekKey
 | 
			
		||||
 *
 | 
			
		||||
 * Entry which associates modifier mask to a key.  This is returned by
 | 
			
		||||
 * eek_keyboard_get_locked_keys().
 | 
			
		||||
 */
 | 
			
		||||
struct _EekModifierKey {
 | 
			
		||||
    /*< public >*/
 | 
			
		||||
    EekModifierType modifiers;
 | 
			
		||||
    EekKey *key;
 | 
			
		||||
};
 | 
			
		||||
typedef struct _EekModifierKey EekModifierKey;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
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_keycode
 | 
			
		||||
                                     (EekKeyboard        *keyboard,
 | 
			
		||||
                                      guint               keycode);
 | 
			
		||||
 | 
			
		||||
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);
 | 
			
		||||
 | 
			
		||||
gchar *             eek_keyboard_get_keymap
 | 
			
		||||
                                     (LevelKeyboard *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_press_key(EekKeyboard *keyboard, EekKey *key, guint32 timestamp);
 | 
			
		||||
void eek_keyboard_release_key(EekKeyboard *keyboard, EekKey *key, guint32 timestamp);
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
#endif  /* EEK_KEYBOARD_H */
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										350
									
								
								eek/eek-keysym.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										350
									
								
								eek/eek-keysym.c
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,350 @@
 | 
			
		||||
/* 
 | 
			
		||||
 * 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
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_CONFIG_H
 | 
			
		||||
#include "config.h"
 | 
			
		||||
#endif  /* HAVE_CONFIG_H */
 | 
			
		||||
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
 | 
			
		||||
#include "eek-keysym.h"
 | 
			
		||||
#include "eek-serializable.h"
 | 
			
		||||
 | 
			
		||||
/* modifier keys */
 | 
			
		||||
#define EEK_KEYSYM_Shift_L 0xffe1
 | 
			
		||||
#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
 | 
			
		||||
 | 
			
		||||
typedef struct _EekKeysymPrivate
 | 
			
		||||
{
 | 
			
		||||
    guint xkeysym;
 | 
			
		||||
} EekKeysymPrivate;
 | 
			
		||||
 | 
			
		||||
struct _EekKeysymEntry {
 | 
			
		||||
    guint xkeysym;
 | 
			
		||||
    const gchar *name;
 | 
			
		||||
    EekSymbolCategory category;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
typedef struct _EekKeysymEntry EekKeysymEntry;
 | 
			
		||||
 | 
			
		||||
#include "eek-special-keysym-entries.h"
 | 
			
		||||
#include "eek-unicode-keysym-entries.h"
 | 
			
		||||
#include "eek-xkeysym-keysym-entries.h"
 | 
			
		||||
 | 
			
		||||
static void eek_serializable_iface_init (EekSerializableIface *iface);
 | 
			
		||||
 | 
			
		||||
G_DEFINE_TYPE_EXTENDED (EekKeysym, eek_keysym, EEK_TYPE_SYMBOL,
 | 
			
		||||
			0, /* GTypeFlags */
 | 
			
		||||
			G_ADD_PRIVATE (EekKeysym)
 | 
			
		||||
                        G_IMPLEMENT_INTERFACE (EEK_TYPE_SERIALIZABLE,
 | 
			
		||||
                                               eek_serializable_iface_init))
 | 
			
		||||
 | 
			
		||||
static EekSerializableIface *eek_keysym_parent_serializable_iface;
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
eek_keysym_real_serialize (EekSerializable *self,
 | 
			
		||||
                           GVariantBuilder *builder)
 | 
			
		||||
{
 | 
			
		||||
    EekKeysymPrivate *priv = eek_keysym_get_instance_private (
 | 
			
		||||
		    EEK_KEYSYM(self));
 | 
			
		||||
 | 
			
		||||
    eek_keysym_parent_serializable_iface->serialize (self, builder);
 | 
			
		||||
 | 
			
		||||
    g_variant_builder_add (builder, "u", priv->xkeysym);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gsize
 | 
			
		||||
eek_keysym_real_deserialize (EekSerializable *self,
 | 
			
		||||
                             GVariant        *variant,
 | 
			
		||||
                             gsize            index)
 | 
			
		||||
{
 | 
			
		||||
    EekKeysymPrivate *priv = eek_keysym_get_instance_private (
 | 
			
		||||
		    EEK_KEYSYM(self));
 | 
			
		||||
 | 
			
		||||
    index = eek_keysym_parent_serializable_iface->deserialize (self,
 | 
			
		||||
                                                               variant,
 | 
			
		||||
                                                               index);
 | 
			
		||||
 | 
			
		||||
    g_variant_get_child (variant, index++, "u", &priv->xkeysym);
 | 
			
		||||
 | 
			
		||||
    return index;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
eek_serializable_iface_init (EekSerializableIface *iface)
 | 
			
		||||
{
 | 
			
		||||
    eek_keysym_parent_serializable_iface =
 | 
			
		||||
        g_type_interface_peek_parent (iface);
 | 
			
		||||
 | 
			
		||||
    iface->serialize = eek_keysym_real_serialize;
 | 
			
		||||
    iface->deserialize = eek_keysym_real_deserialize;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gchar *
 | 
			
		||||
unichar_to_utf8 (gunichar uc)
 | 
			
		||||
{
 | 
			
		||||
    if (g_unichar_isgraph (uc)) {
 | 
			
		||||
        gchar *buf;
 | 
			
		||||
        gint len;
 | 
			
		||||
 | 
			
		||||
        len = g_unichar_to_utf8 (uc, NULL);
 | 
			
		||||
        buf = g_malloc0 (len + 1);
 | 
			
		||||
        g_unichar_to_utf8 (uc, buf);
 | 
			
		||||
        return buf;
 | 
			
		||||
    }
 | 
			
		||||
    return g_strdup ("");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int
 | 
			
		||||
keysym_entry_compare_by_xkeysym (const void *key0, const void *key1)
 | 
			
		||||
{
 | 
			
		||||
    const EekKeysymEntry *entry0 = key0, *entry1 = key1;
 | 
			
		||||
    return (gint) (entry0->xkeysym - entry1->xkeysym);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static EekKeysymEntry *
 | 
			
		||||
find_keysym_entry_by_xkeysym (guint xkeysym,
 | 
			
		||||
                              const EekKeysymEntry *entries,
 | 
			
		||||
                              gint num_entries)
 | 
			
		||||
{
 | 
			
		||||
    EekKeysymEntry key;
 | 
			
		||||
 | 
			
		||||
    key.xkeysym = xkeysym;
 | 
			
		||||
    return bsearch (&key, entries, num_entries, sizeof (EekKeysymEntry),
 | 
			
		||||
                    keysym_entry_compare_by_xkeysym);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
get_unichar (guint xkeysym, gunichar *uc) {
 | 
			
		||||
    /* Check for Latin-1 characters (1:1 mapping) */
 | 
			
		||||
    if ((xkeysym >= 0x0020 && xkeysym <= 0x007e) ||
 | 
			
		||||
        (xkeysym >= 0x00a0 && xkeysym <= 0x00ff)) {
 | 
			
		||||
        *uc = xkeysym;
 | 
			
		||||
        return TRUE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* Also check for directly encoded 24-bit UCS characters:
 | 
			
		||||
     */
 | 
			
		||||
    if ((xkeysym & 0xff000000) == 0x01000000) {
 | 
			
		||||
        *uc = xkeysym & 0x00ffffff;
 | 
			
		||||
        return TRUE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return FALSE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
G_INLINE_FUNC EekModifierType
 | 
			
		||||
get_modifier_mask (guint xkeysym)
 | 
			
		||||
{
 | 
			
		||||
    switch (xkeysym) {
 | 
			
		||||
    case EEK_KEYSYM_Shift_L:
 | 
			
		||||
    case EEK_KEYSYM_Shift_R:
 | 
			
		||||
    case EEK_KEYSYM_Caps_Lock:
 | 
			
		||||
    case EEK_KEYSYM_Shift_Lock:
 | 
			
		||||
        return EEK_SHIFT_MASK;
 | 
			
		||||
    case EEK_KEYSYM_ISO_Level3_Shift:
 | 
			
		||||
        return EEK_BUTTON1_MASK;
 | 
			
		||||
    case EEK_KEYSYM_Control_L:
 | 
			
		||||
    case EEK_KEYSYM_Control_R:
 | 
			
		||||
        return EEK_CONTROL_MASK;
 | 
			
		||||
    case EEK_KEYSYM_Alt_L:
 | 
			
		||||
    case EEK_KEYSYM_Alt_R:
 | 
			
		||||
        return EEK_MOD1_MASK;
 | 
			
		||||
    case EEK_KEYSYM_Meta_L:
 | 
			
		||||
    case EEK_KEYSYM_Meta_R:
 | 
			
		||||
        return EEK_META_MASK;
 | 
			
		||||
    case EEK_KEYSYM_Super_L:
 | 
			
		||||
    case EEK_KEYSYM_Super_R:
 | 
			
		||||
        return EEK_SUPER_MASK;
 | 
			
		||||
    case EEK_KEYSYM_Hyper_L:
 | 
			
		||||
    case EEK_KEYSYM_Hyper_R:
 | 
			
		||||
        return EEK_HYPER_MASK;
 | 
			
		||||
    }
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
eek_keysym_class_init (EekKeysymClass *klass)
 | 
			
		||||
{
 | 
			
		||||
    /* void */
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
eek_keysym_init (EekKeysym *self)
 | 
			
		||||
{
 | 
			
		||||
    /* void */
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eek_keysym_new_with_modifier:
 | 
			
		||||
 * @xkeysym: an X keysym value
 | 
			
		||||
 * @modifier_mask: modifier assigned to @xkeysym
 | 
			
		||||
 *
 | 
			
		||||
 * Create an #EekKeysym with given X keysym value @xkeysym and
 | 
			
		||||
 * modifier @modifier_mask.
 | 
			
		||||
 */
 | 
			
		||||
EekKeysym *
 | 
			
		||||
eek_keysym_new_with_modifier (guint           xkeysym,
 | 
			
		||||
                              EekModifierType modifier_mask)
 | 
			
		||||
{
 | 
			
		||||
    EekKeysym *keysym;
 | 
			
		||||
    EekKeysymPrivate *priv;
 | 
			
		||||
    EekKeysymEntry *special_entry, *xkeysym_entry, *unicode_entry,
 | 
			
		||||
        *unichar_entry;
 | 
			
		||||
    gchar *name, *label;
 | 
			
		||||
    EekSymbolCategory category;
 | 
			
		||||
    gunichar uc;
 | 
			
		||||
 | 
			
		||||
    special_entry =
 | 
			
		||||
        find_keysym_entry_by_xkeysym (xkeysym,
 | 
			
		||||
                                      special_keysym_entries,
 | 
			
		||||
                                      G_N_ELEMENTS(special_keysym_entries));
 | 
			
		||||
    xkeysym_entry =
 | 
			
		||||
        find_keysym_entry_by_xkeysym (xkeysym,
 | 
			
		||||
                                      xkeysym_keysym_entries,
 | 
			
		||||
                                      G_N_ELEMENTS(xkeysym_keysym_entries));
 | 
			
		||||
    unicode_entry =
 | 
			
		||||
        find_keysym_entry_by_xkeysym (xkeysym,
 | 
			
		||||
                                      unicode_keysym_entries,
 | 
			
		||||
                                      G_N_ELEMENTS(unicode_keysym_entries));
 | 
			
		||||
    unichar_entry = NULL;
 | 
			
		||||
    if (get_unichar (xkeysym, &uc)) {
 | 
			
		||||
        unichar_entry = g_slice_new (EekKeysymEntry);
 | 
			
		||||
        unichar_entry->xkeysym = xkeysym;
 | 
			
		||||
        unichar_entry->name = unichar_to_utf8 (uc);
 | 
			
		||||
        unichar_entry->category = EEK_SYMBOL_CATEGORY_LETTER;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* name and category */
 | 
			
		||||
    name = NULL;
 | 
			
		||||
    if (xkeysym_entry) {
 | 
			
		||||
        name = g_strdup (xkeysym_entry->name);
 | 
			
		||||
        category = xkeysym_entry->category;
 | 
			
		||||
    } else if (unichar_entry) {
 | 
			
		||||
        name = g_strdup (unichar_entry->name);
 | 
			
		||||
        category = unichar_entry->category;
 | 
			
		||||
    } else if (unicode_entry) {
 | 
			
		||||
        name = g_strdup (unicode_entry->name);
 | 
			
		||||
        category = unicode_entry->category;
 | 
			
		||||
    } else {
 | 
			
		||||
        name = g_strdup ("");
 | 
			
		||||
        category = EEK_SYMBOL_CATEGORY_UNKNOWN;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* label */
 | 
			
		||||
    if (special_entry)
 | 
			
		||||
        label = g_strdup (special_entry->name);
 | 
			
		||||
    else if (unichar_entry)
 | 
			
		||||
        label = g_strdup (unichar_entry->name);
 | 
			
		||||
    else if (unicode_entry)
 | 
			
		||||
        label = g_strdup (unicode_entry->name);
 | 
			
		||||
    else
 | 
			
		||||
        label = g_strdup (name);
 | 
			
		||||
 | 
			
		||||
    keysym = g_object_new (EEK_TYPE_KEYSYM,
 | 
			
		||||
                           "name", name,
 | 
			
		||||
                           "label", label,
 | 
			
		||||
                           "category", category,
 | 
			
		||||
                           "modifier-mask", modifier_mask,
 | 
			
		||||
                           NULL);
 | 
			
		||||
    g_free (name);
 | 
			
		||||
    g_free (label);
 | 
			
		||||
 | 
			
		||||
    if (unichar_entry) {
 | 
			
		||||
        g_free ((gpointer) unichar_entry->name);
 | 
			
		||||
        g_slice_free (EekKeysymEntry, unichar_entry);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    priv = eek_keysym_get_instance_private (keysym);
 | 
			
		||||
    priv->xkeysym = xkeysym;
 | 
			
		||||
 | 
			
		||||
    return keysym;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eek_keysym_new:
 | 
			
		||||
 * @xkeysym: an X keysym value
 | 
			
		||||
 *
 | 
			
		||||
 * Create an #EekKeysym with given X keysym value @xkeysym.
 | 
			
		||||
 */
 | 
			
		||||
EekKeysym *
 | 
			
		||||
eek_keysym_new (guint xkeysym)
 | 
			
		||||
{
 | 
			
		||||
    return eek_keysym_new_with_modifier (xkeysym, get_modifier_mask (xkeysym));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eek_keysym_new_from_name:
 | 
			
		||||
 * @name: an X keysym name
 | 
			
		||||
 *
 | 
			
		||||
 * Create an #EekKeysym with an X keysym value looked up by @name.
 | 
			
		||||
 */
 | 
			
		||||
EekKeysym *
 | 
			
		||||
eek_keysym_new_from_name (const gchar *name)
 | 
			
		||||
{
 | 
			
		||||
    gint i;
 | 
			
		||||
 | 
			
		||||
    for (i = 0; i < G_N_ELEMENTS(xkeysym_keysym_entries); i++)
 | 
			
		||||
        if (g_strcmp0 (xkeysym_keysym_entries[i].name, name) == 0)
 | 
			
		||||
            return eek_keysym_new (xkeysym_keysym_entries[i].xkeysym);
 | 
			
		||||
 | 
			
		||||
    // g_warning ("can't find keysym entry for %s", name);
 | 
			
		||||
    return g_object_new (EEK_TYPE_KEYSYM,
 | 
			
		||||
                         "name", name,
 | 
			
		||||
                         "label", name,
 | 
			
		||||
                         "category", EEK_SYMBOL_CATEGORY_UNKNOWN,
 | 
			
		||||
                         "modifier-mask", 0,
 | 
			
		||||
                         NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eek_keysym_get_xkeysym:
 | 
			
		||||
 * @keysym: an #EekKeysym
 | 
			
		||||
 *
 | 
			
		||||
 * Get an X keysym value associated with @keysym
 | 
			
		||||
 */
 | 
			
		||||
guint
 | 
			
		||||
eek_keysym_get_xkeysym (EekKeysym *keysym)
 | 
			
		||||
{
 | 
			
		||||
    EekKeysymPrivate *priv;
 | 
			
		||||
 | 
			
		||||
    g_assert (EEK_IS_KEYSYM(keysym));
 | 
			
		||||
    priv = eek_keysym_get_instance_private (keysym);
 | 
			
		||||
    return priv->xkeysym;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										58
									
								
								eek/eek-keysym.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										58
									
								
								eek/eek-keysym.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,58 @@
 | 
			
		||||
/* 
 | 
			
		||||
 * 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)
 | 
			
		||||
 | 
			
		||||
#define EEK_TYPE_KEYSYM (eek_keysym_get_type())
 | 
			
		||||
G_DECLARE_DERIVABLE_TYPE (EekKeysym, eek_keysym, EEK, KEYSYM, EekSymbol)
 | 
			
		||||
 | 
			
		||||
struct _EekKeysymClass {
 | 
			
		||||
    /*< private >*/
 | 
			
		||||
    EekSymbolClass parent_class;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
GType      eek_keysym_get_type          (void) G_GNUC_CONST;
 | 
			
		||||
EekKeysym *eek_keysym_new               (guint           xkeysym);
 | 
			
		||||
guint      eek_keysym_get_xkeysym       (EekKeysym      *keysym);
 | 
			
		||||
 | 
			
		||||
EekKeysym *eek_keysym_new_from_name     (const gchar    *name);
 | 
			
		||||
EekKeysym *eek_keysym_new_with_modifier (guint           xkeysym,
 | 
			
		||||
                                         EekModifierType modifier_mask);
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
 | 
			
		||||
#endif  /* EEK_KEYSYM_H */
 | 
			
		||||
@ -26,12 +26,13 @@
 | 
			
		||||
 * arranges keyboard elements.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_CONFIG_H
 | 
			
		||||
#include "config.h"
 | 
			
		||||
#endif  /* HAVE_CONFIG_H */
 | 
			
		||||
 | 
			
		||||
#include "eek-layout.h"
 | 
			
		||||
#include "eek-keyboard.h"
 | 
			
		||||
#include "eekboard/eekboard-context-service.h"
 | 
			
		||||
#include "eek-xml-layout.h"
 | 
			
		||||
 | 
			
		||||
G_DEFINE_ABSTRACT_TYPE (EekLayout, eek_layout, G_TYPE_OBJECT)
 | 
			
		||||
 | 
			
		||||
@ -45,3 +46,26 @@ 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);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -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);
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										1
									
								
								eek/eek-marshalers.list
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								eek/eek-marshalers.list
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1 @@
 | 
			
		||||
VOID:INT,INT
 | 
			
		||||
							
								
								
									
										1306
									
								
								eek/eek-renderer.c
									
									
									
									
									
								
							
							
						
						
									
										1306
									
								
								eek/eek-renderer.c
									
									
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@ -21,11 +21,12 @@
 | 
			
		||||
#ifndef EEK_RENDERER_H
 | 
			
		||||
#define EEK_RENDERER_H 1
 | 
			
		||||
 | 
			
		||||
#include <gtk/gtk.h>
 | 
			
		||||
#include <pango/pangocairo.h>
 | 
			
		||||
 | 
			
		||||
#include "eek-keyboard.h"
 | 
			
		||||
#include "eek-keysym.h"
 | 
			
		||||
#include "eek-types.h"
 | 
			
		||||
#include "eek-theme.h"
 | 
			
		||||
#include "eek-theme-context.h"
 | 
			
		||||
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
@ -36,9 +37,19 @@ struct _EekRendererClass
 | 
			
		||||
{
 | 
			
		||||
    GObjectClass parent_class;
 | 
			
		||||
 | 
			
		||||
    void             (* render_button)         (EekRenderer *self,
 | 
			
		||||
    void             (* render_key_label)   (EekRenderer *self,
 | 
			
		||||
                                             PangoLayout *layout,
 | 
			
		||||
                                             EekKey      *key);
 | 
			
		||||
 | 
			
		||||
    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);
 | 
			
		||||
 | 
			
		||||
@ -47,8 +58,7 @@ struct _EekRendererClass
 | 
			
		||||
 | 
			
		||||
    cairo_surface_t *(* get_icon_surface)   (EekRenderer *self,
 | 
			
		||||
                                             const gchar *icon_name,
 | 
			
		||||
                                             gint         size,
 | 
			
		||||
                                             gint         scale);
 | 
			
		||||
                                             gint         size);
 | 
			
		||||
 | 
			
		||||
    /*< private >*/
 | 
			
		||||
    /* padding */
 | 
			
		||||
@ -56,7 +66,7 @@ struct _EekRendererClass
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
GType            eek_renderer_get_type         (void) G_GNUC_CONST;
 | 
			
		||||
EekRenderer     *eek_renderer_new              (LevelKeyboard     *keyboard,
 | 
			
		||||
EekRenderer     *eek_renderer_new              (EekKeyboard     *keyboard,
 | 
			
		||||
                                                PangoContext    *pcontext);
 | 
			
		||||
void             eek_renderer_set_allocation_size
 | 
			
		||||
                                               (EekRenderer     *renderer,
 | 
			
		||||
@ -65,27 +75,35 @@ 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);
 | 
			
		||||
 | 
			
		||||
gdouble          eek_renderer_get_scale        (EekRenderer     *renderer);
 | 
			
		||||
void             eek_renderer_set_scale_factor (EekRenderer     *renderer,
 | 
			
		||||
                                                gint             scale);
 | 
			
		||||
 | 
			
		||||
PangoLayout     *eek_renderer_create_pango_layout
 | 
			
		||||
                                               (EekRenderer     *renderer);
 | 
			
		||||
void             eek_renderer_render_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);
 | 
			
		||||
 | 
			
		||||
cairo_surface_t *eek_renderer_get_icon_surface (EekRenderer     *renderer,
 | 
			
		||||
                                                const gchar     *icon_name,
 | 
			
		||||
                                                gint             size,
 | 
			
		||||
                                                gint             scale);
 | 
			
		||||
                                                gint             size);
 | 
			
		||||
 | 
			
		||||
void             eek_renderer_render_keyboard  (EekRenderer     *renderer,
 | 
			
		||||
                                                cairo_t         *cr);
 | 
			
		||||
@ -98,18 +116,33 @@ void             eek_renderer_set_default_background_color
 | 
			
		||||
                                                const EekColor  *color);
 | 
			
		||||
void             eek_renderer_get_foreground_color
 | 
			
		||||
                                               (EekRenderer     *renderer,
 | 
			
		||||
                                                GtkStyleContext *context,
 | 
			
		||||
                                                EekElement      *element,
 | 
			
		||||
                                                EekColor        *color);
 | 
			
		||||
void             eek_renderer_get_background_color
 | 
			
		||||
                                               (EekRenderer     *renderer,
 | 
			
		||||
                                                EekElement      *element,
 | 
			
		||||
                                                EekColor        *color);
 | 
			
		||||
void             eek_renderer_get_background_gradient
 | 
			
		||||
                                               (EekRenderer     *renderer,
 | 
			
		||||
                                                EekElement      *element,
 | 
			
		||||
                                                EekGradientType *type,
 | 
			
		||||
                                                EekColor        *start,
 | 
			
		||||
                                                EekColor        *end);
 | 
			
		||||
void             eek_renderer_set_border_width (EekRenderer     *renderer,
 | 
			
		||||
                                                gdouble          border_width);
 | 
			
		||||
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);
 | 
			
		||||
 | 
			
		||||
void             eek_renderer_set_theme        (EekRenderer     *renderer,
 | 
			
		||||
                                                EekTheme        *theme);
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
#endif  /* EEK_RENDERER_H */
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										562
									
								
								eek/eek-section.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										562
									
								
								eek/eek-section.c
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,562 @@
 | 
			
		||||
/*
 | 
			
		||||
 * 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.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_CONFIG_H
 | 
			
		||||
#include "config.h"
 | 
			
		||||
#endif  /* HAVE_CONFIG_H */
 | 
			
		||||
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
#include "eek-keyboard.h"
 | 
			
		||||
#include "eek-section.h"
 | 
			
		||||
#include "eek-key.h"
 | 
			
		||||
#include "eek-symbol.h"
 | 
			
		||||
 | 
			
		||||
enum {
 | 
			
		||||
    PROP_0,
 | 
			
		||||
    PROP_ANGLE,
 | 
			
		||||
    PROP_LAST
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
enum {
 | 
			
		||||
    KEY_LOCKED,
 | 
			
		||||
    KEY_UNLOCKED,
 | 
			
		||||
    LAST_SIGNAL
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static guint signals[LAST_SIGNAL] = { 0, };
 | 
			
		||||
 | 
			
		||||
struct _EekRow
 | 
			
		||||
{
 | 
			
		||||
    gint num_columns;
 | 
			
		||||
    EekOrientation orientation;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
typedef struct _EekRow EekRow;
 | 
			
		||||
 | 
			
		||||
typedef struct _EekSectionPrivate
 | 
			
		||||
{
 | 
			
		||||
    gint angle;
 | 
			
		||||
    GSList *rows;
 | 
			
		||||
    EekModifierType modifiers;
 | 
			
		||||
} EekSectionPrivate;
 | 
			
		||||
 | 
			
		||||
G_DEFINE_TYPE_WITH_PRIVATE (EekSection, eek_section, EEK_TYPE_CONTAINER)
 | 
			
		||||
 | 
			
		||||
static gint
 | 
			
		||||
eek_section_real_get_n_rows (EekSection *self)
 | 
			
		||||
{
 | 
			
		||||
    EekSectionPrivate *priv = eek_section_get_instance_private (self);
 | 
			
		||||
 | 
			
		||||
    return g_slist_length (priv->rows);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
eek_section_real_add_row (EekSection    *self,
 | 
			
		||||
                          gint           num_columns,
 | 
			
		||||
                          EekOrientation orientation)
 | 
			
		||||
{
 | 
			
		||||
    EekSectionPrivate *priv = eek_section_get_instance_private (self);
 | 
			
		||||
    EekRow *row;
 | 
			
		||||
 | 
			
		||||
    row = g_slice_new (EekRow);
 | 
			
		||||
    row->num_columns = num_columns;
 | 
			
		||||
    row->orientation = orientation;
 | 
			
		||||
    priv->rows = g_slist_append (priv->rows, row);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
eek_section_real_get_row (EekSection     *self,
 | 
			
		||||
                          gint            index,
 | 
			
		||||
                          gint           *num_columns,
 | 
			
		||||
                          EekOrientation *orientation)
 | 
			
		||||
{
 | 
			
		||||
    EekSectionPrivate *priv = eek_section_get_instance_private (self);
 | 
			
		||||
    EekRow *row;
 | 
			
		||||
 | 
			
		||||
    row = g_slist_nth_data (priv->rows, index);
 | 
			
		||||
    g_return_if_fail (row);
 | 
			
		||||
    if (num_columns)
 | 
			
		||||
        *num_columns = row->num_columns;
 | 
			
		||||
    if (orientation)
 | 
			
		||||
        *orientation = row->orientation;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
on_locked (EekKey     *key,
 | 
			
		||||
           EekSection *section)
 | 
			
		||||
{
 | 
			
		||||
    g_signal_emit (section, signals[KEY_LOCKED], 0, key);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
on_unlocked (EekKey     *key,
 | 
			
		||||
             EekSection *section)
 | 
			
		||||
{
 | 
			
		||||
    g_signal_emit (section, signals[KEY_UNLOCKED], 0, key);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static EekKey *
 | 
			
		||||
eek_section_real_create_key (EekSection *self,
 | 
			
		||||
                             guint       keycode,
 | 
			
		||||
                             gint        column_index,
 | 
			
		||||
                             gint        row_index)
 | 
			
		||||
{
 | 
			
		||||
    EekKey *key;
 | 
			
		||||
    gint num_rows;
 | 
			
		||||
    EekRow *row;
 | 
			
		||||
 | 
			
		||||
    num_rows = eek_section_get_n_rows (self);
 | 
			
		||||
    g_return_val_if_fail (0 <= row_index && row_index < num_rows, NULL);
 | 
			
		||||
 | 
			
		||||
    EekSectionPrivate *priv = eek_section_get_instance_private (self);
 | 
			
		||||
 | 
			
		||||
    row = g_slist_nth_data (priv->rows, row_index);
 | 
			
		||||
    if (row->num_columns < column_index + 1)
 | 
			
		||||
        row->num_columns = column_index + 1;
 | 
			
		||||
 | 
			
		||||
    key = g_object_new (EEK_TYPE_KEY,
 | 
			
		||||
                        "keycode", keycode,
 | 
			
		||||
                        "column", column_index,
 | 
			
		||||
                        "row", row_index,
 | 
			
		||||
                        NULL);
 | 
			
		||||
    g_return_val_if_fail (key, NULL);
 | 
			
		||||
 | 
			
		||||
    EEK_CONTAINER_GET_CLASS(self)->add_child (EEK_CONTAINER(self),
 | 
			
		||||
                                              EEK_ELEMENT(key));
 | 
			
		||||
 | 
			
		||||
    return key;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
set_level_from_modifiers (EekSection *self)
 | 
			
		||||
{
 | 
			
		||||
    EekSectionPrivate *priv = eek_section_get_instance_private (self);
 | 
			
		||||
    EekKeyboard *keyboard;
 | 
			
		||||
    EekModifierType num_lock_mask;
 | 
			
		||||
    gint level = -1;
 | 
			
		||||
 | 
			
		||||
    keyboard = EEK_KEYBOARD(eek_element_get_parent (EEK_ELEMENT(self)));
 | 
			
		||||
    num_lock_mask = eek_keyboard_get_num_lock_mask (keyboard);
 | 
			
		||||
    if (priv->modifiers & num_lock_mask)
 | 
			
		||||
        level = 1;
 | 
			
		||||
    eek_element_set_level (EEK_ELEMENT(self), level);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
eek_section_real_key_pressed (EekSection *self, EekKey *key)
 | 
			
		||||
{
 | 
			
		||||
    EekSectionPrivate *priv = eek_section_get_instance_private (self);
 | 
			
		||||
    EekSymbol *symbol;
 | 
			
		||||
    EekKeyboard *keyboard;
 | 
			
		||||
    EekModifierBehavior behavior;
 | 
			
		||||
    EekModifierType modifier;
 | 
			
		||||
 | 
			
		||||
    symbol = eek_key_get_symbol_with_fallback (key, 0, 0);
 | 
			
		||||
    if (!symbol)
 | 
			
		||||
        return;
 | 
			
		||||
 | 
			
		||||
    keyboard = EEK_KEYBOARD(eek_element_get_parent (EEK_ELEMENT(self)));
 | 
			
		||||
    behavior = eek_keyboard_get_modifier_behavior (keyboard);
 | 
			
		||||
    modifier = eek_symbol_get_modifier_mask (symbol);
 | 
			
		||||
    if (behavior == EEK_MODIFIER_BEHAVIOR_NONE) {
 | 
			
		||||
        priv->modifiers |= modifier;
 | 
			
		||||
        set_level_from_modifiers (self);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
eek_section_real_key_released (EekSection *self, EekKey *key)
 | 
			
		||||
{
 | 
			
		||||
    EekSectionPrivate *priv = eek_section_get_instance_private (self);
 | 
			
		||||
    EekSymbol *symbol;
 | 
			
		||||
    EekKeyboard *keyboard;
 | 
			
		||||
    EekModifierBehavior behavior;
 | 
			
		||||
    EekModifierType modifier;
 | 
			
		||||
 | 
			
		||||
    symbol = eek_key_get_symbol_with_fallback (key, 0, 0);
 | 
			
		||||
    if (!symbol)
 | 
			
		||||
        return;
 | 
			
		||||
 | 
			
		||||
    keyboard = EEK_KEYBOARD(eek_element_get_parent (EEK_ELEMENT(self)));
 | 
			
		||||
    behavior = eek_keyboard_get_modifier_behavior (keyboard);
 | 
			
		||||
    modifier = eek_symbol_get_modifier_mask (symbol);
 | 
			
		||||
    switch (behavior) {
 | 
			
		||||
    case EEK_MODIFIER_BEHAVIOR_NONE:
 | 
			
		||||
        priv->modifiers &= ~modifier;
 | 
			
		||||
        break;
 | 
			
		||||
    case EEK_MODIFIER_BEHAVIOR_LOCK:
 | 
			
		||||
        priv->modifiers ^= modifier;
 | 
			
		||||
        break;
 | 
			
		||||
    case EEK_MODIFIER_BEHAVIOR_LATCH:
 | 
			
		||||
        priv->modifiers = (priv->modifiers ^ modifier) & modifier;
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
    set_level_from_modifiers (self);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
eek_section_finalize (GObject *object)
 | 
			
		||||
{
 | 
			
		||||
    EekSection        *self = EEK_SECTION (object);
 | 
			
		||||
    EekSectionPrivate *priv = eek_section_get_instance_private (self);
 | 
			
		||||
    GSList *head;
 | 
			
		||||
 | 
			
		||||
    for (head = priv->rows; head; head = g_slist_next (head))
 | 
			
		||||
        g_slice_free (EekRow, head->data);
 | 
			
		||||
    g_slist_free (priv->rows);
 | 
			
		||||
 | 
			
		||||
    G_OBJECT_CLASS (eek_section_parent_class)->finalize (object);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
eek_section_set_property (GObject      *object,
 | 
			
		||||
                          guint         prop_id,
 | 
			
		||||
                          const GValue *value,
 | 
			
		||||
                          GParamSpec   *pspec)
 | 
			
		||||
{
 | 
			
		||||
    switch (prop_id) {
 | 
			
		||||
    case PROP_ANGLE:
 | 
			
		||||
        eek_section_set_angle (EEK_SECTION(object),
 | 
			
		||||
                               g_value_get_int (value));
 | 
			
		||||
        break;
 | 
			
		||||
    default:
 | 
			
		||||
        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
eek_section_get_property (GObject    *object,
 | 
			
		||||
                          guint       prop_id,
 | 
			
		||||
                          GValue     *value,
 | 
			
		||||
                          GParamSpec *pspec)
 | 
			
		||||
{
 | 
			
		||||
    switch (prop_id) {
 | 
			
		||||
    case PROP_ANGLE:
 | 
			
		||||
        g_value_set_int (value, eek_section_get_angle (EEK_SECTION(object)));
 | 
			
		||||
        break;
 | 
			
		||||
    default:
 | 
			
		||||
        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
eek_section_real_child_added (EekContainer *self,
 | 
			
		||||
                              EekElement   *element)
 | 
			
		||||
{
 | 
			
		||||
    g_signal_connect (element, "locked", G_CALLBACK(on_locked), self);
 | 
			
		||||
    g_signal_connect (element, "unlocked", G_CALLBACK(on_unlocked), self);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
eek_section_real_child_removed (EekContainer *self,
 | 
			
		||||
                                EekElement   *element)
 | 
			
		||||
{
 | 
			
		||||
    g_signal_handlers_disconnect_by_func (element, on_locked, self);
 | 
			
		||||
    g_signal_handlers_disconnect_by_func (element, on_unlocked, self);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
eek_section_class_init (EekSectionClass *klass)
 | 
			
		||||
{
 | 
			
		||||
    EekContainerClass *container_class = EEK_CONTAINER_CLASS (klass);
 | 
			
		||||
    GObjectClass      *gobject_class = G_OBJECT_CLASS (klass);
 | 
			
		||||
    GParamSpec        *pspec;
 | 
			
		||||
 | 
			
		||||
    klass->get_n_rows = eek_section_real_get_n_rows;
 | 
			
		||||
    klass->add_row = eek_section_real_add_row;
 | 
			
		||||
    klass->get_row = eek_section_real_get_row;
 | 
			
		||||
    klass->create_key = eek_section_real_create_key;
 | 
			
		||||
 | 
			
		||||
    /* signals */
 | 
			
		||||
    klass->key_pressed = eek_section_real_key_pressed;
 | 
			
		||||
    klass->key_released = eek_section_real_key_released;
 | 
			
		||||
 | 
			
		||||
    container_class->child_added = eek_section_real_child_added;
 | 
			
		||||
    container_class->child_removed = eek_section_real_child_removed;
 | 
			
		||||
 | 
			
		||||
    gobject_class->set_property = eek_section_set_property;
 | 
			
		||||
    gobject_class->get_property = eek_section_get_property;
 | 
			
		||||
    gobject_class->finalize     = eek_section_finalize;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * EekSection:angle:
 | 
			
		||||
     *
 | 
			
		||||
     * The rotation angle of #EekSection.
 | 
			
		||||
     */
 | 
			
		||||
    pspec = g_param_spec_int ("angle",
 | 
			
		||||
                              "Angle",
 | 
			
		||||
                              "Rotation angle of the section",
 | 
			
		||||
                              -360, 360, 0,
 | 
			
		||||
                              G_PARAM_READWRITE);
 | 
			
		||||
    g_object_class_install_property (gobject_class,
 | 
			
		||||
                                     PROP_ANGLE,
 | 
			
		||||
                                     pspec);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * EekSection::key-locked:
 | 
			
		||||
     * @section: an #EekSection
 | 
			
		||||
     * @key: an #EekKey
 | 
			
		||||
     *
 | 
			
		||||
     * The ::key-locked signal is emitted each time a key in @section
 | 
			
		||||
     * is shifted to the locked state.
 | 
			
		||||
     */
 | 
			
		||||
    signals[KEY_LOCKED] =
 | 
			
		||||
        g_signal_new (I_("key-locked"),
 | 
			
		||||
                      G_TYPE_FROM_CLASS(gobject_class),
 | 
			
		||||
                      G_SIGNAL_RUN_LAST,
 | 
			
		||||
                      G_STRUCT_OFFSET(EekSectionClass, key_locked),
 | 
			
		||||
                      NULL,
 | 
			
		||||
                      NULL,
 | 
			
		||||
                      g_cclosure_marshal_VOID__OBJECT,
 | 
			
		||||
                      G_TYPE_NONE,
 | 
			
		||||
                      1,
 | 
			
		||||
                      EEK_TYPE_KEY);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * EekSection::key-unlocked:
 | 
			
		||||
     * @section: an #EekSection
 | 
			
		||||
     * @key: an #EekKey
 | 
			
		||||
     *
 | 
			
		||||
     * The ::key-unlocked signal is emitted each time a key in @section
 | 
			
		||||
     * is shifted to the unlocked state.
 | 
			
		||||
     */
 | 
			
		||||
    signals[KEY_UNLOCKED] =
 | 
			
		||||
        g_signal_new (I_("key-unlocked"),
 | 
			
		||||
                      G_TYPE_FROM_CLASS(gobject_class),
 | 
			
		||||
                      G_SIGNAL_RUN_LAST,
 | 
			
		||||
                      G_STRUCT_OFFSET(EekSectionClass, key_unlocked),
 | 
			
		||||
                      NULL,
 | 
			
		||||
                      NULL,
 | 
			
		||||
                      g_cclosure_marshal_VOID__OBJECT,
 | 
			
		||||
                      G_TYPE_NONE,
 | 
			
		||||
                      1,
 | 
			
		||||
                      EEK_TYPE_KEY);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
eek_section_init (EekSection *self)
 | 
			
		||||
{
 | 
			
		||||
    /* void */
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eek_section_set_angle:
 | 
			
		||||
 * @section: an #EekSection
 | 
			
		||||
 * @angle: rotation angle
 | 
			
		||||
 *
 | 
			
		||||
 * Set rotation angle of @section to @angle.
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
eek_section_set_angle (EekSection  *section,
 | 
			
		||||
                       gint         angle)
 | 
			
		||||
{
 | 
			
		||||
    g_return_if_fail (EEK_IS_SECTION(section));
 | 
			
		||||
 | 
			
		||||
    EekSectionPrivate *priv = eek_section_get_instance_private (section);
 | 
			
		||||
 | 
			
		||||
    if (priv->angle != angle) {
 | 
			
		||||
        priv->angle = angle;
 | 
			
		||||
        g_object_notify (G_OBJECT(section), "angle");
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eek_section_get_angle:
 | 
			
		||||
 * @section: an #EekSection
 | 
			
		||||
 *
 | 
			
		||||
 * Get rotation angle of @section.
 | 
			
		||||
 */
 | 
			
		||||
gint
 | 
			
		||||
eek_section_get_angle (EekSection *section)
 | 
			
		||||
{
 | 
			
		||||
    g_return_val_if_fail (EEK_IS_SECTION(section), -1);
 | 
			
		||||
 | 
			
		||||
    EekSectionPrivate *priv = eek_section_get_instance_private (section);
 | 
			
		||||
 | 
			
		||||
    return priv->angle;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eek_section_get_n_rows:
 | 
			
		||||
 * @section: an #EekSection
 | 
			
		||||
 *
 | 
			
		||||
 * Get the number of rows in @section.
 | 
			
		||||
 */
 | 
			
		||||
gint
 | 
			
		||||
eek_section_get_n_rows (EekSection *section)
 | 
			
		||||
{
 | 
			
		||||
    g_return_val_if_fail (EEK_IS_SECTION(section), -1);
 | 
			
		||||
    return EEK_SECTION_GET_CLASS(section)->get_n_rows (section);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eek_section_add_row:
 | 
			
		||||
 * @section: an #EekSection
 | 
			
		||||
 * @num_columns: the number of column in the row
 | 
			
		||||
 * @orientation: #EekOrientation of the row
 | 
			
		||||
 *
 | 
			
		||||
 * Add a row which has @num_columns columns and whose orientation is
 | 
			
		||||
 * @orientation to @section.
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
eek_section_add_row (EekSection    *section,
 | 
			
		||||
                     gint           num_columns,
 | 
			
		||||
                     EekOrientation orientation)
 | 
			
		||||
{
 | 
			
		||||
    g_return_if_fail (EEK_IS_SECTION(section));
 | 
			
		||||
    EEK_SECTION_GET_CLASS(section)->add_row (section,
 | 
			
		||||
                                             num_columns,
 | 
			
		||||
                                             orientation);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eek_section_get_row:
 | 
			
		||||
 * @section: an #EekSection
 | 
			
		||||
 * @index: the index of row
 | 
			
		||||
 * @num_columns: pointer where the number of column in the row will be stored
 | 
			
		||||
 * @orientation: pointer where #EekOrientation of the row will be stored
 | 
			
		||||
 *
 | 
			
		||||
 * Get the information about the @index-th row in @section.
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
eek_section_get_row (EekSection     *section,
 | 
			
		||||
                     gint            index,
 | 
			
		||||
                     gint           *num_columns,
 | 
			
		||||
                     EekOrientation *orientation)
 | 
			
		||||
{
 | 
			
		||||
    g_return_if_fail (EEK_IS_SECTION(section));
 | 
			
		||||
    EEK_SECTION_GET_CLASS(section)->get_row (section,
 | 
			
		||||
                                             index,
 | 
			
		||||
                                             num_columns,
 | 
			
		||||
                                             orientation);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eek_section_create_key:
 | 
			
		||||
 * @section: an #EekSection
 | 
			
		||||
 * @keycode: a keycode
 | 
			
		||||
 * @column: the column index of the key
 | 
			
		||||
 * @row: the row index of the key
 | 
			
		||||
 *
 | 
			
		||||
 * Create an #EekKey instance and append it to @section.  This
 | 
			
		||||
 * function is rarely called by application but called by #EekLayout
 | 
			
		||||
 * implementation.
 | 
			
		||||
 */
 | 
			
		||||
EekKey *
 | 
			
		||||
eek_section_create_key (EekSection *section,
 | 
			
		||||
                        guint       keycode,
 | 
			
		||||
                        gint        column,
 | 
			
		||||
                        gint        row)
 | 
			
		||||
{
 | 
			
		||||
    g_return_val_if_fail (EEK_IS_SECTION(section), NULL);
 | 
			
		||||
    return EEK_SECTION_GET_CLASS(section)->create_key (section,
 | 
			
		||||
                                                       keycode,
 | 
			
		||||
                                                       column,
 | 
			
		||||
                                                       row);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void keysizer(EekElement *element, gpointer user_data) {
 | 
			
		||||
    EekKey *key = EEK_KEY(element);
 | 
			
		||||
    EekKeyboard *keyboard = EEK_KEYBOARD(user_data);
 | 
			
		||||
    uint oref = eek_key_get_oref (key);
 | 
			
		||||
    EekOutline *outline = eek_keyboard_get_outline (keyboard, oref);
 | 
			
		||||
    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);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
struct keys_info {
 | 
			
		||||
    uint count;
 | 
			
		||||
    double total_width;
 | 
			
		||||
    double biggest_height;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static void keycounter (EekElement *element, gpointer user_data) {
 | 
			
		||||
    struct keys_info *data = user_data;
 | 
			
		||||
    data->count++;
 | 
			
		||||
    EekBounds key_bounds = {0};
 | 
			
		||||
    eek_element_get_bounds(element, &key_bounds);
 | 
			
		||||
    data->total_width += key_bounds.width;
 | 
			
		||||
    if (key_bounds.height > data->biggest_height) {
 | 
			
		||||
        data->biggest_height = key_bounds.height;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const double keyspacing = 4.0;
 | 
			
		||||
 | 
			
		||||
static void keyplacer(EekElement *element, gpointer user_data) {
 | 
			
		||||
    double *current_offset = user_data;
 | 
			
		||||
    EekBounds key_bounds = {0};
 | 
			
		||||
    eek_element_get_bounds(element, &key_bounds);
 | 
			
		||||
    key_bounds.x = *current_offset;
 | 
			
		||||
    key_bounds.y = 0;
 | 
			
		||||
    eek_element_set_bounds(element, &key_bounds);
 | 
			
		||||
    *current_offset += key_bounds.width + keyspacing;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void eek_section_place_keys(EekSection *section, EekKeyboard *keyboard)
 | 
			
		||||
{
 | 
			
		||||
    eek_container_foreach_child(EEK_CONTAINER(section), keysizer, keyboard);
 | 
			
		||||
 | 
			
		||||
    struct keys_info keyinfo = {0};
 | 
			
		||||
    eek_container_foreach_child(EEK_CONTAINER(section), keycounter, &keyinfo);
 | 
			
		||||
    EekBounds section_bounds = {0};
 | 
			
		||||
    eek_element_get_bounds(EEK_ELEMENT(section), §ion_bounds);
 | 
			
		||||
 | 
			
		||||
    double key_offset = (section_bounds.width - (keyinfo.total_width + (keyinfo.count - 1) * keyspacing)) / 2;
 | 
			
		||||
    eek_container_foreach_child(EEK_CONTAINER(section), keyplacer, &key_offset);
 | 
			
		||||
 | 
			
		||||
    section_bounds.height = keyinfo.biggest_height;
 | 
			
		||||
    eek_element_set_bounds(EEK_ELEMENT(section), §ion_bounds);
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										112
									
								
								eek/eek-section.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										112
									
								
								eek/eek-section.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,112 @@
 | 
			
		||||
/* 
 | 
			
		||||
 * 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,
 | 
			
		||||
                                     guint           keycode,
 | 
			
		||||
                                     gint            row,
 | 
			
		||||
                                     gint            column);
 | 
			
		||||
 | 
			
		||||
    /* signals */
 | 
			
		||||
    void    (* key_pressed)         (EekSection     *self,
 | 
			
		||||
                                     EekKey         *key);
 | 
			
		||||
    void    (* key_released)        (EekSection     *self,
 | 
			
		||||
                                     EekKey         *key);
 | 
			
		||||
    void    (* key_locked)          (EekSection     *self,
 | 
			
		||||
                                     EekKey         *key);
 | 
			
		||||
    void    (* key_unlocked)        (EekSection     *self,
 | 
			
		||||
                                     EekKey         *key);
 | 
			
		||||
    void    (* key_cancelled)       (EekSection     *self,
 | 
			
		||||
                                     EekKey         *key);
 | 
			
		||||
 | 
			
		||||
    /*< private >*/
 | 
			
		||||
    /* padding */
 | 
			
		||||
    gpointer pdummy[19];
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
GType   eek_section_get_type             (void) G_GNUC_CONST;
 | 
			
		||||
 | 
			
		||||
void    eek_section_set_angle            (EekSection     *section,
 | 
			
		||||
                                          gint            angle);
 | 
			
		||||
gint    eek_section_get_angle            (EekSection     *section);
 | 
			
		||||
 | 
			
		||||
gint    eek_section_get_n_rows           (EekSection     *section);
 | 
			
		||||
void    eek_section_add_row              (EekSection     *section,
 | 
			
		||||
                                          gint            num_columns,
 | 
			
		||||
                                          EekOrientation  orientation);
 | 
			
		||||
void    eek_section_get_row              (EekSection     *section,
 | 
			
		||||
                                          gint            index,
 | 
			
		||||
                                          gint           *num_columns,
 | 
			
		||||
                                          EekOrientation *orientation);
 | 
			
		||||
 | 
			
		||||
EekKey *eek_section_create_key           (EekSection     *section,
 | 
			
		||||
                                          guint           keycode,
 | 
			
		||||
                                          gint            column,
 | 
			
		||||
                                          gint            row);
 | 
			
		||||
 | 
			
		||||
EekKey *eek_section_find_key_by_keycode  (EekSection     *section,
 | 
			
		||||
                                          guint           keycode);
 | 
			
		||||
 | 
			
		||||
void eek_section_place_keys              (EekSection     *section, EekKeyboard *keyboard);
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
#endif  /* EEK_SECTION_H */
 | 
			
		||||
							
								
								
									
										93
									
								
								eek/eek-serializable.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										93
									
								
								eek/eek-serializable.c
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,93 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2008-2010 Peng Huang <shawn.p.huang@gmail.com>
 | 
			
		||||
 * Copyright (C) 2008-2010 Red Hat, Inc.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is free software; you can redistribute it and/or
 | 
			
		||||
 * modify it under the terms of the GNU Lesser General Public
 | 
			
		||||
 * License as published by the Free Software Foundation; either
 | 
			
		||||
 * version 2 of the License, or (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the GNU
 | 
			
		||||
 * Lesser General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General Public
 | 
			
		||||
 * License along with this library; if not, write to the
 | 
			
		||||
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 | 
			
		||||
 * Boston, MA 02111-1307, USA.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * SECTION:eek-serializable
 | 
			
		||||
 * @short_description: Interface which provides object serialization
 | 
			
		||||
 * into #GVariant
 | 
			
		||||
 *
 | 
			
		||||
 * The #EekSerializableIface interface defines serialize/deserialize
 | 
			
		||||
 * method.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_CONFIG_H
 | 
			
		||||
#include "config.h"
 | 
			
		||||
#endif  /* HAVE_CONFIG_H */
 | 
			
		||||
 | 
			
		||||
#include "eek-serializable.h"
 | 
			
		||||
 | 
			
		||||
GType
 | 
			
		||||
eek_serializable_get_type (void)
 | 
			
		||||
{
 | 
			
		||||
    static GType iface_type = 0;
 | 
			
		||||
    if (iface_type == 0) {
 | 
			
		||||
        static const GTypeInfo info = {
 | 
			
		||||
            sizeof (EekSerializableIface),
 | 
			
		||||
            NULL,
 | 
			
		||||
            NULL,
 | 
			
		||||
        };
 | 
			
		||||
        iface_type = g_type_register_static (G_TYPE_INTERFACE,
 | 
			
		||||
                                             "EekSerializable",
 | 
			
		||||
                                             &info, 0);
 | 
			
		||||
    }
 | 
			
		||||
    return iface_type;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
GVariant *
 | 
			
		||||
eek_serializable_serialize (EekSerializable *object)
 | 
			
		||||
{
 | 
			
		||||
    GVariantBuilder builder;
 | 
			
		||||
 | 
			
		||||
    g_return_val_if_fail (EEK_IS_SERIALIZABLE (object), FALSE);
 | 
			
		||||
 | 
			
		||||
    g_variant_builder_init (&builder, G_VARIANT_TYPE_TUPLE);
 | 
			
		||||
    g_variant_builder_add (&builder, "s", g_type_name (G_OBJECT_TYPE (object)));
 | 
			
		||||
    EEK_SERIALIZABLE_GET_IFACE (object)->serialize (object, &builder);
 | 
			
		||||
 | 
			
		||||
    return g_variant_builder_end (&builder);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
EekSerializable *
 | 
			
		||||
eek_serializable_deserialize (GVariant *variant)
 | 
			
		||||
{
 | 
			
		||||
    gchar *type_name = NULL;
 | 
			
		||||
    GType type;
 | 
			
		||||
    EekSerializable *object;
 | 
			
		||||
    gsize index = 0;
 | 
			
		||||
 | 
			
		||||
    g_return_val_if_fail (variant != NULL, NULL);
 | 
			
		||||
 | 
			
		||||
    g_variant_get_child (variant, index++, "&s", &type_name);
 | 
			
		||||
    type = g_type_from_name (type_name);
 | 
			
		||||
 | 
			
		||||
    g_return_val_if_fail (g_type_is_a (type, EEK_TYPE_SERIALIZABLE), NULL);
 | 
			
		||||
 | 
			
		||||
    object = g_object_new (type, NULL);
 | 
			
		||||
 | 
			
		||||
    index = EEK_SERIALIZABLE_GET_IFACE (object)->deserialize (object,
 | 
			
		||||
                                                              variant,
 | 
			
		||||
                                                              index);
 | 
			
		||||
    if (index < 0) {
 | 
			
		||||
        g_object_unref (object);
 | 
			
		||||
        g_return_val_if_reached (NULL);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return object;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										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 */
 | 
			
		||||
							
								
								
									
										105
									
								
								eek/eek-symbol-matrix.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										105
									
								
								eek/eek-symbol-matrix.c
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,105 @@
 | 
			
		||||
/* 
 | 
			
		||||
 * Copyright (C) 2011 Daiki Ueno <ueno@unixuser.org>
 | 
			
		||||
 * Copyright (C) 2011 Red Hat, Inc.
 | 
			
		||||
 * 
 | 
			
		||||
 * This library is free software; you can redistribute it and/or
 | 
			
		||||
 * modify it under the terms of the GNU Lesser General Public License
 | 
			
		||||
 * as published by the Free Software Foundation; either version 2 of
 | 
			
		||||
 * the License, or (at your option) any later version.
 | 
			
		||||
 * 
 | 
			
		||||
 * This library is distributed in the hope that it will be useful, but
 | 
			
		||||
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
			
		||||
 * Lesser General Public License for more details.
 | 
			
		||||
 * 
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General Public
 | 
			
		||||
 * License along with this library; if not, write to the Free Software
 | 
			
		||||
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 | 
			
		||||
 * 02110-1301 USA
 | 
			
		||||
 */
 | 
			
		||||
#include "eek-symbol-matrix.h"
 | 
			
		||||
 | 
			
		||||
EekSymbolMatrix *
 | 
			
		||||
eek_symbol_matrix_new (gint num_groups,
 | 
			
		||||
                       gint num_levels)
 | 
			
		||||
{
 | 
			
		||||
    EekSymbolMatrix *matrix = g_slice_new (EekSymbolMatrix);
 | 
			
		||||
 | 
			
		||||
    matrix->num_groups = num_groups;
 | 
			
		||||
    matrix->num_levels = num_levels;
 | 
			
		||||
    matrix->data = g_slice_alloc0 (sizeof (EekSymbol *) *
 | 
			
		||||
                                   num_groups * num_levels);
 | 
			
		||||
    return matrix;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
EekSymbolMatrix *
 | 
			
		||||
eek_symbol_matrix_copy (const EekSymbolMatrix *matrix)
 | 
			
		||||
{
 | 
			
		||||
    EekSymbolMatrix *retval;
 | 
			
		||||
    gint i, num_symbols = matrix->num_groups * matrix->num_levels;
 | 
			
		||||
 | 
			
		||||
    retval = g_slice_dup (EekSymbolMatrix, matrix);
 | 
			
		||||
    retval->data = g_slice_copy (sizeof (EekSymbol *) * num_symbols,
 | 
			
		||||
                                 matrix->data);
 | 
			
		||||
    for (i = 0; i < num_symbols; i++)
 | 
			
		||||
        if (retval->data[i])
 | 
			
		||||
            g_object_ref (retval->data[i]);
 | 
			
		||||
    return retval;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
eek_symbol_matrix_free (EekSymbolMatrix *matrix)
 | 
			
		||||
{
 | 
			
		||||
    gint i, num_symbols = matrix->num_groups * matrix->num_levels;
 | 
			
		||||
    for (i = 0; i < num_symbols; i++)
 | 
			
		||||
        if (matrix->data[i])
 | 
			
		||||
            g_object_unref (matrix->data[i]);
 | 
			
		||||
    g_slice_free1 (sizeof (EekSymbol *) * num_symbols, matrix->data);
 | 
			
		||||
    g_slice_free (EekSymbolMatrix, matrix);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
GType
 | 
			
		||||
eek_symbol_matrix_get_type (void)
 | 
			
		||||
{
 | 
			
		||||
    static GType our_type = 0;
 | 
			
		||||
 | 
			
		||||
    if (our_type == 0)
 | 
			
		||||
        our_type =
 | 
			
		||||
            g_boxed_type_register_static ("EekSymbolMatrix",
 | 
			
		||||
                                          (GBoxedCopyFunc)eek_symbol_matrix_copy,
 | 
			
		||||
                                          (GBoxedFreeFunc)eek_symbol_matrix_free);
 | 
			
		||||
    return our_type;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
eek_symbol_matrix_set_symbol (EekSymbolMatrix *matrix,
 | 
			
		||||
                              gint             group,
 | 
			
		||||
                              gint             level,
 | 
			
		||||
                              EekSymbol       *symbol)
 | 
			
		||||
{
 | 
			
		||||
    g_return_if_fail (group >= 0 && group < matrix->num_groups);
 | 
			
		||||
    g_return_if_fail (level >= 0 && level < matrix->num_levels);
 | 
			
		||||
    g_return_if_fail (EEK_IS_SYMBOL(symbol));
 | 
			
		||||
    matrix->data[group * matrix->num_levels + level] = g_object_ref (symbol);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eek_symbol_matrix_get_symbol:
 | 
			
		||||
 * @matrix: an #EekSymbolMatrix
 | 
			
		||||
 * @group: group index of @matrix
 | 
			
		||||
 * @level: level index of @matrix
 | 
			
		||||
 *
 | 
			
		||||
 * Get an #EekSymbol stored in the cell selected by (@group, @level)
 | 
			
		||||
 * in @matrix.
 | 
			
		||||
 *
 | 
			
		||||
 * Return value: (transfer none): an #EekSymbol.
 | 
			
		||||
 */
 | 
			
		||||
EekSymbol *
 | 
			
		||||
eek_symbol_matrix_get_symbol (EekSymbolMatrix *matrix,
 | 
			
		||||
                              gint             group,
 | 
			
		||||
                              gint             level)
 | 
			
		||||
{
 | 
			
		||||
    g_return_val_if_fail (group >= 0 && group < matrix->num_groups, NULL);
 | 
			
		||||
    g_return_val_if_fail (level >= 0 && level < matrix->num_levels, NULL);
 | 
			
		||||
    return matrix->data[group * matrix->num_levels + level];
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										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 */
 | 
			
		||||
							
								
								
									
										445
									
								
								eek/eek-symbol.c
									
									
									
									
									
								
							
							
						
						
									
										445
									
								
								eek/eek-symbol.c
									
									
									
									
									
								
							@ -25,18 +25,275 @@
 | 
			
		||||
 * The #EekSymbolClass class represents a symbol assigned to a key.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_CONFIG_H
 | 
			
		||||
#include "config.h"
 | 
			
		||||
#endif  /* HAVE_CONFIG_H */
 | 
			
		||||
 | 
			
		||||
#include "eek-symbol.h"
 | 
			
		||||
#include "eek-serializable.h"
 | 
			
		||||
#include "eek-enumtypes.h"
 | 
			
		||||
 | 
			
		||||
enum {
 | 
			
		||||
    PROP_0,
 | 
			
		||||
    PROP_NAME,
 | 
			
		||||
    PROP_LABEL,
 | 
			
		||||
    PROP_CATEGORY,
 | 
			
		||||
    PROP_MODIFIER_MASK,
 | 
			
		||||
    PROP_ICON_NAME,
 | 
			
		||||
    PROP_TOOLTIP,
 | 
			
		||||
    PROP_LAST
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
typedef struct _EekSymbolPrivate
 | 
			
		||||
{
 | 
			
		||||
    gchar *name;
 | 
			
		||||
    gchar *label;
 | 
			
		||||
    EekSymbolCategory category;
 | 
			
		||||
    EekModifierType modifier_mask;
 | 
			
		||||
    gchar *icon_name;
 | 
			
		||||
    gchar *tooltip;
 | 
			
		||||
} EekSymbolPrivate;
 | 
			
		||||
 | 
			
		||||
static void eek_serializable_iface_init (EekSerializableIface *iface);
 | 
			
		||||
 | 
			
		||||
G_DEFINE_TYPE_EXTENDED (EekSymbol,
 | 
			
		||||
			eek_symbol,
 | 
			
		||||
			G_TYPE_OBJECT,
 | 
			
		||||
			0, /* GTypeFlags */
 | 
			
		||||
			G_ADD_PRIVATE (EekSymbol)
 | 
			
		||||
                        G_IMPLEMENT_INTERFACE (EEK_TYPE_SERIALIZABLE,
 | 
			
		||||
                                               eek_serializable_iface_init))
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
eek_symbol_real_serialize (EekSerializable *self,
 | 
			
		||||
                           GVariantBuilder *builder)
 | 
			
		||||
{
 | 
			
		||||
    EekSymbolPrivate *priv = eek_symbol_get_instance_private (EEK_SYMBOL (self));
 | 
			
		||||
#define NOTNULL(s) ((s) != NULL ? (s) : "")
 | 
			
		||||
    g_variant_builder_add (builder, "s", NOTNULL(priv->name));
 | 
			
		||||
    g_variant_builder_add (builder, "s", NOTNULL(priv->label));
 | 
			
		||||
    g_variant_builder_add (builder, "u", priv->category);
 | 
			
		||||
    g_variant_builder_add (builder, "u", priv->modifier_mask);
 | 
			
		||||
    g_variant_builder_add (builder, "s", NOTNULL(priv->icon_name));
 | 
			
		||||
    g_variant_builder_add (builder, "s", NOTNULL(priv->tooltip));
 | 
			
		||||
#undef NOTNULL
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gsize
 | 
			
		||||
eek_symbol_real_deserialize (EekSerializable *self,
 | 
			
		||||
                             GVariant        *variant,
 | 
			
		||||
                             gsize            index)
 | 
			
		||||
{
 | 
			
		||||
    EekSymbolPrivate *priv = eek_symbol_get_instance_private (EEK_SYMBOL (self));
 | 
			
		||||
 | 
			
		||||
    g_variant_get_child (variant, index++, "s", &priv->name);
 | 
			
		||||
    g_variant_get_child (variant, index++, "s", &priv->label);
 | 
			
		||||
    g_variant_get_child (variant, index++, "u", &priv->category);
 | 
			
		||||
    g_variant_get_child (variant, index++, "u", &priv->modifier_mask);
 | 
			
		||||
    g_variant_get_child (variant, index++, "s", &priv->icon_name);
 | 
			
		||||
    g_variant_get_child (variant, index++, "s", &priv->tooltip);
 | 
			
		||||
 | 
			
		||||
    return index;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
eek_serializable_iface_init (EekSerializableIface *iface)
 | 
			
		||||
{
 | 
			
		||||
    iface->serialize = eek_symbol_real_serialize;
 | 
			
		||||
    iface->deserialize = eek_symbol_real_deserialize;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
eek_symbol_set_property (GObject      *object,
 | 
			
		||||
                         guint         prop_id,
 | 
			
		||||
                         const GValue *value,
 | 
			
		||||
                         GParamSpec   *pspec)
 | 
			
		||||
{
 | 
			
		||||
    switch (prop_id) {
 | 
			
		||||
    case PROP_NAME:
 | 
			
		||||
        eek_symbol_set_name (EEK_SYMBOL(object), g_value_get_string (value));
 | 
			
		||||
        break;
 | 
			
		||||
    case PROP_LABEL:
 | 
			
		||||
        eek_symbol_set_label (EEK_SYMBOL(object), g_value_get_string (value));
 | 
			
		||||
        break;
 | 
			
		||||
    case PROP_CATEGORY:
 | 
			
		||||
        eek_symbol_set_category (EEK_SYMBOL(object), g_value_get_enum (value));
 | 
			
		||||
        break;
 | 
			
		||||
    case PROP_MODIFIER_MASK:
 | 
			
		||||
        eek_symbol_set_modifier_mask (EEK_SYMBOL(object),
 | 
			
		||||
                                      g_value_get_flags (value));
 | 
			
		||||
        break;
 | 
			
		||||
    case PROP_ICON_NAME:
 | 
			
		||||
        eek_symbol_set_icon_name (EEK_SYMBOL(object),
 | 
			
		||||
                                  g_value_get_string (value));
 | 
			
		||||
        break;
 | 
			
		||||
    case PROP_TOOLTIP:
 | 
			
		||||
        eek_symbol_set_tooltip (EEK_SYMBOL(object),
 | 
			
		||||
                                g_value_get_string (value));
 | 
			
		||||
        break;
 | 
			
		||||
    default:
 | 
			
		||||
        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
eek_symbol_get_property (GObject    *object,
 | 
			
		||||
                         guint       prop_id,
 | 
			
		||||
                         GValue     *value,
 | 
			
		||||
                         GParamSpec *pspec)
 | 
			
		||||
{
 | 
			
		||||
    switch (prop_id) {
 | 
			
		||||
    case PROP_NAME:
 | 
			
		||||
        g_value_set_string (value, eek_symbol_get_name (EEK_SYMBOL(object)));
 | 
			
		||||
        break;
 | 
			
		||||
    case PROP_LABEL:
 | 
			
		||||
        g_value_set_string (value, eek_symbol_get_label (EEK_SYMBOL(object)));
 | 
			
		||||
        break;
 | 
			
		||||
    case PROP_CATEGORY:
 | 
			
		||||
        g_value_set_enum (value, eek_symbol_get_category (EEK_SYMBOL(object)));
 | 
			
		||||
        break;
 | 
			
		||||
    case PROP_MODIFIER_MASK:
 | 
			
		||||
        g_value_set_flags (value,
 | 
			
		||||
                           eek_symbol_get_modifier_mask (EEK_SYMBOL(object)));
 | 
			
		||||
        break;
 | 
			
		||||
    case PROP_ICON_NAME:
 | 
			
		||||
        g_value_set_string (value,
 | 
			
		||||
                            eek_symbol_get_icon_name (EEK_SYMBOL(object)));
 | 
			
		||||
        break;
 | 
			
		||||
    case PROP_TOOLTIP:
 | 
			
		||||
        g_value_set_string (value,
 | 
			
		||||
                            eek_symbol_get_tooltip (EEK_SYMBOL(object)));
 | 
			
		||||
        break;
 | 
			
		||||
    default:
 | 
			
		||||
        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
eek_symbol_finalize (GObject *object)
 | 
			
		||||
{
 | 
			
		||||
    EekSymbol        *self = EEK_SYMBOL (object);
 | 
			
		||||
    EekSymbolPrivate *priv = eek_symbol_get_instance_private (self);
 | 
			
		||||
 | 
			
		||||
    g_free (priv->name);
 | 
			
		||||
    g_free (priv->label);
 | 
			
		||||
    g_free (priv->icon_name);
 | 
			
		||||
    g_free (priv->tooltip);
 | 
			
		||||
    G_OBJECT_CLASS (eek_symbol_parent_class)->finalize (object);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
eek_symbol_class_init (EekSymbolClass *klass)
 | 
			
		||||
{
 | 
			
		||||
    GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
 | 
			
		||||
    GParamSpec *pspec;
 | 
			
		||||
 | 
			
		||||
    gobject_class->set_property = eek_symbol_set_property;
 | 
			
		||||
    gobject_class->get_property = eek_symbol_get_property;
 | 
			
		||||
    gobject_class->finalize = eek_symbol_finalize;
 | 
			
		||||
 | 
			
		||||
    pspec = g_param_spec_string ("name",
 | 
			
		||||
                                 "Name",
 | 
			
		||||
                                 "Canonical name of the symbol",
 | 
			
		||||
                                 NULL,
 | 
			
		||||
                                 G_PARAM_CONSTRUCT | G_PARAM_READWRITE);
 | 
			
		||||
    g_object_class_install_property (gobject_class, PROP_NAME, pspec);
 | 
			
		||||
 | 
			
		||||
    pspec = g_param_spec_string ("label",
 | 
			
		||||
                                 "Label",
 | 
			
		||||
                                 "Text used to display the symbol",
 | 
			
		||||
                                 NULL,
 | 
			
		||||
                                 G_PARAM_CONSTRUCT | G_PARAM_READWRITE);
 | 
			
		||||
    g_object_class_install_property (gobject_class, PROP_LABEL, pspec);
 | 
			
		||||
 | 
			
		||||
    pspec = g_param_spec_enum ("category",
 | 
			
		||||
                               "Category",
 | 
			
		||||
                               "Category of the symbol",
 | 
			
		||||
                               EEK_TYPE_SYMBOL_CATEGORY,
 | 
			
		||||
                               EEK_SYMBOL_CATEGORY_UNKNOWN,
 | 
			
		||||
                               G_PARAM_CONSTRUCT | G_PARAM_READWRITE);
 | 
			
		||||
    g_object_class_install_property (gobject_class, PROP_CATEGORY, pspec);
 | 
			
		||||
 | 
			
		||||
    pspec = g_param_spec_flags ("modifier-mask",
 | 
			
		||||
                                "Modifier mask",
 | 
			
		||||
                                "Modifier mask of the symbol",
 | 
			
		||||
                                EEK_TYPE_MODIFIER_TYPE,
 | 
			
		||||
                                0,
 | 
			
		||||
                                G_PARAM_CONSTRUCT | G_PARAM_READWRITE);
 | 
			
		||||
    g_object_class_install_property (gobject_class, PROP_MODIFIER_MASK, pspec);
 | 
			
		||||
 | 
			
		||||
    pspec = g_param_spec_string ("icon-name",
 | 
			
		||||
                                 "Icon name",
 | 
			
		||||
                                 "Icon name used to render the symbol",
 | 
			
		||||
                                 NULL,
 | 
			
		||||
                                 G_PARAM_CONSTRUCT | G_PARAM_READWRITE);
 | 
			
		||||
    g_object_class_install_property (gobject_class, PROP_ICON_NAME, pspec);
 | 
			
		||||
 | 
			
		||||
    pspec = g_param_spec_string ("tooltip",
 | 
			
		||||
                                 "Tooltip",
 | 
			
		||||
                                 "Tooltip text",
 | 
			
		||||
                                 NULL,
 | 
			
		||||
                                 G_PARAM_CONSTRUCT | G_PARAM_READWRITE);
 | 
			
		||||
    g_object_class_install_property (gobject_class, PROP_TOOLTIP, pspec);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
eek_symbol_init (EekSymbol *self)
 | 
			
		||||
{
 | 
			
		||||
    EekSymbolPrivate *priv = eek_symbol_get_instance_private (self);
 | 
			
		||||
 | 
			
		||||
    priv->category = EEK_SYMBOL_CATEGORY_UNKNOWN;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eek_symbol_new:
 | 
			
		||||
 * @name: name of the symbol
 | 
			
		||||
 *
 | 
			
		||||
 * Create a new #EekSymbol with @name.
 | 
			
		||||
 */
 | 
			
		||||
EekSymbol *
 | 
			
		||||
eek_symbol_new (const gchar *name)
 | 
			
		||||
{
 | 
			
		||||
    EekSymbol *self = g_new0(EekSymbol, 1);
 | 
			
		||||
    self->name = g_strdup (name);
 | 
			
		||||
    self->category = EEK_SYMBOL_CATEGORY_UNKNOWN;
 | 
			
		||||
    return self;
 | 
			
		||||
    return g_object_new (EEK_TYPE_SYMBOL, "name", name, NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eek_symbol_set_name:
 | 
			
		||||
 * @symbol: an #EekSymbol
 | 
			
		||||
 * @name: name of the symbol
 | 
			
		||||
 *
 | 
			
		||||
 * Set the name of @symbol to @name.
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
eek_symbol_set_name (EekSymbol   *symbol,
 | 
			
		||||
                     const gchar *name)
 | 
			
		||||
{
 | 
			
		||||
    g_return_if_fail (EEK_IS_SYMBOL(symbol));
 | 
			
		||||
 | 
			
		||||
    EekSymbolPrivate *priv = eek_symbol_get_instance_private (symbol);
 | 
			
		||||
 | 
			
		||||
    g_free (priv->name);
 | 
			
		||||
    priv->name = g_strdup (name);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eek_symbol_get_name:
 | 
			
		||||
 * @symbol: an #EekSymbol
 | 
			
		||||
 *
 | 
			
		||||
 * Get the name of @symbol.
 | 
			
		||||
 */
 | 
			
		||||
const gchar *
 | 
			
		||||
eek_symbol_get_name (EekSymbol *symbol)
 | 
			
		||||
{
 | 
			
		||||
    g_return_val_if_fail (EEK_IS_SYMBOL(symbol), NULL);
 | 
			
		||||
 | 
			
		||||
    EekSymbolPrivate *priv = eek_symbol_get_instance_private (symbol);
 | 
			
		||||
 | 
			
		||||
    if (priv->name == NULL || *priv->name == '\0')
 | 
			
		||||
        return NULL;
 | 
			
		||||
    return priv->name;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@ -50,8 +307,64 @@ void
 | 
			
		||||
eek_symbol_set_label (EekSymbol   *symbol,
 | 
			
		||||
                      const gchar *label)
 | 
			
		||||
{
 | 
			
		||||
    g_free (symbol->label);
 | 
			
		||||
    symbol->label = g_strdup (label);
 | 
			
		||||
    g_return_if_fail (EEK_IS_SYMBOL(symbol));
 | 
			
		||||
 | 
			
		||||
    EekSymbolPrivate *priv = eek_symbol_get_instance_private (symbol);
 | 
			
		||||
 | 
			
		||||
    g_free (priv->label);
 | 
			
		||||
    priv->label = g_strdup (label);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eek_symbol_get_label:
 | 
			
		||||
 * @symbol: an #EekSymbol
 | 
			
		||||
 *
 | 
			
		||||
 * Get the label text of @symbol.
 | 
			
		||||
 */
 | 
			
		||||
const gchar *
 | 
			
		||||
eek_symbol_get_label (EekSymbol *symbol)
 | 
			
		||||
{
 | 
			
		||||
    g_return_val_if_fail (EEK_IS_SYMBOL(symbol), NULL);
 | 
			
		||||
 | 
			
		||||
    EekSymbolPrivate *priv = eek_symbol_get_instance_private (symbol);
 | 
			
		||||
 | 
			
		||||
    if (priv->label == NULL || *priv->label == '\0')
 | 
			
		||||
        return NULL;
 | 
			
		||||
    return priv->label;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eek_symbol_set_category:
 | 
			
		||||
 * @symbol: an #EekSymbol
 | 
			
		||||
 * @category: an #EekSymbolCategory
 | 
			
		||||
 *
 | 
			
		||||
 * Set symbol category of @symbol to @category.
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
eek_symbol_set_category (EekSymbol        *symbol,
 | 
			
		||||
                         EekSymbolCategory category)
 | 
			
		||||
{
 | 
			
		||||
    g_return_if_fail (EEK_IS_SYMBOL(symbol));
 | 
			
		||||
 | 
			
		||||
    EekSymbolPrivate *priv = eek_symbol_get_instance_private (symbol);
 | 
			
		||||
 | 
			
		||||
    priv->category = category;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eek_symbol_get_category:
 | 
			
		||||
 * @symbol: an #EekSymbol
 | 
			
		||||
 *
 | 
			
		||||
 * Get symbol category of @symbol.
 | 
			
		||||
 */
 | 
			
		||||
EekSymbolCategory
 | 
			
		||||
eek_symbol_get_category (EekSymbol *symbol)
 | 
			
		||||
{
 | 
			
		||||
    g_return_val_if_fail (EEK_IS_SYMBOL(symbol), EEK_SYMBOL_CATEGORY_UNKNOWN);
 | 
			
		||||
 | 
			
		||||
    EekSymbolPrivate *priv = eek_symbol_get_instance_private (symbol);
 | 
			
		||||
 | 
			
		||||
    return priv->category;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@ -65,7 +378,11 @@ void
 | 
			
		||||
eek_symbol_set_modifier_mask (EekSymbol      *symbol,
 | 
			
		||||
                              EekModifierType mask)
 | 
			
		||||
{
 | 
			
		||||
    symbol->modifier_mask = mask;
 | 
			
		||||
    g_return_if_fail (EEK_IS_SYMBOL(symbol));
 | 
			
		||||
 | 
			
		||||
    EekSymbolPrivate *priv = eek_symbol_get_instance_private (symbol);
 | 
			
		||||
 | 
			
		||||
    priv->modifier_mask = mask;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@ -77,37 +394,131 @@ eek_symbol_set_modifier_mask (EekSymbol      *symbol,
 | 
			
		||||
EekModifierType
 | 
			
		||||
eek_symbol_get_modifier_mask (EekSymbol *symbol)
 | 
			
		||||
{
 | 
			
		||||
    return 0;
 | 
			
		||||
    return symbol->modifier_mask;
 | 
			
		||||
    g_return_val_if_fail (EEK_IS_SYMBOL(symbol), 0);
 | 
			
		||||
 | 
			
		||||
    EekSymbolPrivate *priv = eek_symbol_get_instance_private (symbol);
 | 
			
		||||
 | 
			
		||||
    return priv->modifier_mask;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eek_symbol_is_modifier:
 | 
			
		||||
 * @symbol: an #EekSymbol
 | 
			
		||||
 *
 | 
			
		||||
 * Check if @symbol is a modifier.
 | 
			
		||||
 * Returns: %TRUE if @symbol is a modifier.
 | 
			
		||||
 */
 | 
			
		||||
gboolean
 | 
			
		||||
eek_symbol_is_modifier (EekSymbol *symbol)
 | 
			
		||||
{
 | 
			
		||||
    return eek_symbol_get_modifier_mask (symbol) != 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eek_symbol_set_icon_name:
 | 
			
		||||
 * @symbol: an #EekSymbol
 | 
			
		||||
 * @icon_name: icon name of @symbol
 | 
			
		||||
 *
 | 
			
		||||
 * Set the icon name of @symbol to @icon_name.
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
eek_symbol_set_icon_name (EekSymbol   *symbol,
 | 
			
		||||
                          const gchar *icon_name)
 | 
			
		||||
{
 | 
			
		||||
    g_free (symbol->icon_name);
 | 
			
		||||
    symbol->icon_name = g_strdup (icon_name);
 | 
			
		||||
    g_return_if_fail (EEK_IS_SYMBOL(symbol));
 | 
			
		||||
 | 
			
		||||
    EekSymbolPrivate *priv = eek_symbol_get_instance_private (symbol);
 | 
			
		||||
 | 
			
		||||
    g_free (priv->icon_name);
 | 
			
		||||
    priv->icon_name = g_strdup (icon_name);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eek_symbol_get_icon_name:
 | 
			
		||||
 * @symbol: an #EekSymbol
 | 
			
		||||
 *
 | 
			
		||||
 * Get the icon name of @symbol.
 | 
			
		||||
 */
 | 
			
		||||
const gchar *
 | 
			
		||||
eek_symbol_get_icon_name (EekSymbol *symbol)
 | 
			
		||||
{
 | 
			
		||||
    return NULL;
 | 
			
		||||
    g_return_val_if_fail (EEK_IS_SYMBOL(symbol), NULL);
 | 
			
		||||
 | 
			
		||||
    EekSymbolPrivate *priv = eek_symbol_get_instance_private (symbol);
 | 
			
		||||
 | 
			
		||||
    if (priv->icon_name == NULL || *priv->icon_name == '\0')
 | 
			
		||||
        return NULL;
 | 
			
		||||
    return priv->icon_name;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eek_symbol_set_tooltip:
 | 
			
		||||
 * @symbol: an #EekSymbol
 | 
			
		||||
 * @tooltip: icon name of @symbol
 | 
			
		||||
 *
 | 
			
		||||
 * Set the tooltip text of @symbol to @tooltip.
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
eek_symbol_set_tooltip (EekSymbol   *symbol,
 | 
			
		||||
                        const gchar *tooltip)
 | 
			
		||||
{
 | 
			
		||||
    g_free (symbol->tooltip);
 | 
			
		||||
    symbol->tooltip = g_strdup (tooltip);
 | 
			
		||||
    g_return_if_fail (EEK_IS_SYMBOL(symbol));
 | 
			
		||||
 | 
			
		||||
    EekSymbolPrivate *priv = eek_symbol_get_instance_private (symbol);
 | 
			
		||||
 | 
			
		||||
    g_free (priv->tooltip);
 | 
			
		||||
    priv->tooltip = g_strdup (tooltip);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eek_symbol_get_tooltip:
 | 
			
		||||
 * @symbol: an #EekSymbol
 | 
			
		||||
 *
 | 
			
		||||
 * Get the tooltip text of @symbol.
 | 
			
		||||
 */
 | 
			
		||||
const gchar *
 | 
			
		||||
eek_symbol_get_tooltip (EekSymbol *symbol)
 | 
			
		||||
{
 | 
			
		||||
    return NULL;
 | 
			
		||||
    if (symbol->tooltip == NULL || *symbol->tooltip == '\0')
 | 
			
		||||
    g_return_val_if_fail (EEK_IS_SYMBOL(symbol), NULL);
 | 
			
		||||
 | 
			
		||||
    EekSymbolPrivate *priv = eek_symbol_get_instance_private (symbol);
 | 
			
		||||
 | 
			
		||||
    if (priv->tooltip == NULL || *priv->tooltip == '\0')
 | 
			
		||||
        return NULL;
 | 
			
		||||
    return symbol->tooltip;
 | 
			
		||||
    return priv->tooltip;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static const struct {
 | 
			
		||||
    EekSymbolCategory category;
 | 
			
		||||
    gchar *name;
 | 
			
		||||
} category_names[] = {
 | 
			
		||||
    { EEK_SYMBOL_CATEGORY_LETTER, "letter" },
 | 
			
		||||
    { EEK_SYMBOL_CATEGORY_FUNCTION, "function" },
 | 
			
		||||
    { EEK_SYMBOL_CATEGORY_KEYNAME, "keyname" },
 | 
			
		||||
    { EEK_SYMBOL_CATEGORY_USER0, "user0" },
 | 
			
		||||
    { EEK_SYMBOL_CATEGORY_USER1, "user1" },
 | 
			
		||||
    { EEK_SYMBOL_CATEGORY_USER2, "user2" },
 | 
			
		||||
    { EEK_SYMBOL_CATEGORY_USER3, "user3" },
 | 
			
		||||
    { EEK_SYMBOL_CATEGORY_USER4, "user4" },
 | 
			
		||||
    { EEK_SYMBOL_CATEGORY_UNKNOWN, NULL }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const gchar *
 | 
			
		||||
eek_symbol_category_get_name (EekSymbolCategory category)
 | 
			
		||||
{
 | 
			
		||||
    gint i;
 | 
			
		||||
    for (i = 0; i < G_N_ELEMENTS(category_names); i++)
 | 
			
		||||
        if (category_names[i].category == category)
 | 
			
		||||
            return category_names[i].name;
 | 
			
		||||
    return NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
EekSymbolCategory
 | 
			
		||||
eek_symbol_category_from_name (const gchar *name)
 | 
			
		||||
{
 | 
			
		||||
    gint i;
 | 
			
		||||
    for (i = 0; i < G_N_ELEMENTS(category_names); i++)
 | 
			
		||||
        if (g_strcmp0 (category_names[i].name, name) == 0)
 | 
			
		||||
            return category_names[i].category;
 | 
			
		||||
    return EEK_SYMBOL_CATEGORY_UNKNOWN;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										100
									
								
								eek/eek-symbol.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										100
									
								
								eek/eek-symbol.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,100 @@
 | 
			
		||||
/* 
 | 
			
		||||
 * Copyright (C) 2011 Daiki Ueno <ueno@unixuser.org>
 | 
			
		||||
 * Copyright (C) 2011 Red Hat, Inc.
 | 
			
		||||
 * 
 | 
			
		||||
 * This library is free software; you can redistribute it and/or
 | 
			
		||||
 * modify it under the terms of the GNU Lesser General Public License
 | 
			
		||||
 * as published by the Free Software Foundation; either version 2 of
 | 
			
		||||
 * the License, or (at your option) any later version.
 | 
			
		||||
 * 
 | 
			
		||||
 * This library is distributed in the hope that it will be useful, but
 | 
			
		||||
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
			
		||||
 * Lesser General Public License for more details.
 | 
			
		||||
 * 
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General Public
 | 
			
		||||
 * License along with this library; if not, write to the Free Software
 | 
			
		||||
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 | 
			
		||||
 * 02110-1301 USA
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#if !defined(__EEK_H_INSIDE__) && !defined(EEK_COMPILATION)
 | 
			
		||||
#error "Only <eek/eek.h> can be included directly."
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef EEK_SYMBOL_H
 | 
			
		||||
#define EEK_SYMBOL_H 1
 | 
			
		||||
 | 
			
		||||
#include "eek-types.h"
 | 
			
		||||
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * EekSymbolCategory:
 | 
			
		||||
 * @EEK_SYMBOL_CATEGORY_LETTER: the symbol represents an alphabet letter
 | 
			
		||||
 * @EEK_SYMBOL_CATEGORY_FUNCTION: the symbol represents a function
 | 
			
		||||
 * @EEK_SYMBOL_CATEGORY_KEYNAME: the symbol does not have meaning but
 | 
			
		||||
 * have a name
 | 
			
		||||
 * @EEK_SYMBOL_CATEGORY_USER0: reserved for future use
 | 
			
		||||
 * @EEK_SYMBOL_CATEGORY_USER1: reserved for future use
 | 
			
		||||
 * @EEK_SYMBOL_CATEGORY_USER2: reserved for future use
 | 
			
		||||
 * @EEK_SYMBOL_CATEGORY_USER3: reserved for future use
 | 
			
		||||
 * @EEK_SYMBOL_CATEGORY_USER4: reserved for future use
 | 
			
		||||
 * @EEK_SYMBOL_CATEGORY_UNKNOWN: used for error reporting
 | 
			
		||||
 * @EEK_SYMBOL_CATEGORY_LAST: the last symbol category
 | 
			
		||||
 *
 | 
			
		||||
 * Category of the key symbols.
 | 
			
		||||
 */
 | 
			
		||||
typedef enum {
 | 
			
		||||
    EEK_SYMBOL_CATEGORY_LETTER,
 | 
			
		||||
    EEK_SYMBOL_CATEGORY_FUNCTION,
 | 
			
		||||
    EEK_SYMBOL_CATEGORY_KEYNAME,
 | 
			
		||||
    EEK_SYMBOL_CATEGORY_USER0,
 | 
			
		||||
    EEK_SYMBOL_CATEGORY_USER1,
 | 
			
		||||
    EEK_SYMBOL_CATEGORY_USER2,
 | 
			
		||||
    EEK_SYMBOL_CATEGORY_USER3,
 | 
			
		||||
    EEK_SYMBOL_CATEGORY_USER4,
 | 
			
		||||
    EEK_SYMBOL_CATEGORY_UNKNOWN,
 | 
			
		||||
    EEK_SYMBOL_CATEGORY_LAST = EEK_SYMBOL_CATEGORY_UNKNOWN
 | 
			
		||||
} EekSymbolCategory;
 | 
			
		||||
 | 
			
		||||
#define EEK_TYPE_SYMBOL (eek_symbol_get_type())
 | 
			
		||||
G_DECLARE_DERIVABLE_TYPE(EekSymbol, eek_symbol, EEK, SYMBOL, GObject)
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * EekSymbolClass:
 | 
			
		||||
 */
 | 
			
		||||
struct _EekSymbolClass {
 | 
			
		||||
    /*< private >*/
 | 
			
		||||
    GObjectClass parent_class;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
GType             eek_symbol_get_type           (void) G_GNUC_CONST;
 | 
			
		||||
 | 
			
		||||
EekSymbol        *eek_symbol_new                (const gchar      *name);
 | 
			
		||||
void              eek_symbol_set_name           (EekSymbol        *symbol,
 | 
			
		||||
                                                 const gchar      *name);
 | 
			
		||||
const gchar      *eek_symbol_get_name           (EekSymbol        *symbol);
 | 
			
		||||
void              eek_symbol_set_label          (EekSymbol        *symbol,
 | 
			
		||||
                                                 const gchar      *label);
 | 
			
		||||
const gchar      *eek_symbol_get_label          (EekSymbol        *symbol);
 | 
			
		||||
void              eek_symbol_set_category       (EekSymbol        *symbol,
 | 
			
		||||
                                                 EekSymbolCategory category);
 | 
			
		||||
EekSymbolCategory eek_symbol_get_category       (EekSymbol        *symbol);
 | 
			
		||||
EekModifierType   eek_symbol_get_modifier_mask  (EekSymbol        *symbol);
 | 
			
		||||
void              eek_symbol_set_modifier_mask  (EekSymbol        *symbol,
 | 
			
		||||
                                                 EekModifierType   mask);
 | 
			
		||||
gboolean          eek_symbol_is_modifier        (EekSymbol        *symbol);
 | 
			
		||||
void              eek_symbol_set_icon_name      (EekSymbol        *symbol,
 | 
			
		||||
                                                 const gchar      *icon_name);
 | 
			
		||||
const gchar      *eek_symbol_get_icon_name      (EekSymbol        *symbol);
 | 
			
		||||
void              eek_symbol_set_tooltip        (EekSymbol        *symbol,
 | 
			
		||||
                                                 const gchar      *tooltip);
 | 
			
		||||
const gchar *     eek_symbol_get_tooltip        (EekSymbol        *symbol);
 | 
			
		||||
 | 
			
		||||
const gchar      *eek_symbol_category_get_name  (EekSymbolCategory category);
 | 
			
		||||
EekSymbolCategory eek_symbol_category_from_name (const gchar      *name);
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
 | 
			
		||||
#endif  /* EEK_SYMBOL_H */
 | 
			
		||||
							
								
								
									
										187
									
								
								eek/eek-text.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										187
									
								
								eek/eek-text.c
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,187 @@
 | 
			
		||||
/* 
 | 
			
		||||
 * Copyright (C) 2011 Daiki Ueno <ueno@unixuser.org>
 | 
			
		||||
 * Copyright (C) 2011 Red Hat, Inc.
 | 
			
		||||
 * 
 | 
			
		||||
 * This library is free software; you can redistribute it and/or
 | 
			
		||||
 * modify it under the terms of the GNU Lesser General Public License
 | 
			
		||||
 * as published by the Free Software Foundation; either version 2 of
 | 
			
		||||
 * the License, or (at your option) any later version.
 | 
			
		||||
 * 
 | 
			
		||||
 * This library is distributed in the hope that it will be useful, but
 | 
			
		||||
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
			
		||||
 * Lesser General Public License for more details.
 | 
			
		||||
 * 
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General Public
 | 
			
		||||
 * License along with this library; if not, write to the Free Software
 | 
			
		||||
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 | 
			
		||||
 * 02110-1301 USA
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * SECTION:eek-text
 | 
			
		||||
 * @short_description: an #EekText represents a text symbol
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_CONFIG_H
 | 
			
		||||
#include "config.h"
 | 
			
		||||
#endif  /* HAVE_CONFIG_H */
 | 
			
		||||
 | 
			
		||||
#include "eek-text.h"
 | 
			
		||||
#include "eek-serializable.h"
 | 
			
		||||
 | 
			
		||||
enum {
 | 
			
		||||
    PROP_0,
 | 
			
		||||
    PROP_TEXT,
 | 
			
		||||
    PROP_LAST
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
typedef struct _EekTextPrivate
 | 
			
		||||
{
 | 
			
		||||
    gchar *text;
 | 
			
		||||
} EekTextPrivate;
 | 
			
		||||
 | 
			
		||||
static void eek_serializable_iface_init (EekSerializableIface *iface);
 | 
			
		||||
 | 
			
		||||
G_DEFINE_TYPE_EXTENDED (EekText,
 | 
			
		||||
			eek_text,
 | 
			
		||||
			EEK_TYPE_SYMBOL,
 | 
			
		||||
			0, /* GTypeFlags */
 | 
			
		||||
			G_ADD_PRIVATE (EekText)
 | 
			
		||||
                        G_IMPLEMENT_INTERFACE (EEK_TYPE_SERIALIZABLE,
 | 
			
		||||
                                               eek_serializable_iface_init))
 | 
			
		||||
 | 
			
		||||
static EekSerializableIface *eek_text_parent_serializable_iface;
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
eek_text_real_serialize (EekSerializable *self,
 | 
			
		||||
                         GVariantBuilder *builder)
 | 
			
		||||
{
 | 
			
		||||
    EekTextPrivate *priv = eek_text_get_instance_private (EEK_TEXT (self));
 | 
			
		||||
 | 
			
		||||
    eek_text_parent_serializable_iface->serialize (self, builder);
 | 
			
		||||
 | 
			
		||||
    g_variant_builder_add (builder, "s", priv->text);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gsize
 | 
			
		||||
eek_text_real_deserialize (EekSerializable *self,
 | 
			
		||||
                           GVariant        *variant,
 | 
			
		||||
                           gsize            index)
 | 
			
		||||
{
 | 
			
		||||
    EekTextPrivate *priv = eek_text_get_instance_private (EEK_TEXT (self));
 | 
			
		||||
 | 
			
		||||
    index = eek_text_parent_serializable_iface->deserialize (self,
 | 
			
		||||
                                                             variant,
 | 
			
		||||
                                                             index);
 | 
			
		||||
    g_variant_get_child (variant, index++, "s", &priv->text);
 | 
			
		||||
 | 
			
		||||
    return index;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
eek_serializable_iface_init (EekSerializableIface *iface)
 | 
			
		||||
{
 | 
			
		||||
    eek_text_parent_serializable_iface =
 | 
			
		||||
        g_type_interface_peek_parent (iface);
 | 
			
		||||
 | 
			
		||||
    iface->serialize = eek_text_real_serialize;
 | 
			
		||||
    iface->deserialize = eek_text_real_deserialize;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
eek_text_set_property (GObject      *object,
 | 
			
		||||
                       guint         prop_id,
 | 
			
		||||
                       const GValue *value,
 | 
			
		||||
                       GParamSpec   *pspec)
 | 
			
		||||
{
 | 
			
		||||
    EekText        *self = EEK_TEXT (object);
 | 
			
		||||
    EekTextPrivate *priv = eek_text_get_instance_private (self);
 | 
			
		||||
 | 
			
		||||
    switch (prop_id) {
 | 
			
		||||
    case PROP_TEXT:
 | 
			
		||||
        g_free (priv->text);
 | 
			
		||||
        priv->text = g_strdup (g_value_get_string (value));
 | 
			
		||||
        break;
 | 
			
		||||
    default:
 | 
			
		||||
        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
eek_text_get_property (GObject    *object,
 | 
			
		||||
                       guint       prop_id,
 | 
			
		||||
                       GValue     *value,
 | 
			
		||||
                       GParamSpec *pspec)
 | 
			
		||||
{
 | 
			
		||||
    EekText        *self = EEK_TEXT (object);
 | 
			
		||||
    EekTextPrivate *priv = eek_text_get_instance_private (self);
 | 
			
		||||
 | 
			
		||||
    switch (prop_id) {
 | 
			
		||||
    case PROP_TEXT:
 | 
			
		||||
        g_value_set_string (value, priv->text);
 | 
			
		||||
        break;
 | 
			
		||||
    default:
 | 
			
		||||
        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
eek_text_finalize (GObject *object)
 | 
			
		||||
{
 | 
			
		||||
    EekText        *self = EEK_TEXT (object);
 | 
			
		||||
    EekTextPrivate *priv = eek_text_get_instance_private (self);
 | 
			
		||||
 | 
			
		||||
    g_free (priv->text);
 | 
			
		||||
    G_OBJECT_CLASS (eek_text_parent_class)->finalize (object);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
eek_text_class_init (EekTextClass *klass)
 | 
			
		||||
{
 | 
			
		||||
    GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
 | 
			
		||||
    GParamSpec *pspec;
 | 
			
		||||
 | 
			
		||||
    gobject_class->set_property = eek_text_set_property;
 | 
			
		||||
    gobject_class->get_property = eek_text_get_property;
 | 
			
		||||
    gobject_class->finalize = eek_text_finalize;
 | 
			
		||||
 | 
			
		||||
    pspec = g_param_spec_string ("text",
 | 
			
		||||
                                 "Text",
 | 
			
		||||
                                 "Text",
 | 
			
		||||
                                 NULL,
 | 
			
		||||
                                 G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE);
 | 
			
		||||
    g_object_class_install_property (gobject_class, PROP_TEXT, pspec);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
eek_text_init (EekText *self)
 | 
			
		||||
{
 | 
			
		||||
    /* void */
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
EekText *
 | 
			
		||||
eek_text_new (const gchar *text)
 | 
			
		||||
{
 | 
			
		||||
    return g_object_new (EEK_TYPE_TEXT,
 | 
			
		||||
                         "label", text,
 | 
			
		||||
                         "category", EEK_SYMBOL_CATEGORY_FUNCTION,
 | 
			
		||||
                         "text", text,
 | 
			
		||||
                         NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eek_text_get_text:
 | 
			
		||||
 * @text: an #EekText
 | 
			
		||||
 *
 | 
			
		||||
 * Get a text value associated with @text
 | 
			
		||||
 */
 | 
			
		||||
const gchar *
 | 
			
		||||
eek_text_get_text (EekText *text)
 | 
			
		||||
{
 | 
			
		||||
    EekTextPrivate *priv = eek_text_get_instance_private (text);
 | 
			
		||||
 | 
			
		||||
    return priv->text;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										46
									
								
								eek/eek-text.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								eek/eek-text.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,46 @@
 | 
			
		||||
/* 
 | 
			
		||||
 * Copyright (C) 2011 Daiki Ueno <ueno@unixuser.org>
 | 
			
		||||
 * Copyright (C) 2011 Red Hat, Inc.
 | 
			
		||||
 * 
 | 
			
		||||
 * This library is free software; you can redistribute it and/or
 | 
			
		||||
 * modify it under the terms of the GNU Lesser General Public License
 | 
			
		||||
 * as published by the Free Software Foundation; either version 2 of
 | 
			
		||||
 * the License, or (at your option) any later version.
 | 
			
		||||
 * 
 | 
			
		||||
 * This library is distributed in the hope that it will be useful, but
 | 
			
		||||
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
			
		||||
 * Lesser General Public License for more details.
 | 
			
		||||
 * 
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General Public
 | 
			
		||||
 * License along with this library; if not, write to the Free Software
 | 
			
		||||
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 | 
			
		||||
 * 02110-1301 USA
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#if !defined(__EEK_H_INSIDE__) && !defined(EEK_COMPILATION)
 | 
			
		||||
#error "Only <eek/eek.h> can be included directly."
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef EEK_TEXT_H
 | 
			
		||||
#define EEK_TEXT_H 1
 | 
			
		||||
 | 
			
		||||
#include "eek-symbol.h"
 | 
			
		||||
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
#define EEK_TYPE_TEXT (eek_text_get_type())
 | 
			
		||||
G_DECLARE_DERIVABLE_TYPE(EekText, eek_text, EEK, TEXT, EekSymbol)
 | 
			
		||||
 | 
			
		||||
struct _EekTextClass {
 | 
			
		||||
    /*< private >*/
 | 
			
		||||
    EekSymbolClass parent_class;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
GType        eek_text_get_type (void) G_GNUC_CONST;
 | 
			
		||||
EekText     *eek_text_new      (const gchar *text);
 | 
			
		||||
const gchar *eek_text_get_text (EekText     *text);
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
 | 
			
		||||
#endif  /* EEK_TEXT_H */
 | 
			
		||||
							
								
								
									
										289
									
								
								eek/eek-theme-context.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										289
									
								
								eek/eek-theme-context.c
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,289 @@
 | 
			
		||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; c-basic-offset: 2; -*- */
 | 
			
		||||
/*
 | 
			
		||||
 * eek-theme-context.c: holds global information about a tree of styled objects
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright 2009, 2010 Red Hat, Inc.
 | 
			
		||||
 * Copyright 2009 Florian Müllner
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU Lesser General Public License as
 | 
			
		||||
 * published by the Free Software Foundation, either version 2.1 of
 | 
			
		||||
 * the License, or (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is distributed in the hope it will be useful, but WITHOUT ANY
 | 
			
		||||
 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 | 
			
		||||
 * FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for
 | 
			
		||||
 * more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General Public License
 | 
			
		||||
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_CONFIG_H
 | 
			
		||||
#include "config.h"
 | 
			
		||||
#endif  /* HAVE_CONFIG_H */
 | 
			
		||||
 | 
			
		||||
#include "eek-theme.h"
 | 
			
		||||
#include "eek-theme-context.h"
 | 
			
		||||
 | 
			
		||||
struct _EekThemeContext {
 | 
			
		||||
  GObject parent;
 | 
			
		||||
 | 
			
		||||
  double resolution;
 | 
			
		||||
  PangoFontDescription *font;
 | 
			
		||||
  EekThemeNode *root_node;
 | 
			
		||||
  EekTheme *theme;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct _EekThemeContextClass {
 | 
			
		||||
  GObjectClass parent_class;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#define DEFAULT_RESOLUTION 96.
 | 
			
		||||
#define DEFAULT_FONT "sans-serif 10"
 | 
			
		||||
 | 
			
		||||
enum
 | 
			
		||||
{
 | 
			
		||||
  CHANGED,
 | 
			
		||||
 | 
			
		||||
  LAST_SIGNAL
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static guint signals[LAST_SIGNAL] = { 0, };
 | 
			
		||||
 | 
			
		||||
G_DEFINE_TYPE (EekThemeContext, eek_theme_context, G_TYPE_OBJECT)
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
eek_theme_context_finalize (GObject *object)
 | 
			
		||||
{
 | 
			
		||||
  EekThemeContext *context = EEK_THEME_CONTEXT (object);
 | 
			
		||||
 | 
			
		||||
  if (context->root_node)
 | 
			
		||||
    g_object_unref (context->root_node);
 | 
			
		||||
  if (context->theme)
 | 
			
		||||
    g_object_unref (context->theme);
 | 
			
		||||
 | 
			
		||||
  pango_font_description_free (context->font);
 | 
			
		||||
 | 
			
		||||
  G_OBJECT_CLASS (eek_theme_context_parent_class)->finalize (object);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
eek_theme_context_class_init (EekThemeContextClass *klass)
 | 
			
		||||
{
 | 
			
		||||
  GObjectClass *object_class = G_OBJECT_CLASS (klass);
 | 
			
		||||
 | 
			
		||||
  object_class->finalize = eek_theme_context_finalize;
 | 
			
		||||
 | 
			
		||||
  signals[CHANGED] =
 | 
			
		||||
    g_signal_new ("changed",
 | 
			
		||||
                  G_TYPE_FROM_CLASS (klass),
 | 
			
		||||
                  G_SIGNAL_RUN_LAST,
 | 
			
		||||
                  0, /* no default handler slot */
 | 
			
		||||
                  NULL, NULL,
 | 
			
		||||
                  g_cclosure_marshal_VOID__VOID,
 | 
			
		||||
                  G_TYPE_NONE, 0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
eek_theme_context_init (EekThemeContext *context)
 | 
			
		||||
{
 | 
			
		||||
  context->resolution = DEFAULT_RESOLUTION;
 | 
			
		||||
  context->font = pango_font_description_from_string (DEFAULT_FONT);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eek_theme_context_new:
 | 
			
		||||
 *
 | 
			
		||||
 * Create a new theme context.
 | 
			
		||||
 */
 | 
			
		||||
EekThemeContext *
 | 
			
		||||
eek_theme_context_new (void)
 | 
			
		||||
{
 | 
			
		||||
  EekThemeContext *context;
 | 
			
		||||
 | 
			
		||||
  context = g_object_new (EEK_TYPE_THEME_CONTEXT, NULL);
 | 
			
		||||
 | 
			
		||||
  return context;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
eek_theme_context_changed (EekThemeContext *context)
 | 
			
		||||
{
 | 
			
		||||
  EekThemeNode *old_root = context->root_node;
 | 
			
		||||
  context->root_node = NULL;
 | 
			
		||||
 | 
			
		||||
  g_signal_emit (context, signals[CHANGED], 0);
 | 
			
		||||
 | 
			
		||||
  if (old_root)
 | 
			
		||||
    g_object_unref (old_root);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eek_theme_context_set_theme:
 | 
			
		||||
 * @context: an #EekThemeContext
 | 
			
		||||
 * @theme: an #EekTheme
 | 
			
		||||
 *
 | 
			
		||||
 * Sets the default set of theme stylesheets for the context. This theme will
 | 
			
		||||
 * be used for the root node and for nodes descending from it, unless some other
 | 
			
		||||
 * style is explicitely specified.
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
eek_theme_context_set_theme (EekThemeContext          *context,
 | 
			
		||||
                            EekTheme                 *theme)
 | 
			
		||||
{
 | 
			
		||||
  g_return_if_fail (EEK_IS_THEME_CONTEXT (context));
 | 
			
		||||
  g_return_if_fail (theme == NULL || EEK_IS_THEME (theme));
 | 
			
		||||
 | 
			
		||||
  if (context->theme != theme)
 | 
			
		||||
    {
 | 
			
		||||
      if (context->theme)
 | 
			
		||||
        g_object_unref (context->theme);
 | 
			
		||||
 | 
			
		||||
      context->theme = theme;
 | 
			
		||||
 | 
			
		||||
      if (context->theme)
 | 
			
		||||
        g_object_ref (context->theme);
 | 
			
		||||
 | 
			
		||||
      eek_theme_context_changed (context);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eek_theme_context_get_theme:
 | 
			
		||||
 * @context: a #EekThemeContext
 | 
			
		||||
 *
 | 
			
		||||
 * Gets the default theme for the context. See eek_theme_context_set_theme()
 | 
			
		||||
 *
 | 
			
		||||
 * Return value: (transfer none): the default theme for the context
 | 
			
		||||
 */
 | 
			
		||||
EekTheme *
 | 
			
		||||
eek_theme_context_get_theme (EekThemeContext *context)
 | 
			
		||||
{
 | 
			
		||||
  g_return_val_if_fail (EEK_IS_THEME_CONTEXT (context), NULL);
 | 
			
		||||
 | 
			
		||||
  return context->theme;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eek_theme_context_set_resolution:
 | 
			
		||||
 * @context: a #EekThemeContext
 | 
			
		||||
 * @resolution: resolution of the context (number of pixels in an "inch")
 | 
			
		||||
 *
 | 
			
		||||
 * Sets the resolution of the theme context. This is the scale factor
 | 
			
		||||
 * used to convert between points and the length units pt, in, and cm.
 | 
			
		||||
 * This does not necessarily need to correspond to the actual number
 | 
			
		||||
 * resolution of the device. A value of 72. means that points and
 | 
			
		||||
 * pixels are identical. The default value is 96.
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
eek_theme_context_set_resolution (EekThemeContext *context,
 | 
			
		||||
                                 double          resolution)
 | 
			
		||||
{
 | 
			
		||||
  g_return_if_fail (EEK_IS_THEME_CONTEXT (context));
 | 
			
		||||
 | 
			
		||||
  if (resolution == context->resolution)
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  context->resolution = resolution;
 | 
			
		||||
  eek_theme_context_changed (context);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eek_theme_context_set_default_resolution:
 | 
			
		||||
 * @context: a #EekThemeContext
 | 
			
		||||
 *
 | 
			
		||||
 * Sets the resolution of the theme context to the default value of 96.
 | 
			
		||||
 * See eek_theme_context_set_resolution().
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
eek_theme_context_set_default_resolution (EekThemeContext *context)
 | 
			
		||||
{
 | 
			
		||||
  g_return_if_fail (EEK_IS_THEME_CONTEXT (context));
 | 
			
		||||
 | 
			
		||||
  if (context->resolution == DEFAULT_RESOLUTION)
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  context->resolution = DEFAULT_RESOLUTION;
 | 
			
		||||
  eek_theme_context_changed (context);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eek_theme_context_get_resolution:
 | 
			
		||||
 * @context: a #EekThemeContext
 | 
			
		||||
 *
 | 
			
		||||
 * Gets the current resolution of the theme context.
 | 
			
		||||
 * See eek_theme_context_set_resolution().
 | 
			
		||||
 *
 | 
			
		||||
 * Return value: the resolution (in dots-per-"inch")
 | 
			
		||||
 */
 | 
			
		||||
double
 | 
			
		||||
eek_theme_context_get_resolution (EekThemeContext *context)
 | 
			
		||||
{
 | 
			
		||||
  g_return_val_if_fail (EEK_IS_THEME_CONTEXT (context), DEFAULT_RESOLUTION);
 | 
			
		||||
 | 
			
		||||
  return context->resolution;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eek_theme_context_set_font:
 | 
			
		||||
 * @context: a #EekThemeContext
 | 
			
		||||
 * @font: the default font for theme context
 | 
			
		||||
 *
 | 
			
		||||
 * Sets the default font for the theme context. This is the font that
 | 
			
		||||
 * is inherited by the root node of the tree of theme nodes. If the
 | 
			
		||||
 * font is not overriden, then this font will be used. If the font is
 | 
			
		||||
 * partially modified (for example, with 'font-size: 110%', then that
 | 
			
		||||
 * modification is based on this font.
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
eek_theme_context_set_font (EekThemeContext             *context,
 | 
			
		||||
                           const PangoFontDescription *font)
 | 
			
		||||
{
 | 
			
		||||
  g_return_if_fail (EEK_IS_THEME_CONTEXT (context));
 | 
			
		||||
  g_return_if_fail (font != NULL);
 | 
			
		||||
 | 
			
		||||
  if (context->font == font ||
 | 
			
		||||
      pango_font_description_equal (context->font, font))
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  pango_font_description_free (context->font);
 | 
			
		||||
  context->font = pango_font_description_copy (font);
 | 
			
		||||
  eek_theme_context_changed (context);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eek_theme_context_get_font:
 | 
			
		||||
 * @context: a #EekThemeContext
 | 
			
		||||
 *
 | 
			
		||||
 * Gets the default font for the theme context. See eek_theme_context_set_font().
 | 
			
		||||
 *
 | 
			
		||||
 * Return value: the default font for the theme context.
 | 
			
		||||
 */
 | 
			
		||||
const PangoFontDescription *
 | 
			
		||||
eek_theme_context_get_font (EekThemeContext *context)
 | 
			
		||||
{
 | 
			
		||||
  g_return_val_if_fail (EEK_IS_THEME_CONTEXT (context), NULL);
 | 
			
		||||
 | 
			
		||||
  return context->font;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eek_theme_context_get_root_node:
 | 
			
		||||
 * @context: a #EekThemeContext
 | 
			
		||||
 *
 | 
			
		||||
 * Gets the root node of the tree of theme style nodes that associated with this
 | 
			
		||||
 * context. For the node tree associated with a stage, this node represents
 | 
			
		||||
 * styles applied to the stage itself.
 | 
			
		||||
 *
 | 
			
		||||
 * Return value: (transfer none): the root node of the context's style tree
 | 
			
		||||
 */
 | 
			
		||||
EekThemeNode *
 | 
			
		||||
eek_theme_context_get_root_node (EekThemeContext *context)
 | 
			
		||||
{
 | 
			
		||||
  if (context->root_node == NULL)
 | 
			
		||||
    context->root_node = eek_theme_node_new (context, NULL, context->theme,
 | 
			
		||||
                                             G_TYPE_NONE, NULL, NULL, NULL, NULL);
 | 
			
		||||
 | 
			
		||||
  return context->root_node;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										78
									
								
								eek/eek-theme-context.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										78
									
								
								eek/eek-theme-context.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,78 @@
 | 
			
		||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
 | 
			
		||||
/*
 | 
			
		||||
 * eek-theme-context.c: holds global information about a tree of styled objects
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright 2009, 2010 Red Hat, Inc.
 | 
			
		||||
 * Copyright 2009 Florian Müllner
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU Lesser General Public License as
 | 
			
		||||
 * published by the Free Software Foundation, either version 2.1 of
 | 
			
		||||
 * the License, or (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is distributed in the hope it will be useful, but WITHOUT ANY
 | 
			
		||||
 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 | 
			
		||||
 * FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for
 | 
			
		||||
 * more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General Public License
 | 
			
		||||
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef __EEK_THEME_CONTEXT_H__
 | 
			
		||||
#define __EEK_THEME_CONTEXT_H__
 | 
			
		||||
 | 
			
		||||
#include <pango/pango.h>
 | 
			
		||||
#include "eek-theme-node.h"
 | 
			
		||||
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * SECTION:eek-theme-context
 | 
			
		||||
 * @short_description: holds global information about a tree of styled objects
 | 
			
		||||
 *
 | 
			
		||||
 * #EekThemeContext is responsible for managing information global to
 | 
			
		||||
 * a tree of styled objects, such as the set of stylesheets or the
 | 
			
		||||
 * default font.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
typedef struct _EekThemeContextClass EekThemeContextClass;
 | 
			
		||||
 | 
			
		||||
#define EEK_TYPE_THEME_CONTEXT             (eek_theme_context_get_type ())
 | 
			
		||||
#define EEK_THEME_CONTEXT(object)          (G_TYPE_CHECK_INSTANCE_CAST ((object), EEK_TYPE_THEME_CONTEXT, EekThemeContext))
 | 
			
		||||
#define EEK_THEME_CONTEXT_CLASS(klass)     (G_TYPE_CHECK_CLASS_CAST ((klass), EEK_TYPE_THEME_CONTEXT, EekThemeContextClass))
 | 
			
		||||
#define EEK_IS_THEME_CONTEXT(object)       (G_TYPE_CHECK_INSTANCE_TYPE ((object), EEK_TYPE_THEME_CONTEXT))
 | 
			
		||||
#define EEK_IS_THEME_CONTEXT_CLASS(klass)  (G_TYPE_CHECK_CLASS_TYPE ((klass), EEK_TYPE_THEME_CONTEXT))
 | 
			
		||||
#define EEK_THEME_CONTEXT_GET_CLASS(obj)   (G_TYPE_INSTANCE_GET_CLASS ((obj), EEK_TYPE_THEME_CONTEXT, EekThemeContextClass))
 | 
			
		||||
 | 
			
		||||
GType                       eek_theme_context_get_type
 | 
			
		||||
                            (void) G_GNUC_CONST;
 | 
			
		||||
 | 
			
		||||
EekThemeContext            *eek_theme_context_new
 | 
			
		||||
                            (void);
 | 
			
		||||
 | 
			
		||||
void                        eek_theme_context_set_theme
 | 
			
		||||
                            (EekThemeContext            *context,
 | 
			
		||||
                             EekTheme                   *theme);
 | 
			
		||||
EekTheme *                  eek_theme_context_get_theme
 | 
			
		||||
                            (EekThemeContext            *context);
 | 
			
		||||
 | 
			
		||||
void                        eek_theme_context_set_resolution
 | 
			
		||||
                            (EekThemeContext            *context,
 | 
			
		||||
                             gdouble                     resolution);
 | 
			
		||||
void                        eek_theme_context_set_default_resolution
 | 
			
		||||
                            (EekThemeContext            *context);
 | 
			
		||||
double                      eek_theme_context_get_resolution
 | 
			
		||||
                            (EekThemeContext            *context);
 | 
			
		||||
void                        eek_theme_context_set_font
 | 
			
		||||
                            (EekThemeContext            *context,
 | 
			
		||||
                             const PangoFontDescription *font);
 | 
			
		||||
const PangoFontDescription *eek_theme_context_get_font
 | 
			
		||||
                            (EekThemeContext            *context);
 | 
			
		||||
 | 
			
		||||
EekThemeNode *              eek_theme_context_get_root_node
 | 
			
		||||
                            (EekThemeContext            *context);
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
 | 
			
		||||
#endif /* __EEK_THEME_CONTEXT_H__ */
 | 
			
		||||
							
								
								
									
										1871
									
								
								eek/eek-theme-node.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1871
									
								
								eek/eek-theme-node.c
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										141
									
								
								eek/eek-theme-node.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										141
									
								
								eek/eek-theme-node.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,141 @@
 | 
			
		||||
/* 
 | 
			
		||||
 * Copyright (C) 2010-2011 Daiki Ueno <ueno@unixuser.org>
 | 
			
		||||
 * Copyright (C) 2010-2011 Red Hat, Inc.
 | 
			
		||||
 * 
 | 
			
		||||
 * This library is free software; you can redistribute it and/or
 | 
			
		||||
 * modify it under the terms of the GNU Lesser General Public License
 | 
			
		||||
 * as published by the Free Software Foundation; either version 2 of
 | 
			
		||||
 * the License, or (at your option) any later version.
 | 
			
		||||
 * 
 | 
			
		||||
 * This library is distributed in the hope that it will be useful, but
 | 
			
		||||
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
			
		||||
 * Lesser General Public License for more details.
 | 
			
		||||
 * 
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General Public
 | 
			
		||||
 * License along with this library; if not, write to the Free Software
 | 
			
		||||
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 | 
			
		||||
 * 02110-1301 USA
 | 
			
		||||
 */
 | 
			
		||||
#ifndef __EEK_THEME_NODE_H__
 | 
			
		||||
#define __EEK_THEME_NODE_H__
 | 
			
		||||
 | 
			
		||||
#include <pango/pango.h>
 | 
			
		||||
#include "eek-types.h"
 | 
			
		||||
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * SECTION:eek-theme-node
 | 
			
		||||
 * @short_description: style information for one node in a tree of
 | 
			
		||||
 * themed objects
 | 
			
		||||
 *
 | 
			
		||||
 * The #EekThemeNode class represents the CSS style information (the
 | 
			
		||||
 * set of CSS properties) for one node in a tree of themed objects. In
 | 
			
		||||
 * typical usage, it represents the style information for a single
 | 
			
		||||
 * #EekElement. A #EekThemeNode is immutable: attributes such as the
 | 
			
		||||
 * CSS classes for the node are passed in at construction. If the
 | 
			
		||||
 * attributes of the node or any parent node change, the node should
 | 
			
		||||
 * be discarded and a new node created.  #EekThemeNode has generic
 | 
			
		||||
 * accessors to look up properties by name and specific accessors for
 | 
			
		||||
 * standard CSS properties that add caching and handling of various
 | 
			
		||||
 * details of the CSS specification. #EekThemeNode also has
 | 
			
		||||
 * convenience functions to help in implementing a #EekElement with
 | 
			
		||||
 * borders and padding.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
typedef enum {
 | 
			
		||||
    EEK_SIDE_TOP,
 | 
			
		||||
    EEK_SIDE_RIGHT,
 | 
			
		||||
    EEK_SIDE_BOTTOM,
 | 
			
		||||
    EEK_SIDE_LEFT
 | 
			
		||||
} EekSide;
 | 
			
		||||
 | 
			
		||||
typedef enum {
 | 
			
		||||
    EEK_CORNER_TOPLEFT,
 | 
			
		||||
    EEK_CORNER_TOPRIGHT,
 | 
			
		||||
    EEK_CORNER_BOTTOMRIGHT,
 | 
			
		||||
    EEK_CORNER_BOTTOMLEFT
 | 
			
		||||
} EekCorner;
 | 
			
		||||
 | 
			
		||||
#define EEK_TYPE_THEME_NODE (eek_theme_node_get_type())
 | 
			
		||||
#define EEK_THEME_NODE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EEK_TYPE_THEME_NODE, EekThemeNode))
 | 
			
		||||
#define EEK_THEME_NODE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EEK_TYPE_THEME_NODE, EekThemeNodeClass))
 | 
			
		||||
#define EEK_IS_THEME_NODE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EEK_TYPE_THEME_NODE))
 | 
			
		||||
#define EEK_IS_THEME_NODE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EEK_TYPE_THEME_NODE))
 | 
			
		||||
#define EEK_THEME_NODE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EEK_TYPE_THEME_NODE, EekThemeNodeClass))
 | 
			
		||||
 | 
			
		||||
typedef struct _EekThemeNodeClass EekThemeNodeClass;
 | 
			
		||||
typedef struct _EekThemeNodePrivate EekThemeNodePrivate;
 | 
			
		||||
 | 
			
		||||
GType         eek_theme_node_get_type
 | 
			
		||||
                                 (void) G_GNUC_CONST;
 | 
			
		||||
 | 
			
		||||
EekThemeNode *eek_theme_node_new (EekThemeContext            *context,
 | 
			
		||||
                                  EekThemeNode               *parent_node,
 | 
			
		||||
                                  /* can be null */ EekTheme *theme,
 | 
			
		||||
                                  /* can be null */ GType     element_type,
 | 
			
		||||
                                  const char                 *element_id,
 | 
			
		||||
                                  const char                 *element_class,
 | 
			
		||||
                                  const char                 *pseudo_class,
 | 
			
		||||
                                  const char                 *inline_style);
 | 
			
		||||
 | 
			
		||||
EekThemeNode *eek_theme_node_get_parent
 | 
			
		||||
                                 (EekThemeNode               *node);
 | 
			
		||||
 | 
			
		||||
EekTheme     *eek_theme_node_get_theme
 | 
			
		||||
                                 (EekThemeNode               *node);
 | 
			
		||||
 | 
			
		||||
GType         eek_theme_node_get_element_type
 | 
			
		||||
                                 (EekThemeNode               *node);
 | 
			
		||||
const char   *eek_theme_node_get_element_id
 | 
			
		||||
                                 (EekThemeNode               *node);
 | 
			
		||||
const char   *eek_theme_node_get_element_class
 | 
			
		||||
                                 (EekThemeNode               *node);
 | 
			
		||||
const char   *eek_theme_node_get_pseudo_class
 | 
			
		||||
                                 (EekThemeNode               *node);
 | 
			
		||||
 | 
			
		||||
/* Generic getters ... these are not cached so are less efficient. The other
 | 
			
		||||
 * reason for adding the more specific version is that we can handle the
 | 
			
		||||
 * details of the actual CSS rules, which can be complicated, especially
 | 
			
		||||
 * for fonts
 | 
			
		||||
 */
 | 
			
		||||
void          eek_theme_node_get_color
 | 
			
		||||
                                 (EekThemeNode               *node,
 | 
			
		||||
                                  const char                 *property_name,
 | 
			
		||||
                                  EekColor                   *color);
 | 
			
		||||
 | 
			
		||||
/* Specific getters for particular properties: cached
 | 
			
		||||
 */
 | 
			
		||||
void          eek_theme_node_get_background_color
 | 
			
		||||
                                 (EekThemeNode               *node,
 | 
			
		||||
                                  EekColor                   *color);
 | 
			
		||||
void          eek_theme_node_get_foreground_color
 | 
			
		||||
                                 (EekThemeNode               *node,
 | 
			
		||||
                                  EekColor                   *color);
 | 
			
		||||
void          eek_theme_node_get_background_gradient
 | 
			
		||||
                                 (EekThemeNode               *node,
 | 
			
		||||
                                  EekGradientType            *type,
 | 
			
		||||
                                  EekColor                   *start,
 | 
			
		||||
                                  EekColor                   *end);
 | 
			
		||||
int           eek_theme_node_get_border_width
 | 
			
		||||
                                 (EekThemeNode               *node,
 | 
			
		||||
                                  EekSide                     side);
 | 
			
		||||
int           eek_theme_node_get_border_radius
 | 
			
		||||
                                 (EekThemeNode               *node,
 | 
			
		||||
                                  EekCorner                   corner);
 | 
			
		||||
void          eek_theme_node_get_border_color
 | 
			
		||||
                                 (EekThemeNode               *node,
 | 
			
		||||
                                  EekSide                     side,
 | 
			
		||||
                                  EekColor                   *color);
 | 
			
		||||
 | 
			
		||||
/* Font rule processing is pretty complicated, so we just hardcode it
 | 
			
		||||
 * under the standard font/font-family/font-size/etc names. This means
 | 
			
		||||
 * you can't have multiple separate styled fonts for a single item,
 | 
			
		||||
 * but that should be OK.
 | 
			
		||||
 */
 | 
			
		||||
const PangoFontDescription *eek_theme_node_get_font (EekThemeNode *node);
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
 | 
			
		||||
#endif /* __EEK_THEME_NODE_H__ */
 | 
			
		||||
							
								
								
									
										22
									
								
								eek/eek-theme-private.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								eek/eek-theme-private.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,22 @@
 | 
			
		||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
 | 
			
		||||
#ifndef __EEK_THEME_PRIVATE_H__
 | 
			
		||||
#define __EEK_THEME_PRIVATE_H__
 | 
			
		||||
 | 
			
		||||
#include <libcroco/libcroco.h>
 | 
			
		||||
#include "eek-theme.h"
 | 
			
		||||
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
GPtrArray *_eek_theme_get_matched_properties (EekTheme       *theme,
 | 
			
		||||
                                             EekThemeNode   *node);
 | 
			
		||||
 | 
			
		||||
/* Resolve an URL from the stylesheet to a filename */
 | 
			
		||||
char *_eek_theme_resolve_url (EekTheme      *theme,
 | 
			
		||||
                             CRStyleSheet *base_stylesheet,
 | 
			
		||||
                             const char   *url);
 | 
			
		||||
 | 
			
		||||
CRDeclaration *_eek_theme_parse_declaration_list (const char *str);
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
 | 
			
		||||
#endif /* __EEK_THEME_PRIVATE_H__ */
 | 
			
		||||
							
								
								
									
										1133
									
								
								eek/eek-theme.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1133
									
								
								eek/eek-theme.c
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										49
									
								
								eek/eek-theme.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										49
									
								
								eek/eek-theme.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,49 @@
 | 
			
		||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
 | 
			
		||||
 | 
			
		||||
#if !defined(__EEK_H_INSIDE__) && !defined(EEK_COMPILATION)
 | 
			
		||||
#error "Only <eek/eek.h> can be included directly."
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef __EEK_THEME_H__
 | 
			
		||||
#define __EEK_THEME_H__
 | 
			
		||||
 | 
			
		||||
#include <glib-object.h>
 | 
			
		||||
 | 
			
		||||
#include "eek-types.h"
 | 
			
		||||
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * SECTION:EekTheme
 | 
			
		||||
 * @short_description: a set of stylesheets
 | 
			
		||||
 *
 | 
			
		||||
 * #EekTheme holds a set of stylesheets. (The "cascade" of the name
 | 
			
		||||
 * Cascading Stylesheets.) An #EekTheme can be set to apply to all the
 | 
			
		||||
 * keyboard elements.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
typedef struct _EekThemeClass EekThemeClass;
 | 
			
		||||
 | 
			
		||||
#define EEK_TYPE_THEME (eek_theme_get_type())
 | 
			
		||||
#define EEK_THEME(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EEK_TYPE_THEME, EekTheme))
 | 
			
		||||
#define EEK_THEME_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EEK_TYPE_THEME, EekThemeClass))
 | 
			
		||||
#define EEK_IS_THEME(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EEK_TYPE_THEME))
 | 
			
		||||
#define EEK_IS_THEME_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EEK_TYPE_THEME))
 | 
			
		||||
#define EEK_THEME_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EEK_TYPE_THEME, EekThemeClass))
 | 
			
		||||
 | 
			
		||||
GType     eek_theme_get_type          (void) G_GNUC_CONST;
 | 
			
		||||
 | 
			
		||||
EekTheme *eek_theme_new               (const char *application_stylesheet,
 | 
			
		||||
                                       const char *theme_stylesheet,
 | 
			
		||||
                                       const char *default_stylesheet);
 | 
			
		||||
 | 
			
		||||
gboolean  eek_theme_load_stylesheet   (EekTheme   *theme,
 | 
			
		||||
                                       const char *path,
 | 
			
		||||
                                       GError    **error);
 | 
			
		||||
 | 
			
		||||
void      eek_theme_unload_stylesheet (EekTheme   *theme,
 | 
			
		||||
                                       const char *path);
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
 | 
			
		||||
#endif /* __EEK_THEME_H__ */
 | 
			
		||||
@ -24,7 +24,9 @@
 | 
			
		||||
 * @short_description: Miscellaneous types used in Libeek
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_CONFIG_H
 | 
			
		||||
#include "config.h"
 | 
			
		||||
#endif  /* HAVE_CONFIG_H */
 | 
			
		||||
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <math.h>
 | 
			
		||||
 | 
			
		||||
@ -134,7 +134,12 @@ typedef enum
 | 
			
		||||
#define EEK_INVALID_KEYCODE (0)
 | 
			
		||||
    
 | 
			
		||||
typedef struct _EekElement EekElement;
 | 
			
		||||
typedef struct _EekContainer EekContainer;
 | 
			
		||||
typedef struct _EekKey EekKey;
 | 
			
		||||
typedef struct _EekSection EekSection;
 | 
			
		||||
typedef struct _EekKeyboard EekKeyboard;
 | 
			
		||||
typedef struct _EekSymbol EekSymbol;
 | 
			
		||||
typedef struct _EekKeysym EekKeysym;
 | 
			
		||||
typedef struct _EekText EekText;
 | 
			
		||||
typedef struct _EekTheme EekTheme;
 | 
			
		||||
typedef struct _EekThemeContext EekThemeContext;
 | 
			
		||||
@ -146,7 +151,6 @@ typedef struct _EekOutline EekOutline;
 | 
			
		||||
typedef struct _EekColor EekColor;
 | 
			
		||||
 | 
			
		||||
typedef struct _EekboardContextService EekboardContextService;
 | 
			
		||||
typedef struct _LevelKeyboard LevelKeyboard;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * EekPoint:
 | 
			
		||||
@ -191,6 +195,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
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										30
									
								
								eek/eek-xkb-0.90.pc.in
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								eek/eek-xkb-0.90.pc.in
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,30 @@
 | 
			
		||||
# Copyright (C) 2010-2011 Daiki Ueno <ueno@unixuser.org>
 | 
			
		||||
# Copyright (C) 2010-2011 Red Hat, Inc.
 | 
			
		||||
 | 
			
		||||
# This library is free software; you can redistribute it and/or
 | 
			
		||||
# modify it under the terms of the GNU Lesser General Public License
 | 
			
		||||
# as published by the Free Software Foundation; either version 2 of
 | 
			
		||||
# the License, or (at your option) any later version.
 | 
			
		||||
 | 
			
		||||
# This library is distributed in the hope that it will be useful, but
 | 
			
		||||
# WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
			
		||||
# Lesser General Public License for more details.
 | 
			
		||||
 | 
			
		||||
# You should have received a copy of the GNU Lesser General Public
 | 
			
		||||
# License along with this library; if not, write to the Free Software
 | 
			
		||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 | 
			
		||||
# 02110-1301 USA
 | 
			
		||||
 | 
			
		||||
prefix=@prefix@
 | 
			
		||||
exec_prefix=@exec_prefix@
 | 
			
		||||
libdir=@libdir@
 | 
			
		||||
includedir=@includedir@
 | 
			
		||||
 | 
			
		||||
Name: libeek-xkb
 | 
			
		||||
Description: A Library to Create Keyboard-like UI (XKB Support)
 | 
			
		||||
URL: http://fedorahosted.org/eekboard/
 | 
			
		||||
Version: @VERSION@
 | 
			
		||||
Requires: eek-@EEK_API_VERSION@ gtk+-x11-@GTK_API_VERSION@
 | 
			
		||||
Libs: -L${libdir} -leek-xkb
 | 
			
		||||
Cflags: -I${includedir}/eek-@EEK_API_VERSION@
 | 
			
		||||
							
								
								
									
										684
									
								
								eek/eek-xkb-layout.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										684
									
								
								eek/eek-xkb-layout.c
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,684 @@
 | 
			
		||||
/* 
 | 
			
		||||
 * Copyright (C) 2006 Sergey V. Udaltsov <svu@gnome.org>
 | 
			
		||||
 * Copyright (C) 2010-2011 Daiki Ueno <ueno@unixuser.org>
 | 
			
		||||
 * Copyright (C) 2010-2011 Red Hat, Inc.
 | 
			
		||||
 * 
 | 
			
		||||
 * This library is free software; you can redistribute it and/or
 | 
			
		||||
 * modify it under the terms of the GNU Lesser General Public License
 | 
			
		||||
 * as published by the Free Software Foundation; either version 2 of
 | 
			
		||||
 * the License, or (at your option) any later version.
 | 
			
		||||
 * 
 | 
			
		||||
 * This library is distributed in the hope that it will be useful, but
 | 
			
		||||
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
			
		||||
 * Lesser General Public License for more details.
 | 
			
		||||
 * 
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General Public
 | 
			
		||||
 * License along with this library; if not, write to the Free Software
 | 
			
		||||
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 | 
			
		||||
 * 02110-1301 USA
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * SECTION:eek-xkb-layout
 | 
			
		||||
 * @short_description: Layout engine using XKB configuration
 | 
			
		||||
 *
 | 
			
		||||
 * The #EekXkbLayout inherits #EekLayout class and arranges keyboard
 | 
			
		||||
 * elements using XKB.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_CONFIG_H
 | 
			
		||||
#include "config.h"
 | 
			
		||||
#endif  /* HAVE_CONFIG_H */
 | 
			
		||||
 | 
			
		||||
#include "eek-xkb-layout.h"
 | 
			
		||||
 | 
			
		||||
#include <X11/keysym.h>
 | 
			
		||||
#include <X11/extensions/XKBgeom.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <stdarg.h>
 | 
			
		||||
#include <gio/gio.h>
 | 
			
		||||
 | 
			
		||||
#include "eek-keyboard.h"
 | 
			
		||||
#include "eek-section.h"
 | 
			
		||||
#include "eek-key.h"
 | 
			
		||||
#include "eek-keysym.h"
 | 
			
		||||
 | 
			
		||||
#define XKB_COMPONENT_MASK (XkbGBN_GeometryMask |       \
 | 
			
		||||
                            XkbGBN_KeyNamesMask |       \
 | 
			
		||||
                            XkbGBN_OtherNamesMask |     \
 | 
			
		||||
                            XkbGBN_SymbolsMask |        \
 | 
			
		||||
                            XkbGBN_IndicatorMapMask)
 | 
			
		||||
 | 
			
		||||
static void initable_iface_init (GInitableIface *initable_iface);
 | 
			
		||||
 | 
			
		||||
enum {
 | 
			
		||||
    PROP_0,
 | 
			
		||||
    PROP_DISPLAY,
 | 
			
		||||
    PROP_LAST
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
typedef struct _EekXkbLayoutPrivate
 | 
			
		||||
{
 | 
			
		||||
    /* Configuration names that should synch'ed to the symbolic names
 | 
			
		||||
       in priv->xkb->names.  Since we use GLib's memory allocator,
 | 
			
		||||
       don't store any address returned from the X server here. */
 | 
			
		||||
    XkbComponentNamesRec names;
 | 
			
		||||
 | 
			
		||||
    Display *display;
 | 
			
		||||
 | 
			
		||||
    /* Actual XKB configuration of DISPLAY. */
 | 
			
		||||
    XkbDescRec *xkb;
 | 
			
		||||
 | 
			
		||||
    /* Hash table to cache orefs by shape address. */
 | 
			
		||||
    GHashTable *shape_oref_hash;
 | 
			
		||||
 | 
			
		||||
    gint scale_numerator;
 | 
			
		||||
    gint scale_denominator;
 | 
			
		||||
} EekXkbLayoutPrivate;
 | 
			
		||||
 | 
			
		||||
G_DEFINE_TYPE_EXTENDED (EekXkbLayout, eek_xkb_layout, EEK_TYPE_LAYOUT,
 | 
			
		||||
			0, /* GTypeFlags */
 | 
			
		||||
			G_ADD_PRIVATE(EekXkbLayout)
 | 
			
		||||
                        G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE,
 | 
			
		||||
                                               initable_iface_init))
 | 
			
		||||
 | 
			
		||||
static guint    find_keycode             (EekXkbLayout *layout,
 | 
			
		||||
                                          gchar        *key_name);
 | 
			
		||||
 | 
			
		||||
static gboolean get_keyboard_from_server (EekXkbLayout *layout,
 | 
			
		||||
                                          GError      **error);
 | 
			
		||||
 | 
			
		||||
static gboolean get_names_from_server    (EekXkbLayout *layout,
 | 
			
		||||
                                          GError      **error);
 | 
			
		||||
 | 
			
		||||
static void     setup_scaling            (EekXkbLayout *layout,
 | 
			
		||||
                                          gdouble       width,
 | 
			
		||||
                                          gdouble       height);
 | 
			
		||||
 | 
			
		||||
G_INLINE_FUNC gint
 | 
			
		||||
xkb_to_pixmap_coord (EekXkbLayout *layout,
 | 
			
		||||
                     gint          n)
 | 
			
		||||
{
 | 
			
		||||
    EekXkbLayoutPrivate *priv = eek_xkb_layout_get_instance_private (layout);
 | 
			
		||||
    return n * priv->scale_numerator / priv->scale_denominator;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
G_INLINE_FUNC gdouble
 | 
			
		||||
xkb_to_pixmap_double (EekXkbLayout *layout,
 | 
			
		||||
                     gdouble       d)
 | 
			
		||||
{
 | 
			
		||||
    EekXkbLayoutPrivate *priv = eek_xkb_layout_get_instance_private (layout);
 | 
			
		||||
    return d * priv->scale_numerator / priv->scale_denominator;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
create_key (EekXkbLayout *layout,
 | 
			
		||||
            EekKeyboard  *keyboard,
 | 
			
		||||
            EekSection   *section,
 | 
			
		||||
            gint          column,
 | 
			
		||||
            gint          row,
 | 
			
		||||
            gdouble       x,
 | 
			
		||||
            gdouble       y,
 | 
			
		||||
            XkbKeyRec    *xkbkey)
 | 
			
		||||
{
 | 
			
		||||
    XkbGeometryRec *xkbgeometry;
 | 
			
		||||
    XkbBoundsRec *xkbbounds;
 | 
			
		||||
    XkbShapeRec *xkbshape;
 | 
			
		||||
    XkbOutlineRec *xkboutline;
 | 
			
		||||
    EekXkbLayoutPrivate *priv = eek_xkb_layout_get_instance_private (layout);
 | 
			
		||||
    EekKey *key;
 | 
			
		||||
    EekBounds bounds;
 | 
			
		||||
    EekSymbolMatrix *matrix = NULL;
 | 
			
		||||
    gchar name[XkbKeyNameLength + 1];
 | 
			
		||||
    KeyCode keycode;
 | 
			
		||||
    gint num_groups, num_levels;
 | 
			
		||||
    guint oref;
 | 
			
		||||
    gpointer v;
 | 
			
		||||
 | 
			
		||||
    xkbgeometry = priv->xkb->geom;
 | 
			
		||||
    xkbshape = &xkbgeometry->shapes[xkbkey->shape_ndx];
 | 
			
		||||
    if (g_hash_table_lookup_extended (priv->shape_oref_hash, xkbshape,
 | 
			
		||||
                                      NULL, &v)) {
 | 
			
		||||
        oref = GPOINTER_TO_UINT(v);
 | 
			
		||||
    } else {
 | 
			
		||||
        EekOutline *outline;
 | 
			
		||||
 | 
			
		||||
        xkboutline = xkbshape->primary == NULL ? &xkbshape->outlines[0] :
 | 
			
		||||
            xkbshape->primary;
 | 
			
		||||
 | 
			
		||||
        outline = g_slice_new (EekOutline);
 | 
			
		||||
        outline->corner_radius = xkb_to_pixmap_coord(layout,
 | 
			
		||||
                                                     xkboutline->corner_radius);
 | 
			
		||||
 | 
			
		||||
        if (xkboutline->num_points <= 2) { /* rectangular */
 | 
			
		||||
            gdouble x1, y1, x2, y2;
 | 
			
		||||
 | 
			
		||||
            outline->num_points = 4;
 | 
			
		||||
            outline->points = g_slice_alloc0 (sizeof (EekPoint) *
 | 
			
		||||
                                              outline->num_points);
 | 
			
		||||
            if (xkboutline->num_points == 1) {
 | 
			
		||||
                x1 = xkb_to_pixmap_coord(layout, xkbshape->bounds.x1);
 | 
			
		||||
                y1 = xkb_to_pixmap_coord(layout, xkbshape->bounds.y1);
 | 
			
		||||
                x2 = xkb_to_pixmap_coord(layout, xkboutline->points[0].x);
 | 
			
		||||
                y2 = xkb_to_pixmap_coord(layout, xkboutline->points[0].y);
 | 
			
		||||
            } else {
 | 
			
		||||
                x1 = xkb_to_pixmap_coord(layout, xkboutline->points[0].x);
 | 
			
		||||
                y1 = xkb_to_pixmap_coord(layout, xkboutline->points[0].y);
 | 
			
		||||
                x2 = xkb_to_pixmap_coord(layout, xkboutline->points[1].x);
 | 
			
		||||
                y2 = xkb_to_pixmap_coord(layout, xkboutline->points[1].y);
 | 
			
		||||
            }
 | 
			
		||||
            outline->points[0].x = outline->points[3].x = x1;
 | 
			
		||||
            outline->points[0].y = outline->points[1].y = y1;
 | 
			
		||||
            outline->points[1].x = outline->points[2].x = x2;
 | 
			
		||||
            outline->points[2].y = outline->points[3].y = y2;
 | 
			
		||||
        } else {                /* polygon */
 | 
			
		||||
            gint i;
 | 
			
		||||
 | 
			
		||||
            outline->num_points = xkboutline->num_points;
 | 
			
		||||
            outline->points = g_new0 (EekPoint, outline->num_points);
 | 
			
		||||
            for (i = 0; i < xkboutline->num_points; i++) {
 | 
			
		||||
                outline->points[i].x =
 | 
			
		||||
                    xkb_to_pixmap_coord(layout, xkboutline->points[i].x);
 | 
			
		||||
                outline->points[i].y =
 | 
			
		||||
                    xkb_to_pixmap_coord(layout, xkboutline->points[i].y);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        oref = eek_keyboard_add_outline (keyboard, outline);
 | 
			
		||||
        eek_outline_free (outline);
 | 
			
		||||
        g_hash_table_insert (priv->shape_oref_hash, xkbshape,
 | 
			
		||||
                             GUINT_TO_POINTER(oref));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    memset (name, 0, sizeof name);
 | 
			
		||||
    memcpy (name, xkbkey->name.name, sizeof name - 1);
 | 
			
		||||
 | 
			
		||||
    xkbbounds = &xkbgeometry->shapes[xkbkey->shape_ndx].bounds;
 | 
			
		||||
    bounds.x = xkb_to_pixmap_coord(layout, xkbbounds->x1 + x);
 | 
			
		||||
    bounds.y = xkb_to_pixmap_coord(layout, xkbbounds->y1 + y);
 | 
			
		||||
    bounds.width = xkb_to_pixmap_coord(layout, xkbbounds->x2 - xkbbounds->x1);
 | 
			
		||||
    bounds.height = xkb_to_pixmap_coord(layout, xkbbounds->y2 - xkbbounds->y1);
 | 
			
		||||
 | 
			
		||||
    keycode = find_keycode (layout, name);
 | 
			
		||||
    if (keycode == EEK_INVALID_KEYCODE) {
 | 
			
		||||
        num_groups = num_levels = 0;
 | 
			
		||||
        matrix = eek_symbol_matrix_new (0, 0);
 | 
			
		||||
    } else {
 | 
			
		||||
        KeySym keysym;
 | 
			
		||||
        gint i, j;
 | 
			
		||||
 | 
			
		||||
        num_groups = XkbKeyNumGroups (priv->xkb, keycode);
 | 
			
		||||
        num_levels = XkbKeyGroupsWidth (priv->xkb, keycode);
 | 
			
		||||
        matrix = eek_symbol_matrix_new (num_groups, num_levels);
 | 
			
		||||
        for (i = 0; i < num_groups; i++)
 | 
			
		||||
            for (j = 0; j < num_levels; j++) {
 | 
			
		||||
                EekModifierType modifier;
 | 
			
		||||
 | 
			
		||||
                keysym = XkbKeySymEntry (priv->xkb, keycode, j, i);
 | 
			
		||||
                modifier = XkbKeysymToModifiers (priv->display, keysym);
 | 
			
		||||
                matrix->data[i * num_levels + j] =
 | 
			
		||||
                    EEK_SYMBOL(eek_keysym_new_with_modifier (keysym,
 | 
			
		||||
                                                             modifier));
 | 
			
		||||
            }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    key = eek_section_create_key (section, keycode, column, row);
 | 
			
		||||
    eek_element_set_name (EEK_ELEMENT(key), name);
 | 
			
		||||
    eek_element_set_bounds (EEK_ELEMENT(key), &bounds);
 | 
			
		||||
    eek_key_set_symbol_matrix (key, matrix);
 | 
			
		||||
    eek_symbol_matrix_free (matrix);
 | 
			
		||||
    eek_key_set_oref (key, oref);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
create_section (EekXkbLayout  *layout,
 | 
			
		||||
                EekKeyboard   *keyboard,
 | 
			
		||||
                XkbSectionRec *xkbsection)
 | 
			
		||||
{
 | 
			
		||||
    XkbGeometryRec *xkbgeometry;
 | 
			
		||||
    EekXkbLayoutPrivate *priv = eek_xkb_layout_get_instance_private (layout);
 | 
			
		||||
    EekSection *section;
 | 
			
		||||
    EekBounds bounds;
 | 
			
		||||
    gchar *name;
 | 
			
		||||
    gfloat left, top;
 | 
			
		||||
    gint i, j;
 | 
			
		||||
 | 
			
		||||
    bounds.x = xkb_to_pixmap_coord(layout, xkbsection->left);
 | 
			
		||||
    bounds.y = xkb_to_pixmap_coord(layout, xkbsection->top);
 | 
			
		||||
    bounds.width = xkb_to_pixmap_coord(layout, xkbsection->width);
 | 
			
		||||
    bounds.height = xkb_to_pixmap_coord(layout, xkbsection->height);
 | 
			
		||||
 | 
			
		||||
    xkbgeometry = priv->xkb->geom;
 | 
			
		||||
    section = eek_keyboard_create_section (keyboard);
 | 
			
		||||
    name = XGetAtomName (priv->display, xkbsection->name);
 | 
			
		||||
    eek_element_set_name (EEK_ELEMENT(section), name);
 | 
			
		||||
    XFree (name);
 | 
			
		||||
    eek_element_set_bounds (EEK_ELEMENT(section), &bounds);
 | 
			
		||||
    eek_section_set_angle (section,
 | 
			
		||||
                           /* angle is in tenth of degree */
 | 
			
		||||
                           xkbsection->angle / 10);
 | 
			
		||||
 | 
			
		||||
    for (i = 0; i < xkbsection->num_rows; i++) {
 | 
			
		||||
        XkbRowRec *xkbrow;
 | 
			
		||||
 | 
			
		||||
        xkbrow = &xkbsection->rows[i];
 | 
			
		||||
        left = xkbrow->left;
 | 
			
		||||
        top = xkbrow->top;
 | 
			
		||||
        eek_section_add_row (section,
 | 
			
		||||
                             xkbrow->num_keys,
 | 
			
		||||
                             xkbrow->vertical ?
 | 
			
		||||
                             EEK_ORIENTATION_VERTICAL :
 | 
			
		||||
                             EEK_ORIENTATION_HORIZONTAL);
 | 
			
		||||
        for (j = 0; j < xkbrow->num_keys; j++) {
 | 
			
		||||
            XkbKeyRec *xkbkey;
 | 
			
		||||
            XkbBoundsRec *xkbbounds;
 | 
			
		||||
 | 
			
		||||
            xkbkey = &xkbrow->keys[j];
 | 
			
		||||
            if (xkbrow->vertical)
 | 
			
		||||
                top += xkbkey->gap;
 | 
			
		||||
            else
 | 
			
		||||
                left += xkbkey->gap;
 | 
			
		||||
            create_key (layout, keyboard, section, j, i, left, top, xkbkey);
 | 
			
		||||
            xkbbounds = &xkbgeometry->shapes[xkbkey->shape_ndx].bounds;
 | 
			
		||||
            if (xkbrow->vertical)
 | 
			
		||||
                top += xkbbounds->y2 - xkbbounds->y1;
 | 
			
		||||
            else
 | 
			
		||||
                left += xkbbounds->x2 - xkbbounds->x1;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
create_keyboard (EekXkbLayout *layout, EekKeyboard *keyboard)
 | 
			
		||||
{
 | 
			
		||||
    EekXkbLayoutPrivate *priv = eek_xkb_layout_get_instance_private (layout);
 | 
			
		||||
    XkbGeometryRec *xkbgeometry;
 | 
			
		||||
    EekBounds bounds;
 | 
			
		||||
    gint i;
 | 
			
		||||
 | 
			
		||||
    g_return_if_fail (priv->xkb);
 | 
			
		||||
    g_return_if_fail (priv->xkb->geom);
 | 
			
		||||
 | 
			
		||||
    xkbgeometry = priv->xkb->geom;
 | 
			
		||||
 | 
			
		||||
    eek_element_get_bounds (EEK_ELEMENT(keyboard), &bounds);
 | 
			
		||||
    setup_scaling (EEK_XKB_LAYOUT(layout), bounds.width, bounds.height);
 | 
			
		||||
 | 
			
		||||
    bounds.x = bounds.y = 0;
 | 
			
		||||
    bounds.width = xkb_to_pixmap_coord(layout, xkbgeometry->width_mm);
 | 
			
		||||
    bounds.height = xkb_to_pixmap_coord(layout, xkbgeometry->height_mm);
 | 
			
		||||
 | 
			
		||||
    for (i = 0; i < xkbgeometry->num_sections; i++) {
 | 
			
		||||
        XkbSectionRec *xkbsection;
 | 
			
		||||
 | 
			
		||||
        xkbsection = &xkbgeometry->sections[i];
 | 
			
		||||
        create_section (layout, keyboard, xkbsection);
 | 
			
		||||
    }
 | 
			
		||||
    eek_element_set_bounds (EEK_ELEMENT(keyboard), &bounds);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static EekKeyboard *
 | 
			
		||||
eek_xkb_layout_real_create_keyboard (EekboardContextService *manager,
 | 
			
		||||
                                     EekLayout *self,
 | 
			
		||||
                                     gdouble    initial_width,
 | 
			
		||||
                                     gdouble    initial_height)
 | 
			
		||||
{
 | 
			
		||||
    EekKeyboard *keyboard = g_object_new (EEK_TYPE_KEYBOARD, "layout", self, NULL);
 | 
			
		||||
    keyboard->manager = manager;
 | 
			
		||||
 | 
			
		||||
    EekBounds bounds = {
 | 
			
		||||
        .x = 0.0,
 | 
			
		||||
        .y = 0.0,
 | 
			
		||||
        .width = initial_width,
 | 
			
		||||
        .height = initial_height
 | 
			
		||||
    };
 | 
			
		||||
    eek_element_set_bounds (EEK_ELEMENT(keyboard), &bounds);
 | 
			
		||||
 | 
			
		||||
    /* resolve modifiers dynamically assigned at run time */
 | 
			
		||||
    EekXkbLayoutPrivate *priv = eek_xkb_layout_get_instance_private (
 | 
			
		||||
		    EEK_XKB_LAYOUT(self));
 | 
			
		||||
    eek_keyboard_set_num_lock_mask (keyboard,
 | 
			
		||||
                                    XkbKeysymToModifiers (priv->display,
 | 
			
		||||
                                                          XK_Num_Lock));
 | 
			
		||||
    eek_keyboard_set_alt_gr_mask (keyboard,
 | 
			
		||||
                                  XkbKeysymToModifiers (priv->display,
 | 
			
		||||
                                                        XK_ISO_Level3_Shift));
 | 
			
		||||
 | 
			
		||||
    if (priv->shape_oref_hash)
 | 
			
		||||
        g_hash_table_destroy (priv->shape_oref_hash);
 | 
			
		||||
 | 
			
		||||
    priv->shape_oref_hash = g_hash_table_new (g_direct_hash, g_direct_equal);
 | 
			
		||||
    create_keyboard (EEK_XKB_LAYOUT(self), keyboard);
 | 
			
		||||
    g_hash_table_destroy (priv->shape_oref_hash);
 | 
			
		||||
 | 
			
		||||
    return keyboard;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
eek_xkb_layout_finalize (GObject *object)
 | 
			
		||||
{
 | 
			
		||||
    EekXkbLayoutPrivate *priv = eek_xkb_layout_get_instance_private (
 | 
			
		||||
		    EEK_XKB_LAYOUT (object));
 | 
			
		||||
 | 
			
		||||
    g_free (priv->names.keycodes);
 | 
			
		||||
    g_free (priv->names.geometry);
 | 
			
		||||
    g_free (priv->names.symbols);
 | 
			
		||||
    XkbFreeKeyboard (priv->xkb, 0, TRUE);	/* free_all = TRUE */
 | 
			
		||||
    G_OBJECT_CLASS (eek_xkb_layout_parent_class)->finalize (object);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void 
 | 
			
		||||
eek_xkb_layout_set_property (GObject      *object,
 | 
			
		||||
                             guint         prop_id,
 | 
			
		||||
                             const GValue *value,
 | 
			
		||||
                             GParamSpec   *pspec)
 | 
			
		||||
{
 | 
			
		||||
    EekXkbLayout *layout = EEK_XKB_LAYOUT (object);
 | 
			
		||||
    EekXkbLayoutPrivate *priv = eek_xkb_layout_get_instance_private (layout);
 | 
			
		||||
 | 
			
		||||
    switch (prop_id) {
 | 
			
		||||
    case PROP_DISPLAY:
 | 
			
		||||
        priv->display = g_value_get_pointer (value);
 | 
			
		||||
        break;
 | 
			
		||||
    default:
 | 
			
		||||
        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void 
 | 
			
		||||
eek_xkb_layout_get_property (GObject    *object,
 | 
			
		||||
                             guint       prop_id,
 | 
			
		||||
                             GValue     *value,
 | 
			
		||||
                             GParamSpec *pspec)
 | 
			
		||||
{
 | 
			
		||||
    EekXkbLayout *layout = EEK_XKB_LAYOUT (object);
 | 
			
		||||
    EekXkbLayoutPrivate *priv = eek_xkb_layout_get_instance_private (layout);
 | 
			
		||||
 | 
			
		||||
    switch (prop_id) {
 | 
			
		||||
    case PROP_DISPLAY:
 | 
			
		||||
        g_value_set_pointer (value, priv->display);
 | 
			
		||||
        break;
 | 
			
		||||
    default:
 | 
			
		||||
        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
eek_xkb_layout_class_init (EekXkbLayoutClass *klass)
 | 
			
		||||
{
 | 
			
		||||
    EekLayoutClass *layout_class = EEK_LAYOUT_CLASS (klass);
 | 
			
		||||
    GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
 | 
			
		||||
    GParamSpec *pspec;
 | 
			
		||||
 | 
			
		||||
    layout_class->create_keyboard = eek_xkb_layout_real_create_keyboard;
 | 
			
		||||
 | 
			
		||||
    gobject_class->finalize = eek_xkb_layout_finalize;
 | 
			
		||||
    gobject_class->set_property = eek_xkb_layout_set_property;
 | 
			
		||||
    gobject_class->get_property = eek_xkb_layout_get_property;
 | 
			
		||||
 | 
			
		||||
    pspec = g_param_spec_pointer ("display",
 | 
			
		||||
                                  "Display",
 | 
			
		||||
                                  "X Display",
 | 
			
		||||
                                  G_PARAM_READWRITE |
 | 
			
		||||
                                  G_PARAM_CONSTRUCT_ONLY);
 | 
			
		||||
    g_object_class_install_property (gobject_class, PROP_DISPLAY, pspec);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
eek_xkb_layout_init (EekXkbLayout *self)
 | 
			
		||||
{
 | 
			
		||||
    /* void */
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
get_names_from_server (EekXkbLayout *layout,
 | 
			
		||||
                       GError      **error)
 | 
			
		||||
{
 | 
			
		||||
    EekXkbLayoutPrivate *priv = eek_xkb_layout_get_instance_private (layout);
 | 
			
		||||
    gchar *name;
 | 
			
		||||
 | 
			
		||||
    XkbGetNames (priv->display, XkbAllNamesMask, priv->xkb);
 | 
			
		||||
 | 
			
		||||
    if (priv->xkb->names->keycodes <= 0)
 | 
			
		||||
        g_warning ("XKB keycodes setting is not loaded properly");
 | 
			
		||||
    else {
 | 
			
		||||
        name = XGetAtomName (priv->display, priv->xkb->names->keycodes);
 | 
			
		||||
        if (!name)
 | 
			
		||||
            g_warning ("Can't get the name of keycodes");
 | 
			
		||||
        else if (!priv->names.keycodes ||
 | 
			
		||||
                 g_strcmp0 (name, priv->names.keycodes)) {
 | 
			
		||||
            g_free (priv->names.keycodes);
 | 
			
		||||
            priv->names.keycodes = g_strdup (name);
 | 
			
		||||
            XFree (name);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (priv->xkb->names->geometry <= 0)
 | 
			
		||||
        g_warning ("XKB geometry setting is not loaded");
 | 
			
		||||
    else {
 | 
			
		||||
        name = XGetAtomName (priv->display, priv->xkb->names->geometry);
 | 
			
		||||
        if (!name)
 | 
			
		||||
            g_warning ("Can't get the name of geometry");
 | 
			
		||||
        else if (!priv->names.geometry ||
 | 
			
		||||
                 g_strcmp0 (name, priv->names.geometry)) {
 | 
			
		||||
            g_free (priv->names.geometry);
 | 
			
		||||
            priv->names.geometry = g_strdup (name);
 | 
			
		||||
            XFree (name);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (priv->xkb->names->symbols <= 0)
 | 
			
		||||
        g_warning ("XKB symbols setting is not loaded");
 | 
			
		||||
    else {
 | 
			
		||||
        name = XGetAtomName (priv->display, priv->xkb->names->symbols);
 | 
			
		||||
        if (!name)
 | 
			
		||||
            g_warning ("Can't get the name of symbols");
 | 
			
		||||
        else if (!priv->names.symbols ||
 | 
			
		||||
                 g_strcmp0 (name, priv->names.symbols)) {
 | 
			
		||||
            g_free (priv->names.symbols);
 | 
			
		||||
            priv->names.symbols = g_strdup (name);
 | 
			
		||||
            XFree (name);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eek_xkb_layout_new:
 | 
			
		||||
 *
 | 
			
		||||
 * Create a new #EekXkbLayout.
 | 
			
		||||
 */
 | 
			
		||||
EekLayout *
 | 
			
		||||
eek_xkb_layout_new (Display *display,
 | 
			
		||||
                    GError **error)
 | 
			
		||||
{
 | 
			
		||||
    return (EekLayout *) g_initable_new (EEK_TYPE_XKB_LAYOUT,
 | 
			
		||||
                                         NULL,
 | 
			
		||||
                                         error,
 | 
			
		||||
                                         "display", display,
 | 
			
		||||
                                         NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eek_xkb_layout_set_names: (skip)
 | 
			
		||||
 * @layout: an #EekXkbLayout
 | 
			
		||||
 * @names: XKB component names
 | 
			
		||||
 * @error: a #GError
 | 
			
		||||
 *
 | 
			
		||||
 * Set the XKB component names to @layout.
 | 
			
		||||
 * Returns: %TRUE if the component names are successfully set, %FALSE otherwise
 | 
			
		||||
 */
 | 
			
		||||
gboolean
 | 
			
		||||
eek_xkb_layout_set_names (EekXkbLayout         *layout,
 | 
			
		||||
                          XkbComponentNamesRec *names,
 | 
			
		||||
                          GError              **error)
 | 
			
		||||
{
 | 
			
		||||
    EekXkbLayoutPrivate *priv = eek_xkb_layout_get_instance_private (layout);
 | 
			
		||||
 | 
			
		||||
    if (g_strcmp0 (names->keycodes, priv->names.keycodes)) {
 | 
			
		||||
        g_free (priv->names.keycodes);
 | 
			
		||||
        priv->names.keycodes = g_strdup (names->keycodes);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (g_strcmp0 (names->geometry, priv->names.geometry)) {
 | 
			
		||||
        g_free (priv->names.geometry);
 | 
			
		||||
        priv->names.geometry = g_strdup (names->geometry);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (g_strcmp0 (names->symbols, priv->names.symbols)) {
 | 
			
		||||
        g_free (priv->names.symbols);
 | 
			
		||||
        priv->names.symbols = g_strdup (names->symbols);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return get_keyboard_from_server (layout, error);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
get_keyboard_from_server (EekXkbLayout *layout,
 | 
			
		||||
                          GError      **error)
 | 
			
		||||
{
 | 
			
		||||
    EekXkbLayoutPrivate *priv = eek_xkb_layout_get_instance_private (layout);
 | 
			
		||||
 | 
			
		||||
    if (priv->xkb) {
 | 
			
		||||
        XkbFreeKeyboard (priv->xkb, 0, True);
 | 
			
		||||
        priv->xkb = NULL;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (priv->names.keycodes && priv->names.geometry && priv->names.symbols) {
 | 
			
		||||
        priv->xkb = XkbGetKeyboardByName (priv->display,
 | 
			
		||||
                                          XkbUseCoreKbd,
 | 
			
		||||
                                          &priv->names,
 | 
			
		||||
                                          0,
 | 
			
		||||
                                          XKB_COMPONENT_MASK,
 | 
			
		||||
                                          False);
 | 
			
		||||
    } else {
 | 
			
		||||
        priv->xkb = XkbGetKeyboard (priv->display,
 | 
			
		||||
                                    XKB_COMPONENT_MASK,
 | 
			
		||||
                                    XkbUseCoreKbd);
 | 
			
		||||
        if (!get_names_from_server (layout, error)) {
 | 
			
		||||
            XkbFreeKeyboard (priv->xkb, 0, True);
 | 
			
		||||
            priv->xkb = NULL;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (priv->xkb == NULL) {
 | 
			
		||||
        g_set_error (error,
 | 
			
		||||
                     EEK_ERROR,
 | 
			
		||||
                     EEK_ERROR_LAYOUT_ERROR,
 | 
			
		||||
                     "can't get keyboard from server");
 | 
			
		||||
        g_free (priv->names.keycodes);
 | 
			
		||||
        priv->names.keycodes = NULL;
 | 
			
		||||
        g_free (priv->names.geometry);
 | 
			
		||||
        priv->names.geometry = NULL;
 | 
			
		||||
        g_free (priv->names.symbols);
 | 
			
		||||
        priv->names.symbols = NULL;
 | 
			
		||||
        return FALSE;
 | 
			
		||||
    }
 | 
			
		||||
    return TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static guint
 | 
			
		||||
find_keycode (EekXkbLayout *layout, gchar *key_name)
 | 
			
		||||
{
 | 
			
		||||
#define KEYSYM_NAME_MAX_LENGTH 4
 | 
			
		||||
    guint keycode;
 | 
			
		||||
    gint i, j;
 | 
			
		||||
    XkbKeyNamePtr pkey;
 | 
			
		||||
    XkbKeyAliasPtr palias;
 | 
			
		||||
    guint is_name_matched;
 | 
			
		||||
    gchar *src, *dst;
 | 
			
		||||
    EekXkbLayoutPrivate *priv = eek_xkb_layout_get_instance_private (layout);
 | 
			
		||||
 | 
			
		||||
    if (!priv->xkb)
 | 
			
		||||
        return EEK_INVALID_KEYCODE;
 | 
			
		||||
 | 
			
		||||
    pkey = priv->xkb->names->keys + priv->xkb->min_key_code;
 | 
			
		||||
    for (keycode = priv->xkb->min_key_code;
 | 
			
		||||
         keycode <= priv->xkb->max_key_code; keycode++) {
 | 
			
		||||
        is_name_matched = 1;
 | 
			
		||||
        src = key_name;
 | 
			
		||||
        dst = pkey->name;
 | 
			
		||||
        for (i = KEYSYM_NAME_MAX_LENGTH; --i >= 0;) {
 | 
			
		||||
            if ('\0' == *src)
 | 
			
		||||
                break;
 | 
			
		||||
            if (*src++ != *dst++) {
 | 
			
		||||
                is_name_matched = 0;
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        if (is_name_matched)
 | 
			
		||||
            return keycode;
 | 
			
		||||
        pkey++;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    palias = priv->xkb->names->key_aliases;
 | 
			
		||||
    for (j = priv->xkb->names->num_key_aliases; --j >= 0;) {
 | 
			
		||||
        is_name_matched = 1;
 | 
			
		||||
        src = key_name;
 | 
			
		||||
        dst = palias->alias;
 | 
			
		||||
        for (i = KEYSYM_NAME_MAX_LENGTH; --i >= 0;) {
 | 
			
		||||
            if ('\0' == *src)
 | 
			
		||||
                break;
 | 
			
		||||
            if (*src++ != *dst++) {
 | 
			
		||||
                is_name_matched = 0;
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (is_name_matched) {
 | 
			
		||||
            keycode = find_keycode (layout, palias->real);
 | 
			
		||||
            return keycode;
 | 
			
		||||
        }
 | 
			
		||||
        palias++;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return EEK_INVALID_KEYCODE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
setup_scaling (EekXkbLayout *layout,
 | 
			
		||||
               gdouble       width,
 | 
			
		||||
               gdouble       height)
 | 
			
		||||
{
 | 
			
		||||
    EekXkbLayoutPrivate *priv = eek_xkb_layout_get_instance_private (layout);
 | 
			
		||||
 | 
			
		||||
    g_return_if_fail (priv->xkb);
 | 
			
		||||
 | 
			
		||||
    g_return_if_fail (priv->xkb->geom->width_mm > 0);
 | 
			
		||||
    g_return_if_fail (priv->xkb->geom->height_mm > 0);
 | 
			
		||||
 | 
			
		||||
    if (width * priv->xkb->geom->height_mm <
 | 
			
		||||
        height * priv->xkb->geom->width_mm) {
 | 
			
		||||
        priv->scale_numerator = width;
 | 
			
		||||
        priv->scale_denominator = priv->xkb->geom->width_mm;
 | 
			
		||||
    } else {
 | 
			
		||||
        priv->scale_numerator = height;
 | 
			
		||||
        priv->scale_denominator = priv->xkb->geom->height_mm;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
initable_init (GInitable    *initable,
 | 
			
		||||
               GCancellable *cancellable,
 | 
			
		||||
               GError      **error)
 | 
			
		||||
{
 | 
			
		||||
    EekXkbLayout *layout = EEK_XKB_LAYOUT (initable);
 | 
			
		||||
 | 
			
		||||
    if (!get_keyboard_from_server (layout, error))
 | 
			
		||||
        return FALSE;
 | 
			
		||||
 | 
			
		||||
    if (!get_names_from_server (layout, error))
 | 
			
		||||
        return FALSE;
 | 
			
		||||
 | 
			
		||||
    return TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
initable_iface_init (GInitableIface *initable_iface)
 | 
			
		||||
{
 | 
			
		||||
  initable_iface->init = initable_init;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										55
									
								
								eek/eek-xkb-layout.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										55
									
								
								eek/eek-xkb-layout.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,55 @@
 | 
			
		||||
/* 
 | 
			
		||||
 * Copyright (C) 2010-2011 Daiki Ueno <ueno@unixuser.org>
 | 
			
		||||
 * Copyright (C) 2010-2011 Red Hat, Inc.
 | 
			
		||||
 * 
 | 
			
		||||
 * This library is free software; you can redistribute it and/or
 | 
			
		||||
 * modify it under the terms of the GNU Lesser General Public License
 | 
			
		||||
 * as published by the Free Software Foundation; either version 2 of
 | 
			
		||||
 * the License, or (at your option) any later version.
 | 
			
		||||
 * 
 | 
			
		||||
 * This library is distributed in the hope that it will be useful, but
 | 
			
		||||
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
			
		||||
 * Lesser General Public License for more details.
 | 
			
		||||
 * 
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General Public
 | 
			
		||||
 * License along with this library; if not, write to the Free Software
 | 
			
		||||
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 | 
			
		||||
 * 02110-1301 USA
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#if !defined(__EEK_H_INSIDE__) && !defined(EEK_COMPILATION)
 | 
			
		||||
#error "Only <eek/eek-xkb.h> can be included directly."
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef EEK_XKB_LAYOUT_H
 | 
			
		||||
#define EEK_XKB_LAYOUT_H 1
 | 
			
		||||
 | 
			
		||||
#include <X11/XKBlib.h>
 | 
			
		||||
#include "eek-layout.h"
 | 
			
		||||
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
#define EEK_TYPE_XKB_LAYOUT (eek_xkb_layout_get_type())
 | 
			
		||||
G_DECLARE_DERIVABLE_TYPE (EekXkbLayout, eek_xkb_layout, EEK, XKB_LAYOUT, EekLayout)
 | 
			
		||||
 | 
			
		||||
struct _EekXkbLayoutClass
 | 
			
		||||
{
 | 
			
		||||
    /*< private >*/
 | 
			
		||||
    EekLayoutClass parent_class;
 | 
			
		||||
 | 
			
		||||
    /*< private >*/
 | 
			
		||||
    /* padding */
 | 
			
		||||
    gpointer pdummy[24];
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
GType      eek_xkb_layout_get_type  (void) G_GNUC_CONST;
 | 
			
		||||
EekLayout *eek_xkb_layout_new       (Display              *display,
 | 
			
		||||
                                     GError              **error);
 | 
			
		||||
 | 
			
		||||
gboolean   eek_xkb_layout_set_names (EekXkbLayout         *layout,
 | 
			
		||||
                                     XkbComponentNamesRec *names,
 | 
			
		||||
                                     GError              **error);
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
#endif				/* #ifndef EEK_XKB_LAYOUT_H */
 | 
			
		||||
							
								
								
									
										26
									
								
								eek/eek-xkb.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								eek/eek-xkb.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,26 @@
 | 
			
		||||
/* 
 | 
			
		||||
 * Copyright (C) 2010-2011 Daiki Ueno <ueno@unixuser.org>
 | 
			
		||||
 * Copyright (C) 2010-2011 Red Hat, Inc.
 | 
			
		||||
 * 
 | 
			
		||||
 * This library is free software; you can redistribute it and/or
 | 
			
		||||
 * modify it under the terms of the GNU Lesser General Public License
 | 
			
		||||
 * as published by the Free Software Foundation; either version 2 of
 | 
			
		||||
 * the License, or (at your option) any later version.
 | 
			
		||||
 * 
 | 
			
		||||
 * This library is distributed in the hope that it will be useful, but
 | 
			
		||||
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
			
		||||
 * Lesser General Public License for more details.
 | 
			
		||||
 * 
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General Public
 | 
			
		||||
 * License along with this library; if not, write to the Free Software
 | 
			
		||||
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 | 
			
		||||
 * 02110-1301 USA
 | 
			
		||||
 */
 | 
			
		||||
#ifndef EEK_XKB_H
 | 
			
		||||
#define EEK_XKB_H 1
 | 
			
		||||
 | 
			
		||||
#include "eek.h"
 | 
			
		||||
#include "eek-xkb-layout.h"
 | 
			
		||||
 | 
			
		||||
#endif  /* EEK_XKB_H */
 | 
			
		||||
							
								
								
									
										30
									
								
								eek/eek-xkl-0.90.pc.in
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								eek/eek-xkl-0.90.pc.in
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,30 @@
 | 
			
		||||
# Copyright (C) 2010-2011 Daiki Ueno <ueno@unixuser.org>
 | 
			
		||||
# Copyright (C) 2010-2011 Red Hat, Inc.
 | 
			
		||||
 | 
			
		||||
# This library is free software; you can redistribute it and/or
 | 
			
		||||
# modify it under the terms of the GNU Lesser General Public License
 | 
			
		||||
# as published by the Free Software Foundation; either version 2 of
 | 
			
		||||
# the License, or (at your option) any later version.
 | 
			
		||||
 | 
			
		||||
# This library is distributed in the hope that it will be useful, but
 | 
			
		||||
# WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
			
		||||
# Lesser General Public License for more details.
 | 
			
		||||
 | 
			
		||||
# You should have received a copy of the GNU Lesser General Public
 | 
			
		||||
# License along with this library; if not, write to the Free Software
 | 
			
		||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 | 
			
		||||
# 02110-1301 USA
 | 
			
		||||
 | 
			
		||||
prefix=@prefix@
 | 
			
		||||
exec_prefix=@exec_prefix@
 | 
			
		||||
libdir=@libdir@
 | 
			
		||||
includedir=@includedir@
 | 
			
		||||
 | 
			
		||||
Name: libeek-xkl
 | 
			
		||||
Description: A Library to Create Keyboard-like UI (Libxklavier Support)
 | 
			
		||||
URL: http://fedorahosted.org/eekboard/
 | 
			
		||||
Version: @VERSION@
 | 
			
		||||
Requires: eek-@EEK_API_VERSION@ libxklavier
 | 
			
		||||
Libs: -L${libdir} -leek-xkl
 | 
			
		||||
Cflags: -I${includedir}/eek-@EEK_API_VERSION@
 | 
			
		||||
							
								
								
									
										662
									
								
								eek/eek-xkl-layout.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										662
									
								
								eek/eek-xkl-layout.c
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,662 @@
 | 
			
		||||
/* 
 | 
			
		||||
 * Copyright (C) 2010-2011 Daiki Ueno <ueno@unixuser.org>
 | 
			
		||||
 * Copyright (C) 2010-2011 Red Hat, Inc.
 | 
			
		||||
 * 
 | 
			
		||||
 * This library is free software; you can redistribute it and/or
 | 
			
		||||
 * modify it under the terms of the GNU Lesser General Public License
 | 
			
		||||
 * as published by the Free Software Foundation; either version 2 of
 | 
			
		||||
 * the License, or (at your option) any later version.
 | 
			
		||||
 * 
 | 
			
		||||
 * This library is distributed in the hope that it will be useful, but
 | 
			
		||||
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
			
		||||
 * Lesser General Public License for more details.
 | 
			
		||||
 * 
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General Public
 | 
			
		||||
 * License along with this library; if not, write to the Free Software
 | 
			
		||||
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 | 
			
		||||
 * 02110-1301 USA
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * SECTION:eek-xkl-layout
 | 
			
		||||
 * @short_description: Layout engine using Libxklavier configuration
 | 
			
		||||
 *
 | 
			
		||||
 * The #EekXklLayout is a simple wrapper around #EekXkbLayout class
 | 
			
		||||
 * to use Libxklavier configuration.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_CONFIG_H
 | 
			
		||||
#include "config.h"
 | 
			
		||||
#endif  /* HAVE_CONFIG_H */
 | 
			
		||||
 | 
			
		||||
#include <libxklavier/xklavier.h>
 | 
			
		||||
#include <gio/gio.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
#include "eek-xkl-layout.h"
 | 
			
		||||
 | 
			
		||||
#define noKBDRAW_DEBUG
 | 
			
		||||
 | 
			
		||||
static GInitableIface *parent_initable_iface;
 | 
			
		||||
 | 
			
		||||
static void initable_iface_init (GInitableIface *initable_iface);
 | 
			
		||||
 | 
			
		||||
enum {
 | 
			
		||||
    PROP_0,
 | 
			
		||||
    PROP_MODEL,
 | 
			
		||||
    PROP_LAYOUTS,
 | 
			
		||||
    PROP_VARIANTS,
 | 
			
		||||
    PROP_OPTIONS,
 | 
			
		||||
    PROP_LAST
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
typedef struct _EekXklLayoutPrivate
 | 
			
		||||
{
 | 
			
		||||
    XklEngine *engine;
 | 
			
		||||
    XklConfigRec *config;
 | 
			
		||||
} EekXklLayoutPrivate;
 | 
			
		||||
 | 
			
		||||
G_DEFINE_TYPE_EXTENDED (EekXklLayout, eek_xkl_layout, EEK_TYPE_XKB_LAYOUT,
 | 
			
		||||
			0, /* GTypeFlags */
 | 
			
		||||
			G_ADD_PRIVATE (EekXklLayout)
 | 
			
		||||
                        G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE,
 | 
			
		||||
                                               initable_iface_init))
 | 
			
		||||
 | 
			
		||||
/* from gnome-keyboard-properties-xkbpv.c:
 | 
			
		||||
 *  BAD STYLE: Taken from xklavier_private_xkb.h
 | 
			
		||||
 *  Any ideas on architectural improvements are WELCOME
 | 
			
		||||
 */
 | 
			
		||||
extern gboolean xkl_xkb_config_native_prepare (XklEngine * engine,
 | 
			
		||||
					       const XklConfigRec * data,
 | 
			
		||||
					       XkbComponentNamesPtr
 | 
			
		||||
					       component_names);
 | 
			
		||||
 | 
			
		||||
extern void xkl_xkb_config_native_cleanup (XklEngine * engine,
 | 
			
		||||
					   XkbComponentNamesPtr
 | 
			
		||||
					   component_names);
 | 
			
		||||
 | 
			
		||||
static gboolean set_xkb_component_names (EekXklLayout *layout,
 | 
			
		||||
                                         XklConfigRec *config);
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
eek_xkl_layout_dispose (GObject *object)
 | 
			
		||||
{
 | 
			
		||||
    EekXklLayoutPrivate *priv = eek_xkl_layout_get_instance_private (
 | 
			
		||||
		    EEK_XKL_LAYOUT (object));
 | 
			
		||||
 | 
			
		||||
    if (priv->config) {
 | 
			
		||||
        g_object_unref (priv->config);
 | 
			
		||||
        priv->config = NULL;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    G_OBJECT_CLASS (eek_xkl_layout_parent_class)->dispose (object);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void 
 | 
			
		||||
eek_xkl_layout_set_property (GObject      *object,
 | 
			
		||||
                             guint         prop_id,
 | 
			
		||||
                             const GValue *value,
 | 
			
		||||
                             GParamSpec   *pspec)
 | 
			
		||||
{
 | 
			
		||||
    EekXklLayout *layout = EEK_XKL_LAYOUT(object);
 | 
			
		||||
 | 
			
		||||
    switch (prop_id) {
 | 
			
		||||
    case PROP_MODEL:
 | 
			
		||||
        eek_xkl_layout_set_model (layout, g_value_get_string (value));
 | 
			
		||||
        break;
 | 
			
		||||
    case PROP_LAYOUTS:
 | 
			
		||||
        eek_xkl_layout_set_layouts (layout, g_value_get_boxed (value));
 | 
			
		||||
        break;
 | 
			
		||||
    case PROP_VARIANTS:
 | 
			
		||||
        eek_xkl_layout_set_variants (layout, g_value_get_boxed (value));
 | 
			
		||||
        break;
 | 
			
		||||
    case PROP_OPTIONS:
 | 
			
		||||
        eek_xkl_layout_set_options (layout, g_value_get_boxed (value));
 | 
			
		||||
        break;
 | 
			
		||||
    default:
 | 
			
		||||
        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void 
 | 
			
		||||
eek_xkl_layout_get_property (GObject    *object,
 | 
			
		||||
                             guint       prop_id,
 | 
			
		||||
                             GValue     *value,
 | 
			
		||||
                             GParamSpec *pspec)
 | 
			
		||||
{
 | 
			
		||||
    EekXklLayout *layout = EEK_XKL_LAYOUT(object);
 | 
			
		||||
 | 
			
		||||
    switch (prop_id) {
 | 
			
		||||
    case PROP_MODEL:
 | 
			
		||||
        g_value_set_string (value,
 | 
			
		||||
                            eek_xkl_layout_get_model (layout));
 | 
			
		||||
        break;
 | 
			
		||||
    case PROP_LAYOUTS:
 | 
			
		||||
        g_value_set_boxed (value,
 | 
			
		||||
                           eek_xkl_layout_get_layouts (layout));
 | 
			
		||||
        break;
 | 
			
		||||
    case PROP_VARIANTS:
 | 
			
		||||
        g_value_set_boxed (value,
 | 
			
		||||
                           eek_xkl_layout_get_variants (layout));
 | 
			
		||||
        break;
 | 
			
		||||
    case PROP_OPTIONS:
 | 
			
		||||
        g_value_set_boxed (value,
 | 
			
		||||
                           eek_xkl_layout_get_options (layout));
 | 
			
		||||
        break;
 | 
			
		||||
    default:
 | 
			
		||||
        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
eek_xkl_layout_class_init (EekXklLayoutClass *klass)
 | 
			
		||||
{
 | 
			
		||||
    GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
 | 
			
		||||
    GParamSpec *pspec;
 | 
			
		||||
 | 
			
		||||
    gobject_class->dispose = eek_xkl_layout_dispose;
 | 
			
		||||
    gobject_class->set_property = eek_xkl_layout_set_property;
 | 
			
		||||
    gobject_class->get_property = eek_xkl_layout_get_property;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * EekXklLayout:model:
 | 
			
		||||
     *
 | 
			
		||||
     * The libxklavier model name of #EekXklLayout.
 | 
			
		||||
     */
 | 
			
		||||
    pspec = g_param_spec_string ("model",
 | 
			
		||||
                                 "Model",
 | 
			
		||||
                                 "Libxklavier model",
 | 
			
		||||
                                 NULL,
 | 
			
		||||
                                 G_PARAM_READWRITE);
 | 
			
		||||
    g_object_class_install_property (gobject_class, PROP_MODEL, pspec);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * EekXklLayout:layouts:
 | 
			
		||||
     *
 | 
			
		||||
     * The libxklavier layout names of #EekXklLayout.
 | 
			
		||||
     */
 | 
			
		||||
    pspec = g_param_spec_boxed ("layouts",
 | 
			
		||||
                                "Layouts",
 | 
			
		||||
                                "Libxklavier layouts",
 | 
			
		||||
                                G_TYPE_STRV,
 | 
			
		||||
                                G_PARAM_READWRITE);
 | 
			
		||||
    g_object_class_install_property (gobject_class, PROP_LAYOUTS, pspec);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * EekXklLayout:variants:
 | 
			
		||||
     *
 | 
			
		||||
     * The libxklavier variant names of #EekXklLayout.
 | 
			
		||||
     */
 | 
			
		||||
    pspec = g_param_spec_boxed ("variants",
 | 
			
		||||
                                "Variants",
 | 
			
		||||
                                "Libxklavier variants",
 | 
			
		||||
                                G_TYPE_STRV,
 | 
			
		||||
                                G_PARAM_READWRITE);
 | 
			
		||||
    g_object_class_install_property (gobject_class, PROP_VARIANTS, pspec);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * EekXklLayout:options:
 | 
			
		||||
     *
 | 
			
		||||
     * The libxklavier option names of #EekXklLayout.
 | 
			
		||||
     */
 | 
			
		||||
    pspec = g_param_spec_boxed ("options",
 | 
			
		||||
                                "Options",
 | 
			
		||||
                                "Libxklavier options",
 | 
			
		||||
                                G_TYPE_STRV,
 | 
			
		||||
                                G_PARAM_READWRITE);
 | 
			
		||||
    g_object_class_install_property (gobject_class, PROP_OPTIONS, pspec);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
eek_xkl_layout_init (EekXklLayout *self)
 | 
			
		||||
{
 | 
			
		||||
    /* void */
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eek_xkl_layout_new:
 | 
			
		||||
 *
 | 
			
		||||
 * Create a new #EekXklLayout.
 | 
			
		||||
 */
 | 
			
		||||
EekLayout *
 | 
			
		||||
eek_xkl_layout_new (Display *display, GError **error)
 | 
			
		||||
{
 | 
			
		||||
    return (EekLayout *) g_initable_new (EEK_TYPE_XKL_LAYOUT,
 | 
			
		||||
                                         NULL,
 | 
			
		||||
                                         error,
 | 
			
		||||
                                         "display", display,
 | 
			
		||||
                                         NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
G_INLINE_FUNC void
 | 
			
		||||
merge_xkl_config_rec (XklConfigRec *dst, XklConfigRec *src)
 | 
			
		||||
{
 | 
			
		||||
    if (src->model) {
 | 
			
		||||
        g_free (dst->model);
 | 
			
		||||
        dst->model = g_strdup (src->model);
 | 
			
		||||
    }
 | 
			
		||||
    if (src->layouts) {
 | 
			
		||||
        g_strfreev (dst->layouts);
 | 
			
		||||
        dst->layouts = g_strdupv (src->layouts);
 | 
			
		||||
    }
 | 
			
		||||
    if (src->variants) {
 | 
			
		||||
        g_strfreev (dst->variants);
 | 
			
		||||
        dst->variants = g_strdupv (src->variants);
 | 
			
		||||
    }
 | 
			
		||||
    if (src->options) {
 | 
			
		||||
        g_strfreev (dst->options);
 | 
			
		||||
        dst->options = g_strdupv (src->options);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eek_xkl_layout_set_config: (skip)
 | 
			
		||||
 * @layout: an #EekXklLayout
 | 
			
		||||
 * @config: Libxklavier configuration
 | 
			
		||||
 *
 | 
			
		||||
 * Reconfigure @layout with @config.
 | 
			
		||||
 * Returns: %TRUE if the current layout changed, %FALSE otherwise
 | 
			
		||||
 */
 | 
			
		||||
gboolean
 | 
			
		||||
eek_xkl_layout_set_config (EekXklLayout *layout,
 | 
			
		||||
                           XklConfigRec *config)
 | 
			
		||||
{
 | 
			
		||||
    EekXklLayoutPrivate *priv = eek_xkl_layout_get_instance_private (layout);
 | 
			
		||||
    XklConfigRec *c;
 | 
			
		||||
    gboolean retval;
 | 
			
		||||
 | 
			
		||||
    g_return_val_if_fail (priv, FALSE);
 | 
			
		||||
    c = xkl_config_rec_new ();
 | 
			
		||||
    merge_xkl_config_rec (c, priv->config);
 | 
			
		||||
    merge_xkl_config_rec (c, config);
 | 
			
		||||
    retval = set_xkb_component_names (layout, c);
 | 
			
		||||
    g_object_unref (c);
 | 
			
		||||
    merge_xkl_config_rec (priv->config, config);
 | 
			
		||||
    return retval;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eek_xkl_layout_set_config_full:
 | 
			
		||||
 * @layout: an #EekXklLayout
 | 
			
		||||
 * @model: Libxklavier model name
 | 
			
		||||
 * @layouts: Libxklavier layouts
 | 
			
		||||
 * @variants: Libxklavier variants
 | 
			
		||||
 * @options: Libxklavier options
 | 
			
		||||
 *
 | 
			
		||||
 * Reconfigure @layout with @model, @layouts, @variants, and @options.
 | 
			
		||||
 * This function is merely a wrapper around
 | 
			
		||||
 * eek_xkl_layout_set_config() to avoid passing a pointer of
 | 
			
		||||
 * XklConfigRec, which is not currently available in the
 | 
			
		||||
 * gobject-introspection repository.
 | 
			
		||||
 *
 | 
			
		||||
 * Returns: %TRUE if the current layout changed, %FALSE otherwise
 | 
			
		||||
 * Since: 0.0.2
 | 
			
		||||
 */
 | 
			
		||||
gboolean
 | 
			
		||||
eek_xkl_layout_set_config_full (EekXklLayout *layout,
 | 
			
		||||
                                gchar *model,
 | 
			
		||||
                                gchar **layouts,
 | 
			
		||||
                                gchar **variants,
 | 
			
		||||
                                gchar **options)
 | 
			
		||||
{
 | 
			
		||||
    XklConfigRec *config;
 | 
			
		||||
    gboolean retval;
 | 
			
		||||
 | 
			
		||||
    config = xkl_config_rec_new ();
 | 
			
		||||
    config->model = g_strdup (model);
 | 
			
		||||
    config->layouts = g_strdupv (layouts);
 | 
			
		||||
    config->variants = g_strdupv (variants);
 | 
			
		||||
    config->options = g_strdupv (options);
 | 
			
		||||
    retval = eek_xkl_layout_set_config (layout, config);
 | 
			
		||||
    g_object_unref (config);
 | 
			
		||||
    return retval;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eek_xkl_layout_set_model:
 | 
			
		||||
 * @layout: an #EekXklLayout
 | 
			
		||||
 * @model: model name
 | 
			
		||||
 *
 | 
			
		||||
 * Set the model name of @layout configuration (in the Libxklavier terminology).
 | 
			
		||||
 * Returns: %TRUE if the current layout changed, %FALSE otherwise
 | 
			
		||||
 */
 | 
			
		||||
gboolean
 | 
			
		||||
eek_xkl_layout_set_model (EekXklLayout *layout,
 | 
			
		||||
                          const gchar  *model)
 | 
			
		||||
{
 | 
			
		||||
    EekXklLayoutPrivate *priv = eek_xkl_layout_get_instance_private (layout);
 | 
			
		||||
    XklConfigRec *config;
 | 
			
		||||
    gboolean retval;
 | 
			
		||||
    
 | 
			
		||||
    g_return_val_if_fail (priv, FALSE);
 | 
			
		||||
    config = xkl_config_rec_new ();
 | 
			
		||||
    /* config->model will be freed on g_object_unref (config) */
 | 
			
		||||
    if (model)
 | 
			
		||||
        config->model = g_strdup (model);
 | 
			
		||||
    else
 | 
			
		||||
        config->model = NULL;
 | 
			
		||||
    retval = eek_xkl_layout_set_config (layout, config);
 | 
			
		||||
    g_object_unref (config);
 | 
			
		||||
    return retval;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eek_xkl_layout_set_layouts:
 | 
			
		||||
 * @layout: an #EekXklLayout
 | 
			
		||||
 * @layouts: layout names
 | 
			
		||||
 *
 | 
			
		||||
 * Set the layout names of @layout (in the Libxklavier terminology).
 | 
			
		||||
 * Returns: %TRUE if the current layout changed, %FALSE otherwise
 | 
			
		||||
 */
 | 
			
		||||
gboolean
 | 
			
		||||
eek_xkl_layout_set_layouts (EekXklLayout *layout,
 | 
			
		||||
                            gchar       **layouts)
 | 
			
		||||
{
 | 
			
		||||
    EekXklLayoutPrivate *priv = eek_xkl_layout_get_instance_private (layout);
 | 
			
		||||
    XklConfigRec *config;
 | 
			
		||||
    gboolean retval;
 | 
			
		||||
 | 
			
		||||
    g_return_val_if_fail (priv, FALSE);
 | 
			
		||||
    config = xkl_config_rec_new ();
 | 
			
		||||
    /* config->layouts will be freed on g_object_unref (config) */
 | 
			
		||||
    if (layouts)
 | 
			
		||||
        config->layouts = g_strdupv (layouts);
 | 
			
		||||
    else
 | 
			
		||||
        config->layouts = layouts;
 | 
			
		||||
    retval = eek_xkl_layout_set_config (layout, config);
 | 
			
		||||
    g_object_unref (config);
 | 
			
		||||
    return retval;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eek_xkl_layout_set_variants:
 | 
			
		||||
 * @layout: an #EekXklLayout
 | 
			
		||||
 * @variants: variant names
 | 
			
		||||
 *
 | 
			
		||||
 * Set the variant names of @layout (in the Libxklavier terminology).
 | 
			
		||||
 * Returns: %TRUE if the current layout changed, %FALSE otherwise
 | 
			
		||||
 */
 | 
			
		||||
gboolean
 | 
			
		||||
eek_xkl_layout_set_variants (EekXklLayout *layout,
 | 
			
		||||
                             gchar       **variants)
 | 
			
		||||
{
 | 
			
		||||
    EekXklLayoutPrivate *priv = eek_xkl_layout_get_instance_private (layout);
 | 
			
		||||
    XklConfigRec *config;
 | 
			
		||||
    gboolean retval;
 | 
			
		||||
 | 
			
		||||
    g_return_val_if_fail (priv, FALSE);
 | 
			
		||||
    config = xkl_config_rec_new ();
 | 
			
		||||
    /* config->variants will be freed on g_object_unref (config) */
 | 
			
		||||
    if (variants)
 | 
			
		||||
        config->variants = g_strdupv (variants);
 | 
			
		||||
    else
 | 
			
		||||
        config->variants = NULL;
 | 
			
		||||
    retval = eek_xkl_layout_set_config (layout, config);
 | 
			
		||||
    g_object_unref (config);
 | 
			
		||||
    return retval;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eek_xkl_layout_set_options:
 | 
			
		||||
 * @layout: an #EekXklLayout
 | 
			
		||||
 * @options: option names
 | 
			
		||||
 *
 | 
			
		||||
 * Set the option names of @layout (in the Libxklavier terminology).
 | 
			
		||||
 * Returns: %TRUE if the current layout changed, %FALSE otherwise
 | 
			
		||||
 */
 | 
			
		||||
gboolean
 | 
			
		||||
eek_xkl_layout_set_options (EekXklLayout *layout,
 | 
			
		||||
                            gchar       **options)
 | 
			
		||||
{
 | 
			
		||||
    EekXklLayoutPrivate *priv = eek_xkl_layout_get_instance_private (layout);
 | 
			
		||||
    XklConfigRec *config;
 | 
			
		||||
    gboolean retval;
 | 
			
		||||
 | 
			
		||||
    g_return_val_if_fail (priv, FALSE);
 | 
			
		||||
    config = xkl_config_rec_new ();
 | 
			
		||||
    /* config->options will be freed on g_object_unref (config) */
 | 
			
		||||
    if (options)
 | 
			
		||||
        config->options = options;
 | 
			
		||||
    else
 | 
			
		||||
        config->options = NULL;
 | 
			
		||||
    retval = eek_xkl_layout_set_config (layout, config);
 | 
			
		||||
    g_object_unref (config);
 | 
			
		||||
    return retval;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eek_xkl_layout_enable_option:
 | 
			
		||||
 * @layout: an #EekXklLayout
 | 
			
		||||
 * @option: option name
 | 
			
		||||
 *
 | 
			
		||||
 * Set the option of @layout (in the Libxklavier terminology).
 | 
			
		||||
 * Returns: %TRUE if the current layout changed, %FALSE otherwise
 | 
			
		||||
 */
 | 
			
		||||
gboolean
 | 
			
		||||
eek_xkl_layout_enable_option  (EekXklLayout *layout,
 | 
			
		||||
                               const gchar  *option)
 | 
			
		||||
{
 | 
			
		||||
    gchar **options, **_options;
 | 
			
		||||
    gint i, j;
 | 
			
		||||
 | 
			
		||||
    options = eek_xkl_layout_get_options (layout);
 | 
			
		||||
    for (i = 0; options && options[i]; i++)
 | 
			
		||||
        if (g_strcmp0 (options[i], option) == 0)
 | 
			
		||||
            return TRUE;
 | 
			
		||||
    _options = g_new0 (gchar *, (i + 2));
 | 
			
		||||
    for (j = 0; j < i; j++)
 | 
			
		||||
        _options[j] = g_strdup (options[j]);
 | 
			
		||||
    _options[i] = g_strdup (option);
 | 
			
		||||
    /* eek_xkl_layout_set_options() will free _options and its elements. */
 | 
			
		||||
    return eek_xkl_layout_set_options (layout, _options);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eek_xkl_layout_disable_option:
 | 
			
		||||
 * @layout: an #EekXklLayout
 | 
			
		||||
 * @option: option name
 | 
			
		||||
 *
 | 
			
		||||
 * Unset the option of @layout (in the Libxklavier terminology).
 | 
			
		||||
 * Returns: %TRUE if the current layout changed, %FALSE otherwise
 | 
			
		||||
 */
 | 
			
		||||
gboolean
 | 
			
		||||
eek_xkl_layout_disable_option (EekXklLayout *layout,
 | 
			
		||||
                               const gchar  *option)
 | 
			
		||||
{
 | 
			
		||||
    gchar **options, **_options;
 | 
			
		||||
    gint i, j, k;
 | 
			
		||||
 | 
			
		||||
    options = eek_xkl_layout_get_options (layout);
 | 
			
		||||
    if (!options)
 | 
			
		||||
        return TRUE;
 | 
			
		||||
    for (i = 0, k = 0; options[i]; i++)
 | 
			
		||||
        if (g_strcmp0 (options[i], option) == 0)
 | 
			
		||||
            k = i;
 | 
			
		||||
    if (options[k] == NULL)
 | 
			
		||||
        return TRUE;
 | 
			
		||||
    _options = g_new0 (gchar *, i);
 | 
			
		||||
    for (j = 0; j < k; j++)
 | 
			
		||||
        _options[j] = g_strdup (options[j]);
 | 
			
		||||
    for (j = k + 1; j < i; j++)
 | 
			
		||||
        _options[j] = g_strdup (options[j]);
 | 
			
		||||
    /* eek_xkl_layout_set_options() will free _options and its elements. */
 | 
			
		||||
    return eek_xkl_layout_set_options (layout, _options);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eek_xkl_layout_get_model:
 | 
			
		||||
 * @layout: an #EekXklLayout
 | 
			
		||||
 *
 | 
			
		||||
 * Get the model name of @layout configuration (in the Libxklavier terminology).
 | 
			
		||||
 */
 | 
			
		||||
gchar *
 | 
			
		||||
eek_xkl_layout_get_model (EekXklLayout *layout)
 | 
			
		||||
{
 | 
			
		||||
    EekXklLayoutPrivate *priv = eek_xkl_layout_get_instance_private (layout);
 | 
			
		||||
 | 
			
		||||
    g_return_val_if_fail (priv, NULL);
 | 
			
		||||
    return g_strdup (priv->config->model);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eek_xkl_layout_get_layouts:
 | 
			
		||||
 * @layout: an #EekXklLayout
 | 
			
		||||
 *
 | 
			
		||||
 * Get the layout names of @layout configuration (in the Libxklavier
 | 
			
		||||
 * terminology).
 | 
			
		||||
 */
 | 
			
		||||
gchar **
 | 
			
		||||
eek_xkl_layout_get_layouts (EekXklLayout *layout)
 | 
			
		||||
{
 | 
			
		||||
    EekXklLayoutPrivate *priv = eek_xkl_layout_get_instance_private (layout);
 | 
			
		||||
 | 
			
		||||
    g_return_val_if_fail (priv, NULL);
 | 
			
		||||
    return g_strdupv (priv->config->layouts);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eek_xkl_layout_get_variants:
 | 
			
		||||
 * @layout: an #EekXklLayout
 | 
			
		||||
 *
 | 
			
		||||
 * Get the variant names of @layout configuration (in the Libxklavier
 | 
			
		||||
 * terminology).
 | 
			
		||||
 */
 | 
			
		||||
gchar **
 | 
			
		||||
eek_xkl_layout_get_variants (EekXklLayout *layout)
 | 
			
		||||
{
 | 
			
		||||
    EekXklLayoutPrivate *priv = eek_xkl_layout_get_instance_private (layout);
 | 
			
		||||
 | 
			
		||||
    g_return_val_if_fail (priv, NULL);
 | 
			
		||||
    return g_strdupv (priv->config->variants);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eek_xkl_layout_get_options:
 | 
			
		||||
 * @layout: an #EekXklLayout
 | 
			
		||||
 *
 | 
			
		||||
 * Get the option names of @layout configuration (in the Libxklavier
 | 
			
		||||
 * terminology).
 | 
			
		||||
 */
 | 
			
		||||
gchar **
 | 
			
		||||
eek_xkl_layout_get_options (EekXklLayout *layout)
 | 
			
		||||
{
 | 
			
		||||
    EekXklLayoutPrivate *priv = eek_xkl_layout_get_instance_private (layout);
 | 
			
		||||
 | 
			
		||||
    g_return_val_if_fail (priv, NULL);
 | 
			
		||||
    return g_strdupv (priv->config->options);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
set_xkb_component_names (EekXklLayout *layout, XklConfigRec *config)
 | 
			
		||||
{
 | 
			
		||||
    EekXklLayoutPrivate *priv = eek_xkl_layout_get_instance_private (layout);
 | 
			
		||||
    XkbComponentNamesRec names;
 | 
			
		||||
    gboolean retval = FALSE;
 | 
			
		||||
 | 
			
		||||
#if DEBUG
 | 
			
		||||
    if (config->layouts) {
 | 
			
		||||
        gint i;
 | 
			
		||||
 | 
			
		||||
        fprintf (stderr, "layout = ");
 | 
			
		||||
        for (i = 0; config->layouts[i] != NULL; i++)
 | 
			
		||||
            fprintf (stderr, "\"%s\" ", config->layouts[i]);
 | 
			
		||||
        fputc ('\n', stderr);
 | 
			
		||||
    } else
 | 
			
		||||
        fprintf (stderr, "layouts = NULL\n");
 | 
			
		||||
    if (config->variants) {
 | 
			
		||||
        gint i;
 | 
			
		||||
 | 
			
		||||
        fprintf (stderr, "variant = ");
 | 
			
		||||
        for (i = 0; config->variants[i]; i++)
 | 
			
		||||
            fprintf (stderr, "\"%s\" ", config->variants[i]);
 | 
			
		||||
        fputc ('\n', stderr);
 | 
			
		||||
    } else
 | 
			
		||||
        fprintf (stderr, "variants = NULL\n");
 | 
			
		||||
    if (config->options) {
 | 
			
		||||
        gint i;
 | 
			
		||||
 | 
			
		||||
        fprintf (stderr, "option = ");
 | 
			
		||||
        for (i = 0; config->options[i]; i++)
 | 
			
		||||
            fprintf (stderr, "\"%s\" ", config->options[i]);
 | 
			
		||||
        fputc ('\n', stderr);
 | 
			
		||||
    } else
 | 
			
		||||
        fprintf (stderr, "options = NULL\n");
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    if (xkl_xkb_config_native_prepare (priv->engine, config, &names)) {
 | 
			
		||||
        GError *error = NULL;
 | 
			
		||||
        retval = eek_xkb_layout_set_names (EEK_XKB_LAYOUT(layout),
 | 
			
		||||
                                           &names,
 | 
			
		||||
                                           &error);
 | 
			
		||||
        if (!retval)
 | 
			
		||||
            g_warning ("can't set XKB layout");
 | 
			
		||||
        xkl_xkb_config_native_cleanup (priv->engine, &names);
 | 
			
		||||
    }
 | 
			
		||||
    return retval;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eek_xkl_layout_get_option:
 | 
			
		||||
 * @layout: an #EekXklLayout
 | 
			
		||||
 * @option: option name
 | 
			
		||||
 *
 | 
			
		||||
 * Tell if the option of @layout (in the Libxklavier terminology) is set.
 | 
			
		||||
 * Returns: %TRUE if the option is set, %FALSE otherwise
 | 
			
		||||
 */
 | 
			
		||||
gboolean
 | 
			
		||||
eek_xkl_layout_get_option (EekXklLayout *layout,
 | 
			
		||||
                           const gchar  *option)
 | 
			
		||||
{
 | 
			
		||||
    gchar **options;
 | 
			
		||||
    gint i;
 | 
			
		||||
 | 
			
		||||
    options = eek_xkl_layout_get_options (layout);
 | 
			
		||||
    for (i = 0; options && options[i]; i++)
 | 
			
		||||
        if (g_strcmp0 (options[i], option) == 0)
 | 
			
		||||
            return TRUE;
 | 
			
		||||
    return FALSE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
initable_init (GInitable    *initable,
 | 
			
		||||
               GCancellable *cancellable,
 | 
			
		||||
               GError      **error)
 | 
			
		||||
{
 | 
			
		||||
    EekXklLayout *layout = EEK_XKL_LAYOUT (initable);
 | 
			
		||||
    EekXklLayoutPrivate *priv = eek_xkl_layout_get_instance_private (layout);
 | 
			
		||||
    Display *display;
 | 
			
		||||
 | 
			
		||||
    if (!parent_initable_iface->init (initable, cancellable, error))
 | 
			
		||||
        return FALSE;
 | 
			
		||||
 | 
			
		||||
    priv->config = xkl_config_rec_new ();
 | 
			
		||||
 | 
			
		||||
    g_object_get (G_OBJECT (initable),
 | 
			
		||||
                  "display", &display,
 | 
			
		||||
                  NULL);
 | 
			
		||||
 | 
			
		||||
    priv->engine = xkl_engine_get_instance (display);
 | 
			
		||||
 | 
			
		||||
    if (!xkl_config_rec_get_from_server (priv->config,
 | 
			
		||||
                                         priv->engine)) {
 | 
			
		||||
        g_set_error (error,
 | 
			
		||||
                     EEK_ERROR,
 | 
			
		||||
                     EEK_ERROR_LAYOUT_ERROR,
 | 
			
		||||
                     "can't load libxklavier configuration");
 | 
			
		||||
        return FALSE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    set_xkb_component_names (layout, priv->config);
 | 
			
		||||
    return TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
initable_iface_init (GInitableIface *initable_iface)
 | 
			
		||||
{
 | 
			
		||||
    parent_initable_iface = g_type_interface_peek_parent (initable_iface);
 | 
			
		||||
    initable_iface->init = initable_init;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										81
									
								
								eek/eek-xkl-layout.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										81
									
								
								eek/eek-xkl-layout.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,81 @@
 | 
			
		||||
/* 
 | 
			
		||||
 * Copyright (C) 2010-2011 Daiki Ueno <ueno@unixuser.org>
 | 
			
		||||
 * Copyright (C) 2010-2011 Red Hat, Inc.
 | 
			
		||||
 * 
 | 
			
		||||
 * This library is free software; you can redistribute it and/or
 | 
			
		||||
 * modify it under the terms of the GNU Lesser General Public License
 | 
			
		||||
 * as published by the Free Software Foundation; either version 2 of
 | 
			
		||||
 * the License, or (at your option) any later version.
 | 
			
		||||
 * 
 | 
			
		||||
 * This library is distributed in the hope that it will be useful, but
 | 
			
		||||
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
			
		||||
 * Lesser General Public License for more details.
 | 
			
		||||
 * 
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General Public
 | 
			
		||||
 * License along with this library; if not, write to the Free Software
 | 
			
		||||
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 | 
			
		||||
 * 02110-1301 USA
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#if !defined(__EEK_H_INSIDE__) && !defined(EEK_COMPILATION)
 | 
			
		||||
#error "Only <eek/eek-xkl.h> can be included directly."
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef EEK_XKL_LAYOUT_H
 | 
			
		||||
#define EEK_XKL_LAYOUT_H 1
 | 
			
		||||
 | 
			
		||||
#include <libxklavier/xklavier.h>
 | 
			
		||||
#include "eek-xkb-layout.h"
 | 
			
		||||
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
#define EEK_TYPE_XKL_LAYOUT (eek_xkl_layout_get_type())
 | 
			
		||||
G_DECLARE_DERIVABLE_TYPE (EekXklLayout, eek_xkl_layout, EEK, XKL_LAYOUT, EekLayout)
 | 
			
		||||
 | 
			
		||||
struct _EekXklLayoutClass
 | 
			
		||||
{
 | 
			
		||||
    /*< private >*/
 | 
			
		||||
    EekXkbLayoutClass parent_class;
 | 
			
		||||
 | 
			
		||||
    /*< private >*/
 | 
			
		||||
    /* padding */
 | 
			
		||||
    gpointer pdummy[24];
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
GType      eek_xkl_layout_get_type        (void) G_GNUC_CONST;
 | 
			
		||||
 | 
			
		||||
EekLayout *eek_xkl_layout_new             (Display      *display,
 | 
			
		||||
                                           GError      **error);
 | 
			
		||||
 | 
			
		||||
gboolean   eek_xkl_layout_set_config      (EekXklLayout *layout,
 | 
			
		||||
                                           XklConfigRec *config);
 | 
			
		||||
 | 
			
		||||
gboolean   eek_xkl_layout_set_config_full (EekXklLayout *layout,
 | 
			
		||||
                                           gchar        *model,
 | 
			
		||||
                                           gchar       **layouts,
 | 
			
		||||
                                           gchar       **variants,
 | 
			
		||||
                                           gchar       **options);
 | 
			
		||||
 | 
			
		||||
gboolean   eek_xkl_layout_set_model       (EekXklLayout *layout,
 | 
			
		||||
                                           const gchar  *model);
 | 
			
		||||
gboolean   eek_xkl_layout_set_layouts     (EekXklLayout *layout,
 | 
			
		||||
                                           gchar       **layouts);
 | 
			
		||||
gboolean   eek_xkl_layout_set_variants    (EekXklLayout *layout,
 | 
			
		||||
                                           gchar       **variants);
 | 
			
		||||
gboolean   eek_xkl_layout_set_options     (EekXklLayout *layout,
 | 
			
		||||
                                           gchar       **options);
 | 
			
		||||
gboolean   eek_xkl_layout_enable_option   (EekXklLayout *layout,
 | 
			
		||||
                                           const gchar  *option);
 | 
			
		||||
gboolean   eek_xkl_layout_disable_option  (EekXklLayout *layout,
 | 
			
		||||
                                           const gchar  *option);
 | 
			
		||||
 | 
			
		||||
gchar     *eek_xkl_layout_get_model       (EekXklLayout *layout);
 | 
			
		||||
gchar    **eek_xkl_layout_get_layouts     (EekXklLayout *layout);
 | 
			
		||||
gchar    **eek_xkl_layout_get_variants    (EekXklLayout *layout);
 | 
			
		||||
gchar    **eek_xkl_layout_get_options     (EekXklLayout *layout);
 | 
			
		||||
gboolean   eek_xkl_layout_get_option      (EekXklLayout *layout,
 | 
			
		||||
                                           const gchar  *option);
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
#endif				/* #ifndef EEK_XKL_LAYOUT_H */
 | 
			
		||||
							
								
								
									
										26
									
								
								eek/eek-xkl.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								eek/eek-xkl.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,26 @@
 | 
			
		||||
/* 
 | 
			
		||||
 * Copyright (C) 2010-2011 Daiki Ueno <ueno@unixuser.org>
 | 
			
		||||
 * Copyright (C) 2010-2011 Red Hat, Inc.
 | 
			
		||||
 * 
 | 
			
		||||
 * This library is free software; you can redistribute it and/or
 | 
			
		||||
 * modify it under the terms of the GNU Lesser General Public License
 | 
			
		||||
 * as published by the Free Software Foundation; either version 2 of
 | 
			
		||||
 * the License, or (at your option) any later version.
 | 
			
		||||
 * 
 | 
			
		||||
 * This library is distributed in the hope that it will be useful, but
 | 
			
		||||
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
			
		||||
 * Lesser General Public License for more details.
 | 
			
		||||
 * 
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General Public
 | 
			
		||||
 * License along with this library; if not, write to the Free Software
 | 
			
		||||
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 | 
			
		||||
 * 02110-1301 USA
 | 
			
		||||
 */
 | 
			
		||||
#ifndef EEK_XKL_H
 | 
			
		||||
#define EEK_XKL_H 1
 | 
			
		||||
 | 
			
		||||
#include "eek.h"
 | 
			
		||||
#include "eek-xkl-layout.h"
 | 
			
		||||
 | 
			
		||||
#endif  /* EEK_XKL_H */
 | 
			
		||||
							
								
								
									
										1533
									
								
								eek/eek-xml-layout.c
									
									
									
									
									
								
							
							
						
						
									
										1533
									
								
								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 */
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										317
									
								
								eek/eek-xml.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										317
									
								
								eek/eek-xml.c
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,317 @@
 | 
			
		||||
/* 
 | 
			
		||||
 * Copyright (C) 2011 Daiki Ueno <ueno@unixuser.org>
 | 
			
		||||
 * Copyright (C) 2011 Red Hat, Inc.
 | 
			
		||||
 * 
 | 
			
		||||
 * This program is free software: you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU General Public License as published by
 | 
			
		||||
 * the Free Software Foundation, either version 3 of the License, or
 | 
			
		||||
 * (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
 * GNU General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU General Public License
 | 
			
		||||
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * SECTION: eek-xml
 | 
			
		||||
 * @title: XML Conversion Utilities
 | 
			
		||||
 * @short_description: #EekKeyboard to XML conversion utilities
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_CONFIG_H
 | 
			
		||||
#include "config.h"
 | 
			
		||||
#endif  /* HAVE_CONFIG_H */
 | 
			
		||||
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <stdarg.h>
 | 
			
		||||
#include <glib/gprintf.h>
 | 
			
		||||
 | 
			
		||||
#include "eek-section.h"
 | 
			
		||||
#include "eek-key.h"
 | 
			
		||||
#include "eek-xml.h"
 | 
			
		||||
#include "eek-keysym.h"
 | 
			
		||||
#include "eek-text.h"
 | 
			
		||||
 | 
			
		||||
#define g_string_append_indent(string, indent)  \
 | 
			
		||||
    {                                           \
 | 
			
		||||
        gint i;                                 \
 | 
			
		||||
        for (i = 0; i < (indent); i++) {        \
 | 
			
		||||
            g_string_append (string, "    ");   \
 | 
			
		||||
        }                                       \
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
g_string_markup_printf (GString *output, const gchar *format, ...)
 | 
			
		||||
{
 | 
			
		||||
    gchar *escaped_text;
 | 
			
		||||
    va_list ap;
 | 
			
		||||
 | 
			
		||||
    va_start (ap, format);
 | 
			
		||||
    escaped_text = g_markup_vprintf_escaped (format, ap);
 | 
			
		||||
    va_end (ap);
 | 
			
		||||
 | 
			
		||||
    g_string_append (output, escaped_text);
 | 
			
		||||
    g_free (escaped_text);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
struct _OutputCallbackData {
 | 
			
		||||
    GString *output;
 | 
			
		||||
    gint indent;
 | 
			
		||||
    GHashTable *oref_hash;
 | 
			
		||||
    gint key_serial;
 | 
			
		||||
};
 | 
			
		||||
typedef struct _OutputCallbackData OutputCallbackData;
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
output_bounds (GString *output, EekBounds *bounds)
 | 
			
		||||
{
 | 
			
		||||
    g_string_markup_printf (output,
 | 
			
		||||
                            "<bounds>%lf,%lf,%lf,%lf</bounds>\n",
 | 
			
		||||
                            bounds->x,
 | 
			
		||||
                            bounds->y,
 | 
			
		||||
                            bounds->width,
 | 
			
		||||
                            bounds->height);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
output_symbol_attributes (GString   *output,
 | 
			
		||||
                          EekSymbol *symbol)
 | 
			
		||||
{
 | 
			
		||||
    if (eek_symbol_get_name (symbol) != NULL)
 | 
			
		||||
        g_string_markup_printf (output, " name=\"%s\"",
 | 
			
		||||
                                eek_symbol_get_name (symbol));
 | 
			
		||||
    if (eek_symbol_get_label (symbol) != NULL)
 | 
			
		||||
        g_string_markup_printf (output, " label=\"%s\"",
 | 
			
		||||
                                eek_symbol_get_label (symbol));
 | 
			
		||||
    if (eek_symbol_get_category (symbol) != EEK_SYMBOL_CATEGORY_UNKNOWN)
 | 
			
		||||
        g_string_markup_printf (output, " category=\"%s\"",
 | 
			
		||||
                                eek_symbol_category_get_name (eek_symbol_get_category (symbol)));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
output_key_callback (EekElement *element, gpointer user_data)
 | 
			
		||||
{
 | 
			
		||||
    OutputCallbackData *data = user_data;
 | 
			
		||||
    EekBounds bounds;
 | 
			
		||||
    gint i, num_symbols;
 | 
			
		||||
    EekSymbolMatrix *matrix;
 | 
			
		||||
    gint column, row;
 | 
			
		||||
    guint keycode;
 | 
			
		||||
    gchar *id;
 | 
			
		||||
    gulong oref;
 | 
			
		||||
 | 
			
		||||
    keycode = eek_key_get_keycode (EEK_KEY(element));
 | 
			
		||||
    if (keycode == EEK_INVALID_KEYCODE)
 | 
			
		||||
        id = g_strdup_printf ("key%d", data->key_serial);
 | 
			
		||||
    else
 | 
			
		||||
        id = g_strdup_printf ("keycode%d", keycode);
 | 
			
		||||
    data->key_serial++;
 | 
			
		||||
 | 
			
		||||
    eek_key_get_index (EEK_KEY(element), &column, &row);
 | 
			
		||||
    g_string_append_indent (data->output, data->indent);
 | 
			
		||||
    if (eek_element_get_name (element))
 | 
			
		||||
        g_string_markup_printf (data->output,
 | 
			
		||||
                                "<key id=\"%s\" name=\"%s\" "
 | 
			
		||||
                                "column=\"%d\" row=\"%d\">\n",
 | 
			
		||||
                                id,
 | 
			
		||||
                                eek_element_get_name (element),
 | 
			
		||||
                                column,
 | 
			
		||||
                                row);
 | 
			
		||||
    else
 | 
			
		||||
        g_string_markup_printf (data->output,
 | 
			
		||||
                                "<key id=\"%s\" "
 | 
			
		||||
                                "column=\"%d\" row=\"%d\">\n",
 | 
			
		||||
                                id,
 | 
			
		||||
                                column,
 | 
			
		||||
                                row);
 | 
			
		||||
    g_free (id);
 | 
			
		||||
 | 
			
		||||
    eek_element_get_bounds (element, &bounds);
 | 
			
		||||
    g_string_append_indent (data->output, data->indent + 1);
 | 
			
		||||
    output_bounds (data->output, &bounds);
 | 
			
		||||
 | 
			
		||||
    oref = eek_key_get_oref (EEK_KEY(element));
 | 
			
		||||
    if (oref != 0) {
 | 
			
		||||
        g_string_append_indent (data->output, data->indent + 1);
 | 
			
		||||
        g_string_markup_printf (data->output,
 | 
			
		||||
                                "<oref>outline%u</oref>\n",
 | 
			
		||||
                                oref);
 | 
			
		||||
        if (!g_hash_table_lookup (data->oref_hash, (gpointer)oref))
 | 
			
		||||
            g_hash_table_insert (data->oref_hash,
 | 
			
		||||
                                 (gpointer)oref,
 | 
			
		||||
                                 (gpointer)TRUE);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    matrix = eek_key_get_symbol_matrix (EEK_KEY(element));
 | 
			
		||||
    num_symbols = matrix->num_groups * matrix->num_levels;
 | 
			
		||||
    if (num_symbols > 0) {
 | 
			
		||||
        g_string_append_indent (data->output, data->indent + 1);
 | 
			
		||||
        g_string_markup_printf (data->output,
 | 
			
		||||
                                "<symbols groups=\"%d\" levels=\"%d\">\n",
 | 
			
		||||
                                matrix->num_groups, matrix->num_levels);
 | 
			
		||||
 | 
			
		||||
        for (i = 0; i < num_symbols; i++) {
 | 
			
		||||
            EekSymbol *symbol = matrix->data[i];
 | 
			
		||||
 | 
			
		||||
            g_string_append_indent (data->output, data->indent + 2);
 | 
			
		||||
            if (EEK_IS_KEYSYM(symbol)) {
 | 
			
		||||
                guint xkeysym = eek_keysym_get_xkeysym (EEK_KEYSYM(symbol));
 | 
			
		||||
 | 
			
		||||
                g_string_markup_printf (data->output, "<keysym");
 | 
			
		||||
                output_symbol_attributes (data->output, symbol);
 | 
			
		||||
                if (xkeysym != EEK_INVALID_KEYSYM)
 | 
			
		||||
                    g_string_markup_printf (data->output, " keyval=\"%u\"",
 | 
			
		||||
                                            xkeysym);
 | 
			
		||||
                g_string_markup_printf (data->output, ">%s</keysym>\n",
 | 
			
		||||
                                        eek_symbol_get_name (symbol));
 | 
			
		||||
            }
 | 
			
		||||
            else if (EEK_IS_TEXT(symbol)) {
 | 
			
		||||
                g_string_markup_printf (data->output, "<text");
 | 
			
		||||
                output_symbol_attributes (data->output, symbol);
 | 
			
		||||
                g_string_markup_printf (data->output,
 | 
			
		||||
                                        ">%s</text>\n",
 | 
			
		||||
                                        eek_text_get_text (EEK_TEXT(symbol)));
 | 
			
		||||
            }
 | 
			
		||||
            else {
 | 
			
		||||
                g_string_markup_printf (data->output, "<symbol");
 | 
			
		||||
                output_symbol_attributes (data->output, symbol);
 | 
			
		||||
                g_string_markup_printf (data->output,
 | 
			
		||||
                                        ">%s</symbol>\n",
 | 
			
		||||
                                        eek_symbol_get_name (symbol));
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        g_string_append_indent (data->output, data->indent + 1);
 | 
			
		||||
        g_string_markup_printf (data->output, "</symbols>\n");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    g_string_append_indent (data->output, data->indent);
 | 
			
		||||
    g_string_markup_printf (data->output, "</key>\n");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
output_section_callback (EekElement *element, gpointer user_data)
 | 
			
		||||
{
 | 
			
		||||
    OutputCallbackData *data = user_data;
 | 
			
		||||
    EekBounds bounds;
 | 
			
		||||
    gint angle, n_rows, i;
 | 
			
		||||
 | 
			
		||||
    g_string_append_indent (data->output, data->indent);
 | 
			
		||||
    if (eek_element_get_name (element))
 | 
			
		||||
        g_string_markup_printf (data->output, "<section name=\"%s\">\n",
 | 
			
		||||
                                eek_element_get_name (element));
 | 
			
		||||
    else
 | 
			
		||||
        g_string_markup_printf (data->output, "<section>\n");
 | 
			
		||||
 | 
			
		||||
    eek_element_get_bounds (element, &bounds);
 | 
			
		||||
    g_string_append_indent (data->output, data->indent + 1);
 | 
			
		||||
    output_bounds (data->output, &bounds);
 | 
			
		||||
 | 
			
		||||
    angle = eek_section_get_angle (EEK_SECTION(element));
 | 
			
		||||
    g_string_append_indent (data->output, data->indent + 1);
 | 
			
		||||
    g_string_markup_printf (data->output, "<angle>%d</angle>\n", angle);
 | 
			
		||||
 | 
			
		||||
    n_rows = eek_section_get_n_rows (EEK_SECTION(element));
 | 
			
		||||
    for (i = 0; i < n_rows; i++) {
 | 
			
		||||
        gint num_columns;
 | 
			
		||||
        EekOrientation orientation;
 | 
			
		||||
 | 
			
		||||
        eek_section_get_row (EEK_SECTION(element),
 | 
			
		||||
                             i,
 | 
			
		||||
                             &num_columns,
 | 
			
		||||
                             &orientation);
 | 
			
		||||
        g_string_append_indent (data->output, data->indent + 1);
 | 
			
		||||
        g_string_markup_printf (data->output, "<row>\n");
 | 
			
		||||
        g_string_append_indent (data->output, data->indent + 2);
 | 
			
		||||
        g_string_markup_printf (data->output, "<columns>%d</columns>\n",
 | 
			
		||||
                                num_columns);
 | 
			
		||||
        g_string_append_indent (data->output, data->indent + 2);
 | 
			
		||||
        g_string_markup_printf (data->output, "<orientation>%d</orientation>\n",
 | 
			
		||||
                                orientation);
 | 
			
		||||
        g_string_append_indent (data->output, data->indent + 1);
 | 
			
		||||
        g_string_markup_printf (data->output, "</row>\n");
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    data->indent++;
 | 
			
		||||
    eek_container_foreach_child (EEK_CONTAINER(element),
 | 
			
		||||
                                 output_key_callback,
 | 
			
		||||
                                 data);
 | 
			
		||||
    data->indent--;
 | 
			
		||||
 | 
			
		||||
    g_string_append_indent (data->output, data->indent);
 | 
			
		||||
    g_string_markup_printf (data->output, "</section>\n");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eek_keyboard_output:
 | 
			
		||||
 * @keyboard: an #EekKeyboard
 | 
			
		||||
 * @output: a GString
 | 
			
		||||
 * @indent: an integer
 | 
			
		||||
 *
 | 
			
		||||
 * Convert @keyboard into the XML format and store it into @output.
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
eek_keyboard_output (EekKeyboard *keyboard, GString *output, gint indent)
 | 
			
		||||
{
 | 
			
		||||
    OutputCallbackData data;
 | 
			
		||||
    EekBounds bounds;
 | 
			
		||||
    gulong oref;
 | 
			
		||||
    GHashTableIter iter;
 | 
			
		||||
 | 
			
		||||
    g_assert (EEK_IS_KEYBOARD(keyboard));
 | 
			
		||||
 
 | 
			
		||||
    g_string_append_indent (output, indent);
 | 
			
		||||
    if (eek_element_get_name (EEK_ELEMENT(keyboard)))
 | 
			
		||||
        g_string_markup_printf (output, "<?xml version=\"1.0\"?>\n"
 | 
			
		||||
                                "<keyboard version=\"%s\" id=\"%s\">\n",
 | 
			
		||||
                                EEK_XML_SCHEMA_VERSION,
 | 
			
		||||
                                eek_element_get_name (EEK_ELEMENT(keyboard)));
 | 
			
		||||
    else
 | 
			
		||||
        g_string_markup_printf (output, "<?xml version=\"1.0\"?>\n"
 | 
			
		||||
                                "<keyboard version=\"%s\">\n",
 | 
			
		||||
                                EEK_XML_SCHEMA_VERSION);
 | 
			
		||||
 | 
			
		||||
    eek_element_get_bounds (EEK_ELEMENT(keyboard), &bounds);
 | 
			
		||||
    g_string_append_indent (output, indent + 1);
 | 
			
		||||
    output_bounds (output, &bounds);
 | 
			
		||||
 | 
			
		||||
    data.output = output;
 | 
			
		||||
    data.indent = indent;
 | 
			
		||||
    data.oref_hash = g_hash_table_new (g_direct_hash, g_direct_equal);
 | 
			
		||||
    data.key_serial = 0;
 | 
			
		||||
 | 
			
		||||
    data.indent++;
 | 
			
		||||
    eek_container_foreach_child (EEK_CONTAINER(keyboard),
 | 
			
		||||
                                 output_section_callback,
 | 
			
		||||
                                 &data);
 | 
			
		||||
    data.indent--;
 | 
			
		||||
 | 
			
		||||
    g_hash_table_iter_init (&iter, data.oref_hash);
 | 
			
		||||
    while (g_hash_table_iter_next (&iter, (gpointer *)&oref, NULL)) {
 | 
			
		||||
        EekOutline *outline;
 | 
			
		||||
        gint j;
 | 
			
		||||
 | 
			
		||||
        outline = eek_keyboard_get_outline (keyboard, oref);
 | 
			
		||||
        g_string_append_indent (output, indent + 1);
 | 
			
		||||
        g_string_markup_printf (output, "<outline id=\"outline%u\">\n", oref);
 | 
			
		||||
        g_string_append_indent (output, indent + 2);
 | 
			
		||||
        g_string_markup_printf (output, "<corner-radius>%lf</corner-radius>\n",
 | 
			
		||||
                                outline->corner_radius);
 | 
			
		||||
        for (j = 0; j < outline->num_points; j++) {
 | 
			
		||||
            g_string_append_indent (output, indent + 2);
 | 
			
		||||
            g_string_markup_printf (output, "<point>%lf,%lf</point>\n",
 | 
			
		||||
                                    outline->points[j].x,
 | 
			
		||||
                                    outline->points[j].y);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        g_string_append_indent (output, indent + 1);
 | 
			
		||||
        g_string_markup_printf (output, "</outline>\n");
 | 
			
		||||
    }
 | 
			
		||||
    g_hash_table_destroy (data.oref_hash);
 | 
			
		||||
 | 
			
		||||
    g_string_append_indent (output, indent);
 | 
			
		||||
    g_string_markup_printf (output, "</keyboard>\n");
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										39
									
								
								eek/eek-xml.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								eek/eek-xml.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,39 @@
 | 
			
		||||
/* 
 | 
			
		||||
 * Copyright (C) 2011 Daiki Ueno <ueno@unixuser.org>
 | 
			
		||||
 * Copyright (C) 2011 Red Hat, Inc.
 | 
			
		||||
 * 
 | 
			
		||||
 * This program is free software: you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU General Public License as published by
 | 
			
		||||
 * the Free Software Foundation, either version 3 of the License, or
 | 
			
		||||
 * (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
 * GNU General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU General Public License
 | 
			
		||||
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#if !defined(__EEK_H_INSIDE__) && !defined(EEK_COMPILATION)
 | 
			
		||||
#error "Only <eek/eek.h> can be included directly."
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef EEK_XML_H
 | 
			
		||||
#define EEK_XML_H 1
 | 
			
		||||
 | 
			
		||||
#include <glib-object.h>
 | 
			
		||||
#include "eek-keyboard.h"
 | 
			
		||||
#include "eek-xml-layout.h"
 | 
			
		||||
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
#define EEK_XML_SCHEMA_VERSION "0.90"
 | 
			
		||||
 | 
			
		||||
void eek_keyboard_output (EekKeyboard *keyboard,
 | 
			
		||||
                          GString     *output,
 | 
			
		||||
                          gint         indent);
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
#endif  /* EEK_XML_H */
 | 
			
		||||
@ -23,7 +23,9 @@
 | 
			
		||||
 * @title: Library Initialization
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_CONFIG_H
 | 
			
		||||
#include "config.h"
 | 
			
		||||
#endif  /* HAVE_CONFIG_H */
 | 
			
		||||
 | 
			
		||||
#include "eek.h"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -23,7 +23,15 @@
 | 
			
		||||
#define __EEK_H_INSIDE__ 1
 | 
			
		||||
 | 
			
		||||
#include "eek-keyboard.h"
 | 
			
		||||
#include "eek-section.h"
 | 
			
		||||
#include "eek-key.h"
 | 
			
		||||
#include "eek-layout.h"
 | 
			
		||||
#include "eek-symbol.h"
 | 
			
		||||
#include "eek-keysym.h"
 | 
			
		||||
#include "eek-text.h"
 | 
			
		||||
#include "eek-xml.h"
 | 
			
		||||
#include "eek-serializable.h"
 | 
			
		||||
#include "eek-theme.h"
 | 
			
		||||
 | 
			
		||||
void eek_init (void);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										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+(\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, %s }" %
 | 
			
		||||
                     (keysym, l, c))
 | 
			
		||||
    if index < len(table) - 1:
 | 
			
		||||
        sys.stdout.write(",")
 | 
			
		||||
    sys.stdout.write("\n")
 | 
			
		||||
sys.stdout.write("};\n")
 | 
			
		||||
@ -65,9 +65,9 @@ static void layer_surface_configure(void                         *data,
 | 
			
		||||
                                    uint32_t                      height)
 | 
			
		||||
{
 | 
			
		||||
  PhoshLayerSurface *self = data;
 | 
			
		||||
 | 
			
		||||
  gtk_window_resize (GTK_WINDOW (self), width, height);
 | 
			
		||||
  zwlr_layer_surface_v1_ack_configure(surface, serial);
 | 
			
		||||
  gtk_widget_show_all (GTK_WIDGET (self));
 | 
			
		||||
 | 
			
		||||
  g_signal_emit (self, signals[CONFIGURED], 0);
 | 
			
		||||
}
 | 
			
		||||
@ -180,39 +180,22 @@ phosh_layer_surface_get_property (GObject    *object,
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
on_phosh_layer_surface_realized (PhoshLayerSurface *self, gpointer unused)
 | 
			
		||||
phosh_layer_surface_constructed (GObject *object)
 | 
			
		||||
{
 | 
			
		||||
  PhoshLayerSurfacePrivate *priv;
 | 
			
		||||
  PhoshLayerSurface *self = PHOSH_LAYER_SURFACE (object);
 | 
			
		||||
  PhoshLayerSurfacePrivate *priv = phosh_layer_surface_get_instance_private (self);
 | 
			
		||||
  GdkWindow *gdk_window;
 | 
			
		||||
 | 
			
		||||
  g_return_if_fail (PHOSH_IS_LAYER_SURFACE (self));
 | 
			
		||||
  G_OBJECT_CLASS (phosh_layer_surface_parent_class)->constructed (object);
 | 
			
		||||
 | 
			
		||||
  priv = phosh_layer_surface_get_instance_private (self);
 | 
			
		||||
  gtk_window_set_decorated (GTK_WINDOW (self), FALSE);
 | 
			
		||||
  /* Realize the window so we can get the GDK window */
 | 
			
		||||
  gtk_widget_realize(GTK_WIDGET (self));
 | 
			
		||||
 | 
			
		||||
  gdk_window = gtk_widget_get_window (GTK_WIDGET (self));
 | 
			
		||||
  gdk_wayland_window_set_use_custom_surface (gdk_window);
 | 
			
		||||
  priv->wl_surface = gdk_wayland_window_get_wl_surface (gdk_window);
 | 
			
		||||
 | 
			
		||||
  gtk_window_set_decorated (GTK_WINDOW (self), FALSE);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
on_phosh_layer_surface_mapped (PhoshLayerSurface *self, gpointer unused)
 | 
			
		||||
{
 | 
			
		||||
  PhoshLayerSurfacePrivate *priv;
 | 
			
		||||
  GdkWindow *gdk_window;
 | 
			
		||||
 | 
			
		||||
  g_return_if_fail (PHOSH_IS_LAYER_SURFACE (self));
 | 
			
		||||
  priv = phosh_layer_surface_get_instance_private (self);
 | 
			
		||||
 | 
			
		||||
  if (!priv->wl_surface) {
 | 
			
		||||
      gdk_window = gtk_widget_get_window (GTK_WIDGET (self));
 | 
			
		||||
      gdk_wayland_window_set_use_custom_surface (gdk_window);
 | 
			
		||||
      priv->wl_surface = gdk_wayland_window_get_wl_surface (gdk_window);
 | 
			
		||||
  }
 | 
			
		||||
  g_debug ("Mapped %p", priv->wl_surface);
 | 
			
		||||
 | 
			
		||||
  priv->layer_surface = zwlr_layer_shell_v1_get_layer_surface(priv->layer_shell,
 | 
			
		||||
                                                              priv->wl_surface,
 | 
			
		||||
                                                              priv->wl_output,
 | 
			
		||||
@ -226,45 +209,8 @@ on_phosh_layer_surface_mapped (PhoshLayerSurface *self, gpointer unused)
 | 
			
		||||
                                     &layer_surface_listener,
 | 
			
		||||
                                     self);
 | 
			
		||||
  wl_surface_commit(priv->wl_surface);
 | 
			
		||||
 | 
			
		||||
  /* Process all pending events, otherwise we end up sending ack configure
 | 
			
		||||
   * to a not yet configured surface */
 | 
			
		||||
  wl_display_roundtrip (gdk_wayland_display_get_wl_display (gdk_display_get_default ()));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
on_phosh_layer_surface_unmapped (PhoshLayerSurface *self, gpointer unused)
 | 
			
		||||
{
 | 
			
		||||
  PhoshLayerSurfacePrivate *priv;
 | 
			
		||||
 | 
			
		||||
  g_return_if_fail (PHOSH_IS_LAYER_SURFACE (self));
 | 
			
		||||
  priv = phosh_layer_surface_get_instance_private (self);
 | 
			
		||||
 | 
			
		||||
  priv = phosh_layer_surface_get_instance_private (self);
 | 
			
		||||
  if (priv->layer_surface) {
 | 
			
		||||
    zwlr_layer_surface_v1_destroy(priv->layer_surface);
 | 
			
		||||
    priv->layer_surface = NULL;
 | 
			
		||||
  }
 | 
			
		||||
  priv->wl_surface = NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
phosh_layer_surface_constructed (GObject *object)
 | 
			
		||||
{
 | 
			
		||||
  PhoshLayerSurface *self = PHOSH_LAYER_SURFACE (object);
 | 
			
		||||
 | 
			
		||||
  g_signal_connect (self, "realize",
 | 
			
		||||
                    G_CALLBACK (on_phosh_layer_surface_realized),
 | 
			
		||||
                    NULL);
 | 
			
		||||
  g_signal_connect (self, "map",
 | 
			
		||||
                    G_CALLBACK (on_phosh_layer_surface_mapped),
 | 
			
		||||
                    NULL);
 | 
			
		||||
  g_signal_connect (self, "unmap",
 | 
			
		||||
                    G_CALLBACK (on_phosh_layer_surface_unmapped),
 | 
			
		||||
                    NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
phosh_layer_surface_dispose (GObject *object)
 | 
			
		||||
{
 | 
			
		||||
@ -406,12 +352,6 @@ phosh_layer_surface_new (gpointer layer_shell,
 | 
			
		||||
                       "wl-output", wl_output);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * phosh_layer_surface_get_surface:
 | 
			
		||||
 *
 | 
			
		||||
 * Get the layer layer surface or #NULL if the window
 | 
			
		||||
 * is not yet realized.
 | 
			
		||||
 */
 | 
			
		||||
struct zwlr_layer_surface_v1 *
 | 
			
		||||
phosh_layer_surface_get_layer_surface(PhoshLayerSurface *self)
 | 
			
		||||
{
 | 
			
		||||
@ -423,12 +363,6 @@ phosh_layer_surface_get_layer_surface(PhoshLayerSurface *self)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * phosh_layer_surface_get_wl_surface:
 | 
			
		||||
 *
 | 
			
		||||
 * Get the layer wayland surface or #NULL if the window
 | 
			
		||||
 * is not yet realized.
 | 
			
		||||
 */
 | 
			
		||||
struct wl_surface *
 | 
			
		||||
phosh_layer_surface_get_wl_surface(PhoshLayerSurface *self)
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
@ -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
											
										
									
								
							
							
								
								
									
										404
									
								
								eekboard/eekboard-client.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										404
									
								
								eekboard/eekboard-client.c
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,404 @@
 | 
			
		||||
/* 
 | 
			
		||||
 * Copyright (C) 2011 Daiki Ueno <ueno@unixuser.org>
 | 
			
		||||
 * Copyright (C) 2011 Red Hat, Inc.
 | 
			
		||||
 * 
 | 
			
		||||
 * This program is free software: you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU General Public License as published by
 | 
			
		||||
 * the Free Software Foundation, either version 3 of the License, or
 | 
			
		||||
 * (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
 * GNU General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU General Public License
 | 
			
		||||
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * SECTION:eekboard-client
 | 
			
		||||
 * @short_description: client interface of eekboard service
 | 
			
		||||
 *
 | 
			
		||||
 * The #EekboardClient class provides a client side access to eekboard-server.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_CONFIG_H
 | 
			
		||||
#include "config.h"
 | 
			
		||||
#endif  /* HAVE_CONFIG_H */
 | 
			
		||||
 | 
			
		||||
#include "eekboard/eekboard-client.h"
 | 
			
		||||
 | 
			
		||||
enum {
 | 
			
		||||
    DESTROYED,
 | 
			
		||||
    LAST_SIGNAL
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static guint signals[LAST_SIGNAL] = { 0, };
 | 
			
		||||
 | 
			
		||||
typedef struct _EekboardClientPrivate
 | 
			
		||||
{
 | 
			
		||||
    GHashTable *context_hash;
 | 
			
		||||
} EekboardClientPrivate;
 | 
			
		||||
 | 
			
		||||
G_DEFINE_TYPE_WITH_PRIVATE (EekboardClient, eekboard_client, G_TYPE_DBUS_PROXY)
 | 
			
		||||
 | 
			
		||||
static void send_destroy_context (EekboardClient  *client,
 | 
			
		||||
                                  EekboardContext *context,
 | 
			
		||||
                                  GCancellable    *cancellable);
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
eekboard_client_real_destroyed (EekboardClient *self)
 | 
			
		||||
{
 | 
			
		||||
    EekboardClientPrivate *priv = eekboard_client_get_instance_private (self);
 | 
			
		||||
 | 
			
		||||
    // g_debug ("eekboard_client_real_destroyed");
 | 
			
		||||
    g_hash_table_remove_all (priv->context_hash);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
eekboard_client_dispose (GObject *object)
 | 
			
		||||
{
 | 
			
		||||
    EekboardClient *client = EEKBOARD_CLIENT(object);
 | 
			
		||||
    EekboardClientPrivate *priv = eekboard_client_get_instance_private (client);
 | 
			
		||||
 | 
			
		||||
    if (priv->context_hash) {
 | 
			
		||||
        GHashTableIter iter;
 | 
			
		||||
        gpointer key, value;
 | 
			
		||||
 | 
			
		||||
        g_hash_table_iter_init (&iter, priv->context_hash);
 | 
			
		||||
        while (g_hash_table_iter_next (&iter, &key, &value)) {
 | 
			
		||||
            send_destroy_context (client, (EekboardContext *)value, NULL);
 | 
			
		||||
            g_hash_table_iter_remove (&iter);
 | 
			
		||||
        }
 | 
			
		||||
        g_hash_table_destroy (priv->context_hash);
 | 
			
		||||
        priv->context_hash = NULL;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    G_OBJECT_CLASS (eekboard_client_parent_class)->dispose (object);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
eekboard_client_class_init (EekboardClientClass *klass)
 | 
			
		||||
{
 | 
			
		||||
    GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
 | 
			
		||||
 | 
			
		||||
    klass->destroyed = eekboard_client_real_destroyed;
 | 
			
		||||
 | 
			
		||||
    gobject_class->dispose = eekboard_client_dispose;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * EekboardClient::destroyed:
 | 
			
		||||
     * @eekboard: an #EekboardClient
 | 
			
		||||
     *
 | 
			
		||||
     * The ::destroyed signal is emitted each time the name of remote
 | 
			
		||||
     * end is vanished.
 | 
			
		||||
     */
 | 
			
		||||
    signals[DESTROYED] =
 | 
			
		||||
        g_signal_new (I_("destroyed"),
 | 
			
		||||
                      G_TYPE_FROM_CLASS(gobject_class),
 | 
			
		||||
                      G_SIGNAL_RUN_LAST,
 | 
			
		||||
                      G_STRUCT_OFFSET(EekboardClientClass, destroyed),
 | 
			
		||||
                      NULL,
 | 
			
		||||
                      NULL,
 | 
			
		||||
                      g_cclosure_marshal_VOID__VOID,
 | 
			
		||||
                      G_TYPE_NONE,
 | 
			
		||||
                      0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
eekboard_client_init (EekboardClient *self)
 | 
			
		||||
{
 | 
			
		||||
    EekboardClientPrivate *priv = eekboard_client_get_instance_private (self);
 | 
			
		||||
 | 
			
		||||
    priv->context_hash =
 | 
			
		||||
        g_hash_table_new_full (g_str_hash,
 | 
			
		||||
                               g_str_equal,
 | 
			
		||||
                               (GDestroyNotify)g_free,
 | 
			
		||||
                               (GDestroyNotify)g_object_unref);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
eekboard_name_vanished_callback (GDBusConnection *connection,
 | 
			
		||||
                                 const gchar     *name,
 | 
			
		||||
                                 gpointer         user_data)
 | 
			
		||||
{
 | 
			
		||||
    EekboardClient *client = user_data;
 | 
			
		||||
    g_signal_emit_by_name (client, "destroyed", NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eekboard_client_new:
 | 
			
		||||
 * @connection: a #GDBusConnection
 | 
			
		||||
 * @cancellable: a #GCancellable
 | 
			
		||||
 *
 | 
			
		||||
 * Create a client.
 | 
			
		||||
 */
 | 
			
		||||
EekboardClient *
 | 
			
		||||
eekboard_client_new (GDBusConnection *connection,
 | 
			
		||||
                     GCancellable    *cancellable)
 | 
			
		||||
{
 | 
			
		||||
    GInitable *initable;
 | 
			
		||||
    GError *error;
 | 
			
		||||
 | 
			
		||||
    g_assert (G_IS_DBUS_CONNECTION(connection));
 | 
			
		||||
 | 
			
		||||
    error = NULL;
 | 
			
		||||
    initable =
 | 
			
		||||
        g_initable_new (EEKBOARD_TYPE_CLIENT,
 | 
			
		||||
                        cancellable,
 | 
			
		||||
                        &error,
 | 
			
		||||
                        "g-connection", connection,
 | 
			
		||||
                        "g-name", "org.fedorahosted.Eekboard",
 | 
			
		||||
                        "g-interface-name", "org.fedorahosted.Eekboard",
 | 
			
		||||
                        "g-object-path", "/org/fedorahosted/Eekboard",
 | 
			
		||||
                        NULL);
 | 
			
		||||
    if (initable != NULL) {
 | 
			
		||||
        EekboardClient *client = EEKBOARD_CLIENT (initable);
 | 
			
		||||
        gchar *name_owner = g_dbus_proxy_get_name_owner (G_DBUS_PROXY(client));
 | 
			
		||||
        if (name_owner == NULL) {
 | 
			
		||||
            g_object_unref (client);
 | 
			
		||||
            return NULL;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /* the vanished callback is called when the server is disconnected */
 | 
			
		||||
        g_bus_watch_name_on_connection (connection,
 | 
			
		||||
                                        name_owner,
 | 
			
		||||
                                        G_BUS_NAME_WATCHER_FLAGS_NONE,
 | 
			
		||||
                                        NULL,
 | 
			
		||||
                                        eekboard_name_vanished_callback,
 | 
			
		||||
                                        client,
 | 
			
		||||
                                        NULL);
 | 
			
		||||
        g_free (name_owner);
 | 
			
		||||
 | 
			
		||||
        return client;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    g_warning ("can't create client: %s", error->message);
 | 
			
		||||
    g_error_free (error);
 | 
			
		||||
    return NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
on_context_destroyed (EekboardContext *context,
 | 
			
		||||
                      gpointer         user_data)
 | 
			
		||||
{
 | 
			
		||||
    EekboardClient *client = user_data;
 | 
			
		||||
    EekboardClientPrivate *priv = eekboard_client_get_instance_private (client);
 | 
			
		||||
 | 
			
		||||
    g_hash_table_remove (priv->context_hash,
 | 
			
		||||
                         g_dbus_proxy_get_object_path (G_DBUS_PROXY(context)));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eekboard_client_create_context:
 | 
			
		||||
 * @eekboard: an #EekboardClient
 | 
			
		||||
 * @client_name: name of the client
 | 
			
		||||
 * @cancellable: a #GCancellable
 | 
			
		||||
 *
 | 
			
		||||
 * Create a new input context.
 | 
			
		||||
 *
 | 
			
		||||
 * Return value: (transfer full): a newly created #EekboardContext.
 | 
			
		||||
 */
 | 
			
		||||
EekboardContext *
 | 
			
		||||
eekboard_client_create_context (EekboardClient *client,
 | 
			
		||||
                                const gchar    *client_name,
 | 
			
		||||
                                GCancellable   *cancellable)
 | 
			
		||||
{
 | 
			
		||||
    GVariant *variant;
 | 
			
		||||
    const gchar *object_path;
 | 
			
		||||
    EekboardContext *context;
 | 
			
		||||
    GError *error;
 | 
			
		||||
    GDBusConnection *connection;
 | 
			
		||||
 | 
			
		||||
    g_assert (EEKBOARD_IS_CLIENT(client));
 | 
			
		||||
    g_assert (client_name);
 | 
			
		||||
 | 
			
		||||
    error = NULL;
 | 
			
		||||
    variant = g_dbus_proxy_call_sync (G_DBUS_PROXY(client),
 | 
			
		||||
                                      "CreateContext",
 | 
			
		||||
                                      g_variant_new ("(s)", client_name),
 | 
			
		||||
                                      G_DBUS_CALL_FLAGS_NONE,
 | 
			
		||||
                                      -1,
 | 
			
		||||
                                      cancellable,
 | 
			
		||||
                                      &error);
 | 
			
		||||
    if (!variant) {
 | 
			
		||||
        g_warning ("failed to call CreateContext: %s", error->message);
 | 
			
		||||
        g_error_free (error);
 | 
			
		||||
        return NULL;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    g_variant_get (variant, "(&s)", &object_path);
 | 
			
		||||
    connection = g_dbus_proxy_get_connection (G_DBUS_PROXY(client));
 | 
			
		||||
    context = eekboard_context_new (connection, object_path, cancellable);
 | 
			
		||||
    if (!context) {
 | 
			
		||||
        g_variant_unref (variant);
 | 
			
		||||
        return NULL;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    EekboardClientPrivate *priv = eekboard_client_get_instance_private (client);
 | 
			
		||||
 | 
			
		||||
    g_hash_table_insert (priv->context_hash,
 | 
			
		||||
                         g_strdup (object_path),
 | 
			
		||||
                         g_object_ref (context));
 | 
			
		||||
    g_signal_connect (context, "destroyed",
 | 
			
		||||
                      G_CALLBACK(on_context_destroyed), client);
 | 
			
		||||
    return context;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
eekboard_async_ready_callback (GObject      *source_object,
 | 
			
		||||
                               GAsyncResult *res,
 | 
			
		||||
                               gpointer      user_data)
 | 
			
		||||
{
 | 
			
		||||
    GError *error = NULL;
 | 
			
		||||
    GVariant *result;
 | 
			
		||||
 | 
			
		||||
    result = g_dbus_proxy_call_finish (G_DBUS_PROXY(source_object),
 | 
			
		||||
                                       res,
 | 
			
		||||
                                       &error);
 | 
			
		||||
    if (result)
 | 
			
		||||
        g_variant_unref (result);
 | 
			
		||||
    else {
 | 
			
		||||
        g_warning ("error in D-Bus proxy call: %s", error->message);
 | 
			
		||||
        g_error_free (error);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eekboard_client_push_context:
 | 
			
		||||
 * @eekboard: an #EekboardClient
 | 
			
		||||
 * @context: an #EekboardContext
 | 
			
		||||
 * @cancellable: a #GCancellable
 | 
			
		||||
 *
 | 
			
		||||
 * Enable the input context @context and disable the others.
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
eekboard_client_push_context (EekboardClient  *client,
 | 
			
		||||
                              EekboardContext *context,
 | 
			
		||||
                              GCancellable    *cancellable)
 | 
			
		||||
{
 | 
			
		||||
    const gchar *object_path;
 | 
			
		||||
 | 
			
		||||
    g_return_if_fail (EEKBOARD_IS_CLIENT(client));
 | 
			
		||||
    g_return_if_fail (EEKBOARD_IS_CONTEXT(context));
 | 
			
		||||
 | 
			
		||||
    EekboardClientPrivate *priv = eekboard_client_get_instance_private (client);
 | 
			
		||||
 | 
			
		||||
    object_path = g_dbus_proxy_get_object_path (G_DBUS_PROXY(context));
 | 
			
		||||
 | 
			
		||||
    context = g_hash_table_lookup (priv->context_hash,
 | 
			
		||||
                                   object_path);
 | 
			
		||||
    if (!context)
 | 
			
		||||
        return;
 | 
			
		||||
 | 
			
		||||
    eekboard_context_set_enabled (context, TRUE);
 | 
			
		||||
    g_dbus_proxy_call (G_DBUS_PROXY(client),
 | 
			
		||||
                       "PushContext",
 | 
			
		||||
                       g_variant_new ("(s)", object_path),
 | 
			
		||||
                       G_DBUS_CALL_FLAGS_NONE,
 | 
			
		||||
                       -1,
 | 
			
		||||
                       cancellable,
 | 
			
		||||
                       eekboard_async_ready_callback,
 | 
			
		||||
                       NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eekboard_client_pop_context:
 | 
			
		||||
 * @eekboard: an #EekboardClient
 | 
			
		||||
 * @cancellable: a #GCancellable
 | 
			
		||||
 *
 | 
			
		||||
 * Disable the current input context and enable the previous one.
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
eekboard_client_pop_context (EekboardClient *client,
 | 
			
		||||
                             GCancellable   *cancellable)
 | 
			
		||||
{
 | 
			
		||||
    g_return_if_fail (EEKBOARD_IS_CLIENT(client));
 | 
			
		||||
 | 
			
		||||
    g_dbus_proxy_call (G_DBUS_PROXY(client),
 | 
			
		||||
                       "PopContext",
 | 
			
		||||
                       NULL,
 | 
			
		||||
                       G_DBUS_CALL_FLAGS_NONE,
 | 
			
		||||
                       -1,
 | 
			
		||||
                       cancellable,
 | 
			
		||||
                       eekboard_async_ready_callback,
 | 
			
		||||
                       NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
eekboard_client_show_keyboard (EekboardClient  *client,
 | 
			
		||||
                               GCancellable    *cancellable)
 | 
			
		||||
{
 | 
			
		||||
    g_return_if_fail (EEKBOARD_IS_CLIENT(client));
 | 
			
		||||
 | 
			
		||||
    g_dbus_proxy_call (G_DBUS_PROXY(client),
 | 
			
		||||
                       "ShowKeyboard",
 | 
			
		||||
                       NULL,
 | 
			
		||||
                       G_DBUS_CALL_FLAGS_NONE,
 | 
			
		||||
                       -1,
 | 
			
		||||
                       cancellable,
 | 
			
		||||
                       eekboard_async_ready_callback,
 | 
			
		||||
                       NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
eekboard_client_hide_keyboard (EekboardClient *client,
 | 
			
		||||
                               GCancellable   *cancellable)
 | 
			
		||||
{
 | 
			
		||||
    g_return_if_fail (EEKBOARD_IS_CLIENT(client));
 | 
			
		||||
 | 
			
		||||
    g_dbus_proxy_call (G_DBUS_PROXY(client),
 | 
			
		||||
                       "HideKeyboard",
 | 
			
		||||
                       NULL,
 | 
			
		||||
                       G_DBUS_CALL_FLAGS_NONE,
 | 
			
		||||
                       -1,
 | 
			
		||||
                       cancellable,
 | 
			
		||||
                       eekboard_async_ready_callback,
 | 
			
		||||
                       NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
send_destroy_context (EekboardClient  *client,
 | 
			
		||||
                      EekboardContext *context,
 | 
			
		||||
                      GCancellable    *cancellable)
 | 
			
		||||
{
 | 
			
		||||
    const gchar *object_path;
 | 
			
		||||
 | 
			
		||||
    object_path = g_dbus_proxy_get_object_path (G_DBUS_PROXY(context));
 | 
			
		||||
 | 
			
		||||
    g_dbus_proxy_call (G_DBUS_PROXY(client),
 | 
			
		||||
                       "DestroyContext",
 | 
			
		||||
                       g_variant_new ("(s)", object_path),
 | 
			
		||||
                       G_DBUS_CALL_FLAGS_NONE,
 | 
			
		||||
                       -1,
 | 
			
		||||
                       cancellable,
 | 
			
		||||
                       eekboard_async_ready_callback,
 | 
			
		||||
                       NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eekboard_client_destroy_context:
 | 
			
		||||
 * @eekboard: an #EekboardClient
 | 
			
		||||
 * @context: an #EekboardContext
 | 
			
		||||
 * @cancellable: a #GCancellable
 | 
			
		||||
 *
 | 
			
		||||
 * Remove @context from @eekboard.
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
eekboard_client_destroy_context (EekboardClient  *client,
 | 
			
		||||
                                 EekboardContext *context,
 | 
			
		||||
                                 GCancellable    *cancellable)
 | 
			
		||||
{
 | 
			
		||||
    const gchar *object_path;
 | 
			
		||||
 | 
			
		||||
    g_return_if_fail (EEKBOARD_IS_CLIENT(client));
 | 
			
		||||
    g_return_if_fail (EEKBOARD_IS_CONTEXT(context));
 | 
			
		||||
 | 
			
		||||
    EekboardClientPrivate *priv = eekboard_client_get_instance_private (client);
 | 
			
		||||
 | 
			
		||||
    object_path = g_dbus_proxy_get_object_path (G_DBUS_PROXY(context));
 | 
			
		||||
    g_hash_table_remove (priv->context_hash, object_path);
 | 
			
		||||
 | 
			
		||||
    send_destroy_context (client, context, cancellable);
 | 
			
		||||
}
 | 
			
		||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user