Compare commits
	
		
			1 Commits
		
	
	
		
			layouts
			...
			wip-input-
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 7f540c0ad9 | 
							
								
								
									
										9
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										9
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							@ -1,9 +0,0 @@
 | 
			
		||||
.zanata-cache/
 | 
			
		||||
_build
 | 
			
		||||
TAGS
 | 
			
		||||
tags
 | 
			
		||||
vgdump
 | 
			
		||||
*.swp
 | 
			
		||||
*~
 | 
			
		||||
\#*#
 | 
			
		||||
.\#*
 | 
			
		||||
@ -2,30 +2,20 @@ image: debian:buster
 | 
			
		||||
 | 
			
		||||
stages:
 | 
			
		||||
  - build
 | 
			
		||||
  - test
 | 
			
		||||
 | 
			
		||||
.tags: &tags
 | 
			
		||||
  tags:
 | 
			
		||||
    - librem5
 | 
			
		||||
 | 
			
		||||
before_script:
 | 
			
		||||
  - apt-get -y update
 | 
			
		||||
  - 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
 | 
			
		||||
 | 
			
		||||
test:
 | 
			
		||||
  <<: *tags
 | 
			
		||||
  stage: test
 | 
			
		||||
  dependencies:
 | 
			
		||||
    - build_meson
 | 
			
		||||
  script:
 | 
			
		||||
    - ninja -C _build test
 | 
			
		||||
 | 
			
		||||
@ -33,8 +33,8 @@ See `.gitlab-ci.yml`.
 | 
			
		||||
### Build from git repo
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
$ git clone https://source.puri.sm/Librem5/squeekboard.git
 | 
			
		||||
$ cd squeekboard
 | 
			
		||||
$ git clone https://source.puri.sm/Librem5/eekboard.git
 | 
			
		||||
$ cd eekboard
 | 
			
		||||
$ mkdir ../build
 | 
			
		||||
$ meson ../build/
 | 
			
		||||
$ cd ../build
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										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,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,64 +1,189 @@
 | 
			
		||||
<?xml version="1.0"?>
 | 
			
		||||
<geometry version="0.90">
 | 
			
		||||
  <bounds x="10" y="10" width="410.0000" height="229"/>
 | 
			
		||||
 | 
			
		||||
  <outline id="default" corner-radius="1.000000">
 | 
			
		||||
  <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"/>
 | 
			
		||||
    <point x="0.000000" y="52"/>
 | 
			
		||||
    <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"/>
 | 
			
		||||
    <point x="0.000000" y="52"/>
 | 
			
		||||
    <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"/>
 | 
			
		||||
    <point x="0.000000" y="52"/>
 | 
			
		||||
    <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"/>
 | 
			
		||||
    <point x="0.000000" y="52"/>
 | 
			
		||||
    <point x="150.5853" y="52.44877"/>
 | 
			
		||||
    <point x="0.000000" y="52.44877"/>
 | 
			
		||||
  </outline>
 | 
			
		||||
 | 
			
		||||
  <button name="Shift_L" oref="altline" />
 | 
			
		||||
  <button name="BackSpace" oref="altline" />
 | 
			
		||||
  <button name="preferences" oref="altline" />
 | 
			
		||||
  <button name="show_numbers" oref="altline" keycode="0" />
 | 
			
		||||
  <button name="show_letters" oref="altline" keycode="0" />
 | 
			
		||||
  <button name="show_symbols" oref="altline" keycode="0" />
 | 
			
		||||
  <button name="period" oref="altline" />
 | 
			
		||||
  <button name="space" oref="spaceline" />
 | 
			
		||||
  <button name="Return" oref="outline7" />
 | 
			
		||||
 | 
			
		||||
  <view>
 | 
			
		||||
    <section angle="0">q w e r t y u i o p</section>
 | 
			
		||||
    <section angle="0">a s d f g h j k l</section>
 | 
			
		||||
    <section angle="0"> Shift_L   z x c v b n m  BackSpace </section>
 | 
			
		||||
    <section angle="0"> show_numbers preferences         space        period    Return    </section>
 | 
			
		||||
  </view>
 | 
			
		||||
  <view>
 | 
			
		||||
    <section angle="0">Q W E R T Y U I O P</section>
 | 
			
		||||
    <section angle="0">A S D F G H J K L</section>
 | 
			
		||||
    <section angle="0"> Shift_L   Z X C V B N M  BackSpace </section>
 | 
			
		||||
    <section angle="0"> show_numbers preferences         space        period    Return    </section>
 | 
			
		||||
  </view>
 | 
			
		||||
  <view>
 | 
			
		||||
    <section angle="0">1 2 3 4 5 6 7 8 9 0</section>
 | 
			
		||||
    <section angle="0">at numbersign dollar percent ampersand minus underscore plus parenleft parenright</section>
 | 
			
		||||
    <section angle="0"> show_symbols   comma quotedbl quoteright colon semicolon exclam question  BackSpace </section>
 | 
			
		||||
    <section angle="0"> show_letters preferences         space        period    Return    </section>
 | 
			
		||||
  </view>
 | 
			
		||||
  <view>
 | 
			
		||||
    <section angle="0">asciitilde quoteleft bar U00B7 squareroot Greek_pi Greek_tau division multiply paragraph</section>
 | 
			
		||||
    <section angle="0">copyright U00AE U00A3 EuroSign U00A5 asciicircum degree asterisk braceleft braceright</section>
 | 
			
		||||
    <section angle="0"> show_numbers   backslash slash less greater equal bracketleft bracketright  BackSpace </section>
 | 
			
		||||
    <section angle="0"> show_letters preferences         space        period    Return    </section>
 | 
			
		||||
  </view>
 | 
			
		||||
</geometry>
 | 
			
		||||
 | 
			
		||||
@ -1,105 +0,0 @@
 | 
			
		||||
<?xml version="1.0"?>
 | 
			
		||||
<geometry version="0.90">
 | 
			
		||||
  <bounds x="0" y="10.000000" width="426.0000" height="296.5853"/>
 | 
			
		||||
 | 
			
		||||
  <outline id="outline2" corner-radius="1.000000">
 | 
			
		||||
    <point x="0.000000" y="0.000000"/>
 | 
			
		||||
    <point x="32" y="0.000000"/>
 | 
			
		||||
    <point x="32" y="52"/>
 | 
			
		||||
    <point x="0.000000" y="52"/>
 | 
			
		||||
  </outline>
 | 
			
		||||
  <outline id="altline" corner-radius="1.000000">
 | 
			
		||||
    <point x="0.000000" y="0.000000"/>
 | 
			
		||||
    <point x="48.39024" y="0.000000"/>
 | 
			
		||||
    <point x="48.39024" y="52"/>
 | 
			
		||||
    <point x="0.000000" y="52"/>
 | 
			
		||||
  </outline>
 | 
			
		||||
  <outline id="outline4" corner-radius="1.000000">
 | 
			
		||||
    <point x="0.000000" y="0.000000"/>
 | 
			
		||||
    <point x="59.31707" y="0.000000"/>
 | 
			
		||||
    <point x="59.31707" y="52"/>
 | 
			
		||||
    <point x="0.000000" y="52"/>
 | 
			
		||||
  </outline>
 | 
			
		||||
  <outline id="outline5" corner-radius="1.000000">
 | 
			
		||||
    <point x="0.000000" y="0.000000"/>
 | 
			
		||||
    <point x="59.31707" y="0.000000"/>
 | 
			
		||||
    <point x="59.31707" y="52"/>
 | 
			
		||||
    <point x="0.000000" y="52"/>
 | 
			
		||||
  </outline>
 | 
			
		||||
  <outline id="outline6" corner-radius="1.000000">
 | 
			
		||||
    <point x="0.000000" y="0.000000"/>
 | 
			
		||||
    <point x="68.68292" y="0.000000"/>
 | 
			
		||||
    <point x="68.68292" y="52"/>
 | 
			
		||||
    <point x="0.000000" y="52"/>
 | 
			
		||||
  </outline>
 | 
			
		||||
  <outline id="outline7" corner-radius="1.000000">
 | 
			
		||||
    <point x="0.000000" y="0.000000"/>
 | 
			
		||||
    <point x="88.97561" y="0.000000"/>
 | 
			
		||||
    <point x="88.97561" y="52"/>
 | 
			
		||||
    <point x="0.000000" y="52"/>
 | 
			
		||||
  </outline>
 | 
			
		||||
  <outline id="outline8" corner-radius="1.000000">
 | 
			
		||||
    <point x="0.000000" y="0.000000"/>
 | 
			
		||||
    <point x="88.97561" y="0.000000"/>
 | 
			
		||||
    <point x="88.97561" y="52"/>
 | 
			
		||||
    <point x="0.000000" y="52"/>
 | 
			
		||||
  </outline>
 | 
			
		||||
  <outline id="outline9" corner-radius="1.000000">
 | 
			
		||||
    <point x="0.000000" y="0.000000"/>
 | 
			
		||||
    <point x="109.2682" y="0.000000"/>
 | 
			
		||||
    <point x="109.2682" y="52"/>
 | 
			
		||||
    <point x="0.000000" y="52"/>
 | 
			
		||||
  </outline>
 | 
			
		||||
  <outline id="outline10" corner-radius="1.000000">
 | 
			
		||||
    <point x="0.000000" y="0.000000"/>
 | 
			
		||||
    <point x="37.46341" y="0.000000"/>
 | 
			
		||||
    <point x="37.46341" y="52"/>
 | 
			
		||||
    <point x="0.000000" y="52"/>
 | 
			
		||||
  </outline>
 | 
			
		||||
  <outline id="outline13" corner-radius="1.000000">
 | 
			
		||||
    <point x="0.000000" y="0.000000"/>
 | 
			
		||||
    <point x="79.60975" y="0.000000"/>
 | 
			
		||||
    <point x="79.60975" y="52"/>
 | 
			
		||||
    <point x="0.000000" y="52"/>
 | 
			
		||||
  </outline>
 | 
			
		||||
  <outline id="spaceline" corner-radius="1.000000">
 | 
			
		||||
    <point x="0.000000" y="0.000000"/>
 | 
			
		||||
    <point x="150.5853" y="0.000000"/>
 | 
			
		||||
    <point x="150.5853" y="52"/>
 | 
			
		||||
    <point x="0.000000" y="52"/>
 | 
			
		||||
  </outline>
 | 
			
		||||
 | 
			
		||||
  <button name="Shift_L" oref="altline" />
 | 
			
		||||
  <button name="BackSpace" oref="altline" />
 | 
			
		||||
  <button name="preferences" oref="altline" />
 | 
			
		||||
  <button name="show_numbers" oref="altline" keycode="0" />
 | 
			
		||||
  <button name="show_letters" oref="altline" keycode="0" />
 | 
			
		||||
  <button name="show_symbols" oref="altline" keycode="0" />
 | 
			
		||||
  <button name="space" oref="spaceline" />
 | 
			
		||||
  <button name="return" oref="outline7" />
 | 
			
		||||
 | 
			
		||||
  <view>
 | 
			
		||||
    <section angle="0">q w e r t y u i o p aring</section>
 | 
			
		||||
    <section angle="0">a s d f g h j k l oslash ae</section>
 | 
			
		||||
    <section angle="0"> Shift_L   z x c v b n m  BackSpace </section>
 | 
			
		||||
    <section angle="0"> show_numbers preferences         space        period    Return    </section>
 | 
			
		||||
  </view>
 | 
			
		||||
  <view>
 | 
			
		||||
    <section angle="0">Q W E R T Y U I O P Aring</section>
 | 
			
		||||
    <section angle="0">A S D F G H J K L Oslash AE</section>
 | 
			
		||||
    <section angle="0"> Shift_L   Z X C V B N M  BackSpace </section>
 | 
			
		||||
    <section angle="0"> show_numbers preferences         space        period    Return    </section>
 | 
			
		||||
  </view>
 | 
			
		||||
  <view>
 | 
			
		||||
    <section angle="0">1 2 3 4 5 6 7 8 9 0</section>
 | 
			
		||||
    <section angle="0">at numbersign dollar percent ampersand minus underscore plus parenleft parenright</section>
 | 
			
		||||
    <section angle="0"> show_symbols   comma quotedbl quoteright colon semicolon exclam question  BackSpace </section>
 | 
			
		||||
    <section angle="0"> show_letters preferences         space        period    Return    </section>
 | 
			
		||||
  </view>
 | 
			
		||||
  <view>
 | 
			
		||||
    <section angle="0">asciitilde quoteleft bar U00B7 squareroot Greek_pi Greek_tau division multiply paragraph</section>
 | 
			
		||||
    <section angle="0">copyright U00AE U00A3 EuroSign U00A5 asciicircum degree asterisk braceleft braceright</section>
 | 
			
		||||
    <section angle="0"> show_numbers   backslash slash less greater equal bracketleft bracketright  BackSpace </section>
 | 
			
		||||
    <section angle="0"> show_letters preferences         space        period    Return    </section>
 | 
			
		||||
  </view>
 | 
			
		||||
</geometry>
 | 
			
		||||
@ -1,40 +0,0 @@
 | 
			
		||||
<?xml version="1.0"?>
 | 
			
		||||
<geometry version="0.90">
 | 
			
		||||
  <bounds x="0" y="10.000000" width="426.0000" height="296.5853"/>
 | 
			
		||||
 | 
			
		||||
  <outline id="default" corner-radius="1.000000">
 | 
			
		||||
    <point x="0.000000" y="0.000000"/>
 | 
			
		||||
    <point x="37.46341" y="0.000000"/>
 | 
			
		||||
    <point x="37.46341" y="52.44877"/>
 | 
			
		||||
    <point x="0.000000" y="52.44877"/>
 | 
			
		||||
  </outline>
 | 
			
		||||
  <outline id="altline" corner-radius="1.000000">
 | 
			
		||||
    <point x="0.000000" y="0.000000"/>
 | 
			
		||||
    <point x="48.39024" y="0.000000"/>
 | 
			
		||||
    <point x="48.39024" y="52.44877"/>
 | 
			
		||||
    <point x="0.000000" y="52.44877"/>
 | 
			
		||||
  </outline>
 | 
			
		||||
  <outline id="outline7" corner-radius="1.000000">
 | 
			
		||||
    <point x="0.000000" y="0.000000"/>
 | 
			
		||||
    <point x="88.97561" y="0.000000"/>
 | 
			
		||||
    <point x="88.97561" y="52.44877"/>
 | 
			
		||||
    <point x="0.000000" y="52.44877"/>
 | 
			
		||||
  </outline>
 | 
			
		||||
  <outline id="spaceline" corner-radius="1.000000">
 | 
			
		||||
    <point x="0.000000" y="0.000000"/>
 | 
			
		||||
    <point x="120.5853" y="0.000000"/>
 | 
			
		||||
    <point x="120.5853" y="52.44877"/>
 | 
			
		||||
    <point x="0.000000" y="52.44877"/>
 | 
			
		||||
  </outline>
 | 
			
		||||
 | 
			
		||||
  <button name="BackSpace" oref="altline" />
 | 
			
		||||
  <button name="space" oref="spaceline" />
 | 
			
		||||
  <button name="Return" oref="outline7" />
 | 
			
		||||
 | 
			
		||||
  <view>
 | 
			
		||||
    <section angle="0">1 2 3 parenleft parenright</section>
 | 
			
		||||
    <section angle="0">4 5 6 numbersign asterisk</section>
 | 
			
		||||
    <section angle="0">7 8 9 plus minus</section>
 | 
			
		||||
    <section angle="0">BackSpace 0 space Return</section>
 | 
			
		||||
  </view>
 | 
			
		||||
</geometry>
 | 
			
		||||
@ -24,9 +24,6 @@
 | 
			
		||||
  <keyboard id="my" name="my"
 | 
			
		||||
	    geometry="compact" symbols="my"
 | 
			
		||||
	    longname="Myanmar" language="my"/>
 | 
			
		||||
  <keyboard id="nb" name="nb"
 | 
			
		||||
	    geometry="extended" symbols="nb"
 | 
			
		||||
	    longname="Norwegian" language="nb"/>
 | 
			
		||||
  <keyboard id="ru" name="ru"
 | 
			
		||||
	    geometry="compact" symbols="us"
 | 
			
		||||
	    longname="Russian" language="ru"/>
 | 
			
		||||
@ -88,13 +85,4 @@
 | 
			
		||||
  <keyboard id="te-inscript" name="te-inscript"
 | 
			
		||||
	    geometry="compact" symbols="te-inscript"
 | 
			
		||||
	    longname="Telugu (Inscript)" language="te"/>
 | 
			
		||||
 | 
			
		||||
  <!-- Common keyboards -->
 | 
			
		||||
  <keyboard id="number" name="number"
 | 
			
		||||
	    geometry="number-keypad" symbols="special/number"
 | 
			
		||||
	    longname="Numeric keypad" language="all"/>
 | 
			
		||||
  <keyboard id="phone" name="phone"
 | 
			
		||||
	    geometry="number-keypad" symbols="special/number"
 | 
			
		||||
	    longname="Phone keypad" language="all"/>
 | 
			
		||||
 | 
			
		||||
</keyboards>
 | 
			
		||||
 | 
			
		||||
@ -1,132 +0,0 @@
 | 
			
		||||
<?xml version='1.0' encoding='UTF-8' standalone='yes'?>
 | 
			
		||||
<symbols version="0.90">
 | 
			
		||||
  <symbol label="*">asterisk</symbol>
 | 
			
		||||
  <symbol label="+/=">show_symbols</symbol>
 | 
			
		||||
  <symbol label="τ">Greek_tau</symbol>
 | 
			
		||||
  <symbol label="å">aring</symbol>
 | 
			
		||||
  <symbol label="ø">oslash</symbol>
 | 
			
		||||
  <symbol label="æ">ae</symbol>
 | 
			
		||||
  <symbol label="Å">Aring</symbol>
 | 
			
		||||
  <symbol label="Ø">Oslash</symbol>
 | 
			
		||||
  <symbol label="Æ">AE</symbol>
 | 
			
		||||
  <symbol label="q">q</symbol>
 | 
			
		||||
  <symbol label="Q">Q</symbol>
 | 
			
		||||
  <symbol label="1">1</symbol>
 | 
			
		||||
  <symbol label="~">asciitilde</symbol>
 | 
			
		||||
  <symbol label="w">w</symbol>
 | 
			
		||||
  <symbol label="W">W</symbol>
 | 
			
		||||
  <symbol label="2">2</symbol>
 | 
			
		||||
  <symbol label="`">quoteleft</symbol>
 | 
			
		||||
  <symbol label="e">e</symbol>
 | 
			
		||||
  <symbol label="E">E</symbol>
 | 
			
		||||
  <symbol label="3">3</symbol>
 | 
			
		||||
  <symbol label="|">bar</symbol>
 | 
			
		||||
  <symbol label="r">r</symbol>
 | 
			
		||||
  <symbol label="R">R</symbol>
 | 
			
		||||
  <symbol label="4">4</symbol>
 | 
			
		||||
  <symbol label="·">U00B7</symbol>
 | 
			
		||||
  <symbol label="t">t</symbol>
 | 
			
		||||
  <symbol label="T">T</symbol>
 | 
			
		||||
  <symbol label="5">5</symbol>
 | 
			
		||||
  <symbol label="√">squareroot</symbol>
 | 
			
		||||
  <symbol label="y">y</symbol>
 | 
			
		||||
  <symbol label="Y">Y</symbol>
 | 
			
		||||
  <symbol label="6">6</symbol>
 | 
			
		||||
  <symbol label="π">Greek_pi</symbol>
 | 
			
		||||
  <symbol label="u">u</symbol>
 | 
			
		||||
  <symbol label="U">U</symbol>
 | 
			
		||||
  <symbol label="7">7</symbol>
 | 
			
		||||
  <symbol label="÷">division</symbol>
 | 
			
		||||
  <symbol label="i">i</symbol>
 | 
			
		||||
  <symbol label="I">I</symbol>
 | 
			
		||||
  <symbol label="8">8</symbol>
 | 
			
		||||
  <symbol label="×">multiply</symbol>
 | 
			
		||||
  <symbol label="o">o</symbol>
 | 
			
		||||
  <symbol label="O">O</symbol>
 | 
			
		||||
  <symbol label="9">9</symbol>
 | 
			
		||||
  <symbol label="¶">paragraph</symbol>
 | 
			
		||||
  <symbol label="p">p</symbol>
 | 
			
		||||
  <symbol label="P">P</symbol>
 | 
			
		||||
  <symbol label="0">0</symbol>
 | 
			
		||||
  <symbol label="△">U25B3</symbol>
 | 
			
		||||
  <symbol keyval="229" label="å">aring</symbol>
 | 
			
		||||
  <symbol keyval="197" label="Å">Aring</symbol>
 | 
			
		||||
  <symbol label="a">a</symbol>
 | 
			
		||||
  <symbol label="A">A</symbol>
 | 
			
		||||
  <symbol label="@">at</symbol>
 | 
			
		||||
  <symbol label="©">copyright</symbol>
 | 
			
		||||
  <symbol label="s">s</symbol>
 | 
			
		||||
  <symbol label="S">S</symbol>
 | 
			
		||||
  <symbol label="#">numbersign</symbol>
 | 
			
		||||
  <symbol label="®">U00AE</symbol>
 | 
			
		||||
  <symbol label="d">d</symbol>
 | 
			
		||||
  <symbol label="D">D</symbol>
 | 
			
		||||
  <symbol label="$">dollar</symbol>
 | 
			
		||||
  <symbol label="£">U00A3</symbol>
 | 
			
		||||
  <symbol label="f">f</symbol>
 | 
			
		||||
  <symbol label="F">F</symbol>
 | 
			
		||||
  <symbol label="%">percent</symbol>
 | 
			
		||||
  <symbol label="€">EuroSign</symbol>
 | 
			
		||||
  <symbol label="g">g</symbol>
 | 
			
		||||
  <symbol label="G">G</symbol>
 | 
			
		||||
  <symbol label="&">ampersand</symbol>
 | 
			
		||||
  <symbol label="¥">U00A5</symbol>
 | 
			
		||||
  <symbol label="h">h</symbol>
 | 
			
		||||
  <symbol label="H">H</symbol>
 | 
			
		||||
  <symbol label="-">minus</symbol>
 | 
			
		||||
  <symbol label="^">asciicircum</symbol>
 | 
			
		||||
  <symbol label="j">j</symbol>
 | 
			
		||||
  <symbol label="J">J</symbol>
 | 
			
		||||
  <symbol label="_">underscore</symbol>
 | 
			
		||||
  <symbol label="°">degree</symbol>
 | 
			
		||||
  <symbol label="k">k</symbol>
 | 
			
		||||
  <symbol label="K">K</symbol>
 | 
			
		||||
  <symbol label="+">plus</symbol>
 | 
			
		||||
  <symbol label="=">equal</symbol>
 | 
			
		||||
  <symbol label="l">l</symbol>
 | 
			
		||||
  <symbol label="L">L</symbol>
 | 
			
		||||
  <symbol label="(">parenleft</symbol>
 | 
			
		||||
  <symbol label="{">braceleft</symbol>
 | 
			
		||||
  <symbol keyval="248" label="ø">oslash</symbol>
 | 
			
		||||
  <symbol keyval="216" label="Ø">Oslash</symbol>
 | 
			
		||||
  <symbol label=")">parenright</symbol>
 | 
			
		||||
  <symbol label="}">braceright</symbol>
 | 
			
		||||
  <symbol keyval="230" label="æ">ae</symbol>
 | 
			
		||||
  <symbol keyval="198" label="Æ">AE</symbol>
 | 
			
		||||
  <symbol keyval="65293" icon="key-enter">Return</symbol>
 | 
			
		||||
  <symbol keyval="65505" icon="key-shift">Shift_L</symbol>
 | 
			
		||||
  <symbol label="z">z</symbol>
 | 
			
		||||
  <symbol label="Z">Z</symbol>
 | 
			
		||||
  <symbol label=",">comma</symbol>
 | 
			
		||||
  <symbol label="\">backslash</symbol>
 | 
			
		||||
  <symbol label="x">x</symbol>
 | 
			
		||||
  <symbol label="X">X</symbol>
 | 
			
		||||
  <symbol label=""">quotedbl</symbol>
 | 
			
		||||
  <symbol label="/">slash</symbol>
 | 
			
		||||
  <symbol label="c">c</symbol>
 | 
			
		||||
  <symbol label="C">C</symbol>
 | 
			
		||||
  <symbol label="'">quoteright</symbol>
 | 
			
		||||
  <symbol label="<">less</symbol>
 | 
			
		||||
  <symbol label="v">v</symbol>
 | 
			
		||||
  <symbol label="V">V</symbol>
 | 
			
		||||
  <symbol label=":">colon</symbol>
 | 
			
		||||
  <symbol label=">">greater</symbol>
 | 
			
		||||
  <symbol label="b">b</symbol>
 | 
			
		||||
  <symbol label="B">B</symbol>
 | 
			
		||||
  <symbol label=";">semicolon</symbol>
 | 
			
		||||
  <symbol label="=">equal</symbol>
 | 
			
		||||
  <symbol label="n">n</symbol>
 | 
			
		||||
  <symbol label="N">N</symbol>
 | 
			
		||||
  <symbol label="!">exclam</symbol>
 | 
			
		||||
  <symbol label="[">bracketleft</symbol>
 | 
			
		||||
  <symbol label="m">m</symbol>
 | 
			
		||||
  <symbol label="M">M</symbol>
 | 
			
		||||
  <symbol label="?">question</symbol>
 | 
			
		||||
  <symbol label="]">bracketright</symbol>
 | 
			
		||||
  <symbol label=".">period</symbol>
 | 
			
		||||
  <symbol label="123">show_numbers</symbol>
 | 
			
		||||
  <symbol label="ABC">show_letters</symbol>
 | 
			
		||||
  <symbol label="☺" icon="keyboard-mode-symbolic" tooltip="Setup">preferences</symbol>
 | 
			
		||||
  <symbol label=" ">space</symbol>
 | 
			
		||||
  <symbol keyval="65288" icon="edit-clear-symbolic">BackSpace</symbol>
 | 
			
		||||
</symbols>
 | 
			
		||||
@ -1,22 +0,0 @@
 | 
			
		||||
<?xml version='1.0' encoding='ASCII' standalone='yes'?>
 | 
			
		||||
<symbols version="0.90">
 | 
			
		||||
  <symbol label="1">1</symbol>
 | 
			
		||||
  <symbol label="2">2</symbol>
 | 
			
		||||
  <symbol label="3">3</symbol>
 | 
			
		||||
  <symbol label="(">parenleft</symbol>
 | 
			
		||||
  <symbol label=")">parenright</symbol>
 | 
			
		||||
  <symbol label="4">4</symbol>
 | 
			
		||||
  <symbol label="5">5</symbol>
 | 
			
		||||
  <symbol label="6">6</symbol>
 | 
			
		||||
  <symbol label="#">numbersign</symbol>
 | 
			
		||||
  <symbol label="*">asterisk</symbol>
 | 
			
		||||
  <symbol label="7">7</symbol>
 | 
			
		||||
  <symbol label="8">8</symbol>
 | 
			
		||||
  <symbol label="9">9</symbol>
 | 
			
		||||
  <symbol label="+">plus</symbol>
 | 
			
		||||
  <symbol label="-">minus</symbol>
 | 
			
		||||
  <symbol label="0">0</symbol>
 | 
			
		||||
  <symbol keyval="65293" icon="key-enter">Return</symbol>
 | 
			
		||||
  <symbol label=" ">space</symbol>
 | 
			
		||||
  <symbol keyval="65288" icon="edit-clear-symbolic">BackSpace</symbol>
 | 
			
		||||
</symbols>
 | 
			
		||||
@ -1,118 +1,304 @@
 | 
			
		||||
<?xml version='1.0' encoding='ASCII' standalone='yes'?>
 | 
			
		||||
<?xml version="1.0"?>
 | 
			
		||||
<symbols version="0.90">
 | 
			
		||||
  <symbol label="*">asterisk</symbol>
 | 
			
		||||
  <symbol label="+/=">show_symbols</symbol>
 | 
			
		||||
  <symbol label="q">q</symbol>
 | 
			
		||||
  <symbol label="Q">Q</symbol>
 | 
			
		||||
  <symbol label="1">1</symbol>
 | 
			
		||||
  <symbol label="~">asciitilde</symbol>
 | 
			
		||||
  <symbol label="w">w</symbol>
 | 
			
		||||
  <symbol label="W">W</symbol>
 | 
			
		||||
  <symbol label="2">2</symbol>
 | 
			
		||||
  <symbol label="`">quoteleft</symbol>
 | 
			
		||||
  <symbol label="e">e</symbol>
 | 
			
		||||
  <symbol label="E">E</symbol>
 | 
			
		||||
  <symbol label="3">3</symbol>
 | 
			
		||||
  <symbol label="|">bar</symbol>
 | 
			
		||||
  <symbol label="r">r</symbol>
 | 
			
		||||
  <symbol label="R">R</symbol>
 | 
			
		||||
  <symbol label="4">4</symbol>
 | 
			
		||||
  <symbol label="·">U00B7</symbol>
 | 
			
		||||
  <symbol label="t">t</symbol>
 | 
			
		||||
  <symbol label="T">T</symbol>
 | 
			
		||||
  <symbol label="5">5</symbol>
 | 
			
		||||
  <symbol label="√">squareroot</symbol>
 | 
			
		||||
  <symbol label="y">y</symbol>
 | 
			
		||||
  <symbol label="Y">Y</symbol>
 | 
			
		||||
  <symbol label="6">6</symbol>
 | 
			
		||||
  <symbol label="π">Greek_pi</symbol>
 | 
			
		||||
  <symbol label="u">u</symbol>
 | 
			
		||||
  <symbol label="U">U</symbol>
 | 
			
		||||
  <symbol label="7">7</symbol>
 | 
			
		||||
  <symbol label="÷">division</symbol>
 | 
			
		||||
  <symbol label="i">i</symbol>
 | 
			
		||||
  <symbol label="I">I</symbol>
 | 
			
		||||
  <symbol label="8">8</symbol>
 | 
			
		||||
  <symbol label="×">multiply</symbol>
 | 
			
		||||
  <symbol label="o">o</symbol>
 | 
			
		||||
  <symbol label="O">O</symbol>
 | 
			
		||||
  <symbol label="9">9</symbol>
 | 
			
		||||
  <symbol label="¶">paragraph</symbol>
 | 
			
		||||
  <symbol label="p">p</symbol>
 | 
			
		||||
  <symbol label="P">P</symbol>
 | 
			
		||||
  <symbol label="0">0</symbol>
 | 
			
		||||
  <symbol label="τ">Greek_tau</symbol>
 | 
			
		||||
  <symbol label="a">a</symbol>
 | 
			
		||||
  <symbol label="A">A</symbol>
 | 
			
		||||
  <symbol label="@">at</symbol>
 | 
			
		||||
  <symbol label="©">copyright</symbol>
 | 
			
		||||
  <symbol label="s">s</symbol>
 | 
			
		||||
  <symbol label="S">S</symbol>
 | 
			
		||||
  <symbol label="#">numbersign</symbol>
 | 
			
		||||
  <symbol label="®">U00AE</symbol>
 | 
			
		||||
  <symbol label="d">d</symbol>
 | 
			
		||||
  <symbol label="D">D</symbol>
 | 
			
		||||
  <symbol label="$">dollar</symbol>
 | 
			
		||||
  <symbol label="£">U00A3</symbol>
 | 
			
		||||
  <symbol label="f">f</symbol>
 | 
			
		||||
  <symbol label="F">F</symbol>
 | 
			
		||||
  <symbol label="%">percent</symbol>
 | 
			
		||||
  <symbol label="€">EuroSign</symbol>
 | 
			
		||||
  <symbol label="g">g</symbol>
 | 
			
		||||
  <symbol label="G">G</symbol>
 | 
			
		||||
  <symbol label="&">ampersand</symbol>
 | 
			
		||||
  <symbol label="¥">U00A5</symbol>
 | 
			
		||||
  <symbol label="h">h</symbol>
 | 
			
		||||
  <symbol label="H">H</symbol>
 | 
			
		||||
  <symbol label="-">minus</symbol>
 | 
			
		||||
  <symbol label="^">asciicircum</symbol>
 | 
			
		||||
  <symbol label="j">j</symbol>
 | 
			
		||||
  <symbol label="J">J</symbol>
 | 
			
		||||
  <symbol label="_">underscore</symbol>
 | 
			
		||||
  <symbol label="°">degree</symbol>
 | 
			
		||||
  <symbol label="k">k</symbol>
 | 
			
		||||
  <symbol label="K">K</symbol>
 | 
			
		||||
  <symbol label="+">plus</symbol>
 | 
			
		||||
  <symbol label="=">equal</symbol>
 | 
			
		||||
  <symbol label="l">l</symbol>
 | 
			
		||||
  <symbol label="L">L</symbol>
 | 
			
		||||
  <symbol label="(">parenleft</symbol>
 | 
			
		||||
  <symbol label="{">braceleft</symbol>
 | 
			
		||||
  <symbol label=")">parenright</symbol>
 | 
			
		||||
  <symbol label="}">braceright</symbol>
 | 
			
		||||
  <symbol keyval="65293" icon="key-enter">Return</symbol>
 | 
			
		||||
  <symbol keyval="65505" icon="key-shift">Shift_L</symbol>
 | 
			
		||||
  <symbol label="z">z</symbol>
 | 
			
		||||
  <symbol label="Z">Z</symbol>
 | 
			
		||||
  <symbol label=",">comma</symbol>
 | 
			
		||||
  <symbol label="\">backslash</symbol>
 | 
			
		||||
  <symbol label="x">x</symbol>
 | 
			
		||||
  <symbol label="X">X</symbol>
 | 
			
		||||
  <symbol label=""">quotedbl</symbol>
 | 
			
		||||
  <symbol label="/">slash</symbol>
 | 
			
		||||
  <symbol label="c">c</symbol>
 | 
			
		||||
  <symbol label="C">C</symbol>
 | 
			
		||||
  <symbol label="'">quoteright</symbol>
 | 
			
		||||
  <symbol label="<">less</symbol>
 | 
			
		||||
  <symbol label="v">v</symbol>
 | 
			
		||||
  <symbol label="V">V</symbol>
 | 
			
		||||
  <symbol label=":">colon</symbol>
 | 
			
		||||
  <symbol label=">">greater</symbol>
 | 
			
		||||
  <symbol label="b">b</symbol>
 | 
			
		||||
  <symbol label="B">B</symbol>
 | 
			
		||||
  <symbol label=";">semicolon</symbol>
 | 
			
		||||
  <symbol label="n">n</symbol>
 | 
			
		||||
  <symbol label="N">N</symbol>
 | 
			
		||||
  <symbol label="!">exclam</symbol>
 | 
			
		||||
  <symbol label="[">bracketleft</symbol>
 | 
			
		||||
  <symbol label="m">m</symbol>
 | 
			
		||||
  <symbol label="M">M</symbol>
 | 
			
		||||
  <symbol label="?">question</symbol>
 | 
			
		||||
  <symbol label="]">bracketright</symbol>
 | 
			
		||||
  <symbol label=".">period</symbol>
 | 
			
		||||
  <symbol label="123">show_numbers</symbol>
 | 
			
		||||
  <symbol label="ABC">show_letters</symbol>
 | 
			
		||||
  <symbol label="☺" icon="keyboard-mode-symbolic" tooltip="Setup">preferences</symbol>
 | 
			
		||||
  <symbol label=" ">space</symbol>
 | 
			
		||||
  <symbol keyval="65288" icon="edit-clear-symbolic">BackSpace</symbol>
 | 
			
		||||
  <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,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',
 | 
			
		||||
 | 
			
		||||
@ -1,43 +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/geometry/compact.xml</file>
 | 
			
		||||
   <file compressed="true" preprocess="xml-stripblanks">keyboards/geometry/extended.xml</file>
 | 
			
		||||
   <file compressed="true" preprocess="xml-stripblanks">keyboards/geometry/number-keypad.xml</file>
 | 
			
		||||
   <file compressed="true" preprocess="xml-stripblanks">keyboards/keyboards.xml</file>
 | 
			
		||||
   <file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/ar.xml</file>
 | 
			
		||||
   <file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/as-inscript.xml</file>
 | 
			
		||||
   <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/nb.xml</file>
 | 
			
		||||
   <file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/or-inscript.xml</file>
 | 
			
		||||
   <file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/pa-inscript.xml</file>
 | 
			
		||||
   <file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/ru.xml</file>
 | 
			
		||||
   <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/us.xml</file>
 | 
			
		||||
   <file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/zh-bopomofo.xml</file>
 | 
			
		||||
   <file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/special/number.xml</file>
 | 
			
		||||
   <file>icons/key-enter.svg</file>
 | 
			
		||||
   <file>icons/key-shift.svg</file>
 | 
			
		||||
   <file>icons/keyboard-mode-symbolic.svg</file>
 | 
			
		||||
  </gresource>
 | 
			
		||||
</gresources>
 | 
			
		||||
@ -7,8 +7,7 @@
 | 
			
		||||
.key {
 | 
			
		||||
    color: #deddda;
 | 
			
		||||
    background: #464448;
 | 
			
		||||
    border-style: solid;
 | 
			
		||||
    border-width: 1px;
 | 
			
		||||
    border-width: 0.5px;
 | 
			
		||||
    border-color: #5e5c64;
 | 
			
		||||
    border-radius: 2px;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										6
									
								
								debian/control
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										6
									
								
								debian/control
									
									
									
									
										vendored
									
									
								
							@ -11,10 +11,8 @@ Build-Depends:
 | 
			
		||||
 libcroco3-dev,
 | 
			
		||||
 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
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										0
									
								
								eek/config.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								eek/config.h
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										240
									
								
								eek/eek-container.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										240
									
								
								eek/eek-container.c
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,240 @@
 | 
			
		||||
/* 
 | 
			
		||||
 * 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, };
 | 
			
		||||
 | 
			
		||||
G_DEFINE_ABSTRACT_TYPE (EekContainer, eek_container, EEK_TYPE_ELEMENT);
 | 
			
		||||
 | 
			
		||||
#define EEK_CONTAINER_GET_PRIVATE(obj)                                  \
 | 
			
		||||
    (G_TYPE_INSTANCE_GET_PRIVATE ((obj), EEK_TYPE_CONTAINER, EekContainerPrivate))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
struct _EekContainerPrivate
 | 
			
		||||
{
 | 
			
		||||
    GList *head;
 | 
			
		||||
    GList *last;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
eek_container_real_add_child (EekContainer *self,
 | 
			
		||||
                              EekElement   *child)
 | 
			
		||||
{
 | 
			
		||||
    EekContainerPrivate *priv = EEK_CONTAINER_GET_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_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_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_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)
 | 
			
		||||
{
 | 
			
		||||
    EekContainerPrivate *priv = EEK_CONTAINER_GET_PRIVATE(object);
 | 
			
		||||
    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);
 | 
			
		||||
 | 
			
		||||
    g_type_class_add_private (gobject_class,
 | 
			
		||||
                              sizeof (EekContainerPrivate));
 | 
			
		||||
 | 
			
		||||
    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)
 | 
			
		||||
{
 | 
			
		||||
    self->priv = EEK_CONTAINER_GET_PRIVATE(self);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * 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);
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										109
									
								
								eek/eek-container.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										109
									
								
								eek/eek-container.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,109 @@
 | 
			
		||||
/* 
 | 
			
		||||
 * 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())
 | 
			
		||||
#define EEK_CONTAINER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EEK_TYPE_CONTAINER, EekContainer))
 | 
			
		||||
#define EEK_CONTAINER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EEK_TYPE_CONTAINER, EekContainerClass))
 | 
			
		||||
#define EEK_IS_CONTAINER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EEK_TYPE_CONTAINER))
 | 
			
		||||
#define EEK_IS_CONTAINER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EEK_TYPE_CONTAINER))
 | 
			
		||||
#define EEK_CONTAINER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EEK_TYPE_CONTAINER, EekContainerClass))
 | 
			
		||||
 | 
			
		||||
typedef struct _EekContainerClass EekContainerClass;
 | 
			
		||||
typedef struct _EekContainerPrivate EekContainerPrivate;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * 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);
 | 
			
		||||
 | 
			
		||||
struct _EekContainer
 | 
			
		||||
{
 | 
			
		||||
    /*< private >*/
 | 
			
		||||
    EekElement parent;
 | 
			
		||||
 | 
			
		||||
    EekContainerPrivate *priv;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * 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,61 @@
 | 
			
		||||
 * 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
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
typedef struct _EekElementPrivate
 | 
			
		||||
{
 | 
			
		||||
    EekBounds bounds;
 | 
			
		||||
} EekElementPrivate;
 | 
			
		||||
enum {
 | 
			
		||||
    SYMBOL_INDEX_CHANGED,
 | 
			
		||||
    LAST_SIGNAL
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (EekElement, eek_element, G_TYPE_OBJECT)
 | 
			
		||||
static guint signals[LAST_SIGNAL] = { 0, };
 | 
			
		||||
 | 
			
		||||
G_DEFINE_ABSTRACT_TYPE (EekElement, eek_element, G_TYPE_OBJECT);
 | 
			
		||||
 | 
			
		||||
#define EEK_ELEMENT_GET_PRIVATE(obj)                                  \
 | 
			
		||||
    (G_TYPE_INSTANCE_GET_PRIVATE ((obj), EEK_TYPE_ELEMENT, EekElementPrivate))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
struct _EekElementPrivate
 | 
			
		||||
{
 | 
			
		||||
    gchar *name;
 | 
			
		||||
    EekBounds bounds;
 | 
			
		||||
    EekElement *parent;
 | 
			
		||||
    gint group;
 | 
			
		||||
    gint level;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
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)
 | 
			
		||||
{
 | 
			
		||||
    EekElementPrivate *priv = EEK_ELEMENT_GET_PRIVATE(object);
 | 
			
		||||
 | 
			
		||||
    g_free (priv->name);
 | 
			
		||||
    G_OBJECT_CLASS (eek_element_parent_class)->finalize (object);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -60,9 +93,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 +121,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;
 | 
			
		||||
@ -95,11 +146,30 @@ eek_element_class_init (EekElementClass *klass)
 | 
			
		||||
    GObjectClass      *gobject_class = G_OBJECT_CLASS (klass);
 | 
			
		||||
    GParamSpec        *pspec;
 | 
			
		||||
 | 
			
		||||
    g_type_class_add_private (gobject_class,
 | 
			
		||||
                              sizeof (EekElementPrivate));
 | 
			
		||||
 | 
			
		||||
    /* 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 +183,139 @@ 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;
 | 
			
		||||
 | 
			
		||||
    priv = self->priv = EEK_ELEMENT_GET_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));
 | 
			
		||||
 | 
			
		||||
    if (element->priv->parent == parent)
 | 
			
		||||
        return;
 | 
			
		||||
 | 
			
		||||
    if (element->priv->parent != NULL) {
 | 
			
		||||
        /* release self-reference acquired when setting parent */
 | 
			
		||||
        g_object_unref (element);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (parent != NULL) {
 | 
			
		||||
        g_object_ref (element);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    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);
 | 
			
		||||
    return element->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));
 | 
			
		||||
    g_free (element->priv->name);
 | 
			
		||||
    element->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);
 | 
			
		||||
    return element->priv->name;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@ -135,10 +332,7 @@ eek_element_set_bounds (EekElement  *element,
 | 
			
		||||
                        EekBounds   *bounds)
 | 
			
		||||
{
 | 
			
		||||
    g_return_if_fail (EEK_IS_ELEMENT(element));
 | 
			
		||||
 | 
			
		||||
    EekElementPrivate *priv = eek_element_get_instance_private (element);
 | 
			
		||||
 | 
			
		||||
    memcpy (&priv->bounds, bounds, sizeof(EekBounds));
 | 
			
		||||
    memcpy (&element->priv->bounds, bounds, sizeof(EekBounds));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@ -156,8 +350,201 @@ eek_element_get_bounds (EekElement  *element,
 | 
			
		||||
{
 | 
			
		||||
    g_return_if_fail (EEK_IS_ELEMENT(element));
 | 
			
		||||
    g_return_if_fail (bounds != NULL);
 | 
			
		||||
 | 
			
		||||
    EekElementPrivate *priv = eek_element_get_instance_private (element);
 | 
			
		||||
 | 
			
		||||
    memcpy (bounds, &priv->bounds, sizeof(EekBounds));
 | 
			
		||||
    memcpy (bounds, &element->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));
 | 
			
		||||
    if (element->priv->group != group) {
 | 
			
		||||
        element->priv->group = group;
 | 
			
		||||
        g_object_notify (G_OBJECT(element), "group");
 | 
			
		||||
        g_signal_emit (element, signals[SYMBOL_INDEX_CHANGED], 0,
 | 
			
		||||
                       group, element->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));
 | 
			
		||||
    if (element->priv->level != level) {
 | 
			
		||||
        element->priv->level = level;
 | 
			
		||||
        g_object_notify (G_OBJECT(element), "level");
 | 
			
		||||
        g_signal_emit (element, signals[SYMBOL_INDEX_CHANGED], 0,
 | 
			
		||||
                       element->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);
 | 
			
		||||
    return element->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);
 | 
			
		||||
    return element->priv->level;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -30,16 +30,39 @@
 | 
			
		||||
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
#define EEK_TYPE_ELEMENT (eek_element_get_type())
 | 
			
		||||
G_DECLARE_DERIVABLE_TYPE (EekElement, eek_element, EEK, ELEMENT, GObject)
 | 
			
		||||
#define EEK_ELEMENT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EEK_TYPE_ELEMENT, EekElement))
 | 
			
		||||
#define EEK_ELEMENT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EEK_TYPE_ELEMENT, EekElementClass))
 | 
			
		||||
#define EEK_IS_ELEMENT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EEK_TYPE_ELEMENT))
 | 
			
		||||
#define EEK_IS_ELEMENT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EEK_TYPE_ELEMENT))
 | 
			
		||||
#define EEK_ELEMENT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EEK_TYPE_ELEMENT, EekElementClass))
 | 
			
		||||
 | 
			
		||||
typedef struct _EekElementClass   EekElementClass;
 | 
			
		||||
typedef struct _EekElementPrivate EekElementPrivate;
 | 
			
		||||
 | 
			
		||||
struct _EekElement
 | 
			
		||||
{
 | 
			
		||||
    /*< private >*/
 | 
			
		||||
    GObject parent;
 | 
			
		||||
 | 
			
		||||
    EekElementPrivate *priv;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
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 +74,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,54 +23,70 @@
 | 
			
		||||
 * @short_description: a #GtkWidget displaying #EekKeyboard
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_CONFIG_H
 | 
			
		||||
#include "config.h"
 | 
			
		||||
#endif  /* HAVE_CONFIG_H */
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_LIBCANBERRA
 | 
			
		||||
#include <canberra-gtk.h>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include <math.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
#include "eek-renderer.h"
 | 
			
		||||
#include "eek-keyboard.h"
 | 
			
		||||
#include "src/symbol.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
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
G_DEFINE_TYPE (EekGtkKeyboard, eek_gtk_keyboard, GTK_TYPE_DRAWING_AREA);
 | 
			
		||||
 | 
			
		||||
#define EEK_GTK_KEYBOARD_GET_PRIVATE(obj)                                  \
 | 
			
		||||
    (G_TYPE_INSTANCE_GET_PRIVATE ((obj), EEK_TYPE_GTK_KEYBOARD, EekGtkKeyboardPrivate))
 | 
			
		||||
 | 
			
		||||
/* since 2.91.5 GDK_DRAWABLE was removed and gdk_cairo_create takes
 | 
			
		||||
   GdkWindow as the argument */
 | 
			
		||||
#ifndef GDK_DRAWABLE
 | 
			
		||||
#define GDK_DRAWABLE(x) (x)
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
typedef struct _EekGtkKeyboardPrivate
 | 
			
		||||
struct _EekGtkKeyboardPrivate
 | 
			
		||||
{
 | 
			
		||||
    EekRenderer *renderer;
 | 
			
		||||
    LevelKeyboard *keyboard;
 | 
			
		||||
    GtkCssProvider *css_provider;
 | 
			
		||||
    GtkStyleContext *scontext;
 | 
			
		||||
    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,
 | 
			
		||||
static void       on_key_pressed          (EekKey      *key,
 | 
			
		||||
                                           EekGtkKeyboard *self);
 | 
			
		||||
static void       on_button_released         (struct squeek_button *button,
 | 
			
		||||
                                           struct squeek_view *view,
 | 
			
		||||
static void       on_key_released         (EekKey      *key,
 | 
			
		||||
                                           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,
 | 
			
		||||
                                           struct squeek_button *button);
 | 
			
		||||
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)
 | 
			
		||||
@ -90,48 +106,40 @@ static gboolean
 | 
			
		||||
eek_gtk_keyboard_real_draw (GtkWidget *self,
 | 
			
		||||
                            cairo_t   *cr)
 | 
			
		||||
{
 | 
			
		||||
    EekGtkKeyboardPrivate *priv =
 | 
			
		||||
	    eek_gtk_keyboard_get_instance_private (EEK_GTK_KEYBOARD (self));
 | 
			
		||||
    EekGtkKeyboardPrivate *priv = EEK_GTK_KEYBOARD_GET_PRIVATE(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, priv->scontext);
 | 
			
		||||
        pcontext = gtk_widget_get_pango_context (self);
 | 
			
		||||
        priv->renderer = eek_gtk_renderer_new (priv->keyboard, pcontext, self);
 | 
			
		||||
        if (priv->theme)
 | 
			
		||||
            eek_renderer_set_theme (priv->renderer, priv->theme);
 | 
			
		||||
 | 
			
		||||
        eek_renderer_set_allocation_size (priv->renderer,
 | 
			
		||||
                                          allocation.width,
 | 
			
		||||
                                          allocation.height);
 | 
			
		||||
        eek_renderer_set_scale_factor (priv->renderer,
 | 
			
		||||
                                       gtk_widget_get_scale_factor (self));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    eek_renderer_render_keyboard (priv->renderer, cr);
 | 
			
		||||
 | 
			
		||||
    struct squeek_view *view = priv->keyboard->views[priv->keyboard->level];
 | 
			
		||||
 | 
			
		||||
    /* redraw pressed key */
 | 
			
		||||
    const GList *list = priv->keyboard->pressed_buttons;
 | 
			
		||||
    for (const GList *head = list; head; head = g_list_next (head)) {
 | 
			
		||||
        struct button_place place = squeek_view_find_key(
 | 
			
		||||
            view, squeek_button_get_key(head->data)
 | 
			
		||||
        );
 | 
			
		||||
        if (place.button)
 | 
			
		||||
            render_pressed_button (self, &place);
 | 
			
		||||
    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_buttons;
 | 
			
		||||
    for (const GList *head = list; head; head = g_list_next (head)) {
 | 
			
		||||
        struct button_place place = squeek_view_find_key(
 | 
			
		||||
            view, squeek_button_get_key(
 | 
			
		||||
                ((EekModifierKey *)head->data)->button
 | 
			
		||||
            )
 | 
			
		||||
        );
 | 
			
		||||
        if (place.button)
 | 
			
		||||
            render_locked_button (self, &place);
 | 
			
		||||
    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;
 | 
			
		||||
}
 | 
			
		||||
@ -140,8 +148,7 @@ static void
 | 
			
		||||
eek_gtk_keyboard_real_size_allocate (GtkWidget     *self,
 | 
			
		||||
                                     GtkAllocation *allocation)
 | 
			
		||||
{
 | 
			
		||||
    EekGtkKeyboardPrivate *priv =
 | 
			
		||||
	    eek_gtk_keyboard_get_instance_private (EEK_GTK_KEYBOARD (self));
 | 
			
		||||
    EekGtkKeyboardPrivate *priv = EEK_GTK_KEYBOARD_GET_PRIVATE(self);
 | 
			
		||||
 | 
			
		||||
    if (priv->renderer)
 | 
			
		||||
        eek_renderer_set_allocation_size (priv->renderer,
 | 
			
		||||
@ -153,63 +160,50 @@ eek_gtk_keyboard_real_size_allocate (GtkWidget     *self,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void depress(EekGtkKeyboard *self,
 | 
			
		||||
                    gdouble x, gdouble y, guint32 time)
 | 
			
		||||
{
 | 
			
		||||
    EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (self);
 | 
			
		||||
    struct squeek_view *view = level_keyboard_current(priv->keyboard);
 | 
			
		||||
    struct squeek_button *button = eek_renderer_find_button_by_position (priv->renderer, view, x, y);
 | 
			
		||||
 | 
			
		||||
    if (button) {
 | 
			
		||||
        eek_keyboard_press_button(priv->keyboard, button, time);
 | 
			
		||||
        on_button_pressed(button, view, self);
 | 
			
		||||
                    gdouble x, gdouble y, guint32 time) {
 | 
			
		||||
    EekGtkKeyboardPrivate *priv = EEK_GTK_KEYBOARD_GET_PRIVATE(self);
 | 
			
		||||
    EekKey *key = eek_renderer_find_key_by_position (priv->renderer, x, y);
 | 
			
		||||
    if (key) {
 | 
			
		||||
        eek_keyboard_press_key(priv->keyboard, key, time);
 | 
			
		||||
        on_key_pressed(key, self);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void drag(EekGtkKeyboard *self,
 | 
			
		||||
                 gdouble x, gdouble y, guint32 time) {
 | 
			
		||||
    EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (self);
 | 
			
		||||
    struct squeek_view *view = level_keyboard_current(priv->keyboard);
 | 
			
		||||
    struct squeek_button *button = eek_renderer_find_button_by_position (priv->renderer, view, x, y);
 | 
			
		||||
    GList *list, *head;
 | 
			
		||||
    EekGtkKeyboardPrivate *priv = EEK_GTK_KEYBOARD_GET_PRIVATE(self);
 | 
			
		||||
    EekKey *key = eek_renderer_find_key_by_position (priv->renderer, x, y);
 | 
			
		||||
 | 
			
		||||
    list = g_list_copy(priv->keyboard->pressed_buttons);
 | 
			
		||||
 | 
			
		||||
    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)) {
 | 
			
		||||
            if (head->data == button) {
 | 
			
		||||
            if (head->data == key)
 | 
			
		||||
                found = TRUE;
 | 
			
		||||
            } else {
 | 
			
		||||
                eek_keyboard_release_button(priv->keyboard, head->data, time);
 | 
			
		||||
                on_button_released(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_button(priv->keyboard, 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)) {
 | 
			
		||||
            eek_keyboard_release_button(priv->keyboard, head->data, time);
 | 
			
		||||
            on_button_released(head->data, view, self);
 | 
			
		||||
        }
 | 
			
		||||
        g_list_free (list);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void release(EekGtkKeyboard *self, guint32 time) {
 | 
			
		||||
    EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (self);
 | 
			
		||||
    EekGtkKeyboardPrivate *priv = EEK_GTK_KEYBOARD_GET_PRIVATE(self);
 | 
			
		||||
 | 
			
		||||
    struct squeek_view *view = level_keyboard_current(priv->keyboard);
 | 
			
		||||
 | 
			
		||||
    GList *list = g_list_copy(priv->keyboard->pressed_buttons);
 | 
			
		||||
    GList *list = eek_keyboard_get_pressed_keys (priv->keyboard);
 | 
			
		||||
    for (GList *head = list; head; head = g_list_next (head)) {
 | 
			
		||||
        struct squeek_button *button = head->data;
 | 
			
		||||
        eek_keyboard_release_button(priv->keyboard, button, time);
 | 
			
		||||
        on_button_released(button, view, self);
 | 
			
		||||
        EekKey *key = EEK_KEY(head->data);
 | 
			
		||||
        eek_keyboard_release_key(priv->keyboard, key, time);
 | 
			
		||||
        on_key_released(key, self);
 | 
			
		||||
    }
 | 
			
		||||
    g_list_free (list);
 | 
			
		||||
}
 | 
			
		||||
@ -248,23 +242,20 @@ eek_gtk_keyboard_real_motion_notify_event (GtkWidget      *self,
 | 
			
		||||
 | 
			
		||||
// Only one touch stream at a time allowed. Others will be completely ignored.
 | 
			
		||||
static gboolean
 | 
			
		||||
handle_touch_event (GtkWidget     *widget,
 | 
			
		||||
                    GdkEventTouch *event)
 | 
			
		||||
{
 | 
			
		||||
    EekGtkKeyboard        *self = EEK_GTK_KEYBOARD (widget);
 | 
			
		||||
    EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (self);
 | 
			
		||||
 | 
			
		||||
handle_touch_event (GtkWidget      *widget,
 | 
			
		||||
                    GdkEventTouch *event) {
 | 
			
		||||
    EekGtkKeyboard *self = EEK_GTK_KEYBOARD(widget);
 | 
			
		||||
    if (event->type == GDK_TOUCH_BEGIN) {
 | 
			
		||||
        if (priv->sequence) {
 | 
			
		||||
        if (self->sequence) {
 | 
			
		||||
            // Ignore second and following touch points
 | 
			
		||||
            return FALSE;
 | 
			
		||||
        }
 | 
			
		||||
        priv->sequence = event->sequence;
 | 
			
		||||
        self->sequence = event->sequence;
 | 
			
		||||
        depress(self, event->x, event->y, event->time);
 | 
			
		||||
        return TRUE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (priv->sequence != event->sequence) {
 | 
			
		||||
    if (self->sequence != event->sequence) {
 | 
			
		||||
        return FALSE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -274,16 +265,16 @@ handle_touch_event (GtkWidget     *widget,
 | 
			
		||||
    if (event->type == GDK_TOUCH_END || event->type == GDK_TOUCH_CANCEL) {
 | 
			
		||||
        // TODO: can the event have different coords than the previous update event?
 | 
			
		||||
        release(self, event->time);
 | 
			
		||||
        priv->sequence = NULL;
 | 
			
		||||
        self->sequence = NULL;
 | 
			
		||||
    }
 | 
			
		||||
    return TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
eek_gtk_keyboard_real_unmap (GtkWidget *self)
 | 
			
		||||
{
 | 
			
		||||
    EekGtkKeyboardPrivate *priv =
 | 
			
		||||
	    eek_gtk_keyboard_get_instance_private (EEK_GTK_KEYBOARD (self));
 | 
			
		||||
    EekGtkKeyboardPrivate *priv = EEK_GTK_KEYBOARD_GET_PRIVATE(self);
 | 
			
		||||
 | 
			
		||||
    if (priv->keyboard) {
 | 
			
		||||
        GList *list, *head;
 | 
			
		||||
@ -292,7 +283,7 @@ eek_gtk_keyboard_real_unmap (GtkWidget *self)
 | 
			
		||||
           elements, so that the default handler of
 | 
			
		||||
           EekKeyboard::key-released signal can remove elements from its
 | 
			
		||||
           internal copy */
 | 
			
		||||
        list = g_list_copy(priv->keyboard->pressed_buttons);
 | 
			
		||||
        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");
 | 
			
		||||
@ -310,17 +301,15 @@ eek_gtk_keyboard_real_query_tooltip (GtkWidget  *widget,
 | 
			
		||||
                                     gboolean    keyboard_tooltip,
 | 
			
		||||
                                     GtkTooltip *tooltip)
 | 
			
		||||
{
 | 
			
		||||
    EekGtkKeyboard        *self = EEK_GTK_KEYBOARD (widget);
 | 
			
		||||
    EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (self);
 | 
			
		||||
    struct squeek_view *view = level_keyboard_current(priv->keyboard);
 | 
			
		||||
    EekGtkKeyboardPrivate *priv = EEK_GTK_KEYBOARD_GET_PRIVATE(widget);
 | 
			
		||||
    EekKey *key;
 | 
			
		||||
 | 
			
		||||
    struct squeek_button *button = eek_renderer_find_button_by_position (priv->renderer,
 | 
			
		||||
                                                     view,
 | 
			
		||||
                                                     (gdouble)x,
 | 
			
		||||
                                                     (gdouble)y);
 | 
			
		||||
    if (button) {
 | 
			
		||||
        //struct squeek_symbol *symbol = eek_key_get_symbol_at_index(key, 0, priv->keyboard->level);
 | 
			
		||||
        const gchar *text = NULL; // FIXME
 | 
			
		||||
    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;
 | 
			
		||||
@ -329,13 +318,37 @@ eek_gtk_keyboard_real_query_tooltip (GtkWidget  *widget,
 | 
			
		||||
    return FALSE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
eek_gtk_keyboard_set_keyboard (EekGtkKeyboard *self,
 | 
			
		||||
                               EekKeyboard    *keyboard)
 | 
			
		||||
{
 | 
			
		||||
    EekGtkKeyboardPrivate *priv = EEK_GTK_KEYBOARD_GET_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;
 | 
			
		||||
@ -345,8 +358,7 @@ eek_gtk_keyboard_set_property (GObject      *object,
 | 
			
		||||
static void
 | 
			
		||||
eek_gtk_keyboard_dispose (GObject *object)
 | 
			
		||||
{
 | 
			
		||||
    EekGtkKeyboard        *self = EEK_GTK_KEYBOARD (object);
 | 
			
		||||
    EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (self);
 | 
			
		||||
    EekGtkKeyboardPrivate *priv = EEK_GTK_KEYBOARD_GET_PRIVATE(object);
 | 
			
		||||
 | 
			
		||||
    if (priv->renderer) {
 | 
			
		||||
        g_object_unref (priv->renderer);
 | 
			
		||||
@ -354,18 +366,37 @@ eek_gtk_keyboard_dispose (GObject *object)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (priv->keyboard) {
 | 
			
		||||
        if (g_signal_handler_is_connected (priv->keyboard,
 | 
			
		||||
                                           priv->key_locked_handler))
 | 
			
		||||
            g_signal_handler_disconnect (priv->keyboard,
 | 
			
		||||
                                         priv->key_locked_handler);
 | 
			
		||||
        if (g_signal_handler_is_connected (priv->keyboard,
 | 
			
		||||
                                           priv->key_unlocked_handler))
 | 
			
		||||
            g_signal_handler_disconnect (priv->keyboard,
 | 
			
		||||
                                         priv->key_unlocked_handler);
 | 
			
		||||
        if (g_signal_handler_is_connected (priv->keyboard,
 | 
			
		||||
                                           priv->symbol_index_changed_handler))
 | 
			
		||||
            g_signal_handler_disconnect (priv->keyboard,
 | 
			
		||||
                                         priv->symbol_index_changed_handler);
 | 
			
		||||
 | 
			
		||||
        GList *list, *head;
 | 
			
		||||
 | 
			
		||||
        list = g_list_copy(priv->keyboard->pressed_buttons);
 | 
			
		||||
        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", level_keyboard_current(priv->keyboard));
 | 
			
		||||
            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);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -374,6 +405,10 @@ eek_gtk_keyboard_class_init (EekGtkKeyboardClass *klass)
 | 
			
		||||
{
 | 
			
		||||
    GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
 | 
			
		||||
    GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
 | 
			
		||||
    GParamSpec *pspec;
 | 
			
		||||
 | 
			
		||||
    g_type_class_add_private (gobject_class,
 | 
			
		||||
                              sizeof (EekGtkKeyboardPrivate));
 | 
			
		||||
 | 
			
		||||
    widget_class->realize = eek_gtk_keyboard_real_realize;
 | 
			
		||||
    widget_class->unmap = eek_gtk_keyboard_real_unmap;
 | 
			
		||||
@ -391,25 +426,21 @@ eek_gtk_keyboard_class_init (EekGtkKeyboardClass *klass)
 | 
			
		||||
 | 
			
		||||
    gobject_class->set_property = eek_gtk_keyboard_set_property;
 | 
			
		||||
    gobject_class->dispose = eek_gtk_keyboard_dispose;
 | 
			
		||||
 | 
			
		||||
    pspec = g_param_spec_object ("keyboard",
 | 
			
		||||
                                 "Keyboard",
 | 
			
		||||
                                 "Keyboard",
 | 
			
		||||
                                 EEK_TYPE_KEYBOARD,
 | 
			
		||||
                                 G_PARAM_CONSTRUCT_ONLY | G_PARAM_WRITABLE);
 | 
			
		||||
    g_object_class_install_property (gobject_class,
 | 
			
		||||
                                     PROP_KEYBOARD,
 | 
			
		||||
                                     pspec);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
eek_gtk_keyboard_init (EekGtkKeyboard *self)
 | 
			
		||||
{
 | 
			
		||||
    EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (self);
 | 
			
		||||
 | 
			
		||||
    /* Create a default CSS provider and load a style sheet */
 | 
			
		||||
    priv->css_provider = gtk_css_provider_new ();
 | 
			
		||||
    gtk_css_provider_load_from_resource (priv->css_provider,
 | 
			
		||||
        "/sm/puri/squeekboard/style.css");
 | 
			
		||||
 | 
			
		||||
    /* Apply the style to the widget */
 | 
			
		||||
    priv->scontext = gtk_widget_get_style_context (GTK_WIDGET(self));
 | 
			
		||||
    gtk_style_context_add_class (priv->scontext, "keyboard");
 | 
			
		||||
    gtk_style_context_add_provider (priv->scontext,
 | 
			
		||||
        GTK_STYLE_PROVIDER(priv->css_provider),
 | 
			
		||||
        GTK_STYLE_PROVIDER_PRIORITY_USER);
 | 
			
		||||
    gtk_style_context_set_state (priv->scontext, GTK_STATE_FLAG_NORMAL);
 | 
			
		||||
    self->priv = EEK_GTK_KEYBOARD_GET_PRIVATE(self);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@ -420,93 +451,121 @@ 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);
 | 
			
		||||
 | 
			
		||||
    eek_renderer_render_button (priv->renderer, cr, place, 1.0, TRUE);
 | 
			
		||||
/*
 | 
			
		||||
    gtk_widget_get_allocation (self, &allocation);
 | 
			
		||||
 | 
			
		||||
    large_bounds->width = bounds->width * scale;
 | 
			
		||||
    large_bounds->height = bounds->height * scale;
 | 
			
		||||
 | 
			
		||||
    x = bounds->x - (large_bounds->width - bounds->width) / 2;
 | 
			
		||||
    y = bounds->y - large_bounds->height;
 | 
			
		||||
 | 
			
		||||
    large_bounds->x = CLAMP(x, 0, allocation.width - large_bounds->width);
 | 
			
		||||
    large_bounds->y = CLAMP(y, 0, allocation.height - large_bounds->height);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
render_pressed_key (GtkWidget *widget,
 | 
			
		||||
                    EekKey    *key)
 | 
			
		||||
{
 | 
			
		||||
    EekGtkKeyboardPrivate *priv = EEK_GTK_KEYBOARD_GET_PRIVATE(widget);
 | 
			
		||||
    EekBounds bounds, large_bounds;
 | 
			
		||||
 | 
			
		||||
    eek_renderer_get_key_bounds (priv->renderer, key, &bounds, TRUE);
 | 
			
		||||
    magnify_bounds (widget, &bounds, &large_bounds, 1.5);
 | 
			
		||||
 | 
			
		||||
    GdkWindow *window = GDK_DRAWABLE (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);
 | 
			
		||||
    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);
 | 
			
		||||
*/
 | 
			
		||||
    gdk_window_end_draw_frame (window, context);
 | 
			
		||||
    cairo_restore (cr);
 | 
			
		||||
 | 
			
		||||
    cairo_region_destroy (region);
 | 
			
		||||
    gdk_window_end_draw_frame(window, context);
 | 
			
		||||
    cairo_region_destroy(region);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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);
 | 
			
		||||
    EekGtkKeyboardPrivate *priv = EEK_GTK_KEYBOARD_GET_PRIVATE(widget);
 | 
			
		||||
    EekBounds bounds;
 | 
			
		||||
    cairo_t *cr;
 | 
			
		||||
 | 
			
		||||
    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);
 | 
			
		||||
    cr = gdk_cairo_create (GDK_DRAWABLE (gtk_widget_get_window (widget)));
 | 
			
		||||
 | 
			
		||||
    eek_renderer_render_button (priv->renderer, cr, place, 1.0, TRUE);
 | 
			
		||||
    eek_renderer_get_key_bounds (priv->renderer, key, &bounds, TRUE);
 | 
			
		||||
    cairo_translate (cr, bounds.x, bounds.y);
 | 
			
		||||
    eek_renderer_render_key (priv->renderer, cr, key, 1.0, TRUE);
 | 
			
		||||
 | 
			
		||||
    gdk_window_end_draw_frame (window, context);
 | 
			
		||||
 | 
			
		||||
    cairo_region_destroy (region);
 | 
			
		||||
    cairo_destroy (cr);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
render_released_button (GtkWidget *widget,
 | 
			
		||||
                        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);
 | 
			
		||||
    EekGtkKeyboardPrivate *priv = EEK_GTK_KEYBOARD_GET_PRIVATE(widget);
 | 
			
		||||
    EekBounds bounds, large_bounds;
 | 
			
		||||
    cairo_t *cr;
 | 
			
		||||
 | 
			
		||||
    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);
 | 
			
		||||
    cr = gdk_cairo_create (GDK_DRAWABLE (gtk_widget_get_window (widget)));
 | 
			
		||||
 | 
			
		||||
    eek_renderer_get_key_bounds (priv->renderer, key, &bounds, TRUE);
 | 
			
		||||
    magnify_bounds (widget, &bounds, &large_bounds, 2.0);
 | 
			
		||||
    cairo_rectangle (cr,
 | 
			
		||||
                     large_bounds.x,
 | 
			
		||||
                     large_bounds.y,
 | 
			
		||||
                     large_bounds.width,
 | 
			
		||||
                     large_bounds.height);
 | 
			
		||||
    cairo_rectangle (cr,
 | 
			
		||||
                     bounds.x,
 | 
			
		||||
                     bounds.y,
 | 
			
		||||
                     bounds.width,
 | 
			
		||||
                     bounds.height);
 | 
			
		||||
    cairo_clip (cr);
 | 
			
		||||
 | 
			
		||||
    eek_renderer_render_keyboard (priv->renderer, cr);
 | 
			
		||||
 | 
			
		||||
    gdk_window_end_draw_frame (window, context);
 | 
			
		||||
 | 
			
		||||
    cairo_region_destroy (region);
 | 
			
		||||
    cairo_destroy (cr);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
on_button_pressed (struct squeek_button *button,
 | 
			
		||||
                struct squeek_view *view,
 | 
			
		||||
on_key_pressed (EekKey      *key,
 | 
			
		||||
                EekGtkKeyboard *self)
 | 
			
		||||
{
 | 
			
		||||
    EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (self);
 | 
			
		||||
    EekGtkKeyboardPrivate *priv = EEK_GTK_KEYBOARD_GET_PRIVATE(self);
 | 
			
		||||
 | 
			
		||||
    /* renderer may have not been set yet if the widget is a popup */
 | 
			
		||||
    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,
 | 
			
		||||
@ -518,19 +577,16 @@ on_button_pressed (struct squeek_button *button,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
on_button_released (struct squeek_button *button,
 | 
			
		||||
                 struct squeek_view *view,
 | 
			
		||||
on_key_released (EekKey      *key,
 | 
			
		||||
                 EekGtkKeyboard *self)
 | 
			
		||||
{
 | 
			
		||||
    (void)view;
 | 
			
		||||
    EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (self);
 | 
			
		||||
    EekGtkKeyboardPrivate *priv = EEK_GTK_KEYBOARD_GET_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,
 | 
			
		||||
@ -540,3 +596,57 @@ on_button_released (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_PRIVATE(widget);
 | 
			
		||||
 | 
			
		||||
    /* 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_PRIVATE(widget);
 | 
			
		||||
 | 
			
		||||
    /* 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)
 | 
			
		||||
{
 | 
			
		||||
    EekGtkKeyboardPrivate *priv;
 | 
			
		||||
 | 
			
		||||
    g_return_if_fail (EEK_IS_GTK_KEYBOARD(keyboard));
 | 
			
		||||
    g_return_if_fail (EEK_IS_THEME(theme));
 | 
			
		||||
 | 
			
		||||
    priv = EEK_GTK_KEYBOARD_GET_PRIVATE(keyboard);
 | 
			
		||||
    priv->theme = g_object_ref (theme);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -32,7 +32,25 @@
 | 
			
		||||
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
#define EEK_TYPE_GTK_KEYBOARD (eek_gtk_keyboard_get_type())
 | 
			
		||||
G_DECLARE_DERIVABLE_TYPE (EekGtkKeyboard, eek_gtk_keyboard, EEK, GTK_KEYBOARD, GtkDrawingArea)
 | 
			
		||||
#define EEK_GTK_KEYBOARD(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EEK_TYPE_GTK_KEYBOARD, EekGtkKeyboard))
 | 
			
		||||
#define EEK_GTK_KEYBOARD_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EEK_TYPE_GTK_KEYBOARD, EekGtkKeyboardClass))
 | 
			
		||||
#define EEK_IS_GTK_KEYBOARD(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EEK_TYPE_GTK_KEYBOARD))
 | 
			
		||||
#define EEK_IS_GTK_KEYBOARD_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EEK_TYPE_GTK_KEYBOARD))
 | 
			
		||||
#define EEK_GTK_KEYBOARD_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EEK_TYPE_GTK_KEYBOARD, EekGtkKeyboardClass))
 | 
			
		||||
 | 
			
		||||
typedef struct _EekGtkKeyboard EekGtkKeyboard;
 | 
			
		||||
typedef struct _EekGtkKeyboardClass EekGtkKeyboardClass;
 | 
			
		||||
typedef struct _EekGtkKeyboardPrivate EekGtkKeyboardPrivate;
 | 
			
		||||
 | 
			
		||||
struct _EekGtkKeyboard
 | 
			
		||||
{
 | 
			
		||||
    /*< private >*/
 | 
			
		||||
    GtkDrawingArea parent;
 | 
			
		||||
 | 
			
		||||
    GdkEventSequence *sequence; // unowned reference
 | 
			
		||||
 | 
			
		||||
    EekGtkKeyboardPrivate *priv;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct _EekGtkKeyboardClass
 | 
			
		||||
{
 | 
			
		||||
@ -45,7 +63,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 */
 | 
			
		||||
							
								
								
									
										589
									
								
								eek/eek-key.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										589
									
								
								eek/eek-key.c
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,589 @@
 | 
			
		||||
/* 
 | 
			
		||||
 * 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, };
 | 
			
		||||
 | 
			
		||||
G_DEFINE_TYPE (EekKey, eek_key, EEK_TYPE_ELEMENT);
 | 
			
		||||
 | 
			
		||||
#define EEK_KEY_GET_PRIVATE(obj)                                  \
 | 
			
		||||
    (G_TYPE_INSTANCE_GET_PRIVATE ((obj), EEK_TYPE_KEY, EekKeyPrivate))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
struct _EekKeyPrivate
 | 
			
		||||
{
 | 
			
		||||
    guint keycode;
 | 
			
		||||
    EekSymbolMatrix *symbol_matrix;
 | 
			
		||||
    gint column;
 | 
			
		||||
    gint row;
 | 
			
		||||
    gulong oref; // UI outline reference
 | 
			
		||||
    gboolean is_pressed;
 | 
			
		||||
    gboolean is_locked;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
eek_key_real_locked (EekKey *self)
 | 
			
		||||
{
 | 
			
		||||
    EekKeyPrivate *priv = EEK_KEY_GET_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_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)
 | 
			
		||||
{
 | 
			
		||||
    EekKeyPrivate *priv = EEK_KEY_GET_PRIVATE(object);
 | 
			
		||||
    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;
 | 
			
		||||
 | 
			
		||||
    g_type_class_add_private (gobject_class,
 | 
			
		||||
                              sizeof (EekKeyPrivate));
 | 
			
		||||
 | 
			
		||||
    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;
 | 
			
		||||
 | 
			
		||||
    priv = self->priv = EEK_KEY_GET_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));
 | 
			
		||||
    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);
 | 
			
		||||
    return key->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));
 | 
			
		||||
 | 
			
		||||
    eek_symbol_matrix_free (key->priv->symbol_matrix);
 | 
			
		||||
    key->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);
 | 
			
		||||
    return key->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_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);
 | 
			
		||||
 | 
			
		||||
    if (key->priv->column != column) {
 | 
			
		||||
        key->priv->column = column;
 | 
			
		||||
        g_object_notify (G_OBJECT(key), "column");
 | 
			
		||||
    }
 | 
			
		||||
    if (key->priv->row != row) {
 | 
			
		||||
        key->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);
 | 
			
		||||
 | 
			
		||||
    if (column != NULL)
 | 
			
		||||
        *column = key->priv->column;
 | 
			
		||||
    if (row != NULL)
 | 
			
		||||
        *row = key->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));
 | 
			
		||||
    if (key->priv->oref != oref) {
 | 
			
		||||
        key->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);
 | 
			
		||||
    return key->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);
 | 
			
		||||
    return key->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);
 | 
			
		||||
    return key->priv->is_locked;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void eek_key_set_pressed(EekKey *key, gboolean value)
 | 
			
		||||
{
 | 
			
		||||
    g_return_if_fail (EEK_IS_KEY(key));
 | 
			
		||||
    key->priv->is_pressed = value;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										117
									
								
								eek/eek-key.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										117
									
								
								eek/eek-key.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,117 @@
 | 
			
		||||
/* 
 | 
			
		||||
 * 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())
 | 
			
		||||
#define EEK_KEY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EEK_TYPE_KEY, EekKey))
 | 
			
		||||
#define EEK_KEY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EEK_TYPE_KEY, EekKeyClass))
 | 
			
		||||
#define EEK_IS_KEY(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EEK_TYPE_KEY))
 | 
			
		||||
#define EEK_IS_KEY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EEK_TYPE_KEY))
 | 
			
		||||
#define EEK_KEY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EEK_TYPE_KEY, EekKeyClass))
 | 
			
		||||
 | 
			
		||||
typedef struct _EekKeyClass EekKeyClass;
 | 
			
		||||
typedef struct _EekKeyPrivate EekKeyPrivate;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * EekKey:
 | 
			
		||||
 *
 | 
			
		||||
 * Contains information about the state of a key.
 | 
			
		||||
 * TODO: rewrite as a plain struct
 | 
			
		||||
 *
 | 
			
		||||
 * The #EekKey structure contains only private data and should only be
 | 
			
		||||
 * accessed using the provided API.
 | 
			
		||||
 */
 | 
			
		||||
struct _EekKey
 | 
			
		||||
{
 | 
			
		||||
    /*< private >*/
 | 
			
		||||
    EekElement parent;
 | 
			
		||||
 | 
			
		||||
    EekKeyPrivate *priv;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * EekKeyClass:
 | 
			
		||||
 * @pressed: class handler for #EekKey::pressed signal
 | 
			
		||||
 * @released: class handler for #EekKey::released signal
 | 
			
		||||
 * @locked: class handler for #EekKey::locked signal
 | 
			
		||||
 * @unlocked: class handler for #EekKey::unlocked signal
 | 
			
		||||
 * @cancelled: class handler for #EekKey::cancelled signal
 | 
			
		||||
 * @is_pressed: virtual function for getting whether the key is pressed
 | 
			
		||||
 * @is_locked: virtual function for getting whether the key is locked
 | 
			
		||||
 */
 | 
			
		||||
struct _EekKeyClass
 | 
			
		||||
{
 | 
			
		||||
    /*< private >*/
 | 
			
		||||
    EekElementClass parent_class;
 | 
			
		||||
 | 
			
		||||
    /*< public >*/
 | 
			
		||||
    /* signals */
 | 
			
		||||
    void (* locked)    (EekKey *key);
 | 
			
		||||
    void (* unlocked)  (EekKey *key);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
GType            eek_key_get_type            (void) G_GNUC_CONST;
 | 
			
		||||
 | 
			
		||||
void             eek_key_set_keycode         (EekKey          *key,
 | 
			
		||||
                                              guint            keycode);
 | 
			
		||||
guint            eek_key_get_keycode         (EekKey          *key);
 | 
			
		||||
void             eek_key_set_symbol_matrix   (EekKey          *key,
 | 
			
		||||
                                              EekSymbolMatrix *matrix);
 | 
			
		||||
EekSymbolMatrix *eek_key_get_symbol_matrix   (EekKey          *key);
 | 
			
		||||
EekSymbol       *eek_key_get_symbol          (EekKey          *key);
 | 
			
		||||
EekSymbol       *eek_key_get_symbol_with_fallback
 | 
			
		||||
                                             (EekKey          *key,
 | 
			
		||||
                                              gint             fallback_group,
 | 
			
		||||
                                              gint             fallback_level);
 | 
			
		||||
EekSymbol       *eek_key_get_symbol_at_index (EekKey          *key,
 | 
			
		||||
                                              gint             group,
 | 
			
		||||
                                              gint             level,
 | 
			
		||||
                                              gint             fallback_group,
 | 
			
		||||
                                              gint             fallback_level);
 | 
			
		||||
 | 
			
		||||
void             eek_key_set_index           (EekKey          *key,
 | 
			
		||||
                                              gint             column,
 | 
			
		||||
                                              gint             row);
 | 
			
		||||
void             eek_key_get_index           (EekKey          *key,
 | 
			
		||||
                                              gint            *column,
 | 
			
		||||
                                              gint            *row);
 | 
			
		||||
 | 
			
		||||
void             eek_key_set_oref            (EekKey          *key,
 | 
			
		||||
                                              guint            oref);
 | 
			
		||||
guint            eek_key_get_oref            (EekKey          *key);
 | 
			
		||||
 | 
			
		||||
gboolean         eek_key_is_pressed          (EekKey          *key);
 | 
			
		||||
gboolean         eek_key_is_locked           (EekKey          *key);
 | 
			
		||||
void             eek_key_set_pressed         (EekKey          *key,
 | 
			
		||||
                                              gboolean         value);
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
#endif  /* EEK_KEY_H */
 | 
			
		||||
@ -17,7 +17,9 @@
 | 
			
		||||
 * Boston, MA 02111-1307, USA.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_CONFIG_H
 | 
			
		||||
#include "config.h"
 | 
			
		||||
#endif  /* HAVE_CONFIG_H */
 | 
			
		||||
 | 
			
		||||
#include <math.h>
 | 
			
		||||
#include <pango/pangocairo.h>
 | 
			
		||||
 | 
			
		||||
@ -1,17 +1,17 @@
 | 
			
		||||
/*
 | 
			
		||||
/* 
 | 
			
		||||
 * Copyright (C) 2010-2011 Daiki Ueno <ueno@unixuser.org>
 | 
			
		||||
 * Copyright (C) 2010-2011 Red Hat, Inc.
 | 
			
		||||
 *
 | 
			
		||||
 * 
 | 
			
		||||
 * This library is free software; you can redistribute it and/or
 | 
			
		||||
 * modify it under the terms of the GNU Lesser General Public License
 | 
			
		||||
 * as published by the Free Software Foundation; either version 2 of
 | 
			
		||||
 * the License, or (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * 
 | 
			
		||||
 * This library is distributed in the hope that it will be useful, but
 | 
			
		||||
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
			
		||||
 * Lesser General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * 
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General Public
 | 
			
		||||
 * License along with this library; if not, write to the Free Software
 | 
			
		||||
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 | 
			
		||||
@ -27,16 +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"
 | 
			
		||||
#include "src/symbol.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)
 | 
			
		||||
@ -47,162 +87,543 @@ eek_modifier_key_copy (EekModifierKey *modkey)
 | 
			
		||||
void
 | 
			
		||||
eek_modifier_key_free (EekModifierKey *modkey)
 | 
			
		||||
{
 | 
			
		||||
    g_object_unref (modkey->key);
 | 
			
		||||
    g_slice_free (EekModifierKey, modkey);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Updates the state of locked keys based on the key that was activated
 | 
			
		||||
/// FIXME: make independent of what the key are named,
 | 
			
		||||
/// and instead refer to the contained symbols
 | 
			
		||||
static guint
 | 
			
		||||
set_key_states (LevelKeyboard    *keyboard,
 | 
			
		||||
                struct squeek_button *button,
 | 
			
		||||
                guint new_level)
 | 
			
		||||
{
 | 
			
		||||
    struct squeek_key *key = squeek_button_get_key(button);
 | 
			
		||||
    // Keys locking rules hardcoded for the time being...
 | 
			
		||||
    const gchar *name = squeek_symbol_get_name(squeek_key_get_symbol(key));
 | 
			
		||||
    // Lock the shift whenever it's pressed on the baselevel
 | 
			
		||||
    // TODO: need to lock shift on the destination level
 | 
			
		||||
    if (g_strcmp0(name, "Shift_L") == 0 && keyboard->level == 0) {
 | 
			
		||||
        EekModifierKey *modifier_key = g_slice_new (EekModifierKey);
 | 
			
		||||
        modifier_key->modifiers = 0;
 | 
			
		||||
        modifier_key->button = button;
 | 
			
		||||
        keyboard->locked_buttons =
 | 
			
		||||
            g_list_prepend (keyboard->locked_buttons, modifier_key);
 | 
			
		||||
        squeek_key_set_locked(key, true);
 | 
			
		||||
    }
 | 
			
		||||
    if (keyboard->level == 1) {
 | 
			
		||||
        // Only shift is locked in this state, unlock on any key press
 | 
			
		||||
        for (GList *head = keyboard->locked_buttons; head; ) {
 | 
			
		||||
            EekModifierKey *modifier_key = head->data;
 | 
			
		||||
            GList *next = g_list_next (head);
 | 
			
		||||
            keyboard->locked_buttons =
 | 
			
		||||
                g_list_remove_link (keyboard->locked_buttons, head);
 | 
			
		||||
            squeek_key_set_locked(squeek_button_get_key(modifier_key->button), false);
 | 
			
		||||
            g_list_free1 (head);
 | 
			
		||||
            head = next;
 | 
			
		||||
        }
 | 
			
		||||
        return 0;
 | 
			
		||||
    }
 | 
			
		||||
    return new_level;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// FIXME: unhardcode, parse some user information as to which key triggers which view (level)
 | 
			
		||||
static void
 | 
			
		||||
set_level_from_press (LevelKeyboard *keyboard, struct squeek_button *button)
 | 
			
		||||
on_key_locked (EekSection  *section,
 | 
			
		||||
                EekKey      *key,
 | 
			
		||||
                EekKeyboard *keyboard)
 | 
			
		||||
{
 | 
			
		||||
    /* The levels are: 0 Letters, 1 Upper case letters, 2 Numbers, 3 Symbols */
 | 
			
		||||
    guint level = keyboard->level;
 | 
			
		||||
    /* Handle non-emitting keys */
 | 
			
		||||
    if (button) {
 | 
			
		||||
        const gchar *name = squeek_symbol_get_name(squeek_key_get_symbol(squeek_button_get_key(button)));
 | 
			
		||||
        if (g_strcmp0(name, "show_numbers") == 0) {
 | 
			
		||||
            level = 2;
 | 
			
		||||
        } else if (g_strcmp0(name, "show_letters") == 0) {
 | 
			
		||||
            level = 0;
 | 
			
		||||
        } else if (g_strcmp0(name, "show_symbols") == 0) {
 | 
			
		||||
            level = 3;
 | 
			
		||||
        } else if (g_strcmp0(name, "Shift_L") == 0) {
 | 
			
		||||
            level ^= 1;
 | 
			
		||||
    g_signal_emit (keyboard, signals[KEY_LOCKED], 0, key);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
on_key_unlocked (EekSection  *section,
 | 
			
		||||
                 EekKey      *key,
 | 
			
		||||
                 EekKeyboard *keyboard)
 | 
			
		||||
{
 | 
			
		||||
    g_signal_emit (keyboard, signals[KEY_UNLOCKED], 0, key);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
on_symbol_index_changed (EekSection *section,
 | 
			
		||||
                         gint group,
 | 
			
		||||
                         gint level,
 | 
			
		||||
                         EekKeyboard *keyboard)
 | 
			
		||||
{
 | 
			
		||||
    g_signal_emit_by_name (keyboard, "symbol-index-changed", group, level);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
section_child_added_cb (EekContainer *container,
 | 
			
		||||
                        EekElement   *element,
 | 
			
		||||
                        EekKeyboard  *keyboard)
 | 
			
		||||
{
 | 
			
		||||
    guint keycode = eek_key_get_keycode (EEK_KEY(element));
 | 
			
		||||
    g_hash_table_insert (keyboard->priv->keycodes,
 | 
			
		||||
                         GUINT_TO_POINTER(keycode),
 | 
			
		||||
                         element);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
section_child_removed_cb (EekContainer *container,
 | 
			
		||||
                          EekElement   *element,
 | 
			
		||||
                          EekKeyboard  *keyboard)
 | 
			
		||||
{
 | 
			
		||||
    guint keycode = eek_key_get_keycode (EEK_KEY(element));
 | 
			
		||||
    g_hash_table_remove (keyboard->priv->keycodes,
 | 
			
		||||
                         GUINT_TO_POINTER(keycode));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static EekSection *
 | 
			
		||||
eek_keyboard_real_create_section (EekKeyboard *self)
 | 
			
		||||
{
 | 
			
		||||
    EekSection *section;
 | 
			
		||||
 | 
			
		||||
    section = g_object_new (EEK_TYPE_SECTION, NULL);
 | 
			
		||||
    g_return_val_if_fail (section, NULL);
 | 
			
		||||
 | 
			
		||||
    g_signal_connect (G_OBJECT(section), "child-added",
 | 
			
		||||
                      G_CALLBACK(section_child_added_cb), self);
 | 
			
		||||
 | 
			
		||||
    g_signal_connect (G_OBJECT(section), "child-removed",
 | 
			
		||||
                      G_CALLBACK(section_child_removed_cb), self);
 | 
			
		||||
 | 
			
		||||
    EEK_CONTAINER_GET_CLASS(self)->add_child (EEK_CONTAINER(self),
 | 
			
		||||
                                              EEK_ELEMENT(section));
 | 
			
		||||
    return section;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
eek_keyboard_set_property (GObject      *object,
 | 
			
		||||
                           guint         prop_id,
 | 
			
		||||
                           const GValue *value,
 | 
			
		||||
                           GParamSpec   *pspec)
 | 
			
		||||
{
 | 
			
		||||
    EekKeyboardPrivate *priv = EEK_KEYBOARD_GET_PRIVATE(object);
 | 
			
		||||
 | 
			
		||||
    switch (prop_id) {
 | 
			
		||||
    case PROP_LAYOUT:
 | 
			
		||||
        priv->layout = g_value_get_object (value);
 | 
			
		||||
        if (priv->layout)
 | 
			
		||||
            g_object_ref (priv->layout);
 | 
			
		||||
        break;
 | 
			
		||||
    case PROP_MODIFIER_BEHAVIOR:
 | 
			
		||||
        eek_keyboard_set_modifier_behavior (EEK_KEYBOARD(object),
 | 
			
		||||
                                            g_value_get_enum (value));
 | 
			
		||||
        break;
 | 
			
		||||
    default:
 | 
			
		||||
        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
eek_keyboard_get_property (GObject    *object,
 | 
			
		||||
                           guint       prop_id,
 | 
			
		||||
                           GValue     *value,
 | 
			
		||||
                           GParamSpec *pspec)
 | 
			
		||||
{
 | 
			
		||||
    EekKeyboardPrivate *priv = EEK_KEYBOARD_GET_PRIVATE(object);
 | 
			
		||||
 | 
			
		||||
    switch (prop_id) {
 | 
			
		||||
    case PROP_LAYOUT:
 | 
			
		||||
        g_value_set_object (value, priv->layout);
 | 
			
		||||
        break;
 | 
			
		||||
    case PROP_MODIFIER_BEHAVIOR:
 | 
			
		||||
        g_value_set_enum (value,
 | 
			
		||||
                          eek_keyboard_get_modifier_behavior (EEK_KEYBOARD(object)));
 | 
			
		||||
        break;
 | 
			
		||||
    default:
 | 
			
		||||
        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    keyboard->level = set_key_states(keyboard, button, level);
 | 
			
		||||
 | 
			
		||||
    eek_layout_update_layout(keyboard);
 | 
			
		||||
    priv->modifiers = modifiers;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void eek_keyboard_press_button(LevelKeyboard *keyboard, struct squeek_button *button, guint32 timestamp) {
 | 
			
		||||
    struct squeek_key *key = squeek_button_get_key(button);
 | 
			
		||||
    squeek_key_set_pressed(key, TRUE);
 | 
			
		||||
    keyboard->pressed_buttons = g_list_prepend (keyboard->pressed_buttons, button);
 | 
			
		||||
void eek_keyboard_press_key(EekKeyboard *keyboard, EekKey *key, guint32 timestamp) {
 | 
			
		||||
    EekKeyboardPrivate *priv = EEK_KEYBOARD_GET_PRIVATE(keyboard);
 | 
			
		||||
 | 
			
		||||
    struct squeek_symbol *symbol = squeek_key_get_symbol(key);
 | 
			
		||||
    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;
 | 
			
		||||
 | 
			
		||||
    // Only take action about setting level *after* the key has taken effect, i.e. on release
 | 
			
		||||
    //set_level_from_press (keyboard, key);
 | 
			
		||||
    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_button(LevelKeyboard *keyboard,
 | 
			
		||||
                              struct squeek_button *button,
 | 
			
		||||
void eek_keyboard_release_key( EekKeyboard *keyboard,
 | 
			
		||||
                               EekKey      *key,
 | 
			
		||||
                               guint32      timestamp) {
 | 
			
		||||
    for (GList *head = keyboard->pressed_buttons; head; head = g_list_next (head)) {
 | 
			
		||||
        if (head->data == button) {
 | 
			
		||||
            keyboard->pressed_buttons = g_list_remove_link (keyboard->pressed_buttons, head);
 | 
			
		||||
    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;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    struct squeek_symbol *symbol = squeek_button_get_symbol(button);
 | 
			
		||||
    EekSymbol *symbol = eek_key_get_symbol_with_fallback (key, 0, 0);
 | 
			
		||||
    if (!symbol)
 | 
			
		||||
        return;
 | 
			
		||||
 | 
			
		||||
    set_level_from_press (keyboard, button);
 | 
			
		||||
    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 (squeek_button_get_key(button));
 | 
			
		||||
    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) {
 | 
			
		||||
    g_hash_table_destroy (self->names);
 | 
			
		||||
    for (guint i = 0; i < self->outline_array->len; i++) {
 | 
			
		||||
        EekOutline *outline = &g_array_index (self->outline_array,
 | 
			
		||||
static void
 | 
			
		||||
eek_keyboard_dispose (GObject *object)
 | 
			
		||||
{
 | 
			
		||||
    EekKeyboardPrivate *priv = EEK_KEYBOARD_GET_PRIVATE(object);
 | 
			
		||||
 | 
			
		||||
    if (priv->layout) {
 | 
			
		||||
        g_object_unref (priv->layout);
 | 
			
		||||
        priv->layout = NULL;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    G_OBJECT_CLASS (eek_keyboard_parent_class)->dispose (object);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
eek_keyboard_finalize (GObject *object)
 | 
			
		||||
{
 | 
			
		||||
    EekKeyboardPrivate *priv = EEK_KEYBOARD_GET_PRIVATE(object);
 | 
			
		||||
    guint i;
 | 
			
		||||
 | 
			
		||||
    g_list_free (priv->pressed_keys);
 | 
			
		||||
    g_list_free_full (priv->locked_keys,
 | 
			
		||||
                      (GDestroyNotify) eek_modifier_key_free);
 | 
			
		||||
 | 
			
		||||
    g_hash_table_destroy (priv->keycodes);
 | 
			
		||||
 | 
			
		||||
    for (i = 0; i < priv->outline_array->len; i++) {
 | 
			
		||||
        EekOutline *outline = &g_array_index (priv->outline_array,
 | 
			
		||||
                                              EekOutline,
 | 
			
		||||
                                              i);
 | 
			
		||||
        g_slice_free1 (sizeof (EekPoint) * outline->num_points,
 | 
			
		||||
                       outline->points);
 | 
			
		||||
    }
 | 
			
		||||
    g_array_free (self->outline_array, TRUE);
 | 
			
		||||
    for (guint i = 0; i < 4; i++) {
 | 
			
		||||
        // free self->view[i];
 | 
			
		||||
    }
 | 
			
		||||
    g_array_free (priv->outline_array, TRUE);
 | 
			
		||||
        
 | 
			
		||||
    G_OBJECT_CLASS (eek_keyboard_parent_class)->finalize (object);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void level_keyboard_free(LevelKeyboard *self) {
 | 
			
		||||
    level_keyboard_deinit(self);
 | 
			
		||||
    g_free(self);
 | 
			
		||||
static void
 | 
			
		||||
eek_keyboard_real_child_added (EekContainer *self,
 | 
			
		||||
                               EekElement   *element)
 | 
			
		||||
{
 | 
			
		||||
    g_signal_connect (element, "key-locked",
 | 
			
		||||
                      G_CALLBACK(on_key_locked), self);
 | 
			
		||||
    g_signal_connect (element, "key-unlocked",
 | 
			
		||||
                      G_CALLBACK(on_key_unlocked), self);
 | 
			
		||||
    g_signal_connect (element, "symbol-index-changed",
 | 
			
		||||
                      G_CALLBACK(on_symbol_index_changed), self);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void level_keyboard_init(LevelKeyboard *self) {
 | 
			
		||||
    self->outline_array = g_array_new (FALSE, TRUE, sizeof (EekOutline));
 | 
			
		||||
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);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
LevelKeyboard *level_keyboard_new(EekboardContextService *manager, struct squeek_view *views[4], GHashTable *name_button_hash) {
 | 
			
		||||
    LevelKeyboard *keyboard = g_new0(LevelKeyboard, 1);
 | 
			
		||||
    level_keyboard_init(keyboard);
 | 
			
		||||
    for (uint i = 0; i < 4; i++) {
 | 
			
		||||
        keyboard->views[i] = views[i];
 | 
			
		||||
    }
 | 
			
		||||
    keyboard->manager = manager;
 | 
			
		||||
    keyboard->names = name_button_hash;
 | 
			
		||||
    return keyboard;
 | 
			
		||||
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_find_key_by_name:
 | 
			
		||||
 * eek_keyboard_create_section:
 | 
			
		||||
 * @keyboard: an #EekKeyboard
 | 
			
		||||
 * @name: a key name
 | 
			
		||||
 *
 | 
			
		||||
 * Find an #EekKey whose name is @name.
 | 
			
		||||
 * Return value: (transfer none): #EekKey whose name is @name
 | 
			
		||||
 * Create an #EekSection instance and append it to @keyboard.  This
 | 
			
		||||
 * function is rarely called by application but called by #EekLayout
 | 
			
		||||
 * implementation.
 | 
			
		||||
 */
 | 
			
		||||
struct squeek_button*
 | 
			
		||||
eek_keyboard_find_button_by_name (LevelKeyboard *keyboard,
 | 
			
		||||
                               const gchar *name)
 | 
			
		||||
EekSection *
 | 
			
		||||
eek_keyboard_create_section (EekKeyboard *keyboard)
 | 
			
		||||
{
 | 
			
		||||
    return g_hash_table_lookup (keyboard->names, name);
 | 
			
		||||
    g_return_val_if_fail (EEK_IS_KEYBOARD(keyboard), NULL);
 | 
			
		||||
    return EEK_KEYBOARD_GET_CLASS(keyboard)->create_section (keyboard);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eek_keyboard_find_key_by_keycode:
 | 
			
		||||
 * @keyboard: an #EekKeyboard
 | 
			
		||||
 * @keycode: a keycode
 | 
			
		||||
 *
 | 
			
		||||
 * Find an #EekKey whose keycode is @keycode.
 | 
			
		||||
 * Return value: (transfer none): #EekKey whose keycode is @keycode
 | 
			
		||||
 */
 | 
			
		||||
EekKey *
 | 
			
		||||
eek_keyboard_find_key_by_keycode (EekKeyboard *keyboard,
 | 
			
		||||
                                  guint        keycode)
 | 
			
		||||
{
 | 
			
		||||
    g_return_val_if_fail (EEK_IS_KEYBOARD(keyboard), NULL);
 | 
			
		||||
    return g_hash_table_lookup (keyboard->priv->keycodes,
 | 
			
		||||
                                GUINT_TO_POINTER(keycode));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eek_keyboard_get_layout:
 | 
			
		||||
 * @keyboard: an #EekKeyboard
 | 
			
		||||
 *
 | 
			
		||||
 * Get the layout used to create @keyboard.
 | 
			
		||||
 * Returns: an #EekLayout
 | 
			
		||||
 */
 | 
			
		||||
EekLayout *
 | 
			
		||||
eek_keyboard_get_layout (EekKeyboard *keyboard)
 | 
			
		||||
{
 | 
			
		||||
    g_return_val_if_fail (EEK_IS_KEYBOARD(keyboard), NULL);
 | 
			
		||||
    return keyboard->priv->layout;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eek_keyboard_get_size:
 | 
			
		||||
 * @keyboard: an #EekKeyboard
 | 
			
		||||
 * @width: width of @keyboard
 | 
			
		||||
 * @height: height of @keyboard
 | 
			
		||||
 *
 | 
			
		||||
 * Get the size of @keyboard.
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
eek_keyboard_get_size (EekKeyboard *keyboard,
 | 
			
		||||
                       gdouble     *width,
 | 
			
		||||
                       gdouble     *height)
 | 
			
		||||
{
 | 
			
		||||
    EekBounds bounds;
 | 
			
		||||
 | 
			
		||||
    eek_element_get_bounds (EEK_ELEMENT(keyboard), &bounds);
 | 
			
		||||
    *width = bounds.width;
 | 
			
		||||
    *height = bounds.height;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eek_keyboard_set_modifier_behavior:
 | 
			
		||||
 * @keyboard: an #EekKeyboard
 | 
			
		||||
 * @modifier_behavior: modifier behavior of @keyboard
 | 
			
		||||
 *
 | 
			
		||||
 * Set the modifier handling mode of @keyboard.
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
eek_keyboard_set_modifier_behavior (EekKeyboard        *keyboard,
 | 
			
		||||
                                    EekModifierBehavior modifier_behavior)
 | 
			
		||||
{
 | 
			
		||||
    g_return_if_fail (EEK_IS_KEYBOARD(keyboard));
 | 
			
		||||
    keyboard->priv->modifier_behavior = modifier_behavior;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eek_keyboard_get_modifier_behavior:
 | 
			
		||||
 * @keyboard: an #EekKeyboard
 | 
			
		||||
 *
 | 
			
		||||
 * Get the modifier handling mode of @keyboard.
 | 
			
		||||
 * Returns: #EekModifierBehavior
 | 
			
		||||
 */
 | 
			
		||||
EekModifierBehavior
 | 
			
		||||
eek_keyboard_get_modifier_behavior (EekKeyboard *keyboard)
 | 
			
		||||
{
 | 
			
		||||
    g_return_val_if_fail (EEK_IS_KEYBOARD(keyboard), 0);
 | 
			
		||||
    return keyboard->priv->modifier_behavior;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
eek_keyboard_set_modifiers (EekKeyboard    *keyboard,
 | 
			
		||||
                            EekModifierType modifiers)
 | 
			
		||||
{
 | 
			
		||||
    g_return_if_fail (EEK_IS_KEYBOARD(keyboard));
 | 
			
		||||
    keyboard->priv->modifiers = modifiers;
 | 
			
		||||
    set_level_from_modifiers (keyboard);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * 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;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@ -214,76 +635,115 @@ eek_keyboard_find_button_by_name (LevelKeyboard *keyboard,
 | 
			
		||||
 * Returns: an #EekOutline, which should not be released
 | 
			
		||||
 */
 | 
			
		||||
EekOutline *
 | 
			
		||||
level_keyboard_get_outline (LevelKeyboard *keyboard,
 | 
			
		||||
eek_keyboard_get_outline (EekKeyboard *keyboard,
 | 
			
		||||
                          guint        oref)
 | 
			
		||||
{
 | 
			
		||||
    if (oref > keyboard->outline_array->len)
 | 
			
		||||
    g_return_val_if_fail (EEK_IS_KEYBOARD(keyboard), NULL);
 | 
			
		||||
 | 
			
		||||
    if (oref > keyboard->priv->outline_array->len)
 | 
			
		||||
        return NULL;
 | 
			
		||||
 | 
			
		||||
    return &g_array_index (keyboard->outline_array, EekOutline, oref);
 | 
			
		||||
    return &g_array_index (keyboard->priv->outline_array, EekOutline, oref);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eek_keyboard_get_keymap:
 | 
			
		||||
 * eek_keyboard_get_n_outlines:
 | 
			
		||||
 * @keyboard: an #EekKeyboard
 | 
			
		||||
 *
 | 
			
		||||
 * Get the keymap for the keyboard.
 | 
			
		||||
 * Returns: a string containing the XKB keymap.
 | 
			
		||||
 * Get the number of outlines defined in @keyboard.
 | 
			
		||||
 * Returns: integer
 | 
			
		||||
 */
 | 
			
		||||
gchar *
 | 
			
		||||
eek_keyboard_get_keymap(LevelKeyboard *keyboard)
 | 
			
		||||
gsize
 | 
			
		||||
eek_keyboard_get_n_outlines (EekKeyboard *keyboard)
 | 
			
		||||
{
 | 
			
		||||
    /* Start the keycodes and symbols sections with their respective headers. */
 | 
			
		||||
    gchar *keycodes = g_strdup(keymap_keycodes_header);
 | 
			
		||||
    gchar *symbols = g_strdup(keymap_symbols_header);
 | 
			
		||||
 | 
			
		||||
    /* Iterate over the keys in the name-to-key hash table. */
 | 
			
		||||
    GHashTableIter iter;
 | 
			
		||||
    gchar *button_name;
 | 
			
		||||
    gpointer button_ptr;
 | 
			
		||||
    g_hash_table_iter_init(&iter, keyboard->names);
 | 
			
		||||
 | 
			
		||||
    while (g_hash_table_iter_next(&iter, (gpointer)&button_name, &button_ptr)) {
 | 
			
		||||
 | 
			
		||||
        gchar *current, *line;
 | 
			
		||||
        struct squeek_button *button = button_ptr;
 | 
			
		||||
        struct squeek_key *key = squeek_button_get_key(button);
 | 
			
		||||
        guint keycode = squeek_key_get_keycode(key);
 | 
			
		||||
 | 
			
		||||
        /* Don't include invalid keycodes in the keymap. */
 | 
			
		||||
        if (keycode == EEK_INVALID_KEYCODE)
 | 
			
		||||
            continue;
 | 
			
		||||
 | 
			
		||||
        /* Append a key name-to-keycode definition to the keycodes section. */
 | 
			
		||||
        current = keycodes;
 | 
			
		||||
        line = g_strdup_printf("        <%s> = %i;\n", (char *)button_name, keycode);
 | 
			
		||||
 | 
			
		||||
        keycodes = g_strconcat(current, line, NULL);
 | 
			
		||||
        g_free(line);
 | 
			
		||||
        g_free(current);
 | 
			
		||||
 | 
			
		||||
        // FIXME: free
 | 
			
		||||
        const char *key_str = squeek_key_to_keymap_entry(
 | 
			
		||||
            (char*)button_name,
 | 
			
		||||
            key
 | 
			
		||||
        );
 | 
			
		||||
        current = symbols;
 | 
			
		||||
        symbols = g_strconcat(current, key_str, NULL);
 | 
			
		||||
        g_free(current);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* Assemble the keymap file from the header, sections and footer. */
 | 
			
		||||
    gchar *keymap = g_strconcat(keymap_header,
 | 
			
		||||
                                keycodes, "    };\n\n",
 | 
			
		||||
                                symbols, "    };\n\n",
 | 
			
		||||
                                keymap_footer, NULL);
 | 
			
		||||
 | 
			
		||||
    g_free(keycodes);
 | 
			
		||||
    g_free(symbols);
 | 
			
		||||
    return keymap;
 | 
			
		||||
    g_return_val_if_fail (EEK_IS_KEYBOARD(keyboard), 0);
 | 
			
		||||
    return keyboard->priv->outline_array->len;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
struct squeek_view *level_keyboard_current(LevelKeyboard *keyboard)
 | 
			
		||||
/**
 | 
			
		||||
 * 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)
 | 
			
		||||
{
 | 
			
		||||
    return keyboard->views[keyboard->level];
 | 
			
		||||
    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,67 +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_button *button;
 | 
			
		||||
};
 | 
			
		||||
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_view *views[4];
 | 
			
		||||
    guint level;
 | 
			
		||||
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
 | 
			
		||||
    GArray *outline_array;
 | 
			
		||||
 | 
			
		||||
    GList *pressed_buttons; // struct squeek_button*
 | 
			
		||||
    GList *locked_buttons; // struct squeek_button*
 | 
			
		||||
 | 
			
		||||
    /* Map button names to button objects: */
 | 
			
		||||
    GHashTable *names;
 | 
			
		||||
 | 
			
		||||
    guint id; // as a key to layout choices
 | 
			
		||||
 | 
			
		||||
    EekboardContextService *manager; // unowned reference
 | 
			
		||||
};
 | 
			
		||||
typedef struct _LevelKeyboard LevelKeyboard;
 | 
			
		||||
 | 
			
		||||
struct squeek_button *eek_keyboard_find_button_by_name(LevelKeyboard *keyboard,
 | 
			
		||||
                                      const gchar        *name);
 | 
			
		||||
/**
 | 
			
		||||
 * 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;
 | 
			
		||||
 | 
			
		||||
/// Represents the path to the button within a view
 | 
			
		||||
struct button_place {
 | 
			
		||||
    const struct squeek_row *row;
 | 
			
		||||
    const struct squeek_button *button;
 | 
			
		||||
    /* 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];
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
EekOutline         *level_keyboard_get_outline
 | 
			
		||||
                                     (LevelKeyboard        *keyboard,
 | 
			
		||||
/**
 | 
			
		||||
 * 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_button(LevelKeyboard *keyboard, struct squeek_button *button, guint32 timestamp);
 | 
			
		||||
void eek_keyboard_release_button(LevelKeyboard *keyboard, struct squeek_button *button, guint32 timestamp);
 | 
			
		||||
 | 
			
		||||
gchar *             eek_keyboard_get_keymap
 | 
			
		||||
                                     (LevelKeyboard *keyboard);
 | 
			
		||||
 | 
			
		||||
struct squeek_view *level_keyboard_current(LevelKeyboard *keyboard);
 | 
			
		||||
LevelKeyboard *level_keyboard_new(EekboardContextService *manager, struct squeek_view *views[], GHashTable *name_button_hash);
 | 
			
		||||
void level_keyboard_deinit(LevelKeyboard *self);
 | 
			
		||||
void level_keyboard_free(LevelKeyboard *self);
 | 
			
		||||
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 */
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										297
									
								
								eek/eek-keysym.c
									
									
									
									
									
								
							
							
						
						
									
										297
									
								
								eek/eek-keysym.c
									
									
									
									
									
								
							@ -23,9 +23,15 @@
 | 
			
		||||
 * @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
 | 
			
		||||
@ -44,22 +50,301 @@
 | 
			
		||||
#define EEK_KEYSYM_Hyper_L 0xffed
 | 
			
		||||
#define EEK_KEYSYM_Hyper_R 0xffee
 | 
			
		||||
 | 
			
		||||
struct _EekKeysymPrivate {
 | 
			
		||||
    guint xkeysym;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
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"
 | 
			
		||||
 | 
			
		||||
guint32
 | 
			
		||||
eek_keysym_from_name (const gchar *name)
 | 
			
		||||
static void eek_serializable_iface_init (EekSerializableIface *iface);
 | 
			
		||||
 | 
			
		||||
G_DEFINE_TYPE_WITH_CODE (EekKeysym, eek_keysym, EEK_TYPE_SYMBOL,
 | 
			
		||||
                         G_IMPLEMENT_INTERFACE (EEK_TYPE_SERIALIZABLE,
 | 
			
		||||
                                                eek_serializable_iface_init));
 | 
			
		||||
 | 
			
		||||
#define EEK_KEYSYM_GET_PRIVATE(obj)                                  \
 | 
			
		||||
    (G_TYPE_INSTANCE_GET_PRIVATE ((obj), EEK_TYPE_KEYSYM, EekKeysymPrivate))
 | 
			
		||||
 | 
			
		||||
static EekSerializableIface *eek_keysym_parent_serializable_iface;
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
eek_keysym_real_serialize (EekSerializable *self,
 | 
			
		||||
                           GVariantBuilder *builder)
 | 
			
		||||
{
 | 
			
		||||
    for (uint i = 0; i < G_N_ELEMENTS(xkeysym_keysym_entries); i++) {
 | 
			
		||||
        if (g_strcmp0 (xkeysym_keysym_entries[i].name, name) == 0) {
 | 
			
		||||
            return xkeysym_keysym_entries[i].xkeysym;
 | 
			
		||||
        }
 | 
			
		||||
    EekKeysymPrivate *priv = EEK_KEYSYM_GET_PRIVATE(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_PRIVATE(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)
 | 
			
		||||
{
 | 
			
		||||
    GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
 | 
			
		||||
 | 
			
		||||
    g_type_class_add_private (gobject_class, sizeof (EekKeysymPrivate));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
eek_keysym_init (EekKeysym *self)
 | 
			
		||||
{
 | 
			
		||||
    self->priv = EEK_KEYSYM_GET_PRIVATE(self);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * 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_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_PRIVATE(keysym);
 | 
			
		||||
    return priv->xkeysym;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -25,8 +25,54 @@
 | 
			
		||||
#ifndef EEK_KEYSYM_H
 | 
			
		||||
#define EEK_KEYSYM_H 1
 | 
			
		||||
 | 
			
		||||
#include "glib.h"
 | 
			
		||||
#include <X11/XKBlib.h>
 | 
			
		||||
#include "eek-symbol.h"
 | 
			
		||||
 | 
			
		||||
guint32    eek_keysym_from_name         (const gchar    *name);
 | 
			
		||||
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())
 | 
			
		||||
#define EEK_KEYSYM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EEK_TYPE_KEYSYM, EekKeysym))
 | 
			
		||||
#define EEK_KEYSYM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EEK_TYPE_KEYSYM, EekKeysymClass))
 | 
			
		||||
#define EEK_IS_KEYSYM(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EEK_TYPE_KEYSYM))
 | 
			
		||||
#define EEK_IS_KEYSYM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EEK_TYPE_KEYSYM))
 | 
			
		||||
#define EEK_KEYSYM_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EEK_TYPE_KEYSYM, EekKeysymClass))
 | 
			
		||||
 | 
			
		||||
typedef struct _EekKeysymClass EekKeysymClass;
 | 
			
		||||
typedef struct _EekKeysymPrivate EekKeysymPrivate;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * EekKeysym:
 | 
			
		||||
 *
 | 
			
		||||
 * The #EekKeysym structure contains only private data and should only
 | 
			
		||||
 * be accessed using the provided API.
 | 
			
		||||
 */
 | 
			
		||||
struct _EekKeysym {
 | 
			
		||||
    /*< private >*/
 | 
			
		||||
    EekSymbol parent;
 | 
			
		||||
 | 
			
		||||
    EekKeysymPrivate *priv;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
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,14 +26,15 @@
 | 
			
		||||
 * 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)
 | 
			
		||||
G_DEFINE_ABSTRACT_TYPE (EekLayout, eek_layout, G_TYPE_OBJECT);
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
eek_layout_class_init (EekLayoutClass *klass)
 | 
			
		||||
@ -46,8 +47,25 @@ eek_layout_init (EekLayout *self)
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
eek_layout_update_layout(LevelKeyboard *keyboard)
 | 
			
		||||
/**
 | 
			
		||||
 * 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)
 | 
			
		||||
{
 | 
			
		||||
    squeek_view_place_contents(level_keyboard_current(keyboard), keyboard);
 | 
			
		||||
    g_assert (EEK_IS_LAYOUT(layout));
 | 
			
		||||
    g_assert (EEK_LAYOUT_GET_CLASS(layout)->create_keyboard);
 | 
			
		||||
 | 
			
		||||
    return EEK_LAYOUT_GET_CLASS(layout)->create_keyboard (manager,
 | 
			
		||||
                                                          layout,
 | 
			
		||||
                                                          initial_width,
 | 
			
		||||
                                                          initial_height);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -27,12 +27,24 @@
 | 
			
		||||
 | 
			
		||||
#include <glib-object.h>
 | 
			
		||||
#include "eek-types.h"
 | 
			
		||||
#include "src/layout.h"
 | 
			
		||||
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
#define EEK_TYPE_LAYOUT (eek_layout_get_type())
 | 
			
		||||
G_DECLARE_DERIVABLE_TYPE (EekLayout, eek_layout, EEK, LAYOUT, GObject)
 | 
			
		||||
#define EEK_LAYOUT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EEK_TYPE_LAYOUT, EekLayout))
 | 
			
		||||
#define EEK_LAYOUT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EEK_TYPE_LAYOUT, EekLayoutClass))
 | 
			
		||||
#define EEK_IS_LAYOUT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EEK_TYPE_LAYOUT))
 | 
			
		||||
#define EEK_IS_LAYOUT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EEK_TYPE_LAYOUT))
 | 
			
		||||
#define EEK_LAYOUT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EEK_TYPE_LAYOUT, EekLayoutClass))
 | 
			
		||||
 | 
			
		||||
typedef struct _EekLayoutClass EekLayoutClass;
 | 
			
		||||
typedef struct _EekLayout EekLayout;
 | 
			
		||||
 | 
			
		||||
struct _EekLayout
 | 
			
		||||
{
 | 
			
		||||
    /*< private >*/
 | 
			
		||||
    GObject parent;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * EekLayoutClass:
 | 
			
		||||
@ -44,7 +56,7 @@ struct _EekLayoutClass
 | 
			
		||||
    GObjectClass parent_class;
 | 
			
		||||
 | 
			
		||||
    /*< public >*/
 | 
			
		||||
    LevelKeyboard* (* create_keyboard) (EekboardContextService *manager,
 | 
			
		||||
    EekKeyboard* (* create_keyboard) (EekboardContextService *manager,
 | 
			
		||||
                                      EekLayout *self,
 | 
			
		||||
                                      gdouble    initial_width,
 | 
			
		||||
                                      gdouble    initial_height);
 | 
			
		||||
@ -56,14 +68,5 @@ struct _EekLayoutClass
 | 
			
		||||
 | 
			
		||||
GType        eek_layout_get_type  (void) G_GNUC_CONST;
 | 
			
		||||
 | 
			
		||||
void         eek_layout_place_rows(LevelKeyboard *keyboard, struct squeek_view *level);
 | 
			
		||||
 | 
			
		||||
void         eek_layout_update_layout(LevelKeyboard *keyboard);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
LevelKeyboard *
 | 
			
		||||
level_keyboard_from_layout (EekLayout *layout,
 | 
			
		||||
                  gdouble    initial_width,
 | 
			
		||||
                  gdouble    initial_height);
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
#endif  /* EEK_LAYOUT_H */
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										1
									
								
								eek/eek-marshalers.list
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								eek/eek-marshalers.list
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1 @@
 | 
			
		||||
VOID:INT,INT
 | 
			
		||||
							
								
								
									
										1216
									
								
								eek/eek-renderer.c
									
									
									
									
									
								
							
							
						
						
									
										1216
									
								
								eek/eek-renderer.c
									
									
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@ -21,24 +21,49 @@
 | 
			
		||||
#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
 | 
			
		||||
 | 
			
		||||
#define EEK_TYPE_RENDERER (eek_renderer_get_type())
 | 
			
		||||
G_DECLARE_DERIVABLE_TYPE (EekRenderer, eek_renderer, EEK, RENDERER, GObject)
 | 
			
		||||
#define EEK_RENDERER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EEK_TYPE_RENDERER, EekRenderer))
 | 
			
		||||
#define EEK_RENDERER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EEK_TYPE_RENDERER, EekRendererClass))
 | 
			
		||||
#define EEK_IS_RENDERER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EEK_TYPE_RENDERER))
 | 
			
		||||
#define EEK_IS_RENDERER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EEK_TYPE_RENDERER))
 | 
			
		||||
#define EEK_RENDERER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EEK_TYPE_RENDERER, EekRendererClass))
 | 
			
		||||
 | 
			
		||||
typedef struct _EekRenderer EekRenderer;
 | 
			
		||||
typedef struct _EekRendererClass EekRendererClass;
 | 
			
		||||
typedef struct _EekRendererPrivate EekRendererPrivate;
 | 
			
		||||
 | 
			
		||||
struct _EekRenderer {
 | 
			
		||||
    GObject parent;
 | 
			
		||||
 | 
			
		||||
    EekRendererPrivate *priv;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
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 +72,7 @@ struct _EekRendererClass
 | 
			
		||||
 | 
			
		||||
    cairo_surface_t *(* get_icon_surface)   (EekRenderer *self,
 | 
			
		||||
                                             const gchar *icon_name,
 | 
			
		||||
                                             gint         size,
 | 
			
		||||
                                             gint         scale);
 | 
			
		||||
                                             gint         size);
 | 
			
		||||
 | 
			
		||||
    /*< private >*/
 | 
			
		||||
    /* padding */
 | 
			
		||||
@ -56,9 +80,8 @@ struct _EekRendererClass
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
GType            eek_renderer_get_type         (void) G_GNUC_CONST;
 | 
			
		||||
EekRenderer     *eek_renderer_new              (LevelKeyboard     *keyboard,
 | 
			
		||||
                                                PangoContext    *pcontext,
 | 
			
		||||
                                                GtkStyleContext *scontext);
 | 
			
		||||
EekRenderer     *eek_renderer_new              (EekKeyboard     *keyboard,
 | 
			
		||||
                                                PangoContext    *pcontext);
 | 
			
		||||
void             eek_renderer_set_allocation_size
 | 
			
		||||
                                               (EekRenderer     *renderer,
 | 
			
		||||
                                                gdouble          width,
 | 
			
		||||
@ -66,27 +89,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);
 | 
			
		||||
@ -99,18 +130,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 */
 | 
			
		||||
 | 
			
		||||
@ -1,29 +1,490 @@
 | 
			
		||||
/*
 | 
			
		||||
/* 
 | 
			
		||||
 * 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"
 | 
			
		||||
 | 
			
		||||
EekBounds eek_get_outline_size(LevelKeyboard *keyboard, uint32_t oref) {
 | 
			
		||||
    EekOutline *outline = level_keyboard_get_outline (keyboard, oref);
 | 
			
		||||
enum {
 | 
			
		||||
    PROP_0,
 | 
			
		||||
    PROP_ANGLE,
 | 
			
		||||
    PROP_LAST
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
enum {
 | 
			
		||||
    KEY_LOCKED,
 | 
			
		||||
    KEY_UNLOCKED,
 | 
			
		||||
    LAST_SIGNAL
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static guint signals[LAST_SIGNAL] = { 0, };
 | 
			
		||||
 | 
			
		||||
G_DEFINE_TYPE (EekSection, eek_section, EEK_TYPE_CONTAINER);
 | 
			
		||||
 | 
			
		||||
#define EEK_SECTION_GET_PRIVATE(obj)                           \
 | 
			
		||||
    (G_TYPE_INSTANCE_GET_PRIVATE ((obj), EEK_TYPE_SECTION, EekSectionPrivate))
 | 
			
		||||
 | 
			
		||||
struct _EekRow
 | 
			
		||||
{
 | 
			
		||||
    gint num_columns;
 | 
			
		||||
    EekOrientation orientation;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
typedef struct _EekRow EekRow;
 | 
			
		||||
 | 
			
		||||
struct _EekSectionPrivate
 | 
			
		||||
{
 | 
			
		||||
    gint angle;
 | 
			
		||||
    GSList *rows;
 | 
			
		||||
    EekModifierType modifiers;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static gint
 | 
			
		||||
eek_section_real_get_n_rows (EekSection *self)
 | 
			
		||||
{
 | 
			
		||||
    EekSectionPrivate *priv = EEK_SECTION_GET_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_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_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,
 | 
			
		||||
                             guint        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);
 | 
			
		||||
 | 
			
		||||
    row = g_slist_nth_data (self->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_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_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_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)
 | 
			
		||||
{
 | 
			
		||||
    EekSectionPrivate *priv = EEK_SECTION_GET_PRIVATE(object);
 | 
			
		||||
    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;
 | 
			
		||||
 | 
			
		||||
    g_type_class_add_private (gobject_class, sizeof (EekSectionPrivate));
 | 
			
		||||
 | 
			
		||||
    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)
 | 
			
		||||
{
 | 
			
		||||
    self->priv = EEK_SECTION_GET_PRIVATE (self);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * 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));
 | 
			
		||||
    if (section->priv->angle != angle) {
 | 
			
		||||
        section->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);
 | 
			
		||||
    return section->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;
 | 
			
		||||
@ -43,14 +504,55 @@ EekBounds eek_get_outline_size(LevelKeyboard *keyboard, uint32_t oref) {
 | 
			
		||||
                maxy = p.y;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        EekBounds key_bounds = {
 | 
			
		||||
            .height = maxy - miny,
 | 
			
		||||
            .width = maxx - minx,
 | 
			
		||||
            .x = 0,
 | 
			
		||||
            .y = 0,
 | 
			
		||||
        };
 | 
			
		||||
        return key_bounds;
 | 
			
		||||
        EekBounds key_bounds = {0};
 | 
			
		||||
        eek_element_get_bounds(element, &key_bounds);
 | 
			
		||||
        key_bounds.height = maxy - miny;
 | 
			
		||||
        key_bounds.width = maxx - minx;
 | 
			
		||||
        eek_element_set_bounds(element, &key_bounds);
 | 
			
		||||
    }
 | 
			
		||||
    EekBounds bounds = {0, 0, 0, 0};
 | 
			
		||||
    return 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);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -25,10 +25,109 @@
 | 
			
		||||
#ifndef EEK_SECTION_H
 | 
			
		||||
#define EEK_SECTION_H 1
 | 
			
		||||
 | 
			
		||||
/* Contains row-related functions that couldn't be done in Rust easily. */
 | 
			
		||||
 | 
			
		||||
#include <glib-object.h>
 | 
			
		||||
#include "eek-keyboard.h"
 | 
			
		||||
#include "src/layout.h"
 | 
			
		||||
#include "eek-container.h"
 | 
			
		||||
#include "eek-types.h"
 | 
			
		||||
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
#define EEK_TYPE_SECTION (eek_section_get_type())
 | 
			
		||||
#define EEK_SECTION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EEK_TYPE_SECTION, EekSection))
 | 
			
		||||
#define EEK_SECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EEK_TYPE_SECTION, EekSectionClass))
 | 
			
		||||
#define EEK_IS_SECTION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EEK_TYPE_SECTION))
 | 
			
		||||
#define EEK_IS_SECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EEK_TYPE_SECTION))
 | 
			
		||||
#define EEK_SECTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EEK_TYPE_SECTION, EekSectionClass))
 | 
			
		||||
 | 
			
		||||
typedef struct _EekSectionClass EekSectionClass;
 | 
			
		||||
typedef struct _EekSectionPrivate EekSectionPrivate;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * EekSection:
 | 
			
		||||
 *
 | 
			
		||||
 * The #EekSection structure contains only private data and should
 | 
			
		||||
 * only be accessed using the provided API.
 | 
			
		||||
 */
 | 
			
		||||
struct _EekSection
 | 
			
		||||
{
 | 
			
		||||
    /*< private >*/
 | 
			
		||||
    EekContainer parent;
 | 
			
		||||
 | 
			
		||||
    EekSectionPrivate *priv;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * 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 */
 | 
			
		||||
							
								
								
									
										457
									
								
								eek/eek-symbol.c
									
									
									
									
									
								
							
							
						
						
									
										457
									
								
								eek/eek-symbol.c
									
									
									
									
									
								
							@ -25,18 +25,277 @@
 | 
			
		||||
 * 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
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct _EekSymbolPrivate {
 | 
			
		||||
    gchar *name;
 | 
			
		||||
    gchar *label;
 | 
			
		||||
    EekSymbolCategory category;
 | 
			
		||||
    EekModifierType modifier_mask;
 | 
			
		||||
    gchar *icon_name;
 | 
			
		||||
    gchar *tooltip;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static void eek_serializable_iface_init (EekSerializableIface *iface);
 | 
			
		||||
 | 
			
		||||
G_DEFINE_TYPE_WITH_CODE (EekSymbol, eek_symbol, G_TYPE_OBJECT,
 | 
			
		||||
                         G_IMPLEMENT_INTERFACE (EEK_TYPE_SERIALIZABLE,
 | 
			
		||||
                                                eek_serializable_iface_init));
 | 
			
		||||
 | 
			
		||||
#define EEK_SYMBOL_GET_PRIVATE(obj)                                  \
 | 
			
		||||
    (G_TYPE_INSTANCE_GET_PRIVATE ((obj), EEK_TYPE_SYMBOL, EekSymbolPrivate))
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
eek_symbol_real_serialize (EekSerializable *self,
 | 
			
		||||
                           GVariantBuilder *builder)
 | 
			
		||||
{
 | 
			
		||||
    EekSymbolPrivate *priv = EEK_SYMBOL_GET_PRIVATE(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_PRIVATE(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)
 | 
			
		||||
{
 | 
			
		||||
    EekSymbolPrivate *priv = EEK_SYMBOL_GET_PRIVATE(object);
 | 
			
		||||
 | 
			
		||||
    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;
 | 
			
		||||
 | 
			
		||||
    g_type_class_add_private (gobject_class, sizeof (EekSymbolPrivate));
 | 
			
		||||
 | 
			
		||||
    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;
 | 
			
		||||
 | 
			
		||||
    priv = self->priv = EEK_SYMBOL_GET_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)
 | 
			
		||||
{
 | 
			
		||||
    EekSymbolPrivate *priv;
 | 
			
		||||
 | 
			
		||||
    g_return_if_fail (EEK_IS_SYMBOL(symbol));
 | 
			
		||||
 | 
			
		||||
    priv = EEK_SYMBOL_GET_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)
 | 
			
		||||
{
 | 
			
		||||
    EekSymbolPrivate *priv;
 | 
			
		||||
 | 
			
		||||
    g_return_val_if_fail (EEK_IS_SYMBOL(symbol), NULL);
 | 
			
		||||
 | 
			
		||||
    priv = EEK_SYMBOL_GET_PRIVATE(symbol);
 | 
			
		||||
    if (priv->name == NULL || *priv->name == '\0')
 | 
			
		||||
        return NULL;
 | 
			
		||||
    return priv->name;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@ -50,8 +309,68 @@ void
 | 
			
		||||
eek_symbol_set_label (EekSymbol   *symbol,
 | 
			
		||||
                      const gchar *label)
 | 
			
		||||
{
 | 
			
		||||
    g_free (symbol->label);
 | 
			
		||||
    symbol->label = g_strdup (label);
 | 
			
		||||
    EekSymbolPrivate *priv;
 | 
			
		||||
 | 
			
		||||
    g_return_if_fail (EEK_IS_SYMBOL(symbol));
 | 
			
		||||
 | 
			
		||||
    priv = EEK_SYMBOL_GET_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)
 | 
			
		||||
{
 | 
			
		||||
    EekSymbolPrivate *priv;
 | 
			
		||||
 | 
			
		||||
    g_return_val_if_fail (EEK_IS_SYMBOL(symbol), NULL);
 | 
			
		||||
 | 
			
		||||
    priv = EEK_SYMBOL_GET_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)
 | 
			
		||||
{
 | 
			
		||||
    EekSymbolPrivate *priv;
 | 
			
		||||
 | 
			
		||||
    g_return_if_fail (EEK_IS_SYMBOL(symbol));
 | 
			
		||||
 | 
			
		||||
    priv = EEK_SYMBOL_GET_PRIVATE(symbol);
 | 
			
		||||
    priv->category = category;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eek_symbol_get_category:
 | 
			
		||||
 * @symbol: an #EekSymbol
 | 
			
		||||
 *
 | 
			
		||||
 * Get symbol category of @symbol.
 | 
			
		||||
 */
 | 
			
		||||
EekSymbolCategory
 | 
			
		||||
eek_symbol_get_category (EekSymbol *symbol)
 | 
			
		||||
{
 | 
			
		||||
    EekSymbolPrivate *priv;
 | 
			
		||||
 | 
			
		||||
    g_return_val_if_fail (EEK_IS_SYMBOL(symbol), EEK_SYMBOL_CATEGORY_UNKNOWN);
 | 
			
		||||
 | 
			
		||||
    priv = EEK_SYMBOL_GET_PRIVATE(symbol);
 | 
			
		||||
    return priv->category;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@ -65,7 +384,12 @@ void
 | 
			
		||||
eek_symbol_set_modifier_mask (EekSymbol      *symbol,
 | 
			
		||||
                              EekModifierType mask)
 | 
			
		||||
{
 | 
			
		||||
    symbol->modifier_mask = mask;
 | 
			
		||||
    EekSymbolPrivate *priv;
 | 
			
		||||
 | 
			
		||||
    g_return_if_fail (EEK_IS_SYMBOL(symbol));
 | 
			
		||||
 | 
			
		||||
    priv = EEK_SYMBOL_GET_PRIVATE(symbol);
 | 
			
		||||
    priv->modifier_mask = mask;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@ -77,37 +401,136 @@ eek_symbol_set_modifier_mask (EekSymbol      *symbol,
 | 
			
		||||
EekModifierType
 | 
			
		||||
eek_symbol_get_modifier_mask (EekSymbol *symbol)
 | 
			
		||||
{
 | 
			
		||||
    return 0;
 | 
			
		||||
    return symbol->modifier_mask;
 | 
			
		||||
    EekSymbolPrivate *priv;
 | 
			
		||||
 | 
			
		||||
    g_return_val_if_fail (EEK_IS_SYMBOL(symbol), 0);
 | 
			
		||||
 | 
			
		||||
    priv = EEK_SYMBOL_GET_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);
 | 
			
		||||
    EekSymbolPrivate *priv;
 | 
			
		||||
 | 
			
		||||
    g_return_if_fail (EEK_IS_SYMBOL(symbol));
 | 
			
		||||
 | 
			
		||||
    priv = EEK_SYMBOL_GET_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;
 | 
			
		||||
    EekSymbolPrivate *priv;
 | 
			
		||||
 | 
			
		||||
    g_return_val_if_fail (EEK_IS_SYMBOL(symbol), NULL);
 | 
			
		||||
 | 
			
		||||
    priv = EEK_SYMBOL_GET_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);
 | 
			
		||||
    EekSymbolPrivate *priv;
 | 
			
		||||
 | 
			
		||||
    g_return_if_fail (EEK_IS_SYMBOL(symbol));
 | 
			
		||||
 | 
			
		||||
    priv = EEK_SYMBOL_GET_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')
 | 
			
		||||
    EekSymbolPrivate *priv;
 | 
			
		||||
 | 
			
		||||
    g_return_val_if_fail (EEK_IS_SYMBOL(symbol), NULL);
 | 
			
		||||
 | 
			
		||||
    priv = EEK_SYMBOL_GET_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;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										120
									
								
								eek/eek-symbol.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										120
									
								
								eek/eek-symbol.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,120 @@
 | 
			
		||||
/* 
 | 
			
		||||
 * 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())
 | 
			
		||||
#define EEK_SYMBOL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EEK_TYPE_SYMBOL, EekSymbol))
 | 
			
		||||
#define EEK_SYMBOL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EEK_TYPE_SYMBOL, EekSymbolClass))
 | 
			
		||||
#define EEK_IS_SYMBOL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EEK_TYPE_SYMBOL))
 | 
			
		||||
#define EEK_IS_SYMBOL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EEK_TYPE_SYMBOL))
 | 
			
		||||
#define EEK_SYMBOL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EEK_TYPE_SYMBOL, EekSymbolClass))
 | 
			
		||||
 | 
			
		||||
typedef struct _EekSymbolClass EekSymbolClass;
 | 
			
		||||
typedef struct _EekSymbolPrivate EekSymbolPrivate;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * EekSymbol:
 | 
			
		||||
 *
 | 
			
		||||
 * The #EekSymbol structure contains only private data and should only
 | 
			
		||||
 * be accessed using the provided API.
 | 
			
		||||
 */
 | 
			
		||||
struct _EekSymbol {
 | 
			
		||||
    /*< private >*/
 | 
			
		||||
    GObject parent;
 | 
			
		||||
 | 
			
		||||
    EekSymbolPrivate *priv;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * 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 */
 | 
			
		||||
							
								
								
									
										182
									
								
								eek/eek-text.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										182
									
								
								eek/eek-text.c
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,182 @@
 | 
			
		||||
/* 
 | 
			
		||||
 * 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
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct _EekTextPrivate {
 | 
			
		||||
    gchar *text;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static void eek_serializable_iface_init (EekSerializableIface *iface);
 | 
			
		||||
 | 
			
		||||
G_DEFINE_TYPE_WITH_CODE (EekText, eek_text, EEK_TYPE_SYMBOL,
 | 
			
		||||
                         G_IMPLEMENT_INTERFACE (EEK_TYPE_SERIALIZABLE,
 | 
			
		||||
                                                eek_serializable_iface_init));
 | 
			
		||||
 | 
			
		||||
#define EEK_TEXT_GET_PRIVATE(obj)                                  \
 | 
			
		||||
    (G_TYPE_INSTANCE_GET_PRIVATE ((obj), EEK_TYPE_TEXT, EekTextPrivate))
 | 
			
		||||
 | 
			
		||||
static EekSerializableIface *eek_text_parent_serializable_iface;
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
eek_text_real_serialize (EekSerializable *self,
 | 
			
		||||
                         GVariantBuilder *builder)
 | 
			
		||||
{
 | 
			
		||||
    EekTextPrivate *priv = EEK_TEXT_GET_PRIVATE(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_PRIVATE(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)
 | 
			
		||||
{
 | 
			
		||||
    EekTextPrivate *priv = EEK_TEXT_GET_PRIVATE(object);
 | 
			
		||||
    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)
 | 
			
		||||
{
 | 
			
		||||
    EekTextPrivate *priv = EEK_TEXT_GET_PRIVATE(object);
 | 
			
		||||
    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)
 | 
			
		||||
{
 | 
			
		||||
    EekTextPrivate *priv = EEK_TEXT_GET_PRIVATE(object);
 | 
			
		||||
 | 
			
		||||
    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;
 | 
			
		||||
 | 
			
		||||
    g_type_class_add_private (gobject_class, sizeof (EekTextPrivate));
 | 
			
		||||
 | 
			
		||||
    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)
 | 
			
		||||
{
 | 
			
		||||
    self->priv = EEK_TEXT_GET_PRIVATE(self);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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_PRIVATE(text);
 | 
			
		||||
 | 
			
		||||
    return priv->text;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										66
									
								
								eek/eek-text.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										66
									
								
								eek/eek-text.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,66 @@
 | 
			
		||||
/* 
 | 
			
		||||
 * 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())
 | 
			
		||||
#define EEK_TEXT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EEK_TYPE_TEXT, EekText))
 | 
			
		||||
#define EEK_TEXT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EEK_TYPE_TEXT, EekTextClass))
 | 
			
		||||
#define EEK_IS_TEXT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EEK_TYPE_TEXT))
 | 
			
		||||
#define EEK_IS_TEXT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EEK_TYPE_TEXT))
 | 
			
		||||
#define EEK_TEXT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EEK_TYPE_TEXT, EekTextClass))
 | 
			
		||||
 | 
			
		||||
typedef struct _EekTextClass EekTextClass;
 | 
			
		||||
typedef struct _EekTextPrivate EekTextPrivate;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * EekText:
 | 
			
		||||
 *
 | 
			
		||||
 * The #EekText structure contains only private data and should only
 | 
			
		||||
 * be accessed using the provided API.
 | 
			
		||||
 */
 | 
			
		||||
struct _EekText {
 | 
			
		||||
    /*< private >*/
 | 
			
		||||
    EekSymbol parent;
 | 
			
		||||
 | 
			
		||||
    EekTextPrivate *priv;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
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__ */
 | 
			
		||||
							
								
								
									
										1869
									
								
								eek/eek-theme-node.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1869
									
								
								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@
 | 
			
		||||
							
								
								
									
										682
									
								
								eek/eek-xkb-layout.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										682
									
								
								eek/eek-xkb-layout.c
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,682 @@
 | 
			
		||||
/* 
 | 
			
		||||
 * 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);
 | 
			
		||||
 | 
			
		||||
G_DEFINE_TYPE_WITH_CODE (EekXkbLayout, eek_xkb_layout, EEK_TYPE_LAYOUT,
 | 
			
		||||
                         G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE,
 | 
			
		||||
                                                initable_iface_init));
 | 
			
		||||
 | 
			
		||||
#define EEK_XKB_LAYOUT_GET_PRIVATE(obj)                                  \
 | 
			
		||||
    (G_TYPE_INSTANCE_GET_PRIVATE ((obj), EEK_TYPE_XKB_LAYOUT, EekXkbLayoutPrivate))
 | 
			
		||||
 | 
			
		||||
enum {
 | 
			
		||||
    PROP_0,
 | 
			
		||||
    PROP_DISPLAY,
 | 
			
		||||
    PROP_LAST
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
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;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
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 = layout->priv;
 | 
			
		||||
    return n * priv->scale_numerator / priv->scale_denominator;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
G_INLINE_FUNC gdouble
 | 
			
		||||
xkb_to_pixmap_double (EekXkbLayout *layout,
 | 
			
		||||
                     gdouble       d)
 | 
			
		||||
{
 | 
			
		||||
    EekXkbLayoutPrivate *priv = layout->priv;
 | 
			
		||||
    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 = layout->priv;
 | 
			
		||||
    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;
 | 
			
		||||
    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);
 | 
			
		||||
 | 
			
		||||
    priv = layout->priv;
 | 
			
		||||
    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 = layout->priv;
 | 
			
		||||
    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_PRIVATE (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_PRIVATE (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);
 | 
			
		||||
 | 
			
		||||
    switch (prop_id) {
 | 
			
		||||
    case PROP_DISPLAY:
 | 
			
		||||
        layout->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);
 | 
			
		||||
 | 
			
		||||
    switch (prop_id) {
 | 
			
		||||
    case PROP_DISPLAY:
 | 
			
		||||
        g_value_set_pointer (value, layout->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;
 | 
			
		||||
 | 
			
		||||
    g_type_class_add_private (gobject_class, sizeof (EekXkbLayoutPrivate));
 | 
			
		||||
 | 
			
		||||
    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)
 | 
			
		||||
{
 | 
			
		||||
    self->priv = EEK_XKB_LAYOUT_GET_PRIVATE (self);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
get_names_from_server (EekXkbLayout *layout,
 | 
			
		||||
                       GError      **error)
 | 
			
		||||
{
 | 
			
		||||
    EekXkbLayoutPrivate *priv = layout->priv;
 | 
			
		||||
    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)
 | 
			
		||||
{
 | 
			
		||||
    if (g_strcmp0 (names->keycodes, layout->priv->names.keycodes)) {
 | 
			
		||||
        g_free (layout->priv->names.keycodes);
 | 
			
		||||
        layout->priv->names.keycodes = g_strdup (names->keycodes);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (g_strcmp0 (names->geometry, layout->priv->names.geometry)) {
 | 
			
		||||
        g_free (layout->priv->names.geometry);
 | 
			
		||||
        layout->priv->names.geometry = g_strdup (names->geometry);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (g_strcmp0 (names->symbols, layout->priv->names.symbols)) {
 | 
			
		||||
        g_free (layout->priv->names.symbols);
 | 
			
		||||
        layout->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 = layout->priv;
 | 
			
		||||
 | 
			
		||||
    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 = layout->priv;
 | 
			
		||||
 | 
			
		||||
    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 = layout->priv;
 | 
			
		||||
 | 
			
		||||
    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;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										71
									
								
								eek/eek-xkb-layout.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										71
									
								
								eek/eek-xkb-layout.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,71 @@
 | 
			
		||||
/* 
 | 
			
		||||
 * 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())
 | 
			
		||||
#define EEK_XKB_LAYOUT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EEK_TYPE_XKB_LAYOUT, EekXkbLayout))
 | 
			
		||||
#define EEK_XKB_LAYOUT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EEK_TYPE_XKB_LAYOUT, EekXkbLayoutClass))
 | 
			
		||||
#define EEK_IS_XKB_LAYOUT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EEK_TYPE_XKB_LAYOUT))
 | 
			
		||||
#define EEK_IS_XKB_LAYOUT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EEK_TYPE_XKB_LAYOUT))
 | 
			
		||||
#define EEK_XKB_LAYOUT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EEK_TYPE_XKB_LAYOUT, EekXkbLayoutClass))
 | 
			
		||||
 | 
			
		||||
typedef struct _EekXkbLayout        EekXkbLayout;
 | 
			
		||||
typedef struct _EekXkbLayoutClass   EekXkbLayoutClass;
 | 
			
		||||
typedef struct _EekXkbLayoutPrivate EekXkbLayoutPrivate;
 | 
			
		||||
 | 
			
		||||
struct _EekXkbLayout
 | 
			
		||||
{
 | 
			
		||||
    /*< private >*/
 | 
			
		||||
    EekLayout parent;
 | 
			
		||||
 | 
			
		||||
    EekXkbLayoutPrivate *priv;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
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@
 | 
			
		||||
							
								
								
									
										663
									
								
								eek/eek-xkl-layout.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										663
									
								
								eek/eek-xkl-layout.c
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,663 @@
 | 
			
		||||
/* 
 | 
			
		||||
 * 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);
 | 
			
		||||
 | 
			
		||||
G_DEFINE_TYPE_WITH_CODE (EekXklLayout, eek_xkl_layout, EEK_TYPE_XKB_LAYOUT,
 | 
			
		||||
                         G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE,
 | 
			
		||||
                                                initable_iface_init));
 | 
			
		||||
 | 
			
		||||
#define EEK_XKL_LAYOUT_GET_PRIVATE(obj)                                  \
 | 
			
		||||
    (G_TYPE_INSTANCE_GET_PRIVATE ((obj), EEK_TYPE_XKL_LAYOUT, EekXklLayoutPrivate))
 | 
			
		||||
 | 
			
		||||
enum {
 | 
			
		||||
    PROP_0,
 | 
			
		||||
    PROP_MODEL,
 | 
			
		||||
    PROP_LAYOUTS,
 | 
			
		||||
    PROP_VARIANTS,
 | 
			
		||||
    PROP_OPTIONS,
 | 
			
		||||
    PROP_LAST
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct _EekXklLayoutPrivate
 | 
			
		||||
{
 | 
			
		||||
    XklEngine *engine;
 | 
			
		||||
    XklConfigRec *config;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/* 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_PRIVATE (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;
 | 
			
		||||
 | 
			
		||||
    g_type_class_add_private (gobject_class, sizeof (EekXklLayoutPrivate));
 | 
			
		||||
 | 
			
		||||
    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)
 | 
			
		||||
{
 | 
			
		||||
    self->priv = EEK_XKL_LAYOUT_GET_PRIVATE (self);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * 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_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_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_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_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_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_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_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_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_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 = layout->priv;
 | 
			
		||||
    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);
 | 
			
		||||
    Display *display;
 | 
			
		||||
 | 
			
		||||
    if (!parent_initable_iface->init (initable, cancellable, error))
 | 
			
		||||
        return FALSE;
 | 
			
		||||
 | 
			
		||||
    layout->priv->config = xkl_config_rec_new ();
 | 
			
		||||
 | 
			
		||||
    g_object_get (G_OBJECT (initable),
 | 
			
		||||
                  "display", &display,
 | 
			
		||||
                  NULL);
 | 
			
		||||
 | 
			
		||||
    layout->priv->engine = xkl_engine_get_instance (display);
 | 
			
		||||
 | 
			
		||||
    if (!xkl_config_rec_get_from_server (layout->priv->config,
 | 
			
		||||
                                         layout->priv->engine)) {
 | 
			
		||||
        g_set_error (error,
 | 
			
		||||
                     EEK_ERROR,
 | 
			
		||||
                     EEK_ERROR_LAYOUT_ERROR,
 | 
			
		||||
                     "can't load libxklavier configuration");
 | 
			
		||||
        return FALSE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    set_xkb_component_names (layout, 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;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										97
									
								
								eek/eek-xkl-layout.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										97
									
								
								eek/eek-xkl-layout.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,97 @@
 | 
			
		||||
/* 
 | 
			
		||||
 * 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())
 | 
			
		||||
#define EEK_XKL_LAYOUT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EEK_TYPE_XKL_LAYOUT, EekXklLayout))
 | 
			
		||||
#define EEK_XKL_LAYOUT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EEK_TYPE_XKL_LAYOUT, EekXklLayoutClass))
 | 
			
		||||
#define EEK_IS_XKL_LAYOUT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EEK_TYPE_XKL_LAYOUT))
 | 
			
		||||
#define EEK_IS_XKL_LAYOUT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EEK_TYPE_XKL_LAYOUT))
 | 
			
		||||
#define EEK_XKL_LAYOUT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EEK_TYPE_XKL_LAYOUT, EekXklLayoutClass))
 | 
			
		||||
 | 
			
		||||
typedef struct _EekXklLayout        EekXklLayout;
 | 
			
		||||
typedef struct _EekXklLayoutClass   EekXklLayoutClass;
 | 
			
		||||
typedef struct _EekXklLayoutPrivate EekXklLayoutPrivate;
 | 
			
		||||
 | 
			
		||||
struct _EekXklLayout
 | 
			
		||||
{
 | 
			
		||||
    /*< private >*/
 | 
			
		||||
    EekXkbLayout parent;
 | 
			
		||||
 | 
			
		||||
    EekXklLayoutPrivate *priv;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
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 */
 | 
			
		||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@ -29,7 +29,29 @@
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
#define EEK_TYPE_XML_LAYOUT (eek_xml_layout_get_type())
 | 
			
		||||
G_DECLARE_DERIVABLE_TYPE (EekXmlLayout, eek_xml_layout, EEK, XML_LAYOUT, EekLayout)
 | 
			
		||||
#define EEK_XML_LAYOUT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EEK_TYPE_XML_LAYOUT, EekXmlLayout))
 | 
			
		||||
#define EEK_XML_LAYOUT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EEK_TYPE_XML_LAYOUT, EekXmlLayoutClass))
 | 
			
		||||
#define EEK_IS_XML_LAYOUT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EEK_TYPE_XML_LAYOUT))
 | 
			
		||||
#define EEK_IS_XML_LAYOUT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EEK_TYPE_XML_LAYOUT))
 | 
			
		||||
#define EEK_XML_LAYOUT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EEK_TYPE_XML_LAYOUT, EekXmlLayoutClass))
 | 
			
		||||
 | 
			
		||||
typedef struct _EekXmlLayout        EekXmlLayout;
 | 
			
		||||
typedef struct _EekXmlLayoutClass   EekXmlLayoutClass;
 | 
			
		||||
typedef struct _EekXmlLayoutPrivate EekXmlLayoutPrivate;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * EekXmlLayout:
 | 
			
		||||
 *
 | 
			
		||||
 * The #EekXmlLayout structure contains only private data and should
 | 
			
		||||
 * only be accessed using the provided API.
 | 
			
		||||
 */
 | 
			
		||||
struct _EekXmlLayout
 | 
			
		||||
{
 | 
			
		||||
    /*< private >*/
 | 
			
		||||
    EekLayout parent;
 | 
			
		||||
 | 
			
		||||
    EekXmlLayoutPrivate *priv;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * EekXmlLayoutClass:
 | 
			
		||||
@ -62,8 +84,5 @@ GList              *eek_xml_list_keyboards     (void);
 | 
			
		||||
EekXmlKeyboardDesc *eek_xml_keyboard_desc_copy (EekXmlKeyboardDesc *desc);
 | 
			
		||||
void                eek_xml_keyboard_desc_free (EekXmlKeyboardDesc *desc);
 | 
			
		||||
 | 
			
		||||
LevelKeyboard *
 | 
			
		||||
eek_xml_layout_real_create_keyboard (EekLayout *self,
 | 
			
		||||
                                     EekboardContextService *manager);
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
#endif  /* EEK_XML_LAYOUT_H */
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										317
									
								
								eek/eek-xml.c
									
									
									
									
									
										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"
 | 
			
		||||
 | 
			
		||||
@ -36,5 +38,9 @@
 | 
			
		||||
void
 | 
			
		||||
eek_init (void)
 | 
			
		||||
{
 | 
			
		||||
    /* void */
 | 
			
		||||
    g_type_init ();
 | 
			
		||||
 | 
			
		||||
    g_type_class_ref (EEK_TYPE_SYMBOL);
 | 
			
		||||
    g_type_class_ref (EEK_TYPE_KEYSYM);
 | 
			
		||||
    g_type_class_ref (EEK_TYPE_TEXT);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -23,8 +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);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -33,7 +33,7 @@ else:
 | 
			
		||||
 | 
			
		||||
table = dict()
 | 
			
		||||
for line in in_stream:
 | 
			
		||||
    match = re.match(r'\s*(0x[0-9A-F]+)\s+"(.*)"\s+(\S*)', line, re.I)
 | 
			
		||||
    match = re.match(r'\s*(0x[0-9A-F]+)\s+(\S*)\s+(\S*)', line, re.I)
 | 
			
		||||
    if match:
 | 
			
		||||
        table[int(match.group(1), 16)] = (match.group(2), match.group(3))
 | 
			
		||||
 | 
			
		||||
@ -42,8 +42,8 @@ sys.stdout.write("static const EekKeysymEntry %s[] = {\n" %
 | 
			
		||||
 | 
			
		||||
for index, (keysym, (l, c)) in enumerate([(keysym, table[keysym])
 | 
			
		||||
                                          for keysym in sorted(table.keys())]):
 | 
			
		||||
    sys.stdout.write("    { 0x%X, \"%s\" }" %
 | 
			
		||||
                     (keysym, l))
 | 
			
		||||
    sys.stdout.write("    { 0x%X, %s, %s }" %
 | 
			
		||||
                     (keysym, l, c))
 | 
			
		||||
    if index < len(table) - 1:
 | 
			
		||||
        sys.stdout.write(",")
 | 
			
		||||
    sys.stdout.write("\n")
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										39
									
								
								eek/keymap.h
									
									
									
									
									
								
							
							
						
						
									
										39
									
								
								eek/keymap.h
									
									
									
									
									
								
							@ -1,39 +0,0 @@
 | 
			
		||||
#include <gdk/gdk.h>
 | 
			
		||||
#include <xkbcommon/xkbcommon.h>
 | 
			
		||||
 | 
			
		||||
gboolean
 | 
			
		||||
squeek_keymap_get_entries_for_keyval (struct xkb_keymap     *xkb_keymap,
 | 
			
		||||
                                      guint          keyval,
 | 
			
		||||
                                      GdkKeymapKey **keys,
 | 
			
		||||
                                      guint          *n_keys);
 | 
			
		||||
 | 
			
		||||
static const char *keymap_header = "xkb_keymap {\n\
 | 
			
		||||
\n";
 | 
			
		||||
 | 
			
		||||
static const char *keymap_keycodes_header = "\
 | 
			
		||||
    xkb_keycodes \"squeekboard\" {\n\n\
 | 
			
		||||
        minimum = 8;\n\
 | 
			
		||||
        maximum = 255;\n\
 | 
			
		||||
\n";
 | 
			
		||||
 | 
			
		||||
static const char *keymap_symbols_header = "\
 | 
			
		||||
    xkb_symbols \"squeekboard\" {\n\
 | 
			
		||||
\n\
 | 
			
		||||
        name[Group1] = \"Letters\";\n\
 | 
			
		||||
        name[Group2] = \"Numbers/Symbols\";\n\
 | 
			
		||||
\n";
 | 
			
		||||
 | 
			
		||||
static const char *keymap_footer = "\
 | 
			
		||||
    xkb_types \"squeekboard\" {\n\
 | 
			
		||||
\n\
 | 
			
		||||
	type \"TWO_LEVEL\" {\n\
 | 
			
		||||
            modifiers = Shift;\n\
 | 
			
		||||
            map[Shift] = Level2;\n\
 | 
			
		||||
            level_name[Level1] = \"Base\";\n\
 | 
			
		||||
            level_name[Level2] = \"Shift\";\n\
 | 
			
		||||
	};\n\
 | 
			
		||||
    };\n\
 | 
			
		||||
\n\
 | 
			
		||||
    xkb_compatibility \"squeekboard\" {\n\
 | 
			
		||||
    };\n\
 | 
			
		||||
};";
 | 
			
		||||
@ -65,9 +65,9 @@ static void layer_surface_configure(void                         *data,
 | 
			
		||||
                                    uint32_t                      height)
 | 
			
		||||
{
 | 
			
		||||
  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,13 +1,35 @@
 | 
			
		||||
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@'],
 | 
			
		||||
@ -16,5 +38,7 @@ gen_keysym_entries_xkeysym = generator(
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
keysym_entries = [
 | 
			
		||||
  gen_keysym_entries_special.process('./special-keysym-entries.txt'),
 | 
			
		||||
  gen_keysym_entries_unicode.process('./unicode-keysym-entries.txt'),
 | 
			
		||||
  gen_keysym_entries_xkeysym.process('./xkeysym-keysym-entries.txt'),
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										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 
 | 
			
		||||
							
								
								
									
										401
									
								
								eekboard/eekboard-client.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										401
									
								
								eekboard/eekboard-client.c
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,401 @@
 | 
			
		||||
/* 
 | 
			
		||||
 * 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, };
 | 
			
		||||
 | 
			
		||||
G_DEFINE_TYPE (EekboardClient, eekboard_client, G_TYPE_DBUS_PROXY);
 | 
			
		||||
 | 
			
		||||
#define EEKBOARD_CLIENT_GET_PRIVATE(obj)                                \
 | 
			
		||||
    (G_TYPE_INSTANCE_GET_PRIVATE ((obj), EEKBOARD_TYPE_CLIENT, EekboardClientPrivate))
 | 
			
		||||
 | 
			
		||||
struct _EekboardClientPrivate
 | 
			
		||||
{
 | 
			
		||||
    GHashTable *context_hash;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static void send_destroy_context (EekboardClient  *client,
 | 
			
		||||
                                  EekboardContext *context,
 | 
			
		||||
                                  GCancellable    *cancellable);
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
eekboard_client_real_destroyed (EekboardClient *self)
 | 
			
		||||
{
 | 
			
		||||
    EekboardClientPrivate *priv = EEKBOARD_CLIENT_GET_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_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);
 | 
			
		||||
 | 
			
		||||
    g_type_class_add_private (gobject_class,
 | 
			
		||||
                              sizeof (EekboardClientPrivate));
 | 
			
		||||
 | 
			
		||||
    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)
 | 
			
		||||
{
 | 
			
		||||
    self->priv = EEKBOARD_CLIENT_GET_PRIVATE(self);
 | 
			
		||||
    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;
 | 
			
		||||
    g_hash_table_remove (client->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;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    g_hash_table_insert (client->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));
 | 
			
		||||
 | 
			
		||||
    object_path = g_dbus_proxy_get_object_path (G_DBUS_PROXY(context));
 | 
			
		||||
 | 
			
		||||
    context = g_hash_table_lookup (client->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));
 | 
			
		||||
 | 
			
		||||
    object_path = g_dbus_proxy_get_object_path (G_DBUS_PROXY(context));
 | 
			
		||||
    g_hash_table_remove (client->priv->context_hash, object_path);
 | 
			
		||||
 | 
			
		||||
    send_destroy_context (client, context, cancellable);
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										79
									
								
								eekboard/eekboard-client.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										79
									
								
								eekboard/eekboard-client.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,79 @@
 | 
			
		||||
/* 
 | 
			
		||||
 * Copyright (C) 2010-2011 Daiki Ueno <ueno@unixuser.org>
 | 
			
		||||
 * Copyright (C) 2010-2011 Red Hat, Inc.
 | 
			
		||||
 * 
 | 
			
		||||
 * This program is free software: you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU General Public License as published by
 | 
			
		||||
 * the Free Software Foundation, either version 3 of the License, or
 | 
			
		||||
 * (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
 * GNU General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU General Public License
 | 
			
		||||
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
#ifndef EEKBOARD_CLIENT_H
 | 
			
		||||
#define EEKBOARD_CLIENT_H 1
 | 
			
		||||
 | 
			
		||||
#define __EEKBOARD_CLIENT_H_INSIDE__ 1
 | 
			
		||||
 | 
			
		||||
#include <gio/gio.h>
 | 
			
		||||
#include "eekboard/eekboard-context.h"
 | 
			
		||||
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
#define EEKBOARD_TYPE_CLIENT (eekboard_client_get_type())
 | 
			
		||||
#define EEKBOARD_CLIENT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EEKBOARD_TYPE_CLIENT, EekboardClient))
 | 
			
		||||
#define EEKBOARD_CLIENT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EEKBOARD_TYPE_CLIENT, EekboardClientClass))
 | 
			
		||||
#define EEKBOARD_IS_CLIENT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EEKBOARD_TYPE_CLIENT))
 | 
			
		||||
#define EEKBOARD_IS_CLIENT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EEKBOARD_TYPE_CLIENT))
 | 
			
		||||
#define EEKBOARD_CLIENT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EEKBOARD_TYPE_CLIENT, EekboardClientClass))
 | 
			
		||||
 | 
			
		||||
typedef struct _EekboardClient EekboardClient;
 | 
			
		||||
typedef struct _EekboardClientClass EekboardClientClass;
 | 
			
		||||
typedef struct _EekboardClientPrivate EekboardClientPrivate;
 | 
			
		||||
 | 
			
		||||
struct _EekboardClient {
 | 
			
		||||
    /*< private >*/
 | 
			
		||||
    GDBusProxy parent;
 | 
			
		||||
 | 
			
		||||
    EekboardClientPrivate *priv;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct _EekboardClientClass {
 | 
			
		||||
    /*< private >*/
 | 
			
		||||
    GDBusProxyClass parent_class;
 | 
			
		||||
 | 
			
		||||
    /* signals */
 | 
			
		||||
    void (* destroyed) (EekboardClient *self);
 | 
			
		||||
 | 
			
		||||
    /*< private >*/
 | 
			
		||||
    /* padding */
 | 
			
		||||
    gpointer pdummy[23];
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
GType            eekboard_client_get_type        (void) G_GNUC_CONST;
 | 
			
		||||
 | 
			
		||||
EekboardClient  *eekboard_client_new             (GDBusConnection *connection,
 | 
			
		||||
                                                  GCancellable    *cancellable);
 | 
			
		||||
EekboardContext *eekboard_client_create_context  (EekboardClient  *eekboard,
 | 
			
		||||
                                                  const gchar     *client_name,
 | 
			
		||||
                                                  GCancellable    *cancellable);
 | 
			
		||||
void             eekboard_client_push_context    (EekboardClient  *eekboard,
 | 
			
		||||
                                                  EekboardContext *context,
 | 
			
		||||
                                                  GCancellable    *cancellable);
 | 
			
		||||
void             eekboard_client_pop_context     (EekboardClient  *eekboard,
 | 
			
		||||
                                                  GCancellable    *cancellable);
 | 
			
		||||
void             eekboard_client_show_keyboard   (EekboardClient  *eekboard,
 | 
			
		||||
                                                  GCancellable    *cancellable);
 | 
			
		||||
void             eekboard_client_hide_keyboard   (EekboardClient  *eekboard,
 | 
			
		||||
                                                  GCancellable    *cancellable);
 | 
			
		||||
void             eekboard_client_destroy_context (EekboardClient  *eekboard,
 | 
			
		||||
                                                  EekboardContext *context,
 | 
			
		||||
                                                  GCancellable    *cancellable);
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
#endif  /* EEKBOARD_CLIENT_H */
 | 
			
		||||
@ -1,7 +1,7 @@
 | 
			
		||||
/*
 | 
			
		||||
/* 
 | 
			
		||||
 * Copyright (C) 2010-2011 Daiki Ueno <ueno@unixuser.org>
 | 
			
		||||
 * Copyright (C) 2010-2011 Red Hat, Inc.
 | 
			
		||||
 *
 | 
			
		||||
 * 
 | 
			
		||||
 * This program is free software: you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU General Public License as published by
 | 
			
		||||
 * the Free Software Foundation, either version 3 of the License, or
 | 
			
		||||
@ -25,7 +25,11 @@
 | 
			
		||||
 * implementation of eekboard input context service.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_CONFIG_H
 | 
			
		||||
#include "config.h"
 | 
			
		||||
#endif  /* HAVE_CONFIG_H */
 | 
			
		||||
 | 
			
		||||
#include "eekboard/eekboard-context-service.h"
 | 
			
		||||
 | 
			
		||||
#include <fcntl.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
@ -34,14 +38,10 @@
 | 
			
		||||
#include <sys/random.h> // TODO: this is Linux-specific
 | 
			
		||||
#include <xkbcommon/xkbcommon.h>
 | 
			
		||||
 | 
			
		||||
#include <gio/gio.h>
 | 
			
		||||
 | 
			
		||||
#include "eekboard/key-emitter.h"
 | 
			
		||||
#include "wayland.h"
 | 
			
		||||
 | 
			
		||||
#include "eek/eek-xml-layout.h"
 | 
			
		||||
 | 
			
		||||
#include "eekboard/eekboard-context-service.h"
 | 
			
		||||
//#include "eekboard/eekboard-xklutil.h"
 | 
			
		||||
//#include "eek/eek-xkl.h"
 | 
			
		||||
 | 
			
		||||
#define CSW 640
 | 
			
		||||
#define CSH 480
 | 
			
		||||
@ -71,24 +71,26 @@ struct _EekboardContextServicePrivate {
 | 
			
		||||
    gboolean visible;
 | 
			
		||||
    gboolean fullscreen;
 | 
			
		||||
 | 
			
		||||
    LevelKeyboard *keyboard; // currently used keyboard
 | 
			
		||||
    EekKeyboard *keyboard; // currently used keyboard
 | 
			
		||||
    GHashTable *keyboard_hash; // a table of available keyboards, per layout
 | 
			
		||||
 | 
			
		||||
    // TODO: make use of repeating buttons
 | 
			
		||||
    EekKey *repeat_key;
 | 
			
		||||
    guint repeat_timeout_id;
 | 
			
		||||
    gboolean repeat_triggered;
 | 
			
		||||
 | 
			
		||||
    GSettings *settings;
 | 
			
		||||
    uint32_t hint;
 | 
			
		||||
    uint32_t purpose;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
G_DEFINE_TYPE_WITH_PRIVATE (EekboardContextService, eekboard_context_service, G_TYPE_OBJECT);
 | 
			
		||||
G_DEFINE_TYPE (EekboardContextService, eekboard_context_service, G_TYPE_OBJECT);
 | 
			
		||||
 | 
			
		||||
static LevelKeyboard *
 | 
			
		||||
static Display *display = NULL;
 | 
			
		||||
 | 
			
		||||
static EekKeyboard *
 | 
			
		||||
eekboard_context_service_real_create_keyboard (EekboardContextService *self,
 | 
			
		||||
                                               const gchar            *keyboard_type)
 | 
			
		||||
{
 | 
			
		||||
    EekKeyboard *keyboard;
 | 
			
		||||
    EekLayout *layout;
 | 
			
		||||
    GError *error;
 | 
			
		||||
 | 
			
		||||
@ -133,7 +135,7 @@ eekboard_context_service_real_create_keyboard (EekboardContextService *self,
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    LevelKeyboard *keyboard = eek_xml_layout_real_create_keyboard(layout, self);
 | 
			
		||||
    keyboard = eek_keyboard_new (self, layout, CSW, CSH);
 | 
			
		||||
    if (!keyboard) {
 | 
			
		||||
        g_error("Failed to create a keyboard");
 | 
			
		||||
    }
 | 
			
		||||
@ -144,27 +146,17 @@ eekboard_context_service_real_create_keyboard (EekboardContextService *self,
 | 
			
		||||
        g_error("No context created");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    gchar *keymap_str = eek_keyboard_get_keymap(keyboard);
 | 
			
		||||
 | 
			
		||||
    int f = open("maprs.map", O_CREAT | O_WRONLY, 0600);
 | 
			
		||||
    write(f, keymap_str, strlen(keymap_str));
 | 
			
		||||
    close(f);
 | 
			
		||||
 | 
			
		||||
    struct xkb_keymap *keymap = xkb_keymap_new_from_string(context, keymap_str,
 | 
			
		||||
        XKB_KEYMAP_FORMAT_TEXT_V1, XKB_KEYMAP_COMPILE_NO_FLAGS);
 | 
			
		||||
 | 
			
		||||
    if (!keymap)
 | 
			
		||||
        g_error("Bad keymap:\n%s", keymap_str);
 | 
			
		||||
 | 
			
		||||
    free(keymap_str);
 | 
			
		||||
 | 
			
		||||
    xkb_context_unref(context);
 | 
			
		||||
    struct xkb_rule_names rules = { 0 };
 | 
			
		||||
    rules.layout = strdup(keyboard_type);
 | 
			
		||||
    struct xkb_keymap *keymap = xkb_keymap_new_from_names(context, &rules,
 | 
			
		||||
        XKB_KEYMAP_COMPILE_NO_FLAGS);
 | 
			
		||||
    if (!keymap) {
 | 
			
		||||
        g_error("Bad keymap");
 | 
			
		||||
    }
 | 
			
		||||
    keyboard->keymap = keymap;
 | 
			
		||||
 | 
			
		||||
    keymap_str = xkb_keymap_get_as_string(keymap, XKB_KEYMAP_FORMAT_TEXT_V1);
 | 
			
		||||
    char *keymap_str = xkb_keymap_get_as_string(keymap, XKB_KEYMAP_FORMAT_TEXT_V1);
 | 
			
		||||
    keyboard->keymap_len = strlen(keymap_str) + 1;
 | 
			
		||||
 | 
			
		||||
    g_autofree char *path = strdup("/eek_keymap-XXXXXX");
 | 
			
		||||
    char *path = strdup("/eek_keymap-XXXXXX");
 | 
			
		||||
    char *r = &path[strlen(path) - 6];
 | 
			
		||||
    getrandom(r, 6, GRND_NONBLOCK);
 | 
			
		||||
    for (uint i = 0; i < 6; i++) {
 | 
			
		||||
@ -219,7 +211,12 @@ eekboard_context_service_set_property (GObject      *object,
 | 
			
		||||
        context->priv->keyboard = g_value_get_object (value);
 | 
			
		||||
        break;
 | 
			
		||||
    case PROP_VISIBLE:
 | 
			
		||||
        context->priv->visible = g_value_get_boolean (value);
 | 
			
		||||
        /*if (context->priv->keyboard) {
 | 
			
		||||
            if (g_value_get_boolean (value))
 | 
			
		||||
                eekboard_context_service_show_keyboard (context);
 | 
			
		||||
            else
 | 
			
		||||
                eekboard_context_service_hide_keyboard (context);
 | 
			
		||||
        }*/
 | 
			
		||||
        break;
 | 
			
		||||
    case PROP_FULLSCREEN:
 | 
			
		||||
        context->priv->fullscreen = g_value_get_boolean (value);
 | 
			
		||||
@ -287,12 +284,10 @@ settings_get_layout(GSettings *settings, char **type, char **layout)
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    g_variant_iter_free(iter);
 | 
			
		||||
    g_variant_unref(inputs);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
settings_update_layout(EekboardContextService *context)
 | 
			
		||||
{
 | 
			
		||||
settings_update_layout(EekboardContextService *context) {
 | 
			
		||||
    g_autofree gchar *keyboard_type = NULL;
 | 
			
		||||
    g_autofree gchar *keyboard_layout = NULL;
 | 
			
		||||
    settings_get_layout(context->priv->settings, &keyboard_type, &keyboard_layout);
 | 
			
		||||
@ -304,29 +299,23 @@ settings_update_layout(EekboardContextService *context)
 | 
			
		||||
        keyboard_layout = g_strdup("undefined");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    EekboardContextServicePrivate *priv = EEKBOARD_CONTEXT_SERVICE_GET_PRIVATE(context);
 | 
			
		||||
 | 
			
		||||
    switch (priv->purpose) {
 | 
			
		||||
    case ZWP_TEXT_INPUT_V3_CONTENT_PURPOSE_NUMBER:
 | 
			
		||||
    case ZWP_TEXT_INPUT_V3_CONTENT_PURPOSE_PHONE:
 | 
			
		||||
        keyboard_layout = g_strdup("number");
 | 
			
		||||
        break;
 | 
			
		||||
    default:
 | 
			
		||||
        ;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // generic part follows
 | 
			
		||||
    static guint keyboard_id = 0;
 | 
			
		||||
    LevelKeyboard *keyboard = g_hash_table_lookup(context->priv->keyboard_hash,
 | 
			
		||||
    EekKeyboard *keyboard = g_hash_table_lookup(context->priv->keyboard_hash,
 | 
			
		||||
                                                GUINT_TO_POINTER(keyboard_id));
 | 
			
		||||
    // create a keyboard
 | 
			
		||||
    if (!keyboard) {
 | 
			
		||||
        keyboard = eekboard_context_service_real_create_keyboard(context, keyboard_layout);
 | 
			
		||||
        EekboardContextServiceClass *klass = EEKBOARD_CONTEXT_SERVICE_GET_CLASS(context);
 | 
			
		||||
        keyboard = klass->create_keyboard (context, keyboard_layout);
 | 
			
		||||
        eek_keyboard_set_modifier_behavior (keyboard,
 | 
			
		||||
                                            EEK_MODIFIER_BEHAVIOR_LATCH);
 | 
			
		||||
 | 
			
		||||
        g_hash_table_insert (context->priv->keyboard_hash,
 | 
			
		||||
                             GUINT_TO_POINTER(keyboard_id),
 | 
			
		||||
                             keyboard);
 | 
			
		||||
        keyboard->id = keyboard_id;
 | 
			
		||||
        g_object_set_data (G_OBJECT(keyboard),
 | 
			
		||||
                           "keyboard-id",
 | 
			
		||||
                           GUINT_TO_POINTER(keyboard_id));
 | 
			
		||||
        keyboard_id++;
 | 
			
		||||
    }
 | 
			
		||||
    // set as current
 | 
			
		||||
@ -367,6 +356,10 @@ eekboard_context_service_class_init (EekboardContextServiceClass *klass)
 | 
			
		||||
    GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
 | 
			
		||||
    GParamSpec *pspec;
 | 
			
		||||
 | 
			
		||||
    g_type_class_add_private (gobject_class,
 | 
			
		||||
                              sizeof (EekboardContextServicePrivate));
 | 
			
		||||
 | 
			
		||||
    klass->create_keyboard = eekboard_context_service_real_create_keyboard;
 | 
			
		||||
    klass->show_keyboard = eekboard_context_service_real_show_keyboard;
 | 
			
		||||
    klass->hide_keyboard = eekboard_context_service_real_hide_keyboard;
 | 
			
		||||
 | 
			
		||||
@ -431,9 +424,10 @@ eekboard_context_service_class_init (EekboardContextServiceClass *klass)
 | 
			
		||||
     *
 | 
			
		||||
     * An #EekKeyboard currently active in this context.
 | 
			
		||||
     */
 | 
			
		||||
    pspec = g_param_spec_pointer("keyboard",
 | 
			
		||||
    pspec = g_param_spec_object ("keyboard",
 | 
			
		||||
                                 "Keyboard",
 | 
			
		||||
                                 "Keyboard",
 | 
			
		||||
                                 EEK_TYPE_KEYBOARD,
 | 
			
		||||
                                 G_PARAM_READWRITE);
 | 
			
		||||
    g_object_class_install_property (gobject_class,
 | 
			
		||||
                                     PROP_KEYBOARD,
 | 
			
		||||
@ -489,6 +483,51 @@ eekboard_context_service_init (EekboardContextService *self)
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean on_repeat_timeout (EekboardContextService *context);
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
on_repeat_timeout (EekboardContextService *context)
 | 
			
		||||
{
 | 
			
		||||
    guint delay = 500; // ms
 | 
			
		||||
 | 
			
		||||
    // hardcoding; needs to connect to yet another settings path because
 | 
			
		||||
    // org.gnome.desktop.input-sources doesn't control repeating
 | 
			
		||||
    //g_settings_get (context->priv->settings, "repeat-interval", "u", &delay);
 | 
			
		||||
 | 
			
		||||
    context->priv->repeat_timeout_id =
 | 
			
		||||
        g_timeout_add (delay,
 | 
			
		||||
                       (GSourceFunc)on_repeat_timeout,
 | 
			
		||||
                       context);
 | 
			
		||||
 | 
			
		||||
    return FALSE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
on_repeat_timeout_init (EekboardContextService *context)
 | 
			
		||||
{
 | 
			
		||||
    /* FIXME: clear modifiers for further key repeat; better not
 | 
			
		||||
       depend on modifier behavior is LATCH */
 | 
			
		||||
    eek_keyboard_set_modifiers (context->priv->keyboard, 0);
 | 
			
		||||
    
 | 
			
		||||
    /* reschedule repeat timeout only when "repeat" option is set */
 | 
			
		||||
    /* TODO: org.gnome.desktop.input-sources doesn't have repeat info.
 | 
			
		||||
     * In addition, repeat is only useful when the keyboard is not in text
 | 
			
		||||
     * input mode */
 | 
			
		||||
    /*
 | 
			
		||||
    if (g_settings_get_boolean (context->priv->settings, "repeat")) {
 | 
			
		||||
        guint delay;
 | 
			
		||||
 | 
			
		||||
        g_settings_get (context->priv->settings, "repeat-interval", "u", &delay);
 | 
			
		||||
        context->priv->repeat_timeout_id =
 | 
			
		||||
            g_timeout_add (delay,
 | 
			
		||||
                           (GSourceFunc)on_repeat_timeout,
 | 
			
		||||
                           context);
 | 
			
		||||
    } else */
 | 
			
		||||
        context->priv->repeat_timeout_id = 0;
 | 
			
		||||
 | 
			
		||||
    return FALSE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eekboard_context_service_enable:
 | 
			
		||||
 * @context: an #EekboardContextService
 | 
			
		||||
@ -530,9 +569,7 @@ eekboard_context_service_show_keyboard (EekboardContextService *context)
 | 
			
		||||
{
 | 
			
		||||
    g_return_if_fail (EEKBOARD_IS_CONTEXT_SERVICE(context));
 | 
			
		||||
 | 
			
		||||
    if (!context->priv->visible) {
 | 
			
		||||
        EEKBOARD_CONTEXT_SERVICE_GET_CLASS(context)->show_keyboard (context);
 | 
			
		||||
    }
 | 
			
		||||
    EEKBOARD_CONTEXT_SERVICE_GET_CLASS(context)->show_keyboard (context);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
@ -540,9 +577,7 @@ eekboard_context_service_hide_keyboard (EekboardContextService *context)
 | 
			
		||||
{
 | 
			
		||||
    g_return_if_fail (EEKBOARD_IS_CONTEXT_SERVICE(context));
 | 
			
		||||
 | 
			
		||||
    if (context->priv->visible) {
 | 
			
		||||
        EEKBOARD_CONTEXT_SERVICE_GET_CLASS(context)->hide_keyboard (context);
 | 
			
		||||
    }
 | 
			
		||||
    EEKBOARD_CONTEXT_SERVICE_GET_CLASS(context)->hide_keyboard (context);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@ -569,7 +604,7 @@ eekboard_context_service_destroy (EekboardContextService *context)
 | 
			
		||||
 * Get keyboard currently active in @context.
 | 
			
		||||
 * Returns: (transfer none): an #EekKeyboard
 | 
			
		||||
 */
 | 
			
		||||
LevelKeyboard *
 | 
			
		||||
EekKeyboard *
 | 
			
		||||
eekboard_context_service_get_keyboard (EekboardContextService *context)
 | 
			
		||||
{
 | 
			
		||||
    return context->priv->keyboard;
 | 
			
		||||
@ -589,21 +624,9 @@ eekboard_context_service_get_fullscreen (EekboardContextService *context)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void eekboard_context_service_set_keymap(EekboardContextService *context,
 | 
			
		||||
                                         const LevelKeyboard *keyboard)
 | 
			
		||||
                                         const EekKeyboard *keyboard)
 | 
			
		||||
{
 | 
			
		||||
    zwp_virtual_keyboard_v1_keymap(context->virtual_keyboard,
 | 
			
		||||
        WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1,
 | 
			
		||||
        keyboard->keymap_fd, keyboard->keymap_len);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void eekboard_context_service_set_hint_purpose(EekboardContextService *context,
 | 
			
		||||
                                               uint32_t hint, uint32_t purpose)
 | 
			
		||||
{
 | 
			
		||||
    EekboardContextServicePrivate *priv = EEKBOARD_CONTEXT_SERVICE_GET_PRIVATE(context);
 | 
			
		||||
 | 
			
		||||
    if (priv->hint != hint || priv->purpose != purpose) {
 | 
			
		||||
        priv->hint = hint;
 | 
			
		||||
        priv->purpose = purpose;
 | 
			
		||||
        settings_update_layout(context);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -25,7 +25,6 @@
 | 
			
		||||
#include <eek/eek.h>
 | 
			
		||||
 | 
			
		||||
#include "virtual-keyboard-unstable-v1-client-protocol.h"
 | 
			
		||||
#include "text-input-unstable-v3-client-protocol.h"
 | 
			
		||||
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
@ -73,7 +72,7 @@ struct _EekboardContextServiceClass {
 | 
			
		||||
    GObjectClass parent_class;
 | 
			
		||||
 | 
			
		||||
    /*< public >*/
 | 
			
		||||
    struct squeek_view *(*create_keyboard)    (EekboardContextService *self,
 | 
			
		||||
    EekKeyboard *(*create_keyboard)    (EekboardContextService *self,
 | 
			
		||||
                                        const gchar            *keyboard_type);
 | 
			
		||||
    void         (*show_keyboard)      (EekboardContextService *self);
 | 
			
		||||
    void         (*hide_keyboard)      (EekboardContextService *self);
 | 
			
		||||
@ -97,16 +96,13 @@ void          eekboard_context_service_show_keyboard
 | 
			
		||||
void          eekboard_context_service_hide_keyboard
 | 
			
		||||
                                              (EekboardContextService *context);
 | 
			
		||||
void          eekboard_context_service_destroy (EekboardContextService *context);
 | 
			
		||||
LevelKeyboard *eekboard_context_service_get_keyboard(EekboardContextService *context);
 | 
			
		||||
EekKeyboard  *eekboard_context_service_get_keyboard
 | 
			
		||||
                                              (EekboardContextService *context);
 | 
			
		||||
gboolean      eekboard_context_service_get_fullscreen
 | 
			
		||||
                                              (EekboardContextService *context);
 | 
			
		||||
 | 
			
		||||
void eekboard_context_service_set_keymap(EekboardContextService *context,
 | 
			
		||||
                                         const LevelKeyboard *keyboard);
 | 
			
		||||
 | 
			
		||||
void eekboard_context_service_set_hint_purpose(EekboardContextService *context,
 | 
			
		||||
                                               uint32_t hint,
 | 
			
		||||
                                               uint32_t purpose);
 | 
			
		||||
                                         const EekKeyboard *keyboard);
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
#endif  /* EEKBOARD_CONTEXT_SERVICE_H */
 | 
			
		||||
 | 
			
		||||
@ -24,7 +24,9 @@
 | 
			
		||||
 * context.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_CONFIG_H
 | 
			
		||||
#include "config.h"
 | 
			
		||||
#endif  /* HAVE_CONFIG_H */
 | 
			
		||||
 | 
			
		||||
#include "eekboard/eekboard-context.h"
 | 
			
		||||
//#include "eekboard/eekboard-marshalers.h"
 | 
			
		||||
@ -35,6 +37,7 @@ enum {
 | 
			
		||||
    ENABLED,
 | 
			
		||||
    DISABLED,
 | 
			
		||||
    DESTROYED,
 | 
			
		||||
    KEY_ACTIVATED,
 | 
			
		||||
    LAST_SIGNAL
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
@ -46,15 +49,18 @@ enum {
 | 
			
		||||
    PROP_LAST
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
typedef struct _EekboardContextPrivate
 | 
			
		||||
G_DEFINE_TYPE (EekboardContext, eekboard_context, G_TYPE_DBUS_PROXY);
 | 
			
		||||
 | 
			
		||||
#define EEKBOARD_CONTEXT_GET_PRIVATE(obj)                               \
 | 
			
		||||
    (G_TYPE_INSTANCE_GET_PRIVATE ((obj), EEKBOARD_TYPE_CONTEXT, EekboardContextPrivate))
 | 
			
		||||
 | 
			
		||||
struct _EekboardContextPrivate
 | 
			
		||||
{
 | 
			
		||||
    gboolean visible;
 | 
			
		||||
    gboolean enabled;
 | 
			
		||||
    gboolean fullscreen;
 | 
			
		||||
    gint group;
 | 
			
		||||
} EekboardContextPrivate;
 | 
			
		||||
 | 
			
		||||
G_DEFINE_TYPE_WITH_PRIVATE (EekboardContext, eekboard_context, G_TYPE_DBUS_PROXY)
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
eekboard_context_real_g_signal (GDBusProxy  *self,
 | 
			
		||||
@ -63,7 +69,6 @@ eekboard_context_real_g_signal (GDBusProxy  *self,
 | 
			
		||||
                                GVariant    *parameters)
 | 
			
		||||
{
 | 
			
		||||
    EekboardContext *context = EEKBOARD_CONTEXT (self);
 | 
			
		||||
    EekboardContextPrivate *priv = eekboard_context_get_instance_private (context);
 | 
			
		||||
 | 
			
		||||
    if (g_strcmp0 (signal_name, "Enabled") == 0) {
 | 
			
		||||
        g_signal_emit (context, signals[ENABLED], 0);
 | 
			
		||||
@ -80,12 +85,34 @@ eekboard_context_real_g_signal (GDBusProxy  *self,
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (g_strcmp0 (signal_name, "KeyActivated") == 0) {
 | 
			
		||||
        guint keycode;
 | 
			
		||||
        GVariant *variant = NULL;
 | 
			
		||||
        guint modifiers = 0;
 | 
			
		||||
        EekSerializable *serializable;
 | 
			
		||||
 | 
			
		||||
        g_variant_get (parameters, "(uvu)",
 | 
			
		||||
                       &keycode, &variant, &modifiers);
 | 
			
		||||
        g_return_if_fail (variant != NULL);
 | 
			
		||||
 | 
			
		||||
        serializable = eek_serializable_deserialize (variant);
 | 
			
		||||
        g_variant_unref (variant);
 | 
			
		||||
 | 
			
		||||
        g_return_if_fail (EEK_IS_SYMBOL(serializable));
 | 
			
		||||
        
 | 
			
		||||
        g_signal_emit (context, signals[KEY_ACTIVATED], 0,
 | 
			
		||||
                       keycode, EEK_SYMBOL(serializable), modifiers);
 | 
			
		||||
        g_object_unref (serializable);
 | 
			
		||||
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (g_strcmp0 (signal_name, "VisibilityChanged") == 0) {
 | 
			
		||||
        gboolean visible = FALSE;
 | 
			
		||||
 | 
			
		||||
        g_variant_get (parameters, "(b)", &visible);
 | 
			
		||||
        if (visible != priv->visible) {
 | 
			
		||||
            priv->visible = visible;
 | 
			
		||||
        if (visible != context->priv->visible) {
 | 
			
		||||
            context->priv->visible = visible;
 | 
			
		||||
            g_object_notify (G_OBJECT(context), "visible");
 | 
			
		||||
        }
 | 
			
		||||
        return;
 | 
			
		||||
@ -95,8 +122,8 @@ eekboard_context_real_g_signal (GDBusProxy  *self,
 | 
			
		||||
        gint group = 0;
 | 
			
		||||
 | 
			
		||||
        g_variant_get (parameters, "(i)", &group);
 | 
			
		||||
        if (group != priv->group) {
 | 
			
		||||
            priv->group = group;
 | 
			
		||||
        if (group != context->priv->group) {
 | 
			
		||||
            context->priv->group = group;
 | 
			
		||||
            /* g_object_notify (G_OBJECT(context), "group"); */
 | 
			
		||||
        }
 | 
			
		||||
        return;
 | 
			
		||||
@ -108,17 +135,13 @@ eekboard_context_real_g_signal (GDBusProxy  *self,
 | 
			
		||||
static void
 | 
			
		||||
eekboard_context_real_enabled (EekboardContext *self)
 | 
			
		||||
{
 | 
			
		||||
    EekboardContextPrivate *priv = eekboard_context_get_instance_private (self);
 | 
			
		||||
 | 
			
		||||
    priv->enabled = TRUE;
 | 
			
		||||
    self->priv->enabled = TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
eekboard_context_real_disabled (EekboardContext *self)
 | 
			
		||||
{
 | 
			
		||||
    EekboardContextPrivate *priv = eekboard_context_get_instance_private (self);
 | 
			
		||||
 | 
			
		||||
    priv->enabled = FALSE;
 | 
			
		||||
    self->priv->enabled = FALSE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
@ -126,6 +149,14 @@ eekboard_context_real_destroyed (EekboardContext *self)
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
eekboard_context_real_key_activated (EekboardContext *self,
 | 
			
		||||
                                     guint            keycode,
 | 
			
		||||
                                     EekSymbol       *symbol,
 | 
			
		||||
                                     guint            modifiers)
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
eekboard_context_get_property (GObject    *object,
 | 
			
		||||
                               guint       prop_id,
 | 
			
		||||
@ -133,11 +164,9 @@ eekboard_context_get_property (GObject    *object,
 | 
			
		||||
                               GParamSpec *pspec)
 | 
			
		||||
{
 | 
			
		||||
    EekboardContext *context = EEKBOARD_CONTEXT(object);
 | 
			
		||||
    EekboardContextPrivate *priv = eekboard_context_get_instance_private (context);
 | 
			
		||||
 | 
			
		||||
    switch (prop_id) {
 | 
			
		||||
    case PROP_VISIBLE:
 | 
			
		||||
        g_value_set_boolean (value, priv->visible);
 | 
			
		||||
        g_value_set_boolean (value, context->priv->visible);
 | 
			
		||||
        break;
 | 
			
		||||
    default:
 | 
			
		||||
        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 | 
			
		||||
@ -152,9 +181,13 @@ eekboard_context_class_init (EekboardContextClass *klass)
 | 
			
		||||
    GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
 | 
			
		||||
    GParamSpec        *pspec;
 | 
			
		||||
 | 
			
		||||
    g_type_class_add_private (gobject_class,
 | 
			
		||||
                              sizeof (EekboardContextPrivate));
 | 
			
		||||
 | 
			
		||||
    klass->enabled = eekboard_context_real_enabled;
 | 
			
		||||
    klass->disabled = eekboard_context_real_disabled;
 | 
			
		||||
    klass->destroyed = eekboard_context_real_destroyed;
 | 
			
		||||
    klass->key_activated = eekboard_context_real_key_activated;
 | 
			
		||||
 | 
			
		||||
    proxy_class->g_signal = eekboard_context_real_g_signal;
 | 
			
		||||
 | 
			
		||||
@ -208,6 +241,31 @@ eekboard_context_class_init (EekboardContextClass *klass)
 | 
			
		||||
                      G_TYPE_NONE,
 | 
			
		||||
                      0);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * EekboardContext::key-activated:
 | 
			
		||||
     * @context: an #EekboardContext
 | 
			
		||||
     * @keycode: a keycode
 | 
			
		||||
     * @symbol: an #EekSymbol
 | 
			
		||||
     * @modifiers: modifiers
 | 
			
		||||
     *
 | 
			
		||||
     * The ::key-activated signal is emitted each time a key is
 | 
			
		||||
     * pressed in @context.
 | 
			
		||||
     */
 | 
			
		||||
    /*
 | 
			
		||||
    signals[KEY_ACTIVATED] =
 | 
			
		||||
        g_signal_new (I_("key-activated"),
 | 
			
		||||
                      G_TYPE_FROM_CLASS(gobject_class),
 | 
			
		||||
                      G_SIGNAL_RUN_LAST,
 | 
			
		||||
                      G_STRUCT_OFFSET(EekboardContextClass, key_activated),
 | 
			
		||||
                      NULL,
 | 
			
		||||
                      NULL,
 | 
			
		||||
                      _eekboard_marshal_VOID__UINT_OBJECT_UINT,
 | 
			
		||||
                      G_TYPE_NONE,
 | 
			
		||||
                      3,
 | 
			
		||||
                      G_TYPE_UINT,
 | 
			
		||||
                      G_TYPE_OBJECT,
 | 
			
		||||
                      G_TYPE_UINT);
 | 
			
		||||
*/
 | 
			
		||||
    /**
 | 
			
		||||
     * EekboardContext::destroyed:
 | 
			
		||||
     * @context: an #EekboardContext
 | 
			
		||||
@ -230,7 +288,7 @@ eekboard_context_class_init (EekboardContextClass *klass)
 | 
			
		||||
static void
 | 
			
		||||
eekboard_context_init (EekboardContext *self)
 | 
			
		||||
{
 | 
			
		||||
    /* void */
 | 
			
		||||
    self->priv = EEKBOARD_CONTEXT_GET_PRIVATE(self);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
@ -427,9 +485,7 @@ eekboard_context_set_group (EekboardContext *context,
 | 
			
		||||
{
 | 
			
		||||
    g_return_if_fail (EEKBOARD_IS_CONTEXT(context));
 | 
			
		||||
 | 
			
		||||
    EekboardContextPrivate *priv = eekboard_context_get_instance_private (context);
 | 
			
		||||
 | 
			
		||||
    if (priv->group != group) {
 | 
			
		||||
    if (context->priv->group != group) {
 | 
			
		||||
        g_dbus_proxy_call (G_DBUS_PROXY(context),
 | 
			
		||||
                           "SetGroup",
 | 
			
		||||
                           g_variant_new ("(i)", group),
 | 
			
		||||
@ -453,10 +509,7 @@ eekboard_context_get_group (EekboardContext *context,
 | 
			
		||||
                            GCancellable    *cancellable)
 | 
			
		||||
{
 | 
			
		||||
    g_return_val_if_fail (EEKBOARD_IS_CONTEXT(context), 0);
 | 
			
		||||
 | 
			
		||||
    EekboardContextPrivate *priv = eekboard_context_get_instance_private (context);
 | 
			
		||||
 | 
			
		||||
    return priv->group;
 | 
			
		||||
    return context->priv->group;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@ -473,9 +526,7 @@ eekboard_context_show_keyboard (EekboardContext *context,
 | 
			
		||||
{
 | 
			
		||||
    g_return_if_fail (EEKBOARD_IS_CONTEXT(context));
 | 
			
		||||
 | 
			
		||||
    EekboardContextPrivate *priv = eekboard_context_get_instance_private (context);
 | 
			
		||||
 | 
			
		||||
    if (priv->enabled) {
 | 
			
		||||
    if (context->priv->enabled) {
 | 
			
		||||
        g_dbus_proxy_call (G_DBUS_PROXY(context),
 | 
			
		||||
                           "ShowKeyboard",
 | 
			
		||||
                           NULL,
 | 
			
		||||
@ -500,9 +551,7 @@ eekboard_context_hide_keyboard (EekboardContext *context,
 | 
			
		||||
{
 | 
			
		||||
    g_return_if_fail (EEKBOARD_IS_CONTEXT(context));
 | 
			
		||||
 | 
			
		||||
    EekboardContextPrivate *priv = eekboard_context_get_instance_private (context);
 | 
			
		||||
 | 
			
		||||
    if (priv->enabled) {
 | 
			
		||||
    if (context->priv->enabled) {
 | 
			
		||||
        g_dbus_proxy_call (G_DBUS_PROXY(context),
 | 
			
		||||
                           "HideKeyboard",
 | 
			
		||||
                           NULL,
 | 
			
		||||
@ -529,9 +578,7 @@ eekboard_context_press_keycode (EekboardContext *context,
 | 
			
		||||
{
 | 
			
		||||
    g_return_if_fail (EEKBOARD_IS_CONTEXT(context));
 | 
			
		||||
 | 
			
		||||
    EekboardContextPrivate *priv = eekboard_context_get_instance_private (context);
 | 
			
		||||
 | 
			
		||||
    if (priv->enabled) {
 | 
			
		||||
    if (context->priv->enabled) {
 | 
			
		||||
        g_dbus_proxy_call (G_DBUS_PROXY(context),
 | 
			
		||||
                           "PressKeycode",
 | 
			
		||||
                           g_variant_new ("(u)", keycode),
 | 
			
		||||
@ -558,9 +605,7 @@ eekboard_context_release_keycode (EekboardContext *context,
 | 
			
		||||
{
 | 
			
		||||
    g_return_if_fail (EEKBOARD_IS_CONTEXT(context));
 | 
			
		||||
 | 
			
		||||
    EekboardContextPrivate *priv = eekboard_context_get_instance_private (context);
 | 
			
		||||
 | 
			
		||||
    if (priv->enabled) {
 | 
			
		||||
    if (context->priv->enabled) {
 | 
			
		||||
        g_dbus_proxy_call (G_DBUS_PROXY(context),
 | 
			
		||||
                           "ReleaseKeycode",
 | 
			
		||||
                           g_variant_new ("(u)", keycode),
 | 
			
		||||
@ -582,10 +627,7 @@ gboolean
 | 
			
		||||
eekboard_context_is_visible (EekboardContext *context)
 | 
			
		||||
{
 | 
			
		||||
    g_return_val_if_fail (EEKBOARD_IS_CONTEXT(context), FALSE);
 | 
			
		||||
 | 
			
		||||
    EekboardContextPrivate *priv = eekboard_context_get_instance_private (context);
 | 
			
		||||
 | 
			
		||||
    return priv->enabled && priv->visible;
 | 
			
		||||
    return context->priv->enabled && context->priv->visible;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@ -602,10 +644,7 @@ eekboard_context_set_enabled (EekboardContext *context,
 | 
			
		||||
                              gboolean         enabled)
 | 
			
		||||
{
 | 
			
		||||
    g_return_if_fail (EEKBOARD_IS_CONTEXT(context));
 | 
			
		||||
 | 
			
		||||
    EekboardContextPrivate *priv = eekboard_context_get_instance_private (context);
 | 
			
		||||
 | 
			
		||||
    priv->enabled = enabled;
 | 
			
		||||
    context->priv->enabled = enabled;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@ -618,10 +657,7 @@ gboolean
 | 
			
		||||
eekboard_context_is_enabled (EekboardContext *context)
 | 
			
		||||
{
 | 
			
		||||
    g_return_val_if_fail (EEKBOARD_IS_CONTEXT(context), FALSE);
 | 
			
		||||
 | 
			
		||||
    EekboardContextPrivate *priv = eekboard_context_get_instance_private (context);
 | 
			
		||||
 | 
			
		||||
    return priv->enabled;
 | 
			
		||||
    return context->priv->enabled;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@ -638,10 +674,7 @@ eekboard_context_set_fullscreen (EekboardContext *context,
 | 
			
		||||
                                 GCancellable    *cancellable)
 | 
			
		||||
{
 | 
			
		||||
    g_return_if_fail (EEKBOARD_IS_CONTEXT(context));
 | 
			
		||||
 | 
			
		||||
    EekboardContextPrivate *priv = eekboard_context_get_instance_private (context);
 | 
			
		||||
 | 
			
		||||
    if (priv->fullscreen != fullscreen) {
 | 
			
		||||
    if (context->priv->fullscreen != fullscreen) {
 | 
			
		||||
        g_dbus_proxy_call (G_DBUS_PROXY(context),
 | 
			
		||||
                           "SetFullscreen",
 | 
			
		||||
                           g_variant_new ("(b)", fullscreen),
 | 
			
		||||
 | 
			
		||||
@ -28,7 +28,28 @@
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
#define EEKBOARD_TYPE_CONTEXT (eekboard_context_get_type())
 | 
			
		||||
G_DECLARE_DERIVABLE_TYPE (EekboardContext, eekboard_context, EEKBOARD, CONTEXT, GDBusProxy)
 | 
			
		||||
#define EEKBOARD_CONTEXT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EEKBOARD_TYPE_CONTEXT, EekboardContext))
 | 
			
		||||
#define EEKBOARD_CONTEXT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EEKBOARD_TYPE_CONTEXT, EekboardContextClass))
 | 
			
		||||
#define EEKBOARD_IS_CONTEXT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EEKBOARD_TYPE_CONTEXT))
 | 
			
		||||
#define EEKBOARD_IS_CONTEXT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EEKBOARD_TYPE_CONTEXT))
 | 
			
		||||
#define EEKBOARD_CONTEXT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EEKBOARD_TYPE_CONTEXT, EekboardContextClass))
 | 
			
		||||
 | 
			
		||||
typedef struct _EekboardContext EekboardContext;
 | 
			
		||||
typedef struct _EekboardContextClass EekboardContextClass;
 | 
			
		||||
typedef struct _EekboardContextPrivate EekboardContextPrivate;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * EekboardContext:
 | 
			
		||||
 *
 | 
			
		||||
 * The #EekboardContext structure contains only private data and
 | 
			
		||||
 * should only be accessed using the provided API.
 | 
			
		||||
 */
 | 
			
		||||
struct _EekboardContext {
 | 
			
		||||
    /*< private >*/
 | 
			
		||||
    GDBusProxy parent;
 | 
			
		||||
 | 
			
		||||
    EekboardContextPrivate *priv;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * EekboardContextClass:
 | 
			
		||||
@ -47,6 +68,11 @@ struct _EekboardContextClass {
 | 
			
		||||
    void (*disabled)      (EekboardContext *self);
 | 
			
		||||
    void (*destroyed)     (EekboardContext *self);
 | 
			
		||||
 | 
			
		||||
    void (*key_activated) (EekboardContext *self,
 | 
			
		||||
                           guint            keycode,
 | 
			
		||||
                           EekSymbol       *symbol,
 | 
			
		||||
                           guint            modifiers);
 | 
			
		||||
 | 
			
		||||
    /*< private >*/
 | 
			
		||||
    /* padding */
 | 
			
		||||
    gpointer pdummy[24];
 | 
			
		||||
 | 
			
		||||
@ -26,16 +26,16 @@
 | 
			
		||||
 * implementation of eekboard service.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_CONFIG_H
 | 
			
		||||
#include "config.h"
 | 
			
		||||
#endif  /* HAVE_CONFIG_H */
 | 
			
		||||
 | 
			
		||||
#include "eekboard/eekboard-service.h"
 | 
			
		||||
 | 
			
		||||
#include "sm.puri.OSK0.h"
 | 
			
		||||
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
 | 
			
		||||
#include <gio/gio.h>
 | 
			
		||||
 | 
			
		||||
#include "eekboard/eekboard-service.h"
 | 
			
		||||
 | 
			
		||||
enum {
 | 
			
		||||
    PROP_0,
 | 
			
		||||
    PROP_OBJECT_PATH,
 | 
			
		||||
@ -50,8 +50,10 @@ enum {
 | 
			
		||||
 | 
			
		||||
static guint signals[LAST_SIGNAL] = { 0, };
 | 
			
		||||
 | 
			
		||||
typedef struct _EekboardServicePrivate
 | 
			
		||||
{
 | 
			
		||||
#define EEKBOARD_SERVICE_GET_PRIVATE(obj)                               \
 | 
			
		||||
    (G_TYPE_INSTANCE_GET_PRIVATE ((obj), EEKBOARD_TYPE_SERVICE, EekboardServicePrivate))
 | 
			
		||||
 | 
			
		||||
struct _EekboardServicePrivate {
 | 
			
		||||
    GDBusConnection *connection;
 | 
			
		||||
    SmPuriOSK0 *dbus_interface;
 | 
			
		||||
    GDBusNodeInfo *introspection_data;
 | 
			
		||||
@ -59,9 +61,9 @@ typedef struct _EekboardServicePrivate
 | 
			
		||||
    char *object_path;
 | 
			
		||||
 | 
			
		||||
    EekboardContextService *context; // unowned reference
 | 
			
		||||
} EekboardServicePrivate;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
G_DEFINE_TYPE_WITH_PRIVATE (EekboardService, eekboard_service, G_TYPE_OBJECT)
 | 
			
		||||
G_DEFINE_TYPE (EekboardService, eekboard_service, G_TYPE_OBJECT);
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
eekboard_service_set_property (GObject      *object,
 | 
			
		||||
@ -70,20 +72,19 @@ eekboard_service_set_property (GObject      *object,
 | 
			
		||||
                               GParamSpec   *pspec)
 | 
			
		||||
{
 | 
			
		||||
    EekboardService *service = EEKBOARD_SERVICE(object);
 | 
			
		||||
    EekboardServicePrivate *priv = eekboard_service_get_instance_private (service);
 | 
			
		||||
    GDBusConnection *connection;
 | 
			
		||||
 | 
			
		||||
    switch (prop_id) {
 | 
			
		||||
    case PROP_OBJECT_PATH:
 | 
			
		||||
        if (priv->object_path)
 | 
			
		||||
            g_free (priv->object_path);
 | 
			
		||||
        priv->object_path = g_value_dup_string (value);
 | 
			
		||||
        if (service->priv->object_path)
 | 
			
		||||
            g_free (service->priv->object_path);
 | 
			
		||||
        service->priv->object_path = g_value_dup_string (value);
 | 
			
		||||
        break;
 | 
			
		||||
    case PROP_CONNECTION:
 | 
			
		||||
        connection = g_value_get_object (value);
 | 
			
		||||
        if (priv->connection)
 | 
			
		||||
            g_object_unref (priv->connection);
 | 
			
		||||
        priv->connection = g_object_ref (connection);
 | 
			
		||||
        if (service->priv->connection)
 | 
			
		||||
            g_object_unref (service->priv->connection);
 | 
			
		||||
        service->priv->connection = g_object_ref (connection);
 | 
			
		||||
        break;
 | 
			
		||||
    default:
 | 
			
		||||
        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 | 
			
		||||
@ -98,14 +99,13 @@ eekboard_service_get_property (GObject    *object,
 | 
			
		||||
                               GParamSpec *pspec)
 | 
			
		||||
{
 | 
			
		||||
    EekboardService *service = EEKBOARD_SERVICE(object);
 | 
			
		||||
    EekboardServicePrivate *priv = eekboard_service_get_instance_private (service);
 | 
			
		||||
 | 
			
		||||
    switch (prop_id) {
 | 
			
		||||
    case PROP_OBJECT_PATH:
 | 
			
		||||
        g_value_set_string (value, priv->object_path);
 | 
			
		||||
        g_value_set_string (value, service->priv->object_path);
 | 
			
		||||
        break;
 | 
			
		||||
    case PROP_CONNECTION:
 | 
			
		||||
        g_value_set_object (value, priv->connection);
 | 
			
		||||
        g_value_set_object (value, service->priv->connection);
 | 
			
		||||
        break;
 | 
			
		||||
    default:
 | 
			
		||||
        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 | 
			
		||||
@ -117,27 +117,20 @@ static void
 | 
			
		||||
eekboard_service_dispose (GObject *object)
 | 
			
		||||
{
 | 
			
		||||
    EekboardService *service = EEKBOARD_SERVICE(object);
 | 
			
		||||
    EekboardServicePrivate *priv = eekboard_service_get_instance_private (service);
 | 
			
		||||
 | 
			
		||||
    if (priv->connection) {
 | 
			
		||||
        if (priv->registration_id > 0) {
 | 
			
		||||
            g_dbus_connection_unregister_object (priv->connection,
 | 
			
		||||
                                                 priv->registration_id);
 | 
			
		||||
            priv->registration_id = 0;
 | 
			
		||||
    if (service->priv->connection) {
 | 
			
		||||
        if (service->priv->registration_id > 0) {
 | 
			
		||||
            g_dbus_connection_unregister_object (service->priv->connection,
 | 
			
		||||
                                                 service->priv->registration_id);
 | 
			
		||||
            service->priv->registration_id = 0;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        g_object_unref (priv->connection);
 | 
			
		||||
        priv->connection = NULL;
 | 
			
		||||
        g_object_unref (service->priv->connection);
 | 
			
		||||
        service->priv->connection = NULL;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (priv->introspection_data) {
 | 
			
		||||
        g_dbus_node_info_unref (priv->introspection_data);
 | 
			
		||||
        priv->introspection_data = NULL;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (priv->context) {
 | 
			
		||||
        g_signal_handlers_disconnect_by_data (priv->context, service);
 | 
			
		||||
        priv->context = NULL;
 | 
			
		||||
    if (service->priv->introspection_data) {
 | 
			
		||||
        g_dbus_node_info_unref (service->priv->introspection_data);
 | 
			
		||||
        service->priv->introspection_data = NULL;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    G_OBJECT_CLASS (eekboard_service_parent_class)->dispose (object);
 | 
			
		||||
@ -147,9 +140,8 @@ static void
 | 
			
		||||
eekboard_service_finalize (GObject *object)
 | 
			
		||||
{
 | 
			
		||||
    EekboardService *service = EEKBOARD_SERVICE(object);
 | 
			
		||||
    EekboardServicePrivate *priv = eekboard_service_get_instance_private (service);
 | 
			
		||||
 | 
			
		||||
    g_free (priv->object_path);
 | 
			
		||||
    g_free (service->priv->object_path);
 | 
			
		||||
 | 
			
		||||
    G_OBJECT_CLASS (eekboard_service_parent_class)->finalize (object);
 | 
			
		||||
}
 | 
			
		||||
@ -158,51 +150,33 @@ static gboolean
 | 
			
		||||
handle_set_visible(SmPuriOSK0 *object, GDBusMethodInvocation *invocation,
 | 
			
		||||
                   gboolean arg_visible, gpointer user_data) {
 | 
			
		||||
    EekboardService *service = user_data;
 | 
			
		||||
    EekboardServicePrivate *priv = eekboard_service_get_instance_private (service);
 | 
			
		||||
 | 
			
		||||
    if (priv->context) {
 | 
			
		||||
    if (service->priv->context) {
 | 
			
		||||
        if (arg_visible) {
 | 
			
		||||
            eekboard_context_service_show_keyboard (priv->context);
 | 
			
		||||
            eekboard_context_service_show_keyboard (service->priv->context);
 | 
			
		||||
        } else {
 | 
			
		||||
            eekboard_context_service_hide_keyboard (priv->context);
 | 
			
		||||
            eekboard_context_service_hide_keyboard (service->priv->context);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    sm_puri_osk0_complete_set_visible(object, invocation);
 | 
			
		||||
    return TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void on_visible(EekboardService *service,
 | 
			
		||||
                       GParamSpec *pspec,
 | 
			
		||||
                       EekboardContextService *context)
 | 
			
		||||
{
 | 
			
		||||
    gboolean visible;
 | 
			
		||||
    EekboardServicePrivate *priv;
 | 
			
		||||
 | 
			
		||||
    g_return_if_fail (EEKBOARD_IS_SERVICE (service));
 | 
			
		||||
    g_return_if_fail (EEKBOARD_IS_CONTEXT_SERVICE (context));
 | 
			
		||||
 | 
			
		||||
    priv = eekboard_service_get_instance_private (service);
 | 
			
		||||
    g_object_get (context, "visible", &visible, NULL);
 | 
			
		||||
 | 
			
		||||
    sm_puri_osk0_set_visible(priv->dbus_interface, visible);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
eekboard_service_constructed (GObject *object)
 | 
			
		||||
{
 | 
			
		||||
    EekboardService *service = EEKBOARD_SERVICE(object);
 | 
			
		||||
    EekboardServicePrivate *priv = eekboard_service_get_instance_private (service);
 | 
			
		||||
 | 
			
		||||
    priv->dbus_interface = sm_puri_osk0_skeleton_new();
 | 
			
		||||
    g_signal_connect(priv->dbus_interface, "handle-set-visible",
 | 
			
		||||
    service->priv->dbus_interface = sm_puri_osk0_skeleton_new();
 | 
			
		||||
    sm_puri_osk0_set_visible(service->priv->dbus_interface, FALSE); // TODO: use actual value
 | 
			
		||||
    g_signal_connect(service->priv->dbus_interface, "handle-set-visible",
 | 
			
		||||
                     G_CALLBACK(handle_set_visible), service);
 | 
			
		||||
 | 
			
		||||
    if (priv->connection && priv->object_path) {
 | 
			
		||||
    if (service->priv->connection && service->priv->object_path) {
 | 
			
		||||
        GError *error = NULL;
 | 
			
		||||
 | 
			
		||||
        if (!g_dbus_interface_skeleton_export(G_DBUS_INTERFACE_SKELETON(priv->dbus_interface),
 | 
			
		||||
                                              priv->connection,
 | 
			
		||||
                                              priv->object_path,
 | 
			
		||||
        if (!g_dbus_interface_skeleton_export(G_DBUS_INTERFACE_SKELETON(service->priv->dbus_interface),
 | 
			
		||||
                                              service->priv->connection,
 | 
			
		||||
                                              service->priv->object_path,
 | 
			
		||||
                                              &error)) {
 | 
			
		||||
            g_warning("Error registering dbus object: %s\n", error->message);
 | 
			
		||||
            g_clear_error(&error);
 | 
			
		||||
@ -216,6 +190,9 @@ eekboard_service_class_init (EekboardServiceClass *klass)
 | 
			
		||||
    GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
 | 
			
		||||
    GParamSpec *pspec;
 | 
			
		||||
 | 
			
		||||
    g_type_class_add_private (gobject_class,
 | 
			
		||||
                              sizeof (EekboardServicePrivate));
 | 
			
		||||
 | 
			
		||||
    klass->create_context = NULL;
 | 
			
		||||
 | 
			
		||||
    gobject_class->constructed = eekboard_service_constructed;
 | 
			
		||||
@ -273,9 +250,8 @@ eekboard_service_class_init (EekboardServiceClass *klass)
 | 
			
		||||
static void
 | 
			
		||||
eekboard_service_init (EekboardService *self)
 | 
			
		||||
{
 | 
			
		||||
    EekboardServicePrivate *priv = eekboard_service_get_instance_private (self);
 | 
			
		||||
 | 
			
		||||
    priv->context = NULL;
 | 
			
		||||
    self->priv = EEKBOARD_SERVICE_GET_PRIVATE(self);
 | 
			
		||||
    self->priv->context = NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@ -295,16 +271,7 @@ eekboard_service_new (GDBusConnection *connection,
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
eekboard_service_set_context(EekboardService *service,
 | 
			
		||||
                             EekboardContextService *context)
 | 
			
		||||
{
 | 
			
		||||
    EekboardServicePrivate *priv = eekboard_service_get_instance_private (service);
 | 
			
		||||
 | 
			
		||||
    g_return_if_fail (!priv->context);
 | 
			
		||||
 | 
			
		||||
    priv->context = context;
 | 
			
		||||
 | 
			
		||||
    g_signal_connect_swapped (priv->context,
 | 
			
		||||
                              "notify::visible",
 | 
			
		||||
                              G_CALLBACK(on_visible),
 | 
			
		||||
                              service);
 | 
			
		||||
                             EekboardContextService *context) {
 | 
			
		||||
    service->priv->context = context;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -28,7 +28,30 @@ G_BEGIN_DECLS
 | 
			
		||||
#define EEKBOARD_SERVICE_INTERFACE "sm.puri.OSK0"
 | 
			
		||||
 | 
			
		||||
#define EEKBOARD_TYPE_SERVICE (eekboard_service_get_type())
 | 
			
		||||
G_DECLARE_DERIVABLE_TYPE (EekboardService, eekboard_service, EEKBOARD, SERVICE, GObject)
 | 
			
		||||
#define EEKBOARD_SERVICE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EEKBOARD_TYPE_SERVICE, EekboardService))
 | 
			
		||||
#define EEKBOARD_SERVICE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EEKBOARD_TYPE_SERVICE, EekboardServiceClass))
 | 
			
		||||
#define EEKBOARD_IS_SERVICE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EEKBOARD_TYPE_SERVICE))
 | 
			
		||||
#define EEKBOARD_IS_SERVICE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EEKBOARD_TYPE_SERVICE))
 | 
			
		||||
#define EEKBOARD_SERVICE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EEKBOARD_TYPE_SERVICE, EekboardServiceClass))
 | 
			
		||||
 | 
			
		||||
typedef struct _EekboardService EekboardService;
 | 
			
		||||
typedef struct _EekboardServiceClass EekboardServiceClass;
 | 
			
		||||
typedef struct _EekboardServicePrivate EekboardServicePrivate;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * EekboardService:
 | 
			
		||||
 *
 | 
			
		||||
 * Manages DBus interaction.
 | 
			
		||||
 *
 | 
			
		||||
 * The #EekboardService structure contains only private data and
 | 
			
		||||
 * should only be accessed using the provided API.
 | 
			
		||||
 */
 | 
			
		||||
struct _EekboardService {
 | 
			
		||||
    /*< private >*/
 | 
			
		||||
    GObject parent;
 | 
			
		||||
 | 
			
		||||
    EekboardServicePrivate *priv;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * EekboardServiceClass:
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										168
									
								
								eekboard/eekboard-xklutil.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										168
									
								
								eekboard/eekboard-xklutil.c
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,168 @@
 | 
			
		||||
/* 
 | 
			
		||||
 * Copyright (C) 2011 Daiki Ueno <ueno@unixuser.org>
 | 
			
		||||
 * Copyright (C) 2011 Red Hat, Inc.
 | 
			
		||||
 * 
 | 
			
		||||
 * This library is free software; you can redistribute it and/or
 | 
			
		||||
 * modify it under the terms of the GNU Lesser General Public License
 | 
			
		||||
 * as published by the Free Software Foundation; either version 2 of
 | 
			
		||||
 * the License, or (at your option) any later version.
 | 
			
		||||
 * 
 | 
			
		||||
 * This library is distributed in the hope that it will be useful, but
 | 
			
		||||
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
			
		||||
 * Lesser General Public License for more details.
 | 
			
		||||
 * 
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General Public
 | 
			
		||||
 * License along with this library; if not, write to the Free Software
 | 
			
		||||
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 | 
			
		||||
 * 02110-1301 USA
 | 
			
		||||
 */
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include "eekboard/eekboard-xklutil.h"
 | 
			
		||||
 | 
			
		||||
XklConfigRec *
 | 
			
		||||
eekboard_xkl_config_rec_from_string (const gchar *layouts)
 | 
			
		||||
{
 | 
			
		||||
    XklConfigRec *rec;
 | 
			
		||||
    gchar **strv, **l, **v;
 | 
			
		||||
    gint i;
 | 
			
		||||
 | 
			
		||||
    strv = g_strsplit (layouts, "/", -1);
 | 
			
		||||
    g_return_val_if_fail (g_strv_length (strv) == 3, NULL);
 | 
			
		||||
    
 | 
			
		||||
    l = g_strsplit (strv[1], ";", -1);
 | 
			
		||||
    v = g_strdupv (l);
 | 
			
		||||
    for (i = 0; l[i]; i++) {
 | 
			
		||||
        gchar *layout = l[i], *variant = v[i],
 | 
			
		||||
            *variant_start, *variant_end;
 | 
			
		||||
 | 
			
		||||
        variant_start = strchr (layout, '(');
 | 
			
		||||
        variant_end = strrchr (layout, ')');
 | 
			
		||||
        if (variant_start && variant_end) {
 | 
			
		||||
            *variant_start++ = '\0';
 | 
			
		||||
            g_strlcpy (variant, variant_start,
 | 
			
		||||
                       variant_end - variant_start + 1);
 | 
			
		||||
        } else
 | 
			
		||||
            *variant = '\0';
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    rec = xkl_config_rec_new ();
 | 
			
		||||
    rec->model = g_strdup (strv[0]);
 | 
			
		||||
    rec->layouts = l;
 | 
			
		||||
    rec->variants = v;
 | 
			
		||||
    rec->options = g_strsplit (strv[2], ";", -1);
 | 
			
		||||
    g_strfreev (strv);
 | 
			
		||||
 | 
			
		||||
    return rec;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
gchar *
 | 
			
		||||
eekboard_xkl_config_rec_to_string (XklConfigRec *rec)
 | 
			
		||||
{
 | 
			
		||||
    gchar **strv, **sp, **lp, **vp, *p;
 | 
			
		||||
    gint n_layouts;
 | 
			
		||||
    GString *str;
 | 
			
		||||
 | 
			
		||||
    n_layouts = g_strv_length (rec->layouts);
 | 
			
		||||
    strv = g_malloc0_n (n_layouts + 2, sizeof (gchar *));
 | 
			
		||||
    for (sp = strv, lp = rec->layouts, vp = rec->variants; *lp; sp++, lp++) {
 | 
			
		||||
        if (*vp != NULL && **vp != '\0')
 | 
			
		||||
            *sp = g_strdup_printf ("%s(%s)", *lp, *vp++);
 | 
			
		||||
        else
 | 
			
		||||
            *sp = g_strdup_printf ("%s", *lp);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* MODEL/L0(V0);L1(V1);...;Ln(Vn)/O0;O1;...;On */
 | 
			
		||||
    str = g_string_new (rec->model);
 | 
			
		||||
 | 
			
		||||
    g_string_append_c (str, '/');
 | 
			
		||||
    p = g_strjoinv (";", strv);
 | 
			
		||||
    g_strfreev (strv);
 | 
			
		||||
    g_string_append (str, p);
 | 
			
		||||
    g_free (p);
 | 
			
		||||
 | 
			
		||||
    g_string_append_c (str, '/');
 | 
			
		||||
    p = g_strjoinv (";", rec->options);
 | 
			
		||||
    g_string_append (str, p);
 | 
			
		||||
    g_free (p);
 | 
			
		||||
 | 
			
		||||
    return g_string_free (str,FALSE);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static XklConfigItem *
 | 
			
		||||
xkl_config_item_copy (const XklConfigItem *item)
 | 
			
		||||
{
 | 
			
		||||
    XklConfigItem *_item = xkl_config_item_new ();
 | 
			
		||||
    memcpy (_item->name,
 | 
			
		||||
            item->name,
 | 
			
		||||
            sizeof (item->name));
 | 
			
		||||
    memcpy (_item->short_description,
 | 
			
		||||
            item->short_description,
 | 
			
		||||
            sizeof (item->short_description));
 | 
			
		||||
    memcpy (_item->description,
 | 
			
		||||
            item->description,
 | 
			
		||||
            sizeof (item->description));
 | 
			
		||||
    return _item;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
prepend_item (XklConfigRegistry   *registry,
 | 
			
		||||
              const XklConfigItem *item,
 | 
			
		||||
              gpointer             data)
 | 
			
		||||
{
 | 
			
		||||
    GSList **list = data;
 | 
			
		||||
    XklConfigItem *_item = xkl_config_item_copy (item);
 | 
			
		||||
    *list = g_slist_prepend (*list, _item);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gint
 | 
			
		||||
compare_item_by_name (gconstpointer a, gconstpointer b)
 | 
			
		||||
{
 | 
			
		||||
    const XklConfigItem *ia = a, *ib = b;
 | 
			
		||||
    return g_strcmp0 (ia->name, ib->name);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
GSList *
 | 
			
		||||
eekboard_xkl_list_models (XklConfigRegistry *registry)
 | 
			
		||||
{
 | 
			
		||||
    GSList *list = NULL;
 | 
			
		||||
    xkl_config_registry_foreach_model (registry, prepend_item, &list);
 | 
			
		||||
    return g_slist_sort (list, compare_item_by_name);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
GSList *
 | 
			
		||||
eekboard_xkl_list_layouts (XklConfigRegistry *registry)
 | 
			
		||||
{
 | 
			
		||||
    GSList *list = NULL;
 | 
			
		||||
    xkl_config_registry_foreach_layout (registry, prepend_item, &list);
 | 
			
		||||
    return g_slist_sort (list, compare_item_by_name);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
GSList *
 | 
			
		||||
eekboard_xkl_list_option_groups (XklConfigRegistry *registry)
 | 
			
		||||
{
 | 
			
		||||
    GSList *list = NULL;
 | 
			
		||||
    xkl_config_registry_foreach_option_group (registry, prepend_item, &list);
 | 
			
		||||
    return g_slist_sort (list, compare_item_by_name);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
GSList *
 | 
			
		||||
eekboard_xkl_list_layout_variants (XklConfigRegistry *registry,
 | 
			
		||||
                                   const gchar       *layout)
 | 
			
		||||
{
 | 
			
		||||
    GSList *list = NULL;
 | 
			
		||||
    xkl_config_registry_foreach_layout_variant (registry,
 | 
			
		||||
                                                layout,
 | 
			
		||||
                                                prepend_item,
 | 
			
		||||
                                                &list);
 | 
			
		||||
    return g_slist_sort (list, compare_item_by_name);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
GSList *
 | 
			
		||||
eekboard_xkl_list_options (XklConfigRegistry *registry,
 | 
			
		||||
                           const gchar       *group)
 | 
			
		||||
{
 | 
			
		||||
    GSList *list = NULL;
 | 
			
		||||
    xkl_config_registry_foreach_option (registry, group, prepend_item, &list);
 | 
			
		||||
    return g_slist_sort (list, compare_item_by_name);
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										39
									
								
								eekboard/eekboard-xklutil.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								eekboard/eekboard-xklutil.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,39 @@
 | 
			
		||||
/* 
 | 
			
		||||
 * Copyright (C) 2011 Daiki Ueno <ueno@unixuser.org>
 | 
			
		||||
 * Copyright (C) 2011 Red Hat, Inc.
 | 
			
		||||
 * 
 | 
			
		||||
 * This library is free software; you can redistribute it and/or
 | 
			
		||||
 * modify it under the terms of the GNU Lesser General Public License
 | 
			
		||||
 * as published by the Free Software Foundation; either version 2 of
 | 
			
		||||
 * the License, or (at your option) any later version.
 | 
			
		||||
 * 
 | 
			
		||||
 * This library is distributed in the hope that it will be useful, but
 | 
			
		||||
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
			
		||||
 * Lesser General Public License for more details.
 | 
			
		||||
 * 
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General Public
 | 
			
		||||
 * License along with this library; if not, write to the Free Software
 | 
			
		||||
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 | 
			
		||||
 * 02110-1301 USA
 | 
			
		||||
 */
 | 
			
		||||
#ifndef EEKBOARD_XKLUTIL_H
 | 
			
		||||
#define EEKBOARD_XKLUTIL_H 1
 | 
			
		||||
 | 
			
		||||
#include <libxklavier/xklavier.h>
 | 
			
		||||
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
XklConfigRec *eekboard_xkl_config_rec_from_string (const gchar       *layouts);
 | 
			
		||||
gchar        *eekboard_xkl_config_rec_to_string   (XklConfigRec      *rec);
 | 
			
		||||
 | 
			
		||||
GSList       *eekboard_xkl_list_models            (XklConfigRegistry *registry);
 | 
			
		||||
GSList       *eekboard_xkl_list_layouts           (XklConfigRegistry *registry);
 | 
			
		||||
GSList       *eekboard_xkl_list_option_groups     (XklConfigRegistry *registry);
 | 
			
		||||
GSList       *eekboard_xkl_list_layout_variants   (XklConfigRegistry *registry,
 | 
			
		||||
                                                   const gchar       *layout);
 | 
			
		||||
GSList       *eekboard_xkl_list_options           (XklConfigRegistry *registry,
 | 
			
		||||
                                                   const gchar       *group);
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
#endif  /* EEKBOARD_XKLUTIL_H */
 | 
			
		||||
@ -20,9 +20,9 @@
 | 
			
		||||
/* This file is responsible for managing keycode data and emitting keycodes. */
 | 
			
		||||
 | 
			
		||||
#include "eekboard/key-emitter.h"
 | 
			
		||||
#include "eekboard/keymap.h"
 | 
			
		||||
 | 
			
		||||
#include <gdk/gdk.h>
 | 
			
		||||
#include <X11/XKBlib.h>
 | 
			
		||||
 | 
			
		||||
#include "eekboard/eekboard-context-service.h"
 | 
			
		||||
 | 
			
		||||
@ -39,6 +39,97 @@ typedef struct {
 | 
			
		||||
} SeatEmitter;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* The following functions for keyboard mapping change are direct
 | 
			
		||||
   translation of the code in Caribou (in libcaribou/xadapter.vala):
 | 
			
		||||
 | 
			
		||||
   - get_replaced_keycode (Caribou: get_reserved_keycode)
 | 
			
		||||
   - replace_keycode
 | 
			
		||||
   - get_keycode_from_gdk_keymap (Caribou: best_keycode_keyval_match)
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
/* Find an unused keycode where a keysym can be assigned. Restricted to Level 1 */
 | 
			
		||||
static guint
 | 
			
		||||
get_replaced_keycode (SeatEmitter *client)
 | 
			
		||||
{
 | 
			
		||||
    guint keycode;
 | 
			
		||||
return 0; // FIXME: no xkb allocated yet
 | 
			
		||||
    for (keycode = client->xkb->max_key_code;
 | 
			
		||||
         keycode >= client->xkb->min_key_code;
 | 
			
		||||
         --keycode) {
 | 
			
		||||
        guint offset = client->xkb->map->key_sym_map[keycode].offset;
 | 
			
		||||
        if (client->xkb->map->key_sym_map[keycode].kt_index[0] == XkbOneLevelIndex &&
 | 
			
		||||
            client->xkb->map->syms[offset] != NoSymbol) {
 | 
			
		||||
            return keycode;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Replace keysym assigned to KEYCODE to KEYSYM.  Both args are used
 | 
			
		||||
   as in-out.  If KEYCODE points to 0, this function picks a keycode
 | 
			
		||||
   from the current map and replace the associated keysym to KEYSYM.
 | 
			
		||||
   In that case, the replaced keycode is stored in KEYCODE and the old
 | 
			
		||||
   keysym is stored in KEYSYM.  If otherwise (KEYCODE points to
 | 
			
		||||
   non-zero keycode), it simply changes the current map with the
 | 
			
		||||
   specified KEYCODE and KEYSYM. */
 | 
			
		||||
static gboolean
 | 
			
		||||
replace_keycode (SeatEmitter *emitter,
 | 
			
		||||
                 guint   keycode,
 | 
			
		||||
                 guint  *keysym)
 | 
			
		||||
{
 | 
			
		||||
    GdkDisplay *display = gdk_display_get_default ();
 | 
			
		||||
    //Display *xdisplay = GDK_DISPLAY_XDISPLAY (display);
 | 
			
		||||
    guint old_keysym;
 | 
			
		||||
    int keysyms_per_keycode;
 | 
			
		||||
    KeySym *syms;
 | 
			
		||||
return TRUE; // FIXME: no xkb allocated at the moment, pretending all is fine
 | 
			
		||||
    g_return_val_if_fail (emitter->xkb->min_key_code <= keycode &&
 | 
			
		||||
                          keycode <= emitter->xkb->max_key_code,
 | 
			
		||||
                          FALSE);
 | 
			
		||||
    g_return_val_if_fail (keysym != NULL, FALSE);
 | 
			
		||||
/*
 | 
			
		||||
 * Update keyboard mapping. Wayland receives keyboard mapping as a string, so XChangeKeyboardMapping needs to translate from the symbol tbale t the string. TODO.
 | 
			
		||||
 *
 | 
			
		||||
    syms = XGetKeyboardMapping (xdisplay, keycode, 1, &keysyms_per_keycode);
 | 
			
		||||
    old_keysym = syms[0];
 | 
			
		||||
    syms[0] = *keysym;
 | 
			
		||||
    XChangeKeyboardMapping (xdisplay, keycode, 1, syms, 1);
 | 
			
		||||
    XSync (xdisplay, False);
 | 
			
		||||
    XFree (syms);
 | 
			
		||||
    *keysym = old_keysym;
 | 
			
		||||
*/
 | 
			
		||||
    return TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
get_keycode_from_gdk_keymap (SeatEmitter *emitter,
 | 
			
		||||
                             guint           keysym,
 | 
			
		||||
                             guint          *keycode,
 | 
			
		||||
                             guint          *modifiers)
 | 
			
		||||
{
 | 
			
		||||
    GdkKeymapKey *keys, *best_match = NULL;
 | 
			
		||||
    guint n_keys, i;
 | 
			
		||||
 | 
			
		||||
    if (!squeek_keymap_get_entries_for_keyval (emitter->keymap, keysym, &keys, &n_keys))
 | 
			
		||||
        return FALSE;
 | 
			
		||||
 | 
			
		||||
    for (i = 0; i < n_keys; i++)
 | 
			
		||||
        if ((guint)keys[i].group == emitter->group)
 | 
			
		||||
            best_match = &keys[i];
 | 
			
		||||
 | 
			
		||||
    if (!best_match) {
 | 
			
		||||
        g_free (keys);
 | 
			
		||||
        return FALSE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    *keycode = best_match->keycode;
 | 
			
		||||
    *modifiers = best_match->level == 1 ? EEK_SHIFT_MASK : 0;
 | 
			
		||||
 | 
			
		||||
    g_free (keys);
 | 
			
		||||
    return TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int send_virtual_keyboard_key(
 | 
			
		||||
    struct zwp_virtual_keyboard_v1 *keyboard,
 | 
			
		||||
    unsigned int keycode,
 | 
			
		||||
@ -49,6 +140,115 @@ int send_virtual_keyboard_key(
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
send_fake_modifiers_events (SeatEmitter         *emitter,
 | 
			
		||||
                              EekModifierType modifiers,
 | 
			
		||||
                              uint32_t        timestamp)
 | 
			
		||||
{
 | 
			
		||||
    (void)timestamp;
 | 
			
		||||
 | 
			
		||||
    uint32_t proto_modifiers = 0;
 | 
			
		||||
    if (modifiers & EEK_SHIFT_MASK) {
 | 
			
		||||
        proto_modifiers |= 1<<MOD_IDX_SHIFT;
 | 
			
		||||
    }
 | 
			
		||||
    if (modifiers & EEK_CONTROL_MASK) {
 | 
			
		||||
        proto_modifiers |= 1<<MOD_IDX_CTRL;
 | 
			
		||||
    }
 | 
			
		||||
    if (modifiers & EEK_MOD1_MASK) {
 | 
			
		||||
        proto_modifiers |= 1<<MOD_IDX_ALT;
 | 
			
		||||
    }
 | 
			
		||||
    zwp_virtual_keyboard_v1_modifiers(emitter->virtual_keyboard, proto_modifiers, 0, 0, emitter->group);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
send_fake_key_event (SeatEmitter *emitter,
 | 
			
		||||
                     guint    xkeysym,
 | 
			
		||||
                     guint    keyboard_modifiers,
 | 
			
		||||
                     gboolean pressed,
 | 
			
		||||
                     uint32_t timestamp)
 | 
			
		||||
{
 | 
			
		||||
    EekModifierType modifiers;
 | 
			
		||||
    guint old_keysym = xkeysym;
 | 
			
		||||
 | 
			
		||||
    g_return_if_fail (xkeysym > 0);
 | 
			
		||||
 | 
			
		||||
    guint keycode;
 | 
			
		||||
    if (!get_keycode_from_gdk_keymap (emitter, xkeysym, &keycode, &modifiers)) {
 | 
			
		||||
        keycode = get_replaced_keycode (emitter);
 | 
			
		||||
        if (keycode == 0) {
 | 
			
		||||
            g_warning ("no available keycode to replace");
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (!replace_keycode (emitter, keycode, &old_keysym)) {
 | 
			
		||||
            g_warning ("failed to lookup X keysym %X", xkeysym);
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    /* Clear level shift modifiers */
 | 
			
		||||
    keyboard_modifiers &= (unsigned)~EEK_SHIFT_MASK;
 | 
			
		||||
    keyboard_modifiers &= (unsigned)~EEK_LOCK_MASK;
 | 
			
		||||
    /* FIXME: may need to remap ISO_Level3_Shift and NumLock */
 | 
			
		||||
 | 
			
		||||
    modifiers |= keyboard_modifiers;
 | 
			
		||||
 | 
			
		||||
    send_fake_modifiers_events (emitter, modifiers, timestamp);
 | 
			
		||||
 | 
			
		||||
    // There's something magical about subtracting/adding 8 to keycodes for some reason
 | 
			
		||||
    send_virtual_keyboard_key (emitter->virtual_keyboard, keycode - 8, (unsigned)pressed, timestamp);
 | 
			
		||||
    send_fake_modifiers_events (emitter, modifiers, timestamp);
 | 
			
		||||
 | 
			
		||||
    if (old_keysym != xkeysym)
 | 
			
		||||
        replace_keycode (emitter, keycode, &old_keysym);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
send_fake_key_events (SeatEmitter *emitter,
 | 
			
		||||
                      EekSymbol *symbol,
 | 
			
		||||
                      EekModifierType      keyboard_modifiers,
 | 
			
		||||
                      gboolean   pressed,
 | 
			
		||||
                      uint32_t   timestamp)
 | 
			
		||||
{
 | 
			
		||||
    /* Ignore modifier keys */
 | 
			
		||||
    if (eek_symbol_is_modifier (symbol))
 | 
			
		||||
        return;
 | 
			
		||||
 | 
			
		||||
    /* If symbol is a text, convert chars in it to keysym */
 | 
			
		||||
    if (EEK_IS_TEXT(symbol)) {
 | 
			
		||||
        const gchar *utf8 = eek_text_get_text (EEK_TEXT(symbol));
 | 
			
		||||
        printf("Attempting to send text %s\n", utf8);
 | 
			
		||||
        /* FIXME:
 | 
			
		||||
        glong items_written;
 | 
			
		||||
        gunichar *ucs4 = g_utf8_to_ucs4_fast (utf8, -1, &items_written);
 | 
			
		||||
        gint i;
 | 
			
		||||
 | 
			
		||||
        for (i = 0; i < items_written; i++) {
 | 
			
		||||
            guint xkeysym;
 | 
			
		||||
            EekKeysym *keysym;
 | 
			
		||||
            gchar *name;
 | 
			
		||||
 | 
			
		||||
            name = g_strdup_printf ("U%04X", ucs4[i]);
 | 
			
		||||
            xkeysym = XStringToKeysym (name); // TODO: use xkb_get_keysym_from_name
 | 
			
		||||
            g_free (name);
 | 
			
		||||
 | 
			
		||||
            keysym = eek_keysym_new (xkeysym);
 | 
			
		||||
            send_fake_key_events (client,
 | 
			
		||||
                                  EEK_SYMBOL(keysym),
 | 
			
		||||
                                  keyboard_modifiers);
 | 
			
		||||
        }
 | 
			
		||||
        g_free (ucs4);
 | 
			
		||||
        */
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (EEK_IS_KEYSYM(symbol)) {
 | 
			
		||||
        guint xkeysym = eek_keysym_get_xkeysym (EEK_KEYSYM(symbol));
 | 
			
		||||
        send_fake_key_event (emitter, xkeysym, keyboard_modifiers, pressed, timestamp);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* Finds the first key code for each modifier and saves it in modifier_keycodes */
 | 
			
		||||
static void
 | 
			
		||||
update_modifier_info (SeatEmitter *client)
 | 
			
		||||
@ -83,25 +283,12 @@ update_modifier_info (SeatEmitter *client)
 | 
			
		||||
    }*/
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
send_fake_key (SeatEmitter *emitter,
 | 
			
		||||
               LevelKeyboard *keyboard,
 | 
			
		||||
               guint    keycode,
 | 
			
		||||
               gboolean pressed,
 | 
			
		||||
               uint32_t timestamp)
 | 
			
		||||
{
 | 
			
		||||
    guint level = keyboard->level;
 | 
			
		||||
    uint32_t group = (level / 2);
 | 
			
		||||
 | 
			
		||||
    zwp_virtual_keyboard_v1_modifiers(emitter->virtual_keyboard, 0, 0, 0, group);
 | 
			
		||||
    send_virtual_keyboard_key (emitter->virtual_keyboard, keycode - 8, (unsigned)pressed, timestamp);
 | 
			
		||||
    zwp_virtual_keyboard_v1_modifiers(emitter->virtual_keyboard, 0, 0, 0, group);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
emit_key_activated (EekboardContextService *manager,
 | 
			
		||||
                    LevelKeyboard     *keyboard,
 | 
			
		||||
                    EekKeyboard     *keyboard,
 | 
			
		||||
                    guint            keycode,
 | 
			
		||||
                    EekSymbol       *symbol,
 | 
			
		||||
                    EekModifierType  modifiers,
 | 
			
		||||
                    gboolean pressed,
 | 
			
		||||
                    uint32_t timestamp)
 | 
			
		||||
{
 | 
			
		||||
@ -136,5 +323,5 @@ emit_key_activated (EekboardContextService *manager,
 | 
			
		||||
    emitter.virtual_keyboard = manager->virtual_keyboard;
 | 
			
		||||
    emitter.keymap = keyboard->keymap;
 | 
			
		||||
    update_modifier_info (&emitter);
 | 
			
		||||
    send_fake_key (&emitter, keyboard, keycode, pressed, timestamp);
 | 
			
		||||
    send_fake_key_events (&emitter, symbol, modifiers, pressed, timestamp);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -3,6 +3,7 @@
 | 
			
		||||
 | 
			
		||||
#include <inttypes.h>
 | 
			
		||||
#include <glib.h>
 | 
			
		||||
#include <X11/XKBlib.h>
 | 
			
		||||
 | 
			
		||||
#include "eek/eek.h"
 | 
			
		||||
 | 
			
		||||
@ -39,7 +40,9 @@ enum mod_indices {
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
emit_key_activated (EekboardContextService *manager, LevelKeyboard *keyboard,
 | 
			
		||||
emit_key_activated (EekboardContextService *manager, EekKeyboard *keyboard,
 | 
			
		||||
                    guint            keycode,
 | 
			
		||||
                    EekSymbol       *symbol,
 | 
			
		||||
                    guint            modifiers,
 | 
			
		||||
                    gboolean pressed, uint32_t timestamp);
 | 
			
		||||
#endif // KEYEMITTER_H
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										66
									
								
								eekboard/keymap.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										66
									
								
								eekboard/keymap.c
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,66 @@
 | 
			
		||||
/* GDK - The GIMP Drawing Kit
 | 
			
		||||
 * Copyright (C) 2000 Red Hat, Inc.
 | 
			
		||||
 * Copyright (C) 2019 Purism, SPC
 | 
			
		||||
 *
 | 
			
		||||
 * This library is free software; you can redistribute it and/or
 | 
			
		||||
 * modify it under the terms of the GNU Lesser General Public
 | 
			
		||||
 * License as published by the Free Software Foundation; either
 | 
			
		||||
 * version 2 of the License, or (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.         See the GNU
 | 
			
		||||
 * Lesser General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General Public
 | 
			
		||||
 * License along with this library. If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
/*
 | 
			
		||||
 * Modified for squeekboard based on GTK
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "keymap.h"
 | 
			
		||||
 | 
			
		||||
gboolean
 | 
			
		||||
squeek_keymap_get_entries_for_keyval (struct xkb_keymap     *xkb_keymap,
 | 
			
		||||
                                      guint          keyval,
 | 
			
		||||
                                      GdkKeymapKey **keys,
 | 
			
		||||
                                      guint          *n_keys)
 | 
			
		||||
{
 | 
			
		||||
  GArray *retval;
 | 
			
		||||
  guint keycode;
 | 
			
		||||
  xkb_keycode_t min_keycode, max_keycode;
 | 
			
		||||
  retval = g_array_new (FALSE, FALSE, sizeof (GdkKeymapKey));
 | 
			
		||||
  min_keycode = xkb_keymap_min_keycode (xkb_keymap);
 | 
			
		||||
  max_keycode = xkb_keymap_max_keycode (xkb_keymap);
 | 
			
		||||
  for (keycode = min_keycode; keycode < max_keycode; keycode++)
 | 
			
		||||
    {
 | 
			
		||||
      xkb_layout_index_t num_layouts, layout;
 | 
			
		||||
      num_layouts = xkb_keymap_num_layouts_for_key (xkb_keymap, keycode);
 | 
			
		||||
      for (layout = 0; layout < num_layouts; layout++)
 | 
			
		||||
        {
 | 
			
		||||
          xkb_layout_index_t num_levels, level;
 | 
			
		||||
          num_levels = xkb_keymap_num_levels_for_key (xkb_keymap, keycode, layout);
 | 
			
		||||
          for (level = 0; level < num_levels; level++)
 | 
			
		||||
            {
 | 
			
		||||
              const xkb_keysym_t *syms;
 | 
			
		||||
              gint num_syms, sym;
 | 
			
		||||
              num_syms = xkb_keymap_key_get_syms_by_level (xkb_keymap, keycode, layout, level, &syms);
 | 
			
		||||
              for (sym = 0; sym < num_syms; sym++)
 | 
			
		||||
                {
 | 
			
		||||
                  if (syms[sym] == keyval)
 | 
			
		||||
                    {
 | 
			
		||||
                      GdkKeymapKey key;
 | 
			
		||||
                      key.keycode = keycode;
 | 
			
		||||
                      key.group = (gint)layout;
 | 
			
		||||
                      key.level = (gint)level;
 | 
			
		||||
                      g_array_append_val (retval, key);
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
  *n_keys = retval->len;
 | 
			
		||||
  *keys = (GdkKeymapKey*) g_array_free (retval, FALSE);
 | 
			
		||||
  return TRUE;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										8
									
								
								eekboard/keymap.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								eekboard/keymap.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,8 @@
 | 
			
		||||
#include <gdk/gdk.h>
 | 
			
		||||
#include <xkbcommon/xkbcommon.h>
 | 
			
		||||
 | 
			
		||||
gboolean
 | 
			
		||||
squeek_keymap_get_entries_for_keyval (struct xkb_keymap     *xkb_keymap,
 | 
			
		||||
                                      guint          keyval,
 | 
			
		||||
                                      GdkKeymapKey **keys,
 | 
			
		||||
                                      guint          *n_keys);
 | 
			
		||||
							
								
								
									
										32
									
								
								meson.build
									
									
									
									
									
								
							
							
						
						
									
										32
									
								
								meson.build
									
									
									
									
									
								
							@ -3,29 +3,12 @@ project(
 | 
			
		||||
    'c', 'rust',
 | 
			
		||||
    version: '1.0.10',
 | 
			
		||||
    license: 'GPLv3',
 | 
			
		||||
    meson_version: '>=0.49.0',
 | 
			
		||||
    default_options: [
 | 
			
		||||
        'warning_level=1',
 | 
			
		||||
        'buildtype=debugoptimized',
 | 
			
		||||
        'c_std=gnu11'
 | 
			
		||||
    ]
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
add_project_arguments(
 | 
			
		||||
  [
 | 
			
		||||
    '-Werror=implicit-function-declaration',
 | 
			
		||||
    '-Werror=implicit-fallthrough=3',
 | 
			
		||||
    '-Werror=maybe-uninitialized',
 | 
			
		||||
    '-Werror=missing-field-initializers',
 | 
			
		||||
    '-Werror=incompatible-pointer-types',
 | 
			
		||||
  ],
 | 
			
		||||
  language: 'c'
 | 
			
		||||
    meson_version: '>=0.43.0',
 | 
			
		||||
    default_options: [ 'warning_level=1', 'buildtype=debugoptimized', 'c_std=gnu11' ],
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
i18n = import('i18n')
 | 
			
		||||
 | 
			
		||||
conf_data = configuration_data()
 | 
			
		||||
 | 
			
		||||
if get_option('buildtype').startswith('debug')
 | 
			
		||||
    add_project_arguments('-DDEBUG=1', language : 'c')
 | 
			
		||||
endif
 | 
			
		||||
@ -43,19 +26,8 @@ else
 | 
			
		||||
endif
 | 
			
		||||
dbusdir = join_paths(depdatadir, 'dbus-1/interfaces')
 | 
			
		||||
 | 
			
		||||
summary = [
 | 
			
		||||
        '',
 | 
			
		||||
        '------------------',
 | 
			
		||||
        'squeekboard @0@'.format(meson.project_version()),
 | 
			
		||||
        '',
 | 
			
		||||
        '------------------',
 | 
			
		||||
        ''
 | 
			
		||||
]
 | 
			
		||||
message('\n'.join(summary))
 | 
			
		||||
 | 
			
		||||
subdir('data')
 | 
			
		||||
subdir('protocols')
 | 
			
		||||
subdir('eek')
 | 
			
		||||
subdir('src')
 | 
			
		||||
subdir('po')
 | 
			
		||||
subdir('tests')
 | 
			
		||||
 | 
			
		||||
@ -1,8 +1 @@
 | 
			
		||||
option('depdatadir',
 | 
			
		||||
       type : 'string',
 | 
			
		||||
       value : '',
 | 
			
		||||
       description : 'System data path. Will be searched for definitions instead of datadir when provided')
 | 
			
		||||
 | 
			
		||||
option('tests',
 | 
			
		||||
       type: 'boolean', value: true,
 | 
			
		||||
       description: 'Whether to compile unit tests')
 | 
			
		||||
option('depdatadir', type : 'string', value : '', description : 'System data path. Will be searched for definitions instead of datadir when provided')
 | 
			
		||||
 | 
			
		||||
@ -11,10 +11,10 @@ gen_scanner_client_code = generator(wl_scanner,
 | 
			
		||||
 | 
			
		||||
wl_protos = [
 | 
			
		||||
  wl_protocol_dir + '/stable/xdg-shell/xdg-shell.xml',
 | 
			
		||||
  wl_protocol_dir + '/unstable/text-input/text-input-unstable-v3.xml',
 | 
			
		||||
  'wlr-layer-shell-unstable-v1.xml',
 | 
			
		||||
  'virtual-keyboard-unstable-v1.xml',
 | 
			
		||||
  'input-method-unstable-v2.xml',
 | 
			
		||||
  'text-input-unstable-v3.xml'
 | 
			
		||||
]
 | 
			
		||||
wl_proto_sources = []
 | 
			
		||||
foreach proto: wl_protos
 | 
			
		||||
 | 
			
		||||
@ -1,441 +0,0 @@
 | 
			
		||||
<?xml version="1.0" encoding="UTF-8"?>
 | 
			
		||||
 | 
			
		||||
<protocol name="text_input_unstable_v3">
 | 
			
		||||
  <copyright>
 | 
			
		||||
    Copyright © 2012, 2013 Intel Corporation
 | 
			
		||||
    Copyright © 2015, 2016 Jan Arne Petersen
 | 
			
		||||
    Copyright © 2017, 2018 Red Hat, Inc.
 | 
			
		||||
    Copyright © 2018       Purism SPC
 | 
			
		||||
 | 
			
		||||
    Permission to use, copy, modify, distribute, and sell this
 | 
			
		||||
    software and its documentation for any purpose is hereby granted
 | 
			
		||||
    without fee, provided that the above copyright notice appear in
 | 
			
		||||
    all copies and that both that copyright notice and this permission
 | 
			
		||||
    notice appear in supporting documentation, and that the name of
 | 
			
		||||
    the copyright holders not be used in advertising or publicity
 | 
			
		||||
    pertaining to distribution of the software without specific,
 | 
			
		||||
    written prior permission.  The copyright holders make no
 | 
			
		||||
    representations about the suitability of this software for any
 | 
			
		||||
    purpose.  It is provided "as is" without express or implied
 | 
			
		||||
    warranty.
 | 
			
		||||
 | 
			
		||||
    THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
 | 
			
		||||
    SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
 | 
			
		||||
    FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
 | 
			
		||||
    SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 | 
			
		||||
    WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
 | 
			
		||||
    AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
 | 
			
		||||
    ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
 | 
			
		||||
    THIS SOFTWARE.
 | 
			
		||||
  </copyright>
 | 
			
		||||
 | 
			
		||||
  <description summary="Protocol for composing text">
 | 
			
		||||
    This protocol allows compositors to act as input methods and to send text
 | 
			
		||||
    to applications. A text input object is used to manage state of what are
 | 
			
		||||
    typically text entry fields in the application.
 | 
			
		||||
 | 
			
		||||
    This document adheres to the RFC 2119 when using words like "must",
 | 
			
		||||
    "should", "may", etc.
 | 
			
		||||
 | 
			
		||||
    Warning! The protocol described in this file is experimental and
 | 
			
		||||
    backward incompatible changes may be made. Backward compatible changes
 | 
			
		||||
    may be added together with the corresponding interface version bump.
 | 
			
		||||
    Backward incompatible changes are done by bumping the version number in
 | 
			
		||||
    the protocol and interface names and resetting the interface version.
 | 
			
		||||
    Once the protocol is to be declared stable, the 'z' prefix and the
 | 
			
		||||
    version number in the protocol and interface names are removed and the
 | 
			
		||||
    interface version number is reset.
 | 
			
		||||
  </description>
 | 
			
		||||
 | 
			
		||||
  <interface name="zwp_text_input_v3" version="1">
 | 
			
		||||
    <description summary="text input">
 | 
			
		||||
      The zwp_text_input_v3 interface represents text input and input methods
 | 
			
		||||
      associated with a seat. It provides enter/leave events to follow the
 | 
			
		||||
      text input focus for a seat.
 | 
			
		||||
 | 
			
		||||
      Requests are used to enable/disable the text-input object and set
 | 
			
		||||
      state information like surrounding and selected text or the content type.
 | 
			
		||||
      The information about the entered text is sent to the text-input object
 | 
			
		||||
      via the preedit_string and commit_string events.
 | 
			
		||||
 | 
			
		||||
      Text is valid UTF-8 encoded, indices and lengths are in bytes. Indices
 | 
			
		||||
      must not point to middle bytes inside a code point: they must either
 | 
			
		||||
      point to the first byte of a code point or to the end of the buffer.
 | 
			
		||||
      Lengths must be measured between two valid indices.
 | 
			
		||||
 | 
			
		||||
      Focus moving throughout surfaces will result in the emission of
 | 
			
		||||
      zwp_text_input_v3.enter and zwp_text_input_v3.leave events. The focused
 | 
			
		||||
      surface must commit zwp_text_input_v3.enable and
 | 
			
		||||
      zwp_text_input_v3.disable requests as the keyboard focus moves across
 | 
			
		||||
      editable and non-editable elements of the UI. Those two requests are not
 | 
			
		||||
      expected to be paired with each other, the compositor must be able to
 | 
			
		||||
      handle consecutive series of the same request.
 | 
			
		||||
 | 
			
		||||
      State is sent by the state requests (set_surrounding_text,
 | 
			
		||||
      set_content_type and set_cursor_rectangle) and a commit request. After an
 | 
			
		||||
      enter event or disable request all state information is invalidated and
 | 
			
		||||
      needs to be resent by the client.
 | 
			
		||||
    </description>
 | 
			
		||||
 | 
			
		||||
    <request name="destroy" type="destructor">
 | 
			
		||||
      <description summary="Destroy the wp_text_input">
 | 
			
		||||
        Destroy the wp_text_input object. Also disables all surfaces enabled
 | 
			
		||||
        through this wp_text_input object.
 | 
			
		||||
      </description>
 | 
			
		||||
    </request>
 | 
			
		||||
 | 
			
		||||
    <request name="enable">
 | 
			
		||||
      <description summary="Request text input to be enabled">
 | 
			
		||||
        Requests text input on the surface previously obtained from the enter
 | 
			
		||||
        event.
 | 
			
		||||
 | 
			
		||||
        This request must be issued every time the active text input changes
 | 
			
		||||
        to a new one, including within the current surface. Use
 | 
			
		||||
        zwp_text_input_v3.disable when there is no longer any input focus on
 | 
			
		||||
        the current surface.
 | 
			
		||||
 | 
			
		||||
        This request resets all state associated with previous enable, disable,
 | 
			
		||||
        set_surrounding_text, set_text_change_cause, set_content_type, and
 | 
			
		||||
        set_cursor_rectangle requests, as well as the state associated with
 | 
			
		||||
        preedit_string, commit_string, and delete_surrounding_text events.
 | 
			
		||||
 | 
			
		||||
        The set_surrounding_text, set_content_type and set_cursor_rectangle
 | 
			
		||||
        requests must follow if the text input supports the necessary
 | 
			
		||||
        functionality.
 | 
			
		||||
 | 
			
		||||
        State set with this request is double-buffered. It will get applied on
 | 
			
		||||
        the next zwp_text_input_v3.commit request, and stay valid until the
 | 
			
		||||
        next committed enable or disable request.
 | 
			
		||||
 | 
			
		||||
        The changes must be applied by the compositor after issuing a
 | 
			
		||||
        zwp_text_input_v3.commit request.
 | 
			
		||||
      </description>
 | 
			
		||||
    </request>
 | 
			
		||||
 | 
			
		||||
    <request name="disable">
 | 
			
		||||
      <description summary="Disable text input on a surface">
 | 
			
		||||
        Explicitly disable text input on the current surface (typically when
 | 
			
		||||
        there is no focus on any text entry inside the surface).
 | 
			
		||||
 | 
			
		||||
        State set with this request is double-buffered. It will get applied on
 | 
			
		||||
        the next zwp_text_input_v3.commit request.
 | 
			
		||||
      </description>
 | 
			
		||||
    </request>
 | 
			
		||||
 | 
			
		||||
    <request name="set_surrounding_text">
 | 
			
		||||
      <description summary="sets the surrounding text">
 | 
			
		||||
        Sets the surrounding plain text around the input, excluding the preedit
 | 
			
		||||
        text.
 | 
			
		||||
 | 
			
		||||
        The client should notify the compositor of any changes in any of the
 | 
			
		||||
        values carried with this request, including changes caused by handling
 | 
			
		||||
        incoming text-input events as well as changes caused by other
 | 
			
		||||
        mechanisms like keyboard typing.
 | 
			
		||||
 | 
			
		||||
        If the client is unaware of the text around the cursor, it should not
 | 
			
		||||
        issue this request, to signify lack of support to the compositor.
 | 
			
		||||
 | 
			
		||||
        Text is UTF-8 encoded, and should include the cursor position, the
 | 
			
		||||
        complete selection and additional characters before and after them.
 | 
			
		||||
        There is a maximum length of wayland messages, so text can not be
 | 
			
		||||
        longer than 4000 bytes.
 | 
			
		||||
 | 
			
		||||
        Cursor is the byte offset of the cursor within text buffer.
 | 
			
		||||
 | 
			
		||||
        Anchor is the byte offset of the selection anchor within text buffer.
 | 
			
		||||
        If there is no selected text, anchor is the same as cursor.
 | 
			
		||||
 | 
			
		||||
        If any preedit text is present, it is replaced with a cursor for the
 | 
			
		||||
        purpose of this event.
 | 
			
		||||
 | 
			
		||||
        Values set with this request are double-buffered. They will get applied
 | 
			
		||||
        on the next zwp_text_input_v3.commit request, and stay valid until the
 | 
			
		||||
        next committed enable or disable request.
 | 
			
		||||
 | 
			
		||||
        The initial state for affected fields is empty, meaning that the text
 | 
			
		||||
        input does not support sending surrounding text. If the empty values
 | 
			
		||||
        get applied, subsequent attempts to change them may have no effect.
 | 
			
		||||
      </description>
 | 
			
		||||
      <arg name="text" type="string"/>
 | 
			
		||||
      <arg name="cursor" type="int"/>
 | 
			
		||||
      <arg name="anchor" type="int"/>
 | 
			
		||||
    </request>
 | 
			
		||||
 | 
			
		||||
    <enum name="change_cause">
 | 
			
		||||
      <description summary="text change reason">
 | 
			
		||||
        Reason for the change of surrounding text or cursor posision.
 | 
			
		||||
      </description>
 | 
			
		||||
      <entry name="input_method" value="0" summary="input method caused the change"/>
 | 
			
		||||
      <entry name="other" value="1" summary="something else than the input method caused the change"/>
 | 
			
		||||
    </enum>
 | 
			
		||||
 | 
			
		||||
    <request name="set_text_change_cause">
 | 
			
		||||
      <description summary="indicates the cause of surrounding text change">
 | 
			
		||||
        Tells the compositor why the text surrounding the cursor changed.
 | 
			
		||||
 | 
			
		||||
        Whenever the client detects an external change in text, cursor, or
 | 
			
		||||
        anchor posision, it must issue this request to the compositor. This
 | 
			
		||||
        request is intended to give the input method a chance to update the
 | 
			
		||||
        preedit text in an appropriate way, e.g. by removing it when the user
 | 
			
		||||
        starts typing with a keyboard.
 | 
			
		||||
 | 
			
		||||
        cause describes the source of the change.
 | 
			
		||||
 | 
			
		||||
        The value set with this request is double-buffered. It must be applied
 | 
			
		||||
        and reset to initial at the next zwp_text_input_v3.commit request.
 | 
			
		||||
 | 
			
		||||
        The initial value of cause is input_method.
 | 
			
		||||
      </description>
 | 
			
		||||
      <arg name="cause" type="uint" enum="change_cause"/>
 | 
			
		||||
    </request>
 | 
			
		||||
 | 
			
		||||
    <enum name="content_hint" bitfield="true">
 | 
			
		||||
      <description summary="content hint">
 | 
			
		||||
        Content hint is a bitmask to allow to modify the behavior of the text
 | 
			
		||||
        input.
 | 
			
		||||
      </description>
 | 
			
		||||
      <entry name="none" value="0x0" summary="no special behavior"/>
 | 
			
		||||
      <entry name="completion" value="0x1" summary="suggest word completions"/>
 | 
			
		||||
      <entry name="spellcheck" value="0x2" summary="suggest word corrections"/>
 | 
			
		||||
      <entry name="auto_capitalization" value="0x4" summary="switch to uppercase letters at the start of a sentence"/>
 | 
			
		||||
      <entry name="lowercase" value="0x8" summary="prefer lowercase letters"/>
 | 
			
		||||
      <entry name="uppercase" value="0x10" summary="prefer uppercase letters"/>
 | 
			
		||||
      <entry name="titlecase" value="0x20" summary="prefer casing for titles and headings (can be language dependent)"/>
 | 
			
		||||
      <entry name="hidden_text" value="0x40" summary="characters should be hidden"/>
 | 
			
		||||
      <entry name="sensitive_data" value="0x80" summary="typed text should not be stored"/>
 | 
			
		||||
      <entry name="latin" value="0x100" summary="just Latin characters should be entered"/>
 | 
			
		||||
      <entry name="multiline" value="0x200" summary="the text input is multiline"/>
 | 
			
		||||
    </enum>
 | 
			
		||||
 | 
			
		||||
    <enum name="content_purpose">
 | 
			
		||||
      <description summary="content purpose">
 | 
			
		||||
        The content purpose allows to specify the primary purpose of a text
 | 
			
		||||
        input.
 | 
			
		||||
 | 
			
		||||
        This allows an input method to show special purpose input panels with
 | 
			
		||||
        extra characters or to disallow some characters.
 | 
			
		||||
      </description>
 | 
			
		||||
      <entry name="normal" value="0" summary="default input, allowing all characters"/>
 | 
			
		||||
      <entry name="alpha" value="1" summary="allow only alphabetic characters"/>
 | 
			
		||||
      <entry name="digits" value="2" summary="allow only digits"/>
 | 
			
		||||
      <entry name="number" value="3" summary="input a number (including decimal separator and sign)"/>
 | 
			
		||||
      <entry name="phone" value="4" summary="input a phone number"/>
 | 
			
		||||
      <entry name="url" value="5" summary="input an URL"/>
 | 
			
		||||
      <entry name="email" value="6" summary="input an email address"/>
 | 
			
		||||
      <entry name="name" value="7" summary="input a name of a person"/>
 | 
			
		||||
      <entry name="password" value="8" summary="input a password (combine with sensitive_data hint)"/>
 | 
			
		||||
      <entry name="pin" value="9" summary="input is a numeric password (combine with sensitive_data hint)"/>
 | 
			
		||||
      <entry name="date" value="10" summary="input a date"/>
 | 
			
		||||
      <entry name="time" value="11" summary="input a time"/>
 | 
			
		||||
      <entry name="datetime" value="12" summary="input a date and time"/>
 | 
			
		||||
      <entry name="terminal" value="13" summary="input for a terminal"/>
 | 
			
		||||
    </enum>
 | 
			
		||||
 | 
			
		||||
    <request name="set_content_type">
 | 
			
		||||
      <description summary="set content purpose and hint">
 | 
			
		||||
        Sets the content purpose and content hint. While the purpose is the
 | 
			
		||||
        basic purpose of an input field, the hint flags allow to modify some of
 | 
			
		||||
        the behavior.
 | 
			
		||||
 | 
			
		||||
        Values set with this request are double-buffered. They will get applied
 | 
			
		||||
        on the next zwp_text_input_v3.commit request.
 | 
			
		||||
        Subsequent attempts to update them may have no effect. The values
 | 
			
		||||
        remain valid until the next committed enable or disable request.
 | 
			
		||||
 | 
			
		||||
        The initial value for hint is none, and the initial value for purpose
 | 
			
		||||
        is normal.
 | 
			
		||||
      </description>
 | 
			
		||||
      <arg name="hint" type="uint" enum="content_hint"/>
 | 
			
		||||
      <arg name="purpose" type="uint" enum="content_purpose"/>
 | 
			
		||||
    </request>
 | 
			
		||||
 | 
			
		||||
    <request name="set_cursor_rectangle">
 | 
			
		||||
      <description summary="set cursor position">
 | 
			
		||||
        Marks an area around the cursor as a x, y, width, height rectangle in
 | 
			
		||||
        surface local coordinates.
 | 
			
		||||
 | 
			
		||||
        Allows the compositor to put a window with word suggestions near the
 | 
			
		||||
        cursor, without obstructing the text being input.
 | 
			
		||||
 | 
			
		||||
        If the client is unaware of the position of edited text, it should not
 | 
			
		||||
        issue this request, to signify lack of support to the compositor.
 | 
			
		||||
 | 
			
		||||
        Values set with this request are double-buffered. They will get applied
 | 
			
		||||
        on the next zwp_text_input_v3.commit request, and stay valid until the
 | 
			
		||||
        next committed enable or disable request.
 | 
			
		||||
 | 
			
		||||
        The initial values describing a cursor rectangle are empty. That means
 | 
			
		||||
        the text input does not support describing the cursor area. If the
 | 
			
		||||
        empty values get applied, subsequent attempts to change them may have
 | 
			
		||||
        no effect.
 | 
			
		||||
      </description>
 | 
			
		||||
      <arg name="x" type="int"/>
 | 
			
		||||
      <arg name="y" type="int"/>
 | 
			
		||||
      <arg name="width" type="int"/>
 | 
			
		||||
      <arg name="height" type="int"/>
 | 
			
		||||
    </request>
 | 
			
		||||
 | 
			
		||||
    <request name="commit">
 | 
			
		||||
      <description summary="commit state">
 | 
			
		||||
        Atomically applies state changes recently sent to the compositor.
 | 
			
		||||
 | 
			
		||||
        The commit request establishes and updates the state of the client, and
 | 
			
		||||
        must be issued after any changes to apply them.
 | 
			
		||||
 | 
			
		||||
        Text input state (enabled status, content purpose, content hint,
 | 
			
		||||
        surrounding text and change cause, cursor rectangle) is conceptually
 | 
			
		||||
        double-buffered within the context of a text input, i.e. between a
 | 
			
		||||
        committed enable request and the following committed enable or disable
 | 
			
		||||
        request.
 | 
			
		||||
 | 
			
		||||
        Protocol requests modify the pending state, as opposed to the current
 | 
			
		||||
        state in use by the input method. A commit request atomically applies
 | 
			
		||||
        all pending state, replacing the current state. After commit, the new
 | 
			
		||||
        pending state is as documented for each related request.
 | 
			
		||||
 | 
			
		||||
        Requests are applied in the order of arrival.
 | 
			
		||||
 | 
			
		||||
        Neither current nor pending state are modified unless noted otherwise.
 | 
			
		||||
 | 
			
		||||
        The compositor must count the number of commit requests coming from
 | 
			
		||||
        each zwp_text_input_v3 object and use the count as the serial in done
 | 
			
		||||
        events.
 | 
			
		||||
      </description>
 | 
			
		||||
    </request>
 | 
			
		||||
 | 
			
		||||
    <event name="enter">
 | 
			
		||||
      <description summary="enter event">
 | 
			
		||||
        Notification that this seat's text-input focus is on a certain surface.
 | 
			
		||||
 | 
			
		||||
        When the seat has the keyboard capability the text-input focus follows
 | 
			
		||||
        the keyboard focus. This event sets the current surface for the
 | 
			
		||||
        text-input object.
 | 
			
		||||
      </description>
 | 
			
		||||
      <arg name="surface" type="object" interface="wl_surface"/>
 | 
			
		||||
    </event>
 | 
			
		||||
 | 
			
		||||
    <event name="leave">
 | 
			
		||||
      <description summary="leave event">
 | 
			
		||||
        Notification that this seat's text-input focus is no longer on a
 | 
			
		||||
        certain surface. The client should reset any preedit string previously
 | 
			
		||||
        set.
 | 
			
		||||
 | 
			
		||||
        The leave notification clears the current surface. It is sent before
 | 
			
		||||
        the enter notification for the new focus.
 | 
			
		||||
 | 
			
		||||
        When the seat has the keyboard capability the text-input focus follows
 | 
			
		||||
        the keyboard focus.
 | 
			
		||||
      </description>
 | 
			
		||||
      <arg name="surface" type="object" interface="wl_surface"/>
 | 
			
		||||
    </event>
 | 
			
		||||
 | 
			
		||||
    <event name="preedit_string">
 | 
			
		||||
      <description summary="pre-edit">
 | 
			
		||||
        Notify when a new composing text (pre-edit) should be set at the
 | 
			
		||||
        current cursor position. Any previously set composing text must be
 | 
			
		||||
        removed. Any previously existing selected text must be removed.
 | 
			
		||||
 | 
			
		||||
        The argument text contains the pre-edit string buffer.
 | 
			
		||||
 | 
			
		||||
        The parameters cursor_begin and cursor_end are counted in bytes
 | 
			
		||||
        relative to the beginning of the submitted text buffer. Cursor should
 | 
			
		||||
        be hidden when both are equal to -1.
 | 
			
		||||
 | 
			
		||||
        They could be represented by the client as a line if both values are
 | 
			
		||||
        the same, or as a text highlight otherwise.
 | 
			
		||||
 | 
			
		||||
        Values set with this event are double-buffered. They must be applied
 | 
			
		||||
        and reset to initial on the next zwp_text_input_v3.done event.
 | 
			
		||||
 | 
			
		||||
        The initial value of text is an empty string, and cursor_begin,
 | 
			
		||||
        cursor_end and cursor_hidden are all 0.
 | 
			
		||||
      </description>
 | 
			
		||||
      <arg name="text" type="string" allow-null="true"/>
 | 
			
		||||
      <arg name="cursor_begin" type="int"/>
 | 
			
		||||
      <arg name="cursor_end" type="int"/>
 | 
			
		||||
    </event>
 | 
			
		||||
 | 
			
		||||
    <event name="commit_string">
 | 
			
		||||
      <description summary="text commit">
 | 
			
		||||
        Notify when text should be inserted into the editor widget. The text to
 | 
			
		||||
        commit could be either just a single character after a key press or the
 | 
			
		||||
        result of some composing (pre-edit).
 | 
			
		||||
 | 
			
		||||
        Values set with this event are double-buffered. They must be applied
 | 
			
		||||
        and reset to initial on the next zwp_text_input_v3.done event.
 | 
			
		||||
 | 
			
		||||
        The initial value of text is an empty string.
 | 
			
		||||
      </description>
 | 
			
		||||
      <arg name="text" type="string" allow-null="true"/>
 | 
			
		||||
    </event>
 | 
			
		||||
 | 
			
		||||
    <event name="delete_surrounding_text">
 | 
			
		||||
      <description summary="delete surrounding text">
 | 
			
		||||
        Notify when the text around the current cursor position should be
 | 
			
		||||
        deleted.
 | 
			
		||||
 | 
			
		||||
        Before_length and after_length are the number of bytes before and after
 | 
			
		||||
        the current cursor index (excluding the selection) to delete.
 | 
			
		||||
 | 
			
		||||
        If a preedit text is present, in effect before_length is counted from
 | 
			
		||||
        the beginning of it, and after_length from its end (see done event
 | 
			
		||||
        sequence).
 | 
			
		||||
 | 
			
		||||
        Values set with this event are double-buffered. They must be applied
 | 
			
		||||
        and reset to initial on the next zwp_text_input_v3.done event.
 | 
			
		||||
 | 
			
		||||
        The initial values of both before_length and after_length are 0.
 | 
			
		||||
      </description>
 | 
			
		||||
      <arg name="before_length" type="uint" summary="length of text before current cursor position"/>
 | 
			
		||||
      <arg name="after_length" type="uint" summary="length of text after current cursor position"/>
 | 
			
		||||
    </event>
 | 
			
		||||
 | 
			
		||||
    <event name="done">
 | 
			
		||||
      <description summary="apply changes">
 | 
			
		||||
        Instruct the application to apply changes to state requested by the
 | 
			
		||||
        preedit_string, commit_string and delete_surrounding_text events. The
 | 
			
		||||
        state relating to these events is double-buffered, and each one
 | 
			
		||||
        modifies the pending state. This event replaces the current state with
 | 
			
		||||
        the pending state.
 | 
			
		||||
 | 
			
		||||
        The application must proceed by evaluating the changes in the following
 | 
			
		||||
        order:
 | 
			
		||||
 | 
			
		||||
        1. Replace existing preedit string with the cursor.
 | 
			
		||||
        2. Delete requested surrounding text.
 | 
			
		||||
        3. Insert commit string with the cursor at its end.
 | 
			
		||||
        4. Calculate surrounding text to send.
 | 
			
		||||
        5. Insert new preedit text in cursor position.
 | 
			
		||||
        6. Place cursor inside preedit text.
 | 
			
		||||
 | 
			
		||||
        The serial number reflects the last state of the zwp_text_input_v3
 | 
			
		||||
        object known to the compositor. The value of the serial argument must
 | 
			
		||||
        be equal to the number of commit requests already issued on that object.
 | 
			
		||||
        When the client receives a done event with a serial different than the
 | 
			
		||||
        number of past commit requests, it must proceed as normal, except it
 | 
			
		||||
        should not change the current state of the zwp_text_input_v3 object.
 | 
			
		||||
      </description>
 | 
			
		||||
      <arg name="serial" type="uint"/>
 | 
			
		||||
    </event>
 | 
			
		||||
  </interface>
 | 
			
		||||
 | 
			
		||||
  <interface name="zwp_text_input_manager_v3" version="1">
 | 
			
		||||
    <description summary="text input manager">
 | 
			
		||||
      A factory for text-input objects. This object is a global singleton.
 | 
			
		||||
    </description>
 | 
			
		||||
 | 
			
		||||
    <request name="destroy" type="destructor">
 | 
			
		||||
      <description summary="Destroy the wp_text_input_manager">
 | 
			
		||||
        Destroy the wp_text_input_manager object.
 | 
			
		||||
      </description>
 | 
			
		||||
    </request>
 | 
			
		||||
 | 
			
		||||
    <request name="get_text_input">
 | 
			
		||||
      <description summary="create a new text input object">
 | 
			
		||||
        Creates a new text-input object for a given seat.
 | 
			
		||||
      </description>
 | 
			
		||||
      <arg name="id" type="new_id" interface="zwp_text_input_v3"/>
 | 
			
		||||
      <arg name="seat" type="object" interface="wl_seat"/>
 | 
			
		||||
    </request>
 | 
			
		||||
  </interface>
 | 
			
		||||
</protocol>
 | 
			
		||||
							
								
								
									
										1350
									
								
								src/bitflags.rs
									
									
									
									
									
								
							
							
						
						
									
										1350
									
								
								src/bitflags.rs
									
									
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user