Compare commits

..

7 Commits

Author SHA1 Message Date
2c355ec966 Resolve diverged APIs to keep string input working 2019-08-05 17:37:08 +00:00
a19bbdc870 Remove unused assignment 2019-08-05 14:36:50 +00:00
8e0b4f05f8 Don't check for touches on hidden keys 2019-08-05 14:36:50 +00:00
1010b916ef Tidy up keymap generation, add bounds check 2019-08-05 14:36:50 +00:00
c475ed6619 Add checks for new purposes 2019-08-05 14:36:50 +00:00
687b260e29 Add keyboard information for new purposes 2019-08-05 14:36:50 +00:00
ecc46733da Add an initial URL keyboard and support for text macros
Text associated with a symbol on a key is sent using the keymap
associated with each keyboard, so the individual symbols need to be
defined in order to be usable in a text macro.
2019-08-05 14:36:50 +00:00
69 changed files with 6863 additions and 2630 deletions

View File

@ -1,8 +1,57 @@
<?xml version="1.0"?>
<geometry version="0.90">
<bounds x="10" y="10" width="410.0000" height="229"/>
<outline id="default" corner-radius="1.000000">
<section angle="0">
<row orientation="1">
<key name="AD01" oref="outline2" />
<key name="AD02" oref="outline2" />
<key name="AD03" oref="outline2" />
<key name="AD04" oref="outline2" />
<key name="AD05" oref="outline2" />
<key name="AD06" oref="outline2" />
<key name="AD07" oref="outline2" />
<key name="AD08" oref="outline2" />
<key name="AD09" oref="outline2" />
<key name="AD10" oref="outline2" />
</row>
</section>
<section angle="0">
<row orientation="1">
<key name="AC01" oref="outline2" />
<key name="AC02" oref="outline2" />
<key name="AC03" oref="outline2" />
<key name="AC04" oref="outline2" />
<key name="AC05" oref="outline2" />
<key name="AC06" oref="outline2" />
<key name="AC07" oref="outline2" />
<key name="AC08" oref="outline2" />
<key name="AC09" oref="outline2" />
<key name="AC10" oref="outline2" />
</row>
</section>
<section angle="0">
<row orientation="1">
<key name="LFSH" oref="altline" />
<key name="AB01" oref="outline2" />
<key name="AB02" oref="outline2" />
<key name="AB03" oref="outline2" />
<key name="AB04" oref="outline2" />
<key name="AB05" oref="outline2" />
<key name="AB06" oref="outline2" />
<key name="AB07" oref="outline2" />
<key name="BKSP" oref="altline" />
</row>
</section>
<section angle="0">
<row orientation="1">
<key keycode="0" name="ABC123" oref="altline" />
<key name="I149" oref="altline" />
<key name="SPCE" oref="spaceline" />
<key name="AB08" oref="outline2" />
<key name="RTRN" oref="outline7" />
</row>
</section>
<outline id="outline2" corner-radius="1.000000">
<point x="0.000000" y="0.000000"/>
<point x="37.46341" y="0.000000"/>
<point x="37.46341" y="52"/>
@ -14,51 +63,58 @@
<point x="48.39024" y="52"/>
<point x="0.000000" y="52"/>
</outline>
<outline id="outline4" corner-radius="1.000000">
<point x="0.000000" y="0.000000"/>
<point x="59.31707" y="0.000000"/>
<point x="59.31707" y="52"/>
<point x="0.000000" y="52"/>
</outline>
<outline id="outline5" corner-radius="1.000000">
<point x="0.000000" y="0.000000"/>
<point x="59.31707" y="0.000000"/>
<point x="59.31707" y="52"/>
<point x="0.000000" y="52"/>
</outline>
<outline id="outline6" corner-radius="1.000000">
<point x="0.000000" y="0.000000"/>
<point x="68.68292" y="0.000000"/>
<point x="68.68292" y="52"/>
<point x="0.000000" y="52"/>
</outline>
<outline id="outline7" corner-radius="1.000000">
<point x="0.000000" y="0.000000"/>
<point x="88.97561" y="0.000000"/>
<point x="88.97561" y="52"/>
<point x="0.000000" y="52"/>
</outline>
<outline id="outline8" corner-radius="1.000000">
<point x="0.000000" y="0.000000"/>
<point x="88.97561" y="0.000000"/>
<point x="88.97561" y="52"/>
<point x="0.000000" y="52"/>
</outline>
<outline id="outline9" corner-radius="1.000000">
<point x="0.000000" y="0.000000"/>
<point x="109.2682" y="0.000000"/>
<point x="109.2682" y="52"/>
<point x="0.000000" y="52"/>
</outline>
<outline id="outline10" corner-radius="1.000000">
<point x="0.000000" y="0.000000"/>
<point x="37.46341" y="0.000000"/>
<point x="37.46341" y="52"/>
<point x="0.000000" y="52"/>
</outline>
<outline id="outline13" corner-radius="1.000000">
<point x="0.000000" y="0.000000"/>
<point x="79.60975" y="0.000000"/>
<point x="79.60975" y="52"/>
<point x="0.000000" y="52"/>
</outline>
<outline id="spaceline" corner-radius="1.000000">
<point x="0.000000" y="0.000000"/>
<point x="150.5853" y="0.000000"/>
<point x="150.5853" y="52"/>
<point x="0.000000" y="52"/>
</outline>
<button name="Shift_L" oref="altline" />
<button name="BackSpace" oref="altline" />
<button name="preferences" oref="altline" />
<button name="show_numbers" oref="altline" keycode="0" />
<button name="show_letters" oref="altline" keycode="0" />
<button name="show_symbols" oref="altline" keycode="0" />
<button name="period" oref="altline" />
<button name="space" oref="spaceline" />
<button name="Return" oref="outline7" />
<view>
<section angle="0">q w e r t y u i o p</section>
<section angle="0">a s d f g h j k l</section>
<section angle="0"> Shift_L z x c v b n m BackSpace </section>
<section angle="0"> show_numbers preferences space period Return </section>
</view>
<view>
<section angle="0">Q W E R T Y U I O P</section>
<section angle="0">A S D F G H J K L</section>
<section angle="0"> Shift_L Z X C V B N M BackSpace </section>
<section angle="0"> show_numbers preferences space period Return </section>
</view>
<view>
<section angle="0">1 2 3 4 5 6 7 8 9 0</section>
<section angle="0">at numbersign dollar percent ampersand minus underscore plus parenleft parenright</section>
<section angle="0"> show_symbols comma quotedbl quoteright colon semicolon exclam question BackSpace </section>
<section angle="0"> show_letters preferences space period Return </section>
</view>
<view>
<section angle="0">asciitilde quoteleft bar U00B7 squareroot Greek_pi Greek_tau division multiply paragraph</section>
<section angle="0">copyright U00AE U00A3 EuroSign U00A5 asciicircum degree asterisk braceleft braceright</section>
<section angle="0"> show_numbers backslash slash less greater equal bracketleft bracketright BackSpace </section>
<section angle="0"> show_letters preferences space period Return </section>
</view>
</geometry>

View File

@ -0,0 +1,98 @@
<?xml version="1.0"?>
<geometry version="0.90">
<bounds x="0" y="10.000000" width="426.0000" height="296.5853"/>
<section angle="0">
<row orientation="1">
<key name="AD01" oref="outline4" />
<key name="AD02" oref="outline4" />
<key name="AD03" oref="outline4" />
</row>
</section>
<section angle="0">
<row orientation="1">
<key name="AC01" oref="outline4" />
<key name="AC02" oref="outline4" />
<key name="AC03" oref="outline4" />
</row>
</section>
<section angle="0">
<row orientation="1">
<key name="AB01" oref="outline4" />
<key name="AB02" oref="outline4" />
<key name="AB03" oref="outline4" />
</row>
</section>
<section angle="0">
<row orientation="1">
<key name="BKSP" oref="altline" />
<key name="AB04" oref="outline4" />
<key name="RTRN" oref="altline" />
</row>
</section>
<outline id="outline2" corner-radius="1.000000">
<point x="0.000000" y="0.000000"/>
<point x="37.46341" y="0.000000"/>
<point x="37.46341" y="52.44877"/>
<point x="0.000000" y="52.44877"/>
</outline>
<outline id="altline" corner-radius="1.000000">
<point x="0.000000" y="0.000000"/>
<point x="48.39024" y="0.000000"/>
<point x="48.39024" y="52.44877"/>
<point x="0.000000" y="52.44877"/>
</outline>
<outline id="outline4" corner-radius="1.000000">
<point x="0.000000" y="0.000000"/>
<point x="59.31707" y="0.000000"/>
<point x="59.31707" y="52.44877"/>
<point x="0.000000" y="52.44877"/>
</outline>
<outline id="outline5" corner-radius="1.000000">
<point x="0.000000" y="0.000000"/>
<point x="59.31707" y="0.000000"/>
<point x="59.31707" y="52.44877"/>
<point x="0.000000" y="52.44877"/>
</outline>
<outline id="outline6" corner-radius="1.000000">
<point x="0.000000" y="0.000000"/>
<point x="68.68292" y="0.000000"/>
<point x="68.68292" y="52.44877"/>
<point x="0.000000" y="52.44877"/>
</outline>
<outline id="outline7" corner-radius="1.000000">
<point x="0.000000" y="0.000000"/>
<point x="88.97561" y="0.000000"/>
<point x="88.97561" y="52.44877"/>
<point x="0.000000" y="52.44877"/>
</outline>
<outline id="outline8" corner-radius="1.000000">
<point x="0.000000" y="0.000000"/>
<point x="88.97561" y="0.000000"/>
<point x="88.97561" y="52.44877"/>
<point x="0.000000" y="52.44877"/>
</outline>
<outline id="outline9" corner-radius="1.000000">
<point x="0.000000" y="0.000000"/>
<point x="109.2682" y="0.000000"/>
<point x="109.2682" y="52.44877"/>
<point x="0.000000" y="52.44877"/>
</outline>
<outline id="outline10" corner-radius="1.000000">
<point x="0.000000" y="0.000000"/>
<point x="37.46341" y="0.000000"/>
<point x="37.46341" y="52.44877"/>
<point x="0.000000" y="52.44877"/>
</outline>
<outline id="outline13" corner-radius="1.000000">
<point x="0.000000" y="0.000000"/>
<point x="79.60975" y="0.000000"/>
<point x="79.60975" y="52.44877"/>
<point x="0.000000" y="52.44877"/>
</outline>
<outline id="spaceline" corner-radius="1.000000">
<point x="0.000000" y="0.000000"/>
<point x="120.5853" y="0.000000"/>
<point x="120.5853" y="52.44877"/>
<point x="0.000000" y="52.44877"/>
</outline>
</geometry>

View File

@ -1,7 +1,58 @@
<?xml version="1.0"?>
<geometry version="0.90">
<bounds x="0" y="10.000000" width="426.0000" height="296.5853"/>
<section angle="0">
<row orientation="1">
<key name="AD01" oref="outline2" />
<key name="AD02" oref="outline2" />
<key name="AD03" oref="outline2" />
<key name="AD04" oref="outline2" />
<key name="AD05" oref="outline2" />
<key name="AD06" oref="outline2" />
<key name="AD07" oref="outline2" />
<key name="AD08" oref="outline2" />
<key name="AD09" oref="outline2" />
<key name="AD10" oref="outline2" />
<key name="AD11" oref="outline2" />
</row>
</section>
<section angle="0">
<row orientation="1">
<key name="AC01" oref="outline2" />
<key name="AC02" oref="outline2" />
<key name="AC03" oref="outline2" />
<key name="AC04" oref="outline2" />
<key name="AC05" oref="outline2" />
<key name="AC06" oref="outline2" />
<key name="AC07" oref="outline2" />
<key name="AC08" oref="outline2" />
<key name="AC09" oref="outline2" />
<key name="AC10" oref="outline2" />
<key name="AC11" oref="outline2" />
</row>
</section>
<section angle="0">
<row orientation="1">
<key name="LFSH" oref="altline" />
<key name="AB01" oref="outline2" />
<key name="AB02" oref="outline2" />
<key name="AB03" oref="outline2" />
<key name="AB04" oref="outline2" />
<key name="AB05" oref="outline2" />
<key name="AB06" oref="outline2" />
<key name="AB07" oref="outline2" />
<key name="BKSP" oref="altline" />
</row>
</section>
<section angle="0">
<row orientation="1">
<key keycode="0" name="ABC123" oref="altline" />
<key name="I149" oref="altline" />
<key name="SPCE" oref="spaceline" />
<key name="AB08" oref="outline2" />
<key name="RTRN" oref="outline7" />
</row>
</section>
<outline id="outline2" corner-radius="1.000000">
<point x="0.000000" y="0.000000"/>
<point x="32" y="0.000000"/>
@ -68,38 +119,4 @@
<point x="150.5853" y="52"/>
<point x="0.000000" y="52"/>
</outline>
<button name="Shift_L" oref="altline" />
<button name="BackSpace" oref="altline" />
<button name="preferences" oref="altline" />
<button name="show_numbers" oref="altline" keycode="0" />
<button name="show_letters" oref="altline" keycode="0" />
<button name="show_symbols" oref="altline" keycode="0" />
<button name="space" oref="spaceline" />
<button name="return" oref="outline7" />
<view>
<section angle="0">q w e r t y u i o p aring</section>
<section angle="0">a s d f g h j k l oslash ae</section>
<section angle="0"> Shift_L z x c v b n m BackSpace </section>
<section angle="0"> show_numbers preferences space period Return </section>
</view>
<view>
<section angle="0">Q W E R T Y U I O P Aring</section>
<section angle="0">A S D F G H J K L Oslash AE</section>
<section angle="0"> Shift_L Z X C V B N M BackSpace </section>
<section angle="0"> show_numbers preferences space period Return </section>
</view>
<view>
<section angle="0">1 2 3 4 5 6 7 8 9 0</section>
<section angle="0">at numbersign dollar percent ampersand minus underscore plus parenleft parenright</section>
<section angle="0"> show_symbols comma quotedbl quoteright colon semicolon exclam question BackSpace </section>
<section angle="0"> show_letters preferences space period Return </section>
</view>
<view>
<section angle="0">asciitilde quoteleft bar U00B7 squareroot Greek_pi Greek_tau division multiply paragraph</section>
<section angle="0">copyright U00AE U00A3 EuroSign U00A5 asciicircum degree asterisk braceleft braceright</section>
<section angle="0"> show_numbers backslash slash less greater equal bracketleft bracketright BackSpace </section>
<section angle="0"> show_letters preferences space period Return </section>
</view>
</geometry>

View File

@ -1,8 +1,42 @@
<?xml version="1.0"?>
<geometry version="0.90">
<bounds x="0" y="10.000000" width="426.0000" height="296.5853"/>
<outline id="default" corner-radius="1.000000">
<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"/>
@ -14,27 +48,58 @@
<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>
<button name="BackSpace" oref="altline" />
<button name="space" oref="spaceline" />
<button name="Return" oref="outline7" />
<view>
<section angle="0">1 2 3 parenleft parenright</section>
<section angle="0">4 5 6 numbersign asterisk</section>
<section angle="0">7 8 9 plus minus</section>
<section angle="0">BackSpace 0 space Return</section>
</view>
</geometry>

View File

@ -0,0 +1,105 @@
<?xml version="1.0"?>
<geometry version="0.90">
<bounds x="0" y="10.000000" width="426.0000" height="296.5853"/>
<section angle="0">
<row orientation="1">
<key name="AD01" oref="outline2" />
<key name="AD02" oref="outline2" />
<key name="AD03" oref="outline2" />
<key name="AD04" oref="outline2" />
<key name="AD05" oref="outline2" />
</row>
</section>
<section angle="0">
<row orientation="1">
<key name="AC01" oref="outline2" />
<key name="AC02" oref="outline2" />
<key name="AC03" oref="outline2" />
<key name="AC04" oref="outline2" />
<key name="AC05" oref="outline2" />
</row>
</section>
<section angle="0">
<row orientation="1">
<key name="AB01" oref="outline2" />
<key name="AB02" oref="outline2" />
<key name="AB03" oref="outline2" />
<key name="AB04" oref="outline2" />
<key name="AB05" oref="outline2" />
</row>
</section>
<section angle="0">
<row orientation="1">
<key name="BKSP" oref="altline" />
<key name="AB06" oref="outline2" />
<key name="SPCE" oref="spaceline" />
<key name="RTRN" oref="outline7" />
</row>
</section>
<outline id="outline2" corner-radius="1.000000">
<point x="0.000000" y="0.000000"/>
<point x="37.46341" y="0.000000"/>
<point x="37.46341" y="52.44877"/>
<point x="0.000000" y="52.44877"/>
</outline>
<outline id="altline" corner-radius="1.000000">
<point x="0.000000" y="0.000000"/>
<point x="48.39024" y="0.000000"/>
<point x="48.39024" y="52.44877"/>
<point x="0.000000" y="52.44877"/>
</outline>
<outline id="outline4" corner-radius="1.000000">
<point x="0.000000" y="0.000000"/>
<point x="59.31707" y="0.000000"/>
<point x="59.31707" y="52.44877"/>
<point x="0.000000" y="52.44877"/>
</outline>
<outline id="outline5" corner-radius="1.000000">
<point x="0.000000" y="0.000000"/>
<point x="59.31707" y="0.000000"/>
<point x="59.31707" y="52.44877"/>
<point x="0.000000" y="52.44877"/>
</outline>
<outline id="outline6" corner-radius="1.000000">
<point x="0.000000" y="0.000000"/>
<point x="68.68292" y="0.000000"/>
<point x="68.68292" y="52.44877"/>
<point x="0.000000" y="52.44877"/>
</outline>
<outline id="outline7" corner-radius="1.000000">
<point x="0.000000" y="0.000000"/>
<point x="88.97561" y="0.000000"/>
<point x="88.97561" y="52.44877"/>
<point x="0.000000" y="52.44877"/>
</outline>
<outline id="outline8" corner-radius="1.000000">
<point x="0.000000" y="0.000000"/>
<point x="88.97561" y="0.000000"/>
<point x="88.97561" y="52.44877"/>
<point x="0.000000" y="52.44877"/>
</outline>
<outline id="outline9" corner-radius="1.000000">
<point x="0.000000" y="0.000000"/>
<point x="109.2682" y="0.000000"/>
<point x="109.2682" y="52.44877"/>
<point x="0.000000" y="52.44877"/>
</outline>
<outline id="outline10" corner-radius="1.000000">
<point x="0.000000" y="0.000000"/>
<point x="37.46341" y="0.000000"/>
<point x="37.46341" y="52.44877"/>
<point x="0.000000" y="52.44877"/>
</outline>
<outline id="outline13" corner-radius="1.000000">
<point x="0.000000" y="0.000000"/>
<point x="79.60975" y="0.000000"/>
<point x="79.60975" y="52.44877"/>
<point x="0.000000" y="52.44877"/>
</outline>
<outline id="spaceline" corner-radius="1.000000">
<point x="0.000000" y="0.000000"/>
<point x="120.5853" y="0.000000"/>
<point x="120.5853" y="52.44877"/>
<point x="0.000000" y="52.44877"/>
</outline>
</geometry>

View File

@ -0,0 +1,126 @@
<?xml version="1.0"?>
<geometry version="0.90">
<bounds x="0" y="10.000000" width="426.0000" height="296.5853"/>
<section angle="0">
<row orientation="1">
<key name="AD01" oref="outline2" />
<key name="AD02" oref="outline2" />
<key name="AD03" oref="outline2" />
<key name="AD04" oref="outline2" />
<key name="AD05" oref="outline2" />
<key name="AD06" oref="outline2" />
<key name="AD07" oref="outline2" />
<key name="AD08" oref="outline2" />
<key name="AD09" oref="outline2" />
<key name="AD10" oref="outline2" />
<key name="AE01" oref="outline6" />
<key name="AE02" oref="outline2" />
<key name="AE03" oref="outline6" />
<key name="AE04" oref="outline6" />
<key name="AE05" oref="outline6" />
<key name="AE06" oref="outline6" />
</row>
</section>
<section angle="0">
<row orientation="1">
<key name="AC01" oref="outline2" />
<key name="AC02" oref="outline2" />
<key name="AC03" oref="outline2" />
<key name="AC04" oref="outline2" />
<key name="AC05" oref="outline2" />
<key name="AC06" oref="outline2" />
<key name="AC07" oref="outline2" />
<key name="AC08" oref="outline2" />
<key name="AC09" oref="outline2" />
<key name="AC10" oref="outline2" />
</row>
</section>
<section angle="0">
<row orientation="1">
<key name="LFSH" oref="altline" />
<key name="AB01" oref="outline2" />
<key name="AB02" oref="outline2" />
<key name="AB03" oref="outline2" />
<key name="AB04" oref="outline2" />
<key name="AB05" oref="outline2" />
<key name="AB06" oref="outline2" />
<key name="AB07" oref="outline2" />
<key name="BKSP" oref="altline" />
</row>
</section>
<section angle="0">
<row orientation="1">
<key keycode="0" name="ABC123" oref="altline" />
<key name="I149" oref="altline" />
<key name="SPCE" oref="spaceline" />
<key name="AB08" oref="outline2" />
<key name="RTRN" oref="outline7" />
</row>
</section>
<outline id="outline2" corner-radius="1.000000">
<point x="0.000000" y="0.000000"/>
<point x="37.46341" y="0.000000"/>
<point x="37.46341" y="52.44877"/>
<point x="0.000000" y="52.44877"/>
</outline>
<outline id="altline" corner-radius="1.000000">
<point x="0.000000" y="0.000000"/>
<point x="48.39024" y="0.000000"/>
<point x="48.39024" y="52.44877"/>
<point x="0.000000" y="52.44877"/>
</outline>
<outline id="outline4" corner-radius="1.000000">
<point x="0.000000" y="0.000000"/>
<point x="59.31707" y="0.000000"/>
<point x="59.31707" y="52.44877"/>
<point x="0.000000" y="52.44877"/>
</outline>
<outline id="outline5" corner-radius="1.000000">
<point x="0.000000" y="0.000000"/>
<point x="59.31707" y="0.000000"/>
<point x="59.31707" y="52.44877"/>
<point x="0.000000" y="52.44877"/>
</outline>
<outline id="outline6" corner-radius="1.000000">
<point x="0.000000" y="0.000000"/>
<point x="68.68292" y="0.000000"/>
<point x="68.68292" y="52.44877"/>
<point x="0.000000" y="52.44877"/>
</outline>
<outline id="outline7" corner-radius="1.000000">
<point x="0.000000" y="0.000000"/>
<point x="88.97561" y="0.000000"/>
<point x="88.97561" y="52.44877"/>
<point x="0.000000" y="52.44877"/>
</outline>
<outline id="outline8" corner-radius="1.000000">
<point x="0.000000" y="0.000000"/>
<point x="88.97561" y="0.000000"/>
<point x="88.97561" y="52.44877"/>
<point x="0.000000" y="52.44877"/>
</outline>
<outline id="outline9" corner-radius="1.000000">
<point x="0.000000" y="0.000000"/>
<point x="109.2682" y="0.000000"/>
<point x="109.2682" y="52.44877"/>
<point x="0.000000" y="52.44877"/>
</outline>
<outline id="outline10" corner-radius="1.000000">
<point x="0.000000" y="0.000000"/>
<point x="37.46341" y="0.000000"/>
<point x="37.46341" y="52.44877"/>
<point x="0.000000" y="52.44877"/>
</outline>
<outline id="outline13" corner-radius="1.000000">
<point x="0.000000" y="0.000000"/>
<point x="79.60975" y="0.000000"/>
<point x="79.60975" y="52.44877"/>
<point x="0.000000" y="52.44877"/>
</outline>
<outline id="spaceline" corner-radius="1.000000">
<point x="0.000000" y="0.000000"/>
<point x="150.5853" y="0.000000"/>
<point x="150.5853" y="52.44877"/>
<point x="0.000000" y="52.44877"/>
</outline>
</geometry>

View File

@ -90,11 +90,17 @@
longname="Telugu (Inscript)" language="te"/>
<!-- Common keyboards -->
<keyboard id="digits" name="digits"
geometry="digits" symbols="special/digits"
longname="Digits" language="all"/>
<keyboard id="number" name="number"
geometry="number-keypad" symbols="special/number"
longname="Numeric keypad" language="all"/>
<keyboard id="phone" name="phone"
geometry="number-keypad" symbols="special/number"
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>

View File

@ -1,132 +1,206 @@
<?xml version='1.0' encoding='UTF-8' standalone='yes'?>
<?xml version='1.0' encoding='ASCII' standalone='yes'?>
<symbols version="0.90">
<symbol label="*">asterisk</symbol>
<symbol label="+/=">show_symbols</symbol>
<symbol label="&#964;">Greek_tau</symbol>
<symbol label="å">aring</symbol>
<symbol label="ø">oslash</symbol>
<symbol label="æ">ae</symbol>
<symbol label="Å">Aring</symbol>
<symbol label="Ø">Oslash</symbol>
<symbol label="Æ">AE</symbol>
<symbol label="q">q</symbol>
<symbol label="Q">Q</symbol>
<symbol label="1">1</symbol>
<symbol label="~">asciitilde</symbol>
<symbol label="w">w</symbol>
<symbol label="W">W</symbol>
<symbol label="2">2</symbol>
<symbol label="`">quoteleft</symbol>
<symbol label="e">e</symbol>
<symbol label="E">E</symbol>
<symbol label="3">3</symbol>
<symbol label="|">bar</symbol>
<symbol label="r">r</symbol>
<symbol label="R">R</symbol>
<symbol label="4">4</symbol>
<symbol label="&#183;">U00B7</symbol>
<symbol label="t">t</symbol>
<symbol label="T">T</symbol>
<symbol label="5">5</symbol>
<symbol label="&#8730;">squareroot</symbol>
<symbol label="y">y</symbol>
<symbol label="Y">Y</symbol>
<symbol label="6">6</symbol>
<symbol label="&#960;">Greek_pi</symbol>
<symbol label="u">u</symbol>
<symbol label="U">U</symbol>
<symbol label="7">7</symbol>
<symbol label="&#247;">division</symbol>
<symbol label="i">i</symbol>
<symbol label="I">I</symbol>
<symbol label="8">8</symbol>
<symbol label="&#215;">multiply</symbol>
<symbol label="o">o</symbol>
<symbol label="O">O</symbol>
<symbol label="9">9</symbol>
<symbol label="&#182;">paragraph</symbol>
<symbol label="p">p</symbol>
<symbol label="P">P</symbol>
<symbol label="0">0</symbol>
<symbol label="&#9651;">U25B3</symbol>
<symbol keyval="229" label="&#229;">aring</symbol>
<symbol keyval="197" label="&#197;">Aring</symbol>
<symbol label="a">a</symbol>
<symbol label="A">A</symbol>
<symbol label="@">at</symbol>
<symbol label="&#169;">copyright</symbol>
<symbol label="s">s</symbol>
<symbol label="S">S</symbol>
<symbol label="#">numbersign</symbol>
<symbol label="&#174;">U00AE</symbol>
<symbol label="d">d</symbol>
<symbol label="D">D</symbol>
<symbol label="$">dollar</symbol>
<symbol label="&#163;">U00A3</symbol>
<symbol label="f">f</symbol>
<symbol label="F">F</symbol>
<symbol label="%">percent</symbol>
<symbol label="&#8364;">EuroSign</symbol>
<symbol label="g">g</symbol>
<symbol label="G">G</symbol>
<symbol label="&amp;">ampersand</symbol>
<symbol label="&#165;">U00A5</symbol>
<symbol label="h">h</symbol>
<symbol label="H">H</symbol>
<symbol label="-">minus</symbol>
<symbol label="^">asciicircum</symbol>
<symbol label="j">j</symbol>
<symbol label="J">J</symbol>
<symbol label="_">underscore</symbol>
<symbol label="&#176;">degree</symbol>
<symbol label="k">k</symbol>
<symbol label="K">K</symbol>
<symbol label="+">plus</symbol>
<symbol label="=">equal</symbol>
<symbol label="l">l</symbol>
<symbol label="L">L</symbol>
<symbol label="(">parenleft</symbol>
<symbol label="{">braceleft</symbol>
<symbol keyval="248" label="&#248;">oslash</symbol>
<symbol keyval="216" label="&#216;">Oslash</symbol>
<symbol label=")">parenright</symbol>
<symbol label="}">braceright</symbol>
<symbol keyval="230" label="&#230;">ae</symbol>
<symbol keyval="198" label="&#198;">AE</symbol>
<symbol keyval="65293" icon="key-enter">Return</symbol>
<symbol keyval="65505" icon="key-shift">Shift_L</symbol>
<symbol label="z">z</symbol>
<symbol label="Z">Z</symbol>
<symbol label=",">comma</symbol>
<symbol label="\">backslash</symbol>
<symbol label="x">x</symbol>
<symbol label="X">X</symbol>
<symbol label="&quot;">quotedbl</symbol>
<symbol label="/">slash</symbol>
<symbol label="c">c</symbol>
<symbol label="C">C</symbol>
<symbol label="'">quoteright</symbol>
<symbol label="&lt;">less</symbol>
<symbol label="v">v</symbol>
<symbol label="V">V</symbol>
<symbol label=":">colon</symbol>
<symbol label="&gt;">greater</symbol>
<symbol label="b">b</symbol>
<symbol label="B">B</symbol>
<symbol label=";">semicolon</symbol>
<symbol label="=">equal</symbol>
<symbol label="n">n</symbol>
<symbol label="N">N</symbol>
<symbol label="!">exclam</symbol>
<symbol label="[">bracketleft</symbol>
<symbol label="m">m</symbol>
<symbol label="M">M</symbol>
<symbol label="?">question</symbol>
<symbol label="]">bracketright</symbol>
<symbol label=".">period</symbol>
<symbol label="123">show_numbers</symbol>
<symbol label="ABC">show_letters</symbol>
<symbol label="&#9786;" icon="keyboard-mode-symbolic" tooltip="Setup">preferences</symbol>
<symbol label=" ">space</symbol>
<symbol keyval="65288" icon="edit-clear-symbolic">BackSpace</symbol>
<key name="AD01">
<symbol label="q">q</symbol>
<symbol label="Q">Q</symbol>
<symbol label="1">1</symbol>
<symbol label="~">asciitilde</symbol>
</key>
<key name="AD02">
<symbol label="w">w</symbol>
<symbol label="W">W</symbol>
<symbol label="2">2</symbol>
<symbol label="`">quoteleft</symbol>
</key>
<key name="AD03">
<symbol label="e">e</symbol>
<symbol label="E">E</symbol>
<symbol label="3">3</symbol>
<symbol label="|">bar</symbol>
</key>
<key name="AD04">
<symbol label="r">r</symbol>
<symbol label="R">R</symbol>
<symbol label="4">4</symbol>
<symbol label="&#183;">U00B7</symbol>
</key>
<key name="AD05">
<symbol label="t">t</symbol>
<symbol label="T">T</symbol>
<symbol label="5">5</symbol>
<symbol label="&#8730;">squareroot</symbol>
</key>
<key name="AD06">
<symbol label="y">y</symbol>
<symbol label="Y">Y</symbol>
<symbol label="6">6</symbol>
<symbol label="&#960;">Greek_pi</symbol>
</key>
<key name="AD07">
<symbol label="u">u</symbol>
<symbol label="U">U</symbol>
<symbol label="7">7</symbol>
<symbol label="&#247;">division</symbol>
</key>
<key name="AD08">
<symbol label="i">i</symbol>
<symbol label="I">I</symbol>
<symbol label="8">8</symbol>
<symbol label="&#215;">multiply</symbol>
</key>
<key name="AD09">
<symbol label="o">o</symbol>
<symbol label="O">O</symbol>
<symbol label="9">9</symbol>
<symbol label="&#182;">paragraph</symbol>
</key>
<key name="AD10">
<symbol label="p">p</symbol>
<symbol label="P">P</symbol>
<symbol label="0">0</symbol>
<symbol label="&#9651;">U25B3</symbol>
</key>
<key name="AD11">
<symbol keyval="229" label="&#229;">aring</symbol>
<symbol keyval="197" label="&#197;">Aring</symbol>
<symbol label=""></symbol>
<symbol label=""></symbol>
<!-- Empty labels cause keys to be hidden when the level they are defined
for is shown. -->
</key>
<key name="AC01">
<symbol label="a">a</symbol>
<symbol label="A">A</symbol>
<symbol label="@">at</symbol>
<symbol label="&#169;">copyright</symbol>
</key>
<key name="AC02">
<symbol label="s">s</symbol>
<symbol label="S">S</symbol>
<symbol label="#">numbersign</symbol>
<symbol label="&#174;">U00AE</symbol>
</key>
<key name="AC03">
<symbol label="d">d</symbol>
<symbol label="D">D</symbol>
<symbol label="$">dollar</symbol>
<symbol label="&#163;">U00A3</symbol>
</key>
<key name="AC04">
<symbol label="f">f</symbol>
<symbol label="F">F</symbol>
<symbol label="%">percent</symbol>
<symbol label="&#8364;">EuroSign</symbol>
</key>
<key name="AC05">
<symbol label="g">g</symbol>
<symbol label="G">G</symbol>
<symbol label="&amp;">ampersand</symbol>
<symbol label="&#165;">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="&#176;">degree</symbol>
</key>
<key name="AC08">
<symbol label="k">k</symbol>
<symbol label="K">K</symbol>
<symbol label="+">plus</symbol>
<symbol label="=">equal</symbol>
</key>
<key name="AC09">
<symbol label="l">l</symbol>
<symbol label="L">L</symbol>
<symbol label="(">parenleft</symbol>
<symbol label="{">braceleft</symbol>
</key>
<key name="AC10">
<symbol keyval="248" label="&#248;">oslash</symbol>
<symbol keyval="216" label="&#216;">Oslash</symbol>
<symbol label=")">parenright</symbol>
<symbol label="}">braceright</symbol>
</key>
<key name="AC11">
<symbol keyval="230" label="&#230;">ae</symbol>
<symbol keyval="198" label="&#198;">AE</symbol>
<symbol label=""></symbol>
<symbol label=""></symbol>
</key>
<key name="RTRN">
<symbol keyval="65293" icon="key-enter">Return</symbol>
</key>
<key name="LFSH">
<keysym keyval="65505" icon="key-shift">Shift_L</keysym>
<keysym keyval="65505" icon="key-shift">Shift_L</keysym>
<keysym keyval="65505" label="=/+">Shift_L</keysym>
<keysym keyval="65505" label="123">Shift_L</keysym>
</key>
<key name="AB01">
<symbol label="z">z</symbol>
<symbol label="Z">Z</symbol>
<symbol label=",">comma</symbol>
<symbol label="\">backslash</symbol>
</key>
<key name="AB02">
<symbol label="x">x</symbol>
<symbol label="X">X</symbol>
<symbol label="&quot;">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="&lt;">less</symbol>
</key>
<key name="AB04">
<symbol label="v">v</symbol>
<symbol label="V">V</symbol>
<symbol label=":">colon</symbol>
<symbol label="&gt;">greater</symbol>
</key>
<key name="AB05">
<symbol label="b">b</symbol>
<symbol label="B">B</symbol>
<symbol label=";">semicolon</symbol>
<symbol label="=">equal</symbol>
</key>
<key name="AB06">
<symbol label="n">n</symbol>
<symbol label="N">N</symbol>
<symbol label="!">exclam</symbol>
<symbol label="[">bracketleft</symbol>
</key>
<key name="AB07">
<symbol label="m">m</symbol>
<symbol label="M">M</symbol>
<symbol label="?">question</symbol>
<symbol label="]">bracketright</symbol>
</key>
<key name="AB08">
<symbol label=".">period</symbol>
</key>
<key name="ABC123">
<symbol label="123">show-numbers</symbol>
<symbol label="123">show-numbers</symbol>
<symbol label="ABC">show-letters</symbol>
<symbol label="ABC">show-letters</symbol>
</key>
<key name="I149">
<symbol icon="keyboard-mode-symbolic" tooltip="Setup">preferences</symbol>
</key>
<key name="SPCE">
<symbol label=" ">space</symbol>
</key>
<key name="BKSP">
<symbol keyval="65288" icon="edit-clear-symbolic">BackSpace</symbol>
</key>
</symbols>

View File

@ -0,0 +1,39 @@
<?xml version='1.0' encoding='ASCII' standalone='yes'?>
<symbols version="0.90">
<key name="AD01">
<symbol label="1">1</symbol>
</key>
<key name="AD02">
<symbol label="2">2</symbol>
</key>
<key name="AD03">
<symbol label="3">3</symbol>
</key>
<key name="AC01">
<symbol label="4">4</symbol>
</key>
<key name="AC02">
<symbol label="5">5</symbol>
</key>
<key name="AC03">
<symbol label="6">6</symbol>
</key>
<key name="AB01">
<symbol label="7">7</symbol>
</key>
<key name="AB02">
<symbol label="8">8</symbol>
</key>
<key name="AB03">
<symbol label="9">9</symbol>
</key>
<key name="AB04">
<symbol label="0">0</symbol>
</key>
<key name="RTRN">
<symbol keyval="65293" icon="key-enter">Return</symbol>
</key>
<key name="BKSP">
<symbol keyval="65288" icon="edit-clear-symbolic">BackSpace</symbol>
</key>
</symbols>

View File

@ -1,22 +1,60 @@
<?xml version='1.0' encoding='ASCII' standalone='yes'?>
<symbols version="0.90">
<symbol label="1">1</symbol>
<symbol label="2">2</symbol>
<symbol label="3">3</symbol>
<symbol label="(">parenleft</symbol>
<symbol label=")">parenright</symbol>
<symbol label="4">4</symbol>
<symbol label="5">5</symbol>
<symbol label="6">6</symbol>
<symbol label="#">numbersign</symbol>
<symbol label="*">asterisk</symbol>
<symbol label="7">7</symbol>
<symbol label="8">8</symbol>
<symbol label="9">9</symbol>
<symbol label="+">plus</symbol>
<symbol label="-">minus</symbol>
<symbol label="0">0</symbol>
<symbol keyval="65293" icon="key-enter">Return</symbol>
<symbol label=" ">space</symbol>
<symbol keyval="65288" icon="edit-clear-symbolic">BackSpace</symbol>
<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>

View File

@ -0,0 +1,60 @@
<?xml version='1.0' encoding='ASCII' standalone='yes'?>
<symbols version="0.90">
<key name="AD01">
<symbol label="1">1</symbol>
</key>
<key name="AD02">
<symbol label="2">2</symbol>
</key>
<key name="AD03">
<symbol label="3">3</symbol>
</key>
<key name="AD04">
<symbol label="(">parenleft</symbol>
</key>
<key name="AD05">
<symbol label=")">parenright</symbol>
</key>
<key name="AC01">
<symbol label="4">4</symbol>
</key>
<key name="AC02">
<symbol label="5">5</symbol>
</key>
<key name="AC03">
<symbol label="6">6</symbol>
</key>
<key name="AC04">
<symbol label="#">numbersign</symbol>
</key>
<key name="AC05">
<symbol label="*">asterisk</symbol>
</key>
<key name="AB01">
<symbol label="7">7</symbol>
</key>
<key name="AB02">
<symbol label="8">8</symbol>
</key>
<key name="AB03">
<symbol label="9">9</symbol>
</key>
<key name="AB04">
<symbol label="+">plus</symbol>
</key>
<key name="AB05">
<symbol label="-">minus</symbol>
</key>
<key name="AB06">
<symbol label="0">0</symbol>
</key>
<key name="RTRN">
<symbol keyval="65293" icon="key-enter">Return</symbol>
</key>
<key name="SPCE">
<symbol label=" ">space</symbol>
</key>
<key name="BKSP">
<symbol keyval="65288" icon="edit-clear-symbolic">BackSpace</symbol>
</key>
</symbols>

View File

@ -0,0 +1,231 @@
<?xml version='1.0' encoding='ASCII' standalone='yes'?>
<symbols version="0.90">
<key name="AD01">
<symbol label="q">q</symbol>
<symbol label="Q">Q</symbol>
<symbol label=""></symbol>
<symbol label="1">1</symbol>
</key>
<key name="AD02">
<symbol label="w">w</symbol>
<symbol label="W">W</symbol>
<symbol label=""></symbol>
<symbol label="2">2</symbol>
</key>
<key name="AD03">
<symbol label="e">e</symbol>
<symbol label="E">E</symbol>
<symbol label=""></symbol>
<symbol label="3">3</symbol>
</key>
<key name="AD04">
<symbol label="r">r</symbol>
<symbol label="R">R</symbol>
<symbol label=""></symbol>
<symbol label="4">4</symbol>
</key>
<key name="AD05">
<symbol label="t">t</symbol>
<symbol label="T">T</symbol>
<symbol label=""></symbol>
<symbol label="5">5</symbol>
</key>
<key name="AD06">
<symbol label="y">y</symbol>
<symbol label="Y">Y</symbol>
<symbol label=""></symbol>
<symbol label="6">6</symbol>
</key>
<key name="AD07">
<symbol label="u">u</symbol>
<symbol label="U">U</symbol>
<symbol label=""></symbol>
<symbol label="7">7</symbol>
</key>
<key name="AD08">
<symbol label="i">i</symbol>
<symbol label="I">I</symbol>
<symbol label=""></symbol>
<symbol label="8">8</symbol>
</key>
<key name="AD09">
<symbol label="o">o</symbol>
<symbol label="O">O</symbol>
<symbol label=""></symbol>
<symbol label="9">9</symbol>
</key>
<key name="AD10">
<symbol label="p">p</symbol>
<symbol label="P">P</symbol>
<symbol label=""></symbol>
<symbol label="0">0</symbol>
</key>
<key name="AC01">
<symbol label="a">a</symbol>
<symbol label="A">A</symbol>
<symbol label="@">at</symbol>
<symbol label="~">asciitilde</symbol>
</key>
<key name="AC02">
<symbol label="s">s</symbol>
<symbol label="S">S</symbol>
<symbol label="#">numbersign</symbol>
<symbol label="&#174;">U00AE</symbol>
</key>
<key name="AC03">
<symbol label="d">d</symbol>
<symbol label="D">D</symbol>
<symbol label="$">dollar</symbol>
<symbol label="&#163;">U00A3</symbol>
</key>
<key name="AC04">
<symbol label="f">f</symbol>
<symbol label="F">F</symbol>
<symbol label="%">percent</symbol>
<symbol label="&#8364;">EuroSign</symbol>
</key>
<key name="AC05">
<symbol label="g">g</symbol>
<symbol label="G">G</symbol>
<symbol label="&amp;">ampersand</symbol>
<symbol label="&#165;">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="&#176;">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="&quot;">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="&lt;">less</symbol>
</key>
<key name="AB04">
<symbol label="v">v</symbol>
<symbol label="V">V</symbol>
<symbol label=":">colon</symbol>
<symbol label="&gt;">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="&#9786;" 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>

View File

@ -1,118 +1,194 @@
<?xml version='1.0' encoding='ASCII' standalone='yes'?>
<symbols version="0.90">
<symbol label="*">asterisk</symbol>
<symbol label="+/=">show_symbols</symbol>
<symbol label="q">q</symbol>
<symbol label="Q">Q</symbol>
<symbol label="1">1</symbol>
<symbol label="~">asciitilde</symbol>
<symbol label="w">w</symbol>
<symbol label="W">W</symbol>
<symbol label="2">2</symbol>
<symbol label="`">quoteleft</symbol>
<symbol label="e">e</symbol>
<symbol label="E">E</symbol>
<symbol label="3">3</symbol>
<symbol label="|">bar</symbol>
<symbol label="r">r</symbol>
<symbol label="R">R</symbol>
<symbol label="4">4</symbol>
<symbol label="&#183;">U00B7</symbol>
<symbol label="t">t</symbol>
<symbol label="T">T</symbol>
<symbol label="5">5</symbol>
<symbol label="&#8730;">squareroot</symbol>
<symbol label="y">y</symbol>
<symbol label="Y">Y</symbol>
<symbol label="6">6</symbol>
<symbol label="&#960;">Greek_pi</symbol>
<symbol label="u">u</symbol>
<symbol label="U">U</symbol>
<symbol label="7">7</symbol>
<symbol label="&#247;">division</symbol>
<symbol label="i">i</symbol>
<symbol label="I">I</symbol>
<symbol label="8">8</symbol>
<symbol label="&#215;">multiply</symbol>
<symbol label="o">o</symbol>
<symbol label="O">O</symbol>
<symbol label="9">9</symbol>
<symbol label="&#182;">paragraph</symbol>
<symbol label="p">p</symbol>
<symbol label="P">P</symbol>
<symbol label="0">0</symbol>
<symbol label="&#964;">Greek_tau</symbol>
<symbol label="a">a</symbol>
<symbol label="A">A</symbol>
<symbol label="@">at</symbol>
<symbol label="&#169;">copyright</symbol>
<symbol label="s">s</symbol>
<symbol label="S">S</symbol>
<symbol label="#">numbersign</symbol>
<symbol label="&#174;">U00AE</symbol>
<symbol label="d">d</symbol>
<symbol label="D">D</symbol>
<symbol label="$">dollar</symbol>
<symbol label="&#163;">U00A3</symbol>
<symbol label="f">f</symbol>
<symbol label="F">F</symbol>
<symbol label="%">percent</symbol>
<symbol label="&#8364;">EuroSign</symbol>
<symbol label="g">g</symbol>
<symbol label="G">G</symbol>
<symbol label="&amp;">ampersand</symbol>
<symbol label="&#165;">U00A5</symbol>
<symbol label="h">h</symbol>
<symbol label="H">H</symbol>
<symbol label="-">minus</symbol>
<symbol label="^">asciicircum</symbol>
<symbol label="j">j</symbol>
<symbol label="J">J</symbol>
<symbol label="_">underscore</symbol>
<symbol label="&#176;">degree</symbol>
<symbol label="k">k</symbol>
<symbol label="K">K</symbol>
<symbol label="+">plus</symbol>
<symbol label="=">equal</symbol>
<symbol label="l">l</symbol>
<symbol label="L">L</symbol>
<symbol label="(">parenleft</symbol>
<symbol label="{">braceleft</symbol>
<symbol label=")">parenright</symbol>
<symbol label="}">braceright</symbol>
<symbol keyval="65293" icon="key-enter">Return</symbol>
<symbol keyval="65505" icon="key-shift">Shift_L</symbol>
<symbol label="z">z</symbol>
<symbol label="Z">Z</symbol>
<symbol label=",">comma</symbol>
<symbol label="\">backslash</symbol>
<symbol label="x">x</symbol>
<symbol label="X">X</symbol>
<symbol label="&quot;">quotedbl</symbol>
<symbol label="/">slash</symbol>
<symbol label="c">c</symbol>
<symbol label="C">C</symbol>
<symbol label="'">quoteright</symbol>
<symbol label="&lt;">less</symbol>
<symbol label="v">v</symbol>
<symbol label="V">V</symbol>
<symbol label=":">colon</symbol>
<symbol label="&gt;">greater</symbol>
<symbol label="b">b</symbol>
<symbol label="B">B</symbol>
<symbol label=";">semicolon</symbol>
<symbol label="n">n</symbol>
<symbol label="N">N</symbol>
<symbol label="!">exclam</symbol>
<symbol label="[">bracketleft</symbol>
<symbol label="m">m</symbol>
<symbol label="M">M</symbol>
<symbol label="?">question</symbol>
<symbol label="]">bracketright</symbol>
<symbol label=".">period</symbol>
<symbol label="123">show_numbers</symbol>
<symbol label="ABC">show_letters</symbol>
<symbol label="&#9786;" icon="keyboard-mode-symbolic" tooltip="Setup">preferences</symbol>
<symbol label=" ">space</symbol>
<symbol keyval="65288" icon="edit-clear-symbolic">BackSpace</symbol>
<key name="AD01">
<symbol label="q">q</symbol>
<symbol label="Q">Q</symbol>
<symbol label="1">1</symbol>
<symbol label="~">asciitilde</symbol>
</key>
<key name="AD02">
<symbol label="w">w</symbol>
<symbol label="W">W</symbol>
<symbol label="2">2</symbol>
<symbol label="`">quoteleft</symbol>
</key>
<key name="AD03">
<symbol label="e">e</symbol>
<symbol label="E">E</symbol>
<symbol label="3">3</symbol>
<symbol label="|">bar</symbol>
</key>
<key name="AD04">
<symbol label="r">r</symbol>
<symbol label="R">R</symbol>
<symbol label="4">4</symbol>
<symbol label="&#183;">U00B7</symbol>
</key>
<key name="AD05">
<symbol label="t">t</symbol>
<symbol label="T">T</symbol>
<symbol label="5">5</symbol>
<symbol label="&#8730;">squareroot</symbol>
</key>
<key name="AD06">
<symbol label="y">y</symbol>
<symbol label="Y">Y</symbol>
<symbol label="6">6</symbol>
<symbol label="&#960;">Greek_pi</symbol>
</key>
<key name="AD07">
<symbol label="u">u</symbol>
<symbol label="U">U</symbol>
<symbol label="7">7</symbol>
<symbol label="&#247;">division</symbol>
</key>
<key name="AD08">
<symbol label="i">i</symbol>
<symbol label="I">I</symbol>
<symbol label="8">8</symbol>
<symbol label="&#215;">multiply</symbol>
</key>
<key name="AD09">
<symbol label="o">o</symbol>
<symbol label="O">O</symbol>
<symbol label="9">9</symbol>
<symbol label="&#182;">paragraph</symbol>
</key>
<key name="AD10">
<symbol label="p">p</symbol>
<symbol label="P">P</symbol>
<symbol label="0">0</symbol>
<symbol label="&#9651;">U25B3</symbol>
</key>
<key name="AC01">
<symbol label="a">a</symbol>
<symbol label="A">A</symbol>
<symbol label="@">at</symbol>
<symbol label="&#169;">copyright</symbol>
</key>
<key name="AC02">
<symbol label="s">s</symbol>
<symbol label="S">S</symbol>
<symbol label="#">numbersign</symbol>
<symbol label="&#174;">U00AE</symbol>
</key>
<key name="AC03">
<symbol label="d">d</symbol>
<symbol label="D">D</symbol>
<symbol label="$">dollar</symbol>
<symbol label="&#163;">U00A3</symbol>
</key>
<key name="AC04">
<symbol label="f">f</symbol>
<symbol label="F">F</symbol>
<symbol label="%">percent</symbol>
<symbol label="&#8364;">EuroSign</symbol>
</key>
<key name="AC05">
<symbol label="g">g</symbol>
<symbol label="G">G</symbol>
<symbol label="&amp;">ampersand</symbol>
<symbol label="&#165;">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="&#176;">degree</symbol>
</key>
<key name="AC08">
<symbol label="k">k</symbol>
<symbol label="K">K</symbol>
<symbol label="+">plus</symbol>
<symbol label="=">equal</symbol>
</key>
<key name="AC09">
<symbol label="l">l</symbol>
<symbol label="L">L</symbol>
<symbol label="(">parenleft</symbol>
<symbol label="{">braceleft</symbol>
</key>
<key name="AC10">
<!-- Empty labels cause keys to be hidden when the level they are defined
for is shown. -->
<symbol label=""></symbol>
<symbol label=""></symbol>
<symbol label=")">parenright</symbol>
<symbol label="}">braceright</symbol>
</key>
<key name="RTRN">
<symbol keyval="65293" icon="key-enter">Return</symbol>
</key>
<key name="LFSH">
<keysym keyval="65505" icon="key-shift">Shift_L</keysym>
<keysym keyval="65505" icon="key-shift">Shift_L</keysym>
<keysym keyval="65505" label="=/+">Shift_L</keysym>
<keysym keyval="65505" label="123">Shift_L</keysym>
</key>
<key name="AB01">
<symbol label="z">z</symbol>
<symbol label="Z">Z</symbol>
<symbol label=",">comma</symbol>
<symbol label="\">backslash</symbol>
</key>
<key name="AB02">
<symbol label="x">x</symbol>
<symbol label="X">X</symbol>
<symbol label="&quot;">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="&lt;">less</symbol>
</key>
<key name="AB04">
<symbol label="v">v</symbol>
<symbol label="V">V</symbol>
<symbol label=":">colon</symbol>
<symbol label="&gt;">greater</symbol>
</key>
<key name="AB05">
<symbol label="b">b</symbol>
<symbol label="B">B</symbol>
<symbol label=";">semicolon</symbol>
<symbol label="=">equal</symbol>
</key>
<key name="AB06">
<symbol label="n">n</symbol>
<symbol label="N">N</symbol>
<symbol label="!">exclam</symbol>
<symbol label="[">bracketleft</symbol>
</key>
<key name="AB07">
<symbol label="m">m</symbol>
<symbol label="M">M</symbol>
<symbol label="?">question</symbol>
<symbol label="]">bracketright</symbol>
</key>
<key name="AB08">
<symbol label=".">period</symbol>
</key>
<key name="ABC123">
<symbol label="123">show-numbers</symbol>
<symbol label="123">show-numbers</symbol>
<symbol label="ABC">show-letters</symbol>
<symbol label="ABC">show-letters</symbol>
</key>
<key name="I149">
<symbol label="&#9786;" icon="keyboard-mode-symbolic" tooltip="Setup">preferences</symbol>
</key>
<key name="SPCE">
<symbol label=" ">space</symbol>
</key>
<key name="BKSP">
<symbol keyval="65288" icon="edit-clear-symbolic">BackSpace</symbol>
</key>
</symbols>

View File

@ -2,10 +2,19 @@
<gresources>
<gresource prefix="/sm/puri/squeekboard">
<file compressed="true">style.css</file>
<!-- Keyboard layouts -->
<file compressed="true" preprocess="xml-stripblanks">keyboards/geometry/compact.xml</file>
<file compressed="true" preprocess="xml-stripblanks">keyboards/geometry/extended.xml</file>
<file compressed="true" preprocess="xml-stripblanks">keyboards/geometry/digits.xml</file>
<file compressed="true" preprocess="xml-stripblanks">keyboards/geometry/number-keypad.xml</file>
<file compressed="true" preprocess="xml-stripblanks">keyboards/geometry/phone-keypad.xml</file>
<file compressed="true" preprocess="xml-stripblanks">keyboards/geometry/url.xml</file>
<!-- Keyboard definitions -->
<file compressed="true" preprocess="xml-stripblanks">keyboards/keyboards.xml</file>
<!-- Natural language keyboards -->
<file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/ar.xml</file>
<file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/as-inscript.xml</file>
<file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/be.xml</file>
@ -35,7 +44,13 @@
<file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/ug.xml</file>
<file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/us.xml</file>
<file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/zh-bopomofo.xml</file>
<!-- Special purpose keyboards -->
<file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/special/digits.xml</file>
<file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/special/number.xml</file>
<file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/special/phone.xml</file>
<file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/special/url.xml</file>
<file>icons/key-enter.svg</file>
<file>icons/key-shift.svg</file>
<file>icons/keyboard-mode-symbolic.svg</file>

View File

@ -7,8 +7,7 @@
.key {
color: #deddda;
background: #464448;
border-style: solid;
border-width: 1px;
border-width: 0.5px;
border-color: #5e5c64;
border-radius: 2px;
}

4
debian/copyright vendored
View File

@ -1,6 +1,6 @@
Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
Upstream-Name: squeekboard
Source: https://source.puri.sm/Librem5/squeekboard
Upstream-Name: evscript
Source: https://source.puri.sm/david.boddie/evscript
Files: *
Copyright: 2010-2011 Daiki Ueno <ueno@unixuser.org>

232
eek/eek-container.c Normal file
View File

@ -0,0 +1,232 @@
/*
* Copyright (C) 2010-2011 Daiki Ueno <ueno@unixuser.org>
* Copyright (C) 2010-2011 Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301 USA
*/
/**
* SECTION:eek-container
* @short_description: Base class of a keyboard container
*
* The #EekContainerClass class represents a keyboard container, which
* shall be used to implement #EekKeyboard and #EekSection.
*/
#include "config.h"
#include "eek-container.h"
enum {
CHILD_ADDED,
CHILD_REMOVED,
LAST_SIGNAL
};
static guint signals[LAST_SIGNAL] = { 0, };
typedef struct _EekContainerPrivate
{
GList *head;
GList *last;
} EekContainerPrivate;
G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (EekContainer, eek_container, EEK_TYPE_ELEMENT)
static void
eek_container_real_add_child (EekContainer *self,
EekElement *child)
{
EekContainerPrivate *priv = (EekContainerPrivate*)eek_container_get_instance_private (self);
g_return_if_fail (EEK_IS_ELEMENT(child));
g_object_ref (child);
if (!priv->head) {
priv->head = priv->last = g_list_prepend (priv->head, child);
} else {
priv->last->next = g_list_prepend (priv->last->next, child);
priv->last = priv->last->next;
}
eek_element_set_parent (child, EEK_ELEMENT(self));
g_signal_emit (self, signals[CHILD_ADDED], 0, child);
}
static void
eek_container_real_remove_child (EekContainer *self,
EekElement *child)
{
EekContainerPrivate *priv = eek_container_get_instance_private (self);
GList *head;
g_return_if_fail (EEK_IS_ELEMENT(child));
head = g_list_find (priv->head, child);
g_return_if_fail (head);
g_object_unref (child);
if (head == priv->last)
priv->last = g_list_previous (priv->last);
priv->head = g_list_remove_link (priv->head, head);
eek_element_set_parent (child, NULL);
g_signal_emit (self, signals[CHILD_REMOVED], 0, child);
}
static void
eek_container_real_foreach_child (EekContainer *self,
EekCallback callback,
gpointer user_data)
{
EekContainerPrivate *priv = eek_container_get_instance_private (self);
GList *head;
for (head = priv->head; head; head = g_list_next (head))
(*callback) (EEK_ELEMENT(head->data), user_data);
}
static EekElement *
eek_container_real_find (EekContainer *self,
EekCompareFunc func,
gpointer user_data)
{
EekContainerPrivate *priv = eek_container_get_instance_private (self);
GList *head;
head = g_list_find_custom (priv->head, user_data, (GCompareFunc)func);
if (head)
return head->data;
return NULL;
}
static void
eek_container_dispose (GObject *object)
{
EekContainer *self = EEK_CONTAINER (object);
EekContainerPrivate *priv = eek_container_get_instance_private (self);
GList *head;
for (head = priv->head; head; head = priv->head) {
g_object_unref (head->data);
priv->head = g_list_next (head);
g_list_free1 (head);
}
G_OBJECT_CLASS(eek_container_parent_class)->dispose (object);
}
static void
eek_container_class_init (EekContainerClass *klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
klass->add_child = eek_container_real_add_child;
klass->remove_child = eek_container_real_remove_child;
klass->foreach_child = eek_container_real_foreach_child;
klass->find = eek_container_real_find;
/* signals */
klass->child_added = NULL;
klass->child_removed = NULL;
gobject_class->dispose = eek_container_dispose;
/**
* EekContainer::child-added:
* @container: an #EekContainer
* @element: an #EekElement
*
* The ::child-added signal is emitted each time an element is
* added to @container.
*/
signals[CHILD_ADDED] =
g_signal_new (I_("child-added"),
G_TYPE_FROM_CLASS(gobject_class),
G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET(EekContainerClass, child_added),
NULL, NULL,
g_cclosure_marshal_VOID__OBJECT,
G_TYPE_NONE, 1,
EEK_TYPE_ELEMENT);
/**
* EekContainer::child-removed:
* @container: an #EekContainer
* @element: an #EekElement
*
* The ::child-removed signal is emitted each time an element is
* removed from @container.
*/
signals[CHILD_REMOVED] =
g_signal_new (I_("child-removed"),
G_TYPE_FROM_CLASS(gobject_class),
G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET(EekContainerClass, child_removed),
NULL,
NULL,
g_cclosure_marshal_VOID__OBJECT,
G_TYPE_NONE, 1,
EEK_TYPE_ELEMENT);
}
static void
eek_container_init (EekContainer *self)
{
/* void */
}
/**
* eek_container_foreach_child:
* @container: an #EekContainer
* @callback: (scope call): an #EekCallback
* @user_data: additional data passed to @callback
*
* Enumerate children of @container and run @callback with each child.
*/
void
eek_container_foreach_child (EekContainer *container,
EekCallback callback,
gpointer user_data)
{
g_return_if_fail (EEK_IS_CONTAINER(container));
EEK_CONTAINER_GET_CLASS(container)->foreach_child (container,
callback,
user_data);
}
/**
* eek_container_find:
* @container: an #EekContainer
* @func: function to be used to compare two children
* @user_data: additional data passed to @func
*
* Find a child which matches the criteria supplied as @func, in @container.
* Returns: an #EekElement or NULL on failure
*/
EekElement *
eek_container_find (EekContainer *container,
EekCompareFunc func,
gpointer user_data)
{
g_return_val_if_fail (EEK_IS_CONTAINER(container), NULL);
return EEK_CONTAINER_GET_CLASS(container)->find (container,
func,
user_data);
}
void
eek_container_add_child (EekContainer *container, EekElement *element)
{
g_return_if_fail (EEK_IS_CONTAINER(container));
g_return_if_fail (EEK_IS_ELEMENT(element));
return EEK_CONTAINER_GET_CLASS(container)->add_child (container, element);
}

94
eek/eek-container.h Normal file
View File

@ -0,0 +1,94 @@
/*
* Copyright (C) 2010-2011 Daiki Ueno <ueno@unixuser.org>
* Copyright (C) 2010-2011 Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301 USA
*/
#if !defined(__EEK_H_INSIDE__) && !defined(EEK_COMPILATION)
#error "Only <eek/eek.h> can be included directly."
#endif
#ifndef EEK_CONTAINER_H
#define EEK_CONTAINER_H 1
#include "eek-element.h"
G_BEGIN_DECLS
#define EEK_TYPE_CONTAINER (eek_container_get_type())
G_DECLARE_DERIVABLE_TYPE (EekContainer, eek_container, EEK, CONTAINER, EekElement)
/**
* EekCallback:
* @element: an #EekElement
* @user_data: user-supplied data
*
* The type of the callback function used for iterating over the
* children of a container, see eek_container_foreach_child().
*/
typedef void (*EekCallback) (EekElement *element, gpointer user_data);
typedef gint (*EekCompareFunc) (EekElement *element, gpointer user_data);
/**
* EekContainerClass:
* @foreach_child: virtual function for iterating over the container's children
* @find: virtual function for looking up a child
* @child_added: class handler for #EekContainer::child-added
* @child_removed: class handler for #EekContainer::child-added
*/
struct _EekContainerClass
{
/*< private >*/
EekElementClass parent_class;
void (* add_child) (EekContainer *self,
EekElement *element);
void (* remove_child) (EekContainer *self,
EekElement *element);
/*< public >*/
void (* foreach_child) (EekContainer *self,
EekCallback callback,
gpointer user_data);
EekElement *(* find) (EekContainer *self,
EekCompareFunc func,
gpointer data);
/* signals */
void (* child_added) (EekContainer *self,
EekElement *element);
void (* child_removed) (EekContainer *self,
EekElement *element);
/*< private >*/
/* padding */
gpointer pdummy[24];
};
GType eek_container_get_type (void) G_GNUC_CONST;
void eek_container_foreach_child (EekContainer *container,
EekCallback callback,
gpointer user_data);
EekElement *eek_container_find (EekContainer *container,
EekCompareFunc func,
gpointer user_data);
void eek_container_add_child (EekContainer *container,
EekElement *element);
G_END_DECLS
#endif /* EEK_CONTAINER_H */

View File

@ -31,23 +31,51 @@
#include <string.h>
#include "eek-element.h"
#include "eek-container.h"
#include "eek-marshalers.h"
enum {
PROP_0,
PROP_NAME,
PROP_BOUNDS,
PROP_GROUP,
PROP_LEVEL,
PROP_LAST
};
enum {
SYMBOL_INDEX_CHANGED,
LAST_SIGNAL
};
static guint signals[LAST_SIGNAL] = { 0, };
typedef struct _EekElementPrivate
{
gchar *name;
EekBounds bounds;
EekElement *parent;
gint group;
gint level;
} EekElementPrivate;
G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (EekElement, eek_element, G_TYPE_OBJECT)
static void
eek_element_real_symbol_index_changed (EekElement *self,
gint group,
gint level)
{
// g_debug ("symbol-index-changed");
}
static void
eek_element_finalize (GObject *object)
{
EekElement *self = EEK_ELEMENT (object);
EekElementPrivate *priv = eek_element_get_instance_private (self);
g_free (priv->name);
G_OBJECT_CLASS (eek_element_parent_class)->finalize (object);
}
@ -60,9 +88,19 @@ eek_element_set_property (GObject *object,
EekElement *element = EEK_ELEMENT(object);
switch (prop_id) {
case PROP_NAME:
eek_element_set_name (element,
g_value_dup_string (value));
break;
case PROP_BOUNDS:
eek_element_set_bounds (element, g_value_get_boxed (value));
break;
case PROP_GROUP:
eek_element_set_group (element, g_value_get_int (value));
break;
case PROP_LEVEL:
eek_element_set_level (element, g_value_get_int (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@ -79,10 +117,19 @@ eek_element_get_property (GObject *object,
EekBounds bounds;
switch (prop_id) {
case PROP_NAME:
g_value_set_string (value, eek_element_get_name (element));
break;
case PROP_BOUNDS:
eek_element_get_bounds (element, &bounds);
g_value_set_boxed (value, &bounds);
break;
case PROP_GROUP:
g_value_set_int (value, eek_element_get_group (element));
break;
case PROP_LEVEL:
g_value_set_int (value, eek_element_get_level (element));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@ -96,10 +143,26 @@ eek_element_class_init (EekElementClass *klass)
GParamSpec *pspec;
/* signals */
klass->symbol_index_changed = eek_element_real_symbol_index_changed;
gobject_class->set_property = eek_element_set_property;
gobject_class->get_property = eek_element_get_property;
gobject_class->finalize = eek_element_finalize;
/**
* EekElement:name:
*
* The name of #EekElement.
*/
pspec = g_param_spec_string ("name",
"Name",
"Name",
NULL,
G_PARAM_READWRITE);
g_object_class_install_property (gobject_class,
PROP_NAME,
pspec);
/**
* EekElement:bounds:
*
@ -113,12 +176,149 @@ eek_element_class_init (EekElementClass *klass)
g_object_class_install_property (gobject_class,
PROP_BOUNDS,
pspec);
/**
* EekElement:group:
*
* The group value of the symbol index of #EekElement.
*/
pspec = g_param_spec_int ("group",
"Group",
"Group value of the symbol index",
-1, G_MAXINT, -1,
G_PARAM_READWRITE);
g_object_class_install_property (gobject_class,
PROP_GROUP,
pspec);
/**
* EekElement:level:
*
* The level value of the symbol index of #EekElement.
*/
pspec = g_param_spec_int ("level",
"Level",
"Level value of the symbol index",
-1, G_MAXINT, -1,
G_PARAM_READWRITE);
g_object_class_install_property (gobject_class,
PROP_LEVEL,
pspec);
/**
* EekElement::symbol-index-changed:
* @element: an #EekElement
* @group: row index of the symbol matrix of keys on @element
* @level: column index of the symbol matrix of keys on @element
*
* The ::symbol-index-changed signal is emitted each time the
* global configuration of group/level index changes.
*/
signals[SYMBOL_INDEX_CHANGED] =
g_signal_new (I_("symbol-index-changed"),
G_TYPE_FROM_CLASS(gobject_class),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET(EekElementClass, symbol_index_changed),
NULL,
NULL,
_eek_marshal_VOID__INT_INT,
G_TYPE_NONE,
2,
G_TYPE_INT,
G_TYPE_INT);
}
static void
eek_element_init (EekElement *self)
{
(void)self;
EekElementPrivate *priv = eek_element_get_instance_private (self);
priv->group = -1;
priv->level = -1;
}
/**
* eek_element_set_parent:
* @element: an #EekElement
* @parent: (allow-none): an #EekElement or %NULL
*
* Set the parent of @element to @parent.
*/
void
eek_element_set_parent (EekElement *element,
EekElement *parent)
{
g_return_if_fail (EEK_IS_ELEMENT(element));
g_return_if_fail (parent == NULL || EEK_IS_ELEMENT(parent));
EekElementPrivate *priv = eek_element_get_instance_private (element);
if (priv->parent == parent)
return;
if (priv->parent != NULL) {
/* release self-reference acquired when setting parent */
g_object_unref (element);
}
if (parent != NULL) {
g_object_ref (element);
}
priv->parent = parent;
}
/**
* eek_element_get_parent:
* @element: an #EekElement
*
* Get the parent of @element.
* Returns: an #EekElement if the parent is set
*/
EekElement *
eek_element_get_parent (EekElement *element)
{
g_return_val_if_fail (EEK_IS_ELEMENT(element), NULL);
EekElementPrivate *priv = eek_element_get_instance_private (element);
return priv->parent;
}
/**
* eek_element_set_name:
* @element: an #EekElement
* @name: name of @element
*
* Set the name of @element to @name.
*/
void
eek_element_set_name (EekElement *element,
const gchar *name)
{
g_return_if_fail (EEK_IS_ELEMENT(element));
EekElementPrivate *priv = eek_element_get_instance_private (element);
g_free (priv->name);
priv->name = g_strdup (name);
}
/**
* eek_element_get_name:
* @element: an #EekElement
*
* Get the name of @element.
* Returns: the name of @element or NULL when the name is not set
*/
const gchar *
eek_element_get_name (EekElement *element)
{
g_return_val_if_fail (EEK_IS_ELEMENT(element), NULL);
EekElementPrivate *priv = eek_element_get_instance_private (element);
return priv->name;
}
/**
@ -161,3 +361,211 @@ eek_element_get_bounds (EekElement *element,
memcpy (bounds, &priv->bounds, sizeof(EekBounds));
}
/**
* eek_element_get_absolute_position:
* @element: an #EekElement
* @x: pointer where the X coordinate of @element will be stored
* @y: pointer where the Y coordinate of @element will be stored
*
* Compute the absolute position of @element.
*/
void
eek_element_get_absolute_position (EekElement *element,
gdouble *x,
gdouble *y)
{
EekBounds bounds;
gdouble ax = 0.0, ay = 0.0;
do {
eek_element_get_bounds (element, &bounds);
ax += bounds.x;
ay += bounds.y;
} while ((element = eek_element_get_parent (element)) != NULL);
*x = ax;
*y = ay;
}
/**
* eek_element_set_position:
* @element: an #EekElement
* @x: X coordinate of top left corner
* @y: Y coordinate of top left corner
*
* Set the relative position of @element.
*/
void
eek_element_set_position (EekElement *element,
gdouble x,
gdouble y)
{
EekBounds bounds;
eek_element_get_bounds (element, &bounds);
bounds.x = x;
bounds.y = y;
eek_element_set_bounds (element, &bounds);
}
/**
* eek_element_set_size:
* @element: an #EekElement
* @width: width of @element
* @height: height of @element
*
* Set the size of @element.
*/
void
eek_element_set_size (EekElement *element,
gdouble width,
gdouble height)
{
EekBounds bounds;
eek_element_get_bounds (element, &bounds);
bounds.width = width;
bounds.height = height;
eek_element_set_bounds (element, &bounds);
}
/**
* eek_element_set_symbol_index:
* @element: an #EekElement
* @group: row index of the symbol matrix
* @level: column index of the symbol matrix
*
* Set the default index of the symbol matrices of @element. The
* setting affects the child, if child does not have the index set, as
* well as this element. To unset, pass -1 as group/level.
*/
void
eek_element_set_symbol_index (EekElement *element,
gint group,
gint level)
{
gboolean emit_signal;
g_return_if_fail (EEK_IS_ELEMENT(element));
emit_signal = group != eek_element_get_group (element) ||
level != eek_element_get_level (element);
eek_element_set_group (element, group);
eek_element_set_level (element, level);
if (emit_signal)
g_signal_emit (element, signals[SYMBOL_INDEX_CHANGED], 0, group, level);
}
/**
* eek_element_get_symbol_index:
* @element: an #EekElement
* @group: a pointer where the group value of the symbol index will be stored
* @level: a pointer where the level value of the symbol index will be stored
*
* Get the default index of the symbol matrices of @element.
* If the index is not set, -1 will be returned.
*/
void
eek_element_get_symbol_index (EekElement *element,
gint *group,
gint *level)
{
g_return_if_fail (EEK_IS_ELEMENT(element));
g_return_if_fail (group != NULL || level != NULL);
if (group != NULL)
*group = eek_element_get_group (element);
if (level != NULL)
*level = eek_element_get_level (element);
}
/**
* eek_element_set_group:
* @element: an #EekElement
* @group: group index of @element
*
* Set the group value of the default symbol index of @element. To
* unset, pass -1 as @group.
*
* See also: eek_element_set_symbol_index()
*/
void
eek_element_set_group (EekElement *element,
gint group)
{
g_return_if_fail (EEK_IS_ELEMENT(element));
EekElementPrivate *priv = eek_element_get_instance_private (element);
if (priv->group != group) {
priv->group = group;
g_object_notify (G_OBJECT(element), "group");
g_signal_emit (element, signals[SYMBOL_INDEX_CHANGED], 0,
group, priv->level);
}
}
/**
* eek_element_set_level:
* @element: an #EekElement
* @level: level index of @element
*
* Set the level value of the default symbol index of @element. To
* unset, pass -1 as @level.
*
* See also: eek_element_set_symbol_index()
*/
void
eek_element_set_level (EekElement *element,
gint level)
{
g_return_if_fail (EEK_IS_ELEMENT(element));
EekElementPrivate *priv = eek_element_get_instance_private (element);
if (priv->level != level) {
priv->level = level;
g_object_notify (G_OBJECT(element), "level");
g_signal_emit (element, signals[SYMBOL_INDEX_CHANGED], 0,
priv->group, level);
}
}
/**
* eek_element_get_group:
* @element: an #EekElement
*
* Return the group value of the default symbol index of @element.
* If the value is not set, -1 will be returned.
*
* See also: eek_element_get_symbol_index()
*/
gint
eek_element_get_group (EekElement *element)
{
g_return_val_if_fail (EEK_IS_ELEMENT(element), -1);
EekElementPrivate *priv = eek_element_get_instance_private (element);
return priv->group;
}
/**
* eek_element_get_level:
* @element: an #EekElement
*
* Return the level value of the default symbol index of @element.
* If the value is not set, -1 will be returned.
*
* See also: eek_element_get_symbol_index()
*/
gint
eek_element_get_level (EekElement *element)
{
g_return_val_if_fail (EEK_IS_ELEMENT(element), -1);
EekElementPrivate *priv = eek_element_get_instance_private (element);
return priv->level;
}

View File

@ -36,10 +36,18 @@ struct _EekElementClass
{
/*< private >*/
GObjectClass parent_class;
/* signals */
void (* symbol_index_changed) (EekElement *self,
gint group,
gint level);
};
GType eek_element_get_type (void) G_GNUC_CONST;
void eek_element_set_parent (EekElement *element,
EekElement *parent);
EekElement *eek_element_get_parent (EekElement *element);
void eek_element_set_name (EekElement *element,
const gchar *name);
@ -51,5 +59,29 @@ void eek_element_set_bounds (EekElement *element,
void eek_element_get_bounds (EekElement *element,
EekBounds *bounds);
void eek_element_set_position (EekElement *element,
gdouble x,
gdouble y);
void eek_element_set_size (EekElement *element,
gdouble width,
gdouble height);
void eek_element_get_absolute_position (EekElement *element,
gdouble *x,
gdouble *y);
void eek_element_set_symbol_index (EekElement *element,
gint group,
gint level);
void eek_element_get_symbol_index (EekElement *element,
gint *group,
gint *level);
void eek_element_set_group (EekElement *element,
gint group);
void eek_element_set_level (EekElement *element,
gint level);
gint eek_element_get_group (EekElement *element);
gint eek_element_get_level (EekElement *element);
G_END_DECLS
#endif /* EEK_ELEMENT_H */

View File

@ -32,14 +32,16 @@
#include <math.h>
#include <string.h>
#include "eek-gtk-keyboard.h"
#include "eek-renderer.h"
#include "eek-keyboard.h"
#include "src/symbol.h"
#include "eek-gtk-keyboard.h"
#include "eek-section.h"
#include "eek-key.h"
#include "eek-symbol.h"
enum {
PROP_0,
PROP_KEYBOARD,
PROP_LAST
};
@ -52,7 +54,7 @@ enum {
typedef struct _EekGtkKeyboardPrivate
{
EekRenderer *renderer;
LevelKeyboard *keyboard;
EekKeyboard *keyboard;
GtkCssProvider *css_provider;
GtkStyleContext *scontext;
@ -61,16 +63,16 @@ typedef struct _EekGtkKeyboardPrivate
G_DEFINE_TYPE_WITH_PRIVATE (EekGtkKeyboard, eek_gtk_keyboard, GTK_TYPE_DRAWING_AREA)
static void on_button_pressed (struct squeek_button *button, struct squeek_view *view,
static void on_key_pressed (EekKey *key,
EekGtkKeyboard *self);
static void on_button_released (struct squeek_button *button,
struct squeek_view *view,
static void on_key_released (EekKey *key,
EekGtkKeyboard *self);
static void render_pressed_button (GtkWidget *widget, struct button_place *place);
static void render_locked_button (GtkWidget *widget,
struct button_place *place);
static void render_released_button (GtkWidget *widget,
struct squeek_button *button);
static void render_pressed_key (GtkWidget *widget,
EekKey *key);
static void render_locked_key (GtkWidget *widget,
EekKey *key);
static void render_released_key (GtkWidget *widget,
EekKey *key);
static void
eek_gtk_keyboard_real_realize (GtkWidget *self)
@ -93,6 +95,8 @@ eek_gtk_keyboard_real_draw (GtkWidget *self,
EekGtkKeyboardPrivate *priv =
eek_gtk_keyboard_get_instance_private (EEK_GTK_KEYBOARD (self));
GtkAllocation allocation;
GList *list, *head;
gtk_widget_get_allocation (self, &allocation);
if (!priv->renderer) {
@ -109,29 +113,19 @@ eek_gtk_keyboard_real_draw (GtkWidget *self,
eek_renderer_render_keyboard (priv->renderer, cr);
struct squeek_view *view = priv->keyboard->views[priv->keyboard->level];
/* redraw pressed key */
const GList *list = priv->keyboard->pressed_buttons;
for (const GList *head = list; head; head = g_list_next (head)) {
struct button_place place = squeek_view_find_key(
view, squeek_button_get_key(head->data)
);
if (place.button)
render_pressed_button (self, &place);
list = eek_keyboard_get_pressed_keys (priv->keyboard);
for (head = list; head; head = g_list_next (head)) {
render_pressed_key (self, head->data);
}
g_list_free (list);
/* redraw locked key */
list = priv->keyboard->locked_buttons;
for (const GList *head = list; head; head = g_list_next (head)) {
struct button_place place = squeek_view_find_key(
view, squeek_button_get_key(
((EekModifierKey *)head->data)->button
)
);
if (place.button)
render_locked_button (self, &place);
list = eek_keyboard_get_locked_keys (priv->keyboard);
for (head = list; head; head = g_list_next (head)) {
render_locked_key (self, ((EekModifierKey *)head->data)->key);
}
g_list_free (list);
return FALSE;
}
@ -156,45 +150,43 @@ static void depress(EekGtkKeyboard *self,
gdouble x, gdouble y, guint32 time)
{
EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (self);
struct squeek_view *view = level_keyboard_current(priv->keyboard);
struct squeek_button *button = eek_renderer_find_button_by_position (priv->renderer, view, x, y);
EekKey *key = eek_renderer_find_key_by_position (priv->renderer, x, y);
if (button) {
eek_keyboard_press_button(priv->keyboard, button, time);
on_button_pressed(button, view, self);
if (key) {
eek_keyboard_press_key(priv->keyboard, key, time);
on_key_pressed(key, self);
}
}
static void drag(EekGtkKeyboard *self,
gdouble x, gdouble y, guint32 time) {
EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (self);
struct squeek_view *view = level_keyboard_current(priv->keyboard);
struct squeek_button *button = eek_renderer_find_button_by_position (priv->renderer, view, x, y);
EekKey *key = eek_renderer_find_key_by_position (priv->renderer, x, y);
GList *list, *head;
list = g_list_copy(priv->keyboard->pressed_buttons);
list = eek_keyboard_get_pressed_keys (priv->keyboard);
if (button) {
if (key) {
gboolean found = FALSE;
for (head = list; head; head = g_list_next (head)) {
if (head->data == button) {
if (head->data == key) {
found = TRUE;
} else {
eek_keyboard_release_button(priv->keyboard, head->data, time);
on_button_released(button, view, self);
eek_keyboard_release_key(priv->keyboard, EEK_KEY(head->data), time);
on_key_released(key, self);
}
}
g_list_free (list);
if (!found) {
eek_keyboard_press_button(priv->keyboard, button, time);
on_button_pressed(button, view, self);
eek_keyboard_press_key(priv->keyboard, key, time);
on_key_pressed(key, self);
}
} else {
for (head = list; head; head = g_list_next (head)) {
eek_keyboard_release_button(priv->keyboard, head->data, time);
on_button_released(head->data, view, self);
eek_keyboard_release_key(priv->keyboard, EEK_KEY(head->data), time);
on_key_released(key, self);
}
g_list_free (list);
}
@ -203,13 +195,11 @@ static void drag(EekGtkKeyboard *self,
static void release(EekGtkKeyboard *self, guint32 time) {
EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (self);
struct squeek_view *view = level_keyboard_current(priv->keyboard);
GList *list = g_list_copy(priv->keyboard->pressed_buttons);
GList *list = eek_keyboard_get_pressed_keys (priv->keyboard);
for (GList *head = list; head; head = g_list_next (head)) {
struct squeek_button *button = head->data;
eek_keyboard_release_button(priv->keyboard, button, time);
on_button_released(button, view, self);
EekKey *key = EEK_KEY(head->data);
eek_keyboard_release_key(priv->keyboard, key, time);
on_key_released(key, self);
}
g_list_free (list);
}
@ -292,7 +282,7 @@ eek_gtk_keyboard_real_unmap (GtkWidget *self)
elements, so that the default handler of
EekKeyboard::key-released signal can remove elements from its
internal copy */
list = g_list_copy(priv->keyboard->pressed_buttons);
list = eek_keyboard_get_pressed_keys (priv->keyboard);
for (head = list; head; head = g_list_next (head)) {
g_log("squeek", G_LOG_LEVEL_DEBUG, "emit EekKey released");
g_signal_emit_by_name (head->data, "released");
@ -312,15 +302,15 @@ eek_gtk_keyboard_real_query_tooltip (GtkWidget *widget,
{
EekGtkKeyboard *self = EEK_GTK_KEYBOARD (widget);
EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (self);
struct squeek_view *view = level_keyboard_current(priv->keyboard);
struct squeek_button *button = eek_renderer_find_button_by_position (priv->renderer,
view,
(gdouble)x,
(gdouble)y);
if (button) {
//struct squeek_symbol *symbol = eek_key_get_symbol_at_index(key, 0, priv->keyboard->level);
const gchar *text = NULL; // FIXME
EekKey *key;
key = eek_renderer_find_key_by_position (priv->renderer,
(gdouble)x,
(gdouble)y);
if (key) {
EekSymbol *symbol = eek_key_get_symbol (key);
const gchar *text = eek_symbol_get_tooltip (symbol);
if (text) {
gtk_tooltip_set_text (tooltip, text);
return TRUE;
@ -329,13 +319,35 @@ eek_gtk_keyboard_real_query_tooltip (GtkWidget *widget,
return FALSE;
}
static void
eek_gtk_keyboard_set_keyboard (EekGtkKeyboard *self,
EekKeyboard *keyboard)
{
EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (self);
if (priv->keyboard == keyboard)
return;
if (priv->keyboard) {
g_object_unref (priv->keyboard);
}
priv->keyboard = g_object_ref (keyboard);
}
static void
eek_gtk_keyboard_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
EekKeyboard *keyboard;
switch (prop_id) {
case PROP_KEYBOARD:
keyboard = g_value_get_object (value);
eek_gtk_keyboard_set_keyboard (EEK_GTK_KEYBOARD(object), keyboard);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@ -356,13 +368,14 @@ eek_gtk_keyboard_dispose (GObject *object)
if (priv->keyboard) {
GList *list, *head;
list = g_list_copy(priv->keyboard->pressed_buttons);
list = eek_keyboard_get_pressed_keys (priv->keyboard);
for (head = list; head; head = g_list_next (head)) {
g_log("squeek", G_LOG_LEVEL_DEBUG, "emit EekKey pressed");
g_signal_emit_by_name (head->data, "released", level_keyboard_current(priv->keyboard));
g_signal_emit_by_name (head->data, "released", priv->keyboard);
}
g_list_free (list);
g_object_unref (priv->keyboard);
priv->keyboard = NULL;
}
@ -374,6 +387,7 @@ eek_gtk_keyboard_class_init (EekGtkKeyboardClass *klass)
{
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
GParamSpec *pspec;
widget_class->realize = eek_gtk_keyboard_real_realize;
widget_class->unmap = eek_gtk_keyboard_real_unmap;
@ -391,6 +405,15 @@ eek_gtk_keyboard_class_init (EekGtkKeyboardClass *klass)
gobject_class->set_property = eek_gtk_keyboard_set_property;
gobject_class->dispose = eek_gtk_keyboard_dispose;
pspec = g_param_spec_object ("keyboard",
"Keyboard",
"Keyboard",
EEK_TYPE_KEYBOARD,
G_PARAM_CONSTRUCT_ONLY | G_PARAM_WRITABLE);
g_object_class_install_property (gobject_class,
PROP_KEYBOARD,
pspec);
}
static void
@ -420,17 +443,37 @@ eek_gtk_keyboard_init (EekGtkKeyboard *self)
* Returns: a #GtkWidget
*/
GtkWidget *
eek_gtk_keyboard_new (LevelKeyboard *keyboard)
eek_gtk_keyboard_new (EekKeyboard *keyboard)
{
EekGtkKeyboard *ret = EEK_GTK_KEYBOARD(g_object_new (EEK_TYPE_GTK_KEYBOARD, NULL));
EekGtkKeyboardPrivate *priv = (EekGtkKeyboardPrivate*)eek_gtk_keyboard_get_instance_private (ret);
priv->keyboard = keyboard;
return GTK_WIDGET(ret);
return g_object_new (EEK_TYPE_GTK_KEYBOARD, "keyboard", keyboard, NULL);
}
static void
render_pressed_button (GtkWidget *widget,
struct button_place *place)
magnify_bounds (GtkWidget *self,
EekBounds *bounds,
EekBounds *large_bounds,
gdouble scale)
{
GtkAllocation allocation;
gdouble x, y;
g_assert (scale >= 1.0);
gtk_widget_get_allocation (self, &allocation);
large_bounds->width = bounds->width * scale;
large_bounds->height = bounds->height * scale;
x = bounds->x - (large_bounds->width - bounds->width) / 2;
y = bounds->y - large_bounds->height;
large_bounds->x = CLAMP(x, 0, allocation.width - large_bounds->width);
large_bounds->y = CLAMP(y, 0, allocation.height - large_bounds->height);
}
static void
render_pressed_key (GtkWidget *widget,
EekKey *key)
{
EekGtkKeyboard *self = EEK_GTK_KEYBOARD (widget);
EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (self);
@ -440,7 +483,7 @@ render_pressed_button (GtkWidget *widget,
GdkDrawingContext *context = gdk_window_begin_draw_frame (window, region);
cairo_t *cr = gdk_drawing_context_get_cairo_context (context);
eek_renderer_render_button (priv->renderer, cr, place, 1.0, TRUE);
eek_renderer_render_key (priv->renderer, cr, key, 1.0, TRUE);
/*
eek_renderer_render_key (priv->renderer, cr, key, 1.5, TRUE);
*/
@ -450,7 +493,8 @@ render_pressed_button (GtkWidget *widget,
}
static void
render_locked_button (GtkWidget *widget, struct button_place *place)
render_locked_key (GtkWidget *widget,
EekKey *key)
{
EekGtkKeyboard *self = EEK_GTK_KEYBOARD (widget);
EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (self);
@ -460,7 +504,7 @@ render_locked_button (GtkWidget *widget, struct button_place *place)
GdkDrawingContext *context = gdk_window_begin_draw_frame (window, region);
cairo_t *cr = gdk_drawing_context_get_cairo_context (context);
eek_renderer_render_button (priv->renderer, cr, place, 1.0, TRUE);
eek_renderer_render_key (priv->renderer, cr, key, 1.0, TRUE);
gdk_window_end_draw_frame (window, context);
@ -468,10 +512,9 @@ render_locked_button (GtkWidget *widget, struct button_place *place)
}
static void
render_released_button (GtkWidget *widget,
struct squeek_button *button)
render_released_key (GtkWidget *widget,
EekKey *key)
{
(void)button;
EekGtkKeyboard *self = EEK_GTK_KEYBOARD (widget);
EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (self);
@ -488,8 +531,7 @@ render_released_button (GtkWidget *widget,
}
static void
on_button_pressed (struct squeek_button *button,
struct squeek_view *view,
on_key_pressed (EekKey *key,
EekGtkKeyboard *self)
{
EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (self);
@ -498,14 +540,7 @@ on_button_pressed (struct squeek_button *button,
if (!priv->renderer)
return;
struct button_place place = {
.button = button,
.row = squeek_view_get_row(view, button),
};
if (!place.row) {
return;
}
render_pressed_button (GTK_WIDGET(self), &place);
render_pressed_key (GTK_WIDGET(self), key);
gtk_widget_queue_draw (GTK_WIDGET(self));
#if HAVE_LIBCANBERRA
@ -518,18 +553,16 @@ on_button_pressed (struct squeek_button *button,
}
static void
on_button_released (struct squeek_button *button,
struct squeek_view *view,
on_key_released (EekKey *key,
EekGtkKeyboard *self)
{
(void)view;
EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (self);
/* renderer may have not been set yet if the widget is a popup */
if (!priv->renderer)
return;
render_released_button (GTK_WIDGET(self), button);
render_released_key (GTK_WIDGET(self), key);
gtk_widget_queue_draw (GTK_WIDGET(self));
#if HAVE_LIBCANBERRA

View File

@ -45,7 +45,7 @@ struct _EekGtkKeyboardClass
};
GType eek_gtk_keyboard_get_type (void) G_GNUC_CONST;
GtkWidget *eek_gtk_keyboard_new (LevelKeyboard *keyboard);
GtkWidget *eek_gtk_keyboard_new (EekKeyboard *keyboard);
G_END_DECLS
#endif /* EEK_GTK_KEYBOARD_H */

518
eek/eek-key.c Normal file
View File

@ -0,0 +1,518 @@
/*
* Copyright (C) 2010-2011 Daiki Ueno <ueno@unixuser.org>
* Copyright (C) 2010-2011 Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301 USA
*/
/**
* SECTION:eek-key
* @short_description: Base class of a key
*
* The #EekKeyClass class represents a key.
*/
#include "config.h"
#include <string.h>
#include "eek-key.h"
#include "eek-section.h"
#include "eek-keyboard.h"
#include "eek-symbol.h"
enum {
PROP_0,
PROP_KEYCODE,
PROP_SYMBOL_MATRIX,
PROP_OREF,
PROP_LAST
};
enum {
LOCKED,
UNLOCKED,
LAST_SIGNAL
};
static guint signals[LAST_SIGNAL] = { 0, };
typedef struct _EekKeyPrivate
{
guint keycode;
EekSymbolMatrix *symbol_matrix;
gulong oref; // UI outline reference
gboolean is_pressed;
gboolean is_locked;
} EekKeyPrivate;
G_DEFINE_TYPE_WITH_PRIVATE (EekKey, eek_key, EEK_TYPE_ELEMENT)
static void
eek_key_real_locked (EekKey *self)
{
EekKeyPrivate *priv = eek_key_get_instance_private (self);
priv->is_locked = TRUE;
#if DEBUG
g_debug ("locked %X", eek_key_get_keycode (self));
#endif
}
static void
eek_key_real_unlocked (EekKey *self)
{
EekKeyPrivate *priv = eek_key_get_instance_private (self);
priv->is_locked = FALSE;
#if DEBUG
g_debug ("unlocked %X", eek_key_get_keycode (self));
#endif
}
static void
eek_key_finalize (GObject *object)
{
EekKey *self = EEK_KEY (object);
EekKeyPrivate *priv = eek_key_get_instance_private (self);
eek_symbol_matrix_free (priv->symbol_matrix);
G_OBJECT_CLASS (eek_key_parent_class)->finalize (object);
}
static void
eek_key_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
EekSymbolMatrix *matrix;
switch (prop_id) {
case PROP_KEYCODE:
eek_key_set_keycode (EEK_KEY(object), g_value_get_uint (value));
break;
case PROP_SYMBOL_MATRIX:
matrix = g_value_get_boxed (value);
eek_key_set_symbol_matrix (EEK_KEY(object), matrix);
break;
case PROP_OREF:
eek_key_set_oref (EEK_KEY(object), g_value_get_uint (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
eek_key_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
switch (prop_id) {
case PROP_KEYCODE:
g_value_set_uint (value, eek_key_get_keycode (EEK_KEY(object)));
break;
case PROP_SYMBOL_MATRIX:
g_value_set_boxed (value,
eek_key_get_symbol_matrix (EEK_KEY(object)));
break;
case PROP_OREF:
g_value_set_uint (value, eek_key_get_oref (EEK_KEY(object)));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
eek_key_class_init (EekKeyClass *klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
GParamSpec *pspec;
gobject_class->set_property = eek_key_set_property;
gobject_class->get_property = eek_key_get_property;
gobject_class->finalize = eek_key_finalize;
/* signals */
klass->locked = eek_key_real_locked;
klass->unlocked = eek_key_real_unlocked;
/**
* EekKey:keycode:
*
* The keycode of #EekKey.
*/
pspec = g_param_spec_uint ("keycode",
"Keycode",
"Keycode of the key",
0, G_MAXUINT, 0,
G_PARAM_READWRITE);
g_object_class_install_property (gobject_class, PROP_KEYCODE, pspec);
/**
* EekKey:symbol-matrix:
*
* The symbol matrix of #EekKey.
*/
pspec = g_param_spec_boxed ("symbol-matrix",
"Symbol matrix",
"Symbol matrix of the key",
EEK_TYPE_SYMBOL_MATRIX,
G_PARAM_READWRITE);
g_object_class_install_property (gobject_class, PROP_SYMBOL_MATRIX, pspec);
/**
* EekKey:oref:
*
* The outline id of #EekKey.
*/
pspec = g_param_spec_ulong ("oref",
"Oref",
"Outline id of the key",
0, G_MAXULONG, 0,
G_PARAM_READWRITE);
g_object_class_install_property (gobject_class, PROP_OREF, pspec);
/**
* EekKey::locked:
* @key: an #EekKey
*
* The ::locked signal is emitted each time @key is shifted to
* the locked state. The class handler runs before signal
* handlers to allow signal handlers to read the status of @key
* with eek_key_is_locked().
*/
signals[LOCKED] =
g_signal_new (I_("locked"),
G_TYPE_FROM_CLASS(gobject_class),
G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET(EekKeyClass, locked),
NULL,
NULL,
g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE, 0);
/**
* EekKey::unlocked:
* @key: an #EekKey
*
* The ::unlocked signal is emitted each time @key is shifted to
* the unlocked state.
*/
signals[UNLOCKED] =
g_signal_new (I_("unlocked"),
G_TYPE_FROM_CLASS(gobject_class),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET(EekKeyClass, unlocked),
NULL,
NULL,
g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE, 0);
}
static void
eek_key_init (EekKey *self)
{
EekKeyPrivate *priv = eek_key_get_instance_private (self);
priv->symbol_matrix = eek_symbol_matrix_new (0, 0);
}
/**
* eek_key_set_keycode:
* @key: an #EekKey
* @keycode: keycode
*
* Set the keycode of @key to @keycode. Since typically the keycode
* value is used to find a key in a keyboard by calling
* eek_keyboard_find_key_by_keycode, it is not necessarily the same as
* the X keycode but it should be unique in the keyboard @key belongs
* to.
*/
void
eek_key_set_keycode (EekKey *key,
guint keycode)
{
g_return_if_fail (EEK_IS_KEY (key));
EekKeyPrivate *priv = eek_key_get_instance_private (key);
priv->keycode = keycode;
}
/**
* eek_key_get_keycode:
* @key: an #EekKey
*
* Get keycode of @key.
* Returns: keycode or %EEK_INVALID_KEYCODE on failure
*/
guint
eek_key_get_keycode (EekKey *key)
{
g_return_val_if_fail (EEK_IS_KEY (key), EEK_INVALID_KEYCODE);
EekKeyPrivate *priv = eek_key_get_instance_private (key);
return priv->keycode;
}
/**
* eek_key_set_symbol_matrix:
* @key: an #EekKey
* @matrix: an #EekSymbolMatrix
*
* Set the symbol matrix of @key to @matrix.
*/
void
eek_key_set_symbol_matrix (EekKey *key,
EekSymbolMatrix *matrix)
{
g_return_if_fail (EEK_IS_KEY(key));
EekKeyPrivate *priv = eek_key_get_instance_private (key);
eek_symbol_matrix_free (priv->symbol_matrix);
priv->symbol_matrix = eek_symbol_matrix_copy (matrix);
}
/**
* eek_key_get_symbol_matrix:
* @key: an #EekKey
*
* Get the symbol matrix of @key.
* Returns: (transfer none): #EekSymbolMatrix or %NULL
*/
EekSymbolMatrix *
eek_key_get_symbol_matrix (EekKey *key)
{
g_return_val_if_fail (EEK_IS_KEY(key), NULL);
EekKeyPrivate *priv = eek_key_get_instance_private (key);
return priv->symbol_matrix;
}
/**
* eek_key_get_symbol:
* @key: an #EekKey
*
* Get the current symbol of @key.
* Return value: (transfer none): the current #EekSymbol or %NULL on failure
*/
EekSymbol *
eek_key_get_symbol (EekKey *key)
{
return eek_key_get_symbol_with_fallback (key, 0, 0);
}
/**
* eek_key_get_symbol_with_fallback:
* @key: an #EekKey
* @fallback_group: fallback group index
* @fallback_level: fallback level index
*
* Get the current symbol of @key.
* Return value: (transfer none): the current #EekSymbol or %NULL on failure
*/
EekSymbol *
eek_key_get_symbol_with_fallback (EekKey *key,
gint fallback_group,
gint fallback_level)
{
gint group, level;
g_return_val_if_fail (EEK_IS_KEY (key), NULL);
g_return_val_if_fail (fallback_group >= 0, NULL);
g_return_val_if_fail (fallback_level >= 0, NULL);
eek_element_get_symbol_index (EEK_ELEMENT(key), &group, &level);
if (group < 0 || level < 0) {
EekElement *section;
section = eek_element_get_parent (EEK_ELEMENT(key));
g_return_val_if_fail (EEK_IS_SECTION (section), NULL);
if (group < 0)
group = eek_element_get_group (section);
if (level < 0)
level = eek_element_get_level (section);
if (group < 0 || level < 0) {
EekElement *keyboard;
keyboard = eek_element_get_parent (section);
g_return_val_if_fail (EEK_IS_KEYBOARD (keyboard), NULL);
if (group < 0)
group = eek_element_get_group (keyboard);
if (level < 0)
level = eek_element_get_level (keyboard);
}
}
return eek_key_get_symbol_at_index (key,
group,
level,
fallback_group,
fallback_level);
}
/**
* eek_key_get_symbol_at_index:
* @key: an #EekKey
* @group: group index of the symbol matrix
* @level: level index of the symbol matrix
* @fallback_group: fallback group index
* @fallback_level: fallback level index
*
* Get the symbol at (@group, @level) in the symbol matrix of @key.
* Return value: (transfer none): an #EekSymbol at (@group, @level), or %NULL
*/
EekSymbol *
eek_key_get_symbol_at_index (EekKey *key,
gint group,
gint level,
gint fallback_group,
gint fallback_level)
{
EekKeyPrivate *priv = eek_key_get_instance_private (key);
gint num_symbols;
g_return_val_if_fail (fallback_group >= 0, NULL);
g_return_val_if_fail (fallback_level >= 0, NULL);
if (group < 0)
group = fallback_group;
if (level < 0)
level = fallback_level;
if (!priv->symbol_matrix)
return NULL;
num_symbols = priv->symbol_matrix->num_groups *
priv->symbol_matrix->num_levels;
if (num_symbols == 0)
return NULL;
if (group >= priv->symbol_matrix->num_groups) {
if (fallback_group < 0)
return NULL;
group = fallback_group;
}
if (level >= priv->symbol_matrix->num_levels) {
if (fallback_level < 0)
return NULL;
level = fallback_level;
}
return priv->symbol_matrix->data[group * priv->symbol_matrix->num_levels +
level];
}
/**
* eek_key_set_oref:
* @key: an #EekKey
* @oref: outline id of @key
*
* Set the outline id of @key to @oref.
*/
void
eek_key_set_oref (EekKey *key,
guint oref)
{
g_return_if_fail (EEK_IS_KEY(key));
EekKeyPrivate *priv = eek_key_get_instance_private (key);
if (priv->oref != oref) {
priv->oref = oref;
g_object_notify (G_OBJECT(key), "oref");
}
}
/**
* eek_key_get_oref:
* @key: an #EekKey
*
* Get the outline id of @key.
* Returns: unsigned integer
*/
guint
eek_key_get_oref (EekKey *key)
{
g_return_val_if_fail (EEK_IS_KEY (key), 0);
EekKeyPrivate *priv = eek_key_get_instance_private (key);
return priv->oref;
}
/**
* eek_key_is_pressed:
* @key: an #EekKey
*
* Return %TRUE if key is marked as pressed.
*/
gboolean
eek_key_is_pressed (EekKey *key)
{
g_return_val_if_fail (EEK_IS_KEY(key), FALSE);
EekKeyPrivate *priv = eek_key_get_instance_private (key);
return priv->is_pressed;
}
/**
* eek_key_is_locked:
* @key: an #EekKey
*
* Return %TRUE if key is marked as locked.
*/
gboolean
eek_key_is_locked (EekKey *key)
{
g_return_val_if_fail (EEK_IS_KEY(key), FALSE);
EekKeyPrivate *priv = eek_key_get_instance_private (key);
return priv->is_locked;
}
void eek_key_set_pressed(EekKey *key, gboolean value)
{
g_return_if_fail (EEK_IS_KEY(key));
EekKeyPrivate *priv = eek_key_get_instance_private (key);
priv->is_pressed = value;
}
gboolean
eek_key_has_label(EekKey *key)
{
EekSymbol *symbol = eek_key_get_symbol(key);
return (eek_symbol_get_label(symbol) != NULL) ||
(eek_symbol_get_icon_name(symbol) != NULL);
}

88
eek/eek-key.h Normal file
View File

@ -0,0 +1,88 @@
/*
* Copyright (C) 2010-2011 Daiki Ueno <ueno@unixuser.org>
* Copyright (C) 2010-2011 Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301 USA
*/
#if !defined(__EEK_H_INSIDE__) && !defined(EEK_COMPILATION)
#error "Only <eek/eek.h> can be included directly."
#endif
#ifndef EEK_KEY_H
#define EEK_KEY_H 1
#include "eek-element.h"
#include "eek-symbol-matrix.h"
G_BEGIN_DECLS
#define EEK_TYPE_KEY (eek_key_get_type())
G_DECLARE_DERIVABLE_TYPE(EekKey, eek_key, EEK, KEY, EekElement)
/**
* EekKeyClass:
* @pressed: class handler for #EekKey::pressed signal
* @released: class handler for #EekKey::released signal
* @locked: class handler for #EekKey::locked signal
* @unlocked: class handler for #EekKey::unlocked signal
* @cancelled: class handler for #EekKey::cancelled signal
* @is_pressed: virtual function for getting whether the key is pressed
* @is_locked: virtual function for getting whether the key is locked
*/
struct _EekKeyClass
{
/*< private >*/
EekElementClass parent_class;
/*< public >*/
/* signals */
void (* locked) (EekKey *key);
void (* unlocked) (EekKey *key);
};
GType eek_key_get_type (void) G_GNUC_CONST;
void eek_key_set_keycode (EekKey *key,
guint keycode);
guint eek_key_get_keycode (EekKey *key);
void eek_key_set_symbol_matrix (EekKey *key,
EekSymbolMatrix *matrix);
EekSymbolMatrix *eek_key_get_symbol_matrix (EekKey *key);
EekSymbol *eek_key_get_symbol (EekKey *key);
EekSymbol *eek_key_get_symbol_with_fallback
(EekKey *key,
gint fallback_group,
gint fallback_level);
EekSymbol *eek_key_get_symbol_at_index (EekKey *key,
gint group,
gint level,
gint fallback_group,
gint fallback_level);
void eek_key_set_oref (EekKey *key,
guint oref);
guint eek_key_get_oref (EekKey *key);
gboolean eek_key_is_pressed (EekKey *key);
gboolean eek_key_is_locked (EekKey *key);
void eek_key_set_pressed (EekKey *key,
gboolean value);
gboolean eek_key_has_label (EekKey *key);
G_END_DECLS
#endif /* EEK_KEY_H */

File diff suppressed because it is too large Load Diff

View File

@ -27,67 +27,191 @@
#include <glib-object.h>
#include <xkbcommon/xkbcommon.h>
#include "eek-container.h"
#include "eek-types.h"
#include "eek-layout.h"
#include "src/layout.h"
G_BEGIN_DECLS
struct _EekModifierKey {
/*< public >*/
EekModifierType modifiers;
struct squeek_button *button;
};
typedef struct _EekModifierKey EekModifierKey;
#define EEK_TYPE_KEYBOARD (eek_keyboard_get_type())
#define EEK_KEYBOARD(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EEK_TYPE_KEYBOARD, EekKeyboard))
#define EEK_KEYBOARD_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EEK_TYPE_KEYBOARD, EekKeyboardClass))
#define EEK_IS_KEYBOARD(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EEK_TYPE_KEYBOARD))
#define EEK_IS_KEYBOARD_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EEK_TYPE_KEYBOARD))
#define EEK_KEYBOARD_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EEK_TYPE_KEYBOARD, EekKeyboardClass))
/// Keyboard state holder
struct _LevelKeyboard {
struct squeek_view *views[4];
guint level;
typedef struct _EekKeyboardClass EekKeyboardClass;
typedef struct _EekKeyboardPrivate EekKeyboardPrivate;
/**
* EekKeyboard:
*
* Contains the state of the physical keyboard.
*
* Is also a graphical element...
*
* The #EekKeyboard structure contains only private data and should
* only be accessed using the provided API.
*/
struct _EekKeyboard
{
/*< private >*/
EekContainer parent;
EekKeyboardPrivate *priv;
struct xkb_keymap *keymap;
int keymap_fd; // keymap formatted as XKB string
size_t keymap_len; // length of the data inside keymap_fd
GArray *outline_array;
GList *pressed_buttons; // struct squeek_button*
GList *locked_buttons; // struct squeek_button*
/* Map button names to button objects: */
GHashTable *names;
guint id; // as a key to layout choices
double scale;
EekboardContextService *manager; // unowned reference
};
typedef struct _LevelKeyboard LevelKeyboard;
struct squeek_button *eek_keyboard_find_button_by_name(LevelKeyboard *keyboard,
const gchar *name);
/**
* EekKeyboardClass:
* @create_section: virtual function for creating a section
* @find_key_by_name: virtual function for finding a key in the
* keyboard by name
* @key_pressed: class handler for #EekKeyboard::key-pressed signal
* @key_released: class handler for #EekKeyboard::key-released signal
* @key_locked: class handler for #EekKeyboard::key-locked signal
* @key_unlocked: class handler for #EekKeyboard::key-unlocked signal
* @key_cancelled: class handler for #EekKeyboard::key-cancelled signal
*/
struct _EekKeyboardClass
{
/*< private >*/
EekContainerClass parent_class;
/// Represents the path to the button within a view
struct button_place {
const struct squeek_row *row;
const struct squeek_button *button;
/* obsolete members moved to EekElement */
gpointer set_symbol_index;
gpointer get_symbol_index;
/*< public >*/
EekSection *(* create_section) (EekKeyboard *self);
EekKey *(* find_key_by_name) (EekKeyboard *self,
const gchar *name);
/*< private >*/
/* obsolete members moved to EekElement */
gpointer symbol_index_changed;
/*< public >*/
/* signals */
void (* key_locked) (EekKeyboard *self,
EekKey *key);
void (* key_unlocked) (EekKeyboard *self,
EekKey *key);
/*< private >*/
/* padding */
gpointer pdummy[21];
};
EekOutline *level_keyboard_get_outline
(LevelKeyboard *keyboard,
/**
* EekModifierKey:
* @modifiers: an #EekModifierType which @key triggers
* @key: an #EekKey
*
* Entry which associates modifier mask to a key. This is returned by
* eek_keyboard_get_locked_keys().
*/
struct _EekModifierKey {
/*< public >*/
EekModifierType modifiers;
EekKey *key;
};
typedef struct _EekModifierKey EekModifierKey;
struct _EekKeyPress {
EekKey *key;
guint level;
};
typedef struct _EekKeyPress EekKeyPress;
EekKeyboard *eek_keyboard_new (EekboardContextService *manager,
EekLayout *layout,
gdouble initial_width,
gdouble initial_height);
GType eek_keyboard_get_type
(void) G_GNUC_CONST;
EekLayout *eek_keyboard_get_layout
(EekKeyboard *keyboard);
void eek_keyboard_get_size
(EekKeyboard *keyboard,
gdouble *width,
gdouble *height);
void eek_keyboard_set_size
(EekKeyboard *keyboard,
gdouble width,
gdouble height);
void eek_keyboard_set_modifier_behavior
(EekKeyboard *keyboard,
EekModifierBehavior modifier_behavior);
EekModifierBehavior eek_keyboard_get_modifier_behavior
(EekKeyboard *keyboard);
void eek_keyboard_set_modifiers
(EekKeyboard *keyboard,
EekModifierType modifiers);
EekModifierType eek_keyboard_get_modifiers
(EekKeyboard *keyboard);
EekSection *eek_keyboard_create_section
(EekKeyboard *keyboard);
EekKey *eek_keyboard_find_key_by_name
(EekKeyboard *keyboard,
const gchar *name);
guint eek_keyboard_add_outline
(EekKeyboard *keyboard,
EekOutline *outline);
EekOutline *eek_keyboard_get_outline
(EekKeyboard *keyboard,
guint oref);
gsize eek_keyboard_get_n_outlines
(EekKeyboard *keyboard);
void eek_keyboard_set_num_lock_mask
(EekKeyboard *keyboard,
EekModifierType num_lock_mask);
EekModifierType eek_keyboard_get_num_lock_mask
(EekKeyboard *keyboard);
void eek_keyboard_set_alt_gr_mask
(EekKeyboard *keyboard,
EekModifierType alt_gr_mask);
EekModifierType eek_keyboard_get_alt_gr_mask
(EekKeyboard *keyboard);
GList *eek_keyboard_get_pressed_keys
(EekKeyboard *keyboard);
GList *eek_keyboard_get_locked_keys
(EekKeyboard *keyboard);
EekModifierKey *eek_modifier_key_copy
(EekModifierKey *modkey);
void eek_modifier_key_free
(EekModifierKey *modkey);
void eek_keyboard_press_button(LevelKeyboard *keyboard, struct squeek_button *button, guint32 timestamp);
void eek_keyboard_release_button(LevelKeyboard *keyboard, struct squeek_button *button, guint32 timestamp);
void eek_keyboard_press_key(EekKeyboard *keyboard, EekKey *key, guint32 timestamp);
void eek_keyboard_release_key(EekKeyboard *keyboard, EekKey *key, guint32 timestamp);
gchar * eek_keyboard_get_keymap
(LevelKeyboard *keyboard);
(EekKeyboard *keyboard);
struct squeek_view *level_keyboard_current(LevelKeyboard *keyboard);
LevelKeyboard *level_keyboard_new(EekboardContextService *manager, struct squeek_view *views[], GHashTable *name_button_hash);
void level_keyboard_deinit(LevelKeyboard *self);
void level_keyboard_free(LevelKeyboard *self);
void eek_keyboard_register_symbol
(EekKeyboard *keyboard,
EekSymbol *symbol,
EekKey *key,
guint level);
EekKeyPress * eek_keyboard_get_key_press
(EekKeyboard *keyboard,
gchar *ch);
G_END_DECLS
#endif /* EEK_KEYBOARD_H */

View File

@ -25,7 +25,11 @@
#include "config.h"
#include <string.h>
#include <stdlib.h>
#include "eek-keysym.h"
#include "eek-serializable.h"
/* modifier keys */
#define EEK_KEYSYM_Shift_L 0xffe1
@ -51,15 +55,208 @@ struct _EekKeysymEntry {
typedef struct _EekKeysymEntry EekKeysymEntry;
#include "eek-special-keysym-entries.h"
#include "eek-unicode-keysym-entries.h"
#include "eek-xkeysym-keysym-entries.h"
guint32
eek_keysym_from_name (const gchar *name)
static gchar *
unichar_to_utf8 (gunichar uc)
{
for (uint i = 0; i < G_N_ELEMENTS(xkeysym_keysym_entries); i++) {
if (g_strcmp0 (xkeysym_keysym_entries[i].name, name) == 0) {
return xkeysym_keysym_entries[i].xkeysym;
}
if (g_unichar_isgraph (uc)) {
gchar *buf;
gint len;
len = g_unichar_to_utf8 (uc, NULL);
buf = g_malloc0 (len + 1);
g_unichar_to_utf8 (uc, buf);
return buf;
}
return g_strdup ("");
}
static int
keysym_entry_compare_by_xkeysym (const void *key0, const void *key1)
{
const EekKeysymEntry *entry0 = key0, *entry1 = key1;
return (gint) (entry0->xkeysym - entry1->xkeysym);
}
static EekKeysymEntry *
find_keysym_entry_by_xkeysym (guint xkeysym,
const EekKeysymEntry *entries,
gint num_entries)
{
EekKeysymEntry key;
key.xkeysym = xkeysym;
return bsearch (&key, entries, num_entries, sizeof (EekKeysymEntry),
keysym_entry_compare_by_xkeysym);
}
static gboolean
get_unichar (guint xkeysym, gunichar *uc) {
/* Check for Latin-1 characters (1:1 mapping) */
if ((xkeysym >= 0x0020 && xkeysym <= 0x007e) ||
(xkeysym >= 0x00a0 && xkeysym <= 0x00ff)) {
*uc = xkeysym;
return TRUE;
}
/* Also check for directly encoded 24-bit UCS characters:
*/
if ((xkeysym & 0xff000000) == 0x01000000) {
*uc = xkeysym & 0x00ffffff;
return TRUE;
}
return FALSE;
}
G_INLINE_FUNC EekModifierType
get_modifier_mask (guint xkeysym)
{
switch (xkeysym) {
case EEK_KEYSYM_Shift_L:
case EEK_KEYSYM_Shift_R:
case EEK_KEYSYM_Caps_Lock:
case EEK_KEYSYM_Shift_Lock:
return EEK_SHIFT_MASK;
case EEK_KEYSYM_ISO_Level3_Shift:
return EEK_BUTTON1_MASK;
case EEK_KEYSYM_Control_L:
case EEK_KEYSYM_Control_R:
return EEK_CONTROL_MASK;
case EEK_KEYSYM_Alt_L:
case EEK_KEYSYM_Alt_R:
return EEK_MOD1_MASK;
case EEK_KEYSYM_Meta_L:
case EEK_KEYSYM_Meta_R:
return EEK_META_MASK;
case EEK_KEYSYM_Super_L:
case EEK_KEYSYM_Super_R:
return EEK_SUPER_MASK;
case EEK_KEYSYM_Hyper_L:
case EEK_KEYSYM_Hyper_R:
return EEK_HYPER_MASK;
}
return 0;
}
/**
* eek_keysym_new_with_modifier:
* @xkeysym: an X keysym value
* @modifier_mask: modifier assigned to @xkeysym
*
* Create an #EekKeysym with given X keysym value @xkeysym and
* modifier @modifier_mask.
*/
EekSymbol *eek_keysym_new_with_modifier(guint xkeysym,
EekModifierType modifier_mask)
{
EekKeysymEntry *special_entry, *xkeysym_entry, *unicode_entry,
*unichar_entry;
gchar *name, *label;
gunichar uc;
special_entry =
find_keysym_entry_by_xkeysym (xkeysym,
special_keysym_entries,
G_N_ELEMENTS(special_keysym_entries));
xkeysym_entry =
find_keysym_entry_by_xkeysym (xkeysym,
xkeysym_keysym_entries,
G_N_ELEMENTS(xkeysym_keysym_entries));
unicode_entry =
find_keysym_entry_by_xkeysym (xkeysym,
unicode_keysym_entries,
G_N_ELEMENTS(unicode_keysym_entries));
unichar_entry = NULL;
if (get_unichar (xkeysym, &uc)) {
unichar_entry = g_slice_new (EekKeysymEntry);
unichar_entry->xkeysym = xkeysym;
unichar_entry->name = unichar_to_utf8 (uc);
}
name = NULL;
if (xkeysym_entry) {
name = g_strdup (xkeysym_entry->name);
} else if (unichar_entry) {
name = g_strdup (unichar_entry->name);
} else if (unicode_entry) {
name = g_strdup (unicode_entry->name);
} else {
name = g_strdup ("");
}
/* label */
if (special_entry)
label = g_strdup (special_entry->name);
else if (unichar_entry)
label = g_strdup (unichar_entry->name);
else if (unicode_entry)
label = g_strdup (unicode_entry->name);
else
label = g_strdup (name);
EekSymbol *keysym = eek_symbol_new(name);
eek_symbol_set_label(keysym, label);
eek_symbol_set_modifier_mask(keysym, modifier_mask);
g_free (name);
g_free (label);
if (unichar_entry) {
g_free ((gpointer) unichar_entry->name);
g_slice_free (EekKeysymEntry, unichar_entry);
}
keysym->xkeysym = xkeysym;
return keysym;
}
/**
* eek_keysym_new:
* @xkeysym: an X keysym value
*
* Create an #EekKeysym with given X keysym value @xkeysym.
*/
EekSymbol*
eek_keysym_new (guint xkeysym)
{
return eek_keysym_new_with_modifier (xkeysym, get_modifier_mask (xkeysym));
}
/**
* eek_keysym_new_from_name:
* @name: an X keysym name
*
* Create an #EekKeysym with an X keysym value looked up by @name.
*/
EekSymbol*
eek_keysym_new_from_name (const gchar *name)
{
for (uint i = 0; i < G_N_ELEMENTS(xkeysym_keysym_entries); i++)
if (g_strcmp0 (xkeysym_keysym_entries[i].name, name) == 0)
return eek_keysym_new (xkeysym_keysym_entries[i].xkeysym);
EekSymbol *ret = eek_symbol_new(name);
eek_symbol_set_label(ret, name);
return ret;
}
/**
* eek_keysym_get_xkeysym:
* @keysym: an #EekKeysym
*
* Get an X keysym value associated with @keysym
*/
guint
eek_keysym_get_xkeysym (EekSymbol *keysym)
{
if (keysym->xkeysym == 0) {
g_warning("Symbol %s was expected to have a valid keysym", keysym->name);
}
return keysym->xkeysym;
}

View File

@ -25,8 +25,25 @@
#ifndef EEK_KEYSYM_H
#define EEK_KEYSYM_H 1
#include "glib.h"
#include <X11/XKBlib.h>
#include "eek-symbol.h"
guint32 eek_keysym_from_name (const gchar *name);
G_BEGIN_DECLS
/**
* EEK_INVALID_KEYSYM:
*
* Pseudo keysym used for error reporting.
*/
#define EEK_INVALID_KEYSYM (0)
EekSymbol *eek_keysym_new (guint xkeysym);
guint eek_keysym_get_xkeysym (EekSymbol *keysym);
EekSymbol *eek_keysym_new_from_name (const gchar *name);
EekSymbol *eek_keysym_new_with_modifier (guint xkeysym,
EekModifierType modifier_mask);
G_END_DECLS
#endif /* EEK_KEYSYM_H */

View File

@ -31,7 +31,6 @@
#include "eek-layout.h"
#include "eek-keyboard.h"
#include "eekboard/eekboard-context-service.h"
#include "eek-xml-layout.h"
G_DEFINE_ABSTRACT_TYPE (EekLayout, eek_layout, G_TYPE_OBJECT)
@ -46,8 +45,92 @@ eek_layout_init (EekLayout *self)
{
}
void
eek_layout_update_layout(LevelKeyboard *keyboard)
/**
* eek_keyboard_new:
* @layout: an #EekLayout
* @initial_width: initial width of the keyboard
* @initial_height: initial height of the keyboard
*
* Create a new #EekKeyboard based on @layout.
*/
EekKeyboard *
eek_keyboard_new (EekboardContextService *manager,
EekLayout *layout,
gdouble initial_width,
gdouble initial_height)
{
squeek_view_place_contents(level_keyboard_current(keyboard), keyboard);
g_assert (EEK_IS_LAYOUT(layout));
g_assert (EEK_LAYOUT_GET_CLASS(layout)->create_keyboard);
return EEK_LAYOUT_GET_CLASS(layout)->create_keyboard (manager,
layout,
initial_width,
initial_height);
}
const double section_spacing = 7.0;
struct place_data {
double desired_width;
double current_offset;
EekKeyboard *keyboard;
};
static void
section_placer(EekElement *element, gpointer user_data)
{
struct place_data *data = (struct place_data*)user_data;
EekBounds section_bounds = {0};
eek_element_get_bounds(element, &section_bounds);
section_bounds.width = data->desired_width;
eek_element_set_bounds(element, &section_bounds);
// Sections are rows now. Gather up all the keys and adjust their bounds.
eek_section_place_keys(EEK_SECTION(element), EEK_KEYBOARD(data->keyboard));
eek_element_get_bounds(element, &section_bounds);
section_bounds.y = data->current_offset;
eek_element_set_bounds(element, &section_bounds);
data->current_offset += section_bounds.height + section_spacing;
}
static void
section_counter(EekElement *element, gpointer user_data) {
double *total_height = user_data;
EekBounds section_bounds = {0};
eek_element_get_bounds(element, &section_bounds);
*total_height += section_bounds.height + section_spacing;
}
void
eek_layout_place_sections(EekKeyboard *keyboard)
{
/* Order rows */
// This needs to be done after outlines, because outlines define key sizes
// TODO: do this only for rows without bounds
// The keyboard width is given by the user via screen size. The height will be given dynamically.
// TODO: calculate max line width beforehand for button centering. Leave keyboard centering to the renderer later
EekBounds keyboard_bounds = {0};
eek_element_get_bounds(EEK_ELEMENT(keyboard), &keyboard_bounds);
struct place_data placer_data = {
.desired_width = keyboard_bounds.width,
.current_offset = 0,
.keyboard = keyboard,
};
eek_container_foreach_child(EEK_CONTAINER(keyboard), section_placer, &placer_data);
double total_height = 0;
eek_container_foreach_child(EEK_CONTAINER(keyboard), section_counter, &total_height);
keyboard_bounds.height = total_height;
eek_element_set_bounds(EEK_ELEMENT(keyboard), &keyboard_bounds);
}
void
eek_layout_update_layout(EekKeyboard *keyboard)
{
eek_layout_place_sections(keyboard);
}

View File

@ -27,7 +27,6 @@
#include <glib-object.h>
#include "eek-types.h"
#include "src/layout.h"
G_BEGIN_DECLS
@ -44,7 +43,7 @@ struct _EekLayoutClass
GObjectClass parent_class;
/*< public >*/
LevelKeyboard* (* create_keyboard) (EekboardContextService *manager,
EekKeyboard* (* create_keyboard) (EekboardContextService *manager,
EekLayout *self,
gdouble initial_width,
gdouble initial_height);
@ -56,14 +55,9 @@ struct _EekLayoutClass
GType eek_layout_get_type (void) G_GNUC_CONST;
void eek_layout_place_rows(LevelKeyboard *keyboard, struct squeek_view *level);
void eek_layout_place_sections(EekKeyboard *keyboard);
void eek_layout_update_layout(LevelKeyboard *keyboard);
void eek_layout_update_layout(EekKeyboard *keyboard);
LevelKeyboard *
level_keyboard_from_layout (EekLayout *layout,
gdouble initial_width,
gdouble initial_height);
G_END_DECLS
#endif /* EEK_LAYOUT_H */

1
eek/eek-marshalers.list Normal file
View File

@ -0,0 +1 @@
VOID:INT,INT

View File

@ -23,13 +23,15 @@
#include <math.h>
#include <string.h>
#include <gdk-pixbuf/gdk-pixbuf.h>
#include <gtk/gtk.h>
#include "src/symbol.h"
#include "eek-key.h"
#include "eek-section.h"
#include "eek-renderer.h"
enum {
PROP_0,
PROP_KEYBOARD,
PROP_PCONTEXT,
PROP_STYLE_CONTEXT,
PROP_LAST
@ -37,7 +39,7 @@ enum {
typedef struct _EekRendererPrivate
{
LevelKeyboard *keyboard;
EekKeyboard *keyboard;
PangoContext *pcontext;
GtkCssProvider *css_provider;
GtkStyleContext *scontext;
@ -60,6 +62,7 @@ typedef struct _EekRendererPrivate
GHashTable *active_outline_surface_cache;
GHashTable *icons;
cairo_surface_t *keyboard_surface;
gulong symbol_index_changed_handler;
} EekRendererPrivate;
@ -74,32 +77,36 @@ extern void _eek_rounded_polygon (cairo_t *cr,
EekPoint *points,
guint num_points);
static void eek_renderer_real_render_button_label (EekRenderer *self,
static void eek_renderer_real_render_key_label (EekRenderer *self,
PangoLayout *layout,
const struct squeek_button *button);
EekKey *key);
static void invalidate (EekRenderer *renderer);
static void render_button (EekRenderer *self,
cairo_t *cr, struct button_place *place,
static void render_key (EekRenderer *self,
cairo_t *cr,
EekKey *key,
gboolean active);
static void on_symbol_index_changed (EekKeyboard *keyboard,
gint group,
gint level,
gpointer user_data);
struct _CreateKeyboardSurfaceCallbackData {
cairo_t *cr;
EekRenderer *renderer;
struct squeek_view *view;
struct squeek_row *row;
};
typedef struct _CreateKeyboardSurfaceCallbackData CreateKeyboardSurfaceCallbackData;
static void
create_keyboard_surface_button_callback (struct squeek_button *button,
create_keyboard_surface_key_callback (EekElement *element,
gpointer user_data)
{
CreateKeyboardSurfaceCallbackData *data = user_data;
EekBounds bounds = squeek_button_get_bounds(button);
EekBounds bounds;
cairo_save (data->cr);
eek_element_get_bounds (element, &bounds);
cairo_translate (data->cr, bounds.x, bounds.y);
cairo_rectangle (data->cr,
0.0,
@ -107,61 +114,54 @@ create_keyboard_surface_button_callback (struct squeek_button *button,
bounds.width + 100,
bounds.height + 100);
cairo_clip (data->cr);
struct button_place place = {
.row = data->row,
.button = button,
};
render_button (data->renderer, data->cr, &place, FALSE);
render_key (data->renderer, data->cr, EEK_KEY(element), FALSE);
cairo_restore (data->cr);
}
static void
create_keyboard_surface_row_callback (struct squeek_row *row,
create_keyboard_surface_section_callback (EekElement *element,
gpointer user_data)
{
CreateKeyboardSurfaceCallbackData *data = user_data;
EekBounds bounds = squeek_row_get_bounds(row);
EekBounds bounds;
gint angle;
cairo_save (data->cr);
eek_element_get_bounds (element, &bounds);
cairo_translate (data->cr, bounds.x, bounds.y);
gint angle = squeek_row_get_angle (row);
angle = eek_section_get_angle (EEK_SECTION(element));
cairo_rotate (data->cr, angle * G_PI / 180);
data->row = row;
squeek_row_foreach(row, create_keyboard_surface_button_callback,
eek_container_foreach_child (EEK_CONTAINER(element),
create_keyboard_surface_key_callback,
data);
cairo_restore (data->cr);
}
static void
render_keyboard_surface (EekRenderer *renderer, struct squeek_view *view)
void
render_keyboard_surface (EekRenderer *renderer)
{
EekRendererPrivate *priv = eek_renderer_get_instance_private (renderer);
EekBounds bounds;
CreateKeyboardSurfaceCallbackData data;
EekColor foreground;
eek_renderer_get_foreground_color (renderer, priv->scontext, &foreground);
EekBounds bounds = squeek_view_get_bounds (level_keyboard_current(priv->keyboard));
eek_element_get_bounds (EEK_ELEMENT(priv->keyboard), &bounds);
CreateKeyboardSurfaceCallbackData data = {
.cr = cairo_create (priv->keyboard_surface),
.renderer = renderer,
.view = view,
};
data.cr = cairo_create (priv->keyboard_surface);
data.renderer = renderer;
/* Paint the background covering the entire widget area */
gtk_render_background (priv->scontext,
data.cr,
0, 0,
priv->allocation_width, priv->allocation_height);
gtk_render_frame (priv->scontext,
data.cr,
0, 0,
priv->allocation_width, priv->allocation_height);
cairo_save (data.cr);
cairo_scale (data.cr, priv->scale, priv->scale);
@ -173,9 +173,9 @@ render_keyboard_surface (EekRenderer *renderer, struct squeek_view *view)
foreground.blue,
foreground.alpha);
/* draw rows */
squeek_view_foreach(level_keyboard_current(priv->keyboard),
create_keyboard_surface_row_callback,
/* draw sections */
eek_container_foreach_child (EEK_CONTAINER(priv->keyboard),
create_keyboard_surface_section_callback,
&data);
cairo_restore (data.cr);
@ -183,52 +183,62 @@ render_keyboard_surface (EekRenderer *renderer, struct squeek_view *view)
}
static void
render_button_outline (EekRenderer *renderer,
render_key_outline (EekRenderer *renderer,
cairo_t *cr,
const struct squeek_button *button,
EekKey *key,
gboolean active)
{
EekRendererPrivate *priv = eek_renderer_get_instance_private (renderer);
EekOutline *outline;
EekBounds bounds;
guint oref;
EekColor foreground, background, gradient_start, gradient_end, border_color;
EekGradientType gradient_type;
gint border_width;
gint border_radius;
guint oref = squeek_button_get_oref(button);
outline = level_keyboard_get_outline (priv->keyboard, oref);
oref = eek_key_get_oref (key);
outline = eek_keyboard_get_outline (priv->keyboard, oref);
if (outline == NULL)
return;
EekBounds bounds = squeek_button_get_bounds(button);
eek_element_get_bounds(EEK_ELEMENT(key), &bounds);
gtk_style_context_set_state(priv->key_context,
active ? GTK_STATE_FLAG_ACTIVE : GTK_STATE_FLAG_NORMAL);
gtk_render_background (priv->key_context,
cr, 0, 0, bounds.width, bounds.height);
gtk_render_frame (priv->key_context,
cr, 0, 0, bounds.width, bounds.height);
gtk_style_context_set_state(priv->key_context, GTK_STATE_FLAG_NORMAL);
}
static void
render_button (EekRenderer *self,
render_key (EekRenderer *self,
cairo_t *cr,
struct button_place *place,
EekKey *key,
gboolean active)
{
EekRendererPrivate *priv = eek_renderer_get_instance_private (self);
EekOutline *outline;
cairo_surface_t *outline_surface;
EekBounds bounds;
guint oref;
EekSymbol *symbol;
GHashTable *outline_surface_cache;
PangoLayout *layout;
PangoRectangle extents = { 0, };
EekColor foreground;
guint oref = squeek_button_get_oref (place->button);
outline = level_keyboard_get_outline (priv->keyboard, oref);
if (!eek_key_has_label(key))
return;
oref = eek_key_get_oref (key);
outline = eek_keyboard_get_outline (priv->keyboard, oref);
if (outline == NULL)
return;
/* render outline */
EekBounds bounds = squeek_button_get_bounds(place->button);
eek_element_get_bounds (EEK_ELEMENT(key), &bounds);
if (active)
outline_surface_cache = priv->active_outline_surface_cache;
@ -252,8 +262,8 @@ render_button (EekRenderer *self,
cairo_paint (cr);
cairo_save (cr);
eek_renderer_apply_transformation_for_button (self, cr, place, 1.0, FALSE);
render_button_outline (self, cr, place->button, active);
eek_renderer_apply_transformation_for_key (self, cr, key, 1.0, FALSE);
render_key_outline (self, cr, key, active);
cairo_restore (cr);
cairo_destroy (cr);
@ -268,15 +278,15 @@ render_button (EekRenderer *self,
eek_renderer_get_foreground_color (self, priv->key_context, &foreground);
/* render icon (if any) */
struct squeek_symbol *symbol = squeek_button_get_symbol(place->button);
symbol = eek_key_get_symbol_with_fallback (key, 0, 0);
if (!symbol)
return;
if (squeek_symbol_get_icon_name (symbol)) {
if (eek_symbol_get_icon_name (symbol)) {
gint scale = priv->scale_factor;
cairo_surface_t *icon_surface =
eek_renderer_get_icon_surface (self,
squeek_symbol_get_icon_name (symbol),
eek_symbol_get_icon_name (symbol),
16 / priv->scale,
scale);
if (icon_surface) {
@ -285,8 +295,8 @@ render_button (EekRenderer *self,
cairo_save (cr);
cairo_translate (cr,
(bounds.width - (double)width / scale) / 2,
(bounds.height - (double)height / scale) / 2);
(bounds.width - width / scale) / 2,
(bounds.height - height / scale) / 2);
cairo_rectangle (cr, 0, 0, width, height);
cairo_clip (cr);
/* Draw the shape of the icon using the foreground color */
@ -304,14 +314,14 @@ render_button (EekRenderer *self,
/* render label */
layout = pango_cairo_create_layout (cr);
eek_renderer_real_render_button_label (self, layout, place->button);
eek_renderer_real_render_key_label (self, layout, key);
pango_layout_get_extents (layout, NULL, &extents);
cairo_save (cr);
cairo_move_to
(cr,
(bounds.width - (double)extents.width / PANGO_SCALE) / 2,
(bounds.height - (double)extents.height / PANGO_SCALE) / 2);
(bounds.width - extents.width / PANGO_SCALE) / 2,
(bounds.height - extents.height / PANGO_SCALE) / 2);
cairo_set_source_rgba (cr,
foreground.red,
@ -340,19 +350,22 @@ render_button (EekRenderer *self,
* normal keys for popups.
*/
void
eek_renderer_apply_transformation_for_button (EekRenderer *self,
eek_renderer_apply_transformation_for_key (EekRenderer *self,
cairo_t *cr,
struct button_place *place,
EekKey *key,
gdouble scale,
gboolean rotate)
{
EekElement *section;
EekBounds bounds, rotated_bounds;
gint angle;
gdouble s;
eek_renderer_get_button_bounds (self, place, &bounds, FALSE);
eek_renderer_get_button_bounds (self, place, &rotated_bounds, TRUE);
eek_renderer_get_key_bounds (self, key, &bounds, FALSE);
eek_renderer_get_key_bounds (self, key, &rotated_bounds, TRUE);
gint angle = squeek_row_get_angle (place->row);
section = eek_element_get_parent (EEK_ELEMENT(key));
angle = eek_section_get_angle (EEK_SECTION(section));
cairo_scale (cr, scale, scale);
if (rotate) {
@ -366,22 +379,23 @@ eek_renderer_apply_transformation_for_button (EekRenderer *self,
}
static void
eek_renderer_real_render_button_label (EekRenderer *self,
eek_renderer_real_render_key_label (EekRenderer *self,
PangoLayout *layout,
const struct squeek_button *button)
EekKey *key)
{
EekRendererPrivate *priv = eek_renderer_get_instance_private (self);
EekSymbol *symbol;
const gchar *label;
EekBounds bounds;
PangoFontDescription *font;
PangoLayoutLine *line;
gdouble scale;
struct squeek_symbol *symbol = squeek_button_get_symbol(button);
symbol = eek_key_get_symbol_with_fallback (key, 0, 0);
if (!symbol)
return;
label = squeek_symbol_get_label (symbol);
label = eek_symbol_get_label (symbol);
if (!label)
return;
@ -402,7 +416,7 @@ eek_renderer_real_render_button_label (EekRenderer *self,
pango_font_description_set_size (priv->font, (gint)round(size * 0.6));
}
EekBounds bounds = squeek_button_get_bounds(button);
eek_element_get_bounds (EEK_ELEMENT(key), &bounds);
scale = MIN((bounds.width - priv->border_width) / bounds.width,
(bounds.height - priv->border_width) / bounds.height);
@ -420,6 +434,19 @@ eek_renderer_real_render_button_label (EekRenderer *self,
PANGO_SCALE * bounds.width * scale);
}
static void
eek_renderer_real_render_key_outline (EekRenderer *self,
cairo_t *cr,
EekKey *key,
gdouble scale,
gboolean rotate)
{
cairo_save (cr);
eek_renderer_apply_transformation_for_key (self, cr, key, scale, rotate);
render_key_outline (self, cr, key, eek_key_is_pressed (key) || eek_key_is_locked (key));
cairo_restore (cr);
}
/*
* eek_renderer_real_render_key:
* @self: The renderer used to render the key
@ -432,16 +459,16 @@ eek_renderer_real_render_button_label (EekRenderer *self,
* Renders a key separately from the normal keyboard rendering.
*/
static void
eek_renderer_real_render_button (EekRenderer *self,
eek_renderer_real_render_key (EekRenderer *self,
cairo_t *cr,
struct button_place *place,
EekKey *key,
gdouble scale,
gboolean rotate)
{
EekRendererPrivate *priv = eek_renderer_get_instance_private (self);
EekBounds bounds;
eek_renderer_get_button_bounds (self, place, &bounds, rotate);
eek_renderer_get_key_bounds (self, key, &bounds, rotate);
cairo_save (cr);
/* Because this function is called separately from the keyboard rendering
@ -450,12 +477,8 @@ eek_renderer_real_render_button (EekRenderer *self,
cairo_scale (cr, priv->scale, priv->scale);
cairo_translate (cr, bounds.x, bounds.y);
eek_renderer_apply_transformation_for_button (self, cr, place, scale, rotate);
struct squeek_key *key = squeek_button_get_key(place->button);
render_button (
self, cr, place,
squeek_key_is_pressed(key) || squeek_key_is_locked (key)
);
eek_renderer_apply_transformation_for_key (self, cr, key, scale, rotate);
render_key (self, cr, key, eek_key_is_pressed (key) || eek_key_is_locked (key));
cairo_restore (cr);
}
@ -481,7 +504,7 @@ eek_renderer_real_render_keyboard (EekRenderer *self,
cairo_get_target (cr), 0, 0,
priv->allocation_width, priv->allocation_height);
render_keyboard_surface (self, priv->keyboard->views[priv->keyboard->level]);
render_keyboard_surface (self);
cairo_set_source_surface (cr, priv->keyboard_surface, 0.0, 0.0);
source = cairo_get_source (cr);
@ -501,6 +524,15 @@ eek_renderer_set_property (GObject *object,
EEK_RENDERER(object));
switch (prop_id) {
case PROP_KEYBOARD:
priv->keyboard = g_value_get_object (value);
g_object_ref (priv->keyboard);
priv->symbol_index_changed_handler =
g_signal_connect (priv->keyboard, "symbol-index-changed",
G_CALLBACK(on_symbol_index_changed),
object);
break;
case PROP_PCONTEXT:
priv->pcontext = g_value_get_object (value);
g_object_ref (priv->pcontext);
@ -521,7 +553,13 @@ eek_renderer_get_property (GObject *object,
GValue *value,
GParamSpec *pspec)
{
EekRendererPrivate *priv = eek_renderer_get_instance_private (
EEK_RENDERER(object));
switch (prop_id) {
case PROP_KEYBOARD:
g_value_set_object (value, priv->keyboard);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@ -535,6 +573,11 @@ eek_renderer_dispose (GObject *object)
EekRendererPrivate *priv = eek_renderer_get_instance_private (self);
if (priv->keyboard) {
if (g_signal_handler_is_connected (priv->keyboard,
priv->symbol_index_changed_handler))
g_signal_handler_disconnect (priv->keyboard,
priv->symbol_index_changed_handler);
g_object_unref (priv->keyboard);
priv->keyboard = NULL;
}
if (priv->pcontext) {
@ -569,7 +612,8 @@ eek_renderer_class_init (EekRendererClass *klass)
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
GParamSpec *pspec;
klass->render_button = eek_renderer_real_render_button;
klass->render_key_outline = eek_renderer_real_render_key_outline;
klass->render_key = eek_renderer_real_render_key;
klass->render_keyboard = eek_renderer_real_render_keyboard;
gobject_class->set_property = eek_renderer_set_property;
@ -577,6 +621,15 @@ eek_renderer_class_init (EekRendererClass *klass)
gobject_class->dispose = eek_renderer_dispose;
gobject_class->finalize = eek_renderer_finalize;
pspec = g_param_spec_object ("keyboard",
"Keyboard",
"Keyboard",
EEK_TYPE_KEYBOARD,
G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE);
g_object_class_install_property (gobject_class,
PROP_KEYBOARD,
pspec);
pspec = g_param_spec_object ("pango-context",
"Pango Context",
"Pango Context",
@ -622,6 +675,7 @@ eek_renderer_init (EekRenderer *self)
NULL,
(GDestroyNotify)cairo_surface_destroy);
priv->keyboard_surface = NULL;
priv->symbol_index_changed_handler = 0;
GtkIconTheme *theme = gtk_icon_theme_get_default ();
@ -667,18 +721,26 @@ invalidate (EekRenderer *renderer)
}
}
static void
on_symbol_index_changed (EekKeyboard *keyboard,
gint group,
gint level,
gpointer user_data)
{
EekRenderer *renderer = user_data;
invalidate (renderer);
}
EekRenderer *
eek_renderer_new (LevelKeyboard *keyboard,
eek_renderer_new (EekKeyboard *keyboard,
PangoContext *pcontext,
GtkStyleContext *scontext)
{
EekRenderer *renderer = g_object_new (EEK_TYPE_RENDERER,
return g_object_new (EEK_TYPE_RENDERER,
"keyboard", keyboard,
"pango-context", pcontext,
"style-context", scontext,
NULL);
EekRendererPrivate *priv = eek_renderer_get_instance_private (renderer);
priv->keyboard = keyboard;
return renderer;
}
void
@ -686,6 +748,7 @@ eek_renderer_set_allocation_size (EekRenderer *renderer,
gdouble width,
gdouble height)
{
EekBounds bounds;
gdouble scale;
g_return_if_fail (EEK_IS_RENDERER(renderer));
@ -698,7 +761,7 @@ eek_renderer_set_allocation_size (EekRenderer *renderer,
/* Calculate a scale factor to use when rendering the keyboard into the
available space. */
EekBounds bounds = squeek_view_get_bounds (level_keyboard_current(priv->keyboard));
eek_element_get_bounds (EEK_ELEMENT(priv->keyboard), &bounds);
gdouble w = (bounds.x * 2) + bounds.width;
gdouble h = (bounds.y * 2) + bounds.height;
@ -707,8 +770,8 @@ eek_renderer_set_allocation_size (EekRenderer *renderer,
priv->scale = scale;
/* Set the rendering offset in widget coordinates to center the keyboard */
priv->origin_x = (gint)floor((width - (scale * w)) / 2);
priv->origin_y = (gint)floor((height - (scale * h)) / 2);
priv->origin_x = (width - (scale * w)) / 2;
priv->origin_y = (height - (scale * h)) / 2;
invalidate (renderer);
}
@ -717,11 +780,13 @@ eek_renderer_get_size (EekRenderer *renderer,
gdouble *width,
gdouble *height)
{
EekBounds bounds;
g_return_if_fail (EEK_IS_RENDERER(renderer));
EekRendererPrivate *priv = eek_renderer_get_instance_private (renderer);
EekBounds bounds = squeek_view_get_bounds (level_keyboard_current(priv->keyboard));
eek_element_get_bounds (EEK_ELEMENT(priv->keyboard), &bounds);
if (width)
*width = bounds.width;
if (height)
@ -729,42 +794,45 @@ eek_renderer_get_size (EekRenderer *renderer,
}
void
eek_renderer_get_button_bounds (EekRenderer *renderer,
struct button_place *place,
eek_renderer_get_key_bounds (EekRenderer *renderer,
EekKey *key,
EekBounds *bounds,
gboolean rotate)
{
EekElement *section;
EekBounds section_bounds, keyboard_bounds;
gint angle = 0;
EekPoint points[4], min, max;
g_return_if_fail (EEK_IS_RENDERER(renderer));
g_return_if_fail (place);
g_return_if_fail (EEK_IS_KEY(key));
g_return_if_fail (bounds != NULL);
EekRendererPrivate *priv = eek_renderer_get_instance_private (renderer);
EekBounds button_bounds = squeek_button_get_bounds(place->button);
EekBounds row_bounds = squeek_row_get_bounds (place->row);
EekBounds view_bounds = squeek_view_get_bounds (level_keyboard_current(priv->keyboard));
section = eek_element_get_parent (EEK_ELEMENT(key));
eek_element_get_bounds (EEK_ELEMENT(key), bounds);
eek_element_get_bounds (section, &section_bounds);
eek_element_get_bounds (EEK_ELEMENT(priv->keyboard),
&keyboard_bounds);
if (!rotate) {
button_bounds.x += view_bounds.x + row_bounds.x;
button_bounds.y += view_bounds.y + row_bounds.y;
*bounds = button_bounds;
bounds->x += keyboard_bounds.x + section_bounds.x;
bounds->y += keyboard_bounds.y + section_bounds.y;
return;
}
points[0].x = button_bounds.x;
points[0].y = button_bounds.y;
points[1].x = points[0].x + button_bounds.width;
points[0].x = bounds->x;
points[0].y = bounds->y;
points[1].x = points[0].x + bounds->width;
points[1].y = points[0].y;
points[2].x = points[1].x;
points[2].y = points[1].y + button_bounds.height;
points[2].y = points[1].y + bounds->height;
points[3].x = points[0].x;
points[3].y = points[2].y;
if (rotate) {
angle = squeek_row_get_angle (place->row);
}
if (rotate)
angle = eek_section_get_angle (EEK_SECTION(section));
min = points[2];
max = points[0];
@ -779,8 +847,8 @@ eek_renderer_get_button_bounds (EekRenderer *renderer,
if (points[i].y > max.y)
max.y = points[i].y;
}
bounds->x = view_bounds.x + row_bounds.x + min.x;
bounds->y = view_bounds.y + row_bounds.y + min.y;
bounds->x = keyboard_bounds.x + section_bounds.x + min.x;
bounds->y = keyboard_bounds.y + section_bounds.y + min.y;
bounds->width = (max.x - min.x);
bounds->height = (max.y - min.y);
}
@ -814,6 +882,24 @@ eek_renderer_create_pango_layout (EekRenderer *renderer)
return pango_layout_new (priv->pcontext);
}
void
eek_renderer_render_key_outline (EekRenderer *renderer,
cairo_t *cr,
EekKey *key,
gdouble scale,
gboolean rotate)
{
g_return_if_fail (EEK_IS_RENDERER(renderer));
g_return_if_fail (EEK_IS_KEY(key));
g_return_if_fail (scale >= 0.0);
EEK_RENDERER_GET_CLASS(renderer)->render_key_outline (renderer,
cr,
key,
scale,
rotate);
}
cairo_surface_t *
eek_renderer_get_icon_surface (EekRenderer *renderer,
const gchar *icon_name,
@ -849,18 +935,18 @@ eek_renderer_get_icon_surface (EekRenderer *renderer,
}
void
eek_renderer_render_button (EekRenderer *renderer,
eek_renderer_render_key (EekRenderer *renderer,
cairo_t *cr,
struct button_place *place,
EekKey *key,
gdouble scale,
gboolean rotate)
{
g_return_if_fail (EEK_IS_RENDERER(renderer));
g_return_if_fail (place);
g_return_if_fail (EEK_IS_KEY(key));
g_return_if_fail (scale >= 0.0);
EEK_RENDERER_GET_CLASS(renderer)->
render_button (renderer, cr, place, scale, rotate);
render_key (renderer, cr, key, scale, rotate);
}
void
@ -903,6 +989,7 @@ eek_renderer_get_foreground_color (EekRenderer *renderer,
g_return_if_fail (EEK_IS_RENDERER(renderer));
g_return_if_fail (color);
EekRendererPrivate *priv = eek_renderer_get_instance_private (renderer);
GtkStateFlags flags = GTK_STATE_FLAG_NORMAL;
GdkRGBA gcolor;
@ -913,20 +1000,33 @@ eek_renderer_get_foreground_color (EekRenderer *renderer,
color->alpha = gcolor.alpha;
}
struct _FindKeyByPositionCallbackData {
EekPoint point;
EekPoint origin;
gint angle;
EekKey *key;
EekRenderer *renderer;
};
typedef struct _FindKeyByPositionCallbackData FindKeyByPositionCallbackData;
static gboolean
sign (EekPoint *p1, EekPoint *p2, EekPoint *p3)
{
// FIXME: what is this actually checking?
return (p1->x - p3->x) * (p2->y - p3->y) -
(p2->x - p3->x) * (p1->y - p3->y);
}
uint32_t
eek_are_bounds_inside (EekBounds bounds, EekPoint point, EekPoint origin, int32_t angle)
static gint
find_key_by_position_key_callback (EekElement *element,
gpointer user_data)
{
FindKeyByPositionCallbackData *data = user_data;
EekBounds bounds;
EekPoint points[4];
gboolean b1, b2, b3;
eek_element_get_bounds (element, &bounds);
points[0].x = bounds.x;
points[0].y = bounds.y;
points[1].x = points[0].x + bounds.width;
@ -937,27 +1037,53 @@ eek_are_bounds_inside (EekBounds bounds, EekPoint point, EekPoint origin, int32_
points[3].y = points[2].y;
for (uint i = 0; i < G_N_ELEMENTS(points); i++) {
eek_point_rotate (&points[i], angle);
points[i].x += origin.x;
points[i].y += origin.y;
eek_point_rotate (&points[i], data->angle);
points[i].x += data->origin.x;
points[i].y += data->origin.y;
}
b1 = sign (&point, &points[0], &points[1]) < 0.0;
b2 = sign (&point, &points[1], &points[2]) < 0.0;
b3 = sign (&point, &points[2], &points[0]) < 0.0;
b1 = sign (&data->point, &points[0], &points[1]) < 0.0;
b2 = sign (&data->point, &points[1], &points[2]) < 0.0;
b3 = sign (&data->point, &points[2], &points[0]) < 0.0;
if (b1 == b2 && b2 == b3) {
return 1;
data->key = EEK_KEY(element);
if (eek_key_has_label(data->key))
return 0;
}
b1 = sign (&point, &points[2], &points[3]) < 0.0;
b2 = sign (&point, &points[3], &points[0]) < 0.0;
b3 = sign (&point, &points[0], &points[2]) < 0.0;
b1 = sign (&data->point, &points[2], &points[3]) < 0.0;
b2 = sign (&data->point, &points[3], &points[0]) < 0.0;
b3 = sign (&data->point, &points[0], &points[2]) < 0.0;
if (b1 == b2 && b2 == b3) {
return 1;
data->key = EEK_KEY(element);
if (eek_key_has_label(data->key))
return 0;
}
return 0;
return -1;
}
static gint
find_key_by_position_section_callback (EekElement *element,
gpointer user_data)
{
FindKeyByPositionCallbackData *data = user_data;
EekBounds bounds;
EekPoint origin;
origin = data->origin;
eek_element_get_bounds (element, &bounds);
data->origin.x += bounds.x;
data->origin.y += bounds.y;
data->angle = eek_section_get_angle (EEK_SECTION(element));
eek_container_find (EEK_CONTAINER(element),
find_key_by_position_key_callback,
data);
data->origin = origin;
return data->key ? 0 : -1;
}
/**
@ -969,19 +1095,38 @@ eek_are_bounds_inside (EekBounds bounds, EekPoint point, EekPoint origin, int32_
* Return value: the key located at the position x, y in widget coordinates, or
* NULL if no key can be found at that location
**/
struct squeek_button *
eek_renderer_find_button_by_position (EekRenderer *renderer,
struct squeek_view *view,
EekKey *
eek_renderer_find_key_by_position (EekRenderer *renderer,
gdouble x,
gdouble y)
{
EekBounds bounds;
FindKeyByPositionCallbackData data;
g_return_val_if_fail (EEK_IS_RENDERER(renderer), NULL);
EekRendererPrivate *priv = eek_renderer_get_instance_private (renderer);
eek_element_get_bounds (EEK_ELEMENT(priv->keyboard), &bounds);
EekPoint point = {
.x = (x - priv->origin_x)/priv->scale,
.y = (y - priv->origin_y)/priv->scale,
};
return squeek_view_find_button_by_position(view, point);
/* Transform from widget coordinates to keyboard coordinates */
x = (x - priv->origin_x)/priv->scale - bounds.x;
y = (y - priv->origin_y)/priv->scale - bounds.y;
if (x < 0 ||
y < 0 ||
x > bounds.width ||
y > bounds.height)
return NULL;
data.point.x = x;
data.point.y = y;
data.origin.x = 0;
data.origin.y = 0;
data.key = NULL;
data.renderer = renderer;
eek_container_find (EEK_CONTAINER(priv->keyboard),
find_key_by_position_section_callback,
&data);
return data.key;
}

View File

@ -21,10 +21,9 @@
#ifndef EEK_RENDERER_H
#define EEK_RENDERER_H 1
#include <gtk/gtk.h>
#include <pango/pangocairo.h>
#include "eek-keyboard.h"
#include "eek-keysym.h"
#include "eek-types.h"
G_BEGIN_DECLS
@ -36,9 +35,15 @@ struct _EekRendererClass
{
GObjectClass parent_class;
void (* render_button) (EekRenderer *self,
void (* render_key_outline) (EekRenderer *self,
cairo_t *cr,
struct button_place *place,
EekKey *key,
gdouble scale,
gboolean rotate);
void (* render_key) (EekRenderer *self,
cairo_t *cr,
EekKey *key,
gdouble scale,
gboolean rotate);
@ -56,7 +61,7 @@ struct _EekRendererClass
};
GType eek_renderer_get_type (void) G_GNUC_CONST;
EekRenderer *eek_renderer_new (LevelKeyboard *keyboard,
EekRenderer *eek_renderer_new (EekKeyboard *keyboard,
PangoContext *pcontext,
GtkStyleContext *scontext);
void eek_renderer_set_allocation_size
@ -66,8 +71,8 @@ void eek_renderer_set_allocation_size
void eek_renderer_get_size (EekRenderer *renderer,
gdouble *width,
gdouble *height);
void eek_renderer_get_button_bounds (EekRenderer *renderer,
struct button_place *button,
void eek_renderer_get_key_bounds (EekRenderer *renderer,
EekKey *key,
EekBounds *bounds,
gboolean rotate);
@ -77,9 +82,20 @@ void eek_renderer_set_scale_factor (EekRenderer *renderer,
PangoLayout *eek_renderer_create_pango_layout
(EekRenderer *renderer);
void eek_renderer_render_button (EekRenderer *renderer,
void eek_renderer_render_key_label (EekRenderer *renderer,
PangoLayout *layout,
EekKey *key);
void eek_renderer_render_key_outline
(EekRenderer *renderer,
cairo_t *cr,
struct button_place *place,
EekKey *key,
gdouble scale,
gboolean rotate);
void eek_renderer_render_key (EekRenderer *renderer,
cairo_t *cr,
EekKey *key,
gdouble scale,
gboolean rotate);
@ -103,12 +119,14 @@ void eek_renderer_get_foreground_color
EekColor *color);
void eek_renderer_set_border_width (EekRenderer *renderer,
gdouble border_width);
struct squeek_button *eek_renderer_find_button_by_position(EekRenderer *renderer, struct squeek_view *view,
EekKey *eek_renderer_find_key_by_position
(EekRenderer *renderer,
gdouble x,
gdouble y);
void eek_renderer_apply_transformation_for_button
void eek_renderer_apply_transformation_for_key
(EekRenderer *renderer,
cairo_t *cr, struct button_place *place,
cairo_t *cr,
EekKey *key,
gdouble scale,
gboolean rotate);

View File

@ -18,12 +18,468 @@
* 02110-1301 USA
*/
/**
* SECTION:eek-section
* @short_description: Base class of a section
* @see_also: #EekKey
*
* The #EekSectionClass class represents a section, which consists
* of one or more keys of the #EekKeyClass class.
*/
#include "config.h"
#include "eek-section.h"
#include <string.h>
EekBounds eek_get_outline_size(LevelKeyboard *keyboard, uint32_t oref) {
EekOutline *outline = level_keyboard_get_outline (keyboard, oref);
#include "eek-keyboard.h"
#include "eek-section.h"
#include "eek-key.h"
#include "eek-symbol.h"
enum {
PROP_0,
PROP_ANGLE,
PROP_LAST
};
enum {
KEY_LOCKED,
KEY_UNLOCKED,
LAST_SIGNAL
};
static guint signals[LAST_SIGNAL] = { 0, };
struct _EekRow
{
gint num_columns;
EekOrientation orientation;
};
typedef struct _EekRow EekRow;
typedef struct _EekSectionPrivate
{
gint angle;
EekRow row;
EekModifierType modifiers;
} EekSectionPrivate;
G_DEFINE_TYPE_WITH_PRIVATE (EekSection, eek_section, EEK_TYPE_CONTAINER)
static gint
eek_section_real_get_n_rows (EekSection *self)
{
return 1;
}
static void
eek_section_real_add_row (EekSection *self,
gint num_columns,
EekOrientation orientation)
{
EekSectionPrivate *priv = (EekSectionPrivate*)eek_section_get_instance_private (self);
priv->row.num_columns = num_columns;
priv->row.orientation = orientation;
/*
row = g_slice_new (EekRow);
row->num_columns = num_columns;
row->orientation = orientation;
priv->rows = g_slist_append (priv->rows, row);*/
}
static void
eek_section_real_get_row (EekSection *self,
gint index,
gint *num_columns,
EekOrientation *orientation)
{
EekSectionPrivate *priv = (EekSectionPrivate*)eek_section_get_instance_private (self);
EekRow *row = &priv->row;
if (num_columns) {
*num_columns = row->num_columns;
}
if (orientation) {
*orientation = row->orientation;
}
}
static void
on_locked (EekKey *key,
EekSection *section)
{
g_signal_emit (section, signals[KEY_LOCKED], 0, key);
}
static void
on_unlocked (EekKey *key,
EekSection *section)
{
g_signal_emit (section, signals[KEY_UNLOCKED], 0, key);
}
static EekKey *
eek_section_real_create_key (EekSection *self,
const gchar *name,
gint keycode)
{
EekSectionPrivate *priv = (EekSectionPrivate*)eek_section_get_instance_private (self);
EekRow *row = &priv->row;
row->num_columns++;
EekKey *key = (EekKey*)g_object_new (EEK_TYPE_KEY,
"name", name,
"keycode", keycode,
NULL);
g_return_val_if_fail (key, NULL);
EEK_CONTAINER_GET_CLASS(self)->add_child (EEK_CONTAINER(self),
EEK_ELEMENT(key));
return key;
}
static void
set_level_from_modifiers (EekSection *self)
{
EekSectionPrivate *priv = eek_section_get_instance_private (self);
EekKeyboard *keyboard;
EekModifierType num_lock_mask;
gint level = -1;
keyboard = EEK_KEYBOARD(eek_element_get_parent (EEK_ELEMENT(self)));
num_lock_mask = eek_keyboard_get_num_lock_mask (keyboard);
if (priv->modifiers & num_lock_mask)
level = 1;
eek_element_set_level (EEK_ELEMENT(self), level);
}
static void
eek_section_real_key_pressed (EekSection *self, EekKey *key)
{
EekSectionPrivate *priv = eek_section_get_instance_private (self);
EekSymbol *symbol;
EekKeyboard *keyboard;
EekModifierBehavior behavior;
EekModifierType modifier;
symbol = eek_key_get_symbol_with_fallback (key, 0, 0);
if (!symbol)
return;
keyboard = EEK_KEYBOARD(eek_element_get_parent (EEK_ELEMENT(self)));
behavior = eek_keyboard_get_modifier_behavior (keyboard);
modifier = eek_symbol_get_modifier_mask (symbol);
if (behavior == EEK_MODIFIER_BEHAVIOR_NONE) {
priv->modifiers |= modifier;
set_level_from_modifiers (self);
}
}
static void
eek_section_real_key_released (EekSection *self, EekKey *key)
{
EekSectionPrivate *priv = eek_section_get_instance_private (self);
EekSymbol *symbol;
EekKeyboard *keyboard;
EekModifierBehavior behavior;
EekModifierType modifier;
symbol = eek_key_get_symbol_with_fallback (key, 0, 0);
if (!symbol)
return;
keyboard = EEK_KEYBOARD(eek_element_get_parent (EEK_ELEMENT(self)));
behavior = eek_keyboard_get_modifier_behavior (keyboard);
modifier = eek_symbol_get_modifier_mask (symbol);
switch (behavior) {
case EEK_MODIFIER_BEHAVIOR_NONE:
priv->modifiers &= ~modifier;
break;
case EEK_MODIFIER_BEHAVIOR_LOCK:
priv->modifiers ^= modifier;
break;
case EEK_MODIFIER_BEHAVIOR_LATCH:
priv->modifiers = (priv->modifiers ^ modifier) & modifier;
break;
}
set_level_from_modifiers (self);
}
static void
eek_section_finalize (GObject *object)
{
EekSection *self = EEK_SECTION (object);
EekSectionPrivate *priv = (EekSectionPrivate*)eek_section_get_instance_private (self);
G_OBJECT_CLASS (eek_section_parent_class)->finalize (object);
}
static void
eek_section_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
switch (prop_id) {
case PROP_ANGLE:
eek_section_set_angle (EEK_SECTION(object),
g_value_get_int (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
eek_section_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
switch (prop_id) {
case PROP_ANGLE:
g_value_set_int (value, eek_section_get_angle (EEK_SECTION(object)));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
eek_section_real_child_added (EekContainer *self,
EekElement *element)
{
g_signal_connect (element, "locked", G_CALLBACK(on_locked), self);
g_signal_connect (element, "unlocked", G_CALLBACK(on_unlocked), self);
}
static void
eek_section_real_child_removed (EekContainer *self,
EekElement *element)
{
g_signal_handlers_disconnect_by_func (element, on_locked, self);
g_signal_handlers_disconnect_by_func (element, on_unlocked, self);
}
static void
eek_section_class_init (EekSectionClass *klass)
{
EekContainerClass *container_class = EEK_CONTAINER_CLASS (klass);
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
GParamSpec *pspec;
klass->get_n_rows = eek_section_real_get_n_rows;
klass->add_row = eek_section_real_add_row;
klass->get_row = eek_section_real_get_row;
klass->create_key = eek_section_real_create_key;
/* signals */
klass->key_pressed = eek_section_real_key_pressed;
klass->key_released = eek_section_real_key_released;
container_class->child_added = eek_section_real_child_added;
container_class->child_removed = eek_section_real_child_removed;
gobject_class->set_property = eek_section_set_property;
gobject_class->get_property = eek_section_get_property;
gobject_class->finalize = eek_section_finalize;
/**
* EekSection:angle:
*
* The rotation angle of #EekSection.
*/
pspec = g_param_spec_int ("angle",
"Angle",
"Rotation angle of the section",
-360, 360, 0,
G_PARAM_READWRITE);
g_object_class_install_property (gobject_class,
PROP_ANGLE,
pspec);
/**
* EekSection::key-locked:
* @section: an #EekSection
* @key: an #EekKey
*
* The ::key-locked signal is emitted each time a key in @section
* is shifted to the locked state.
*/
signals[KEY_LOCKED] =
g_signal_new (I_("key-locked"),
G_TYPE_FROM_CLASS(gobject_class),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET(EekSectionClass, key_locked),
NULL,
NULL,
g_cclosure_marshal_VOID__OBJECT,
G_TYPE_NONE,
1,
EEK_TYPE_KEY);
/**
* EekSection::key-unlocked:
* @section: an #EekSection
* @key: an #EekKey
*
* The ::key-unlocked signal is emitted each time a key in @section
* is shifted to the unlocked state.
*/
signals[KEY_UNLOCKED] =
g_signal_new (I_("key-unlocked"),
G_TYPE_FROM_CLASS(gobject_class),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET(EekSectionClass, key_unlocked),
NULL,
NULL,
g_cclosure_marshal_VOID__OBJECT,
G_TYPE_NONE,
1,
EEK_TYPE_KEY);
}
static void
eek_section_init (EekSection *self)
{
/* void */
}
/**
* eek_section_set_angle:
* @section: an #EekSection
* @angle: rotation angle
*
* Set rotation angle of @section to @angle.
*/
void
eek_section_set_angle (EekSection *section,
gint angle)
{
g_return_if_fail (EEK_IS_SECTION(section));
EekSectionPrivate *priv = eek_section_get_instance_private (section);
if (priv->angle != angle) {
priv->angle = angle;
g_object_notify (G_OBJECT(section), "angle");
}
}
/**
* eek_section_get_angle:
* @section: an #EekSection
*
* Get rotation angle of @section.
*/
gint
eek_section_get_angle (EekSection *section)
{
g_return_val_if_fail (EEK_IS_SECTION(section), -1);
EekSectionPrivate *priv = eek_section_get_instance_private (section);
return priv->angle;
}
/**
* eek_section_get_n_rows:
* @section: an #EekSection
*
* Get the number of rows in @section.
*/
gint
eek_section_get_n_rows (EekSection *section)
{
g_return_val_if_fail (EEK_IS_SECTION(section), -1);
return EEK_SECTION_GET_CLASS(section)->get_n_rows (section);
}
/**
* eek_section_add_row:
* @section: an #EekSection
* @num_columns: the number of column in the row
* @orientation: #EekOrientation of the row
*
* Add a row which has @num_columns columns and whose orientation is
* @orientation to @section.
*/
void
eek_section_add_row (EekSection *section,
gint num_columns,
EekOrientation orientation)
{
g_return_if_fail (EEK_IS_SECTION(section));
EEK_SECTION_GET_CLASS(section)->add_row (section,
num_columns,
orientation);
}
/**
* eek_section_get_row:
* @section: an #EekSection
* @index: the index of row
* @num_columns: pointer where the number of column in the row will be stored
* @orientation: pointer where #EekOrientation of the row will be stored
*
* Get the information about the @index-th row in @section.
*/
void
eek_section_get_row (EekSection *section,
gint index,
gint *num_columns,
EekOrientation *orientation)
{
g_return_if_fail (EEK_IS_SECTION(section));
EEK_SECTION_GET_CLASS(section)->get_row (section,
index,
num_columns,
orientation);
}
/**
* eek_section_create_key:
* @section: an #EekSection
* @name: a name
* @keycode: a keycode
* @column: the column index of the key
* @row: the row index of the key
*
* Create an #EekKey instance and append it to @section. This
* function is rarely called by application but called by #EekLayout
* implementation.
*/
EekKey *
eek_section_create_key (EekSection *section,
const gchar *name,
gint keycode)
{
g_return_val_if_fail (EEK_IS_SECTION(section), NULL);
return EEK_SECTION_GET_CLASS(section)->create_key (section,
name,
keycode);
}
const double keyspacing = 4.0;
struct keys_info {
uint count;
double total_width;
double biggest_height;
};
static void
keysizer(EekElement *element, gpointer user_data)
{
EekKey *key = EEK_KEY(element);
EekKeyboard *keyboard = EEK_KEYBOARD(user_data);
uint oref = eek_key_get_oref (key);
EekOutline *outline = eek_keyboard_get_outline (keyboard, oref);
if (outline && outline->num_points > 0) {
double minx = outline->points[0].x;
double maxx = minx;
@ -43,14 +499,65 @@ EekBounds eek_get_outline_size(LevelKeyboard *keyboard, uint32_t oref) {
maxy = p.y;
}
}
EekBounds key_bounds = {
.height = maxy - miny,
.width = maxx - minx,
.x = 0,
.y = 0,
};
return key_bounds;
EekBounds key_bounds = {0};
eek_element_get_bounds(element, &key_bounds);
key_bounds.height = maxy - miny;
key_bounds.width = maxx - minx;
eek_element_set_bounds(element, &key_bounds);
}
EekBounds bounds = {0, 0, 0, 0};
return bounds;
}
static void
keycounter (EekElement *element, gpointer user_data)
{
EekKey *key = EEK_KEY(element);
/* Skip keys without labels for the current level. This causes those
keys to be hidden in the visible layout. */
if (!eek_key_has_label(key))
return;
struct keys_info *data = user_data;
data->count++;
EekBounds key_bounds = {0};
eek_element_get_bounds(element, &key_bounds);
data->total_width += key_bounds.width;
if (key_bounds.height > data->biggest_height) {
data->biggest_height = key_bounds.height;
}
}
static void
keyplacer(EekElement *element, gpointer user_data)
{
EekKey *key = EEK_KEY(element);
/* Skip keys without labels for the current level. */
if (!eek_key_has_label(key))
return;
double *current_offset = user_data;
EekBounds key_bounds = {0};
eek_element_get_bounds(element, &key_bounds);
key_bounds.x = *current_offset;
key_bounds.y = 0;
eek_element_set_bounds(element, &key_bounds);
*current_offset += key_bounds.width + keyspacing;
}
void
eek_section_place_keys(EekSection *section, EekKeyboard *keyboard)
{
eek_container_foreach_child(EEK_CONTAINER(section), keysizer, keyboard);
struct keys_info keyinfo = {0};
eek_container_foreach_child(EEK_CONTAINER(section), keycounter, &keyinfo);
EekBounds section_bounds = {0};
eek_element_get_bounds(EEK_ELEMENT(section), &section_bounds);
double key_offset = (section_bounds.width - (keyinfo.total_width + (keyinfo.count - 1) * keyspacing)) / 2;
eek_container_foreach_child(EEK_CONTAINER(section), keyplacer, &key_offset);
section_bounds.height = keyinfo.biggest_height;
eek_element_set_bounds(EEK_ELEMENT(section), &section_bounds);
}

View File

@ -25,10 +25,86 @@
#ifndef EEK_SECTION_H
#define EEK_SECTION_H 1
/* Contains row-related functions that couldn't be done in Rust easily. */
#include <glib-object.h>
#include "eek-keyboard.h"
#include "src/layout.h"
#include "eek-container.h"
#include "eek-types.h"
G_BEGIN_DECLS
#define EEK_TYPE_SECTION (eek_section_get_type())
G_DECLARE_DERIVABLE_TYPE(EekSection, eek_section, EEK, SECTION, EekContainer)
/**
* EekSectionClass:
* @get_n_rows: virtual function for getting the number of rows in the section
* @add_row: virtual function for adding a new row to the section
* @get_row: virtual function for accessing a row in the section
* @create_key: virtual function for creating key in the section
* @key_pressed: class handler for #EekSection::key-pressed signal
* @key_released: class handler for #EekSection::key-released signal
* @key_locked: class handler for #EekSection::key-locked signal
* @key_unlocked: class handler for #EekSection::key-unlocked signal
* @key_cancelled: class handler for #EekSection::key-cancelled signal
*/
struct _EekSectionClass
{
/*< private >*/
EekContainerClass parent_class;
/*< public >*/
gint (* get_n_rows) (EekSection *self);
void (* add_row) (EekSection *self,
gint num_columns,
EekOrientation orientation);
void (* get_row) (EekSection *self,
gint index,
gint *num_columns,
EekOrientation *orientation);
EekKey *(* create_key) (EekSection *self,
const gchar *name,
gint keycode);
/* signals */
void (* key_pressed) (EekSection *self,
EekKey *key);
void (* key_released) (EekSection *self,
EekKey *key);
void (* key_locked) (EekSection *self,
EekKey *key);
void (* key_unlocked) (EekSection *self,
EekKey *key);
void (* key_cancelled) (EekSection *self,
EekKey *key);
/*< private >*/
/* padding */
gpointer pdummy[19];
};
GType eek_section_get_type (void) G_GNUC_CONST;
void eek_section_set_angle (EekSection *section,
gint angle);
gint eek_section_get_angle (EekSection *section);
gint eek_section_get_n_rows (EekSection *section);
void eek_section_add_row (EekSection *section,
gint num_columns,
EekOrientation orientation);
void eek_section_get_row (EekSection *section,
gint index,
gint *num_columns,
EekOrientation *orientation);
EekKey *eek_section_create_key (EekSection *section,
const gchar *name,
gint keycode);
EekKey *eek_section_find_key_by_keycode (EekSection *section,
guint keycode);
void eek_section_place_keys (EekSection *section, EekKeyboard *keyboard);
G_END_DECLS
#endif /* EEK_SECTION_H */

89
eek/eek-serializable.c Normal file
View File

@ -0,0 +1,89 @@
/*
* Copyright (C) 2008-2010 Peng Huang <shawn.p.huang@gmail.com>
* Copyright (C) 2008-2010 Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
/**
* SECTION:eek-serializable
* @short_description: Interface which provides object serialization
* into #GVariant
*
* The #EekSerializableIface interface defines serialize/deserialize
* method.
*/
#include "config.h"
#include "eek-serializable.h"
GType
eek_serializable_get_type (void)
{
static GType iface_type = 0;
if (iface_type == 0) {
static GTypeInfo info = {
.class_size = sizeof (EekSerializableIface)
};
iface_type = g_type_register_static (G_TYPE_INTERFACE,
"EekSerializable",
&info, 0);
}
return iface_type;
}
GVariant *
eek_serializable_serialize (EekSerializable *object)
{
GVariantBuilder builder;
g_return_val_if_fail (EEK_IS_SERIALIZABLE (object), FALSE);
g_variant_builder_init (&builder, G_VARIANT_TYPE_TUPLE);
g_variant_builder_add (&builder, "s", g_type_name (G_OBJECT_TYPE (object)));
EEK_SERIALIZABLE_GET_IFACE (object)->serialize (object, &builder);
return g_variant_builder_end (&builder);
}
EekSerializable *
eek_serializable_deserialize (GVariant *variant)
{
gchar *type_name = NULL;
GType type;
EekSerializable *object;
gsize index = 0;
g_return_val_if_fail (variant != NULL, NULL);
g_variant_get_child (variant, index++, "&s", &type_name);
type = g_type_from_name (type_name);
g_return_val_if_fail (g_type_is_a (type, EEK_TYPE_SERIALIZABLE), NULL);
object = g_object_new (type, NULL);
index = EEK_SERIALIZABLE_GET_IFACE (object)->deserialize (object,
variant,
index);
if (index < 0) {
g_object_unref (object);
g_return_val_if_reached (NULL);
}
return object;
}

66
eek/eek-serializable.h Normal file
View File

@ -0,0 +1,66 @@
/*
* Copyright (C) 2011 Daiki Ueno <ueno@unixuser.org>
* Copyright (C) 2011 Red Hat, Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#if !defined(__EEK_H_INSIDE__) && !defined(EEK_COMPILATION)
#error "Only <eek/eek.h> can be included directly."
#endif
#ifndef EEK_SERIALIZABLE_H
#define EEK_SERIALIZABLE_H 1
#include <glib-object.h>
G_BEGIN_DECLS
#define EEK_TYPE_SERIALIZABLE (eek_serializable_get_type())
#define EEK_SERIALIZABLE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EEK_TYPE_SERIALIZABLE, EekSerializable))
#define EEK_IS_SERIALIZABLE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EEK_TYPE_SERIALIZABLE))
#define EEK_SERIALIZABLE_GET_IFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), EEK_TYPE_SERIALIZABLE, EekSerializableIface))
typedef struct _EekSerializable EekSerializable;
typedef struct _EekSerializableIface EekSerializableIface;
/**
* EekSerializableIface:
*
* @serialize: virtual function for serializing object into #GVariant
* @deserialize: virtual function for deserializing object from #GVariant
*/
struct _EekSerializableIface
{
/*< private >*/
GTypeInterface parent_iface;
void (* serialize) (EekSerializable *object,
GVariantBuilder *builder);
gsize (* deserialize) (EekSerializable *object,
GVariant *variant,
gsize index);
/*< private >*/
/* padding */
gpointer pdummy[24];
};
GType eek_serializable_get_type (void);
GVariant *eek_serializable_serialize (EekSerializable *object);
EekSerializable *eek_serializable_deserialize (GVariant *variant);
G_END_DECLS
#endif /* EEK_SERIALIZABLE_H */

99
eek/eek-symbol-matrix.c Normal file
View File

@ -0,0 +1,99 @@
/*
* Copyright (C) 2011 Daiki Ueno <ueno@unixuser.org>
* Copyright (C) 2011 Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301 USA
*/
#include "eek-symbol-matrix.h"
EekSymbolMatrix *
eek_symbol_matrix_new (gint num_groups,
gint num_levels)
{
EekSymbolMatrix *matrix = g_slice_new (EekSymbolMatrix);
matrix->num_groups = num_groups;
matrix->num_levels = num_levels;
matrix->data = g_slice_alloc0 (sizeof (EekSymbol *) *
num_groups * num_levels);
return matrix;
}
EekSymbolMatrix *
eek_symbol_matrix_copy (const EekSymbolMatrix *matrix)
{
EekSymbolMatrix *retval;
guint num_symbols = matrix->num_groups * matrix->num_levels;
retval = g_slice_dup (EekSymbolMatrix, matrix);
retval->data = g_slice_copy (sizeof (EekSymbol *) * num_symbols,
matrix->data);
// FIXME: do a deep copy over the data in EekSymbol
return retval;
}
void
eek_symbol_matrix_free (EekSymbolMatrix *matrix)
{
guint num_symbols = matrix->num_groups * matrix->num_levels;
g_slice_free1 (sizeof (EekSymbol *) * num_symbols, matrix->data);
g_slice_free (EekSymbolMatrix, matrix);
}
GType
eek_symbol_matrix_get_type (void)
{
static GType our_type = 0;
if (our_type == 0)
our_type =
g_boxed_type_register_static ("EekSymbolMatrix",
(GBoxedCopyFunc)eek_symbol_matrix_copy,
(GBoxedFreeFunc)eek_symbol_matrix_free);
return our_type;
}
void
eek_symbol_matrix_set_symbol (EekSymbolMatrix *matrix,
gint group,
gint level,
EekSymbol *symbol)
{
g_return_if_fail (group >= 0 && group < matrix->num_groups);
g_return_if_fail (level >= 0 && level < matrix->num_levels);
matrix->data[group * matrix->num_levels + level] = g_object_ref (symbol);
}
/**
* eek_symbol_matrix_get_symbol:
* @matrix: an #EekSymbolMatrix
* @group: group index of @matrix
* @level: level index of @matrix
*
* Get an #EekSymbol stored in the cell selected by (@group, @level)
* in @matrix.
*
* Return value: (transfer none): an #EekSymbol.
*/
EekSymbol *
eek_symbol_matrix_get_symbol (EekSymbolMatrix *matrix,
gint group,
gint level)
{
g_return_val_if_fail (group >= 0 && group < matrix->num_groups, NULL);
g_return_val_if_fail (level >= 0 && level < matrix->num_levels, NULL);
return matrix->data[group * matrix->num_levels + level];
}

62
eek/eek-symbol-matrix.h Normal file
View File

@ -0,0 +1,62 @@
/*
* Copyright (C) 2011 Daiki Ueno <ueno@unixuser.org>
* Copyright (C) 2011 Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301 USA
*/
#ifndef EEK_SYMBOL_MATRIX_H
#define EEK_SYMBOL_MATRIX_H 1
#include "eek-symbol.h"
G_BEGIN_DECLS
/**
* EekSymbolMatrix:
* @data: array of symbols
* @num_groups: the number of groups (rows)
* @num_levels: the number of levels (columns)
*
* Symbol matrix of a key.
*/
struct _EekSymbolMatrix
{
/*< public >*/
gint num_groups;
gint num_levels;
EekSymbol **data;
};
#define EEK_TYPE_SYMBOL_MATRIX (eek_symbol_matrix_get_type ())
GType eek_symbol_matrix_get_type (void) G_GNUC_CONST;
EekSymbolMatrix *eek_symbol_matrix_new (gint num_groups,
gint num_levels);
EekSymbolMatrix *eek_symbol_matrix_copy (const EekSymbolMatrix *matrix);
void eek_symbol_matrix_free (EekSymbolMatrix *matrix);
void eek_symbol_matrix_set_symbol
(EekSymbolMatrix *matrix,
gint group,
gint level,
EekSymbol *symbol);
EekSymbol *eek_symbol_matrix_get_symbol
(EekSymbolMatrix *matrix,
gint group,
gint level);
G_END_DECLS
#endif /* EEK_SYMBOL_MATRIX_H */

View File

@ -30,15 +30,42 @@
#include "eek-symbol.h"
#include "eek-enumtypes.h"
void
eek_symbol_destroy (EekSymbol *priv)
{
g_free (priv->name);
g_free (priv->label);
g_free (priv->icon_name);
g_free (priv->tooltip);
g_free(priv->text);
g_free(priv);
}
EekSymbol *
eek_symbol_new (const gchar *name)
{
EekSymbol *self = g_new0(EekSymbol, 1);
self->name = g_strdup (name);
eek_symbol_set_name(self, name);
self->category = EEK_SYMBOL_CATEGORY_UNKNOWN;
return self;
}
void
eek_symbol_set_name (EekSymbol *symbol,
const gchar *name)
{
g_free (symbol->name);
symbol->name = g_strdup (name);
}
const gchar *
eek_symbol_get_name (EekSymbol *symbol)
{
if (symbol->name == NULL || *symbol->name == '\0')
return NULL;
return symbol->name;
}
/**
* eek_symbol_set_label:
* @symbol: an #EekSymbol
@ -54,6 +81,20 @@ eek_symbol_set_label (EekSymbol *symbol,
symbol->label = g_strdup (label);
}
/**
* eek_symbol_get_label:
* @symbol: an #EekSymbol
*
* Get the label text of @symbol.
*/
const gchar *
eek_symbol_get_label (EekSymbol *symbol)
{
if (symbol->label == NULL || *symbol->label == '\0')
return NULL;
return symbol->label;
}
/**
* eek_symbol_set_modifier_mask:
* @symbol: an #EekSymbol
@ -77,10 +118,15 @@ eek_symbol_set_modifier_mask (EekSymbol *symbol,
EekModifierType
eek_symbol_get_modifier_mask (EekSymbol *symbol)
{
return 0;
return symbol->modifier_mask;
}
gboolean
eek_symbol_is_modifier (EekSymbol *symbol)
{
return eek_symbol_get_modifier_mask (symbol) != 0;
}
void
eek_symbol_set_icon_name (EekSymbol *symbol,
const gchar *icon_name)
@ -92,7 +138,9 @@ eek_symbol_set_icon_name (EekSymbol *symbol,
const gchar *
eek_symbol_get_icon_name (EekSymbol *symbol)
{
return NULL;
if (symbol->icon_name == NULL || *symbol->icon_name == '\0')
return NULL;
return symbol->icon_name;
}
void
@ -106,7 +154,6 @@ eek_symbol_set_tooltip (EekSymbol *symbol,
const gchar *
eek_symbol_get_tooltip (EekSymbol *symbol)
{
return NULL;
if (symbol->tooltip == NULL || *symbol->tooltip == '\0')
return NULL;
return symbol->tooltip;

107
eek/eek-symbol.h Normal file
View File

@ -0,0 +1,107 @@
/*
* Copyright (C) 2011 Daiki Ueno <ueno@unixuser.org>
* Copyright (C) 2011 Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301 USA
*/
#if !defined(__EEK_H_INSIDE__) && !defined(EEK_COMPILATION)
#error "Only <eek/eek.h> can be included directly."
#endif
#ifndef EEK_SYMBOL_H
#define EEK_SYMBOL_H 1
#include "eek-types.h"
G_BEGIN_DECLS
/**
* EekSymbolCategory:
* @EEK_SYMBOL_CATEGORY_LETTER: the symbol represents an alphabet letter
* @EEK_SYMBOL_CATEGORY_FUNCTION: the symbol represents a function
* @EEK_SYMBOL_CATEGORY_KEYNAME: the symbol does not have meaning but
* have a name
* @EEK_SYMBOL_CATEGORY_USER0: reserved for future use
* @EEK_SYMBOL_CATEGORY_USER1: reserved for future use
* @EEK_SYMBOL_CATEGORY_USER2: reserved for future use
* @EEK_SYMBOL_CATEGORY_USER3: reserved for future use
* @EEK_SYMBOL_CATEGORY_USER4: reserved for future use
* @EEK_SYMBOL_CATEGORY_UNKNOWN: used for error reporting
* @EEK_SYMBOL_CATEGORY_LAST: the last symbol category
*
* Category of the key symbols.
*/
typedef enum {
EEK_SYMBOL_CATEGORY_LETTER,
EEK_SYMBOL_CATEGORY_FUNCTION,
EEK_SYMBOL_CATEGORY_KEYNAME,
EEK_SYMBOL_CATEGORY_USER0,
EEK_SYMBOL_CATEGORY_USER1,
EEK_SYMBOL_CATEGORY_USER2,
EEK_SYMBOL_CATEGORY_USER3,
EEK_SYMBOL_CATEGORY_USER4,
EEK_SYMBOL_CATEGORY_UNKNOWN,
EEK_SYMBOL_CATEGORY_LAST = EEK_SYMBOL_CATEGORY_UNKNOWN
} EekSymbolCategory;
typedef struct _EekSymbol
{
/// Canonical name of the symbol
gchar *name;
/// Text used to display the symbol
gchar *label;
EekSymbolCategory category;
EekModifierType modifier_mask;
/// Icon name used to render the symbol
gchar *icon_name;
/// Tooltip text
gchar *tooltip;
// May not be present
guint xkeysym;
gchar *text;
} EekSymbol;
EekSymbol *eek_symbol_new (const gchar *name);
void eek_symbol_free (EekSymbol *symbol);
void eek_symbol_set_name (EekSymbol *symbol,
const gchar *name);
const gchar *eek_symbol_get_name (EekSymbol *symbol);
void eek_symbol_set_label (EekSymbol *symbol,
const gchar *label);
const gchar *eek_symbol_get_label (EekSymbol *symbol);
void eek_symbol_set_category (EekSymbol *symbol,
EekSymbolCategory category);
EekSymbolCategory eek_symbol_get_category (EekSymbol *symbol);
EekModifierType eek_symbol_get_modifier_mask (EekSymbol *symbol);
void eek_symbol_set_modifier_mask (EekSymbol *symbol,
EekModifierType mask);
gboolean eek_symbol_is_modifier (EekSymbol *symbol);
void eek_symbol_set_icon_name (EekSymbol *symbol,
const gchar *icon_name);
const gchar *eek_symbol_get_icon_name (EekSymbol *symbol);
void eek_symbol_set_tooltip (EekSymbol *symbol,
const gchar *tooltip);
const gchar * eek_symbol_get_tooltip (EekSymbol *symbol);
const gchar *eek_symbol_category_get_name (EekSymbolCategory category);
EekSymbolCategory eek_symbol_category_from_name (const gchar *name);
G_END_DECLS
#endif /* EEK_SYMBOL_H */

43
eek/eek-text.c Normal file
View File

@ -0,0 +1,43 @@
/*
* Copyright (C) 2011 Daiki Ueno <ueno@unixuser.org>
* Copyright (C) 2011 Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301 USA
*/
/**
* SECTION:eek-text
* @short_description: an #EekText represents a text symbol
*/
#include "config.h"
#include "eek-text.h"
EekSymbol *
eek_text_new (const gchar *text)
{
EekSymbol *ret = eek_symbol_new("");
eek_symbol_set_label(ret, text);
ret->text = g_strdup (text);
return ret;
}
const gchar *
eek_text_get_text (EekSymbol *text)
{
return text->text;
}

38
eek/eek-text.h Normal file
View File

@ -0,0 +1,38 @@
/*
* Copyright (C) 2011 Daiki Ueno <ueno@unixuser.org>
* Copyright (C) 2011 Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301 USA
*/
#if !defined(__EEK_H_INSIDE__) && !defined(EEK_COMPILATION)
#error "Only <eek/eek.h> can be included directly."
#endif
#ifndef EEK_TEXT_H
#define EEK_TEXT_H 1
#include "eek-symbol.h"
G_BEGIN_DECLS
GType eek_text_get_type (void) G_GNUC_CONST;
EekSymbol *eek_text_new (const gchar *text);
const gchar *eek_text_get_text (EekSymbol *text);
G_END_DECLS
#endif /* EEK_TEXT_H */

View File

@ -134,6 +134,10 @@ typedef enum
#define EEK_INVALID_KEYCODE (0)
typedef struct _EekElement EekElement;
typedef struct _EekContainer EekContainer;
typedef struct _EekKey EekKey;
typedef struct _EekSection EekSection;
typedef struct _EekKeyboard EekKeyboard;
typedef struct _EekSymbol EekSymbol;
typedef struct _EekText EekText;
typedef struct _EekTheme EekTheme;
@ -146,7 +150,6 @@ typedef struct _EekOutline EekOutline;
typedef struct _EekColor EekColor;
typedef struct _EekboardContextService EekboardContextService;
typedef struct _LevelKeyboard LevelKeyboard;
/**
* EekPoint:
@ -191,6 +194,12 @@ GType eek_bounds_get_type (void) G_GNUC_CONST;
EekBounds *eek_bounds_copy (const EekBounds *bounds);
void eek_bounds_free (EekBounds *bounds);
G_INLINE_FUNC gdouble
eek_bounds_long_side (EekBounds *bounds)
{
return bounds->width > bounds->height ? bounds->width : bounds->height;
}
/**
* EekOutline:
* @corner_radius: radius of corners of rounded polygon

View File

@ -27,14 +27,15 @@
#include <stdlib.h>
#include <string.h>
#include "eek-xml-layout.h"
#include "eek-keyboard.h"
#include "src/keyboard.h"
#include "src/symbol.h"
#include "eek-section.h"
#include "eek-key.h"
#include "eek-keysym.h"
#include "eek-text.h"
#include "squeekboard-resources.h"
#include "eek-xml-layout.h"
enum {
PROP_0,
PROP_ID,
@ -51,8 +52,8 @@ typedef struct _EekXmlLayoutPrivate
} EekXmlLayoutPrivate;
G_DEFINE_TYPE_EXTENDED (EekXmlLayout, eek_xml_layout, EEK_TYPE_LAYOUT,
0, /* GTypeFlags */
G_ADD_PRIVATE(EekXmlLayout)
0, /* GTypeFlags */
G_ADD_PRIVATE(EekXmlLayout)
G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE,
initable_iface_init))
@ -66,16 +67,16 @@ static GList *parse_prerequisites
(const gchar *path,
GError **error);
static gboolean parse_geometry (const gchar *path,
struct squeek_view **views, GArray *outline_array, GHashTable *name_button_hash,
EekKeyboard *keyboard,
GError **error);
static gboolean parse_symbols_with_prerequisites
(const gchar *keyboards_dir,
const gchar *name,
LevelKeyboard *keyboard,
EekKeyboard *keyboard,
GList **loaded,
GError **error);
static gboolean parse_symbols (const gchar *path,
LevelKeyboard *keyboard,
EekKeyboard *keyboard,
GError **error);
static gboolean validate (const gchar **valid_path_list,
@ -231,48 +232,40 @@ struct _GeometryParseData {
GSList *element_stack;
EekBounds bounds;
struct squeek_view **views;
guint view_idx;
struct squeek_row *row;
EekKeyboard *keyboard;
EekSection *section;
EekKey *key;
gint num_columns;
gint num_rows;
EekOrientation orientation;
gdouble corner_radius;
GSList *points;
gchar *name;
EekOutline outline;
gchar *outline_id;
guint keycode;
gchar *oref;
gint keycode;
GString *text;
GArray *outline_array;
GHashTable *name_button_hash; // char* -> struct squeek_button*
GHashTable *keyname_oref_hash; // char* -> guint
GHashTable *outlineid_oref_hash; // char* -> guint
GHashTable *key_oref_hash;
GHashTable *oref_outline_hash;
};
typedef struct _GeometryParseData GeometryParseData;
static GeometryParseData *
geometry_parse_data_new (struct squeek_view **views, GHashTable *name_button_hash, GArray *outline_array)
geometry_parse_data_new (EekKeyboard *keyboard)
{
GeometryParseData *data = g_slice_new0 (GeometryParseData);
data->views = views;
data->outline_array = outline_array;
data->keyname_oref_hash =
data->keyboard = g_object_ref (keyboard);
data->key_oref_hash =
g_hash_table_new_full (g_direct_hash,
g_direct_equal,
NULL,
g_free);
data->oref_outline_hash =
g_hash_table_new_full (g_str_hash,
g_str_equal,
g_free,
NULL);
data->outlineid_oref_hash =
g_hash_table_new_full (g_str_hash,
g_str_equal,
g_free,
NULL);
data->name_button_hash = name_button_hash;
data->text = g_string_sized_new (BUFSIZE);
(GDestroyNotify)eek_outline_free);
data->keycode = 8;
return data;
}
@ -280,19 +273,21 @@ geometry_parse_data_new (struct squeek_view **views, GHashTable *name_button_has
static void
geometry_parse_data_free (GeometryParseData *data)
{
g_hash_table_destroy (data->keyname_oref_hash);
g_hash_table_destroy (data->outlineid_oref_hash);
g_string_free (data->text, TRUE);
g_object_unref (data->keyboard);
g_hash_table_destroy (data->key_oref_hash);
g_hash_table_destroy (data->oref_outline_hash);
g_slice_free (GeometryParseData, data);
}
static const gchar *geometry_valid_path_list[] = {
"geometry",
"button/geometry",
"bounds/geometry",
"view/geometry",
"section/view/geometry",
"section/geometry",
"outline/geometry",
"bounds/section/geometry",
"row/section/geometry",
"key/row/section/geometry",
"bounds/key/row/section/geometry",
"point/outline/geometry",
};
@ -360,67 +355,81 @@ geometry_start_element_callback (GMarkupParseContext *pcontext,
return;
}
bounds.height = g_strtod (attribute, NULL);
data->bounds = bounds;
goto out;
}
if (g_strcmp0 (element_name, "view") == 0) {
/* Create an empty keyboard to which geometry and symbols
information are applied. */
struct squeek_view *view = squeek_view_new(data->bounds);
data->views[data->view_idx] = view;
if (g_strcmp0 (data->element_stack->data, "geometry") == 0)
eek_element_set_bounds (EEK_ELEMENT(data->keyboard), &bounds);
goto out;
}
if (g_strcmp0 (element_name, "section") == 0) {
gint angle = 0;
data->section = eek_keyboard_create_section (data->keyboard);
attribute = get_attribute (attribute_names, attribute_values,
"id");
if (attribute != NULL)
eek_element_set_name (EEK_ELEMENT(data->section), attribute);
attribute = get_attribute (attribute_names, attribute_values,
"angle");
if (attribute != NULL) {
gint angle;
angle = strtol (attribute, NULL, 10);
eek_section_set_angle (data->section, angle);
}
data->row = squeek_view_create_row(data->views[data->view_idx], angle);
goto out;
}
if (g_strcmp0 (element_name, "button") == 0) {
const gchar *base_name = get_attribute (attribute_names, attribute_values,
if (g_strcmp0 (element_name, "row") == 0) {
attribute = get_attribute (attribute_names, attribute_values,
"orientation");
if (attribute != NULL)
data->orientation = strtol (attribute, NULL, 10);
eek_section_add_row (data->section,
data->num_columns,
data->orientation);
data->num_rows++;
goto out;
}
if (g_strcmp0 (element_name, "key") == 0) {
guint keycode;
attribute = get_attribute (attribute_names, attribute_values,
"name");
if (base_name == NULL) {
if (attribute == NULL) {
g_set_error (error,
G_MARKUP_ERROR,
G_MARKUP_ERROR_MISSING_ATTRIBUTE,
"no \"name\" attribute for \"button\"");
"no \"name\" attribute for \"key\"");
return;
}
gchar *name = g_strdup (attribute);
const gchar *oref_name = get_attribute (attribute_names, attribute_values,
"oref");
if (oref_name == NULL) {
oref_name = "default";
}
const gchar *keycode_name = get_attribute (attribute_names, attribute_values,
attribute = get_attribute (attribute_names, attribute_values,
"keycode");
if (attribute != NULL)
keycode = strtol (attribute, NULL, 10);
else
keycode = data->keycode++;
guint oref = GPOINTER_TO_UINT(g_hash_table_lookup(data->outlineid_oref_hash,
oref_name));
const gchar *name = base_name;
g_hash_table_insert (data->keyname_oref_hash,
g_strdup(name),
GUINT_TO_POINTER(oref));
data->key = eek_section_create_key (data->section,
name,
keycode);
struct squeek_button *button = g_hash_table_lookup(data->name_button_hash, name);
// never gets used! this section gets executed before any buttons get defined
if (button) {
if (keycode_name != NULL) {
// This sets the keycode for all buttons,
// since they share state
// TODO: get rid of this in the parser;
// this belongs after keymap is defined
struct squeek_key *key = squeek_button_get_key(button);
squeek_key_set_keycode(key, strtol (keycode_name, NULL, 10));
}
attribute = get_attribute (attribute_names, attribute_values,
"oref");
if (attribute == NULL) {
g_set_error (error,
G_MARKUP_ERROR,
G_MARKUP_ERROR_MISSING_ATTRIBUTE,
"no \"oref\" attribute for \"key\"");
return;
}
g_hash_table_insert (data->key_oref_hash,
data->key,
g_strdup (attribute));
data->num_columns++;
goto out;
}
@ -434,7 +443,7 @@ geometry_start_element_callback (GMarkupParseContext *pcontext,
"no \"id\" attribute for \"outline\"");
return;
}
data->outline_id = g_strdup (attribute);
data->oref = g_strdup (attribute);
attribute = get_attribute (attribute_names, attribute_values,
"corner-radius");
@ -479,30 +488,6 @@ geometry_start_element_callback (GMarkupParseContext *pcontext,
out:
data->element_stack = g_slist_prepend (data->element_stack,
g_strdup (element_name));
data->text->len = 0;
}
/**
* eek_keyboard_add_outline:
* @keyboard: an #EekKeyboard
* @outline: an #EekOutline
*
* Register an outline of @keyboard.
* Returns: an unsigned integer ID of the registered outline, for
* later reference
*/
static guint
add_outline (GArray *outline_array,
EekOutline *outline)
{
EekOutline *_outline;
_outline = eek_outline_copy (outline);
g_array_append_val (outline_array, *_outline);
/* don't use eek_outline_free here, so as to keep _outline->points */
g_slice_free (EekOutline, _outline);
return outline_array->len - 1;
}
static void
@ -518,65 +503,20 @@ geometry_end_element_callback (GMarkupParseContext *pcontext,
data->element_stack = g_slist_next (data->element_stack);
g_slist_free1 (head);
const gchar *text = g_strndup (data->text->str, data->text->len);
if (g_strcmp0 (element_name, "view") == 0) {
data->view_idx++;
if (g_strcmp0 (element_name, "section") == 0) {
data->section = NULL;
data->num_rows = 0;
return;
}
if (g_strcmp0 (element_name, "section") == 0) {
// Split text on spaces and process each part
unsigned head = 0;
while (head < strlen(text)) {
// Skip to the first non-space character
for (; head < strlen(text); head++) {
if (text[head] != ' ') {
break;
}
}
unsigned start = head;
if (g_strcmp0 (element_name, "key") == 0) {
data->key = NULL;
return;
}
// Skip to the first space character
for (; head < strlen(text); head++) {
if (text[head] == ' ') {
break;
}
}
unsigned end = head;
/// Reached the end
if (start == end) {
break;
}
gchar *name = g_strndup (&text[start], end - start);
struct squeek_button *button = g_hash_table_lookup(data->name_button_hash, name);
if (!button) {
// Save button name together with its level,
// to account for buttons with the same name in multiple levels
guint keycode = data->keycode++;
guint oref = GPOINTER_TO_UINT(g_hash_table_lookup(data->keyname_oref_hash, name));
// default value gives idx 0, which is guaranteed to be occupied
button = squeek_row_create_button (data->row, keycode, oref);
g_hash_table_insert (data->name_button_hash,
g_strdup(name),
button);
} else {
struct squeek_button *new_button = squeek_row_create_button_with_state(data->row, button);
if (!new_button) {
g_set_error (error,
G_MARKUP_ERROR,
G_MARKUP_ERROR_MISSING_ATTRIBUTE,
"Couldn't create a shared button");
return;
}
}
}
data->row = NULL;
data->num_rows = 0;
if (g_strcmp0 (element_name, "row") == 0) {
data->num_columns = 0;
data->orientation = EEK_ORIENTATION_HORIZONTAL;
return;
}
@ -599,30 +539,19 @@ geometry_end_element_callback (GMarkupParseContext *pcontext,
g_slist_free (data->points);
data->points = NULL;
guint oref = add_outline (data->outline_array, outline);
g_hash_table_insert (data->oref_outline_hash,
g_strdup (data->oref),
outline);
g_hash_table_insert (data->outlineid_oref_hash,
data->outline_id,
GUINT_TO_POINTER(oref));
g_free (data->oref);
return;
}
}
static void
geometry_text_callback (GMarkupParseContext *pcontext,
const gchar *text,
gsize text_len,
gpointer user_data,
GError **error)
{
GeometryParseData *data = user_data;
g_string_append_len (data->text, text, (gssize)text_len);
}
static const GMarkupParser geometry_parser = {
geometry_start_element_callback,
geometry_end_element_callback,
geometry_text_callback,
0,
0,
0
};
@ -631,22 +560,23 @@ struct _SymbolsParseData {
GSList *element_stack;
GString *text;
LevelKeyboard *keyboard;
struct squeek_view *view;
EekKeyboard *keyboard;
EekKey *key;
GSList *symbols;
gchar *label;
gchar *icon;
gchar *tooltip;
guint keyval;
gint groups;
};
typedef struct _SymbolsParseData SymbolsParseData;
static SymbolsParseData *
symbols_parse_data_new (LevelKeyboard *keyboard)
symbols_parse_data_new (EekKeyboard *keyboard)
{
SymbolsParseData *data = g_slice_new0 (SymbolsParseData);
data->keyboard = keyboard;
data->keyboard = g_object_ref (keyboard);
data->text = g_string_sized_new (BUFSIZE);
return data;
}
@ -654,14 +584,19 @@ symbols_parse_data_new (LevelKeyboard *keyboard)
static void
symbols_parse_data_free (SymbolsParseData *data)
{
g_object_unref (data->keyboard);
g_string_free (data->text, TRUE);
g_slice_free (SymbolsParseData, data);
}
static const gchar *symbols_valid_path_list[] = {
"symbols",
"symbol/symbols",
"include/symbols",
"key/symbols",
"text/key/symbols",
"keysym/key/symbols",
"symbol/key/symbols",
"invalid/key/symbols",
};
static void
@ -682,7 +617,53 @@ symbols_start_element_callback (GMarkupParseContext *pcontext,
error))
return;
if (g_strcmp0 (element_name, "symbol") == 0) {
if (g_strcmp0 (element_name, "key") == 0) {
attribute = get_attribute (attribute_names, attribute_values,
"name");
if (attribute == NULL) {
g_set_error (error,
G_MARKUP_ERROR,
G_MARKUP_ERROR_MISSING_ATTRIBUTE,
"no \"name\" attribute for \"key\"");
return;
}
data->key = eek_keyboard_find_key_by_name (data->keyboard,
attribute);
if (data->key == NULL) {
g_set_error (error,
G_MARKUP_ERROR,
G_MARKUP_ERROR_INVALID_CONTENT,
"no such key %s", attribute);
}
attribute = get_attribute (attribute_names, attribute_values,
"groups");
if (attribute != NULL)
data->groups = strtol (attribute, NULL, 10);
else
data->groups = 1;
data->symbols = NULL;
goto out;
}
if (g_strcmp0 (element_name, "keysym") == 0) {
attribute = get_attribute (attribute_names, attribute_values,
"keyval");
if (attribute == NULL) {
g_set_error (error,
G_MARKUP_ERROR,
G_MARKUP_ERROR_MISSING_ATTRIBUTE,
"no \"keyval\" attribute for \"keysym\"");
return;
}
data->keyval = strtoul (attribute, NULL, 0);
}
if (g_strcmp0 (element_name, "symbol") == 0 ||
g_strcmp0 (element_name, "keysym") == 0 ||
g_strcmp0 (element_name, "text") == 0) {
attribute = get_attribute (attribute_names, attribute_values,
"label");
if (attribute != NULL)
@ -699,6 +680,7 @@ symbols_start_element_callback (GMarkupParseContext *pcontext,
data->tooltip = g_strdup (attribute);
}
out:
data->element_stack = g_slist_prepend (data->element_stack,
g_strdup (element_name));
data->text->len = 0;
@ -713,42 +695,82 @@ symbols_end_element_callback (GMarkupParseContext *pcontext,
SymbolsParseData *data = user_data;
GSList *head = data->element_stack;
gchar *text;
gint i;
g_free (head->data);
data->element_stack = g_slist_next (data->element_stack);
g_slist_free1 (head);
// TODO: this could all be moved to text handler
text = g_strndup (data->text->str, data->text->len);
if (g_strcmp0 (element_name, "symbol") == 0) {
gchar *name = text;
struct squeek_button *button = eek_keyboard_find_button_by_name (data->keyboard,
name);
if (button) {
squeek_key_add_symbol(
squeek_button_get_key(button),
element_name,
text,
data->keyval,
data->label,
data->icon,
data->tooltip
);
if (g_strcmp0 (element_name, "key") == 0) {
if (!data->key) {
return;
}
data->keyval = 0;
g_free(data->label);
data->label = NULL;
g_free(data->icon);
data->icon = NULL;
g_free(data->tooltip);
data->tooltip = NULL;
gint num_symbols = g_slist_length (data->symbols);
gint levels = num_symbols / data->groups;
EekSymbolMatrix *matrix = eek_symbol_matrix_new (data->groups,
levels);
head = data->symbols = g_slist_reverse (data->symbols);
for (i = 0; i < num_symbols; i++) {
if (head && head->data) {
matrix->data[i] = head->data;
head = g_slist_next (head);
} else
matrix->data[i] = NULL;
}
g_slist_free (data->symbols);
data->symbols = NULL;
eek_key_set_symbol_matrix (data->key, matrix);
eek_symbol_matrix_free (matrix);
data->key = NULL;
goto out;
}
if (g_strcmp0 (element_name, "symbol") == 0 ||
g_strcmp0 (element_name, "keysym") == 0 ||
g_strcmp0 (element_name, "text") == 0) {
EekSymbol *symbol;
if (g_strcmp0 (element_name, "keysym") == 0) {
EekSymbol *keysym;
if (data->keyval != EEK_INVALID_KEYSYM)
keysym = eek_keysym_new (data->keyval);
else
keysym = eek_keysym_new_from_name (text);
symbol = keysym;
} else if (g_strcmp0 (element_name, "text") == 0) {
symbol = eek_text_new (text);
} else {
symbol = eek_symbol_new (text);
}
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;
}
if (data->icon) {
eek_symbol_set_icon_name (symbol, data->icon);
g_free (data->icon);
data->icon = NULL;
}
if (data->tooltip) {
eek_symbol_set_tooltip (symbol, data->tooltip);
g_free (data->tooltip);
data->tooltip = NULL;
}
data->symbols = g_slist_prepend (data->symbols, symbol);
goto out;
}
if (g_strcmp0 (element_name, "invalid") == 0) {
data->symbols = g_slist_prepend (data->symbols, NULL);
goto out;
}
@ -860,37 +882,31 @@ static const GMarkupParser prerequisites_parser = {
0
};
LevelKeyboard *
eek_xml_layout_real_create_keyboard (EekLayout *self,
EekboardContextService *manager)
static EekKeyboard *
eek_xml_layout_real_create_keyboard (EekboardContextService *manager,
EekLayout *self,
gdouble initial_width,
gdouble initial_height)
{
EekXmlLayout *layout = EEK_XML_LAYOUT (self);
EekXmlLayoutPrivate *priv = eek_xml_layout_get_instance_private (layout);
gboolean retval;
/* Create an empty keyboard to which geometry and symbols
information are applied. */
EekKeyboard *keyboard = g_object_new (EEK_TYPE_KEYBOARD, "layout", layout, NULL);
keyboard->manager = manager;
/* Read geometry information. */
gchar *filename = g_strdup_printf ("%s.xml", priv->desc->geometry);
gchar *path = g_build_filename (priv->keyboards_dir, "geometry", filename, NULL);
g_free (filename);
GArray *outline_array = g_array_new (FALSE, TRUE, sizeof (EekOutline));
// char* -> struct squeek_button*
GHashTable *name_button_hash =
g_hash_table_new_full (g_str_hash,
g_str_equal,
g_free,
NULL);
// One view for each level
struct squeek_view *views[4] = {0};
GError *error = NULL;
retval = parse_geometry (path, views, outline_array, name_button_hash, &error);
retval = parse_geometry (path, keyboard, &error);
g_free (path);
if (!retval) {
for (uint i = 0; i < 4; i++) {
g_object_unref (views[i]);
}
g_object_unref (keyboard);
g_warning ("can't parse geometry file %s: %s",
priv->desc->geometry,
error->message);
@ -898,12 +914,6 @@ eek_xml_layout_real_create_keyboard (EekLayout *self,
return NULL;
}
LevelKeyboard *keyboard = level_keyboard_new(manager, views, name_button_hash);
keyboard->outline_array = outline_array;
// FIXME: are symbols shared betwen views?
/* Read symbols information. */
GList *loaded = NULL;
retval = parse_symbols_with_prerequisites (priv->keyboards_dir,
@ -913,13 +923,7 @@ eek_xml_layout_real_create_keyboard (EekLayout *self,
&error);
g_list_free_full (loaded, g_free);
if (!retval) {
for (uint i = 0; i < 4; i++) {
if (views[i]) {
g_object_unref(views[i]);
views[i] = NULL;
}
}
//g_object_unref (view);
g_object_unref (keyboard);
g_warning ("can't parse symbols file %s: %s",
priv->desc->symbols,
error->message);
@ -927,11 +931,12 @@ eek_xml_layout_real_create_keyboard (EekLayout *self,
return NULL;
}
for (uint i = 0; i < 4; i++) {
if (views[i]) {
squeek_view_place_contents(views[i], keyboard);
}
}
/* Arrange the sections in the original coordinate system. */
eek_layout_place_sections(keyboard);
/* 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);
return keyboard;
}
@ -979,7 +984,7 @@ static void
eek_xml_layout_finalize (GObject *object)
{
EekXmlLayoutPrivate *priv = eek_xml_layout_get_instance_private (
EEK_XML_LAYOUT (object));
EEK_XML_LAYOUT (object));
g_free (priv->id);
@ -994,18 +999,21 @@ eek_xml_layout_finalize (GObject *object)
static void
eek_xml_layout_class_init (EekXmlLayoutClass *klass)
{
EekLayoutClass *layout_class = EEK_LAYOUT_CLASS (klass);
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
GParamSpec *pspec;
layout_class->create_keyboard = eek_xml_layout_real_create_keyboard;
gobject_class->set_property = eek_xml_layout_set_property;
gobject_class->get_property = eek_xml_layout_get_property;
gobject_class->finalize = eek_xml_layout_finalize;
pspec = g_param_spec_string ("id",
"ID",
"ID",
NULL,
G_PARAM_CONSTRUCT_ONLY |
"ID",
"ID",
NULL,
G_PARAM_CONSTRUCT_ONLY |
G_PARAM_READWRITE);
g_object_class_install_property (gobject_class, PROP_ID, pspec);
}
@ -1117,10 +1125,13 @@ eek_xml_keyboard_desc_free (EekXmlKeyboardDesc *desc)
}
static gboolean
parse_geometry (const gchar *path, struct squeek_view **views, GArray *outline_array, GHashTable *name_button_hash, GError **error)
parse_geometry (const gchar *path, EekKeyboard *keyboard, GError **error)
{
GeometryParseData *data;
GMarkupParseContext *pcontext;
GHashTable *oref_hash;
GHashTableIter iter;
gpointer k, v;
GFile *file;
GFileInputStream *input;
gboolean retval;
@ -1134,7 +1145,7 @@ parse_geometry (const gchar *path, struct squeek_view **views, GArray *outline_a
if (input == NULL)
return FALSE;
data = geometry_parse_data_new (views, name_button_hash, outline_array);
data = geometry_parse_data_new (keyboard);
pcontext = g_markup_parse_context_new (&geometry_parser,
0,
data,
@ -1149,29 +1160,23 @@ parse_geometry (const gchar *path, struct squeek_view **views, GArray *outline_a
}
/* Resolve outline references. */
/*
* GHashTable *oref_hash;
GHashTableIter iter;
gpointer k, v;
oref_hash = g_hash_table_new (g_str_hash, g_str_equal);
g_hash_table_iter_init (&iter, data->oref_outline_hash);
while (g_hash_table_iter_next (&iter, &k, &v)) {
EekOutline *outline = v;
gulong oref;
oref = add_outline (outline_array, outline);
oref = eek_keyboard_add_outline (data->keyboard, outline);
g_hash_table_insert (oref_hash, k, GUINT_TO_POINTER(oref));
}*/
}
/*
g_hash_table_iter_init (&iter, data->key_oref_hash);
while (g_hash_table_iter_next (&iter, &k, &v)) {
gpointer oref;
if (g_hash_table_lookup_extended (oref_hash, v, NULL, &oref))
eek_key_set_oref (EEK_KEY(k), GPOINTER_TO_UINT(oref));
}*/
// g_hash_table_destroy (oref_hash);
}
g_hash_table_destroy (oref_hash);
geometry_parse_data_free (data);
return TRUE;
@ -1180,7 +1185,7 @@ parse_geometry (const gchar *path, struct squeek_view **views, GArray *outline_a
static gboolean
parse_symbols_with_prerequisites (const gchar *keyboards_dir,
const gchar *name,
LevelKeyboard *keyboard,
EekKeyboard *keyboard,
GList **loaded,
GError **error)
{
@ -1230,7 +1235,7 @@ parse_symbols_with_prerequisites (const gchar *keyboards_dir,
}
static gboolean
parse_symbols (const gchar *path, LevelKeyboard *keyboard, GError **error)
parse_symbols (const gchar *path, EekKeyboard *keyboard, GError **error)
{
SymbolsParseData *data;
GMarkupParseContext *pcontext;
@ -1345,7 +1350,7 @@ validate (const gchar **valid_path_list,
GSList *element_stack,
GError **error)
{
guint i;
gint i;
gchar *element_path;
GSList *head, *p;
GString *string;

View File

@ -62,8 +62,5 @@ GList *eek_xml_list_keyboards (void);
EekXmlKeyboardDesc *eek_xml_keyboard_desc_copy (EekXmlKeyboardDesc *desc);
void eek_xml_keyboard_desc_free (EekXmlKeyboardDesc *desc);
LevelKeyboard *
eek_xml_layout_real_create_keyboard (EekLayout *self,
EekboardContextService *manager);
G_END_DECLS
#endif /* EEK_XML_LAYOUT_H */

View File

@ -23,8 +23,13 @@
#define __EEK_H_INSIDE__ 1
#include "eek-keyboard.h"
#include "eek-section.h"
#include "eek-key.h"
#include "eek-layout.h"
#include "eek-symbol.h"
#include "eek-keysym.h"
#include "eek-text.h"
#include "eek-serializable.h"
void eek_init (void);

View File

@ -1,13 +1,35 @@
gnome = import('gnome')
enum_headers = [
'eek-symbol.h',
'eek-types.h',
]
enums = gnome.mkenums_simple('eek-enumtypes', sources: enum_headers)
marshalers = gnome.genmarshal(
'eek-marshalers',
sources: ['eek-marshalers.list'],
prefix: '_eek_marshal',
internal: true,
)
python = find_program('python3')
gen_keysym_entries_special = generator(
python,
arguments: ['@CURRENT_SOURCE_DIR@/gen-keysym-entries.py', 'special_keysym_entries', '@INPUT@'],
capture: true,
output: 'eek-@BASENAME@.h',
)
gen_keysym_entries_unicode = generator(
python,
arguments: ['@CURRENT_SOURCE_DIR@/gen-keysym-entries.py', 'unicode_keysym_entries', '@INPUT@'],
capture: true,
output: 'eek-@BASENAME@.h',
)
gen_keysym_entries_xkeysym = generator(
python,
arguments: ['@CURRENT_SOURCE_DIR@/gen-keysym-entries.py', 'xkeysym_keysym_entries', '@INPUT@'],
@ -16,5 +38,7 @@ gen_keysym_entries_xkeysym = generator(
)
keysym_entries = [
gen_keysym_entries_special.process('./special-keysym-entries.txt'),
gen_keysym_entries_unicode.process('./unicode-keysym-entries.txt'),
gen_keysym_entries_xkeysym.process('./xkeysym-keysym-entries.txt'),
]

View File

@ -0,0 +1,62 @@
0x20 "" EEK_SYMBOL_CATEGORY_LETTER
0x8A3 "horiz\nconn" EEK_SYMBOL_CATEGORY_LETTER
0xFE50 "ˋ" EEK_SYMBOL_CATEGORY_LETTER
0xFE51 "ˊ" EEK_SYMBOL_CATEGORY_LETTER
0xFE52 "ˆ" EEK_SYMBOL_CATEGORY_LETTER
0xFE53 "~" EEK_SYMBOL_CATEGORY_LETTER
0xFE54 "ˉ" EEK_SYMBOL_CATEGORY_LETTER
0xFE55 "˘" EEK_SYMBOL_CATEGORY_LETTER
0xFE56 "˙" EEK_SYMBOL_CATEGORY_LETTER
0xFE57 "¨" EEK_SYMBOL_CATEGORY_LETTER
0xFE58 "˚" EEK_SYMBOL_CATEGORY_LETTER
0xFE59 "˝" EEK_SYMBOL_CATEGORY_LETTER
0xFE5A "ˇ" EEK_SYMBOL_CATEGORY_LETTER
0xFE5B "¸" EEK_SYMBOL_CATEGORY_LETTER
0xFE5C "˛" EEK_SYMBOL_CATEGORY_LETTER
0xFF14 "Scroll\nLock" EEK_SYMBOL_CATEGORY_FUNCTION
0xFF20 "Compose" EEK_SYMBOL_CATEGORY_FUNCTION
0xFF55 "Page\nUp" EEK_SYMBOL_CATEGORY_FUNCTION
0xFF56 "Page\nDown" EEK_SYMBOL_CATEGORY_FUNCTION
0xFF7E "AltGr" EEK_SYMBOL_CATEGORY_FUNCTION
0xFF7F "Num\nLock" EEK_SYMBOL_CATEGORY_FUNCTION
0xFF8D "Enter" EEK_SYMBOL_CATEGORY_FUNCTION
0xFF95 "Home" EEK_SYMBOL_CATEGORY_FUNCTION
0xFF96 "Left" EEK_SYMBOL_CATEGORY_FUNCTION
0xFF97 "Up" EEK_SYMBOL_CATEGORY_FUNCTION
0xFF98 "Right" EEK_SYMBOL_CATEGORY_FUNCTION
0xFF99 "Down" EEK_SYMBOL_CATEGORY_FUNCTION
0xFF9C "End" EEK_SYMBOL_CATEGORY_FUNCTION
0xFF9D "Begin" EEK_SYMBOL_CATEGORY_FUNCTION
0xFF9E "Ins" EEK_SYMBOL_CATEGORY_FUNCTION
0xFF9F "Del" EEK_SYMBOL_CATEGORY_FUNCTION
# aliases
0xFE03 "123" EEK_SYMBOL_CATEGORY_KEYNAME
0xFE04 "⇮" EEK_SYMBOL_CATEGORY_KEYNAME
0xFE05 "⇮" EEK_SYMBOL_CATEGORY_KEYNAME
0xFE08 "Next" EEK_SYMBOL_CATEGORY_KEYNAME
0xFE0A "Prev" EEK_SYMBOL_CATEGORY_KEYNAME
0xFF08 "←" EEK_SYMBOL_CATEGORY_KEYNAME
0xFF09 "⇥" EEK_SYMBOL_CATEGORY_KEYNAME
0xFE20 "⇤" EEK_SYMBOL_CATEGORY_KEYNAME
0xFF0D "↵" EEK_SYMBOL_CATEGORY_KEYNAME
0xFF1B "Esc" EEK_SYMBOL_CATEGORY_KEYNAME
0xFFE1 "⇧" EEK_SYMBOL_CATEGORY_KEYNAME
0xFFE2 "⇧" EEK_SYMBOL_CATEGORY_KEYNAME
0xFFE3 "Ctrl" EEK_SYMBOL_CATEGORY_KEYNAME
0xFFE4 "Ctrl" EEK_SYMBOL_CATEGORY_KEYNAME
0xFFE5 "⇪" EEK_SYMBOL_CATEGORY_KEYNAME
0xFFE9 "Alt" EEK_SYMBOL_CATEGORY_KEYNAME
0xFFEA "Alt" EEK_SYMBOL_CATEGORY_KEYNAME
0xFFE7 "Meta" EEK_SYMBOL_CATEGORY_KEYNAME
0xFFE8 "Meta" EEK_SYMBOL_CATEGORY_KEYNAME
0xFFEB "Super" EEK_SYMBOL_CATEGORY_KEYNAME
0xFFEC "Super" EEK_SYMBOL_CATEGORY_KEYNAME
0xFFED "Hyper" EEK_SYMBOL_CATEGORY_KEYNAME
0xFFEE "Hyper" EEK_SYMBOL_CATEGORY_KEYNAME
0xFF2A "半" EEK_SYMBOL_CATEGORY_KEYNAME
0xFF21 "漢" EEK_SYMBOL_CATEGORY_KEYNAME
0xff51 "⇠" EEK_SYMBOL_CATEGORY_KEYNAME # 1
0xff52 "⇡" EEK_SYMBOL_CATEGORY_KEYNAME # 1
0xff53 "⇢" EEK_SYMBOL_CATEGORY_KEYNAME # 1
0xff54 "⇣" EEK_SYMBOL_CATEGORY_KEYNAME # 1
0xff30 "英" EEK_SYMBOL_CATEGORY_KEYNAME

View File

@ -0,0 +1,826 @@
# This file is derived from gdkkeyuni.c in GTK+. Thanks for the
# team. The original comments are below:
# Modified by the GTK+ Team and others 1997-2000. See the AUTHORS
# file for a list of people on the GTK+ Team. See the ChangeLog
# files for a list of changes. These files are distributed with
# GTK+ at ftp://ftp.gtk.org/pub/gtk/.
# Thanks to Markus G. Kuhn <mkuhn@acm.org> for the ksysym<->Unicode
# mapping functions, from the xterm sources.
# These tables could be compressed by contiguous ranges, but the
# benefit of doing so is smallish. It would save about ~1000 bytes
# total.
0x01a1 "Ą" EEK_SYMBOL_CATEGORY_LETTER # Aogonek Ą LATIN CAPITAL LETTER A WITH OGONEK
0x01a2 "˘" EEK_SYMBOL_CATEGORY_LETTER # breve ˘ BREVE
0x01a3 "Ł" EEK_SYMBOL_CATEGORY_LETTER # Lstroke Ł LATIN CAPITAL LETTER L WITH STROKE
0x01a5 "Ľ" EEK_SYMBOL_CATEGORY_LETTER # Lcaron Ľ LATIN CAPITAL LETTER L WITH CARON
0x01a6 "Ś" EEK_SYMBOL_CATEGORY_LETTER # Sacute Ś LATIN CAPITAL LETTER S WITH ACUTE
0x01a9 "Š" EEK_SYMBOL_CATEGORY_LETTER # Scaron Š LATIN CAPITAL LETTER S WITH CARON
0x01aa "Ş" EEK_SYMBOL_CATEGORY_LETTER # Scedilla Ş LATIN CAPITAL LETTER S WITH CEDILLA
0x01ab "Ť" EEK_SYMBOL_CATEGORY_LETTER # Tcaron Ť LATIN CAPITAL LETTER T WITH CARON
0x01ac "Ź" EEK_SYMBOL_CATEGORY_LETTER # Zacute Ź LATIN CAPITAL LETTER Z WITH ACUTE
0x01ae "Ž" EEK_SYMBOL_CATEGORY_LETTER # Zcaron Ž LATIN CAPITAL LETTER Z WITH CARON
0x01af "Ż" EEK_SYMBOL_CATEGORY_LETTER # Zabovedot Ż LATIN CAPITAL LETTER Z WITH DOT ABOVE
0x01b1 "ą" EEK_SYMBOL_CATEGORY_LETTER # aogonek ą LATIN SMALL LETTER A WITH OGONEK
0x01b2 "˛" EEK_SYMBOL_CATEGORY_LETTER # ogonek ˛ OGONEK
0x01b3 "ł" EEK_SYMBOL_CATEGORY_LETTER # lstroke ł LATIN SMALL LETTER L WITH STROKE
0x01b5 "ľ" EEK_SYMBOL_CATEGORY_LETTER # lcaron ľ LATIN SMALL LETTER L WITH CARON
0x01b6 "ś" EEK_SYMBOL_CATEGORY_LETTER # sacute ś LATIN SMALL LETTER S WITH ACUTE
0x01b7 "ˇ" EEK_SYMBOL_CATEGORY_LETTER # caron ˇ CARON
0x01b9 "š" EEK_SYMBOL_CATEGORY_LETTER # scaron š LATIN SMALL LETTER S WITH CARON
0x01ba "ş" EEK_SYMBOL_CATEGORY_LETTER # scedilla ş LATIN SMALL LETTER S WITH CEDILLA
0x01bb "ť" EEK_SYMBOL_CATEGORY_LETTER # tcaron ť LATIN SMALL LETTER T WITH CARON
0x01bc "ź" EEK_SYMBOL_CATEGORY_LETTER # zacute ź LATIN SMALL LETTER Z WITH ACUTE
0x01bd "˝" EEK_SYMBOL_CATEGORY_LETTER # doubleacute ˝ DOUBLE ACUTE ACCENT
0x01be "ž" EEK_SYMBOL_CATEGORY_LETTER # zcaron ž LATIN SMALL LETTER Z WITH CARON
0x01bf "ż" EEK_SYMBOL_CATEGORY_LETTER # zabovedot ż LATIN SMALL LETTER Z WITH DOT ABOVE
0x01c0 "Ŕ" EEK_SYMBOL_CATEGORY_LETTER # Racute Ŕ LATIN CAPITAL LETTER R WITH ACUTE
0x01c3 "Ă" EEK_SYMBOL_CATEGORY_LETTER # Abreve Ă LATIN CAPITAL LETTER A WITH BREVE
0x01c5 "Ĺ" EEK_SYMBOL_CATEGORY_LETTER # Lacute Ĺ LATIN CAPITAL LETTER L WITH ACUTE
0x01c6 "Ć" EEK_SYMBOL_CATEGORY_LETTER # Cacute Ć LATIN CAPITAL LETTER C WITH ACUTE
0x01c8 "Č" EEK_SYMBOL_CATEGORY_LETTER # Ccaron Č LATIN CAPITAL LETTER C WITH CARON
0x01ca "Ę" EEK_SYMBOL_CATEGORY_LETTER # Eogonek Ę LATIN CAPITAL LETTER E WITH OGONEK
0x01cc "Ě" EEK_SYMBOL_CATEGORY_LETTER # Ecaron Ě LATIN CAPITAL LETTER E WITH CARON
0x01cf "Ď" EEK_SYMBOL_CATEGORY_LETTER # Dcaron Ď LATIN CAPITAL LETTER D WITH CARON
0x01d0 "Đ" EEK_SYMBOL_CATEGORY_LETTER # Dstroke Đ LATIN CAPITAL LETTER D WITH STROKE
0x01d1 "Ń" EEK_SYMBOL_CATEGORY_LETTER # Nacute Ń LATIN CAPITAL LETTER N WITH ACUTE
0x01d2 "Ň" EEK_SYMBOL_CATEGORY_LETTER # Ncaron Ň LATIN CAPITAL LETTER N WITH CARON
0x01d5 "Ő" EEK_SYMBOL_CATEGORY_LETTER # Odoubleacute Ő LATIN CAPITAL LETTER O WITH DOUBLE ACUTE
0x01d8 "Ř" EEK_SYMBOL_CATEGORY_LETTER # Rcaron Ř LATIN CAPITAL LETTER R WITH CARON
0x01d9 "Ů" EEK_SYMBOL_CATEGORY_LETTER # Uring Ů LATIN CAPITAL LETTER U WITH RING ABOVE
0x01db "Ű" EEK_SYMBOL_CATEGORY_LETTER # Udoubleacute Ű LATIN CAPITAL LETTER U WITH DOUBLE ACUTE
0x01de "Ţ" EEK_SYMBOL_CATEGORY_LETTER # Tcedilla Ţ LATIN CAPITAL LETTER T WITH CEDILLA
0x01e0 "ŕ" EEK_SYMBOL_CATEGORY_LETTER # racute ŕ LATIN SMALL LETTER R WITH ACUTE
0x01e3 "ă" EEK_SYMBOL_CATEGORY_LETTER # abreve ă LATIN SMALL LETTER A WITH BREVE
0x01e5 "ĺ" EEK_SYMBOL_CATEGORY_LETTER # lacute ĺ LATIN SMALL LETTER L WITH ACUTE
0x01e6 "ć" EEK_SYMBOL_CATEGORY_LETTER # cacute ć LATIN SMALL LETTER C WITH ACUTE
0x01e8 "č" EEK_SYMBOL_CATEGORY_LETTER # ccaron č LATIN SMALL LETTER C WITH CARON
0x01ea "ę" EEK_SYMBOL_CATEGORY_LETTER # eogonek ę LATIN SMALL LETTER E WITH OGONEK
0x01ec "ě" EEK_SYMBOL_CATEGORY_LETTER # ecaron ě LATIN SMALL LETTER E WITH CARON
0x01ef "ď" EEK_SYMBOL_CATEGORY_LETTER # dcaron ď LATIN SMALL LETTER D WITH CARON
0x01f0 "đ" EEK_SYMBOL_CATEGORY_LETTER # dstroke đ LATIN SMALL LETTER D WITH STROKE
0x01f1 "ń" EEK_SYMBOL_CATEGORY_LETTER # nacute ń LATIN SMALL LETTER N WITH ACUTE
0x01f2 "ň" EEK_SYMBOL_CATEGORY_LETTER # ncaron ň LATIN SMALL LETTER N WITH CARON
0x01f5 "ő" EEK_SYMBOL_CATEGORY_LETTER # odoubleacute ő LATIN SMALL LETTER O WITH DOUBLE ACUTE
0x01f8 "ř" EEK_SYMBOL_CATEGORY_LETTER # rcaron ř LATIN SMALL LETTER R WITH CARON
0x01f9 "ů" EEK_SYMBOL_CATEGORY_LETTER # uring ů LATIN SMALL LETTER U WITH RING ABOVE
0x01fb "ű" EEK_SYMBOL_CATEGORY_LETTER # udoubleacute ű LATIN SMALL LETTER U WITH DOUBLE ACUTE
0x01fe "ţ" EEK_SYMBOL_CATEGORY_LETTER # tcedilla ţ LATIN SMALL LETTER T WITH CEDILLA
0x01ff "˙" EEK_SYMBOL_CATEGORY_LETTER # abovedot ˙ DOT ABOVE
0x02a1 "Ħ" EEK_SYMBOL_CATEGORY_LETTER # Hstroke Ħ LATIN CAPITAL LETTER H WITH STROKE
0x02a6 "Ĥ" EEK_SYMBOL_CATEGORY_LETTER # Hcircumflex Ĥ LATIN CAPITAL LETTER H WITH CIRCUMFLEX
0x02a9 "İ" EEK_SYMBOL_CATEGORY_LETTER # Iabovedot İ LATIN CAPITAL LETTER I WITH DOT ABOVE
0x02ab "Ğ" EEK_SYMBOL_CATEGORY_LETTER # Gbreve Ğ LATIN CAPITAL LETTER G WITH BREVE
0x02ac "Ĵ" EEK_SYMBOL_CATEGORY_LETTER # Jcircumflex Ĵ LATIN CAPITAL LETTER J WITH CIRCUMFLEX
0x02b1 "ħ" EEK_SYMBOL_CATEGORY_LETTER # hstroke ħ LATIN SMALL LETTER H WITH STROKE
0x02b6 "ĥ" EEK_SYMBOL_CATEGORY_LETTER # hcircumflex ĥ LATIN SMALL LETTER H WITH CIRCUMFLEX
0x02b9 "ı" EEK_SYMBOL_CATEGORY_LETTER # idotless ı LATIN SMALL LETTER DOTLESS I
0x02bb "ğ" EEK_SYMBOL_CATEGORY_LETTER # gbreve ğ LATIN SMALL LETTER G WITH BREVE
0x02bc "ĵ" EEK_SYMBOL_CATEGORY_LETTER # jcircumflex ĵ LATIN SMALL LETTER J WITH CIRCUMFLEX
0x02c5 "Ċ" EEK_SYMBOL_CATEGORY_LETTER # Cabovedot Ċ LATIN CAPITAL LETTER C WITH DOT ABOVE
0x02c6 "Ĉ" EEK_SYMBOL_CATEGORY_LETTER # Ccircumflex Ĉ LATIN CAPITAL LETTER C WITH CIRCUMFLEX
0x02d5 "Ġ" EEK_SYMBOL_CATEGORY_LETTER # Gabovedot Ġ LATIN CAPITAL LETTER G WITH DOT ABOVE
0x02d8 "Ĝ" EEK_SYMBOL_CATEGORY_LETTER # Gcircumflex Ĝ LATIN CAPITAL LETTER G WITH CIRCUMFLEX
0x02dd "Ŭ" EEK_SYMBOL_CATEGORY_LETTER # Ubreve Ŭ LATIN CAPITAL LETTER U WITH BREVE
0x02de "Ŝ" EEK_SYMBOL_CATEGORY_LETTER # Scircumflex Ŝ LATIN CAPITAL LETTER S WITH CIRCUMFLEX
0x02e5 "ċ" EEK_SYMBOL_CATEGORY_LETTER # cabovedot ċ LATIN SMALL LETTER C WITH DOT ABOVE
0x02e6 "ĉ" EEK_SYMBOL_CATEGORY_LETTER # ccircumflex ĉ LATIN SMALL LETTER C WITH CIRCUMFLEX
0x02f5 "ġ" EEK_SYMBOL_CATEGORY_LETTER # gabovedot ġ LATIN SMALL LETTER G WITH DOT ABOVE
0x02f8 "ĝ" EEK_SYMBOL_CATEGORY_LETTER # gcircumflex ĝ LATIN SMALL LETTER G WITH CIRCUMFLEX
0x02fd "ŭ" EEK_SYMBOL_CATEGORY_LETTER # ubreve ŭ LATIN SMALL LETTER U WITH BREVE
0x02fe "ŝ" EEK_SYMBOL_CATEGORY_LETTER # scircumflex ŝ LATIN SMALL LETTER S WITH CIRCUMFLEX
0x03a2 "ĸ" EEK_SYMBOL_CATEGORY_LETTER # kra ĸ LATIN SMALL LETTER KRA
0x03a3 "Ŗ" EEK_SYMBOL_CATEGORY_LETTER # Rcedilla Ŗ LATIN CAPITAL LETTER R WITH CEDILLA
0x03a5 "Ĩ" EEK_SYMBOL_CATEGORY_LETTER # Itilde Ĩ LATIN CAPITAL LETTER I WITH TILDE
0x03a6 "Ļ" EEK_SYMBOL_CATEGORY_LETTER # Lcedilla Ļ LATIN CAPITAL LETTER L WITH CEDILLA
0x03aa "Ē" EEK_SYMBOL_CATEGORY_LETTER # Emacron Ē LATIN CAPITAL LETTER E WITH MACRON
0x03ab "Ģ" EEK_SYMBOL_CATEGORY_LETTER # Gcedilla Ģ LATIN CAPITAL LETTER G WITH CEDILLA
0x03ac "Ŧ" EEK_SYMBOL_CATEGORY_LETTER # Tslash Ŧ LATIN CAPITAL LETTER T WITH STROKE
0x03b3 "ŗ" EEK_SYMBOL_CATEGORY_LETTER # rcedilla ŗ LATIN SMALL LETTER R WITH CEDILLA
0x03b5 "ĩ" EEK_SYMBOL_CATEGORY_LETTER # itilde ĩ LATIN SMALL LETTER I WITH TILDE
0x03b6 "ļ" EEK_SYMBOL_CATEGORY_LETTER # lcedilla ļ LATIN SMALL LETTER L WITH CEDILLA
0x03ba "ē" EEK_SYMBOL_CATEGORY_LETTER # emacron ē LATIN SMALL LETTER E WITH MACRON
0x03bb "ģ" EEK_SYMBOL_CATEGORY_LETTER # gcedilla ģ LATIN SMALL LETTER G WITH CEDILLA
0x03bc "ŧ" EEK_SYMBOL_CATEGORY_LETTER # tslash ŧ LATIN SMALL LETTER T WITH STROKE
0x03bd "Ŋ" EEK_SYMBOL_CATEGORY_LETTER # ENG Ŋ LATIN CAPITAL LETTER ENG
0x03bf "ŋ" EEK_SYMBOL_CATEGORY_LETTER # eng ŋ LATIN SMALL LETTER ENG
0x03c0 "Ā" EEK_SYMBOL_CATEGORY_LETTER # Amacron Ā LATIN CAPITAL LETTER A WITH MACRON
0x03c7 "Į" EEK_SYMBOL_CATEGORY_LETTER # Iogonek Į LATIN CAPITAL LETTER I WITH OGONEK
0x03cc "Ė" EEK_SYMBOL_CATEGORY_LETTER # Eabovedot Ė LATIN CAPITAL LETTER E WITH DOT ABOVE
0x03cf "Ī" EEK_SYMBOL_CATEGORY_LETTER # Imacron Ī LATIN CAPITAL LETTER I WITH MACRON
0x03d1 "Ņ" EEK_SYMBOL_CATEGORY_LETTER # Ncedilla Ņ LATIN CAPITAL LETTER N WITH CEDILLA
0x03d2 "Ō" EEK_SYMBOL_CATEGORY_LETTER # Omacron Ō LATIN CAPITAL LETTER O WITH MACRON
0x03d3 "Ķ" EEK_SYMBOL_CATEGORY_LETTER # Kcedilla Ķ LATIN CAPITAL LETTER K WITH CEDILLA
0x03d9 "Ų" EEK_SYMBOL_CATEGORY_LETTER # Uogonek Ų LATIN CAPITAL LETTER U WITH OGONEK
0x03dd "Ũ" EEK_SYMBOL_CATEGORY_LETTER # Utilde Ũ LATIN CAPITAL LETTER U WITH TILDE
0x03de "Ū" EEK_SYMBOL_CATEGORY_LETTER # Umacron Ū LATIN CAPITAL LETTER U WITH MACRON
0x03e0 "ā" EEK_SYMBOL_CATEGORY_LETTER # amacron ā LATIN SMALL LETTER A WITH MACRON
0x03e7 "į" EEK_SYMBOL_CATEGORY_LETTER # iogonek į LATIN SMALL LETTER I WITH OGONEK
0x03ec "ė" EEK_SYMBOL_CATEGORY_LETTER # eabovedot ė LATIN SMALL LETTER E WITH DOT ABOVE
0x03ef "ī" EEK_SYMBOL_CATEGORY_LETTER # imacron ī LATIN SMALL LETTER I WITH MACRON
0x03f1 "ņ" EEK_SYMBOL_CATEGORY_LETTER # ncedilla ņ LATIN SMALL LETTER N WITH CEDILLA
0x03f2 "ō" EEK_SYMBOL_CATEGORY_LETTER # omacron ō LATIN SMALL LETTER O WITH MACRON
0x03f3 "ķ" EEK_SYMBOL_CATEGORY_LETTER # kcedilla ķ LATIN SMALL LETTER K WITH CEDILLA
0x03f9 "ų" EEK_SYMBOL_CATEGORY_LETTER # uogonek ų LATIN SMALL LETTER U WITH OGONEK
0x03fd "ũ" EEK_SYMBOL_CATEGORY_LETTER # utilde ũ LATIN SMALL LETTER U WITH TILDE
0x03fe "ū" EEK_SYMBOL_CATEGORY_LETTER # umacron ū LATIN SMALL LETTER U WITH MACRON
0x047e "‾" EEK_SYMBOL_CATEGORY_LETTER # overline ‾ OVERLINE
0x04a1 "。" EEK_SYMBOL_CATEGORY_LETTER # kana_fullstop 。 IDEOGRAPHIC FULL STOP
0x04a2 "「" EEK_SYMBOL_CATEGORY_LETTER # kana_openingbracket 「 LEFT CORNER BRACKET
0x04a3 "」" EEK_SYMBOL_CATEGORY_LETTER # kana_closingbracket 」 RIGHT CORNER BRACKET
0x04a4 "、" EEK_SYMBOL_CATEGORY_LETTER # kana_comma 、 IDEOGRAPHIC COMMA
0x04a5 "・" EEK_SYMBOL_CATEGORY_LETTER # kana_conjunctive ・ KATAKANA MIDDLE DOT
0x04a6 "ヲ" EEK_SYMBOL_CATEGORY_LETTER # kana_WO ヲ KATAKANA LETTER WO
0x04a7 "ァ" EEK_SYMBOL_CATEGORY_LETTER # kana_a ァ KATAKANA LETTER SMALL A
0x04a8 "ィ" EEK_SYMBOL_CATEGORY_LETTER # kana_i ィ KATAKANA LETTER SMALL I
0x04a9 "ゥ" EEK_SYMBOL_CATEGORY_LETTER # kana_u ゥ KATAKANA LETTER SMALL U
0x04aa "ェ" EEK_SYMBOL_CATEGORY_LETTER # kana_e ェ KATAKANA LETTER SMALL E
0x04ab "ォ" EEK_SYMBOL_CATEGORY_LETTER # kana_o ォ KATAKANA LETTER SMALL O
0x04ac "ャ" EEK_SYMBOL_CATEGORY_LETTER # kana_ya ャ KATAKANA LETTER SMALL YA
0x04ad "ュ" EEK_SYMBOL_CATEGORY_LETTER # kana_yu ュ KATAKANA LETTER SMALL YU
0x04ae "ョ" EEK_SYMBOL_CATEGORY_LETTER # kana_yo ョ KATAKANA LETTER SMALL YO
0x04af "ッ" EEK_SYMBOL_CATEGORY_LETTER # kana_tsu ッ KATAKANA LETTER SMALL TU
0x04b0 "ー" EEK_SYMBOL_CATEGORY_LETTER # prolongedsound ー KATAKANA-HIRAGANA PROLONGED SOUND MARK
0x04b1 "ア" EEK_SYMBOL_CATEGORY_LETTER # kana_A ア KATAKANA LETTER A
0x04b2 "イ" EEK_SYMBOL_CATEGORY_LETTER # kana_I イ KATAKANA LETTER I
0x04b3 "ウ" EEK_SYMBOL_CATEGORY_LETTER # kana_U ウ KATAKANA LETTER U
0x04b4 "エ" EEK_SYMBOL_CATEGORY_LETTER # kana_E エ KATAKANA LETTER E
0x04b5 "オ" EEK_SYMBOL_CATEGORY_LETTER # kana_O オ KATAKANA LETTER O
0x04b6 "カ" EEK_SYMBOL_CATEGORY_LETTER # kana_KA カ KATAKANA LETTER KA
0x04b7 "キ" EEK_SYMBOL_CATEGORY_LETTER # kana_KI キ KATAKANA LETTER KI
0x04b8 "ク" EEK_SYMBOL_CATEGORY_LETTER # kana_KU ク KATAKANA LETTER KU
0x04b9 "ケ" EEK_SYMBOL_CATEGORY_LETTER # kana_KE ケ KATAKANA LETTER KE
0x04ba "コ" EEK_SYMBOL_CATEGORY_LETTER # kana_KO コ KATAKANA LETTER KO
0x04bb "サ" EEK_SYMBOL_CATEGORY_LETTER # kana_SA サ KATAKANA LETTER SA
0x04bc "シ" EEK_SYMBOL_CATEGORY_LETTER # kana_SHI シ KATAKANA LETTER SI
0x04bd "ス" EEK_SYMBOL_CATEGORY_LETTER # kana_SU ス KATAKANA LETTER SU
0x04be "セ" EEK_SYMBOL_CATEGORY_LETTER # kana_SE セ KATAKANA LETTER SE
0x04bf "ソ" EEK_SYMBOL_CATEGORY_LETTER # kana_SO ソ KATAKANA LETTER SO
0x04c0 "タ" EEK_SYMBOL_CATEGORY_LETTER # kana_TA タ KATAKANA LETTER TA
0x04c1 "チ" EEK_SYMBOL_CATEGORY_LETTER # kana_CHI チ KATAKANA LETTER TI
0x04c2 "ツ" EEK_SYMBOL_CATEGORY_LETTER # kana_TSU ツ KATAKANA LETTER TU
0x04c3 "テ" EEK_SYMBOL_CATEGORY_LETTER # kana_TE テ KATAKANA LETTER TE
0x04c4 "ト" EEK_SYMBOL_CATEGORY_LETTER # kana_TO ト KATAKANA LETTER TO
0x04c5 "ナ" EEK_SYMBOL_CATEGORY_LETTER # kana_NA ナ KATAKANA LETTER NA
0x04c6 "ニ" EEK_SYMBOL_CATEGORY_LETTER # kana_NI ニ KATAKANA LETTER NI
0x04c7 "ヌ" EEK_SYMBOL_CATEGORY_LETTER # kana_NU ヌ KATAKANA LETTER NU
0x04c8 "ネ" EEK_SYMBOL_CATEGORY_LETTER # kana_NE ネ KATAKANA LETTER NE
0x04c9 "" EEK_SYMBOL_CATEGORY_LETTER # kana_NO KATAKANA LETTER NO
0x04ca "ハ" EEK_SYMBOL_CATEGORY_LETTER # kana_HA ハ KATAKANA LETTER HA
0x04cb "ヒ" EEK_SYMBOL_CATEGORY_LETTER # kana_HI ヒ KATAKANA LETTER HI
0x04cc "フ" EEK_SYMBOL_CATEGORY_LETTER # kana_FU フ KATAKANA LETTER HU
0x04cd "ヘ" EEK_SYMBOL_CATEGORY_LETTER # kana_HE ヘ KATAKANA LETTER HE
0x04ce "ホ" EEK_SYMBOL_CATEGORY_LETTER # kana_HO ホ KATAKANA LETTER HO
0x04cf "マ" EEK_SYMBOL_CATEGORY_LETTER # kana_MA マ KATAKANA LETTER MA
0x04d0 "ミ" EEK_SYMBOL_CATEGORY_LETTER # kana_MI ミ KATAKANA LETTER MI
0x04d1 "ム" EEK_SYMBOL_CATEGORY_LETTER # kana_MU ム KATAKANA LETTER MU
0x04d2 "メ" EEK_SYMBOL_CATEGORY_LETTER # kana_ME メ KATAKANA LETTER ME
0x04d3 "モ" EEK_SYMBOL_CATEGORY_LETTER # kana_MO モ KATAKANA LETTER MO
0x04d4 "ヤ" EEK_SYMBOL_CATEGORY_LETTER # kana_YA ヤ KATAKANA LETTER YA
0x04d5 "ユ" EEK_SYMBOL_CATEGORY_LETTER # kana_YU ユ KATAKANA LETTER YU
0x04d6 "ヨ" EEK_SYMBOL_CATEGORY_LETTER # kana_YO ヨ KATAKANA LETTER YO
0x04d7 "ラ" EEK_SYMBOL_CATEGORY_LETTER # kana_RA ラ KATAKANA LETTER RA
0x04d8 "リ" EEK_SYMBOL_CATEGORY_LETTER # kana_RI リ KATAKANA LETTER RI
0x04d9 "ル" EEK_SYMBOL_CATEGORY_LETTER # kana_RU ル KATAKANA LETTER RU
0x04da "レ" EEK_SYMBOL_CATEGORY_LETTER # kana_RE レ KATAKANA LETTER RE
0x04db "ロ" EEK_SYMBOL_CATEGORY_LETTER # kana_RO ロ KATAKANA LETTER RO
0x04dc "ワ" EEK_SYMBOL_CATEGORY_LETTER # kana_WA ワ KATAKANA LETTER WA
0x04dd "ン" EEK_SYMBOL_CATEGORY_LETTER # kana_N ン KATAKANA LETTER N
0x04de "゛" EEK_SYMBOL_CATEGORY_LETTER # voicedsound ゛ KATAKANA-HIRAGANA VOICED SOUND MARK
0x04df "゜" EEK_SYMBOL_CATEGORY_LETTER # semivoicedsound ゜ KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK
0x05ac "،" EEK_SYMBOL_CATEGORY_LETTER # Arabic_comma ، ARABIC COMMA
0x05bb "؛" EEK_SYMBOL_CATEGORY_LETTER # Arabic_semicolon ؛ ARABIC SEMICOLON
0x05bf "؟" EEK_SYMBOL_CATEGORY_LETTER # Arabic_question_mark ؟ ARABIC QUESTION MARK
0x05c1 "ء" EEK_SYMBOL_CATEGORY_LETTER # Arabic_hamza ء ARABIC LETTER HAMZA
0x05c2 "آ" EEK_SYMBOL_CATEGORY_LETTER # Arabic_maddaonalef آ ARABIC LETTER ALEF WITH MADDA ABOVE
0x05c3 "أ" EEK_SYMBOL_CATEGORY_LETTER # Arabic_hamzaonalef أ ARABIC LETTER ALEF WITH HAMZA ABOVE
0x05c4 "ؤ" EEK_SYMBOL_CATEGORY_LETTER # Arabic_hamzaonwaw ؤ ARABIC LETTER WAW WITH HAMZA ABOVE
0x05c5 "إ" EEK_SYMBOL_CATEGORY_LETTER # Arabic_hamzaunderalef إ ARABIC LETTER ALEF WITH HAMZA BELOW
0x05c6 "ئ" EEK_SYMBOL_CATEGORY_LETTER # Arabic_hamzaonyeh ئ ARABIC LETTER YEH WITH HAMZA ABOVE
0x05c7 "ا" EEK_SYMBOL_CATEGORY_LETTER # Arabic_alef ا ARABIC LETTER ALEF
0x05c8 "ب" EEK_SYMBOL_CATEGORY_LETTER # Arabic_beh ب ARABIC LETTER BEH
0x05c9 "ة" EEK_SYMBOL_CATEGORY_LETTER # Arabic_tehmarbuta ة ARABIC LETTER TEH MARBUTA
0x05ca "ت" EEK_SYMBOL_CATEGORY_LETTER # Arabic_teh ت ARABIC LETTER TEH
0x05cb "ث" EEK_SYMBOL_CATEGORY_LETTER # Arabic_theh ث ARABIC LETTER THEH
0x05cc "ج" EEK_SYMBOL_CATEGORY_LETTER # Arabic_jeem ج ARABIC LETTER JEEM
0x05cd "ح" EEK_SYMBOL_CATEGORY_LETTER # Arabic_hah ح ARABIC LETTER HAH
0x05ce "خ" EEK_SYMBOL_CATEGORY_LETTER # Arabic_khah خ ARABIC LETTER KHAH
0x05cf "د" EEK_SYMBOL_CATEGORY_LETTER # Arabic_dal د ARABIC LETTER DAL
0x05d0 "ذ" EEK_SYMBOL_CATEGORY_LETTER # Arabic_thal ذ ARABIC LETTER THAL
0x05d1 "ر" EEK_SYMBOL_CATEGORY_LETTER # Arabic_ra ر ARABIC LETTER REH
0x05d2 "ز" EEK_SYMBOL_CATEGORY_LETTER # Arabic_zain ز ARABIC LETTER ZAIN
0x05d3 "س" EEK_SYMBOL_CATEGORY_LETTER # Arabic_seen س ARABIC LETTER SEEN
0x05d4 "ش" EEK_SYMBOL_CATEGORY_LETTER # Arabic_sheen ش ARABIC LETTER SHEEN
0x05d5 "ص" EEK_SYMBOL_CATEGORY_LETTER # Arabic_sad ص ARABIC LETTER SAD
0x05d6 "ض" EEK_SYMBOL_CATEGORY_LETTER # Arabic_dad ض ARABIC LETTER DAD
0x05d7 "ط" EEK_SYMBOL_CATEGORY_LETTER # Arabic_tah ط ARABIC LETTER TAH
0x05d8 "ظ" EEK_SYMBOL_CATEGORY_LETTER # Arabic_zah ظ ARABIC LETTER ZAH
0x05d9 "ع" EEK_SYMBOL_CATEGORY_LETTER # Arabic_ain ع ARABIC LETTER AIN
0x05da "غ" EEK_SYMBOL_CATEGORY_LETTER # Arabic_ghain غ ARABIC LETTER GHAIN
0x05e0 "ـ" EEK_SYMBOL_CATEGORY_LETTER # Arabic_tatweel ـ ARABIC TATWEEL
0x05e1 "ف" EEK_SYMBOL_CATEGORY_LETTER # Arabic_feh ف ARABIC LETTER FEH
0x05e2 "ق" EEK_SYMBOL_CATEGORY_LETTER # Arabic_qaf ق ARABIC LETTER QAF
0x05e3 "ك" EEK_SYMBOL_CATEGORY_LETTER # Arabic_kaf ك ARABIC LETTER KAF
0x05e4 "ل" EEK_SYMBOL_CATEGORY_LETTER # Arabic_lam ل ARABIC LETTER LAM
0x05e5 "م" EEK_SYMBOL_CATEGORY_LETTER # Arabic_meem م ARABIC LETTER MEEM
0x05e6 "ن" EEK_SYMBOL_CATEGORY_LETTER # Arabic_noon ن ARABIC LETTER NOON
0x05e7 "ه" EEK_SYMBOL_CATEGORY_LETTER # Arabic_ha ه ARABIC LETTER HEH
0x05e8 "و" EEK_SYMBOL_CATEGORY_LETTER # Arabic_waw و ARABIC LETTER WAW
0x05e9 "ى" EEK_SYMBOL_CATEGORY_LETTER # Arabic_alefmaksura ى ARABIC LETTER ALEF MAKSURA
0x05ea "ي" EEK_SYMBOL_CATEGORY_LETTER # Arabic_yeh ي ARABIC LETTER YEH
0x05eb "ً" EEK_SYMBOL_CATEGORY_LETTER # Arabic_fathatan ً ARABIC FATHATAN
0x05ec "ٌ" EEK_SYMBOL_CATEGORY_LETTER # Arabic_dammatan ٌ ARABIC DAMMATAN
0x05ed "ٍ" EEK_SYMBOL_CATEGORY_LETTER # Arabic_kasratan ٍ ARABIC KASRATAN
0x05ee "َ" EEK_SYMBOL_CATEGORY_LETTER # Arabic_fatha َ ARABIC FATHA
0x05ef "ُ" EEK_SYMBOL_CATEGORY_LETTER # Arabic_damma ُ ARABIC DAMMA
0x05f0 "ِ" EEK_SYMBOL_CATEGORY_LETTER # Arabic_kasra ِ ARABIC KASRA
0x05f1 "ّ" EEK_SYMBOL_CATEGORY_LETTER # Arabic_shadda ّ ARABIC SHADDA
0x05f2 "ْ" EEK_SYMBOL_CATEGORY_LETTER # Arabic_sukun ْ ARABIC SUKUN
0x06a1 "ђ" EEK_SYMBOL_CATEGORY_LETTER # Serbian_dje ђ CYRILLIC SMALL LETTER DJE
0x06a2 "ѓ" EEK_SYMBOL_CATEGORY_LETTER # Macedonia_gje ѓ CYRILLIC SMALL LETTER GJE
0x06a3 "ё" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_io ё CYRILLIC SMALL LETTER IO
0x06a4 "є" EEK_SYMBOL_CATEGORY_LETTER # Ukrainian_ie є CYRILLIC SMALL LETTER UKRAINIAN IE
0x06a5 "ѕ" EEK_SYMBOL_CATEGORY_LETTER # Macedonia_dse ѕ CYRILLIC SMALL LETTER DZE
0x06a6 "і" EEK_SYMBOL_CATEGORY_LETTER # Ukrainian_i і CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I
0x06a7 "ї" EEK_SYMBOL_CATEGORY_LETTER # Ukrainian_yi ї CYRILLIC SMALL LETTER YI
0x06a8 "ј" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_je ј CYRILLIC SMALL LETTER JE
0x06a9 "љ" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_lje љ CYRILLIC SMALL LETTER LJE
0x06aa "њ" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_nje њ CYRILLIC SMALL LETTER NJE
0x06ab "ћ" EEK_SYMBOL_CATEGORY_LETTER # Serbian_tshe ћ CYRILLIC SMALL LETTER TSHE
0x06ac "ќ" EEK_SYMBOL_CATEGORY_LETTER # Macedonia_kje ќ CYRILLIC SMALL LETTER KJE
0x06ad "ґ" EEK_SYMBOL_CATEGORY_LETTER # Ukrainian_ghe_with_upturn ґ CYRILLIC SMALL LETTER GHE WITH UPTURN
0x06ae "ў" EEK_SYMBOL_CATEGORY_LETTER # Byelorussian_shortu ў CYRILLIC SMALL LETTER SHORT U
0x06af "џ" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_dzhe џ CYRILLIC SMALL LETTER DZHE
0x06b0 "№" EEK_SYMBOL_CATEGORY_LETTER # numerosign № NUMERO SIGN
0x06b1 "Ђ" EEK_SYMBOL_CATEGORY_LETTER # Serbian_DJE Ђ CYRILLIC CAPITAL LETTER DJE
0x06b2 "Ѓ" EEK_SYMBOL_CATEGORY_LETTER # Macedonia_GJE Ѓ CYRILLIC CAPITAL LETTER GJE
0x06b3 "Ё" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_IO Ё CYRILLIC CAPITAL LETTER IO
0x06b4 "Є" EEK_SYMBOL_CATEGORY_LETTER # Ukrainian_IE Є CYRILLIC CAPITAL LETTER UKRAINIAN IE
0x06b5 "Ѕ" EEK_SYMBOL_CATEGORY_LETTER # Macedonia_DSE Ѕ CYRILLIC CAPITAL LETTER DZE
0x06b6 "І" EEK_SYMBOL_CATEGORY_LETTER # Ukrainian_I І CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I
0x06b7 "Ї" EEK_SYMBOL_CATEGORY_LETTER # Ukrainian_YI Ї CYRILLIC CAPITAL LETTER YI
0x06b8 "Ј" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_JE Ј CYRILLIC CAPITAL LETTER JE
0x06b9 "Љ" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_LJE Љ CYRILLIC CAPITAL LETTER LJE
0x06ba "Њ" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_NJE Њ CYRILLIC CAPITAL LETTER NJE
0x06bb "Ћ" EEK_SYMBOL_CATEGORY_LETTER # Serbian_TSHE Ћ CYRILLIC CAPITAL LETTER TSHE
0x06bc "Ќ" EEK_SYMBOL_CATEGORY_LETTER # Macedonia_KJE Ќ CYRILLIC CAPITAL LETTER KJE
0x06bd "Ґ" EEK_SYMBOL_CATEGORY_LETTER # Ukrainian_GHE_WITH_UPTURN Ґ CYRILLIC CAPITAL LETTER GHE WITH UPTURN
0x06be "Ў" EEK_SYMBOL_CATEGORY_LETTER # Byelorussian_SHORTU Ў CYRILLIC CAPITAL LETTER SHORT U
0x06bf "Џ" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_DZHE Џ CYRILLIC CAPITAL LETTER DZHE
0x06c0 "ю" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_yu ю CYRILLIC SMALL LETTER YU
0x06c1 "а" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_a а CYRILLIC SMALL LETTER A
0x06c2 "б" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_be б CYRILLIC SMALL LETTER BE
0x06c3 "ц" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_tse ц CYRILLIC SMALL LETTER TSE
0x06c4 "д" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_de д CYRILLIC SMALL LETTER DE
0x06c5 "е" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_ie е CYRILLIC SMALL LETTER IE
0x06c6 "ф" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_ef ф CYRILLIC SMALL LETTER EF
0x06c7 "г" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_ghe г CYRILLIC SMALL LETTER GHE
0x06c8 "х" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_ha х CYRILLIC SMALL LETTER HA
0x06c9 "и" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_i и CYRILLIC SMALL LETTER I
0x06ca "й" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_shorti й CYRILLIC SMALL LETTER SHORT I
0x06cb "к" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_ka к CYRILLIC SMALL LETTER KA
0x06cc "л" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_el л CYRILLIC SMALL LETTER EL
0x06cd "м" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_em м CYRILLIC SMALL LETTER EM
0x06ce "н" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_en н CYRILLIC SMALL LETTER EN
0x06cf "о" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_o о CYRILLIC SMALL LETTER O
0x06d0 "п" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_pe п CYRILLIC SMALL LETTER PE
0x06d1 "я" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_ya я CYRILLIC SMALL LETTER YA
0x06d2 "р" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_er р CYRILLIC SMALL LETTER ER
0x06d3 "с" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_es с CYRILLIC SMALL LETTER ES
0x06d4 "т" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_te т CYRILLIC SMALL LETTER TE
0x06d5 "у" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_u у CYRILLIC SMALL LETTER U
0x06d6 "ж" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_zhe ж CYRILLIC SMALL LETTER ZHE
0x06d7 "в" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_ve в CYRILLIC SMALL LETTER VE
0x06d8 "ь" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_softsign ь CYRILLIC SMALL LETTER SOFT SIGN
0x06d9 "ы" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_yeru ы CYRILLIC SMALL LETTER YERU
0x06da "з" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_ze з CYRILLIC SMALL LETTER ZE
0x06db "ш" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_sha ш CYRILLIC SMALL LETTER SHA
0x06dc "э" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_e э CYRILLIC SMALL LETTER E
0x06dd "щ" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_shcha щ CYRILLIC SMALL LETTER SHCHA
0x06de "ч" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_che ч CYRILLIC SMALL LETTER CHE
0x06df "ъ" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_hardsign ъ CYRILLIC SMALL LETTER HARD SIGN
0x06e0 "Ю" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_YU Ю CYRILLIC CAPITAL LETTER YU
0x06e1 "А" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_A А CYRILLIC CAPITAL LETTER A
0x06e2 "Б" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_BE Б CYRILLIC CAPITAL LETTER BE
0x06e3 "Ц" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_TSE Ц CYRILLIC CAPITAL LETTER TSE
0x06e4 "Д" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_DE Д CYRILLIC CAPITAL LETTER DE
0x06e5 "Е" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_IE Е CYRILLIC CAPITAL LETTER IE
0x06e6 "Ф" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_EF Ф CYRILLIC CAPITAL LETTER EF
0x06e7 "Г" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_GHE Г CYRILLIC CAPITAL LETTER GHE
0x06e8 "Х" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_HA Х CYRILLIC CAPITAL LETTER HA
0x06e9 "И" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_I И CYRILLIC CAPITAL LETTER I
0x06ea "Й" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_SHORTI Й CYRILLIC CAPITAL LETTER SHORT I
0x06eb "К" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_KA К CYRILLIC CAPITAL LETTER KA
0x06ec "Л" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_EL Л CYRILLIC CAPITAL LETTER EL
0x06ed "М" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_EM М CYRILLIC CAPITAL LETTER EM
0x06ee "Н" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_EN Н CYRILLIC CAPITAL LETTER EN
0x06ef "О" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_O О CYRILLIC CAPITAL LETTER O
0x06f0 "П" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_PE П CYRILLIC CAPITAL LETTER PE
0x06f1 "Я" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_YA Я CYRILLIC CAPITAL LETTER YA
0x06f2 "Р" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_ER Р CYRILLIC CAPITAL LETTER ER
0x06f3 "С" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_ES С CYRILLIC CAPITAL LETTER ES
0x06f4 "Т" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_TE Т CYRILLIC CAPITAL LETTER TE
0x06f5 "У" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_U У CYRILLIC CAPITAL LETTER U
0x06f6 "Ж" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_ZHE Ж CYRILLIC CAPITAL LETTER ZHE
0x06f7 "В" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_VE В CYRILLIC CAPITAL LETTER VE
0x06f8 "Ь" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_SOFTSIGN Ь CYRILLIC CAPITAL LETTER SOFT SIGN
0x06f9 "Ы" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_YERU Ы CYRILLIC CAPITAL LETTER YERU
0x06fa "З" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_ZE З CYRILLIC CAPITAL LETTER ZE
0x06fb "Ш" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_SHA Ш CYRILLIC CAPITAL LETTER SHA
0x06fc "Э" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_E Э CYRILLIC CAPITAL LETTER E
0x06fd "Щ" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_SHCHA Щ CYRILLIC CAPITAL LETTER SHCHA
0x06fe "Ч" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_CHE Ч CYRILLIC CAPITAL LETTER CHE
0x06ff "Ъ" EEK_SYMBOL_CATEGORY_LETTER # Cyrillic_HARDSIGN Ъ CYRILLIC CAPITAL LETTER HARD SIGN
0x07a1 "Ά" EEK_SYMBOL_CATEGORY_LETTER # Geek_ALPHAaccent Ά GREEK CAPITAL LETTER ALPHA WITH TONOS
0x07a2 "Έ" EEK_SYMBOL_CATEGORY_LETTER # Geek_EPSILONaccent Έ GREEK CAPITAL LETTER EPSILON WITH TONOS
0x07a3 "Ή" EEK_SYMBOL_CATEGORY_LETTER # Geek_ETAaccent Ή GREEK CAPITAL LETTER ETA WITH TONOS
0x07a4 "Ί" EEK_SYMBOL_CATEGORY_LETTER # Geek_IOTAaccent Ί GREEK CAPITAL LETTER IOTA WITH TONOS
0x07a5 "Ϊ" EEK_SYMBOL_CATEGORY_LETTER # Geek_IOTAdieresis Ϊ GREEK CAPITAL LETTER IOTA WITH DIALYTIKA
0x07a7 "Ό" EEK_SYMBOL_CATEGORY_LETTER # Geek_OMICRONaccent Ό GREEK CAPITAL LETTER OMICRON WITH TONOS
0x07a8 "Ύ" EEK_SYMBOL_CATEGORY_LETTER # Geek_UPSILONaccent Ύ GREEK CAPITAL LETTER UPSILON WITH TONOS
0x07a9 "Ϋ" EEK_SYMBOL_CATEGORY_LETTER # Geek_UPSILONdieresis Ϋ GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA
0x07ab "Ώ" EEK_SYMBOL_CATEGORY_LETTER # Geek_OMEGAaccent Ώ GREEK CAPITAL LETTER OMEGA WITH TONOS
0x07ae "΅" EEK_SYMBOL_CATEGORY_LETTER # Geek_accentdieresis ΅ GREEK DIALYTIKA TONOS
0x07af "―" EEK_SYMBOL_CATEGORY_LETTER # Geek_horizbar ― HORIZONTAL BAR
0x07b1 "ά" EEK_SYMBOL_CATEGORY_LETTER # Geek_alphaaccent ά GREEK SMALL LETTER ALPHA WITH TONOS
0x07b2 "έ" EEK_SYMBOL_CATEGORY_LETTER # Geek_epsilonaccent έ GREEK SMALL LETTER EPSILON WITH TONOS
0x07b3 "ή" EEK_SYMBOL_CATEGORY_LETTER # Geek_etaaccent ή GREEK SMALL LETTER ETA WITH TONOS
0x07b4 "ί" EEK_SYMBOL_CATEGORY_LETTER # Geek_iotaaccent ί GREEK SMALL LETTER IOTA WITH TONOS
0x07b5 "ϊ" EEK_SYMBOL_CATEGORY_LETTER # Geek_iotadieresis ϊ GREEK SMALL LETTER IOTA WITH DIALYTIKA
0x07b6 "ΐ" EEK_SYMBOL_CATEGORY_LETTER # Geek_iotaaccentdieresis ΐ GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS
0x07b7 "ό" EEK_SYMBOL_CATEGORY_LETTER # Geek_omicronaccent ό GREEK SMALL LETTER OMICRON WITH TONOS
0x07b8 "ύ" EEK_SYMBOL_CATEGORY_LETTER # Geek_upsilonaccent ύ GREEK SMALL LETTER UPSILON WITH TONOS
0x07b9 "ϋ" EEK_SYMBOL_CATEGORY_LETTER # Geek_upsilondieresis ϋ GREEK SMALL LETTER UPSILON WITH DIALYTIKA
0x07ba "ΰ" EEK_SYMBOL_CATEGORY_LETTER # Geek_upsilonaccentdieresis ΰ GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS
0x07bb "ώ" EEK_SYMBOL_CATEGORY_LETTER # Geek_omegaaccent ώ GREEK SMALL LETTER OMEGA WITH TONOS
0x07c1 "Α" EEK_SYMBOL_CATEGORY_LETTER # Geek_ALPHA Α GREEK CAPITAL LETTER ALPHA
0x07c2 "Β" EEK_SYMBOL_CATEGORY_LETTER # Geek_BETA Β GREEK CAPITAL LETTER BETA
0x07c3 "Γ" EEK_SYMBOL_CATEGORY_LETTER # Geek_GAMMA Γ GREEK CAPITAL LETTER GAMMA
0x07c4 "Δ" EEK_SYMBOL_CATEGORY_LETTER # Geek_DELTA Δ GREEK CAPITAL LETTER DELTA
0x07c5 "Ε" EEK_SYMBOL_CATEGORY_LETTER # Geek_EPSILON Ε GREEK CAPITAL LETTER EPSILON
0x07c6 "Ζ" EEK_SYMBOL_CATEGORY_LETTER # Geek_ZETA Ζ GREEK CAPITAL LETTER ZETA
0x07c7 "Η" EEK_SYMBOL_CATEGORY_LETTER # Geek_ETA Η GREEK CAPITAL LETTER ETA
0x07c8 "Θ" EEK_SYMBOL_CATEGORY_LETTER # Geek_THETA Θ GREEK CAPITAL LETTER THETA
0x07c9 "Ι" EEK_SYMBOL_CATEGORY_LETTER # Geek_IOTA Ι GREEK CAPITAL LETTER IOTA
0x07ca "Κ" EEK_SYMBOL_CATEGORY_LETTER # Geek_KAPPA Κ GREEK CAPITAL LETTER KAPPA
0x07cb "Λ" EEK_SYMBOL_CATEGORY_LETTER # Geek_LAMBDA Λ GREEK CAPITAL LETTER LAMDA
0x07cc "Μ" EEK_SYMBOL_CATEGORY_LETTER # Geek_MU Μ GREEK CAPITAL LETTER MU
0x07cd "Ν" EEK_SYMBOL_CATEGORY_LETTER # Geek_NU Ν GREEK CAPITAL LETTER NU
0x07ce "Ξ" EEK_SYMBOL_CATEGORY_LETTER # Geek_XI Ξ GREEK CAPITAL LETTER XI
0x07cf "Ο" EEK_SYMBOL_CATEGORY_LETTER # Geek_OMICRON Ο GREEK CAPITAL LETTER OMICRON
0x07d0 "Π" EEK_SYMBOL_CATEGORY_LETTER # Geek_PI Π GREEK CAPITAL LETTER PI
0x07d1 "Ρ" EEK_SYMBOL_CATEGORY_LETTER # Geek_RHO Ρ GREEK CAPITAL LETTER RHO
0x07d2 "Σ" EEK_SYMBOL_CATEGORY_LETTER # Geek_SIGMA Σ GREEK CAPITAL LETTER SIGMA
0x07d4 "Τ" EEK_SYMBOL_CATEGORY_LETTER # Geek_TAU Τ GREEK CAPITAL LETTER TAU
0x07d5 "Υ" EEK_SYMBOL_CATEGORY_LETTER # Geek_UPSILON Υ GREEK CAPITAL LETTER UPSILON
0x07d6 "Φ" EEK_SYMBOL_CATEGORY_LETTER # Geek_PHI Φ GREEK CAPITAL LETTER PHI
0x07d7 "Χ" EEK_SYMBOL_CATEGORY_LETTER # Geek_CHI Χ GREEK CAPITAL LETTER CHI
0x07d8 "Ψ" EEK_SYMBOL_CATEGORY_LETTER # Geek_PSI Ψ GREEK CAPITAL LETTER PSI
0x07d9 "Ω" EEK_SYMBOL_CATEGORY_LETTER # Geek_OMEGA Ω GREEK CAPITAL LETTER OMEGA
0x07e1 "α" EEK_SYMBOL_CATEGORY_LETTER # Geek_alpha α GREEK SMALL LETTER ALPHA
0x07e2 "β" EEK_SYMBOL_CATEGORY_LETTER # Geek_beta β GREEK SMALL LETTER BETA
0x07e3 "γ" EEK_SYMBOL_CATEGORY_LETTER # Geek_gamma γ GREEK SMALL LETTER GAMMA
0x07e4 "δ" EEK_SYMBOL_CATEGORY_LETTER # Geek_delta δ GREEK SMALL LETTER DELTA
0x07e5 "ε" EEK_SYMBOL_CATEGORY_LETTER # Geek_epsilon ε GREEK SMALL LETTER EPSILON
0x07e6 "ζ" EEK_SYMBOL_CATEGORY_LETTER # Geek_zeta ζ GREEK SMALL LETTER ZETA
0x07e7 "η" EEK_SYMBOL_CATEGORY_LETTER # Geek_eta η GREEK SMALL LETTER ETA
0x07e8 "θ" EEK_SYMBOL_CATEGORY_LETTER # Geek_theta θ GREEK SMALL LETTER THETA
0x07e9 "ι" EEK_SYMBOL_CATEGORY_LETTER # Geek_iota ι GREEK SMALL LETTER IOTA
0x07ea "κ" EEK_SYMBOL_CATEGORY_LETTER # Geek_kappa κ GREEK SMALL LETTER KAPPA
0x07eb "λ" EEK_SYMBOL_CATEGORY_LETTER # Geek_lambda λ GREEK SMALL LETTER LAMDA
0x07ec "μ" EEK_SYMBOL_CATEGORY_LETTER # Geek_mu μ GREEK SMALL LETTER MU
0x07ed "ν" EEK_SYMBOL_CATEGORY_LETTER # Geek_nu ν GREEK SMALL LETTER NU
0x07ee "ξ" EEK_SYMBOL_CATEGORY_LETTER # Geek_xi ξ GREEK SMALL LETTER XI
0x07ef "ο" EEK_SYMBOL_CATEGORY_LETTER # Geek_omicron ο GREEK SMALL LETTER OMICRON
0x07f0 "π" EEK_SYMBOL_CATEGORY_LETTER # Geek_pi π GREEK SMALL LETTER PI
0x07f1 "ρ" EEK_SYMBOL_CATEGORY_LETTER # Geek_rho ρ GREEK SMALL LETTER RHO
0x07f2 "σ" EEK_SYMBOL_CATEGORY_LETTER # Geek_sigma σ GREEK SMALL LETTER SIGMA
0x07f3 "ς" EEK_SYMBOL_CATEGORY_LETTER # Geek_finalsmallsigma ς GREEK SMALL LETTER FINAL SIGMA
0x07f4 "τ" EEK_SYMBOL_CATEGORY_LETTER # Geek_tau τ GREEK SMALL LETTER TAU
0x07f5 "υ" EEK_SYMBOL_CATEGORY_LETTER # Geek_upsilon υ GREEK SMALL LETTER UPSILON
0x07f6 "φ" EEK_SYMBOL_CATEGORY_LETTER # Geek_phi φ GREEK SMALL LETTER PHI
0x07f7 "χ" EEK_SYMBOL_CATEGORY_LETTER # Geek_chi χ GREEK SMALL LETTER CHI
0x07f8 "ψ" EEK_SYMBOL_CATEGORY_LETTER # Geek_psi ψ GREEK SMALL LETTER PSI
0x07f9 "ω" EEK_SYMBOL_CATEGORY_LETTER # Geek_omega ω GREEK SMALL LETTER OMEGA
# 0x08a1 leftradical ? ???
# 0x08a2 topleftradical ? ???
# 0x08a3 horizconnector ? ???
0x08a4 "⌠" EEK_SYMBOL_CATEGORY_LETTER # topintegral ⌠ TOP HALF INTEGRAL
0x08a5 "⌡" EEK_SYMBOL_CATEGORY_LETTER # botintegral ⌡ BOTTOM HALF INTEGRAL
0x08a6 "│" EEK_SYMBOL_CATEGORY_LETTER # vertconnector │ BOX DRAWINGS LIGHT VERTICAL
# 0x08a7 topleftsqbracket ? ???
# 0x08a8 botleftsqbracket ? ???
# 0x08a9 toprightsqbracket ? ???
# 0x08aa botrightsqbracket ? ???
# 0x08ab topleftparens ? ???
# 0x08ac botleftparens ? ???
# 0x08ad toprightparens ? ???
# 0x08ae botrightparens ? ???
# 0x08af leftmiddlecurlybrace ? ???
# 0x08b0 rightmiddlecurlybrace ? ???
# 0x08b1 topleftsummation ? ???
# 0x08b2 botleftsummation ? ???
# 0x08b3 topvertsummationconnector ? ???
# 0x08b4 botvertsummationconnector ? ???
# 0x08b5 toprightsummation ? ???
# 0x08b6 botrightsummation ? ???
# 0x08b7 rightmiddlesummation ? ???
0x08bc "≤" EEK_SYMBOL_CATEGORY_LETTER # lessthanequal ≤ LESS-THAN OR EQUAL TO
0x08bd "≠" EEK_SYMBOL_CATEGORY_LETTER # notequal ≠ NOT EQUAL TO
0x08be "≥" EEK_SYMBOL_CATEGORY_LETTER # greaterthanequal ≥ GREATER-THAN OR EQUAL TO
0x08bf "∫" EEK_SYMBOL_CATEGORY_LETTER # integral ∫ INTEGRAL
0x08c0 "∴" EEK_SYMBOL_CATEGORY_LETTER # therefore ∴ THEREFORE
0x08c1 "∝" EEK_SYMBOL_CATEGORY_LETTER # variation ∝ PROPORTIONAL TO
0x08c2 "∞" EEK_SYMBOL_CATEGORY_LETTER # infinity ∞ INFINITY
0x08c5 "∇" EEK_SYMBOL_CATEGORY_LETTER # nabla ∇ NABLA
0x08c8 "≅" EEK_SYMBOL_CATEGORY_LETTER # approximate ≅ APPROXIMATELY EQUAL TO
# 0x08c9 similarequal ? ???
0x08cd "⇔" EEK_SYMBOL_CATEGORY_LETTER # ifonlyif ⇔ LEFT RIGHT DOUBLE ARROW
0x08ce "⇒" EEK_SYMBOL_CATEGORY_LETTER # implies ⇒ RIGHTWARDS DOUBLE ARROW
0x08cf "≡" EEK_SYMBOL_CATEGORY_LETTER # identical ≡ IDENTICAL TO
0x08d6 "√" EEK_SYMBOL_CATEGORY_LETTER # radical √ SQUARE ROOT
0x08da "⊂" EEK_SYMBOL_CATEGORY_LETTER # includedin ⊂ SUBSET OF
0x08db "⊃" EEK_SYMBOL_CATEGORY_LETTER # includes ⊃ SUPERSET OF
0x08dc "∩" EEK_SYMBOL_CATEGORY_LETTER # intersection ∩ INTERSECTION
0x08dd "" EEK_SYMBOL_CATEGORY_LETTER # union UNION
0x08de "∧" EEK_SYMBOL_CATEGORY_LETTER # logicaland ∧ LOGICAL AND
0x08df "" EEK_SYMBOL_CATEGORY_LETTER # logicalor LOGICAL OR
0x08ef "∂" EEK_SYMBOL_CATEGORY_LETTER # partialderivative ∂ PARTIAL DIFFERENTIAL
0x08f6 "ƒ" EEK_SYMBOL_CATEGORY_LETTER # function ƒ LATIN SMALL LETTER F WITH HOOK
0x08fb "←" EEK_SYMBOL_CATEGORY_LETTER # leftarrow ← LEFTWARDS ARROW
0x08fc "↑" EEK_SYMBOL_CATEGORY_LETTER # uparrow ↑ UPWARDS ARROW
0x08fd "→" EEK_SYMBOL_CATEGORY_LETTER # rightarrow → RIGHTWARDS ARROW
0x08fe "↓" EEK_SYMBOL_CATEGORY_LETTER # downarrow ↓ DOWNWARDS ARROW
0x09df "␢" EEK_SYMBOL_CATEGORY_LETTER # blank ␢ BLANK SYMBOL
0x09e0 "◆" EEK_SYMBOL_CATEGORY_LETTER # soliddiamond ◆ BLACK DIAMOND
0x09e1 "▒" EEK_SYMBOL_CATEGORY_LETTER # checkerboard ▒ MEDIUM SHADE
0x09e2 "␉" EEK_SYMBOL_CATEGORY_LETTER # ht ␉ SYMBOL FOR HORIZONTAL TABULATION
0x09e3 "␌" EEK_SYMBOL_CATEGORY_LETTER # ff ␌ SYMBOL FOR FORM FEED
0x09e4 "␍" EEK_SYMBOL_CATEGORY_LETTER # cr ␍ SYMBOL FOR CARRIAGE RETURN
0x09e5 "␊" EEK_SYMBOL_CATEGORY_LETTER # lf ␊ SYMBOL FOR LINE FEED
0x09e8 "␤" EEK_SYMBOL_CATEGORY_LETTER # nl ␤ SYMBOL FOR NEWLINE
0x09e9 "␋" EEK_SYMBOL_CATEGORY_LETTER # vt ␋ SYMBOL FOR VERTICAL TABULATION
0x09ea "┘" EEK_SYMBOL_CATEGORY_LETTER # lowrightcorner ┘ BOX DRAWINGS LIGHT UP AND LEFT
0x09eb "┐" EEK_SYMBOL_CATEGORY_LETTER # uprightcorner ┐ BOX DRAWINGS LIGHT DOWN AND LEFT
0x09ec "┌" EEK_SYMBOL_CATEGORY_LETTER # upleftcorner ┌ BOX DRAWINGS LIGHT DOWN AND RIGHT
0x09ed "└" EEK_SYMBOL_CATEGORY_LETTER # lowleftcorner └ BOX DRAWINGS LIGHT UP AND RIGHT
0x09ee "┼" EEK_SYMBOL_CATEGORY_LETTER # crossinglines ┼ BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL
# 0x09ef horizlinescan1 ? ???
# 0x09f0 horizlinescan3 ? ???
0x09f1 "─" EEK_SYMBOL_CATEGORY_LETTER # horizlinescan5 ─ BOX DRAWINGS LIGHT HORIZONTAL
# 0x09f2 horizlinescan7 ? ???
# 0x09f3 horizlinescan9 ? ???
0x09f4 "├" EEK_SYMBOL_CATEGORY_LETTER # leftt ├ BOX DRAWINGS LIGHT VERTICAL AND RIGHT
0x09f5 "┤" EEK_SYMBOL_CATEGORY_LETTER # rightt ┤ BOX DRAWINGS LIGHT VERTICAL AND LEFT
0x09f6 "┴" EEK_SYMBOL_CATEGORY_LETTER # bott ┴ BOX DRAWINGS LIGHT UP AND HORIZONTAL
0x09f7 "┬" EEK_SYMBOL_CATEGORY_LETTER # topt ┬ BOX DRAWINGS LIGHT DOWN AND HORIZONTAL
0x09f8 "│" EEK_SYMBOL_CATEGORY_LETTER # vertbar │ BOX DRAWINGS LIGHT VERTICAL
0x0aa1 "" EEK_SYMBOL_CATEGORY_LETTER # emspace EM SPACE
0x0aa2 "" EEK_SYMBOL_CATEGORY_LETTER # enspace EN SPACE
0x0aa3 "" EEK_SYMBOL_CATEGORY_LETTER # em3space THREE-PER-EM SPACE
0x0aa4 "" EEK_SYMBOL_CATEGORY_LETTER # em4space FOUR-PER-EM SPACE
0x0aa5 "" EEK_SYMBOL_CATEGORY_LETTER # digitspace FIGURE SPACE
0x0aa6 "" EEK_SYMBOL_CATEGORY_LETTER # punctspace PUNCTUATION SPACE
0x0aa7 "" EEK_SYMBOL_CATEGORY_LETTER # thinspace THIN SPACE
0x0aa8 "" EEK_SYMBOL_CATEGORY_LETTER # hairspace HAIR SPACE
0x0aa9 "—" EEK_SYMBOL_CATEGORY_LETTER # emdash — EM DASH
0x0aaa "" EEK_SYMBOL_CATEGORY_LETTER # endash EN DASH
# 0x0aac signifblank ? ???
0x0aae "…" EEK_SYMBOL_CATEGORY_LETTER # ellipsis … HORIZONTAL ELLIPSIS
# 0x0aaf doubbaselinedot ? ???
0x0ab0 "⅓" EEK_SYMBOL_CATEGORY_LETTER # onethird ⅓ VULGAR FRACTION ONE THIRD
0x0ab1 "⅔" EEK_SYMBOL_CATEGORY_LETTER # twothirds ⅔ VULGAR FRACTION TWO THIRDS
0x0ab2 "⅕" EEK_SYMBOL_CATEGORY_LETTER # onefifth ⅕ VULGAR FRACTION ONE FIFTH
0x0ab3 "⅖" EEK_SYMBOL_CATEGORY_LETTER # twofifths ⅖ VULGAR FRACTION TWO FIFTHS
0x0ab4 "⅗" EEK_SYMBOL_CATEGORY_LETTER # threefifths ⅗ VULGAR FRACTION THREE FIFTHS
0x0ab5 "⅘" EEK_SYMBOL_CATEGORY_LETTER # fourfifths ⅘ VULGAR FRACTION FOUR FIFTHS
0x0ab6 "⅙" EEK_SYMBOL_CATEGORY_LETTER # onesixth ⅙ VULGAR FRACTION ONE SIXTH
0x0ab7 "⅚" EEK_SYMBOL_CATEGORY_LETTER # fivesixths ⅚ VULGAR FRACTION FIVE SIXTHS
0x0ab8 "℅" EEK_SYMBOL_CATEGORY_LETTER # careof ℅ CARE OF
0x0abb "" EEK_SYMBOL_CATEGORY_LETTER # figdash FIGURE DASH
0x0abc "〈" EEK_SYMBOL_CATEGORY_LETTER # leftanglebracket 〈 LEFT-POINTING ANGLE BRACKET
0x0abd "." EEK_SYMBOL_CATEGORY_LETTER # decimalpoint . FULL STOP
0x0abe "〉" EEK_SYMBOL_CATEGORY_LETTER # rightanglebracket 〉 RIGHT-POINTING ANGLE BRACKET
# 0x0abf marker ? ???
0x0ac3 "⅛" EEK_SYMBOL_CATEGORY_LETTER # oneeighth ⅛ VULGAR FRACTION ONE EIGHTH
0x0ac4 "⅜" EEK_SYMBOL_CATEGORY_LETTER # threeeighths ⅜ VULGAR FRACTION THREE EIGHTHS
0x0ac5 "⅝" EEK_SYMBOL_CATEGORY_LETTER # fiveeighths ⅝ VULGAR FRACTION FIVE EIGHTHS
0x0ac6 "⅞" EEK_SYMBOL_CATEGORY_LETTER # seveneighths ⅞ VULGAR FRACTION SEVEN EIGHTHS
0x0ac9 "™" EEK_SYMBOL_CATEGORY_LETTER # trademark ™ TRADE MARK SIGN
0x0aca "☓" EEK_SYMBOL_CATEGORY_LETTER # signaturemark ☓ SALTIRE
# 0x0acb trademarkincircle ? ???
0x0acc "◁" EEK_SYMBOL_CATEGORY_LETTER # leftopentriangle ◁ WHITE LEFT-POINTING TRIANGLE
0x0acd "▷" EEK_SYMBOL_CATEGORY_LETTER # rightopentriangle ▷ WHITE RIGHT-POINTING TRIANGLE
0x0ace "○" EEK_SYMBOL_CATEGORY_LETTER # emopencircle ○ WHITE CIRCLE
0x0acf "□" EEK_SYMBOL_CATEGORY_LETTER # emopenrectangle □ WHITE SQUARE
0x0ad0 "" EEK_SYMBOL_CATEGORY_LETTER # leftsinglequotemark LEFT SINGLE QUOTATION MARK
0x0ad1 "" EEK_SYMBOL_CATEGORY_LETTER # rightsinglequotemark RIGHT SINGLE QUOTATION MARK
0x0ad2 "“" EEK_SYMBOL_CATEGORY_LETTER # leftdoublequotemark “ LEFT DOUBLE QUOTATION MARK
0x0ad3 "”" EEK_SYMBOL_CATEGORY_LETTER # rightdoublequotemark ” RIGHT DOUBLE QUOTATION MARK
0x0ad4 "℞" EEK_SYMBOL_CATEGORY_LETTER # prescription ℞ PRESCRIPTION TAKE
0x0ad6 "" EEK_SYMBOL_CATEGORY_LETTER # minutes PRIME
0x0ad7 "″" EEK_SYMBOL_CATEGORY_LETTER # seconds ″ DOUBLE PRIME
0x0ad9 "✝" EEK_SYMBOL_CATEGORY_LETTER # latincross ✝ LATIN CROSS
# 0x0ada hexagram ? ???
0x0adb "▬" EEK_SYMBOL_CATEGORY_LETTER # filledrectbullet ▬ BLACK RECTANGLE
0x0adc "◀" EEK_SYMBOL_CATEGORY_LETTER # filledlefttribullet ◀ BLACK LEFT-POINTING TRIANGLE
0x0add "▶" EEK_SYMBOL_CATEGORY_LETTER # filledrighttribullet ▶ BLACK RIGHT-POINTING TRIANGLE
0x0ade "●" EEK_SYMBOL_CATEGORY_LETTER # emfilledcircle ● BLACK CIRCLE
0x0adf "■" EEK_SYMBOL_CATEGORY_LETTER # emfilledrect ■ BLACK SQUARE
0x0ae0 "◦" EEK_SYMBOL_CATEGORY_LETTER # enopencircbullet ◦ WHITE BULLET
0x0ae1 "▫" EEK_SYMBOL_CATEGORY_LETTER # enopensquarebullet ▫ WHITE SMALL SQUARE
0x0ae2 "▭" EEK_SYMBOL_CATEGORY_LETTER # openrectbullet ▭ WHITE RECTANGLE
0x0ae3 "△" EEK_SYMBOL_CATEGORY_LETTER # opentribulletup △ WHITE UP-POINTING TRIANGLE
0x0ae4 "▽" EEK_SYMBOL_CATEGORY_LETTER # opentribulletdown ▽ WHITE DOWN-POINTING TRIANGLE
0x0ae5 "☆" EEK_SYMBOL_CATEGORY_LETTER # openstar ☆ WHITE STAR
0x0ae6 "•" EEK_SYMBOL_CATEGORY_LETTER # enfilledcircbullet • BULLET
0x0ae7 "▪" EEK_SYMBOL_CATEGORY_LETTER # enfilledsqbullet ▪ BLACK SMALL SQUARE
0x0ae8 "▲" EEK_SYMBOL_CATEGORY_LETTER # filledtribulletup ▲ BLACK UP-POINTING TRIANGLE
0x0ae9 "▼" EEK_SYMBOL_CATEGORY_LETTER # filledtribulletdown ▼ BLACK DOWN-POINTING TRIANGLE
0x0aea "☜" EEK_SYMBOL_CATEGORY_LETTER # leftpointer ☜ WHITE LEFT POINTING INDEX
0x0aeb "☞" EEK_SYMBOL_CATEGORY_LETTER # rightpointer ☞ WHITE RIGHT POINTING INDEX
0x0aec "♣" EEK_SYMBOL_CATEGORY_LETTER # club ♣ BLACK CLUB SUIT
0x0aed "♦" EEK_SYMBOL_CATEGORY_LETTER # diamond ♦ BLACK DIAMOND SUIT
0x0aee "♥" EEK_SYMBOL_CATEGORY_LETTER # heart ♥ BLACK HEART SUIT
0x0af0 "✠" EEK_SYMBOL_CATEGORY_LETTER # maltesecross ✠ MALTESE CROSS
0x0af1 "†" EEK_SYMBOL_CATEGORY_LETTER # dagger † DAGGER
0x0af2 "‡" EEK_SYMBOL_CATEGORY_LETTER # doubledagger ‡ DOUBLE DAGGER
0x0af3 "✓" EEK_SYMBOL_CATEGORY_LETTER # checkmark ✓ CHECK MARK
0x0af4 "✗" EEK_SYMBOL_CATEGORY_LETTER # ballotcross ✗ BALLOT X
0x0af5 "♯" EEK_SYMBOL_CATEGORY_LETTER # musicalsharp ♯ MUSIC SHARP SIGN
0x0af6 "♭" EEK_SYMBOL_CATEGORY_LETTER # musicalflat ♭ MUSIC FLAT SIGN
0x0af7 "♂" EEK_SYMBOL_CATEGORY_LETTER # malesymbol ♂ MALE SIGN
0x0af8 "♀" EEK_SYMBOL_CATEGORY_LETTER # femalesymbol ♀ FEMALE SIGN
0x0af9 "☎" EEK_SYMBOL_CATEGORY_LETTER # telephone ☎ BLACK TELEPHONE
0x0afa "⌕" EEK_SYMBOL_CATEGORY_LETTER # telephonerecorder ⌕ TELEPHONE RECORDER
0x0afb "℗" EEK_SYMBOL_CATEGORY_LETTER # phonographcopyright ℗ SOUND RECORDING COPYRIGHT
0x0afc "‸" EEK_SYMBOL_CATEGORY_LETTER # caret ‸ CARET
0x0afd "" EEK_SYMBOL_CATEGORY_LETTER # singlelowquotemark SINGLE LOW-9 QUOTATION MARK
0x0afe "„" EEK_SYMBOL_CATEGORY_LETTER # doublelowquotemark „ DOUBLE LOW-9 QUOTATION MARK
# 0x0aff cursor ? ???
0x0ba3 "<" EEK_SYMBOL_CATEGORY_LETTER # leftcaret < LESS-THAN SIGN
0x0ba6 ">" EEK_SYMBOL_CATEGORY_LETTER # rightcaret > GREATER-THAN SIGN
0x0ba8 "" EEK_SYMBOL_CATEGORY_LETTER # downcaret LOGICAL OR
0x0ba9 "∧" EEK_SYMBOL_CATEGORY_LETTER # upcaret ∧ LOGICAL AND
0x0bc0 "¯" EEK_SYMBOL_CATEGORY_LETTER # overbar ¯ MACRON
0x0bc2 "" EEK_SYMBOL_CATEGORY_LETTER # downtack DOWN TACK
0x0bc3 "∩" EEK_SYMBOL_CATEGORY_LETTER # upshoe ∩ INTERSECTION
0x0bc4 "⌊" EEK_SYMBOL_CATEGORY_LETTER # downstile ⌊ LEFT FLOOR
0x0bc6 "_" EEK_SYMBOL_CATEGORY_LETTER # underbar _ LOW LINE
0x0bca "∘" EEK_SYMBOL_CATEGORY_LETTER # jot ∘ RING OPERATOR
0x0bcc "⎕" EEK_SYMBOL_CATEGORY_LETTER # quad ⎕ APL FUNCTIONAL SYMBOL QUAD (Unicode 3.0)
0x0bce "⊥" EEK_SYMBOL_CATEGORY_LETTER # uptack ⊥ UP TACK
0x0bcf "○" EEK_SYMBOL_CATEGORY_LETTER # circle ○ WHITE CIRCLE
0x0bd3 "⌈" EEK_SYMBOL_CATEGORY_LETTER # upstile ⌈ LEFT CEILING
0x0bd6 "" EEK_SYMBOL_CATEGORY_LETTER # downshoe UNION
0x0bd8 "⊃" EEK_SYMBOL_CATEGORY_LETTER # rightshoe ⊃ SUPERSET OF
0x0bda "⊂" EEK_SYMBOL_CATEGORY_LETTER # leftshoe ⊂ SUBSET OF
0x0bdc "⊣" EEK_SYMBOL_CATEGORY_LETTER # lefttack ⊣ LEFT TACK
0x0bfc "⊢" EEK_SYMBOL_CATEGORY_LETTER # righttack ⊢ RIGHT TACK
0x0cdf "‗" EEK_SYMBOL_CATEGORY_LETTER # hebrew_doublelowline ‗ DOUBLE LOW LINE
0x0ce0 "א" EEK_SYMBOL_CATEGORY_LETTER # hebrew_aleph א HEBREW LETTER ALEF
0x0ce1 "ב" EEK_SYMBOL_CATEGORY_LETTER # hebrew_bet ב HEBREW LETTER BET
0x0ce2 "ג" EEK_SYMBOL_CATEGORY_LETTER # hebrew_gimel ג HEBREW LETTER GIMEL
0x0ce3 "ד" EEK_SYMBOL_CATEGORY_LETTER # hebrew_dalet ד HEBREW LETTER DALET
0x0ce4 "ה" EEK_SYMBOL_CATEGORY_LETTER # hebrew_he ה HEBREW LETTER HE
0x0ce5 "ו" EEK_SYMBOL_CATEGORY_LETTER # hebrew_waw ו HEBREW LETTER VAV
0x0ce6 "ז" EEK_SYMBOL_CATEGORY_LETTER # hebrew_zain ז HEBREW LETTER ZAYIN
0x0ce7 "ח" EEK_SYMBOL_CATEGORY_LETTER # hebrew_chet ח HEBREW LETTER HET
0x0ce8 "ט" EEK_SYMBOL_CATEGORY_LETTER # hebrew_tet ט HEBREW LETTER TET
0x0ce9 "י" EEK_SYMBOL_CATEGORY_LETTER # hebrew_yod י HEBREW LETTER YOD
0x0cea "ך" EEK_SYMBOL_CATEGORY_LETTER # hebrew_finalkaph ך HEBREW LETTER FINAL KAF
0x0ceb "כ" EEK_SYMBOL_CATEGORY_LETTER # hebrew_kaph כ HEBREW LETTER KAF
0x0cec "ל" EEK_SYMBOL_CATEGORY_LETTER # hebrew_lamed ל HEBREW LETTER LAMED
0x0ced "ם" EEK_SYMBOL_CATEGORY_LETTER # hebrew_finalmem ם HEBREW LETTER FINAL MEM
0x0cee "מ" EEK_SYMBOL_CATEGORY_LETTER # hebrew_mem מ HEBREW LETTER MEM
0x0cef "ן" EEK_SYMBOL_CATEGORY_LETTER # hebrew_finalnun ן HEBREW LETTER FINAL NUN
0x0cf0 "נ" EEK_SYMBOL_CATEGORY_LETTER # hebrew_nun נ HEBREW LETTER NUN
0x0cf1 "ס" EEK_SYMBOL_CATEGORY_LETTER # hebrew_samech ס HEBREW LETTER SAMEKH
0x0cf2 "ע" EEK_SYMBOL_CATEGORY_LETTER # hebrew_ayin ע HEBREW LETTER AYIN
0x0cf3 "ף" EEK_SYMBOL_CATEGORY_LETTER # hebrew_finalpe ף HEBREW LETTER FINAL PE
0x0cf4 "פ" EEK_SYMBOL_CATEGORY_LETTER # hebrew_pe פ HEBREW LETTER PE
0x0cf5 "ץ" EEK_SYMBOL_CATEGORY_LETTER # hebrew_finalzade ץ HEBREW LETTER FINAL TSADI
0x0cf6 "צ" EEK_SYMBOL_CATEGORY_LETTER # hebrew_zade צ HEBREW LETTER TSADI
0x0cf7 "ק" EEK_SYMBOL_CATEGORY_LETTER # hebrew_qoph ק HEBREW LETTER QOF
0x0cf8 "ר" EEK_SYMBOL_CATEGORY_LETTER # hebrew_resh ר HEBREW LETTER RESH
0x0cf9 "ש" EEK_SYMBOL_CATEGORY_LETTER # hebrew_shin ש HEBREW LETTER SHIN
0x0cfa "ת" EEK_SYMBOL_CATEGORY_LETTER # hebrew_taw ת HEBREW LETTER TAV
0x0da1 "ก" EEK_SYMBOL_CATEGORY_LETTER # Thai_kokai ก THAI CHARACTER KO KAI
0x0da2 "ข" EEK_SYMBOL_CATEGORY_LETTER # Thai_khokhai ข THAI CHARACTER KHO KHAI
0x0da3 "ฃ" EEK_SYMBOL_CATEGORY_LETTER # Thai_khokhuat ฃ THAI CHARACTER KHO KHUAT
0x0da4 "ค" EEK_SYMBOL_CATEGORY_LETTER # Thai_khokhwai ค THAI CHARACTER KHO KHWAI
0x0da5 "ฅ" EEK_SYMBOL_CATEGORY_LETTER # Thai_khokhon ฅ THAI CHARACTER KHO KHON
0x0da6 "ฆ" EEK_SYMBOL_CATEGORY_LETTER # Thai_khorakhang ฆ THAI CHARACTER KHO RAKHANG
0x0da7 "ง" EEK_SYMBOL_CATEGORY_LETTER # Thai_ngongu ง THAI CHARACTER NGO NGU
0x0da8 "จ" EEK_SYMBOL_CATEGORY_LETTER # Thai_chochan จ THAI CHARACTER CHO CHAN
0x0da9 "ฉ" EEK_SYMBOL_CATEGORY_LETTER # Thai_choching ฉ THAI CHARACTER CHO CHING
0x0daa "ช" EEK_SYMBOL_CATEGORY_LETTER # Thai_chochang ช THAI CHARACTER CHO CHANG
0x0dab "ซ" EEK_SYMBOL_CATEGORY_LETTER # Thai_soso ซ THAI CHARACTER SO SO
0x0dac "ฌ" EEK_SYMBOL_CATEGORY_LETTER # Thai_chochoe ฌ THAI CHARACTER CHO CHOE
0x0dad "ญ" EEK_SYMBOL_CATEGORY_LETTER # Thai_yoying ญ THAI CHARACTER YO YING
0x0dae "ฎ" EEK_SYMBOL_CATEGORY_LETTER # Thai_dochada ฎ THAI CHARACTER DO CHADA
0x0daf "ฏ" EEK_SYMBOL_CATEGORY_LETTER # Thai_topatak ฏ THAI CHARACTER TO PATAK
0x0db0 "ฐ" EEK_SYMBOL_CATEGORY_LETTER # Thai_thothan ฐ THAI CHARACTER THO THAN
0x0db1 "ฑ" EEK_SYMBOL_CATEGORY_LETTER # Thai_thonangmontho ฑ THAI CHARACTER THO NANGMONTHO
0x0db2 "ฒ" EEK_SYMBOL_CATEGORY_LETTER # Thai_thophuthao ฒ THAI CHARACTER THO PHUTHAO
0x0db3 "ณ" EEK_SYMBOL_CATEGORY_LETTER # Thai_nonen ณ THAI CHARACTER NO NEN
0x0db4 "ด" EEK_SYMBOL_CATEGORY_LETTER # Thai_dodek ด THAI CHARACTER DO DEK
0x0db5 "ต" EEK_SYMBOL_CATEGORY_LETTER # Thai_totao ต THAI CHARACTER TO TAO
0x0db6 "ถ" EEK_SYMBOL_CATEGORY_LETTER # Thai_thothung ถ THAI CHARACTER THO THUNG
0x0db7 "ท" EEK_SYMBOL_CATEGORY_LETTER # Thai_thothahan ท THAI CHARACTER THO THAHAN
0x0db8 "ธ" EEK_SYMBOL_CATEGORY_LETTER # Thai_thothong ธ THAI CHARACTER THO THONG
0x0db9 "น" EEK_SYMBOL_CATEGORY_LETTER # Thai_nonu น THAI CHARACTER NO NU
0x0dba "บ" EEK_SYMBOL_CATEGORY_LETTER # Thai_bobaimai บ THAI CHARACTER BO BAIMAI
0x0dbb "ป" EEK_SYMBOL_CATEGORY_LETTER # Thai_popla ป THAI CHARACTER PO PLA
0x0dbc "ผ" EEK_SYMBOL_CATEGORY_LETTER # Thai_phophung ผ THAI CHARACTER PHO PHUNG
0x0dbd "ฝ" EEK_SYMBOL_CATEGORY_LETTER # Thai_fofa ฝ THAI CHARACTER FO FA
0x0dbe "พ" EEK_SYMBOL_CATEGORY_LETTER # Thai_phophan พ THAI CHARACTER PHO PHAN
0x0dbf "ฟ" EEK_SYMBOL_CATEGORY_LETTER # Thai_fofan ฟ THAI CHARACTER FO FAN
0x0dc0 "ภ" EEK_SYMBOL_CATEGORY_LETTER # Thai_phosamphao ภ THAI CHARACTER PHO SAMPHAO
0x0dc1 "ม" EEK_SYMBOL_CATEGORY_LETTER # Thai_moma ม THAI CHARACTER MO MA
0x0dc2 "ย" EEK_SYMBOL_CATEGORY_LETTER # Thai_yoyak ย THAI CHARACTER YO YAK
0x0dc3 "ร" EEK_SYMBOL_CATEGORY_LETTER # Thai_rorua ร THAI CHARACTER RO RUA
0x0dc4 "ฤ" EEK_SYMBOL_CATEGORY_LETTER # Thai_ru ฤ THAI CHARACTER RU
0x0dc5 "ล" EEK_SYMBOL_CATEGORY_LETTER # Thai_loling ล THAI CHARACTER LO LING
0x0dc6 "ฦ" EEK_SYMBOL_CATEGORY_LETTER # Thai_lu ฦ THAI CHARACTER LU
0x0dc7 "ว" EEK_SYMBOL_CATEGORY_LETTER # Thai_wowaen ว THAI CHARACTER WO WAEN
0x0dc8 "ศ" EEK_SYMBOL_CATEGORY_LETTER # Thai_sosala ศ THAI CHARACTER SO SALA
0x0dc9 "ษ" EEK_SYMBOL_CATEGORY_LETTER # Thai_sorusi ษ THAI CHARACTER SO RUSI
0x0dca "ส" EEK_SYMBOL_CATEGORY_LETTER # Thai_sosua ส THAI CHARACTER SO SUA
0x0dcb "ห" EEK_SYMBOL_CATEGORY_LETTER # Thai_hohip ห THAI CHARACTER HO HIP
0x0dcc "ฬ" EEK_SYMBOL_CATEGORY_LETTER # Thai_lochula ฬ THAI CHARACTER LO CHULA
0x0dcd "อ" EEK_SYMBOL_CATEGORY_LETTER # Thai_oang อ THAI CHARACTER O ANG
0x0dce "ฮ" EEK_SYMBOL_CATEGORY_LETTER # Thai_honokhuk ฮ THAI CHARACTER HO NOKHUK
0x0dcf "ฯ" EEK_SYMBOL_CATEGORY_LETTER # Thai_paiyannoi ฯ THAI CHARACTER PAIYANNOI
0x0dd0 "ะ" EEK_SYMBOL_CATEGORY_LETTER # Thai_saraa ะ THAI CHARACTER SARA A
0x0dd1 "ั" EEK_SYMBOL_CATEGORY_LETTER # Thai_maihanakat ั THAI CHARACTER MAI HAN-AKAT
0x0dd2 "า" EEK_SYMBOL_CATEGORY_LETTER # Thai_saraaa า THAI CHARACTER SARA AA
0x0dd3 "ำ" EEK_SYMBOL_CATEGORY_LETTER # Thai_saraam ำ THAI CHARACTER SARA AM
0x0dd4 "ิ" EEK_SYMBOL_CATEGORY_LETTER # Thai_sarai ิ THAI CHARACTER SARA I
0x0dd5 "ี" EEK_SYMBOL_CATEGORY_LETTER # Thai_saraii ี THAI CHARACTER SARA II
0x0dd6 "ึ" EEK_SYMBOL_CATEGORY_LETTER # Thai_saraue ึ THAI CHARACTER SARA UE
0x0dd7 "ื" EEK_SYMBOL_CATEGORY_LETTER # Thai_sarauee ื THAI CHARACTER SARA UEE
0x0dd8 "ุ" EEK_SYMBOL_CATEGORY_LETTER # Thai_sarau ุ THAI CHARACTER SARA U
0x0dd9 "ู" EEK_SYMBOL_CATEGORY_LETTER # Thai_sarauu ู THAI CHARACTER SARA UU
0x0dda "ฺ" EEK_SYMBOL_CATEGORY_LETTER # Thai_phinthu ฺ THAI CHARACTER PHINTHU
0x0dde "฾" EEK_SYMBOL_CATEGORY_LETTER # Thai_maihanakat_maitho ฾ ???
0x0ddf "฿" EEK_SYMBOL_CATEGORY_LETTER # Thai_baht ฿ THAI CURRENCY SYMBOL BAHT
0x0de0 "เ" EEK_SYMBOL_CATEGORY_LETTER # Thai_sarae เ THAI CHARACTER SARA E
0x0de1 "แ" EEK_SYMBOL_CATEGORY_LETTER # Thai_saraae แ THAI CHARACTER SARA AE
0x0de2 "โ" EEK_SYMBOL_CATEGORY_LETTER # Thai_sarao โ THAI CHARACTER SARA O
0x0de3 "ใ" EEK_SYMBOL_CATEGORY_LETTER # Thai_saraaimaimuan ใ THAI CHARACTER SARA AI MAIMUAN
0x0de4 "ไ" EEK_SYMBOL_CATEGORY_LETTER # Thai_saraaimaimalai ไ THAI CHARACTER SARA AI MAIMALAI
0x0de5 "ๅ" EEK_SYMBOL_CATEGORY_LETTER # Thai_lakkhangyao ๅ THAI CHARACTER LAKKHANGYAO
0x0de6 "ๆ" EEK_SYMBOL_CATEGORY_LETTER # Thai_maiyamok ๆ THAI CHARACTER MAIYAMOK
0x0de7 "็" EEK_SYMBOL_CATEGORY_LETTER # Thai_maitaikhu ็ THAI CHARACTER MAITAIKHU
0x0de8 "่" EEK_SYMBOL_CATEGORY_LETTER # Thai_maiek ่ THAI CHARACTER MAI EK
0x0de9 "้" EEK_SYMBOL_CATEGORY_LETTER # Thai_maitho ้ THAI CHARACTER MAI THO
0x0dea "๊" EEK_SYMBOL_CATEGORY_LETTER # Thai_maitri ๊ THAI CHARACTER MAI TRI
0x0deb "๋" EEK_SYMBOL_CATEGORY_LETTER # Thai_maichattawa ๋ THAI CHARACTER MAI CHATTAWA
0x0dec "์" EEK_SYMBOL_CATEGORY_LETTER # Thai_thanthakhat ์ THAI CHARACTER THANTHAKHAT
0x0ded "ํ" EEK_SYMBOL_CATEGORY_LETTER # Thai_nikhahit ํ THAI CHARACTER NIKHAHIT
0x0df0 "" EEK_SYMBOL_CATEGORY_LETTER # Thai_leksun THAI DIGIT ZERO
0x0df1 "๑" EEK_SYMBOL_CATEGORY_LETTER # Thai_leknung ๑ THAI DIGIT ONE
0x0df2 "๒" EEK_SYMBOL_CATEGORY_LETTER # Thai_leksong ๒ THAI DIGIT TWO
0x0df3 "๓" EEK_SYMBOL_CATEGORY_LETTER # Thai_leksam ๓ THAI DIGIT THREE
0x0df4 "๔" EEK_SYMBOL_CATEGORY_LETTER # Thai_leksi ๔ THAI DIGIT FOUR
0x0df5 "๕" EEK_SYMBOL_CATEGORY_LETTER # Thai_lekha ๕ THAI DIGIT FIVE
0x0df6 "๖" EEK_SYMBOL_CATEGORY_LETTER # Thai_lekhok ๖ THAI DIGIT SIX
0x0df7 "๗" EEK_SYMBOL_CATEGORY_LETTER # Thai_lekchet ๗ THAI DIGIT SEVEN
0x0df8 "๘" EEK_SYMBOL_CATEGORY_LETTER # Thai_lekpaet ๘ THAI DIGIT EIGHT
0x0df9 "๙" EEK_SYMBOL_CATEGORY_LETTER # Thai_lekkao ๙ THAI DIGIT NINE
0x0ea1 "ㄱ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_Kiyeog ㄱ HANGUL LETTER KIYEOK
0x0ea2 "ㄲ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_SsangKiyeog ㄲ HANGUL LETTER SSANGKIYEOK
0x0ea3 "ㄳ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_KiyeogSios ㄳ HANGUL LETTER KIYEOK-SIOS
0x0ea4 "ㄴ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_Nieun ㄴ HANGUL LETTER NIEUN
0x0ea5 "ㄵ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_NieunJieuj ㄵ HANGUL LETTER NIEUN-CIEUC
0x0ea6 "ㄶ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_NieunHieuh ㄶ HANGUL LETTER NIEUN-HIEUH
0x0ea7 "ㄷ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_Dikeud ㄷ HANGUL LETTER TIKEUT
0x0ea8 "ㄸ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_SsangDikeud ㄸ HANGUL LETTER SSANGTIKEUT
0x0ea9 "ㄹ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_Rieul ㄹ HANGUL LETTER RIEUL
0x0eaa "ㄺ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_RieulKiyeog ㄺ HANGUL LETTER RIEUL-KIYEOK
0x0eab "ㄻ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_RieulMieum ㄻ HANGUL LETTER RIEUL-MIEUM
0x0eac "ㄼ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_RieulPieub ㄼ HANGUL LETTER RIEUL-PIEUP
0x0ead "ㄽ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_RieulSios ㄽ HANGUL LETTER RIEUL-SIOS
0x0eae "ㄾ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_RieulTieut ㄾ HANGUL LETTER RIEUL-THIEUTH
0x0eaf "ㄿ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_RieulPhieuf ㄿ HANGUL LETTER RIEUL-PHIEUPH
0x0eb0 "ㅀ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_RieulHieuh ㅀ HANGUL LETTER RIEUL-HIEUH
0x0eb1 "ㅁ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_Mieum ㅁ HANGUL LETTER MIEUM
0x0eb2 "ㅂ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_Pieub ㅂ HANGUL LETTER PIEUP
0x0eb3 "ㅃ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_SsangPieub ㅃ HANGUL LETTER SSANGPIEUP
0x0eb4 "ㅄ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_PieubSios ㅄ HANGUL LETTER PIEUP-SIOS
0x0eb5 "ㅅ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_Sios ㅅ HANGUL LETTER SIOS
0x0eb6 "ㅆ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_SsangSios ㅆ HANGUL LETTER SSANGSIOS
0x0eb7 "ㅇ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_Ieung ㅇ HANGUL LETTER IEUNG
0x0eb8 "ㅈ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_Jieuj ㅈ HANGUL LETTER CIEUC
0x0eb9 "ㅉ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_SsangJieuj ㅉ HANGUL LETTER SSANGCIEUC
0x0eba "ㅊ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_Cieuc ㅊ HANGUL LETTER CHIEUCH
0x0ebb "ㅋ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_Khieuq ㅋ HANGUL LETTER KHIEUKH
0x0ebc "ㅌ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_Tieut ㅌ HANGUL LETTER THIEUTH
0x0ebd "ㅍ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_Phieuf ㅍ HANGUL LETTER PHIEUPH
0x0ebe "ㅎ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_Hieuh ㅎ HANGUL LETTER HIEUH
0x0ebf "ㅏ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_A ㅏ HANGUL LETTER A
0x0ec0 "ㅐ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_AE ㅐ HANGUL LETTER AE
0x0ec1 "ㅑ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_YA ㅑ HANGUL LETTER YA
0x0ec2 "ㅒ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_YAE ㅒ HANGUL LETTER YAE
0x0ec3 "ㅓ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_EO ㅓ HANGUL LETTER EO
0x0ec4 "ㅔ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_E ㅔ HANGUL LETTER E
0x0ec5 "ㅕ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_YEO ㅕ HANGUL LETTER YEO
0x0ec6 "ㅖ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_YE ㅖ HANGUL LETTER YE
0x0ec7 "ㅗ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_O ㅗ HANGUL LETTER O
0x0ec8 "ㅘ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_WA ㅘ HANGUL LETTER WA
0x0ec9 "ㅙ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_WAE ㅙ HANGUL LETTER WAE
0x0eca "ㅚ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_OE ㅚ HANGUL LETTER OE
0x0ecb "ㅛ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_YO ㅛ HANGUL LETTER YO
0x0ecc "ㅜ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_U ㅜ HANGUL LETTER U
0x0ecd "ㅝ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_WEO ㅝ HANGUL LETTER WEO
0x0ece "ㅞ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_WE ㅞ HANGUL LETTER WE
0x0ecf "ㅟ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_WI ㅟ HANGUL LETTER WI
0x0ed0 "ㅠ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_YU ㅠ HANGUL LETTER YU
0x0ed1 "ㅡ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_EU ㅡ HANGUL LETTER EU
0x0ed2 "ㅢ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_YI ㅢ HANGUL LETTER YI
0x0ed3 "ㅣ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_I ㅣ HANGUL LETTER I
0x0ed4 "ᆨ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_J_Kiyeog ᆨ HANGUL JONGSEONG KIYEOK
0x0ed5 "ᆩ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_J_SsangKiyeog ᆩ HANGUL JONGSEONG SSANGKIYEOK
0x0ed6 "ᆪ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_J_KiyeogSios ᆪ HANGUL JONGSEONG KIYEOK-SIOS
0x0ed7 "ᆫ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_J_Nieun ᆫ HANGUL JONGSEONG NIEUN
0x0ed8 "ᆬ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_J_NieunJieuj ᆬ HANGUL JONGSEONG NIEUN-CIEUC
0x0ed9 "ᆭ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_J_NieunHieuh ᆭ HANGUL JONGSEONG NIEUN-HIEUH
0x0eda "ᆮ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_J_Dikeud ᆮ HANGUL JONGSEONG TIKEUT
0x0edb "ᆯ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_J_Rieul ᆯ HANGUL JONGSEONG RIEUL
0x0edc "ᆰ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_J_RieulKiyeog ᆰ HANGUL JONGSEONG RIEUL-KIYEOK
0x0edd "ᆱ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_J_RieulMieum ᆱ HANGUL JONGSEONG RIEUL-MIEUM
0x0ede "ᆲ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_J_RieulPieub ᆲ HANGUL JONGSEONG RIEUL-PIEUP
0x0edf "ᆳ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_J_RieulSios ᆳ HANGUL JONGSEONG RIEUL-SIOS
0x0ee0 "ᆴ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_J_RieulTieut ᆴ HANGUL JONGSEONG RIEUL-THIEUTH
0x0ee1 "ᆵ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_J_RieulPhieuf ᆵ HANGUL JONGSEONG RIEUL-PHIEUPH
0x0ee2 "ᆶ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_J_RieulHieuh ᆶ HANGUL JONGSEONG RIEUL-HIEUH
0x0ee3 "ᆷ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_J_Mieum ᆷ HANGUL JONGSEONG MIEUM
0x0ee4 "ᆸ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_J_Pieub ᆸ HANGUL JONGSEONG PIEUP
0x0ee5 "ᆹ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_J_PieubSios ᆹ HANGUL JONGSEONG PIEUP-SIOS
0x0ee6 "ᆺ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_J_Sios ᆺ HANGUL JONGSEONG SIOS
0x0ee7 "ᆻ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_J_SsangSios ᆻ HANGUL JONGSEONG SSANGSIOS
0x0ee8 "ᆼ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_J_Ieung ᆼ HANGUL JONGSEONG IEUNG
0x0ee9 "ᆽ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_J_Jieuj ᆽ HANGUL JONGSEONG CIEUC
0x0eea "ᆾ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_J_Cieuc ᆾ HANGUL JONGSEONG CHIEUCH
0x0eeb "ᆿ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_J_Khieuq ᆿ HANGUL JONGSEONG KHIEUKH
0x0eec "ᇀ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_J_Tieut ᇀ HANGUL JONGSEONG THIEUTH
0x0eed "ᇁ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_J_Phieuf ᇁ HANGUL JONGSEONG PHIEUPH
0x0eee "ᇂ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_J_Hieuh ᇂ HANGUL JONGSEONG HIEUH
0x0eef "ㅭ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_RieulYeorinHieuh ㅭ HANGUL LETTER RIEUL-YEORINHIEUH
0x0ef0 "ㅱ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_SunkyeongeumMieum ㅱ HANGUL LETTER KAPYEOUNMIEUM
0x0ef1 "ㅸ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_SunkyeongeumPieub ㅸ HANGUL LETTER KAPYEOUNPIEUP
0x0ef2 "ㅿ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_PanSios ㅿ HANGUL LETTER PANSIOS
# 0x0ef3 Hangul_KkogjiDalrinIeung ? ???
0x0ef4 "ㆄ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_SunkyeongeumPhieuf ㆄ HANGUL LETTER KAPYEOUNPHIEUPH
0x0ef5 "ㆆ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_YeorinHieuh ㆆ HANGUL LETTER YEORINHIEUH
0x0ef6 "ㆍ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_AraeA ㆍ HANGUL LETTER ARAEA
0x0ef7 "ㆎ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_AraeAE ㆎ HANGUL LETTER ARAEAE
0x0ef8 "ᇫ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_J_PanSios ᇫ HANGUL JONGSEONG PANSIOS
# 0x0ef9 Hangul_J_KkogjiDalrinIeung ? ???
0x0efa "ᇹ" EEK_SYMBOL_CATEGORY_LETTER # Hangul_J_YeorinHieuh ᇹ HANGUL JONGSEONG YEORINHIEUH
0x0eff "₩" EEK_SYMBOL_CATEGORY_LETTER # Korean_Won ₩ WON SIGN
0x13bc "Œ" EEK_SYMBOL_CATEGORY_LETTER # OE Œ LATIN CAPITAL LIGATURE OE
0x13bd "œ" EEK_SYMBOL_CATEGORY_LETTER # oe œ LATIN SMALL LIGATURE OE
0x13be "Ÿ" EEK_SYMBOL_CATEGORY_LETTER # Ydiaeresis Ÿ LATIN CAPITAL LETTER Y WITH DIAERESIS
0x20a0 "₠" EEK_SYMBOL_CATEGORY_LETTER # EcuSign ₠ EURO-CURRENCY SIGN
0x20a1 "₡" EEK_SYMBOL_CATEGORY_LETTER # ColonSign ₡ COLON SIGN
0x20a2 "₢" EEK_SYMBOL_CATEGORY_LETTER # CruzeiroSign ₢ CRUZEIRO SIGN
0x20a3 "₣" EEK_SYMBOL_CATEGORY_LETTER # FFrancSign ₣ FRENCH FRANC SIGN
0x20a4 "₤" EEK_SYMBOL_CATEGORY_LETTER # LiraSign ₤ LIRA SIGN
0x20a5 "₥" EEK_SYMBOL_CATEGORY_LETTER # MillSign ₥ MILL SIGN
0x20a6 "₦" EEK_SYMBOL_CATEGORY_LETTER # NairaSign ₦ NAIRA SIGN
0x20a7 "₧" EEK_SYMBOL_CATEGORY_LETTER # PesetaSign ₧ PESETA SIGN
0x20a8 "₨" EEK_SYMBOL_CATEGORY_LETTER # RupeeSign ₨ RUPEE SIGN
0x20a9 "₩" EEK_SYMBOL_CATEGORY_LETTER # WonSign ₩ WON SIGN
0x20aa "₪" EEK_SYMBOL_CATEGORY_LETTER # NewSheqelSign ₪ NEW SHEQEL SIGN
0x20ab "₫" EEK_SYMBOL_CATEGORY_LETTER # DongSign ₫ DONG SIGN
0x20ac "€" EEK_SYMBOL_CATEGORY_LETTER # EuroSign € EURO SIGN
# Following items added to GTK, not in the xterm table
# Numeric keypad
# 0xFF80 # Space *
0xFFAA "*" EEK_SYMBOL_CATEGORY_LETTER # Multiply *
0xFFAB "+" EEK_SYMBOL_CATEGORY_LETTER # Add *
0xFFAC "," EEK_SYMBOL_CATEGORY_LETTER # Separator *
0xFFAD "-" EEK_SYMBOL_CATEGORY_LETTER # Subtract *
0xFFAE "." EEK_SYMBOL_CATEGORY_LETTER # Decimal *
0xFFAF "/" EEK_SYMBOL_CATEGORY_LETTER # Divide *
0xFFB0 "0" EEK_SYMBOL_CATEGORY_LETTER # 0 *
0xFFB1 "1" EEK_SYMBOL_CATEGORY_LETTER # 1 *
0xFFB2 "2" EEK_SYMBOL_CATEGORY_LETTER # 2 *
0xFFB3 "3" EEK_SYMBOL_CATEGORY_LETTER # 3 *
0xFFB4 "4" EEK_SYMBOL_CATEGORY_LETTER # 4 *
0xFFB5 "5" EEK_SYMBOL_CATEGORY_LETTER # 5 *
0xFFB6 "6" EEK_SYMBOL_CATEGORY_LETTER # 6 *
0xFFB7 "7" EEK_SYMBOL_CATEGORY_LETTER # 7 *
0xFFB8 "8" EEK_SYMBOL_CATEGORY_LETTER # 8 *
0xFFB9 "9" EEK_SYMBOL_CATEGORY_LETTER # 9 *
0xFFBD "=" EEK_SYMBOL_CATEGORY_LETTER # Equal *
# End numeric keypad

View File

@ -71,10 +71,11 @@ struct _EekboardContextServicePrivate {
gboolean visible;
gboolean fullscreen;
LevelKeyboard *keyboard; // currently used keyboard
EekKeyboard *keyboard; // currently used keyboard
GHashTable *keyboard_hash; // a table of available keyboards, per layout
// TODO: make use of repeating buttons
EekKey *repeat_key;
guint repeat_timeout_id;
gboolean repeat_triggered;
@ -85,10 +86,11 @@ struct _EekboardContextServicePrivate {
G_DEFINE_TYPE_WITH_PRIVATE (EekboardContextService, eekboard_context_service, G_TYPE_OBJECT);
static LevelKeyboard *
static EekKeyboard *
eekboard_context_service_real_create_keyboard (EekboardContextService *self,
const gchar *keyboard_type)
{
EekKeyboard *keyboard;
EekLayout *layout;
GError *error;
@ -133,7 +135,7 @@ eekboard_context_service_real_create_keyboard (EekboardContextService *self,
}
}
}
LevelKeyboard *keyboard = eek_xml_layout_real_create_keyboard(layout, self);
keyboard = eek_keyboard_new (self, layout, CSW, CSH);
if (!keyboard) {
g_error("Failed to create a keyboard");
}
@ -146,19 +148,15 @@ eekboard_context_service_real_create_keyboard (EekboardContextService *self,
gchar *keymap_str = eek_keyboard_get_keymap(keyboard);
int f = open("maprs.map", O_CREAT | O_WRONLY, 0600);
write(f, keymap_str, strlen(keymap_str));
close(f);
struct xkb_keymap *keymap = xkb_keymap_new_from_string(context, keymap_str,
XKB_KEYMAP_FORMAT_TEXT_V1, XKB_KEYMAP_COMPILE_NO_FLAGS);
if (!keymap)
g_error("Bad keymap:\n%s", keymap_str);
free(keymap_str);
xkb_context_unref(context);
if (!keymap) {
g_error("Bad keymap");
}
keyboard->keymap = keymap;
keymap_str = xkb_keymap_get_as_string(keymap, XKB_KEYMAP_FORMAT_TEXT_V1);
@ -307,26 +305,41 @@ settings_update_layout(EekboardContextService *context)
EekboardContextServicePrivate *priv = EEKBOARD_CONTEXT_SERVICE_GET_PRIVATE(context);
switch (priv->purpose) {
case ZWP_TEXT_INPUT_V3_CONTENT_PURPOSE_DIGITS:
case ZWP_TEXT_INPUT_V3_CONTENT_PURPOSE_PIN:
keyboard_layout = g_strdup("digits");
break;
case ZWP_TEXT_INPUT_V3_CONTENT_PURPOSE_NUMBER:
case ZWP_TEXT_INPUT_V3_CONTENT_PURPOSE_PHONE:
keyboard_layout = g_strdup("number");
break;
case ZWP_TEXT_INPUT_V3_CONTENT_PURPOSE_PHONE:
keyboard_layout = g_strdup("phone");
break;
case ZWP_TEXT_INPUT_V3_CONTENT_PURPOSE_URL:
keyboard_layout = g_strdup("url");
break;
case ZWP_TEXT_INPUT_V3_CONTENT_PURPOSE_NORMAL:
default:
;
}
// generic part follows
static guint keyboard_id = 0;
LevelKeyboard *keyboard = g_hash_table_lookup(context->priv->keyboard_hash,
EekKeyboard *keyboard = g_hash_table_lookup(context->priv->keyboard_hash,
GUINT_TO_POINTER(keyboard_id));
// create a keyboard
if (!keyboard) {
keyboard = eekboard_context_service_real_create_keyboard(context, keyboard_layout);
EekboardContextServiceClass *klass = EEKBOARD_CONTEXT_SERVICE_GET_CLASS(context);
keyboard = klass->create_keyboard (context, keyboard_layout);
eek_keyboard_set_modifier_behavior (keyboard,
EEK_MODIFIER_BEHAVIOR_LATCH);
g_hash_table_insert (context->priv->keyboard_hash,
GUINT_TO_POINTER(keyboard_id),
keyboard);
keyboard->id = keyboard_id;
g_object_set_data (G_OBJECT(keyboard),
"keyboard-id",
GUINT_TO_POINTER(keyboard_id));
keyboard_id++;
}
// set as current
@ -367,6 +380,7 @@ eekboard_context_service_class_init (EekboardContextServiceClass *klass)
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
GParamSpec *pspec;
klass->create_keyboard = eekboard_context_service_real_create_keyboard;
klass->show_keyboard = eekboard_context_service_real_show_keyboard;
klass->hide_keyboard = eekboard_context_service_real_hide_keyboard;
@ -431,9 +445,10 @@ eekboard_context_service_class_init (EekboardContextServiceClass *klass)
*
* An #EekKeyboard currently active in this context.
*/
pspec = g_param_spec_pointer("keyboard",
pspec = g_param_spec_object ("keyboard",
"Keyboard",
"Keyboard",
EEK_TYPE_KEYBOARD,
G_PARAM_READWRITE);
g_object_class_install_property (gobject_class,
PROP_KEYBOARD,
@ -569,7 +584,7 @@ eekboard_context_service_destroy (EekboardContextService *context)
* Get keyboard currently active in @context.
* Returns: (transfer none): an #EekKeyboard
*/
LevelKeyboard *
EekKeyboard *
eekboard_context_service_get_keyboard (EekboardContextService *context)
{
return context->priv->keyboard;
@ -589,7 +604,7 @@ eekboard_context_service_get_fullscreen (EekboardContextService *context)
}
void eekboard_context_service_set_keymap(EekboardContextService *context,
const LevelKeyboard *keyboard)
const EekKeyboard *keyboard)
{
zwp_virtual_keyboard_v1_keymap(context->virtual_keyboard,
WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1,

View File

@ -73,7 +73,7 @@ struct _EekboardContextServiceClass {
GObjectClass parent_class;
/*< public >*/
struct squeek_view *(*create_keyboard) (EekboardContextService *self,
EekKeyboard *(*create_keyboard) (EekboardContextService *self,
const gchar *keyboard_type);
void (*show_keyboard) (EekboardContextService *self);
void (*hide_keyboard) (EekboardContextService *self);
@ -97,12 +97,13 @@ void eekboard_context_service_show_keyboard
void eekboard_context_service_hide_keyboard
(EekboardContextService *context);
void eekboard_context_service_destroy (EekboardContextService *context);
LevelKeyboard *eekboard_context_service_get_keyboard(EekboardContextService *context);
EekKeyboard *eekboard_context_service_get_keyboard
(EekboardContextService *context);
gboolean eekboard_context_service_get_fullscreen
(EekboardContextService *context);
void eekboard_context_service_set_keymap(EekboardContextService *context,
const LevelKeyboard *keyboard);
const EekKeyboard *keyboard);
void eekboard_context_service_set_hint_purpose(EekboardContextService *context,
uint32_t hint,

View File

@ -22,7 +22,6 @@
#include "eekboard/key-emitter.h"
#include <gdk/gdk.h>
#include <X11/XKBlib.h>
#include "eekboard/eekboard-context-service.h"
@ -85,23 +84,61 @@ update_modifier_info (SeatEmitter *client)
static void
send_fake_key (SeatEmitter *emitter,
LevelKeyboard *keyboard,
guint level,
guint keycode,
guint keyboard_modifiers,
gboolean pressed,
uint32_t timestamp)
{
guint level = keyboard->level;
uint32_t proto_modifiers = 0;
uint32_t group = (level / 2);
zwp_virtual_keyboard_v1_modifiers(emitter->virtual_keyboard, 0, 0, 0, group);
if (keyboard_modifiers & EEK_SHIFT_MASK)
proto_modifiers |= 1<<MOD_IDX_SHIFT;
zwp_virtual_keyboard_v1_modifiers(emitter->virtual_keyboard, proto_modifiers, 0, 0, group);
send_virtual_keyboard_key (emitter->virtual_keyboard, keycode - 8, (unsigned)pressed, timestamp);
zwp_virtual_keyboard_v1_modifiers(emitter->virtual_keyboard, 0, 0, 0, group);
zwp_virtual_keyboard_v1_modifiers(emitter->virtual_keyboard, proto_modifiers, 0, 0, group);
}
static void
send_fake_text (SeatEmitter *emitter,
EekKeyboard *keyboard,
const gchar *text,
uint32_t timestamp)
{
gchar *ptr = (gchar *)text;
while (*ptr) {
gchar buf[7];
gunichar c = g_utf8_get_char(ptr);
int n = g_unichar_to_utf8(c, buf);
*(buf + n) = 0;
EekKeyPress *key_press = eek_keyboard_get_key_press(keyboard, buf);
if (key_press) {
EekKey *key = key_press->key;
send_fake_key (emitter, key_press->level, eek_key_get_keycode(key),
(key_press->level % 2) == 1 ? EEK_SHIFT_MASK : 0,
1, timestamp);
send_fake_key (emitter, key_press->level, eek_key_get_keycode(key),
(key_press->level % 2) == 1 ? EEK_SHIFT_MASK : 0,
0, timestamp);
}
ptr = g_utf8_find_next_char(ptr, NULL);
}
}
void
emit_key_activated (EekboardContextService *manager,
LevelKeyboard *keyboard,
EekKeyboard *keyboard,
guint keycode,
EekSymbol *symbol,
EekModifierType modifiers,
gboolean pressed,
uint32_t timestamp)
{
@ -136,5 +173,12 @@ emit_key_activated (EekboardContextService *manager,
emitter.virtual_keyboard = manager->virtual_keyboard;
emitter.keymap = keyboard->keymap;
update_modifier_info (&emitter);
send_fake_key (&emitter, keyboard, keycode, pressed, timestamp);
const gchar *text = (gchar *)eek_text_get_text(symbol);
if (text && pressed) {
send_fake_text (&emitter, keyboard, text, timestamp);
} else {
guint level = eek_element_get_level(EEK_ELEMENT(keyboard));
send_fake_key (&emitter, level, keycode, modifiers, pressed, timestamp);
}
}

View File

@ -39,7 +39,9 @@ enum mod_indices {
};
void
emit_key_activated (EekboardContextService *manager, LevelKeyboard *keyboard,
emit_key_activated (EekboardContextService *manager, EekKeyboard *keyboard,
guint keycode,
EekSymbol *symbol,
guint modifiers,
gboolean pressed, uint32_t timestamp);
#endif // KEYEMITTER_H

View File

@ -17,7 +17,6 @@ add_project_arguments(
'-Werror=implicit-fallthrough=3',
'-Werror=maybe-uninitialized',
'-Werror=missing-field-initializers',
'-Werror=incompatible-pointer-types',
],
language: 'c'
)

View File

@ -1,141 +0,0 @@
//! Order floating point numbers, into this ordering:
//!
//! NaN | -Infinity | x < 0 | -0 | +0 | x > 0 | +Infinity | NaN
/* Adapted from https://github.com/notriddle/rust-float-ord revision e995165f
* maintained by Michael Howell <michael@notriddle.com>
* licensed under MIT / Apache-2.0 licenses
*/
extern crate core;
use ::float_ord::core::cmp::{Eq, Ord, Ordering, PartialEq, PartialOrd};
use ::float_ord::core::hash::{Hash, Hasher};
use ::float_ord::core::mem::transmute;
/// A wrapper for floats, that implements total equality and ordering
/// and hashing.
#[derive(Clone, Copy)]
pub struct FloatOrd<T>(pub T);
macro_rules! float_ord_impl {
($f:ident, $i:ident, $n:expr) => {
impl FloatOrd<$f> {
fn convert(self) -> $i {
let u = unsafe { transmute::<$f, $i>(self.0) };
let bit = 1 << ($n - 1);
if u & bit == 0 {
u | bit
} else {
!u
}
}
}
impl PartialEq for FloatOrd<$f> {
fn eq(&self, other: &Self) -> bool {
self.convert() == other.convert()
}
}
impl Eq for FloatOrd<$f> {}
impl PartialOrd for FloatOrd<$f> {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
self.convert().partial_cmp(&other.convert())
}
}
impl Ord for FloatOrd<$f> {
fn cmp(&self, other: &Self) -> Ordering {
self.convert().cmp(&other.convert())
}
}
impl Hash for FloatOrd<$f> {
fn hash<H: Hasher>(&self, state: &mut H) {
self.convert().hash(state);
}
}
}
}
float_ord_impl!(f32, u32, 32);
float_ord_impl!(f64, u64, 64);
/// Sort a slice of floats.
///
/// # Allocation behavior
///
/// This routine uses a quicksort implementation that does not heap allocate.
///
/// # Example
///
/// ```
/// let mut v = [-5.0, 4.0, 1.0, -3.0, 2.0];
///
/// float_ord::sort(&mut v);
/// assert!(v == [-5.0, -3.0, 1.0, 2.0, 4.0]);
/// ```
#[allow(dead_code)]
pub fn sort<T>(v: &mut [T]) where FloatOrd<T>: Ord {
let v_: &mut [FloatOrd<T>] = unsafe { transmute(v) };
v_.sort_unstable();
}
#[cfg(test)]
mod tests {
extern crate std;
use self::std::collections::hash_map::DefaultHasher;
use self::std::hash::{Hash, Hasher};
use super::FloatOrd;
#[test]
fn test_ord() {
assert!(FloatOrd(1.0f64) < FloatOrd(2.0f64));
assert!(FloatOrd(2.0f32) > FloatOrd(1.0f32));
assert!(FloatOrd(1.0f64) == FloatOrd(1.0f64));
assert!(FloatOrd(1.0f32) == FloatOrd(1.0f32));
assert!(FloatOrd(0.0f64) > FloatOrd(-0.0f64));
assert!(FloatOrd(0.0f32) > FloatOrd(-0.0f32));
assert!(FloatOrd(::float_ord::core::f64::NAN) == FloatOrd(::float_ord::core::f64::NAN));
assert!(FloatOrd(::float_ord::core::f32::NAN) == FloatOrd(::float_ord::core::f32::NAN));
assert!(FloatOrd(-::float_ord::core::f64::NAN) < FloatOrd(::float_ord::core::f64::NAN));
assert!(FloatOrd(-::float_ord::core::f32::NAN) < FloatOrd(::float_ord::core::f32::NAN));
assert!(FloatOrd(-::float_ord::core::f64::INFINITY) < FloatOrd(::float_ord::core::f64::INFINITY));
assert!(FloatOrd(-::float_ord::core::f32::INFINITY) < FloatOrd(::float_ord::core::f32::INFINITY));
assert!(FloatOrd(::float_ord::core::f64::INFINITY) < FloatOrd(::float_ord::core::f64::NAN));
assert!(FloatOrd(::float_ord::core::f32::INFINITY) < FloatOrd(::float_ord::core::f32::NAN));
assert!(FloatOrd(-::float_ord::core::f64::NAN) < FloatOrd(::float_ord::core::f64::INFINITY));
assert!(FloatOrd(-::float_ord::core::f32::NAN) < FloatOrd(::float_ord::core::f32::INFINITY));
}
fn hash<F: Hash>(f: F) -> u64 {
let mut hasher = DefaultHasher::new();
f.hash(&mut hasher);
hasher.finish()
}
#[test]
fn test_hash() {
assert_ne!(hash(FloatOrd(0.0f64)), hash(FloatOrd(-0.0f64)));
assert_ne!(hash(FloatOrd(0.0f32)), hash(FloatOrd(-0.0f32)));
assert_eq!(hash(FloatOrd(-0.0f64)), hash(FloatOrd(-0.0f64)));
assert_eq!(hash(FloatOrd(0.0f32)), hash(FloatOrd(0.0f32)));
assert_ne!(hash(FloatOrd(::float_ord::core::f64::NAN)), hash(FloatOrd(-::float_ord::core::f64::NAN)));
assert_ne!(hash(FloatOrd(::float_ord::core::f32::NAN)), hash(FloatOrd(-::float_ord::core::f32::NAN)));
assert_eq!(hash(FloatOrd(::float_ord::core::f64::NAN)), hash(FloatOrd(::float_ord::core::f64::NAN)));
assert_eq!(hash(FloatOrd(-::float_ord::core::f32::NAN)), hash(FloatOrd(-::float_ord::core::f32::NAN)));
}
#[test]
fn test_sort_nan() {
let nan = ::float_ord::core::f64::NAN;
let mut v = [-1.0, 5.0, 0.0, -0.0, nan, 1.5, nan, 3.7];
super::sort(&mut v);
assert!(v[0] == -1.0);
assert!(v[1] == 0.0 && v[1].is_sign_negative());
assert!(v[2] == 0.0 && !v[2].is_sign_negative());
assert!(v[3] == 1.5);
assert!(v[4] == 3.7);
assert!(v[5] == 5.0);
assert!(v[6].is_nan());
assert!(v[7].is_nan());
}
}

View File

@ -1,25 +0,0 @@
#ifndef __KEYBOARD_H
#define __KYBOARD_H
#include "stdbool.h"
#include "inttypes.h"
struct squeek_key;
struct squeek_key *squeek_key_new(uint32_t keycode);
void squeek_key_free(struct squeek_key *key);
void squeek_key_add_symbol(struct squeek_key* key,
const char *element_name,
const char *text, uint32_t keyval,
const char *label, const char *icon,
const char *tooltip);
uint32_t squeek_key_is_pressed(struct squeek_key *key);
void squeek_key_set_pressed(struct squeek_key *key, uint32_t pressed);
uint32_t squeek_key_is_locked(struct squeek_key *key);
void squeek_key_set_locked(struct squeek_key *key, uint32_t pressed);
uint32_t squeek_key_get_keycode(struct squeek_key *key);
void squeek_key_set_keycode(struct squeek_key *key, uint32_t keycode);
struct squeek_symbol *squeek_key_get_symbol(struct squeek_key* key);
const char* squeek_key_to_keymap_entry(const char *key_name, struct squeek_key *key);
#endif

View File

@ -1,300 +0,0 @@
use std::vec::Vec;
use super::symbol;
/// Gathers stuff defined in C or called by C
pub mod c {
use super::*;
use ::util::c::{ as_cstr, into_cstring };
use std::cell::RefCell;
use std::ffi::CString;
use std::os::raw::c_char;
use std::ptr;
use std::rc::Rc;
// traits
use std::borrow::ToOwned;
// The following defined in C
#[no_mangle]
extern "C" {
fn eek_keysym_from_name(name: *const c_char) -> u32;
}
/// The wrapped structure for KeyState suitable for handling in C
/// Since C doesn't respect borrowing rules,
/// RefCell will enforce them dynamically (only 1 writer/many readers)
/// Rc is implied and will ensure timely dropping
#[repr(transparent)]
pub struct CKeyState(*const RefCell<KeyState>);
impl Clone for CKeyState {
fn clone(&self) -> Self {
CKeyState(self.0.clone())
}
}
impl CKeyState {
pub fn wrap(state: Rc<RefCell<KeyState>>) -> CKeyState {
CKeyState(Rc::into_raw(state))
}
pub fn unwrap(self) -> Rc<RefCell<KeyState>> {
unsafe { Rc::from_raw(self.0) }
}
fn to_owned(self) -> KeyState {
let rc = self.unwrap();
let state = rc.borrow().to_owned();
Rc::into_raw(rc); // Prevent dropping
state
}
fn borrow_mut<F, T>(self, f: F) -> T where F: FnOnce(&mut KeyState) -> T {
let rc = self.unwrap();
let ret = {
let mut state = rc.borrow_mut();
f(&mut state)
};
Rc::into_raw(rc); // Prevent dropping
ret
}
}
// TODO: unwrapping
// The following defined in Rust. TODO: wrap naked pointers to Rust data inside RefCells to prevent multiple writers
// TODO: this will receive data from the filesystem,
// so it should handle garbled strings in the future
#[no_mangle]
pub extern "C"
fn squeek_key_new(keycode: u32) -> CKeyState {
let state: Rc<RefCell<KeyState>> = Rc::new(RefCell::new(
KeyState {
pressed: false,
locked: false,
keycode: keycode,
symbol: None,
}
));
CKeyState::wrap(state)
}
#[no_mangle]
pub extern "C"
fn squeek_key_free(key: CKeyState) {
key.unwrap(); // reference dropped
}
#[no_mangle]
pub extern "C"
fn squeek_key_is_pressed(key: CKeyState) -> u32 {
//let key = unsafe { Rc::from_raw(key.0) };
return key.to_owned().pressed as u32;
}
#[no_mangle]
pub extern "C"
fn squeek_key_set_pressed(key: CKeyState, pressed: u32) {
key.borrow_mut(|key| key.pressed = pressed != 0);
}
#[no_mangle]
pub extern "C"
fn squeek_key_is_locked(key: CKeyState) -> u32 {
return key.to_owned().locked as u32;
}
#[no_mangle]
pub extern "C"
fn squeek_key_set_locked(key: CKeyState, locked: u32) {
key.borrow_mut(|key| key.locked = locked != 0);
}
#[no_mangle]
pub extern "C"
fn squeek_key_get_keycode(key: CKeyState) -> u32 {
return key.to_owned().keycode as u32;
}
#[no_mangle]
pub extern "C"
fn squeek_key_set_keycode(key: CKeyState, code: u32) {
key.borrow_mut(|key| key.keycode = code);
}
// TODO: this will receive data from the filesystem,
// so it should handle garbled strings in the future
#[no_mangle]
pub extern "C"
fn squeek_key_add_symbol(
key: CKeyState,
element: *const c_char,
text_raw: *const c_char, keyval: u32,
label: *const c_char, icon: *const c_char,
tooltip: *const c_char,
) {
let element = as_cstr(&element)
.expect("Missing element name");
let text = into_cstring(text_raw)
.unwrap_or_else(|e| {
eprintln!("Text unreadable: {}", e);
None
})
.and_then(|text| {
if text.as_bytes() == b"" {
None
} else {
Some(text)
}
});
let icon = into_cstring(icon)
.unwrap_or_else(|e| {
eprintln!("Icon name unreadable: {}", e);
None
});
use symbol::*;
// Only read label if there's no icon
let label = match icon {
Some(icon) => Label::IconName(icon),
None => Label::Text(
into_cstring(label)
.unwrap_or_else(|e| {
eprintln!("Label unreadable: {}", e);
Some(CString::new(" ").unwrap())
})
.unwrap_or_else(|| {
eprintln!("Label missing");
CString::new(" ").unwrap()
})
),
};
let tooltip = into_cstring(tooltip)
.unwrap_or_else(|e| {
eprintln!("Tooltip unreadable: {}", e);
None
});
key.borrow_mut(|key| {
if let Some(_) = key.symbol {
eprintln!("Key {:?} already has a symbol defined", text);
return;
}
key.symbol = Some(match element.to_bytes() {
b"symbol" => Symbol {
action: Action::Submit {
text: text,
keys: Vec::new(),
},
label: label,
tooltip: tooltip,
},
_ => panic!("unsupported element type {:?}", element),
});
});
}
#[no_mangle]
pub extern "C"
fn squeek_key_get_symbol(key: CKeyState) -> *const symbol::Symbol {
key.borrow_mut(|key| {
match key.symbol {
// This pointer stays after the function exits,
// so it must reference borrowed data and not any copy
Some(ref symbol) => symbol as *const symbol::Symbol,
None => ptr::null(),
}
})
}
#[no_mangle]
pub extern "C"
fn squeek_key_to_keymap_entry(
key_name: *const c_char,
key: CKeyState,
) -> *const c_char {
let key_name = as_cstr(&key_name)
.expect("Missing key name")
.to_str()
.expect("Bad key name");
let symbol_name = match key.to_owned().symbol {
Some(ref symbol) => match &symbol.action {
symbol::Action::Submit { text: Some(text), .. } => {
Some(
text.clone()
.into_string().expect("Bad symbol")
)
},
_ => None
},
None => {
eprintln!("Key {} has no symbol", key_name);
None
},
};
let inner = match symbol_name {
Some(name) => format!("[ {} ]", name),
_ => format!("[ ]"),
};
CString::new(format!(" key <{}> {{ {} }};\n", key_name, inner))
.expect("Couldn't convert string")
.into_raw()
}
#[no_mangle]
pub extern "C"
fn squeek_key_get_action_name(
key_name: *const c_char,
key: CKeyState,
) -> *const c_char {
let key_name = as_cstr(&key_name)
.expect("Missing key name")
.to_str()
.expect("Bad key name");
let symbol_name = match key.to_owned().symbol {
Some(ref symbol) => match &symbol.action {
symbol::Action::Submit { text: Some(text), .. } => {
Some(
text.clone()
.into_string().expect("Bad symbol")
)
},
_ => None
},
None => {
eprintln!("Key {} has no symbol", key_name);
None
},
};
let inner = match symbol_name {
Some(name) => format!("[ {} ]", name),
_ => format!("[ ]"),
};
CString::new(format!(" key <{}> {{ {} }};\n", key_name, inner))
.expect("Couldn't convert string")
.into_raw()
}
}
#[derive(Debug, Clone)]
pub struct KeyState {
pub pressed: bool,
pub locked: bool,
pub keycode: u32,
// TODO: remove the optionality of a symbol
pub symbol: Option<symbol::Symbol>,
}

View File

@ -1,78 +0,0 @@
#ifndef __LAYOUT_H
#define __LAYOUT_H
#include <inttypes.h>
#include <glib.h>
#include "eek/eek-element.h"
#include "src/keyboard.h"
struct squeek_button;
struct squeek_row;
struct squeek_view;
struct squeek_row *squeek_row_new(int32_t angle);
struct squeek_button *squeek_row_create_button (struct squeek_row *row,
guint keycode, guint oref);
struct squeek_button *squeek_row_create_button_with_state(struct squeek_row *row,
struct squeek_button *source);
void squeek_row_set_angle(struct squeek_row *row, int32_t angle);
int32_t squeek_row_get_angle(const struct squeek_row*);
EekBounds squeek_row_get_bounds(const struct squeek_row*);
void squeek_row_set_bounds(struct squeek_row* row, EekBounds bounds);
uint32_t squeek_row_contains(struct squeek_row*, struct squeek_button *button);
struct button_place squeek_view_find_key(struct squeek_view*, struct squeek_key *state);
typedef void (*ButtonCallback) (struct squeek_button *button, gpointer user_data);
void squeek_row_foreach(struct squeek_row*,
ButtonCallback callback,
gpointer user_data);
void squeek_row_free(struct squeek_row*);
/*
struct squeek_button *squeek_buttons_find_by_position(
const struct squeek_buttons *buttons,
double x, double y,
double origin_x, double origin_y,
double angle);
void squeek_buttons_add(struct squeek_buttons*, const struct squeek_button* button);
void squeek_buttons_remove_key(struct squeek_buttons*, const struct squeek_key* key);
*/
struct squeek_button *squeek_button_new(uint32_t keycode, uint32_t oref);
struct squeek_button *squeek_button_new_with_state(const struct squeek_button* source);
uint32_t squeek_button_get_oref(const struct squeek_button*);
EekBounds squeek_button_get_bounds(const struct squeek_button*);
void squeek_button_set_bounds(struct squeek_button* button, EekBounds bounds);
struct squeek_symbol *squeek_button_get_symbol (
const struct squeek_button *button);
struct squeek_key *squeek_button_get_key(const struct squeek_button*);
uint32_t *squeek_button_has_key(const struct squeek_button* button,
const struct squeek_key *key);
void squeek_button_print(const struct squeek_button* button);
struct squeek_view *squeek_view_new(EekBounds bounds);
struct squeek_row *squeek_view_create_row(struct squeek_view *, int32_t angle);
EekBounds squeek_view_get_bounds(const struct squeek_view*);
void squeek_view_set_bounds(const struct squeek_view*, EekBounds bounds);
typedef void (*RowCallback) (struct squeek_row *row, gpointer user_data);
void squeek_view_foreach(struct squeek_view*,
RowCallback callback,
gpointer user_data);
struct squeek_row *squeek_view_get_row(struct squeek_view *view,
struct squeek_button *button);
void
squeek_view_place_contents(struct squeek_view *view, LevelKeyboard *keyboard);
struct squeek_button *squeek_view_find_button_by_position(struct squeek_view *view, EekPoint point);
#endif

View File

@ -1,764 +0,0 @@
/**
* Layout-related data.
*
* The `View` contains `Row`s and each `Row` contains `Button`s.
* They carry data relevant to their positioning only,
* except the Button, which also carries some data
* about its appearance and function.
*
* The layout is determined bottom-up, by measuring `Button` sizes,
* deriving `Row` sizes from them, and then centering them within the `View`.
*
* That makes the `View` position immutable,
* and therefore different than the other positions.
*
* Note that it might be a better idea
* to make `View` position depend on its contents,
* and let the renderer scale and center it within the widget.
*/
use std::cell::RefCell;
use std::rc::Rc;
use std::vec::Vec;
use ::keyboard::*;
use ::float_ord::FloatOrd;
use ::symbol::*;
/// Gathers stuff defined in C or called by C
pub mod c {
use super::*;
use std::os::raw::c_void;
use std::ptr;
// The following defined in C
#[repr(transparent)]
pub struct UserData(*const c_void);
/// The index in the relevant outline table
#[repr(C)]
#[derive(Clone, Debug)]
pub struct OutlineRef(u32);
/// Defined in eek-types.h
#[repr(C)]
#[derive(Clone, Debug)]
pub struct Point {
pub x: f64,
pub y: f64,
}
/// Defined in eek-types.h
#[repr(C)]
#[derive(Clone, Debug)]
pub struct Bounds {
pub x: f64,
pub y: f64,
pub width: f64,
pub height: f64
}
impl Bounds {
pub fn zero() -> Bounds {
Bounds { x: 0f64, y: 0f64, width: 0f64, height: 0f64 }
}
}
type ButtonCallback = unsafe extern "C" fn(button: *mut ::layout::Button, data: *mut UserData);
type RowCallback = unsafe extern "C" fn(row: *mut ::layout::Row, data: *mut UserData);
// The following defined in Rust. TODO: wrap naked pointers to Rust data inside RefCells to prevent multiple writers
#[no_mangle]
pub extern "C"
fn squeek_view_new(bounds: Bounds) -> *mut ::layout::View {
Box::into_raw(Box::new(::layout::View {
rows: Vec::new(),
bounds: bounds,
}))
}
#[no_mangle]
pub extern "C"
fn squeek_view_get_bounds(view: *const ::layout::View) -> Bounds {
unsafe { &*view }.bounds.clone()
}
#[no_mangle]
pub extern "C"
fn squeek_view_set_bounds(view: *mut ::layout::View, bounds: Bounds) {
unsafe { &mut *view }.bounds = bounds;
}
/// Places a row into the view and returns a reference to it
#[no_mangle]
pub extern "C"
fn squeek_view_create_row(
view: *mut ::layout::View,
angle: i32,
) -> *mut ::layout::Row {
let view = unsafe { &mut *view };
view.rows.push(Box::new(::layout::Row::new(angle)));
// Return the reference directly instead of a Box, it's not on the stack
// It will live as long as the Vec
let last_idx = view.rows.len() - 1;
// Caution: Box can't be returned directly,
// so returning a reference to its innards
view.rows[last_idx].as_mut() as *mut ::layout::Row
}
#[no_mangle]
pub extern "C"
fn squeek_view_foreach(
view: *mut ::layout::View,
callback: RowCallback,
data: *mut UserData,
) {
let view = unsafe { &mut *view };
for row in view.rows.iter_mut() {
let row = row.as_mut() as *mut ::layout::Row;
unsafe { callback(row, data) };
}
}
#[no_mangle]
pub extern "C"
fn squeek_row_new(angle: i32) -> *mut ::layout::Row {
Box::into_raw(Box::new(::layout::Row::new(angle)))
}
/// Places a button into the row and returns a reference to it
#[no_mangle]
pub extern "C"
fn squeek_row_create_button(
row: *mut ::layout::Row,
keycode: u32, oref: u32
) -> *mut ::layout::Button {
let row = unsafe { &mut *row };
let state: Rc<RefCell<::keyboard::KeyState>> = Rc::new(RefCell::new(
::keyboard::KeyState {
pressed: false,
locked: false,
keycode: keycode,
symbol: None,
}
));
row.buttons.push(Box::new(::layout::Button {
oref: OutlineRef(oref),
bounds: None,
state: state,
}));
// Return the reference directly instead of a Box, it's not on the stack
// It will live as long as the Vec
let last_idx = row.buttons.len() - 1;
// Caution: Box can't be returned directly,
// so returning a reference to its innards
row.buttons[last_idx].as_mut() as *mut ::layout::Button
}
/// Places a button into the row, copying its state,
/// and returns a reference to it
#[no_mangle]
pub extern "C"
fn squeek_row_create_button_with_state(
row: *mut ::layout::Row,
button: *const ::layout::Button,
) -> *mut ::layout::Button {
let row = unsafe { &mut *row };
let source = unsafe { &*button };
row.buttons.push(Box::new(source.clone()));
// Return the reference directly instead of a Box, it's not on the stack
// It will live as long as the Vec
let last_idx = row.buttons.len() - 1;
// Caution: Box can't be returned directly,
// so returning a reference to its innards directly
row.buttons[last_idx].as_mut() as *mut ::layout::Button
}
#[no_mangle]
pub extern "C"
fn squeek_row_set_angle(row: *mut ::layout::Row, angle: i32) {
let row = unsafe { &mut *row };
row.angle = angle;
}
#[no_mangle]
pub extern "C"
fn squeek_row_get_angle(row: *const ::layout::Row) -> i32 {
let row = unsafe { &*row };
row.angle
}
#[no_mangle]
pub extern "C"
fn squeek_row_get_bounds(row: *const ::layout::Row) -> Bounds {
let row = unsafe { &*row };
match &row.bounds {
Some(bounds) => bounds.clone(),
None => panic!("Row doesn't have any bounds yet"),
}
}
/// Set bounds by consuming the value
#[no_mangle]
pub extern "C"
fn squeek_row_set_bounds(row: *mut ::layout::Row, bounds: Bounds) {
let row = unsafe { &mut *row };
row.bounds = Some(bounds);
}
#[no_mangle]
pub extern "C"
fn squeek_row_foreach(
row: *mut ::layout::Row,
callback: ButtonCallback,
data: *mut UserData,
) {
let row = unsafe { &mut *row };
for button in row.buttons.iter_mut() {
let button = button.as_mut() as *mut ::layout::Button;
unsafe { callback(button, data) };
}
}
#[no_mangle]
pub extern "C"
fn squeek_row_free(row: *mut ::layout::Row) {
unsafe { Box::from_raw(row) }; // gets dropped
}
#[no_mangle]
pub extern "C"
fn squeek_button_new(keycode: u32, oref: u32) -> *mut ::layout::Button {
let state: Rc<RefCell<::keyboard::KeyState>> = Rc::new(RefCell::new(
::keyboard::KeyState {
pressed: false,
locked: false,
keycode: keycode,
symbol: None,
}
));
Box::into_raw(Box::new(::layout::Button {
oref: OutlineRef(oref),
bounds: None,
state: state,
}))
}
#[no_mangle]
pub extern "C"
fn squeek_button_new_with_state(source: *mut ::layout::Button) -> *mut ::layout::Button {
let source = unsafe { &*source };
let button = Box::new(source.clone());
Box::into_raw(button)
}
#[no_mangle]
pub extern "C"
fn squeek_button_get_oref(button: *const ::layout::Button) -> u32 {
let button = unsafe { &*button };
button.oref.0
}
// Bounds transparently mapped to C, therefore no pointer needed
#[no_mangle]
pub extern "C"
fn squeek_button_get_bounds(button: *const ::layout::Button) -> Bounds {
let button = unsafe { &*button };
match &button.bounds {
Some(bounds) => bounds.clone(),
None => panic!("Button doesn't have any bounds yet"),
}
}
/// Set bounds by consuming the value
#[no_mangle]
pub extern "C"
fn squeek_button_set_bounds(button: *mut ::layout::Button, bounds: Bounds) {
let button = unsafe { &mut *button };
button.bounds = Some(bounds);
}
/// Borrow a new reference to key state. Doesn't need freeing
#[no_mangle]
pub extern "C"
fn squeek_button_get_key(
button: *const ::layout::Button
) -> ::keyboard::c::CKeyState {
let button = unsafe { &*button };
::keyboard::c::CKeyState::wrap(button.state.clone())
}
/// Really should just return the label
#[no_mangle]
pub extern "C"
fn squeek_button_get_symbol(
button: *const ::layout::Button,
) -> *const Symbol {
let button = unsafe { &*button };
let state = button.state.borrow();
match state.symbol {
Some(ref symbol) => symbol as *const Symbol,
None => ptr::null(),
}
}
#[no_mangle]
pub extern "C"
fn squeek_button_has_key(
button: *const ::layout::Button,
state: ::keyboard::c::CKeyState,
) -> u32 {
let button = unsafe { &*button };
let state = state.unwrap();
let equal = Rc::ptr_eq(&button.state, &state);
Rc::into_raw(state); // Prevent dropping
equal as u32
}
#[no_mangle]
pub extern "C"
fn squeek_button_print(button: *const ::layout::Button) {
let button = unsafe { &*button };
println!("{:?}", button);
}
/// Entry points for more complex procedures and algoithms which span multiple modules
pub mod procedures {
use super::*;
#[repr(transparent)]
pub struct LevelKeyboard(*const c_void);
#[repr(C)]
#[derive(PartialEq, Debug)]
pub struct ButtonPlace {
row: *const Row,
button: *const Button,
}
#[no_mangle]
extern "C" {
fn eek_get_outline_size(
keyboard: *const LevelKeyboard,
outline: u32
) -> Bounds;
/// Checks if point falls within bounds,
/// which are relative to origin and rotated by angle (I think)
pub fn eek_are_bounds_inside (bounds: Bounds,
point: Point,
origin: Point,
angle: i32
) -> u32;
}
fn squeek_buttons_get_outlines(
buttons: &Vec<Box<Button>>,
keyboard: *const LevelKeyboard,
) -> Vec<Bounds> {
buttons.iter().map(|button| {
unsafe { eek_get_outline_size(keyboard, button.oref.0) }
}).collect()
}
/// Places each button in order, starting from 0 on the left,
/// keeping the spacing.
/// Sizes each button according to outline dimensions.
/// Places each row in order, starting from 0 on the top,
/// keeping the spacing.
/// Sets button and row sizes according to their contents.
#[no_mangle]
pub extern "C"
fn squeek_view_place_contents(
view: *mut ::layout::View,
keyboard: *const LevelKeyboard, // source of outlines
) {
let view = unsafe { &mut *view };
let sizes: Vec<Vec<Bounds>> = view.rows.iter().map(|row|
squeek_buttons_get_outlines(&row.buttons, keyboard)
).collect();
view.place_buttons_with_sizes(sizes);
}
fn squeek_row_contains(row: &Row, needle: *const Button) -> bool {
row.buttons.iter().position(
// TODO: wrap Button properly in Rc; this comparison is unreliable
|button| button.as_ref() as *const ::layout::Button == needle
).is_some()
}
#[no_mangle]
pub extern "C"
fn squeek_view_get_row(
view: *mut View,
needle: *const ::layout::Button,
) -> *mut Row {
let view = unsafe { &mut *view };
let result = view.rows.iter_mut().find(|row| {
squeek_row_contains(row, needle)
});
match result {
Some(row) => row.as_mut() as *mut Row,
None => ptr::null_mut(),
}
}
#[no_mangle]
pub extern "C"
fn squeek_view_find_key(
view: *const View,
needle: ::keyboard::c::CKeyState,
) -> ButtonPlace {
let view = unsafe { &*view };
let state = needle.unwrap();
let paths = ::layout::procedures::find_key_paths(view, &state);
// Iterators used up, can turn the reference back into pointer
Rc::into_raw(state);
// Can only return 1 entry back to C
let (row, button) = match paths.get(0) {
Some((row, button)) => (
row.as_ref() as *const Row,
button.as_ref() as *const Button,
),
None => ( ptr::null(), ptr::null() ),
};
ButtonPlace { row, button }
}
#[no_mangle]
pub extern "C"
fn squeek_view_find_button_by_position(
view: *mut View, point: Point
) -> *mut Button {
let view = unsafe { &mut *view };
let result = view.find_button_by_position(point);
match result {
Some(button) => button.as_mut() as *mut Button,
None => ptr::null_mut(),
}
}
#[cfg(test)]
mod test {
use super::*;
#[test]
fn row_has_button() {
let mut row = Row::new(0);
let button = squeek_row_create_button(&mut row as *mut Row, 0, 0);
assert_eq!(squeek_row_contains(&row, button), true);
let shared_button = squeek_row_create_button_with_state(
&mut row as *mut Row,
button
);
assert_eq!(squeek_row_contains(&row, shared_button), true);
let row = Row::new(0);
assert_eq!(squeek_row_contains(&row, button), false);
}
#[test]
fn view_has_button() {
let state = Rc::new(RefCell::new(::keyboard::KeyState {
pressed: false,
locked: false,
keycode: 0,
symbol: None,
}));
let state_clone = ::keyboard::c::CKeyState::wrap(state.clone());
let button = Box::new(Button {
oref: OutlineRef(0),
bounds: None,
state: state,
});
let button_ptr = button.as_ref() as *const Button;
let row = Box::new(Row {
buttons: vec!(button),
angle: 0,
bounds: None
});
let row_ptr = row.as_ref() as *const Row;
let view = View {
bounds: Bounds {
x: 0f64, y: 0f64,
width: 0f64, height: 0f64
},
rows: vec!(row),
};
assert_eq!(
squeek_view_find_key(
&view as *const View,
state_clone.clone(),
),
ButtonPlace {
row: row_ptr,
button: button_ptr,
}
);
let view = View {
bounds: Bounds {
x: 0f64, y: 0f64,
width: 0f64, height: 0f64
},
rows: Vec::new(),
};
assert_eq!(
squeek_view_find_key(
&view as *const View,
state_clone.clone()
),
ButtonPlace {
row: ptr::null(),
button: ptr::null(),
}
);
}
}
}
#[cfg(test)]
mod test {
use super::*;
#[test]
fn button_has_key() {
let button = squeek_button_new(0, 0);
let state = squeek_button_get_key(button);
assert_eq!(squeek_button_has_key(button, state.clone()), 1);
let other_button = squeek_button_new(0, 0);
assert_eq!(squeek_button_has_key(other_button, state.clone()), 0);
let other_state = ::keyboard::c::squeek_key_new(0);
assert_eq!(squeek_button_has_key(button, other_state), 0);
let shared_button = squeek_button_new_with_state(button);
assert_eq!(squeek_button_has_key(shared_button, state), 1);
}
}
}
#[derive(Debug)]
pub struct Size {
pub width: f64,
pub height: f64,
}
/// The graphical representation of a button
#[derive(Clone, Debug)]
pub struct Button {
oref: c::OutlineRef,
/// TODO: abolish Option, buttons should be created with bounds fully formed
/// Position relative to some origin (i.e. parent/row)
bounds: Option<c::Bounds>,
/// current state, shared with other buttons
pub state: Rc<RefCell<KeyState>>,
}
// FIXME: derive from the style/margin/padding
const BUTTON_SPACING: f64 = 4.0;
const ROW_SPACING: f64 = 7.0;
/// The graphical representation of a row of buttons
pub struct Row {
buttons: Vec<Box<Button>>,
/// Angle is not really used anywhere...
angle: i32,
/// Position relative to some origin (i.e. parent/view origin)
bounds: Option<c::Bounds>,
}
impl Row {
fn new(angle: i32) -> Row {
Row {
buttons: Vec::new(),
angle: angle,
bounds: None,
}
}
fn last(positions: &Vec<c::Bounds>) -> Option<&c::Bounds> {
let len = positions.len();
match len {
0 => None,
l => Some(&positions[l - 1])
}
}
fn calculate_button_positions(outlines: Vec<c::Bounds>)
-> Vec<c::Bounds>
{
let mut x_offset = 0f64;
outlines.iter().map(|outline| {
x_offset += outline.x; // account for offset outlines
let position = c::Bounds {
x: x_offset,
..outline.clone()
};
x_offset += outline.width + BUTTON_SPACING;
position
}).collect()
}
fn calculate_row_size(positions: &Vec<c::Bounds>) -> Size {
let max_height = positions.iter().map(
|bounds| FloatOrd(bounds.height)
).max()
.unwrap_or(FloatOrd(0f64))
.0;
let total_width = match Row::last(positions) {
Some(position) => position.x + position.width,
None => 0f64,
};
Size { width: total_width, height: max_height }
}
/// Finds the first button that covers the specified point
/// relative to row's position's origin
fn find_button_by_position(&mut self, point: c::Point)
-> Option<&mut Box<Button>>
{
let row_bounds = self.bounds.as_ref().expect("Missing bounds on row");
let origin = c::Point {
x: row_bounds.x,
y: row_bounds.y,
};
let angle = self.angle;
self.buttons.iter_mut().find(|button| {
let bounds = button.bounds
.as_ref().expect("Missing bounds on button")
.clone();
let point = point.clone();
let origin = origin.clone();
procedures::is_point_inside(bounds, point, origin, angle)
})
}
}
pub struct View {
/// Position relative to keyboard origin
bounds: c::Bounds,
rows: Vec<Box<Row>>,
}
impl View {
/// Determines the positions of rows based on their sizes
/// Each row will be centered horizontally
/// The collection of rows will not be altered vertically
/// (TODO: maybe make view bounds a constraint,
/// and derive a scaling factor that lets contents fit into view)
/// (or TODO: blow up view bounds to match contents
/// and then scale the entire thing)
fn calculate_row_positions(&self, sizes: Vec<Size>) -> Vec<c::Bounds> {
let mut y_offset = self.bounds.y;
sizes.into_iter().map(|size| {
let position = c::Bounds {
x: (self.bounds.width - size.width) / 2f64,
y: y_offset,
width: size.width,
height: size.height,
};
y_offset += size.height + ROW_SPACING;
position
}).collect()
}
/// Uses button outline information to place all buttons and rows inside.
/// The view itself will not be affected by the sizes
fn place_buttons_with_sizes(
&mut self,
button_outlines: Vec<Vec<c::Bounds>>
) {
// Determine all positions
let button_positions: Vec<_>
= button_outlines.into_iter()
.map(Row::calculate_button_positions)
.collect();
let row_sizes = button_positions.iter()
.map(Row::calculate_row_size)
.collect();
let row_positions = self.calculate_row_positions(row_sizes);
// Apply all positions
for ((mut row, row_position), button_positions)
in self.rows.iter_mut()
.zip(row_positions)
.zip(button_positions) {
row.bounds = Some(row_position);
for (mut button, button_position)
in row.buttons.iter_mut()
.zip(button_positions) {
button.bounds = Some(button_position);
}
}
}
/// Finds the first button that covers the specified point
/// relative to view's position's origin
fn find_button_by_position(&mut self, point: c::Point)
-> Option<&mut Box<Button>>
{
// make point relative to the inside of the view,
// which is the origin of all rows
let point = c::Point {
x: point.x - self.bounds.x,
y: point.y - self.bounds.y,
};
self.rows.iter_mut().find_map(
|row| row.find_button_by_position(point.clone())
)
}
}
mod procedures {
use super::*;
type Path<'v> = (&'v Box<Row>, &'v Box<Button>);
/// Finds all `(row, button)` paths that refer to the specified key `state`
pub fn find_key_paths<'v, 's>(
view: &'v View,
state: &'s Rc<RefCell<KeyState>>
) -> Vec<Path<'v>> {
view.rows.iter().flat_map(|row| {
let row_paths: Vec<Path> = row.buttons.iter().filter_map(|button| {
if Rc::ptr_eq(&button.state, state) {
Some((row, button))
} else {
None
}
}).collect(); // collecting not to let row references outlive the function
row_paths.into_iter()
}).collect()
}
/// Checks if point is inside bounds which are rotated by angle.
/// FIXME: what's origin about?
pub fn is_point_inside(
bounds: c::Bounds,
point: c::Point,
origin: c::Point,
angle: i32
) -> bool {
(unsafe {
c::procedures::eek_are_bounds_inside(bounds, point, origin, angle)
}) == 1
}
}

View File

@ -1,9 +1,4 @@
#[macro_use]
mod bitflags;
mod float_ord;
mod imservice;
mod keyboard;
mod layout;
mod symbol;
mod util;

View File

@ -16,20 +16,27 @@ sources = [
'server-context-service.c',
'wayland.c',
'../eek/eek.c',
'../eek/eek-container.c',
'../eek/eek-element.c',
'../eek/eek-gtk-keyboard.c',
'../eek/eek-key.c',
'../eek/eek-keyboard.c',
'../eek/eek-keyboard-drawing.c',
'../eek/eek-keysym.c',
'../eek/eek-layout.c',
'../eek/eek-renderer.c',
'../eek/eek-section.c',
'../eek/eek-serializable.c',
'../eek/eek-symbol.c',
'../eek/eek-symbol-matrix.c',
'../eek/eek-text.c',
'../eek/eek-types.c',
'../eek/eek-xml-layout.c',
'../eek/layersurface.c',
dbus_src,
enums,
keysym_entries,
marshalers,
'../eekboard/key-emitter.c',
'../eekboard/eekboard-context-service.c',
'../eekboard/eekboard-context.c',

View File

@ -83,7 +83,9 @@ on_notify_keyboard (GObject *object,
GParamSpec *spec,
ServerContextService *context)
{
const LevelKeyboard *keyboard = eekboard_context_service_get_keyboard (EEKBOARD_CONTEXT_SERVICE(context));
const EekKeyboard *keyboard;
keyboard = eekboard_context_service_get_keyboard (EEKBOARD_CONTEXT_SERVICE(context));
if (!keyboard)
g_error("Programmer error: keyboard layout was unset!");
@ -139,12 +141,13 @@ set_geometry (ServerContextService *context)
GdkWindow *root = gdk_screen_get_root_window (screen);
GdkDisplay *display = gdk_display_get_default ();
GdkMonitor *monitor = gdk_display_get_monitor_at_window (display, root);
LevelKeyboard *keyboard = eekboard_context_service_get_keyboard (EEKBOARD_CONTEXT_SERVICE(context));
EekKeyboard *keyboard = eekboard_context_service_get_keyboard (EEKBOARD_CONTEXT_SERVICE(context));
GdkRectangle rect;
EekBounds bounds;
gdk_monitor_get_geometry (monitor, &rect);
EekBounds bounds = squeek_view_get_bounds (level_keyboard_current(keyboard));
eek_element_get_bounds (EEK_ELEMENT(keyboard), &bounds);
if (eekboard_context_service_get_fullscreen (EEKBOARD_CONTEXT_SERVICE(context))) {
gint width = rect.width;
@ -225,12 +228,14 @@ destroy_window (ServerContextService *context)
static void
make_widget (ServerContextService *context)
{
EekKeyboard *keyboard;
if (context->widget) {
gtk_widget_destroy(context->widget);
context->widget = NULL;
}
LevelKeyboard *keyboard = eekboard_context_service_get_keyboard (EEKBOARD_CONTEXT_SERVICE(context));
keyboard = eekboard_context_service_get_keyboard (EEKBOARD_CONTEXT_SERVICE(context));
context->widget = eek_gtk_keyboard_new (keyboard);

View File

@ -1,24 +0,0 @@
#ifndef __SYMBOL_H
#define __SYMBOL_H
#include "stdbool.h"
#include "inttypes.h"
// Defined in Rust
struct squeek_symbol;
struct squeek_symbols;
void squeek_symbols_add(struct squeek_symbols*,
const char *element_name,
const char *text, uint32_t keyval,
const char *label, const char *icon,
const char *tooltip);
const char *squeek_symbol_get_name(struct squeek_symbol* symbol);
const char *squeek_symbol_get_label(struct squeek_symbol* symbol);
const char *squeek_symbol_get_icon_name(struct squeek_symbol* symbol);
uint32_t squeek_symbol_get_modifier_mask(struct squeek_symbol* symbol);
void squeek_symbol_print(struct squeek_symbol* symbol);
#endif

View File

@ -1,138 +0,0 @@
use std::ffi::CString;
/// Gathers stuff defined in C or called by C
pub mod c {
use super::*;
use std::ffi::CStr;
use std::os::raw::c_char;
use std::ptr;
// The following defined in C
// Legacy; Will never be used in Rust as a bit field
enum ModifierMask {
Nothing = 0,
Shift = 1,
}
// The following defined in Rust.
// TODO: wrap naked pointers to Rust data inside RefCells to prevent multiple writers
// Symbols are owned by Rust and will move towards no C manipulation, so it may make sense not to wrap them
#[no_mangle]
pub extern "C"
fn squeek_symbol_get_name(symbol: *const Symbol) -> *const c_char {
let symbol = unsafe { &*symbol };
match &symbol.action {
Action::Submit { text: Some(text), .. } => text.as_ptr(),
_ => ptr::null(),
}
}
#[no_mangle]
pub extern "C"
fn squeek_symbol_get_label(symbol: *const Symbol) -> *const c_char {
let symbol = unsafe { &*symbol };
match &symbol.label {
Label::Text(text) => text.as_ptr(),
// returning static strings to C is a bit cumbersome
Label::IconName(_) => unsafe {
CStr::from_bytes_with_nul_unchecked(b"icon\0")
}.as_ptr(),
}
}
#[no_mangle]
pub extern "C"
fn squeek_symbol_get_icon_name(symbol: *const Symbol) -> *const c_char {
let symbol = unsafe { &*symbol };
match &symbol.label {
Label::Text(_) => ptr::null(),
Label::IconName(name) => name.as_ptr(),
}
}
// Legacy; throw away
#[no_mangle]
pub extern "C"
fn squeek_symbol_get_modifier_mask(symbol: *const Symbol) -> u32 {
let symbol = unsafe { &*symbol };
(match &symbol.action {
Action::SetLevel(1) => ModifierMask::Shift,
_ => ModifierMask::Nothing,
}) as u32
}
#[no_mangle]
pub extern "C"
fn squeek_symbol_print(symbol: *const Symbol) {
let symbol = unsafe { &*symbol };
println!("{:?}", symbol);
}
}
/// Just defines some int->identifier mappings for convenience
#[derive(Debug, Clone)]
pub enum KeySym {
Unknown = 0,
Shift = 0xffe1,
}
impl KeySym {
pub fn from_u32(num: u32) -> KeySym {
match num {
0xffe1 => KeySym::Shift,
_ => KeySym::Unknown,
}
}
}
#[derive(Debug, Clone)]
pub struct XKeySym(pub u32);
#[derive(Debug, Clone)]
pub enum Label {
/// Text used to display the symbol
Text(CString),
/// Icon name used to render the symbol
IconName(CString),
}
/// Use to switch layouts
type Level = u8;
/// Use to send modified keypresses
#[derive(Debug, Clone)]
pub enum Modifier {
Control,
Alt,
}
/// Action to perform on the keypress and, in reverse, on keyrelease
#[derive(Debug, Clone)]
pub enum Action {
/// Switch to this level TODO: reverse?
SetLevel(Level),
/// Set this modifier TODO: release?
SetModifier(Modifier),
/// Submit some text
Submit {
/// orig: Canonical name of the symbol
text: Option<CString>,
/// The key events this symbol submits when submitting text is not possible
keys: Vec<XKeySym>,
},
}
/// Contains a static description of a particular key's actions
#[derive(Debug, Clone)]
pub struct Symbol {
/// The action that this key performs
pub action: Action,
/// Label to display to the user
pub label: Label,
// FIXME: is it used?
pub tooltip: Option<CString>,
}

View File

@ -1,50 +0,0 @@
pub mod c {
use std::ffi::{ CStr, CString };
use std::os::raw::c_char;
use std::str::Utf8Error;
#[allow(dead_code)]
pub fn as_str(s: &*const c_char) -> Result<Option<&str>, Utf8Error> {
if s.is_null() {
Ok(None)
} else {
unsafe {CStr::from_ptr(*s)}
.to_str()
.map(Some)
}
}
pub fn as_cstr(s: &*const c_char) -> Option<&CStr> {
if s.is_null() {
None
} else {
Some(unsafe {CStr::from_ptr(*s)})
}
}
pub fn into_cstring(s: *const c_char) -> Result<Option<CString>, std::ffi::NulError> {
if s.is_null() {
Ok(None)
} else {
CString::new(
unsafe {CStr::from_ptr(s)}.to_bytes()
).map(Some)
}
}
#[cfg(test)]
mod tests {
use super::*;
use std::ptr;
#[test]
fn test_null_cstring() {
assert_eq!(into_cstring(ptr::null()), Ok(None))
}
#[test]
fn test_null_str() {
assert_eq!(as_str(&ptr::null()), Ok(None))
}
}
}

View File

@ -24,16 +24,18 @@
static void
test_create (void)
{
EekBounds bounds = {0};
struct squeek_view *view = squeek_view_new(bounds);
struct squeek_button *button0, *button1;
EekKeyboard *keyboard;
EekSection *section;
EekKey *key0, *key1;
struct squeek_row *row = squeek_view_create_row (view, 0);
g_assert (row);
button0 = squeek_row_create_button (row, 1, 0);
g_assert (button0);
button1 = squeek_row_create_button (row, 2, 0);
g_assert (button1);
keyboard = g_object_new (EEK_TYPE_KEYBOARD, NULL);
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);
g_assert (EEK_IS_KEY(key0));
key1 = eek_section_create_key (section, "key1", 2);
g_assert (EEK_IS_KEY(key1));
}
int

View File

@ -30,7 +30,7 @@ static void
test_output_parse (void)
{
EekLayout *layout;
LevelKeyboard *keyboard;
EekKeyboard *keyboard;
GError *error;
error = NULL;
@ -39,9 +39,9 @@ test_output_parse (void)
/* We don't need the context service to parse an XML file, so we can pass
NULL when creating a keyboard. */
keyboard = eek_xml_layout_real_create_keyboard(layout, NULL);
keyboard = eek_keyboard_new (NULL, layout, 640, 480);
g_object_unref (layout);
level_keyboard_free(keyboard);
g_object_unref (keyboard);
}
int

View File

@ -32,14 +32,14 @@ static void
test_check_xkb (void)
{
EekLayout *layout;
LevelKeyboard *keyboard;
EekKeyboard *keyboard;
GError *error;
error = NULL;
layout = eek_xml_layout_new ("us", &error);
g_assert_no_error (error);
keyboard = eek_xml_layout_real_create_keyboard(layout, NULL);
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);
@ -58,7 +58,7 @@ test_check_xkb (void)
}
g_object_unref (layout);
level_keyboard_free(keyboard);
g_object_unref (keyboard);
}
int