Compare commits
	
		
			6 Commits
		
	
	
		
			add-more-p
			...
			enable-tes
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| a175226ce3 | |||
| 7c53d75718 | |||
| fa32a03fbf | |||
| 53a6876830 | |||
| 629b15840a | |||
| ff3a7b02b6 | 
@ -28,4 +28,6 @@ test:
 | 
			
		||||
  dependencies:
 | 
			
		||||
    - build_meson
 | 
			
		||||
  script:
 | 
			
		||||
    - export LC_ALL=C.UTF-8
 | 
			
		||||
    - 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
 | 
			
		||||
 | 
			
		||||
@ -1,120 +1,120 @@
 | 
			
		||||
<?xml version="1.0"?>
 | 
			
		||||
<geometry version="0.90">
 | 
			
		||||
  <bounds x="10" y="10" width="410.0000" height="229"/>
 | 
			
		||||
  <bounds x="0" y="10.000000" width="426.0000" height="296.5853"/>
 | 
			
		||||
  <section angle="0">
 | 
			
		||||
    <row orientation="1">
 | 
			
		||||
      <key name="AD01" oref="outline2" />
 | 
			
		||||
      <key name="AD02" oref="outline2" />
 | 
			
		||||
      <key name="AD03" oref="outline2" />
 | 
			
		||||
      <key name="AD04" oref="outline2" />
 | 
			
		||||
      <key name="AD05" oref="outline2" />
 | 
			
		||||
      <key name="AD06" oref="outline2" />
 | 
			
		||||
      <key name="AD07" oref="outline2" />
 | 
			
		||||
      <key name="AD08" oref="outline2" />
 | 
			
		||||
      <key name="AD09" oref="outline2" />
 | 
			
		||||
      <key name="AD10" oref="outline2" />
 | 
			
		||||
      <key keycode="24" name="AD01" oref="outline2" />
 | 
			
		||||
      <key keycode="25" name="AD02" oref="outline2" />
 | 
			
		||||
      <key keycode="26" name="AD03" oref="outline2" />
 | 
			
		||||
      <key keycode="27" name="AD04" oref="outline2" />
 | 
			
		||||
      <key keycode="28" name="AD05" oref="outline2" />
 | 
			
		||||
      <key keycode="29" name="AD06" oref="outline2" />
 | 
			
		||||
      <key keycode="30" name="AD07" oref="outline2" />
 | 
			
		||||
      <key keycode="31" name="AD08" oref="outline2" />
 | 
			
		||||
      <key keycode="32" name="AD09" oref="outline2" />
 | 
			
		||||
      <key keycode="33" name="AD10" oref="outline2" />
 | 
			
		||||
    </row>
 | 
			
		||||
  </section>
 | 
			
		||||
  <section angle="0">
 | 
			
		||||
    <row orientation="1">
 | 
			
		||||
      <key name="AC01" oref="outline2" />
 | 
			
		||||
      <key name="AC02" oref="outline2" />
 | 
			
		||||
      <key name="AC03" oref="outline2" />
 | 
			
		||||
      <key name="AC04" oref="outline2" />
 | 
			
		||||
      <key name="AC05" oref="outline2" />
 | 
			
		||||
      <key name="AC06" oref="outline2" />
 | 
			
		||||
      <key name="AC07" oref="outline2" />
 | 
			
		||||
      <key name="AC08" oref="outline2" />
 | 
			
		||||
      <key name="AC09" oref="outline2" />
 | 
			
		||||
      <key name="AC10" oref="outline2" />
 | 
			
		||||
      <key keycode="38" name="AC01" oref="outline2" />
 | 
			
		||||
      <key keycode="39" name="AC02" oref="outline2" />
 | 
			
		||||
      <key keycode="40" name="AC03" oref="outline2" />
 | 
			
		||||
      <key keycode="41" name="AC04" oref="outline2" />
 | 
			
		||||
      <key keycode="42" name="AC05" oref="outline2" />
 | 
			
		||||
      <key keycode="43" name="AC06" oref="outline2" />
 | 
			
		||||
      <key keycode="44" name="AC07" oref="outline2" />
 | 
			
		||||
      <key keycode="45" name="AC08" oref="outline2" />
 | 
			
		||||
      <key keycode="46" name="AC09" oref="outline2" />
 | 
			
		||||
      <key keycode="47" name="AC10" oref="outline2" />
 | 
			
		||||
    </row>
 | 
			
		||||
  </section>
 | 
			
		||||
  <section angle="0">
 | 
			
		||||
    <row orientation="1">
 | 
			
		||||
      <key name="LFSH" oref="altline" />
 | 
			
		||||
      <key name="AB01" oref="outline2" />
 | 
			
		||||
      <key name="AB02" oref="outline2" />
 | 
			
		||||
      <key name="AB03" oref="outline2" />
 | 
			
		||||
      <key name="AB04" oref="outline2" />
 | 
			
		||||
      <key name="AB05" oref="outline2" />
 | 
			
		||||
      <key name="AB06" oref="outline2" />
 | 
			
		||||
      <key name="AB07" oref="outline2" />
 | 
			
		||||
      <key name="BKSP" oref="altline" />
 | 
			
		||||
      <key keycode="50" name="LFSH" oref="altline" />
 | 
			
		||||
      <key keycode="52" name="AB01" oref="outline2" />
 | 
			
		||||
      <key keycode="53" name="AB02" oref="outline2" />
 | 
			
		||||
      <key keycode="54" name="AB03" oref="outline2" />
 | 
			
		||||
      <key keycode="55" name="AB04" oref="outline2" />
 | 
			
		||||
      <key keycode="56" name="AB05" oref="outline2" />
 | 
			
		||||
      <key keycode="57" name="AB06" oref="outline2" />
 | 
			
		||||
      <key keycode="58" name="AB07" oref="outline2" />
 | 
			
		||||
      <key keycode="22" name="BKSP" oref="altline" />
 | 
			
		||||
    </row>
 | 
			
		||||
  </section>
 | 
			
		||||
  <section angle="0">
 | 
			
		||||
    <row orientation="1">
 | 
			
		||||
      <key keycode="0" name="ABC123" oref="altline" />
 | 
			
		||||
      <key name="I149" oref="altline" />
 | 
			
		||||
      <key name="SPCE" oref="spaceline" />
 | 
			
		||||
      <key name="AB08" oref="outline2" />
 | 
			
		||||
      <key name="RTRN" oref="outline7" />
 | 
			
		||||
      <key keycode="149" name="I149" oref="altline" />
 | 
			
		||||
      <key keycode="65" name="SPCE" oref="spaceline" />
 | 
			
		||||
      <key keycode="59" name="AB08" oref="outline2" />
 | 
			
		||||
      <key keycode="36" name="RTRN" oref="outline7" />
 | 
			
		||||
    </row>
 | 
			
		||||
  </section>
 | 
			
		||||
  <outline id="outline2" corner-radius="1.000000">
 | 
			
		||||
    <point x="0.000000" y="0.000000"/>
 | 
			
		||||
    <point x="37.46341" y="0.000000"/>
 | 
			
		||||
    <point x="37.46341" y="52"/>
 | 
			
		||||
    <point x="0.000000" y="52"/>
 | 
			
		||||
    <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"/>
 | 
			
		||||
    <point x="0.000000" y="52"/>
 | 
			
		||||
    <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"/>
 | 
			
		||||
    <point x="0.000000" y="52"/>
 | 
			
		||||
    <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"/>
 | 
			
		||||
    <point x="0.000000" y="52"/>
 | 
			
		||||
    <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"/>
 | 
			
		||||
    <point x="0.000000" y="52"/>
 | 
			
		||||
    <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"/>
 | 
			
		||||
    <point x="0.000000" y="52"/>
 | 
			
		||||
    <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"/>
 | 
			
		||||
    <point x="0.000000" y="52"/>
 | 
			
		||||
    <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"/>
 | 
			
		||||
    <point x="0.000000" y="52"/>
 | 
			
		||||
    <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>
 | 
			
		||||
</geometry>
 | 
			
		||||
 | 
			
		||||
@ -1,122 +1,126 @@
 | 
			
		||||
<?xml version="1.0"?>
 | 
			
		||||
<geometry version="0.90">
 | 
			
		||||
  <bounds x="0" y="10.000000" width="426.0000" height="296.5853"/>
 | 
			
		||||
  <!-- Keycodes correspond to those used in /usr/share/X11/xkb/keycodes/evdev.
 | 
			
		||||
       For Squeekboard, the values have no connection to evdev. They are only
 | 
			
		||||
       used as indices into the keymap sent to the compositor. They must have
 | 
			
		||||
       values in the range from 8 to 255. -->
 | 
			
		||||
  <section angle="0">
 | 
			
		||||
    <row orientation="1">
 | 
			
		||||
      <key name="AD01" oref="outline2" />
 | 
			
		||||
      <key name="AD02" oref="outline2" />
 | 
			
		||||
      <key name="AD03" oref="outline2" />
 | 
			
		||||
      <key name="AD04" oref="outline2" />
 | 
			
		||||
      <key name="AD05" oref="outline2" />
 | 
			
		||||
      <key name="AD06" oref="outline2" />
 | 
			
		||||
      <key name="AD07" oref="outline2" />
 | 
			
		||||
      <key name="AD08" oref="outline2" />
 | 
			
		||||
      <key name="AD09" oref="outline2" />
 | 
			
		||||
      <key name="AD10" oref="outline2" />
 | 
			
		||||
      <key name="AD11" oref="outline2" />
 | 
			
		||||
      <key keycode="24" name="AD01" oref="outline2" />
 | 
			
		||||
      <key keycode="25" name="AD02" oref="outline2" />
 | 
			
		||||
      <key keycode="26" name="AD03" oref="outline2" />
 | 
			
		||||
      <key keycode="27" name="AD04" oref="outline2" />
 | 
			
		||||
      <key keycode="28" name="AD05" oref="outline2" />
 | 
			
		||||
      <key keycode="29" name="AD06" oref="outline2" />
 | 
			
		||||
      <key keycode="30" name="AD07" oref="outline2" />
 | 
			
		||||
      <key keycode="31" name="AD08" oref="outline2" />
 | 
			
		||||
      <key keycode="32" name="AD09" oref="outline2" />
 | 
			
		||||
      <key keycode="33" name="AD10" oref="outline2" />
 | 
			
		||||
      <key keycode="34" name="AD11" oref="outline2" />
 | 
			
		||||
    </row>
 | 
			
		||||
  </section>
 | 
			
		||||
  <section angle="0">
 | 
			
		||||
    <row orientation="1">
 | 
			
		||||
      <key name="AC01" oref="outline2" />
 | 
			
		||||
      <key name="AC02" oref="outline2" />
 | 
			
		||||
      <key name="AC03" oref="outline2" />
 | 
			
		||||
      <key name="AC04" oref="outline2" />
 | 
			
		||||
      <key name="AC05" oref="outline2" />
 | 
			
		||||
      <key name="AC06" oref="outline2" />
 | 
			
		||||
      <key name="AC07" oref="outline2" />
 | 
			
		||||
      <key name="AC08" oref="outline2" />
 | 
			
		||||
      <key name="AC09" oref="outline2" />
 | 
			
		||||
      <key name="AC10" oref="outline2" />
 | 
			
		||||
      <key name="AC11" oref="outline2" />
 | 
			
		||||
      <key keycode="38" name="AC01" oref="outline2" />
 | 
			
		||||
      <key keycode="39" name="AC02" oref="outline2" />
 | 
			
		||||
      <key keycode="40" name="AC03" oref="outline2" />
 | 
			
		||||
      <key keycode="41" name="AC04" oref="outline2" />
 | 
			
		||||
      <key keycode="42" name="AC05" oref="outline2" />
 | 
			
		||||
      <key keycode="43" name="AC06" oref="outline2" />
 | 
			
		||||
      <key keycode="44" name="AC07" oref="outline2" />
 | 
			
		||||
      <key keycode="45" name="AC08" oref="outline2" />
 | 
			
		||||
      <key keycode="46" name="AC09" oref="outline2" />
 | 
			
		||||
      <key keycode="47" name="AC10" oref="outline2" />
 | 
			
		||||
      <key keycode="48" name="AC11" oref="outline2" />
 | 
			
		||||
    </row>
 | 
			
		||||
  </section>
 | 
			
		||||
  <section angle="0">
 | 
			
		||||
    <row orientation="1">
 | 
			
		||||
      <key name="LFSH" oref="altline" />
 | 
			
		||||
      <key name="AB01" oref="outline2" />
 | 
			
		||||
      <key name="AB02" oref="outline2" />
 | 
			
		||||
      <key name="AB03" oref="outline2" />
 | 
			
		||||
      <key name="AB04" oref="outline2" />
 | 
			
		||||
      <key name="AB05" oref="outline2" />
 | 
			
		||||
      <key name="AB06" oref="outline2" />
 | 
			
		||||
      <key name="AB07" oref="outline2" />
 | 
			
		||||
      <key name="BKSP" oref="altline" />
 | 
			
		||||
      <key keycode="50" name="LFSH" oref="altline" />
 | 
			
		||||
      <key keycode="52" name="AB01" oref="outline2" />
 | 
			
		||||
      <key keycode="53" name="AB02" oref="outline2" />
 | 
			
		||||
      <key keycode="54" name="AB03" oref="outline2" />
 | 
			
		||||
      <key keycode="55" name="AB04" oref="outline2" />
 | 
			
		||||
      <key keycode="56" name="AB05" oref="outline2" />
 | 
			
		||||
      <key keycode="57" name="AB06" oref="outline2" />
 | 
			
		||||
      <key keycode="58" name="AB07" oref="outline2" />
 | 
			
		||||
      <key keycode="22" name="BKSP" oref="altline" />
 | 
			
		||||
    </row>
 | 
			
		||||
  </section>
 | 
			
		||||
  <section angle="0">
 | 
			
		||||
    <row orientation="1">
 | 
			
		||||
      <key keycode="0" name="ABC123" oref="altline" />
 | 
			
		||||
      <key name="I149" oref="altline" />
 | 
			
		||||
      <key name="SPCE" oref="spaceline" />
 | 
			
		||||
      <key name="AB08" oref="outline2" />
 | 
			
		||||
      <key name="RTRN" oref="outline7" />
 | 
			
		||||
      <key keycode="149" name="I149" oref="altline" />
 | 
			
		||||
      <key keycode="65" name="SPCE" oref="spaceline" />
 | 
			
		||||
      <key keycode="59" name="AB08" oref="outline2" />
 | 
			
		||||
      <key keycode="36" name="RTRN" oref="outline7" />
 | 
			
		||||
    </row>
 | 
			
		||||
  </section>
 | 
			
		||||
  <outline id="outline2" corner-radius="1.000000">
 | 
			
		||||
    <point x="0.000000" y="0.000000"/>
 | 
			
		||||
    <point x="32" y="0.000000"/>
 | 
			
		||||
    <point x="32" y="52"/>
 | 
			
		||||
    <point x="0.000000" y="52"/>
 | 
			
		||||
    <point x="32" 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"/>
 | 
			
		||||
    <point x="0.000000" y="52"/>
 | 
			
		||||
    <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"/>
 | 
			
		||||
    <point x="0.000000" y="52"/>
 | 
			
		||||
    <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"/>
 | 
			
		||||
    <point x="0.000000" y="52"/>
 | 
			
		||||
    <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"/>
 | 
			
		||||
    <point x="0.000000" y="52"/>
 | 
			
		||||
    <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"/>
 | 
			
		||||
    <point x="0.000000" y="52"/>
 | 
			
		||||
    <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"/>
 | 
			
		||||
    <point x="0.000000" y="52"/>
 | 
			
		||||
    <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"/>
 | 
			
		||||
    <point x="0.000000" y="52"/>
 | 
			
		||||
    <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>
 | 
			
		||||
</geometry>
 | 
			
		||||
 | 
			
		||||
@ -1,105 +0,0 @@
 | 
			
		||||
<?xml version="1.0"?>
 | 
			
		||||
<geometry version="0.90">
 | 
			
		||||
  <bounds x="0" y="10.000000" width="426.0000" height="296.5853"/>
 | 
			
		||||
  <section angle="0">
 | 
			
		||||
    <row orientation="1">
 | 
			
		||||
      <key name="AD01" oref="outline2" />
 | 
			
		||||
      <key name="AD02" oref="outline2" />
 | 
			
		||||
      <key name="AD03" oref="outline2" />
 | 
			
		||||
      <key name="AD04" oref="outline2" />
 | 
			
		||||
      <key name="AD05" oref="outline2" />
 | 
			
		||||
    </row>
 | 
			
		||||
  </section>
 | 
			
		||||
  <section angle="0">
 | 
			
		||||
    <row orientation="1">
 | 
			
		||||
      <key name="AC01" oref="outline2" />
 | 
			
		||||
      <key name="AC02" oref="outline2" />
 | 
			
		||||
      <key name="AC03" oref="outline2" />
 | 
			
		||||
      <key name="AC04" oref="outline2" />
 | 
			
		||||
      <key name="AC05" oref="outline2" />
 | 
			
		||||
    </row>
 | 
			
		||||
  </section>
 | 
			
		||||
  <section angle="0">
 | 
			
		||||
    <row orientation="1">
 | 
			
		||||
      <key name="AB01" oref="outline2" />
 | 
			
		||||
      <key name="AB02" oref="outline2" />
 | 
			
		||||
      <key name="AB03" oref="outline2" />
 | 
			
		||||
      <key name="AB04" oref="outline2" />
 | 
			
		||||
      <key name="AB05" oref="outline2" />
 | 
			
		||||
    </row>
 | 
			
		||||
  </section>
 | 
			
		||||
  <section angle="0">
 | 
			
		||||
    <row orientation="1">
 | 
			
		||||
      <key name="BKSP" oref="altline" />
 | 
			
		||||
      <key name="AB06" oref="outline2" />
 | 
			
		||||
      <key name="SPCE" oref="spaceline" />
 | 
			
		||||
      <key name="RTRN" oref="outline7" />
 | 
			
		||||
    </row>
 | 
			
		||||
  </section>
 | 
			
		||||
  <outline id="outline2" corner-radius="1.000000">
 | 
			
		||||
    <point x="0.000000" y="0.000000"/>
 | 
			
		||||
    <point x="37.46341" y="0.000000"/>
 | 
			
		||||
    <point x="37.46341" y="52.44877"/>
 | 
			
		||||
    <point x="0.000000" y="52.44877"/>
 | 
			
		||||
  </outline>
 | 
			
		||||
  <outline id="altline" corner-radius="1.000000">
 | 
			
		||||
    <point x="0.000000" y="0.000000"/>
 | 
			
		||||
    <point x="48.39024" y="0.000000"/>
 | 
			
		||||
    <point x="48.39024" y="52.44877"/>
 | 
			
		||||
    <point x="0.000000" y="52.44877"/>
 | 
			
		||||
  </outline>
 | 
			
		||||
  <outline id="outline4" corner-radius="1.000000">
 | 
			
		||||
    <point x="0.000000" y="0.000000"/>
 | 
			
		||||
    <point x="59.31707" y="0.000000"/>
 | 
			
		||||
    <point x="59.31707" y="52.44877"/>
 | 
			
		||||
    <point x="0.000000" y="52.44877"/>
 | 
			
		||||
  </outline>
 | 
			
		||||
  <outline id="outline5" corner-radius="1.000000">
 | 
			
		||||
    <point x="0.000000" y="0.000000"/>
 | 
			
		||||
    <point x="59.31707" y="0.000000"/>
 | 
			
		||||
    <point x="59.31707" y="52.44877"/>
 | 
			
		||||
    <point x="0.000000" y="52.44877"/>
 | 
			
		||||
  </outline>
 | 
			
		||||
  <outline id="outline6" corner-radius="1.000000">
 | 
			
		||||
    <point x="0.000000" y="0.000000"/>
 | 
			
		||||
    <point x="68.68292" y="0.000000"/>
 | 
			
		||||
    <point x="68.68292" y="52.44877"/>
 | 
			
		||||
    <point x="0.000000" y="52.44877"/>
 | 
			
		||||
  </outline>
 | 
			
		||||
  <outline id="outline7" corner-radius="1.000000">
 | 
			
		||||
    <point x="0.000000" y="0.000000"/>
 | 
			
		||||
    <point x="88.97561" y="0.000000"/>
 | 
			
		||||
    <point x="88.97561" y="52.44877"/>
 | 
			
		||||
    <point x="0.000000" y="52.44877"/>
 | 
			
		||||
  </outline>
 | 
			
		||||
  <outline id="outline8" corner-radius="1.000000">
 | 
			
		||||
    <point x="0.000000" y="0.000000"/>
 | 
			
		||||
    <point x="88.97561" y="0.000000"/>
 | 
			
		||||
    <point x="88.97561" y="52.44877"/>
 | 
			
		||||
    <point x="0.000000" y="52.44877"/>
 | 
			
		||||
  </outline>
 | 
			
		||||
  <outline id="outline9" corner-radius="1.000000">
 | 
			
		||||
    <point x="0.000000" y="0.000000"/>
 | 
			
		||||
    <point x="109.2682" y="0.000000"/>
 | 
			
		||||
    <point x="109.2682" y="52.44877"/>
 | 
			
		||||
    <point x="0.000000" y="52.44877"/>
 | 
			
		||||
  </outline>
 | 
			
		||||
  <outline id="outline10" corner-radius="1.000000">
 | 
			
		||||
    <point x="0.000000" y="0.000000"/>
 | 
			
		||||
    <point x="37.46341" y="0.000000"/>
 | 
			
		||||
    <point x="37.46341" y="52.44877"/>
 | 
			
		||||
    <point x="0.000000" y="52.44877"/>
 | 
			
		||||
  </outline>
 | 
			
		||||
  <outline id="outline13" corner-radius="1.000000">
 | 
			
		||||
    <point x="0.000000" y="0.000000"/>
 | 
			
		||||
    <point x="79.60975" y="0.000000"/>
 | 
			
		||||
    <point x="79.60975" y="52.44877"/>
 | 
			
		||||
    <point x="0.000000" y="52.44877"/>
 | 
			
		||||
  </outline>
 | 
			
		||||
  <outline id="spaceline" corner-radius="1.000000">
 | 
			
		||||
    <point x="0.000000" y="0.000000"/>
 | 
			
		||||
    <point x="120.5853" y="0.000000"/>
 | 
			
		||||
    <point x="120.5853" y="52.44877"/>
 | 
			
		||||
    <point x="0.000000" y="52.44877"/>
 | 
			
		||||
  </outline>
 | 
			
		||||
</geometry>
 | 
			
		||||
@ -3,30 +3,37 @@
 | 
			
		||||
  <bounds x="0" y="10.000000" width="426.0000" height="296.5853"/>
 | 
			
		||||
  <section angle="0">
 | 
			
		||||
    <row orientation="1">
 | 
			
		||||
      <key name="AD01" oref="outline4" />
 | 
			
		||||
      <key name="AD02" oref="outline4" />
 | 
			
		||||
      <key name="AD03" oref="outline4" />
 | 
			
		||||
      <key keycode="24" name="AD01" oref="outline2" />
 | 
			
		||||
      <key keycode="25" name="AD02" oref="outline2" />
 | 
			
		||||
      <key keycode="26" name="AD03" oref="outline2" />
 | 
			
		||||
      <key keycode="27" name="AD04" oref="outline2" />
 | 
			
		||||
      <key keycode="28" name="AD05" oref="outline2" />
 | 
			
		||||
    </row>
 | 
			
		||||
  </section>
 | 
			
		||||
  <section angle="0">
 | 
			
		||||
    <row orientation="1">
 | 
			
		||||
      <key name="AC01" oref="outline4" />
 | 
			
		||||
      <key name="AC02" oref="outline4" />
 | 
			
		||||
      <key name="AC03" oref="outline4" />
 | 
			
		||||
      <key keycode="38" name="AC01" oref="outline2" />
 | 
			
		||||
      <key keycode="39" name="AC02" oref="outline2" />
 | 
			
		||||
      <key keycode="40" name="AC03" oref="outline2" />
 | 
			
		||||
      <key keycode="41" name="AC04" oref="outline2" />
 | 
			
		||||
      <key keycode="42" name="AC05" oref="outline2" />
 | 
			
		||||
    </row>
 | 
			
		||||
  </section>
 | 
			
		||||
  <section angle="0">
 | 
			
		||||
    <row orientation="1">
 | 
			
		||||
      <key name="AB01" oref="outline4" />
 | 
			
		||||
      <key name="AB02" oref="outline4" />
 | 
			
		||||
      <key name="AB03" oref="outline4" />
 | 
			
		||||
      <key keycode="52" name="AB01" oref="outline2" />
 | 
			
		||||
      <key keycode="53" name="AB02" oref="outline2" />
 | 
			
		||||
      <key keycode="54" name="AB03" oref="outline2" />
 | 
			
		||||
      <key keycode="55" name="AB04" oref="outline2" />
 | 
			
		||||
      <key keycode="56" name="AB05" oref="outline2" />
 | 
			
		||||
    </row>
 | 
			
		||||
  </section>
 | 
			
		||||
  <section angle="0">
 | 
			
		||||
    <row orientation="1">
 | 
			
		||||
      <key name="BKSP" oref="altline" />
 | 
			
		||||
      <key name="AB04" oref="outline4" />
 | 
			
		||||
      <key name="RTRN" oref="altline" />
 | 
			
		||||
      <key keycode="22" name="BKSP" oref="altline" />
 | 
			
		||||
      <key keycode="57" name="AB06" oref="outline2" />
 | 
			
		||||
      <key keycode="65" name="SPCE" oref="spaceline" />
 | 
			
		||||
      <key keycode="36" name="RTRN" oref="outline7" />
 | 
			
		||||
    </row>
 | 
			
		||||
  </section>
 | 
			
		||||
  <outline id="outline2" corner-radius="1.000000">
 | 
			
		||||
@ -1,105 +0,0 @@
 | 
			
		||||
<?xml version="1.0"?>
 | 
			
		||||
<geometry version="0.90">
 | 
			
		||||
  <bounds x="0" y="10.000000" width="426.0000" height="296.5853"/>
 | 
			
		||||
  <section angle="0">
 | 
			
		||||
    <row orientation="1">
 | 
			
		||||
      <key name="AD01" oref="outline2" />
 | 
			
		||||
      <key name="AD02" oref="outline2" />
 | 
			
		||||
      <key name="AD03" oref="outline2" />
 | 
			
		||||
      <key name="AD04" oref="outline2" />
 | 
			
		||||
      <key name="AD05" oref="outline2" />
 | 
			
		||||
    </row>
 | 
			
		||||
  </section>
 | 
			
		||||
  <section angle="0">
 | 
			
		||||
    <row orientation="1">
 | 
			
		||||
      <key name="AC01" oref="outline2" />
 | 
			
		||||
      <key name="AC02" oref="outline2" />
 | 
			
		||||
      <key name="AC03" oref="outline2" />
 | 
			
		||||
      <key name="AC04" oref="outline2" />
 | 
			
		||||
      <key name="AC05" oref="outline2" />
 | 
			
		||||
    </row>
 | 
			
		||||
  </section>
 | 
			
		||||
  <section angle="0">
 | 
			
		||||
    <row orientation="1">
 | 
			
		||||
      <key name="AB01" oref="outline2" />
 | 
			
		||||
      <key name="AB02" oref="outline2" />
 | 
			
		||||
      <key name="AB03" oref="outline2" />
 | 
			
		||||
      <key name="AB04" oref="outline2" />
 | 
			
		||||
      <key name="AB05" oref="outline2" />
 | 
			
		||||
    </row>
 | 
			
		||||
  </section>
 | 
			
		||||
  <section angle="0">
 | 
			
		||||
    <row orientation="1">
 | 
			
		||||
      <key name="BKSP" oref="altline" />
 | 
			
		||||
      <key name="AB06" oref="outline2" />
 | 
			
		||||
      <key name="SPCE" oref="spaceline" />
 | 
			
		||||
      <key name="RTRN" oref="outline7" />
 | 
			
		||||
    </row>
 | 
			
		||||
  </section>
 | 
			
		||||
  <outline id="outline2" corner-radius="1.000000">
 | 
			
		||||
    <point x="0.000000" y="0.000000"/>
 | 
			
		||||
    <point x="37.46341" y="0.000000"/>
 | 
			
		||||
    <point x="37.46341" y="52.44877"/>
 | 
			
		||||
    <point x="0.000000" y="52.44877"/>
 | 
			
		||||
  </outline>
 | 
			
		||||
  <outline id="altline" corner-radius="1.000000">
 | 
			
		||||
    <point x="0.000000" y="0.000000"/>
 | 
			
		||||
    <point x="48.39024" y="0.000000"/>
 | 
			
		||||
    <point x="48.39024" y="52.44877"/>
 | 
			
		||||
    <point x="0.000000" y="52.44877"/>
 | 
			
		||||
  </outline>
 | 
			
		||||
  <outline id="outline4" corner-radius="1.000000">
 | 
			
		||||
    <point x="0.000000" y="0.000000"/>
 | 
			
		||||
    <point x="59.31707" y="0.000000"/>
 | 
			
		||||
    <point x="59.31707" y="52.44877"/>
 | 
			
		||||
    <point x="0.000000" y="52.44877"/>
 | 
			
		||||
  </outline>
 | 
			
		||||
  <outline id="outline5" corner-radius="1.000000">
 | 
			
		||||
    <point x="0.000000" y="0.000000"/>
 | 
			
		||||
    <point x="59.31707" y="0.000000"/>
 | 
			
		||||
    <point x="59.31707" y="52.44877"/>
 | 
			
		||||
    <point x="0.000000" y="52.44877"/>
 | 
			
		||||
  </outline>
 | 
			
		||||
  <outline id="outline6" corner-radius="1.000000">
 | 
			
		||||
    <point x="0.000000" y="0.000000"/>
 | 
			
		||||
    <point x="68.68292" y="0.000000"/>
 | 
			
		||||
    <point x="68.68292" y="52.44877"/>
 | 
			
		||||
    <point x="0.000000" y="52.44877"/>
 | 
			
		||||
  </outline>
 | 
			
		||||
  <outline id="outline7" corner-radius="1.000000">
 | 
			
		||||
    <point x="0.000000" y="0.000000"/>
 | 
			
		||||
    <point x="88.97561" y="0.000000"/>
 | 
			
		||||
    <point x="88.97561" y="52.44877"/>
 | 
			
		||||
    <point x="0.000000" y="52.44877"/>
 | 
			
		||||
  </outline>
 | 
			
		||||
  <outline id="outline8" corner-radius="1.000000">
 | 
			
		||||
    <point x="0.000000" y="0.000000"/>
 | 
			
		||||
    <point x="88.97561" y="0.000000"/>
 | 
			
		||||
    <point x="88.97561" y="52.44877"/>
 | 
			
		||||
    <point x="0.000000" y="52.44877"/>
 | 
			
		||||
  </outline>
 | 
			
		||||
  <outline id="outline9" corner-radius="1.000000">
 | 
			
		||||
    <point x="0.000000" y="0.000000"/>
 | 
			
		||||
    <point x="109.2682" y="0.000000"/>
 | 
			
		||||
    <point x="109.2682" y="52.44877"/>
 | 
			
		||||
    <point x="0.000000" y="52.44877"/>
 | 
			
		||||
  </outline>
 | 
			
		||||
  <outline id="outline10" corner-radius="1.000000">
 | 
			
		||||
    <point x="0.000000" y="0.000000"/>
 | 
			
		||||
    <point x="37.46341" y="0.000000"/>
 | 
			
		||||
    <point x="37.46341" y="52.44877"/>
 | 
			
		||||
    <point x="0.000000" y="52.44877"/>
 | 
			
		||||
  </outline>
 | 
			
		||||
  <outline id="outline13" corner-radius="1.000000">
 | 
			
		||||
    <point x="0.000000" y="0.000000"/>
 | 
			
		||||
    <point x="79.60975" y="0.000000"/>
 | 
			
		||||
    <point x="79.60975" y="52.44877"/>
 | 
			
		||||
    <point x="0.000000" y="52.44877"/>
 | 
			
		||||
  </outline>
 | 
			
		||||
  <outline id="spaceline" corner-radius="1.000000">
 | 
			
		||||
    <point x="0.000000" y="0.000000"/>
 | 
			
		||||
    <point x="120.5853" y="0.000000"/>
 | 
			
		||||
    <point x="120.5853" y="52.44877"/>
 | 
			
		||||
    <point x="0.000000" y="52.44877"/>
 | 
			
		||||
  </outline>
 | 
			
		||||
</geometry>
 | 
			
		||||
@ -1,126 +0,0 @@
 | 
			
		||||
<?xml version="1.0"?>
 | 
			
		||||
<geometry version="0.90">
 | 
			
		||||
  <bounds x="0" y="10.000000" width="426.0000" height="296.5853"/>
 | 
			
		||||
  <section angle="0">
 | 
			
		||||
    <row orientation="1">
 | 
			
		||||
      <key name="AD01" oref="outline2" />
 | 
			
		||||
      <key name="AD02" oref="outline2" />
 | 
			
		||||
      <key name="AD03" oref="outline2" />
 | 
			
		||||
      <key name="AD04" oref="outline2" />
 | 
			
		||||
      <key name="AD05" oref="outline2" />
 | 
			
		||||
      <key name="AD06" oref="outline2" />
 | 
			
		||||
      <key name="AD07" oref="outline2" />
 | 
			
		||||
      <key name="AD08" oref="outline2" />
 | 
			
		||||
      <key name="AD09" oref="outline2" />
 | 
			
		||||
      <key name="AD10" oref="outline2" />
 | 
			
		||||
      <key name="AE01" oref="outline6" />
 | 
			
		||||
      <key name="AE02" oref="outline2" />
 | 
			
		||||
      <key name="AE03" oref="outline6" />
 | 
			
		||||
      <key name="AE04" oref="outline6" />
 | 
			
		||||
      <key name="AE05" oref="outline6" />
 | 
			
		||||
      <key name="AE06" oref="outline6" />
 | 
			
		||||
    </row>
 | 
			
		||||
  </section>
 | 
			
		||||
  <section angle="0">
 | 
			
		||||
    <row orientation="1">
 | 
			
		||||
      <key name="AC01" oref="outline2" />
 | 
			
		||||
      <key name="AC02" oref="outline2" />
 | 
			
		||||
      <key name="AC03" oref="outline2" />
 | 
			
		||||
      <key name="AC04" oref="outline2" />
 | 
			
		||||
      <key name="AC05" oref="outline2" />
 | 
			
		||||
      <key name="AC06" oref="outline2" />
 | 
			
		||||
      <key name="AC07" oref="outline2" />
 | 
			
		||||
      <key name="AC08" oref="outline2" />
 | 
			
		||||
      <key name="AC09" oref="outline2" />
 | 
			
		||||
      <key name="AC10" oref="outline2" />
 | 
			
		||||
    </row>
 | 
			
		||||
  </section>
 | 
			
		||||
  <section angle="0">
 | 
			
		||||
    <row orientation="1">
 | 
			
		||||
      <key name="LFSH" oref="altline" />
 | 
			
		||||
      <key name="AB01" oref="outline2" />
 | 
			
		||||
      <key name="AB02" oref="outline2" />
 | 
			
		||||
      <key name="AB03" oref="outline2" />
 | 
			
		||||
      <key name="AB04" oref="outline2" />
 | 
			
		||||
      <key name="AB05" oref="outline2" />
 | 
			
		||||
      <key name="AB06" oref="outline2" />
 | 
			
		||||
      <key name="AB07" oref="outline2" />
 | 
			
		||||
      <key name="BKSP" oref="altline" />
 | 
			
		||||
    </row>
 | 
			
		||||
  </section>
 | 
			
		||||
  <section angle="0">
 | 
			
		||||
    <row orientation="1">
 | 
			
		||||
      <key keycode="0" name="ABC123" oref="altline" />
 | 
			
		||||
      <key name="I149" oref="altline" />
 | 
			
		||||
      <key name="SPCE" oref="spaceline" />
 | 
			
		||||
      <key name="AB08" oref="outline2" />
 | 
			
		||||
      <key name="RTRN" oref="outline7" />
 | 
			
		||||
    </row>
 | 
			
		||||
  </section>
 | 
			
		||||
  <outline id="outline2" corner-radius="1.000000">
 | 
			
		||||
    <point x="0.000000" y="0.000000"/>
 | 
			
		||||
    <point x="37.46341" y="0.000000"/>
 | 
			
		||||
    <point x="37.46341" y="52.44877"/>
 | 
			
		||||
    <point x="0.000000" y="52.44877"/>
 | 
			
		||||
  </outline>
 | 
			
		||||
  <outline id="altline" corner-radius="1.000000">
 | 
			
		||||
    <point x="0.000000" y="0.000000"/>
 | 
			
		||||
    <point x="48.39024" y="0.000000"/>
 | 
			
		||||
    <point x="48.39024" y="52.44877"/>
 | 
			
		||||
    <point x="0.000000" y="52.44877"/>
 | 
			
		||||
  </outline>
 | 
			
		||||
  <outline id="outline4" corner-radius="1.000000">
 | 
			
		||||
    <point x="0.000000" y="0.000000"/>
 | 
			
		||||
    <point x="59.31707" y="0.000000"/>
 | 
			
		||||
    <point x="59.31707" y="52.44877"/>
 | 
			
		||||
    <point x="0.000000" y="52.44877"/>
 | 
			
		||||
  </outline>
 | 
			
		||||
  <outline id="outline5" corner-radius="1.000000">
 | 
			
		||||
    <point x="0.000000" y="0.000000"/>
 | 
			
		||||
    <point x="59.31707" y="0.000000"/>
 | 
			
		||||
    <point x="59.31707" y="52.44877"/>
 | 
			
		||||
    <point x="0.000000" y="52.44877"/>
 | 
			
		||||
  </outline>
 | 
			
		||||
  <outline id="outline6" corner-radius="1.000000">
 | 
			
		||||
    <point x="0.000000" y="0.000000"/>
 | 
			
		||||
    <point x="68.68292" y="0.000000"/>
 | 
			
		||||
    <point x="68.68292" y="52.44877"/>
 | 
			
		||||
    <point x="0.000000" y="52.44877"/>
 | 
			
		||||
  </outline>
 | 
			
		||||
  <outline id="outline7" corner-radius="1.000000">
 | 
			
		||||
    <point x="0.000000" y="0.000000"/>
 | 
			
		||||
    <point x="88.97561" y="0.000000"/>
 | 
			
		||||
    <point x="88.97561" y="52.44877"/>
 | 
			
		||||
    <point x="0.000000" y="52.44877"/>
 | 
			
		||||
  </outline>
 | 
			
		||||
  <outline id="outline8" corner-radius="1.000000">
 | 
			
		||||
    <point x="0.000000" y="0.000000"/>
 | 
			
		||||
    <point x="88.97561" y="0.000000"/>
 | 
			
		||||
    <point x="88.97561" y="52.44877"/>
 | 
			
		||||
    <point x="0.000000" y="52.44877"/>
 | 
			
		||||
  </outline>
 | 
			
		||||
  <outline id="outline9" corner-radius="1.000000">
 | 
			
		||||
    <point x="0.000000" y="0.000000"/>
 | 
			
		||||
    <point x="109.2682" y="0.000000"/>
 | 
			
		||||
    <point x="109.2682" y="52.44877"/>
 | 
			
		||||
    <point x="0.000000" y="52.44877"/>
 | 
			
		||||
  </outline>
 | 
			
		||||
  <outline id="outline10" corner-radius="1.000000">
 | 
			
		||||
    <point x="0.000000" y="0.000000"/>
 | 
			
		||||
    <point x="37.46341" y="0.000000"/>
 | 
			
		||||
    <point x="37.46341" y="52.44877"/>
 | 
			
		||||
    <point x="0.000000" y="52.44877"/>
 | 
			
		||||
  </outline>
 | 
			
		||||
  <outline id="outline13" corner-radius="1.000000">
 | 
			
		||||
    <point x="0.000000" y="0.000000"/>
 | 
			
		||||
    <point x="79.60975" y="0.000000"/>
 | 
			
		||||
    <point x="79.60975" y="52.44877"/>
 | 
			
		||||
    <point x="0.000000" y="52.44877"/>
 | 
			
		||||
  </outline>
 | 
			
		||||
  <outline id="spaceline" corner-radius="1.000000">
 | 
			
		||||
    <point x="0.000000" y="0.000000"/>
 | 
			
		||||
    <point x="150.5853" y="0.000000"/>
 | 
			
		||||
    <point x="150.5853" y="52.44877"/>
 | 
			
		||||
    <point x="0.000000" y="52.44877"/>
 | 
			
		||||
  </outline>
 | 
			
		||||
</geometry>
 | 
			
		||||
@ -90,17 +90,8 @@
 | 
			
		||||
	    longname="Telugu (Inscript)" language="te"/>
 | 
			
		||||
 | 
			
		||||
  <!-- Common keyboards -->
 | 
			
		||||
  <keyboard id="digits" name="digits"
 | 
			
		||||
	    geometry="digits" symbols="special/digits"
 | 
			
		||||
	    longname="Digits" language="all"/>
 | 
			
		||||
  <keyboard id="number" name="number"
 | 
			
		||||
	    geometry="number-keypad" symbols="special/number"
 | 
			
		||||
  <keyboard id="numbers" name="numbers"
 | 
			
		||||
	    geometry="numbers-keypad" symbols="special/numbers"
 | 
			
		||||
	    longname="Numeric keypad" language="all"/>
 | 
			
		||||
  <keyboard id="phone" name="phone"
 | 
			
		||||
	    geometry="phone-keypad" symbols="special/phone"
 | 
			
		||||
	    longname="Phone keypad" language="all"/>
 | 
			
		||||
  <keyboard id="url" name="url"
 | 
			
		||||
	    geometry="url" symbols="special/url"
 | 
			
		||||
	    longname="Uniform Resource Locator" language="all"/>
 | 
			
		||||
 | 
			
		||||
</keyboards>
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										308
									
								
								data/keyboards/keymaps/nb.xkb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										308
									
								
								data/keyboards/keymaps/nb.xkb
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,308 @@
 | 
			
		||||
xkb_keymap {
 | 
			
		||||
 | 
			
		||||
    xkb_keycodes "squeekboard" {
 | 
			
		||||
        minimum = 8;
 | 
			
		||||
        maximum = 255;
 | 
			
		||||
        <ESC>                = 9;
 | 
			
		||||
        <AE01>               = 10;
 | 
			
		||||
        <AE02>               = 11;
 | 
			
		||||
        <AE03>               = 12;
 | 
			
		||||
        <AE04>               = 13;
 | 
			
		||||
        <AE05>               = 14;
 | 
			
		||||
        <AE06>               = 15;
 | 
			
		||||
        <AE07>               = 16;
 | 
			
		||||
        <AE08>               = 17;
 | 
			
		||||
        <AE09>               = 18;
 | 
			
		||||
        <AE10>               = 19;
 | 
			
		||||
        <AE11>               = 20;
 | 
			
		||||
        <AE12>               = 21;
 | 
			
		||||
        <BKSP>               = 22;
 | 
			
		||||
        <TAB>                = 23;
 | 
			
		||||
        <AD01>               = 24;
 | 
			
		||||
        <AD02>               = 25;
 | 
			
		||||
        <AD03>               = 26;
 | 
			
		||||
        <AD04>               = 27;
 | 
			
		||||
        <AD05>               = 28;
 | 
			
		||||
        <AD06>               = 29;
 | 
			
		||||
        <AD07>               = 30;
 | 
			
		||||
        <AD08>               = 31;
 | 
			
		||||
        <AD09>               = 32;
 | 
			
		||||
        <AD10>               = 33;
 | 
			
		||||
        <AD11>               = 34;
 | 
			
		||||
        <AD12>               = 35;
 | 
			
		||||
        <RTRN>               = 36;
 | 
			
		||||
        <LCTL>               = 37;
 | 
			
		||||
        <AC01>               = 38;
 | 
			
		||||
        <AC02>               = 39;
 | 
			
		||||
        <AC03>               = 40;
 | 
			
		||||
        <AC04>               = 41;
 | 
			
		||||
        <AC05>               = 42;
 | 
			
		||||
        <AC06>               = 43;
 | 
			
		||||
        <AC07>               = 44;
 | 
			
		||||
        <AC08>               = 45;
 | 
			
		||||
        <AC09>               = 46;
 | 
			
		||||
        <AC10>               = 47;
 | 
			
		||||
        <AC11>               = 48;
 | 
			
		||||
        <TLDE>               = 49;
 | 
			
		||||
        <LFSH>               = 50;
 | 
			
		||||
        <BKSL>               = 51;
 | 
			
		||||
        <AB01>               = 52;
 | 
			
		||||
        <AB02>               = 53;
 | 
			
		||||
        <AB03>               = 54;
 | 
			
		||||
        <AB04>               = 55;
 | 
			
		||||
        <AB05>               = 56;
 | 
			
		||||
        <AB06>               = 57;
 | 
			
		||||
        <AB07>               = 58;
 | 
			
		||||
        <AB08>               = 59;
 | 
			
		||||
        <AB09>               = 60;
 | 
			
		||||
        <AB10>               = 61;
 | 
			
		||||
        <RTSH>               = 62;
 | 
			
		||||
        <KPMU>               = 63;
 | 
			
		||||
        <LALT>               = 64;
 | 
			
		||||
        <SPCE>               = 65;
 | 
			
		||||
        <CAPS>               = 66;
 | 
			
		||||
        <FK01>               = 67;
 | 
			
		||||
        <FK02>               = 68;
 | 
			
		||||
        <FK03>               = 69;
 | 
			
		||||
        <FK04>               = 70;
 | 
			
		||||
        <FK05>               = 71;
 | 
			
		||||
        <FK06>               = 72;
 | 
			
		||||
        <FK07>               = 73;
 | 
			
		||||
        <FK08>               = 74;
 | 
			
		||||
        <FK09>               = 75;
 | 
			
		||||
        <FK10>               = 76;
 | 
			
		||||
        <NMLK>               = 77;
 | 
			
		||||
        <SCLK>               = 78;
 | 
			
		||||
        <KP7>                = 79;
 | 
			
		||||
        <KP8>                = 80;
 | 
			
		||||
        <KP9>                = 81;
 | 
			
		||||
        <KPSU>               = 82;
 | 
			
		||||
        <KP4>                = 83;
 | 
			
		||||
        <KP5>                = 84;
 | 
			
		||||
        <KP6>                = 85;
 | 
			
		||||
        <KPAD>               = 86;
 | 
			
		||||
        <KP1>                = 87;
 | 
			
		||||
        <KP2>                = 88;
 | 
			
		||||
        <KP3>                = 89;
 | 
			
		||||
        <KP0>                = 90;
 | 
			
		||||
        <KPDL>               = 91;
 | 
			
		||||
        <LVL3>               = 92;
 | 
			
		||||
        <LSGT>               = 94;
 | 
			
		||||
        <FK11>               = 95;
 | 
			
		||||
        <FK12>               = 96;
 | 
			
		||||
        <AB11>               = 97;
 | 
			
		||||
        <KATA>               = 98;
 | 
			
		||||
        <HIRA>               = 99;
 | 
			
		||||
        <HENK>               = 100;
 | 
			
		||||
        <HKTG>               = 101;
 | 
			
		||||
        <MUHE>               = 102;
 | 
			
		||||
        <JPCM>               = 103;
 | 
			
		||||
        <KPEN>               = 104;
 | 
			
		||||
        <RCTL>               = 105;
 | 
			
		||||
        <KPDV>               = 106;
 | 
			
		||||
        <PRSC>               = 107;
 | 
			
		||||
        <RALT>               = 108;
 | 
			
		||||
        <LNFD>               = 109;
 | 
			
		||||
        <HOME>               = 110;
 | 
			
		||||
        <UP>                 = 111;
 | 
			
		||||
        <PGUP>               = 112;
 | 
			
		||||
        <LEFT>               = 113;
 | 
			
		||||
        <RGHT>               = 114;
 | 
			
		||||
        <END>                = 115;
 | 
			
		||||
        <DOWN>               = 116;
 | 
			
		||||
        <PGDN>               = 117;
 | 
			
		||||
        <INS>                = 118;
 | 
			
		||||
        <DELE>               = 119;
 | 
			
		||||
        <I120>               = 120;
 | 
			
		||||
        <MUTE>               = 121;
 | 
			
		||||
        <VOL->               = 122;
 | 
			
		||||
        <VOL+>               = 123;
 | 
			
		||||
        <POWR>               = 124;
 | 
			
		||||
        <KPEQ>               = 125;
 | 
			
		||||
        <I126>               = 126;
 | 
			
		||||
        <PAUS>               = 127;
 | 
			
		||||
        <I128>               = 128;
 | 
			
		||||
        <I129>               = 129;
 | 
			
		||||
        <HNGL>               = 130;
 | 
			
		||||
        <HJCV>               = 131;
 | 
			
		||||
        <AE13>               = 132;
 | 
			
		||||
        <LWIN>               = 133;
 | 
			
		||||
        <RWIN>               = 134;
 | 
			
		||||
        <COMP>               = 135;
 | 
			
		||||
        <STOP>               = 136;
 | 
			
		||||
        <AGAI>               = 137;
 | 
			
		||||
        <PROP>               = 138;
 | 
			
		||||
        <UNDO>               = 139;
 | 
			
		||||
        <FRNT>               = 140;
 | 
			
		||||
        <COPY>               = 141;
 | 
			
		||||
        <OPEN>               = 142;
 | 
			
		||||
        <PAST>               = 143;
 | 
			
		||||
        <FIND>               = 144;
 | 
			
		||||
        <CUT>                = 145;
 | 
			
		||||
        <HELP>               = 146;
 | 
			
		||||
        <I147>               = 147;
 | 
			
		||||
        <I148>               = 148;
 | 
			
		||||
        <I149>               = 149;
 | 
			
		||||
        <I150>               = 150;
 | 
			
		||||
        <I151>               = 151;
 | 
			
		||||
        <I152>               = 152;
 | 
			
		||||
        <I153>               = 153;
 | 
			
		||||
        <I154>               = 154;
 | 
			
		||||
        <I155>               = 155;
 | 
			
		||||
        <I156>               = 156;
 | 
			
		||||
        <I157>               = 157;
 | 
			
		||||
        <I158>               = 158;
 | 
			
		||||
        <I159>               = 159;
 | 
			
		||||
        <I160>               = 160;
 | 
			
		||||
        <I161>               = 161;
 | 
			
		||||
        <I162>               = 162;
 | 
			
		||||
        <I163>               = 163;
 | 
			
		||||
        <I164>               = 164;
 | 
			
		||||
        <I165>               = 165;
 | 
			
		||||
        <I166>               = 166;
 | 
			
		||||
        <I167>               = 167;
 | 
			
		||||
        <I168>               = 168;
 | 
			
		||||
        <I169>               = 169;
 | 
			
		||||
        <I170>               = 170;
 | 
			
		||||
        <I171>               = 171;
 | 
			
		||||
        <I172>               = 172;
 | 
			
		||||
        <I173>               = 173;
 | 
			
		||||
        <I174>               = 174;
 | 
			
		||||
        <I175>               = 175;
 | 
			
		||||
        <I176>               = 176;
 | 
			
		||||
        <I177>               = 177;
 | 
			
		||||
        <I178>               = 178;
 | 
			
		||||
        <I179>               = 179;
 | 
			
		||||
        <I180>               = 180;
 | 
			
		||||
        <I181>               = 181;
 | 
			
		||||
        <I182>               = 182;
 | 
			
		||||
        <I183>               = 183;
 | 
			
		||||
        <I184>               = 184;
 | 
			
		||||
        <I185>               = 185;
 | 
			
		||||
        <I186>               = 186;
 | 
			
		||||
        <I187>               = 187;
 | 
			
		||||
        <I188>               = 188;
 | 
			
		||||
        <I189>               = 189;
 | 
			
		||||
        <I190>               = 190;
 | 
			
		||||
        <FK13>               = 191;
 | 
			
		||||
        <FK14>               = 192;
 | 
			
		||||
        <FK15>               = 193;
 | 
			
		||||
        <FK16>               = 194;
 | 
			
		||||
        <FK17>               = 195;
 | 
			
		||||
        <FK18>               = 196;
 | 
			
		||||
        <FK19>               = 197;
 | 
			
		||||
        <FK20>               = 198;
 | 
			
		||||
        <FK21>               = 199;
 | 
			
		||||
        <FK22>               = 200;
 | 
			
		||||
        <FK23>               = 201;
 | 
			
		||||
        <FK24>               = 202;
 | 
			
		||||
        <MDSW>               = 203;
 | 
			
		||||
        <ALT>                = 204;
 | 
			
		||||
        <META>               = 205;
 | 
			
		||||
        <SUPR>               = 206;
 | 
			
		||||
        <HYPR>               = 207;
 | 
			
		||||
        <I208>               = 208;
 | 
			
		||||
        <I209>               = 209;
 | 
			
		||||
        <I210>               = 210;
 | 
			
		||||
        <I211>               = 211;
 | 
			
		||||
        <I212>               = 212;
 | 
			
		||||
        <I213>               = 213;
 | 
			
		||||
        <I214>               = 214;
 | 
			
		||||
        <I215>               = 215;
 | 
			
		||||
        <I216>               = 216;
 | 
			
		||||
        <I217>               = 217;
 | 
			
		||||
        <I218>               = 218;
 | 
			
		||||
        <I219>               = 219;
 | 
			
		||||
        <I220>               = 220;
 | 
			
		||||
        <I221>               = 221;
 | 
			
		||||
        <I222>               = 222;
 | 
			
		||||
        <I223>               = 223;
 | 
			
		||||
        <I224>               = 224;
 | 
			
		||||
        <I225>               = 225;
 | 
			
		||||
        <I226>               = 226;
 | 
			
		||||
        <I227>               = 227;
 | 
			
		||||
        <I228>               = 228;
 | 
			
		||||
        <I229>               = 229;
 | 
			
		||||
        <I230>               = 230;
 | 
			
		||||
        <I231>               = 231;
 | 
			
		||||
        <I232>               = 232;
 | 
			
		||||
        <I233>               = 233;
 | 
			
		||||
        <I234>               = 234;
 | 
			
		||||
        <I235>               = 235;
 | 
			
		||||
        <I236>               = 236;
 | 
			
		||||
        <I237>               = 237;
 | 
			
		||||
        <I238>               = 238;
 | 
			
		||||
        <I239>               = 239;
 | 
			
		||||
        <I240>               = 240;
 | 
			
		||||
        <I241>               = 241;
 | 
			
		||||
        <I242>               = 242;
 | 
			
		||||
        <I243>               = 243;
 | 
			
		||||
        <I244>               = 244;
 | 
			
		||||
        <I245>               = 245;
 | 
			
		||||
        <I246>               = 246;
 | 
			
		||||
        <I247>               = 247;
 | 
			
		||||
        <I248>               = 248;
 | 
			
		||||
        <I249>               = 249;
 | 
			
		||||
        <I250>               = 250;
 | 
			
		||||
        <I251>               = 251;
 | 
			
		||||
        <I252>               = 252;
 | 
			
		||||
        <I253>               = 253;
 | 
			
		||||
        <I254>               = 254;
 | 
			
		||||
        <I255>               = 255;
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    xkb_symbols "squeekboard" {
 | 
			
		||||
 | 
			
		||||
        name[Group1] = "Letters";
 | 
			
		||||
        name[Group2] = "Numbers/Symbols";
 | 
			
		||||
 | 
			
		||||
        key <AD01> { [ q, Q ], [ 1, asciitilde ] };
 | 
			
		||||
        key <AD02> { [ w, W ], [ 2, quoteleft ] };
 | 
			
		||||
        key <AD03> { [ e, E ], [ 3, bar ] };
 | 
			
		||||
        key <AD04> { [ r, R ], [ 4, U00B7 ] };
 | 
			
		||||
        key <AD05> { [ t, T ], [ 5, squareroot ] };
 | 
			
		||||
        key <AD06> { [ y, Y ], [ 6, Greek_pi ] };
 | 
			
		||||
        key <AD07> { [ u, U ], [ 7, division ] };
 | 
			
		||||
        key <AD08> { [ i, I ], [ 8, multiply ] };
 | 
			
		||||
        key <AD09> { [ o, O ], [ 9, paragraph ] };
 | 
			
		||||
        key <AD10> { [ p, P ], [ 0, U25B3 ] };
 | 
			
		||||
        key <AD11> { [ aring, Aring ], [ U00B1, U00A7 ] };
 | 
			
		||||
        key <AC01> { [ a, A ], [ at, copyright ] };
 | 
			
		||||
        key <AC02> { [ s, S ], [ numbersign, U00AE ] };
 | 
			
		||||
        key <AC03> { [ d, D ], [ dollar, U00A3 ] };
 | 
			
		||||
        key <AC04> { [ f, F ], [ percent, EuroSign ] };
 | 
			
		||||
        key <AC05> { [ g, G ], [ ampersand, U00A5 ] };
 | 
			
		||||
        key <AC06> { [ h, H ], [ minus, underscore ] };
 | 
			
		||||
        key <AC07> { [ j, J ], [ plus, equal ] };
 | 
			
		||||
        key <AC08> { [ k, K ], [ U00FC, asciicircum ] };
 | 
			
		||||
        key <AC09> { [ l, L ], [ U00F6, degree ] };
 | 
			
		||||
        key <AC10> { [ oslash, Oslash ], [ parenleft, braceleft ] };
 | 
			
		||||
        key <AC11> { [ ae, AE ], [ parenright, braceright ] };
 | 
			
		||||
        key <RTRN> { [ Return, Return ], [ Return, Return ] };
 | 
			
		||||
        key <LFSH> { [ Shift_L, Shift_L ], [ Shift_L, Shift_L ] };
 | 
			
		||||
        key <AB01> { [ z, Z ], [ comma, backslash ] };
 | 
			
		||||
        key <AB02> { [ x, X ], [ quotedbl, slash ] };
 | 
			
		||||
        key <AB03> { [ c, C ], [ quoteright, less ] };
 | 
			
		||||
        key <AB04> { [ v, V ], [ colon, greater ] };
 | 
			
		||||
        key <AB05> { [ b, B ], [ semicolon, equal ] };
 | 
			
		||||
        key <AB06> { [ n, N ], [ exclam, bracketleft ] };
 | 
			
		||||
        key <AB07> { [ m, M ], [ question, bracketright ] };
 | 
			
		||||
        key <AB08> { [ period, period ], [ period, period ] };
 | 
			
		||||
        key <I149> { [ preferences, preferences ], [ preferences, preferences ] };
 | 
			
		||||
        key <SPCE> { [ space, space ], [ space, space ] };
 | 
			
		||||
        key <BKSP> { [ BackSpace, BackSpace ], [ BackSpace, BackSpace ] };
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    xkb_types "squeekboard" {
 | 
			
		||||
 | 
			
		||||
	type "TWO_LEVEL" {
 | 
			
		||||
            modifiers = Shift;
 | 
			
		||||
            map[Shift] = Level2;
 | 
			
		||||
            level_name[Level1] = "Base";
 | 
			
		||||
            level_name[Level2] = "Shift";
 | 
			
		||||
	};
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    xkb_compatibility "squeekboard" {
 | 
			
		||||
    };
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										292
									
								
								data/keyboards/keymaps/numbers.xkb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										292
									
								
								data/keyboards/keymaps/numbers.xkb
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,292 @@
 | 
			
		||||
xkb_keymap {
 | 
			
		||||
 | 
			
		||||
    xkb_keycodes "squeekboard" {
 | 
			
		||||
        minimum = 8;
 | 
			
		||||
        maximum = 255;
 | 
			
		||||
        <ESC>                = 9;
 | 
			
		||||
        <AE01>               = 10;
 | 
			
		||||
        <AE02>               = 11;
 | 
			
		||||
        <AE03>               = 12;
 | 
			
		||||
        <AE04>               = 13;
 | 
			
		||||
        <AE05>               = 14;
 | 
			
		||||
        <AE06>               = 15;
 | 
			
		||||
        <AE07>               = 16;
 | 
			
		||||
        <AE08>               = 17;
 | 
			
		||||
        <AE09>               = 18;
 | 
			
		||||
        <AE10>               = 19;
 | 
			
		||||
        <AE11>               = 20;
 | 
			
		||||
        <AE12>               = 21;
 | 
			
		||||
        <BKSP>               = 22;
 | 
			
		||||
        <TAB>                = 23;
 | 
			
		||||
        <AD01>               = 24;
 | 
			
		||||
        <AD02>               = 25;
 | 
			
		||||
        <AD03>               = 26;
 | 
			
		||||
        <AD04>               = 27;
 | 
			
		||||
        <AD05>               = 28;
 | 
			
		||||
        <AD06>               = 29;
 | 
			
		||||
        <AD07>               = 30;
 | 
			
		||||
        <AD08>               = 31;
 | 
			
		||||
        <AD09>               = 32;
 | 
			
		||||
        <AD10>               = 33;
 | 
			
		||||
        <AD11>               = 34;
 | 
			
		||||
        <AD12>               = 35;
 | 
			
		||||
        <RTRN>               = 36;
 | 
			
		||||
        <LCTL>               = 37;
 | 
			
		||||
        <AC01>               = 38;
 | 
			
		||||
        <AC02>               = 39;
 | 
			
		||||
        <AC03>               = 40;
 | 
			
		||||
        <AC04>               = 41;
 | 
			
		||||
        <AC05>               = 42;
 | 
			
		||||
        <AC06>               = 43;
 | 
			
		||||
        <AC07>               = 44;
 | 
			
		||||
        <AC08>               = 45;
 | 
			
		||||
        <AC09>               = 46;
 | 
			
		||||
        <AC10>               = 47;
 | 
			
		||||
        <AC11>               = 48;
 | 
			
		||||
        <TLDE>               = 49;
 | 
			
		||||
        <LFSH>               = 50;
 | 
			
		||||
        <BKSL>               = 51;
 | 
			
		||||
        <AB01>               = 52;
 | 
			
		||||
        <AB02>               = 53;
 | 
			
		||||
        <AB03>               = 54;
 | 
			
		||||
        <AB04>               = 55;
 | 
			
		||||
        <AB05>               = 56;
 | 
			
		||||
        <AB06>               = 57;
 | 
			
		||||
        <AB07>               = 58;
 | 
			
		||||
        <AB08>               = 59;
 | 
			
		||||
        <AB09>               = 60;
 | 
			
		||||
        <AB10>               = 61;
 | 
			
		||||
        <RTSH>               = 62;
 | 
			
		||||
        <KPMU>               = 63;
 | 
			
		||||
        <LALT>               = 64;
 | 
			
		||||
        <SPCE>               = 65;
 | 
			
		||||
        <CAPS>               = 66;
 | 
			
		||||
        <FK01>               = 67;
 | 
			
		||||
        <FK02>               = 68;
 | 
			
		||||
        <FK03>               = 69;
 | 
			
		||||
        <FK04>               = 70;
 | 
			
		||||
        <FK05>               = 71;
 | 
			
		||||
        <FK06>               = 72;
 | 
			
		||||
        <FK07>               = 73;
 | 
			
		||||
        <FK08>               = 74;
 | 
			
		||||
        <FK09>               = 75;
 | 
			
		||||
        <FK10>               = 76;
 | 
			
		||||
        <NMLK>               = 77;
 | 
			
		||||
        <SCLK>               = 78;
 | 
			
		||||
        <KP7>                = 79;
 | 
			
		||||
        <KP8>                = 80;
 | 
			
		||||
        <KP9>                = 81;
 | 
			
		||||
        <KPSU>               = 82;
 | 
			
		||||
        <KP4>                = 83;
 | 
			
		||||
        <KP5>                = 84;
 | 
			
		||||
        <KP6>                = 85;
 | 
			
		||||
        <KPAD>               = 86;
 | 
			
		||||
        <KP1>                = 87;
 | 
			
		||||
        <KP2>                = 88;
 | 
			
		||||
        <KP3>                = 89;
 | 
			
		||||
        <KP0>                = 90;
 | 
			
		||||
        <KPDL>               = 91;
 | 
			
		||||
        <LVL3>               = 92;
 | 
			
		||||
        <LSGT>               = 94;
 | 
			
		||||
        <FK11>               = 95;
 | 
			
		||||
        <FK12>               = 96;
 | 
			
		||||
        <AB11>               = 97;
 | 
			
		||||
        <KATA>               = 98;
 | 
			
		||||
        <HIRA>               = 99;
 | 
			
		||||
        <HENK>               = 100;
 | 
			
		||||
        <HKTG>               = 101;
 | 
			
		||||
        <MUHE>               = 102;
 | 
			
		||||
        <JPCM>               = 103;
 | 
			
		||||
        <KPEN>               = 104;
 | 
			
		||||
        <RCTL>               = 105;
 | 
			
		||||
        <KPDV>               = 106;
 | 
			
		||||
        <PRSC>               = 107;
 | 
			
		||||
        <RALT>               = 108;
 | 
			
		||||
        <LNFD>               = 109;
 | 
			
		||||
        <HOME>               = 110;
 | 
			
		||||
        <UP>                 = 111;
 | 
			
		||||
        <PGUP>               = 112;
 | 
			
		||||
        <LEFT>               = 113;
 | 
			
		||||
        <RGHT>               = 114;
 | 
			
		||||
        <END>                = 115;
 | 
			
		||||
        <DOWN>               = 116;
 | 
			
		||||
        <PGDN>               = 117;
 | 
			
		||||
        <INS>                = 118;
 | 
			
		||||
        <DELE>               = 119;
 | 
			
		||||
        <I120>               = 120;
 | 
			
		||||
        <MUTE>               = 121;
 | 
			
		||||
        <VOL->               = 122;
 | 
			
		||||
        <VOL+>               = 123;
 | 
			
		||||
        <POWR>               = 124;
 | 
			
		||||
        <KPEQ>               = 125;
 | 
			
		||||
        <I126>               = 126;
 | 
			
		||||
        <PAUS>               = 127;
 | 
			
		||||
        <I128>               = 128;
 | 
			
		||||
        <I129>               = 129;
 | 
			
		||||
        <HNGL>               = 130;
 | 
			
		||||
        <HJCV>               = 131;
 | 
			
		||||
        <AE13>               = 132;
 | 
			
		||||
        <LWIN>               = 133;
 | 
			
		||||
        <RWIN>               = 134;
 | 
			
		||||
        <COMP>               = 135;
 | 
			
		||||
        <STOP>               = 136;
 | 
			
		||||
        <AGAI>               = 137;
 | 
			
		||||
        <PROP>               = 138;
 | 
			
		||||
        <UNDO>               = 139;
 | 
			
		||||
        <FRNT>               = 140;
 | 
			
		||||
        <COPY>               = 141;
 | 
			
		||||
        <OPEN>               = 142;
 | 
			
		||||
        <PAST>               = 143;
 | 
			
		||||
        <FIND>               = 144;
 | 
			
		||||
        <CUT>                = 145;
 | 
			
		||||
        <HELP>               = 146;
 | 
			
		||||
        <I147>               = 147;
 | 
			
		||||
        <I148>               = 148;
 | 
			
		||||
        <I149>               = 149;
 | 
			
		||||
        <I150>               = 150;
 | 
			
		||||
        <I151>               = 151;
 | 
			
		||||
        <I152>               = 152;
 | 
			
		||||
        <I153>               = 153;
 | 
			
		||||
        <I154>               = 154;
 | 
			
		||||
        <I155>               = 155;
 | 
			
		||||
        <I156>               = 156;
 | 
			
		||||
        <I157>               = 157;
 | 
			
		||||
        <I158>               = 158;
 | 
			
		||||
        <I159>               = 159;
 | 
			
		||||
        <I160>               = 160;
 | 
			
		||||
        <I161>               = 161;
 | 
			
		||||
        <I162>               = 162;
 | 
			
		||||
        <I163>               = 163;
 | 
			
		||||
        <I164>               = 164;
 | 
			
		||||
        <I165>               = 165;
 | 
			
		||||
        <I166>               = 166;
 | 
			
		||||
        <I167>               = 167;
 | 
			
		||||
        <I168>               = 168;
 | 
			
		||||
        <I169>               = 169;
 | 
			
		||||
        <I170>               = 170;
 | 
			
		||||
        <I171>               = 171;
 | 
			
		||||
        <I172>               = 172;
 | 
			
		||||
        <I173>               = 173;
 | 
			
		||||
        <I174>               = 174;
 | 
			
		||||
        <I175>               = 175;
 | 
			
		||||
        <I176>               = 176;
 | 
			
		||||
        <I177>               = 177;
 | 
			
		||||
        <I178>               = 178;
 | 
			
		||||
        <I179>               = 179;
 | 
			
		||||
        <I180>               = 180;
 | 
			
		||||
        <I181>               = 181;
 | 
			
		||||
        <I182>               = 182;
 | 
			
		||||
        <I183>               = 183;
 | 
			
		||||
        <I184>               = 184;
 | 
			
		||||
        <I185>               = 185;
 | 
			
		||||
        <I186>               = 186;
 | 
			
		||||
        <I187>               = 187;
 | 
			
		||||
        <I188>               = 188;
 | 
			
		||||
        <I189>               = 189;
 | 
			
		||||
        <I190>               = 190;
 | 
			
		||||
        <FK13>               = 191;
 | 
			
		||||
        <FK14>               = 192;
 | 
			
		||||
        <FK15>               = 193;
 | 
			
		||||
        <FK16>               = 194;
 | 
			
		||||
        <FK17>               = 195;
 | 
			
		||||
        <FK18>               = 196;
 | 
			
		||||
        <FK19>               = 197;
 | 
			
		||||
        <FK20>               = 198;
 | 
			
		||||
        <FK21>               = 199;
 | 
			
		||||
        <FK22>               = 200;
 | 
			
		||||
        <FK23>               = 201;
 | 
			
		||||
        <FK24>               = 202;
 | 
			
		||||
        <MDSW>               = 203;
 | 
			
		||||
        <ALT>                = 204;
 | 
			
		||||
        <META>               = 205;
 | 
			
		||||
        <SUPR>               = 206;
 | 
			
		||||
        <HYPR>               = 207;
 | 
			
		||||
        <I208>               = 208;
 | 
			
		||||
        <I209>               = 209;
 | 
			
		||||
        <I210>               = 210;
 | 
			
		||||
        <I211>               = 211;
 | 
			
		||||
        <I212>               = 212;
 | 
			
		||||
        <I213>               = 213;
 | 
			
		||||
        <I214>               = 214;
 | 
			
		||||
        <I215>               = 215;
 | 
			
		||||
        <I216>               = 216;
 | 
			
		||||
        <I217>               = 217;
 | 
			
		||||
        <I218>               = 218;
 | 
			
		||||
        <I219>               = 219;
 | 
			
		||||
        <I220>               = 220;
 | 
			
		||||
        <I221>               = 221;
 | 
			
		||||
        <I222>               = 222;
 | 
			
		||||
        <I223>               = 223;
 | 
			
		||||
        <I224>               = 224;
 | 
			
		||||
        <I225>               = 225;
 | 
			
		||||
        <I226>               = 226;
 | 
			
		||||
        <I227>               = 227;
 | 
			
		||||
        <I228>               = 228;
 | 
			
		||||
        <I229>               = 229;
 | 
			
		||||
        <I230>               = 230;
 | 
			
		||||
        <I231>               = 231;
 | 
			
		||||
        <I232>               = 232;
 | 
			
		||||
        <I233>               = 233;
 | 
			
		||||
        <I234>               = 234;
 | 
			
		||||
        <I235>               = 235;
 | 
			
		||||
        <I236>               = 236;
 | 
			
		||||
        <I237>               = 237;
 | 
			
		||||
        <I238>               = 238;
 | 
			
		||||
        <I239>               = 239;
 | 
			
		||||
        <I240>               = 240;
 | 
			
		||||
        <I241>               = 241;
 | 
			
		||||
        <I242>               = 242;
 | 
			
		||||
        <I243>               = 243;
 | 
			
		||||
        <I244>               = 244;
 | 
			
		||||
        <I245>               = 245;
 | 
			
		||||
        <I246>               = 246;
 | 
			
		||||
        <I247>               = 247;
 | 
			
		||||
        <I248>               = 248;
 | 
			
		||||
        <I249>               = 249;
 | 
			
		||||
        <I250>               = 250;
 | 
			
		||||
        <I251>               = 251;
 | 
			
		||||
        <I252>               = 252;
 | 
			
		||||
        <I253>               = 253;
 | 
			
		||||
        <I254>               = 254;
 | 
			
		||||
        <I255>               = 255;
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    xkb_symbols "squeekboard" {
 | 
			
		||||
 | 
			
		||||
        name[Group1] = "Letters";
 | 
			
		||||
        name[Group2] = "Numbers/Symbols";
 | 
			
		||||
 | 
			
		||||
        key <AD01> { [ 1, 1 ], [ 1, 1 ] };
 | 
			
		||||
        key <AD02> { [ 2, 2 ], [ 2, 2 ] };
 | 
			
		||||
        key <AD03> { [ 3, 3 ], [ 3, 3 ] };
 | 
			
		||||
        key <AD04> { [ parenleft, parenleft ], [ parenleft, parenleft ] };
 | 
			
		||||
        key <AD05> { [ parenright, parenright ], [ parenright, parenright ] };
 | 
			
		||||
        key <AC01> { [ 4, 4 ], [ 4, 4 ] };
 | 
			
		||||
        key <AC02> { [ 5, 5 ], [ 5, 5 ] };
 | 
			
		||||
        key <AC03> { [ 6, 6 ], [ 6, 6 ] };
 | 
			
		||||
        key <AC04> { [ numbersign, numbersign ], [ numbersign, numbersign ] };
 | 
			
		||||
        key <AC05> { [ asterisk, asterisk ], [ asterisk, asterisk ] };
 | 
			
		||||
        key <AB01> { [ 7, 7 ], [ 7, 7 ] };
 | 
			
		||||
        key <AB02> { [ 8, 8 ], [ 8, 8 ] };
 | 
			
		||||
        key <AB03> { [ 9, 9 ], [ 9, 9 ] };
 | 
			
		||||
        key <AB04> { [ plus, plus ], [ plus, plus ] };
 | 
			
		||||
        key <AB05> { [ minus, minus ], [ minus, minus ] };
 | 
			
		||||
        key <AB06> { [ 0, 0 ], [ 0, 0 ] };
 | 
			
		||||
        key <RTRN> { [ Return, Return ], [ Return, Return ] };
 | 
			
		||||
        key <SPCE> { [ space, space ], [ space, space ] };
 | 
			
		||||
        key <BKSP> { [ BackSpace, BackSpace ], [ BackSpace, BackSpace ] };
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    xkb_types "squeekboard" {
 | 
			
		||||
 | 
			
		||||
	type "TWO_LEVEL" {
 | 
			
		||||
            modifiers = Shift;
 | 
			
		||||
            map[Shift] = Level2;
 | 
			
		||||
            level_name[Level1] = "Base";
 | 
			
		||||
            level_name[Level2] = "Shift";
 | 
			
		||||
	};
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    xkb_compatibility "squeekboard" {
 | 
			
		||||
    };
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										306
									
								
								data/keyboards/keymaps/us.xkb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										306
									
								
								data/keyboards/keymaps/us.xkb
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,306 @@
 | 
			
		||||
xkb_keymap {
 | 
			
		||||
 | 
			
		||||
    xkb_keycodes "squeekboard" {
 | 
			
		||||
        minimum = 8;
 | 
			
		||||
        maximum = 255;
 | 
			
		||||
        <ESC>                = 9;
 | 
			
		||||
        <AE01>               = 10;
 | 
			
		||||
        <AE02>               = 11;
 | 
			
		||||
        <AE03>               = 12;
 | 
			
		||||
        <AE04>               = 13;
 | 
			
		||||
        <AE05>               = 14;
 | 
			
		||||
        <AE06>               = 15;
 | 
			
		||||
        <AE07>               = 16;
 | 
			
		||||
        <AE08>               = 17;
 | 
			
		||||
        <AE09>               = 18;
 | 
			
		||||
        <AE10>               = 19;
 | 
			
		||||
        <AE11>               = 20;
 | 
			
		||||
        <AE12>               = 21;
 | 
			
		||||
        <BKSP>               = 22;
 | 
			
		||||
        <TAB>                = 23;
 | 
			
		||||
        <AD01>               = 24;
 | 
			
		||||
        <AD02>               = 25;
 | 
			
		||||
        <AD03>               = 26;
 | 
			
		||||
        <AD04>               = 27;
 | 
			
		||||
        <AD05>               = 28;
 | 
			
		||||
        <AD06>               = 29;
 | 
			
		||||
        <AD07>               = 30;
 | 
			
		||||
        <AD08>               = 31;
 | 
			
		||||
        <AD09>               = 32;
 | 
			
		||||
        <AD10>               = 33;
 | 
			
		||||
        <AD11>               = 34;
 | 
			
		||||
        <AD12>               = 35;
 | 
			
		||||
        <RTRN>               = 36;
 | 
			
		||||
        <LCTL>               = 37;
 | 
			
		||||
        <AC01>               = 38;
 | 
			
		||||
        <AC02>               = 39;
 | 
			
		||||
        <AC03>               = 40;
 | 
			
		||||
        <AC04>               = 41;
 | 
			
		||||
        <AC05>               = 42;
 | 
			
		||||
        <AC06>               = 43;
 | 
			
		||||
        <AC07>               = 44;
 | 
			
		||||
        <AC08>               = 45;
 | 
			
		||||
        <AC09>               = 46;
 | 
			
		||||
        <AC10>               = 47;
 | 
			
		||||
        <AC11>               = 48;
 | 
			
		||||
        <TLDE>               = 49;
 | 
			
		||||
        <LFSH>               = 50;
 | 
			
		||||
        <BKSL>               = 51;
 | 
			
		||||
        <AB01>               = 52;
 | 
			
		||||
        <AB02>               = 53;
 | 
			
		||||
        <AB03>               = 54;
 | 
			
		||||
        <AB04>               = 55;
 | 
			
		||||
        <AB05>               = 56;
 | 
			
		||||
        <AB06>               = 57;
 | 
			
		||||
        <AB07>               = 58;
 | 
			
		||||
        <AB08>               = 59;
 | 
			
		||||
        <AB09>               = 60;
 | 
			
		||||
        <AB10>               = 61;
 | 
			
		||||
        <RTSH>               = 62;
 | 
			
		||||
        <KPMU>               = 63;
 | 
			
		||||
        <LALT>               = 64;
 | 
			
		||||
        <SPCE>               = 65;
 | 
			
		||||
        <CAPS>               = 66;
 | 
			
		||||
        <FK01>               = 67;
 | 
			
		||||
        <FK02>               = 68;
 | 
			
		||||
        <FK03>               = 69;
 | 
			
		||||
        <FK04>               = 70;
 | 
			
		||||
        <FK05>               = 71;
 | 
			
		||||
        <FK06>               = 72;
 | 
			
		||||
        <FK07>               = 73;
 | 
			
		||||
        <FK08>               = 74;
 | 
			
		||||
        <FK09>               = 75;
 | 
			
		||||
        <FK10>               = 76;
 | 
			
		||||
        <NMLK>               = 77;
 | 
			
		||||
        <SCLK>               = 78;
 | 
			
		||||
        <KP7>                = 79;
 | 
			
		||||
        <KP8>                = 80;
 | 
			
		||||
        <KP9>                = 81;
 | 
			
		||||
        <KPSU>               = 82;
 | 
			
		||||
        <KP4>                = 83;
 | 
			
		||||
        <KP5>                = 84;
 | 
			
		||||
        <KP6>                = 85;
 | 
			
		||||
        <KPAD>               = 86;
 | 
			
		||||
        <KP1>                = 87;
 | 
			
		||||
        <KP2>                = 88;
 | 
			
		||||
        <KP3>                = 89;
 | 
			
		||||
        <KP0>                = 90;
 | 
			
		||||
        <KPDL>               = 91;
 | 
			
		||||
        <LVL3>               = 92;
 | 
			
		||||
        <LSGT>               = 94;
 | 
			
		||||
        <FK11>               = 95;
 | 
			
		||||
        <FK12>               = 96;
 | 
			
		||||
        <AB11>               = 97;
 | 
			
		||||
        <KATA>               = 98;
 | 
			
		||||
        <HIRA>               = 99;
 | 
			
		||||
        <HENK>               = 100;
 | 
			
		||||
        <HKTG>               = 101;
 | 
			
		||||
        <MUHE>               = 102;
 | 
			
		||||
        <JPCM>               = 103;
 | 
			
		||||
        <KPEN>               = 104;
 | 
			
		||||
        <RCTL>               = 105;
 | 
			
		||||
        <KPDV>               = 106;
 | 
			
		||||
        <PRSC>               = 107;
 | 
			
		||||
        <RALT>               = 108;
 | 
			
		||||
        <LNFD>               = 109;
 | 
			
		||||
        <HOME>               = 110;
 | 
			
		||||
        <UP>                 = 111;
 | 
			
		||||
        <PGUP>               = 112;
 | 
			
		||||
        <LEFT>               = 113;
 | 
			
		||||
        <RGHT>               = 114;
 | 
			
		||||
        <END>                = 115;
 | 
			
		||||
        <DOWN>               = 116;
 | 
			
		||||
        <PGDN>               = 117;
 | 
			
		||||
        <INS>                = 118;
 | 
			
		||||
        <DELE>               = 119;
 | 
			
		||||
        <I120>               = 120;
 | 
			
		||||
        <MUTE>               = 121;
 | 
			
		||||
        <VOL->               = 122;
 | 
			
		||||
        <VOL+>               = 123;
 | 
			
		||||
        <POWR>               = 124;
 | 
			
		||||
        <KPEQ>               = 125;
 | 
			
		||||
        <I126>               = 126;
 | 
			
		||||
        <PAUS>               = 127;
 | 
			
		||||
        <I128>               = 128;
 | 
			
		||||
        <I129>               = 129;
 | 
			
		||||
        <HNGL>               = 130;
 | 
			
		||||
        <HJCV>               = 131;
 | 
			
		||||
        <AE13>               = 132;
 | 
			
		||||
        <LWIN>               = 133;
 | 
			
		||||
        <RWIN>               = 134;
 | 
			
		||||
        <COMP>               = 135;
 | 
			
		||||
        <STOP>               = 136;
 | 
			
		||||
        <AGAI>               = 137;
 | 
			
		||||
        <PROP>               = 138;
 | 
			
		||||
        <UNDO>               = 139;
 | 
			
		||||
        <FRNT>               = 140;
 | 
			
		||||
        <COPY>               = 141;
 | 
			
		||||
        <OPEN>               = 142;
 | 
			
		||||
        <PAST>               = 143;
 | 
			
		||||
        <FIND>               = 144;
 | 
			
		||||
        <CUT>                = 145;
 | 
			
		||||
        <HELP>               = 146;
 | 
			
		||||
        <I147>               = 147;
 | 
			
		||||
        <I148>               = 148;
 | 
			
		||||
        <I149>               = 149;
 | 
			
		||||
        <I150>               = 150;
 | 
			
		||||
        <I151>               = 151;
 | 
			
		||||
        <I152>               = 152;
 | 
			
		||||
        <I153>               = 153;
 | 
			
		||||
        <I154>               = 154;
 | 
			
		||||
        <I155>               = 155;
 | 
			
		||||
        <I156>               = 156;
 | 
			
		||||
        <I157>               = 157;
 | 
			
		||||
        <I158>               = 158;
 | 
			
		||||
        <I159>               = 159;
 | 
			
		||||
        <I160>               = 160;
 | 
			
		||||
        <I161>               = 161;
 | 
			
		||||
        <I162>               = 162;
 | 
			
		||||
        <I163>               = 163;
 | 
			
		||||
        <I164>               = 164;
 | 
			
		||||
        <I165>               = 165;
 | 
			
		||||
        <I166>               = 166;
 | 
			
		||||
        <I167>               = 167;
 | 
			
		||||
        <I168>               = 168;
 | 
			
		||||
        <I169>               = 169;
 | 
			
		||||
        <I170>               = 170;
 | 
			
		||||
        <I171>               = 171;
 | 
			
		||||
        <I172>               = 172;
 | 
			
		||||
        <I173>               = 173;
 | 
			
		||||
        <I174>               = 174;
 | 
			
		||||
        <I175>               = 175;
 | 
			
		||||
        <I176>               = 176;
 | 
			
		||||
        <I177>               = 177;
 | 
			
		||||
        <I178>               = 178;
 | 
			
		||||
        <I179>               = 179;
 | 
			
		||||
        <I180>               = 180;
 | 
			
		||||
        <I181>               = 181;
 | 
			
		||||
        <I182>               = 182;
 | 
			
		||||
        <I183>               = 183;
 | 
			
		||||
        <I184>               = 184;
 | 
			
		||||
        <I185>               = 185;
 | 
			
		||||
        <I186>               = 186;
 | 
			
		||||
        <I187>               = 187;
 | 
			
		||||
        <I188>               = 188;
 | 
			
		||||
        <I189>               = 189;
 | 
			
		||||
        <I190>               = 190;
 | 
			
		||||
        <FK13>               = 191;
 | 
			
		||||
        <FK14>               = 192;
 | 
			
		||||
        <FK15>               = 193;
 | 
			
		||||
        <FK16>               = 194;
 | 
			
		||||
        <FK17>               = 195;
 | 
			
		||||
        <FK18>               = 196;
 | 
			
		||||
        <FK19>               = 197;
 | 
			
		||||
        <FK20>               = 198;
 | 
			
		||||
        <FK21>               = 199;
 | 
			
		||||
        <FK22>               = 200;
 | 
			
		||||
        <FK23>               = 201;
 | 
			
		||||
        <FK24>               = 202;
 | 
			
		||||
        <MDSW>               = 203;
 | 
			
		||||
        <ALT>                = 204;
 | 
			
		||||
        <META>               = 205;
 | 
			
		||||
        <SUPR>               = 206;
 | 
			
		||||
        <HYPR>               = 207;
 | 
			
		||||
        <I208>               = 208;
 | 
			
		||||
        <I209>               = 209;
 | 
			
		||||
        <I210>               = 210;
 | 
			
		||||
        <I211>               = 211;
 | 
			
		||||
        <I212>               = 212;
 | 
			
		||||
        <I213>               = 213;
 | 
			
		||||
        <I214>               = 214;
 | 
			
		||||
        <I215>               = 215;
 | 
			
		||||
        <I216>               = 216;
 | 
			
		||||
        <I217>               = 217;
 | 
			
		||||
        <I218>               = 218;
 | 
			
		||||
        <I219>               = 219;
 | 
			
		||||
        <I220>               = 220;
 | 
			
		||||
        <I221>               = 221;
 | 
			
		||||
        <I222>               = 222;
 | 
			
		||||
        <I223>               = 223;
 | 
			
		||||
        <I224>               = 224;
 | 
			
		||||
        <I225>               = 225;
 | 
			
		||||
        <I226>               = 226;
 | 
			
		||||
        <I227>               = 227;
 | 
			
		||||
        <I228>               = 228;
 | 
			
		||||
        <I229>               = 229;
 | 
			
		||||
        <I230>               = 230;
 | 
			
		||||
        <I231>               = 231;
 | 
			
		||||
        <I232>               = 232;
 | 
			
		||||
        <I233>               = 233;
 | 
			
		||||
        <I234>               = 234;
 | 
			
		||||
        <I235>               = 235;
 | 
			
		||||
        <I236>               = 236;
 | 
			
		||||
        <I237>               = 237;
 | 
			
		||||
        <I238>               = 238;
 | 
			
		||||
        <I239>               = 239;
 | 
			
		||||
        <I240>               = 240;
 | 
			
		||||
        <I241>               = 241;
 | 
			
		||||
        <I242>               = 242;
 | 
			
		||||
        <I243>               = 243;
 | 
			
		||||
        <I244>               = 244;
 | 
			
		||||
        <I245>               = 245;
 | 
			
		||||
        <I246>               = 246;
 | 
			
		||||
        <I247>               = 247;
 | 
			
		||||
        <I248>               = 248;
 | 
			
		||||
        <I249>               = 249;
 | 
			
		||||
        <I250>               = 250;
 | 
			
		||||
        <I251>               = 251;
 | 
			
		||||
        <I252>               = 252;
 | 
			
		||||
        <I253>               = 253;
 | 
			
		||||
        <I254>               = 254;
 | 
			
		||||
        <I255>               = 255;
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    xkb_symbols "squeekboard" {
 | 
			
		||||
 | 
			
		||||
        name[Group1] = "Letters";
 | 
			
		||||
        name[Group2] = "Numbers/Symbols";
 | 
			
		||||
 | 
			
		||||
        key <AD01> { [ q, Q ], [ 1, asciitilde ] };
 | 
			
		||||
        key <AD02> { [ w, W ], [ 2, quoteleft ] };
 | 
			
		||||
        key <AD03> { [ e, E ], [ 3, bar ] };
 | 
			
		||||
        key <AD04> { [ r, R ], [ 4, U00B7 ] };
 | 
			
		||||
        key <AD05> { [ t, T ], [ 5, squareroot ] };
 | 
			
		||||
        key <AD06> { [ y, Y ], [ 6, Greek_pi ] };
 | 
			
		||||
        key <AD07> { [ u, U ], [ 7, division ] };
 | 
			
		||||
        key <AD08> { [ i, I ], [ 8, multiply ] };
 | 
			
		||||
        key <AD09> { [ o, O ], [ 9, paragraph ] };
 | 
			
		||||
        key <AD10> { [ p, P ], [ 0, U25B3 ] };
 | 
			
		||||
        key <AC01> { [ a, A ], [ at, copyright ] };
 | 
			
		||||
        key <AC02> { [ s, S ], [ numbersign, U00AE ] };
 | 
			
		||||
        key <AC03> { [ d, D ], [ dollar, U00A3 ] };
 | 
			
		||||
        key <AC04> { [ f, F ], [ percent, EuroSign ] };
 | 
			
		||||
        key <AC05> { [ g, G ], [ ampersand, U00A5 ] };
 | 
			
		||||
        key <AC06> { [ h, H ], [ minus, asciicircum ] };
 | 
			
		||||
        key <AC07> { [ j, J ], [ underscore, degree ] };
 | 
			
		||||
        key <AC08> { [ k, K ], [ plus, equal ] };
 | 
			
		||||
        key <AC09> { [ l, L ], [ parenleft, braceleft ] };
 | 
			
		||||
        key <AC10> { [   ], [ parenright, braceright ] };
 | 
			
		||||
        key <RTRN> { [ Return, Return ], [ Return, Return ] };
 | 
			
		||||
        key <LFSH> { [ Shift_L, Shift_L ], [ Shift_L, Shift_L ] };
 | 
			
		||||
        key <AB01> { [ z, Z ], [ comma, backslash ] };
 | 
			
		||||
        key <AB02> { [ x, X ], [ quotedbl, slash ] };
 | 
			
		||||
        key <AB03> { [ c, C ], [ quoteright, less ] };
 | 
			
		||||
        key <AB04> { [ v, V ], [ colon, greater ] };
 | 
			
		||||
        key <AB05> { [ b, B ], [ semicolon, equal ] };
 | 
			
		||||
        key <AB06> { [ n, N ], [ exclam, bracketleft ] };
 | 
			
		||||
        key <AB07> { [ m, M ], [ question, bracketright ] };
 | 
			
		||||
        key <AB08> { [ period, period ], [ period, period ] };
 | 
			
		||||
        key <I149> { [ preferences, preferences ], [ preferences, preferences ] };
 | 
			
		||||
        key <SPCE> { [ space, space ], [ space, space ] };
 | 
			
		||||
        key <BKSP> { [ BackSpace, BackSpace ], [ BackSpace, BackSpace ] };
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    xkb_types "squeekboard" {
 | 
			
		||||
 | 
			
		||||
	type "TWO_LEVEL" {
 | 
			
		||||
            modifiers = Shift;
 | 
			
		||||
            map[Shift] = Level2;
 | 
			
		||||
            level_name[Level1] = "Base";
 | 
			
		||||
            level_name[Level2] = "Shift";
 | 
			
		||||
	};
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    xkb_compatibility "squeekboard" {
 | 
			
		||||
    };
 | 
			
		||||
};
 | 
			
		||||
@ -63,10 +63,8 @@
 | 
			
		||||
  <key name="AD11">
 | 
			
		||||
    <symbol keyval="229" label="å">aring</symbol>
 | 
			
		||||
    <symbol keyval="197" label="Å">Aring</symbol>
 | 
			
		||||
    <symbol label=""></symbol>
 | 
			
		||||
    <symbol label=""></symbol>
 | 
			
		||||
    <!-- Empty labels cause keys to be hidden when the level they are defined
 | 
			
		||||
         for is shown. -->
 | 
			
		||||
    <symbol label="±">U00B1</symbol>
 | 
			
		||||
    <symbol label="§">U00A7</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AC01">
 | 
			
		||||
    <symbol label="a">a</symbol>
 | 
			
		||||
@ -102,37 +100,37 @@
 | 
			
		||||
    <symbol label="h">h</symbol>
 | 
			
		||||
    <symbol label="H">H</symbol>
 | 
			
		||||
    <symbol label="-">minus</symbol>
 | 
			
		||||
    <symbol label="^">asciicircum</symbol>
 | 
			
		||||
    <symbol label="_">underscore</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AC07">
 | 
			
		||||
    <symbol label="j">j</symbol>
 | 
			
		||||
    <symbol label="J">J</symbol>
 | 
			
		||||
    <symbol label="_">underscore</symbol>
 | 
			
		||||
    <symbol label="°">degree</symbol>
 | 
			
		||||
    <symbol label="+">plus</symbol>
 | 
			
		||||
    <symbol label="=">equal</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AC08">
 | 
			
		||||
    <symbol label="k">k</symbol>
 | 
			
		||||
    <symbol label="K">K</symbol>
 | 
			
		||||
    <symbol label="+">plus</symbol>
 | 
			
		||||
    <symbol label="=">equal</symbol>
 | 
			
		||||
    <symbol label="ü">U00FC</symbol>
 | 
			
		||||
    <symbol label="^">asciicircum</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AC09">
 | 
			
		||||
    <symbol label="l">l</symbol>
 | 
			
		||||
    <symbol label="L">L</symbol>
 | 
			
		||||
    <symbol label="(">parenleft</symbol>
 | 
			
		||||
    <symbol label="{">braceleft</symbol>
 | 
			
		||||
    <symbol label="ö">U00F6</symbol>
 | 
			
		||||
    <symbol label="°">degree</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AC10">
 | 
			
		||||
    <symbol keyval="248" label="ø">oslash</symbol>
 | 
			
		||||
    <symbol keyval="216" label="Ø">Oslash</symbol>
 | 
			
		||||
    <symbol label=")">parenright</symbol>
 | 
			
		||||
    <symbol label="}">braceright</symbol>
 | 
			
		||||
    <symbol label="(">parenleft</symbol>
 | 
			
		||||
    <symbol label="{">braceleft</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AC11">
 | 
			
		||||
    <symbol keyval="230" label="æ">ae</symbol>
 | 
			
		||||
    <symbol keyval="198" label="Æ">AE</symbol>
 | 
			
		||||
    <symbol label=""></symbol>
 | 
			
		||||
    <symbol label=""></symbol>
 | 
			
		||||
    <symbol label=")">parenright</symbol>
 | 
			
		||||
    <symbol label="}">braceright</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="RTRN">
 | 
			
		||||
    <symbol keyval="65293" icon="key-enter">Return</symbol>
 | 
			
		||||
 | 
			
		||||
@ -1,39 +0,0 @@
 | 
			
		||||
<?xml version='1.0' encoding='ASCII' standalone='yes'?>
 | 
			
		||||
<symbols version="0.90">
 | 
			
		||||
  <key name="AD01">
 | 
			
		||||
    <symbol label="1">1</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AD02">
 | 
			
		||||
    <symbol label="2">2</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AD03">
 | 
			
		||||
    <symbol label="3">3</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AC01">
 | 
			
		||||
    <symbol label="4">4</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AC02">
 | 
			
		||||
    <symbol label="5">5</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AC03">
 | 
			
		||||
    <symbol label="6">6</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AB01">
 | 
			
		||||
    <symbol label="7">7</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AB02">
 | 
			
		||||
    <symbol label="8">8</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AB03">
 | 
			
		||||
    <symbol label="9">9</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AB04">
 | 
			
		||||
    <symbol label="0">0</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="RTRN">
 | 
			
		||||
    <symbol keyval="65293" icon="key-enter">Return</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="BKSP">
 | 
			
		||||
    <symbol keyval="65288" icon="edit-clear-symbolic">BackSpace</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
</symbols>
 | 
			
		||||
@ -1,60 +0,0 @@
 | 
			
		||||
<?xml version='1.0' encoding='ASCII' standalone='yes'?>
 | 
			
		||||
<symbols version="0.90">
 | 
			
		||||
  <key name="AD01">
 | 
			
		||||
    <symbol label="1">1</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AD02">
 | 
			
		||||
    <symbol label="2">2</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AD03">
 | 
			
		||||
    <symbol label="3">3</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AD04">
 | 
			
		||||
    <symbol label=".">period</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AD05">
 | 
			
		||||
    <symbol label=",">comma</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AC01">
 | 
			
		||||
    <symbol label="4">4</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AC02">
 | 
			
		||||
    <symbol label="5">5</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AC03">
 | 
			
		||||
    <symbol label="6">6</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AC04">
 | 
			
		||||
    <symbol label="/">slash</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AC05">
 | 
			
		||||
    <symbol label="*">asterisk</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AB01">
 | 
			
		||||
    <symbol label="7">7</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AB02">
 | 
			
		||||
    <symbol label="8">8</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AB03">
 | 
			
		||||
    <symbol label="9">9</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AB04">
 | 
			
		||||
    <symbol label="+">plus</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AB05">
 | 
			
		||||
    <symbol label="-">minus</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AB06">
 | 
			
		||||
    <symbol label="0">0</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="RTRN">
 | 
			
		||||
    <symbol keyval="65293" icon="key-enter">Return</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="SPCE">
 | 
			
		||||
    <symbol label=" ">space</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="BKSP">
 | 
			
		||||
    <symbol keyval="65288" icon="edit-clear-symbolic">BackSpace</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
</symbols>
 | 
			
		||||
@ -1,231 +0,0 @@
 | 
			
		||||
<?xml version='1.0' encoding='ASCII' standalone='yes'?>
 | 
			
		||||
<symbols version="0.90">
 | 
			
		||||
  <key name="AD01">
 | 
			
		||||
    <symbol label="q">q</symbol>
 | 
			
		||||
    <symbol label="Q">Q</symbol>
 | 
			
		||||
    <symbol label=""></symbol>
 | 
			
		||||
    <symbol label="1">1</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AD02">
 | 
			
		||||
    <symbol label="w">w</symbol>
 | 
			
		||||
    <symbol label="W">W</symbol>
 | 
			
		||||
    <symbol label=""></symbol>
 | 
			
		||||
    <symbol label="2">2</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AD03">
 | 
			
		||||
    <symbol label="e">e</symbol>
 | 
			
		||||
    <symbol label="E">E</symbol>
 | 
			
		||||
    <symbol label=""></symbol>
 | 
			
		||||
    <symbol label="3">3</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AD04">
 | 
			
		||||
    <symbol label="r">r</symbol>
 | 
			
		||||
    <symbol label="R">R</symbol>
 | 
			
		||||
    <symbol label=""></symbol>
 | 
			
		||||
    <symbol label="4">4</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AD05">
 | 
			
		||||
    <symbol label="t">t</symbol>
 | 
			
		||||
    <symbol label="T">T</symbol>
 | 
			
		||||
    <symbol label=""></symbol>
 | 
			
		||||
    <symbol label="5">5</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AD06">
 | 
			
		||||
    <symbol label="y">y</symbol>
 | 
			
		||||
    <symbol label="Y">Y</symbol>
 | 
			
		||||
    <symbol label=""></symbol>
 | 
			
		||||
    <symbol label="6">6</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AD07">
 | 
			
		||||
    <symbol label="u">u</symbol>
 | 
			
		||||
    <symbol label="U">U</symbol>
 | 
			
		||||
    <symbol label=""></symbol>
 | 
			
		||||
    <symbol label="7">7</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AD08">
 | 
			
		||||
    <symbol label="i">i</symbol>
 | 
			
		||||
    <symbol label="I">I</symbol>
 | 
			
		||||
    <symbol label=""></symbol>
 | 
			
		||||
    <symbol label="8">8</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AD09">
 | 
			
		||||
    <symbol label="o">o</symbol>
 | 
			
		||||
    <symbol label="O">O</symbol>
 | 
			
		||||
    <symbol label=""></symbol>
 | 
			
		||||
    <symbol label="9">9</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AD10">
 | 
			
		||||
    <symbol label="p">p</symbol>
 | 
			
		||||
    <symbol label="P">P</symbol>
 | 
			
		||||
    <symbol label=""></symbol>
 | 
			
		||||
    <symbol label="0">0</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AC01">
 | 
			
		||||
    <symbol label="a">a</symbol>
 | 
			
		||||
    <symbol label="A">A</symbol>
 | 
			
		||||
    <symbol label="@">at</symbol>
 | 
			
		||||
    <symbol label="~">asciitilde</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AC02">
 | 
			
		||||
    <symbol label="s">s</symbol>
 | 
			
		||||
    <symbol label="S">S</symbol>
 | 
			
		||||
    <symbol label="#">numbersign</symbol>
 | 
			
		||||
    <symbol label="®">U00AE</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AC03">
 | 
			
		||||
    <symbol label="d">d</symbol>
 | 
			
		||||
    <symbol label="D">D</symbol>
 | 
			
		||||
    <symbol label="$">dollar</symbol>
 | 
			
		||||
    <symbol label="£">U00A3</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AC04">
 | 
			
		||||
    <symbol label="f">f</symbol>
 | 
			
		||||
    <symbol label="F">F</symbol>
 | 
			
		||||
    <symbol label="%">percent</symbol>
 | 
			
		||||
    <symbol label="€">EuroSign</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AC05">
 | 
			
		||||
    <symbol label="g">g</symbol>
 | 
			
		||||
    <symbol label="G">G</symbol>
 | 
			
		||||
    <symbol label="&">ampersand</symbol>
 | 
			
		||||
    <symbol label="¥">U00A5</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AC06">
 | 
			
		||||
    <symbol label="h">h</symbol>
 | 
			
		||||
    <symbol label="H">H</symbol>
 | 
			
		||||
    <symbol label="-">minus</symbol>
 | 
			
		||||
    <symbol label="^">asciicircum</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AC07">
 | 
			
		||||
    <symbol label="j">j</symbol>
 | 
			
		||||
    <symbol label="J">J</symbol>
 | 
			
		||||
    <symbol label="_">underscore</symbol>
 | 
			
		||||
    <symbol label="°">degree</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AC08">
 | 
			
		||||
    <symbol label="k">k</symbol>
 | 
			
		||||
    <symbol label="K">K</symbol>
 | 
			
		||||
    <symbol label="+">plus</symbol>
 | 
			
		||||
    <symbol label="=">equal</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AC09">
 | 
			
		||||
    <symbol label="l">l</symbol>
 | 
			
		||||
    <symbol label="L">L</symbol>
 | 
			
		||||
    <symbol label="(">parenleft</symbol>
 | 
			
		||||
    <symbol label="{">braceleft</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AC10">
 | 
			
		||||
    <symbol label=""></symbol>
 | 
			
		||||
    <symbol label=""></symbol>
 | 
			
		||||
    <symbol label=")">parenright</symbol>
 | 
			
		||||
    <symbol label="}">braceright</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="RTRN">
 | 
			
		||||
    <symbol keyval="65293" icon="key-enter">Return</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="LFSH">
 | 
			
		||||
    <keysym keyval="65505" icon="key-shift">Shift_L</keysym>
 | 
			
		||||
    <keysym keyval="65505" icon="key-shift">Shift_L</keysym>
 | 
			
		||||
    <keysym keyval="65505" label="123">Shift_L</keysym>
 | 
			
		||||
    <keysym keyval="65505" label="URL">Shift_L</keysym>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AB01">
 | 
			
		||||
    <symbol label="z">z</symbol>
 | 
			
		||||
    <symbol label="Z">Z</symbol>
 | 
			
		||||
    <symbol label=",">comma</symbol>
 | 
			
		||||
    <symbol label="\">backslash</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AB02">
 | 
			
		||||
    <symbol label="x">x</symbol>
 | 
			
		||||
    <symbol label="X">X</symbol>
 | 
			
		||||
    <symbol label=""">quotedbl</symbol>
 | 
			
		||||
    <symbol label="/">slash</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AB03">
 | 
			
		||||
    <symbol label="c">c</symbol>
 | 
			
		||||
    <symbol label="C">C</symbol>
 | 
			
		||||
    <symbol label="'">quoteright</symbol>
 | 
			
		||||
    <symbol label="<">less</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AB04">
 | 
			
		||||
    <symbol label="v">v</symbol>
 | 
			
		||||
    <symbol label="V">V</symbol>
 | 
			
		||||
    <symbol label=":">colon</symbol>
 | 
			
		||||
    <symbol label=">">greater</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AB05">
 | 
			
		||||
    <symbol label="b">b</symbol>
 | 
			
		||||
    <symbol label="B">B</symbol>
 | 
			
		||||
    <symbol label=";">semicolon</symbol>
 | 
			
		||||
    <symbol label="=">equal</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AB06">
 | 
			
		||||
    <symbol label="n">n</symbol>
 | 
			
		||||
    <symbol label="N">N</symbol>
 | 
			
		||||
    <symbol label="!">exclam</symbol>
 | 
			
		||||
    <symbol label="[">bracketleft</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AB07">
 | 
			
		||||
    <symbol label="m">m</symbol>
 | 
			
		||||
    <symbol label="M">M</symbol>
 | 
			
		||||
    <symbol label="?">question</symbol>
 | 
			
		||||
    <symbol label="]">bracketright</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AB08">
 | 
			
		||||
    <symbol label=".">period</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="ABC123">
 | 
			
		||||
    <symbol label="URL">show-url</symbol>
 | 
			
		||||
    <symbol label="URL">show-url</symbol>
 | 
			
		||||
    <symbol label="ABC">show-letters</symbol>
 | 
			
		||||
    <symbol label="ABC">show-letters</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="I149">
 | 
			
		||||
    <symbol label="☺" icon="keyboard-mode-symbolic" tooltip="Setup">preferences</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="SPCE">
 | 
			
		||||
    <symbol label=" ">space</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="BKSP">
 | 
			
		||||
    <symbol keyval="65288" icon="edit-clear-symbolic">BackSpace</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
 | 
			
		||||
<!-- Extra URL mode buttons -->
 | 
			
		||||
  <key name="AE01">
 | 
			
		||||
    <symbol label=""></symbol>
 | 
			
		||||
    <symbol label=""></symbol>
 | 
			
		||||
    <text label="https">https</text>
 | 
			
		||||
    <symbol label=""></symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AE02">
 | 
			
		||||
    <symbol label=""></symbol>
 | 
			
		||||
    <symbol label=""></symbol>
 | 
			
		||||
    <text label="://">://</text>
 | 
			
		||||
    <symbol label=""></symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AE03">
 | 
			
		||||
    <symbol label=""></symbol>
 | 
			
		||||
    <symbol label=""></symbol>
 | 
			
		||||
    <text label="www.">www.</text>
 | 
			
		||||
    <symbol label=""></symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AE04">
 | 
			
		||||
    <symbol label=""></symbol>
 | 
			
		||||
    <symbol label=""></symbol>
 | 
			
		||||
    <text label=".com">.com</text>
 | 
			
		||||
    <symbol label=""></symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AE05">
 | 
			
		||||
    <symbol label=""></symbol>
 | 
			
		||||
    <symbol label=""></symbol>
 | 
			
		||||
    <text label=".org">.org</text>
 | 
			
		||||
    <symbol label=""></symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AE06">
 | 
			
		||||
    <symbol label=""></symbol>
 | 
			
		||||
    <symbol label=""></symbol>
 | 
			
		||||
    <text label=".net">.net</text>
 | 
			
		||||
    <symbol label=""></symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
 | 
			
		||||
</symbols>
 | 
			
		||||
@ -115,8 +115,6 @@
 | 
			
		||||
    <symbol label="{">braceleft</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AC10">
 | 
			
		||||
    <!-- Empty labels cause keys to be hidden when the level they are defined
 | 
			
		||||
         for is shown. -->
 | 
			
		||||
    <symbol label=""></symbol>
 | 
			
		||||
    <symbol label=""></symbol>
 | 
			
		||||
    <symbol label=")">parenright</symbol>
 | 
			
		||||
 | 
			
		||||
@ -2,19 +2,13 @@
 | 
			
		||||
<gresources>
 | 
			
		||||
  <gresource prefix="/sm/puri/squeekboard">
 | 
			
		||||
   <file compressed="true">style.css</file>
 | 
			
		||||
 | 
			
		||||
<!-- Keyboard layouts -->
 | 
			
		||||
   <file compressed="true" preprocess="xml-stripblanks">keyboards/geometry/compact.xml</file>
 | 
			
		||||
   <file compressed="true" preprocess="xml-stripblanks">keyboards/geometry/extended.xml</file>
 | 
			
		||||
   <file compressed="true" preprocess="xml-stripblanks">keyboards/geometry/digits.xml</file>
 | 
			
		||||
   <file compressed="true" preprocess="xml-stripblanks">keyboards/geometry/number-keypad.xml</file>
 | 
			
		||||
   <file compressed="true" preprocess="xml-stripblanks">keyboards/geometry/phone-keypad.xml</file>
 | 
			
		||||
   <file compressed="true" preprocess="xml-stripblanks">keyboards/geometry/url.xml</file>
 | 
			
		||||
 | 
			
		||||
<!-- Keyboard definitions -->
 | 
			
		||||
   <file compressed="true" preprocess="xml-stripblanks">keyboards/geometry/numbers-keypad.xml</file>
 | 
			
		||||
   <file compressed="true" preprocess="xml-stripblanks">keyboards/keyboards.xml</file>
 | 
			
		||||
 | 
			
		||||
<!-- Natural language keyboards -->
 | 
			
		||||
   <file compressed="true">keyboards/keymaps/nb.xkb</file>
 | 
			
		||||
   <file compressed="true">keyboards/keymaps/us.xkb</file>
 | 
			
		||||
   <file compressed="true">keyboards/keymaps/numbers.xkb</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>
 | 
			
		||||
@ -44,13 +38,7 @@
 | 
			
		||||
   <file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/ug.xml</file>
 | 
			
		||||
   <file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/us.xml</file>
 | 
			
		||||
   <file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/zh-bopomofo.xml</file>
 | 
			
		||||
 | 
			
		||||
<!-- Special purpose keyboards -->
 | 
			
		||||
   <file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/special/digits.xml</file>
 | 
			
		||||
   <file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/special/number.xml</file>
 | 
			
		||||
   <file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/special/phone.xml</file>
 | 
			
		||||
   <file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/special/url.xml</file>
 | 
			
		||||
 | 
			
		||||
   <file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/special/numbers.xml</file>
 | 
			
		||||
   <file>icons/key-enter.svg</file>
 | 
			
		||||
   <file>icons/key-shift.svg</file>
 | 
			
		||||
   <file>icons/keyboard-mode-symbolic.svg</file>
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										5
									
								
								debian/control
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										5
									
								
								debian/control
									
									
									
									
										vendored
									
									
								
							@ -11,10 +11,7 @@ Build-Depends:
 | 
			
		||||
 libcroco3-dev,
 | 
			
		||||
 libwayland-dev (>= 1.16),
 | 
			
		||||
 rustc,
 | 
			
		||||
 wayland-protocols (>= 1.14),
 | 
			
		||||
# for running the tests
 | 
			
		||||
 xvfb,
 | 
			
		||||
 xauth,
 | 
			
		||||
 wayland-protocols (>= 1.14)
 | 
			
		||||
Standards-Version: 4.1.3
 | 
			
		||||
Homepage: https://source.puri.sm/Librem5/squeekboard
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -50,7 +50,7 @@ static void
 | 
			
		||||
eek_container_real_add_child (EekContainer *self,
 | 
			
		||||
                              EekElement   *child)
 | 
			
		||||
{
 | 
			
		||||
    EekContainerPrivate *priv = (EekContainerPrivate*)eek_container_get_instance_private (self);
 | 
			
		||||
    EekContainerPrivate *priv = eek_container_get_instance_private (self);
 | 
			
		||||
 | 
			
		||||
    g_return_if_fail (EEK_IS_ELEMENT(child));
 | 
			
		||||
    g_object_ref (child);
 | 
			
		||||
 | 
			
		||||
@ -100,7 +100,6 @@ eek_element_set_property (GObject      *object,
 | 
			
		||||
        break;
 | 
			
		||||
    case PROP_LEVEL:
 | 
			
		||||
        eek_element_set_level (element, g_value_get_int (value));
 | 
			
		||||
        break;
 | 
			
		||||
    default:
 | 
			
		||||
        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 | 
			
		||||
        break;
 | 
			
		||||
 | 
			
		||||
@ -55,8 +55,7 @@ typedef struct _EekGtkKeyboardPrivate
 | 
			
		||||
{
 | 
			
		||||
    EekRenderer *renderer;
 | 
			
		||||
    EekKeyboard *keyboard;
 | 
			
		||||
    GtkCssProvider *css_provider;
 | 
			
		||||
    GtkStyleContext *scontext;
 | 
			
		||||
    EekTheme *theme;
 | 
			
		||||
 | 
			
		||||
    GdkEventSequence *sequence; // unowned reference
 | 
			
		||||
} EekGtkKeyboardPrivate;
 | 
			
		||||
@ -67,6 +66,16 @@ static void       on_key_pressed          (EekKey      *key,
 | 
			
		||||
                                           EekGtkKeyboard *self);
 | 
			
		||||
static void       on_key_released         (EekKey      *key,
 | 
			
		||||
                                           EekGtkKeyboard *self);
 | 
			
		||||
static void       on_key_locked          (EekKeyboard *keyboard,
 | 
			
		||||
                                           EekKey      *key,
 | 
			
		||||
                                           gpointer     user_data);
 | 
			
		||||
static void       on_key_unlocked         (EekKeyboard *keyboard,
 | 
			
		||||
                                           EekKey      *key,
 | 
			
		||||
                                           gpointer     user_data);
 | 
			
		||||
static void       on_symbol_index_changed (EekKeyboard *keyboard,
 | 
			
		||||
                                           gint         group,
 | 
			
		||||
                                           gint         level,
 | 
			
		||||
                                           gpointer     user_data);
 | 
			
		||||
static void       render_pressed_key      (GtkWidget   *widget,
 | 
			
		||||
                                           EekKey      *key);
 | 
			
		||||
static void       render_locked_key       (GtkWidget   *widget,
 | 
			
		||||
@ -100,9 +109,12 @@ eek_gtk_keyboard_real_draw (GtkWidget *self,
 | 
			
		||||
    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_renderer_new (priv->keyboard, pcontext);
 | 
			
		||||
        if (priv->theme)
 | 
			
		||||
            eek_renderer_set_theme (priv->renderer, priv->theme);
 | 
			
		||||
 | 
			
		||||
        eek_renderer_set_allocation_size (priv->renderer,
 | 
			
		||||
                                          allocation.width,
 | 
			
		||||
@ -147,11 +159,9 @@ eek_gtk_keyboard_real_size_allocate (GtkWidget     *self,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void depress(EekGtkKeyboard *self,
 | 
			
		||||
                    gdouble x, gdouble y, guint32 time)
 | 
			
		||||
{
 | 
			
		||||
                    gdouble x, gdouble y, guint32 time) {
 | 
			
		||||
    EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (self);
 | 
			
		||||
    EekKey *key = eek_renderer_find_key_by_position (priv->renderer, x, y);
 | 
			
		||||
 | 
			
		||||
    if (key) {
 | 
			
		||||
        eek_keyboard_press_key(priv->keyboard, key, time);
 | 
			
		||||
        on_key_pressed(key, self);
 | 
			
		||||
@ -162,17 +172,16 @@ static void drag(EekGtkKeyboard *self,
 | 
			
		||||
                 gdouble x, gdouble y, guint32 time) {
 | 
			
		||||
    EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (self);
 | 
			
		||||
    EekKey *key = eek_renderer_find_key_by_position (priv->renderer, x, y);
 | 
			
		||||
    GList *list, *head;
 | 
			
		||||
 | 
			
		||||
    list = eek_keyboard_get_pressed_keys (priv->keyboard);
 | 
			
		||||
 | 
			
		||||
    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 == key) {
 | 
			
		||||
            if (head->data == key)
 | 
			
		||||
                found = TRUE;
 | 
			
		||||
            } else {
 | 
			
		||||
            else {
 | 
			
		||||
                eek_keyboard_release_key(priv->keyboard, EEK_KEY(head->data), time);
 | 
			
		||||
                on_key_released(key, self);
 | 
			
		||||
            }
 | 
			
		||||
@ -183,12 +192,6 @@ static void drag(EekGtkKeyboard *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_key(priv->keyboard, EEK_KEY(head->data), time);
 | 
			
		||||
            on_key_released(key, self);
 | 
			
		||||
        }
 | 
			
		||||
        g_list_free (list);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -329,10 +332,18 @@ eek_gtk_keyboard_set_keyboard (EekGtkKeyboard *self,
 | 
			
		||||
        return;
 | 
			
		||||
 | 
			
		||||
    if (priv->keyboard) {
 | 
			
		||||
        g_signal_handlers_disconnect_by_data(priv->keyboard, self);
 | 
			
		||||
        g_object_unref (priv->keyboard);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    priv->keyboard = g_object_ref (keyboard);
 | 
			
		||||
 | 
			
		||||
    g_signal_connect (priv->keyboard, "key-locked",
 | 
			
		||||
                      G_CALLBACK(on_key_locked), self);
 | 
			
		||||
    g_signal_connect (priv->keyboard, "key-unlocked",
 | 
			
		||||
                      G_CALLBACK(on_key_unlocked), self);
 | 
			
		||||
    g_signal_connect (priv->keyboard, "symbol-index-changed",
 | 
			
		||||
                      G_CALLBACK(on_symbol_index_changed), self);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
@ -368,6 +379,7 @@ eek_gtk_keyboard_dispose (GObject *object)
 | 
			
		||||
    if (priv->keyboard) {
 | 
			
		||||
        GList *list, *head;
 | 
			
		||||
 | 
			
		||||
        g_signal_handlers_disconnect_by_data(priv->keyboard, self);
 | 
			
		||||
        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");
 | 
			
		||||
@ -379,6 +391,11 @@ eek_gtk_keyboard_dispose (GObject *object)
 | 
			
		||||
        priv->keyboard = NULL;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (priv->theme) {
 | 
			
		||||
        g_object_unref (priv->theme);
 | 
			
		||||
        priv->theme = NULL;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    G_OBJECT_CLASS (eek_gtk_keyboard_parent_class)->dispose (object);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -419,20 +436,7 @@ eek_gtk_keyboard_class_init (EekGtkKeyboardClass *klass)
 | 
			
		||||
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);
 | 
			
		||||
    /* void */
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@ -477,15 +481,25 @@ render_pressed_key (GtkWidget *widget,
 | 
			
		||||
{
 | 
			
		||||
    EekGtkKeyboard        *self = EEK_GTK_KEYBOARD (widget);
 | 
			
		||||
    EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (self);
 | 
			
		||||
    EekBounds bounds, large_bounds;
 | 
			
		||||
 | 
			
		||||
    GdkWindow         *window  = gtk_widget_get_window (widget);
 | 
			
		||||
    cairo_region_t    *region  = gdk_window_get_clip_region (window);
 | 
			
		||||
    GdkDrawingContext *context = gdk_window_begin_draw_frame (window, region);
 | 
			
		||||
    cairo_t           *cr      = gdk_drawing_context_get_cairo_context (context);
 | 
			
		||||
 | 
			
		||||
    eek_renderer_get_key_bounds (priv->renderer, key, &bounds, TRUE);
 | 
			
		||||
    magnify_bounds (widget, &bounds, &large_bounds, 1.5);
 | 
			
		||||
 | 
			
		||||
    cairo_save (cr);
 | 
			
		||||
    cairo_translate (cr, bounds.x, bounds.y);
 | 
			
		||||
    eek_renderer_render_key (priv->renderer, cr, key, 1.0, TRUE);
 | 
			
		||||
    cairo_restore (cr);
 | 
			
		||||
/*
 | 
			
		||||
    cairo_save (cr);
 | 
			
		||||
    cairo_translate (cr, large_bounds.x, large_bounds.y);
 | 
			
		||||
    eek_renderer_render_key (priv->renderer, cr, key, 1.5, TRUE);
 | 
			
		||||
    cairo_restore (cr);
 | 
			
		||||
*/
 | 
			
		||||
    gdk_window_end_draw_frame (window, context);
 | 
			
		||||
 | 
			
		||||
@ -498,12 +512,16 @@ render_locked_key (GtkWidget *widget,
 | 
			
		||||
{
 | 
			
		||||
    EekGtkKeyboard        *self = EEK_GTK_KEYBOARD (widget);
 | 
			
		||||
    EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (self);
 | 
			
		||||
    EekBounds bounds;
 | 
			
		||||
 | 
			
		||||
    GdkWindow         *window  = gtk_widget_get_window (widget);
 | 
			
		||||
    cairo_region_t    *region  = gdk_window_get_clip_region (window);
 | 
			
		||||
    GdkDrawingContext *context = gdk_window_begin_draw_frame (window, region);
 | 
			
		||||
    cairo_t           *cr      = gdk_drawing_context_get_cairo_context (context);
 | 
			
		||||
 | 
			
		||||
    eek_renderer_get_key_bounds (priv->renderer, key, &bounds, TRUE);
 | 
			
		||||
 | 
			
		||||
    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);
 | 
			
		||||
@ -517,12 +535,16 @@ render_released_key (GtkWidget *widget,
 | 
			
		||||
{
 | 
			
		||||
    EekGtkKeyboard        *self = EEK_GTK_KEYBOARD (widget);
 | 
			
		||||
    EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (self);
 | 
			
		||||
    EekBounds bounds, large_bounds;
 | 
			
		||||
 | 
			
		||||
    GdkWindow         *window  = gtk_widget_get_window (widget);
 | 
			
		||||
    cairo_region_t    *region  = gdk_window_get_clip_region (window);
 | 
			
		||||
    GdkDrawingContext *context = gdk_window_begin_draw_frame (window, region);
 | 
			
		||||
    cairo_t           *cr      = gdk_drawing_context_get_cairo_context (context);
 | 
			
		||||
 | 
			
		||||
    eek_renderer_get_key_bounds (priv->renderer, key, &bounds, TRUE);
 | 
			
		||||
    magnify_bounds (widget, &bounds, &large_bounds, 1.5);
 | 
			
		||||
 | 
			
		||||
    eek_renderer_render_keyboard (priv->renderer, cr);
 | 
			
		||||
 | 
			
		||||
    gdk_window_end_draw_frame (window, context);
 | 
			
		||||
@ -573,3 +595,57 @@ on_key_released (EekKey      *key,
 | 
			
		||||
                            NULL);
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
on_key_locked (EekKeyboard *keyboard,
 | 
			
		||||
               EekKey      *key,
 | 
			
		||||
               gpointer     user_data)
 | 
			
		||||
{
 | 
			
		||||
    GtkWidget *widget = user_data;
 | 
			
		||||
    EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (user_data);
 | 
			
		||||
 | 
			
		||||
    /* renderer may have not been set yet if the widget is a popup */
 | 
			
		||||
    if (!priv->renderer)
 | 
			
		||||
        return;
 | 
			
		||||
 | 
			
		||||
    render_locked_key (widget, key);
 | 
			
		||||
    gtk_widget_queue_draw (widget);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
on_key_unlocked (EekKeyboard *keyboard,
 | 
			
		||||
                 EekKey      *key,
 | 
			
		||||
                 gpointer     user_data)
 | 
			
		||||
{
 | 
			
		||||
    GtkWidget *widget = user_data;
 | 
			
		||||
    EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (user_data);
 | 
			
		||||
 | 
			
		||||
    /* renderer may have not been set yet if the widget is a popup */
 | 
			
		||||
    if (!priv->renderer)
 | 
			
		||||
        return;
 | 
			
		||||
 | 
			
		||||
    render_released_key (widget, key);
 | 
			
		||||
    gtk_widget_queue_draw (GTK_WIDGET(widget));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
on_symbol_index_changed (EekKeyboard *keyboard,
 | 
			
		||||
                         gint         group,
 | 
			
		||||
                         gint         level,
 | 
			
		||||
                         gpointer     user_data)
 | 
			
		||||
{
 | 
			
		||||
    GtkWidget *widget = user_data;
 | 
			
		||||
 | 
			
		||||
    gtk_widget_queue_draw (widget);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
eek_gtk_keyboard_set_theme (EekGtkKeyboard *keyboard,
 | 
			
		||||
                            EekTheme       *theme)
 | 
			
		||||
{
 | 
			
		||||
    g_return_if_fail (EEK_IS_GTK_KEYBOARD(keyboard));
 | 
			
		||||
    g_return_if_fail (EEK_IS_THEME(theme));
 | 
			
		||||
 | 
			
		||||
    EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (keyboard);
 | 
			
		||||
    priv->theme = g_object_ref (theme);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -46,6 +46,8 @@ struct _EekGtkKeyboardClass
 | 
			
		||||
 | 
			
		||||
GType      eek_gtk_keyboard_get_type  (void) G_GNUC_CONST;
 | 
			
		||||
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 */
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										101
									
								
								eek/eek-key.c
									
									
									
									
									
								
							
							
						
						
									
										101
									
								
								eek/eek-key.c
									
									
									
									
									
								
							@ -38,6 +38,8 @@ enum {
 | 
			
		||||
    PROP_0,
 | 
			
		||||
    PROP_KEYCODE,
 | 
			
		||||
    PROP_SYMBOL_MATRIX,
 | 
			
		||||
    PROP_COLUMN,
 | 
			
		||||
    PROP_ROW,
 | 
			
		||||
    PROP_OREF,
 | 
			
		||||
    PROP_LAST
 | 
			
		||||
};
 | 
			
		||||
@ -54,6 +56,8 @@ typedef struct _EekKeyPrivate
 | 
			
		||||
{
 | 
			
		||||
    guint keycode;
 | 
			
		||||
    EekSymbolMatrix *symbol_matrix;
 | 
			
		||||
    gint column;
 | 
			
		||||
    gint row;
 | 
			
		||||
    gulong oref; // UI outline reference
 | 
			
		||||
    gboolean is_pressed;
 | 
			
		||||
    gboolean is_locked;
 | 
			
		||||
@ -101,6 +105,8 @@ eek_key_set_property (GObject      *object,
 | 
			
		||||
                      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));
 | 
			
		||||
@ -109,6 +115,14 @@ eek_key_set_property (GObject      *object,
 | 
			
		||||
        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;
 | 
			
		||||
@ -124,6 +138,8 @@ eek_key_get_property (GObject    *object,
 | 
			
		||||
                      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)));
 | 
			
		||||
@ -132,6 +148,14 @@ eek_key_get_property (GObject    *object,
 | 
			
		||||
        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;
 | 
			
		||||
@ -179,6 +203,30 @@ eek_key_class_init (EekKeyClass *klass)
 | 
			
		||||
                                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:
 | 
			
		||||
     *
 | 
			
		||||
@ -430,6 +478,59 @@ eek_key_get_symbol_at_index (EekKey *key,
 | 
			
		||||
                                     level];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eek_key_set_index:
 | 
			
		||||
 * @key: an #EekKey
 | 
			
		||||
 * @column: column index of @key in #EekSection
 | 
			
		||||
 * @row: row index of @key in #EekSection
 | 
			
		||||
 *
 | 
			
		||||
 * Set the location of @key in #EekSection with @column and @row.
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
eek_key_set_index (EekKey *key,
 | 
			
		||||
                   gint    column,
 | 
			
		||||
                   gint    row)
 | 
			
		||||
{
 | 
			
		||||
    g_return_if_fail (EEK_IS_KEY(key));
 | 
			
		||||
    g_return_if_fail (0 <= column);
 | 
			
		||||
    g_return_if_fail (0 <= row);
 | 
			
		||||
 | 
			
		||||
    EekKeyPrivate *priv = eek_key_get_instance_private (key);
 | 
			
		||||
 | 
			
		||||
    if (priv->column != column) {
 | 
			
		||||
        priv->column = column;
 | 
			
		||||
        g_object_notify (G_OBJECT(key), "column");
 | 
			
		||||
    }
 | 
			
		||||
    if (priv->row != row) {
 | 
			
		||||
        priv->row = row;
 | 
			
		||||
        g_object_notify (G_OBJECT(key), "row");
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eek_key_get_index:
 | 
			
		||||
 * @key: an #EekKey
 | 
			
		||||
 * @column: (allow-none): pointer where the column index of @key in #EekSection will be stored
 | 
			
		||||
 * @row: (allow-none): pointer where the row index of @key in #EekSection will be stored
 | 
			
		||||
 *
 | 
			
		||||
 * Get the location of @key in #EekSection.
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
eek_key_get_index (EekKey *key,
 | 
			
		||||
                   gint   *column,
 | 
			
		||||
                   gint   *row)
 | 
			
		||||
{
 | 
			
		||||
    g_return_if_fail (EEK_IS_KEY(key));
 | 
			
		||||
    g_return_if_fail (column != NULL || row != NULL);
 | 
			
		||||
 | 
			
		||||
    EekKeyPrivate *priv = eek_key_get_instance_private (key);
 | 
			
		||||
 | 
			
		||||
    if (column != NULL)
 | 
			
		||||
        *column = priv->column;
 | 
			
		||||
    if (row != NULL)
 | 
			
		||||
        *row = priv->row;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eek_key_set_oref:
 | 
			
		||||
 * @key: an #EekKey
 | 
			
		||||
 | 
			
		||||
@ -73,6 +73,13 @@ EekSymbol       *eek_key_get_symbol_at_index (EekKey          *key,
 | 
			
		||||
                                              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);
 | 
			
		||||
 | 
			
		||||
@ -28,7 +28,6 @@
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "config.h"
 | 
			
		||||
#include <glib/gprintf.h>
 | 
			
		||||
 | 
			
		||||
#include "eek-keyboard.h"
 | 
			
		||||
#include "eek-marshalers.h"
 | 
			
		||||
@ -37,7 +36,6 @@
 | 
			
		||||
#include "eek-symbol.h"
 | 
			
		||||
#include "eek-enumtypes.h"
 | 
			
		||||
#include "eekboard/key-emitter.h"
 | 
			
		||||
#include "keymap.h"
 | 
			
		||||
 | 
			
		||||
enum {
 | 
			
		||||
    PROP_0,
 | 
			
		||||
@ -74,11 +72,7 @@ struct _EekKeyboardPrivate
 | 
			
		||||
    GList *pressed_keys;
 | 
			
		||||
    GList *locked_keys;
 | 
			
		||||
    GArray *outline_array;
 | 
			
		||||
 | 
			
		||||
    /* Map key names to key objects */
 | 
			
		||||
    GHashTable *names;
 | 
			
		||||
    /* Map characters to symbols and levels */
 | 
			
		||||
    GHashTable *character_map;
 | 
			
		||||
 | 
			
		||||
    /* modifiers dynamically assigned at run time */
 | 
			
		||||
    EekModifierType num_lock_mask;
 | 
			
		||||
@ -407,7 +401,6 @@ eek_keyboard_finalize (GObject *object)
 | 
			
		||||
                      (GDestroyNotify) eek_modifier_key_free);
 | 
			
		||||
 | 
			
		||||
    g_hash_table_destroy (priv->names);
 | 
			
		||||
    g_hash_table_destroy (priv->character_map);
 | 
			
		||||
 | 
			
		||||
    for (i = 0; i < priv->outline_array->len; i++) {
 | 
			
		||||
        EekOutline *outline = &g_array_index (priv->outline_array,
 | 
			
		||||
@ -536,8 +529,6 @@ eek_keyboard_init (EekKeyboard *self)
 | 
			
		||||
    self->priv->modifier_behavior = EEK_MODIFIER_BEHAVIOR_NONE;
 | 
			
		||||
    self->priv->outline_array = g_array_new (FALSE, TRUE, sizeof (EekOutline));
 | 
			
		||||
    self->priv->names = g_hash_table_new (g_str_hash, g_str_equal);
 | 
			
		||||
    self->priv->character_map = g_hash_table_new_full (g_str_hash, g_str_equal,
 | 
			
		||||
        NULL, g_free);
 | 
			
		||||
    eek_element_set_symbol_index (EEK_ELEMENT(self), 0, 0);
 | 
			
		||||
    self->scale = 1.0;
 | 
			
		||||
}
 | 
			
		||||
@ -805,117 +796,3 @@ eek_keyboard_get_locked_keys (EekKeyboard *keyboard)
 | 
			
		||||
    g_return_val_if_fail (EEK_IS_KEYBOARD(keyboard), NULL);
 | 
			
		||||
    return g_list_copy (keyboard->priv->locked_keys);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eek_keyboard_get_keymap:
 | 
			
		||||
 * @keyboard: an #EekKeyboard
 | 
			
		||||
 *
 | 
			
		||||
 * Get the keymap for the keyboard.
 | 
			
		||||
 * Returns: a string containing the XKB keymap.
 | 
			
		||||
 */
 | 
			
		||||
gchar *
 | 
			
		||||
eek_keyboard_get_keymap(EekKeyboard *keyboard)
 | 
			
		||||
{
 | 
			
		||||
    /* Start the keycodes and symbols sections with their respective headers. */
 | 
			
		||||
    gchar *keycodes = g_strdup(keymap_keycodes_header);
 | 
			
		||||
    gchar *symbols = g_strdup(keymap_symbols_header);
 | 
			
		||||
 | 
			
		||||
    /* Iterate over the keys in the name-to-key hash table. */
 | 
			
		||||
    GHashTableIter iter;
 | 
			
		||||
    gpointer key_name, key_ptr;
 | 
			
		||||
    g_hash_table_iter_init(&iter, keyboard->priv->names);
 | 
			
		||||
 | 
			
		||||
    while (g_hash_table_iter_next(&iter, &key_name, &key_ptr)) {
 | 
			
		||||
 | 
			
		||||
        gchar *current, *line;
 | 
			
		||||
        EekKey *key = EEK_KEY(key_ptr);
 | 
			
		||||
        int keycode = eek_key_get_keycode(key);
 | 
			
		||||
 | 
			
		||||
        /* Don't include invalid keycodes in the keymap. */
 | 
			
		||||
        if (keycode == EEK_INVALID_KEYCODE)
 | 
			
		||||
            continue;
 | 
			
		||||
 | 
			
		||||
        /* Append a key name-to-keycode definition to the keycodes section. */
 | 
			
		||||
        current = keycodes;
 | 
			
		||||
        line = g_strdup_printf("        <%s> = %i;\n", (char *)key_name, keycode);
 | 
			
		||||
 | 
			
		||||
        keycodes = g_strconcat(current, line, NULL);
 | 
			
		||||
        g_free(line);
 | 
			
		||||
        g_free(current);
 | 
			
		||||
 | 
			
		||||
        /* Find the symbols associated with the key. */
 | 
			
		||||
        EekSymbolMatrix *matrix = eek_key_get_symbol_matrix(key);
 | 
			
		||||
        EekSymbol *syms[4];
 | 
			
		||||
        int i, j;
 | 
			
		||||
 | 
			
		||||
        /* Get the symbols for all the levels defined for the key, then
 | 
			
		||||
           pad it out with the first symbol for all levels up to the fourth. */
 | 
			
		||||
        for (i = 0; (i < matrix->num_levels) && (i < 4); ++i)
 | 
			
		||||
            syms[i] = eek_symbol_matrix_get_symbol(matrix, 0, i);
 | 
			
		||||
 | 
			
		||||
        while (i < 4) {
 | 
			
		||||
            syms[i] = eek_symbol_matrix_get_symbol(matrix, 0, 0);
 | 
			
		||||
            i++;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /* The four levels are split into two groups in the keymap.
 | 
			
		||||
           Generate strings for each of these groups, where an empty group is
 | 
			
		||||
           treated specially. */
 | 
			
		||||
 | 
			
		||||
        gchar *groups[2] = {NULL, NULL};
 | 
			
		||||
        for (i = 0, j = 0; i < 2; ++i, j += 2) {
 | 
			
		||||
            if (syms[j] && syms[j + 1])
 | 
			
		||||
                groups[i] = g_strjoin(", ", eek_symbol_get_name(syms[j]),
 | 
			
		||||
                                            eek_symbol_get_name(syms[j + 1]),
 | 
			
		||||
                                            NULL);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /* Append a key definition to the symbols section. */
 | 
			
		||||
        current = symbols;
 | 
			
		||||
        line = g_strdup_printf("        key <%s> { [ %s ], [ %s ] };\n",
 | 
			
		||||
                               (char *)key_name, groups[0], groups[1]);
 | 
			
		||||
 | 
			
		||||
        g_free(groups[0]);
 | 
			
		||||
        g_free(groups[1]);
 | 
			
		||||
 | 
			
		||||
        symbols = g_strconcat(current, line, NULL);
 | 
			
		||||
        g_free(line);
 | 
			
		||||
        g_free(current);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* Assemble the keymap file from the header, sections and footer. */
 | 
			
		||||
    gchar *keymap = g_strconcat(keymap_header,
 | 
			
		||||
                                keycodes, "    };\n\n",
 | 
			
		||||
                                symbols, "    };\n\n",
 | 
			
		||||
                                keymap_footer, NULL);
 | 
			
		||||
 | 
			
		||||
    g_free(keycodes);
 | 
			
		||||
    g_free(symbols);
 | 
			
		||||
    return keymap;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
eek_keyboard_register_symbol (EekKeyboard *keyboard,
 | 
			
		||||
                              EekSymbol   *symbol,
 | 
			
		||||
                              EekKey      *key,
 | 
			
		||||
                              guint        level)
 | 
			
		||||
{
 | 
			
		||||
    const gchar *label = eek_symbol_get_label(symbol);
 | 
			
		||||
 | 
			
		||||
    if (label) {
 | 
			
		||||
        EekKeyPress *key_press = g_malloc0 (sizeof(EekKeyPress));
 | 
			
		||||
        key_press->key = key;
 | 
			
		||||
        key_press->level = level;
 | 
			
		||||
 | 
			
		||||
        g_hash_table_insert (keyboard->priv->character_map,
 | 
			
		||||
                             (gpointer)label,
 | 
			
		||||
                             key_press);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
EekKeyPress *
 | 
			
		||||
eek_keyboard_get_key_press (EekKeyboard *keyboard,
 | 
			
		||||
                         gchar       *ch)
 | 
			
		||||
{
 | 
			
		||||
    return g_hash_table_lookup (keyboard->priv->character_map, ch);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -124,11 +124,6 @@ struct _EekModifierKey {
 | 
			
		||||
};
 | 
			
		||||
typedef struct _EekModifierKey EekModifierKey;
 | 
			
		||||
 | 
			
		||||
struct _EekKeyPress {
 | 
			
		||||
    EekKey *key;
 | 
			
		||||
    guint level;
 | 
			
		||||
};
 | 
			
		||||
typedef struct _EekKeyPress EekKeyPress;
 | 
			
		||||
 | 
			
		||||
EekKeyboard        *eek_keyboard_new (EekboardContextService *manager,
 | 
			
		||||
                                      EekLayout          *layout,
 | 
			
		||||
@ -200,18 +195,5 @@ void                eek_modifier_key_free
 | 
			
		||||
void eek_keyboard_press_key(EekKeyboard *keyboard, EekKey *key, guint32 timestamp);
 | 
			
		||||
void eek_keyboard_release_key(EekKeyboard *keyboard, EekKey *key, guint32 timestamp);
 | 
			
		||||
 | 
			
		||||
gchar *             eek_keyboard_get_keymap
 | 
			
		||||
                                     (EekKeyboard        *keyboard);
 | 
			
		||||
 | 
			
		||||
void                eek_keyboard_register_symbol
 | 
			
		||||
                                     (EekKeyboard        *keyboard,
 | 
			
		||||
                                      EekSymbol          *symbol,
 | 
			
		||||
                                      EekKey             *key,
 | 
			
		||||
                                      guint               level);
 | 
			
		||||
 | 
			
		||||
EekKeyPress *       eek_keyboard_get_key_press
 | 
			
		||||
                                     (EekKeyboard        *keyboard,
 | 
			
		||||
                                      gchar              *ch);
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
#endif  /* EEK_KEYBOARD_H */
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										122
									
								
								eek/eek-keysym.c
									
									
									
									
									
								
							
							
						
						
									
										122
									
								
								eek/eek-keysym.c
									
									
									
									
									
								
							@ -48,9 +48,15 @@
 | 
			
		||||
#define EEK_KEYSYM_Hyper_L 0xffed
 | 
			
		||||
#define EEK_KEYSYM_Hyper_R 0xffee
 | 
			
		||||
 | 
			
		||||
typedef struct _EekKeysymPrivate
 | 
			
		||||
{
 | 
			
		||||
    guint xkeysym;
 | 
			
		||||
} EekKeysymPrivate;
 | 
			
		||||
 | 
			
		||||
struct _EekKeysymEntry {
 | 
			
		||||
    guint xkeysym;
 | 
			
		||||
    const gchar *name;
 | 
			
		||||
    EekSymbolCategory category;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
typedef struct _EekKeysymEntry EekKeysymEntry;
 | 
			
		||||
@ -59,6 +65,54 @@ typedef struct _EekKeysymEntry EekKeysymEntry;
 | 
			
		||||
#include "eek-unicode-keysym-entries.h"
 | 
			
		||||
#include "eek-xkeysym-keysym-entries.h"
 | 
			
		||||
 | 
			
		||||
static void eek_serializable_iface_init (EekSerializableIface *iface);
 | 
			
		||||
 | 
			
		||||
G_DEFINE_TYPE_EXTENDED (EekKeysym, eek_keysym, EEK_TYPE_SYMBOL,
 | 
			
		||||
			0, /* GTypeFlags */
 | 
			
		||||
			G_ADD_PRIVATE (EekKeysym)
 | 
			
		||||
                        G_IMPLEMENT_INTERFACE (EEK_TYPE_SERIALIZABLE,
 | 
			
		||||
                                               eek_serializable_iface_init))
 | 
			
		||||
 | 
			
		||||
static EekSerializableIface *eek_keysym_parent_serializable_iface;
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
eek_keysym_real_serialize (EekSerializable *self,
 | 
			
		||||
                           GVariantBuilder *builder)
 | 
			
		||||
{
 | 
			
		||||
    EekKeysymPrivate *priv = eek_keysym_get_instance_private (
 | 
			
		||||
		    EEK_KEYSYM(self));
 | 
			
		||||
 | 
			
		||||
    eek_keysym_parent_serializable_iface->serialize (self, builder);
 | 
			
		||||
 | 
			
		||||
    g_variant_builder_add (builder, "u", priv->xkeysym);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gsize
 | 
			
		||||
eek_keysym_real_deserialize (EekSerializable *self,
 | 
			
		||||
                             GVariant        *variant,
 | 
			
		||||
                             gsize            index)
 | 
			
		||||
{
 | 
			
		||||
    EekKeysymPrivate *priv = eek_keysym_get_instance_private (
 | 
			
		||||
		    EEK_KEYSYM(self));
 | 
			
		||||
 | 
			
		||||
    index = eek_keysym_parent_serializable_iface->deserialize (self,
 | 
			
		||||
                                                               variant,
 | 
			
		||||
                                                               index);
 | 
			
		||||
 | 
			
		||||
    g_variant_get_child (variant, index++, "u", &priv->xkeysym);
 | 
			
		||||
 | 
			
		||||
    return index;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
eek_serializable_iface_init (EekSerializableIface *iface)
 | 
			
		||||
{
 | 
			
		||||
    eek_keysym_parent_serializable_iface =
 | 
			
		||||
        g_type_interface_peek_parent (iface);
 | 
			
		||||
 | 
			
		||||
    iface->serialize = eek_keysym_real_serialize;
 | 
			
		||||
    iface->deserialize = eek_keysym_real_deserialize;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gchar *
 | 
			
		||||
unichar_to_utf8 (gunichar uc)
 | 
			
		||||
@ -143,6 +197,18 @@ get_modifier_mask (guint xkeysym)
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
eek_keysym_class_init (EekKeysymClass *klass)
 | 
			
		||||
{
 | 
			
		||||
    /* void */
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
eek_keysym_init (EekKeysym *self)
 | 
			
		||||
{
 | 
			
		||||
    /* void */
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eek_keysym_new_with_modifier:
 | 
			
		||||
 * @xkeysym: an X keysym value
 | 
			
		||||
@ -151,12 +217,16 @@ get_modifier_mask (guint xkeysym)
 | 
			
		||||
 * Create an #EekKeysym with given X keysym value @xkeysym and
 | 
			
		||||
 * modifier @modifier_mask.
 | 
			
		||||
 */
 | 
			
		||||
EekSymbol *eek_keysym_new_with_modifier(guint           xkeysym,
 | 
			
		||||
                                        EekModifierType modifier_mask)
 | 
			
		||||
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 =
 | 
			
		||||
@ -176,17 +246,23 @@ EekSymbol *eek_keysym_new_with_modifier(guint           xkeysym,
 | 
			
		||||
        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 */
 | 
			
		||||
@ -199,10 +275,12 @@ EekSymbol *eek_keysym_new_with_modifier(guint           xkeysym,
 | 
			
		||||
    else
 | 
			
		||||
        label = g_strdup (name);
 | 
			
		||||
 | 
			
		||||
    EekSymbol *keysym = eek_symbol_new(name);
 | 
			
		||||
    eek_symbol_set_label(keysym, label);
 | 
			
		||||
    eek_symbol_set_modifier_mask(keysym, modifier_mask);
 | 
			
		||||
 | 
			
		||||
    keysym = g_object_new (EEK_TYPE_KEYSYM,
 | 
			
		||||
                           "name", name,
 | 
			
		||||
                           "label", label,
 | 
			
		||||
                           "category", category,
 | 
			
		||||
                           "modifier-mask", modifier_mask,
 | 
			
		||||
                           NULL);
 | 
			
		||||
    g_free (name);
 | 
			
		||||
    g_free (label);
 | 
			
		||||
 | 
			
		||||
@ -211,7 +289,8 @@ EekSymbol *eek_keysym_new_with_modifier(guint           xkeysym,
 | 
			
		||||
        g_slice_free (EekKeysymEntry, unichar_entry);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    keysym->xkeysym = xkeysym;
 | 
			
		||||
    priv = eek_keysym_get_instance_private (keysym);
 | 
			
		||||
    priv->xkeysym = xkeysym;
 | 
			
		||||
 | 
			
		||||
    return keysym;
 | 
			
		||||
}
 | 
			
		||||
@ -222,7 +301,7 @@ EekSymbol *eek_keysym_new_with_modifier(guint           xkeysym,
 | 
			
		||||
 *
 | 
			
		||||
 * Create an #EekKeysym with given X keysym value @xkeysym.
 | 
			
		||||
 */
 | 
			
		||||
EekSymbol*
 | 
			
		||||
EekKeysym *
 | 
			
		||||
eek_keysym_new (guint xkeysym)
 | 
			
		||||
{
 | 
			
		||||
    return eek_keysym_new_with_modifier (xkeysym, get_modifier_mask (xkeysym));
 | 
			
		||||
@ -234,16 +313,22 @@ eek_keysym_new (guint xkeysym)
 | 
			
		||||
 *
 | 
			
		||||
 * Create an #EekKeysym with an X keysym value looked up by @name.
 | 
			
		||||
 */
 | 
			
		||||
EekSymbol*
 | 
			
		||||
EekKeysym *
 | 
			
		||||
eek_keysym_new_from_name (const gchar *name)
 | 
			
		||||
{
 | 
			
		||||
    for (uint i = 0; i < G_N_ELEMENTS(xkeysym_keysym_entries); i++)
 | 
			
		||||
    gint i;
 | 
			
		||||
 | 
			
		||||
    for (i = 0; i < G_N_ELEMENTS(xkeysym_keysym_entries); i++)
 | 
			
		||||
        if (g_strcmp0 (xkeysym_keysym_entries[i].name, name) == 0)
 | 
			
		||||
            return eek_keysym_new (xkeysym_keysym_entries[i].xkeysym);
 | 
			
		||||
 | 
			
		||||
    EekSymbol *ret = eek_symbol_new(name);
 | 
			
		||||
    eek_symbol_set_label(ret, name);
 | 
			
		||||
    return ret;
 | 
			
		||||
    // 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);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@ -253,10 +338,11 @@ eek_keysym_new_from_name (const gchar *name)
 | 
			
		||||
 * Get an X keysym value associated with @keysym
 | 
			
		||||
 */
 | 
			
		||||
guint
 | 
			
		||||
eek_keysym_get_xkeysym (EekSymbol *keysym)
 | 
			
		||||
eek_keysym_get_xkeysym (EekKeysym *keysym)
 | 
			
		||||
{
 | 
			
		||||
    if (keysym->xkeysym == 0) {
 | 
			
		||||
        g_warning("Symbol %s was expected to have a valid keysym", keysym->name);
 | 
			
		||||
    }
 | 
			
		||||
    return keysym->xkeysym;
 | 
			
		||||
    EekKeysymPrivate *priv;
 | 
			
		||||
 | 
			
		||||
    g_assert (EEK_IS_KEYSYM(keysym));
 | 
			
		||||
    priv = eek_keysym_get_instance_private (keysym);
 | 
			
		||||
    return priv->xkeysym;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -37,11 +37,20 @@ G_BEGIN_DECLS
 | 
			
		||||
 */
 | 
			
		||||
#define EEK_INVALID_KEYSYM (0)
 | 
			
		||||
 | 
			
		||||
EekSymbol *eek_keysym_new               (guint           xkeysym);
 | 
			
		||||
guint      eek_keysym_get_xkeysym       (EekSymbol      *keysym);
 | 
			
		||||
#define EEK_TYPE_KEYSYM (eek_keysym_get_type())
 | 
			
		||||
G_DECLARE_DERIVABLE_TYPE (EekKeysym, eek_keysym, EEK, KEYSYM, EekSymbol)
 | 
			
		||||
 | 
			
		||||
EekSymbol *eek_keysym_new_from_name     (const gchar    *name);
 | 
			
		||||
EekSymbol *eek_keysym_new_with_modifier (guint           xkeysym,
 | 
			
		||||
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
 | 
			
		||||
 | 
			
		||||
@ -129,8 +129,60 @@ eek_layout_place_sections(EekKeyboard *keyboard)
 | 
			
		||||
    eek_element_set_bounds(EEK_ELEMENT(keyboard), &keyboard_bounds);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void scale_bounds_callback (EekElement *element,
 | 
			
		||||
                                   gpointer    user_data);
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
scale_bounds (EekElement *element,
 | 
			
		||||
              gdouble     scale)
 | 
			
		||||
{
 | 
			
		||||
    EekBounds bounds;
 | 
			
		||||
 | 
			
		||||
    eek_element_get_bounds (element, &bounds);
 | 
			
		||||
    bounds.x *= scale;
 | 
			
		||||
    bounds.y *= scale;
 | 
			
		||||
    bounds.width *= scale;
 | 
			
		||||
    bounds.height *= scale;
 | 
			
		||||
    eek_element_set_bounds (element, &bounds);
 | 
			
		||||
 | 
			
		||||
    if (EEK_IS_CONTAINER(element))
 | 
			
		||||
        eek_container_foreach_child (EEK_CONTAINER(element),
 | 
			
		||||
                                     scale_bounds_callback,
 | 
			
		||||
                                     &scale);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
scale_bounds_callback (EekElement *element,
 | 
			
		||||
                       gpointer    user_data)
 | 
			
		||||
{
 | 
			
		||||
    scale_bounds (element, *(gdouble *)user_data);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
eek_layout_scale_keyboard(EekKeyboard *keyboard, gdouble scale)
 | 
			
		||||
{
 | 
			
		||||
    gsize n_outlines;
 | 
			
		||||
 | 
			
		||||
    scale_bounds (EEK_ELEMENT(keyboard), scale);
 | 
			
		||||
 | 
			
		||||
    n_outlines = eek_keyboard_get_n_outlines (keyboard);
 | 
			
		||||
    for (guint i = 0; i < n_outlines; i++) {
 | 
			
		||||
        EekOutline *outline = eek_keyboard_get_outline (keyboard, i);
 | 
			
		||||
        gint j;
 | 
			
		||||
 | 
			
		||||
        for (j = 0; j < outline->num_points; j++) {
 | 
			
		||||
            outline->points[j].x *= scale;
 | 
			
		||||
            outline->points[j].y *= scale;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    keyboard->scale = scale;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
eek_layout_update_layout(EekKeyboard *keyboard)
 | 
			
		||||
{
 | 
			
		||||
    eek_layout_scale_keyboard(keyboard, 1.0 / keyboard->scale);
 | 
			
		||||
    eek_layout_place_sections(keyboard);
 | 
			
		||||
    eek_layout_scale_keyboard(keyboard, 1.0 / keyboard->scale);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -57,6 +57,8 @@ GType        eek_layout_get_type  (void) G_GNUC_CONST;
 | 
			
		||||
 | 
			
		||||
void         eek_layout_place_sections(EekKeyboard *keyboard);
 | 
			
		||||
 | 
			
		||||
void         eek_layout_scale_keyboard(EekKeyboard *keyboard, gdouble scale);
 | 
			
		||||
 | 
			
		||||
void         eek_layout_update_layout(EekKeyboard *keyboard);
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
 | 
			
		||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@ -25,6 +25,8 @@
 | 
			
		||||
#include "eek-keyboard.h"
 | 
			
		||||
#include "eek-keysym.h"
 | 
			
		||||
#include "eek-types.h"
 | 
			
		||||
#include "eek-theme.h"
 | 
			
		||||
#include "eek-theme-context.h"
 | 
			
		||||
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
@ -35,6 +37,10 @@ struct _EekRendererClass
 | 
			
		||||
{
 | 
			
		||||
    GObjectClass parent_class;
 | 
			
		||||
 | 
			
		||||
    void             (* render_key_label)   (EekRenderer *self,
 | 
			
		||||
                                             PangoLayout *layout,
 | 
			
		||||
                                             EekKey      *key);
 | 
			
		||||
 | 
			
		||||
    void             (* render_key_outline) (EekRenderer *self,
 | 
			
		||||
                                             cairo_t     *cr,
 | 
			
		||||
                                             EekKey      *key,
 | 
			
		||||
@ -62,8 +68,7 @@ struct _EekRendererClass
 | 
			
		||||
 | 
			
		||||
GType            eek_renderer_get_type         (void) G_GNUC_CONST;
 | 
			
		||||
EekRenderer     *eek_renderer_new              (EekKeyboard     *keyboard,
 | 
			
		||||
                                                PangoContext    *pcontext,
 | 
			
		||||
                                                GtkStyleContext *scontext);
 | 
			
		||||
                                                PangoContext    *pcontext);
 | 
			
		||||
void             eek_renderer_set_allocation_size
 | 
			
		||||
                                               (EekRenderer     *renderer,
 | 
			
		||||
                                                gdouble          width,
 | 
			
		||||
@ -115,8 +120,18 @@ 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);
 | 
			
		||||
EekKey          *eek_renderer_find_key_by_position
 | 
			
		||||
@ -130,5 +145,8 @@ void             eek_renderer_apply_transformation_for_key
 | 
			
		||||
                                                gdouble          scale,
 | 
			
		||||
                                                gboolean         rotate);
 | 
			
		||||
 | 
			
		||||
void             eek_renderer_set_theme        (EekRenderer     *renderer,
 | 
			
		||||
                                                EekTheme        *theme);
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
#endif  /* EEK_RENDERER_H */
 | 
			
		||||
 | 
			
		||||
@ -61,7 +61,7 @@ typedef struct _EekRow EekRow;
 | 
			
		||||
typedef struct _EekSectionPrivate
 | 
			
		||||
{
 | 
			
		||||
    gint angle;
 | 
			
		||||
    EekRow row;
 | 
			
		||||
    GSList *rows;
 | 
			
		||||
    EekModifierType modifiers;
 | 
			
		||||
} EekSectionPrivate;
 | 
			
		||||
 | 
			
		||||
@ -70,7 +70,9 @@ G_DEFINE_TYPE_WITH_PRIVATE (EekSection, eek_section, EEK_TYPE_CONTAINER)
 | 
			
		||||
static gint
 | 
			
		||||
eek_section_real_get_n_rows (EekSection *self)
 | 
			
		||||
{
 | 
			
		||||
return 1;
 | 
			
		||||
    EekSectionPrivate *priv = eek_section_get_instance_private (self);
 | 
			
		||||
 | 
			
		||||
    return g_slist_length (priv->rows);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
@ -78,14 +80,13 @@ eek_section_real_add_row (EekSection    *self,
 | 
			
		||||
                          gint           num_columns,
 | 
			
		||||
                          EekOrientation orientation)
 | 
			
		||||
{
 | 
			
		||||
    EekSectionPrivate *priv = (EekSectionPrivate*)eek_section_get_instance_private (self);
 | 
			
		||||
    priv->row.num_columns = num_columns;
 | 
			
		||||
    priv->row.orientation = orientation;
 | 
			
		||||
/*
 | 
			
		||||
    EekSectionPrivate *priv = eek_section_get_instance_private (self);
 | 
			
		||||
    EekRow *row;
 | 
			
		||||
 | 
			
		||||
    row = g_slice_new (EekRow);
 | 
			
		||||
    row->num_columns = num_columns;
 | 
			
		||||
    row->orientation = orientation;
 | 
			
		||||
    priv->rows = g_slist_append (priv->rows, row);*/
 | 
			
		||||
    priv->rows = g_slist_append (priv->rows, row);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
@ -94,14 +95,15 @@ eek_section_real_get_row (EekSection     *self,
 | 
			
		||||
                          gint           *num_columns,
 | 
			
		||||
                          EekOrientation *orientation)
 | 
			
		||||
{
 | 
			
		||||
    EekSectionPrivate *priv = (EekSectionPrivate*)eek_section_get_instance_private (self);
 | 
			
		||||
    EekRow *row = &priv->row;
 | 
			
		||||
    if (num_columns) {
 | 
			
		||||
    EekSectionPrivate *priv = eek_section_get_instance_private (self);
 | 
			
		||||
    EekRow *row;
 | 
			
		||||
 | 
			
		||||
    row = g_slist_nth_data (priv->rows, index);
 | 
			
		||||
    g_return_if_fail (row);
 | 
			
		||||
    if (num_columns)
 | 
			
		||||
        *num_columns = row->num_columns;
 | 
			
		||||
    }
 | 
			
		||||
    if (orientation) {
 | 
			
		||||
    if (orientation)
 | 
			
		||||
        *orientation = row->orientation;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
@ -121,17 +123,29 @@ on_unlocked (EekKey     *key,
 | 
			
		||||
static EekKey *
 | 
			
		||||
eek_section_real_create_key (EekSection *self,
 | 
			
		||||
                             const gchar *name,
 | 
			
		||||
                             gint        keycode)
 | 
			
		||||
                             gint        keycode,
 | 
			
		||||
                             gint        column_index,
 | 
			
		||||
                             gint        row_index)
 | 
			
		||||
{
 | 
			
		||||
    EekSectionPrivate *priv = (EekSectionPrivate*)eek_section_get_instance_private (self);
 | 
			
		||||
    EekKey *key;
 | 
			
		||||
    gint num_rows;
 | 
			
		||||
    EekRow *row;
 | 
			
		||||
 | 
			
		||||
    EekRow *row = &priv->row;
 | 
			
		||||
    row->num_columns++;
 | 
			
		||||
    num_rows = eek_section_get_n_rows (self);
 | 
			
		||||
    g_return_val_if_fail (0 <= row_index && row_index < num_rows, NULL);
 | 
			
		||||
 | 
			
		||||
    EekKey *key = (EekKey*)g_object_new (EEK_TYPE_KEY,
 | 
			
		||||
                                         "name", name,
 | 
			
		||||
                                         "keycode", keycode,
 | 
			
		||||
                                         NULL);
 | 
			
		||||
    EekSectionPrivate *priv = eek_section_get_instance_private (self);
 | 
			
		||||
 | 
			
		||||
    row = g_slist_nth_data (priv->rows, row_index);
 | 
			
		||||
    if (row->num_columns < column_index + 1)
 | 
			
		||||
        row->num_columns = column_index + 1;
 | 
			
		||||
 | 
			
		||||
    key = g_object_new (EEK_TYPE_KEY,
 | 
			
		||||
                        "name", name,
 | 
			
		||||
                        "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),
 | 
			
		||||
@ -211,7 +225,12 @@ static void
 | 
			
		||||
eek_section_finalize (GObject *object)
 | 
			
		||||
{
 | 
			
		||||
    EekSection        *self = EEK_SECTION (object);
 | 
			
		||||
    EekSectionPrivate *priv = (EekSectionPrivate*)eek_section_get_instance_private (self);
 | 
			
		||||
    EekSectionPrivate *priv = eek_section_get_instance_private (self);
 | 
			
		||||
    GSList *head;
 | 
			
		||||
 | 
			
		||||
    for (head = priv->rows; head; head = g_slist_next (head))
 | 
			
		||||
        g_slice_free (EekRow, head->data);
 | 
			
		||||
    g_slist_free (priv->rows);
 | 
			
		||||
 | 
			
		||||
    G_OBJECT_CLASS (eek_section_parent_class)->finalize (object);
 | 
			
		||||
}
 | 
			
		||||
@ -456,12 +475,16 @@ eek_section_get_row (EekSection     *section,
 | 
			
		||||
EekKey *
 | 
			
		||||
eek_section_create_key (EekSection *section,
 | 
			
		||||
                        const gchar *name,
 | 
			
		||||
                        gint        keycode)
 | 
			
		||||
                        gint        keycode,
 | 
			
		||||
                        gint        column,
 | 
			
		||||
                        gint        row)
 | 
			
		||||
{
 | 
			
		||||
    g_return_val_if_fail (EEK_IS_SECTION(section), NULL);
 | 
			
		||||
    return EEK_SECTION_GET_CLASS(section)->create_key (section,
 | 
			
		||||
                                                       name,
 | 
			
		||||
                                                       keycode);
 | 
			
		||||
                                                       keycode,
 | 
			
		||||
                                                       column,
 | 
			
		||||
                                                       row);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const double keyspacing = 4.0;
 | 
			
		||||
@ -512,8 +535,7 @@ keycounter (EekElement *element, gpointer user_data)
 | 
			
		||||
{
 | 
			
		||||
    EekKey *key = EEK_KEY(element);
 | 
			
		||||
 | 
			
		||||
    /* Skip keys without labels for the current level. This causes those
 | 
			
		||||
       keys to be hidden in the visible layout. */
 | 
			
		||||
    /* Skip keys without labels for the current level. */
 | 
			
		||||
    if (!eek_key_has_label(key))
 | 
			
		||||
        return;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -63,7 +63,9 @@ struct _EekSectionClass
 | 
			
		||||
 | 
			
		||||
    EekKey *(* create_key)          (EekSection     *self,
 | 
			
		||||
                                     const gchar    *name,
 | 
			
		||||
                                     gint            keycode);
 | 
			
		||||
                                     gint            keycode,
 | 
			
		||||
                                     gint            row,
 | 
			
		||||
                                     gint            column);
 | 
			
		||||
 | 
			
		||||
    /* signals */
 | 
			
		||||
    void    (* key_pressed)         (EekSection     *self,
 | 
			
		||||
@ -99,7 +101,9 @@ void    eek_section_get_row              (EekSection     *section,
 | 
			
		||||
 | 
			
		||||
EekKey *eek_section_create_key           (EekSection     *section,
 | 
			
		||||
                                          const gchar    *name,
 | 
			
		||||
                                          gint            keycode);
 | 
			
		||||
                                          gint            keycode,
 | 
			
		||||
                                          gint            column,
 | 
			
		||||
                                          gint            row);
 | 
			
		||||
 | 
			
		||||
EekKey *eek_section_find_key_by_keycode  (EekSection     *section,
 | 
			
		||||
                                          guint           keycode);
 | 
			
		||||
 | 
			
		||||
@ -36,8 +36,10 @@ eek_serializable_get_type (void)
 | 
			
		||||
{
 | 
			
		||||
    static GType iface_type = 0;
 | 
			
		||||
    if (iface_type == 0) {
 | 
			
		||||
        static GTypeInfo info = {
 | 
			
		||||
            .class_size = sizeof (EekSerializableIface)
 | 
			
		||||
        static const GTypeInfo info = {
 | 
			
		||||
            sizeof (EekSerializableIface),
 | 
			
		||||
            NULL,
 | 
			
		||||
            NULL,
 | 
			
		||||
        };
 | 
			
		||||
        iface_type = g_type_register_static (G_TYPE_INTERFACE,
 | 
			
		||||
                                             "EekSerializable",
 | 
			
		||||
 | 
			
		||||
@ -36,19 +36,24 @@ EekSymbolMatrix *
 | 
			
		||||
eek_symbol_matrix_copy (const EekSymbolMatrix *matrix)
 | 
			
		||||
{
 | 
			
		||||
    EekSymbolMatrix *retval;
 | 
			
		||||
    guint num_symbols = matrix->num_groups * matrix->num_levels;
 | 
			
		||||
    gint i, num_symbols = matrix->num_groups * matrix->num_levels;
 | 
			
		||||
 | 
			
		||||
    retval = g_slice_dup (EekSymbolMatrix, matrix);
 | 
			
		||||
    retval->data = g_slice_copy (sizeof (EekSymbol *) * num_symbols,
 | 
			
		||||
                                 matrix->data);
 | 
			
		||||
    // FIXME: do a deep copy over the data in EekSymbol
 | 
			
		||||
    for (i = 0; i < num_symbols; i++)
 | 
			
		||||
        if (retval->data[i])
 | 
			
		||||
            g_object_ref (retval->data[i]);
 | 
			
		||||
    return retval;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
eek_symbol_matrix_free (EekSymbolMatrix *matrix)
 | 
			
		||||
{
 | 
			
		||||
    guint num_symbols = matrix->num_groups * matrix->num_levels;
 | 
			
		||||
    gint i, num_symbols = matrix->num_groups * matrix->num_levels;
 | 
			
		||||
    for (i = 0; i < num_symbols; i++)
 | 
			
		||||
        if (matrix->data[i])
 | 
			
		||||
            g_object_unref (matrix->data[i]);
 | 
			
		||||
    g_slice_free1 (sizeof (EekSymbol *) * num_symbols, matrix->data);
 | 
			
		||||
    g_slice_free (EekSymbolMatrix, matrix);
 | 
			
		||||
}
 | 
			
		||||
@ -74,6 +79,7 @@ eek_symbol_matrix_set_symbol (EekSymbolMatrix *matrix,
 | 
			
		||||
{
 | 
			
		||||
    g_return_if_fail (group >= 0 && group < matrix->num_groups);
 | 
			
		||||
    g_return_if_fail (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);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										414
									
								
								eek/eek-symbol.c
									
									
									
									
									
								
							
							
						
						
									
										414
									
								
								eek/eek-symbol.c
									
									
									
									
									
								
							@ -28,42 +28,270 @@
 | 
			
		||||
#include "config.h"
 | 
			
		||||
 | 
			
		||||
#include "eek-symbol.h"
 | 
			
		||||
#include "eek-serializable.h"
 | 
			
		||||
#include "eek-enumtypes.h"
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
eek_symbol_destroy (EekSymbol *priv)
 | 
			
		||||
enum {
 | 
			
		||||
    PROP_0,
 | 
			
		||||
    PROP_NAME,
 | 
			
		||||
    PROP_LABEL,
 | 
			
		||||
    PROP_CATEGORY,
 | 
			
		||||
    PROP_MODIFIER_MASK,
 | 
			
		||||
    PROP_ICON_NAME,
 | 
			
		||||
    PROP_TOOLTIP,
 | 
			
		||||
    PROP_LAST
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
typedef struct _EekSymbolPrivate
 | 
			
		||||
{
 | 
			
		||||
    gchar *name;
 | 
			
		||||
    gchar *label;
 | 
			
		||||
    EekSymbolCategory category;
 | 
			
		||||
    EekModifierType modifier_mask;
 | 
			
		||||
    gchar *icon_name;
 | 
			
		||||
    gchar *tooltip;
 | 
			
		||||
} EekSymbolPrivate;
 | 
			
		||||
 | 
			
		||||
static void eek_serializable_iface_init (EekSerializableIface *iface);
 | 
			
		||||
 | 
			
		||||
G_DEFINE_TYPE_EXTENDED (EekSymbol,
 | 
			
		||||
			eek_symbol,
 | 
			
		||||
			G_TYPE_OBJECT,
 | 
			
		||||
			0, /* GTypeFlags */
 | 
			
		||||
			G_ADD_PRIVATE (EekSymbol)
 | 
			
		||||
                        G_IMPLEMENT_INTERFACE (EEK_TYPE_SERIALIZABLE,
 | 
			
		||||
                                               eek_serializable_iface_init))
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
eek_symbol_real_serialize (EekSerializable *self,
 | 
			
		||||
                           GVariantBuilder *builder)
 | 
			
		||||
{
 | 
			
		||||
    EekSymbolPrivate *priv = eek_symbol_get_instance_private (EEK_SYMBOL (self));
 | 
			
		||||
#define NOTNULL(s) ((s) != NULL ? (s) : "")
 | 
			
		||||
    g_variant_builder_add (builder, "s", NOTNULL(priv->name));
 | 
			
		||||
    g_variant_builder_add (builder, "s", NOTNULL(priv->label));
 | 
			
		||||
    g_variant_builder_add (builder, "u", priv->category);
 | 
			
		||||
    g_variant_builder_add (builder, "u", priv->modifier_mask);
 | 
			
		||||
    g_variant_builder_add (builder, "s", NOTNULL(priv->icon_name));
 | 
			
		||||
    g_variant_builder_add (builder, "s", NOTNULL(priv->tooltip));
 | 
			
		||||
#undef NOTNULL
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gsize
 | 
			
		||||
eek_symbol_real_deserialize (EekSerializable *self,
 | 
			
		||||
                             GVariant        *variant,
 | 
			
		||||
                             gsize            index)
 | 
			
		||||
{
 | 
			
		||||
    EekSymbolPrivate *priv = eek_symbol_get_instance_private (EEK_SYMBOL (self));
 | 
			
		||||
 | 
			
		||||
    g_variant_get_child (variant, index++, "s", &priv->name);
 | 
			
		||||
    g_variant_get_child (variant, index++, "s", &priv->label);
 | 
			
		||||
    g_variant_get_child (variant, index++, "u", &priv->category);
 | 
			
		||||
    g_variant_get_child (variant, index++, "u", &priv->modifier_mask);
 | 
			
		||||
    g_variant_get_child (variant, index++, "s", &priv->icon_name);
 | 
			
		||||
    g_variant_get_child (variant, index++, "s", &priv->tooltip);
 | 
			
		||||
 | 
			
		||||
    return index;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
eek_serializable_iface_init (EekSerializableIface *iface)
 | 
			
		||||
{
 | 
			
		||||
    iface->serialize = eek_symbol_real_serialize;
 | 
			
		||||
    iface->deserialize = eek_symbol_real_deserialize;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
eek_symbol_set_property (GObject      *object,
 | 
			
		||||
                         guint         prop_id,
 | 
			
		||||
                         const GValue *value,
 | 
			
		||||
                         GParamSpec   *pspec)
 | 
			
		||||
{
 | 
			
		||||
    switch (prop_id) {
 | 
			
		||||
    case PROP_NAME:
 | 
			
		||||
        eek_symbol_set_name (EEK_SYMBOL(object), g_value_get_string (value));
 | 
			
		||||
        break;
 | 
			
		||||
    case PROP_LABEL:
 | 
			
		||||
        eek_symbol_set_label (EEK_SYMBOL(object), g_value_get_string (value));
 | 
			
		||||
        break;
 | 
			
		||||
    case PROP_CATEGORY:
 | 
			
		||||
        eek_symbol_set_category (EEK_SYMBOL(object), g_value_get_enum (value));
 | 
			
		||||
        break;
 | 
			
		||||
    case PROP_MODIFIER_MASK:
 | 
			
		||||
        eek_symbol_set_modifier_mask (EEK_SYMBOL(object),
 | 
			
		||||
                                      g_value_get_flags (value));
 | 
			
		||||
        break;
 | 
			
		||||
    case PROP_ICON_NAME:
 | 
			
		||||
        eek_symbol_set_icon_name (EEK_SYMBOL(object),
 | 
			
		||||
                                  g_value_get_string (value));
 | 
			
		||||
        break;
 | 
			
		||||
    case PROP_TOOLTIP:
 | 
			
		||||
        eek_symbol_set_tooltip (EEK_SYMBOL(object),
 | 
			
		||||
                                g_value_get_string (value));
 | 
			
		||||
        break;
 | 
			
		||||
    default:
 | 
			
		||||
        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
eek_symbol_get_property (GObject    *object,
 | 
			
		||||
                         guint       prop_id,
 | 
			
		||||
                         GValue     *value,
 | 
			
		||||
                         GParamSpec *pspec)
 | 
			
		||||
{
 | 
			
		||||
    switch (prop_id) {
 | 
			
		||||
    case PROP_NAME:
 | 
			
		||||
        g_value_set_string (value, eek_symbol_get_name (EEK_SYMBOL(object)));
 | 
			
		||||
        break;
 | 
			
		||||
    case PROP_LABEL:
 | 
			
		||||
        g_value_set_string (value, eek_symbol_get_label (EEK_SYMBOL(object)));
 | 
			
		||||
        break;
 | 
			
		||||
    case PROP_CATEGORY:
 | 
			
		||||
        g_value_set_enum (value, eek_symbol_get_category (EEK_SYMBOL(object)));
 | 
			
		||||
        break;
 | 
			
		||||
    case PROP_MODIFIER_MASK:
 | 
			
		||||
        g_value_set_flags (value,
 | 
			
		||||
                           eek_symbol_get_modifier_mask (EEK_SYMBOL(object)));
 | 
			
		||||
        break;
 | 
			
		||||
    case PROP_ICON_NAME:
 | 
			
		||||
        g_value_set_string (value,
 | 
			
		||||
                            eek_symbol_get_icon_name (EEK_SYMBOL(object)));
 | 
			
		||||
        break;
 | 
			
		||||
    case PROP_TOOLTIP:
 | 
			
		||||
        g_value_set_string (value,
 | 
			
		||||
                            eek_symbol_get_tooltip (EEK_SYMBOL(object)));
 | 
			
		||||
        break;
 | 
			
		||||
    default:
 | 
			
		||||
        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
eek_symbol_finalize (GObject *object)
 | 
			
		||||
{
 | 
			
		||||
    EekSymbol        *self = EEK_SYMBOL (object);
 | 
			
		||||
    EekSymbolPrivate *priv = eek_symbol_get_instance_private (self);
 | 
			
		||||
 | 
			
		||||
    g_free (priv->name);
 | 
			
		||||
    g_free (priv->label);
 | 
			
		||||
    g_free (priv->icon_name);
 | 
			
		||||
    g_free (priv->tooltip);
 | 
			
		||||
    g_free(priv->text);
 | 
			
		||||
    g_free(priv);
 | 
			
		||||
    G_OBJECT_CLASS (eek_symbol_parent_class)->finalize (object);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
eek_symbol_class_init (EekSymbolClass *klass)
 | 
			
		||||
{
 | 
			
		||||
    GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
 | 
			
		||||
    GParamSpec *pspec;
 | 
			
		||||
 | 
			
		||||
    gobject_class->set_property = eek_symbol_set_property;
 | 
			
		||||
    gobject_class->get_property = eek_symbol_get_property;
 | 
			
		||||
    gobject_class->finalize = eek_symbol_finalize;
 | 
			
		||||
 | 
			
		||||
    pspec = g_param_spec_string ("name",
 | 
			
		||||
                                 "Name",
 | 
			
		||||
                                 "Canonical name of the symbol",
 | 
			
		||||
                                 NULL,
 | 
			
		||||
                                 G_PARAM_CONSTRUCT | G_PARAM_READWRITE);
 | 
			
		||||
    g_object_class_install_property (gobject_class, PROP_NAME, pspec);
 | 
			
		||||
 | 
			
		||||
    pspec = g_param_spec_string ("label",
 | 
			
		||||
                                 "Label",
 | 
			
		||||
                                 "Text used to display the symbol",
 | 
			
		||||
                                 NULL,
 | 
			
		||||
                                 G_PARAM_CONSTRUCT | G_PARAM_READWRITE);
 | 
			
		||||
    g_object_class_install_property (gobject_class, PROP_LABEL, pspec);
 | 
			
		||||
 | 
			
		||||
    pspec = g_param_spec_enum ("category",
 | 
			
		||||
                               "Category",
 | 
			
		||||
                               "Category of the symbol",
 | 
			
		||||
                               EEK_TYPE_SYMBOL_CATEGORY,
 | 
			
		||||
                               EEK_SYMBOL_CATEGORY_UNKNOWN,
 | 
			
		||||
                               G_PARAM_CONSTRUCT | G_PARAM_READWRITE);
 | 
			
		||||
    g_object_class_install_property (gobject_class, PROP_CATEGORY, pspec);
 | 
			
		||||
 | 
			
		||||
    pspec = g_param_spec_flags ("modifier-mask",
 | 
			
		||||
                                "Modifier mask",
 | 
			
		||||
                                "Modifier mask of the symbol",
 | 
			
		||||
                                EEK_TYPE_MODIFIER_TYPE,
 | 
			
		||||
                                0,
 | 
			
		||||
                                G_PARAM_CONSTRUCT | G_PARAM_READWRITE);
 | 
			
		||||
    g_object_class_install_property (gobject_class, PROP_MODIFIER_MASK, pspec);
 | 
			
		||||
 | 
			
		||||
    pspec = g_param_spec_string ("icon-name",
 | 
			
		||||
                                 "Icon name",
 | 
			
		||||
                                 "Icon name used to render the symbol",
 | 
			
		||||
                                 NULL,
 | 
			
		||||
                                 G_PARAM_CONSTRUCT | G_PARAM_READWRITE);
 | 
			
		||||
    g_object_class_install_property (gobject_class, PROP_ICON_NAME, pspec);
 | 
			
		||||
 | 
			
		||||
    pspec = g_param_spec_string ("tooltip",
 | 
			
		||||
                                 "Tooltip",
 | 
			
		||||
                                 "Tooltip text",
 | 
			
		||||
                                 NULL,
 | 
			
		||||
                                 G_PARAM_CONSTRUCT | G_PARAM_READWRITE);
 | 
			
		||||
    g_object_class_install_property (gobject_class, PROP_TOOLTIP, pspec);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
eek_symbol_init (EekSymbol *self)
 | 
			
		||||
{
 | 
			
		||||
    EekSymbolPrivate *priv = eek_symbol_get_instance_private (self);
 | 
			
		||||
 | 
			
		||||
    priv->category = EEK_SYMBOL_CATEGORY_UNKNOWN;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eek_symbol_new:
 | 
			
		||||
 * @name: name of the symbol
 | 
			
		||||
 *
 | 
			
		||||
 * Create a new #EekSymbol with @name.
 | 
			
		||||
 */
 | 
			
		||||
EekSymbol *
 | 
			
		||||
eek_symbol_new (const gchar *name)
 | 
			
		||||
{
 | 
			
		||||
    EekSymbol *self = g_new0(EekSymbol, 1);
 | 
			
		||||
    eek_symbol_set_name(self, name);
 | 
			
		||||
    self->category = EEK_SYMBOL_CATEGORY_UNKNOWN;
 | 
			
		||||
    return self;
 | 
			
		||||
    return g_object_new (EEK_TYPE_SYMBOL, "name", name, NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eek_symbol_set_name:
 | 
			
		||||
 * @symbol: an #EekSymbol
 | 
			
		||||
 * @name: name of the symbol
 | 
			
		||||
 *
 | 
			
		||||
 * Set the name of @symbol to @name.
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
eek_symbol_set_name (EekSymbol   *symbol,
 | 
			
		||||
                     const gchar *name)
 | 
			
		||||
{
 | 
			
		||||
    g_free (symbol->name);
 | 
			
		||||
    symbol->name = g_strdup (name);
 | 
			
		||||
    g_return_if_fail (EEK_IS_SYMBOL(symbol));
 | 
			
		||||
 | 
			
		||||
    EekSymbolPrivate *priv = eek_symbol_get_instance_private (symbol);
 | 
			
		||||
 | 
			
		||||
    g_free (priv->name);
 | 
			
		||||
    priv->name = g_strdup (name);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eek_symbol_get_name:
 | 
			
		||||
 * @symbol: an #EekSymbol
 | 
			
		||||
 *
 | 
			
		||||
 * Get the name of @symbol.
 | 
			
		||||
 */
 | 
			
		||||
const gchar *
 | 
			
		||||
eek_symbol_get_name (EekSymbol *symbol)
 | 
			
		||||
{
 | 
			
		||||
    if (symbol->name == NULL || *symbol->name == '\0')
 | 
			
		||||
    g_return_val_if_fail (EEK_IS_SYMBOL(symbol), NULL);
 | 
			
		||||
 | 
			
		||||
    EekSymbolPrivate *priv = eek_symbol_get_instance_private (symbol);
 | 
			
		||||
 | 
			
		||||
    if (priv->name == NULL || *priv->name == '\0')
 | 
			
		||||
        return NULL;
 | 
			
		||||
    return symbol->name;
 | 
			
		||||
    return priv->name;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@ -77,8 +305,12 @@ void
 | 
			
		||||
eek_symbol_set_label (EekSymbol   *symbol,
 | 
			
		||||
                      const gchar *label)
 | 
			
		||||
{
 | 
			
		||||
    g_free (symbol->label);
 | 
			
		||||
    symbol->label = g_strdup (label);
 | 
			
		||||
    g_return_if_fail (EEK_IS_SYMBOL(symbol));
 | 
			
		||||
 | 
			
		||||
    EekSymbolPrivate *priv = eek_symbol_get_instance_private (symbol);
 | 
			
		||||
 | 
			
		||||
    g_free (priv->label);
 | 
			
		||||
    priv->label = g_strdup (label);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@ -90,9 +322,47 @@ eek_symbol_set_label (EekSymbol   *symbol,
 | 
			
		||||
const gchar *
 | 
			
		||||
eek_symbol_get_label (EekSymbol *symbol)
 | 
			
		||||
{
 | 
			
		||||
    if (symbol->label == NULL || *symbol->label == '\0')
 | 
			
		||||
    g_return_val_if_fail (EEK_IS_SYMBOL(symbol), NULL);
 | 
			
		||||
 | 
			
		||||
    EekSymbolPrivate *priv = eek_symbol_get_instance_private (symbol);
 | 
			
		||||
 | 
			
		||||
    if (priv->label == NULL || *priv->label == '\0')
 | 
			
		||||
        return NULL;
 | 
			
		||||
    return symbol->label;
 | 
			
		||||
    return priv->label;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eek_symbol_set_category:
 | 
			
		||||
 * @symbol: an #EekSymbol
 | 
			
		||||
 * @category: an #EekSymbolCategory
 | 
			
		||||
 *
 | 
			
		||||
 * Set symbol category of @symbol to @category.
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
eek_symbol_set_category (EekSymbol        *symbol,
 | 
			
		||||
                         EekSymbolCategory category)
 | 
			
		||||
{
 | 
			
		||||
    g_return_if_fail (EEK_IS_SYMBOL(symbol));
 | 
			
		||||
 | 
			
		||||
    EekSymbolPrivate *priv = eek_symbol_get_instance_private (symbol);
 | 
			
		||||
 | 
			
		||||
    priv->category = category;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eek_symbol_get_category:
 | 
			
		||||
 * @symbol: an #EekSymbol
 | 
			
		||||
 *
 | 
			
		||||
 * Get symbol category of @symbol.
 | 
			
		||||
 */
 | 
			
		||||
EekSymbolCategory
 | 
			
		||||
eek_symbol_get_category (EekSymbol *symbol)
 | 
			
		||||
{
 | 
			
		||||
    g_return_val_if_fail (EEK_IS_SYMBOL(symbol), EEK_SYMBOL_CATEGORY_UNKNOWN);
 | 
			
		||||
 | 
			
		||||
    EekSymbolPrivate *priv = eek_symbol_get_instance_private (symbol);
 | 
			
		||||
 | 
			
		||||
    return priv->category;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@ -106,7 +376,11 @@ void
 | 
			
		||||
eek_symbol_set_modifier_mask (EekSymbol      *symbol,
 | 
			
		||||
                              EekModifierType mask)
 | 
			
		||||
{
 | 
			
		||||
    symbol->modifier_mask = mask;
 | 
			
		||||
    g_return_if_fail (EEK_IS_SYMBOL(symbol));
 | 
			
		||||
 | 
			
		||||
    EekSymbolPrivate *priv = eek_symbol_get_instance_private (symbol);
 | 
			
		||||
 | 
			
		||||
    priv->modifier_mask = mask;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@ -118,43 +392,131 @@ eek_symbol_set_modifier_mask (EekSymbol      *symbol,
 | 
			
		||||
EekModifierType
 | 
			
		||||
eek_symbol_get_modifier_mask (EekSymbol *symbol)
 | 
			
		||||
{
 | 
			
		||||
    return symbol->modifier_mask;
 | 
			
		||||
    g_return_val_if_fail (EEK_IS_SYMBOL(symbol), 0);
 | 
			
		||||
 | 
			
		||||
    EekSymbolPrivate *priv = eek_symbol_get_instance_private (symbol);
 | 
			
		||||
 | 
			
		||||
    return priv->modifier_mask;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eek_symbol_is_modifier:
 | 
			
		||||
 * @symbol: an #EekSymbol
 | 
			
		||||
 *
 | 
			
		||||
 * Check if @symbol is a modifier.
 | 
			
		||||
 * Returns: %TRUE if @symbol is a modifier.
 | 
			
		||||
 */
 | 
			
		||||
gboolean
 | 
			
		||||
eek_symbol_is_modifier (EekSymbol *symbol)
 | 
			
		||||
{
 | 
			
		||||
    return eek_symbol_get_modifier_mask (symbol) != 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eek_symbol_set_icon_name:
 | 
			
		||||
 * @symbol: an #EekSymbol
 | 
			
		||||
 * @icon_name: icon name of @symbol
 | 
			
		||||
 *
 | 
			
		||||
 * Set the icon name of @symbol to @icon_name.
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
eek_symbol_set_icon_name (EekSymbol   *symbol,
 | 
			
		||||
                          const gchar *icon_name)
 | 
			
		||||
{
 | 
			
		||||
    g_free (symbol->icon_name);
 | 
			
		||||
    symbol->icon_name = g_strdup (icon_name);
 | 
			
		||||
    g_return_if_fail (EEK_IS_SYMBOL(symbol));
 | 
			
		||||
 | 
			
		||||
    EekSymbolPrivate *priv = eek_symbol_get_instance_private (symbol);
 | 
			
		||||
 | 
			
		||||
    g_free (priv->icon_name);
 | 
			
		||||
    priv->icon_name = g_strdup (icon_name);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eek_symbol_get_icon_name:
 | 
			
		||||
 * @symbol: an #EekSymbol
 | 
			
		||||
 *
 | 
			
		||||
 * Get the icon name of @symbol.
 | 
			
		||||
 */
 | 
			
		||||
const gchar *
 | 
			
		||||
eek_symbol_get_icon_name (EekSymbol *symbol)
 | 
			
		||||
{
 | 
			
		||||
    if (symbol->icon_name == NULL || *symbol->icon_name == '\0')
 | 
			
		||||
    g_return_val_if_fail (EEK_IS_SYMBOL(symbol), NULL);
 | 
			
		||||
 | 
			
		||||
    EekSymbolPrivate *priv = eek_symbol_get_instance_private (symbol);
 | 
			
		||||
 | 
			
		||||
    if (priv->icon_name == NULL || *priv->icon_name == '\0')
 | 
			
		||||
        return NULL;
 | 
			
		||||
    return symbol->icon_name;
 | 
			
		||||
    return priv->icon_name;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eek_symbol_set_tooltip:
 | 
			
		||||
 * @symbol: an #EekSymbol
 | 
			
		||||
 * @tooltip: icon name of @symbol
 | 
			
		||||
 *
 | 
			
		||||
 * Set the tooltip text of @symbol to @tooltip.
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
eek_symbol_set_tooltip (EekSymbol   *symbol,
 | 
			
		||||
                        const gchar *tooltip)
 | 
			
		||||
{
 | 
			
		||||
    g_free (symbol->tooltip);
 | 
			
		||||
    symbol->tooltip = g_strdup (tooltip);
 | 
			
		||||
    g_return_if_fail (EEK_IS_SYMBOL(symbol));
 | 
			
		||||
 | 
			
		||||
    EekSymbolPrivate *priv = eek_symbol_get_instance_private (symbol);
 | 
			
		||||
 | 
			
		||||
    g_free (priv->tooltip);
 | 
			
		||||
    priv->tooltip = g_strdup (tooltip);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eek_symbol_get_tooltip:
 | 
			
		||||
 * @symbol: an #EekSymbol
 | 
			
		||||
 *
 | 
			
		||||
 * Get the tooltip text of @symbol.
 | 
			
		||||
 */
 | 
			
		||||
const gchar *
 | 
			
		||||
eek_symbol_get_tooltip (EekSymbol *symbol)
 | 
			
		||||
{
 | 
			
		||||
    if (symbol->tooltip == NULL || *symbol->tooltip == '\0')
 | 
			
		||||
    g_return_val_if_fail (EEK_IS_SYMBOL(symbol), NULL);
 | 
			
		||||
 | 
			
		||||
    EekSymbolPrivate *priv = eek_symbol_get_instance_private (symbol);
 | 
			
		||||
 | 
			
		||||
    if (priv->tooltip == NULL || *priv->tooltip == '\0')
 | 
			
		||||
        return NULL;
 | 
			
		||||
    return symbol->tooltip;
 | 
			
		||||
    return priv->tooltip;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static const struct {
 | 
			
		||||
    EekSymbolCategory category;
 | 
			
		||||
    gchar *name;
 | 
			
		||||
} category_names[] = {
 | 
			
		||||
    { EEK_SYMBOL_CATEGORY_LETTER, "letter" },
 | 
			
		||||
    { EEK_SYMBOL_CATEGORY_FUNCTION, "function" },
 | 
			
		||||
    { EEK_SYMBOL_CATEGORY_KEYNAME, "keyname" },
 | 
			
		||||
    { EEK_SYMBOL_CATEGORY_USER0, "user0" },
 | 
			
		||||
    { EEK_SYMBOL_CATEGORY_USER1, "user1" },
 | 
			
		||||
    { EEK_SYMBOL_CATEGORY_USER2, "user2" },
 | 
			
		||||
    { EEK_SYMBOL_CATEGORY_USER3, "user3" },
 | 
			
		||||
    { EEK_SYMBOL_CATEGORY_USER4, "user4" },
 | 
			
		||||
    { EEK_SYMBOL_CATEGORY_UNKNOWN, NULL }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const gchar *
 | 
			
		||||
eek_symbol_category_get_name (EekSymbolCategory category)
 | 
			
		||||
{
 | 
			
		||||
    gint i;
 | 
			
		||||
    for (i = 0; i < G_N_ELEMENTS(category_names); i++)
 | 
			
		||||
        if (category_names[i].category == category)
 | 
			
		||||
            return category_names[i].name;
 | 
			
		||||
    return NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
EekSymbolCategory
 | 
			
		||||
eek_symbol_category_from_name (const gchar *name)
 | 
			
		||||
{
 | 
			
		||||
    gint i;
 | 
			
		||||
    for (i = 0; i < G_N_ELEMENTS(category_names); i++)
 | 
			
		||||
        if (g_strcmp0 (category_names[i].name, name) == 0)
 | 
			
		||||
            return category_names[i].category;
 | 
			
		||||
    return EEK_SYMBOL_CATEGORY_UNKNOWN;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -58,27 +58,20 @@ typedef enum {
 | 
			
		||||
    EEK_SYMBOL_CATEGORY_LAST = EEK_SYMBOL_CATEGORY_UNKNOWN
 | 
			
		||||
} EekSymbolCategory;
 | 
			
		||||
 | 
			
		||||
#define EEK_TYPE_SYMBOL (eek_symbol_get_type())
 | 
			
		||||
G_DECLARE_DERIVABLE_TYPE(EekSymbol, eek_symbol, EEK, SYMBOL, GObject)
 | 
			
		||||
 | 
			
		||||
typedef struct _EekSymbol
 | 
			
		||||
{
 | 
			
		||||
    /// Canonical name of the symbol
 | 
			
		||||
    gchar *name;
 | 
			
		||||
    /// Text used to display the symbol
 | 
			
		||||
    gchar *label;
 | 
			
		||||
    EekSymbolCategory category;
 | 
			
		||||
    EekModifierType modifier_mask;
 | 
			
		||||
    /// Icon name used to render the symbol
 | 
			
		||||
    gchar *icon_name;
 | 
			
		||||
    /// Tooltip text
 | 
			
		||||
    gchar *tooltip;
 | 
			
		||||
/**
 | 
			
		||||
 * EekSymbolClass:
 | 
			
		||||
 */
 | 
			
		||||
struct _EekSymbolClass {
 | 
			
		||||
    /*< private >*/
 | 
			
		||||
    GObjectClass parent_class;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
    // May not be present
 | 
			
		||||
    guint xkeysym;
 | 
			
		||||
    gchar *text;
 | 
			
		||||
} EekSymbol;
 | 
			
		||||
GType             eek_symbol_get_type           (void) G_GNUC_CONST;
 | 
			
		||||
 | 
			
		||||
EekSymbol        *eek_symbol_new                (const gchar      *name);
 | 
			
		||||
void              eek_symbol_free               (EekSymbol        *symbol);
 | 
			
		||||
void              eek_symbol_set_name           (EekSymbol        *symbol,
 | 
			
		||||
                                                 const gchar      *name);
 | 
			
		||||
const gchar      *eek_symbol_get_name           (EekSymbol        *symbol);
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										156
									
								
								eek/eek-text.c
									
									
									
									
									
								
							
							
						
						
									
										156
									
								
								eek/eek-text.c
									
									
									
									
									
								
							@ -26,18 +26,160 @@
 | 
			
		||||
#include "config.h"
 | 
			
		||||
 | 
			
		||||
#include "eek-text.h"
 | 
			
		||||
#include "eek-serializable.h"
 | 
			
		||||
 | 
			
		||||
EekSymbol *
 | 
			
		||||
enum {
 | 
			
		||||
    PROP_0,
 | 
			
		||||
    PROP_TEXT,
 | 
			
		||||
    PROP_LAST
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
typedef struct _EekTextPrivate
 | 
			
		||||
{
 | 
			
		||||
    gchar *text;
 | 
			
		||||
} EekTextPrivate;
 | 
			
		||||
 | 
			
		||||
static void eek_serializable_iface_init (EekSerializableIface *iface);
 | 
			
		||||
 | 
			
		||||
G_DEFINE_TYPE_EXTENDED (EekText,
 | 
			
		||||
			eek_text,
 | 
			
		||||
			EEK_TYPE_SYMBOL,
 | 
			
		||||
			0, /* GTypeFlags */
 | 
			
		||||
			G_ADD_PRIVATE (EekText)
 | 
			
		||||
                        G_IMPLEMENT_INTERFACE (EEK_TYPE_SERIALIZABLE,
 | 
			
		||||
                                               eek_serializable_iface_init))
 | 
			
		||||
 | 
			
		||||
static EekSerializableIface *eek_text_parent_serializable_iface;
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
eek_text_real_serialize (EekSerializable *self,
 | 
			
		||||
                         GVariantBuilder *builder)
 | 
			
		||||
{
 | 
			
		||||
    EekTextPrivate *priv = eek_text_get_instance_private (EEK_TEXT (self));
 | 
			
		||||
 | 
			
		||||
    eek_text_parent_serializable_iface->serialize (self, builder);
 | 
			
		||||
 | 
			
		||||
    g_variant_builder_add (builder, "s", priv->text);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gsize
 | 
			
		||||
eek_text_real_deserialize (EekSerializable *self,
 | 
			
		||||
                           GVariant        *variant,
 | 
			
		||||
                           gsize            index)
 | 
			
		||||
{
 | 
			
		||||
    EekTextPrivate *priv = eek_text_get_instance_private (EEK_TEXT (self));
 | 
			
		||||
 | 
			
		||||
    index = eek_text_parent_serializable_iface->deserialize (self,
 | 
			
		||||
                                                             variant,
 | 
			
		||||
                                                             index);
 | 
			
		||||
    g_variant_get_child (variant, index++, "s", &priv->text);
 | 
			
		||||
 | 
			
		||||
    return index;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
eek_serializable_iface_init (EekSerializableIface *iface)
 | 
			
		||||
{
 | 
			
		||||
    eek_text_parent_serializable_iface =
 | 
			
		||||
        g_type_interface_peek_parent (iface);
 | 
			
		||||
 | 
			
		||||
    iface->serialize = eek_text_real_serialize;
 | 
			
		||||
    iface->deserialize = eek_text_real_deserialize;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
eek_text_set_property (GObject      *object,
 | 
			
		||||
                       guint         prop_id,
 | 
			
		||||
                       const GValue *value,
 | 
			
		||||
                       GParamSpec   *pspec)
 | 
			
		||||
{
 | 
			
		||||
    EekText        *self = EEK_TEXT (object);
 | 
			
		||||
    EekTextPrivate *priv = eek_text_get_instance_private (self);
 | 
			
		||||
 | 
			
		||||
    switch (prop_id) {
 | 
			
		||||
    case PROP_TEXT:
 | 
			
		||||
        g_free (priv->text);
 | 
			
		||||
        priv->text = g_strdup (g_value_get_string (value));
 | 
			
		||||
        break;
 | 
			
		||||
    default:
 | 
			
		||||
        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
eek_text_get_property (GObject    *object,
 | 
			
		||||
                       guint       prop_id,
 | 
			
		||||
                       GValue     *value,
 | 
			
		||||
                       GParamSpec *pspec)
 | 
			
		||||
{
 | 
			
		||||
    EekText        *self = EEK_TEXT (object);
 | 
			
		||||
    EekTextPrivate *priv = eek_text_get_instance_private (self);
 | 
			
		||||
 | 
			
		||||
    switch (prop_id) {
 | 
			
		||||
    case PROP_TEXT:
 | 
			
		||||
        g_value_set_string (value, priv->text);
 | 
			
		||||
        break;
 | 
			
		||||
    default:
 | 
			
		||||
        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
eek_text_finalize (GObject *object)
 | 
			
		||||
{
 | 
			
		||||
    EekText        *self = EEK_TEXT (object);
 | 
			
		||||
    EekTextPrivate *priv = eek_text_get_instance_private (self);
 | 
			
		||||
 | 
			
		||||
    g_free (priv->text);
 | 
			
		||||
    G_OBJECT_CLASS (eek_text_parent_class)->finalize (object);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
eek_text_class_init (EekTextClass *klass)
 | 
			
		||||
{
 | 
			
		||||
    GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
 | 
			
		||||
    GParamSpec *pspec;
 | 
			
		||||
 | 
			
		||||
    gobject_class->set_property = eek_text_set_property;
 | 
			
		||||
    gobject_class->get_property = eek_text_get_property;
 | 
			
		||||
    gobject_class->finalize = eek_text_finalize;
 | 
			
		||||
 | 
			
		||||
    pspec = g_param_spec_string ("text",
 | 
			
		||||
                                 "Text",
 | 
			
		||||
                                 "Text",
 | 
			
		||||
                                 NULL,
 | 
			
		||||
                                 G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE);
 | 
			
		||||
    g_object_class_install_property (gobject_class, PROP_TEXT, pspec);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
eek_text_init (EekText *self)
 | 
			
		||||
{
 | 
			
		||||
    /* void */
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
EekText *
 | 
			
		||||
eek_text_new (const gchar *text)
 | 
			
		||||
{
 | 
			
		||||
    EekSymbol *ret = eek_symbol_new("");
 | 
			
		||||
    eek_symbol_set_label(ret, text);
 | 
			
		||||
    ret->text = g_strdup (text);
 | 
			
		||||
    return ret;
 | 
			
		||||
    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 (EekSymbol *text)
 | 
			
		||||
eek_text_get_text (EekText *text)
 | 
			
		||||
{
 | 
			
		||||
    return text->text;
 | 
			
		||||
    EekTextPrivate *priv = eek_text_get_instance_private (text);
 | 
			
		||||
 | 
			
		||||
    return priv->text;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -29,9 +29,17 @@
 | 
			
		||||
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
#define EEK_TYPE_TEXT (eek_text_get_type())
 | 
			
		||||
G_DECLARE_DERIVABLE_TYPE(EekText, eek_text, EEK, TEXT, EekSymbol)
 | 
			
		||||
 | 
			
		||||
struct _EekTextClass {
 | 
			
		||||
    /*< private >*/
 | 
			
		||||
    EekSymbolClass parent_class;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
GType        eek_text_get_type (void) G_GNUC_CONST;
 | 
			
		||||
EekSymbol   *eek_text_new      (const gchar *text);
 | 
			
		||||
const gchar *eek_text_get_text (EekSymbol   *text);
 | 
			
		||||
EekText     *eek_text_new      (const gchar *text);
 | 
			
		||||
const gchar *eek_text_get_text (EekText     *text);
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										287
									
								
								eek/eek-theme-context.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										287
									
								
								eek/eek-theme-context.c
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,287 @@
 | 
			
		||||
/* -*- 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/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "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__ */
 | 
			
		||||
							
								
								
									
										1864
									
								
								eek/eek-theme-node.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1864
									
								
								eek/eek-theme-node.c
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										141
									
								
								eek/eek-theme-node.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										141
									
								
								eek/eek-theme-node.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,141 @@
 | 
			
		||||
/* 
 | 
			
		||||
 * Copyright (C) 2010-2011 Daiki Ueno <ueno@unixuser.org>
 | 
			
		||||
 * Copyright (C) 2010-2011 Red Hat, Inc.
 | 
			
		||||
 * 
 | 
			
		||||
 * This library is free software; you can redistribute it and/or
 | 
			
		||||
 * modify it under the terms of the GNU Lesser General Public License
 | 
			
		||||
 * as published by the Free Software Foundation; either version 2 of
 | 
			
		||||
 * the License, or (at your option) any later version.
 | 
			
		||||
 * 
 | 
			
		||||
 * This library is distributed in the hope that it will be useful, but
 | 
			
		||||
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
			
		||||
 * Lesser General Public License for more details.
 | 
			
		||||
 * 
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General Public
 | 
			
		||||
 * License along with this library; if not, write to the Free Software
 | 
			
		||||
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 | 
			
		||||
 * 02110-1301 USA
 | 
			
		||||
 */
 | 
			
		||||
#ifndef __EEK_THEME_NODE_H__
 | 
			
		||||
#define __EEK_THEME_NODE_H__
 | 
			
		||||
 | 
			
		||||
#include <pango/pango.h>
 | 
			
		||||
#include "eek-types.h"
 | 
			
		||||
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * SECTION:eek-theme-node
 | 
			
		||||
 * @short_description: style information for one node in a tree of
 | 
			
		||||
 * themed objects
 | 
			
		||||
 *
 | 
			
		||||
 * The #EekThemeNode class represents the CSS style information (the
 | 
			
		||||
 * set of CSS properties) for one node in a tree of themed objects. In
 | 
			
		||||
 * typical usage, it represents the style information for a single
 | 
			
		||||
 * #EekElement. A #EekThemeNode is immutable: attributes such as the
 | 
			
		||||
 * CSS classes for the node are passed in at construction. If the
 | 
			
		||||
 * attributes of the node or any parent node change, the node should
 | 
			
		||||
 * be discarded and a new node created.  #EekThemeNode has generic
 | 
			
		||||
 * accessors to look up properties by name and specific accessors for
 | 
			
		||||
 * standard CSS properties that add caching and handling of various
 | 
			
		||||
 * details of the CSS specification. #EekThemeNode also has
 | 
			
		||||
 * convenience functions to help in implementing a #EekElement with
 | 
			
		||||
 * borders and padding.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
typedef enum {
 | 
			
		||||
    EEK_SIDE_TOP,
 | 
			
		||||
    EEK_SIDE_RIGHT,
 | 
			
		||||
    EEK_SIDE_BOTTOM,
 | 
			
		||||
    EEK_SIDE_LEFT
 | 
			
		||||
} EekSide;
 | 
			
		||||
 | 
			
		||||
typedef enum {
 | 
			
		||||
    EEK_CORNER_TOPLEFT,
 | 
			
		||||
    EEK_CORNER_TOPRIGHT,
 | 
			
		||||
    EEK_CORNER_BOTTOMRIGHT,
 | 
			
		||||
    EEK_CORNER_BOTTOMLEFT
 | 
			
		||||
} EekCorner;
 | 
			
		||||
 | 
			
		||||
#define EEK_TYPE_THEME_NODE (eek_theme_node_get_type())
 | 
			
		||||
#define EEK_THEME_NODE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EEK_TYPE_THEME_NODE, EekThemeNode))
 | 
			
		||||
#define EEK_THEME_NODE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EEK_TYPE_THEME_NODE, EekThemeNodeClass))
 | 
			
		||||
#define EEK_IS_THEME_NODE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EEK_TYPE_THEME_NODE))
 | 
			
		||||
#define EEK_IS_THEME_NODE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EEK_TYPE_THEME_NODE))
 | 
			
		||||
#define EEK_THEME_NODE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EEK_TYPE_THEME_NODE, EekThemeNodeClass))
 | 
			
		||||
 | 
			
		||||
typedef struct _EekThemeNodeClass EekThemeNodeClass;
 | 
			
		||||
typedef struct _EekThemeNodePrivate EekThemeNodePrivate;
 | 
			
		||||
 | 
			
		||||
GType         eek_theme_node_get_type
 | 
			
		||||
                                 (void) G_GNUC_CONST;
 | 
			
		||||
 | 
			
		||||
EekThemeNode *eek_theme_node_new (EekThemeContext            *context,
 | 
			
		||||
                                  EekThemeNode               *parent_node,
 | 
			
		||||
                                  /* can be null */ EekTheme *theme,
 | 
			
		||||
                                  /* can be null */ GType     element_type,
 | 
			
		||||
                                  const char                 *element_id,
 | 
			
		||||
                                  const char                 *element_class,
 | 
			
		||||
                                  const char                 *pseudo_class,
 | 
			
		||||
                                  const char                 *inline_style);
 | 
			
		||||
 | 
			
		||||
EekThemeNode *eek_theme_node_get_parent
 | 
			
		||||
                                 (EekThemeNode               *node);
 | 
			
		||||
 | 
			
		||||
EekTheme     *eek_theme_node_get_theme
 | 
			
		||||
                                 (EekThemeNode               *node);
 | 
			
		||||
 | 
			
		||||
GType         eek_theme_node_get_element_type
 | 
			
		||||
                                 (EekThemeNode               *node);
 | 
			
		||||
const char   *eek_theme_node_get_element_id
 | 
			
		||||
                                 (EekThemeNode               *node);
 | 
			
		||||
const char   *eek_theme_node_get_element_class
 | 
			
		||||
                                 (EekThemeNode               *node);
 | 
			
		||||
const char   *eek_theme_node_get_pseudo_class
 | 
			
		||||
                                 (EekThemeNode               *node);
 | 
			
		||||
 | 
			
		||||
/* Generic getters ... these are not cached so are less efficient. The other
 | 
			
		||||
 * reason for adding the more specific version is that we can handle the
 | 
			
		||||
 * details of the actual CSS rules, which can be complicated, especially
 | 
			
		||||
 * for fonts
 | 
			
		||||
 */
 | 
			
		||||
void          eek_theme_node_get_color
 | 
			
		||||
                                 (EekThemeNode               *node,
 | 
			
		||||
                                  const char                 *property_name,
 | 
			
		||||
                                  EekColor                   *color);
 | 
			
		||||
 | 
			
		||||
/* Specific getters for particular properties: cached
 | 
			
		||||
 */
 | 
			
		||||
void          eek_theme_node_get_background_color
 | 
			
		||||
                                 (EekThemeNode               *node,
 | 
			
		||||
                                  EekColor                   *color);
 | 
			
		||||
void          eek_theme_node_get_foreground_color
 | 
			
		||||
                                 (EekThemeNode               *node,
 | 
			
		||||
                                  EekColor                   *color);
 | 
			
		||||
void          eek_theme_node_get_background_gradient
 | 
			
		||||
                                 (EekThemeNode               *node,
 | 
			
		||||
                                  EekGradientType            *type,
 | 
			
		||||
                                  EekColor                   *start,
 | 
			
		||||
                                  EekColor                   *end);
 | 
			
		||||
int           eek_theme_node_get_border_width
 | 
			
		||||
                                 (EekThemeNode               *node,
 | 
			
		||||
                                  EekSide                     side);
 | 
			
		||||
int           eek_theme_node_get_border_radius
 | 
			
		||||
                                 (EekThemeNode               *node,
 | 
			
		||||
                                  EekCorner                   corner);
 | 
			
		||||
void          eek_theme_node_get_border_color
 | 
			
		||||
                                 (EekThemeNode               *node,
 | 
			
		||||
                                  EekSide                     side,
 | 
			
		||||
                                  EekColor                   *color);
 | 
			
		||||
 | 
			
		||||
/* Font rule processing is pretty complicated, so we just hardcode it
 | 
			
		||||
 * under the standard font/font-family/font-size/etc names. This means
 | 
			
		||||
 * you can't have multiple separate styled fonts for a single item,
 | 
			
		||||
 * but that should be OK.
 | 
			
		||||
 */
 | 
			
		||||
const PangoFontDescription *eek_theme_node_get_font (EekThemeNode *node);
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
 | 
			
		||||
#endif /* __EEK_THEME_NODE_H__ */
 | 
			
		||||
							
								
								
									
										22
									
								
								eek/eek-theme-private.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								eek/eek-theme-private.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,22 @@
 | 
			
		||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
 | 
			
		||||
#ifndef __EEK_THEME_PRIVATE_H__
 | 
			
		||||
#define __EEK_THEME_PRIVATE_H__
 | 
			
		||||
 | 
			
		||||
#include <libcroco/libcroco.h>
 | 
			
		||||
#include "eek-theme.h"
 | 
			
		||||
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
GPtrArray *_eek_theme_get_matched_properties (EekTheme       *theme,
 | 
			
		||||
                                             EekThemeNode   *node);
 | 
			
		||||
 | 
			
		||||
/* Resolve an URL from the stylesheet to a filename */
 | 
			
		||||
char *_eek_theme_resolve_url (EekTheme      *theme,
 | 
			
		||||
                             CRStyleSheet *base_stylesheet,
 | 
			
		||||
                             const char   *url);
 | 
			
		||||
 | 
			
		||||
CRDeclaration *_eek_theme_parse_declaration_list (const char *str);
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
 | 
			
		||||
#endif /* __EEK_THEME_PRIVATE_H__ */
 | 
			
		||||
							
								
								
									
										1095
									
								
								eek/eek-theme.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1095
									
								
								eek/eek-theme.c
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										49
									
								
								eek/eek-theme.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										49
									
								
								eek/eek-theme.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,49 @@
 | 
			
		||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
 | 
			
		||||
 | 
			
		||||
#if !defined(__EEK_H_INSIDE__) && !defined(EEK_COMPILATION)
 | 
			
		||||
#error "Only <eek/eek.h> can be included directly."
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef __EEK_THEME_H__
 | 
			
		||||
#define __EEK_THEME_H__
 | 
			
		||||
 | 
			
		||||
#include <glib-object.h>
 | 
			
		||||
 | 
			
		||||
#include "eek-types.h"
 | 
			
		||||
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * SECTION:EekTheme
 | 
			
		||||
 * @short_description: a set of stylesheets
 | 
			
		||||
 *
 | 
			
		||||
 * #EekTheme holds a set of stylesheets. (The "cascade" of the name
 | 
			
		||||
 * Cascading Stylesheets.) An #EekTheme can be set to apply to all the
 | 
			
		||||
 * keyboard elements.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
typedef struct _EekThemeClass EekThemeClass;
 | 
			
		||||
 | 
			
		||||
#define EEK_TYPE_THEME (eek_theme_get_type())
 | 
			
		||||
#define EEK_THEME(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EEK_TYPE_THEME, EekTheme))
 | 
			
		||||
#define EEK_THEME_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EEK_TYPE_THEME, EekThemeClass))
 | 
			
		||||
#define EEK_IS_THEME(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EEK_TYPE_THEME))
 | 
			
		||||
#define EEK_IS_THEME_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EEK_TYPE_THEME))
 | 
			
		||||
#define EEK_THEME_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EEK_TYPE_THEME, EekThemeClass))
 | 
			
		||||
 | 
			
		||||
GType     eek_theme_get_type          (void) G_GNUC_CONST;
 | 
			
		||||
 | 
			
		||||
EekTheme *eek_theme_new               (const char *application_stylesheet,
 | 
			
		||||
                                       const char *theme_stylesheet,
 | 
			
		||||
                                       const char *default_stylesheet);
 | 
			
		||||
 | 
			
		||||
gboolean  eek_theme_load_stylesheet   (EekTheme   *theme,
 | 
			
		||||
                                       const char *path,
 | 
			
		||||
                                       GError    **error);
 | 
			
		||||
 | 
			
		||||
void      eek_theme_unload_stylesheet (EekTheme   *theme,
 | 
			
		||||
                                       const char *path);
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
 | 
			
		||||
#endif /* __EEK_THEME_H__ */
 | 
			
		||||
@ -139,6 +139,7 @@ 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;
 | 
			
		||||
 | 
			
		||||
@ -79,6 +79,10 @@ static gboolean      parse_symbols   (const gchar         *path,
 | 
			
		||||
                                      EekKeyboard         *keyboard,
 | 
			
		||||
                                      GError             **error);
 | 
			
		||||
 | 
			
		||||
static void          scale_keyboard  (EekKeyboard         *keyboard,
 | 
			
		||||
                                      gdouble              width,
 | 
			
		||||
                                      gdouble              height);
 | 
			
		||||
 | 
			
		||||
static gboolean      validate        (const gchar        **valid_path_list,
 | 
			
		||||
                                      gsize                valid_path_list_len,
 | 
			
		||||
                                      const gchar         *element_name,
 | 
			
		||||
@ -243,7 +247,6 @@ struct _GeometryParseData {
 | 
			
		||||
    gchar *name;
 | 
			
		||||
    EekOutline outline;
 | 
			
		||||
    gchar *oref;
 | 
			
		||||
    gint keycode;
 | 
			
		||||
 | 
			
		||||
    GHashTable *key_oref_hash;
 | 
			
		||||
    GHashTable *oref_outline_hash;
 | 
			
		||||
@ -266,7 +269,6 @@ geometry_parse_data_new (EekKeyboard *keyboard)
 | 
			
		||||
                               g_str_equal,
 | 
			
		||||
                               g_free,
 | 
			
		||||
                               (GDestroyNotify)eek_outline_free);
 | 
			
		||||
    data->keycode = 8;
 | 
			
		||||
    return data;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -394,6 +396,17 @@ geometry_start_element_callback (GMarkupParseContext *pcontext,
 | 
			
		||||
    if (g_strcmp0 (element_name, "key") == 0) {
 | 
			
		||||
        guint keycode;
 | 
			
		||||
 | 
			
		||||
        attribute = get_attribute (attribute_names, attribute_values,
 | 
			
		||||
                                   "keycode");
 | 
			
		||||
        if (attribute == NULL) {
 | 
			
		||||
            g_set_error (error,
 | 
			
		||||
                         G_MARKUP_ERROR,
 | 
			
		||||
                         G_MARKUP_ERROR_MISSING_ATTRIBUTE,
 | 
			
		||||
                         "no \"keycode\" attribute for \"key\"");
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
        keycode = strtol (attribute, NULL, 10);
 | 
			
		||||
 | 
			
		||||
        attribute = get_attribute (attribute_names, attribute_values,
 | 
			
		||||
                                   "name");
 | 
			
		||||
        if (attribute == NULL) {
 | 
			
		||||
@ -403,18 +416,12 @@ geometry_start_element_callback (GMarkupParseContext *pcontext,
 | 
			
		||||
                         "no \"name\" attribute for \"key\"");
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
        gchar *name = g_strdup (attribute);
 | 
			
		||||
 | 
			
		||||
        attribute = get_attribute (attribute_names, attribute_values,
 | 
			
		||||
                                   "keycode");
 | 
			
		||||
        if (attribute != NULL)
 | 
			
		||||
            keycode = strtol (attribute, NULL, 10);
 | 
			
		||||
        else
 | 
			
		||||
            keycode = data->keycode++;
 | 
			
		||||
 | 
			
		||||
        data->key = eek_section_create_key (data->section,
 | 
			
		||||
                                            name,
 | 
			
		||||
                                            keycode);
 | 
			
		||||
                                            g_strdup (attribute),
 | 
			
		||||
                                            keycode,
 | 
			
		||||
                                            data->num_columns,
 | 
			
		||||
                                            data->num_rows - 1);
 | 
			
		||||
 | 
			
		||||
        attribute = get_attribute (attribute_names, attribute_values,
 | 
			
		||||
                                   "oref");
 | 
			
		||||
@ -566,6 +573,7 @@ struct _SymbolsParseData {
 | 
			
		||||
    gchar *label;
 | 
			
		||||
    gchar *icon;
 | 
			
		||||
    gchar *tooltip;
 | 
			
		||||
    EekSymbolCategory category;
 | 
			
		||||
    guint keyval;
 | 
			
		||||
    gint groups;
 | 
			
		||||
};
 | 
			
		||||
@ -678,6 +686,13 @@ symbols_start_element_callback (GMarkupParseContext *pcontext,
 | 
			
		||||
                                   "tooltip");
 | 
			
		||||
        if (attribute != NULL)
 | 
			
		||||
            data->tooltip = g_strdup (attribute);
 | 
			
		||||
 | 
			
		||||
        attribute = get_attribute (attribute_names, attribute_values,
 | 
			
		||||
                                   "category");
 | 
			
		||||
        if (attribute != NULL)
 | 
			
		||||
            data->category = strtoul (attribute, NULL, 10);
 | 
			
		||||
        else
 | 
			
		||||
            data->category = EEK_SYMBOL_CATEGORY_KEYNAME;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 out:
 | 
			
		||||
@ -712,6 +727,7 @@ symbols_end_element_callback (GMarkupParseContext *pcontext,
 | 
			
		||||
        gint levels = num_symbols / data->groups;
 | 
			
		||||
        EekSymbolMatrix *matrix = eek_symbol_matrix_new (data->groups,
 | 
			
		||||
                                                         levels);
 | 
			
		||||
 | 
			
		||||
        head = data->symbols = g_slist_reverse (data->symbols);
 | 
			
		||||
        for (i = 0; i < num_symbols; i++) {
 | 
			
		||||
            if (head && head->data) {
 | 
			
		||||
@ -735,22 +751,21 @@ symbols_end_element_callback (GMarkupParseContext *pcontext,
 | 
			
		||||
        EekSymbol *symbol;
 | 
			
		||||
 | 
			
		||||
        if (g_strcmp0 (element_name, "keysym") == 0) {
 | 
			
		||||
            EekSymbol *keysym;
 | 
			
		||||
            EekKeysym *keysym;
 | 
			
		||||
            if (data->keyval != EEK_INVALID_KEYSYM)
 | 
			
		||||
                keysym = eek_keysym_new (data->keyval);
 | 
			
		||||
            else
 | 
			
		||||
                keysym = eek_keysym_new_from_name (text);
 | 
			
		||||
            symbol = keysym;
 | 
			
		||||
            symbol = EEK_SYMBOL(keysym);
 | 
			
		||||
        } else if (g_strcmp0 (element_name, "text") == 0) {
 | 
			
		||||
            symbol = eek_text_new (text);
 | 
			
		||||
            symbol = EEK_SYMBOL(eek_text_new (text));
 | 
			
		||||
        } else {
 | 
			
		||||
            symbol = eek_symbol_new (text);
 | 
			
		||||
            eek_symbol_set_category (symbol, EEK_SYMBOL_CATEGORY_KEYNAME);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (data->label) {
 | 
			
		||||
            eek_symbol_set_label (symbol, data->label);
 | 
			
		||||
            eek_keyboard_register_symbol (data->keyboard, symbol, data->key,
 | 
			
		||||
                                          g_slist_length (data->symbols));
 | 
			
		||||
            g_free (data->label);
 | 
			
		||||
            data->label = NULL;
 | 
			
		||||
        }
 | 
			
		||||
@ -931,9 +946,11 @@ eek_xml_layout_real_create_keyboard (EekboardContextService *manager,
 | 
			
		||||
        return NULL;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* Arrange the sections in the original coordinate system. */
 | 
			
		||||
    eek_layout_place_sections(keyboard);
 | 
			
		||||
 | 
			
		||||
    /* Fit keyboard in the given width and height. */
 | 
			
		||||
    scale_keyboard (keyboard, initial_width, initial_height);
 | 
			
		||||
 | 
			
		||||
    /* Use pre-defined modifier mask here. */
 | 
			
		||||
    eek_keyboard_set_num_lock_mask (keyboard, EEK_MOD2_MASK);
 | 
			
		||||
    eek_keyboard_set_alt_gr_mask (keyboard, EEK_BUTTON1_MASK);
 | 
			
		||||
@ -1343,6 +1360,23 @@ parse_keyboards (const gchar *path, GError **error)
 | 
			
		||||
    return keyboards;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void scale_keyboard (EekKeyboard *keyboard,
 | 
			
		||||
                            gdouble      width,
 | 
			
		||||
                            gdouble      height)
 | 
			
		||||
{
 | 
			
		||||
    gdouble scale;
 | 
			
		||||
    EekBounds bounds;
 | 
			
		||||
 | 
			
		||||
    eek_element_get_bounds (EEK_ELEMENT(keyboard), &bounds);
 | 
			
		||||
 | 
			
		||||
    if (width * bounds.height < height * bounds.width)
 | 
			
		||||
        scale = width / bounds.width;
 | 
			
		||||
    else
 | 
			
		||||
        scale = height / bounds.height;
 | 
			
		||||
 | 
			
		||||
    eek_layout_scale_keyboard(keyboard, scale);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
validate (const gchar **valid_path_list,
 | 
			
		||||
          gsize         valid_path_list_len,
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										315
									
								
								eek/eek-xml.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										315
									
								
								eek/eek-xml.c
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,315 @@
 | 
			
		||||
/* 
 | 
			
		||||
 * 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
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "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 */
 | 
			
		||||
@ -29,7 +29,9 @@
 | 
			
		||||
#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\
 | 
			
		||||
};";
 | 
			
		||||
@ -27,6 +27,9 @@
 | 
			
		||||
 | 
			
		||||
#include "config.h"
 | 
			
		||||
 | 
			
		||||
#include "eekboard/eekboard-context-service.h"
 | 
			
		||||
#include "keymap.h"
 | 
			
		||||
 | 
			
		||||
#include <fcntl.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
@ -34,14 +37,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
 | 
			
		||||
@ -86,6 +85,55 @@ struct _EekboardContextServicePrivate {
 | 
			
		||||
 | 
			
		||||
G_DEFINE_TYPE_WITH_PRIVATE (EekboardContextService, eekboard_context_service, G_TYPE_OBJECT);
 | 
			
		||||
 | 
			
		||||
/*static Display *display = NULL; */
 | 
			
		||||
gchar *
 | 
			
		||||
get_keymap_from_resource(const gchar *keyboard_type, gboolean fallback)
 | 
			
		||||
{
 | 
			
		||||
    g_autoptr (GFile) file = NULL;
 | 
			
		||||
    g_autoptr (GFileInfo) info = NULL;
 | 
			
		||||
    g_autoptr (GFileInputStream) stream = NULL;
 | 
			
		||||
    goffset size = 0;
 | 
			
		||||
    gsize bytes_read = 0;
 | 
			
		||||
    g_autofree gchar *contents = NULL;
 | 
			
		||||
    g_autofree gchar *path = NULL;
 | 
			
		||||
    GError *error = NULL;
 | 
			
		||||
 | 
			
		||||
    if (fallback)
 | 
			
		||||
        g_debug ("falling back to loading a %s keymap", keyboard_type);
 | 
			
		||||
 | 
			
		||||
    path = g_strconcat ("resource:///sm/puri/squeekboard/keyboards/keymaps/",
 | 
			
		||||
                        keyboard_type, ".xkb", NULL);
 | 
			
		||||
    file = g_file_new_for_uri (path);
 | 
			
		||||
    stream = g_file_read (file, NULL, &error);
 | 
			
		||||
 | 
			
		||||
    if (!stream)
 | 
			
		||||
        goto keymap_error;
 | 
			
		||||
 | 
			
		||||
    info = g_file_input_stream_query_info (stream,
 | 
			
		||||
                                           G_FILE_ATTRIBUTE_STANDARD_SIZE,
 | 
			
		||||
                                           NULL,
 | 
			
		||||
                                           &error);
 | 
			
		||||
 | 
			
		||||
    if (!info)
 | 
			
		||||
        goto keymap_error;
 | 
			
		||||
 | 
			
		||||
    size = g_file_info_get_size (info);
 | 
			
		||||
    contents = g_malloc0 (size);
 | 
			
		||||
 | 
			
		||||
    if (!g_input_stream_read_all (G_INPUT_STREAM(stream), contents, size,
 | 
			
		||||
                                  &bytes_read, NULL, &error))
 | 
			
		||||
        goto keymap_error;
 | 
			
		||||
 | 
			
		||||
    return g_utf8_make_valid (contents, -1);
 | 
			
		||||
 | 
			
		||||
keymap_error:
 | 
			
		||||
    if (fallback)
 | 
			
		||||
        g_error ("failed to load keymap from resource: %s", error->message);
 | 
			
		||||
 | 
			
		||||
    g_error_free (error);
 | 
			
		||||
    return NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static EekKeyboard *
 | 
			
		||||
eekboard_context_service_real_create_keyboard (EekboardContextService *self,
 | 
			
		||||
                                               const gchar            *keyboard_type)
 | 
			
		||||
@ -145,8 +193,13 @@ eekboard_context_service_real_create_keyboard (EekboardContextService *self,
 | 
			
		||||
    if (!context) {
 | 
			
		||||
        g_error("No context created");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    gchar *keymap_str = eek_keyboard_get_keymap(keyboard);
 | 
			
		||||
/*
 | 
			
		||||
    struct xkb_rule_names rules = { 0 };
 | 
			
		||||
    rules.layout = strdup(keyboard_type);
 | 
			
		||||
*/
 | 
			
		||||
    char *keymap_str = get_keymap_from_resource(keyboard_type, FALSE);
 | 
			
		||||
    if (!keymap_str)
 | 
			
		||||
        keymap_str = get_keymap_from_resource("us", TRUE);
 | 
			
		||||
 | 
			
		||||
    struct xkb_keymap *keymap = xkb_keymap_new_from_string(context, keymap_str,
 | 
			
		||||
        XKB_KEYMAP_FORMAT_TEXT_V1, XKB_KEYMAP_COMPILE_NO_FLAGS);
 | 
			
		||||
@ -304,24 +357,8 @@ settings_update_layout(EekboardContextService *context)
 | 
			
		||||
 | 
			
		||||
    EekboardContextServicePrivate *priv = EEKBOARD_CONTEXT_SERVICE_GET_PRIVATE(context);
 | 
			
		||||
 | 
			
		||||
    switch (priv->purpose) {
 | 
			
		||||
    case ZWP_TEXT_INPUT_V3_CONTENT_PURPOSE_DIGITS:
 | 
			
		||||
    case ZWP_TEXT_INPUT_V3_CONTENT_PURPOSE_PIN:
 | 
			
		||||
        keyboard_layout = g_strdup("digits");
 | 
			
		||||
        break;
 | 
			
		||||
    case ZWP_TEXT_INPUT_V3_CONTENT_PURPOSE_NUMBER:
 | 
			
		||||
        keyboard_layout = g_strdup("number");
 | 
			
		||||
        break;
 | 
			
		||||
    case ZWP_TEXT_INPUT_V3_CONTENT_PURPOSE_PHONE:
 | 
			
		||||
        keyboard_layout = g_strdup("phone");
 | 
			
		||||
        break;
 | 
			
		||||
    case ZWP_TEXT_INPUT_V3_CONTENT_PURPOSE_URL:
 | 
			
		||||
        keyboard_layout = g_strdup("url");
 | 
			
		||||
        break;
 | 
			
		||||
    case ZWP_TEXT_INPUT_V3_CONTENT_PURPOSE_NORMAL:
 | 
			
		||||
    default:
 | 
			
		||||
        ;
 | 
			
		||||
    }
 | 
			
		||||
    if (priv->purpose == ZWP_TEXT_INPUT_V3_CONTENT_PURPOSE_PHONE)
 | 
			
		||||
        keyboard_layout = g_strdup("numbers");
 | 
			
		||||
 | 
			
		||||
    // generic part follows
 | 
			
		||||
    static guint keyboard_id = 0;
 | 
			
		||||
 | 
			
		||||
@ -35,6 +35,7 @@ enum {
 | 
			
		||||
    ENABLED,
 | 
			
		||||
    DISABLED,
 | 
			
		||||
    DESTROYED,
 | 
			
		||||
    KEY_ACTIVATED,
 | 
			
		||||
    LAST_SIGNAL
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
@ -80,6 +81,28 @@ 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;
 | 
			
		||||
 | 
			
		||||
@ -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,
 | 
			
		||||
@ -155,6 +186,7 @@ eekboard_context_class_init (EekboardContextClass *klass)
 | 
			
		||||
    klass->enabled = eekboard_context_real_enabled;
 | 
			
		||||
    klass->disabled = eekboard_context_real_disabled;
 | 
			
		||||
    klass->destroyed = eekboard_context_real_destroyed;
 | 
			
		||||
    klass->key_activated = eekboard_context_real_key_activated;
 | 
			
		||||
 | 
			
		||||
    proxy_class->g_signal = eekboard_context_real_g_signal;
 | 
			
		||||
 | 
			
		||||
@ -208,6 +240,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
 | 
			
		||||
 | 
			
		||||
@ -47,6 +47,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];
 | 
			
		||||
 | 
			
		||||
@ -28,14 +28,12 @@
 | 
			
		||||
 | 
			
		||||
#include "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,
 | 
			
		||||
 | 
			
		||||
@ -20,6 +20,7 @@
 | 
			
		||||
/* This file is responsible for managing keycode data and emitting keycodes. */
 | 
			
		||||
 | 
			
		||||
#include "eekboard/key-emitter.h"
 | 
			
		||||
#include "eekboard/keymap.h"
 | 
			
		||||
 | 
			
		||||
#include <gdk/gdk.h>
 | 
			
		||||
 | 
			
		||||
@ -38,6 +39,98 @@ 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,
 | 
			
		||||
@ -48,6 +141,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)
 | 
			
		||||
@ -84,13 +286,14 @@ update_modifier_info (SeatEmitter *client)
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
send_fake_key (SeatEmitter *emitter,
 | 
			
		||||
               guint    level,
 | 
			
		||||
               EekKeyboard *keyboard,
 | 
			
		||||
               guint    keycode,
 | 
			
		||||
               guint    keyboard_modifiers,
 | 
			
		||||
               gboolean pressed,
 | 
			
		||||
               uint32_t timestamp)
 | 
			
		||||
{
 | 
			
		||||
    uint32_t proto_modifiers = 0;
 | 
			
		||||
    guint level = eek_element_get_level(EEK_ELEMENT(keyboard));
 | 
			
		||||
    uint32_t group = (level / 2);
 | 
			
		||||
 | 
			
		||||
    if (keyboard_modifiers & EEK_SHIFT_MASK)
 | 
			
		||||
@ -101,38 +304,6 @@ send_fake_key (SeatEmitter *emitter,
 | 
			
		||||
    zwp_virtual_keyboard_v1_modifiers(emitter->virtual_keyboard, proto_modifiers, 0, 0, group);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
send_fake_text (SeatEmitter *emitter,
 | 
			
		||||
                EekKeyboard *keyboard,
 | 
			
		||||
                const gchar *text,
 | 
			
		||||
                uint32_t timestamp)
 | 
			
		||||
{
 | 
			
		||||
    gchar *ptr = (gchar *)text;
 | 
			
		||||
 | 
			
		||||
    while (*ptr) {
 | 
			
		||||
        gchar buf[7];
 | 
			
		||||
        gunichar c = g_utf8_get_char(ptr);
 | 
			
		||||
        int n = g_unichar_to_utf8(c, buf);
 | 
			
		||||
        *(buf + n) = 0;
 | 
			
		||||
 | 
			
		||||
        EekKeyPress *key_press = eek_keyboard_get_key_press(keyboard, buf);
 | 
			
		||||
 | 
			
		||||
        if (key_press) {
 | 
			
		||||
            EekKey *key = key_press->key;
 | 
			
		||||
 | 
			
		||||
            send_fake_key (emitter, key_press->level, eek_key_get_keycode(key),
 | 
			
		||||
                           (key_press->level % 2) == 1 ? EEK_SHIFT_MASK : 0,
 | 
			
		||||
                           1, timestamp);
 | 
			
		||||
 | 
			
		||||
            send_fake_key (emitter, key_press->level, eek_key_get_keycode(key),
 | 
			
		||||
                           (key_press->level % 2) == 1 ? EEK_SHIFT_MASK : 0,
 | 
			
		||||
                           0, timestamp);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        ptr = g_utf8_find_next_char(ptr, NULL);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
emit_key_activated (EekboardContextService *manager,
 | 
			
		||||
                    EekKeyboard     *keyboard,
 | 
			
		||||
@ -173,12 +344,5 @@ emit_key_activated (EekboardContextService *manager,
 | 
			
		||||
    emitter.virtual_keyboard = manager->virtual_keyboard;
 | 
			
		||||
    emitter.keymap = keyboard->keymap;
 | 
			
		||||
    update_modifier_info (&emitter);
 | 
			
		||||
 | 
			
		||||
    const gchar *text = (gchar *)eek_text_get_text(symbol);
 | 
			
		||||
    if (text && pressed) {
 | 
			
		||||
        send_fake_text (&emitter, keyboard, text, timestamp);
 | 
			
		||||
    } else {
 | 
			
		||||
        guint level = eek_element_get_level(EEK_ELEMENT(keyboard));
 | 
			
		||||
        send_fake_key (&emitter, level, keycode, modifiers, pressed, timestamp);
 | 
			
		||||
    }
 | 
			
		||||
    send_fake_key (&emitter, keyboard, keycode, modifiers, pressed, timestamp);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										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);
 | 
			
		||||
							
								
								
									
										10
									
								
								meson.build
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								meson.build
									
									
									
									
									
								
							@ -11,16 +11,6 @@ project(
 | 
			
		||||
    ]
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
add_project_arguments(
 | 
			
		||||
  [
 | 
			
		||||
    '-Werror=implicit-function-declaration',
 | 
			
		||||
    '-Werror=implicit-fallthrough=3',
 | 
			
		||||
    '-Werror=maybe-uninitialized',
 | 
			
		||||
    '-Werror=missing-field-initializers',
 | 
			
		||||
  ],
 | 
			
		||||
  language: 'c'
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
i18n = import('i18n')
 | 
			
		||||
 | 
			
		||||
conf_data = configuration_data()
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										1350
									
								
								src/bitflags.rs
									
									
									
									
									
								
							
							
						
						
									
										1350
									
								
								src/bitflags.rs
									
									
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@ -5,6 +5,19 @@
 | 
			
		||||
#include "eekboard/eekboard-context-service.h"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void imservice_handle_text_change_cause(void *data, struct zwp_input_method_v2 *input_method, uint32_t cause) {}
 | 
			
		||||
 | 
			
		||||
void imservice_handle_content_type(void *data, struct zwp_input_method_v2 *input_method, uint32_t hint, uint32_t purpose)
 | 
			
		||||
{
 | 
			
		||||
    struct imservice *ims = (struct imservice*)data;
 | 
			
		||||
    EekboardContextService *context = EEKBOARD_CONTEXT_SERVICE(ims->ui_manager);
 | 
			
		||||
 | 
			
		||||
    eekboard_context_service_set_hint_purpose(context, hint, purpose);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void imservice_handle_unavailable(void *data, struct zwp_input_method_v2 *input_method) {}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static const struct zwp_input_method_v2_listener input_method_listener = {
 | 
			
		||||
    .activate = imservice_handle_input_method_activate,
 | 
			
		||||
    .deactivate = imservice_handle_input_method_deactivate,
 | 
			
		||||
@ -28,16 +41,14 @@ struct imservice* get_imservice(EekboardContextService *context,
 | 
			
		||||
    return imservice;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void imservice_make_visible(EekboardContextService *context) {
 | 
			
		||||
void imservice_make_visible(EekboardContextService *context,
 | 
			
		||||
                            struct zwp_input_method_v2 *im) {
 | 
			
		||||
    (void)im;
 | 
			
		||||
    eekboard_context_service_show_keyboard (context);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void imservice_try_hide(EekboardContextService *context) {
 | 
			
		||||
void imservice_try_hide(EekboardContextService *context,
 | 
			
		||||
                        struct zwp_input_method_v2 *im) {
 | 
			
		||||
    (void)im;
 | 
			
		||||
    eekboard_context_service_hide_keyboard (context);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Declared explicitly because _destroy is inline,
 | 
			
		||||
/// making it unavailable in Rust
 | 
			
		||||
void imservice_destroy_im(struct zwp_input_method_v2 *im) {
 | 
			
		||||
    zwp_input_method_v2_destroy(im);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -4,7 +4,11 @@
 | 
			
		||||
#include "input-method-unstable-v2-client-protocol.h"
 | 
			
		||||
#include "eek/eek-types.h"
 | 
			
		||||
 | 
			
		||||
struct imservice;
 | 
			
		||||
struct imservice
 | 
			
		||||
{
 | 
			
		||||
    struct zwp_input_method_v2 *im;
 | 
			
		||||
    EekboardContextService *ui_manager;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct imservice* get_imservice(EekboardContextService *context,
 | 
			
		||||
                                struct zwp_input_method_manager_v2 *manager,
 | 
			
		||||
@ -18,8 +22,5 @@ void imservice_handle_input_method_deactivate(void *data, struct zwp_input_metho
 | 
			
		||||
void imservice_handle_surrounding_text(void *data, struct zwp_input_method_v2 *input_method,
 | 
			
		||||
                                       const char *text, uint32_t cursor, uint32_t anchor);
 | 
			
		||||
void imservice_handle_commit_state(void *data, struct zwp_input_method_v2 *input_method);
 | 
			
		||||
void imservice_handle_content_type(void *data, struct zwp_input_method_v2 *input_method, uint32_t hint, uint32_t purpose);
 | 
			
		||||
void imservice_handle_text_change_cause(void *data, struct zwp_input_method_v2 *input_method, uint32_t cause);
 | 
			
		||||
void imservice_handle_unavailable(void *data, struct zwp_input_method_v2 *input_method);
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										226
									
								
								src/imservice.rs
									
									
									
									
									
								
							
							
						
						
									
										226
									
								
								src/imservice.rs
									
									
									
									
									
								
							@ -3,11 +3,6 @@ use std::ffi::CString;
 | 
			
		||||
use std::num::Wrapping;
 | 
			
		||||
use std::string::String;
 | 
			
		||||
 | 
			
		||||
use super::bitflags;
 | 
			
		||||
 | 
			
		||||
// Traits
 | 
			
		||||
use std::convert::TryFrom;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/// Gathers stuff defined in C or called by C
 | 
			
		||||
pub mod c {
 | 
			
		||||
@ -34,10 +29,8 @@ pub mod c {
 | 
			
		||||
    
 | 
			
		||||
    #[no_mangle]
 | 
			
		||||
    extern "C" {
 | 
			
		||||
        fn imservice_destroy_im(im: *mut c::InputMethod);
 | 
			
		||||
        fn eekboard_context_service_set_hint_purpose(imservice: *const UIManager, hint: u32, purpose: u32);
 | 
			
		||||
        fn eekboard_context_service_show_keyboard(imservice: *const UIManager);
 | 
			
		||||
        fn eekboard_context_service_hide_keyboard(imservice: *const UIManager);
 | 
			
		||||
        fn imservice_make_visible(imservice: *const UIManager);
 | 
			
		||||
        fn imservice_try_hide(imservice: *const UIManager);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    // The following defined in Rust. TODO: wrap naked pointers to Rust data inside RefCells to prevent multiple writers
 | 
			
		||||
@ -61,9 +54,9 @@ pub mod c {
 | 
			
		||||
    #[no_mangle]
 | 
			
		||||
    pub unsafe extern "C"
 | 
			
		||||
    fn imservice_handle_input_method_activate(imservice: *mut IMService,
 | 
			
		||||
        im: *const InputMethod)
 | 
			
		||||
        _im: *const InputMethod)
 | 
			
		||||
    {
 | 
			
		||||
        let imservice = check_imservice(imservice, im).unwrap();
 | 
			
		||||
        let imservice = &mut *imservice;
 | 
			
		||||
        imservice.preedit_string = String::new();
 | 
			
		||||
        imservice.pending = IMProtocolState {
 | 
			
		||||
            active: true,
 | 
			
		||||
@ -74,9 +67,9 @@ pub mod c {
 | 
			
		||||
    #[no_mangle]
 | 
			
		||||
    pub unsafe extern "C"
 | 
			
		||||
    fn imservice_handle_input_method_deactivate(imservice: *mut IMService,
 | 
			
		||||
        im: *const InputMethod)
 | 
			
		||||
        _im: *const InputMethod)
 | 
			
		||||
    {
 | 
			
		||||
        let imservice = check_imservice(imservice, im).unwrap();
 | 
			
		||||
        let imservice = &mut *imservice;
 | 
			
		||||
        imservice.pending = IMProtocolState {
 | 
			
		||||
            active: false,
 | 
			
		||||
            ..imservice.pending.clone()
 | 
			
		||||
@ -86,65 +79,23 @@ pub mod c {
 | 
			
		||||
    #[no_mangle]
 | 
			
		||||
    pub unsafe extern "C"
 | 
			
		||||
    fn imservice_handle_surrounding_text(imservice: *mut IMService,
 | 
			
		||||
        im: *const InputMethod,
 | 
			
		||||
        _im: *const InputMethod,
 | 
			
		||||
        text: *const c_char, cursor: u32, _anchor: u32)
 | 
			
		||||
    {
 | 
			
		||||
        let imservice = check_imservice(imservice, im).unwrap();
 | 
			
		||||
        let imservice = &mut *imservice;
 | 
			
		||||
        imservice.pending = IMProtocolState {
 | 
			
		||||
            surrounding_text: into_cstring(text).expect("Received invalid string"),
 | 
			
		||||
            surrounding_cursor: cursor,
 | 
			
		||||
            ..imservice.pending.clone()
 | 
			
		||||
        };
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    #[no_mangle]
 | 
			
		||||
    pub unsafe extern "C"
 | 
			
		||||
    fn imservice_handle_content_type(imservice: *mut IMService,
 | 
			
		||||
        im: *const InputMethod,
 | 
			
		||||
        hint: u32, purpose: u32)
 | 
			
		||||
    {
 | 
			
		||||
        let imservice = check_imservice(imservice, im).unwrap();
 | 
			
		||||
        imservice.pending = IMProtocolState {
 | 
			
		||||
            content_hint: {
 | 
			
		||||
                ContentHint::from_bits(hint).unwrap_or_else(|| {
 | 
			
		||||
                    eprintln!("Warning: received invalid hint flags");
 | 
			
		||||
                    ContentHint::NONE
 | 
			
		||||
                })
 | 
			
		||||
            },
 | 
			
		||||
            content_purpose: {
 | 
			
		||||
                ContentPurpose::try_from(purpose).unwrap_or_else(|_e| {
 | 
			
		||||
                    eprintln!("Warning: Received invalid purpose value");
 | 
			
		||||
                    ContentPurpose::Normal
 | 
			
		||||
                })
 | 
			
		||||
            },
 | 
			
		||||
            ..imservice.pending.clone()
 | 
			
		||||
        };
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    #[no_mangle]
 | 
			
		||||
    pub unsafe extern "C"
 | 
			
		||||
    fn imservice_handle_text_change_cause(imservice: *mut IMService,
 | 
			
		||||
        im: *const InputMethod,
 | 
			
		||||
        cause: u32)
 | 
			
		||||
    {
 | 
			
		||||
        let imservice = check_imservice(imservice, im).unwrap();
 | 
			
		||||
        imservice.pending = IMProtocolState {
 | 
			
		||||
            text_change_cause: {
 | 
			
		||||
                ChangeCause::try_from(cause).unwrap_or_else(|_e| {
 | 
			
		||||
                    eprintln!("Warning: received invalid cause value");
 | 
			
		||||
                    ChangeCause::InputMethod
 | 
			
		||||
                })
 | 
			
		||||
            },
 | 
			
		||||
            ..imservice.pending.clone()
 | 
			
		||||
            ..imservice.pending
 | 
			
		||||
        };
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    #[no_mangle]
 | 
			
		||||
    pub unsafe extern "C"
 | 
			
		||||
    fn imservice_handle_commit_state(imservice: *mut IMService,
 | 
			
		||||
        im: *const InputMethod)
 | 
			
		||||
        _im: *const InputMethod)
 | 
			
		||||
    {
 | 
			
		||||
        let imservice = check_imservice(imservice, im).unwrap();
 | 
			
		||||
        let imservice = &mut *imservice;
 | 
			
		||||
        let active_changed = imservice.current.active ^ imservice.pending.active;
 | 
			
		||||
        
 | 
			
		||||
        imservice.serial += Wrapping(1u32);
 | 
			
		||||
@ -155,174 +106,27 @@ pub mod c {
 | 
			
		||||
        };
 | 
			
		||||
        if active_changed {
 | 
			
		||||
            if imservice.current.active {
 | 
			
		||||
                eekboard_context_service_show_keyboard(imservice.ui_manager);
 | 
			
		||||
                eekboard_context_service_set_hint_purpose(
 | 
			
		||||
                    imservice.ui_manager,
 | 
			
		||||
                    imservice.current.content_hint.bits(),
 | 
			
		||||
                    imservice.current.content_purpose.clone() as u32);
 | 
			
		||||
                imservice_make_visible(imservice.ui_manager);
 | 
			
		||||
            } else {
 | 
			
		||||
                eekboard_context_service_hide_keyboard(imservice.ui_manager);
 | 
			
		||||
                imservice_try_hide(imservice.ui_manager);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    #[no_mangle]
 | 
			
		||||
    pub unsafe extern "C"
 | 
			
		||||
    fn imservice_handle_unavailable(imservice: *mut IMService,
 | 
			
		||||
        im: *mut InputMethod)
 | 
			
		||||
    {
 | 
			
		||||
        let imservice = check_imservice(imservice, im).unwrap();
 | 
			
		||||
        imservice_destroy_im(im);
 | 
			
		||||
 | 
			
		||||
        // no need to care about proper double-buffering,
 | 
			
		||||
        // the keyboard is already decommissioned
 | 
			
		||||
        imservice.current.active = false;
 | 
			
		||||
 | 
			
		||||
        eekboard_context_service_hide_keyboard(imservice.ui_manager);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // FIXME: destroy and deallocate
 | 
			
		||||
    
 | 
			
		||||
    // Helpers
 | 
			
		||||
    
 | 
			
		||||
    /// Convenience method for referencing the IMService raw pointer,
 | 
			
		||||
    /// and for verifying that the input method passed along
 | 
			
		||||
    /// matches the one in the `imservice`.
 | 
			
		||||
    ///
 | 
			
		||||
    /// The lifetime of the returned value is 'static,
 | 
			
		||||
    /// due to the fact that the lifetime of a raw pointer is undefined.
 | 
			
		||||
    /// Care must be take
 | 
			
		||||
    /// not to exceed the lifetime of the pointer with the reference,
 | 
			
		||||
    /// especially not to store it.
 | 
			
		||||
    fn check_imservice(imservice: *mut IMService, im: *const InputMethod)
 | 
			
		||||
        -> Result<&'static mut IMService, &'static str>
 | 
			
		||||
    {
 | 
			
		||||
        if imservice.is_null() {
 | 
			
		||||
            return Err("Null imservice pointer");
 | 
			
		||||
        }
 | 
			
		||||
        let imservice: &mut IMService = unsafe { &mut *imservice };
 | 
			
		||||
        if im == imservice.im {
 | 
			
		||||
            Ok(imservice)
 | 
			
		||||
        } else {
 | 
			
		||||
            Err("Imservice doesn't contain the input method")
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
bitflags!{
 | 
			
		||||
    /// Map to `text_input_unstable_v3.content_hint` values
 | 
			
		||||
    pub struct ContentHint: u32 {
 | 
			
		||||
        const NONE = 0x0;
 | 
			
		||||
        const COMPLETION = 0x1;
 | 
			
		||||
        const SPELLCHECK = 0x2;
 | 
			
		||||
        const AUTO_CAPITALIZATION = 0x4;
 | 
			
		||||
        const LOWERCASE = 0x8;
 | 
			
		||||
        const UPPERCASE = 0x10;
 | 
			
		||||
        const TITLECASE = 0x20;
 | 
			
		||||
        const HIDDEN_TEXT = 0x40;
 | 
			
		||||
        const SENSITIVE_DATA = 0x80;
 | 
			
		||||
        const LATIN = 0x100;
 | 
			
		||||
        const MULTILINE = 0x200;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Map to `text_input_unstable_v3.content_purpose` values
 | 
			
		||||
///
 | 
			
		||||
/// ```
 | 
			
		||||
/// assert_eq!(ContentPurpose::Alpha as u32, 0);
 | 
			
		||||
/// ```
 | 
			
		||||
#[derive(Debug, Clone)]
 | 
			
		||||
pub enum ContentPurpose {
 | 
			
		||||
    Normal = 0,
 | 
			
		||||
    Alpha = 1,
 | 
			
		||||
    Digits = 2,
 | 
			
		||||
    Number = 3,
 | 
			
		||||
    Phone = 4,
 | 
			
		||||
    Url = 5,
 | 
			
		||||
    Email = 6,
 | 
			
		||||
    Name = 7,
 | 
			
		||||
    Password = 8,
 | 
			
		||||
    Pin = 9,
 | 
			
		||||
    Date = 10,
 | 
			
		||||
    Time = 11,
 | 
			
		||||
    Datetime = 12,
 | 
			
		||||
    Terminal = 13,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl TryFrom<u32> for ContentPurpose {
 | 
			
		||||
    // There's only one way to fail: number not in protocol,
 | 
			
		||||
    // so no special error type is needed
 | 
			
		||||
    type Error = ();
 | 
			
		||||
    fn try_from(num: u32) -> Result<Self, Self::Error> {
 | 
			
		||||
        use self::ContentPurpose::*;
 | 
			
		||||
        match num {
 | 
			
		||||
            0 => Ok(Normal),
 | 
			
		||||
            1 => Ok(Alpha),
 | 
			
		||||
            2 => Ok(Digits),
 | 
			
		||||
            3 => Ok(Number),
 | 
			
		||||
            4 => Ok(Phone),
 | 
			
		||||
            5 => Ok(Url),
 | 
			
		||||
            6 => Ok(Email),
 | 
			
		||||
            7 => Ok(Name),
 | 
			
		||||
            8 => Ok(Password),
 | 
			
		||||
            9 => Ok(Pin),
 | 
			
		||||
            10 => Ok(Date),
 | 
			
		||||
            11 => Ok(Time),
 | 
			
		||||
            12 => Ok(Datetime),
 | 
			
		||||
            13 => Ok(Terminal),
 | 
			
		||||
            _ => Err(()),
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Map to `text_input_unstable_v3.change_cause` values
 | 
			
		||||
#[derive(Debug, Clone)]
 | 
			
		||||
pub enum ChangeCause {
 | 
			
		||||
    InputMethod = 0,
 | 
			
		||||
    Other = 1,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl TryFrom<u32> for ChangeCause {
 | 
			
		||||
    // There's only one way to fail: number not in protocol,
 | 
			
		||||
    // so no special error type is needed
 | 
			
		||||
    type Error = ();
 | 
			
		||||
    fn try_from(num: u32) -> Result<Self, Self::Error> {
 | 
			
		||||
        match num {
 | 
			
		||||
            0 => Ok(ChangeCause::InputMethod),
 | 
			
		||||
            1 => Ok(ChangeCause::Other),
 | 
			
		||||
            _ => Err(())
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Describes the desired state of the input method as requested by the server
 | 
			
		||||
#[derive(Clone)]
 | 
			
		||||
#[derive(Default, Clone)]
 | 
			
		||||
struct IMProtocolState {
 | 
			
		||||
    surrounding_text: CString,
 | 
			
		||||
    surrounding_cursor: u32,
 | 
			
		||||
    content_purpose: ContentPurpose,
 | 
			
		||||
    content_hint: ContentHint,
 | 
			
		||||
    text_change_cause: ChangeCause,
 | 
			
		||||
    active: bool,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl Default for IMProtocolState {
 | 
			
		||||
    fn default() -> IMProtocolState {
 | 
			
		||||
        IMProtocolState {
 | 
			
		||||
            surrounding_text: CString::default(),
 | 
			
		||||
            surrounding_cursor: 0, // TODO: mark that there's no cursor
 | 
			
		||||
            content_hint: ContentHint::NONE,
 | 
			
		||||
            content_purpose: ContentPurpose::Normal,
 | 
			
		||||
            text_change_cause: ChangeCause::InputMethod,
 | 
			
		||||
            active: false,
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub struct IMService {
 | 
			
		||||
    /// Owned reference (still created and destroyed in C)
 | 
			
		||||
    pub im: *const c::InputMethod,
 | 
			
		||||
    im: *const c::InputMethod,
 | 
			
		||||
    /// Unowned reference. Be careful, it's shared with C at large
 | 
			
		||||
    ui_manager: *const c::UIManager,
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -1,4 +0,0 @@
 | 
			
		||||
#[macro_use]
 | 
			
		||||
mod bitflags;
 | 
			
		||||
 | 
			
		||||
mod imservice;
 | 
			
		||||
@ -30,6 +30,9 @@ sources = [
 | 
			
		||||
  '../eek/eek-symbol.c',
 | 
			
		||||
  '../eek/eek-symbol-matrix.c',
 | 
			
		||||
  '../eek/eek-text.c',
 | 
			
		||||
  '../eek/eek-theme.c',
 | 
			
		||||
  '../eek/eek-theme-context.c',
 | 
			
		||||
  '../eek/eek-theme-node.c',
 | 
			
		||||
  '../eek/eek-types.c',
 | 
			
		||||
  '../eek/eek-xml-layout.c',
 | 
			
		||||
  '../eek/layersurface.c',
 | 
			
		||||
@ -37,6 +40,7 @@ sources = [
 | 
			
		||||
  enums,
 | 
			
		||||
  keysym_entries,
 | 
			
		||||
  marshalers,
 | 
			
		||||
  '../eekboard/keymap.c',
 | 
			
		||||
  '../eekboard/key-emitter.c',
 | 
			
		||||
  '../eekboard/eekboard-context-service.c',
 | 
			
		||||
  '../eekboard/eekboard-context.c',
 | 
			
		||||
@ -66,19 +70,10 @@ deps = [
 | 
			
		||||
# Replacement for eekboard-server
 | 
			
		||||
rslib = static_library(
 | 
			
		||||
  'rslib',
 | 
			
		||||
  sources: ['lib.rs'],
 | 
			
		||||
  sources: ['imservice.rs'],
 | 
			
		||||
  rust_crate_type: 'staticlib'
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
rstests = executable(
 | 
			
		||||
  'rstests',
 | 
			
		||||
  sources: ['lib.rs'],
 | 
			
		||||
  rust_args: ['--test'],
 | 
			
		||||
  install: false
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
test('rstests', rstests)
 | 
			
		||||
 | 
			
		||||
libsqueekboard = static_library('libsqueekboard',
 | 
			
		||||
  sources,
 | 
			
		||||
  link_with: rslib,
 | 
			
		||||
@ -94,7 +89,6 @@ libsqueekboard = static_library('libsqueekboard',
 | 
			
		||||
squeekboard = executable('squeekboard',
 | 
			
		||||
  'server-main.c',
 | 
			
		||||
  wl_proto_sources,
 | 
			
		||||
  squeekboard_resources,
 | 
			
		||||
  link_with: libsqueekboard,
 | 
			
		||||
  include_directories: [include_directories('..'), include_directories('../eek')],
 | 
			
		||||
  dependencies: deps,
 | 
			
		||||
 | 
			
		||||
@ -75,9 +75,6 @@ on_destroy (GtkWidget *widget, gpointer user_data)
 | 
			
		||||
    eekboard_context_service_destroy (EEKBOARD_CONTEXT_SERVICE (context));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
make_widget (ServerContextService *context);
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
on_notify_keyboard (GObject              *object,
 | 
			
		||||
                    GParamSpec           *spec,
 | 
			
		||||
@ -97,9 +94,6 @@ on_notify_keyboard (GObject              *object,
 | 
			
		||||
                                        keyboard);
 | 
			
		||||
 | 
			
		||||
    /* Recreate the keyboard widget to keep in sync with the keymap. */
 | 
			
		||||
    if (context->window)
 | 
			
		||||
        make_widget(context);
 | 
			
		||||
 | 
			
		||||
    gboolean visible;
 | 
			
		||||
    g_object_get (context, "visible", &visible, NULL);
 | 
			
		||||
 | 
			
		||||
@ -174,6 +168,13 @@ set_geometry (ServerContextService *context)
 | 
			
		||||
 | 
			
		||||
        gtk_window_set_decorated (GTK_WINDOW(context->window), FALSE);
 | 
			
		||||
        gtk_window_set_resizable (GTK_WINDOW(context->window), FALSE);
 | 
			
		||||
    } else {
 | 
			
		||||
        gtk_window_resize (GTK_WINDOW(context->window),
 | 
			
		||||
                           bounds.width,
 | 
			
		||||
                           bounds.height);
 | 
			
		||||
        gtk_window_move (GTK_WINDOW(context->window),
 | 
			
		||||
                         MAX(rect.width - 20 - bounds.width, 0),
 | 
			
		||||
                         MAX(rect.height - 40 - bounds.height, 0));
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -229,16 +230,20 @@ static void
 | 
			
		||||
make_widget (ServerContextService *context)
 | 
			
		||||
{
 | 
			
		||||
    EekKeyboard *keyboard;
 | 
			
		||||
    EekTheme *theme;
 | 
			
		||||
 | 
			
		||||
    if (context->widget) {
 | 
			
		||||
        gtk_widget_destroy(context->widget);
 | 
			
		||||
        context->widget = NULL;
 | 
			
		||||
    }
 | 
			
		||||
    g_return_if_fail (!context->widget);
 | 
			
		||||
    theme = eek_theme_new ("resource:///sm/puri/squeekboard/style.css",
 | 
			
		||||
                           NULL,
 | 
			
		||||
                           NULL);
 | 
			
		||||
 | 
			
		||||
    keyboard = eekboard_context_service_get_keyboard (EEKBOARD_CONTEXT_SERVICE(context));
 | 
			
		||||
 | 
			
		||||
    context->widget = eek_gtk_keyboard_new (keyboard);
 | 
			
		||||
 | 
			
		||||
    eek_gtk_keyboard_set_theme (EEK_GTK_KEYBOARD(context->widget), theme);
 | 
			
		||||
    g_clear_object (&theme);
 | 
			
		||||
 | 
			
		||||
    gtk_widget_set_has_tooltip (context->widget, TRUE);
 | 
			
		||||
    gtk_container_add (GTK_CONTAINER(context->window), context->widget);
 | 
			
		||||
    gtk_widget_show (context->widget);
 | 
			
		||||
@ -252,8 +257,12 @@ server_context_service_real_show_keyboard (EekboardContextService *_context)
 | 
			
		||||
 | 
			
		||||
    if (!context->window)
 | 
			
		||||
        make_window (context);
 | 
			
		||||
    if (!context->widget)
 | 
			
		||||
        make_widget (context);
 | 
			
		||||
    if (context->widget) {
 | 
			
		||||
        gtk_widget_destroy(context->widget);
 | 
			
		||||
        context->widget = NULL;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    make_widget (context);
 | 
			
		||||
 | 
			
		||||
    EEKBOARD_CONTEXT_SERVICE_CLASS (server_context_service_parent_class)->
 | 
			
		||||
        show_keyboard (_context);
 | 
			
		||||
 | 
			
		||||
@ -19,8 +19,6 @@
 | 
			
		||||
 */
 | 
			
		||||
#include "eek/eek.h"
 | 
			
		||||
 | 
			
		||||
#include <gtk/gtk.h>
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
test_create (void)
 | 
			
		||||
{
 | 
			
		||||
@ -32,9 +30,9 @@ test_create (void)
 | 
			
		||||
    section = eek_keyboard_create_section (keyboard);
 | 
			
		||||
    g_assert (EEK_IS_SECTION(section));
 | 
			
		||||
    eek_section_add_row (section, 2, EEK_ORIENTATION_HORIZONTAL);
 | 
			
		||||
    key0 = eek_section_create_key (section, "key0", 1);
 | 
			
		||||
    key0 = eek_section_create_key (section, "key0", 1, 0, 0);
 | 
			
		||||
    g_assert (EEK_IS_KEY(key0));
 | 
			
		||||
    key1 = eek_section_create_key (section, "key1", 2);
 | 
			
		||||
    key1 = eek_section_create_key (section, "key1", 2, 1, 0);
 | 
			
		||||
    g_assert (EEK_IS_KEY(key1));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -24,7 +24,6 @@
 | 
			
		||||
#include "config.h"
 | 
			
		||||
 | 
			
		||||
#include "eek/eek.h"
 | 
			
		||||
#include "eek/eek-xml-layout.h"
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
test_output_parse (void)
 | 
			
		||||
@ -48,6 +47,7 @@ int
 | 
			
		||||
main (int argc, char **argv)
 | 
			
		||||
{
 | 
			
		||||
    g_test_init (&argc, &argv, NULL);
 | 
			
		||||
    gtk_init (&argc, &argv);  /* for gdk_x11_display_get_xdisplay() */
 | 
			
		||||
 | 
			
		||||
    g_test_add_func ("/eek-xml-test/output-parse", test_output_parse);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -21,8 +21,7 @@ test_link_args = [
 | 
			
		||||
 | 
			
		||||
tests = [
 | 
			
		||||
  'eek-simple-test',
 | 
			
		||||
  'eek-xml-test',
 | 
			
		||||
  'test-keymap-generation'
 | 
			
		||||
  'eek-xml-test'
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
foreach name : tests
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										181
									
								
								tests/test-keyboard.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										181
									
								
								tests/test-keyboard.xml
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,181 @@
 | 
			
		||||
<?xml version="1.0"?>
 | 
			
		||||
<keyboard version="0.90">
 | 
			
		||||
    <bounds>0.000000,0.000000,124.000000,149.000000</bounds>
 | 
			
		||||
    <section name="Keypad">
 | 
			
		||||
        <bounds>10.000000,10.000000,104.000000,129.000000</bounds>
 | 
			
		||||
        <angle>0</angle>
 | 
			
		||||
        <row>
 | 
			
		||||
            <columns>4</columns>
 | 
			
		||||
            <orientation>1</orientation>
 | 
			
		||||
        </row>
 | 
			
		||||
        <row>
 | 
			
		||||
            <columns>4</columns>
 | 
			
		||||
            <orientation>1</orientation>
 | 
			
		||||
        </row>
 | 
			
		||||
        <row>
 | 
			
		||||
            <columns>3</columns>
 | 
			
		||||
            <orientation>1</orientation>
 | 
			
		||||
        </row>
 | 
			
		||||
        <row>
 | 
			
		||||
            <columns>4</columns>
 | 
			
		||||
            <orientation>1</orientation>
 | 
			
		||||
        </row>
 | 
			
		||||
        <row>
 | 
			
		||||
            <columns>2</columns>
 | 
			
		||||
            <orientation>1</orientation>
 | 
			
		||||
        </row>
 | 
			
		||||
        <key id="keycode91" name="KPDL" column="1" row="4">
 | 
			
		||||
            <bounds>54.000000,104.000000,24.000000,24.000000</bounds>
 | 
			
		||||
            <outline-ref>outline0</outline-ref>
 | 
			
		||||
            <symbols groups="1" levels="2">
 | 
			
		||||
                <keysym keyval="65439">KP_Delete</keysym>
 | 
			
		||||
                <keysym keyval="65454">KP_Decimal</keysym>
 | 
			
		||||
            </symbols>
 | 
			
		||||
        </key>
 | 
			
		||||
        <key id="keycode90" name="KP0" column="0" row="4">
 | 
			
		||||
            <bounds>2.000000,104.000000,50.000000,24.000000</bounds>
 | 
			
		||||
            <outline-ref>outline1</outline-ref>
 | 
			
		||||
            <symbols groups="1" levels="2">
 | 
			
		||||
                <keysym keyval="65438">KP_Insert</keysym>
 | 
			
		||||
                <keysym keyval="65456">KP_0</keysym>
 | 
			
		||||
            </symbols>
 | 
			
		||||
        </key>
 | 
			
		||||
        <key id="keycode108" name="KPEN" column="3" row="3">
 | 
			
		||||
            <bounds>80.000000,78.000000,24.000000,50.000000</bounds>
 | 
			
		||||
            <outline-ref>outline2</outline-ref>
 | 
			
		||||
            <symbols groups="1" levels="1">
 | 
			
		||||
                <keysym keyval="65421">KP_Enter</keysym>
 | 
			
		||||
            </symbols>
 | 
			
		||||
        </key>
 | 
			
		||||
        <key id="keycode89" name="KP3" column="2" row="3">
 | 
			
		||||
            <bounds>54.000000,78.000000,24.000000,24.000000</bounds>
 | 
			
		||||
            <outline-ref>outline0</outline-ref>
 | 
			
		||||
            <symbols groups="1" levels="2">
 | 
			
		||||
                <keysym keyval="65435">KP_Next</keysym>
 | 
			
		||||
                <keysym keyval="65459">KP_3</keysym>
 | 
			
		||||
            </symbols>
 | 
			
		||||
        </key>
 | 
			
		||||
        <key id="keycode88" name="KP2" column="1" row="3">
 | 
			
		||||
            <bounds>28.000000,78.000000,24.000000,24.000000</bounds>
 | 
			
		||||
            <outline-ref>outline0</outline-ref>
 | 
			
		||||
            <symbols groups="1" levels="2">
 | 
			
		||||
                <keysym keyval="65433">KP_Down</keysym>
 | 
			
		||||
                <keysym keyval="65458">KP_2</keysym>
 | 
			
		||||
            </symbols>
 | 
			
		||||
        </key>
 | 
			
		||||
        <key id="keycode87" name="KP1" column="0" row="3">
 | 
			
		||||
            <bounds>2.000000,78.000000,24.000000,24.000000</bounds>
 | 
			
		||||
            <outline-ref>outline0</outline-ref>
 | 
			
		||||
            <symbols groups="1" levels="2">
 | 
			
		||||
                <keysym keyval="65436">KP_End</keysym>
 | 
			
		||||
                <keysym keyval="65457">KP_1</keysym>
 | 
			
		||||
            </symbols>
 | 
			
		||||
        </key>
 | 
			
		||||
        <key id="keycode85" name="KP6" column="2" row="2">
 | 
			
		||||
            <bounds>54.000000,53.000000,24.000000,24.000000</bounds>
 | 
			
		||||
            <outline-ref>outline0</outline-ref>
 | 
			
		||||
            <symbols groups="1" levels="2">
 | 
			
		||||
                <keysym keyval="65432">KP_Right</keysym>
 | 
			
		||||
                <keysym keyval="65462">KP_6</keysym>
 | 
			
		||||
            </symbols>
 | 
			
		||||
        </key>
 | 
			
		||||
        <key id="keycode84" name="KP5" column="1" row="2">
 | 
			
		||||
            <bounds>28.000000,53.000000,24.000000,24.000000</bounds>
 | 
			
		||||
            <outline-ref>outline0</outline-ref>
 | 
			
		||||
            <symbols groups="1" levels="2">
 | 
			
		||||
                <keysym keyval="65437">KP_Begin</keysym>
 | 
			
		||||
                <keysym keyval="65461">KP_5</keysym>
 | 
			
		||||
            </symbols>
 | 
			
		||||
        </key>
 | 
			
		||||
        <key id="keycode83" name="KP4" column="0" row="2">
 | 
			
		||||
            <bounds>2.000000,53.000000,24.000000,24.000000</bounds>
 | 
			
		||||
            <outline-ref>outline0</outline-ref>
 | 
			
		||||
            <symbols groups="1" levels="2">
 | 
			
		||||
                <keysym keyval="65430">KP_Left</keysym>
 | 
			
		||||
                <keysym keyval="65460">KP_4</keysym>
 | 
			
		||||
            </symbols>
 | 
			
		||||
        </key>
 | 
			
		||||
        <key id="keycode86" name="KPAD" column="3" row="1">
 | 
			
		||||
            <bounds>80.000000,27.000000,24.000000,50.000000</bounds>
 | 
			
		||||
            <outline-ref>outline2</outline-ref>
 | 
			
		||||
            <symbols groups="1" levels="2">
 | 
			
		||||
                <keysym keyval="65451">KP_Add</keysym>
 | 
			
		||||
                <keysym keyval="269024802"></keysym>
 | 
			
		||||
            </symbols>
 | 
			
		||||
        </key>
 | 
			
		||||
        <key id="keycode81" name="KP9" column="2" row="1">
 | 
			
		||||
            <bounds>54.000000,27.000000,24.000000,24.000000</bounds>
 | 
			
		||||
            <outline-ref>outline0</outline-ref>
 | 
			
		||||
            <symbols groups="1" levels="2">
 | 
			
		||||
                <keysym keyval="65434">KP_Prior</keysym>
 | 
			
		||||
                <keysym keyval="65465">KP_9</keysym>
 | 
			
		||||
            </symbols>
 | 
			
		||||
        </key>
 | 
			
		||||
        <key id="keycode80" name="KP8" column="1" row="1">
 | 
			
		||||
            <bounds>28.000000,27.000000,24.000000,24.000000</bounds>
 | 
			
		||||
            <outline-ref>outline0</outline-ref>
 | 
			
		||||
            <symbols groups="1" levels="2">
 | 
			
		||||
                <keysym keyval="65431">KP_Up</keysym>
 | 
			
		||||
                <keysym keyval="65464">KP_8</keysym>
 | 
			
		||||
            </symbols>
 | 
			
		||||
        </key>
 | 
			
		||||
        <key id="keycode79" name="KP7" column="0" row="1">
 | 
			
		||||
            <bounds>2.000000,27.000000,24.000000,24.000000</bounds>
 | 
			
		||||
            <outline-ref>outline0</outline-ref>
 | 
			
		||||
            <symbols groups="1" levels="2">
 | 
			
		||||
                <keysym keyval="65429">KP_Home</keysym>
 | 
			
		||||
                <keysym keyval="65463">KP_7</keysym>
 | 
			
		||||
            </symbols>
 | 
			
		||||
        </key>
 | 
			
		||||
        <key id="keycode82" name="KPSU" column="3" row="0">
 | 
			
		||||
            <bounds>80.000000,1.000000,24.000000,24.000000</bounds>
 | 
			
		||||
            <outline-ref>outline0</outline-ref>
 | 
			
		||||
            <symbols groups="1" levels="2">
 | 
			
		||||
                <keysym keyval="65453">KP_Subtract</keysym>
 | 
			
		||||
                <keysym keyval="269024803"></keysym>
 | 
			
		||||
            </symbols>
 | 
			
		||||
        </key>
 | 
			
		||||
        <key id="keycode63" name="KPMU" column="2" row="0">
 | 
			
		||||
            <bounds>54.000000,1.000000,24.000000,24.000000</bounds>
 | 
			
		||||
            <outline-ref>outline0</outline-ref>
 | 
			
		||||
            <symbols groups="1" levels="2">
 | 
			
		||||
                <keysym keyval="65450">KP_Multiply</keysym>
 | 
			
		||||
                <keysym keyval="269024801"></keysym>
 | 
			
		||||
            </symbols>
 | 
			
		||||
        </key>
 | 
			
		||||
        <key id="keycode112" name="KPDV" column="1" row="0">
 | 
			
		||||
            <bounds>28.000000,1.000000,24.000000,24.000000</bounds>
 | 
			
		||||
            <outline-ref>outline0</outline-ref>
 | 
			
		||||
            <symbols groups="1" levels="2">
 | 
			
		||||
                <keysym keyval="65455">KP_Divide</keysym>
 | 
			
		||||
                <keysym keyval="269024800"></keysym>
 | 
			
		||||
            </symbols>
 | 
			
		||||
        </key>
 | 
			
		||||
        <key id="keycode77" name="NMLK" column="0" row="0">
 | 
			
		||||
            <bounds>2.000000,1.000000,24.000000,24.000000</bounds>
 | 
			
		||||
            <outline-ref>outline0</outline-ref>
 | 
			
		||||
            <symbols groups="1" levels="2">
 | 
			
		||||
                <keysym keyval="65407">Num_Lock</keysym>
 | 
			
		||||
                <keysym keyval="65273">Pointer_EnableKeys</keysym>
 | 
			
		||||
            </symbols>
 | 
			
		||||
        </key>
 | 
			
		||||
    </section>
 | 
			
		||||
    <outline id="outline0">
 | 
			
		||||
        <point>0.000000,0.000000</point>
 | 
			
		||||
        <point>24.000000,0.000000</point>
 | 
			
		||||
        <point>24.000000,24.000000</point>
 | 
			
		||||
        <point>0.000000,24.000000</point>
 | 
			
		||||
    </outline>
 | 
			
		||||
    <outline id="outline1">
 | 
			
		||||
        <point>0.000000,0.000000</point>
 | 
			
		||||
        <point>50.000000,0.000000</point>
 | 
			
		||||
        <point>50.000000,24.000000</point>
 | 
			
		||||
        <point>0.000000,24.000000</point>
 | 
			
		||||
    </outline>
 | 
			
		||||
    <outline id="outline2">
 | 
			
		||||
        <point>0.000000,0.000000</point>
 | 
			
		||||
        <point>24.000000,0.000000</point>
 | 
			
		||||
        <point>24.000000,50.000000</point>
 | 
			
		||||
        <point>0.000000,50.000000</point>
 | 
			
		||||
    </outline>
 | 
			
		||||
</keyboard>
 | 
			
		||||
@ -1,72 +0,0 @@
 | 
			
		||||
/* 
 | 
			
		||||
 * Copyright (C) 2010-2011 Daiki Ueno <ueno@unixuser.org>
 | 
			
		||||
 * Copyright (C) 2010-2011 Red Hat, Inc.
 | 
			
		||||
 * Copyright (C) 2019 Purism SPC
 | 
			
		||||
 * 
 | 
			
		||||
 * This library is free software; you can redistribute it and/or
 | 
			
		||||
 * modify it under the terms of the GNU Lesser General Public License
 | 
			
		||||
 * as published by the Free Software Foundation; either version 2 of
 | 
			
		||||
 * the License, or (at your option) any later version.
 | 
			
		||||
 * 
 | 
			
		||||
 * This library is distributed in the hope that it will be useful, but
 | 
			
		||||
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
			
		||||
 * Lesser General Public License for more details.
 | 
			
		||||
 * 
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General Public
 | 
			
		||||
 * License along with this library; if not, write to the Free Software
 | 
			
		||||
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 | 
			
		||||
 * 02110-1301 USA
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/* For gdk_x11_display_get_xdisplay().  See main(). */
 | 
			
		||||
#include <gtk/gtk.h>
 | 
			
		||||
#include <xkbcommon/xkbcommon.h>
 | 
			
		||||
 | 
			
		||||
#include "config.h"
 | 
			
		||||
 | 
			
		||||
#include "eek/eek.h"
 | 
			
		||||
#include "eek/eek-xml-layout.h"
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
test_check_xkb (void)
 | 
			
		||||
{
 | 
			
		||||
    EekLayout *layout;
 | 
			
		||||
    EekKeyboard *keyboard;
 | 
			
		||||
    GError *error;
 | 
			
		||||
 | 
			
		||||
    error = NULL;
 | 
			
		||||
    layout = eek_xml_layout_new ("us", &error);
 | 
			
		||||
    g_assert_no_error (error);
 | 
			
		||||
 | 
			
		||||
    keyboard = eek_keyboard_new (NULL, layout, 640, 480);
 | 
			
		||||
    gchar *keymap_str = eek_keyboard_get_keymap(keyboard);
 | 
			
		||||
 | 
			
		||||
    struct xkb_context *context = xkb_context_new(XKB_CONTEXT_NO_FLAGS);
 | 
			
		||||
    if (!context) {
 | 
			
		||||
        g_error("No context created");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    struct xkb_keymap *keymap = xkb_keymap_new_from_string(context, keymap_str,
 | 
			
		||||
        XKB_KEYMAP_FORMAT_TEXT_V1, XKB_KEYMAP_COMPILE_NO_FLAGS);
 | 
			
		||||
 | 
			
		||||
    free(keymap_str);
 | 
			
		||||
 | 
			
		||||
    xkb_context_unref(context);
 | 
			
		||||
    if (!keymap) {
 | 
			
		||||
        g_error("Bad keymap");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    g_object_unref (layout);
 | 
			
		||||
    g_object_unref (keyboard);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
main (int argc, char **argv)
 | 
			
		||||
{
 | 
			
		||||
    g_test_init (&argc, &argv, NULL);
 | 
			
		||||
 | 
			
		||||
    g_test_add_func ("/test-keymap-generation/check-xkb", test_check_xkb);
 | 
			
		||||
 | 
			
		||||
    return g_test_run ();
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user