Merge branch 'eekkey' into 'master'
Redesign how keys are handled See merge request Librem5/squeekboard!117
This commit is contained in:
@ -1,57 +1,8 @@
|
|||||||
<?xml version="1.0"?>
|
<?xml version="1.0"?>
|
||||||
<geometry version="0.90">
|
<geometry version="0.90">
|
||||||
<bounds x="10" y="10" width="410.0000" height="229"/>
|
<bounds x="10" y="10" width="410.0000" height="229"/>
|
||||||
<section angle="0">
|
|
||||||
<row orientation="1">
|
<outline id="default" corner-radius="1.000000">
|
||||||
<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="0.000000" y="0.000000"/>
|
||||||
<point x="37.46341" y="0.000000"/>
|
<point x="37.46341" y="0.000000"/>
|
||||||
<point x="37.46341" y="52"/>
|
<point x="37.46341" y="52"/>
|
||||||
@ -117,4 +68,38 @@
|
|||||||
<point x="150.5853" y="52"/>
|
<point x="150.5853" y="52"/>
|
||||||
<point x="0.000000" y="52"/>
|
<point x="0.000000" y="52"/>
|
||||||
</outline>
|
</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</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>
|
</geometry>
|
||||||
|
|||||||
@ -1,42 +1,8 @@
|
|||||||
<?xml version="1.0"?>
|
<?xml version="1.0"?>
|
||||||
<geometry version="0.90">
|
<geometry version="0.90">
|
||||||
<bounds x="0" y="10.000000" width="426.0000" height="296.5853"/>
|
<bounds x="0" y="10.000000" width="426.0000" height="296.5853"/>
|
||||||
<section angle="0">
|
|
||||||
<row orientation="1">
|
<outline id="default" corner-radius="1.000000">
|
||||||
<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="0.000000" y="0.000000"/>
|
||||||
<point x="37.46341" y="0.000000"/>
|
<point x="37.46341" y="0.000000"/>
|
||||||
<point x="37.46341" y="52.44877"/>
|
<point x="37.46341" y="52.44877"/>
|
||||||
@ -48,58 +14,27 @@
|
|||||||
<point x="48.39024" y="52.44877"/>
|
<point x="48.39024" y="52.44877"/>
|
||||||
<point x="0.000000" y="52.44877"/>
|
<point x="0.000000" y="52.44877"/>
|
||||||
</outline>
|
</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">
|
<outline id="outline7" corner-radius="1.000000">
|
||||||
<point x="0.000000" y="0.000000"/>
|
<point x="0.000000" y="0.000000"/>
|
||||||
<point x="88.97561" y="0.000000"/>
|
<point x="88.97561" y="0.000000"/>
|
||||||
<point x="88.97561" y="52.44877"/>
|
<point x="88.97561" y="52.44877"/>
|
||||||
<point x="0.000000" y="52.44877"/>
|
<point x="0.000000" y="52.44877"/>
|
||||||
</outline>
|
</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">
|
<outline id="spaceline" corner-radius="1.000000">
|
||||||
<point x="0.000000" y="0.000000"/>
|
<point x="0.000000" y="0.000000"/>
|
||||||
<point x="120.5853" y="0.000000"/>
|
<point x="120.5853" y="0.000000"/>
|
||||||
<point x="120.5853" y="52.44877"/>
|
<point x="120.5853" y="52.44877"/>
|
||||||
<point x="0.000000" y="52.44877"/>
|
<point x="0.000000" y="52.44877"/>
|
||||||
</outline>
|
</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>
|
</geometry>
|
||||||
|
|||||||
@ -2,59 +2,116 @@
|
|||||||
<symbols version="0.90">
|
<symbols version="0.90">
|
||||||
<key name="AD01">
|
<key name="AD01">
|
||||||
<symbol label="1">1</symbol>
|
<symbol label="1">1</symbol>
|
||||||
|
<symbol label="1">1</symbol>
|
||||||
|
<symbol label="1">1</symbol>
|
||||||
|
<symbol label="1">1</symbol>
|
||||||
</key>
|
</key>
|
||||||
<key name="AD02">
|
<key name="AD02">
|
||||||
<symbol label="2">2</symbol>
|
<symbol label="2">2</symbol>
|
||||||
|
<symbol label="2">2</symbol>
|
||||||
|
<symbol label="2">2</symbol>
|
||||||
|
<symbol label="2">2</symbol>
|
||||||
</key>
|
</key>
|
||||||
<key name="AD03">
|
<key name="AD03">
|
||||||
<symbol label="3">3</symbol>
|
<symbol label="3">3</symbol>
|
||||||
|
<symbol label="3">3</symbol>
|
||||||
|
<symbol label="3">3</symbol>
|
||||||
|
<symbol label="3">3</symbol>
|
||||||
</key>
|
</key>
|
||||||
<key name="AD04">
|
<key name="AD04">
|
||||||
<symbol label="(">parenleft</symbol>
|
<symbol label="(">parenleft</symbol>
|
||||||
|
<symbol label="(">parenleft</symbol>
|
||||||
|
<symbol label="(">parenleft</symbol>
|
||||||
|
<symbol label="(">parenleft</symbol>
|
||||||
</key>
|
</key>
|
||||||
<key name="AD05">
|
<key name="AD05">
|
||||||
<symbol label=")">parenright</symbol>
|
<symbol label=")">parenright</symbol>
|
||||||
|
<symbol label=")">parenright</symbol>
|
||||||
|
<symbol label=")">parenright</symbol>
|
||||||
|
<symbol label=")">parenright</symbol>
|
||||||
</key>
|
</key>
|
||||||
<key name="AC01">
|
<key name="AC01">
|
||||||
<symbol label="4">4</symbol>
|
<symbol label="4">4</symbol>
|
||||||
|
<symbol label="4">4</symbol>
|
||||||
|
<symbol label="4">4</symbol>
|
||||||
|
<symbol label="4">4</symbol>
|
||||||
</key>
|
</key>
|
||||||
<key name="AC02">
|
<key name="AC02">
|
||||||
<symbol label="5">5</symbol>
|
<symbol label="5">5</symbol>
|
||||||
|
<symbol label="5">5</symbol>
|
||||||
|
<symbol label="5">5</symbol>
|
||||||
|
<symbol label="5">5</symbol>
|
||||||
</key>
|
</key>
|
||||||
<key name="AC03">
|
<key name="AC03">
|
||||||
<symbol label="6">6</symbol>
|
<symbol label="6">6</symbol>
|
||||||
|
<symbol label="6">6</symbol>
|
||||||
|
<symbol label="6">6</symbol>
|
||||||
|
<symbol label="6">6</symbol>
|
||||||
</key>
|
</key>
|
||||||
<key name="AC04">
|
<key name="AC04">
|
||||||
<symbol label="#">numbersign</symbol>
|
<symbol label="#">numbersign</symbol>
|
||||||
|
<symbol label="#">numbersign</symbol>
|
||||||
|
<symbol label="#">numbersign</symbol>
|
||||||
|
<symbol label="#">numbersign</symbol>
|
||||||
</key>
|
</key>
|
||||||
<key name="AC05">
|
<key name="AC05">
|
||||||
<symbol label="*">asterisk</symbol>
|
<symbol label="*">asterisk</symbol>
|
||||||
|
<symbol label="*">asterisk</symbol>
|
||||||
|
<symbol label="*">asterisk</symbol>
|
||||||
|
<symbol label="*">asterisk</symbol>
|
||||||
</key>
|
</key>
|
||||||
<key name="AB01">
|
<key name="AB01">
|
||||||
<symbol label="7">7</symbol>
|
<symbol label="7">7</symbol>
|
||||||
|
<symbol label="7">7</symbol>
|
||||||
|
<symbol label="7">7</symbol>
|
||||||
|
<symbol label="7">7</symbol>
|
||||||
</key>
|
</key>
|
||||||
<key name="AB02">
|
<key name="AB02">
|
||||||
<symbol label="8">8</symbol>
|
<symbol label="8">8</symbol>
|
||||||
|
<symbol label="8">8</symbol>
|
||||||
|
<symbol label="8">8</symbol>
|
||||||
|
<symbol label="8">8</symbol>
|
||||||
</key>
|
</key>
|
||||||
<key name="AB03">
|
<key name="AB03">
|
||||||
<symbol label="9">9</symbol>
|
<symbol label="9">9</symbol>
|
||||||
|
<symbol label="9">9</symbol>
|
||||||
|
<symbol label="9">9</symbol>
|
||||||
|
<symbol label="9">9</symbol>
|
||||||
</key>
|
</key>
|
||||||
<key name="AB04">
|
<key name="AB04">
|
||||||
<symbol label="+">plus</symbol>
|
<symbol label="+">plus</symbol>
|
||||||
|
<symbol label="+">plus</symbol>
|
||||||
|
<symbol label="+">plus</symbol>
|
||||||
|
<symbol label="+">plus</symbol>
|
||||||
</key>
|
</key>
|
||||||
<key name="AB05">
|
<key name="AB05">
|
||||||
<symbol label="-">minus</symbol>
|
<symbol label="-">minus</symbol>
|
||||||
|
<symbol label="-">minus</symbol>
|
||||||
|
<symbol label="-">minus</symbol>
|
||||||
|
<symbol label="-">minus</symbol>
|
||||||
</key>
|
</key>
|
||||||
<key name="AB06">
|
<key name="AB06">
|
||||||
<symbol label="0">0</symbol>
|
<symbol label="0">0</symbol>
|
||||||
|
<symbol label="0">0</symbol>
|
||||||
|
<symbol label="0">0</symbol>
|
||||||
|
<symbol label="0">0</symbol>
|
||||||
</key>
|
</key>
|
||||||
<key name="RTRN">
|
<key name="RTRN">
|
||||||
<symbol keyval="65293" icon="key-enter">Return</symbol>
|
<symbol keyval="65293" icon="key-enter">Return</symbol>
|
||||||
|
<symbol keyval="65293" icon="key-enter">Return</symbol>
|
||||||
|
<symbol keyval="65293" icon="key-enter">Return</symbol>
|
||||||
|
<symbol keyval="65293" icon="key-enter">Return</symbol>
|
||||||
</key>
|
</key>
|
||||||
<key name="SPCE">
|
<key name="SPCE">
|
||||||
<symbol label=" ">space</symbol>
|
<symbol label=" ">space</symbol>
|
||||||
|
<symbol label=" ">space</symbol>
|
||||||
|
<symbol label=" ">space</symbol>
|
||||||
|
<symbol label=" ">space</symbol>
|
||||||
</key>
|
</key>
|
||||||
<key name="BKSP">
|
<key name="BKSP">
|
||||||
<symbol keyval="65288" icon="edit-clear-symbolic">BackSpace</symbol>
|
<symbol keyval="65288" icon="edit-clear-symbolic">BackSpace</symbol>
|
||||||
|
<symbol keyval="65288" icon="edit-clear-symbolic">BackSpace</symbol>
|
||||||
|
<symbol keyval="65288" icon="edit-clear-symbolic">BackSpace</symbol>
|
||||||
|
<symbol keyval="65288" icon="edit-clear-symbolic">BackSpace</symbol>
|
||||||
</key>
|
</key>
|
||||||
</symbols>
|
</symbols>
|
||||||
|
|||||||
@ -1,5 +1,7 @@
|
|||||||
<?xml version='1.0' encoding='ASCII' standalone='yes'?>
|
<?xml version='1.0' encoding='ASCII' standalone='yes'?>
|
||||||
<symbols version="0.90">
|
<symbols version="0.90">
|
||||||
|
<symbol label="*">asterisk</symbol>
|
||||||
|
<symbol label="+/=">show_symbols</symbol>
|
||||||
<key name="AD01">
|
<key name="AD01">
|
||||||
<symbol label="q">q</symbol>
|
<symbol label="q">q</symbol>
|
||||||
<symbol label="Q">Q</symbol>
|
<symbol label="Q">Q</symbol>
|
||||||
@ -58,7 +60,7 @@
|
|||||||
<symbol label="p">p</symbol>
|
<symbol label="p">p</symbol>
|
||||||
<symbol label="P">P</symbol>
|
<symbol label="P">P</symbol>
|
||||||
<symbol label="0">0</symbol>
|
<symbol label="0">0</symbol>
|
||||||
<symbol label="△">U25B3</symbol>
|
<symbol label="ρ">Greek_tau</symbol>
|
||||||
</key>
|
</key>
|
||||||
<key name="AC01">
|
<key name="AC01">
|
||||||
<symbol label="a">a</symbol>
|
<symbol label="a">a</symbol>
|
||||||
@ -124,6 +126,9 @@
|
|||||||
</key>
|
</key>
|
||||||
<key name="RTRN">
|
<key name="RTRN">
|
||||||
<symbol keyval="65293" icon="key-enter">Return</symbol>
|
<symbol keyval="65293" icon="key-enter">Return</symbol>
|
||||||
|
<symbol keyval="65293" icon="key-enter">Return</symbol>
|
||||||
|
<symbol keyval="65293" icon="key-enter">Return</symbol>
|
||||||
|
<symbol keyval="65293" icon="key-enter">Return</symbol>
|
||||||
</key>
|
</key>
|
||||||
<key name="LFSH">
|
<key name="LFSH">
|
||||||
<keysym keyval="65505" icon="key-shift">Shift_L</keysym>
|
<keysym keyval="65505" icon="key-shift">Shift_L</keysym>
|
||||||
@ -175,20 +180,30 @@
|
|||||||
</key>
|
</key>
|
||||||
<key name="AB08">
|
<key name="AB08">
|
||||||
<symbol label=".">period</symbol>
|
<symbol label=".">period</symbol>
|
||||||
|
<symbol label=".">period</symbol>
|
||||||
|
<symbol label=".">period</symbol>
|
||||||
|
<symbol label=".">period</symbol>
|
||||||
</key>
|
</key>
|
||||||
<key name="ABC123">
|
<key name="ABC123">
|
||||||
<symbol label="123">show-numbers</symbol>
|
<symbol label="123">show_numbers</symbol>
|
||||||
<symbol label="123">show-numbers</symbol>
|
<symbol label="ABC">show_letters</symbol>
|
||||||
<symbol label="ABC">show-letters</symbol>
|
|
||||||
<symbol label="ABC">show-letters</symbol>
|
|
||||||
</key>
|
</key>
|
||||||
<key name="I149">
|
<key name="I149">
|
||||||
<symbol label="☺" icon="keyboard-mode-symbolic" tooltip="Setup">preferences</symbol>
|
<symbol label="☺" icon="keyboard-mode-symbolic" tooltip="Setup">preferences</symbol>
|
||||||
|
<symbol label="☺" icon="keyboard-mode-symbolic" tooltip="Setup">preferences</symbol>
|
||||||
|
<symbol label="☺" icon="keyboard-mode-symbolic" tooltip="Setup">preferences</symbol>
|
||||||
|
<symbol label="☺" icon="keyboard-mode-symbolic" tooltip="Setup">preferences</symbol>
|
||||||
</key>
|
</key>
|
||||||
<key name="SPCE">
|
<key name="SPCE">
|
||||||
<symbol label=" ">space</symbol>
|
<symbol label=" ">space</symbol>
|
||||||
|
<symbol label=" ">space</symbol>
|
||||||
|
<symbol label=" ">space</symbol>
|
||||||
|
<symbol label=" ">space</symbol>
|
||||||
</key>
|
</key>
|
||||||
<key name="BKSP">
|
<key name="BKSP">
|
||||||
<symbol keyval="65288" icon="edit-clear-symbolic">BackSpace</symbol>
|
<symbol keyval="65288" icon="edit-clear-symbolic">BackSpace</symbol>
|
||||||
|
<symbol keyval="65288" icon="edit-clear-symbolic">BackSpace</symbol>
|
||||||
|
<symbol keyval="65288" icon="edit-clear-symbolic">BackSpace</symbol>
|
||||||
|
<symbol keyval="65288" icon="edit-clear-symbolic">BackSpace</symbol>
|
||||||
</key>
|
</key>
|
||||||
</symbols>
|
</symbols>
|
||||||
|
|||||||
@ -38,8 +38,6 @@ enum {
|
|||||||
PROP_0,
|
PROP_0,
|
||||||
PROP_NAME,
|
PROP_NAME,
|
||||||
PROP_BOUNDS,
|
PROP_BOUNDS,
|
||||||
PROP_GROUP,
|
|
||||||
PROP_LEVEL,
|
|
||||||
PROP_LAST
|
PROP_LAST
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -55,20 +53,10 @@ typedef struct _EekElementPrivate
|
|||||||
gchar *name;
|
gchar *name;
|
||||||
EekBounds bounds;
|
EekBounds bounds;
|
||||||
EekElement *parent;
|
EekElement *parent;
|
||||||
gint group;
|
|
||||||
gint level;
|
|
||||||
} EekElementPrivate;
|
} EekElementPrivate;
|
||||||
|
|
||||||
G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (EekElement, eek_element, G_TYPE_OBJECT)
|
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
|
static void
|
||||||
eek_element_finalize (GObject *object)
|
eek_element_finalize (GObject *object)
|
||||||
{
|
{
|
||||||
@ -95,12 +83,6 @@ eek_element_set_property (GObject *object,
|
|||||||
case PROP_BOUNDS:
|
case PROP_BOUNDS:
|
||||||
eek_element_set_bounds (element, g_value_get_boxed (value));
|
eek_element_set_bounds (element, g_value_get_boxed (value));
|
||||||
break;
|
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:
|
default:
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
break;
|
break;
|
||||||
@ -124,12 +106,6 @@ eek_element_get_property (GObject *object,
|
|||||||
eek_element_get_bounds (element, &bounds);
|
eek_element_get_bounds (element, &bounds);
|
||||||
g_value_set_boxed (value, &bounds);
|
g_value_set_boxed (value, &bounds);
|
||||||
break;
|
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:
|
default:
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
break;
|
break;
|
||||||
@ -143,8 +119,6 @@ eek_element_class_init (EekElementClass *klass)
|
|||||||
GParamSpec *pspec;
|
GParamSpec *pspec;
|
||||||
|
|
||||||
/* signals */
|
/* signals */
|
||||||
klass->symbol_index_changed = eek_element_real_symbol_index_changed;
|
|
||||||
|
|
||||||
gobject_class->set_property = eek_element_set_property;
|
gobject_class->set_property = eek_element_set_property;
|
||||||
gobject_class->get_property = eek_element_get_property;
|
gobject_class->get_property = eek_element_get_property;
|
||||||
gobject_class->finalize = eek_element_finalize;
|
gobject_class->finalize = eek_element_finalize;
|
||||||
@ -176,65 +150,12 @@ eek_element_class_init (EekElementClass *klass)
|
|||||||
g_object_class_install_property (gobject_class,
|
g_object_class_install_property (gobject_class,
|
||||||
PROP_BOUNDS,
|
PROP_BOUNDS,
|
||||||
pspec);
|
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
|
static void
|
||||||
eek_element_init (EekElement *self)
|
eek_element_init (EekElement *self)
|
||||||
{
|
{
|
||||||
EekElementPrivate *priv = eek_element_get_instance_private (self);
|
(void)self;
|
||||||
|
|
||||||
priv->group = -1;
|
|
||||||
priv->level = -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -428,144 +349,3 @@ eek_element_set_size (EekElement *element,
|
|||||||
bounds.height = height;
|
bounds.height = height;
|
||||||
eek_element_set_bounds (element, &bounds);
|
eek_element_set_bounds (element, &bounds);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* eek_element_set_symbol_index:
|
|
||||||
* @element: an #EekElement
|
|
||||||
* @group: row index of the symbol matrix
|
|
||||||
* @level: column index of the symbol matrix
|
|
||||||
*
|
|
||||||
* Set the default index of the symbol matrices of @element. The
|
|
||||||
* setting affects the child, if child does not have the index set, as
|
|
||||||
* well as this element. To unset, pass -1 as group/level.
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
eek_element_set_symbol_index (EekElement *element,
|
|
||||||
gint group,
|
|
||||||
gint level)
|
|
||||||
{
|
|
||||||
gboolean emit_signal;
|
|
||||||
|
|
||||||
g_return_if_fail (EEK_IS_ELEMENT(element));
|
|
||||||
|
|
||||||
emit_signal = group != eek_element_get_group (element) ||
|
|
||||||
level != eek_element_get_level (element);
|
|
||||||
|
|
||||||
eek_element_set_group (element, group);
|
|
||||||
eek_element_set_level (element, level);
|
|
||||||
|
|
||||||
if (emit_signal)
|
|
||||||
g_signal_emit (element, signals[SYMBOL_INDEX_CHANGED], 0, group, level);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* eek_element_get_symbol_index:
|
|
||||||
* @element: an #EekElement
|
|
||||||
* @group: a pointer where the group value of the symbol index will be stored
|
|
||||||
* @level: a pointer where the level value of the symbol index will be stored
|
|
||||||
*
|
|
||||||
* Get the default index of the symbol matrices of @element.
|
|
||||||
* If the index is not set, -1 will be returned.
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
eek_element_get_symbol_index (EekElement *element,
|
|
||||||
gint *group,
|
|
||||||
gint *level)
|
|
||||||
{
|
|
||||||
g_return_if_fail (EEK_IS_ELEMENT(element));
|
|
||||||
g_return_if_fail (group != NULL || level != NULL);
|
|
||||||
if (group != NULL)
|
|
||||||
*group = eek_element_get_group (element);
|
|
||||||
if (level != NULL)
|
|
||||||
*level = eek_element_get_level (element);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* eek_element_set_group:
|
|
||||||
* @element: an #EekElement
|
|
||||||
* @group: group index of @element
|
|
||||||
*
|
|
||||||
* Set the group value of the default symbol index of @element. To
|
|
||||||
* unset, pass -1 as @group.
|
|
||||||
*
|
|
||||||
* See also: eek_element_set_symbol_index()
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
eek_element_set_group (EekElement *element,
|
|
||||||
gint group)
|
|
||||||
{
|
|
||||||
g_return_if_fail (EEK_IS_ELEMENT(element));
|
|
||||||
|
|
||||||
EekElementPrivate *priv = eek_element_get_instance_private (element);
|
|
||||||
|
|
||||||
if (priv->group != group) {
|
|
||||||
priv->group = group;
|
|
||||||
g_object_notify (G_OBJECT(element), "group");
|
|
||||||
g_signal_emit (element, signals[SYMBOL_INDEX_CHANGED], 0,
|
|
||||||
group, priv->level);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* eek_element_set_level:
|
|
||||||
* @element: an #EekElement
|
|
||||||
* @level: level index of @element
|
|
||||||
*
|
|
||||||
* Set the level value of the default symbol index of @element. To
|
|
||||||
* unset, pass -1 as @level.
|
|
||||||
*
|
|
||||||
* See also: eek_element_set_symbol_index()
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
eek_element_set_level (EekElement *element,
|
|
||||||
gint level)
|
|
||||||
{
|
|
||||||
g_return_if_fail (EEK_IS_ELEMENT(element));
|
|
||||||
|
|
||||||
EekElementPrivate *priv = eek_element_get_instance_private (element);
|
|
||||||
|
|
||||||
if (priv->level != level) {
|
|
||||||
priv->level = level;
|
|
||||||
g_object_notify (G_OBJECT(element), "level");
|
|
||||||
g_signal_emit (element, signals[SYMBOL_INDEX_CHANGED], 0,
|
|
||||||
priv->group, level);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* eek_element_get_group:
|
|
||||||
* @element: an #EekElement
|
|
||||||
*
|
|
||||||
* Return the group value of the default symbol index of @element.
|
|
||||||
* If the value is not set, -1 will be returned.
|
|
||||||
*
|
|
||||||
* See also: eek_element_get_symbol_index()
|
|
||||||
*/
|
|
||||||
gint
|
|
||||||
eek_element_get_group (EekElement *element)
|
|
||||||
{
|
|
||||||
g_return_val_if_fail (EEK_IS_ELEMENT(element), -1);
|
|
||||||
|
|
||||||
EekElementPrivate *priv = eek_element_get_instance_private (element);
|
|
||||||
|
|
||||||
return priv->group;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* eek_element_get_level:
|
|
||||||
* @element: an #EekElement
|
|
||||||
*
|
|
||||||
* Return the level value of the default symbol index of @element.
|
|
||||||
* If the value is not set, -1 will be returned.
|
|
||||||
*
|
|
||||||
* See also: eek_element_get_symbol_index()
|
|
||||||
*/
|
|
||||||
gint
|
|
||||||
eek_element_get_level (EekElement *element)
|
|
||||||
{
|
|
||||||
g_return_val_if_fail (EEK_IS_ELEMENT(element), -1);
|
|
||||||
|
|
||||||
EekElementPrivate *priv = eek_element_get_instance_private (element);
|
|
||||||
|
|
||||||
return priv->level;
|
|
||||||
}
|
|
||||||
|
|||||||
@ -36,11 +36,6 @@ struct _EekElementClass
|
|||||||
{
|
{
|
||||||
/*< private >*/
|
/*< private >*/
|
||||||
GObjectClass parent_class;
|
GObjectClass parent_class;
|
||||||
|
|
||||||
/* signals */
|
|
||||||
void (* symbol_index_changed) (EekElement *self,
|
|
||||||
gint group,
|
|
||||||
gint level);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
GType eek_element_get_type (void) G_GNUC_CONST;
|
GType eek_element_get_type (void) G_GNUC_CONST;
|
||||||
@ -70,18 +65,5 @@ void eek_element_get_absolute_position (EekElement *element,
|
|||||||
gdouble *x,
|
gdouble *x,
|
||||||
gdouble *y);
|
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
|
G_END_DECLS
|
||||||
#endif /* EEK_ELEMENT_H */
|
#endif /* EEK_ELEMENT_H */
|
||||||
|
|||||||
@ -32,12 +32,13 @@
|
|||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "eek-gtk-keyboard.h"
|
|
||||||
#include "eek-renderer.h"
|
#include "eek-renderer.h"
|
||||||
#include "eek-keyboard.h"
|
#include "eek-keyboard.h"
|
||||||
#include "eek-section.h"
|
#include "eek-section.h"
|
||||||
#include "eek-key.h"
|
#include "eek-key.h"
|
||||||
#include "eek-symbol.h"
|
#include "src/symbol.h"
|
||||||
|
|
||||||
|
#include "eek-gtk-keyboard.h"
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
PROP_0,
|
PROP_0,
|
||||||
@ -54,7 +55,7 @@ enum {
|
|||||||
typedef struct _EekGtkKeyboardPrivate
|
typedef struct _EekGtkKeyboardPrivate
|
||||||
{
|
{
|
||||||
EekRenderer *renderer;
|
EekRenderer *renderer;
|
||||||
EekKeyboard *keyboard;
|
LevelKeyboard *keyboard;
|
||||||
GtkCssProvider *css_provider;
|
GtkCssProvider *css_provider;
|
||||||
GtkStyleContext *scontext;
|
GtkStyleContext *scontext;
|
||||||
|
|
||||||
@ -64,13 +65,13 @@ typedef struct _EekGtkKeyboardPrivate
|
|||||||
G_DEFINE_TYPE_WITH_PRIVATE (EekGtkKeyboard, eek_gtk_keyboard, GTK_TYPE_DRAWING_AREA)
|
G_DEFINE_TYPE_WITH_PRIVATE (EekGtkKeyboard, eek_gtk_keyboard, GTK_TYPE_DRAWING_AREA)
|
||||||
|
|
||||||
static void on_key_pressed (EekKey *key,
|
static void on_key_pressed (EekKey *key,
|
||||||
EekGtkKeyboard *self);
|
EekGtkKeyboard *self, guint level);
|
||||||
static void on_key_released (EekKey *key,
|
static void on_key_released (EekKey *key,
|
||||||
EekGtkKeyboard *self);
|
EekGtkKeyboard *self);
|
||||||
static void render_pressed_key (GtkWidget *widget,
|
static void render_pressed_key (GtkWidget *widget,
|
||||||
EekKey *key);
|
EekKey *key, guint level);
|
||||||
static void render_locked_key (GtkWidget *widget,
|
static void render_locked_key (GtkWidget *widget,
|
||||||
EekKey *key);
|
EekKey *key, guint level);
|
||||||
static void render_released_key (GtkWidget *widget,
|
static void render_released_key (GtkWidget *widget,
|
||||||
EekKey *key);
|
EekKey *key);
|
||||||
|
|
||||||
@ -95,8 +96,6 @@ eek_gtk_keyboard_real_draw (GtkWidget *self,
|
|||||||
EekGtkKeyboardPrivate *priv =
|
EekGtkKeyboardPrivate *priv =
|
||||||
eek_gtk_keyboard_get_instance_private (EEK_GTK_KEYBOARD (self));
|
eek_gtk_keyboard_get_instance_private (EEK_GTK_KEYBOARD (self));
|
||||||
GtkAllocation allocation;
|
GtkAllocation allocation;
|
||||||
GList *list, *head;
|
|
||||||
|
|
||||||
gtk_widget_get_allocation (self, &allocation);
|
gtk_widget_get_allocation (self, &allocation);
|
||||||
|
|
||||||
if (!priv->renderer) {
|
if (!priv->renderer) {
|
||||||
@ -113,19 +112,19 @@ eek_gtk_keyboard_real_draw (GtkWidget *self,
|
|||||||
|
|
||||||
eek_renderer_render_keyboard (priv->renderer, cr);
|
eek_renderer_render_keyboard (priv->renderer, cr);
|
||||||
|
|
||||||
|
uint level = priv->keyboard->level;
|
||||||
|
|
||||||
/* redraw pressed key */
|
/* redraw pressed key */
|
||||||
list = eek_keyboard_get_pressed_keys (priv->keyboard);
|
const GList *list = priv->keyboard->pressed_keys;
|
||||||
for (head = list; head; head = g_list_next (head)) {
|
for (const GList *head = list; head; head = g_list_next (head)) {
|
||||||
render_pressed_key (self, head->data);
|
render_pressed_key (self, head->data, level);
|
||||||
}
|
}
|
||||||
g_list_free (list);
|
|
||||||
|
|
||||||
/* redraw locked key */
|
/* redraw locked key */
|
||||||
list = eek_keyboard_get_locked_keys (priv->keyboard);
|
list = priv->keyboard->locked_keys;
|
||||||
for (head = list; head; head = g_list_next (head)) {
|
for (const GList *head = list; head; head = g_list_next (head)) {
|
||||||
render_locked_key (self, ((EekModifierKey *)head->data)->key);
|
render_locked_key (self, ((EekModifierKey *)head->data)->key, level);
|
||||||
}
|
}
|
||||||
g_list_free (list);
|
|
||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
@ -154,7 +153,8 @@ static void depress(EekGtkKeyboard *self,
|
|||||||
|
|
||||||
if (key) {
|
if (key) {
|
||||||
eek_keyboard_press_key(priv->keyboard, key, time);
|
eek_keyboard_press_key(priv->keyboard, key, time);
|
||||||
on_key_pressed(key, self);
|
guint level = priv->keyboard->level;
|
||||||
|
on_key_pressed(key, self, level);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -164,7 +164,7 @@ static void drag(EekGtkKeyboard *self,
|
|||||||
EekKey *key = eek_renderer_find_key_by_position (priv->renderer, x, y);
|
EekKey *key = eek_renderer_find_key_by_position (priv->renderer, x, y);
|
||||||
GList *list, *head;
|
GList *list, *head;
|
||||||
|
|
||||||
list = eek_keyboard_get_pressed_keys (priv->keyboard);
|
list = g_list_copy(priv->keyboard->pressed_keys);
|
||||||
|
|
||||||
if (key) {
|
if (key) {
|
||||||
gboolean found = FALSE;
|
gboolean found = FALSE;
|
||||||
@ -181,7 +181,8 @@ static void drag(EekGtkKeyboard *self,
|
|||||||
|
|
||||||
if (!found) {
|
if (!found) {
|
||||||
eek_keyboard_press_key(priv->keyboard, key, time);
|
eek_keyboard_press_key(priv->keyboard, key, time);
|
||||||
on_key_pressed(key, self);
|
guint level = priv->keyboard->level;
|
||||||
|
on_key_pressed(key, self, level);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for (head = list; head; head = g_list_next (head)) {
|
for (head = list; head; head = g_list_next (head)) {
|
||||||
@ -195,7 +196,7 @@ static void drag(EekGtkKeyboard *self,
|
|||||||
static void release(EekGtkKeyboard *self, guint32 time) {
|
static void release(EekGtkKeyboard *self, guint32 time) {
|
||||||
EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (self);
|
EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (self);
|
||||||
|
|
||||||
GList *list = eek_keyboard_get_pressed_keys (priv->keyboard);
|
GList *list = g_list_copy(priv->keyboard->pressed_keys);
|
||||||
for (GList *head = list; head; head = g_list_next (head)) {
|
for (GList *head = list; head; head = g_list_next (head)) {
|
||||||
EekKey *key = EEK_KEY(head->data);
|
EekKey *key = EEK_KEY(head->data);
|
||||||
eek_keyboard_release_key(priv->keyboard, key, time);
|
eek_keyboard_release_key(priv->keyboard, key, time);
|
||||||
@ -282,7 +283,7 @@ eek_gtk_keyboard_real_unmap (GtkWidget *self)
|
|||||||
elements, so that the default handler of
|
elements, so that the default handler of
|
||||||
EekKeyboard::key-released signal can remove elements from its
|
EekKeyboard::key-released signal can remove elements from its
|
||||||
internal copy */
|
internal copy */
|
||||||
list = eek_keyboard_get_pressed_keys (priv->keyboard);
|
list = g_list_copy(priv->keyboard->pressed_keys);
|
||||||
for (head = list; head; head = g_list_next (head)) {
|
for (head = list; head; head = g_list_next (head)) {
|
||||||
g_log("squeek", G_LOG_LEVEL_DEBUG, "emit EekKey released");
|
g_log("squeek", G_LOG_LEVEL_DEBUG, "emit EekKey released");
|
||||||
g_signal_emit_by_name (head->data, "released");
|
g_signal_emit_by_name (head->data, "released");
|
||||||
@ -309,8 +310,8 @@ eek_gtk_keyboard_real_query_tooltip (GtkWidget *widget,
|
|||||||
(gdouble)x,
|
(gdouble)x,
|
||||||
(gdouble)y);
|
(gdouble)y);
|
||||||
if (key) {
|
if (key) {
|
||||||
EekSymbol *symbol = eek_key_get_symbol (key);
|
//struct squeek_symbol *symbol = eek_key_get_symbol_at_index(key, 0, priv->keyboard->level);
|
||||||
const gchar *text = eek_symbol_get_tooltip (symbol);
|
const gchar *text = NULL; // FIXME
|
||||||
if (text) {
|
if (text) {
|
||||||
gtk_tooltip_set_text (tooltip, text);
|
gtk_tooltip_set_text (tooltip, text);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
@ -321,18 +322,14 @@ eek_gtk_keyboard_real_query_tooltip (GtkWidget *widget,
|
|||||||
|
|
||||||
static void
|
static void
|
||||||
eek_gtk_keyboard_set_keyboard (EekGtkKeyboard *self,
|
eek_gtk_keyboard_set_keyboard (EekGtkKeyboard *self,
|
||||||
EekKeyboard *keyboard)
|
LevelKeyboard *keyboard)
|
||||||
{
|
{
|
||||||
EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (self);
|
EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (self);
|
||||||
|
|
||||||
if (priv->keyboard == keyboard)
|
if (priv->keyboard == keyboard)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (priv->keyboard) {
|
priv->keyboard = keyboard;
|
||||||
g_object_unref (priv->keyboard);
|
|
||||||
}
|
|
||||||
|
|
||||||
priv->keyboard = g_object_ref (keyboard);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -341,7 +338,7 @@ eek_gtk_keyboard_set_property (GObject *object,
|
|||||||
const GValue *value,
|
const GValue *value,
|
||||||
GParamSpec *pspec)
|
GParamSpec *pspec)
|
||||||
{
|
{
|
||||||
EekKeyboard *keyboard;
|
LevelKeyboard *keyboard;
|
||||||
|
|
||||||
switch (prop_id) {
|
switch (prop_id) {
|
||||||
case PROP_KEYBOARD:
|
case PROP_KEYBOARD:
|
||||||
@ -368,14 +365,13 @@ eek_gtk_keyboard_dispose (GObject *object)
|
|||||||
if (priv->keyboard) {
|
if (priv->keyboard) {
|
||||||
GList *list, *head;
|
GList *list, *head;
|
||||||
|
|
||||||
list = eek_keyboard_get_pressed_keys (priv->keyboard);
|
list = g_list_copy(priv->keyboard->pressed_keys);
|
||||||
for (head = list; head; head = g_list_next (head)) {
|
for (head = list; head; head = g_list_next (head)) {
|
||||||
g_log("squeek", G_LOG_LEVEL_DEBUG, "emit EekKey pressed");
|
g_log("squeek", G_LOG_LEVEL_DEBUG, "emit EekKey pressed");
|
||||||
g_signal_emit_by_name (head->data, "released", priv->keyboard);
|
g_signal_emit_by_name (head->data, "released", level_keyboard_current(priv->keyboard));
|
||||||
}
|
}
|
||||||
g_list_free (list);
|
g_list_free (list);
|
||||||
|
|
||||||
g_object_unref (priv->keyboard);
|
|
||||||
priv->keyboard = NULL;
|
priv->keyboard = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -443,37 +439,18 @@ eek_gtk_keyboard_init (EekGtkKeyboard *self)
|
|||||||
* Returns: a #GtkWidget
|
* Returns: a #GtkWidget
|
||||||
*/
|
*/
|
||||||
GtkWidget *
|
GtkWidget *
|
||||||
eek_gtk_keyboard_new (EekKeyboard *keyboard)
|
eek_gtk_keyboard_new (LevelKeyboard *keyboard)
|
||||||
{
|
{
|
||||||
return g_object_new (EEK_TYPE_GTK_KEYBOARD, "keyboard", keyboard, NULL);
|
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;
|
||||||
static void
|
return GTK_WIDGET(ret);
|
||||||
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
|
static void
|
||||||
render_pressed_key (GtkWidget *widget,
|
render_pressed_key (GtkWidget *widget,
|
||||||
EekKey *key)
|
EekKey *key,
|
||||||
|
guint level)
|
||||||
{
|
{
|
||||||
EekGtkKeyboard *self = EEK_GTK_KEYBOARD (widget);
|
EekGtkKeyboard *self = EEK_GTK_KEYBOARD (widget);
|
||||||
EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (self);
|
EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (self);
|
||||||
@ -483,7 +460,7 @@ render_pressed_key (GtkWidget *widget,
|
|||||||
GdkDrawingContext *context = gdk_window_begin_draw_frame (window, region);
|
GdkDrawingContext *context = gdk_window_begin_draw_frame (window, region);
|
||||||
cairo_t *cr = gdk_drawing_context_get_cairo_context (context);
|
cairo_t *cr = gdk_drawing_context_get_cairo_context (context);
|
||||||
|
|
||||||
eek_renderer_render_key (priv->renderer, cr, key, 1.0, TRUE);
|
eek_renderer_render_key (priv->renderer, cr, key, level, 1.0, TRUE);
|
||||||
/*
|
/*
|
||||||
eek_renderer_render_key (priv->renderer, cr, key, 1.5, TRUE);
|
eek_renderer_render_key (priv->renderer, cr, key, 1.5, TRUE);
|
||||||
*/
|
*/
|
||||||
@ -494,7 +471,8 @@ render_pressed_key (GtkWidget *widget,
|
|||||||
|
|
||||||
static void
|
static void
|
||||||
render_locked_key (GtkWidget *widget,
|
render_locked_key (GtkWidget *widget,
|
||||||
EekKey *key)
|
EekKey *key,
|
||||||
|
guint level)
|
||||||
{
|
{
|
||||||
EekGtkKeyboard *self = EEK_GTK_KEYBOARD (widget);
|
EekGtkKeyboard *self = EEK_GTK_KEYBOARD (widget);
|
||||||
EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (self);
|
EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (self);
|
||||||
@ -504,7 +482,7 @@ render_locked_key (GtkWidget *widget,
|
|||||||
GdkDrawingContext *context = gdk_window_begin_draw_frame (window, region);
|
GdkDrawingContext *context = gdk_window_begin_draw_frame (window, region);
|
||||||
cairo_t *cr = gdk_drawing_context_get_cairo_context (context);
|
cairo_t *cr = gdk_drawing_context_get_cairo_context (context);
|
||||||
|
|
||||||
eek_renderer_render_key (priv->renderer, cr, key, 1.0, TRUE);
|
eek_renderer_render_key (priv->renderer, cr, key, level, 1.0, TRUE);
|
||||||
|
|
||||||
gdk_window_end_draw_frame (window, context);
|
gdk_window_end_draw_frame (window, context);
|
||||||
|
|
||||||
@ -532,7 +510,8 @@ render_released_key (GtkWidget *widget,
|
|||||||
|
|
||||||
static void
|
static void
|
||||||
on_key_pressed (EekKey *key,
|
on_key_pressed (EekKey *key,
|
||||||
EekGtkKeyboard *self)
|
EekGtkKeyboard *self,
|
||||||
|
guint level)
|
||||||
{
|
{
|
||||||
EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (self);
|
EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (self);
|
||||||
|
|
||||||
@ -540,7 +519,7 @@ on_key_pressed (EekKey *key,
|
|||||||
if (!priv->renderer)
|
if (!priv->renderer)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
render_pressed_key (GTK_WIDGET(self), key);
|
render_pressed_key (GTK_WIDGET(self), key, level);
|
||||||
gtk_widget_queue_draw (GTK_WIDGET(self));
|
gtk_widget_queue_draw (GTK_WIDGET(self));
|
||||||
|
|
||||||
#if HAVE_LIBCANBERRA
|
#if HAVE_LIBCANBERRA
|
||||||
|
|||||||
@ -45,7 +45,7 @@ struct _EekGtkKeyboardClass
|
|||||||
};
|
};
|
||||||
|
|
||||||
GType eek_gtk_keyboard_get_type (void) G_GNUC_CONST;
|
GType eek_gtk_keyboard_get_type (void) G_GNUC_CONST;
|
||||||
GtkWidget *eek_gtk_keyboard_new (EekKeyboard *keyboard);
|
GtkWidget *eek_gtk_keyboard_new (LevelKeyboard *keyboard);
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
#endif /* EEK_GTK_KEYBOARD_H */
|
#endif /* EEK_GTK_KEYBOARD_H */
|
||||||
|
|||||||
220
eek/eek-key.c
220
eek/eek-key.c
@ -29,15 +29,15 @@
|
|||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "eek-key.h"
|
|
||||||
#include "eek-section.h"
|
#include "eek-section.h"
|
||||||
#include "eek-keyboard.h"
|
#include "eek-keyboard.h"
|
||||||
#include "eek-symbol.h"
|
#include "src/keyboard.h"
|
||||||
|
#include "src/symbol.h"
|
||||||
|
|
||||||
|
#include "eek-key.h"
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
PROP_0,
|
PROP_0,
|
||||||
PROP_KEYCODE,
|
|
||||||
PROP_SYMBOL_MATRIX,
|
|
||||||
PROP_OREF,
|
PROP_OREF,
|
||||||
PROP_LAST
|
PROP_LAST
|
||||||
};
|
};
|
||||||
@ -52,10 +52,8 @@ static guint signals[LAST_SIGNAL] = { 0, };
|
|||||||
|
|
||||||
typedef struct _EekKeyPrivate
|
typedef struct _EekKeyPrivate
|
||||||
{
|
{
|
||||||
guint keycode;
|
|
||||||
EekSymbolMatrix *symbol_matrix;
|
|
||||||
gulong oref; // UI outline reference
|
gulong oref; // UI outline reference
|
||||||
gboolean is_pressed;
|
struct squeek_key *state;
|
||||||
gboolean is_locked;
|
gboolean is_locked;
|
||||||
} EekKeyPrivate;
|
} EekKeyPrivate;
|
||||||
|
|
||||||
@ -89,7 +87,7 @@ eek_key_finalize (GObject *object)
|
|||||||
EekKey *self = EEK_KEY (object);
|
EekKey *self = EEK_KEY (object);
|
||||||
EekKeyPrivate *priv = eek_key_get_instance_private (self);
|
EekKeyPrivate *priv = eek_key_get_instance_private (self);
|
||||||
|
|
||||||
eek_symbol_matrix_free (priv->symbol_matrix);
|
squeek_key_free (priv->state);
|
||||||
|
|
||||||
G_OBJECT_CLASS (eek_key_parent_class)->finalize (object);
|
G_OBJECT_CLASS (eek_key_parent_class)->finalize (object);
|
||||||
}
|
}
|
||||||
@ -100,15 +98,7 @@ eek_key_set_property (GObject *object,
|
|||||||
const GValue *value,
|
const GValue *value,
|
||||||
GParamSpec *pspec)
|
GParamSpec *pspec)
|
||||||
{
|
{
|
||||||
EekSymbolMatrix *matrix;
|
|
||||||
switch (prop_id) {
|
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:
|
case PROP_OREF:
|
||||||
eek_key_set_oref (EEK_KEY(object), g_value_get_uint (value));
|
eek_key_set_oref (EEK_KEY(object), g_value_get_uint (value));
|
||||||
break;
|
break;
|
||||||
@ -125,13 +115,6 @@ eek_key_get_property (GObject *object,
|
|||||||
GParamSpec *pspec)
|
GParamSpec *pspec)
|
||||||
{
|
{
|
||||||
switch (prop_id) {
|
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:
|
case PROP_OREF:
|
||||||
g_value_set_uint (value, eek_key_get_oref (EEK_KEY(object)));
|
g_value_set_uint (value, eek_key_get_oref (EEK_KEY(object)));
|
||||||
break;
|
break;
|
||||||
@ -155,30 +138,6 @@ eek_key_class_init (EekKeyClass *klass)
|
|||||||
klass->locked = eek_key_real_locked;
|
klass->locked = eek_key_real_locked;
|
||||||
klass->unlocked = eek_key_real_unlocked;
|
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:
|
* EekKey:oref:
|
||||||
*
|
*
|
||||||
@ -232,9 +191,13 @@ static void
|
|||||||
eek_key_init (EekKey *self)
|
eek_key_init (EekKey *self)
|
||||||
{
|
{
|
||||||
EekKeyPrivate *priv = eek_key_get_instance_private (self);
|
EekKeyPrivate *priv = eek_key_get_instance_private (self);
|
||||||
priv->symbol_matrix = eek_symbol_matrix_new (0, 0);
|
priv->state = squeek_key_new (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void eek_key_share_state(EekKey *self, struct squeek_key *state) {
|
||||||
|
EekKeyPrivate *priv = eek_key_get_instance_private (self);
|
||||||
|
priv->state = state;
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* eek_key_set_keycode:
|
* eek_key_set_keycode:
|
||||||
* @key: an #EekKey
|
* @key: an #EekKey
|
||||||
@ -254,7 +217,7 @@ eek_key_set_keycode (EekKey *key,
|
|||||||
|
|
||||||
EekKeyPrivate *priv = eek_key_get_instance_private (key);
|
EekKeyPrivate *priv = eek_key_get_instance_private (key);
|
||||||
|
|
||||||
priv->keycode = keycode;
|
squeek_key_set_keycode(priv->state, keycode);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -271,110 +234,7 @@ eek_key_get_keycode (EekKey *key)
|
|||||||
|
|
||||||
EekKeyPrivate *priv = eek_key_get_instance_private (key);
|
EekKeyPrivate *priv = eek_key_get_instance_private (key);
|
||||||
|
|
||||||
return priv->keycode;
|
return squeek_key_get_keycode(priv->state);
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -388,46 +248,13 @@ eek_key_get_symbol_with_fallback (EekKey *key,
|
|||||||
* Get the symbol at (@group, @level) in the symbol matrix of @key.
|
* Get the symbol at (@group, @level) in the symbol matrix of @key.
|
||||||
* Return value: (transfer none): an #EekSymbol at (@group, @level), or %NULL
|
* Return value: (transfer none): an #EekSymbol at (@group, @level), or %NULL
|
||||||
*/
|
*/
|
||||||
EekSymbol *
|
struct squeek_symbol*
|
||||||
eek_key_get_symbol_at_index (EekKey *key,
|
eek_key_get_symbol_at_index (EekKey *key,
|
||||||
gint group,
|
gint group,
|
||||||
gint level,
|
guint level)
|
||||||
gint fallback_group,
|
|
||||||
gint fallback_level)
|
|
||||||
{
|
{
|
||||||
EekKeyPrivate *priv = eek_key_get_instance_private (key);
|
EekKeyPrivate *priv = eek_key_get_instance_private (key);
|
||||||
gint num_symbols;
|
return squeek_key_get_symbol(priv->state, level);
|
||||||
|
|
||||||
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];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -479,9 +306,9 @@ eek_key_is_pressed (EekKey *key)
|
|||||||
{
|
{
|
||||||
g_return_val_if_fail (EEK_IS_KEY(key), FALSE);
|
g_return_val_if_fail (EEK_IS_KEY(key), FALSE);
|
||||||
|
|
||||||
EekKeyPrivate *priv = eek_key_get_instance_private (key);
|
EekKeyPrivate *priv = (EekKeyPrivate*)eek_key_get_instance_private (key);
|
||||||
|
|
||||||
return priv->is_pressed;
|
return (bool)squeek_key_is_pressed(priv->state);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -506,13 +333,10 @@ void eek_key_set_pressed(EekKey *key, gboolean value)
|
|||||||
|
|
||||||
EekKeyPrivate *priv = eek_key_get_instance_private (key);
|
EekKeyPrivate *priv = eek_key_get_instance_private (key);
|
||||||
|
|
||||||
priv->is_pressed = value;
|
squeek_key_set_pressed(priv->state, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
gboolean
|
struct squeek_key *eek_key_get_state(EekKey *key) {
|
||||||
eek_key_has_label(EekKey *key)
|
EekKeyPrivate *priv = eek_key_get_instance_private (key);
|
||||||
{
|
return priv->state;
|
||||||
EekSymbol *symbol = eek_key_get_symbol(key);
|
|
||||||
return (eek_symbol_get_label(symbol) != NULL) ||
|
|
||||||
(eek_symbol_get_icon_name(symbol) != NULL);
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -26,7 +26,6 @@
|
|||||||
#define EEK_KEY_H 1
|
#define EEK_KEY_H 1
|
||||||
|
|
||||||
#include "eek-element.h"
|
#include "eek-element.h"
|
||||||
#include "eek-symbol-matrix.h"
|
|
||||||
|
|
||||||
G_BEGIN_DECLS
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
@ -59,19 +58,10 @@ GType eek_key_get_type (void) G_GNUC_CONST;
|
|||||||
void eek_key_set_keycode (EekKey *key,
|
void eek_key_set_keycode (EekKey *key,
|
||||||
guint keycode);
|
guint keycode);
|
||||||
guint eek_key_get_keycode (EekKey *key);
|
guint eek_key_get_keycode (EekKey *key);
|
||||||
void eek_key_set_symbol_matrix (EekKey *key,
|
struct squeek_key *eek_key_get_state(EekKey *key);
|
||||||
EekSymbolMatrix *matrix);
|
struct squeek_symbol *eek_key_get_symbol_at_index (EekKey *key,
|
||||||
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 group,
|
||||||
gint level,
|
guint level);
|
||||||
gint fallback_group,
|
|
||||||
gint fallback_level);
|
|
||||||
|
|
||||||
void eek_key_set_oref (EekKey *key,
|
void eek_key_set_oref (EekKey *key,
|
||||||
guint oref);
|
guint oref);
|
||||||
@ -81,8 +71,6 @@ gboolean eek_key_is_pressed (EekKey *key);
|
|||||||
gboolean eek_key_is_locked (EekKey *key);
|
gboolean eek_key_is_locked (EekKey *key);
|
||||||
void eek_key_set_pressed (EekKey *key,
|
void eek_key_set_pressed (EekKey *key,
|
||||||
gboolean value);
|
gboolean value);
|
||||||
|
void eek_key_share_state(EekKey *self, struct squeek_key *state);
|
||||||
gboolean eek_key_has_label (EekKey *key);
|
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
#endif /* EEK_KEY_H */
|
#endif /* EEK_KEY_H */
|
||||||
|
|||||||
@ -30,18 +30,19 @@
|
|||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include <glib/gprintf.h>
|
#include <glib/gprintf.h>
|
||||||
|
|
||||||
#include "eek-keyboard.h"
|
|
||||||
#include "eek-marshalers.h"
|
#include "eek-marshalers.h"
|
||||||
#include "eek-section.h"
|
#include "eek-section.h"
|
||||||
#include "eek-key.h"
|
#include "eek-key.h"
|
||||||
#include "eek-symbol.h"
|
|
||||||
#include "eek-enumtypes.h"
|
#include "eek-enumtypes.h"
|
||||||
#include "eekboard/key-emitter.h"
|
#include "eekboard/key-emitter.h"
|
||||||
#include "keymap.h"
|
#include "keymap.h"
|
||||||
|
#include "src/keyboard.h"
|
||||||
|
#include "src/symbol.h"
|
||||||
|
|
||||||
|
#include "eek-keyboard.h"
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
PROP_0,
|
PROP_0,
|
||||||
PROP_MODIFIER_BEHAVIOR,
|
|
||||||
PROP_LAST
|
PROP_LAST
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -66,19 +67,7 @@ static guint signals[LAST_SIGNAL] = { 0, };
|
|||||||
|
|
||||||
struct _EekKeyboardPrivate
|
struct _EekKeyboardPrivate
|
||||||
{
|
{
|
||||||
EekModifierBehavior modifier_behavior;
|
char dummy; // won't run otherwise
|
||||||
EekModifierType modifiers;
|
|
||||||
unsigned int old_level;
|
|
||||||
GList *pressed_keys;
|
|
||||||
GList *locked_keys;
|
|
||||||
GArray *outline_array;
|
|
||||||
|
|
||||||
/* Map key names to key objects: */
|
|
||||||
GHashTable *names;
|
|
||||||
|
|
||||||
/* modifiers dynamically assigned at run time */
|
|
||||||
EekModifierType num_lock_mask;
|
|
||||||
EekModifierType alt_gr_mask;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
G_DEFINE_TYPE_WITH_PRIVATE (EekKeyboard, eek_keyboard, EEK_TYPE_CONTAINER);
|
G_DEFINE_TYPE_WITH_PRIVATE (EekKeyboard, eek_keyboard, EEK_TYPE_CONTAINER);
|
||||||
@ -115,37 +104,7 @@ on_key_unlocked (EekSection *section,
|
|||||||
g_signal_emit (keyboard, signals[KEY_UNLOCKED], 0, key);
|
g_signal_emit (keyboard, signals[KEY_UNLOCKED], 0, key);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
EekSection *
|
||||||
on_symbol_index_changed (EekSection *section,
|
|
||||||
gint group,
|
|
||||||
gint level,
|
|
||||||
EekKeyboard *keyboard)
|
|
||||||
{
|
|
||||||
g_signal_emit_by_name (keyboard, "symbol-index-changed", group, level);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
section_child_added_cb (EekContainer *container,
|
|
||||||
EekElement *element,
|
|
||||||
EekKeyboard *keyboard)
|
|
||||||
{
|
|
||||||
const gchar *name = eek_element_get_name(element);
|
|
||||||
g_hash_table_insert (keyboard->priv->names,
|
|
||||||
(gpointer)name,
|
|
||||||
element);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
section_child_removed_cb (EekContainer *container,
|
|
||||||
EekElement *element,
|
|
||||||
EekKeyboard *keyboard)
|
|
||||||
{
|
|
||||||
const gchar *name = eek_element_get_name(element);
|
|
||||||
g_hash_table_remove (keyboard->priv->names,
|
|
||||||
name);
|
|
||||||
}
|
|
||||||
|
|
||||||
static EekSection *
|
|
||||||
eek_keyboard_real_create_section (EekKeyboard *self)
|
eek_keyboard_real_create_section (EekKeyboard *self)
|
||||||
{
|
{
|
||||||
EekSection *section;
|
EekSection *section;
|
||||||
@ -153,12 +112,6 @@ eek_keyboard_real_create_section (EekKeyboard *self)
|
|||||||
section = g_object_new (EEK_TYPE_SECTION, NULL);
|
section = g_object_new (EEK_TYPE_SECTION, NULL);
|
||||||
g_return_val_if_fail (section, NULL);
|
g_return_val_if_fail (section, NULL);
|
||||||
|
|
||||||
g_signal_connect (G_OBJECT(section), "child-added",
|
|
||||||
G_CALLBACK(section_child_added_cb), self);
|
|
||||||
|
|
||||||
g_signal_connect (G_OBJECT(section), "child-removed",
|
|
||||||
G_CALLBACK(section_child_removed_cb), self);
|
|
||||||
|
|
||||||
EEK_CONTAINER_GET_CLASS(self)->add_child (EEK_CONTAINER(self),
|
EEK_CONTAINER_GET_CLASS(self)->add_child (EEK_CONTAINER(self),
|
||||||
EEK_ELEMENT(section));
|
EEK_ELEMENT(section));
|
||||||
return section;
|
return section;
|
||||||
@ -171,10 +124,6 @@ eek_keyboard_set_property (GObject *object,
|
|||||||
GParamSpec *pspec)
|
GParamSpec *pspec)
|
||||||
{
|
{
|
||||||
switch (prop_id) {
|
switch (prop_id) {
|
||||||
case PROP_MODIFIER_BEHAVIOR:
|
|
||||||
eek_keyboard_set_modifier_behavior (EEK_KEYBOARD(object),
|
|
||||||
g_value_get_enum (value));
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
break;
|
break;
|
||||||
@ -188,183 +137,117 @@ eek_keyboard_get_property (GObject *object,
|
|||||||
GParamSpec *pspec)
|
GParamSpec *pspec)
|
||||||
{
|
{
|
||||||
switch (prop_id) {
|
switch (prop_id) {
|
||||||
case PROP_MODIFIER_BEHAVIOR:
|
|
||||||
g_value_set_enum (value,
|
|
||||||
eek_keyboard_get_modifier_behavior (EEK_KEYBOARD(object)));
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
/// Updates the state of locked keys based on the key that was activated
|
||||||
set_level_from_modifiers (EekKeyboard *self, EekKey *key)
|
/// FIXME: make independent of what the key are named,
|
||||||
|
/// and instead refer to the contained symbols
|
||||||
|
static guint
|
||||||
|
set_key_states (LevelKeyboard *keyboard,
|
||||||
|
EekKey *key,
|
||||||
|
guint new_level)
|
||||||
{
|
{
|
||||||
EekKeyboardPrivate *priv = EEK_KEYBOARD_GET_PRIVATE(self);
|
// Keys locking rules hardcoded for the time being...
|
||||||
|
const gchar *name = eek_element_get_name(EEK_ELEMENT(key));
|
||||||
|
// Lock the shift whenever it's pressed on the baselevel
|
||||||
|
// TODO: need to lock shift on the destination level
|
||||||
|
if (g_strcmp0(name, "Shift_L") == 0 && keyboard->level == 0) {
|
||||||
|
EekModifierKey *modifier_key = g_slice_new (EekModifierKey);
|
||||||
|
modifier_key->modifiers = 0;
|
||||||
|
modifier_key->key = g_object_ref (key);
|
||||||
|
keyboard->locked_keys =
|
||||||
|
g_list_prepend (keyboard->locked_keys, modifier_key);
|
||||||
|
g_signal_emit_by_name (modifier_key->key, "locked");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (keyboard->level == 1) {
|
||||||
|
// Only shift is locked in this state, unlock on any key press
|
||||||
|
for (GList *head = keyboard->locked_keys; head; ) {
|
||||||
|
EekModifierKey *modifier_key = head->data;
|
||||||
|
GList *next = g_list_next (head);
|
||||||
|
keyboard->locked_keys =
|
||||||
|
g_list_remove_link (keyboard->locked_keys, head);
|
||||||
|
g_signal_emit_by_name (modifier_key->key, "unlocked");
|
||||||
|
g_list_free1 (head);
|
||||||
|
head = next;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return new_level;
|
||||||
|
}
|
||||||
|
|
||||||
|
// FIXME: unhardcode, parse some user information as to which key triggers which view (level)
|
||||||
|
static void
|
||||||
|
set_level_from_press (LevelKeyboard *keyboard, EekKey *key)
|
||||||
|
{
|
||||||
/* The levels are: 0 Letters, 1 Upper case letters, 2 Numbers, 3 Symbols */
|
/* The levels are: 0 Letters, 1 Upper case letters, 2 Numbers, 3 Symbols */
|
||||||
|
guint level = keyboard->level;
|
||||||
/* Use the numbers/letters bit from the old level */
|
|
||||||
gint level = priv->old_level & 2;
|
|
||||||
|
|
||||||
/* Handle non-emitting keys */
|
/* Handle non-emitting keys */
|
||||||
if (key) {
|
if (key) {
|
||||||
const gchar *name = eek_element_get_name(EEK_ELEMENT(key));
|
const gchar *name = eek_element_get_name(EEK_ELEMENT(key));
|
||||||
if (g_strcmp0(name, "ABC123") == 0)
|
if (g_strcmp0(name, "show_numbers") == 0) {
|
||||||
level ^= 2;
|
level = 2;
|
||||||
}
|
} else if (g_strcmp0(name, "show_letters") == 0) {
|
||||||
|
level = 0;
|
||||||
level |= ((priv->modifiers & EEK_SHIFT_MASK) ? 1 : 0);
|
} else if (g_strcmp0(name, "show_symbols") == 0) {
|
||||||
|
level = 3;
|
||||||
switch (priv->old_level) {
|
} else if (g_strcmp0(name, "Shift_L") == 0) {
|
||||||
case VIEW_LETTERS_UPPER:
|
level ^= 1;
|
||||||
{
|
|
||||||
/* Redirect upper case letters to numbers instead of symbols, clearing
|
|
||||||
the shift modifier to keep the modifiers in sync with the level */
|
|
||||||
if (level == VIEW_SYMBOLS) {
|
|
||||||
level = VIEW_NUMBERS;
|
|
||||||
priv->modifiers &= ~EEK_SHIFT_MASK;
|
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
}
|
|
||||||
case VIEW_SYMBOLS:
|
|
||||||
{
|
|
||||||
/* Redirect symbols to lower case letters instead of upper case,
|
|
||||||
clearing the shift modifier to keep the modifiers in sync with the
|
|
||||||
level */
|
|
||||||
if (level == VIEW_LETTERS_UPPER) {
|
|
||||||
level = VIEW_LETTERS_LOWER;
|
|
||||||
priv->modifiers &= ~EEK_SHIFT_MASK;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case VIEW_LETTERS_LOWER: /* Direct transitions between views */
|
|
||||||
case VIEW_NUMBERS:
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (level == VIEW_NUMBERS || level == VIEW_SYMBOLS)
|
keyboard->level = set_key_states(keyboard, key, level);
|
||||||
priv->modifier_behavior = EEK_MODIFIER_BEHAVIOR_LOCK;
|
|
||||||
else
|
|
||||||
priv->modifier_behavior = EEK_MODIFIER_BEHAVIOR_LATCH;
|
|
||||||
|
|
||||||
priv->old_level = level;
|
eek_layout_update_layout(keyboard);
|
||||||
eek_element_set_level (EEK_ELEMENT(self), level);
|
|
||||||
|
|
||||||
eek_layout_update_layout(self);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
void eek_keyboard_press_key(LevelKeyboard *keyboard, EekKey *key, guint32 timestamp) {
|
||||||
set_modifiers_with_key (EekKeyboard *self,
|
|
||||||
EekKey *key,
|
|
||||||
EekModifierType modifiers)
|
|
||||||
{
|
|
||||||
EekKeyboardPrivate *priv = EEK_KEYBOARD_GET_PRIVATE(self);
|
|
||||||
EekModifierType enabled = (priv->modifiers ^ modifiers) & modifiers;
|
|
||||||
EekModifierType disabled = (priv->modifiers ^ modifiers) & priv->modifiers;
|
|
||||||
|
|
||||||
if (enabled != 0) {
|
|
||||||
if (priv->modifier_behavior != EEK_MODIFIER_BEHAVIOR_NONE) {
|
|
||||||
EekModifierKey *modifier_key = g_slice_new (EekModifierKey);
|
|
||||||
modifier_key->modifiers = enabled;
|
|
||||||
modifier_key->key = g_object_ref (key);
|
|
||||||
priv->locked_keys =
|
|
||||||
g_list_prepend (priv->locked_keys, modifier_key);
|
|
||||||
g_signal_emit_by_name (modifier_key->key, "locked");
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (priv->modifier_behavior != EEK_MODIFIER_BEHAVIOR_NONE) {
|
|
||||||
GList *head;
|
|
||||||
for (head = priv->locked_keys; head; ) {
|
|
||||||
EekModifierKey *modifier_key = head->data;
|
|
||||||
if (modifier_key->modifiers & disabled) {
|
|
||||||
GList *next = g_list_next (head);
|
|
||||||
priv->locked_keys =
|
|
||||||
g_list_remove_link (priv->locked_keys, head);
|
|
||||||
g_signal_emit_by_name (modifier_key->key, "unlocked");
|
|
||||||
g_list_free1 (head);
|
|
||||||
head = next;
|
|
||||||
} else
|
|
||||||
head = g_list_next (head);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
priv->modifiers = modifiers;
|
|
||||||
}
|
|
||||||
|
|
||||||
void eek_keyboard_press_key(EekKeyboard *keyboard, EekKey *key, guint32 timestamp) {
|
|
||||||
EekKeyboardPrivate *priv = EEK_KEYBOARD_GET_PRIVATE(keyboard);
|
|
||||||
|
|
||||||
eek_key_set_pressed(key, TRUE);
|
eek_key_set_pressed(key, TRUE);
|
||||||
priv->pressed_keys = g_list_prepend (priv->pressed_keys, key);
|
keyboard->pressed_keys = g_list_prepend (keyboard->pressed_keys, key);
|
||||||
|
|
||||||
EekSymbol *symbol = eek_key_get_symbol_with_fallback (key, 0, 0);
|
struct squeek_symbol *symbol = eek_key_get_symbol_at_index(
|
||||||
|
key, 0, keyboard->level
|
||||||
|
);
|
||||||
if (!symbol)
|
if (!symbol)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
EekModifierType modifier = eek_symbol_get_modifier_mask (symbol);
|
// Only take action about setting level *after* the key has taken effect, i.e. on release
|
||||||
if (priv->modifier_behavior == EEK_MODIFIER_BEHAVIOR_NONE) {
|
//set_level_from_press (keyboard, key);
|
||||||
set_modifiers_with_key (keyboard, key, priv->modifiers | modifier);
|
|
||||||
set_level_from_modifiers (keyboard, key);
|
|
||||||
}
|
|
||||||
|
|
||||||
// "Borrowed" from eek-context-service; doesn't influence the state but forwards the event
|
// "Borrowed" from eek-context-service; doesn't influence the state but forwards the event
|
||||||
|
|
||||||
guint keycode = eek_key_get_keycode (key);
|
guint keycode = eek_key_get_keycode (key);
|
||||||
EekModifierType modifiers = eek_keyboard_get_modifiers (keyboard);
|
|
||||||
|
|
||||||
emit_key_activated(keyboard->manager, keyboard, keycode, symbol, modifiers, TRUE, timestamp);
|
emit_key_activated(keyboard->manager, keyboard, keycode, symbol, 0, TRUE, timestamp);
|
||||||
}
|
}
|
||||||
|
|
||||||
void eek_keyboard_release_key( EekKeyboard *keyboard,
|
void eek_keyboard_release_key(LevelKeyboard *keyboard,
|
||||||
EekKey *key,
|
EekKey *key,
|
||||||
guint32 timestamp) {
|
guint32 timestamp) {
|
||||||
EekKeyboardPrivate *priv = EEK_KEYBOARD_GET_PRIVATE(keyboard);
|
for (GList *head = keyboard->pressed_keys; head; head = g_list_next (head)) {
|
||||||
|
|
||||||
for (GList *head = priv->pressed_keys; head; head = g_list_next (head)) {
|
|
||||||
if (head->data == key) {
|
if (head->data == key) {
|
||||||
priv->pressed_keys = g_list_remove_link (priv->pressed_keys, head);
|
keyboard->pressed_keys = g_list_remove_link (keyboard->pressed_keys, head);
|
||||||
g_list_free1 (head);
|
g_list_free1 (head);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
EekSymbol *symbol = eek_key_get_symbol_with_fallback (key, 0, 0);
|
struct squeek_symbol *symbol = eek_key_get_symbol_at_index(
|
||||||
|
key, 0, keyboard->level);
|
||||||
if (!symbol)
|
if (!symbol)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
EekModifierType modifier = eek_symbol_get_modifier_mask (symbol);
|
set_level_from_press (keyboard, key);
|
||||||
|
|
||||||
if (!symbol)
|
|
||||||
return;
|
|
||||||
|
|
||||||
modifier = eek_symbol_get_modifier_mask (symbol);
|
|
||||||
switch (priv->modifier_behavior) {
|
|
||||||
case EEK_MODIFIER_BEHAVIOR_NONE:
|
|
||||||
set_modifiers_with_key (keyboard, key, priv->modifiers & ~modifier);
|
|
||||||
break;
|
|
||||||
case EEK_MODIFIER_BEHAVIOR_LOCK:
|
|
||||||
priv->modifiers ^= modifier;
|
|
||||||
break;
|
|
||||||
case EEK_MODIFIER_BEHAVIOR_LATCH:
|
|
||||||
if (modifier)
|
|
||||||
set_modifiers_with_key (keyboard, key, priv->modifiers ^ modifier);
|
|
||||||
else
|
|
||||||
set_modifiers_with_key (keyboard, key,
|
|
||||||
(priv->modifiers ^ modifier) & modifier);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
set_level_from_modifiers (keyboard, key);
|
|
||||||
|
|
||||||
// "Borrowed" from eek-context-service; doesn't influence the state but forwards the event
|
// "Borrowed" from eek-context-service; doesn't influence the state but forwards the event
|
||||||
|
|
||||||
guint keycode = eek_key_get_keycode (key);
|
guint keycode = eek_key_get_keycode (key);
|
||||||
guint modifiers = eek_keyboard_get_modifiers (keyboard);
|
|
||||||
|
|
||||||
emit_key_activated(keyboard->manager, keyboard, keycode, symbol, modifiers, FALSE, timestamp);
|
emit_key_activated(keyboard->manager, keyboard, keycode, symbol, 0, FALSE, timestamp);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -376,25 +259,27 @@ eek_keyboard_dispose (GObject *object)
|
|||||||
static void
|
static void
|
||||||
eek_keyboard_finalize (GObject *object)
|
eek_keyboard_finalize (GObject *object)
|
||||||
{
|
{
|
||||||
EekKeyboardPrivate *priv = EEK_KEYBOARD_GET_PRIVATE(object);
|
G_OBJECT_CLASS (eek_keyboard_parent_class)->finalize (object);
|
||||||
guint i;
|
}
|
||||||
|
|
||||||
g_list_free (priv->pressed_keys);
|
void level_keyboard_deinit(LevelKeyboard *self) {
|
||||||
g_list_free_full (priv->locked_keys,
|
g_hash_table_destroy (self->names);
|
||||||
(GDestroyNotify) eek_modifier_key_free);
|
for (guint i = 0; i < self->outline_array->len; i++) {
|
||||||
|
EekOutline *outline = &g_array_index (self->outline_array,
|
||||||
g_hash_table_destroy (priv->names);
|
|
||||||
|
|
||||||
for (i = 0; i < priv->outline_array->len; i++) {
|
|
||||||
EekOutline *outline = &g_array_index (priv->outline_array,
|
|
||||||
EekOutline,
|
EekOutline,
|
||||||
i);
|
i);
|
||||||
g_slice_free1 (sizeof (EekPoint) * outline->num_points,
|
g_slice_free1 (sizeof (EekPoint) * outline->num_points,
|
||||||
outline->points);
|
outline->points);
|
||||||
}
|
}
|
||||||
g_array_free (priv->outline_array, TRUE);
|
g_array_free (self->outline_array, TRUE);
|
||||||
|
for (guint i = 0; i < 4; i++) {
|
||||||
G_OBJECT_CLASS (eek_keyboard_parent_class)->finalize (object);
|
// free self->view[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void level_keyboard_free(LevelKeyboard *self) {
|
||||||
|
level_keyboard_deinit(self);
|
||||||
|
g_free(self);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -405,8 +290,6 @@ eek_keyboard_real_child_added (EekContainer *self,
|
|||||||
G_CALLBACK(on_key_locked), self);
|
G_CALLBACK(on_key_locked), self);
|
||||||
g_signal_connect (element, "key-unlocked",
|
g_signal_connect (element, "key-unlocked",
|
||||||
G_CALLBACK(on_key_unlocked), self);
|
G_CALLBACK(on_key_unlocked), self);
|
||||||
g_signal_connect (element, "symbol-index-changed",
|
|
||||||
G_CALLBACK(on_symbol_index_changed), self);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -422,9 +305,6 @@ eek_keyboard_class_init (EekKeyboardClass *klass)
|
|||||||
{
|
{
|
||||||
EekContainerClass *container_class = EEK_CONTAINER_CLASS (klass);
|
EekContainerClass *container_class = EEK_CONTAINER_CLASS (klass);
|
||||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||||
GParamSpec *pspec;
|
|
||||||
|
|
||||||
klass->create_section = eek_keyboard_real_create_section;
|
|
||||||
|
|
||||||
/* signals */
|
/* signals */
|
||||||
container_class->child_added = eek_keyboard_real_child_added;
|
container_class->child_added = eek_keyboard_real_child_added;
|
||||||
@ -435,21 +315,6 @@ eek_keyboard_class_init (EekKeyboardClass *klass)
|
|||||||
gobject_class->dispose = eek_keyboard_dispose;
|
gobject_class->dispose = eek_keyboard_dispose;
|
||||||
gobject_class->finalize = eek_keyboard_finalize;
|
gobject_class->finalize = eek_keyboard_finalize;
|
||||||
|
|
||||||
/**
|
|
||||||
* EekKeyboard:modifier-behavior:
|
|
||||||
*
|
|
||||||
* The modifier handling mode of #EekKeyboard.
|
|
||||||
*/
|
|
||||||
pspec = g_param_spec_enum ("modifier-behavior",
|
|
||||||
"Modifier behavior",
|
|
||||||
"Modifier handling mode of the keyboard",
|
|
||||||
EEK_TYPE_MODIFIER_BEHAVIOR,
|
|
||||||
EEK_MODIFIER_BEHAVIOR_NONE,
|
|
||||||
G_PARAM_READWRITE);
|
|
||||||
g_object_class_install_property (gobject_class,
|
|
||||||
PROP_MODIFIER_BEHAVIOR,
|
|
||||||
pspec);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* EekKeyboard::key-locked:
|
* EekKeyboard::key-locked:
|
||||||
* @keyboard: an #EekKeyboard
|
* @keyboard: an #EekKeyboard
|
||||||
@ -495,26 +360,22 @@ static void
|
|||||||
eek_keyboard_init (EekKeyboard *self)
|
eek_keyboard_init (EekKeyboard *self)
|
||||||
{
|
{
|
||||||
self->priv = EEK_KEYBOARD_GET_PRIVATE(self);
|
self->priv = EEK_KEYBOARD_GET_PRIVATE(self);
|
||||||
self->priv->modifier_behavior = EEK_MODIFIER_BEHAVIOR_NONE;
|
|
||||||
self->priv->outline_array = g_array_new (FALSE, TRUE, sizeof (EekOutline));
|
|
||||||
self->priv->names = g_hash_table_new (g_str_hash, g_str_equal);
|
|
||||||
eek_element_set_symbol_index (EEK_ELEMENT(self), 0, 0);
|
|
||||||
self->scale = 1.0;
|
self->scale = 1.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
void level_keyboard_init(LevelKeyboard *self) {
|
||||||
* eek_keyboard_create_section:
|
self->outline_array = g_array_new (FALSE, TRUE, sizeof (EekOutline));
|
||||||
* @keyboard: an #EekKeyboard
|
}
|
||||||
*
|
|
||||||
* Create an #EekSection instance and append it to @keyboard. This
|
LevelKeyboard *level_keyboard_new(EekboardContextService *manager, EekKeyboard *views[4], GHashTable *name_key_hash) {
|
||||||
* function is rarely called by application but called by #EekLayout
|
LevelKeyboard *keyboard = g_new0(LevelKeyboard, 1);
|
||||||
* implementation.
|
level_keyboard_init(keyboard);
|
||||||
*/
|
for (uint i = 0; i < 4; i++) {
|
||||||
EekSection *
|
keyboard->views[i] = views[i];
|
||||||
eek_keyboard_create_section (EekKeyboard *keyboard)
|
}
|
||||||
{
|
keyboard->manager = manager;
|
||||||
g_return_val_if_fail (EEK_IS_KEYBOARD(keyboard), NULL);
|
keyboard->names = name_key_hash;
|
||||||
return EEK_KEYBOARD_GET_CLASS(keyboard)->create_section (keyboard);
|
return keyboard;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -526,12 +387,10 @@ eek_keyboard_create_section (EekKeyboard *keyboard)
|
|||||||
* Return value: (transfer none): #EekKey whose name is @name
|
* Return value: (transfer none): #EekKey whose name is @name
|
||||||
*/
|
*/
|
||||||
EekKey *
|
EekKey *
|
||||||
eek_keyboard_find_key_by_name (EekKeyboard *keyboard,
|
eek_keyboard_find_key_by_name (LevelKeyboard *keyboard,
|
||||||
const gchar *name)
|
const gchar *name)
|
||||||
{
|
{
|
||||||
g_return_val_if_fail (EEK_IS_KEYBOARD(keyboard), NULL);
|
return g_hash_table_lookup (keyboard->names, name);
|
||||||
return g_hash_table_lookup (keyboard->priv->names,
|
|
||||||
name);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -554,82 +413,6 @@ eek_keyboard_get_size (EekKeyboard *keyboard,
|
|||||||
*height = bounds.height;
|
*height = bounds.height;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* eek_keyboard_set_modifier_behavior:
|
|
||||||
* @keyboard: an #EekKeyboard
|
|
||||||
* @modifier_behavior: modifier behavior of @keyboard
|
|
||||||
*
|
|
||||||
* Set the modifier handling mode of @keyboard.
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
eek_keyboard_set_modifier_behavior (EekKeyboard *keyboard,
|
|
||||||
EekModifierBehavior modifier_behavior)
|
|
||||||
{
|
|
||||||
g_return_if_fail (EEK_IS_KEYBOARD(keyboard));
|
|
||||||
keyboard->priv->modifier_behavior = modifier_behavior;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* eek_keyboard_get_modifier_behavior:
|
|
||||||
* @keyboard: an #EekKeyboard
|
|
||||||
*
|
|
||||||
* Get the modifier handling mode of @keyboard.
|
|
||||||
* Returns: #EekModifierBehavior
|
|
||||||
*/
|
|
||||||
EekModifierBehavior
|
|
||||||
eek_keyboard_get_modifier_behavior (EekKeyboard *keyboard)
|
|
||||||
{
|
|
||||||
g_return_val_if_fail (EEK_IS_KEYBOARD(keyboard), 0);
|
|
||||||
return keyboard->priv->modifier_behavior;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
eek_keyboard_set_modifiers (EekKeyboard *keyboard,
|
|
||||||
EekModifierType modifiers)
|
|
||||||
{
|
|
||||||
g_return_if_fail (EEK_IS_KEYBOARD(keyboard));
|
|
||||||
keyboard->priv->modifiers = modifiers;
|
|
||||||
set_level_from_modifiers (keyboard, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* eek_keyboard_get_modifiers:
|
|
||||||
* @keyboard: an #EekKeyboard
|
|
||||||
*
|
|
||||||
* Get the current modifier status of @keyboard.
|
|
||||||
* Returns: #EekModifierType
|
|
||||||
*/
|
|
||||||
EekModifierType
|
|
||||||
eek_keyboard_get_modifiers (EekKeyboard *keyboard)
|
|
||||||
{
|
|
||||||
g_return_val_if_fail (EEK_IS_KEYBOARD(keyboard), 0);
|
|
||||||
return keyboard->priv->modifiers;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* eek_keyboard_add_outline:
|
|
||||||
* @keyboard: an #EekKeyboard
|
|
||||||
* @outline: an #EekOutline
|
|
||||||
*
|
|
||||||
* Register an outline of @keyboard.
|
|
||||||
* Returns: an unsigned integer ID of the registered outline, for
|
|
||||||
* later reference
|
|
||||||
*/
|
|
||||||
guint
|
|
||||||
eek_keyboard_add_outline (EekKeyboard *keyboard,
|
|
||||||
EekOutline *outline)
|
|
||||||
{
|
|
||||||
EekOutline *_outline;
|
|
||||||
|
|
||||||
g_return_val_if_fail (EEK_IS_KEYBOARD(keyboard), 0);
|
|
||||||
|
|
||||||
_outline = eek_outline_copy (outline);
|
|
||||||
g_array_append_val (keyboard->priv->outline_array, *_outline);
|
|
||||||
/* don't use eek_outline_free here, so as to keep _outline->points */
|
|
||||||
g_slice_free (EekOutline, _outline);
|
|
||||||
return keyboard->priv->outline_array->len - 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* eek_keyboard_get_outline:
|
* eek_keyboard_get_outline:
|
||||||
* @keyboard: an #EekKeyboard
|
* @keyboard: an #EekKeyboard
|
||||||
@ -639,117 +422,13 @@ eek_keyboard_add_outline (EekKeyboard *keyboard,
|
|||||||
* Returns: an #EekOutline, which should not be released
|
* Returns: an #EekOutline, which should not be released
|
||||||
*/
|
*/
|
||||||
EekOutline *
|
EekOutline *
|
||||||
eek_keyboard_get_outline (EekKeyboard *keyboard,
|
level_keyboard_get_outline (LevelKeyboard *keyboard,
|
||||||
guint oref)
|
guint oref)
|
||||||
{
|
{
|
||||||
g_return_val_if_fail (EEK_IS_KEYBOARD(keyboard), NULL);
|
if (oref > keyboard->outline_array->len)
|
||||||
|
|
||||||
if (oref > keyboard->priv->outline_array->len)
|
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
return &g_array_index (keyboard->priv->outline_array, EekOutline, oref);
|
return &g_array_index (keyboard->outline_array, EekOutline, oref);
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* eek_keyboard_get_n_outlines:
|
|
||||||
* @keyboard: an #EekKeyboard
|
|
||||||
*
|
|
||||||
* Get the number of outlines defined in @keyboard.
|
|
||||||
* Returns: integer
|
|
||||||
*/
|
|
||||||
gsize
|
|
||||||
eek_keyboard_get_n_outlines (EekKeyboard *keyboard)
|
|
||||||
{
|
|
||||||
g_return_val_if_fail (EEK_IS_KEYBOARD(keyboard), 0);
|
|
||||||
return keyboard->priv->outline_array->len;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* eek_keyboard_set_num_lock_mask:
|
|
||||||
* @keyboard: an #EekKeyboard
|
|
||||||
* @num_lock_mask: an #EekModifierType
|
|
||||||
*
|
|
||||||
* Set modifier mask used as Num_Lock.
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
eek_keyboard_set_num_lock_mask (EekKeyboard *keyboard,
|
|
||||||
EekModifierType num_lock_mask)
|
|
||||||
{
|
|
||||||
g_return_if_fail (EEK_IS_KEYBOARD(keyboard));
|
|
||||||
keyboard->priv->num_lock_mask = num_lock_mask;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* eek_keyboard_get_num_lock_mask:
|
|
||||||
* @keyboard: an #EekKeyboard
|
|
||||||
*
|
|
||||||
* Get modifier mask used as Num_Lock.
|
|
||||||
* Returns: an #EekModifierType
|
|
||||||
*/
|
|
||||||
EekModifierType
|
|
||||||
eek_keyboard_get_num_lock_mask (EekKeyboard *keyboard)
|
|
||||||
{
|
|
||||||
g_return_val_if_fail (EEK_IS_KEYBOARD(keyboard), 0);
|
|
||||||
return keyboard->priv->num_lock_mask;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* eek_keyboard_set_alt_gr_mask:
|
|
||||||
* @keyboard: an #EekKeyboard
|
|
||||||
* @alt_gr_mask: an #EekModifierType
|
|
||||||
*
|
|
||||||
* Set modifier mask used as Alt_Gr.
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
eek_keyboard_set_alt_gr_mask (EekKeyboard *keyboard,
|
|
||||||
EekModifierType alt_gr_mask)
|
|
||||||
{
|
|
||||||
g_return_if_fail (EEK_IS_KEYBOARD(keyboard));
|
|
||||||
keyboard->priv->alt_gr_mask = alt_gr_mask;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* eek_keyboard_get_alt_gr_mask:
|
|
||||||
* @keyboard: an #EekKeyboard
|
|
||||||
*
|
|
||||||
* Get modifier mask used as Alt_Gr.
|
|
||||||
* Returns: an #EekModifierType
|
|
||||||
*/
|
|
||||||
EekModifierType
|
|
||||||
eek_keyboard_get_alt_gr_mask (EekKeyboard *keyboard)
|
|
||||||
{
|
|
||||||
g_return_val_if_fail (EEK_IS_KEYBOARD(keyboard), 0);
|
|
||||||
return keyboard->priv->alt_gr_mask;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* eek_keyboard_get_pressed_keys:
|
|
||||||
* @keyboard: an #EekKeyboard
|
|
||||||
*
|
|
||||||
* Get pressed keys.
|
|
||||||
* Returns: (transfer container) (element-type EekKey): A list of
|
|
||||||
* pressed keys.
|
|
||||||
*/
|
|
||||||
GList *
|
|
||||||
eek_keyboard_get_pressed_keys (EekKeyboard *keyboard)
|
|
||||||
{
|
|
||||||
g_return_val_if_fail (EEK_IS_KEYBOARD(keyboard), NULL);
|
|
||||||
return g_list_copy (keyboard->priv->pressed_keys);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* eek_keyboard_get_locked_keys:
|
|
||||||
* @keyboard: an #EekKeyboard
|
|
||||||
*
|
|
||||||
* Get locked keys.
|
|
||||||
* Returns: (transfer container) (element-type Eek.ModifierKey): A list
|
|
||||||
* of locked keys.
|
|
||||||
*/
|
|
||||||
GList *
|
|
||||||
eek_keyboard_get_locked_keys (EekKeyboard *keyboard)
|
|
||||||
{
|
|
||||||
g_return_val_if_fail (EEK_IS_KEYBOARD(keyboard), NULL);
|
|
||||||
return g_list_copy (keyboard->priv->locked_keys);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -760,7 +439,7 @@ eek_keyboard_get_locked_keys (EekKeyboard *keyboard)
|
|||||||
* Returns: a string containing the XKB keymap.
|
* Returns: a string containing the XKB keymap.
|
||||||
*/
|
*/
|
||||||
gchar *
|
gchar *
|
||||||
eek_keyboard_get_keymap(EekKeyboard *keyboard)
|
eek_keyboard_get_keymap(LevelKeyboard *keyboard)
|
||||||
{
|
{
|
||||||
/* Start the keycodes and symbols sections with their respective headers. */
|
/* Start the keycodes and symbols sections with their respective headers. */
|
||||||
gchar *keycodes = g_strdup(keymap_keycodes_header);
|
gchar *keycodes = g_strdup(keymap_keycodes_header);
|
||||||
@ -768,14 +447,15 @@ eek_keyboard_get_keymap(EekKeyboard *keyboard)
|
|||||||
|
|
||||||
/* Iterate over the keys in the name-to-key hash table. */
|
/* Iterate over the keys in the name-to-key hash table. */
|
||||||
GHashTableIter iter;
|
GHashTableIter iter;
|
||||||
gpointer key_name, key_ptr;
|
gchar *key_name;
|
||||||
g_hash_table_iter_init(&iter, keyboard->priv->names);
|
gpointer key_ptr;
|
||||||
|
g_hash_table_iter_init(&iter, keyboard->names);
|
||||||
|
|
||||||
while (g_hash_table_iter_next(&iter, &key_name, &key_ptr)) {
|
while (g_hash_table_iter_next(&iter, (gpointer)&key_name, &key_ptr)) {
|
||||||
|
|
||||||
gchar *current, *line;
|
gchar *current, *line;
|
||||||
EekKey *key = EEK_KEY(key_ptr);
|
EekKey *key = EEK_KEY(key_ptr);
|
||||||
int keycode = eek_key_get_keycode(key);
|
guint keycode = eek_key_get_keycode(key);
|
||||||
|
|
||||||
/* Don't include invalid keycodes in the keymap. */
|
/* Don't include invalid keycodes in the keymap. */
|
||||||
if (keycode == EEK_INVALID_KEYCODE)
|
if (keycode == EEK_INVALID_KEYCODE)
|
||||||
@ -789,45 +469,13 @@ eek_keyboard_get_keymap(EekKeyboard *keyboard)
|
|||||||
g_free(line);
|
g_free(line);
|
||||||
g_free(current);
|
g_free(current);
|
||||||
|
|
||||||
/* Find the symbols associated with the key. */
|
// FIXME: free
|
||||||
EekSymbolMatrix *matrix = eek_key_get_symbol_matrix(key);
|
const char *key_str = squeek_key_to_keymap_entry(
|
||||||
EekSymbol *syms[4];
|
(char*)key_name,
|
||||||
int i, j;
|
eek_key_get_state(key)
|
||||||
|
);
|
||||||
/* Get the symbols for all the levels defined for the key, then
|
|
||||||
pad it out with the first symbol for all levels up to the fourth. */
|
|
||||||
for (i = 0; i < matrix->num_levels; ++i)
|
|
||||||
syms[i] = eek_symbol_matrix_get_symbol(matrix, 0, i);
|
|
||||||
|
|
||||||
while (i < 4) {
|
|
||||||
syms[i] = eek_symbol_matrix_get_symbol(matrix, 0, 0);
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* The four levels are split into two groups in the keymap.
|
|
||||||
Generate strings for each of these groups, where an empty group is
|
|
||||||
treated specially. */
|
|
||||||
|
|
||||||
gchar *groups[2];
|
|
||||||
for (i = 0, j = 0; i < 2; ++i, j += 2) {
|
|
||||||
if (syms[j] && syms[j + 1])
|
|
||||||
groups[i] = g_strjoin(", ", eek_symbol_get_name(syms[j]),
|
|
||||||
eek_symbol_get_name(syms[j + 1]),
|
|
||||||
NULL);
|
|
||||||
else
|
|
||||||
groups[i] = "";
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Append a key definition to the symbols section. */
|
|
||||||
current = symbols;
|
current = symbols;
|
||||||
line = g_strdup_printf(" key <%s> { [ %s ], [ %s ] };\n",
|
symbols = g_strconcat(current, key_str, NULL);
|
||||||
(char *)key_name, groups[0], groups[1]);
|
|
||||||
|
|
||||||
g_free(groups[0]);
|
|
||||||
g_free(groups[1]);
|
|
||||||
|
|
||||||
symbols = g_strconcat(current, line, NULL);
|
|
||||||
g_free(line);
|
|
||||||
g_free(current);
|
g_free(current);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -841,3 +489,8 @@ eek_keyboard_get_keymap(EekKeyboard *keyboard)
|
|||||||
g_free(symbols);
|
g_free(symbols);
|
||||||
return keymap;
|
return keymap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EekKeyboard *level_keyboard_current(LevelKeyboard *keyboard)
|
||||||
|
{
|
||||||
|
return keyboard->views[keyboard->level];
|
||||||
|
}
|
||||||
|
|||||||
@ -59,12 +59,7 @@ struct _EekKeyboard
|
|||||||
EekContainer parent;
|
EekContainer parent;
|
||||||
|
|
||||||
EekKeyboardPrivate *priv;
|
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
|
|
||||||
double scale;
|
double scale;
|
||||||
|
|
||||||
EekboardContextService *manager; // unowned reference
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -88,8 +83,6 @@ struct _EekKeyboardClass
|
|||||||
gpointer get_symbol_index;
|
gpointer get_symbol_index;
|
||||||
|
|
||||||
/*< public >*/
|
/*< public >*/
|
||||||
EekSection *(* create_section) (EekKeyboard *self);
|
|
||||||
|
|
||||||
EekKey *(* find_key_by_name) (EekKeyboard *self,
|
EekKey *(* find_key_by_name) (EekKeyboard *self,
|
||||||
const gchar *name);
|
const gchar *name);
|
||||||
|
|
||||||
@ -124,8 +117,28 @@ struct _EekModifierKey {
|
|||||||
};
|
};
|
||||||
typedef struct _EekModifierKey EekModifierKey;
|
typedef struct _EekModifierKey EekModifierKey;
|
||||||
|
|
||||||
|
/// Keyboard state holder
|
||||||
|
struct _LevelKeyboard {
|
||||||
|
EekKeyboard *views[4];
|
||||||
|
guint level;
|
||||||
|
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;
|
||||||
|
|
||||||
EekKeyboard *eek_keyboard_new (EekboardContextService *manager,
|
GList *pressed_keys;
|
||||||
|
GList *locked_keys;
|
||||||
|
|
||||||
|
/* Map key names to key objects: */
|
||||||
|
GHashTable *names;
|
||||||
|
|
||||||
|
guint id; // as a key to layout choices
|
||||||
|
|
||||||
|
EekboardContextService *manager; // unowned reference
|
||||||
|
};
|
||||||
|
typedef struct _LevelKeyboard LevelKeyboard;
|
||||||
|
|
||||||
|
LevelKeyboard *eek_keyboard_new(EekboardContextService *manager,
|
||||||
EekLayout *layout,
|
EekLayout *layout,
|
||||||
gdouble initial_width,
|
gdouble initial_width,
|
||||||
gdouble initial_height);
|
gdouble initial_height);
|
||||||
@ -140,61 +153,37 @@ void eek_keyboard_set_size
|
|||||||
gdouble width,
|
gdouble width,
|
||||||
gdouble height);
|
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
|
EekSection *eek_keyboard_create_section
|
||||||
(EekKeyboard *keyboard);
|
(EekKeyboard *keyboard);
|
||||||
|
|
||||||
EekKey *eek_keyboard_find_key_by_name
|
EekKey *eek_keyboard_find_key_by_name
|
||||||
(EekKeyboard *keyboard,
|
(LevelKeyboard *keyboard,
|
||||||
const gchar *name);
|
const gchar *name);
|
||||||
|
|
||||||
guint eek_keyboard_add_outline
|
EekOutline *level_keyboard_get_outline
|
||||||
(EekKeyboard *keyboard,
|
(LevelKeyboard *keyboard,
|
||||||
EekOutline *outline);
|
|
||||||
|
|
||||||
EekOutline *eek_keyboard_get_outline
|
|
||||||
(EekKeyboard *keyboard,
|
|
||||||
guint oref);
|
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 *eek_modifier_key_copy
|
||||||
(EekModifierKey *modkey);
|
(EekModifierKey *modkey);
|
||||||
void eek_modifier_key_free
|
void eek_modifier_key_free
|
||||||
(EekModifierKey *modkey);
|
(EekModifierKey *modkey);
|
||||||
|
|
||||||
void eek_keyboard_press_key(EekKeyboard *keyboard, EekKey *key, guint32 timestamp);
|
void eek_keyboard_press_key(LevelKeyboard *keyboard, EekKey *key, guint32 timestamp);
|
||||||
void eek_keyboard_release_key(EekKeyboard *keyboard, EekKey *key, guint32 timestamp);
|
void eek_keyboard_release_key(LevelKeyboard *keyboard, EekKey *key, guint32 timestamp);
|
||||||
|
|
||||||
gchar * eek_keyboard_get_keymap
|
gchar * eek_keyboard_get_keymap
|
||||||
(EekKeyboard *keyboard);
|
(LevelKeyboard *keyboard);
|
||||||
|
|
||||||
|
EekKeyboard *level_keyboard_current(LevelKeyboard *keyboard);
|
||||||
|
LevelKeyboard *level_keyboard_new(EekboardContextService *manager, EekKeyboard *views[4], GHashTable *name_key_hash);
|
||||||
|
void level_keyboard_deinit(LevelKeyboard *self);
|
||||||
|
void level_keyboard_free(LevelKeyboard *self);
|
||||||
|
/* Create an #EekSection instance and append it to @keyboard. This
|
||||||
|
* function is rarely called by application but called by #EekLayout
|
||||||
|
* implementation.
|
||||||
|
*/
|
||||||
|
EekSection *
|
||||||
|
eek_keyboard_real_create_section (EekKeyboard *self);
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
#endif /* EEK_KEYBOARD_H */
|
#endif /* EEK_KEYBOARD_H */
|
||||||
|
|||||||
207
eek/eek-keysym.c
207
eek/eek-keysym.c
@ -25,11 +25,7 @@
|
|||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
#include <string.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
#include "eek-keysym.h"
|
#include "eek-keysym.h"
|
||||||
#include "eek-serializable.h"
|
|
||||||
|
|
||||||
/* modifier keys */
|
/* modifier keys */
|
||||||
#define EEK_KEYSYM_Shift_L 0xffe1
|
#define EEK_KEYSYM_Shift_L 0xffe1
|
||||||
@ -59,204 +55,13 @@ typedef struct _EekKeysymEntry EekKeysymEntry;
|
|||||||
#include "eek-unicode-keysym-entries.h"
|
#include "eek-unicode-keysym-entries.h"
|
||||||
#include "eek-xkeysym-keysym-entries.h"
|
#include "eek-xkeysym-keysym-entries.h"
|
||||||
|
|
||||||
|
guint32
|
||||||
static gchar *
|
eek_keysym_from_name (const gchar *name)
|
||||||
unichar_to_utf8 (gunichar uc)
|
|
||||||
{
|
{
|
||||||
if (g_unichar_isgraph (uc)) {
|
for (uint i = 0; i < G_N_ELEMENTS(xkeysym_keysym_entries); i++) {
|
||||||
gchar *buf;
|
if (g_strcmp0 (xkeysym_keysym_entries[i].name, name) == 0) {
|
||||||
gint len;
|
return xkeysym_keysym_entries[i].xkeysym;
|
||||||
|
}
|
||||||
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;
|
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;
|
|
||||||
}
|
|
||||||
|
|||||||
@ -25,25 +25,8 @@
|
|||||||
#ifndef EEK_KEYSYM_H
|
#ifndef EEK_KEYSYM_H
|
||||||
#define EEK_KEYSYM_H 1
|
#define EEK_KEYSYM_H 1
|
||||||
|
|
||||||
#include <X11/XKBlib.h>
|
#include "glib.h"
|
||||||
#include "eek-symbol.h"
|
|
||||||
|
|
||||||
G_BEGIN_DECLS
|
guint32 eek_keysym_from_name (const gchar *name);
|
||||||
|
|
||||||
/**
|
|
||||||
* 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 */
|
#endif /* EEK_KEYSYM_H */
|
||||||
|
|||||||
@ -31,6 +31,7 @@
|
|||||||
#include "eek-layout.h"
|
#include "eek-layout.h"
|
||||||
#include "eek-keyboard.h"
|
#include "eek-keyboard.h"
|
||||||
#include "eekboard/eekboard-context-service.h"
|
#include "eekboard/eekboard-context-service.h"
|
||||||
|
#include "eek-xml-layout.h"
|
||||||
|
|
||||||
G_DEFINE_ABSTRACT_TYPE (EekLayout, eek_layout, G_TYPE_OBJECT)
|
G_DEFINE_ABSTRACT_TYPE (EekLayout, eek_layout, G_TYPE_OBJECT)
|
||||||
|
|
||||||
@ -45,35 +46,13 @@ eek_layout_init (EekLayout *self)
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* eek_keyboard_new:
|
|
||||||
* @layout: an #EekLayout
|
|
||||||
* @initial_width: initial width of the keyboard
|
|
||||||
* @initial_height: initial height of the keyboard
|
|
||||||
*
|
|
||||||
* Create a new #EekKeyboard based on @layout.
|
|
||||||
*/
|
|
||||||
EekKeyboard *
|
|
||||||
eek_keyboard_new (EekboardContextService *manager,
|
|
||||||
EekLayout *layout,
|
|
||||||
gdouble initial_width,
|
|
||||||
gdouble initial_height)
|
|
||||||
{
|
|
||||||
g_assert (EEK_IS_LAYOUT(layout));
|
|
||||||
g_assert (EEK_LAYOUT_GET_CLASS(layout)->create_keyboard);
|
|
||||||
|
|
||||||
return EEK_LAYOUT_GET_CLASS(layout)->create_keyboard (manager,
|
|
||||||
layout,
|
|
||||||
initial_width,
|
|
||||||
initial_height);
|
|
||||||
}
|
|
||||||
|
|
||||||
const double section_spacing = 7.0;
|
const double section_spacing = 7.0;
|
||||||
|
|
||||||
struct place_data {
|
struct place_data {
|
||||||
double desired_width;
|
double desired_width;
|
||||||
double current_offset;
|
double current_offset;
|
||||||
EekKeyboard *keyboard;
|
// Needed for outline (bounds) retrieval
|
||||||
|
LevelKeyboard *keyboard;
|
||||||
};
|
};
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -87,7 +66,7 @@ section_placer(EekElement *element, gpointer user_data)
|
|||||||
eek_element_set_bounds(element, §ion_bounds);
|
eek_element_set_bounds(element, §ion_bounds);
|
||||||
|
|
||||||
// Sections are rows now. Gather up all the keys and adjust their 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_section_place_keys(EEK_SECTION(element), data->keyboard);
|
||||||
|
|
||||||
eek_element_get_bounds(element, §ion_bounds);
|
eek_element_get_bounds(element, §ion_bounds);
|
||||||
section_bounds.y = data->current_offset;
|
section_bounds.y = data->current_offset;
|
||||||
@ -105,7 +84,7 @@ section_counter(EekElement *element, gpointer user_data) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
eek_layout_place_sections(EekKeyboard *keyboard)
|
eek_layout_place_sections(LevelKeyboard *keyboard, EekKeyboard *level)
|
||||||
{
|
{
|
||||||
/* Order rows */
|
/* Order rows */
|
||||||
// This needs to be done after outlines, because outlines define key sizes
|
// This needs to be done after outlines, because outlines define key sizes
|
||||||
@ -114,23 +93,23 @@ eek_layout_place_sections(EekKeyboard *keyboard)
|
|||||||
// The keyboard width is given by the user via screen size. The height will be given dynamically.
|
// 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
|
// TODO: calculate max line width beforehand for button centering. Leave keyboard centering to the renderer later
|
||||||
EekBounds keyboard_bounds = {0};
|
EekBounds keyboard_bounds = {0};
|
||||||
eek_element_get_bounds(EEK_ELEMENT(keyboard), &keyboard_bounds);
|
eek_element_get_bounds(EEK_ELEMENT(level), &keyboard_bounds);
|
||||||
|
|
||||||
struct place_data placer_data = {
|
struct place_data placer_data = {
|
||||||
.desired_width = keyboard_bounds.width,
|
.desired_width = keyboard_bounds.width,
|
||||||
.current_offset = 0,
|
.current_offset = 0,
|
||||||
.keyboard = keyboard,
|
.keyboard = keyboard,
|
||||||
};
|
};
|
||||||
eek_container_foreach_child(EEK_CONTAINER(keyboard), section_placer, &placer_data);
|
eek_container_foreach_child(EEK_CONTAINER(level), section_placer, &placer_data);
|
||||||
|
|
||||||
double total_height = 0;
|
double total_height = 0;
|
||||||
eek_container_foreach_child(EEK_CONTAINER(keyboard), section_counter, &total_height);
|
eek_container_foreach_child(EEK_CONTAINER(level), section_counter, &total_height);
|
||||||
keyboard_bounds.height = total_height;
|
keyboard_bounds.height = total_height;
|
||||||
eek_element_set_bounds(EEK_ELEMENT(keyboard), &keyboard_bounds);
|
eek_element_set_bounds(EEK_ELEMENT(level), &keyboard_bounds);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
eek_layout_update_layout(EekKeyboard *keyboard)
|
eek_layout_update_layout(LevelKeyboard *keyboard)
|
||||||
{
|
{
|
||||||
eek_layout_place_sections(keyboard);
|
eek_layout_place_sections(keyboard, level_keyboard_current(keyboard));
|
||||||
}
|
}
|
||||||
|
|||||||
@ -43,7 +43,7 @@ struct _EekLayoutClass
|
|||||||
GObjectClass parent_class;
|
GObjectClass parent_class;
|
||||||
|
|
||||||
/*< public >*/
|
/*< public >*/
|
||||||
EekKeyboard* (* create_keyboard) (EekboardContextService *manager,
|
LevelKeyboard* (* create_keyboard) (EekboardContextService *manager,
|
||||||
EekLayout *self,
|
EekLayout *self,
|
||||||
gdouble initial_width,
|
gdouble initial_width,
|
||||||
gdouble initial_height);
|
gdouble initial_height);
|
||||||
@ -55,9 +55,14 @@ struct _EekLayoutClass
|
|||||||
|
|
||||||
GType eek_layout_get_type (void) G_GNUC_CONST;
|
GType eek_layout_get_type (void) G_GNUC_CONST;
|
||||||
|
|
||||||
void eek_layout_place_sections(EekKeyboard *keyboard);
|
void eek_layout_place_sections(LevelKeyboard *keyboard, EekKeyboard *level);
|
||||||
|
|
||||||
void eek_layout_update_layout(EekKeyboard *keyboard);
|
void eek_layout_update_layout(LevelKeyboard *keyboard);
|
||||||
|
|
||||||
|
|
||||||
|
LevelKeyboard *
|
||||||
|
level_keyboard_from_layout (EekLayout *layout,
|
||||||
|
gdouble initial_width,
|
||||||
|
gdouble initial_height);
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
#endif /* EEK_LAYOUT_H */
|
#endif /* EEK_LAYOUT_H */
|
||||||
|
|||||||
@ -23,15 +23,15 @@
|
|||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <gdk-pixbuf/gdk-pixbuf.h>
|
#include <gdk-pixbuf/gdk-pixbuf.h>
|
||||||
#include <gtk/gtk.h>
|
|
||||||
|
|
||||||
#include "eek-key.h"
|
#include "eek-key.h"
|
||||||
#include "eek-section.h"
|
#include "eek-section.h"
|
||||||
|
#include "src/symbol.h"
|
||||||
|
|
||||||
#include "eek-renderer.h"
|
#include "eek-renderer.h"
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
PROP_0,
|
PROP_0,
|
||||||
PROP_KEYBOARD,
|
|
||||||
PROP_PCONTEXT,
|
PROP_PCONTEXT,
|
||||||
PROP_STYLE_CONTEXT,
|
PROP_STYLE_CONTEXT,
|
||||||
PROP_LAST
|
PROP_LAST
|
||||||
@ -39,7 +39,7 @@ enum {
|
|||||||
|
|
||||||
typedef struct _EekRendererPrivate
|
typedef struct _EekRendererPrivate
|
||||||
{
|
{
|
||||||
EekKeyboard *keyboard;
|
LevelKeyboard *keyboard;
|
||||||
PangoContext *pcontext;
|
PangoContext *pcontext;
|
||||||
GtkCssProvider *css_provider;
|
GtkCssProvider *css_provider;
|
||||||
GtkStyleContext *scontext;
|
GtkStyleContext *scontext;
|
||||||
@ -62,7 +62,6 @@ typedef struct _EekRendererPrivate
|
|||||||
GHashTable *active_outline_surface_cache;
|
GHashTable *active_outline_surface_cache;
|
||||||
GHashTable *icons;
|
GHashTable *icons;
|
||||||
cairo_surface_t *keyboard_surface;
|
cairo_surface_t *keyboard_surface;
|
||||||
gulong symbol_index_changed_handler;
|
|
||||||
|
|
||||||
} EekRendererPrivate;
|
} EekRendererPrivate;
|
||||||
|
|
||||||
@ -79,21 +78,18 @@ extern void _eek_rounded_polygon (cairo_t *cr,
|
|||||||
|
|
||||||
static void eek_renderer_real_render_key_label (EekRenderer *self,
|
static void eek_renderer_real_render_key_label (EekRenderer *self,
|
||||||
PangoLayout *layout,
|
PangoLayout *layout,
|
||||||
EekKey *key);
|
EekKey *key, guint level);
|
||||||
|
|
||||||
static void invalidate (EekRenderer *renderer);
|
static void invalidate (EekRenderer *renderer);
|
||||||
static void render_key (EekRenderer *self,
|
static void render_key (EekRenderer *self,
|
||||||
cairo_t *cr,
|
cairo_t *cr,
|
||||||
EekKey *key,
|
EekKey *key, guint level,
|
||||||
gboolean active);
|
gboolean active);
|
||||||
static void on_symbol_index_changed (EekKeyboard *keyboard,
|
|
||||||
gint group,
|
|
||||||
gint level,
|
|
||||||
gpointer user_data);
|
|
||||||
|
|
||||||
struct _CreateKeyboardSurfaceCallbackData {
|
struct _CreateKeyboardSurfaceCallbackData {
|
||||||
cairo_t *cr;
|
cairo_t *cr;
|
||||||
EekRenderer *renderer;
|
EekRenderer *renderer;
|
||||||
|
uint level;
|
||||||
};
|
};
|
||||||
typedef struct _CreateKeyboardSurfaceCallbackData CreateKeyboardSurfaceCallbackData;
|
typedef struct _CreateKeyboardSurfaceCallbackData CreateKeyboardSurfaceCallbackData;
|
||||||
|
|
||||||
@ -114,7 +110,7 @@ create_keyboard_surface_key_callback (EekElement *element,
|
|||||||
bounds.width + 100,
|
bounds.width + 100,
|
||||||
bounds.height + 100);
|
bounds.height + 100);
|
||||||
cairo_clip (data->cr);
|
cairo_clip (data->cr);
|
||||||
render_key (data->renderer, data->cr, EEK_KEY(element), FALSE);
|
render_key (data->renderer, data->cr, EEK_KEY(element), data->level, FALSE);
|
||||||
|
|
||||||
cairo_restore (data->cr);
|
cairo_restore (data->cr);
|
||||||
}
|
}
|
||||||
@ -152,7 +148,7 @@ render_keyboard_surface (EekRenderer *renderer)
|
|||||||
|
|
||||||
eek_renderer_get_foreground_color (renderer, priv->scontext, &foreground);
|
eek_renderer_get_foreground_color (renderer, priv->scontext, &foreground);
|
||||||
|
|
||||||
eek_element_get_bounds (EEK_ELEMENT(priv->keyboard), &bounds);
|
eek_element_get_bounds (EEK_ELEMENT(level_keyboard_current(priv->keyboard)), &bounds);
|
||||||
|
|
||||||
data.cr = cairo_create (priv->keyboard_surface);
|
data.cr = cairo_create (priv->keyboard_surface);
|
||||||
data.renderer = renderer;
|
data.renderer = renderer;
|
||||||
@ -177,8 +173,9 @@ render_keyboard_surface (EekRenderer *renderer)
|
|||||||
foreground.blue,
|
foreground.blue,
|
||||||
foreground.alpha);
|
foreground.alpha);
|
||||||
|
|
||||||
|
data.level = priv->keyboard->level;
|
||||||
/* draw sections */
|
/* draw sections */
|
||||||
eek_container_foreach_child (EEK_CONTAINER(priv->keyboard),
|
eek_container_foreach_child (EEK_CONTAINER(level_keyboard_current(priv->keyboard)),
|
||||||
create_keyboard_surface_section_callback,
|
create_keyboard_surface_section_callback,
|
||||||
&data);
|
&data);
|
||||||
cairo_restore (data.cr);
|
cairo_restore (data.cr);
|
||||||
@ -198,7 +195,7 @@ render_key_outline (EekRenderer *renderer,
|
|||||||
guint oref;
|
guint oref;
|
||||||
|
|
||||||
oref = eek_key_get_oref (key);
|
oref = eek_key_get_oref (key);
|
||||||
outline = eek_keyboard_get_outline (priv->keyboard, oref);
|
outline = level_keyboard_get_outline (priv->keyboard, oref);
|
||||||
if (outline == NULL)
|
if (outline == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -218,6 +215,7 @@ static void
|
|||||||
render_key (EekRenderer *self,
|
render_key (EekRenderer *self,
|
||||||
cairo_t *cr,
|
cairo_t *cr,
|
||||||
EekKey *key,
|
EekKey *key,
|
||||||
|
guint level,
|
||||||
gboolean active)
|
gboolean active)
|
||||||
{
|
{
|
||||||
EekRendererPrivate *priv = eek_renderer_get_instance_private (self);
|
EekRendererPrivate *priv = eek_renderer_get_instance_private (self);
|
||||||
@ -225,17 +223,14 @@ render_key (EekRenderer *self,
|
|||||||
cairo_surface_t *outline_surface;
|
cairo_surface_t *outline_surface;
|
||||||
EekBounds bounds;
|
EekBounds bounds;
|
||||||
guint oref;
|
guint oref;
|
||||||
EekSymbol *symbol;
|
struct squeek_symbol *symbol;
|
||||||
GHashTable *outline_surface_cache;
|
GHashTable *outline_surface_cache;
|
||||||
PangoLayout *layout;
|
PangoLayout *layout;
|
||||||
PangoRectangle extents = { 0, };
|
PangoRectangle extents = { 0, };
|
||||||
EekColor foreground;
|
EekColor foreground;
|
||||||
|
|
||||||
if (!eek_key_has_label(key))
|
|
||||||
return;
|
|
||||||
|
|
||||||
oref = eek_key_get_oref (key);
|
oref = eek_key_get_oref (key);
|
||||||
outline = eek_keyboard_get_outline (priv->keyboard, oref);
|
outline = level_keyboard_get_outline (priv->keyboard, oref);
|
||||||
if (outline == NULL)
|
if (outline == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -280,15 +275,15 @@ render_key (EekRenderer *self,
|
|||||||
|
|
||||||
eek_renderer_get_foreground_color (self, priv->key_context, &foreground);
|
eek_renderer_get_foreground_color (self, priv->key_context, &foreground);
|
||||||
/* render icon (if any) */
|
/* render icon (if any) */
|
||||||
symbol = eek_key_get_symbol_with_fallback (key, 0, 0);
|
symbol = eek_key_get_symbol_at_index (key, 0, level);
|
||||||
if (!symbol)
|
if (!symbol)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (eek_symbol_get_icon_name (symbol)) {
|
if (squeek_symbol_get_icon_name (symbol)) {
|
||||||
gint scale = priv->scale_factor;
|
gint scale = priv->scale_factor;
|
||||||
cairo_surface_t *icon_surface =
|
cairo_surface_t *icon_surface =
|
||||||
eek_renderer_get_icon_surface (self,
|
eek_renderer_get_icon_surface (self,
|
||||||
eek_symbol_get_icon_name (symbol),
|
squeek_symbol_get_icon_name (symbol),
|
||||||
16 / priv->scale,
|
16 / priv->scale,
|
||||||
scale);
|
scale);
|
||||||
if (icon_surface) {
|
if (icon_surface) {
|
||||||
@ -316,7 +311,7 @@ render_key (EekRenderer *self,
|
|||||||
|
|
||||||
/* render label */
|
/* render label */
|
||||||
layout = pango_cairo_create_layout (cr);
|
layout = pango_cairo_create_layout (cr);
|
||||||
eek_renderer_real_render_key_label (self, layout, key);
|
eek_renderer_real_render_key_label (self, layout, key, level);
|
||||||
pango_layout_get_extents (layout, NULL, &extents);
|
pango_layout_get_extents (layout, NULL, &extents);
|
||||||
|
|
||||||
cairo_save (cr);
|
cairo_save (cr);
|
||||||
@ -383,21 +378,22 @@ eek_renderer_apply_transformation_for_key (EekRenderer *self,
|
|||||||
static void
|
static void
|
||||||
eek_renderer_real_render_key_label (EekRenderer *self,
|
eek_renderer_real_render_key_label (EekRenderer *self,
|
||||||
PangoLayout *layout,
|
PangoLayout *layout,
|
||||||
EekKey *key)
|
EekKey *key,
|
||||||
|
guint level)
|
||||||
{
|
{
|
||||||
EekRendererPrivate *priv = eek_renderer_get_instance_private (self);
|
EekRendererPrivate *priv = eek_renderer_get_instance_private (self);
|
||||||
EekSymbol *symbol;
|
struct squeek_symbol *symbol;
|
||||||
const gchar *label;
|
const gchar *label;
|
||||||
EekBounds bounds;
|
EekBounds bounds;
|
||||||
PangoFontDescription *font;
|
PangoFontDescription *font;
|
||||||
PangoLayoutLine *line;
|
PangoLayoutLine *line;
|
||||||
gdouble scale;
|
gdouble scale;
|
||||||
|
|
||||||
symbol = eek_key_get_symbol_with_fallback (key, 0, 0);
|
symbol = eek_key_get_symbol_at_index(key, 0, level);
|
||||||
if (!symbol)
|
if (!symbol)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
label = eek_symbol_get_label (symbol);
|
label = squeek_symbol_get_label (symbol);
|
||||||
if (!label)
|
if (!label)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -464,6 +460,7 @@ static void
|
|||||||
eek_renderer_real_render_key (EekRenderer *self,
|
eek_renderer_real_render_key (EekRenderer *self,
|
||||||
cairo_t *cr,
|
cairo_t *cr,
|
||||||
EekKey *key,
|
EekKey *key,
|
||||||
|
guint level,
|
||||||
gdouble scale,
|
gdouble scale,
|
||||||
gboolean rotate)
|
gboolean rotate)
|
||||||
{
|
{
|
||||||
@ -480,7 +477,7 @@ eek_renderer_real_render_key (EekRenderer *self,
|
|||||||
cairo_translate (cr, bounds.x, bounds.y);
|
cairo_translate (cr, bounds.x, bounds.y);
|
||||||
|
|
||||||
eek_renderer_apply_transformation_for_key (self, cr, key, scale, rotate);
|
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));
|
render_key (self, cr, key, level, eek_key_is_pressed (key) || eek_key_is_locked (key));
|
||||||
cairo_restore (cr);
|
cairo_restore (cr);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -526,15 +523,6 @@ eek_renderer_set_property (GObject *object,
|
|||||||
EEK_RENDERER(object));
|
EEK_RENDERER(object));
|
||||||
|
|
||||||
switch (prop_id) {
|
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:
|
case PROP_PCONTEXT:
|
||||||
priv->pcontext = g_value_get_object (value);
|
priv->pcontext = g_value_get_object (value);
|
||||||
g_object_ref (priv->pcontext);
|
g_object_ref (priv->pcontext);
|
||||||
@ -555,13 +543,7 @@ eek_renderer_get_property (GObject *object,
|
|||||||
GValue *value,
|
GValue *value,
|
||||||
GParamSpec *pspec)
|
GParamSpec *pspec)
|
||||||
{
|
{
|
||||||
EekRendererPrivate *priv = eek_renderer_get_instance_private (
|
|
||||||
EEK_RENDERER(object));
|
|
||||||
|
|
||||||
switch (prop_id) {
|
switch (prop_id) {
|
||||||
case PROP_KEYBOARD:
|
|
||||||
g_value_set_object (value, priv->keyboard);
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
break;
|
break;
|
||||||
@ -575,11 +557,6 @@ eek_renderer_dispose (GObject *object)
|
|||||||
EekRendererPrivate *priv = eek_renderer_get_instance_private (self);
|
EekRendererPrivate *priv = eek_renderer_get_instance_private (self);
|
||||||
|
|
||||||
if (priv->keyboard) {
|
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;
|
priv->keyboard = NULL;
|
||||||
}
|
}
|
||||||
if (priv->pcontext) {
|
if (priv->pcontext) {
|
||||||
@ -623,15 +600,6 @@ eek_renderer_class_init (EekRendererClass *klass)
|
|||||||
gobject_class->dispose = eek_renderer_dispose;
|
gobject_class->dispose = eek_renderer_dispose;
|
||||||
gobject_class->finalize = eek_renderer_finalize;
|
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",
|
pspec = g_param_spec_object ("pango-context",
|
||||||
"Pango Context",
|
"Pango Context",
|
||||||
"Pango Context",
|
"Pango Context",
|
||||||
@ -677,7 +645,6 @@ eek_renderer_init (EekRenderer *self)
|
|||||||
NULL,
|
NULL,
|
||||||
(GDestroyNotify)cairo_surface_destroy);
|
(GDestroyNotify)cairo_surface_destroy);
|
||||||
priv->keyboard_surface = NULL;
|
priv->keyboard_surface = NULL;
|
||||||
priv->symbol_index_changed_handler = 0;
|
|
||||||
|
|
||||||
GtkIconTheme *theme = gtk_icon_theme_get_default ();
|
GtkIconTheme *theme = gtk_icon_theme_get_default ();
|
||||||
|
|
||||||
@ -723,26 +690,18 @@ 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 *
|
EekRenderer *
|
||||||
eek_renderer_new (EekKeyboard *keyboard,
|
eek_renderer_new (LevelKeyboard *keyboard,
|
||||||
PangoContext *pcontext,
|
PangoContext *pcontext,
|
||||||
GtkStyleContext *scontext)
|
GtkStyleContext *scontext)
|
||||||
{
|
{
|
||||||
return g_object_new (EEK_TYPE_RENDERER,
|
EekRenderer *renderer = g_object_new (EEK_TYPE_RENDERER,
|
||||||
"keyboard", keyboard,
|
|
||||||
"pango-context", pcontext,
|
"pango-context", pcontext,
|
||||||
"style-context", scontext,
|
"style-context", scontext,
|
||||||
NULL);
|
NULL);
|
||||||
|
EekRendererPrivate *priv = eek_renderer_get_instance_private (renderer);
|
||||||
|
priv->keyboard = keyboard;
|
||||||
|
return renderer;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -763,7 +722,7 @@ eek_renderer_set_allocation_size (EekRenderer *renderer,
|
|||||||
|
|
||||||
/* Calculate a scale factor to use when rendering the keyboard into the
|
/* Calculate a scale factor to use when rendering the keyboard into the
|
||||||
available space. */
|
available space. */
|
||||||
eek_element_get_bounds (EEK_ELEMENT(priv->keyboard), &bounds);
|
eek_element_get_bounds (EEK_ELEMENT(level_keyboard_current(priv->keyboard)), &bounds);
|
||||||
|
|
||||||
gdouble w = (bounds.x * 2) + bounds.width;
|
gdouble w = (bounds.x * 2) + bounds.width;
|
||||||
gdouble h = (bounds.y * 2) + bounds.height;
|
gdouble h = (bounds.y * 2) + bounds.height;
|
||||||
@ -788,7 +747,7 @@ eek_renderer_get_size (EekRenderer *renderer,
|
|||||||
|
|
||||||
EekRendererPrivate *priv = eek_renderer_get_instance_private (renderer);
|
EekRendererPrivate *priv = eek_renderer_get_instance_private (renderer);
|
||||||
|
|
||||||
eek_element_get_bounds (EEK_ELEMENT(priv->keyboard), &bounds);
|
eek_element_get_bounds (EEK_ELEMENT(level_keyboard_current(priv->keyboard)), &bounds);
|
||||||
if (width)
|
if (width)
|
||||||
*width = bounds.width;
|
*width = bounds.width;
|
||||||
if (height)
|
if (height)
|
||||||
@ -816,7 +775,7 @@ eek_renderer_get_key_bounds (EekRenderer *renderer,
|
|||||||
|
|
||||||
eek_element_get_bounds (EEK_ELEMENT(key), bounds);
|
eek_element_get_bounds (EEK_ELEMENT(key), bounds);
|
||||||
eek_element_get_bounds (section, §ion_bounds);
|
eek_element_get_bounds (section, §ion_bounds);
|
||||||
eek_element_get_bounds (EEK_ELEMENT(priv->keyboard),
|
eek_element_get_bounds (EEK_ELEMENT(level_keyboard_current(priv->keyboard)),
|
||||||
&keyboard_bounds);
|
&keyboard_bounds);
|
||||||
|
|
||||||
if (!rotate) {
|
if (!rotate) {
|
||||||
@ -940,6 +899,7 @@ void
|
|||||||
eek_renderer_render_key (EekRenderer *renderer,
|
eek_renderer_render_key (EekRenderer *renderer,
|
||||||
cairo_t *cr,
|
cairo_t *cr,
|
||||||
EekKey *key,
|
EekKey *key,
|
||||||
|
guint level,
|
||||||
gdouble scale,
|
gdouble scale,
|
||||||
gboolean rotate)
|
gboolean rotate)
|
||||||
{
|
{
|
||||||
@ -948,7 +908,7 @@ eek_renderer_render_key (EekRenderer *renderer,
|
|||||||
g_return_if_fail (scale >= 0.0);
|
g_return_if_fail (scale >= 0.0);
|
||||||
|
|
||||||
EEK_RENDERER_GET_CLASS(renderer)->
|
EEK_RENDERER_GET_CLASS(renderer)->
|
||||||
render_key (renderer, cr, key, scale, rotate);
|
render_key (renderer, cr, key, level, scale, rotate);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -1106,7 +1066,7 @@ eek_renderer_find_key_by_position (EekRenderer *renderer,
|
|||||||
g_return_val_if_fail (EEK_IS_RENDERER(renderer), NULL);
|
g_return_val_if_fail (EEK_IS_RENDERER(renderer), NULL);
|
||||||
|
|
||||||
EekRendererPrivate *priv = eek_renderer_get_instance_private (renderer);
|
EekRendererPrivate *priv = eek_renderer_get_instance_private (renderer);
|
||||||
eek_element_get_bounds (EEK_ELEMENT(priv->keyboard), &bounds);
|
eek_element_get_bounds (EEK_ELEMENT(level_keyboard_current(priv->keyboard)), &bounds);
|
||||||
|
|
||||||
/* Transform from widget coordinates to keyboard coordinates */
|
/* Transform from widget coordinates to keyboard coordinates */
|
||||||
x = (x - priv->origin_x)/priv->scale - bounds.x;
|
x = (x - priv->origin_x)/priv->scale - bounds.x;
|
||||||
@ -1125,7 +1085,7 @@ eek_renderer_find_key_by_position (EekRenderer *renderer,
|
|||||||
data.key = NULL;
|
data.key = NULL;
|
||||||
data.renderer = renderer;
|
data.renderer = renderer;
|
||||||
|
|
||||||
eek_container_find (EEK_CONTAINER(priv->keyboard),
|
eek_container_find (EEK_CONTAINER(level_keyboard_current(priv->keyboard)),
|
||||||
find_key_by_position_section_callback,
|
find_key_by_position_section_callback,
|
||||||
&data);
|
&data);
|
||||||
return data.key;
|
return data.key;
|
||||||
|
|||||||
@ -21,9 +21,10 @@
|
|||||||
#ifndef EEK_RENDERER_H
|
#ifndef EEK_RENDERER_H
|
||||||
#define EEK_RENDERER_H 1
|
#define EEK_RENDERER_H 1
|
||||||
|
|
||||||
|
#include <gtk/gtk.h>
|
||||||
#include <pango/pangocairo.h>
|
#include <pango/pangocairo.h>
|
||||||
|
|
||||||
#include "eek-keyboard.h"
|
#include "eek-keyboard.h"
|
||||||
#include "eek-keysym.h"
|
|
||||||
#include "eek-types.h"
|
#include "eek-types.h"
|
||||||
|
|
||||||
G_BEGIN_DECLS
|
G_BEGIN_DECLS
|
||||||
@ -44,6 +45,7 @@ struct _EekRendererClass
|
|||||||
void (* render_key) (EekRenderer *self,
|
void (* render_key) (EekRenderer *self,
|
||||||
cairo_t *cr,
|
cairo_t *cr,
|
||||||
EekKey *key,
|
EekKey *key,
|
||||||
|
guint level,
|
||||||
gdouble scale,
|
gdouble scale,
|
||||||
gboolean rotate);
|
gboolean rotate);
|
||||||
|
|
||||||
@ -61,7 +63,7 @@ struct _EekRendererClass
|
|||||||
};
|
};
|
||||||
|
|
||||||
GType eek_renderer_get_type (void) G_GNUC_CONST;
|
GType eek_renderer_get_type (void) G_GNUC_CONST;
|
||||||
EekRenderer *eek_renderer_new (EekKeyboard *keyboard,
|
EekRenderer *eek_renderer_new (LevelKeyboard *keyboard,
|
||||||
PangoContext *pcontext,
|
PangoContext *pcontext,
|
||||||
GtkStyleContext *scontext);
|
GtkStyleContext *scontext);
|
||||||
void eek_renderer_set_allocation_size
|
void eek_renderer_set_allocation_size
|
||||||
@ -95,7 +97,7 @@ void eek_renderer_render_key_outline
|
|||||||
|
|
||||||
void eek_renderer_render_key (EekRenderer *renderer,
|
void eek_renderer_render_key (EekRenderer *renderer,
|
||||||
cairo_t *cr,
|
cairo_t *cr,
|
||||||
EekKey *key,
|
EekKey *key, guint level,
|
||||||
gdouble scale,
|
gdouble scale,
|
||||||
gboolean rotate);
|
gboolean rotate);
|
||||||
|
|
||||||
|
|||||||
@ -32,9 +32,9 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "eek-keyboard.h"
|
#include "eek-keyboard.h"
|
||||||
#include "eek-section.h"
|
|
||||||
#include "eek-key.h"
|
#include "eek-key.h"
|
||||||
#include "eek-symbol.h"
|
|
||||||
|
#include "eek-section.h"
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
PROP_0,
|
PROP_0,
|
||||||
@ -121,7 +121,8 @@ on_unlocked (EekKey *key,
|
|||||||
static EekKey *
|
static EekKey *
|
||||||
eek_section_real_create_key (EekSection *self,
|
eek_section_real_create_key (EekSection *self,
|
||||||
const gchar *name,
|
const gchar *name,
|
||||||
gint keycode)
|
gint keycode,
|
||||||
|
guint oref)
|
||||||
{
|
{
|
||||||
EekSectionPrivate *priv = (EekSectionPrivate*)eek_section_get_instance_private (self);
|
EekSectionPrivate *priv = (EekSectionPrivate*)eek_section_get_instance_private (self);
|
||||||
|
|
||||||
@ -130,9 +131,10 @@ eek_section_real_create_key (EekSection *self,
|
|||||||
|
|
||||||
EekKey *key = (EekKey*)g_object_new (EEK_TYPE_KEY,
|
EekKey *key = (EekKey*)g_object_new (EEK_TYPE_KEY,
|
||||||
"name", name,
|
"name", name,
|
||||||
"keycode", keycode,
|
|
||||||
NULL);
|
NULL);
|
||||||
g_return_val_if_fail (key, NULL);
|
g_return_val_if_fail (key, NULL);
|
||||||
|
eek_key_set_keycode(key, keycode);
|
||||||
|
eek_key_set_oref(key, oref);
|
||||||
|
|
||||||
EEK_CONTAINER_GET_CLASS(self)->add_child (EEK_CONTAINER(self),
|
EEK_CONTAINER_GET_CLASS(self)->add_child (EEK_CONTAINER(self),
|
||||||
EEK_ELEMENT(key));
|
EEK_ELEMENT(key));
|
||||||
@ -140,79 +142,28 @@ eek_section_real_create_key (EekSection *self,
|
|||||||
return key;
|
return key;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
EekKey *eek_section_create_button(EekSection *self,
|
||||||
set_level_from_modifiers (EekSection *self)
|
const gchar *name,
|
||||||
{
|
struct squeek_key *state) {
|
||||||
EekSectionPrivate *priv = eek_section_get_instance_private (self);
|
EekSectionPrivate *priv = (EekSectionPrivate*)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)));
|
EekRow *row = &priv->row;
|
||||||
num_lock_mask = eek_keyboard_get_num_lock_mask (keyboard);
|
row->num_columns++;
|
||||||
if (priv->modifiers & num_lock_mask)
|
|
||||||
level = 1;
|
|
||||||
eek_element_set_level (EEK_ELEMENT(self), level);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
EekKey *key = (EekKey*)g_object_new (EEK_TYPE_KEY,
|
||||||
eek_section_real_key_pressed (EekSection *self, EekKey *key)
|
"name", name,
|
||||||
{
|
NULL);
|
||||||
EekSectionPrivate *priv = eek_section_get_instance_private (self);
|
g_return_val_if_fail (key, NULL);
|
||||||
EekSymbol *symbol;
|
eek_key_share_state(key, state);
|
||||||
EekKeyboard *keyboard;
|
|
||||||
EekModifierBehavior behavior;
|
|
||||||
EekModifierType modifier;
|
|
||||||
|
|
||||||
symbol = eek_key_get_symbol_with_fallback (key, 0, 0);
|
EEK_CONTAINER_GET_CLASS(self)->add_child (EEK_CONTAINER(self),
|
||||||
if (!symbol)
|
EEK_ELEMENT(key));
|
||||||
return;
|
return key;
|
||||||
|
|
||||||
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
|
static void
|
||||||
eek_section_finalize (GObject *object)
|
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);
|
G_OBJECT_CLASS (eek_section_parent_class)->finalize (object);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -278,9 +229,6 @@ eek_section_class_init (EekSectionClass *klass)
|
|||||||
klass->create_key = eek_section_real_create_key;
|
klass->create_key = eek_section_real_create_key;
|
||||||
|
|
||||||
/* signals */
|
/* 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_added = eek_section_real_child_added;
|
||||||
container_class->child_removed = eek_section_real_child_removed;
|
container_class->child_removed = eek_section_real_child_removed;
|
||||||
|
|
||||||
@ -456,12 +404,13 @@ eek_section_get_row (EekSection *section,
|
|||||||
EekKey *
|
EekKey *
|
||||||
eek_section_create_key (EekSection *section,
|
eek_section_create_key (EekSection *section,
|
||||||
const gchar *name,
|
const gchar *name,
|
||||||
gint keycode)
|
guint keycode,
|
||||||
|
guint oref)
|
||||||
{
|
{
|
||||||
g_return_val_if_fail (EEK_IS_SECTION(section), NULL);
|
g_return_val_if_fail (EEK_IS_SECTION(section), NULL);
|
||||||
return EEK_SECTION_GET_CLASS(section)->create_key (section,
|
return eek_section_real_create_key (section,
|
||||||
name,
|
name,
|
||||||
keycode);
|
keycode, oref);
|
||||||
}
|
}
|
||||||
|
|
||||||
const double keyspacing = 4.0;
|
const double keyspacing = 4.0;
|
||||||
@ -477,9 +426,9 @@ keysizer(EekElement *element, gpointer user_data)
|
|||||||
{
|
{
|
||||||
EekKey *key = EEK_KEY(element);
|
EekKey *key = EEK_KEY(element);
|
||||||
|
|
||||||
EekKeyboard *keyboard = EEK_KEYBOARD(user_data);
|
LevelKeyboard *keyboard = user_data;
|
||||||
uint oref = eek_key_get_oref (key);
|
uint oref = eek_key_get_oref (key);
|
||||||
EekOutline *outline = eek_keyboard_get_outline (keyboard, oref);
|
EekOutline *outline = level_keyboard_get_outline (keyboard, oref);
|
||||||
if (outline && outline->num_points > 0) {
|
if (outline && outline->num_points > 0) {
|
||||||
double minx = outline->points[0].x;
|
double minx = outline->points[0].x;
|
||||||
double maxx = minx;
|
double maxx = minx;
|
||||||
@ -512,11 +461,6 @@ keycounter (EekElement *element, gpointer user_data)
|
|||||||
{
|
{
|
||||||
EekKey *key = EEK_KEY(element);
|
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;
|
struct keys_info *data = user_data;
|
||||||
data->count++;
|
data->count++;
|
||||||
EekBounds key_bounds = {0};
|
EekBounds key_bounds = {0};
|
||||||
@ -532,10 +476,6 @@ keyplacer(EekElement *element, gpointer user_data)
|
|||||||
{
|
{
|
||||||
EekKey *key = EEK_KEY(element);
|
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;
|
double *current_offset = user_data;
|
||||||
EekBounds key_bounds = {0};
|
EekBounds key_bounds = {0};
|
||||||
eek_element_get_bounds(element, &key_bounds);
|
eek_element_get_bounds(element, &key_bounds);
|
||||||
@ -546,7 +486,7 @@ keyplacer(EekElement *element, gpointer user_data)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
eek_section_place_keys(EekSection *section, EekKeyboard *keyboard)
|
eek_section_place_keys(EekSection *section, LevelKeyboard *keyboard)
|
||||||
{
|
{
|
||||||
eek_container_foreach_child(EEK_CONTAINER(section), keysizer, keyboard);
|
eek_container_foreach_child(EEK_CONTAINER(section), keysizer, keyboard);
|
||||||
|
|
||||||
|
|||||||
@ -28,6 +28,8 @@
|
|||||||
#include <glib-object.h>
|
#include <glib-object.h>
|
||||||
#include "eek-container.h"
|
#include "eek-container.h"
|
||||||
#include "eek-types.h"
|
#include "eek-types.h"
|
||||||
|
#include "eek-keyboard.h"
|
||||||
|
#include "src/keyboard.h"
|
||||||
|
|
||||||
G_BEGIN_DECLS
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
@ -66,10 +68,6 @@ struct _EekSectionClass
|
|||||||
gint keycode);
|
gint keycode);
|
||||||
|
|
||||||
/* signals */
|
/* signals */
|
||||||
void (* key_pressed) (EekSection *self,
|
|
||||||
EekKey *key);
|
|
||||||
void (* key_released) (EekSection *self,
|
|
||||||
EekKey *key);
|
|
||||||
void (* key_locked) (EekSection *self,
|
void (* key_locked) (EekSection *self,
|
||||||
EekKey *key);
|
EekKey *key);
|
||||||
void (* key_unlocked) (EekSection *self,
|
void (* key_unlocked) (EekSection *self,
|
||||||
@ -99,12 +97,11 @@ void eek_section_get_row (EekSection *section,
|
|||||||
|
|
||||||
EekKey *eek_section_create_key (EekSection *section,
|
EekKey *eek_section_create_key (EekSection *section,
|
||||||
const gchar *name,
|
const gchar *name,
|
||||||
gint keycode);
|
guint keycode, guint oref);
|
||||||
|
EekKey *eek_section_create_button(EekSection *self,
|
||||||
EekKey *eek_section_find_key_by_keycode (EekSection *section,
|
const gchar *name,
|
||||||
guint keycode);
|
struct squeek_key *state);
|
||||||
|
void eek_section_place_keys (EekSection *section, LevelKeyboard *keyboard);
|
||||||
void eek_section_place_keys (EekSection *section, EekKeyboard *keyboard);
|
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
#endif /* EEK_SECTION_H */
|
#endif /* EEK_SECTION_H */
|
||||||
|
|||||||
@ -1,99 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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];
|
|
||||||
}
|
|
||||||
@ -1,62 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2011 Daiki Ueno <ueno@unixuser.org>
|
|
||||||
* Copyright (C) 2011 Red Hat, Inc.
|
|
||||||
*
|
|
||||||
* This library is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of the GNU Lesser General Public License
|
|
||||||
* as published by the Free Software Foundation; either version 2 of
|
|
||||||
* the License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This library is distributed in the hope that it will be useful, but
|
|
||||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
* Lesser General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public
|
|
||||||
* License along with this library; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
|
||||||
* 02110-1301 USA
|
|
||||||
*/
|
|
||||||
#ifndef EEK_SYMBOL_MATRIX_H
|
|
||||||
#define EEK_SYMBOL_MATRIX_H 1
|
|
||||||
|
|
||||||
#include "eek-symbol.h"
|
|
||||||
|
|
||||||
G_BEGIN_DECLS
|
|
||||||
|
|
||||||
/**
|
|
||||||
* EekSymbolMatrix:
|
|
||||||
* @data: array of symbols
|
|
||||||
* @num_groups: the number of groups (rows)
|
|
||||||
* @num_levels: the number of levels (columns)
|
|
||||||
*
|
|
||||||
* Symbol matrix of a key.
|
|
||||||
*/
|
|
||||||
struct _EekSymbolMatrix
|
|
||||||
{
|
|
||||||
/*< public >*/
|
|
||||||
gint num_groups;
|
|
||||||
gint num_levels;
|
|
||||||
EekSymbol **data;
|
|
||||||
};
|
|
||||||
|
|
||||||
#define EEK_TYPE_SYMBOL_MATRIX (eek_symbol_matrix_get_type ())
|
|
||||||
GType eek_symbol_matrix_get_type (void) G_GNUC_CONST;
|
|
||||||
EekSymbolMatrix *eek_symbol_matrix_new (gint num_groups,
|
|
||||||
gint num_levels);
|
|
||||||
EekSymbolMatrix *eek_symbol_matrix_copy (const EekSymbolMatrix *matrix);
|
|
||||||
void eek_symbol_matrix_free (EekSymbolMatrix *matrix);
|
|
||||||
|
|
||||||
void eek_symbol_matrix_set_symbol
|
|
||||||
(EekSymbolMatrix *matrix,
|
|
||||||
gint group,
|
|
||||||
gint level,
|
|
||||||
EekSymbol *symbol);
|
|
||||||
EekSymbol *eek_symbol_matrix_get_symbol
|
|
||||||
(EekSymbolMatrix *matrix,
|
|
||||||
gint group,
|
|
||||||
gint level);
|
|
||||||
|
|
||||||
G_END_DECLS
|
|
||||||
|
|
||||||
#endif /* EEK_SYMBOL_MATRIX_H */
|
|
||||||
@ -30,42 +30,15 @@
|
|||||||
#include "eek-symbol.h"
|
#include "eek-symbol.h"
|
||||||
#include "eek-enumtypes.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 *
|
EekSymbol *
|
||||||
eek_symbol_new (const gchar *name)
|
eek_symbol_new (const gchar *name)
|
||||||
{
|
{
|
||||||
EekSymbol *self = g_new0(EekSymbol, 1);
|
EekSymbol *self = g_new0(EekSymbol, 1);
|
||||||
eek_symbol_set_name(self, name);
|
self->name = g_strdup (name);
|
||||||
self->category = EEK_SYMBOL_CATEGORY_UNKNOWN;
|
self->category = EEK_SYMBOL_CATEGORY_UNKNOWN;
|
||||||
return self;
|
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:
|
* eek_symbol_set_label:
|
||||||
* @symbol: an #EekSymbol
|
* @symbol: an #EekSymbol
|
||||||
@ -81,20 +54,6 @@ eek_symbol_set_label (EekSymbol *symbol,
|
|||||||
symbol->label = g_strdup (label);
|
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:
|
* eek_symbol_set_modifier_mask:
|
||||||
* @symbol: an #EekSymbol
|
* @symbol: an #EekSymbol
|
||||||
@ -118,15 +77,10 @@ eek_symbol_set_modifier_mask (EekSymbol *symbol,
|
|||||||
EekModifierType
|
EekModifierType
|
||||||
eek_symbol_get_modifier_mask (EekSymbol *symbol)
|
eek_symbol_get_modifier_mask (EekSymbol *symbol)
|
||||||
{
|
{
|
||||||
|
return 0;
|
||||||
return symbol->modifier_mask;
|
return symbol->modifier_mask;
|
||||||
}
|
}
|
||||||
|
|
||||||
gboolean
|
|
||||||
eek_symbol_is_modifier (EekSymbol *symbol)
|
|
||||||
{
|
|
||||||
return eek_symbol_get_modifier_mask (symbol) != 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
eek_symbol_set_icon_name (EekSymbol *symbol,
|
eek_symbol_set_icon_name (EekSymbol *symbol,
|
||||||
const gchar *icon_name)
|
const gchar *icon_name)
|
||||||
@ -138,9 +92,7 @@ eek_symbol_set_icon_name (EekSymbol *symbol,
|
|||||||
const gchar *
|
const gchar *
|
||||||
eek_symbol_get_icon_name (EekSymbol *symbol)
|
eek_symbol_get_icon_name (EekSymbol *symbol)
|
||||||
{
|
{
|
||||||
if (symbol->icon_name == NULL || *symbol->icon_name == '\0')
|
return NULL;
|
||||||
return NULL;
|
|
||||||
return symbol->icon_name;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -154,6 +106,7 @@ eek_symbol_set_tooltip (EekSymbol *symbol,
|
|||||||
const gchar *
|
const gchar *
|
||||||
eek_symbol_get_tooltip (EekSymbol *symbol)
|
eek_symbol_get_tooltip (EekSymbol *symbol)
|
||||||
{
|
{
|
||||||
|
return NULL;
|
||||||
if (symbol->tooltip == NULL || *symbol->tooltip == '\0')
|
if (symbol->tooltip == NULL || *symbol->tooltip == '\0')
|
||||||
return NULL;
|
return NULL;
|
||||||
return symbol->tooltip;
|
return symbol->tooltip;
|
||||||
|
|||||||
107
eek/eek-symbol.h
107
eek/eek-symbol.h
@ -1,107 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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 */
|
|
||||||
@ -150,6 +150,7 @@ typedef struct _EekOutline EekOutline;
|
|||||||
typedef struct _EekColor EekColor;
|
typedef struct _EekColor EekColor;
|
||||||
|
|
||||||
typedef struct _EekboardContextService EekboardContextService;
|
typedef struct _EekboardContextService EekboardContextService;
|
||||||
|
typedef struct _LevelKeyboard LevelKeyboard;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* EekPoint:
|
* EekPoint:
|
||||||
|
|||||||
@ -27,15 +27,16 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "eek-xml-layout.h"
|
|
||||||
#include "eek-keyboard.h"
|
#include "eek-keyboard.h"
|
||||||
#include "eek-section.h"
|
#include "eek-section.h"
|
||||||
#include "eek-key.h"
|
#include "eek-key.h"
|
||||||
#include "eek-keysym.h"
|
#include "src/keyboard.h"
|
||||||
#include "eek-text.h"
|
#include "src/symbol.h"
|
||||||
|
|
||||||
#include "squeekboard-resources.h"
|
#include "squeekboard-resources.h"
|
||||||
|
|
||||||
|
#include "eek-xml-layout.h"
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
PROP_0,
|
PROP_0,
|
||||||
PROP_ID,
|
PROP_ID,
|
||||||
@ -67,16 +68,16 @@ static GList *parse_prerequisites
|
|||||||
(const gchar *path,
|
(const gchar *path,
|
||||||
GError **error);
|
GError **error);
|
||||||
static gboolean parse_geometry (const gchar *path,
|
static gboolean parse_geometry (const gchar *path,
|
||||||
EekKeyboard *keyboard,
|
EekKeyboard **views, GArray *outline_array, GHashTable *name_key_hash,
|
||||||
GError **error);
|
GError **error);
|
||||||
static gboolean parse_symbols_with_prerequisites
|
static gboolean parse_symbols_with_prerequisites
|
||||||
(const gchar *keyboards_dir,
|
(const gchar *keyboards_dir,
|
||||||
const gchar *name,
|
const gchar *name,
|
||||||
EekKeyboard *keyboard,
|
LevelKeyboard *keyboard,
|
||||||
GList **loaded,
|
GList **loaded,
|
||||||
GError **error);
|
GError **error);
|
||||||
static gboolean parse_symbols (const gchar *path,
|
static gboolean parse_symbols (const gchar *path,
|
||||||
EekKeyboard *keyboard,
|
LevelKeyboard *keyboard,
|
||||||
GError **error);
|
GError **error);
|
||||||
|
|
||||||
static gboolean validate (const gchar **valid_path_list,
|
static gboolean validate (const gchar **valid_path_list,
|
||||||
@ -232,40 +233,49 @@ struct _GeometryParseData {
|
|||||||
GSList *element_stack;
|
GSList *element_stack;
|
||||||
|
|
||||||
EekBounds bounds;
|
EekBounds bounds;
|
||||||
EekKeyboard *keyboard;
|
EekKeyboard **views;
|
||||||
|
guint view_idx;
|
||||||
EekSection *section;
|
EekSection *section;
|
||||||
EekKey *key;
|
EekKey *key;
|
||||||
gint num_columns;
|
|
||||||
gint num_rows;
|
gint num_rows;
|
||||||
EekOrientation orientation;
|
EekOrientation orientation;
|
||||||
gdouble corner_radius;
|
gdouble corner_radius;
|
||||||
GSList *points;
|
GSList *points;
|
||||||
gchar *name;
|
gchar *name;
|
||||||
EekOutline outline;
|
EekOutline outline;
|
||||||
gchar *oref;
|
gchar *outline_id;
|
||||||
gint keycode;
|
guint keycode;
|
||||||
|
|
||||||
GHashTable *key_oref_hash;
|
GString *text;
|
||||||
GHashTable *oref_outline_hash;
|
|
||||||
|
GArray *outline_array;
|
||||||
|
|
||||||
|
GHashTable *name_key_hash; // char* -> EekKey*
|
||||||
|
GHashTable *keyname_oref_hash; // char* -> guint
|
||||||
|
GHashTable *outlineid_oref_hash; // char* -> guint
|
||||||
};
|
};
|
||||||
typedef struct _GeometryParseData GeometryParseData;
|
typedef struct _GeometryParseData GeometryParseData;
|
||||||
|
|
||||||
static GeometryParseData *
|
static GeometryParseData *
|
||||||
geometry_parse_data_new (EekKeyboard *keyboard)
|
geometry_parse_data_new (EekKeyboard **views, GHashTable *name_key_hash, GArray *outline_array)
|
||||||
{
|
{
|
||||||
GeometryParseData *data = g_slice_new0 (GeometryParseData);
|
GeometryParseData *data = g_slice_new0 (GeometryParseData);
|
||||||
|
|
||||||
data->keyboard = g_object_ref (keyboard);
|
data->views = views;
|
||||||
data->key_oref_hash =
|
data->outline_array = outline_array;
|
||||||
g_hash_table_new_full (g_direct_hash,
|
data->keyname_oref_hash =
|
||||||
g_direct_equal,
|
|
||||||
NULL,
|
|
||||||
g_free);
|
|
||||||
data->oref_outline_hash =
|
|
||||||
g_hash_table_new_full (g_str_hash,
|
g_hash_table_new_full (g_str_hash,
|
||||||
g_str_equal,
|
g_str_equal,
|
||||||
g_free,
|
g_free,
|
||||||
(GDestroyNotify)eek_outline_free);
|
NULL);
|
||||||
|
data->outlineid_oref_hash =
|
||||||
|
g_hash_table_new_full (g_str_hash,
|
||||||
|
g_str_equal,
|
||||||
|
g_free,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
data->name_key_hash = name_key_hash;
|
||||||
|
data->text = g_string_sized_new (BUFSIZE);
|
||||||
data->keycode = 8;
|
data->keycode = 8;
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
@ -273,21 +283,19 @@ geometry_parse_data_new (EekKeyboard *keyboard)
|
|||||||
static void
|
static void
|
||||||
geometry_parse_data_free (GeometryParseData *data)
|
geometry_parse_data_free (GeometryParseData *data)
|
||||||
{
|
{
|
||||||
g_object_unref (data->keyboard);
|
g_hash_table_destroy (data->keyname_oref_hash);
|
||||||
g_hash_table_destroy (data->key_oref_hash);
|
g_hash_table_destroy (data->outlineid_oref_hash);
|
||||||
g_hash_table_destroy (data->oref_outline_hash);
|
g_string_free (data->text, TRUE);
|
||||||
g_slice_free (GeometryParseData, data);
|
g_slice_free (GeometryParseData, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const gchar *geometry_valid_path_list[] = {
|
static const gchar *geometry_valid_path_list[] = {
|
||||||
"geometry",
|
"geometry",
|
||||||
|
"button/geometry",
|
||||||
"bounds/geometry",
|
"bounds/geometry",
|
||||||
"section/geometry",
|
"view/geometry",
|
||||||
|
"section/view/geometry",
|
||||||
"outline/geometry",
|
"outline/geometry",
|
||||||
"bounds/section/geometry",
|
|
||||||
"row/section/geometry",
|
|
||||||
"key/row/section/geometry",
|
|
||||||
"bounds/key/row/section/geometry",
|
|
||||||
"point/outline/geometry",
|
"point/outline/geometry",
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -355,14 +363,20 @@ geometry_start_element_callback (GMarkupParseContext *pcontext,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
bounds.height = g_strtod (attribute, NULL);
|
bounds.height = g_strtod (attribute, NULL);
|
||||||
|
data->bounds = bounds;
|
||||||
if (g_strcmp0 (data->element_stack->data, "geometry") == 0)
|
|
||||||
eek_element_set_bounds (EEK_ELEMENT(data->keyboard), &bounds);
|
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (g_strcmp0 (element_name, "view") == 0) {
|
||||||
|
/* Create an empty keyboard to which geometry and symbols
|
||||||
|
information are applied. */
|
||||||
|
EekKeyboard *view = g_object_new (EEK_TYPE_KEYBOARD, NULL);
|
||||||
|
eek_element_set_bounds (EEK_ELEMENT(view), &data->bounds);
|
||||||
|
data->views[data->view_idx] = view;
|
||||||
|
}
|
||||||
|
|
||||||
if (g_strcmp0 (element_name, "section") == 0) {
|
if (g_strcmp0 (element_name, "section") == 0) {
|
||||||
data->section = eek_keyboard_create_section (data->keyboard);
|
data->section = eek_keyboard_real_create_section (data->views[data->view_idx]);
|
||||||
attribute = get_attribute (attribute_names, attribute_values,
|
attribute = get_attribute (attribute_names, attribute_values,
|
||||||
"id");
|
"id");
|
||||||
if (attribute != NULL)
|
if (attribute != NULL)
|
||||||
@ -374,62 +388,47 @@ geometry_start_element_callback (GMarkupParseContext *pcontext,
|
|||||||
angle = strtol (attribute, NULL, 10);
|
angle = strtol (attribute, NULL, 10);
|
||||||
eek_section_set_angle (data->section, angle);
|
eek_section_set_angle (data->section, angle);
|
||||||
}
|
}
|
||||||
|
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (g_strcmp0 (element_name, "row") == 0) {
|
if (g_strcmp0 (element_name, "button") == 0) {
|
||||||
attribute = get_attribute (attribute_names, attribute_values,
|
const gchar *base_name = 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");
|
"name");
|
||||||
if (attribute == NULL) {
|
if (base_name == NULL) {
|
||||||
g_set_error (error,
|
g_set_error (error,
|
||||||
G_MARKUP_ERROR,
|
G_MARKUP_ERROR,
|
||||||
G_MARKUP_ERROR_MISSING_ATTRIBUTE,
|
G_MARKUP_ERROR_MISSING_ATTRIBUTE,
|
||||||
"no \"name\" attribute for \"key\"");
|
"no \"name\" attribute for \"button\"");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
gchar *name = g_strdup (attribute);
|
|
||||||
|
|
||||||
attribute = get_attribute (attribute_names, attribute_values,
|
const gchar *oref_name = get_attribute (attribute_names, attribute_values,
|
||||||
"keycode");
|
|
||||||
if (attribute != NULL)
|
|
||||||
keycode = strtol (attribute, NULL, 10);
|
|
||||||
else
|
|
||||||
keycode = data->keycode++;
|
|
||||||
|
|
||||||
data->key = eek_section_create_key (data->section,
|
|
||||||
name,
|
|
||||||
keycode);
|
|
||||||
|
|
||||||
attribute = get_attribute (attribute_names, attribute_values,
|
|
||||||
"oref");
|
"oref");
|
||||||
if (attribute == NULL) {
|
if (oref_name == NULL) {
|
||||||
g_set_error (error,
|
oref_name = "default";
|
||||||
G_MARKUP_ERROR,
|
|
||||||
G_MARKUP_ERROR_MISSING_ATTRIBUTE,
|
|
||||||
"no \"oref\" attribute for \"key\"");
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
g_hash_table_insert (data->key_oref_hash,
|
const gchar *keycode_name = get_attribute (attribute_names, attribute_values,
|
||||||
data->key,
|
"keycode");
|
||||||
g_strdup (attribute));
|
|
||||||
|
|
||||||
data->num_columns++;
|
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));
|
||||||
|
|
||||||
|
EekKey *key = g_hash_table_lookup(data->name_key_hash, name);
|
||||||
|
// never gets used! this section gets executed before any buttons get defined
|
||||||
|
if (key) {
|
||||||
|
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
|
||||||
|
eek_key_set_keycode(key, strtol (keycode_name, NULL, 10));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
@ -443,7 +442,7 @@ geometry_start_element_callback (GMarkupParseContext *pcontext,
|
|||||||
"no \"id\" attribute for \"outline\"");
|
"no \"id\" attribute for \"outline\"");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
data->oref = g_strdup (attribute);
|
data->outline_id = g_strdup (attribute);
|
||||||
|
|
||||||
attribute = get_attribute (attribute_names, attribute_values,
|
attribute = get_attribute (attribute_names, attribute_values,
|
||||||
"corner-radius");
|
"corner-radius");
|
||||||
@ -488,6 +487,30 @@ geometry_start_element_callback (GMarkupParseContext *pcontext,
|
|||||||
out:
|
out:
|
||||||
data->element_stack = g_slist_prepend (data->element_stack,
|
data->element_stack = g_slist_prepend (data->element_stack,
|
||||||
g_strdup (element_name));
|
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
|
static void
|
||||||
@ -503,23 +526,72 @@ geometry_end_element_callback (GMarkupParseContext *pcontext,
|
|||||||
data->element_stack = g_slist_next (data->element_stack);
|
data->element_stack = g_slist_next (data->element_stack);
|
||||||
g_slist_free1 (head);
|
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++;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (g_strcmp0 (element_name, "section") == 0) {
|
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;
|
||||||
|
|
||||||
|
// 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);
|
||||||
|
EekKey *key = g_hash_table_lookup(data->name_key_hash, name);
|
||||||
|
if (!key) {
|
||||||
|
// 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
|
||||||
|
key = eek_section_create_key (data->section,
|
||||||
|
name,
|
||||||
|
keycode,
|
||||||
|
oref);
|
||||||
|
g_hash_table_insert (data->name_key_hash,
|
||||||
|
g_strdup(name),
|
||||||
|
key);
|
||||||
|
} else {
|
||||||
|
EekKey *new_key = eek_section_create_button(data->section, name, eek_key_get_state(key));
|
||||||
|
if (!new_key) {
|
||||||
|
g_set_error (error,
|
||||||
|
G_MARKUP_ERROR,
|
||||||
|
G_MARKUP_ERROR_MISSING_ATTRIBUTE,
|
||||||
|
"Couldn't create a shared button");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
eek_key_set_oref(new_key, eek_key_get_oref(key));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
data->section = NULL;
|
data->section = NULL;
|
||||||
data->num_rows = 0;
|
data->num_rows = 0;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (g_strcmp0 (element_name, "key") == 0) {
|
|
||||||
data->key = NULL;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (g_strcmp0 (element_name, "row") == 0) {
|
|
||||||
data->num_columns = 0;
|
|
||||||
data->orientation = EEK_ORIENTATION_HORIZONTAL;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (g_strcmp0 (element_name, "outline") == 0) {
|
if (g_strcmp0 (element_name, "outline") == 0) {
|
||||||
EekOutline *outline = g_slice_new (EekOutline);
|
EekOutline *outline = g_slice_new (EekOutline);
|
||||||
|
|
||||||
@ -539,19 +611,30 @@ geometry_end_element_callback (GMarkupParseContext *pcontext,
|
|||||||
g_slist_free (data->points);
|
g_slist_free (data->points);
|
||||||
data->points = NULL;
|
data->points = NULL;
|
||||||
|
|
||||||
g_hash_table_insert (data->oref_outline_hash,
|
guint oref = add_outline (data->outline_array, outline);
|
||||||
g_strdup (data->oref),
|
|
||||||
outline);
|
|
||||||
|
|
||||||
g_free (data->oref);
|
g_hash_table_insert (data->outlineid_oref_hash,
|
||||||
|
data->outline_id,
|
||||||
|
GUINT_TO_POINTER(oref));
|
||||||
return;
|
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 = {
|
static const GMarkupParser geometry_parser = {
|
||||||
geometry_start_element_callback,
|
geometry_start_element_callback,
|
||||||
geometry_end_element_callback,
|
geometry_end_element_callback,
|
||||||
0,
|
geometry_text_callback,
|
||||||
0,
|
0,
|
||||||
0
|
0
|
||||||
};
|
};
|
||||||
@ -560,23 +643,22 @@ struct _SymbolsParseData {
|
|||||||
GSList *element_stack;
|
GSList *element_stack;
|
||||||
GString *text;
|
GString *text;
|
||||||
|
|
||||||
EekKeyboard *keyboard;
|
LevelKeyboard *keyboard;
|
||||||
EekKey *key;
|
EekKeyboard *view;
|
||||||
GSList *symbols;
|
|
||||||
gchar *label;
|
gchar *label;
|
||||||
gchar *icon;
|
gchar *icon;
|
||||||
gchar *tooltip;
|
gchar *tooltip;
|
||||||
guint keyval;
|
guint keyval;
|
||||||
gint groups;
|
|
||||||
};
|
};
|
||||||
typedef struct _SymbolsParseData SymbolsParseData;
|
typedef struct _SymbolsParseData SymbolsParseData;
|
||||||
|
|
||||||
static SymbolsParseData *
|
static SymbolsParseData *
|
||||||
symbols_parse_data_new (EekKeyboard *keyboard)
|
symbols_parse_data_new (LevelKeyboard *keyboard)
|
||||||
{
|
{
|
||||||
SymbolsParseData *data = g_slice_new0 (SymbolsParseData);
|
SymbolsParseData *data = g_slice_new0 (SymbolsParseData);
|
||||||
|
|
||||||
data->keyboard = g_object_ref (keyboard);
|
data->keyboard = keyboard;
|
||||||
data->text = g_string_sized_new (BUFSIZE);
|
data->text = g_string_sized_new (BUFSIZE);
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
@ -584,13 +666,13 @@ symbols_parse_data_new (EekKeyboard *keyboard)
|
|||||||
static void
|
static void
|
||||||
symbols_parse_data_free (SymbolsParseData *data)
|
symbols_parse_data_free (SymbolsParseData *data)
|
||||||
{
|
{
|
||||||
g_object_unref (data->keyboard);
|
|
||||||
g_string_free (data->text, TRUE);
|
g_string_free (data->text, TRUE);
|
||||||
g_slice_free (SymbolsParseData, data);
|
g_slice_free (SymbolsParseData, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const gchar *symbols_valid_path_list[] = {
|
static const gchar *symbols_valid_path_list[] = {
|
||||||
"symbols",
|
"symbols",
|
||||||
|
"symbol/symbols",
|
||||||
"include/symbols",
|
"include/symbols",
|
||||||
"key/symbols",
|
"key/symbols",
|
||||||
"text/key/symbols",
|
"text/key/symbols",
|
||||||
@ -617,37 +699,6 @@ symbols_start_element_callback (GMarkupParseContext *pcontext,
|
|||||||
error))
|
error))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
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) {
|
if (g_strcmp0 (element_name, "keysym") == 0) {
|
||||||
attribute = get_attribute (attribute_names, attribute_values,
|
attribute = get_attribute (attribute_names, attribute_values,
|
||||||
"keyval");
|
"keyval");
|
||||||
@ -680,7 +731,6 @@ symbols_start_element_callback (GMarkupParseContext *pcontext,
|
|||||||
data->tooltip = g_strdup (attribute);
|
data->tooltip = g_strdup (attribute);
|
||||||
}
|
}
|
||||||
|
|
||||||
out:
|
|
||||||
data->element_stack = g_slist_prepend (data->element_stack,
|
data->element_stack = g_slist_prepend (data->element_stack,
|
||||||
g_strdup (element_name));
|
g_strdup (element_name));
|
||||||
data->text->len = 0;
|
data->text->len = 0;
|
||||||
@ -695,80 +745,44 @@ symbols_end_element_callback (GMarkupParseContext *pcontext,
|
|||||||
SymbolsParseData *data = user_data;
|
SymbolsParseData *data = user_data;
|
||||||
GSList *head = data->element_stack;
|
GSList *head = data->element_stack;
|
||||||
gchar *text;
|
gchar *text;
|
||||||
gint i;
|
|
||||||
|
|
||||||
g_free (head->data);
|
g_free (head->data);
|
||||||
data->element_stack = g_slist_next (data->element_stack);
|
data->element_stack = g_slist_next (data->element_stack);
|
||||||
g_slist_free1 (head);
|
g_slist_free1 (head);
|
||||||
|
|
||||||
|
// TODO: this could all be moved to text handler
|
||||||
text = g_strndup (data->text->str, data->text->len);
|
text = g_strndup (data->text->str, data->text->len);
|
||||||
|
|
||||||
if (g_strcmp0 (element_name, "key") == 0) {
|
|
||||||
if (!data->key) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
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 ||
|
if (g_strcmp0 (element_name, "symbol") == 0 ||
|
||||||
g_strcmp0 (element_name, "keysym") == 0 ||
|
g_strcmp0 (element_name, "keysym") == 0 ||
|
||||||
g_strcmp0 (element_name, "text") == 0) {
|
g_strcmp0 (element_name, "text") == 0) {
|
||||||
EekSymbol *symbol;
|
|
||||||
|
|
||||||
if (g_strcmp0 (element_name, "keysym") == 0) {
|
gchar *name = text;
|
||||||
EekSymbol *keysym;
|
EekKey *key = eek_keyboard_find_key_by_name (data->keyboard,
|
||||||
if (data->keyval != EEK_INVALID_KEYSYM)
|
name);
|
||||||
keysym = eek_keysym_new (data->keyval);
|
if (key) {
|
||||||
else
|
squeek_key_add_symbol(
|
||||||
keysym = eek_keysym_new_from_name (text);
|
eek_key_get_state(key),
|
||||||
symbol = keysym;
|
element_name,
|
||||||
} else if (g_strcmp0 (element_name, "text") == 0) {
|
text,
|
||||||
symbol = eek_text_new (text);
|
data->keyval,
|
||||||
} else {
|
data->label,
|
||||||
symbol = eek_symbol_new (text);
|
data->icon,
|
||||||
|
data->tooltip
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data->label) {
|
data->keyval = 0;
|
||||||
eek_symbol_set_label (symbol, data->label);
|
g_free(data->label);
|
||||||
g_free (data->label);
|
data->label = NULL;
|
||||||
data->label = NULL;
|
g_free(data->icon);
|
||||||
}
|
data->icon = NULL;
|
||||||
if (data->icon) {
|
g_free(data->tooltip);
|
||||||
eek_symbol_set_icon_name (symbol, data->icon);
|
data->tooltip = NULL;
|
||||||
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;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (g_strcmp0 (element_name, "invalid") == 0) {
|
if (g_strcmp0 (element_name, "invalid") == 0) {
|
||||||
data->symbols = g_slist_prepend (data->symbols, NULL);
|
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -880,31 +894,37 @@ static const GMarkupParser prerequisites_parser = {
|
|||||||
0
|
0
|
||||||
};
|
};
|
||||||
|
|
||||||
static EekKeyboard *
|
LevelKeyboard *
|
||||||
eek_xml_layout_real_create_keyboard (EekboardContextService *manager,
|
eek_xml_layout_real_create_keyboard (EekLayout *self,
|
||||||
EekLayout *self,
|
EekboardContextService *manager)
|
||||||
gdouble initial_width,
|
|
||||||
gdouble initial_height)
|
|
||||||
{
|
{
|
||||||
EekXmlLayout *layout = EEK_XML_LAYOUT (self);
|
EekXmlLayout *layout = EEK_XML_LAYOUT (self);
|
||||||
EekXmlLayoutPrivate *priv = eek_xml_layout_get_instance_private (layout);
|
EekXmlLayoutPrivate *priv = eek_xml_layout_get_instance_private (layout);
|
||||||
gboolean retval;
|
gboolean retval;
|
||||||
|
|
||||||
/* Create an empty keyboard to which geometry and symbols
|
|
||||||
information are applied. */
|
|
||||||
EekKeyboard *keyboard = g_object_new (EEK_TYPE_KEYBOARD, NULL);
|
|
||||||
keyboard->manager = manager;
|
|
||||||
|
|
||||||
/* Read geometry information. */
|
/* Read geometry information. */
|
||||||
gchar *filename = g_strdup_printf ("%s.xml", priv->desc->geometry);
|
gchar *filename = g_strdup_printf ("%s.xml", priv->desc->geometry);
|
||||||
gchar *path = g_build_filename (priv->keyboards_dir, "geometry", filename, NULL);
|
gchar *path = g_build_filename (priv->keyboards_dir, "geometry", filename, NULL);
|
||||||
g_free (filename);
|
g_free (filename);
|
||||||
|
|
||||||
|
GArray *outline_array = g_array_new (FALSE, TRUE, sizeof (EekOutline));
|
||||||
|
|
||||||
|
// char* -> EekKey*
|
||||||
|
GHashTable *name_key_hash =
|
||||||
|
g_hash_table_new_full (g_str_hash,
|
||||||
|
g_str_equal,
|
||||||
|
g_free,
|
||||||
|
NULL);
|
||||||
|
// One view for each level
|
||||||
|
EekKeyboard *views[4] = {0};
|
||||||
|
|
||||||
GError *error = NULL;
|
GError *error = NULL;
|
||||||
retval = parse_geometry (path, keyboard, &error);
|
retval = parse_geometry (path, views, outline_array, name_key_hash, &error);
|
||||||
g_free (path);
|
g_free (path);
|
||||||
if (!retval) {
|
if (!retval) {
|
||||||
g_object_unref (keyboard);
|
for (uint i = 0; i < 4; i++) {
|
||||||
|
g_object_unref (views[i]);
|
||||||
|
}
|
||||||
g_warning ("can't parse geometry file %s: %s",
|
g_warning ("can't parse geometry file %s: %s",
|
||||||
priv->desc->geometry,
|
priv->desc->geometry,
|
||||||
error->message);
|
error->message);
|
||||||
@ -912,6 +932,12 @@ eek_xml_layout_real_create_keyboard (EekboardContextService *manager,
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
LevelKeyboard *keyboard = level_keyboard_new(manager, views, name_key_hash);
|
||||||
|
|
||||||
|
keyboard->outline_array = outline_array;
|
||||||
|
// FIXME: are symbols shared betwen views?
|
||||||
|
|
||||||
/* Read symbols information. */
|
/* Read symbols information. */
|
||||||
GList *loaded = NULL;
|
GList *loaded = NULL;
|
||||||
retval = parse_symbols_with_prerequisites (priv->keyboards_dir,
|
retval = parse_symbols_with_prerequisites (priv->keyboards_dir,
|
||||||
@ -921,7 +947,13 @@ eek_xml_layout_real_create_keyboard (EekboardContextService *manager,
|
|||||||
&error);
|
&error);
|
||||||
g_list_free_full (loaded, g_free);
|
g_list_free_full (loaded, g_free);
|
||||||
if (!retval) {
|
if (!retval) {
|
||||||
g_object_unref (keyboard);
|
for (uint i = 0; i < 4; i++) {
|
||||||
|
if (views[i]) {
|
||||||
|
g_object_unref(views[i]);
|
||||||
|
views[i] = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//g_object_unref (view);
|
||||||
g_warning ("can't parse symbols file %s: %s",
|
g_warning ("can't parse symbols file %s: %s",
|
||||||
priv->desc->symbols,
|
priv->desc->symbols,
|
||||||
error->message);
|
error->message);
|
||||||
@ -929,11 +961,9 @@ eek_xml_layout_real_create_keyboard (EekboardContextService *manager,
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
eek_layout_place_sections(keyboard);
|
for (uint i = 0; i < 4; i++) {
|
||||||
|
eek_layout_place_sections(keyboard, views[i]);
|
||||||
/* 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;
|
return keyboard;
|
||||||
}
|
}
|
||||||
@ -996,12 +1026,9 @@ eek_xml_layout_finalize (GObject *object)
|
|||||||
static void
|
static void
|
||||||
eek_xml_layout_class_init (EekXmlLayoutClass *klass)
|
eek_xml_layout_class_init (EekXmlLayoutClass *klass)
|
||||||
{
|
{
|
||||||
EekLayoutClass *layout_class = EEK_LAYOUT_CLASS (klass);
|
|
||||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||||
GParamSpec *pspec;
|
GParamSpec *pspec;
|
||||||
|
|
||||||
layout_class->create_keyboard = eek_xml_layout_real_create_keyboard;
|
|
||||||
|
|
||||||
gobject_class->set_property = eek_xml_layout_set_property;
|
gobject_class->set_property = eek_xml_layout_set_property;
|
||||||
gobject_class->get_property = eek_xml_layout_get_property;
|
gobject_class->get_property = eek_xml_layout_get_property;
|
||||||
gobject_class->finalize = eek_xml_layout_finalize;
|
gobject_class->finalize = eek_xml_layout_finalize;
|
||||||
@ -1122,13 +1149,10 @@ eek_xml_keyboard_desc_free (EekXmlKeyboardDesc *desc)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
parse_geometry (const gchar *path, EekKeyboard *keyboard, GError **error)
|
parse_geometry (const gchar *path, EekKeyboard **views, GArray *outline_array, GHashTable *name_key_hash, GError **error)
|
||||||
{
|
{
|
||||||
GeometryParseData *data;
|
GeometryParseData *data;
|
||||||
GMarkupParseContext *pcontext;
|
GMarkupParseContext *pcontext;
|
||||||
GHashTable *oref_hash;
|
|
||||||
GHashTableIter iter;
|
|
||||||
gpointer k, v;
|
|
||||||
GFile *file;
|
GFile *file;
|
||||||
GFileInputStream *input;
|
GFileInputStream *input;
|
||||||
gboolean retval;
|
gboolean retval;
|
||||||
@ -1142,7 +1166,7 @@ parse_geometry (const gchar *path, EekKeyboard *keyboard, GError **error)
|
|||||||
if (input == NULL)
|
if (input == NULL)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
data = geometry_parse_data_new (keyboard);
|
data = geometry_parse_data_new (views, name_key_hash, outline_array);
|
||||||
pcontext = g_markup_parse_context_new (&geometry_parser,
|
pcontext = g_markup_parse_context_new (&geometry_parser,
|
||||||
0,
|
0,
|
||||||
data,
|
data,
|
||||||
@ -1157,23 +1181,29 @@ parse_geometry (const gchar *path, EekKeyboard *keyboard, GError **error)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Resolve outline references. */
|
/* Resolve outline references. */
|
||||||
|
/*
|
||||||
|
* GHashTable *oref_hash;
|
||||||
|
GHashTableIter iter;
|
||||||
|
gpointer k, v;
|
||||||
|
|
||||||
oref_hash = g_hash_table_new (g_str_hash, g_str_equal);
|
oref_hash = g_hash_table_new (g_str_hash, g_str_equal);
|
||||||
g_hash_table_iter_init (&iter, data->oref_outline_hash);
|
g_hash_table_iter_init (&iter, data->oref_outline_hash);
|
||||||
while (g_hash_table_iter_next (&iter, &k, &v)) {
|
while (g_hash_table_iter_next (&iter, &k, &v)) {
|
||||||
EekOutline *outline = v;
|
EekOutline *outline = v;
|
||||||
gulong oref;
|
gulong oref;
|
||||||
|
|
||||||
oref = eek_keyboard_add_outline (data->keyboard, outline);
|
oref = add_outline (outline_array, outline);
|
||||||
g_hash_table_insert (oref_hash, k, GUINT_TO_POINTER(oref));
|
g_hash_table_insert (oref_hash, k, GUINT_TO_POINTER(oref));
|
||||||
}
|
}*/
|
||||||
|
|
||||||
|
/*
|
||||||
g_hash_table_iter_init (&iter, data->key_oref_hash);
|
g_hash_table_iter_init (&iter, data->key_oref_hash);
|
||||||
while (g_hash_table_iter_next (&iter, &k, &v)) {
|
while (g_hash_table_iter_next (&iter, &k, &v)) {
|
||||||
gpointer oref;
|
gpointer oref;
|
||||||
if (g_hash_table_lookup_extended (oref_hash, v, NULL, &oref))
|
if (g_hash_table_lookup_extended (oref_hash, v, NULL, &oref))
|
||||||
eek_key_set_oref (EEK_KEY(k), GPOINTER_TO_UINT(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);
|
geometry_parse_data_free (data);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
@ -1182,7 +1212,7 @@ parse_geometry (const gchar *path, EekKeyboard *keyboard, GError **error)
|
|||||||
static gboolean
|
static gboolean
|
||||||
parse_symbols_with_prerequisites (const gchar *keyboards_dir,
|
parse_symbols_with_prerequisites (const gchar *keyboards_dir,
|
||||||
const gchar *name,
|
const gchar *name,
|
||||||
EekKeyboard *keyboard,
|
LevelKeyboard *keyboard,
|
||||||
GList **loaded,
|
GList **loaded,
|
||||||
GError **error)
|
GError **error)
|
||||||
{
|
{
|
||||||
@ -1232,7 +1262,7 @@ parse_symbols_with_prerequisites (const gchar *keyboards_dir,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
parse_symbols (const gchar *path, EekKeyboard *keyboard, GError **error)
|
parse_symbols (const gchar *path, LevelKeyboard *keyboard, GError **error)
|
||||||
{
|
{
|
||||||
SymbolsParseData *data;
|
SymbolsParseData *data;
|
||||||
GMarkupParseContext *pcontext;
|
GMarkupParseContext *pcontext;
|
||||||
|
|||||||
@ -62,5 +62,8 @@ GList *eek_xml_list_keyboards (void);
|
|||||||
EekXmlKeyboardDesc *eek_xml_keyboard_desc_copy (EekXmlKeyboardDesc *desc);
|
EekXmlKeyboardDesc *eek_xml_keyboard_desc_copy (EekXmlKeyboardDesc *desc);
|
||||||
void eek_xml_keyboard_desc_free (EekXmlKeyboardDesc *desc);
|
void eek_xml_keyboard_desc_free (EekXmlKeyboardDesc *desc);
|
||||||
|
|
||||||
|
LevelKeyboard *
|
||||||
|
eek_xml_layout_real_create_keyboard (EekLayout *self,
|
||||||
|
EekboardContextService *manager);
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
#endif /* EEK_XML_LAYOUT_H */
|
#endif /* EEK_XML_LAYOUT_H */
|
||||||
|
|||||||
@ -26,9 +26,7 @@
|
|||||||
#include "eek-section.h"
|
#include "eek-section.h"
|
||||||
#include "eek-key.h"
|
#include "eek-key.h"
|
||||||
#include "eek-layout.h"
|
#include "eek-layout.h"
|
||||||
#include "eek-symbol.h"
|
|
||||||
#include "eek-keysym.h"
|
#include "eek-keysym.h"
|
||||||
#include "eek-text.h"
|
|
||||||
#include "eek-serializable.h"
|
#include "eek-serializable.h"
|
||||||
|
|
||||||
void eek_init (void);
|
void eek_init (void);
|
||||||
|
|||||||
@ -1,7 +1,6 @@
|
|||||||
gnome = import('gnome')
|
gnome = import('gnome')
|
||||||
|
|
||||||
enum_headers = [
|
enum_headers = [
|
||||||
'eek-symbol.h',
|
|
||||||
'eek-types.h',
|
'eek-types.h',
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|||||||
@ -71,7 +71,7 @@ struct _EekboardContextServicePrivate {
|
|||||||
gboolean visible;
|
gboolean visible;
|
||||||
gboolean fullscreen;
|
gboolean fullscreen;
|
||||||
|
|
||||||
EekKeyboard *keyboard; // currently used keyboard
|
LevelKeyboard *keyboard; // currently used keyboard
|
||||||
GHashTable *keyboard_hash; // a table of available keyboards, per layout
|
GHashTable *keyboard_hash; // a table of available keyboards, per layout
|
||||||
|
|
||||||
// TODO: make use of repeating buttons
|
// TODO: make use of repeating buttons
|
||||||
@ -86,11 +86,10 @@ struct _EekboardContextServicePrivate {
|
|||||||
|
|
||||||
G_DEFINE_TYPE_WITH_PRIVATE (EekboardContextService, eekboard_context_service, G_TYPE_OBJECT);
|
G_DEFINE_TYPE_WITH_PRIVATE (EekboardContextService, eekboard_context_service, G_TYPE_OBJECT);
|
||||||
|
|
||||||
static EekKeyboard *
|
static LevelKeyboard *
|
||||||
eekboard_context_service_real_create_keyboard (EekboardContextService *self,
|
eekboard_context_service_real_create_keyboard (EekboardContextService *self,
|
||||||
const gchar *keyboard_type)
|
const gchar *keyboard_type)
|
||||||
{
|
{
|
||||||
EekKeyboard *keyboard;
|
|
||||||
EekLayout *layout;
|
EekLayout *layout;
|
||||||
GError *error;
|
GError *error;
|
||||||
|
|
||||||
@ -135,7 +134,7 @@ eekboard_context_service_real_create_keyboard (EekboardContextService *self,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
keyboard = eek_keyboard_new (self, layout, CSW, CSH);
|
LevelKeyboard *keyboard = eek_xml_layout_real_create_keyboard(layout, self);
|
||||||
if (!keyboard) {
|
if (!keyboard) {
|
||||||
g_error("Failed to create a keyboard");
|
g_error("Failed to create a keyboard");
|
||||||
}
|
}
|
||||||
@ -148,6 +147,10 @@ eekboard_context_service_real_create_keyboard (EekboardContextService *self,
|
|||||||
|
|
||||||
gchar *keymap_str = eek_keyboard_get_keymap(keyboard);
|
gchar *keymap_str = eek_keyboard_get_keymap(keyboard);
|
||||||
|
|
||||||
|
int f = open("maprs.map", O_CREAT | O_WRONLY);
|
||||||
|
write(f, keymap_str, strlen(keymap_str));
|
||||||
|
close(f);
|
||||||
|
|
||||||
struct xkb_keymap *keymap = xkb_keymap_new_from_string(context, keymap_str,
|
struct xkb_keymap *keymap = xkb_keymap_new_from_string(context, keymap_str,
|
||||||
XKB_KEYMAP_FORMAT_TEXT_V1, XKB_KEYMAP_COMPILE_NO_FLAGS);
|
XKB_KEYMAP_FORMAT_TEXT_V1, XKB_KEYMAP_COMPILE_NO_FLAGS);
|
||||||
|
|
||||||
@ -315,21 +318,16 @@ settings_update_layout(EekboardContextService *context)
|
|||||||
|
|
||||||
// generic part follows
|
// generic part follows
|
||||||
static guint keyboard_id = 0;
|
static guint keyboard_id = 0;
|
||||||
EekKeyboard *keyboard = g_hash_table_lookup(context->priv->keyboard_hash,
|
LevelKeyboard *keyboard = g_hash_table_lookup(context->priv->keyboard_hash,
|
||||||
GUINT_TO_POINTER(keyboard_id));
|
GUINT_TO_POINTER(keyboard_id));
|
||||||
// create a keyboard
|
// create a keyboard
|
||||||
if (!keyboard) {
|
if (!keyboard) {
|
||||||
EekboardContextServiceClass *klass = EEKBOARD_CONTEXT_SERVICE_GET_CLASS(context);
|
keyboard = eekboard_context_service_real_create_keyboard(context, keyboard_layout);
|
||||||
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,
|
g_hash_table_insert (context->priv->keyboard_hash,
|
||||||
GUINT_TO_POINTER(keyboard_id),
|
GUINT_TO_POINTER(keyboard_id),
|
||||||
keyboard);
|
keyboard);
|
||||||
g_object_set_data (G_OBJECT(keyboard),
|
keyboard->id = keyboard_id;
|
||||||
"keyboard-id",
|
|
||||||
GUINT_TO_POINTER(keyboard_id));
|
|
||||||
keyboard_id++;
|
keyboard_id++;
|
||||||
}
|
}
|
||||||
// set as current
|
// set as current
|
||||||
@ -370,7 +368,6 @@ eekboard_context_service_class_init (EekboardContextServiceClass *klass)
|
|||||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||||
GParamSpec *pspec;
|
GParamSpec *pspec;
|
||||||
|
|
||||||
klass->create_keyboard = eekboard_context_service_real_create_keyboard;
|
|
||||||
klass->show_keyboard = eekboard_context_service_real_show_keyboard;
|
klass->show_keyboard = eekboard_context_service_real_show_keyboard;
|
||||||
klass->hide_keyboard = eekboard_context_service_real_hide_keyboard;
|
klass->hide_keyboard = eekboard_context_service_real_hide_keyboard;
|
||||||
|
|
||||||
@ -574,7 +571,7 @@ eekboard_context_service_destroy (EekboardContextService *context)
|
|||||||
* Get keyboard currently active in @context.
|
* Get keyboard currently active in @context.
|
||||||
* Returns: (transfer none): an #EekKeyboard
|
* Returns: (transfer none): an #EekKeyboard
|
||||||
*/
|
*/
|
||||||
EekKeyboard *
|
LevelKeyboard *
|
||||||
eekboard_context_service_get_keyboard (EekboardContextService *context)
|
eekboard_context_service_get_keyboard (EekboardContextService *context)
|
||||||
{
|
{
|
||||||
return context->priv->keyboard;
|
return context->priv->keyboard;
|
||||||
@ -594,7 +591,7 @@ eekboard_context_service_get_fullscreen (EekboardContextService *context)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void eekboard_context_service_set_keymap(EekboardContextService *context,
|
void eekboard_context_service_set_keymap(EekboardContextService *context,
|
||||||
const EekKeyboard *keyboard)
|
const LevelKeyboard *keyboard)
|
||||||
{
|
{
|
||||||
zwp_virtual_keyboard_v1_keymap(context->virtual_keyboard,
|
zwp_virtual_keyboard_v1_keymap(context->virtual_keyboard,
|
||||||
WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1,
|
WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1,
|
||||||
|
|||||||
@ -97,13 +97,12 @@ void eekboard_context_service_show_keyboard
|
|||||||
void eekboard_context_service_hide_keyboard
|
void eekboard_context_service_hide_keyboard
|
||||||
(EekboardContextService *context);
|
(EekboardContextService *context);
|
||||||
void eekboard_context_service_destroy (EekboardContextService *context);
|
void eekboard_context_service_destroy (EekboardContextService *context);
|
||||||
EekKeyboard *eekboard_context_service_get_keyboard
|
LevelKeyboard *eekboard_context_service_get_keyboard(EekboardContextService *context);
|
||||||
(EekboardContextService *context);
|
|
||||||
gboolean eekboard_context_service_get_fullscreen
|
gboolean eekboard_context_service_get_fullscreen
|
||||||
(EekboardContextService *context);
|
(EekboardContextService *context);
|
||||||
|
|
||||||
void eekboard_context_service_set_keymap(EekboardContextService *context,
|
void eekboard_context_service_set_keymap(EekboardContextService *context,
|
||||||
const EekKeyboard *keyboard);
|
const LevelKeyboard *keyboard);
|
||||||
|
|
||||||
void eekboard_context_service_set_hint_purpose(EekboardContextService *context,
|
void eekboard_context_service_set_hint_purpose(EekboardContextService *context,
|
||||||
uint32_t hint,
|
uint32_t hint,
|
||||||
|
|||||||
@ -22,6 +22,7 @@
|
|||||||
#include "eekboard/key-emitter.h"
|
#include "eekboard/key-emitter.h"
|
||||||
|
|
||||||
#include <gdk/gdk.h>
|
#include <gdk/gdk.h>
|
||||||
|
#include <X11/XKBlib.h>
|
||||||
|
|
||||||
#include "eekboard/eekboard-context-service.h"
|
#include "eekboard/eekboard-context-service.h"
|
||||||
|
|
||||||
@ -84,14 +85,14 @@ update_modifier_info (SeatEmitter *client)
|
|||||||
|
|
||||||
static void
|
static void
|
||||||
send_fake_key (SeatEmitter *emitter,
|
send_fake_key (SeatEmitter *emitter,
|
||||||
EekKeyboard *keyboard,
|
LevelKeyboard *keyboard,
|
||||||
guint keycode,
|
guint keycode,
|
||||||
guint keyboard_modifiers,
|
guint keyboard_modifiers,
|
||||||
gboolean pressed,
|
gboolean pressed,
|
||||||
uint32_t timestamp)
|
uint32_t timestamp)
|
||||||
{
|
{
|
||||||
uint32_t proto_modifiers = 0;
|
uint32_t proto_modifiers = 0;
|
||||||
guint level = eek_element_get_level(EEK_ELEMENT(keyboard));
|
guint level = keyboard->level;
|
||||||
uint32_t group = (level / 2);
|
uint32_t group = (level / 2);
|
||||||
|
|
||||||
if (keyboard_modifiers & EEK_SHIFT_MASK)
|
if (keyboard_modifiers & EEK_SHIFT_MASK)
|
||||||
@ -104,7 +105,7 @@ send_fake_key (SeatEmitter *emitter,
|
|||||||
|
|
||||||
void
|
void
|
||||||
emit_key_activated (EekboardContextService *manager,
|
emit_key_activated (EekboardContextService *manager,
|
||||||
EekKeyboard *keyboard,
|
LevelKeyboard *keyboard,
|
||||||
guint keycode,
|
guint keycode,
|
||||||
EekSymbol *symbol,
|
EekSymbol *symbol,
|
||||||
EekModifierType modifiers,
|
EekModifierType modifiers,
|
||||||
|
|||||||
@ -39,7 +39,7 @@ enum mod_indices {
|
|||||||
};
|
};
|
||||||
|
|
||||||
void
|
void
|
||||||
emit_key_activated (EekboardContextService *manager, EekKeyboard *keyboard,
|
emit_key_activated (EekboardContextService *manager, LevelKeyboard *keyboard,
|
||||||
guint keycode,
|
guint keycode,
|
||||||
EekSymbol *symbol,
|
EekSymbol *symbol,
|
||||||
guint modifiers,
|
guint modifiers,
|
||||||
|
|||||||
23
src/keyboard.h
Normal file
23
src/keyboard.h
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
#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_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, uint32_t level);
|
||||||
|
const char* squeek_key_to_keymap_entry(const char *key_name, struct squeek_key *key);
|
||||||
|
#endif
|
||||||
237
src/keyboard.rs
Normal file
237
src/keyboard.rs
Normal file
@ -0,0 +1,237 @@
|
|||||||
|
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::ffi::CString;
|
||||||
|
use std::os::raw::c_char;
|
||||||
|
|
||||||
|
// The following defined in C
|
||||||
|
#[no_mangle]
|
||||||
|
extern "C" {
|
||||||
|
fn eek_keysym_from_name(name: *const c_char) -> u32;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 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) -> *mut KeyState {
|
||||||
|
Box::into_raw(Box::new(
|
||||||
|
KeyState {
|
||||||
|
pressed: false,
|
||||||
|
keycode: keycode,
|
||||||
|
symbols: Vec::new(),
|
||||||
|
}
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub extern "C"
|
||||||
|
fn squeek_key_free(key: *mut KeyState) {
|
||||||
|
unsafe { Box::from_raw(key) }; // gets dropped
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub extern "C"
|
||||||
|
fn squeek_key_is_pressed(key: *const KeyState) -> u32 {
|
||||||
|
let key = unsafe { &*key };
|
||||||
|
return key.pressed as u32;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub extern "C"
|
||||||
|
fn squeek_key_set_pressed(key: *mut KeyState, pressed: u32) {
|
||||||
|
let key = unsafe { &mut *key };
|
||||||
|
key.pressed = pressed != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub extern "C"
|
||||||
|
fn squeek_key_get_keycode(key: *const KeyState) -> u32 {
|
||||||
|
let key = unsafe { &*key };
|
||||||
|
return key.keycode as u32;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub extern "C"
|
||||||
|
fn squeek_key_set_keycode(key: *mut KeyState, code: u32) {
|
||||||
|
let key = unsafe { &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: *mut KeyState,
|
||||||
|
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 key = unsafe { &mut *key };
|
||||||
|
|
||||||
|
if key.symbols.len() > 0 {
|
||||||
|
eprintln!("Key {:?} already has a symbol defined", text);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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
|
||||||
|
});
|
||||||
|
|
||||||
|
let symbol = match element.to_bytes() {
|
||||||
|
b"symbol" => Symbol {
|
||||||
|
action: Action::Submit {
|
||||||
|
text: text,
|
||||||
|
keys: Vec::new(),
|
||||||
|
},
|
||||||
|
label: label,
|
||||||
|
tooltip: tooltip,
|
||||||
|
},
|
||||||
|
b"keysym" => {
|
||||||
|
let keysym = XKeySym(
|
||||||
|
if keyval == 0 {
|
||||||
|
unsafe { eek_keysym_from_name(text_raw) }
|
||||||
|
} else {
|
||||||
|
keyval
|
||||||
|
}
|
||||||
|
);
|
||||||
|
Symbol {
|
||||||
|
action: match KeySym::from_u32(keysym.0) {
|
||||||
|
KeySym::Shift => Action::SetLevel(1),
|
||||||
|
_ => Action::Submit {
|
||||||
|
text: text,
|
||||||
|
keys: vec![keysym],
|
||||||
|
}
|
||||||
|
},
|
||||||
|
label: label,
|
||||||
|
tooltip: tooltip,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
_ => panic!("unsupported element type {:?}", element),
|
||||||
|
};
|
||||||
|
|
||||||
|
key.symbols.push(symbol);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub extern "C"
|
||||||
|
fn squeek_key_get_symbol(
|
||||||
|
key: *const KeyState, index: u32
|
||||||
|
) -> *const symbol::Symbol {
|
||||||
|
let key = unsafe { &*key };
|
||||||
|
let index = index as usize;
|
||||||
|
&key.symbols[
|
||||||
|
if index < key.symbols.len() { index } else { 0 }
|
||||||
|
] as *const symbol::Symbol
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub extern "C"
|
||||||
|
fn squeek_key_to_keymap_entry(
|
||||||
|
key_name: *const c_char,
|
||||||
|
key: *const KeyState,
|
||||||
|
) -> *const c_char {
|
||||||
|
let key_name = as_cstr(&key_name)
|
||||||
|
.expect("Missing key name")
|
||||||
|
.to_str()
|
||||||
|
.expect("Bad key name");
|
||||||
|
|
||||||
|
let key = unsafe { &*key };
|
||||||
|
let symbol_names = key.symbols.iter()
|
||||||
|
.map(|symbol| {
|
||||||
|
match &symbol.action {
|
||||||
|
symbol::Action::Submit { text: Some(text), .. } => {
|
||||||
|
Some(
|
||||||
|
text.clone()
|
||||||
|
.into_string().expect("Bad symbol")
|
||||||
|
)
|
||||||
|
},
|
||||||
|
_ => None
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
|
let inner = match symbol_names.len() {
|
||||||
|
1 => match &symbol_names[0] {
|
||||||
|
Some(name) => format!("[ {} ]", name),
|
||||||
|
_ => format!("[ ]"),
|
||||||
|
},
|
||||||
|
4 => {
|
||||||
|
let first = match (&symbol_names[0], &symbol_names[1]) {
|
||||||
|
(Some(left), Some(right)) => format!("{}, {}", left, right),
|
||||||
|
_ => format!(""),
|
||||||
|
};
|
||||||
|
let second = match (&symbol_names[2], &symbol_names[3]) {
|
||||||
|
(Some(left), Some(right)) => format!("{}, {}", left, right),
|
||||||
|
_ => format!(""),
|
||||||
|
};
|
||||||
|
format!("[ {} ], [ {} ]", first, second)
|
||||||
|
},
|
||||||
|
_ => panic!("Unsupported number of symbols: {}", symbol_names.len()),
|
||||||
|
};
|
||||||
|
|
||||||
|
CString::new(format!(" key <{}> {{ {} }};\n", key_name, inner))
|
||||||
|
.expect("Couldn't convert string")
|
||||||
|
.into_raw()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct KeyState {
|
||||||
|
pressed: bool,
|
||||||
|
keycode: u32,
|
||||||
|
symbols: Vec<symbol::Symbol>,
|
||||||
|
}
|
||||||
@ -2,3 +2,6 @@
|
|||||||
mod bitflags;
|
mod bitflags;
|
||||||
|
|
||||||
mod imservice;
|
mod imservice;
|
||||||
|
mod keyboard;
|
||||||
|
mod symbol;
|
||||||
|
mod util;
|
||||||
|
|||||||
@ -27,9 +27,6 @@ sources = [
|
|||||||
'../eek/eek-renderer.c',
|
'../eek/eek-renderer.c',
|
||||||
'../eek/eek-section.c',
|
'../eek/eek-section.c',
|
||||||
'../eek/eek-serializable.c',
|
'../eek/eek-serializable.c',
|
||||||
'../eek/eek-symbol.c',
|
|
||||||
'../eek/eek-symbol-matrix.c',
|
|
||||||
'../eek/eek-text.c',
|
|
||||||
'../eek/eek-types.c',
|
'../eek/eek-types.c',
|
||||||
'../eek/eek-xml-layout.c',
|
'../eek/eek-xml-layout.c',
|
||||||
'../eek/layersurface.c',
|
'../eek/layersurface.c',
|
||||||
|
|||||||
@ -83,9 +83,7 @@ on_notify_keyboard (GObject *object,
|
|||||||
GParamSpec *spec,
|
GParamSpec *spec,
|
||||||
ServerContextService *context)
|
ServerContextService *context)
|
||||||
{
|
{
|
||||||
const EekKeyboard *keyboard;
|
const LevelKeyboard *keyboard = eekboard_context_service_get_keyboard (EEKBOARD_CONTEXT_SERVICE(context));
|
||||||
|
|
||||||
keyboard = eekboard_context_service_get_keyboard (EEKBOARD_CONTEXT_SERVICE(context));
|
|
||||||
|
|
||||||
if (!keyboard)
|
if (!keyboard)
|
||||||
g_error("Programmer error: keyboard layout was unset!");
|
g_error("Programmer error: keyboard layout was unset!");
|
||||||
@ -141,13 +139,13 @@ set_geometry (ServerContextService *context)
|
|||||||
GdkWindow *root = gdk_screen_get_root_window (screen);
|
GdkWindow *root = gdk_screen_get_root_window (screen);
|
||||||
GdkDisplay *display = gdk_display_get_default ();
|
GdkDisplay *display = gdk_display_get_default ();
|
||||||
GdkMonitor *monitor = gdk_display_get_monitor_at_window (display, root);
|
GdkMonitor *monitor = gdk_display_get_monitor_at_window (display, root);
|
||||||
EekKeyboard *keyboard = eekboard_context_service_get_keyboard (EEKBOARD_CONTEXT_SERVICE(context));
|
LevelKeyboard *keyboard = eekboard_context_service_get_keyboard (EEKBOARD_CONTEXT_SERVICE(context));
|
||||||
|
|
||||||
GdkRectangle rect;
|
GdkRectangle rect;
|
||||||
EekBounds bounds;
|
EekBounds bounds;
|
||||||
|
|
||||||
gdk_monitor_get_geometry (monitor, &rect);
|
gdk_monitor_get_geometry (monitor, &rect);
|
||||||
eek_element_get_bounds (EEK_ELEMENT(keyboard), &bounds);
|
eek_element_get_bounds (EEK_ELEMENT(level_keyboard_current(keyboard)), &bounds);
|
||||||
|
|
||||||
if (eekboard_context_service_get_fullscreen (EEKBOARD_CONTEXT_SERVICE(context))) {
|
if (eekboard_context_service_get_fullscreen (EEKBOARD_CONTEXT_SERVICE(context))) {
|
||||||
gint width = rect.width;
|
gint width = rect.width;
|
||||||
@ -228,14 +226,12 @@ destroy_window (ServerContextService *context)
|
|||||||
static void
|
static void
|
||||||
make_widget (ServerContextService *context)
|
make_widget (ServerContextService *context)
|
||||||
{
|
{
|
||||||
EekKeyboard *keyboard;
|
|
||||||
|
|
||||||
if (context->widget) {
|
if (context->widget) {
|
||||||
gtk_widget_destroy(context->widget);
|
gtk_widget_destroy(context->widget);
|
||||||
context->widget = NULL;
|
context->widget = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
keyboard = eekboard_context_service_get_keyboard (EEKBOARD_CONTEXT_SERVICE(context));
|
LevelKeyboard *keyboard = eekboard_context_service_get_keyboard (EEKBOARD_CONTEXT_SERVICE(context));
|
||||||
|
|
||||||
context->widget = eek_gtk_keyboard_new (keyboard);
|
context->widget = eek_gtk_keyboard_new (keyboard);
|
||||||
|
|
||||||
|
|||||||
24
src/symbol.h
Normal file
24
src/symbol.h
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
#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
|
||||||
138
src/symbol.rs
Normal file
138
src/symbol.rs
Normal file
@ -0,0 +1,138 @@
|
|||||||
|
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)]
|
||||||
|
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)]
|
||||||
|
pub struct XKeySym(pub u32);
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
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)]
|
||||||
|
pub enum Modifier {
|
||||||
|
Control,
|
||||||
|
Alt,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Action to perform on the keypress and, in reverse, on keyrelease
|
||||||
|
#[derive(Debug)]
|
||||||
|
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)]
|
||||||
|
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>,
|
||||||
|
}
|
||||||
49
src/util.rs
Normal file
49
src/util.rs
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
pub mod c {
|
||||||
|
use std::ffi::{ CStr, CString };
|
||||||
|
use std::os::raw::c_char;
|
||||||
|
use std::str::Utf8Error;
|
||||||
|
|
||||||
|
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))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -29,12 +29,12 @@ test_create (void)
|
|||||||
EekKey *key0, *key1;
|
EekKey *key0, *key1;
|
||||||
|
|
||||||
keyboard = g_object_new (EEK_TYPE_KEYBOARD, NULL);
|
keyboard = g_object_new (EEK_TYPE_KEYBOARD, NULL);
|
||||||
section = eek_keyboard_create_section (keyboard);
|
section = eek_keyboard_real_create_section (keyboard);
|
||||||
g_assert (EEK_IS_SECTION(section));
|
g_assert (EEK_IS_SECTION(section));
|
||||||
eek_section_add_row (section, 2, EEK_ORIENTATION_HORIZONTAL);
|
eek_section_add_row (section, 2, EEK_ORIENTATION_HORIZONTAL);
|
||||||
key0 = eek_section_create_key (section, "key0", 1);
|
key0 = eek_section_create_key (section, "key0", 1, 0);
|
||||||
g_assert (EEK_IS_KEY(key0));
|
g_assert (EEK_IS_KEY(key0));
|
||||||
key1 = eek_section_create_key (section, "key1", 2);
|
key1 = eek_section_create_key (section, "key1", 2, 0);
|
||||||
g_assert (EEK_IS_KEY(key1));
|
g_assert (EEK_IS_KEY(key1));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -30,7 +30,7 @@ static void
|
|||||||
test_output_parse (void)
|
test_output_parse (void)
|
||||||
{
|
{
|
||||||
EekLayout *layout;
|
EekLayout *layout;
|
||||||
EekKeyboard *keyboard;
|
LevelKeyboard *keyboard;
|
||||||
GError *error;
|
GError *error;
|
||||||
|
|
||||||
error = NULL;
|
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
|
/* We don't need the context service to parse an XML file, so we can pass
|
||||||
NULL when creating a keyboard. */
|
NULL when creating a keyboard. */
|
||||||
keyboard = eek_keyboard_new (NULL, layout, 640, 480);
|
keyboard = eek_xml_layout_real_create_keyboard(layout, NULL);
|
||||||
g_object_unref (layout);
|
g_object_unref (layout);
|
||||||
g_object_unref (keyboard);
|
level_keyboard_free(keyboard);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
|||||||
@ -32,14 +32,14 @@ static void
|
|||||||
test_check_xkb (void)
|
test_check_xkb (void)
|
||||||
{
|
{
|
||||||
EekLayout *layout;
|
EekLayout *layout;
|
||||||
EekKeyboard *keyboard;
|
LevelKeyboard *keyboard;
|
||||||
GError *error;
|
GError *error;
|
||||||
|
|
||||||
error = NULL;
|
error = NULL;
|
||||||
layout = eek_xml_layout_new ("us", &error);
|
layout = eek_xml_layout_new ("us", &error);
|
||||||
g_assert_no_error (error);
|
g_assert_no_error (error);
|
||||||
|
|
||||||
keyboard = eek_keyboard_new (NULL, layout, 640, 480);
|
keyboard = eek_xml_layout_real_create_keyboard(layout, NULL);
|
||||||
gchar *keymap_str = eek_keyboard_get_keymap(keyboard);
|
gchar *keymap_str = eek_keyboard_get_keymap(keyboard);
|
||||||
|
|
||||||
struct xkb_context *context = xkb_context_new(XKB_CONTEXT_NO_FLAGS);
|
struct xkb_context *context = xkb_context_new(XKB_CONTEXT_NO_FLAGS);
|
||||||
@ -58,7 +58,7 @@ test_check_xkb (void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
g_object_unref (layout);
|
g_object_unref (layout);
|
||||||
g_object_unref (keyboard);
|
level_keyboard_free(keyboard);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
|||||||
Reference in New Issue
Block a user