Compare commits
	
		
			94 Commits
		
	
	
		
			update-deb
			...
			fix-render
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 99a7786dc3 | |||
| e9cf572a3c | |||
| 1246776328 | |||
| ea15f69e73 | |||
| 2e22bb5431 | |||
| a9a6e1d2b5 | |||
| 4b66add65f | |||
| 79dce7c4c3 | |||
| aff71e0e33 | |||
| 9b10f56ba6 | |||
| 2391947b34 | |||
| e903150971 | |||
| 7495ec9bbb | |||
| e25d5a84b2 | |||
| 88ade4df1b | |||
| 00c3903672 | |||
| c801b17ba0 | |||
| 9ec8d62f3f | |||
| b1edcfcb1b | |||
| 54b0f59935 | |||
| 531b09f296 | |||
| e5b6d66d60 | |||
| a045810af6 | |||
| d68a8fef9a | |||
| 9162d4291f | |||
| 93d7699aa7 | |||
| 6eb63f6a4c | |||
| f6d4ca0387 | |||
| 7b41466a77 | |||
| 18c25084db | |||
| a5875402ef | |||
| f3ed1ba247 | |||
| 633d69baca | |||
| dbc8cc14bc | |||
| c65583b911 | |||
| 3d518b5757 | |||
| bfa72d7f61 | |||
| 373713ba54 | |||
| 068c325ee2 | |||
| 3b076e5e64 | |||
| 07d6e3a0f2 | |||
| 7690ef9a1a | |||
| 9974c385e5 | |||
| 8dafad80b1 | |||
| 93e9b2dde9 | |||
| c3a54595ea | |||
| 95ef52fe42 | |||
| c638c40a09 | |||
| 83d48d24ce | |||
| d807e43929 | |||
| 0a112be956 | |||
| 078efa2a6e | |||
| 5827827008 | |||
| 9c61d8de72 | |||
| f72ddc8129 | |||
| 7e9c3b40bb | |||
| a8371af9c0 | |||
| 4e11d071d9 | |||
| a7140705c4 | |||
| 69986132b4 | |||
| 3c97a3a592 | |||
| 268dda4da0 | |||
| 45f58a97b9 | |||
| bdbbaf6099 | |||
| 839968dc84 | |||
| fbdc5f4a93 | |||
| e5648a82a3 | |||
| 38133d326b | |||
| cc00fcb5c9 | |||
| 53f7a14717 | |||
| 922495ca06 | |||
| e5e2e08ff4 | |||
| c7c410210b | |||
| cb7c214aa0 | |||
| 6f5f49729c | |||
| 94c9442de1 | |||
| 8c044d0852 | |||
| 1f0cc0a5f3 | |||
| 5693ce3df7 | |||
| bcf04ab11e | |||
| 086f6bd772 | |||
| d0fa444a0e | |||
| cd81aeb286 | |||
| 7db33bc92e | |||
| fb6c501e44 | |||
| ce7b398f7b | |||
| 4d8d3a8109 | |||
| a183cf8b63 | |||
| f834edcf94 | |||
| 17802a9408 | |||
| ac1aad881c | |||
| 928110a92d | |||
| f6479fafe2 | |||
| 62b1c2ba84 | 
							
								
								
									
										9
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1,9 @@
 | 
			
		||||
.zanata-cache/
 | 
			
		||||
_build
 | 
			
		||||
TAGS
 | 
			
		||||
tags
 | 
			
		||||
vgdump
 | 
			
		||||
*.swp
 | 
			
		||||
*~
 | 
			
		||||
\#*#
 | 
			
		||||
.\#*
 | 
			
		||||
@ -2,16 +2,30 @@ image: debian:buster
 | 
			
		||||
 | 
			
		||||
stages:
 | 
			
		||||
  - build
 | 
			
		||||
  - test
 | 
			
		||||
 | 
			
		||||
.tags: &tags
 | 
			
		||||
  tags:
 | 
			
		||||
    - librem5
 | 
			
		||||
 | 
			
		||||
before_script:
 | 
			
		||||
  - apt-get -y update
 | 
			
		||||
  - apt-get -y build-dep .
 | 
			
		||||
 | 
			
		||||
build_meson:
 | 
			
		||||
  <<: *tags
 | 
			
		||||
  stage: build
 | 
			
		||||
  tags:
 | 
			
		||||
    - librem5
 | 
			
		||||
  artifacts:
 | 
			
		||||
    paths:
 | 
			
		||||
      - _build
 | 
			
		||||
  script:
 | 
			
		||||
    - meson . _build/ -Ddepdatadir=/usr/share
 | 
			
		||||
    - ninja -C _build install
 | 
			
		||||
 | 
			
		||||
test:
 | 
			
		||||
  <<: *tags
 | 
			
		||||
  stage: test
 | 
			
		||||
  dependencies:
 | 
			
		||||
    - build_meson
 | 
			
		||||
  script:
 | 
			
		||||
    - xvfb-run -s -noreset ninja -C _build test
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										20
									
								
								autogen.sh
									
									
									
									
									
								
							
							
						
						
									
										20
									
								
								autogen.sh
									
									
									
									
									
								
							@ -1,20 +0,0 @@
 | 
			
		||||
#!/bin/sh
 | 
			
		||||
# Run this to generate all the initial makefiles, etc.
 | 
			
		||||
 | 
			
		||||
srcdir=`dirname $0`
 | 
			
		||||
test -z "$srcdir" && srcdir=.
 | 
			
		||||
 | 
			
		||||
PKG_NAME="eekboard"
 | 
			
		||||
 | 
			
		||||
(test -f $srcdir/configure.ac \
 | 
			
		||||
  && test -f $srcdir/README.md ) || {
 | 
			
		||||
    echo -n "**Error**: Directory "\`$srcdir\'" does not look like the"
 | 
			
		||||
    echo " top-level $PKG_NAME directory"
 | 
			
		||||
    exit 1
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ACLOCAL_FLAGS="$ACLOCAL_FLAGS -I m4"
 | 
			
		||||
REQUIRED_AUTOMAKE_VERSION=1.10
 | 
			
		||||
REQUIRED_AUTOCONF_VERSION=2.60
 | 
			
		||||
 | 
			
		||||
. gnome-autogen.sh
 | 
			
		||||
@ -1,6 +1,6 @@
 | 
			
		||||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
 | 
			
		||||
 | 
			
		||||
<svg xmlns="http://www.w3.org/2000/svg" height="24" width="24"
 | 
			
		||||
<svg xmlns="http://www.w3.org/2000/svg" height="16" width="16"
 | 
			
		||||
     version="1.1" viewBox="0 0 24 24">
 | 
			
		||||
   
 | 
			
		||||
    <path d="M 24,1 L 24,10 C 24,15 20,17 17,17 L 7,17 L 10,20 L 10,23
 | 
			
		||||
 | 
			
		||||
| 
		 Before Width: | Height: | Size: 388 B After Width: | Height: | Size: 388 B  | 
@ -1,6 +1,6 @@
 | 
			
		||||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
 | 
			
		||||
 | 
			
		||||
<svg xmlns="http://www.w3.org/2000/svg" height="24" width="24"
 | 
			
		||||
<svg xmlns="http://www.w3.org/2000/svg" height="16" width="16"
 | 
			
		||||
     version="1.1" viewBox="0 0 24 24">
 | 
			
		||||
   
 | 
			
		||||
    <path d="M 12,2 L 22,14 L 16,14 L 16,22 L 8,22 L 8,14 L 2,14 Z"
 | 
			
		||||
 | 
			
		||||
| 
		 Before Width: | Height: | Size: 279 B After Width: | Height: | Size: 279 B  | 
							
								
								
									
										52
									
								
								data/icons/keyboard-mode-symbolic.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										52
									
								
								data/icons/keyboard-mode-symbolic.svg
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,52 @@
 | 
			
		||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
 | 
			
		||||
<svg
 | 
			
		||||
   xmlns:dc="http://purl.org/dc/elements/1.1/"
 | 
			
		||||
   xmlns:cc="http://creativecommons.org/ns#"
 | 
			
		||||
   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
 | 
			
		||||
   xmlns:svg="http://www.w3.org/2000/svg"
 | 
			
		||||
   xmlns="http://www.w3.org/2000/svg"
 | 
			
		||||
   id="svg4043"
 | 
			
		||||
   version="1.1"
 | 
			
		||||
   viewBox="0 0 4.2333331 4.2333093"
 | 
			
		||||
   height="4.2333093mm"
 | 
			
		||||
   width="4.2333331mm">
 | 
			
		||||
  <defs
 | 
			
		||||
     id="defs4037" />
 | 
			
		||||
  <metadata
 | 
			
		||||
     id="metadata4040">
 | 
			
		||||
    <rdf:RDF>
 | 
			
		||||
      <cc:Work
 | 
			
		||||
         rdf:about="">
 | 
			
		||||
        <dc:format>image/svg+xml</dc:format>
 | 
			
		||||
        <dc:type
 | 
			
		||||
           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
 | 
			
		||||
        <dc:title></dc:title>
 | 
			
		||||
      </cc:Work>
 | 
			
		||||
    </rdf:RDF>
 | 
			
		||||
  </metadata>
 | 
			
		||||
  <g
 | 
			
		||||
     transform="translate(-86.329776,-68.097636)"
 | 
			
		||||
     id="layer1">
 | 
			
		||||
    <g
 | 
			
		||||
       style="stroke-width:1.00004983;fill:#2e3436;fill-opacity:1"
 | 
			
		||||
       transform="matrix(0.99990029,0,0,1,-7.1823833,-1.8799927)"
 | 
			
		||||
       id="g842">
 | 
			
		||||
      <g
 | 
			
		||||
         style="stroke-width:1.00004983;fill:#2e3436;fill-opacity:1"
 | 
			
		||||
         id="g836">
 | 
			
		||||
        <path
 | 
			
		||||
           id="path5166"
 | 
			
		||||
           d="m 95.636719,69.978516 c -1.165869,0 -2.115235,0.949365 -2.115235,2.115234 0,1.165869 0.949366,2.117188 2.115235,2.117188 1.165869,0 2.117187,-0.951319 2.117187,-2.117188 0,-1.165869 -0.951318,-2.115234 -2.117187,-2.115234 z m 0,0.529296 c 0.879886,0 1.58789,0.706052 1.58789,1.585938 0,0.879886 -0.708004,1.587891 -1.58789,1.587891 -0.879886,0 -1.585938,-0.708005 -1.585938,-1.587891 0,-0.879886 0.706052,-1.585937 1.585938,-1.585938 z"
 | 
			
		||||
           style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#2e3436;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.52919304;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" />
 | 
			
		||||
      </g>
 | 
			
		||||
      <path
 | 
			
		||||
         style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#2e3436;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.26459652;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
 | 
			
		||||
         d="m 95.636719,70.109375 c -0.144398,0 -0.27248,0.07793 -0.373047,0.189453 -0.100567,0.111521 -0.18209,0.261405 -0.25,0.439453 -0.135821,0.356096 -0.214844,0.830395 -0.214844,1.355469 0,0.525074 0.07902,1.001326 0.214844,1.357422 0.06791,0.178048 0.149433,0.327932 0.25,0.439453 0.100567,0.111521 0.228649,0.1875 0.373047,0.1875 0.144397,0 0.27248,-0.07598 0.373047,-0.1875 0.100566,-0.111521 0.182089,-0.261405 0.25,-0.439453 0.135821,-0.356096 0.216797,-0.832348 0.216796,-1.357422 0,-0.525074 -0.08097,-0.999373 -0.216796,-1.355469 -0.06791,-0.178048 -0.149434,-0.327932 -0.25,-0.439453 -0.100567,-0.111521 -0.22865,-0.189453 -0.373047,-0.189453 z m 0,0.265625 c 0.05067,0 0.109272,0.02564 0.177734,0.101562 0.06846,0.07592 0.139293,0.198356 0.199219,0.355469 0.119851,0.314227 0.197266,0.763915 0.197266,1.261719 0,0.497804 -0.07742,0.949446 -0.197266,1.263672 -0.05993,0.157113 -0.130756,0.279549 -0.199219,0.355469 -0.06846,0.07592 -0.12706,0.101562 -0.177734,0.101562 -0.05067,0 -0.107319,-0.02564 -0.175781,-0.101562 -0.06846,-0.07592 -0.139294,-0.198356 -0.199219,-0.355469 C 95.141867,73.043196 95.0625,72.591554 95.0625,72.09375 c 0,-0.497804 0.07937,-0.947492 0.199219,-1.261719 0.05993,-0.157113 0.130756,-0.279549 0.199219,-0.355469 C 95.5294,70.400643 95.586045,70.375 95.636719,70.375 Z"
 | 
			
		||||
         id="circle5168" />
 | 
			
		||||
      <path
 | 
			
		||||
         style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#2e3436;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.26459652;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
 | 
			
		||||
         d="m 93.697266,71.962891 v 0.263671 h 3.96875 v -0.263671 z"
 | 
			
		||||
         id="path5170" />
 | 
			
		||||
    </g>
 | 
			
		||||
  </g>
 | 
			
		||||
</svg>
 | 
			
		||||
| 
		 After Width: | Height: | Size: 6.6 KiB  | 
@ -26,6 +26,7 @@
 | 
			
		||||
      <key keycode="44" name="AC07" oref="outline2" />
 | 
			
		||||
      <key keycode="45" name="AC08" oref="outline2" />
 | 
			
		||||
      <key keycode="46" name="AC09" oref="outline2" />
 | 
			
		||||
      <key keycode="47" name="AC10" oref="outline2" />
 | 
			
		||||
    </row>
 | 
			
		||||
  </section>
 | 
			
		||||
  <section angle="0">
 | 
			
		||||
@ -44,9 +45,9 @@
 | 
			
		||||
  <section angle="0">
 | 
			
		||||
    <row orientation="1">
 | 
			
		||||
      <key keycode="0" name="ABC123" oref="altline" />
 | 
			
		||||
      <key keycode="150" name="I150" oref="altline" />
 | 
			
		||||
      <key keycode="149" name="I149" oref="altline" />
 | 
			
		||||
      <key keycode="65" name="SPCE" oref="spaceline" />
 | 
			
		||||
      <key keycode="60" name="AB09" oref="outline2" />
 | 
			
		||||
      <key keycode="59" name="AB08" oref="outline2" />
 | 
			
		||||
      <key keycode="36" name="RTRN" oref="outline7" />
 | 
			
		||||
    </row>
 | 
			
		||||
  </section>
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										126
									
								
								data/keyboards/geometry/extended.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										126
									
								
								data/keyboards/geometry/extended.xml
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,126 @@
 | 
			
		||||
<?xml version="1.0"?>
 | 
			
		||||
<geometry version="0.90">
 | 
			
		||||
  <bounds x="0" y="10.000000" width="426.0000" height="296.5853"/>
 | 
			
		||||
  <!-- Keycodes correspond to those used in /usr/share/X11/xkb/keycodes/evdev.
 | 
			
		||||
       For Squeekboard, the values have no connection to evdev. They are only
 | 
			
		||||
       used as indices into the keymap sent to the compositor. They must have
 | 
			
		||||
       values in the range from 8 to 255. -->
 | 
			
		||||
  <section angle="0">
 | 
			
		||||
    <row orientation="1">
 | 
			
		||||
      <key keycode="24" name="AD01" oref="outline2" />
 | 
			
		||||
      <key keycode="25" name="AD02" oref="outline2" />
 | 
			
		||||
      <key keycode="26" name="AD03" oref="outline2" />
 | 
			
		||||
      <key keycode="27" name="AD04" oref="outline2" />
 | 
			
		||||
      <key keycode="28" name="AD05" oref="outline2" />
 | 
			
		||||
      <key keycode="29" name="AD06" oref="outline2" />
 | 
			
		||||
      <key keycode="30" name="AD07" oref="outline2" />
 | 
			
		||||
      <key keycode="31" name="AD08" oref="outline2" />
 | 
			
		||||
      <key keycode="32" name="AD09" oref="outline2" />
 | 
			
		||||
      <key keycode="33" name="AD10" oref="outline2" />
 | 
			
		||||
      <key keycode="34" name="AD11" oref="outline2" />
 | 
			
		||||
    </row>
 | 
			
		||||
  </section>
 | 
			
		||||
  <section angle="0">
 | 
			
		||||
    <row orientation="1">
 | 
			
		||||
      <key keycode="38" name="AC01" oref="outline2" />
 | 
			
		||||
      <key keycode="39" name="AC02" oref="outline2" />
 | 
			
		||||
      <key keycode="40" name="AC03" oref="outline2" />
 | 
			
		||||
      <key keycode="41" name="AC04" oref="outline2" />
 | 
			
		||||
      <key keycode="42" name="AC05" oref="outline2" />
 | 
			
		||||
      <key keycode="43" name="AC06" oref="outline2" />
 | 
			
		||||
      <key keycode="44" name="AC07" oref="outline2" />
 | 
			
		||||
      <key keycode="45" name="AC08" oref="outline2" />
 | 
			
		||||
      <key keycode="46" name="AC09" oref="outline2" />
 | 
			
		||||
      <key keycode="47" name="AC10" oref="outline2" />
 | 
			
		||||
      <key keycode="48" name="AC11" oref="outline2" />
 | 
			
		||||
    </row>
 | 
			
		||||
  </section>
 | 
			
		||||
  <section angle="0">
 | 
			
		||||
    <row orientation="1">
 | 
			
		||||
      <key keycode="50" name="LFSH" oref="altline" />
 | 
			
		||||
      <key keycode="52" name="AB01" oref="outline2" />
 | 
			
		||||
      <key keycode="53" name="AB02" oref="outline2" />
 | 
			
		||||
      <key keycode="54" name="AB03" oref="outline2" />
 | 
			
		||||
      <key keycode="55" name="AB04" oref="outline2" />
 | 
			
		||||
      <key keycode="56" name="AB05" oref="outline2" />
 | 
			
		||||
      <key keycode="57" name="AB06" oref="outline2" />
 | 
			
		||||
      <key keycode="58" name="AB07" oref="outline2" />
 | 
			
		||||
      <key keycode="22" name="BKSP" oref="altline" />
 | 
			
		||||
    </row>
 | 
			
		||||
  </section>
 | 
			
		||||
  <section angle="0">
 | 
			
		||||
    <row orientation="1">
 | 
			
		||||
      <key keycode="0" name="ABC123" oref="altline" />
 | 
			
		||||
      <key keycode="149" name="I149" oref="altline" />
 | 
			
		||||
      <key keycode="65" name="SPCE" oref="spaceline" />
 | 
			
		||||
      <key keycode="59" name="AB08" oref="outline2" />
 | 
			
		||||
      <key keycode="36" name="RTRN" oref="outline7" />
 | 
			
		||||
    </row>
 | 
			
		||||
  </section>
 | 
			
		||||
  <outline id="outline2" corner-radius="1.000000">
 | 
			
		||||
    <point x="0.000000" y="0.000000"/>
 | 
			
		||||
    <point x="32" y="0.000000"/>
 | 
			
		||||
    <point x="32" y="52.44877"/>
 | 
			
		||||
    <point x="0.000000" y="52.44877"/>
 | 
			
		||||
  </outline>
 | 
			
		||||
  <outline id="altline" corner-radius="1.000000">
 | 
			
		||||
    <point x="0.000000" y="0.000000"/>
 | 
			
		||||
    <point x="48.39024" y="0.000000"/>
 | 
			
		||||
    <point x="48.39024" y="52.44877"/>
 | 
			
		||||
    <point x="0.000000" y="52.44877"/>
 | 
			
		||||
  </outline>
 | 
			
		||||
  <outline id="outline4" corner-radius="1.000000">
 | 
			
		||||
    <point x="0.000000" y="0.000000"/>
 | 
			
		||||
    <point x="59.31707" y="0.000000"/>
 | 
			
		||||
    <point x="59.31707" y="52.44877"/>
 | 
			
		||||
    <point x="0.000000" y="52.44877"/>
 | 
			
		||||
  </outline>
 | 
			
		||||
  <outline id="outline5" corner-radius="1.000000">
 | 
			
		||||
    <point x="0.000000" y="0.000000"/>
 | 
			
		||||
    <point x="59.31707" y="0.000000"/>
 | 
			
		||||
    <point x="59.31707" y="52.44877"/>
 | 
			
		||||
    <point x="0.000000" y="52.44877"/>
 | 
			
		||||
  </outline>
 | 
			
		||||
  <outline id="outline6" corner-radius="1.000000">
 | 
			
		||||
    <point x="0.000000" y="0.000000"/>
 | 
			
		||||
    <point x="68.68292" y="0.000000"/>
 | 
			
		||||
    <point x="68.68292" y="52.44877"/>
 | 
			
		||||
    <point x="0.000000" y="52.44877"/>
 | 
			
		||||
  </outline>
 | 
			
		||||
  <outline id="outline7" corner-radius="1.000000">
 | 
			
		||||
    <point x="0.000000" y="0.000000"/>
 | 
			
		||||
    <point x="88.97561" y="0.000000"/>
 | 
			
		||||
    <point x="88.97561" y="52.44877"/>
 | 
			
		||||
    <point x="0.000000" y="52.44877"/>
 | 
			
		||||
  </outline>
 | 
			
		||||
  <outline id="outline8" corner-radius="1.000000">
 | 
			
		||||
    <point x="0.000000" y="0.000000"/>
 | 
			
		||||
    <point x="88.97561" y="0.000000"/>
 | 
			
		||||
    <point x="88.97561" y="52.44877"/>
 | 
			
		||||
    <point x="0.000000" y="52.44877"/>
 | 
			
		||||
  </outline>
 | 
			
		||||
  <outline id="outline9" corner-radius="1.000000">
 | 
			
		||||
    <point x="0.000000" y="0.000000"/>
 | 
			
		||||
    <point x="109.2682" y="0.000000"/>
 | 
			
		||||
    <point x="109.2682" y="52.44877"/>
 | 
			
		||||
    <point x="0.000000" y="52.44877"/>
 | 
			
		||||
  </outline>
 | 
			
		||||
  <outline id="outline10" corner-radius="1.000000">
 | 
			
		||||
    <point x="0.000000" y="0.000000"/>
 | 
			
		||||
    <point x="37.46341" y="0.000000"/>
 | 
			
		||||
    <point x="37.46341" y="52.44877"/>
 | 
			
		||||
    <point x="0.000000" y="52.44877"/>
 | 
			
		||||
  </outline>
 | 
			
		||||
  <outline id="outline13" corner-radius="1.000000">
 | 
			
		||||
    <point x="0.000000" y="0.000000"/>
 | 
			
		||||
    <point x="79.60975" y="0.000000"/>
 | 
			
		||||
    <point x="79.60975" y="52.44877"/>
 | 
			
		||||
    <point x="0.000000" y="52.44877"/>
 | 
			
		||||
  </outline>
 | 
			
		||||
  <outline id="spaceline" corner-radius="1.000000">
 | 
			
		||||
    <point x="0.000000" y="0.000000"/>
 | 
			
		||||
    <point x="150.5853" y="0.000000"/>
 | 
			
		||||
    <point x="150.5853" y="52.44877"/>
 | 
			
		||||
    <point x="0.000000" y="52.44877"/>
 | 
			
		||||
  </outline>
 | 
			
		||||
</geometry>
 | 
			
		||||
							
								
								
									
										105
									
								
								data/keyboards/geometry/numbers-keypad.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										105
									
								
								data/keyboards/geometry/numbers-keypad.xml
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,105 @@
 | 
			
		||||
<?xml version="1.0"?>
 | 
			
		||||
<geometry version="0.90">
 | 
			
		||||
  <bounds x="0" y="10.000000" width="426.0000" height="296.5853"/>
 | 
			
		||||
  <section angle="0">
 | 
			
		||||
    <row orientation="1">
 | 
			
		||||
      <key keycode="24" name="AD01" oref="outline2" />
 | 
			
		||||
      <key keycode="25" name="AD02" oref="outline2" />
 | 
			
		||||
      <key keycode="26" name="AD03" oref="outline2" />
 | 
			
		||||
      <key keycode="27" name="AD04" oref="outline2" />
 | 
			
		||||
      <key keycode="28" name="AD05" oref="outline2" />
 | 
			
		||||
    </row>
 | 
			
		||||
  </section>
 | 
			
		||||
  <section angle="0">
 | 
			
		||||
    <row orientation="1">
 | 
			
		||||
      <key keycode="38" name="AC01" oref="outline2" />
 | 
			
		||||
      <key keycode="39" name="AC02" oref="outline2" />
 | 
			
		||||
      <key keycode="40" name="AC03" oref="outline2" />
 | 
			
		||||
      <key keycode="41" name="AC04" oref="outline2" />
 | 
			
		||||
      <key keycode="42" name="AC05" oref="outline2" />
 | 
			
		||||
    </row>
 | 
			
		||||
  </section>
 | 
			
		||||
  <section angle="0">
 | 
			
		||||
    <row orientation="1">
 | 
			
		||||
      <key keycode="52" name="AB01" oref="outline2" />
 | 
			
		||||
      <key keycode="53" name="AB02" oref="outline2" />
 | 
			
		||||
      <key keycode="54" name="AB03" oref="outline2" />
 | 
			
		||||
      <key keycode="55" name="AB04" oref="outline2" />
 | 
			
		||||
      <key keycode="56" name="AB05" oref="outline2" />
 | 
			
		||||
    </row>
 | 
			
		||||
  </section>
 | 
			
		||||
  <section angle="0">
 | 
			
		||||
    <row orientation="1">
 | 
			
		||||
      <key keycode="22" name="BKSP" oref="altline" />
 | 
			
		||||
      <key keycode="57" name="AB06" oref="outline2" />
 | 
			
		||||
      <key keycode="65" name="SPCE" oref="spaceline" />
 | 
			
		||||
      <key keycode="36" name="RTRN" oref="outline7" />
 | 
			
		||||
    </row>
 | 
			
		||||
  </section>
 | 
			
		||||
  <outline id="outline2" corner-radius="1.000000">
 | 
			
		||||
    <point x="0.000000" y="0.000000"/>
 | 
			
		||||
    <point x="37.46341" y="0.000000"/>
 | 
			
		||||
    <point x="37.46341" y="52.44877"/>
 | 
			
		||||
    <point x="0.000000" y="52.44877"/>
 | 
			
		||||
  </outline>
 | 
			
		||||
  <outline id="altline" corner-radius="1.000000">
 | 
			
		||||
    <point x="0.000000" y="0.000000"/>
 | 
			
		||||
    <point x="48.39024" y="0.000000"/>
 | 
			
		||||
    <point x="48.39024" y="52.44877"/>
 | 
			
		||||
    <point x="0.000000" y="52.44877"/>
 | 
			
		||||
  </outline>
 | 
			
		||||
  <outline id="outline4" corner-radius="1.000000">
 | 
			
		||||
    <point x="0.000000" y="0.000000"/>
 | 
			
		||||
    <point x="59.31707" y="0.000000"/>
 | 
			
		||||
    <point x="59.31707" y="52.44877"/>
 | 
			
		||||
    <point x="0.000000" y="52.44877"/>
 | 
			
		||||
  </outline>
 | 
			
		||||
  <outline id="outline5" corner-radius="1.000000">
 | 
			
		||||
    <point x="0.000000" y="0.000000"/>
 | 
			
		||||
    <point x="59.31707" y="0.000000"/>
 | 
			
		||||
    <point x="59.31707" y="52.44877"/>
 | 
			
		||||
    <point x="0.000000" y="52.44877"/>
 | 
			
		||||
  </outline>
 | 
			
		||||
  <outline id="outline6" corner-radius="1.000000">
 | 
			
		||||
    <point x="0.000000" y="0.000000"/>
 | 
			
		||||
    <point x="68.68292" y="0.000000"/>
 | 
			
		||||
    <point x="68.68292" y="52.44877"/>
 | 
			
		||||
    <point x="0.000000" y="52.44877"/>
 | 
			
		||||
  </outline>
 | 
			
		||||
  <outline id="outline7" corner-radius="1.000000">
 | 
			
		||||
    <point x="0.000000" y="0.000000"/>
 | 
			
		||||
    <point x="88.97561" y="0.000000"/>
 | 
			
		||||
    <point x="88.97561" y="52.44877"/>
 | 
			
		||||
    <point x="0.000000" y="52.44877"/>
 | 
			
		||||
  </outline>
 | 
			
		||||
  <outline id="outline8" corner-radius="1.000000">
 | 
			
		||||
    <point x="0.000000" y="0.000000"/>
 | 
			
		||||
    <point x="88.97561" y="0.000000"/>
 | 
			
		||||
    <point x="88.97561" y="52.44877"/>
 | 
			
		||||
    <point x="0.000000" y="52.44877"/>
 | 
			
		||||
  </outline>
 | 
			
		||||
  <outline id="outline9" corner-radius="1.000000">
 | 
			
		||||
    <point x="0.000000" y="0.000000"/>
 | 
			
		||||
    <point x="109.2682" y="0.000000"/>
 | 
			
		||||
    <point x="109.2682" y="52.44877"/>
 | 
			
		||||
    <point x="0.000000" y="52.44877"/>
 | 
			
		||||
  </outline>
 | 
			
		||||
  <outline id="outline10" corner-radius="1.000000">
 | 
			
		||||
    <point x="0.000000" y="0.000000"/>
 | 
			
		||||
    <point x="37.46341" y="0.000000"/>
 | 
			
		||||
    <point x="37.46341" y="52.44877"/>
 | 
			
		||||
    <point x="0.000000" y="52.44877"/>
 | 
			
		||||
  </outline>
 | 
			
		||||
  <outline id="outline13" corner-radius="1.000000">
 | 
			
		||||
    <point x="0.000000" y="0.000000"/>
 | 
			
		||||
    <point x="79.60975" y="0.000000"/>
 | 
			
		||||
    <point x="79.60975" y="52.44877"/>
 | 
			
		||||
    <point x="0.000000" y="52.44877"/>
 | 
			
		||||
  </outline>
 | 
			
		||||
  <outline id="spaceline" corner-radius="1.000000">
 | 
			
		||||
    <point x="0.000000" y="0.000000"/>
 | 
			
		||||
    <point x="120.5853" y="0.000000"/>
 | 
			
		||||
    <point x="120.5853" y="52.44877"/>
 | 
			
		||||
    <point x="0.000000" y="52.44877"/>
 | 
			
		||||
  </outline>
 | 
			
		||||
</geometry>
 | 
			
		||||
@ -24,6 +24,9 @@
 | 
			
		||||
  <keyboard id="my" name="my"
 | 
			
		||||
	    geometry="compact" symbols="my"
 | 
			
		||||
	    longname="Myanmar" language="my"/>
 | 
			
		||||
  <keyboard id="nb" name="nb"
 | 
			
		||||
	    geometry="extended" symbols="nb"
 | 
			
		||||
	    longname="Norwegian" language="nb"/>
 | 
			
		||||
  <keyboard id="ru" name="ru"
 | 
			
		||||
	    geometry="compact" symbols="us"
 | 
			
		||||
	    longname="Russian" language="ru"/>
 | 
			
		||||
@ -85,4 +88,10 @@
 | 
			
		||||
  <keyboard id="te-inscript" name="te-inscript"
 | 
			
		||||
	    geometry="compact" symbols="te-inscript"
 | 
			
		||||
	    longname="Telugu (Inscript)" language="te"/>
 | 
			
		||||
 | 
			
		||||
  <!-- Common keyboards -->
 | 
			
		||||
  <keyboard id="numbers" name="numbers"
 | 
			
		||||
	    geometry="numbers-keypad" symbols="special/numbers"
 | 
			
		||||
	    longname="Numeric keypad" language="all"/>
 | 
			
		||||
 | 
			
		||||
</keyboards>
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										308
									
								
								data/keyboards/keymaps/nb.xkb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										308
									
								
								data/keyboards/keymaps/nb.xkb
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,308 @@
 | 
			
		||||
xkb_keymap {
 | 
			
		||||
 | 
			
		||||
    xkb_keycodes "squeekboard" {
 | 
			
		||||
        minimum = 8;
 | 
			
		||||
        maximum = 255;
 | 
			
		||||
        <ESC>                = 9;
 | 
			
		||||
        <AE01>               = 10;
 | 
			
		||||
        <AE02>               = 11;
 | 
			
		||||
        <AE03>               = 12;
 | 
			
		||||
        <AE04>               = 13;
 | 
			
		||||
        <AE05>               = 14;
 | 
			
		||||
        <AE06>               = 15;
 | 
			
		||||
        <AE07>               = 16;
 | 
			
		||||
        <AE08>               = 17;
 | 
			
		||||
        <AE09>               = 18;
 | 
			
		||||
        <AE10>               = 19;
 | 
			
		||||
        <AE11>               = 20;
 | 
			
		||||
        <AE12>               = 21;
 | 
			
		||||
        <BKSP>               = 22;
 | 
			
		||||
        <TAB>                = 23;
 | 
			
		||||
        <AD01>               = 24;
 | 
			
		||||
        <AD02>               = 25;
 | 
			
		||||
        <AD03>               = 26;
 | 
			
		||||
        <AD04>               = 27;
 | 
			
		||||
        <AD05>               = 28;
 | 
			
		||||
        <AD06>               = 29;
 | 
			
		||||
        <AD07>               = 30;
 | 
			
		||||
        <AD08>               = 31;
 | 
			
		||||
        <AD09>               = 32;
 | 
			
		||||
        <AD10>               = 33;
 | 
			
		||||
        <AD11>               = 34;
 | 
			
		||||
        <AD12>               = 35;
 | 
			
		||||
        <RTRN>               = 36;
 | 
			
		||||
        <LCTL>               = 37;
 | 
			
		||||
        <AC01>               = 38;
 | 
			
		||||
        <AC02>               = 39;
 | 
			
		||||
        <AC03>               = 40;
 | 
			
		||||
        <AC04>               = 41;
 | 
			
		||||
        <AC05>               = 42;
 | 
			
		||||
        <AC06>               = 43;
 | 
			
		||||
        <AC07>               = 44;
 | 
			
		||||
        <AC08>               = 45;
 | 
			
		||||
        <AC09>               = 46;
 | 
			
		||||
        <AC10>               = 47;
 | 
			
		||||
        <AC11>               = 48;
 | 
			
		||||
        <TLDE>               = 49;
 | 
			
		||||
        <LFSH>               = 50;
 | 
			
		||||
        <BKSL>               = 51;
 | 
			
		||||
        <AB01>               = 52;
 | 
			
		||||
        <AB02>               = 53;
 | 
			
		||||
        <AB03>               = 54;
 | 
			
		||||
        <AB04>               = 55;
 | 
			
		||||
        <AB05>               = 56;
 | 
			
		||||
        <AB06>               = 57;
 | 
			
		||||
        <AB07>               = 58;
 | 
			
		||||
        <AB08>               = 59;
 | 
			
		||||
        <AB09>               = 60;
 | 
			
		||||
        <AB10>               = 61;
 | 
			
		||||
        <RTSH>               = 62;
 | 
			
		||||
        <KPMU>               = 63;
 | 
			
		||||
        <LALT>               = 64;
 | 
			
		||||
        <SPCE>               = 65;
 | 
			
		||||
        <CAPS>               = 66;
 | 
			
		||||
        <FK01>               = 67;
 | 
			
		||||
        <FK02>               = 68;
 | 
			
		||||
        <FK03>               = 69;
 | 
			
		||||
        <FK04>               = 70;
 | 
			
		||||
        <FK05>               = 71;
 | 
			
		||||
        <FK06>               = 72;
 | 
			
		||||
        <FK07>               = 73;
 | 
			
		||||
        <FK08>               = 74;
 | 
			
		||||
        <FK09>               = 75;
 | 
			
		||||
        <FK10>               = 76;
 | 
			
		||||
        <NMLK>               = 77;
 | 
			
		||||
        <SCLK>               = 78;
 | 
			
		||||
        <KP7>                = 79;
 | 
			
		||||
        <KP8>                = 80;
 | 
			
		||||
        <KP9>                = 81;
 | 
			
		||||
        <KPSU>               = 82;
 | 
			
		||||
        <KP4>                = 83;
 | 
			
		||||
        <KP5>                = 84;
 | 
			
		||||
        <KP6>                = 85;
 | 
			
		||||
        <KPAD>               = 86;
 | 
			
		||||
        <KP1>                = 87;
 | 
			
		||||
        <KP2>                = 88;
 | 
			
		||||
        <KP3>                = 89;
 | 
			
		||||
        <KP0>                = 90;
 | 
			
		||||
        <KPDL>               = 91;
 | 
			
		||||
        <LVL3>               = 92;
 | 
			
		||||
        <LSGT>               = 94;
 | 
			
		||||
        <FK11>               = 95;
 | 
			
		||||
        <FK12>               = 96;
 | 
			
		||||
        <AB11>               = 97;
 | 
			
		||||
        <KATA>               = 98;
 | 
			
		||||
        <HIRA>               = 99;
 | 
			
		||||
        <HENK>               = 100;
 | 
			
		||||
        <HKTG>               = 101;
 | 
			
		||||
        <MUHE>               = 102;
 | 
			
		||||
        <JPCM>               = 103;
 | 
			
		||||
        <KPEN>               = 104;
 | 
			
		||||
        <RCTL>               = 105;
 | 
			
		||||
        <KPDV>               = 106;
 | 
			
		||||
        <PRSC>               = 107;
 | 
			
		||||
        <RALT>               = 108;
 | 
			
		||||
        <LNFD>               = 109;
 | 
			
		||||
        <HOME>               = 110;
 | 
			
		||||
        <UP>                 = 111;
 | 
			
		||||
        <PGUP>               = 112;
 | 
			
		||||
        <LEFT>               = 113;
 | 
			
		||||
        <RGHT>               = 114;
 | 
			
		||||
        <END>                = 115;
 | 
			
		||||
        <DOWN>               = 116;
 | 
			
		||||
        <PGDN>               = 117;
 | 
			
		||||
        <INS>                = 118;
 | 
			
		||||
        <DELE>               = 119;
 | 
			
		||||
        <I120>               = 120;
 | 
			
		||||
        <MUTE>               = 121;
 | 
			
		||||
        <VOL->               = 122;
 | 
			
		||||
        <VOL+>               = 123;
 | 
			
		||||
        <POWR>               = 124;
 | 
			
		||||
        <KPEQ>               = 125;
 | 
			
		||||
        <I126>               = 126;
 | 
			
		||||
        <PAUS>               = 127;
 | 
			
		||||
        <I128>               = 128;
 | 
			
		||||
        <I129>               = 129;
 | 
			
		||||
        <HNGL>               = 130;
 | 
			
		||||
        <HJCV>               = 131;
 | 
			
		||||
        <AE13>               = 132;
 | 
			
		||||
        <LWIN>               = 133;
 | 
			
		||||
        <RWIN>               = 134;
 | 
			
		||||
        <COMP>               = 135;
 | 
			
		||||
        <STOP>               = 136;
 | 
			
		||||
        <AGAI>               = 137;
 | 
			
		||||
        <PROP>               = 138;
 | 
			
		||||
        <UNDO>               = 139;
 | 
			
		||||
        <FRNT>               = 140;
 | 
			
		||||
        <COPY>               = 141;
 | 
			
		||||
        <OPEN>               = 142;
 | 
			
		||||
        <PAST>               = 143;
 | 
			
		||||
        <FIND>               = 144;
 | 
			
		||||
        <CUT>                = 145;
 | 
			
		||||
        <HELP>               = 146;
 | 
			
		||||
        <I147>               = 147;
 | 
			
		||||
        <I148>               = 148;
 | 
			
		||||
        <I149>               = 149;
 | 
			
		||||
        <I150>               = 150;
 | 
			
		||||
        <I151>               = 151;
 | 
			
		||||
        <I152>               = 152;
 | 
			
		||||
        <I153>               = 153;
 | 
			
		||||
        <I154>               = 154;
 | 
			
		||||
        <I155>               = 155;
 | 
			
		||||
        <I156>               = 156;
 | 
			
		||||
        <I157>               = 157;
 | 
			
		||||
        <I158>               = 158;
 | 
			
		||||
        <I159>               = 159;
 | 
			
		||||
        <I160>               = 160;
 | 
			
		||||
        <I161>               = 161;
 | 
			
		||||
        <I162>               = 162;
 | 
			
		||||
        <I163>               = 163;
 | 
			
		||||
        <I164>               = 164;
 | 
			
		||||
        <I165>               = 165;
 | 
			
		||||
        <I166>               = 166;
 | 
			
		||||
        <I167>               = 167;
 | 
			
		||||
        <I168>               = 168;
 | 
			
		||||
        <I169>               = 169;
 | 
			
		||||
        <I170>               = 170;
 | 
			
		||||
        <I171>               = 171;
 | 
			
		||||
        <I172>               = 172;
 | 
			
		||||
        <I173>               = 173;
 | 
			
		||||
        <I174>               = 174;
 | 
			
		||||
        <I175>               = 175;
 | 
			
		||||
        <I176>               = 176;
 | 
			
		||||
        <I177>               = 177;
 | 
			
		||||
        <I178>               = 178;
 | 
			
		||||
        <I179>               = 179;
 | 
			
		||||
        <I180>               = 180;
 | 
			
		||||
        <I181>               = 181;
 | 
			
		||||
        <I182>               = 182;
 | 
			
		||||
        <I183>               = 183;
 | 
			
		||||
        <I184>               = 184;
 | 
			
		||||
        <I185>               = 185;
 | 
			
		||||
        <I186>               = 186;
 | 
			
		||||
        <I187>               = 187;
 | 
			
		||||
        <I188>               = 188;
 | 
			
		||||
        <I189>               = 189;
 | 
			
		||||
        <I190>               = 190;
 | 
			
		||||
        <FK13>               = 191;
 | 
			
		||||
        <FK14>               = 192;
 | 
			
		||||
        <FK15>               = 193;
 | 
			
		||||
        <FK16>               = 194;
 | 
			
		||||
        <FK17>               = 195;
 | 
			
		||||
        <FK18>               = 196;
 | 
			
		||||
        <FK19>               = 197;
 | 
			
		||||
        <FK20>               = 198;
 | 
			
		||||
        <FK21>               = 199;
 | 
			
		||||
        <FK22>               = 200;
 | 
			
		||||
        <FK23>               = 201;
 | 
			
		||||
        <FK24>               = 202;
 | 
			
		||||
        <MDSW>               = 203;
 | 
			
		||||
        <ALT>                = 204;
 | 
			
		||||
        <META>               = 205;
 | 
			
		||||
        <SUPR>               = 206;
 | 
			
		||||
        <HYPR>               = 207;
 | 
			
		||||
        <I208>               = 208;
 | 
			
		||||
        <I209>               = 209;
 | 
			
		||||
        <I210>               = 210;
 | 
			
		||||
        <I211>               = 211;
 | 
			
		||||
        <I212>               = 212;
 | 
			
		||||
        <I213>               = 213;
 | 
			
		||||
        <I214>               = 214;
 | 
			
		||||
        <I215>               = 215;
 | 
			
		||||
        <I216>               = 216;
 | 
			
		||||
        <I217>               = 217;
 | 
			
		||||
        <I218>               = 218;
 | 
			
		||||
        <I219>               = 219;
 | 
			
		||||
        <I220>               = 220;
 | 
			
		||||
        <I221>               = 221;
 | 
			
		||||
        <I222>               = 222;
 | 
			
		||||
        <I223>               = 223;
 | 
			
		||||
        <I224>               = 224;
 | 
			
		||||
        <I225>               = 225;
 | 
			
		||||
        <I226>               = 226;
 | 
			
		||||
        <I227>               = 227;
 | 
			
		||||
        <I228>               = 228;
 | 
			
		||||
        <I229>               = 229;
 | 
			
		||||
        <I230>               = 230;
 | 
			
		||||
        <I231>               = 231;
 | 
			
		||||
        <I232>               = 232;
 | 
			
		||||
        <I233>               = 233;
 | 
			
		||||
        <I234>               = 234;
 | 
			
		||||
        <I235>               = 235;
 | 
			
		||||
        <I236>               = 236;
 | 
			
		||||
        <I237>               = 237;
 | 
			
		||||
        <I238>               = 238;
 | 
			
		||||
        <I239>               = 239;
 | 
			
		||||
        <I240>               = 240;
 | 
			
		||||
        <I241>               = 241;
 | 
			
		||||
        <I242>               = 242;
 | 
			
		||||
        <I243>               = 243;
 | 
			
		||||
        <I244>               = 244;
 | 
			
		||||
        <I245>               = 245;
 | 
			
		||||
        <I246>               = 246;
 | 
			
		||||
        <I247>               = 247;
 | 
			
		||||
        <I248>               = 248;
 | 
			
		||||
        <I249>               = 249;
 | 
			
		||||
        <I250>               = 250;
 | 
			
		||||
        <I251>               = 251;
 | 
			
		||||
        <I252>               = 252;
 | 
			
		||||
        <I253>               = 253;
 | 
			
		||||
        <I254>               = 254;
 | 
			
		||||
        <I255>               = 255;
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    xkb_symbols "squeekboard" {
 | 
			
		||||
 | 
			
		||||
        name[Group1] = "Letters";
 | 
			
		||||
        name[Group2] = "Numbers/Symbols";
 | 
			
		||||
 | 
			
		||||
        key <AD01> { [ q, Q ], [ 1, asciitilde ] };
 | 
			
		||||
        key <AD02> { [ w, W ], [ 2, quoteleft ] };
 | 
			
		||||
        key <AD03> { [ e, E ], [ 3, bar ] };
 | 
			
		||||
        key <AD04> { [ r, R ], [ 4, U00B7 ] };
 | 
			
		||||
        key <AD05> { [ t, T ], [ 5, squareroot ] };
 | 
			
		||||
        key <AD06> { [ y, Y ], [ 6, Greek_pi ] };
 | 
			
		||||
        key <AD07> { [ u, U ], [ 7, division ] };
 | 
			
		||||
        key <AD08> { [ i, I ], [ 8, multiply ] };
 | 
			
		||||
        key <AD09> { [ o, O ], [ 9, paragraph ] };
 | 
			
		||||
        key <AD10> { [ p, P ], [ 0, U25B3 ] };
 | 
			
		||||
        key <AD11> { [ aring, Aring ], [ U00B1, U00A7 ] };
 | 
			
		||||
        key <AC01> { [ a, A ], [ at, copyright ] };
 | 
			
		||||
        key <AC02> { [ s, S ], [ numbersign, U00AE ] };
 | 
			
		||||
        key <AC03> { [ d, D ], [ dollar, U00A3 ] };
 | 
			
		||||
        key <AC04> { [ f, F ], [ percent, EuroSign ] };
 | 
			
		||||
        key <AC05> { [ g, G ], [ ampersand, U00A5 ] };
 | 
			
		||||
        key <AC06> { [ h, H ], [ minus, underscore ] };
 | 
			
		||||
        key <AC07> { [ j, J ], [ plus, equal ] };
 | 
			
		||||
        key <AC08> { [ k, K ], [ U00FC, asciicircum ] };
 | 
			
		||||
        key <AC09> { [ l, L ], [ U00F6, degree ] };
 | 
			
		||||
        key <AC10> { [ oslash, Oslash ], [ parenleft, braceleft ] };
 | 
			
		||||
        key <AC11> { [ ae, AE ], [ parenright, braceright ] };
 | 
			
		||||
        key <RTRN> { [ Return, Return ], [ Return, Return ] };
 | 
			
		||||
        key <LFSH> { [ Shift_L, Shift_L ], [ Shift_L, Shift_L ] };
 | 
			
		||||
        key <AB01> { [ z, Z ], [ comma, backslash ] };
 | 
			
		||||
        key <AB02> { [ x, X ], [ quotedbl, slash ] };
 | 
			
		||||
        key <AB03> { [ c, C ], [ quoteright, less ] };
 | 
			
		||||
        key <AB04> { [ v, V ], [ colon, greater ] };
 | 
			
		||||
        key <AB05> { [ b, B ], [ semicolon, equal ] };
 | 
			
		||||
        key <AB06> { [ n, N ], [ exclam, bracketleft ] };
 | 
			
		||||
        key <AB07> { [ m, M ], [ question, bracketright ] };
 | 
			
		||||
        key <AB08> { [ period, period ], [ period, period ] };
 | 
			
		||||
        key <I149> { [ preferences, preferences ], [ preferences, preferences ] };
 | 
			
		||||
        key <SPCE> { [ space, space ], [ space, space ] };
 | 
			
		||||
        key <BKSP> { [ BackSpace, BackSpace ], [ BackSpace, BackSpace ] };
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    xkb_types "squeekboard" {
 | 
			
		||||
 | 
			
		||||
	type "TWO_LEVEL" {
 | 
			
		||||
            modifiers = Shift;
 | 
			
		||||
            map[Shift] = Level2;
 | 
			
		||||
            level_name[Level1] = "Base";
 | 
			
		||||
            level_name[Level2] = "Shift";
 | 
			
		||||
	};
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    xkb_compatibility "squeekboard" {
 | 
			
		||||
    };
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										292
									
								
								data/keyboards/keymaps/numbers.xkb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										292
									
								
								data/keyboards/keymaps/numbers.xkb
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,292 @@
 | 
			
		||||
xkb_keymap {
 | 
			
		||||
 | 
			
		||||
    xkb_keycodes "squeekboard" {
 | 
			
		||||
        minimum = 8;
 | 
			
		||||
        maximum = 255;
 | 
			
		||||
        <ESC>                = 9;
 | 
			
		||||
        <AE01>               = 10;
 | 
			
		||||
        <AE02>               = 11;
 | 
			
		||||
        <AE03>               = 12;
 | 
			
		||||
        <AE04>               = 13;
 | 
			
		||||
        <AE05>               = 14;
 | 
			
		||||
        <AE06>               = 15;
 | 
			
		||||
        <AE07>               = 16;
 | 
			
		||||
        <AE08>               = 17;
 | 
			
		||||
        <AE09>               = 18;
 | 
			
		||||
        <AE10>               = 19;
 | 
			
		||||
        <AE11>               = 20;
 | 
			
		||||
        <AE12>               = 21;
 | 
			
		||||
        <BKSP>               = 22;
 | 
			
		||||
        <TAB>                = 23;
 | 
			
		||||
        <AD01>               = 24;
 | 
			
		||||
        <AD02>               = 25;
 | 
			
		||||
        <AD03>               = 26;
 | 
			
		||||
        <AD04>               = 27;
 | 
			
		||||
        <AD05>               = 28;
 | 
			
		||||
        <AD06>               = 29;
 | 
			
		||||
        <AD07>               = 30;
 | 
			
		||||
        <AD08>               = 31;
 | 
			
		||||
        <AD09>               = 32;
 | 
			
		||||
        <AD10>               = 33;
 | 
			
		||||
        <AD11>               = 34;
 | 
			
		||||
        <AD12>               = 35;
 | 
			
		||||
        <RTRN>               = 36;
 | 
			
		||||
        <LCTL>               = 37;
 | 
			
		||||
        <AC01>               = 38;
 | 
			
		||||
        <AC02>               = 39;
 | 
			
		||||
        <AC03>               = 40;
 | 
			
		||||
        <AC04>               = 41;
 | 
			
		||||
        <AC05>               = 42;
 | 
			
		||||
        <AC06>               = 43;
 | 
			
		||||
        <AC07>               = 44;
 | 
			
		||||
        <AC08>               = 45;
 | 
			
		||||
        <AC09>               = 46;
 | 
			
		||||
        <AC10>               = 47;
 | 
			
		||||
        <AC11>               = 48;
 | 
			
		||||
        <TLDE>               = 49;
 | 
			
		||||
        <LFSH>               = 50;
 | 
			
		||||
        <BKSL>               = 51;
 | 
			
		||||
        <AB01>               = 52;
 | 
			
		||||
        <AB02>               = 53;
 | 
			
		||||
        <AB03>               = 54;
 | 
			
		||||
        <AB04>               = 55;
 | 
			
		||||
        <AB05>               = 56;
 | 
			
		||||
        <AB06>               = 57;
 | 
			
		||||
        <AB07>               = 58;
 | 
			
		||||
        <AB08>               = 59;
 | 
			
		||||
        <AB09>               = 60;
 | 
			
		||||
        <AB10>               = 61;
 | 
			
		||||
        <RTSH>               = 62;
 | 
			
		||||
        <KPMU>               = 63;
 | 
			
		||||
        <LALT>               = 64;
 | 
			
		||||
        <SPCE>               = 65;
 | 
			
		||||
        <CAPS>               = 66;
 | 
			
		||||
        <FK01>               = 67;
 | 
			
		||||
        <FK02>               = 68;
 | 
			
		||||
        <FK03>               = 69;
 | 
			
		||||
        <FK04>               = 70;
 | 
			
		||||
        <FK05>               = 71;
 | 
			
		||||
        <FK06>               = 72;
 | 
			
		||||
        <FK07>               = 73;
 | 
			
		||||
        <FK08>               = 74;
 | 
			
		||||
        <FK09>               = 75;
 | 
			
		||||
        <FK10>               = 76;
 | 
			
		||||
        <NMLK>               = 77;
 | 
			
		||||
        <SCLK>               = 78;
 | 
			
		||||
        <KP7>                = 79;
 | 
			
		||||
        <KP8>                = 80;
 | 
			
		||||
        <KP9>                = 81;
 | 
			
		||||
        <KPSU>               = 82;
 | 
			
		||||
        <KP4>                = 83;
 | 
			
		||||
        <KP5>                = 84;
 | 
			
		||||
        <KP6>                = 85;
 | 
			
		||||
        <KPAD>               = 86;
 | 
			
		||||
        <KP1>                = 87;
 | 
			
		||||
        <KP2>                = 88;
 | 
			
		||||
        <KP3>                = 89;
 | 
			
		||||
        <KP0>                = 90;
 | 
			
		||||
        <KPDL>               = 91;
 | 
			
		||||
        <LVL3>               = 92;
 | 
			
		||||
        <LSGT>               = 94;
 | 
			
		||||
        <FK11>               = 95;
 | 
			
		||||
        <FK12>               = 96;
 | 
			
		||||
        <AB11>               = 97;
 | 
			
		||||
        <KATA>               = 98;
 | 
			
		||||
        <HIRA>               = 99;
 | 
			
		||||
        <HENK>               = 100;
 | 
			
		||||
        <HKTG>               = 101;
 | 
			
		||||
        <MUHE>               = 102;
 | 
			
		||||
        <JPCM>               = 103;
 | 
			
		||||
        <KPEN>               = 104;
 | 
			
		||||
        <RCTL>               = 105;
 | 
			
		||||
        <KPDV>               = 106;
 | 
			
		||||
        <PRSC>               = 107;
 | 
			
		||||
        <RALT>               = 108;
 | 
			
		||||
        <LNFD>               = 109;
 | 
			
		||||
        <HOME>               = 110;
 | 
			
		||||
        <UP>                 = 111;
 | 
			
		||||
        <PGUP>               = 112;
 | 
			
		||||
        <LEFT>               = 113;
 | 
			
		||||
        <RGHT>               = 114;
 | 
			
		||||
        <END>                = 115;
 | 
			
		||||
        <DOWN>               = 116;
 | 
			
		||||
        <PGDN>               = 117;
 | 
			
		||||
        <INS>                = 118;
 | 
			
		||||
        <DELE>               = 119;
 | 
			
		||||
        <I120>               = 120;
 | 
			
		||||
        <MUTE>               = 121;
 | 
			
		||||
        <VOL->               = 122;
 | 
			
		||||
        <VOL+>               = 123;
 | 
			
		||||
        <POWR>               = 124;
 | 
			
		||||
        <KPEQ>               = 125;
 | 
			
		||||
        <I126>               = 126;
 | 
			
		||||
        <PAUS>               = 127;
 | 
			
		||||
        <I128>               = 128;
 | 
			
		||||
        <I129>               = 129;
 | 
			
		||||
        <HNGL>               = 130;
 | 
			
		||||
        <HJCV>               = 131;
 | 
			
		||||
        <AE13>               = 132;
 | 
			
		||||
        <LWIN>               = 133;
 | 
			
		||||
        <RWIN>               = 134;
 | 
			
		||||
        <COMP>               = 135;
 | 
			
		||||
        <STOP>               = 136;
 | 
			
		||||
        <AGAI>               = 137;
 | 
			
		||||
        <PROP>               = 138;
 | 
			
		||||
        <UNDO>               = 139;
 | 
			
		||||
        <FRNT>               = 140;
 | 
			
		||||
        <COPY>               = 141;
 | 
			
		||||
        <OPEN>               = 142;
 | 
			
		||||
        <PAST>               = 143;
 | 
			
		||||
        <FIND>               = 144;
 | 
			
		||||
        <CUT>                = 145;
 | 
			
		||||
        <HELP>               = 146;
 | 
			
		||||
        <I147>               = 147;
 | 
			
		||||
        <I148>               = 148;
 | 
			
		||||
        <I149>               = 149;
 | 
			
		||||
        <I150>               = 150;
 | 
			
		||||
        <I151>               = 151;
 | 
			
		||||
        <I152>               = 152;
 | 
			
		||||
        <I153>               = 153;
 | 
			
		||||
        <I154>               = 154;
 | 
			
		||||
        <I155>               = 155;
 | 
			
		||||
        <I156>               = 156;
 | 
			
		||||
        <I157>               = 157;
 | 
			
		||||
        <I158>               = 158;
 | 
			
		||||
        <I159>               = 159;
 | 
			
		||||
        <I160>               = 160;
 | 
			
		||||
        <I161>               = 161;
 | 
			
		||||
        <I162>               = 162;
 | 
			
		||||
        <I163>               = 163;
 | 
			
		||||
        <I164>               = 164;
 | 
			
		||||
        <I165>               = 165;
 | 
			
		||||
        <I166>               = 166;
 | 
			
		||||
        <I167>               = 167;
 | 
			
		||||
        <I168>               = 168;
 | 
			
		||||
        <I169>               = 169;
 | 
			
		||||
        <I170>               = 170;
 | 
			
		||||
        <I171>               = 171;
 | 
			
		||||
        <I172>               = 172;
 | 
			
		||||
        <I173>               = 173;
 | 
			
		||||
        <I174>               = 174;
 | 
			
		||||
        <I175>               = 175;
 | 
			
		||||
        <I176>               = 176;
 | 
			
		||||
        <I177>               = 177;
 | 
			
		||||
        <I178>               = 178;
 | 
			
		||||
        <I179>               = 179;
 | 
			
		||||
        <I180>               = 180;
 | 
			
		||||
        <I181>               = 181;
 | 
			
		||||
        <I182>               = 182;
 | 
			
		||||
        <I183>               = 183;
 | 
			
		||||
        <I184>               = 184;
 | 
			
		||||
        <I185>               = 185;
 | 
			
		||||
        <I186>               = 186;
 | 
			
		||||
        <I187>               = 187;
 | 
			
		||||
        <I188>               = 188;
 | 
			
		||||
        <I189>               = 189;
 | 
			
		||||
        <I190>               = 190;
 | 
			
		||||
        <FK13>               = 191;
 | 
			
		||||
        <FK14>               = 192;
 | 
			
		||||
        <FK15>               = 193;
 | 
			
		||||
        <FK16>               = 194;
 | 
			
		||||
        <FK17>               = 195;
 | 
			
		||||
        <FK18>               = 196;
 | 
			
		||||
        <FK19>               = 197;
 | 
			
		||||
        <FK20>               = 198;
 | 
			
		||||
        <FK21>               = 199;
 | 
			
		||||
        <FK22>               = 200;
 | 
			
		||||
        <FK23>               = 201;
 | 
			
		||||
        <FK24>               = 202;
 | 
			
		||||
        <MDSW>               = 203;
 | 
			
		||||
        <ALT>                = 204;
 | 
			
		||||
        <META>               = 205;
 | 
			
		||||
        <SUPR>               = 206;
 | 
			
		||||
        <HYPR>               = 207;
 | 
			
		||||
        <I208>               = 208;
 | 
			
		||||
        <I209>               = 209;
 | 
			
		||||
        <I210>               = 210;
 | 
			
		||||
        <I211>               = 211;
 | 
			
		||||
        <I212>               = 212;
 | 
			
		||||
        <I213>               = 213;
 | 
			
		||||
        <I214>               = 214;
 | 
			
		||||
        <I215>               = 215;
 | 
			
		||||
        <I216>               = 216;
 | 
			
		||||
        <I217>               = 217;
 | 
			
		||||
        <I218>               = 218;
 | 
			
		||||
        <I219>               = 219;
 | 
			
		||||
        <I220>               = 220;
 | 
			
		||||
        <I221>               = 221;
 | 
			
		||||
        <I222>               = 222;
 | 
			
		||||
        <I223>               = 223;
 | 
			
		||||
        <I224>               = 224;
 | 
			
		||||
        <I225>               = 225;
 | 
			
		||||
        <I226>               = 226;
 | 
			
		||||
        <I227>               = 227;
 | 
			
		||||
        <I228>               = 228;
 | 
			
		||||
        <I229>               = 229;
 | 
			
		||||
        <I230>               = 230;
 | 
			
		||||
        <I231>               = 231;
 | 
			
		||||
        <I232>               = 232;
 | 
			
		||||
        <I233>               = 233;
 | 
			
		||||
        <I234>               = 234;
 | 
			
		||||
        <I235>               = 235;
 | 
			
		||||
        <I236>               = 236;
 | 
			
		||||
        <I237>               = 237;
 | 
			
		||||
        <I238>               = 238;
 | 
			
		||||
        <I239>               = 239;
 | 
			
		||||
        <I240>               = 240;
 | 
			
		||||
        <I241>               = 241;
 | 
			
		||||
        <I242>               = 242;
 | 
			
		||||
        <I243>               = 243;
 | 
			
		||||
        <I244>               = 244;
 | 
			
		||||
        <I245>               = 245;
 | 
			
		||||
        <I246>               = 246;
 | 
			
		||||
        <I247>               = 247;
 | 
			
		||||
        <I248>               = 248;
 | 
			
		||||
        <I249>               = 249;
 | 
			
		||||
        <I250>               = 250;
 | 
			
		||||
        <I251>               = 251;
 | 
			
		||||
        <I252>               = 252;
 | 
			
		||||
        <I253>               = 253;
 | 
			
		||||
        <I254>               = 254;
 | 
			
		||||
        <I255>               = 255;
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    xkb_symbols "squeekboard" {
 | 
			
		||||
 | 
			
		||||
        name[Group1] = "Letters";
 | 
			
		||||
        name[Group2] = "Numbers/Symbols";
 | 
			
		||||
 | 
			
		||||
        key <AD01> { [ 1, 1 ], [ 1, 1 ] };
 | 
			
		||||
        key <AD02> { [ 2, 2 ], [ 2, 2 ] };
 | 
			
		||||
        key <AD03> { [ 3, 3 ], [ 3, 3 ] };
 | 
			
		||||
        key <AD04> { [ parenleft, parenleft ], [ parenleft, parenleft ] };
 | 
			
		||||
        key <AD05> { [ parenright, parenright ], [ parenright, parenright ] };
 | 
			
		||||
        key <AC01> { [ 4, 4 ], [ 4, 4 ] };
 | 
			
		||||
        key <AC02> { [ 5, 5 ], [ 5, 5 ] };
 | 
			
		||||
        key <AC03> { [ 6, 6 ], [ 6, 6 ] };
 | 
			
		||||
        key <AC04> { [ numbersign, numbersign ], [ numbersign, numbersign ] };
 | 
			
		||||
        key <AC05> { [ asterisk, asterisk ], [ asterisk, asterisk ] };
 | 
			
		||||
        key <AB01> { [ 7, 7 ], [ 7, 7 ] };
 | 
			
		||||
        key <AB02> { [ 8, 8 ], [ 8, 8 ] };
 | 
			
		||||
        key <AB03> { [ 9, 9 ], [ 9, 9 ] };
 | 
			
		||||
        key <AB04> { [ plus, plus ], [ plus, plus ] };
 | 
			
		||||
        key <AB05> { [ minus, minus ], [ minus, minus ] };
 | 
			
		||||
        key <AB06> { [ 0, 0 ], [ 0, 0 ] };
 | 
			
		||||
        key <RTRN> { [ Return, Return ], [ Return, Return ] };
 | 
			
		||||
        key <SPCE> { [ space, space ], [ space, space ] };
 | 
			
		||||
        key <BKSP> { [ BackSpace, BackSpace ], [ BackSpace, BackSpace ] };
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    xkb_types "squeekboard" {
 | 
			
		||||
 | 
			
		||||
	type "TWO_LEVEL" {
 | 
			
		||||
            modifiers = Shift;
 | 
			
		||||
            map[Shift] = Level2;
 | 
			
		||||
            level_name[Level1] = "Base";
 | 
			
		||||
            level_name[Level2] = "Shift";
 | 
			
		||||
	};
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    xkb_compatibility "squeekboard" {
 | 
			
		||||
    };
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										306
									
								
								data/keyboards/keymaps/us.xkb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										306
									
								
								data/keyboards/keymaps/us.xkb
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,306 @@
 | 
			
		||||
xkb_keymap {
 | 
			
		||||
 | 
			
		||||
    xkb_keycodes "squeekboard" {
 | 
			
		||||
        minimum = 8;
 | 
			
		||||
        maximum = 255;
 | 
			
		||||
        <ESC>                = 9;
 | 
			
		||||
        <AE01>               = 10;
 | 
			
		||||
        <AE02>               = 11;
 | 
			
		||||
        <AE03>               = 12;
 | 
			
		||||
        <AE04>               = 13;
 | 
			
		||||
        <AE05>               = 14;
 | 
			
		||||
        <AE06>               = 15;
 | 
			
		||||
        <AE07>               = 16;
 | 
			
		||||
        <AE08>               = 17;
 | 
			
		||||
        <AE09>               = 18;
 | 
			
		||||
        <AE10>               = 19;
 | 
			
		||||
        <AE11>               = 20;
 | 
			
		||||
        <AE12>               = 21;
 | 
			
		||||
        <BKSP>               = 22;
 | 
			
		||||
        <TAB>                = 23;
 | 
			
		||||
        <AD01>               = 24;
 | 
			
		||||
        <AD02>               = 25;
 | 
			
		||||
        <AD03>               = 26;
 | 
			
		||||
        <AD04>               = 27;
 | 
			
		||||
        <AD05>               = 28;
 | 
			
		||||
        <AD06>               = 29;
 | 
			
		||||
        <AD07>               = 30;
 | 
			
		||||
        <AD08>               = 31;
 | 
			
		||||
        <AD09>               = 32;
 | 
			
		||||
        <AD10>               = 33;
 | 
			
		||||
        <AD11>               = 34;
 | 
			
		||||
        <AD12>               = 35;
 | 
			
		||||
        <RTRN>               = 36;
 | 
			
		||||
        <LCTL>               = 37;
 | 
			
		||||
        <AC01>               = 38;
 | 
			
		||||
        <AC02>               = 39;
 | 
			
		||||
        <AC03>               = 40;
 | 
			
		||||
        <AC04>               = 41;
 | 
			
		||||
        <AC05>               = 42;
 | 
			
		||||
        <AC06>               = 43;
 | 
			
		||||
        <AC07>               = 44;
 | 
			
		||||
        <AC08>               = 45;
 | 
			
		||||
        <AC09>               = 46;
 | 
			
		||||
        <AC10>               = 47;
 | 
			
		||||
        <AC11>               = 48;
 | 
			
		||||
        <TLDE>               = 49;
 | 
			
		||||
        <LFSH>               = 50;
 | 
			
		||||
        <BKSL>               = 51;
 | 
			
		||||
        <AB01>               = 52;
 | 
			
		||||
        <AB02>               = 53;
 | 
			
		||||
        <AB03>               = 54;
 | 
			
		||||
        <AB04>               = 55;
 | 
			
		||||
        <AB05>               = 56;
 | 
			
		||||
        <AB06>               = 57;
 | 
			
		||||
        <AB07>               = 58;
 | 
			
		||||
        <AB08>               = 59;
 | 
			
		||||
        <AB09>               = 60;
 | 
			
		||||
        <AB10>               = 61;
 | 
			
		||||
        <RTSH>               = 62;
 | 
			
		||||
        <KPMU>               = 63;
 | 
			
		||||
        <LALT>               = 64;
 | 
			
		||||
        <SPCE>               = 65;
 | 
			
		||||
        <CAPS>               = 66;
 | 
			
		||||
        <FK01>               = 67;
 | 
			
		||||
        <FK02>               = 68;
 | 
			
		||||
        <FK03>               = 69;
 | 
			
		||||
        <FK04>               = 70;
 | 
			
		||||
        <FK05>               = 71;
 | 
			
		||||
        <FK06>               = 72;
 | 
			
		||||
        <FK07>               = 73;
 | 
			
		||||
        <FK08>               = 74;
 | 
			
		||||
        <FK09>               = 75;
 | 
			
		||||
        <FK10>               = 76;
 | 
			
		||||
        <NMLK>               = 77;
 | 
			
		||||
        <SCLK>               = 78;
 | 
			
		||||
        <KP7>                = 79;
 | 
			
		||||
        <KP8>                = 80;
 | 
			
		||||
        <KP9>                = 81;
 | 
			
		||||
        <KPSU>               = 82;
 | 
			
		||||
        <KP4>                = 83;
 | 
			
		||||
        <KP5>                = 84;
 | 
			
		||||
        <KP6>                = 85;
 | 
			
		||||
        <KPAD>               = 86;
 | 
			
		||||
        <KP1>                = 87;
 | 
			
		||||
        <KP2>                = 88;
 | 
			
		||||
        <KP3>                = 89;
 | 
			
		||||
        <KP0>                = 90;
 | 
			
		||||
        <KPDL>               = 91;
 | 
			
		||||
        <LVL3>               = 92;
 | 
			
		||||
        <LSGT>               = 94;
 | 
			
		||||
        <FK11>               = 95;
 | 
			
		||||
        <FK12>               = 96;
 | 
			
		||||
        <AB11>               = 97;
 | 
			
		||||
        <KATA>               = 98;
 | 
			
		||||
        <HIRA>               = 99;
 | 
			
		||||
        <HENK>               = 100;
 | 
			
		||||
        <HKTG>               = 101;
 | 
			
		||||
        <MUHE>               = 102;
 | 
			
		||||
        <JPCM>               = 103;
 | 
			
		||||
        <KPEN>               = 104;
 | 
			
		||||
        <RCTL>               = 105;
 | 
			
		||||
        <KPDV>               = 106;
 | 
			
		||||
        <PRSC>               = 107;
 | 
			
		||||
        <RALT>               = 108;
 | 
			
		||||
        <LNFD>               = 109;
 | 
			
		||||
        <HOME>               = 110;
 | 
			
		||||
        <UP>                 = 111;
 | 
			
		||||
        <PGUP>               = 112;
 | 
			
		||||
        <LEFT>               = 113;
 | 
			
		||||
        <RGHT>               = 114;
 | 
			
		||||
        <END>                = 115;
 | 
			
		||||
        <DOWN>               = 116;
 | 
			
		||||
        <PGDN>               = 117;
 | 
			
		||||
        <INS>                = 118;
 | 
			
		||||
        <DELE>               = 119;
 | 
			
		||||
        <I120>               = 120;
 | 
			
		||||
        <MUTE>               = 121;
 | 
			
		||||
        <VOL->               = 122;
 | 
			
		||||
        <VOL+>               = 123;
 | 
			
		||||
        <POWR>               = 124;
 | 
			
		||||
        <KPEQ>               = 125;
 | 
			
		||||
        <I126>               = 126;
 | 
			
		||||
        <PAUS>               = 127;
 | 
			
		||||
        <I128>               = 128;
 | 
			
		||||
        <I129>               = 129;
 | 
			
		||||
        <HNGL>               = 130;
 | 
			
		||||
        <HJCV>               = 131;
 | 
			
		||||
        <AE13>               = 132;
 | 
			
		||||
        <LWIN>               = 133;
 | 
			
		||||
        <RWIN>               = 134;
 | 
			
		||||
        <COMP>               = 135;
 | 
			
		||||
        <STOP>               = 136;
 | 
			
		||||
        <AGAI>               = 137;
 | 
			
		||||
        <PROP>               = 138;
 | 
			
		||||
        <UNDO>               = 139;
 | 
			
		||||
        <FRNT>               = 140;
 | 
			
		||||
        <COPY>               = 141;
 | 
			
		||||
        <OPEN>               = 142;
 | 
			
		||||
        <PAST>               = 143;
 | 
			
		||||
        <FIND>               = 144;
 | 
			
		||||
        <CUT>                = 145;
 | 
			
		||||
        <HELP>               = 146;
 | 
			
		||||
        <I147>               = 147;
 | 
			
		||||
        <I148>               = 148;
 | 
			
		||||
        <I149>               = 149;
 | 
			
		||||
        <I150>               = 150;
 | 
			
		||||
        <I151>               = 151;
 | 
			
		||||
        <I152>               = 152;
 | 
			
		||||
        <I153>               = 153;
 | 
			
		||||
        <I154>               = 154;
 | 
			
		||||
        <I155>               = 155;
 | 
			
		||||
        <I156>               = 156;
 | 
			
		||||
        <I157>               = 157;
 | 
			
		||||
        <I158>               = 158;
 | 
			
		||||
        <I159>               = 159;
 | 
			
		||||
        <I160>               = 160;
 | 
			
		||||
        <I161>               = 161;
 | 
			
		||||
        <I162>               = 162;
 | 
			
		||||
        <I163>               = 163;
 | 
			
		||||
        <I164>               = 164;
 | 
			
		||||
        <I165>               = 165;
 | 
			
		||||
        <I166>               = 166;
 | 
			
		||||
        <I167>               = 167;
 | 
			
		||||
        <I168>               = 168;
 | 
			
		||||
        <I169>               = 169;
 | 
			
		||||
        <I170>               = 170;
 | 
			
		||||
        <I171>               = 171;
 | 
			
		||||
        <I172>               = 172;
 | 
			
		||||
        <I173>               = 173;
 | 
			
		||||
        <I174>               = 174;
 | 
			
		||||
        <I175>               = 175;
 | 
			
		||||
        <I176>               = 176;
 | 
			
		||||
        <I177>               = 177;
 | 
			
		||||
        <I178>               = 178;
 | 
			
		||||
        <I179>               = 179;
 | 
			
		||||
        <I180>               = 180;
 | 
			
		||||
        <I181>               = 181;
 | 
			
		||||
        <I182>               = 182;
 | 
			
		||||
        <I183>               = 183;
 | 
			
		||||
        <I184>               = 184;
 | 
			
		||||
        <I185>               = 185;
 | 
			
		||||
        <I186>               = 186;
 | 
			
		||||
        <I187>               = 187;
 | 
			
		||||
        <I188>               = 188;
 | 
			
		||||
        <I189>               = 189;
 | 
			
		||||
        <I190>               = 190;
 | 
			
		||||
        <FK13>               = 191;
 | 
			
		||||
        <FK14>               = 192;
 | 
			
		||||
        <FK15>               = 193;
 | 
			
		||||
        <FK16>               = 194;
 | 
			
		||||
        <FK17>               = 195;
 | 
			
		||||
        <FK18>               = 196;
 | 
			
		||||
        <FK19>               = 197;
 | 
			
		||||
        <FK20>               = 198;
 | 
			
		||||
        <FK21>               = 199;
 | 
			
		||||
        <FK22>               = 200;
 | 
			
		||||
        <FK23>               = 201;
 | 
			
		||||
        <FK24>               = 202;
 | 
			
		||||
        <MDSW>               = 203;
 | 
			
		||||
        <ALT>                = 204;
 | 
			
		||||
        <META>               = 205;
 | 
			
		||||
        <SUPR>               = 206;
 | 
			
		||||
        <HYPR>               = 207;
 | 
			
		||||
        <I208>               = 208;
 | 
			
		||||
        <I209>               = 209;
 | 
			
		||||
        <I210>               = 210;
 | 
			
		||||
        <I211>               = 211;
 | 
			
		||||
        <I212>               = 212;
 | 
			
		||||
        <I213>               = 213;
 | 
			
		||||
        <I214>               = 214;
 | 
			
		||||
        <I215>               = 215;
 | 
			
		||||
        <I216>               = 216;
 | 
			
		||||
        <I217>               = 217;
 | 
			
		||||
        <I218>               = 218;
 | 
			
		||||
        <I219>               = 219;
 | 
			
		||||
        <I220>               = 220;
 | 
			
		||||
        <I221>               = 221;
 | 
			
		||||
        <I222>               = 222;
 | 
			
		||||
        <I223>               = 223;
 | 
			
		||||
        <I224>               = 224;
 | 
			
		||||
        <I225>               = 225;
 | 
			
		||||
        <I226>               = 226;
 | 
			
		||||
        <I227>               = 227;
 | 
			
		||||
        <I228>               = 228;
 | 
			
		||||
        <I229>               = 229;
 | 
			
		||||
        <I230>               = 230;
 | 
			
		||||
        <I231>               = 231;
 | 
			
		||||
        <I232>               = 232;
 | 
			
		||||
        <I233>               = 233;
 | 
			
		||||
        <I234>               = 234;
 | 
			
		||||
        <I235>               = 235;
 | 
			
		||||
        <I236>               = 236;
 | 
			
		||||
        <I237>               = 237;
 | 
			
		||||
        <I238>               = 238;
 | 
			
		||||
        <I239>               = 239;
 | 
			
		||||
        <I240>               = 240;
 | 
			
		||||
        <I241>               = 241;
 | 
			
		||||
        <I242>               = 242;
 | 
			
		||||
        <I243>               = 243;
 | 
			
		||||
        <I244>               = 244;
 | 
			
		||||
        <I245>               = 245;
 | 
			
		||||
        <I246>               = 246;
 | 
			
		||||
        <I247>               = 247;
 | 
			
		||||
        <I248>               = 248;
 | 
			
		||||
        <I249>               = 249;
 | 
			
		||||
        <I250>               = 250;
 | 
			
		||||
        <I251>               = 251;
 | 
			
		||||
        <I252>               = 252;
 | 
			
		||||
        <I253>               = 253;
 | 
			
		||||
        <I254>               = 254;
 | 
			
		||||
        <I255>               = 255;
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    xkb_symbols "squeekboard" {
 | 
			
		||||
 | 
			
		||||
        name[Group1] = "Letters";
 | 
			
		||||
        name[Group2] = "Numbers/Symbols";
 | 
			
		||||
 | 
			
		||||
        key <AD01> { [ q, Q ], [ 1, asciitilde ] };
 | 
			
		||||
        key <AD02> { [ w, W ], [ 2, quoteleft ] };
 | 
			
		||||
        key <AD03> { [ e, E ], [ 3, bar ] };
 | 
			
		||||
        key <AD04> { [ r, R ], [ 4, U00B7 ] };
 | 
			
		||||
        key <AD05> { [ t, T ], [ 5, squareroot ] };
 | 
			
		||||
        key <AD06> { [ y, Y ], [ 6, Greek_pi ] };
 | 
			
		||||
        key <AD07> { [ u, U ], [ 7, division ] };
 | 
			
		||||
        key <AD08> { [ i, I ], [ 8, multiply ] };
 | 
			
		||||
        key <AD09> { [ o, O ], [ 9, paragraph ] };
 | 
			
		||||
        key <AD10> { [ p, P ], [ 0, U25B3 ] };
 | 
			
		||||
        key <AC01> { [ a, A ], [ at, copyright ] };
 | 
			
		||||
        key <AC02> { [ s, S ], [ numbersign, U00AE ] };
 | 
			
		||||
        key <AC03> { [ d, D ], [ dollar, U00A3 ] };
 | 
			
		||||
        key <AC04> { [ f, F ], [ percent, EuroSign ] };
 | 
			
		||||
        key <AC05> { [ g, G ], [ ampersand, U00A5 ] };
 | 
			
		||||
        key <AC06> { [ h, H ], [ minus, asciicircum ] };
 | 
			
		||||
        key <AC07> { [ j, J ], [ underscore, degree ] };
 | 
			
		||||
        key <AC08> { [ k, K ], [ plus, equal ] };
 | 
			
		||||
        key <AC09> { [ l, L ], [ parenleft, braceleft ] };
 | 
			
		||||
        key <AC10> { [   ], [ parenright, braceright ] };
 | 
			
		||||
        key <RTRN> { [ Return, Return ], [ Return, Return ] };
 | 
			
		||||
        key <LFSH> { [ Shift_L, Shift_L ], [ Shift_L, Shift_L ] };
 | 
			
		||||
        key <AB01> { [ z, Z ], [ comma, backslash ] };
 | 
			
		||||
        key <AB02> { [ x, X ], [ quotedbl, slash ] };
 | 
			
		||||
        key <AB03> { [ c, C ], [ quoteright, less ] };
 | 
			
		||||
        key <AB04> { [ v, V ], [ colon, greater ] };
 | 
			
		||||
        key <AB05> { [ b, B ], [ semicolon, equal ] };
 | 
			
		||||
        key <AB06> { [ n, N ], [ exclam, bracketleft ] };
 | 
			
		||||
        key <AB07> { [ m, M ], [ question, bracketright ] };
 | 
			
		||||
        key <AB08> { [ period, period ], [ period, period ] };
 | 
			
		||||
        key <I149> { [ preferences, preferences ], [ preferences, preferences ] };
 | 
			
		||||
        key <SPCE> { [ space, space ], [ space, space ] };
 | 
			
		||||
        key <BKSP> { [ BackSpace, BackSpace ], [ BackSpace, BackSpace ] };
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    xkb_types "squeekboard" {
 | 
			
		||||
 | 
			
		||||
	type "TWO_LEVEL" {
 | 
			
		||||
            modifiers = Shift;
 | 
			
		||||
            map[Shift] = Level2;
 | 
			
		||||
            level_name[Level1] = "Base";
 | 
			
		||||
            level_name[Level2] = "Shift";
 | 
			
		||||
	};
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    xkb_compatibility "squeekboard" {
 | 
			
		||||
    };
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										204
									
								
								data/keyboards/symbols/nb.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										204
									
								
								data/keyboards/symbols/nb.xml
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,204 @@
 | 
			
		||||
<?xml version='1.0' encoding='ASCII' standalone='yes'?>
 | 
			
		||||
<symbols version="0.90">
 | 
			
		||||
  <key name="AD01">
 | 
			
		||||
    <symbol label="q">q</symbol>
 | 
			
		||||
    <symbol label="Q">Q</symbol>
 | 
			
		||||
    <symbol label="1">1</symbol>
 | 
			
		||||
    <symbol label="~">asciitilde</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AD02">
 | 
			
		||||
    <symbol label="w">w</symbol>
 | 
			
		||||
    <symbol label="W">W</symbol>
 | 
			
		||||
    <symbol label="2">2</symbol>
 | 
			
		||||
    <symbol label="`">quoteleft</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AD03">
 | 
			
		||||
    <symbol label="e">e</symbol>
 | 
			
		||||
    <symbol label="E">E</symbol>
 | 
			
		||||
    <symbol label="3">3</symbol>
 | 
			
		||||
    <symbol label="|">bar</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AD04">
 | 
			
		||||
    <symbol label="r">r</symbol>
 | 
			
		||||
    <symbol label="R">R</symbol>
 | 
			
		||||
    <symbol label="4">4</symbol>
 | 
			
		||||
    <symbol label="·">U00B7</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AD05">
 | 
			
		||||
    <symbol label="t">t</symbol>
 | 
			
		||||
    <symbol label="T">T</symbol>
 | 
			
		||||
    <symbol label="5">5</symbol>
 | 
			
		||||
    <symbol label="√">squareroot</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AD06">
 | 
			
		||||
    <symbol label="y">y</symbol>
 | 
			
		||||
    <symbol label="Y">Y</symbol>
 | 
			
		||||
    <symbol label="6">6</symbol>
 | 
			
		||||
    <symbol label="π">Greek_pi</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AD07">
 | 
			
		||||
    <symbol label="u">u</symbol>
 | 
			
		||||
    <symbol label="U">U</symbol>
 | 
			
		||||
    <symbol label="7">7</symbol>
 | 
			
		||||
    <symbol label="÷">division</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AD08">
 | 
			
		||||
    <symbol label="i">i</symbol>
 | 
			
		||||
    <symbol label="I">I</symbol>
 | 
			
		||||
    <symbol label="8">8</symbol>
 | 
			
		||||
    <symbol label="×">multiply</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AD09">
 | 
			
		||||
    <symbol label="o">o</symbol>
 | 
			
		||||
    <symbol label="O">O</symbol>
 | 
			
		||||
    <symbol label="9">9</symbol>
 | 
			
		||||
    <symbol label="¶">paragraph</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AD10">
 | 
			
		||||
    <symbol label="p">p</symbol>
 | 
			
		||||
    <symbol label="P">P</symbol>
 | 
			
		||||
    <symbol label="0">0</symbol>
 | 
			
		||||
    <symbol label="△">U25B3</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AD11">
 | 
			
		||||
    <symbol keyval="229" label="å">aring</symbol>
 | 
			
		||||
    <symbol keyval="197" label="Å">Aring</symbol>
 | 
			
		||||
    <symbol label="±">U00B1</symbol>
 | 
			
		||||
    <symbol label="§">U00A7</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AC01">
 | 
			
		||||
    <symbol label="a">a</symbol>
 | 
			
		||||
    <symbol label="A">A</symbol>
 | 
			
		||||
    <symbol label="@">at</symbol>
 | 
			
		||||
    <symbol label="©">copyright</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AC02">
 | 
			
		||||
    <symbol label="s">s</symbol>
 | 
			
		||||
    <symbol label="S">S</symbol>
 | 
			
		||||
    <symbol label="#">numbersign</symbol>
 | 
			
		||||
    <symbol label="®">U00AE</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AC03">
 | 
			
		||||
    <symbol label="d">d</symbol>
 | 
			
		||||
    <symbol label="D">D</symbol>
 | 
			
		||||
    <symbol label="$">dollar</symbol>
 | 
			
		||||
    <symbol label="£">U00A3</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AC04">
 | 
			
		||||
    <symbol label="f">f</symbol>
 | 
			
		||||
    <symbol label="F">F</symbol>
 | 
			
		||||
    <symbol label="%">percent</symbol>
 | 
			
		||||
    <symbol label="€">EuroSign</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AC05">
 | 
			
		||||
    <symbol label="g">g</symbol>
 | 
			
		||||
    <symbol label="G">G</symbol>
 | 
			
		||||
    <symbol label="&">ampersand</symbol>
 | 
			
		||||
    <symbol label="¥">U00A5</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AC06">
 | 
			
		||||
    <symbol label="h">h</symbol>
 | 
			
		||||
    <symbol label="H">H</symbol>
 | 
			
		||||
    <symbol label="-">minus</symbol>
 | 
			
		||||
    <symbol label="_">underscore</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AC07">
 | 
			
		||||
    <symbol label="j">j</symbol>
 | 
			
		||||
    <symbol label="J">J</symbol>
 | 
			
		||||
    <symbol label="+">plus</symbol>
 | 
			
		||||
    <symbol label="=">equal</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AC08">
 | 
			
		||||
    <symbol label="k">k</symbol>
 | 
			
		||||
    <symbol label="K">K</symbol>
 | 
			
		||||
    <symbol label="ü">U00FC</symbol>
 | 
			
		||||
    <symbol label="^">asciicircum</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AC09">
 | 
			
		||||
    <symbol label="l">l</symbol>
 | 
			
		||||
    <symbol label="L">L</symbol>
 | 
			
		||||
    <symbol label="ö">U00F6</symbol>
 | 
			
		||||
    <symbol label="°">degree</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AC10">
 | 
			
		||||
    <symbol keyval="248" label="ø">oslash</symbol>
 | 
			
		||||
    <symbol keyval="216" label="Ø">Oslash</symbol>
 | 
			
		||||
    <symbol label="(">parenleft</symbol>
 | 
			
		||||
    <symbol label="{">braceleft</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AC11">
 | 
			
		||||
    <symbol keyval="230" label="æ">ae</symbol>
 | 
			
		||||
    <symbol keyval="198" label="Æ">AE</symbol>
 | 
			
		||||
    <symbol label=")">parenright</symbol>
 | 
			
		||||
    <symbol label="}">braceright</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="RTRN">
 | 
			
		||||
    <symbol keyval="65293" icon="key-enter">Return</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="LFSH">
 | 
			
		||||
    <keysym keyval="65505" icon="key-shift">Shift_L</keysym>
 | 
			
		||||
    <keysym keyval="65505" icon="key-shift">Shift_L</keysym>
 | 
			
		||||
    <keysym keyval="65505" label="=/+">Shift_L</keysym>
 | 
			
		||||
    <keysym keyval="65505" label="123">Shift_L</keysym>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AB01">
 | 
			
		||||
    <symbol label="z">z</symbol>
 | 
			
		||||
    <symbol label="Z">Z</symbol>
 | 
			
		||||
    <symbol label=",">comma</symbol>
 | 
			
		||||
    <symbol label="\">backslash</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AB02">
 | 
			
		||||
    <symbol label="x">x</symbol>
 | 
			
		||||
    <symbol label="X">X</symbol>
 | 
			
		||||
    <symbol label=""">quotedbl</symbol>
 | 
			
		||||
    <symbol label="/">slash</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AB03">
 | 
			
		||||
    <symbol label="c">c</symbol>
 | 
			
		||||
    <symbol label="C">C</symbol>
 | 
			
		||||
    <symbol label="'">quoteright</symbol>
 | 
			
		||||
    <symbol label="<">less</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AB04">
 | 
			
		||||
    <symbol label="v">v</symbol>
 | 
			
		||||
    <symbol label="V">V</symbol>
 | 
			
		||||
    <symbol label=":">colon</symbol>
 | 
			
		||||
    <symbol label=">">greater</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AB05">
 | 
			
		||||
    <symbol label="b">b</symbol>
 | 
			
		||||
    <symbol label="B">B</symbol>
 | 
			
		||||
    <symbol label=";">semicolon</symbol>
 | 
			
		||||
    <symbol label="=">equal</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AB06">
 | 
			
		||||
    <symbol label="n">n</symbol>
 | 
			
		||||
    <symbol label="N">N</symbol>
 | 
			
		||||
    <symbol label="!">exclam</symbol>
 | 
			
		||||
    <symbol label="[">bracketleft</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AB07">
 | 
			
		||||
    <symbol label="m">m</symbol>
 | 
			
		||||
    <symbol label="M">M</symbol>
 | 
			
		||||
    <symbol label="?">question</symbol>
 | 
			
		||||
    <symbol label="]">bracketright</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AB08">
 | 
			
		||||
    <symbol label=".">period</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="ABC123">
 | 
			
		||||
    <symbol label="123">show-numbers</symbol>
 | 
			
		||||
    <symbol label="123">show-numbers</symbol>
 | 
			
		||||
    <symbol label="ABC">show-letters</symbol>
 | 
			
		||||
    <symbol label="ABC">show-letters</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="I149">
 | 
			
		||||
    <symbol icon="keyboard-mode-symbolic" tooltip="Setup">preferences</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="SPCE">
 | 
			
		||||
    <symbol label=" ">space</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="BKSP">
 | 
			
		||||
    <symbol keyval="65288" icon="edit-clear-symbolic">BackSpace</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
</symbols>
 | 
			
		||||
							
								
								
									
										60
									
								
								data/keyboards/symbols/special/numbers.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										60
									
								
								data/keyboards/symbols/special/numbers.xml
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,60 @@
 | 
			
		||||
<?xml version='1.0' encoding='ASCII' standalone='yes'?>
 | 
			
		||||
<symbols version="0.90">
 | 
			
		||||
  <key name="AD01">
 | 
			
		||||
    <symbol label="1">1</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AD02">
 | 
			
		||||
    <symbol label="2">2</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AD03">
 | 
			
		||||
    <symbol label="3">3</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AD04">
 | 
			
		||||
    <symbol label="(">parenleft</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AD05">
 | 
			
		||||
    <symbol label=")">parenright</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AC01">
 | 
			
		||||
    <symbol label="4">4</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AC02">
 | 
			
		||||
    <symbol label="5">5</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AC03">
 | 
			
		||||
    <symbol label="6">6</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AC04">
 | 
			
		||||
    <symbol label="#">numbersign</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AC05">
 | 
			
		||||
    <symbol label="*">asterisk</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AB01">
 | 
			
		||||
    <symbol label="7">7</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AB02">
 | 
			
		||||
    <symbol label="8">8</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AB03">
 | 
			
		||||
    <symbol label="9">9</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AB04">
 | 
			
		||||
    <symbol label="+">plus</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AB05">
 | 
			
		||||
    <symbol label="-">minus</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="AB06">
 | 
			
		||||
    <symbol label="0">0</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="RTRN">
 | 
			
		||||
    <symbol keyval="65293" icon="key-enter">Return</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="SPCE">
 | 
			
		||||
    <symbol label=" ">space</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key name="BKSP">
 | 
			
		||||
    <symbol keyval="65288" icon="edit-clear-symbolic">BackSpace</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
</symbols>
 | 
			
		||||
@ -1,276 +1,192 @@
 | 
			
		||||
<?xml version="1.0"?>
 | 
			
		||||
<?xml version='1.0' encoding='ASCII' standalone='yes'?>
 | 
			
		||||
<symbols version="0.90">
 | 
			
		||||
  <key keycode="9" name="ESC">
 | 
			
		||||
    <keysym keyval="65307">Escape</keysym>
 | 
			
		||||
  <key name="AD01">
 | 
			
		||||
    <symbol label="q">q</symbol>
 | 
			
		||||
    <symbol label="Q">Q</symbol>
 | 
			
		||||
    <symbol label="1">1</symbol>
 | 
			
		||||
    <symbol label="~">asciitilde</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key keycode="67" name="FK01">
 | 
			
		||||
    <keysym keyval="65470">F1</keysym>
 | 
			
		||||
  <key name="AD02">
 | 
			
		||||
    <symbol label="w">w</symbol>
 | 
			
		||||
    <symbol label="W">W</symbol>
 | 
			
		||||
    <symbol label="2">2</symbol>
 | 
			
		||||
    <symbol label="`">quoteleft</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key keycode="68" name="FK02">
 | 
			
		||||
    <keysym keyval="65471">F2</keysym>
 | 
			
		||||
  <key name="AD03">
 | 
			
		||||
    <symbol label="e">e</symbol>
 | 
			
		||||
    <symbol label="E">E</symbol>
 | 
			
		||||
    <symbol label="3">3</symbol>
 | 
			
		||||
    <symbol label="|">bar</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key keycode="69" name="FK03">
 | 
			
		||||
    <keysym keyval="65472">F3</keysym>
 | 
			
		||||
  <key name="AD04">
 | 
			
		||||
    <symbol label="r">r</symbol>
 | 
			
		||||
    <symbol label="R">R</symbol>
 | 
			
		||||
    <symbol label="4">4</symbol>
 | 
			
		||||
    <symbol label="·">U00B7</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key keycode="70" name="FK04">
 | 
			
		||||
    <keysym keyval="65473">F4</keysym>
 | 
			
		||||
  <key name="AD05">
 | 
			
		||||
    <symbol label="t">t</symbol>
 | 
			
		||||
    <symbol label="T">T</symbol>
 | 
			
		||||
    <symbol label="5">5</symbol>
 | 
			
		||||
    <symbol label="√">squareroot</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key keycode="71" name="FK05">
 | 
			
		||||
    <keysym keyval="65474">F5</keysym>
 | 
			
		||||
  <key name="AD06">
 | 
			
		||||
    <symbol label="y">y</symbol>
 | 
			
		||||
    <symbol label="Y">Y</symbol>
 | 
			
		||||
    <symbol label="6">6</symbol>
 | 
			
		||||
    <symbol label="π">Greek_pi</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key keycode="72" name="FK06">
 | 
			
		||||
    <keysym keyval="65475">F6</keysym>
 | 
			
		||||
  <key name="AD07">
 | 
			
		||||
    <symbol label="u">u</symbol>
 | 
			
		||||
    <symbol label="U">U</symbol>
 | 
			
		||||
    <symbol label="7">7</symbol>
 | 
			
		||||
    <symbol label="÷">division</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key keycode="73" name="FK07">
 | 
			
		||||
    <keysym keyval="65476">F7</keysym>
 | 
			
		||||
  <key name="AD08">
 | 
			
		||||
    <symbol label="i">i</symbol>
 | 
			
		||||
    <symbol label="I">I</symbol>
 | 
			
		||||
    <symbol label="8">8</symbol>
 | 
			
		||||
    <symbol label="×">multiply</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key keycode="74" name="FK08">
 | 
			
		||||
    <keysym keyval="65477">F8</keysym>
 | 
			
		||||
  <key name="AD09">
 | 
			
		||||
    <symbol label="o">o</symbol>
 | 
			
		||||
    <symbol label="O">O</symbol>
 | 
			
		||||
    <symbol label="9">9</symbol>
 | 
			
		||||
    <symbol label="¶">paragraph</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key keycode="75" name="FK09">
 | 
			
		||||
    <keysym keyval="65478">F9</keysym>
 | 
			
		||||
  <key name="AD10">
 | 
			
		||||
    <symbol label="p">p</symbol>
 | 
			
		||||
    <symbol label="P">P</symbol>
 | 
			
		||||
    <symbol label="0">0</symbol>
 | 
			
		||||
    <symbol label="△">U25B3</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key keycode="76" name="FK10">
 | 
			
		||||
    <keysym keyval="65479">F10</keysym>
 | 
			
		||||
  <key name="AC01">
 | 
			
		||||
    <symbol label="a">a</symbol>
 | 
			
		||||
    <symbol label="A">A</symbol>
 | 
			
		||||
    <symbol label="@">at</symbol>
 | 
			
		||||
    <symbol label="©">copyright</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key keycode="95" name="FK11">
 | 
			
		||||
    <keysym keyval="65480">F11</keysym>
 | 
			
		||||
  <key name="AC02">
 | 
			
		||||
    <symbol label="s">s</symbol>
 | 
			
		||||
    <symbol label="S">S</symbol>
 | 
			
		||||
    <symbol label="#">numbersign</symbol>
 | 
			
		||||
    <symbol label="®">U00AE</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key keycode="96" name="FK12">
 | 
			
		||||
    <keysym keyval="65481">F12</keysym>
 | 
			
		||||
  <key name="AC03">
 | 
			
		||||
    <symbol label="d">d</symbol>
 | 
			
		||||
    <symbol label="D">D</symbol>
 | 
			
		||||
    <symbol label="$">dollar</symbol>
 | 
			
		||||
    <symbol label="£">U00A3</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key keycode="22" name="BKSP">
 | 
			
		||||
    <keysym keyval="65288" icon="edit-clear-symbolic">backspace</keysym>
 | 
			
		||||
  <key name="AC04">
 | 
			
		||||
    <symbol label="f">f</symbol>
 | 
			
		||||
    <symbol label="F">F</symbol>
 | 
			
		||||
    <symbol label="%">percent</symbol>
 | 
			
		||||
    <symbol label="€">EuroSign</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key keycode="23" name="TAB">
 | 
			
		||||
    <keysym keyval="65289">Tab</keysym>
 | 
			
		||||
    <keysym keyval="65056">ISO_Left_Tab</keysym>
 | 
			
		||||
  <key name="AC05">
 | 
			
		||||
    <symbol label="g">g</symbol>
 | 
			
		||||
    <symbol label="G">G</symbol>
 | 
			
		||||
    <symbol label="&">ampersand</symbol>
 | 
			
		||||
    <symbol label="¥">U00A5</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key keycode="24" name="AD01">
 | 
			
		||||
    <keysym keyval="113">q</keysym>
 | 
			
		||||
    <keysym keyval="81">Q</keysym>
 | 
			
		||||
    <keysym keyval="49">1</keysym>
 | 
			
		||||
    <keysym keyval="126">asciitilde</keysym>
 | 
			
		||||
  <key name="AC06">
 | 
			
		||||
    <symbol label="h">h</symbol>
 | 
			
		||||
    <symbol label="H">H</symbol>
 | 
			
		||||
    <symbol label="-">minus</symbol>
 | 
			
		||||
    <symbol label="^">asciicircum</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key keycode="25" name="AD02">
 | 
			
		||||
    <keysym keyval="119">w</keysym>
 | 
			
		||||
    <keysym keyval="87">W</keysym>
 | 
			
		||||
    <keysym keyval="50">2</keysym>
 | 
			
		||||
    <keysym keyval="96">quoteleft</keysym>
 | 
			
		||||
  <key name="AC07">
 | 
			
		||||
    <symbol label="j">j</symbol>
 | 
			
		||||
    <symbol label="J">J</symbol>
 | 
			
		||||
    <symbol label="_">underscore</symbol>
 | 
			
		||||
    <symbol label="°">degree</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key keycode="26" name="AD03">
 | 
			
		||||
    <keysym keyval="101">e</keysym>
 | 
			
		||||
    <keysym keyval="69">E</keysym>
 | 
			
		||||
    <keysym keyval="51">3</keysym>
 | 
			
		||||
    <keysym keyval="124">bar</keysym>
 | 
			
		||||
  <key name="AC08">
 | 
			
		||||
    <symbol label="k">k</symbol>
 | 
			
		||||
    <symbol label="K">K</symbol>
 | 
			
		||||
    <symbol label="+">plus</symbol>
 | 
			
		||||
    <symbol label="=">equal</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key keycode="27" name="AD04">
 | 
			
		||||
    <keysym keyval="114">r</keysym>
 | 
			
		||||
    <keysym keyval="82">R</keysym>
 | 
			
		||||
    <keysym keyval="52">4</keysym>
 | 
			
		||||
    <keysym keyval="183">middledot</keysym>
 | 
			
		||||
  <key name="AC09">
 | 
			
		||||
    <symbol label="l">l</symbol>
 | 
			
		||||
    <symbol label="L">L</symbol>
 | 
			
		||||
    <symbol label="(">parenleft</symbol>
 | 
			
		||||
    <symbol label="{">braceleft</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key keycode="28" name="AD05">
 | 
			
		||||
    <keysym keyval="116">t</keysym>
 | 
			
		||||
    <keysym keyval="84">T</keysym>
 | 
			
		||||
    <keysym keyval="53">5</keysym>
 | 
			
		||||
  <key name="AC10">
 | 
			
		||||
    <symbol label=""></symbol>
 | 
			
		||||
    <symbol label=""></symbol>
 | 
			
		||||
    <symbol label=")">parenright</symbol>
 | 
			
		||||
    <symbol label="}">braceright</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key keycode="29" name="AD06">
 | 
			
		||||
    <keysym keyval="121">y</keysym>
 | 
			
		||||
    <keysym keyval="89">Y</keysym>
 | 
			
		||||
    <keysym keyval="54">6</keysym>
 | 
			
		||||
  <key name="RTRN">
 | 
			
		||||
    <symbol keyval="65293" icon="key-enter">Return</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key keycode="30" name="AD07">
 | 
			
		||||
    <keysym keyval="117">u</keysym>
 | 
			
		||||
    <keysym keyval="85">U</keysym>
 | 
			
		||||
    <keysym keyval="55">7</keysym>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key keycode="31" name="AD08">
 | 
			
		||||
    <keysym keyval="105">i</keysym>
 | 
			
		||||
    <keysym keyval="73">I</keysym>
 | 
			
		||||
    <keysym keyval="56">8</keysym>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key keycode="32" name="AD09">
 | 
			
		||||
    <keysym keyval="111">o</keysym>
 | 
			
		||||
    <keysym keyval="79">O</keysym>
 | 
			
		||||
    <keysym keyval="57">9</keysym>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key keycode="33" name="AD10">
 | 
			
		||||
    <keysym keyval="112">p</keysym>
 | 
			
		||||
    <keysym keyval="80">P</keysym>
 | 
			
		||||
    <keysym keyval="48">0</keysym>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key keycode="34" name="AD11">
 | 
			
		||||
    <keysym keyval="91">bracketleft</keysym>
 | 
			
		||||
    <keysym keyval="123">braceleft</keysym>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key keycode="35" name="AD12">
 | 
			
		||||
    <keysym keyval="93">bracketright</keysym>
 | 
			
		||||
    <keysym keyval="125">braceright</keysym>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key keycode="51" name="BKSL">
 | 
			
		||||
    <keysym keyval="92">backslash</keysym>
 | 
			
		||||
    <keysym keyval="124">bar</keysym>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key keycode="0" name="ABC123">
 | 
			
		||||
    <symbol label="123">show-numbers</symbol>
 | 
			
		||||
    <symbol label="123">show-numbers</symbol>
 | 
			
		||||
    <symbol label="ABC">show-letters</symbol>
 | 
			
		||||
    <symbol label="ABC">show-letters</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key keycode="38" name="AC01">
 | 
			
		||||
    <keysym keyval="97">a</keysym>
 | 
			
		||||
    <keysym keyval="65">A</keysym>
 | 
			
		||||
    <keysym keyval="64">at</keysym>
 | 
			
		||||
    <keysym keyval="169">copyright</keysym>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key keycode="39" name="AC02">
 | 
			
		||||
    <keysym keyval="115">s</keysym>
 | 
			
		||||
    <keysym keyval="83">S</keysym>
 | 
			
		||||
    <keysym keyval="35">numbersign</keysym>
 | 
			
		||||
    <keysym keyval="174">registeredtrademark</keysym>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key keycode="40" name="AC03">
 | 
			
		||||
    <keysym keyval="100">d</keysym>
 | 
			
		||||
    <keysym keyval="68">D</keysym>
 | 
			
		||||
    <keysym keyval="36">dollar</keysym>
 | 
			
		||||
    <keysym keyval="163">poundsign</keysym>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key keycode="41" name="AC04">
 | 
			
		||||
    <keysym keyval="102">f</keysym>
 | 
			
		||||
    <keysym keyval="70">F</keysym>
 | 
			
		||||
    <keysym keyval="37">percent</keysym>
 | 
			
		||||
    <text>€</text>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key keycode="42" name="AC05">
 | 
			
		||||
    <keysym keyval="103">g</keysym>
 | 
			
		||||
    <keysym keyval="71">G</keysym>
 | 
			
		||||
    <keysym keyval="38">ampersand</keysym>
 | 
			
		||||
    <keysym keyval="165">yensign</keysym>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key keycode="43" name="AC06">
 | 
			
		||||
    <keysym keyval="104">h</keysym>
 | 
			
		||||
    <keysym keyval="72">H</keysym>
 | 
			
		||||
    <keysym keyval="45">minus</keysym>
 | 
			
		||||
    <keysym keyval="94">asciicircum</keysym>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key keycode="44" name="AC07">
 | 
			
		||||
    <keysym keyval="106">j</keysym>
 | 
			
		||||
    <keysym keyval="74">J</keysym>
 | 
			
		||||
    <keysym keyval="43">plus</keysym>
 | 
			
		||||
    <keysym keyval="176">degreesign</keysym>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key keycode="45" name="AC08">
 | 
			
		||||
    <keysym keyval="107">k</keysym>
 | 
			
		||||
    <keysym keyval="75">K</keysym>
 | 
			
		||||
    <keysym keyval="40">parenleft</keysym>
 | 
			
		||||
    <keysym keyval="123">braceleft</keysym>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key keycode="46" name="AC09">
 | 
			
		||||
    <keysym keyval="108">l</keysym>
 | 
			
		||||
    <keysym keyval="76">L</keysym>
 | 
			
		||||
    <keysym keyval="41">parenright</keysym>
 | 
			
		||||
    <keysym keyval="125">braceright</keysym>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key keycode="47" name="AC10">
 | 
			
		||||
    <keysym keyval="59">semicolon</keysym>
 | 
			
		||||
    <keysym keyval="58">colon</keysym>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key keycode="48" name="AC11">
 | 
			
		||||
    <keysym keyval="39">quoteright</keysym>
 | 
			
		||||
    <keysym keyval="34">quotedbl</keysym>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key keycode="36" name="RTRN">
 | 
			
		||||
    <keysym keyval="65293" icon="key-enter">Return</keysym>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key keycode="50" name="LFSH">
 | 
			
		||||
  <key name="LFSH">
 | 
			
		||||
    <keysym keyval="65505" icon="key-shift">Shift_L</keysym>
 | 
			
		||||
    <keysym keyval="65505" icon="key-shift">Shift_L</keysym>
 | 
			
		||||
    <keysym keyval="65505" label="=/+">Shift_L</keysym>
 | 
			
		||||
    <keysym keyval="65505" label="123">Shift_L</keysym>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key keycode="52" name="AB01">
 | 
			
		||||
    <keysym keyval="122">z</keysym>
 | 
			
		||||
    <keysym keyval="90">Z</keysym>
 | 
			
		||||
    <keysym keyval="44">comma</keysym>
 | 
			
		||||
    <keysym keyval="92">backslash</keysym>
 | 
			
		||||
  <key name="AB01">
 | 
			
		||||
    <symbol label="z">z</symbol>
 | 
			
		||||
    <symbol label="Z">Z</symbol>
 | 
			
		||||
    <symbol label=",">comma</symbol>
 | 
			
		||||
    <symbol label="\">backslash</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key keycode="53" name="AB02">
 | 
			
		||||
    <keysym keyval="120">x</keysym>
 | 
			
		||||
    <keysym keyval="88">X</keysym>
 | 
			
		||||
    <keysym keyval="34">quotedbl</keysym>
 | 
			
		||||
    <keysym keyval="47">slash</keysym>
 | 
			
		||||
  <key name="AB02">
 | 
			
		||||
    <symbol label="x">x</symbol>
 | 
			
		||||
    <symbol label="X">X</symbol>
 | 
			
		||||
    <symbol label=""">quotedbl</symbol>
 | 
			
		||||
    <symbol label="/">slash</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key keycode="54" name="AB03">
 | 
			
		||||
    <keysym keyval="99">c</keysym>
 | 
			
		||||
    <keysym keyval="67">C</keysym>
 | 
			
		||||
    <keysym keyval="39">quoteright</keysym>
 | 
			
		||||
    <keysym keyval="60">less</keysym>
 | 
			
		||||
  <key name="AB03">
 | 
			
		||||
    <symbol label="c">c</symbol>
 | 
			
		||||
    <symbol label="C">C</symbol>
 | 
			
		||||
    <symbol label="'">quoteright</symbol>
 | 
			
		||||
    <symbol label="<">less</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key keycode="55" name="AB04">
 | 
			
		||||
    <keysym keyval="118">v</keysym>
 | 
			
		||||
    <keysym keyval="86">V</keysym>
 | 
			
		||||
    <keysym keyval="58">colon</keysym>
 | 
			
		||||
    <keysym keyval="62">greater</keysym>
 | 
			
		||||
  <key name="AB04">
 | 
			
		||||
    <symbol label="v">v</symbol>
 | 
			
		||||
    <symbol label="V">V</symbol>
 | 
			
		||||
    <symbol label=":">colon</symbol>
 | 
			
		||||
    <symbol label=">">greater</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key keycode="56" name="AB05">
 | 
			
		||||
    <keysym keyval="98">b</keysym>
 | 
			
		||||
    <keysym keyval="66">B</keysym>
 | 
			
		||||
    <keysym keyval="59">semicolon</keysym>
 | 
			
		||||
    <keysym keyval="61">equal</keysym>
 | 
			
		||||
  <key name="AB05">
 | 
			
		||||
    <symbol label="b">b</symbol>
 | 
			
		||||
    <symbol label="B">B</symbol>
 | 
			
		||||
    <symbol label=";">semicolon</symbol>
 | 
			
		||||
    <symbol label="=">equal</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key keycode="57" name="AB06">
 | 
			
		||||
    <keysym keyval="110">n</keysym>
 | 
			
		||||
    <keysym keyval="78">N</keysym>
 | 
			
		||||
    <keysym keyval="33">exclam</keysym>
 | 
			
		||||
    <keysym keyval="91">bracketleft</keysym>
 | 
			
		||||
  <key name="AB06">
 | 
			
		||||
    <symbol label="n">n</symbol>
 | 
			
		||||
    <symbol label="N">N</symbol>
 | 
			
		||||
    <symbol label="!">exclam</symbol>
 | 
			
		||||
    <symbol label="[">bracketleft</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key keycode="58" name="AB07">
 | 
			
		||||
    <keysym keyval="109">m</keysym>
 | 
			
		||||
    <keysym keyval="77">M</keysym>
 | 
			
		||||
    <keysym keyval="63">question</keysym>
 | 
			
		||||
    <keysym keyval="93">bracketright</keysym>
 | 
			
		||||
  <key name="AB07">
 | 
			
		||||
    <symbol label="m">m</symbol>
 | 
			
		||||
    <symbol label="M">M</symbol>
 | 
			
		||||
    <symbol label="?">question</symbol>
 | 
			
		||||
    <symbol label="]">bracketright</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key keycode="59" name="AB08">
 | 
			
		||||
    <keysym keyval="44">comma</keysym>
 | 
			
		||||
    <keysym keyval="60">less</keysym>
 | 
			
		||||
  <key name="AB08">
 | 
			
		||||
    <symbol label=".">period</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key keycode="60" name="AB09">
 | 
			
		||||
    <keysym keyval="46">period</keysym>
 | 
			
		||||
  <key name="ABC123">
 | 
			
		||||
    <symbol label="123">show-numbers</symbol>
 | 
			
		||||
    <symbol label="123">show-numbers</symbol>
 | 
			
		||||
    <symbol label="ABC">show-letters</symbol>
 | 
			
		||||
    <symbol label="ABC">show-letters</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key keycode="61" name="AB10">
 | 
			
		||||
    <keysym keyval="47">slash</keysym>
 | 
			
		||||
    <keysym keyval="63">question</keysym>
 | 
			
		||||
  <key name="I149">
 | 
			
		||||
    <symbol label="☺" icon="keyboard-mode-symbolic" tooltip="Setup">preferences</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key keycode="62" name="RTSH">
 | 
			
		||||
    <keysym keyval="65506">Shift_R</keysym>
 | 
			
		||||
  <key name="SPCE">
 | 
			
		||||
    <symbol label=" ">space</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key keycode="149" name="I149">
 | 
			
		||||
    <symbol label="⌨" icon="input-keyboard-symbolic" tooltip="Change keyboard">cycle-keyboard</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key keycode="150" name="I150">
 | 
			
		||||
    <symbol label="☺" icon="preferences-system-symbolic" tooltip="Setup">preferences</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key keycode="37" name="LCTL">
 | 
			
		||||
    <keysym keyval="65507">Control_L</keysym>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key keycode="64" name="LALT">
 | 
			
		||||
    <keysym keyval="65513">Alt_L</keysym>
 | 
			
		||||
    <keysym keyval="65511">Meta_L</keysym>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key keycode="65" name="SPCE">
 | 
			
		||||
    <keysym keyval="32">space</keysym>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key keycode="113" name="LEFT">
 | 
			
		||||
    <keysym keyval="65361">Left</keysym>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key keycode="111" name="UP">
 | 
			
		||||
    <keysym keyval="65362">Up</keysym>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key keycode="116" name="DOWN">
 | 
			
		||||
    <keysym keyval="65364">Down</keysym>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key keycode="114" name="RGHT">
 | 
			
		||||
    <keysym keyval="65363">Right</keysym>
 | 
			
		||||
  <key name="BKSP">
 | 
			
		||||
    <symbol keyval="65288" icon="edit-clear-symbolic">BackSpace</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
</symbols>
 | 
			
		||||
 | 
			
		||||
@ -3,7 +3,12 @@
 | 
			
		||||
  <gresource prefix="/sm/puri/squeekboard">
 | 
			
		||||
   <file compressed="true">style.css</file>
 | 
			
		||||
   <file compressed="true" preprocess="xml-stripblanks">keyboards/geometry/compact.xml</file>
 | 
			
		||||
   <file compressed="true" preprocess="xml-stripblanks">keyboards/geometry/extended.xml</file>
 | 
			
		||||
   <file compressed="true" preprocess="xml-stripblanks">keyboards/geometry/numbers-keypad.xml</file>
 | 
			
		||||
   <file compressed="true" preprocess="xml-stripblanks">keyboards/keyboards.xml</file>
 | 
			
		||||
   <file compressed="true">keyboards/keymaps/nb.xkb</file>
 | 
			
		||||
   <file compressed="true">keyboards/keymaps/us.xkb</file>
 | 
			
		||||
   <file compressed="true">keyboards/keymaps/numbers.xkb</file>
 | 
			
		||||
   <file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/ar.xml</file>
 | 
			
		||||
   <file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/as-inscript.xml</file>
 | 
			
		||||
   <file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/be.xml</file>
 | 
			
		||||
@ -21,6 +26,7 @@
 | 
			
		||||
   <file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/ml-inscript.xml</file>
 | 
			
		||||
   <file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/mr-inscript.xml</file>
 | 
			
		||||
   <file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/my.xml</file>
 | 
			
		||||
   <file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/nb.xml</file>
 | 
			
		||||
   <file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/or-inscript.xml</file>
 | 
			
		||||
   <file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/pa-inscript.xml</file>
 | 
			
		||||
   <file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/ru.xml</file>
 | 
			
		||||
@ -32,7 +38,9 @@
 | 
			
		||||
   <file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/ug.xml</file>
 | 
			
		||||
   <file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/us.xml</file>
 | 
			
		||||
   <file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/zh-bopomofo.xml</file>
 | 
			
		||||
   <file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/special/numbers.xml</file>
 | 
			
		||||
   <file>icons/key-enter.svg</file>
 | 
			
		||||
   <file>icons/key-shift.svg</file>
 | 
			
		||||
   <file>icons/keyboard-mode-symbolic.svg</file>
 | 
			
		||||
  </gresource>
 | 
			
		||||
</gresources>
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										9
									
								
								debian/changelog
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										9
									
								
								debian/changelog
									
									
									
									
										vendored
									
									
								
							@ -1,12 +1,3 @@
 | 
			
		||||
squeekboard (1.0.11) unstable; urgency=medium
 | 
			
		||||
 | 
			
		||||
  * Handle keyboard views according to the design
 | 
			
		||||
  * Fix compiler warnings and errors by addressing deprecated code
 | 
			
		||||
  * Remove unused XML and handling code
 | 
			
		||||
  * Improve rendering and responsiveness
 | 
			
		||||
 | 
			
		||||
 -- David Boddie <david.boddie@puri.sm>  Fri, 12 Jul 2019 21:19:48 +0200
 | 
			
		||||
 | 
			
		||||
squeekboard (1.0.10) unstable; urgency=medium
 | 
			
		||||
 | 
			
		||||
  * Use a shared DBus definition
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										5
									
								
								debian/control
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										5
									
								
								debian/control
									
									
									
									
										vendored
									
									
								
							@ -11,7 +11,10 @@ Build-Depends:
 | 
			
		||||
 libcroco3-dev,
 | 
			
		||||
 libwayland-dev (>= 1.16),
 | 
			
		||||
 rustc,
 | 
			
		||||
 wayland-protocols (>= 1.14)
 | 
			
		||||
 wayland-protocols (>= 1.14),
 | 
			
		||||
# for running the tests
 | 
			
		||||
 xvfb,
 | 
			
		||||
 xauth,
 | 
			
		||||
Standards-Version: 4.1.3
 | 
			
		||||
Homepage: https://source.puri.sm/Librem5/squeekboard
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										54
									
								
								debian/copyright
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										54
									
								
								debian/copyright
									
									
									
									
										vendored
									
									
								
							@ -6,68 +6,17 @@ Files: *
 | 
			
		||||
Copyright: 2010-2011 Daiki Ueno <ueno@unixuser.org>
 | 
			
		||||
           2010-2011 Red Hat, Inc.
 | 
			
		||||
           2019 Purism SPC
 | 
			
		||||
           2019 Hysterical Raisins <sybolt-dev@xs4all.nl>
 | 
			
		||||
License: GPL-3+
 | 
			
		||||
 | 
			
		||||
Files: eek/eek.c
 | 
			
		||||
       eek/eek-container.c
 | 
			
		||||
       eek/eek-container.h
 | 
			
		||||
       eek/eek-element.c
 | 
			
		||||
       eek/eek-element.h
 | 
			
		||||
       eek/eek-gtk-keyboard.c
 | 
			
		||||
       eek/eek-gtk-keyboard.h
 | 
			
		||||
       eek/eek-key.c
 | 
			
		||||
       eek/eek-key.h
 | 
			
		||||
       eek/eek-keysym.c
 | 
			
		||||
       eek/eek-keysym.h
 | 
			
		||||
       eek/eek-layout.c
 | 
			
		||||
       eek/eek-layout.h
 | 
			
		||||
       eek/eek-renderer.c
 | 
			
		||||
       eek/eek-renderer.h
 | 
			
		||||
       eek/eek-section.c
 | 
			
		||||
       eek/eek-section.h
 | 
			
		||||
       eek/eek-symbol.c
 | 
			
		||||
       eek/eek-symbol.h
 | 
			
		||||
       eek/eek-text.c
 | 
			
		||||
       eek/eek-text.h
 | 
			
		||||
       eek/eek-xkb-layout.c
 | 
			
		||||
       eek/eek-xkb-layout.h
 | 
			
		||||
       eek/eek-xkl-layout.c
 | 
			
		||||
       eek/eek-xkl-layout.h
 | 
			
		||||
       eek/eek-xml-layout.c
 | 
			
		||||
       eek/eek-xml-layout.c
 | 
			
		||||
       eek/eek-xml-layout.h
 | 
			
		||||
       eekboard/eekboard-client.c
 | 
			
		||||
       eekboard/eekboard-client.h
 | 
			
		||||
       eekboard/eekboard-context.c
 | 
			
		||||
       eekboard/eekboard-context.h
 | 
			
		||||
       eekboard/eekboard-context-service.c
 | 
			
		||||
       eekboard/eekboard-service.c
 | 
			
		||||
       eekboard/eekboard-service.h
 | 
			
		||||
Copyright: 2010-2011 Daiki Ueno <ueno@unixuser.org>
 | 
			
		||||
           2010-2011 Red Hat, Inc.
 | 
			
		||||
           2019 Purism SPC
 | 
			
		||||
           2019 Hysterical Raisins <sybolt-dev@xs4all.nl>
 | 
			
		||||
License: GPL-3+
 | 
			
		||||
 | 
			
		||||
Files: eek/layersurface.c
 | 
			
		||||
       src/wayland.c
 | 
			
		||||
       src/key-emitter.c
 | 
			
		||||
       meson.build
 | 
			
		||||
       src/meson.build
 | 
			
		||||
       po/meson.build
 | 
			
		||||
Copyright: 2018-2019 Purism SPC
 | 
			
		||||
License: GPL-3+
 | 
			
		||||
 | 
			
		||||
Files: data/meson.build
 | 
			
		||||
       data/squeekboard.gresources.xml
 | 
			
		||||
       data/style.css
 | 
			
		||||
       src/imservice.c
 | 
			
		||||
       src/meson.build
 | 
			
		||||
       src/server-context-service.c
 | 
			
		||||
Copyright: 2019 Purism SPC
 | 
			
		||||
           2019 Hysterical Raisins <sybolt-dev@xs4all.nl>
 | 
			
		||||
License: GPL-3+
 | 
			
		||||
 | 
			
		||||
Files: eekboard/keymap.c
 | 
			
		||||
Copyright: 2000 Red Hat, Inc.
 | 
			
		||||
           2019 Purism, SPC
 | 
			
		||||
@ -122,4 +71,3 @@ License: GPL-3+
 | 
			
		||||
 .
 | 
			
		||||
 On Debian systems, the complete text of the GNU General
 | 
			
		||||
 Public License version 3 can be found in "/usr/share/common-licenses/GPL-3".
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -26,9 +26,7 @@
 | 
			
		||||
 * shall be used to implement #EekKeyboard and #EekSection.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_CONFIG_H
 | 
			
		||||
#include "config.h"
 | 
			
		||||
#endif  /* HAVE_CONFIG_H */
 | 
			
		||||
 | 
			
		||||
#include "eek-container.h"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -26,9 +26,7 @@
 | 
			
		||||
 * shall be used to implement #EekKeyboard, #EekSection, or #EekKey.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_CONFIG_H
 | 
			
		||||
#include "config.h"
 | 
			
		||||
#endif  /* HAVE_CONFIG_H */
 | 
			
		||||
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -23,9 +23,7 @@
 | 
			
		||||
 * @short_description: a #GtkWidget displaying #EekKeyboard
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_CONFIG_H
 | 
			
		||||
#include "config.h"
 | 
			
		||||
#endif  /* HAVE_CONFIG_H */
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_LIBCANBERRA
 | 
			
		||||
#include <canberra-gtk.h>
 | 
			
		||||
@ -35,7 +33,7 @@
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
#include "eek-gtk-keyboard.h"
 | 
			
		||||
#include "eek-gtk-renderer.h"
 | 
			
		||||
#include "eek-renderer.h"
 | 
			
		||||
#include "eek-keyboard.h"
 | 
			
		||||
#include "eek-section.h"
 | 
			
		||||
#include "eek-key.h"
 | 
			
		||||
@ -57,9 +55,6 @@ typedef struct _EekGtkKeyboardPrivate
 | 
			
		||||
{
 | 
			
		||||
    EekRenderer *renderer;
 | 
			
		||||
    EekKeyboard *keyboard;
 | 
			
		||||
    gulong key_locked_handler;
 | 
			
		||||
    gulong key_unlocked_handler;
 | 
			
		||||
    gulong symbol_index_changed_handler;
 | 
			
		||||
    EekTheme *theme;
 | 
			
		||||
 | 
			
		||||
    GdkEventSequence *sequence; // unowned reference
 | 
			
		||||
@ -117,13 +112,15 @@ eek_gtk_keyboard_real_draw (GtkWidget *self,
 | 
			
		||||
        PangoContext *pcontext;
 | 
			
		||||
 | 
			
		||||
        pcontext = gtk_widget_get_pango_context (self);
 | 
			
		||||
        priv->renderer = eek_gtk_renderer_new (priv->keyboard, pcontext, self);
 | 
			
		||||
        priv->renderer = eek_renderer_new (priv->keyboard, pcontext);
 | 
			
		||||
        if (priv->theme)
 | 
			
		||||
            eek_renderer_set_theme (priv->renderer, priv->theme);
 | 
			
		||||
 | 
			
		||||
        eek_renderer_set_allocation_size (priv->renderer,
 | 
			
		||||
                                          allocation.width,
 | 
			
		||||
                                          allocation.height);
 | 
			
		||||
        eek_renderer_set_scale_factor (priv->renderer,
 | 
			
		||||
                                       gtk_widget_get_scale_factor (self));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    eek_renderer_render_keyboard (priv->renderer, cr);
 | 
			
		||||
@ -330,17 +327,23 @@ eek_gtk_keyboard_set_keyboard (EekGtkKeyboard *self,
 | 
			
		||||
                               EekKeyboard    *keyboard)
 | 
			
		||||
{
 | 
			
		||||
    EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (self);
 | 
			
		||||
 | 
			
		||||
    if (priv->keyboard == keyboard)
 | 
			
		||||
        return;
 | 
			
		||||
 | 
			
		||||
    if (priv->keyboard) {
 | 
			
		||||
        g_signal_handlers_disconnect_by_data(priv->keyboard, self);
 | 
			
		||||
        g_object_unref (priv->keyboard);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    priv->keyboard = g_object_ref (keyboard);
 | 
			
		||||
 | 
			
		||||
    priv->key_locked_handler =
 | 
			
		||||
        g_signal_connect (priv->keyboard, "key-locked",
 | 
			
		||||
                          G_CALLBACK(on_key_locked), self);
 | 
			
		||||
    priv->key_unlocked_handler =
 | 
			
		||||
        g_signal_connect (priv->keyboard, "key-unlocked",
 | 
			
		||||
                          G_CALLBACK(on_key_unlocked), self);
 | 
			
		||||
    priv->symbol_index_changed_handler =
 | 
			
		||||
        g_signal_connect (priv->keyboard, "symbol-index-changed",
 | 
			
		||||
                          G_CALLBACK(on_symbol_index_changed), self);
 | 
			
		||||
    g_signal_connect (priv->keyboard, "key-locked",
 | 
			
		||||
                      G_CALLBACK(on_key_locked), self);
 | 
			
		||||
    g_signal_connect (priv->keyboard, "key-unlocked",
 | 
			
		||||
                      G_CALLBACK(on_key_unlocked), self);
 | 
			
		||||
    g_signal_connect (priv->keyboard, "symbol-index-changed",
 | 
			
		||||
                      G_CALLBACK(on_symbol_index_changed), self);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
@ -374,21 +377,9 @@ eek_gtk_keyboard_dispose (GObject *object)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (priv->keyboard) {
 | 
			
		||||
        if (g_signal_handler_is_connected (priv->keyboard,
 | 
			
		||||
                                           priv->key_locked_handler))
 | 
			
		||||
            g_signal_handler_disconnect (priv->keyboard,
 | 
			
		||||
                                         priv->key_locked_handler);
 | 
			
		||||
        if (g_signal_handler_is_connected (priv->keyboard,
 | 
			
		||||
                                           priv->key_unlocked_handler))
 | 
			
		||||
            g_signal_handler_disconnect (priv->keyboard,
 | 
			
		||||
                                         priv->key_unlocked_handler);
 | 
			
		||||
        if (g_signal_handler_is_connected (priv->keyboard,
 | 
			
		||||
                                           priv->symbol_index_changed_handler))
 | 
			
		||||
            g_signal_handler_disconnect (priv->keyboard,
 | 
			
		||||
                                         priv->symbol_index_changed_handler);
 | 
			
		||||
 | 
			
		||||
        GList *list, *head;
 | 
			
		||||
 | 
			
		||||
        g_signal_handlers_disconnect_by_data(priv->keyboard, self);
 | 
			
		||||
        list = eek_keyboard_get_pressed_keys (priv->keyboard);
 | 
			
		||||
        for (head = list; head; head = g_list_next (head)) {
 | 
			
		||||
            g_log("squeek", G_LOG_LEVEL_DEBUG, "emit EekKey pressed");
 | 
			
		||||
@ -484,45 +475,6 @@ magnify_bounds (GtkWidget *self,
 | 
			
		||||
    large_bounds->y = CLAMP(y, 0, allocation.height - large_bounds->height);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Alleviate the asymmetry between drawing a pressed key and a released key,
 | 
			
		||||
 * and consistently draw to the exact same area.
 | 
			
		||||
 *
 | 
			
		||||
 * By saving the dirty rectangle we can limit drawing of the backbuffer to
 | 
			
		||||
 * the screen as well, eg gdk_window_invalidate_rect() instead of
 | 
			
		||||
 * gtk_widget_queue_draw() which redraws the entire widget.
 | 
			
		||||
 *
 | 
			
		||||
 * b1 is mandatory, b2 is optional
 | 
			
		||||
 */
 | 
			
		||||
static GdkRectangle
 | 
			
		||||
clip_bounds_to_dirty_rectangle (cairo_t *cr, EekBounds *b1, EekBounds *b2)
 | 
			
		||||
{
 | 
			
		||||
    if (b2)
 | 
			
		||||
        cairo_rectangle (cr, b2->x, b2->y, b2->width, b2->height);
 | 
			
		||||
 | 
			
		||||
    cairo_rectangle (cr, b1->x, b1->y, b1->width, b1->height);
 | 
			
		||||
    cairo_clip (cr);
 | 
			
		||||
 | 
			
		||||
    /*
 | 
			
		||||
     * save the clipped region to a bounding box so we can limit
 | 
			
		||||
     * the drawing of the backbuffer to the screen to the same area
 | 
			
		||||
     */
 | 
			
		||||
    cairo_rectangle_t bbox;
 | 
			
		||||
 | 
			
		||||
    cairo_clip_extents (cr, &bbox.x, &bbox.y, &bbox.width, &bbox.height);
 | 
			
		||||
 | 
			
		||||
    /* convert double to int, making sure r strictly covers bbox to avoid
 | 
			
		||||
     * artefacts. floor() is unnecessary, ceil() is not */
 | 
			
		||||
    GdkRectangle r = {
 | 
			
		||||
        floor (bbox.x),
 | 
			
		||||
        floor (bbox.y),
 | 
			
		||||
        ceil  (bbox.width),
 | 
			
		||||
        ceil  (bbox.height)
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    return r;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
render_pressed_key (GtkWidget *widget,
 | 
			
		||||
                    EekKey    *key)
 | 
			
		||||
@ -539,12 +491,6 @@ render_pressed_key (GtkWidget *widget,
 | 
			
		||||
    eek_renderer_get_key_bounds (priv->renderer, key, &bounds, TRUE);
 | 
			
		||||
    magnify_bounds (widget, &bounds, &large_bounds, 1.5);
 | 
			
		||||
 | 
			
		||||
    /*
 | 
			
		||||
     * clip to limit drawing to backbuffer and save clip region to dirty_rect
 | 
			
		||||
     * to limit redrawing of the backbuffer to the same area
 | 
			
		||||
     */
 | 
			
		||||
    GdkRectangle dirty_rect = clip_bounds_to_dirty_rectangle (cr, &bounds, &large_bounds);
 | 
			
		||||
 | 
			
		||||
    cairo_save (cr);
 | 
			
		||||
    cairo_translate (cr, bounds.x, bounds.y);
 | 
			
		||||
    eek_renderer_render_key (priv->renderer, cr, key, 1.0, TRUE);
 | 
			
		||||
@ -558,9 +504,6 @@ render_pressed_key (GtkWidget *widget,
 | 
			
		||||
    gdk_window_end_draw_frame (window, context);
 | 
			
		||||
 | 
			
		||||
    cairo_region_destroy (region);
 | 
			
		||||
 | 
			
		||||
    /* force immediate drawing of the backbuffer to the screen */
 | 
			
		||||
    gdk_window_invalidate_rect (window, &dirty_rect, FALSE);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
@ -578,21 +521,12 @@ render_locked_key (GtkWidget *widget,
 | 
			
		||||
 | 
			
		||||
    eek_renderer_get_key_bounds (priv->renderer, key, &bounds, TRUE);
 | 
			
		||||
 | 
			
		||||
    /*
 | 
			
		||||
     * clip to limit drawing to backbuffer and save clip region to dirty_rect
 | 
			
		||||
     * to limit redrawing of the backbuffer to the same area
 | 
			
		||||
     */
 | 
			
		||||
    GdkRectangle dirty_rect = clip_bounds_to_dirty_rectangle (cr, &bounds, NULL);
 | 
			
		||||
 | 
			
		||||
    cairo_translate (cr, bounds.x, bounds.y);
 | 
			
		||||
    eek_renderer_render_key (priv->renderer, cr, key, 1.0, TRUE);
 | 
			
		||||
 | 
			
		||||
    gdk_window_end_draw_frame (window, context);
 | 
			
		||||
 | 
			
		||||
    cairo_region_destroy (region);
 | 
			
		||||
 | 
			
		||||
    /* force immediate drawing of the backbuffer to the screen */
 | 
			
		||||
    gdk_window_invalidate_rect (window, &dirty_rect, FALSE);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
@ -611,20 +545,11 @@ render_released_key (GtkWidget *widget,
 | 
			
		||||
    eek_renderer_get_key_bounds (priv->renderer, key, &bounds, TRUE);
 | 
			
		||||
    magnify_bounds (widget, &bounds, &large_bounds, 1.5);
 | 
			
		||||
 | 
			
		||||
    /*
 | 
			
		||||
     * clip to limit drawing to backbuffer and save clip region to dirty_rect
 | 
			
		||||
     * to limit redrawing of the backbuffer to the same area
 | 
			
		||||
     */
 | 
			
		||||
    GdkRectangle dirty_rect = clip_bounds_to_dirty_rectangle(cr, &bounds, &large_bounds);
 | 
			
		||||
 | 
			
		||||
    eek_renderer_render_keyboard (priv->renderer, cr);
 | 
			
		||||
 | 
			
		||||
    gdk_window_end_draw_frame (window, context);
 | 
			
		||||
 | 
			
		||||
    cairo_region_destroy (region);
 | 
			
		||||
 | 
			
		||||
    /* force immediate drawing of the backbuffer to the screen */
 | 
			
		||||
    gdk_window_invalidate_rect (window, &dirty_rect, FALSE);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
@ -638,6 +563,7 @@ on_key_pressed (EekKey      *key,
 | 
			
		||||
        return;
 | 
			
		||||
 | 
			
		||||
    render_pressed_key (GTK_WIDGET(self), key);
 | 
			
		||||
    gtk_widget_queue_draw (GTK_WIDGET(self));
 | 
			
		||||
 | 
			
		||||
#if HAVE_LIBCANBERRA
 | 
			
		||||
    ca_gtk_play_for_widget (widget, 0,
 | 
			
		||||
@ -659,6 +585,7 @@ on_key_released (EekKey      *key,
 | 
			
		||||
        return;
 | 
			
		||||
 | 
			
		||||
    render_released_key (GTK_WIDGET(self), key);
 | 
			
		||||
    gtk_widget_queue_draw (GTK_WIDGET(self));
 | 
			
		||||
 | 
			
		||||
#if HAVE_LIBCANBERRA
 | 
			
		||||
    ca_gtk_play_for_widget (widget, 0,
 | 
			
		||||
@ -682,6 +609,7 @@ on_key_locked (EekKeyboard *keyboard,
 | 
			
		||||
        return;
 | 
			
		||||
 | 
			
		||||
    render_locked_key (widget, key);
 | 
			
		||||
    gtk_widget_queue_draw (widget);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
@ -697,6 +625,7 @@ on_key_unlocked (EekKeyboard *keyboard,
 | 
			
		||||
        return;
 | 
			
		||||
 | 
			
		||||
    render_released_key (widget, key);
 | 
			
		||||
    gtk_widget_queue_draw (GTK_WIDGET(widget));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
 | 
			
		||||
@ -1,118 +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
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_CONFIG_H
 | 
			
		||||
#include "config.h"
 | 
			
		||||
#endif  /* HAVE_CONFIG_H */
 | 
			
		||||
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <gdk-pixbuf/gdk-pixbuf.h>
 | 
			
		||||
 | 
			
		||||
#include "eek-gtk-renderer.h"
 | 
			
		||||
#include "eek-key.h"
 | 
			
		||||
 | 
			
		||||
G_DEFINE_TYPE (EekGtkRenderer, eek_gtk_renderer, EEK_TYPE_RENDERER);
 | 
			
		||||
 | 
			
		||||
static cairo_surface_t *
 | 
			
		||||
pixbuf_to_cairo_surface (GdkPixbuf *pixbuf)
 | 
			
		||||
{
 | 
			
		||||
  cairo_surface_t *dummy_surface;
 | 
			
		||||
  cairo_pattern_t *pattern;
 | 
			
		||||
  cairo_surface_t *surface;
 | 
			
		||||
  cairo_t *cr;
 | 
			
		||||
 | 
			
		||||
  dummy_surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 1, 1);
 | 
			
		||||
 | 
			
		||||
  cr = cairo_create (dummy_surface);
 | 
			
		||||
  gdk_cairo_set_source_pixbuf (cr, pixbuf, 0, 0);
 | 
			
		||||
  pattern = cairo_get_source (cr);
 | 
			
		||||
  cairo_pattern_get_surface (pattern, &surface);
 | 
			
		||||
  cairo_surface_reference (surface);
 | 
			
		||||
  cairo_destroy (cr);
 | 
			
		||||
  cairo_surface_destroy (dummy_surface);
 | 
			
		||||
 | 
			
		||||
  return surface;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static cairo_surface_t *
 | 
			
		||||
eek_gtk_renderer_real_get_icon_surface (EekRenderer *self,
 | 
			
		||||
                                        const gchar *icon_name,
 | 
			
		||||
                                        gint size)
 | 
			
		||||
{
 | 
			
		||||
    GdkPixbuf *pixbuf;
 | 
			
		||||
    GError *error = NULL;
 | 
			
		||||
    cairo_surface_t *surface;
 | 
			
		||||
 | 
			
		||||
    gchar *path = g_strconcat("/sm/puri/squeekboard/icons/", icon_name, ".svg", NULL);
 | 
			
		||||
 | 
			
		||||
    pixbuf = gdk_pixbuf_new_from_resource_at_scale (path, size, size,
 | 
			
		||||
                                                    TRUE, &error);
 | 
			
		||||
 | 
			
		||||
    if (pixbuf != NULL)
 | 
			
		||||
        goto found;
 | 
			
		||||
    else {
 | 
			
		||||
        g_warning ("can't get icon pixbuf for %s: %s", path, error->message);
 | 
			
		||||
        g_error_free (error);
 | 
			
		||||
        error = NULL;
 | 
			
		||||
    }
 | 
			
		||||
    g_free(path);
 | 
			
		||||
 | 
			
		||||
    pixbuf = gtk_icon_theme_load_icon (gtk_icon_theme_get_default (),
 | 
			
		||||
                                       icon_name,
 | 
			
		||||
                                       size,
 | 
			
		||||
                                       0,
 | 
			
		||||
                                       &error);
 | 
			
		||||
    if (pixbuf == NULL) {
 | 
			
		||||
        g_warning ("can't get icon pixbuf for %s: %s",
 | 
			
		||||
                   icon_name,
 | 
			
		||||
                   error->message);
 | 
			
		||||
        g_error_free (error);
 | 
			
		||||
        return NULL;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
found:
 | 
			
		||||
    surface = pixbuf_to_cairo_surface (pixbuf);
 | 
			
		||||
    g_object_unref (pixbuf);
 | 
			
		||||
    return surface;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
eek_gtk_renderer_class_init (EekGtkRendererClass *klass)
 | 
			
		||||
{
 | 
			
		||||
    EekRendererClass *renderer_class = EEK_RENDERER_CLASS (klass);
 | 
			
		||||
 | 
			
		||||
    renderer_class->get_icon_surface = eek_gtk_renderer_real_get_icon_surface;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
eek_gtk_renderer_init (EekGtkRenderer *self)
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
EekRenderer *
 | 
			
		||||
eek_gtk_renderer_new (EekKeyboard  *keyboard,
 | 
			
		||||
                      PangoContext *pcontext,
 | 
			
		||||
                      GtkWidget    *widget)
 | 
			
		||||
{
 | 
			
		||||
    return g_object_new (EEK_TYPE_GTK_RENDERER,
 | 
			
		||||
                         "keyboard", keyboard,
 | 
			
		||||
                         "pango-context", pcontext,
 | 
			
		||||
                         NULL);
 | 
			
		||||
}
 | 
			
		||||
@ -1,61 +0,0 @@
 | 
			
		||||
/* 
 | 
			
		||||
 * Copyright (C) 2010-2011 Daiki Ueno <ueno@unixuser.org>
 | 
			
		||||
 * Copyright (C) 2010-2011 Red Hat, Inc.
 | 
			
		||||
 * 
 | 
			
		||||
 * This library is free software; you can redistribute it and/or
 | 
			
		||||
 * modify it under the terms of the GNU Lesser General Public License
 | 
			
		||||
 * as published by the Free Software Foundation; either version 2 of
 | 
			
		||||
 * the License, or (at your option) any later version.
 | 
			
		||||
 * 
 | 
			
		||||
 * This library is distributed in the hope that it will be useful, but
 | 
			
		||||
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
			
		||||
 * Lesser General Public License for more details.
 | 
			
		||||
 * 
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General Public
 | 
			
		||||
 * License along with this library; if not, write to the Free Software
 | 
			
		||||
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 | 
			
		||||
 * 02110-1301 USA
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef EEK_GTK_RENDERER_H
 | 
			
		||||
#define EEK_GTK_RENDERER_H 1
 | 
			
		||||
 | 
			
		||||
#include <gtk/gtk.h>
 | 
			
		||||
#include "eek-renderer.h"
 | 
			
		||||
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
#define EEK_TYPE_GTK_RENDERER (eek_gtk_renderer_get_type())
 | 
			
		||||
#define EEK_GTK_RENDERER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EEK_TYPE_GTK_RENDERER, EekGtkRenderer))
 | 
			
		||||
#define EEK_GTK_RENDERER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EEK_TYPE_GTK_RENDERER, EekGtkRendererClass))
 | 
			
		||||
#define EEK_IS_GTK_RENDERER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EEK_TYPE_GTK_RENDERER))
 | 
			
		||||
#define EEK_IS_GTK_RENDERER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EEK_TYPE_GTK_RENDERER))
 | 
			
		||||
#define EEK_GTK_RENDERER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EEK_TYPE_GTK_RENDERER, EekGtkRendererClass))
 | 
			
		||||
 | 
			
		||||
typedef struct _EekGtkRenderer EekGtkRenderer;
 | 
			
		||||
typedef struct _EekGtkRendererClass EekGtkRendererClass;
 | 
			
		||||
typedef struct _EekGtkRendererPrivate EekGtkRendererPrivate;
 | 
			
		||||
 | 
			
		||||
struct _EekGtkRenderer {
 | 
			
		||||
    EekRenderer parent;
 | 
			
		||||
 | 
			
		||||
    EekGtkRendererPrivate *priv;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct _EekGtkRendererClass
 | 
			
		||||
{
 | 
			
		||||
    EekRendererClass parent_class;
 | 
			
		||||
 | 
			
		||||
    /*< private >*/
 | 
			
		||||
    /* padding */
 | 
			
		||||
    gpointer pdummy[24];
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
GType        eek_gtk_renderer_get_type (void) G_GNUC_CONST;
 | 
			
		||||
EekRenderer *eek_gtk_renderer_new      (EekKeyboard  *keyboard,
 | 
			
		||||
                                        PangoContext *pcontext,
 | 
			
		||||
                                        GtkWidget *widget);
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
#endif  /* EEK_GTK_RENDERER_H */
 | 
			
		||||
@ -25,9 +25,7 @@
 | 
			
		||||
 * The #EekKeyClass class represents a key.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_CONFIG_H
 | 
			
		||||
#include "config.h"
 | 
			
		||||
#endif  /* HAVE_CONFIG_H */
 | 
			
		||||
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
@ -611,3 +609,11 @@ void eek_key_set_pressed(EekKey *key, gboolean value)
 | 
			
		||||
 | 
			
		||||
    priv->is_pressed = value;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
gboolean
 | 
			
		||||
eek_key_has_label(EekKey *key)
 | 
			
		||||
{
 | 
			
		||||
    EekSymbol *symbol = eek_key_get_symbol(key);
 | 
			
		||||
    return (eek_symbol_get_label(symbol) != NULL) ||
 | 
			
		||||
           (eek_symbol_get_icon_name(symbol) != NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -89,5 +89,7 @@ gboolean         eek_key_is_locked           (EekKey          *key);
 | 
			
		||||
void             eek_key_set_pressed         (EekKey          *key,
 | 
			
		||||
                                              gboolean         value);
 | 
			
		||||
 | 
			
		||||
gboolean         eek_key_has_label           (EekKey          *key);
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
#endif  /* EEK_KEY_H */
 | 
			
		||||
 | 
			
		||||
@ -17,9 +17,7 @@
 | 
			
		||||
 * Boston, MA 02111-1307, USA.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_CONFIG_H
 | 
			
		||||
#include "config.h"
 | 
			
		||||
#endif  /* HAVE_CONFIG_H */
 | 
			
		||||
 | 
			
		||||
#include <math.h>
 | 
			
		||||
#include <pango/pangocairo.h>
 | 
			
		||||
 | 
			
		||||
@ -27,9 +27,7 @@
 | 
			
		||||
 * of one or more sections of the #EekSectionClass class.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_CONFIG_H
 | 
			
		||||
#include "config.h"
 | 
			
		||||
#endif  /* HAVE_CONFIG_H */
 | 
			
		||||
 | 
			
		||||
#include "eek-keyboard.h"
 | 
			
		||||
#include "eek-marshalers.h"
 | 
			
		||||
@ -70,11 +68,11 @@ struct _EekKeyboardPrivate
 | 
			
		||||
    EekLayout *layout;
 | 
			
		||||
    EekModifierBehavior modifier_behavior;
 | 
			
		||||
    EekModifierType modifiers;
 | 
			
		||||
    EekModifierType old_level;
 | 
			
		||||
    unsigned int old_level;
 | 
			
		||||
    GList *pressed_keys;
 | 
			
		||||
    GList *locked_keys;
 | 
			
		||||
    GArray *outline_array;
 | 
			
		||||
    GHashTable *keycodes;
 | 
			
		||||
    GHashTable *names;
 | 
			
		||||
 | 
			
		||||
    /* modifiers dynamically assigned at run time */
 | 
			
		||||
    EekModifierType num_lock_mask;
 | 
			
		||||
@ -129,9 +127,9 @@ section_child_added_cb (EekContainer *container,
 | 
			
		||||
                        EekElement   *element,
 | 
			
		||||
                        EekKeyboard  *keyboard)
 | 
			
		||||
{
 | 
			
		||||
    guint keycode = eek_key_get_keycode (EEK_KEY(element));
 | 
			
		||||
    g_hash_table_insert (keyboard->priv->keycodes,
 | 
			
		||||
                         GUINT_TO_POINTER(keycode),
 | 
			
		||||
    const gchar *name = eek_element_get_name(element);
 | 
			
		||||
    g_hash_table_insert (keyboard->priv->names,
 | 
			
		||||
                         (gpointer)name,
 | 
			
		||||
                         element);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -140,9 +138,9 @@ section_child_removed_cb (EekContainer *container,
 | 
			
		||||
                          EekElement   *element,
 | 
			
		||||
                          EekKeyboard  *keyboard)
 | 
			
		||||
{
 | 
			
		||||
    guint keycode = eek_key_get_keycode (EEK_KEY(element));
 | 
			
		||||
    g_hash_table_remove (keyboard->priv->keycodes,
 | 
			
		||||
                         GUINT_TO_POINTER(keycode));
 | 
			
		||||
    const gchar *name = eek_element_get_name(element);
 | 
			
		||||
    g_hash_table_remove (keyboard->priv->names,
 | 
			
		||||
                         name);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static EekSection *
 | 
			
		||||
@ -221,7 +219,7 @@ set_level_from_modifiers (EekKeyboard *self, EekKey *key)
 | 
			
		||||
    gint level = priv->old_level & 2;
 | 
			
		||||
 | 
			
		||||
    /* Handle non-emitting keys */
 | 
			
		||||
    if (key && (eek_key_get_keycode(key) == 0)) {
 | 
			
		||||
    if (key) {
 | 
			
		||||
        const gchar *name = eek_element_get_name(EEK_ELEMENT(key));
 | 
			
		||||
        if (g_strcmp0(name, "ABC123") == 0)
 | 
			
		||||
            level ^= 2;
 | 
			
		||||
@ -259,11 +257,13 @@ set_level_from_modifiers (EekKeyboard *self, EekKey *key)
 | 
			
		||||
 | 
			
		||||
    if (level == VIEW_NUMBERS || level == VIEW_SYMBOLS)
 | 
			
		||||
        priv->modifier_behavior = EEK_MODIFIER_BEHAVIOR_LOCK;
 | 
			
		||||
    else if (level == VIEW_LETTERS_UPPER)
 | 
			
		||||
    else
 | 
			
		||||
        priv->modifier_behavior = EEK_MODIFIER_BEHAVIOR_LATCH;
 | 
			
		||||
 | 
			
		||||
    priv->old_level = level;
 | 
			
		||||
    eek_element_set_level (EEK_ELEMENT(self), level);
 | 
			
		||||
 | 
			
		||||
    eek_layout_update_layout(self);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
@ -400,7 +400,7 @@ eek_keyboard_finalize (GObject *object)
 | 
			
		||||
    g_list_free_full (priv->locked_keys,
 | 
			
		||||
                      (GDestroyNotify) eek_modifier_key_free);
 | 
			
		||||
 | 
			
		||||
    g_hash_table_destroy (priv->keycodes);
 | 
			
		||||
    g_hash_table_destroy (priv->names);
 | 
			
		||||
 | 
			
		||||
    for (i = 0; i < priv->outline_array->len; i++) {
 | 
			
		||||
        EekOutline *outline = &g_array_index (priv->outline_array,
 | 
			
		||||
@ -528,8 +528,9 @@ eek_keyboard_init (EekKeyboard *self)
 | 
			
		||||
    self->priv = EEK_KEYBOARD_GET_PRIVATE(self);
 | 
			
		||||
    self->priv->modifier_behavior = EEK_MODIFIER_BEHAVIOR_NONE;
 | 
			
		||||
    self->priv->outline_array = g_array_new (FALSE, TRUE, sizeof (EekOutline));
 | 
			
		||||
    self->priv->keycodes = g_hash_table_new (g_direct_hash, g_direct_equal);
 | 
			
		||||
    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;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@ -548,20 +549,20 @@ eek_keyboard_create_section (EekKeyboard *keyboard)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eek_keyboard_find_key_by_keycode:
 | 
			
		||||
 * eek_keyboard_find_key_by_name:
 | 
			
		||||
 * @keyboard: an #EekKeyboard
 | 
			
		||||
 * @keycode: a keycode
 | 
			
		||||
 * @name: a key name
 | 
			
		||||
 *
 | 
			
		||||
 * Find an #EekKey whose keycode is @keycode.
 | 
			
		||||
 * Return value: (transfer none): #EekKey whose keycode is @keycode
 | 
			
		||||
 * Find an #EekKey whose name is @name.
 | 
			
		||||
 * Return value: (transfer none): #EekKey whose name is @name
 | 
			
		||||
 */
 | 
			
		||||
EekKey *
 | 
			
		||||
eek_keyboard_find_key_by_keycode (EekKeyboard *keyboard,
 | 
			
		||||
                                  guint        keycode)
 | 
			
		||||
eek_keyboard_find_key_by_name (EekKeyboard *keyboard,
 | 
			
		||||
                               const gchar *name)
 | 
			
		||||
{
 | 
			
		||||
    g_return_val_if_fail (EEK_IS_KEYBOARD(keyboard), NULL);
 | 
			
		||||
    return g_hash_table_lookup (keyboard->priv->keycodes,
 | 
			
		||||
                                GUINT_TO_POINTER(keycode));
 | 
			
		||||
    return g_hash_table_lookup (keyboard->priv->names,
 | 
			
		||||
                                name);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 | 
			
		||||
@ -62,6 +62,7 @@ struct _EekKeyboard
 | 
			
		||||
    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;
 | 
			
		||||
 | 
			
		||||
    EekboardContextService *manager; // unowned reference
 | 
			
		||||
};
 | 
			
		||||
@ -69,8 +70,8 @@ struct _EekKeyboard
 | 
			
		||||
/**
 | 
			
		||||
 * EekKeyboardClass:
 | 
			
		||||
 * @create_section: virtual function for creating a section
 | 
			
		||||
 * @find_key_by_keycode: virtual function for finding a key in the
 | 
			
		||||
 * keyboard by keycode
 | 
			
		||||
 * @find_key_by_name: virtual function for finding a key in the
 | 
			
		||||
 * keyboard by name
 | 
			
		||||
 * @key_pressed: class handler for #EekKeyboard::key-pressed signal
 | 
			
		||||
 * @key_released: class handler for #EekKeyboard::key-released signal
 | 
			
		||||
 * @key_locked: class handler for #EekKeyboard::key-locked signal
 | 
			
		||||
@ -89,8 +90,8 @@ struct _EekKeyboardClass
 | 
			
		||||
    /*< public >*/
 | 
			
		||||
    EekSection *(* create_section)      (EekKeyboard *self);
 | 
			
		||||
 | 
			
		||||
    EekKey     *(* find_key_by_keycode) (EekKeyboard *self,
 | 
			
		||||
                                         guint        keycode);
 | 
			
		||||
    EekKey     *(* find_key_by_name)    (EekKeyboard *self,
 | 
			
		||||
                                         const gchar *name);
 | 
			
		||||
 | 
			
		||||
    /*< private >*/
 | 
			
		||||
    /* obsolete members moved to EekElement */
 | 
			
		||||
@ -155,9 +156,9 @@ EekModifierType     eek_keyboard_get_modifiers
 | 
			
		||||
EekSection         *eek_keyboard_create_section
 | 
			
		||||
                                     (EekKeyboard        *keyboard);
 | 
			
		||||
 | 
			
		||||
EekKey             *eek_keyboard_find_key_by_keycode
 | 
			
		||||
EekKey             *eek_keyboard_find_key_by_name
 | 
			
		||||
                                     (EekKeyboard        *keyboard,
 | 
			
		||||
                                      guint               keycode);
 | 
			
		||||
                                      const gchar        *name);
 | 
			
		||||
 | 
			
		||||
guint               eek_keyboard_add_outline
 | 
			
		||||
                                     (EekKeyboard        *keyboard,
 | 
			
		||||
 | 
			
		||||
@ -23,9 +23,7 @@
 | 
			
		||||
 * @short_description: an #EekSymbol represents an X keysym
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_CONFIG_H
 | 
			
		||||
#include "config.h"
 | 
			
		||||
#endif  /* HAVE_CONFIG_H */
 | 
			
		||||
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										121
									
								
								eek/eek-layout.c
									
									
									
									
									
								
							
							
						
						
									
										121
									
								
								eek/eek-layout.c
									
									
									
									
									
								
							@ -26,9 +26,7 @@
 | 
			
		||||
 * arranges keyboard elements.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_CONFIG_H
 | 
			
		||||
#include "config.h"
 | 
			
		||||
#endif  /* HAVE_CONFIG_H */
 | 
			
		||||
 | 
			
		||||
#include "eek-layout.h"
 | 
			
		||||
#include "eek-keyboard.h"
 | 
			
		||||
@ -69,3 +67,122 @@ eek_keyboard_new (EekboardContextService *manager,
 | 
			
		||||
                                                          initial_width,
 | 
			
		||||
                                                          initial_height);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const double section_spacing = 7.0;
 | 
			
		||||
 | 
			
		||||
struct place_data {
 | 
			
		||||
    double desired_width;
 | 
			
		||||
    double current_offset;
 | 
			
		||||
    EekKeyboard *keyboard;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
section_placer(EekElement *element, gpointer user_data)
 | 
			
		||||
{
 | 
			
		||||
    struct place_data *data = (struct place_data*)user_data;
 | 
			
		||||
 | 
			
		||||
    EekBounds section_bounds = {0};
 | 
			
		||||
    eek_element_get_bounds(element, §ion_bounds);
 | 
			
		||||
    section_bounds.width = data->desired_width;
 | 
			
		||||
    eek_element_set_bounds(element, §ion_bounds);
 | 
			
		||||
 | 
			
		||||
    // Sections are rows now. Gather up all the keys and adjust their bounds.
 | 
			
		||||
    eek_section_place_keys(EEK_SECTION(element), EEK_KEYBOARD(data->keyboard));
 | 
			
		||||
 | 
			
		||||
    eek_element_get_bounds(element, §ion_bounds);
 | 
			
		||||
    section_bounds.y = data->current_offset;
 | 
			
		||||
    eek_element_set_bounds(element, §ion_bounds);
 | 
			
		||||
    data->current_offset += section_bounds.height + section_spacing;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
section_counter(EekElement *element, gpointer user_data) {
 | 
			
		||||
 | 
			
		||||
    double *total_height = user_data;
 | 
			
		||||
    EekBounds section_bounds = {0};
 | 
			
		||||
    eek_element_get_bounds(element, §ion_bounds);
 | 
			
		||||
    *total_height += section_bounds.height + section_spacing;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
eek_layout_place_sections(EekKeyboard *keyboard)
 | 
			
		||||
{
 | 
			
		||||
    /* Order rows */
 | 
			
		||||
    // This needs to be done after outlines, because outlines define key sizes
 | 
			
		||||
    // TODO: do this only for rows without bounds
 | 
			
		||||
 | 
			
		||||
    // The keyboard width is given by the user via screen size. The height will be given dynamically.
 | 
			
		||||
    // TODO: calculate max line width beforehand for button centering. Leave keyboard centering to the renderer later
 | 
			
		||||
    EekBounds keyboard_bounds = {0};
 | 
			
		||||
    eek_element_get_bounds(EEK_ELEMENT(keyboard), &keyboard_bounds);
 | 
			
		||||
 | 
			
		||||
    struct place_data placer_data = {
 | 
			
		||||
        .desired_width = keyboard_bounds.width,
 | 
			
		||||
        .current_offset = 0,
 | 
			
		||||
        .keyboard = keyboard,
 | 
			
		||||
    };
 | 
			
		||||
    eek_container_foreach_child(EEK_CONTAINER(keyboard), section_placer, &placer_data);
 | 
			
		||||
 | 
			
		||||
    double total_height = 0;
 | 
			
		||||
    eek_container_foreach_child(EEK_CONTAINER(keyboard), section_counter, &total_height);
 | 
			
		||||
    keyboard_bounds.height = total_height;
 | 
			
		||||
    eek_element_set_bounds(EEK_ELEMENT(keyboard), &keyboard_bounds);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void scale_bounds_callback (EekElement *element,
 | 
			
		||||
                                   gpointer    user_data);
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
scale_bounds (EekElement *element,
 | 
			
		||||
              gdouble     scale)
 | 
			
		||||
{
 | 
			
		||||
    EekBounds bounds;
 | 
			
		||||
 | 
			
		||||
    eek_element_get_bounds (element, &bounds);
 | 
			
		||||
    bounds.x *= scale;
 | 
			
		||||
    bounds.y *= scale;
 | 
			
		||||
    bounds.width *= scale;
 | 
			
		||||
    bounds.height *= scale;
 | 
			
		||||
    eek_element_set_bounds (element, &bounds);
 | 
			
		||||
 | 
			
		||||
    if (EEK_IS_CONTAINER(element))
 | 
			
		||||
        eek_container_foreach_child (EEK_CONTAINER(element),
 | 
			
		||||
                                     scale_bounds_callback,
 | 
			
		||||
                                     &scale);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
scale_bounds_callback (EekElement *element,
 | 
			
		||||
                       gpointer    user_data)
 | 
			
		||||
{
 | 
			
		||||
    scale_bounds (element, *(gdouble *)user_data);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
eek_layout_scale_keyboard(EekKeyboard *keyboard, gdouble scale)
 | 
			
		||||
{
 | 
			
		||||
    gsize n_outlines;
 | 
			
		||||
 | 
			
		||||
    scale_bounds (EEK_ELEMENT(keyboard), scale);
 | 
			
		||||
 | 
			
		||||
    n_outlines = eek_keyboard_get_n_outlines (keyboard);
 | 
			
		||||
    for (guint i = 0; i < n_outlines; i++) {
 | 
			
		||||
        EekOutline *outline = eek_keyboard_get_outline (keyboard, i);
 | 
			
		||||
        gint j;
 | 
			
		||||
 | 
			
		||||
        for (j = 0; j < outline->num_points; j++) {
 | 
			
		||||
            outline->points[j].x *= scale;
 | 
			
		||||
            outline->points[j].y *= scale;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    keyboard->scale = scale;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
eek_layout_update_layout(EekKeyboard *keyboard)
 | 
			
		||||
{
 | 
			
		||||
    eek_layout_scale_keyboard(keyboard, 1.0 / keyboard->scale);
 | 
			
		||||
    eek_layout_place_sections(keyboard);
 | 
			
		||||
    eek_layout_scale_keyboard(keyboard, 1.0 / keyboard->scale);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -55,5 +55,11 @@ struct _EekLayoutClass
 | 
			
		||||
 | 
			
		||||
GType        eek_layout_get_type  (void) G_GNUC_CONST;
 | 
			
		||||
 | 
			
		||||
void         eek_layout_place_sections(EekKeyboard *keyboard);
 | 
			
		||||
 | 
			
		||||
void         eek_layout_scale_keyboard(EekKeyboard *keyboard, gdouble scale);
 | 
			
		||||
 | 
			
		||||
void         eek_layout_update_layout(EekKeyboard *keyboard);
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
#endif  /* EEK_LAYOUT_H */
 | 
			
		||||
 | 
			
		||||
@ -18,12 +18,12 @@
 | 
			
		||||
 * 02110-1301 USA
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_CONFIG_H
 | 
			
		||||
#include "config.h"
 | 
			
		||||
#endif  /* HAVE_CONFIG_H */
 | 
			
		||||
 | 
			
		||||
#include <math.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <gdk-pixbuf/gdk-pixbuf.h>
 | 
			
		||||
#include <gtk/gtk.h>
 | 
			
		||||
 | 
			
		||||
#include "eek-key.h"
 | 
			
		||||
#include "eek-section.h"
 | 
			
		||||
@ -48,11 +48,13 @@ typedef struct _EekRendererPrivate
 | 
			
		||||
    gdouble allocation_width;
 | 
			
		||||
    gdouble allocation_height;
 | 
			
		||||
    gdouble scale;
 | 
			
		||||
    gint scale_factor; /* the outputs scale factor */
 | 
			
		||||
 | 
			
		||||
    PangoFontDescription *ascii_font;
 | 
			
		||||
    PangoFontDescription *font;
 | 
			
		||||
    GHashTable *outline_surface_cache;
 | 
			
		||||
    GHashTable *active_outline_surface_cache;
 | 
			
		||||
    GHashTable *icons;
 | 
			
		||||
    cairo_surface_t *keyboard_surface;
 | 
			
		||||
    gulong symbol_index_changed_handler;
 | 
			
		||||
 | 
			
		||||
@ -145,12 +147,11 @@ create_keyboard_surface_section_callback (EekElement *element,
 | 
			
		||||
    cairo_restore (data->cr);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static cairo_surface_t *
 | 
			
		||||
create_keyboard_surface (EekRenderer *renderer)
 | 
			
		||||
void
 | 
			
		||||
render_keyboard_surface (EekRenderer *renderer)
 | 
			
		||||
{
 | 
			
		||||
    EekRendererPrivate *priv = eek_renderer_get_instance_private (renderer);
 | 
			
		||||
    EekBounds bounds;
 | 
			
		||||
    cairo_surface_t *keyboard_surface;
 | 
			
		||||
    CreateKeyboardSurfaceCallbackData data;
 | 
			
		||||
    EekColor foreground, background;
 | 
			
		||||
 | 
			
		||||
@ -163,14 +164,7 @@ create_keyboard_surface (EekRenderer *renderer)
 | 
			
		||||
 | 
			
		||||
    eek_element_get_bounds (EEK_ELEMENT(priv->keyboard), &bounds);
 | 
			
		||||
 | 
			
		||||
    /* Create a surface that encompasses the dimensions of the keyboard as well
 | 
			
		||||
       as the margin around the edge. */
 | 
			
		||||
    keyboard_surface = cairo_image_surface_create (
 | 
			
		||||
        CAIRO_FORMAT_ARGB32,
 | 
			
		||||
        ceil(((bounds.x * 2) + bounds.width) * priv->scale),
 | 
			
		||||
        ceil(((bounds.y * 2) + bounds.height) * priv->scale));
 | 
			
		||||
 | 
			
		||||
    data.cr = cairo_create (keyboard_surface);
 | 
			
		||||
    data.cr = cairo_create (priv->keyboard_surface);
 | 
			
		||||
    data.renderer = renderer;
 | 
			
		||||
 | 
			
		||||
    cairo_translate (data.cr, bounds.x * priv->scale, bounds.y * priv->scale);
 | 
			
		||||
@ -194,8 +188,6 @@ create_keyboard_surface (EekRenderer *renderer)
 | 
			
		||||
                                 create_keyboard_surface_section_callback,
 | 
			
		||||
                                 &data);
 | 
			
		||||
    cairo_destroy (data.cr);
 | 
			
		||||
 | 
			
		||||
    return keyboard_surface;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
@ -445,6 +437,9 @@ render_key (EekRenderer *self,
 | 
			
		||||
    PangoRectangle extents = { 0, };
 | 
			
		||||
    EekColor foreground;
 | 
			
		||||
 | 
			
		||||
    if (!eek_key_has_label(key))
 | 
			
		||||
        return;
 | 
			
		||||
 | 
			
		||||
    oref = eek_key_get_oref (key);
 | 
			
		||||
    outline = eek_keyboard_get_outline (priv->keyboard, oref);
 | 
			
		||||
    if (outline == NULL)
 | 
			
		||||
@ -499,21 +494,21 @@ render_key (EekRenderer *self,
 | 
			
		||||
 | 
			
		||||
 #define SCALE 0.4
 | 
			
		||||
    if (eek_symbol_get_icon_name (symbol)) {
 | 
			
		||||
 | 
			
		||||
        gint scale = priv->scale_factor;
 | 
			
		||||
        cairo_surface_t *icon_surface =
 | 
			
		||||
            eek_renderer_get_icon_surface (self,
 | 
			
		||||
                                           eek_symbol_get_icon_name (symbol),
 | 
			
		||||
                                           MIN(bounds.width, bounds.height));
 | 
			
		||||
                                           SCALE * MIN(bounds.width, bounds.height),
 | 
			
		||||
                                           scale);
 | 
			
		||||
        if (icon_surface) {
 | 
			
		||||
            gint width = cairo_image_surface_get_width (icon_surface);
 | 
			
		||||
            gint height = cairo_image_surface_get_height (icon_surface);
 | 
			
		||||
 | 
			
		||||
            cairo_save (cr);
 | 
			
		||||
            cairo_translate (cr,
 | 
			
		||||
                             (bounds.width - width * SCALE) / 2,
 | 
			
		||||
                             (bounds.height - height * SCALE) / 2);
 | 
			
		||||
                             (bounds.width - width / scale) / 2,
 | 
			
		||||
                             (bounds.height - height / scale) / 2);
 | 
			
		||||
            cairo_rectangle (cr, 0, 0, width, height);
 | 
			
		||||
            cairo_scale (cr, SCALE, SCALE);
 | 
			
		||||
            cairo_clip (cr);
 | 
			
		||||
            /* Draw the shape of the icon using the foreground color */
 | 
			
		||||
            cairo_set_source_rgba (cr, foreground.red,
 | 
			
		||||
@ -701,8 +696,14 @@ eek_renderer_real_render_keyboard (EekRenderer *self,
 | 
			
		||||
    g_return_if_fail (priv->allocation_width > 0.0);
 | 
			
		||||
    g_return_if_fail (priv->allocation_height > 0.0);
 | 
			
		||||
 | 
			
		||||
    if (!priv->keyboard_surface)
 | 
			
		||||
        priv->keyboard_surface = create_keyboard_surface (self);
 | 
			
		||||
    if (priv->keyboard_surface)
 | 
			
		||||
        cairo_surface_destroy (priv->keyboard_surface);
 | 
			
		||||
 | 
			
		||||
    priv->keyboard_surface = cairo_surface_create_for_rectangle (
 | 
			
		||||
        cairo_get_target (cr), 0, 0,
 | 
			
		||||
        priv->allocation_width, priv->allocation_height);
 | 
			
		||||
 | 
			
		||||
    render_keyboard_surface (self);
 | 
			
		||||
 | 
			
		||||
    cairo_set_source_surface (cr, priv->keyboard_surface, 0.0, 0.0);
 | 
			
		||||
    source = cairo_get_source (cr);
 | 
			
		||||
@ -777,6 +778,8 @@ eek_renderer_dispose (GObject *object)
 | 
			
		||||
        priv->pcontext = NULL;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    g_clear_pointer (&priv->icons, g_hash_table_destroy);
 | 
			
		||||
 | 
			
		||||
    /* this will release all allocated surfaces and font if any */
 | 
			
		||||
    invalidate (EEK_RENDERER(object));
 | 
			
		||||
 | 
			
		||||
@ -844,6 +847,7 @@ eek_renderer_init (EekRenderer *self)
 | 
			
		||||
    priv->allocation_width = 0.0;
 | 
			
		||||
    priv->allocation_height = 0.0;
 | 
			
		||||
    priv->scale = 1.0;
 | 
			
		||||
    priv->scale_factor = 1;
 | 
			
		||||
    priv->font = NULL;
 | 
			
		||||
    priv->outline_surface_cache =
 | 
			
		||||
        g_hash_table_new_full (g_direct_hash,
 | 
			
		||||
@ -857,6 +861,14 @@ eek_renderer_init (EekRenderer *self)
 | 
			
		||||
                               (GDestroyNotify)cairo_surface_destroy);
 | 
			
		||||
    priv->keyboard_surface = NULL;
 | 
			
		||||
    priv->symbol_index_changed_handler = 0;
 | 
			
		||||
 | 
			
		||||
    GtkIconTheme *theme = gtk_icon_theme_get_default ();
 | 
			
		||||
 | 
			
		||||
    gtk_icon_theme_add_resource_path (theme, "/sm/puri/squeekboard/icons");
 | 
			
		||||
    priv->icons = g_hash_table_new_full (g_str_hash,
 | 
			
		||||
                                         g_str_equal,
 | 
			
		||||
                                         g_free,
 | 
			
		||||
                                         (GDestroyNotify)cairo_surface_destroy);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
@ -1028,6 +1040,15 @@ eek_renderer_get_scale (EekRenderer *renderer)
 | 
			
		||||
    return priv->scale;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
eek_renderer_set_scale_factor (EekRenderer *renderer, gint scale)
 | 
			
		||||
{
 | 
			
		||||
    g_return_if_fail (EEK_IS_RENDERER(renderer));
 | 
			
		||||
 | 
			
		||||
    EekRendererPrivate *priv = eek_renderer_get_instance_private (renderer);
 | 
			
		||||
    priv->scale_factor = scale;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
PangoLayout *
 | 
			
		||||
eek_renderer_create_pango_layout (EekRenderer  *renderer)
 | 
			
		||||
{
 | 
			
		||||
@ -1071,16 +1092,35 @@ eek_renderer_render_key_outline (EekRenderer *renderer,
 | 
			
		||||
cairo_surface_t *
 | 
			
		||||
eek_renderer_get_icon_surface (EekRenderer *renderer,
 | 
			
		||||
                               const gchar *icon_name,
 | 
			
		||||
                               gint size)
 | 
			
		||||
                               gint size,
 | 
			
		||||
                               gint scale)
 | 
			
		||||
{
 | 
			
		||||
    EekRendererClass *klass;
 | 
			
		||||
    GError *error = NULL;
 | 
			
		||||
    cairo_surface_t *surface;
 | 
			
		||||
 | 
			
		||||
    g_return_val_if_fail (EEK_IS_RENDERER(renderer), NULL);
 | 
			
		||||
 | 
			
		||||
    klass = EEK_RENDERER_GET_CLASS(renderer);
 | 
			
		||||
    if (klass->get_icon_surface)
 | 
			
		||||
        return klass->get_icon_surface (renderer, icon_name, size);
 | 
			
		||||
    return NULL;
 | 
			
		||||
    EekRendererPrivate *priv = eek_renderer_get_instance_private (renderer);
 | 
			
		||||
 | 
			
		||||
    surface = g_hash_table_lookup (priv->icons, icon_name);
 | 
			
		||||
    if (!surface) {
 | 
			
		||||
        surface = gtk_icon_theme_load_surface (gtk_icon_theme_get_default (),
 | 
			
		||||
                                               icon_name,
 | 
			
		||||
                                               size,
 | 
			
		||||
                                               scale,
 | 
			
		||||
                                               NULL,
 | 
			
		||||
                                               0,
 | 
			
		||||
                                               &error);
 | 
			
		||||
        g_hash_table_insert (priv->icons, g_strdup(icon_name), surface);
 | 
			
		||||
        if (surface == NULL) {
 | 
			
		||||
            g_warning ("can't get icon surface for %s: %s",
 | 
			
		||||
                       icon_name,
 | 
			
		||||
                       error->message);
 | 
			
		||||
            g_error_free (error);
 | 
			
		||||
            return NULL;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    return surface;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
 | 
			
		||||
@ -58,7 +58,8 @@ struct _EekRendererClass
 | 
			
		||||
 | 
			
		||||
    cairo_surface_t *(* get_icon_surface)   (EekRenderer *self,
 | 
			
		||||
                                             const gchar *icon_name,
 | 
			
		||||
                                             gint         size);
 | 
			
		||||
                                             gint         size,
 | 
			
		||||
                                             gint         scale);
 | 
			
		||||
 | 
			
		||||
    /*< private >*/
 | 
			
		||||
    /* padding */
 | 
			
		||||
@ -81,6 +82,8 @@ void             eek_renderer_get_key_bounds   (EekRenderer     *renderer,
 | 
			
		||||
                                                gboolean         rotate);
 | 
			
		||||
 | 
			
		||||
gdouble          eek_renderer_get_scale        (EekRenderer     *renderer);
 | 
			
		||||
void             eek_renderer_set_scale_factor (EekRenderer     *renderer,
 | 
			
		||||
                                                gint             scale);
 | 
			
		||||
 | 
			
		||||
PangoLayout     *eek_renderer_create_pango_layout
 | 
			
		||||
                                               (EekRenderer     *renderer);
 | 
			
		||||
@ -103,7 +106,8 @@ void             eek_renderer_render_key       (EekRenderer     *renderer,
 | 
			
		||||
 | 
			
		||||
cairo_surface_t *eek_renderer_get_icon_surface (EekRenderer     *renderer,
 | 
			
		||||
                                                const gchar     *icon_name,
 | 
			
		||||
                                                gint             size);
 | 
			
		||||
                                                gint             size,
 | 
			
		||||
                                                gint             scale);
 | 
			
		||||
 | 
			
		||||
void             eek_renderer_render_keyboard  (EekRenderer     *renderer,
 | 
			
		||||
                                                cairo_t         *cr);
 | 
			
		||||
 | 
			
		||||
@ -27,9 +27,7 @@
 | 
			
		||||
 * of one or more keys of the #EekKeyClass class.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_CONFIG_H
 | 
			
		||||
#include "config.h"
 | 
			
		||||
#endif  /* HAVE_CONFIG_H */
 | 
			
		||||
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
@ -124,7 +122,8 @@ on_unlocked (EekKey     *key,
 | 
			
		||||
 | 
			
		||||
static EekKey *
 | 
			
		||||
eek_section_real_create_key (EekSection *self,
 | 
			
		||||
                             guint       keycode,
 | 
			
		||||
                             const gchar *name,
 | 
			
		||||
                             gint        keycode,
 | 
			
		||||
                             gint        column_index,
 | 
			
		||||
                             gint        row_index)
 | 
			
		||||
{
 | 
			
		||||
@ -142,6 +141,7 @@ eek_section_real_create_key (EekSection *self,
 | 
			
		||||
        row->num_columns = column_index + 1;
 | 
			
		||||
 | 
			
		||||
    key = g_object_new (EEK_TYPE_KEY,
 | 
			
		||||
                        "name", name,
 | 
			
		||||
                        "keycode", keycode,
 | 
			
		||||
                        "column", column_index,
 | 
			
		||||
                        "row", row_index,
 | 
			
		||||
@ -463,6 +463,7 @@ eek_section_get_row (EekSection     *section,
 | 
			
		||||
/**
 | 
			
		||||
 * eek_section_create_key:
 | 
			
		||||
 * @section: an #EekSection
 | 
			
		||||
 * @name: a name
 | 
			
		||||
 * @keycode: a keycode
 | 
			
		||||
 * @column: the column index of the key
 | 
			
		||||
 * @row: the row index of the key
 | 
			
		||||
@ -473,19 +474,32 @@ eek_section_get_row (EekSection     *section,
 | 
			
		||||
 */
 | 
			
		||||
EekKey *
 | 
			
		||||
eek_section_create_key (EekSection *section,
 | 
			
		||||
                        guint       keycode,
 | 
			
		||||
                        const gchar *name,
 | 
			
		||||
                        gint        keycode,
 | 
			
		||||
                        gint        column,
 | 
			
		||||
                        gint        row)
 | 
			
		||||
{
 | 
			
		||||
    g_return_val_if_fail (EEK_IS_SECTION(section), NULL);
 | 
			
		||||
    return EEK_SECTION_GET_CLASS(section)->create_key (section,
 | 
			
		||||
                                                       name,
 | 
			
		||||
                                                       keycode,
 | 
			
		||||
                                                       column,
 | 
			
		||||
                                                       row);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void keysizer(EekElement *element, gpointer user_data) {
 | 
			
		||||
const double keyspacing = 4.0;
 | 
			
		||||
 | 
			
		||||
struct keys_info {
 | 
			
		||||
    uint count;
 | 
			
		||||
    double total_width;
 | 
			
		||||
    double biggest_height;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
keysizer(EekElement *element, gpointer user_data)
 | 
			
		||||
{
 | 
			
		||||
    EekKey *key = EEK_KEY(element);
 | 
			
		||||
 | 
			
		||||
    EekKeyboard *keyboard = EEK_KEYBOARD(user_data);
 | 
			
		||||
    uint oref = eek_key_get_oref (key);
 | 
			
		||||
    EekOutline *outline = eek_keyboard_get_outline (keyboard, oref);
 | 
			
		||||
@ -516,13 +530,15 @@ static void keysizer(EekElement *element, gpointer user_data) {
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
struct keys_info {
 | 
			
		||||
    uint count;
 | 
			
		||||
    double total_width;
 | 
			
		||||
    double biggest_height;
 | 
			
		||||
};
 | 
			
		||||
static void
 | 
			
		||||
keycounter (EekElement *element, gpointer user_data)
 | 
			
		||||
{
 | 
			
		||||
    EekKey *key = EEK_KEY(element);
 | 
			
		||||
 | 
			
		||||
    /* Skip keys without labels for the current level. */
 | 
			
		||||
    if (!eek_key_has_label(key))
 | 
			
		||||
        return;
 | 
			
		||||
 | 
			
		||||
static void keycounter (EekElement *element, gpointer user_data) {
 | 
			
		||||
    struct keys_info *data = user_data;
 | 
			
		||||
    data->count++;
 | 
			
		||||
    EekBounds key_bounds = {0};
 | 
			
		||||
@ -533,9 +549,15 @@ static void keycounter (EekElement *element, gpointer user_data) {
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const double keyspacing = 4.0;
 | 
			
		||||
static void
 | 
			
		||||
keyplacer(EekElement *element, gpointer user_data)
 | 
			
		||||
{
 | 
			
		||||
    EekKey *key = EEK_KEY(element);
 | 
			
		||||
 | 
			
		||||
    /* Skip keys without labels for the current level. */
 | 
			
		||||
    if (!eek_key_has_label(key))
 | 
			
		||||
        return;
 | 
			
		||||
 | 
			
		||||
static void keyplacer(EekElement *element, gpointer user_data) {
 | 
			
		||||
    double *current_offset = user_data;
 | 
			
		||||
    EekBounds key_bounds = {0};
 | 
			
		||||
    eek_element_get_bounds(element, &key_bounds);
 | 
			
		||||
@ -545,7 +567,8 @@ static void keyplacer(EekElement *element, gpointer user_data) {
 | 
			
		||||
    *current_offset += key_bounds.width + keyspacing;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void eek_section_place_keys(EekSection *section, EekKeyboard *keyboard)
 | 
			
		||||
void
 | 
			
		||||
eek_section_place_keys(EekSection *section, EekKeyboard *keyboard)
 | 
			
		||||
{
 | 
			
		||||
    eek_container_foreach_child(EEK_CONTAINER(section), keysizer, keyboard);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -62,7 +62,8 @@ struct _EekSectionClass
 | 
			
		||||
                                     EekOrientation *orientation);
 | 
			
		||||
 | 
			
		||||
    EekKey *(* create_key)          (EekSection     *self,
 | 
			
		||||
                                     guint           keycode,
 | 
			
		||||
                                     const gchar    *name,
 | 
			
		||||
                                     gint            keycode,
 | 
			
		||||
                                     gint            row,
 | 
			
		||||
                                     gint            column);
 | 
			
		||||
 | 
			
		||||
@ -99,7 +100,8 @@ void    eek_section_get_row              (EekSection     *section,
 | 
			
		||||
                                          EekOrientation *orientation);
 | 
			
		||||
 | 
			
		||||
EekKey *eek_section_create_key           (EekSection     *section,
 | 
			
		||||
                                          guint           keycode,
 | 
			
		||||
                                          const gchar    *name,
 | 
			
		||||
                                          gint            keycode,
 | 
			
		||||
                                          gint            column,
 | 
			
		||||
                                          gint            row);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -27,9 +27,7 @@
 | 
			
		||||
 * method.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_CONFIG_H
 | 
			
		||||
#include "config.h"
 | 
			
		||||
#endif  /* HAVE_CONFIG_H */
 | 
			
		||||
 | 
			
		||||
#include "eek-serializable.h"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -25,9 +25,7 @@
 | 
			
		||||
 * The #EekSymbolClass class represents a symbol assigned to a key.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_CONFIG_H
 | 
			
		||||
#include "config.h"
 | 
			
		||||
#endif  /* HAVE_CONFIG_H */
 | 
			
		||||
 | 
			
		||||
#include "eek-symbol.h"
 | 
			
		||||
#include "eek-serializable.h"
 | 
			
		||||
 | 
			
		||||
@ -23,9 +23,7 @@
 | 
			
		||||
 * @short_description: an #EekText represents a text symbol
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_CONFIG_H
 | 
			
		||||
#include "config.h"
 | 
			
		||||
#endif  /* HAVE_CONFIG_H */
 | 
			
		||||
 | 
			
		||||
#include "eek-text.h"
 | 
			
		||||
#include "eek-serializable.h"
 | 
			
		||||
 | 
			
		||||
@ -19,9 +19,7 @@
 | 
			
		||||
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_CONFIG_H
 | 
			
		||||
#include "config.h"
 | 
			
		||||
#endif  /* HAVE_CONFIG_H */
 | 
			
		||||
 | 
			
		||||
#include "eek-theme.h"
 | 
			
		||||
#include "eek-theme-context.h"
 | 
			
		||||
 | 
			
		||||
@ -23,9 +23,7 @@
 | 
			
		||||
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_CONFIG_H
 | 
			
		||||
#include "config.h"
 | 
			
		||||
#endif  /* HAVE_CONFIG_H */
 | 
			
		||||
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
@ -24,9 +24,7 @@
 | 
			
		||||
 * @short_description: Miscellaneous types used in Libeek
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_CONFIG_H
 | 
			
		||||
#include "config.h"
 | 
			
		||||
#endif  /* HAVE_CONFIG_H */
 | 
			
		||||
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <math.h>
 | 
			
		||||
 | 
			
		||||
@ -1,30 +0,0 @@
 | 
			
		||||
# Copyright (C) 2010-2011 Daiki Ueno <ueno@unixuser.org>
 | 
			
		||||
# Copyright (C) 2010-2011 Red Hat, Inc.
 | 
			
		||||
 | 
			
		||||
# This library is free software; you can redistribute it and/or
 | 
			
		||||
# modify it under the terms of the GNU Lesser General Public License
 | 
			
		||||
# as published by the Free Software Foundation; either version 2 of
 | 
			
		||||
# the License, or (at your option) any later version.
 | 
			
		||||
 | 
			
		||||
# This library is distributed in the hope that it will be useful, but
 | 
			
		||||
# WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
			
		||||
# Lesser General Public License for more details.
 | 
			
		||||
 | 
			
		||||
# You should have received a copy of the GNU Lesser General Public
 | 
			
		||||
# License along with this library; if not, write to the Free Software
 | 
			
		||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 | 
			
		||||
# 02110-1301 USA
 | 
			
		||||
 | 
			
		||||
prefix=@prefix@
 | 
			
		||||
exec_prefix=@exec_prefix@
 | 
			
		||||
libdir=@libdir@
 | 
			
		||||
includedir=@includedir@
 | 
			
		||||
 | 
			
		||||
Name: libeek-xkb
 | 
			
		||||
Description: A Library to Create Keyboard-like UI (XKB Support)
 | 
			
		||||
URL: http://fedorahosted.org/eekboard/
 | 
			
		||||
Version: @VERSION@
 | 
			
		||||
Requires: eek-@EEK_API_VERSION@ gtk+-x11-@GTK_API_VERSION@
 | 
			
		||||
Libs: -L${libdir} -leek-xkb
 | 
			
		||||
Cflags: -I${includedir}/eek-@EEK_API_VERSION@
 | 
			
		||||
@ -1,684 +0,0 @@
 | 
			
		||||
/* 
 | 
			
		||||
 * Copyright (C) 2006 Sergey V. Udaltsov <svu@gnome.org>
 | 
			
		||||
 * Copyright (C) 2010-2011 Daiki Ueno <ueno@unixuser.org>
 | 
			
		||||
 * Copyright (C) 2010-2011 Red Hat, Inc.
 | 
			
		||||
 * 
 | 
			
		||||
 * This library is free software; you can redistribute it and/or
 | 
			
		||||
 * modify it under the terms of the GNU Lesser General Public License
 | 
			
		||||
 * as published by the Free Software Foundation; either version 2 of
 | 
			
		||||
 * the License, or (at your option) any later version.
 | 
			
		||||
 * 
 | 
			
		||||
 * This library is distributed in the hope that it will be useful, but
 | 
			
		||||
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
			
		||||
 * Lesser General Public License for more details.
 | 
			
		||||
 * 
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General Public
 | 
			
		||||
 * License along with this library; if not, write to the Free Software
 | 
			
		||||
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 | 
			
		||||
 * 02110-1301 USA
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * SECTION:eek-xkb-layout
 | 
			
		||||
 * @short_description: Layout engine using XKB configuration
 | 
			
		||||
 *
 | 
			
		||||
 * The #EekXkbLayout inherits #EekLayout class and arranges keyboard
 | 
			
		||||
 * elements using XKB.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_CONFIG_H
 | 
			
		||||
#include "config.h"
 | 
			
		||||
#endif  /* HAVE_CONFIG_H */
 | 
			
		||||
 | 
			
		||||
#include "eek-xkb-layout.h"
 | 
			
		||||
 | 
			
		||||
#include <X11/keysym.h>
 | 
			
		||||
#include <X11/extensions/XKBgeom.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <stdarg.h>
 | 
			
		||||
#include <gio/gio.h>
 | 
			
		||||
 | 
			
		||||
#include "eek-keyboard.h"
 | 
			
		||||
#include "eek-section.h"
 | 
			
		||||
#include "eek-key.h"
 | 
			
		||||
#include "eek-keysym.h"
 | 
			
		||||
 | 
			
		||||
#define XKB_COMPONENT_MASK (XkbGBN_GeometryMask |       \
 | 
			
		||||
                            XkbGBN_KeyNamesMask |       \
 | 
			
		||||
                            XkbGBN_OtherNamesMask |     \
 | 
			
		||||
                            XkbGBN_SymbolsMask |        \
 | 
			
		||||
                            XkbGBN_IndicatorMapMask)
 | 
			
		||||
 | 
			
		||||
static void initable_iface_init (GInitableIface *initable_iface);
 | 
			
		||||
 | 
			
		||||
enum {
 | 
			
		||||
    PROP_0,
 | 
			
		||||
    PROP_DISPLAY,
 | 
			
		||||
    PROP_LAST
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
typedef struct _EekXkbLayoutPrivate
 | 
			
		||||
{
 | 
			
		||||
    /* Configuration names that should synch'ed to the symbolic names
 | 
			
		||||
       in priv->xkb->names.  Since we use GLib's memory allocator,
 | 
			
		||||
       don't store any address returned from the X server here. */
 | 
			
		||||
    XkbComponentNamesRec names;
 | 
			
		||||
 | 
			
		||||
    Display *display;
 | 
			
		||||
 | 
			
		||||
    /* Actual XKB configuration of DISPLAY. */
 | 
			
		||||
    XkbDescRec *xkb;
 | 
			
		||||
 | 
			
		||||
    /* Hash table to cache orefs by shape address. */
 | 
			
		||||
    GHashTable *shape_oref_hash;
 | 
			
		||||
 | 
			
		||||
    gint scale_numerator;
 | 
			
		||||
    gint scale_denominator;
 | 
			
		||||
} EekXkbLayoutPrivate;
 | 
			
		||||
 | 
			
		||||
G_DEFINE_TYPE_EXTENDED (EekXkbLayout, eek_xkb_layout, EEK_TYPE_LAYOUT,
 | 
			
		||||
			0, /* GTypeFlags */
 | 
			
		||||
			G_ADD_PRIVATE(EekXkbLayout)
 | 
			
		||||
                        G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE,
 | 
			
		||||
                                               initable_iface_init))
 | 
			
		||||
 | 
			
		||||
static guint    find_keycode             (EekXkbLayout *layout,
 | 
			
		||||
                                          gchar        *key_name);
 | 
			
		||||
 | 
			
		||||
static gboolean get_keyboard_from_server (EekXkbLayout *layout,
 | 
			
		||||
                                          GError      **error);
 | 
			
		||||
 | 
			
		||||
static gboolean get_names_from_server    (EekXkbLayout *layout,
 | 
			
		||||
                                          GError      **error);
 | 
			
		||||
 | 
			
		||||
static void     setup_scaling            (EekXkbLayout *layout,
 | 
			
		||||
                                          gdouble       width,
 | 
			
		||||
                                          gdouble       height);
 | 
			
		||||
 | 
			
		||||
G_INLINE_FUNC gint
 | 
			
		||||
xkb_to_pixmap_coord (EekXkbLayout *layout,
 | 
			
		||||
                     gint          n)
 | 
			
		||||
{
 | 
			
		||||
    EekXkbLayoutPrivate *priv = eek_xkb_layout_get_instance_private (layout);
 | 
			
		||||
    return n * priv->scale_numerator / priv->scale_denominator;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
G_INLINE_FUNC gdouble
 | 
			
		||||
xkb_to_pixmap_double (EekXkbLayout *layout,
 | 
			
		||||
                     gdouble       d)
 | 
			
		||||
{
 | 
			
		||||
    EekXkbLayoutPrivate *priv = eek_xkb_layout_get_instance_private (layout);
 | 
			
		||||
    return d * priv->scale_numerator / priv->scale_denominator;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
create_key (EekXkbLayout *layout,
 | 
			
		||||
            EekKeyboard  *keyboard,
 | 
			
		||||
            EekSection   *section,
 | 
			
		||||
            gint          column,
 | 
			
		||||
            gint          row,
 | 
			
		||||
            gdouble       x,
 | 
			
		||||
            gdouble       y,
 | 
			
		||||
            XkbKeyRec    *xkbkey)
 | 
			
		||||
{
 | 
			
		||||
    XkbGeometryRec *xkbgeometry;
 | 
			
		||||
    XkbBoundsRec *xkbbounds;
 | 
			
		||||
    XkbShapeRec *xkbshape;
 | 
			
		||||
    XkbOutlineRec *xkboutline;
 | 
			
		||||
    EekXkbLayoutPrivate *priv = eek_xkb_layout_get_instance_private (layout);
 | 
			
		||||
    EekKey *key;
 | 
			
		||||
    EekBounds bounds;
 | 
			
		||||
    EekSymbolMatrix *matrix = NULL;
 | 
			
		||||
    gchar name[XkbKeyNameLength + 1];
 | 
			
		||||
    KeyCode keycode;
 | 
			
		||||
    gint num_groups, num_levels;
 | 
			
		||||
    guint oref;
 | 
			
		||||
    gpointer v;
 | 
			
		||||
 | 
			
		||||
    xkbgeometry = priv->xkb->geom;
 | 
			
		||||
    xkbshape = &xkbgeometry->shapes[xkbkey->shape_ndx];
 | 
			
		||||
    if (g_hash_table_lookup_extended (priv->shape_oref_hash, xkbshape,
 | 
			
		||||
                                      NULL, &v)) {
 | 
			
		||||
        oref = GPOINTER_TO_UINT(v);
 | 
			
		||||
    } else {
 | 
			
		||||
        EekOutline *outline;
 | 
			
		||||
 | 
			
		||||
        xkboutline = xkbshape->primary == NULL ? &xkbshape->outlines[0] :
 | 
			
		||||
            xkbshape->primary;
 | 
			
		||||
 | 
			
		||||
        outline = g_slice_new (EekOutline);
 | 
			
		||||
        outline->corner_radius = xkb_to_pixmap_coord(layout,
 | 
			
		||||
                                                     xkboutline->corner_radius);
 | 
			
		||||
 | 
			
		||||
        if (xkboutline->num_points <= 2) { /* rectangular */
 | 
			
		||||
            gdouble x1, y1, x2, y2;
 | 
			
		||||
 | 
			
		||||
            outline->num_points = 4;
 | 
			
		||||
            outline->points = g_slice_alloc0 (sizeof (EekPoint) *
 | 
			
		||||
                                              outline->num_points);
 | 
			
		||||
            if (xkboutline->num_points == 1) {
 | 
			
		||||
                x1 = xkb_to_pixmap_coord(layout, xkbshape->bounds.x1);
 | 
			
		||||
                y1 = xkb_to_pixmap_coord(layout, xkbshape->bounds.y1);
 | 
			
		||||
                x2 = xkb_to_pixmap_coord(layout, xkboutline->points[0].x);
 | 
			
		||||
                y2 = xkb_to_pixmap_coord(layout, xkboutline->points[0].y);
 | 
			
		||||
            } else {
 | 
			
		||||
                x1 = xkb_to_pixmap_coord(layout, xkboutline->points[0].x);
 | 
			
		||||
                y1 = xkb_to_pixmap_coord(layout, xkboutline->points[0].y);
 | 
			
		||||
                x2 = xkb_to_pixmap_coord(layout, xkboutline->points[1].x);
 | 
			
		||||
                y2 = xkb_to_pixmap_coord(layout, xkboutline->points[1].y);
 | 
			
		||||
            }
 | 
			
		||||
            outline->points[0].x = outline->points[3].x = x1;
 | 
			
		||||
            outline->points[0].y = outline->points[1].y = y1;
 | 
			
		||||
            outline->points[1].x = outline->points[2].x = x2;
 | 
			
		||||
            outline->points[2].y = outline->points[3].y = y2;
 | 
			
		||||
        } else {                /* polygon */
 | 
			
		||||
            gint i;
 | 
			
		||||
 | 
			
		||||
            outline->num_points = xkboutline->num_points;
 | 
			
		||||
            outline->points = g_new0 (EekPoint, outline->num_points);
 | 
			
		||||
            for (i = 0; i < xkboutline->num_points; i++) {
 | 
			
		||||
                outline->points[i].x =
 | 
			
		||||
                    xkb_to_pixmap_coord(layout, xkboutline->points[i].x);
 | 
			
		||||
                outline->points[i].y =
 | 
			
		||||
                    xkb_to_pixmap_coord(layout, xkboutline->points[i].y);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        oref = eek_keyboard_add_outline (keyboard, outline);
 | 
			
		||||
        eek_outline_free (outline);
 | 
			
		||||
        g_hash_table_insert (priv->shape_oref_hash, xkbshape,
 | 
			
		||||
                             GUINT_TO_POINTER(oref));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    memset (name, 0, sizeof name);
 | 
			
		||||
    memcpy (name, xkbkey->name.name, sizeof name - 1);
 | 
			
		||||
 | 
			
		||||
    xkbbounds = &xkbgeometry->shapes[xkbkey->shape_ndx].bounds;
 | 
			
		||||
    bounds.x = xkb_to_pixmap_coord(layout, xkbbounds->x1 + x);
 | 
			
		||||
    bounds.y = xkb_to_pixmap_coord(layout, xkbbounds->y1 + y);
 | 
			
		||||
    bounds.width = xkb_to_pixmap_coord(layout, xkbbounds->x2 - xkbbounds->x1);
 | 
			
		||||
    bounds.height = xkb_to_pixmap_coord(layout, xkbbounds->y2 - xkbbounds->y1);
 | 
			
		||||
 | 
			
		||||
    keycode = find_keycode (layout, name);
 | 
			
		||||
    if (keycode == EEK_INVALID_KEYCODE) {
 | 
			
		||||
        num_groups = num_levels = 0;
 | 
			
		||||
        matrix = eek_symbol_matrix_new (0, 0);
 | 
			
		||||
    } else {
 | 
			
		||||
        KeySym keysym;
 | 
			
		||||
        gint i, j;
 | 
			
		||||
 | 
			
		||||
        num_groups = XkbKeyNumGroups (priv->xkb, keycode);
 | 
			
		||||
        num_levels = XkbKeyGroupsWidth (priv->xkb, keycode);
 | 
			
		||||
        matrix = eek_symbol_matrix_new (num_groups, num_levels);
 | 
			
		||||
        for (i = 0; i < num_groups; i++)
 | 
			
		||||
            for (j = 0; j < num_levels; j++) {
 | 
			
		||||
                EekModifierType modifier;
 | 
			
		||||
 | 
			
		||||
                keysym = XkbKeySymEntry (priv->xkb, keycode, j, i);
 | 
			
		||||
                modifier = XkbKeysymToModifiers (priv->display, keysym);
 | 
			
		||||
                matrix->data[i * num_levels + j] =
 | 
			
		||||
                    EEK_SYMBOL(eek_keysym_new_with_modifier (keysym,
 | 
			
		||||
                                                             modifier));
 | 
			
		||||
            }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    key = eek_section_create_key (section, keycode, column, row);
 | 
			
		||||
    eek_element_set_name (EEK_ELEMENT(key), name);
 | 
			
		||||
    eek_element_set_bounds (EEK_ELEMENT(key), &bounds);
 | 
			
		||||
    eek_key_set_symbol_matrix (key, matrix);
 | 
			
		||||
    eek_symbol_matrix_free (matrix);
 | 
			
		||||
    eek_key_set_oref (key, oref);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
create_section (EekXkbLayout  *layout,
 | 
			
		||||
                EekKeyboard   *keyboard,
 | 
			
		||||
                XkbSectionRec *xkbsection)
 | 
			
		||||
{
 | 
			
		||||
    XkbGeometryRec *xkbgeometry;
 | 
			
		||||
    EekXkbLayoutPrivate *priv = eek_xkb_layout_get_instance_private (layout);
 | 
			
		||||
    EekSection *section;
 | 
			
		||||
    EekBounds bounds;
 | 
			
		||||
    gchar *name;
 | 
			
		||||
    gfloat left, top;
 | 
			
		||||
    gint i, j;
 | 
			
		||||
 | 
			
		||||
    bounds.x = xkb_to_pixmap_coord(layout, xkbsection->left);
 | 
			
		||||
    bounds.y = xkb_to_pixmap_coord(layout, xkbsection->top);
 | 
			
		||||
    bounds.width = xkb_to_pixmap_coord(layout, xkbsection->width);
 | 
			
		||||
    bounds.height = xkb_to_pixmap_coord(layout, xkbsection->height);
 | 
			
		||||
 | 
			
		||||
    xkbgeometry = priv->xkb->geom;
 | 
			
		||||
    section = eek_keyboard_create_section (keyboard);
 | 
			
		||||
    name = XGetAtomName (priv->display, xkbsection->name);
 | 
			
		||||
    eek_element_set_name (EEK_ELEMENT(section), name);
 | 
			
		||||
    XFree (name);
 | 
			
		||||
    eek_element_set_bounds (EEK_ELEMENT(section), &bounds);
 | 
			
		||||
    eek_section_set_angle (section,
 | 
			
		||||
                           /* angle is in tenth of degree */
 | 
			
		||||
                           xkbsection->angle / 10);
 | 
			
		||||
 | 
			
		||||
    for (i = 0; i < xkbsection->num_rows; i++) {
 | 
			
		||||
        XkbRowRec *xkbrow;
 | 
			
		||||
 | 
			
		||||
        xkbrow = &xkbsection->rows[i];
 | 
			
		||||
        left = xkbrow->left;
 | 
			
		||||
        top = xkbrow->top;
 | 
			
		||||
        eek_section_add_row (section,
 | 
			
		||||
                             xkbrow->num_keys,
 | 
			
		||||
                             xkbrow->vertical ?
 | 
			
		||||
                             EEK_ORIENTATION_VERTICAL :
 | 
			
		||||
                             EEK_ORIENTATION_HORIZONTAL);
 | 
			
		||||
        for (j = 0; j < xkbrow->num_keys; j++) {
 | 
			
		||||
            XkbKeyRec *xkbkey;
 | 
			
		||||
            XkbBoundsRec *xkbbounds;
 | 
			
		||||
 | 
			
		||||
            xkbkey = &xkbrow->keys[j];
 | 
			
		||||
            if (xkbrow->vertical)
 | 
			
		||||
                top += xkbkey->gap;
 | 
			
		||||
            else
 | 
			
		||||
                left += xkbkey->gap;
 | 
			
		||||
            create_key (layout, keyboard, section, j, i, left, top, xkbkey);
 | 
			
		||||
            xkbbounds = &xkbgeometry->shapes[xkbkey->shape_ndx].bounds;
 | 
			
		||||
            if (xkbrow->vertical)
 | 
			
		||||
                top += xkbbounds->y2 - xkbbounds->y1;
 | 
			
		||||
            else
 | 
			
		||||
                left += xkbbounds->x2 - xkbbounds->x1;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
create_keyboard (EekXkbLayout *layout, EekKeyboard *keyboard)
 | 
			
		||||
{
 | 
			
		||||
    EekXkbLayoutPrivate *priv = eek_xkb_layout_get_instance_private (layout);
 | 
			
		||||
    XkbGeometryRec *xkbgeometry;
 | 
			
		||||
    EekBounds bounds;
 | 
			
		||||
    gint i;
 | 
			
		||||
 | 
			
		||||
    g_return_if_fail (priv->xkb);
 | 
			
		||||
    g_return_if_fail (priv->xkb->geom);
 | 
			
		||||
 | 
			
		||||
    xkbgeometry = priv->xkb->geom;
 | 
			
		||||
 | 
			
		||||
    eek_element_get_bounds (EEK_ELEMENT(keyboard), &bounds);
 | 
			
		||||
    setup_scaling (EEK_XKB_LAYOUT(layout), bounds.width, bounds.height);
 | 
			
		||||
 | 
			
		||||
    bounds.x = bounds.y = 0;
 | 
			
		||||
    bounds.width = xkb_to_pixmap_coord(layout, xkbgeometry->width_mm);
 | 
			
		||||
    bounds.height = xkb_to_pixmap_coord(layout, xkbgeometry->height_mm);
 | 
			
		||||
 | 
			
		||||
    for (i = 0; i < xkbgeometry->num_sections; i++) {
 | 
			
		||||
        XkbSectionRec *xkbsection;
 | 
			
		||||
 | 
			
		||||
        xkbsection = &xkbgeometry->sections[i];
 | 
			
		||||
        create_section (layout, keyboard, xkbsection);
 | 
			
		||||
    }
 | 
			
		||||
    eek_element_set_bounds (EEK_ELEMENT(keyboard), &bounds);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static EekKeyboard *
 | 
			
		||||
eek_xkb_layout_real_create_keyboard (EekboardContextService *manager,
 | 
			
		||||
                                     EekLayout *self,
 | 
			
		||||
                                     gdouble    initial_width,
 | 
			
		||||
                                     gdouble    initial_height)
 | 
			
		||||
{
 | 
			
		||||
    EekKeyboard *keyboard = g_object_new (EEK_TYPE_KEYBOARD, "layout", self, NULL);
 | 
			
		||||
    keyboard->manager = manager;
 | 
			
		||||
 | 
			
		||||
    EekBounds bounds = {
 | 
			
		||||
        .x = 0.0,
 | 
			
		||||
        .y = 0.0,
 | 
			
		||||
        .width = initial_width,
 | 
			
		||||
        .height = initial_height
 | 
			
		||||
    };
 | 
			
		||||
    eek_element_set_bounds (EEK_ELEMENT(keyboard), &bounds);
 | 
			
		||||
 | 
			
		||||
    /* resolve modifiers dynamically assigned at run time */
 | 
			
		||||
    EekXkbLayoutPrivate *priv = eek_xkb_layout_get_instance_private (
 | 
			
		||||
		    EEK_XKB_LAYOUT(self));
 | 
			
		||||
    eek_keyboard_set_num_lock_mask (keyboard,
 | 
			
		||||
                                    XkbKeysymToModifiers (priv->display,
 | 
			
		||||
                                                          XK_Num_Lock));
 | 
			
		||||
    eek_keyboard_set_alt_gr_mask (keyboard,
 | 
			
		||||
                                  XkbKeysymToModifiers (priv->display,
 | 
			
		||||
                                                        XK_ISO_Level3_Shift));
 | 
			
		||||
 | 
			
		||||
    if (priv->shape_oref_hash)
 | 
			
		||||
        g_hash_table_destroy (priv->shape_oref_hash);
 | 
			
		||||
 | 
			
		||||
    priv->shape_oref_hash = g_hash_table_new (g_direct_hash, g_direct_equal);
 | 
			
		||||
    create_keyboard (EEK_XKB_LAYOUT(self), keyboard);
 | 
			
		||||
    g_hash_table_destroy (priv->shape_oref_hash);
 | 
			
		||||
 | 
			
		||||
    return keyboard;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
eek_xkb_layout_finalize (GObject *object)
 | 
			
		||||
{
 | 
			
		||||
    EekXkbLayoutPrivate *priv = eek_xkb_layout_get_instance_private (
 | 
			
		||||
		    EEK_XKB_LAYOUT (object));
 | 
			
		||||
 | 
			
		||||
    g_free (priv->names.keycodes);
 | 
			
		||||
    g_free (priv->names.geometry);
 | 
			
		||||
    g_free (priv->names.symbols);
 | 
			
		||||
    XkbFreeKeyboard (priv->xkb, 0, TRUE);	/* free_all = TRUE */
 | 
			
		||||
    G_OBJECT_CLASS (eek_xkb_layout_parent_class)->finalize (object);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void 
 | 
			
		||||
eek_xkb_layout_set_property (GObject      *object,
 | 
			
		||||
                             guint         prop_id,
 | 
			
		||||
                             const GValue *value,
 | 
			
		||||
                             GParamSpec   *pspec)
 | 
			
		||||
{
 | 
			
		||||
    EekXkbLayout *layout = EEK_XKB_LAYOUT (object);
 | 
			
		||||
    EekXkbLayoutPrivate *priv = eek_xkb_layout_get_instance_private (layout);
 | 
			
		||||
 | 
			
		||||
    switch (prop_id) {
 | 
			
		||||
    case PROP_DISPLAY:
 | 
			
		||||
        priv->display = g_value_get_pointer (value);
 | 
			
		||||
        break;
 | 
			
		||||
    default:
 | 
			
		||||
        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void 
 | 
			
		||||
eek_xkb_layout_get_property (GObject    *object,
 | 
			
		||||
                             guint       prop_id,
 | 
			
		||||
                             GValue     *value,
 | 
			
		||||
                             GParamSpec *pspec)
 | 
			
		||||
{
 | 
			
		||||
    EekXkbLayout *layout = EEK_XKB_LAYOUT (object);
 | 
			
		||||
    EekXkbLayoutPrivate *priv = eek_xkb_layout_get_instance_private (layout);
 | 
			
		||||
 | 
			
		||||
    switch (prop_id) {
 | 
			
		||||
    case PROP_DISPLAY:
 | 
			
		||||
        g_value_set_pointer (value, priv->display);
 | 
			
		||||
        break;
 | 
			
		||||
    default:
 | 
			
		||||
        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
eek_xkb_layout_class_init (EekXkbLayoutClass *klass)
 | 
			
		||||
{
 | 
			
		||||
    EekLayoutClass *layout_class = EEK_LAYOUT_CLASS (klass);
 | 
			
		||||
    GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
 | 
			
		||||
    GParamSpec *pspec;
 | 
			
		||||
 | 
			
		||||
    layout_class->create_keyboard = eek_xkb_layout_real_create_keyboard;
 | 
			
		||||
 | 
			
		||||
    gobject_class->finalize = eek_xkb_layout_finalize;
 | 
			
		||||
    gobject_class->set_property = eek_xkb_layout_set_property;
 | 
			
		||||
    gobject_class->get_property = eek_xkb_layout_get_property;
 | 
			
		||||
 | 
			
		||||
    pspec = g_param_spec_pointer ("display",
 | 
			
		||||
                                  "Display",
 | 
			
		||||
                                  "X Display",
 | 
			
		||||
                                  G_PARAM_READWRITE |
 | 
			
		||||
                                  G_PARAM_CONSTRUCT_ONLY);
 | 
			
		||||
    g_object_class_install_property (gobject_class, PROP_DISPLAY, pspec);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
eek_xkb_layout_init (EekXkbLayout *self)
 | 
			
		||||
{
 | 
			
		||||
    /* void */
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
get_names_from_server (EekXkbLayout *layout,
 | 
			
		||||
                       GError      **error)
 | 
			
		||||
{
 | 
			
		||||
    EekXkbLayoutPrivate *priv = eek_xkb_layout_get_instance_private (layout);
 | 
			
		||||
    gchar *name;
 | 
			
		||||
 | 
			
		||||
    XkbGetNames (priv->display, XkbAllNamesMask, priv->xkb);
 | 
			
		||||
 | 
			
		||||
    if (priv->xkb->names->keycodes <= 0)
 | 
			
		||||
        g_warning ("XKB keycodes setting is not loaded properly");
 | 
			
		||||
    else {
 | 
			
		||||
        name = XGetAtomName (priv->display, priv->xkb->names->keycodes);
 | 
			
		||||
        if (!name)
 | 
			
		||||
            g_warning ("Can't get the name of keycodes");
 | 
			
		||||
        else if (!priv->names.keycodes ||
 | 
			
		||||
                 g_strcmp0 (name, priv->names.keycodes)) {
 | 
			
		||||
            g_free (priv->names.keycodes);
 | 
			
		||||
            priv->names.keycodes = g_strdup (name);
 | 
			
		||||
            XFree (name);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (priv->xkb->names->geometry <= 0)
 | 
			
		||||
        g_warning ("XKB geometry setting is not loaded");
 | 
			
		||||
    else {
 | 
			
		||||
        name = XGetAtomName (priv->display, priv->xkb->names->geometry);
 | 
			
		||||
        if (!name)
 | 
			
		||||
            g_warning ("Can't get the name of geometry");
 | 
			
		||||
        else if (!priv->names.geometry ||
 | 
			
		||||
                 g_strcmp0 (name, priv->names.geometry)) {
 | 
			
		||||
            g_free (priv->names.geometry);
 | 
			
		||||
            priv->names.geometry = g_strdup (name);
 | 
			
		||||
            XFree (name);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (priv->xkb->names->symbols <= 0)
 | 
			
		||||
        g_warning ("XKB symbols setting is not loaded");
 | 
			
		||||
    else {
 | 
			
		||||
        name = XGetAtomName (priv->display, priv->xkb->names->symbols);
 | 
			
		||||
        if (!name)
 | 
			
		||||
            g_warning ("Can't get the name of symbols");
 | 
			
		||||
        else if (!priv->names.symbols ||
 | 
			
		||||
                 g_strcmp0 (name, priv->names.symbols)) {
 | 
			
		||||
            g_free (priv->names.symbols);
 | 
			
		||||
            priv->names.symbols = g_strdup (name);
 | 
			
		||||
            XFree (name);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eek_xkb_layout_new:
 | 
			
		||||
 *
 | 
			
		||||
 * Create a new #EekXkbLayout.
 | 
			
		||||
 */
 | 
			
		||||
EekLayout *
 | 
			
		||||
eek_xkb_layout_new (Display *display,
 | 
			
		||||
                    GError **error)
 | 
			
		||||
{
 | 
			
		||||
    return (EekLayout *) g_initable_new (EEK_TYPE_XKB_LAYOUT,
 | 
			
		||||
                                         NULL,
 | 
			
		||||
                                         error,
 | 
			
		||||
                                         "display", display,
 | 
			
		||||
                                         NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eek_xkb_layout_set_names: (skip)
 | 
			
		||||
 * @layout: an #EekXkbLayout
 | 
			
		||||
 * @names: XKB component names
 | 
			
		||||
 * @error: a #GError
 | 
			
		||||
 *
 | 
			
		||||
 * Set the XKB component names to @layout.
 | 
			
		||||
 * Returns: %TRUE if the component names are successfully set, %FALSE otherwise
 | 
			
		||||
 */
 | 
			
		||||
gboolean
 | 
			
		||||
eek_xkb_layout_set_names (EekXkbLayout         *layout,
 | 
			
		||||
                          XkbComponentNamesRec *names,
 | 
			
		||||
                          GError              **error)
 | 
			
		||||
{
 | 
			
		||||
    EekXkbLayoutPrivate *priv = eek_xkb_layout_get_instance_private (layout);
 | 
			
		||||
 | 
			
		||||
    if (g_strcmp0 (names->keycodes, priv->names.keycodes)) {
 | 
			
		||||
        g_free (priv->names.keycodes);
 | 
			
		||||
        priv->names.keycodes = g_strdup (names->keycodes);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (g_strcmp0 (names->geometry, priv->names.geometry)) {
 | 
			
		||||
        g_free (priv->names.geometry);
 | 
			
		||||
        priv->names.geometry = g_strdup (names->geometry);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (g_strcmp0 (names->symbols, priv->names.symbols)) {
 | 
			
		||||
        g_free (priv->names.symbols);
 | 
			
		||||
        priv->names.symbols = g_strdup (names->symbols);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return get_keyboard_from_server (layout, error);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
get_keyboard_from_server (EekXkbLayout *layout,
 | 
			
		||||
                          GError      **error)
 | 
			
		||||
{
 | 
			
		||||
    EekXkbLayoutPrivate *priv = eek_xkb_layout_get_instance_private (layout);
 | 
			
		||||
 | 
			
		||||
    if (priv->xkb) {
 | 
			
		||||
        XkbFreeKeyboard (priv->xkb, 0, True);
 | 
			
		||||
        priv->xkb = NULL;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (priv->names.keycodes && priv->names.geometry && priv->names.symbols) {
 | 
			
		||||
        priv->xkb = XkbGetKeyboardByName (priv->display,
 | 
			
		||||
                                          XkbUseCoreKbd,
 | 
			
		||||
                                          &priv->names,
 | 
			
		||||
                                          0,
 | 
			
		||||
                                          XKB_COMPONENT_MASK,
 | 
			
		||||
                                          False);
 | 
			
		||||
    } else {
 | 
			
		||||
        priv->xkb = XkbGetKeyboard (priv->display,
 | 
			
		||||
                                    XKB_COMPONENT_MASK,
 | 
			
		||||
                                    XkbUseCoreKbd);
 | 
			
		||||
        if (!get_names_from_server (layout, error)) {
 | 
			
		||||
            XkbFreeKeyboard (priv->xkb, 0, True);
 | 
			
		||||
            priv->xkb = NULL;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (priv->xkb == NULL) {
 | 
			
		||||
        g_set_error (error,
 | 
			
		||||
                     EEK_ERROR,
 | 
			
		||||
                     EEK_ERROR_LAYOUT_ERROR,
 | 
			
		||||
                     "can't get keyboard from server");
 | 
			
		||||
        g_free (priv->names.keycodes);
 | 
			
		||||
        priv->names.keycodes = NULL;
 | 
			
		||||
        g_free (priv->names.geometry);
 | 
			
		||||
        priv->names.geometry = NULL;
 | 
			
		||||
        g_free (priv->names.symbols);
 | 
			
		||||
        priv->names.symbols = NULL;
 | 
			
		||||
        return FALSE;
 | 
			
		||||
    }
 | 
			
		||||
    return TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static guint
 | 
			
		||||
find_keycode (EekXkbLayout *layout, gchar *key_name)
 | 
			
		||||
{
 | 
			
		||||
#define KEYSYM_NAME_MAX_LENGTH 4
 | 
			
		||||
    guint keycode;
 | 
			
		||||
    gint i, j;
 | 
			
		||||
    XkbKeyNamePtr pkey;
 | 
			
		||||
    XkbKeyAliasPtr palias;
 | 
			
		||||
    guint is_name_matched;
 | 
			
		||||
    gchar *src, *dst;
 | 
			
		||||
    EekXkbLayoutPrivate *priv = eek_xkb_layout_get_instance_private (layout);
 | 
			
		||||
 | 
			
		||||
    if (!priv->xkb)
 | 
			
		||||
        return EEK_INVALID_KEYCODE;
 | 
			
		||||
 | 
			
		||||
    pkey = priv->xkb->names->keys + priv->xkb->min_key_code;
 | 
			
		||||
    for (keycode = priv->xkb->min_key_code;
 | 
			
		||||
         keycode <= priv->xkb->max_key_code; keycode++) {
 | 
			
		||||
        is_name_matched = 1;
 | 
			
		||||
        src = key_name;
 | 
			
		||||
        dst = pkey->name;
 | 
			
		||||
        for (i = KEYSYM_NAME_MAX_LENGTH; --i >= 0;) {
 | 
			
		||||
            if ('\0' == *src)
 | 
			
		||||
                break;
 | 
			
		||||
            if (*src++ != *dst++) {
 | 
			
		||||
                is_name_matched = 0;
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        if (is_name_matched)
 | 
			
		||||
            return keycode;
 | 
			
		||||
        pkey++;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    palias = priv->xkb->names->key_aliases;
 | 
			
		||||
    for (j = priv->xkb->names->num_key_aliases; --j >= 0;) {
 | 
			
		||||
        is_name_matched = 1;
 | 
			
		||||
        src = key_name;
 | 
			
		||||
        dst = palias->alias;
 | 
			
		||||
        for (i = KEYSYM_NAME_MAX_LENGTH; --i >= 0;) {
 | 
			
		||||
            if ('\0' == *src)
 | 
			
		||||
                break;
 | 
			
		||||
            if (*src++ != *dst++) {
 | 
			
		||||
                is_name_matched = 0;
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (is_name_matched) {
 | 
			
		||||
            keycode = find_keycode (layout, palias->real);
 | 
			
		||||
            return keycode;
 | 
			
		||||
        }
 | 
			
		||||
        palias++;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return EEK_INVALID_KEYCODE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
setup_scaling (EekXkbLayout *layout,
 | 
			
		||||
               gdouble       width,
 | 
			
		||||
               gdouble       height)
 | 
			
		||||
{
 | 
			
		||||
    EekXkbLayoutPrivate *priv = eek_xkb_layout_get_instance_private (layout);
 | 
			
		||||
 | 
			
		||||
    g_return_if_fail (priv->xkb);
 | 
			
		||||
 | 
			
		||||
    g_return_if_fail (priv->xkb->geom->width_mm > 0);
 | 
			
		||||
    g_return_if_fail (priv->xkb->geom->height_mm > 0);
 | 
			
		||||
 | 
			
		||||
    if (width * priv->xkb->geom->height_mm <
 | 
			
		||||
        height * priv->xkb->geom->width_mm) {
 | 
			
		||||
        priv->scale_numerator = width;
 | 
			
		||||
        priv->scale_denominator = priv->xkb->geom->width_mm;
 | 
			
		||||
    } else {
 | 
			
		||||
        priv->scale_numerator = height;
 | 
			
		||||
        priv->scale_denominator = priv->xkb->geom->height_mm;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
initable_init (GInitable    *initable,
 | 
			
		||||
               GCancellable *cancellable,
 | 
			
		||||
               GError      **error)
 | 
			
		||||
{
 | 
			
		||||
    EekXkbLayout *layout = EEK_XKB_LAYOUT (initable);
 | 
			
		||||
 | 
			
		||||
    if (!get_keyboard_from_server (layout, error))
 | 
			
		||||
        return FALSE;
 | 
			
		||||
 | 
			
		||||
    if (!get_names_from_server (layout, error))
 | 
			
		||||
        return FALSE;
 | 
			
		||||
 | 
			
		||||
    return TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
initable_iface_init (GInitableIface *initable_iface)
 | 
			
		||||
{
 | 
			
		||||
  initable_iface->init = initable_init;
 | 
			
		||||
}
 | 
			
		||||
@ -1,55 +0,0 @@
 | 
			
		||||
/* 
 | 
			
		||||
 * Copyright (C) 2010-2011 Daiki Ueno <ueno@unixuser.org>
 | 
			
		||||
 * Copyright (C) 2010-2011 Red Hat, Inc.
 | 
			
		||||
 * 
 | 
			
		||||
 * This library is free software; you can redistribute it and/or
 | 
			
		||||
 * modify it under the terms of the GNU Lesser General Public License
 | 
			
		||||
 * as published by the Free Software Foundation; either version 2 of
 | 
			
		||||
 * the License, or (at your option) any later version.
 | 
			
		||||
 * 
 | 
			
		||||
 * This library is distributed in the hope that it will be useful, but
 | 
			
		||||
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
			
		||||
 * Lesser General Public License for more details.
 | 
			
		||||
 * 
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General Public
 | 
			
		||||
 * License along with this library; if not, write to the Free Software
 | 
			
		||||
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 | 
			
		||||
 * 02110-1301 USA
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#if !defined(__EEK_H_INSIDE__) && !defined(EEK_COMPILATION)
 | 
			
		||||
#error "Only <eek/eek-xkb.h> can be included directly."
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef EEK_XKB_LAYOUT_H
 | 
			
		||||
#define EEK_XKB_LAYOUT_H 1
 | 
			
		||||
 | 
			
		||||
#include <X11/XKBlib.h>
 | 
			
		||||
#include "eek-layout.h"
 | 
			
		||||
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
#define EEK_TYPE_XKB_LAYOUT (eek_xkb_layout_get_type())
 | 
			
		||||
G_DECLARE_DERIVABLE_TYPE (EekXkbLayout, eek_xkb_layout, EEK, XKB_LAYOUT, EekLayout)
 | 
			
		||||
 | 
			
		||||
struct _EekXkbLayoutClass
 | 
			
		||||
{
 | 
			
		||||
    /*< private >*/
 | 
			
		||||
    EekLayoutClass parent_class;
 | 
			
		||||
 | 
			
		||||
    /*< private >*/
 | 
			
		||||
    /* padding */
 | 
			
		||||
    gpointer pdummy[24];
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
GType      eek_xkb_layout_get_type  (void) G_GNUC_CONST;
 | 
			
		||||
EekLayout *eek_xkb_layout_new       (Display              *display,
 | 
			
		||||
                                     GError              **error);
 | 
			
		||||
 | 
			
		||||
gboolean   eek_xkb_layout_set_names (EekXkbLayout         *layout,
 | 
			
		||||
                                     XkbComponentNamesRec *names,
 | 
			
		||||
                                     GError              **error);
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
#endif				/* #ifndef EEK_XKB_LAYOUT_H */
 | 
			
		||||
@ -1,26 +0,0 @@
 | 
			
		||||
/* 
 | 
			
		||||
 * Copyright (C) 2010-2011 Daiki Ueno <ueno@unixuser.org>
 | 
			
		||||
 * Copyright (C) 2010-2011 Red Hat, Inc.
 | 
			
		||||
 * 
 | 
			
		||||
 * This library is free software; you can redistribute it and/or
 | 
			
		||||
 * modify it under the terms of the GNU Lesser General Public License
 | 
			
		||||
 * as published by the Free Software Foundation; either version 2 of
 | 
			
		||||
 * the License, or (at your option) any later version.
 | 
			
		||||
 * 
 | 
			
		||||
 * This library is distributed in the hope that it will be useful, but
 | 
			
		||||
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
			
		||||
 * Lesser General Public License for more details.
 | 
			
		||||
 * 
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General Public
 | 
			
		||||
 * License along with this library; if not, write to the Free Software
 | 
			
		||||
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 | 
			
		||||
 * 02110-1301 USA
 | 
			
		||||
 */
 | 
			
		||||
#ifndef EEK_XKB_H
 | 
			
		||||
#define EEK_XKB_H 1
 | 
			
		||||
 | 
			
		||||
#include "eek.h"
 | 
			
		||||
#include "eek-xkb-layout.h"
 | 
			
		||||
 | 
			
		||||
#endif  /* EEK_XKB_H */
 | 
			
		||||
@ -1,30 +0,0 @@
 | 
			
		||||
# Copyright (C) 2010-2011 Daiki Ueno <ueno@unixuser.org>
 | 
			
		||||
# Copyright (C) 2010-2011 Red Hat, Inc.
 | 
			
		||||
 | 
			
		||||
# This library is free software; you can redistribute it and/or
 | 
			
		||||
# modify it under the terms of the GNU Lesser General Public License
 | 
			
		||||
# as published by the Free Software Foundation; either version 2 of
 | 
			
		||||
# the License, or (at your option) any later version.
 | 
			
		||||
 | 
			
		||||
# This library is distributed in the hope that it will be useful, but
 | 
			
		||||
# WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
			
		||||
# Lesser General Public License for more details.
 | 
			
		||||
 | 
			
		||||
# You should have received a copy of the GNU Lesser General Public
 | 
			
		||||
# License along with this library; if not, write to the Free Software
 | 
			
		||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 | 
			
		||||
# 02110-1301 USA
 | 
			
		||||
 | 
			
		||||
prefix=@prefix@
 | 
			
		||||
exec_prefix=@exec_prefix@
 | 
			
		||||
libdir=@libdir@
 | 
			
		||||
includedir=@includedir@
 | 
			
		||||
 | 
			
		||||
Name: libeek-xkl
 | 
			
		||||
Description: A Library to Create Keyboard-like UI (Libxklavier Support)
 | 
			
		||||
URL: http://fedorahosted.org/eekboard/
 | 
			
		||||
Version: @VERSION@
 | 
			
		||||
Requires: eek-@EEK_API_VERSION@ libxklavier
 | 
			
		||||
Libs: -L${libdir} -leek-xkl
 | 
			
		||||
Cflags: -I${includedir}/eek-@EEK_API_VERSION@
 | 
			
		||||
@ -1,662 +0,0 @@
 | 
			
		||||
/* 
 | 
			
		||||
 * Copyright (C) 2010-2011 Daiki Ueno <ueno@unixuser.org>
 | 
			
		||||
 * Copyright (C) 2010-2011 Red Hat, Inc.
 | 
			
		||||
 * 
 | 
			
		||||
 * This library is free software; you can redistribute it and/or
 | 
			
		||||
 * modify it under the terms of the GNU Lesser General Public License
 | 
			
		||||
 * as published by the Free Software Foundation; either version 2 of
 | 
			
		||||
 * the License, or (at your option) any later version.
 | 
			
		||||
 * 
 | 
			
		||||
 * This library is distributed in the hope that it will be useful, but
 | 
			
		||||
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
			
		||||
 * Lesser General Public License for more details.
 | 
			
		||||
 * 
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General Public
 | 
			
		||||
 * License along with this library; if not, write to the Free Software
 | 
			
		||||
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 | 
			
		||||
 * 02110-1301 USA
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * SECTION:eek-xkl-layout
 | 
			
		||||
 * @short_description: Layout engine using Libxklavier configuration
 | 
			
		||||
 *
 | 
			
		||||
 * The #EekXklLayout is a simple wrapper around #EekXkbLayout class
 | 
			
		||||
 * to use Libxklavier configuration.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_CONFIG_H
 | 
			
		||||
#include "config.h"
 | 
			
		||||
#endif  /* HAVE_CONFIG_H */
 | 
			
		||||
 | 
			
		||||
#include <libxklavier/xklavier.h>
 | 
			
		||||
#include <gio/gio.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
#include "eek-xkl-layout.h"
 | 
			
		||||
 | 
			
		||||
#define noKBDRAW_DEBUG
 | 
			
		||||
 | 
			
		||||
static GInitableIface *parent_initable_iface;
 | 
			
		||||
 | 
			
		||||
static void initable_iface_init (GInitableIface *initable_iface);
 | 
			
		||||
 | 
			
		||||
enum {
 | 
			
		||||
    PROP_0,
 | 
			
		||||
    PROP_MODEL,
 | 
			
		||||
    PROP_LAYOUTS,
 | 
			
		||||
    PROP_VARIANTS,
 | 
			
		||||
    PROP_OPTIONS,
 | 
			
		||||
    PROP_LAST
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
typedef struct _EekXklLayoutPrivate
 | 
			
		||||
{
 | 
			
		||||
    XklEngine *engine;
 | 
			
		||||
    XklConfigRec *config;
 | 
			
		||||
} EekXklLayoutPrivate;
 | 
			
		||||
 | 
			
		||||
G_DEFINE_TYPE_EXTENDED (EekXklLayout, eek_xkl_layout, EEK_TYPE_XKB_LAYOUT,
 | 
			
		||||
			0, /* GTypeFlags */
 | 
			
		||||
			G_ADD_PRIVATE (EekXklLayout)
 | 
			
		||||
                        G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE,
 | 
			
		||||
                                               initable_iface_init))
 | 
			
		||||
 | 
			
		||||
/* from gnome-keyboard-properties-xkbpv.c:
 | 
			
		||||
 *  BAD STYLE: Taken from xklavier_private_xkb.h
 | 
			
		||||
 *  Any ideas on architectural improvements are WELCOME
 | 
			
		||||
 */
 | 
			
		||||
extern gboolean xkl_xkb_config_native_prepare (XklEngine * engine,
 | 
			
		||||
					       const XklConfigRec * data,
 | 
			
		||||
					       XkbComponentNamesPtr
 | 
			
		||||
					       component_names);
 | 
			
		||||
 | 
			
		||||
extern void xkl_xkb_config_native_cleanup (XklEngine * engine,
 | 
			
		||||
					   XkbComponentNamesPtr
 | 
			
		||||
					   component_names);
 | 
			
		||||
 | 
			
		||||
static gboolean set_xkb_component_names (EekXklLayout *layout,
 | 
			
		||||
                                         XklConfigRec *config);
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
eek_xkl_layout_dispose (GObject *object)
 | 
			
		||||
{
 | 
			
		||||
    EekXklLayoutPrivate *priv = eek_xkl_layout_get_instance_private (
 | 
			
		||||
		    EEK_XKL_LAYOUT (object));
 | 
			
		||||
 | 
			
		||||
    if (priv->config) {
 | 
			
		||||
        g_object_unref (priv->config);
 | 
			
		||||
        priv->config = NULL;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    G_OBJECT_CLASS (eek_xkl_layout_parent_class)->dispose (object);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void 
 | 
			
		||||
eek_xkl_layout_set_property (GObject      *object,
 | 
			
		||||
                             guint         prop_id,
 | 
			
		||||
                             const GValue *value,
 | 
			
		||||
                             GParamSpec   *pspec)
 | 
			
		||||
{
 | 
			
		||||
    EekXklLayout *layout = EEK_XKL_LAYOUT(object);
 | 
			
		||||
 | 
			
		||||
    switch (prop_id) {
 | 
			
		||||
    case PROP_MODEL:
 | 
			
		||||
        eek_xkl_layout_set_model (layout, g_value_get_string (value));
 | 
			
		||||
        break;
 | 
			
		||||
    case PROP_LAYOUTS:
 | 
			
		||||
        eek_xkl_layout_set_layouts (layout, g_value_get_boxed (value));
 | 
			
		||||
        break;
 | 
			
		||||
    case PROP_VARIANTS:
 | 
			
		||||
        eek_xkl_layout_set_variants (layout, g_value_get_boxed (value));
 | 
			
		||||
        break;
 | 
			
		||||
    case PROP_OPTIONS:
 | 
			
		||||
        eek_xkl_layout_set_options (layout, g_value_get_boxed (value));
 | 
			
		||||
        break;
 | 
			
		||||
    default:
 | 
			
		||||
        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void 
 | 
			
		||||
eek_xkl_layout_get_property (GObject    *object,
 | 
			
		||||
                             guint       prop_id,
 | 
			
		||||
                             GValue     *value,
 | 
			
		||||
                             GParamSpec *pspec)
 | 
			
		||||
{
 | 
			
		||||
    EekXklLayout *layout = EEK_XKL_LAYOUT(object);
 | 
			
		||||
 | 
			
		||||
    switch (prop_id) {
 | 
			
		||||
    case PROP_MODEL:
 | 
			
		||||
        g_value_set_string (value,
 | 
			
		||||
                            eek_xkl_layout_get_model (layout));
 | 
			
		||||
        break;
 | 
			
		||||
    case PROP_LAYOUTS:
 | 
			
		||||
        g_value_set_boxed (value,
 | 
			
		||||
                           eek_xkl_layout_get_layouts (layout));
 | 
			
		||||
        break;
 | 
			
		||||
    case PROP_VARIANTS:
 | 
			
		||||
        g_value_set_boxed (value,
 | 
			
		||||
                           eek_xkl_layout_get_variants (layout));
 | 
			
		||||
        break;
 | 
			
		||||
    case PROP_OPTIONS:
 | 
			
		||||
        g_value_set_boxed (value,
 | 
			
		||||
                           eek_xkl_layout_get_options (layout));
 | 
			
		||||
        break;
 | 
			
		||||
    default:
 | 
			
		||||
        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
eek_xkl_layout_class_init (EekXklLayoutClass *klass)
 | 
			
		||||
{
 | 
			
		||||
    GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
 | 
			
		||||
    GParamSpec *pspec;
 | 
			
		||||
 | 
			
		||||
    gobject_class->dispose = eek_xkl_layout_dispose;
 | 
			
		||||
    gobject_class->set_property = eek_xkl_layout_set_property;
 | 
			
		||||
    gobject_class->get_property = eek_xkl_layout_get_property;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * EekXklLayout:model:
 | 
			
		||||
     *
 | 
			
		||||
     * The libxklavier model name of #EekXklLayout.
 | 
			
		||||
     */
 | 
			
		||||
    pspec = g_param_spec_string ("model",
 | 
			
		||||
                                 "Model",
 | 
			
		||||
                                 "Libxklavier model",
 | 
			
		||||
                                 NULL,
 | 
			
		||||
                                 G_PARAM_READWRITE);
 | 
			
		||||
    g_object_class_install_property (gobject_class, PROP_MODEL, pspec);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * EekXklLayout:layouts:
 | 
			
		||||
     *
 | 
			
		||||
     * The libxklavier layout names of #EekXklLayout.
 | 
			
		||||
     */
 | 
			
		||||
    pspec = g_param_spec_boxed ("layouts",
 | 
			
		||||
                                "Layouts",
 | 
			
		||||
                                "Libxklavier layouts",
 | 
			
		||||
                                G_TYPE_STRV,
 | 
			
		||||
                                G_PARAM_READWRITE);
 | 
			
		||||
    g_object_class_install_property (gobject_class, PROP_LAYOUTS, pspec);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * EekXklLayout:variants:
 | 
			
		||||
     *
 | 
			
		||||
     * The libxklavier variant names of #EekXklLayout.
 | 
			
		||||
     */
 | 
			
		||||
    pspec = g_param_spec_boxed ("variants",
 | 
			
		||||
                                "Variants",
 | 
			
		||||
                                "Libxklavier variants",
 | 
			
		||||
                                G_TYPE_STRV,
 | 
			
		||||
                                G_PARAM_READWRITE);
 | 
			
		||||
    g_object_class_install_property (gobject_class, PROP_VARIANTS, pspec);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * EekXklLayout:options:
 | 
			
		||||
     *
 | 
			
		||||
     * The libxklavier option names of #EekXklLayout.
 | 
			
		||||
     */
 | 
			
		||||
    pspec = g_param_spec_boxed ("options",
 | 
			
		||||
                                "Options",
 | 
			
		||||
                                "Libxklavier options",
 | 
			
		||||
                                G_TYPE_STRV,
 | 
			
		||||
                                G_PARAM_READWRITE);
 | 
			
		||||
    g_object_class_install_property (gobject_class, PROP_OPTIONS, pspec);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
eek_xkl_layout_init (EekXklLayout *self)
 | 
			
		||||
{
 | 
			
		||||
    /* void */
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eek_xkl_layout_new:
 | 
			
		||||
 *
 | 
			
		||||
 * Create a new #EekXklLayout.
 | 
			
		||||
 */
 | 
			
		||||
EekLayout *
 | 
			
		||||
eek_xkl_layout_new (Display *display, GError **error)
 | 
			
		||||
{
 | 
			
		||||
    return (EekLayout *) g_initable_new (EEK_TYPE_XKL_LAYOUT,
 | 
			
		||||
                                         NULL,
 | 
			
		||||
                                         error,
 | 
			
		||||
                                         "display", display,
 | 
			
		||||
                                         NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
G_INLINE_FUNC void
 | 
			
		||||
merge_xkl_config_rec (XklConfigRec *dst, XklConfigRec *src)
 | 
			
		||||
{
 | 
			
		||||
    if (src->model) {
 | 
			
		||||
        g_free (dst->model);
 | 
			
		||||
        dst->model = g_strdup (src->model);
 | 
			
		||||
    }
 | 
			
		||||
    if (src->layouts) {
 | 
			
		||||
        g_strfreev (dst->layouts);
 | 
			
		||||
        dst->layouts = g_strdupv (src->layouts);
 | 
			
		||||
    }
 | 
			
		||||
    if (src->variants) {
 | 
			
		||||
        g_strfreev (dst->variants);
 | 
			
		||||
        dst->variants = g_strdupv (src->variants);
 | 
			
		||||
    }
 | 
			
		||||
    if (src->options) {
 | 
			
		||||
        g_strfreev (dst->options);
 | 
			
		||||
        dst->options = g_strdupv (src->options);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eek_xkl_layout_set_config: (skip)
 | 
			
		||||
 * @layout: an #EekXklLayout
 | 
			
		||||
 * @config: Libxklavier configuration
 | 
			
		||||
 *
 | 
			
		||||
 * Reconfigure @layout with @config.
 | 
			
		||||
 * Returns: %TRUE if the current layout changed, %FALSE otherwise
 | 
			
		||||
 */
 | 
			
		||||
gboolean
 | 
			
		||||
eek_xkl_layout_set_config (EekXklLayout *layout,
 | 
			
		||||
                           XklConfigRec *config)
 | 
			
		||||
{
 | 
			
		||||
    EekXklLayoutPrivate *priv = eek_xkl_layout_get_instance_private (layout);
 | 
			
		||||
    XklConfigRec *c;
 | 
			
		||||
    gboolean retval;
 | 
			
		||||
 | 
			
		||||
    g_return_val_if_fail (priv, FALSE);
 | 
			
		||||
    c = xkl_config_rec_new ();
 | 
			
		||||
    merge_xkl_config_rec (c, priv->config);
 | 
			
		||||
    merge_xkl_config_rec (c, config);
 | 
			
		||||
    retval = set_xkb_component_names (layout, c);
 | 
			
		||||
    g_object_unref (c);
 | 
			
		||||
    merge_xkl_config_rec (priv->config, config);
 | 
			
		||||
    return retval;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eek_xkl_layout_set_config_full:
 | 
			
		||||
 * @layout: an #EekXklLayout
 | 
			
		||||
 * @model: Libxklavier model name
 | 
			
		||||
 * @layouts: Libxklavier layouts
 | 
			
		||||
 * @variants: Libxklavier variants
 | 
			
		||||
 * @options: Libxklavier options
 | 
			
		||||
 *
 | 
			
		||||
 * Reconfigure @layout with @model, @layouts, @variants, and @options.
 | 
			
		||||
 * This function is merely a wrapper around
 | 
			
		||||
 * eek_xkl_layout_set_config() to avoid passing a pointer of
 | 
			
		||||
 * XklConfigRec, which is not currently available in the
 | 
			
		||||
 * gobject-introspection repository.
 | 
			
		||||
 *
 | 
			
		||||
 * Returns: %TRUE if the current layout changed, %FALSE otherwise
 | 
			
		||||
 * Since: 0.0.2
 | 
			
		||||
 */
 | 
			
		||||
gboolean
 | 
			
		||||
eek_xkl_layout_set_config_full (EekXklLayout *layout,
 | 
			
		||||
                                gchar *model,
 | 
			
		||||
                                gchar **layouts,
 | 
			
		||||
                                gchar **variants,
 | 
			
		||||
                                gchar **options)
 | 
			
		||||
{
 | 
			
		||||
    XklConfigRec *config;
 | 
			
		||||
    gboolean retval;
 | 
			
		||||
 | 
			
		||||
    config = xkl_config_rec_new ();
 | 
			
		||||
    config->model = g_strdup (model);
 | 
			
		||||
    config->layouts = g_strdupv (layouts);
 | 
			
		||||
    config->variants = g_strdupv (variants);
 | 
			
		||||
    config->options = g_strdupv (options);
 | 
			
		||||
    retval = eek_xkl_layout_set_config (layout, config);
 | 
			
		||||
    g_object_unref (config);
 | 
			
		||||
    return retval;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eek_xkl_layout_set_model:
 | 
			
		||||
 * @layout: an #EekXklLayout
 | 
			
		||||
 * @model: model name
 | 
			
		||||
 *
 | 
			
		||||
 * Set the model name of @layout configuration (in the Libxklavier terminology).
 | 
			
		||||
 * Returns: %TRUE if the current layout changed, %FALSE otherwise
 | 
			
		||||
 */
 | 
			
		||||
gboolean
 | 
			
		||||
eek_xkl_layout_set_model (EekXklLayout *layout,
 | 
			
		||||
                          const gchar  *model)
 | 
			
		||||
{
 | 
			
		||||
    EekXklLayoutPrivate *priv = eek_xkl_layout_get_instance_private (layout);
 | 
			
		||||
    XklConfigRec *config;
 | 
			
		||||
    gboolean retval;
 | 
			
		||||
    
 | 
			
		||||
    g_return_val_if_fail (priv, FALSE);
 | 
			
		||||
    config = xkl_config_rec_new ();
 | 
			
		||||
    /* config->model will be freed on g_object_unref (config) */
 | 
			
		||||
    if (model)
 | 
			
		||||
        config->model = g_strdup (model);
 | 
			
		||||
    else
 | 
			
		||||
        config->model = NULL;
 | 
			
		||||
    retval = eek_xkl_layout_set_config (layout, config);
 | 
			
		||||
    g_object_unref (config);
 | 
			
		||||
    return retval;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eek_xkl_layout_set_layouts:
 | 
			
		||||
 * @layout: an #EekXklLayout
 | 
			
		||||
 * @layouts: layout names
 | 
			
		||||
 *
 | 
			
		||||
 * Set the layout names of @layout (in the Libxklavier terminology).
 | 
			
		||||
 * Returns: %TRUE if the current layout changed, %FALSE otherwise
 | 
			
		||||
 */
 | 
			
		||||
gboolean
 | 
			
		||||
eek_xkl_layout_set_layouts (EekXklLayout *layout,
 | 
			
		||||
                            gchar       **layouts)
 | 
			
		||||
{
 | 
			
		||||
    EekXklLayoutPrivate *priv = eek_xkl_layout_get_instance_private (layout);
 | 
			
		||||
    XklConfigRec *config;
 | 
			
		||||
    gboolean retval;
 | 
			
		||||
 | 
			
		||||
    g_return_val_if_fail (priv, FALSE);
 | 
			
		||||
    config = xkl_config_rec_new ();
 | 
			
		||||
    /* config->layouts will be freed on g_object_unref (config) */
 | 
			
		||||
    if (layouts)
 | 
			
		||||
        config->layouts = g_strdupv (layouts);
 | 
			
		||||
    else
 | 
			
		||||
        config->layouts = layouts;
 | 
			
		||||
    retval = eek_xkl_layout_set_config (layout, config);
 | 
			
		||||
    g_object_unref (config);
 | 
			
		||||
    return retval;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eek_xkl_layout_set_variants:
 | 
			
		||||
 * @layout: an #EekXklLayout
 | 
			
		||||
 * @variants: variant names
 | 
			
		||||
 *
 | 
			
		||||
 * Set the variant names of @layout (in the Libxklavier terminology).
 | 
			
		||||
 * Returns: %TRUE if the current layout changed, %FALSE otherwise
 | 
			
		||||
 */
 | 
			
		||||
gboolean
 | 
			
		||||
eek_xkl_layout_set_variants (EekXklLayout *layout,
 | 
			
		||||
                             gchar       **variants)
 | 
			
		||||
{
 | 
			
		||||
    EekXklLayoutPrivate *priv = eek_xkl_layout_get_instance_private (layout);
 | 
			
		||||
    XklConfigRec *config;
 | 
			
		||||
    gboolean retval;
 | 
			
		||||
 | 
			
		||||
    g_return_val_if_fail (priv, FALSE);
 | 
			
		||||
    config = xkl_config_rec_new ();
 | 
			
		||||
    /* config->variants will be freed on g_object_unref (config) */
 | 
			
		||||
    if (variants)
 | 
			
		||||
        config->variants = g_strdupv (variants);
 | 
			
		||||
    else
 | 
			
		||||
        config->variants = NULL;
 | 
			
		||||
    retval = eek_xkl_layout_set_config (layout, config);
 | 
			
		||||
    g_object_unref (config);
 | 
			
		||||
    return retval;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eek_xkl_layout_set_options:
 | 
			
		||||
 * @layout: an #EekXklLayout
 | 
			
		||||
 * @options: option names
 | 
			
		||||
 *
 | 
			
		||||
 * Set the option names of @layout (in the Libxklavier terminology).
 | 
			
		||||
 * Returns: %TRUE if the current layout changed, %FALSE otherwise
 | 
			
		||||
 */
 | 
			
		||||
gboolean
 | 
			
		||||
eek_xkl_layout_set_options (EekXklLayout *layout,
 | 
			
		||||
                            gchar       **options)
 | 
			
		||||
{
 | 
			
		||||
    EekXklLayoutPrivate *priv = eek_xkl_layout_get_instance_private (layout);
 | 
			
		||||
    XklConfigRec *config;
 | 
			
		||||
    gboolean retval;
 | 
			
		||||
 | 
			
		||||
    g_return_val_if_fail (priv, FALSE);
 | 
			
		||||
    config = xkl_config_rec_new ();
 | 
			
		||||
    /* config->options will be freed on g_object_unref (config) */
 | 
			
		||||
    if (options)
 | 
			
		||||
        config->options = options;
 | 
			
		||||
    else
 | 
			
		||||
        config->options = NULL;
 | 
			
		||||
    retval = eek_xkl_layout_set_config (layout, config);
 | 
			
		||||
    g_object_unref (config);
 | 
			
		||||
    return retval;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eek_xkl_layout_enable_option:
 | 
			
		||||
 * @layout: an #EekXklLayout
 | 
			
		||||
 * @option: option name
 | 
			
		||||
 *
 | 
			
		||||
 * Set the option of @layout (in the Libxklavier terminology).
 | 
			
		||||
 * Returns: %TRUE if the current layout changed, %FALSE otherwise
 | 
			
		||||
 */
 | 
			
		||||
gboolean
 | 
			
		||||
eek_xkl_layout_enable_option  (EekXklLayout *layout,
 | 
			
		||||
                               const gchar  *option)
 | 
			
		||||
{
 | 
			
		||||
    gchar **options, **_options;
 | 
			
		||||
    gint i, j;
 | 
			
		||||
 | 
			
		||||
    options = eek_xkl_layout_get_options (layout);
 | 
			
		||||
    for (i = 0; options && options[i]; i++)
 | 
			
		||||
        if (g_strcmp0 (options[i], option) == 0)
 | 
			
		||||
            return TRUE;
 | 
			
		||||
    _options = g_new0 (gchar *, (i + 2));
 | 
			
		||||
    for (j = 0; j < i; j++)
 | 
			
		||||
        _options[j] = g_strdup (options[j]);
 | 
			
		||||
    _options[i] = g_strdup (option);
 | 
			
		||||
    /* eek_xkl_layout_set_options() will free _options and its elements. */
 | 
			
		||||
    return eek_xkl_layout_set_options (layout, _options);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eek_xkl_layout_disable_option:
 | 
			
		||||
 * @layout: an #EekXklLayout
 | 
			
		||||
 * @option: option name
 | 
			
		||||
 *
 | 
			
		||||
 * Unset the option of @layout (in the Libxklavier terminology).
 | 
			
		||||
 * Returns: %TRUE if the current layout changed, %FALSE otherwise
 | 
			
		||||
 */
 | 
			
		||||
gboolean
 | 
			
		||||
eek_xkl_layout_disable_option (EekXklLayout *layout,
 | 
			
		||||
                               const gchar  *option)
 | 
			
		||||
{
 | 
			
		||||
    gchar **options, **_options;
 | 
			
		||||
    gint i, j, k;
 | 
			
		||||
 | 
			
		||||
    options = eek_xkl_layout_get_options (layout);
 | 
			
		||||
    if (!options)
 | 
			
		||||
        return TRUE;
 | 
			
		||||
    for (i = 0, k = 0; options[i]; i++)
 | 
			
		||||
        if (g_strcmp0 (options[i], option) == 0)
 | 
			
		||||
            k = i;
 | 
			
		||||
    if (options[k] == NULL)
 | 
			
		||||
        return TRUE;
 | 
			
		||||
    _options = g_new0 (gchar *, i);
 | 
			
		||||
    for (j = 0; j < k; j++)
 | 
			
		||||
        _options[j] = g_strdup (options[j]);
 | 
			
		||||
    for (j = k + 1; j < i; j++)
 | 
			
		||||
        _options[j] = g_strdup (options[j]);
 | 
			
		||||
    /* eek_xkl_layout_set_options() will free _options and its elements. */
 | 
			
		||||
    return eek_xkl_layout_set_options (layout, _options);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eek_xkl_layout_get_model:
 | 
			
		||||
 * @layout: an #EekXklLayout
 | 
			
		||||
 *
 | 
			
		||||
 * Get the model name of @layout configuration (in the Libxklavier terminology).
 | 
			
		||||
 */
 | 
			
		||||
gchar *
 | 
			
		||||
eek_xkl_layout_get_model (EekXklLayout *layout)
 | 
			
		||||
{
 | 
			
		||||
    EekXklLayoutPrivate *priv = eek_xkl_layout_get_instance_private (layout);
 | 
			
		||||
 | 
			
		||||
    g_return_val_if_fail (priv, NULL);
 | 
			
		||||
    return g_strdup (priv->config->model);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eek_xkl_layout_get_layouts:
 | 
			
		||||
 * @layout: an #EekXklLayout
 | 
			
		||||
 *
 | 
			
		||||
 * Get the layout names of @layout configuration (in the Libxklavier
 | 
			
		||||
 * terminology).
 | 
			
		||||
 */
 | 
			
		||||
gchar **
 | 
			
		||||
eek_xkl_layout_get_layouts (EekXklLayout *layout)
 | 
			
		||||
{
 | 
			
		||||
    EekXklLayoutPrivate *priv = eek_xkl_layout_get_instance_private (layout);
 | 
			
		||||
 | 
			
		||||
    g_return_val_if_fail (priv, NULL);
 | 
			
		||||
    return g_strdupv (priv->config->layouts);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eek_xkl_layout_get_variants:
 | 
			
		||||
 * @layout: an #EekXklLayout
 | 
			
		||||
 *
 | 
			
		||||
 * Get the variant names of @layout configuration (in the Libxklavier
 | 
			
		||||
 * terminology).
 | 
			
		||||
 */
 | 
			
		||||
gchar **
 | 
			
		||||
eek_xkl_layout_get_variants (EekXklLayout *layout)
 | 
			
		||||
{
 | 
			
		||||
    EekXklLayoutPrivate *priv = eek_xkl_layout_get_instance_private (layout);
 | 
			
		||||
 | 
			
		||||
    g_return_val_if_fail (priv, NULL);
 | 
			
		||||
    return g_strdupv (priv->config->variants);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eek_xkl_layout_get_options:
 | 
			
		||||
 * @layout: an #EekXklLayout
 | 
			
		||||
 *
 | 
			
		||||
 * Get the option names of @layout configuration (in the Libxklavier
 | 
			
		||||
 * terminology).
 | 
			
		||||
 */
 | 
			
		||||
gchar **
 | 
			
		||||
eek_xkl_layout_get_options (EekXklLayout *layout)
 | 
			
		||||
{
 | 
			
		||||
    EekXklLayoutPrivate *priv = eek_xkl_layout_get_instance_private (layout);
 | 
			
		||||
 | 
			
		||||
    g_return_val_if_fail (priv, NULL);
 | 
			
		||||
    return g_strdupv (priv->config->options);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
set_xkb_component_names (EekXklLayout *layout, XklConfigRec *config)
 | 
			
		||||
{
 | 
			
		||||
    EekXklLayoutPrivate *priv = eek_xkl_layout_get_instance_private (layout);
 | 
			
		||||
    XkbComponentNamesRec names;
 | 
			
		||||
    gboolean retval = FALSE;
 | 
			
		||||
 | 
			
		||||
#if DEBUG
 | 
			
		||||
    if (config->layouts) {
 | 
			
		||||
        gint i;
 | 
			
		||||
 | 
			
		||||
        fprintf (stderr, "layout = ");
 | 
			
		||||
        for (i = 0; config->layouts[i] != NULL; i++)
 | 
			
		||||
            fprintf (stderr, "\"%s\" ", config->layouts[i]);
 | 
			
		||||
        fputc ('\n', stderr);
 | 
			
		||||
    } else
 | 
			
		||||
        fprintf (stderr, "layouts = NULL\n");
 | 
			
		||||
    if (config->variants) {
 | 
			
		||||
        gint i;
 | 
			
		||||
 | 
			
		||||
        fprintf (stderr, "variant = ");
 | 
			
		||||
        for (i = 0; config->variants[i]; i++)
 | 
			
		||||
            fprintf (stderr, "\"%s\" ", config->variants[i]);
 | 
			
		||||
        fputc ('\n', stderr);
 | 
			
		||||
    } else
 | 
			
		||||
        fprintf (stderr, "variants = NULL\n");
 | 
			
		||||
    if (config->options) {
 | 
			
		||||
        gint i;
 | 
			
		||||
 | 
			
		||||
        fprintf (stderr, "option = ");
 | 
			
		||||
        for (i = 0; config->options[i]; i++)
 | 
			
		||||
            fprintf (stderr, "\"%s\" ", config->options[i]);
 | 
			
		||||
        fputc ('\n', stderr);
 | 
			
		||||
    } else
 | 
			
		||||
        fprintf (stderr, "options = NULL\n");
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    if (xkl_xkb_config_native_prepare (priv->engine, config, &names)) {
 | 
			
		||||
        GError *error = NULL;
 | 
			
		||||
        retval = eek_xkb_layout_set_names (EEK_XKB_LAYOUT(layout),
 | 
			
		||||
                                           &names,
 | 
			
		||||
                                           &error);
 | 
			
		||||
        if (!retval)
 | 
			
		||||
            g_warning ("can't set XKB layout");
 | 
			
		||||
        xkl_xkb_config_native_cleanup (priv->engine, &names);
 | 
			
		||||
    }
 | 
			
		||||
    return retval;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eek_xkl_layout_get_option:
 | 
			
		||||
 * @layout: an #EekXklLayout
 | 
			
		||||
 * @option: option name
 | 
			
		||||
 *
 | 
			
		||||
 * Tell if the option of @layout (in the Libxklavier terminology) is set.
 | 
			
		||||
 * Returns: %TRUE if the option is set, %FALSE otherwise
 | 
			
		||||
 */
 | 
			
		||||
gboolean
 | 
			
		||||
eek_xkl_layout_get_option (EekXklLayout *layout,
 | 
			
		||||
                           const gchar  *option)
 | 
			
		||||
{
 | 
			
		||||
    gchar **options;
 | 
			
		||||
    gint i;
 | 
			
		||||
 | 
			
		||||
    options = eek_xkl_layout_get_options (layout);
 | 
			
		||||
    for (i = 0; options && options[i]; i++)
 | 
			
		||||
        if (g_strcmp0 (options[i], option) == 0)
 | 
			
		||||
            return TRUE;
 | 
			
		||||
    return FALSE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
initable_init (GInitable    *initable,
 | 
			
		||||
               GCancellable *cancellable,
 | 
			
		||||
               GError      **error)
 | 
			
		||||
{
 | 
			
		||||
    EekXklLayout *layout = EEK_XKL_LAYOUT (initable);
 | 
			
		||||
    EekXklLayoutPrivate *priv = eek_xkl_layout_get_instance_private (layout);
 | 
			
		||||
    Display *display;
 | 
			
		||||
 | 
			
		||||
    if (!parent_initable_iface->init (initable, cancellable, error))
 | 
			
		||||
        return FALSE;
 | 
			
		||||
 | 
			
		||||
    priv->config = xkl_config_rec_new ();
 | 
			
		||||
 | 
			
		||||
    g_object_get (G_OBJECT (initable),
 | 
			
		||||
                  "display", &display,
 | 
			
		||||
                  NULL);
 | 
			
		||||
 | 
			
		||||
    priv->engine = xkl_engine_get_instance (display);
 | 
			
		||||
 | 
			
		||||
    if (!xkl_config_rec_get_from_server (priv->config,
 | 
			
		||||
                                         priv->engine)) {
 | 
			
		||||
        g_set_error (error,
 | 
			
		||||
                     EEK_ERROR,
 | 
			
		||||
                     EEK_ERROR_LAYOUT_ERROR,
 | 
			
		||||
                     "can't load libxklavier configuration");
 | 
			
		||||
        return FALSE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    set_xkb_component_names (layout, priv->config);
 | 
			
		||||
    return TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
initable_iface_init (GInitableIface *initable_iface)
 | 
			
		||||
{
 | 
			
		||||
    parent_initable_iface = g_type_interface_peek_parent (initable_iface);
 | 
			
		||||
    initable_iface->init = initable_init;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -1,81 +0,0 @@
 | 
			
		||||
/* 
 | 
			
		||||
 * Copyright (C) 2010-2011 Daiki Ueno <ueno@unixuser.org>
 | 
			
		||||
 * Copyright (C) 2010-2011 Red Hat, Inc.
 | 
			
		||||
 * 
 | 
			
		||||
 * This library is free software; you can redistribute it and/or
 | 
			
		||||
 * modify it under the terms of the GNU Lesser General Public License
 | 
			
		||||
 * as published by the Free Software Foundation; either version 2 of
 | 
			
		||||
 * the License, or (at your option) any later version.
 | 
			
		||||
 * 
 | 
			
		||||
 * This library is distributed in the hope that it will be useful, but
 | 
			
		||||
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
			
		||||
 * Lesser General Public License for more details.
 | 
			
		||||
 * 
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General Public
 | 
			
		||||
 * License along with this library; if not, write to the Free Software
 | 
			
		||||
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 | 
			
		||||
 * 02110-1301 USA
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#if !defined(__EEK_H_INSIDE__) && !defined(EEK_COMPILATION)
 | 
			
		||||
#error "Only <eek/eek-xkl.h> can be included directly."
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef EEK_XKL_LAYOUT_H
 | 
			
		||||
#define EEK_XKL_LAYOUT_H 1
 | 
			
		||||
 | 
			
		||||
#include <libxklavier/xklavier.h>
 | 
			
		||||
#include "eek-xkb-layout.h"
 | 
			
		||||
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
#define EEK_TYPE_XKL_LAYOUT (eek_xkl_layout_get_type())
 | 
			
		||||
G_DECLARE_DERIVABLE_TYPE (EekXklLayout, eek_xkl_layout, EEK, XKL_LAYOUT, EekLayout)
 | 
			
		||||
 | 
			
		||||
struct _EekXklLayoutClass
 | 
			
		||||
{
 | 
			
		||||
    /*< private >*/
 | 
			
		||||
    EekXkbLayoutClass parent_class;
 | 
			
		||||
 | 
			
		||||
    /*< private >*/
 | 
			
		||||
    /* padding */
 | 
			
		||||
    gpointer pdummy[24];
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
GType      eek_xkl_layout_get_type        (void) G_GNUC_CONST;
 | 
			
		||||
 | 
			
		||||
EekLayout *eek_xkl_layout_new             (Display      *display,
 | 
			
		||||
                                           GError      **error);
 | 
			
		||||
 | 
			
		||||
gboolean   eek_xkl_layout_set_config      (EekXklLayout *layout,
 | 
			
		||||
                                           XklConfigRec *config);
 | 
			
		||||
 | 
			
		||||
gboolean   eek_xkl_layout_set_config_full (EekXklLayout *layout,
 | 
			
		||||
                                           gchar        *model,
 | 
			
		||||
                                           gchar       **layouts,
 | 
			
		||||
                                           gchar       **variants,
 | 
			
		||||
                                           gchar       **options);
 | 
			
		||||
 | 
			
		||||
gboolean   eek_xkl_layout_set_model       (EekXklLayout *layout,
 | 
			
		||||
                                           const gchar  *model);
 | 
			
		||||
gboolean   eek_xkl_layout_set_layouts     (EekXklLayout *layout,
 | 
			
		||||
                                           gchar       **layouts);
 | 
			
		||||
gboolean   eek_xkl_layout_set_variants    (EekXklLayout *layout,
 | 
			
		||||
                                           gchar       **variants);
 | 
			
		||||
gboolean   eek_xkl_layout_set_options     (EekXklLayout *layout,
 | 
			
		||||
                                           gchar       **options);
 | 
			
		||||
gboolean   eek_xkl_layout_enable_option   (EekXklLayout *layout,
 | 
			
		||||
                                           const gchar  *option);
 | 
			
		||||
gboolean   eek_xkl_layout_disable_option  (EekXklLayout *layout,
 | 
			
		||||
                                           const gchar  *option);
 | 
			
		||||
 | 
			
		||||
gchar     *eek_xkl_layout_get_model       (EekXklLayout *layout);
 | 
			
		||||
gchar    **eek_xkl_layout_get_layouts     (EekXklLayout *layout);
 | 
			
		||||
gchar    **eek_xkl_layout_get_variants    (EekXklLayout *layout);
 | 
			
		||||
gchar    **eek_xkl_layout_get_options     (EekXklLayout *layout);
 | 
			
		||||
gboolean   eek_xkl_layout_get_option      (EekXklLayout *layout,
 | 
			
		||||
                                           const gchar  *option);
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
#endif				/* #ifndef EEK_XKL_LAYOUT_H */
 | 
			
		||||
@ -1,26 +0,0 @@
 | 
			
		||||
/* 
 | 
			
		||||
 * Copyright (C) 2010-2011 Daiki Ueno <ueno@unixuser.org>
 | 
			
		||||
 * Copyright (C) 2010-2011 Red Hat, Inc.
 | 
			
		||||
 * 
 | 
			
		||||
 * This library is free software; you can redistribute it and/or
 | 
			
		||||
 * modify it under the terms of the GNU Lesser General Public License
 | 
			
		||||
 * as published by the Free Software Foundation; either version 2 of
 | 
			
		||||
 * the License, or (at your option) any later version.
 | 
			
		||||
 * 
 | 
			
		||||
 * This library is distributed in the hope that it will be useful, but
 | 
			
		||||
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
			
		||||
 * Lesser General Public License for more details.
 | 
			
		||||
 * 
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General Public
 | 
			
		||||
 * License along with this library; if not, write to the Free Software
 | 
			
		||||
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 | 
			
		||||
 * 02110-1301 USA
 | 
			
		||||
 */
 | 
			
		||||
#ifndef EEK_XKL_H
 | 
			
		||||
#define EEK_XKL_H 1
 | 
			
		||||
 | 
			
		||||
#include "eek.h"
 | 
			
		||||
#include "eek-xkl-layout.h"
 | 
			
		||||
 | 
			
		||||
#endif  /* EEK_XKL_H */
 | 
			
		||||
@ -21,9 +21,7 @@
 | 
			
		||||
 * @short_description: Layout engine which loads layout information from XML
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_CONFIG_H
 | 
			
		||||
#include "config.h"
 | 
			
		||||
#endif  /* HAVE_CONFIG_H */
 | 
			
		||||
 | 
			
		||||
#include <gio/gio.h> /* GResource */
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
@ -407,17 +405,23 @@ geometry_start_element_callback (GMarkupParseContext *pcontext,
 | 
			
		||||
                         "no \"keycode\" attribute for \"key\"");
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
        keycode = strtoul (attribute, NULL, 10);
 | 
			
		||||
 | 
			
		||||
        data->key = eek_section_create_key (data->section,
 | 
			
		||||
                                            keycode,
 | 
			
		||||
                                            data->num_columns,
 | 
			
		||||
                                            data->num_rows - 1);
 | 
			
		||||
        keycode = strtol (attribute, NULL, 10);
 | 
			
		||||
 | 
			
		||||
        attribute = get_attribute (attribute_names, attribute_values,
 | 
			
		||||
                                   "name");
 | 
			
		||||
        if (attribute != NULL)
 | 
			
		||||
            eek_element_set_name (EEK_ELEMENT(data->key), attribute);
 | 
			
		||||
        if (attribute == NULL) {
 | 
			
		||||
            g_set_error (error,
 | 
			
		||||
                         G_MARKUP_ERROR,
 | 
			
		||||
                         G_MARKUP_ERROR_MISSING_ATTRIBUTE,
 | 
			
		||||
                         "no \"name\" attribute for \"key\"");
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        data->key = eek_section_create_key (data->section,
 | 
			
		||||
                                            g_strdup (attribute),
 | 
			
		||||
                                            keycode,
 | 
			
		||||
                                            data->num_columns,
 | 
			
		||||
                                            data->num_rows - 1);
 | 
			
		||||
 | 
			
		||||
        attribute = get_attribute (attribute_names, attribute_values,
 | 
			
		||||
                                   "oref");
 | 
			
		||||
@ -622,28 +626,25 @@ symbols_start_element_callback (GMarkupParseContext *pcontext,
 | 
			
		||||
        return;
 | 
			
		||||
 | 
			
		||||
    if (g_strcmp0 (element_name, "key") == 0) {
 | 
			
		||||
        guint keycode;
 | 
			
		||||
 | 
			
		||||
        attribute = get_attribute (attribute_names, attribute_values,
 | 
			
		||||
                                   "keycode");
 | 
			
		||||
                                   "name");
 | 
			
		||||
        if (attribute == NULL) {
 | 
			
		||||
            g_set_error (error,
 | 
			
		||||
                         G_MARKUP_ERROR,
 | 
			
		||||
                         G_MARKUP_ERROR_MISSING_ATTRIBUTE,
 | 
			
		||||
                         "no \"keycode\" attribute for \"key\"");
 | 
			
		||||
                         "no \"name\" attribute for \"key\"");
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
        keycode = strtoul (attribute, NULL, 10);
 | 
			
		||||
 | 
			
		||||
        data->key = eek_keyboard_find_key_by_keycode (data->keyboard,
 | 
			
		||||
                                                      keycode);
 | 
			
		||||
        /*if (data->key == NULL) {
 | 
			
		||||
        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 keycode %u", keycode);
 | 
			
		||||
            return;
 | 
			
		||||
        }*/
 | 
			
		||||
                         "no such key %s", attribute);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        attribute = get_attribute (attribute_names, attribute_values,
 | 
			
		||||
                                   "groups");
 | 
			
		||||
@ -945,7 +946,9 @@ eek_xml_layout_real_create_keyboard (EekboardContextService *manager,
 | 
			
		||||
        return NULL;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* Fit keyboard in the given width and hight. */
 | 
			
		||||
    eek_layout_place_sections(keyboard);
 | 
			
		||||
 | 
			
		||||
    /* Fit keyboard in the given width and height. */
 | 
			
		||||
    scale_keyboard (keyboard, initial_width, initial_height);
 | 
			
		||||
 | 
			
		||||
    /* Use pre-defined modifier mask here. */
 | 
			
		||||
@ -1138,38 +1141,6 @@ eek_xml_keyboard_desc_free (EekXmlKeyboardDesc *desc)
 | 
			
		||||
    g_slice_free (EekXmlKeyboardDesc, desc);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
struct place_data {
 | 
			
		||||
    double desired_width;
 | 
			
		||||
    double current_offset;
 | 
			
		||||
    EekKeyboard *keyboard;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const double section_spacing = 7.0;
 | 
			
		||||
 | 
			
		||||
static void section_placer(EekElement *element, gpointer user_data) {
 | 
			
		||||
    struct place_data *data = (struct place_data*)user_data;
 | 
			
		||||
 | 
			
		||||
    EekBounds section_bounds = {0};
 | 
			
		||||
    eek_element_get_bounds(element, §ion_bounds);
 | 
			
		||||
    section_bounds.width = data->desired_width;
 | 
			
		||||
    eek_element_set_bounds(element, §ion_bounds);
 | 
			
		||||
 | 
			
		||||
    // Sections are rows now. Gather up all the keys and adjust their bounds.
 | 
			
		||||
    eek_section_place_keys(EEK_SECTION(element), EEK_KEYBOARD(data->keyboard));
 | 
			
		||||
 | 
			
		||||
    eek_element_get_bounds(element, §ion_bounds);
 | 
			
		||||
    section_bounds.y = data->current_offset;
 | 
			
		||||
    eek_element_set_bounds(element, §ion_bounds);
 | 
			
		||||
    data->current_offset += section_bounds.height + section_spacing;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void section_counter(EekElement *element, gpointer user_data) {
 | 
			
		||||
    double *total_height = user_data;
 | 
			
		||||
    EekBounds section_bounds = {0};
 | 
			
		||||
    eek_element_get_bounds(element, §ion_bounds);
 | 
			
		||||
    *total_height += section_bounds.height + section_spacing;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
parse_geometry (const gchar *path, EekKeyboard *keyboard, GError **error)
 | 
			
		||||
{
 | 
			
		||||
@ -1224,27 +1195,6 @@ parse_geometry (const gchar *path, EekKeyboard *keyboard, GError **error)
 | 
			
		||||
    }
 | 
			
		||||
    g_hash_table_destroy (oref_hash);
 | 
			
		||||
 | 
			
		||||
    /* Order rows */
 | 
			
		||||
    // This needs to be done after outlines, because outlines define key sizes
 | 
			
		||||
    // TODO: do this only for rows without bounds
 | 
			
		||||
 | 
			
		||||
    // The keyboard width is given by the user via screen size. The height will be given dynamically.
 | 
			
		||||
    // TODO: calculate max line width beforehand for button centering. Leave keyboard centering to the renderer later
 | 
			
		||||
    EekBounds keyboard_bounds = {0};
 | 
			
		||||
    eek_element_get_bounds(EEK_ELEMENT(keyboard), &keyboard_bounds);
 | 
			
		||||
 | 
			
		||||
    struct place_data placer_data = {
 | 
			
		||||
        .desired_width = keyboard_bounds.width,
 | 
			
		||||
        .current_offset = 0,
 | 
			
		||||
        .keyboard = keyboard,
 | 
			
		||||
    };
 | 
			
		||||
    eek_container_foreach_child(EEK_CONTAINER(keyboard), section_placer, &placer_data);
 | 
			
		||||
 | 
			
		||||
    double total_height = 0;
 | 
			
		||||
    eek_container_foreach_child(EEK_CONTAINER(keyboard), section_counter, &total_height);
 | 
			
		||||
    keyboard_bounds.height = total_height;
 | 
			
		||||
    eek_element_set_bounds(EEK_ELEMENT(keyboard), &keyboard_bounds);
 | 
			
		||||
 | 
			
		||||
    geometry_parse_data_free (data);
 | 
			
		||||
    return TRUE;
 | 
			
		||||
}
 | 
			
		||||
@ -1410,43 +1360,12 @@ parse_keyboards (const gchar *path, GError **error)
 | 
			
		||||
    return keyboards;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void scale_bounds_callback (EekElement *element,
 | 
			
		||||
                                   gpointer    user_data);
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
scale_bounds (EekElement *element,
 | 
			
		||||
              gdouble     scale)
 | 
			
		||||
{
 | 
			
		||||
    EekBounds bounds;
 | 
			
		||||
 | 
			
		||||
    eek_element_get_bounds (element, &bounds);
 | 
			
		||||
    bounds.x *= scale;
 | 
			
		||||
    bounds.y *= scale;
 | 
			
		||||
    bounds.width *= scale;
 | 
			
		||||
    bounds.height *= scale;
 | 
			
		||||
    eek_element_set_bounds (element, &bounds);
 | 
			
		||||
 | 
			
		||||
    if (EEK_IS_CONTAINER(element))
 | 
			
		||||
        eek_container_foreach_child (EEK_CONTAINER(element),
 | 
			
		||||
                                     scale_bounds_callback,
 | 
			
		||||
                                     &scale);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
scale_bounds_callback (EekElement *element,
 | 
			
		||||
                       gpointer    user_data)
 | 
			
		||||
{
 | 
			
		||||
    scale_bounds (element, *(gdouble *)user_data);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void scale_keyboard (EekKeyboard *keyboard,
 | 
			
		||||
                            gdouble      width,
 | 
			
		||||
                            gdouble      height)
 | 
			
		||||
{
 | 
			
		||||
    gdouble scale;
 | 
			
		||||
    EekBounds bounds;
 | 
			
		||||
    gsize n_outlines;
 | 
			
		||||
    guint i;
 | 
			
		||||
 | 
			
		||||
    eek_element_get_bounds (EEK_ELEMENT(keyboard), &bounds);
 | 
			
		||||
 | 
			
		||||
@ -1455,18 +1374,7 @@ static void scale_keyboard (EekKeyboard *keyboard,
 | 
			
		||||
    else
 | 
			
		||||
        scale = height / bounds.height;
 | 
			
		||||
 | 
			
		||||
    scale_bounds (EEK_ELEMENT(keyboard), scale);
 | 
			
		||||
 | 
			
		||||
    n_outlines = eek_keyboard_get_n_outlines (keyboard);
 | 
			
		||||
    for (i = 0; i < n_outlines; i++) {
 | 
			
		||||
        EekOutline *outline = eek_keyboard_get_outline (keyboard, i);
 | 
			
		||||
        gint j;
 | 
			
		||||
 | 
			
		||||
        for (j = 0; j < outline->num_points; j++) {
 | 
			
		||||
            outline->points[j].x *= scale;
 | 
			
		||||
            outline->points[j].y *= scale;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    eek_layout_scale_keyboard(keyboard, scale);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
 | 
			
		||||
@ -22,9 +22,7 @@
 | 
			
		||||
 * @short_description: #EekKeyboard to XML conversion utilities
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_CONFIG_H
 | 
			
		||||
#include "config.h"
 | 
			
		||||
#endif  /* HAVE_CONFIG_H */
 | 
			
		||||
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <stdarg.h>
 | 
			
		||||
 | 
			
		||||
@ -23,9 +23,7 @@
 | 
			
		||||
 * @title: Library Initialization
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_CONFIG_H
 | 
			
		||||
#include "config.h"
 | 
			
		||||
#endif  /* HAVE_CONFIG_H */
 | 
			
		||||
 | 
			
		||||
#include "eek.h"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -65,9 +65,9 @@ static void layer_surface_configure(void                         *data,
 | 
			
		||||
                                    uint32_t                      height)
 | 
			
		||||
{
 | 
			
		||||
  PhoshLayerSurface *self = data;
 | 
			
		||||
 | 
			
		||||
  gtk_window_resize (GTK_WINDOW (self), width, height);
 | 
			
		||||
  zwlr_layer_surface_v1_ack_configure(surface, serial);
 | 
			
		||||
  gtk_widget_show_all (GTK_WIDGET (self));
 | 
			
		||||
 | 
			
		||||
  g_signal_emit (self, signals[CONFIGURED], 0);
 | 
			
		||||
}
 | 
			
		||||
@ -180,22 +180,39 @@ phosh_layer_surface_get_property (GObject    *object,
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
phosh_layer_surface_constructed (GObject *object)
 | 
			
		||||
on_phosh_layer_surface_realized (PhoshLayerSurface *self, gpointer unused)
 | 
			
		||||
{
 | 
			
		||||
  PhoshLayerSurface *self = PHOSH_LAYER_SURFACE (object);
 | 
			
		||||
  PhoshLayerSurfacePrivate *priv = phosh_layer_surface_get_instance_private (self);
 | 
			
		||||
  PhoshLayerSurfacePrivate *priv;
 | 
			
		||||
  GdkWindow *gdk_window;
 | 
			
		||||
 | 
			
		||||
  G_OBJECT_CLASS (phosh_layer_surface_parent_class)->constructed (object);
 | 
			
		||||
  g_return_if_fail (PHOSH_IS_LAYER_SURFACE (self));
 | 
			
		||||
 | 
			
		||||
  gtk_window_set_decorated (GTK_WINDOW (self), FALSE);
 | 
			
		||||
  /* Realize the window so we can get the GDK window */
 | 
			
		||||
  gtk_widget_realize(GTK_WIDGET (self));
 | 
			
		||||
  priv = phosh_layer_surface_get_instance_private (self);
 | 
			
		||||
 | 
			
		||||
  gdk_window = gtk_widget_get_window (GTK_WIDGET (self));
 | 
			
		||||
  gdk_wayland_window_set_use_custom_surface (gdk_window);
 | 
			
		||||
  priv->wl_surface = gdk_wayland_window_get_wl_surface (gdk_window);
 | 
			
		||||
 | 
			
		||||
  gtk_window_set_decorated (GTK_WINDOW (self), FALSE);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
on_phosh_layer_surface_mapped (PhoshLayerSurface *self, gpointer unused)
 | 
			
		||||
{
 | 
			
		||||
  PhoshLayerSurfacePrivate *priv;
 | 
			
		||||
  GdkWindow *gdk_window;
 | 
			
		||||
 | 
			
		||||
  g_return_if_fail (PHOSH_IS_LAYER_SURFACE (self));
 | 
			
		||||
  priv = phosh_layer_surface_get_instance_private (self);
 | 
			
		||||
 | 
			
		||||
  if (!priv->wl_surface) {
 | 
			
		||||
      gdk_window = gtk_widget_get_window (GTK_WIDGET (self));
 | 
			
		||||
      gdk_wayland_window_set_use_custom_surface (gdk_window);
 | 
			
		||||
      priv->wl_surface = gdk_wayland_window_get_wl_surface (gdk_window);
 | 
			
		||||
  }
 | 
			
		||||
  g_debug ("Mapped %p", priv->wl_surface);
 | 
			
		||||
 | 
			
		||||
  priv->layer_surface = zwlr_layer_shell_v1_get_layer_surface(priv->layer_shell,
 | 
			
		||||
                                                              priv->wl_surface,
 | 
			
		||||
                                                              priv->wl_output,
 | 
			
		||||
@ -209,8 +226,45 @@ phosh_layer_surface_constructed (GObject *object)
 | 
			
		||||
                                     &layer_surface_listener,
 | 
			
		||||
                                     self);
 | 
			
		||||
  wl_surface_commit(priv->wl_surface);
 | 
			
		||||
 | 
			
		||||
  /* Process all pending events, otherwise we end up sending ack configure
 | 
			
		||||
   * to a not yet configured surface */
 | 
			
		||||
  wl_display_roundtrip (gdk_wayland_display_get_wl_display (gdk_display_get_default ()));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
on_phosh_layer_surface_unmapped (PhoshLayerSurface *self, gpointer unused)
 | 
			
		||||
{
 | 
			
		||||
  PhoshLayerSurfacePrivate *priv;
 | 
			
		||||
 | 
			
		||||
  g_return_if_fail (PHOSH_IS_LAYER_SURFACE (self));
 | 
			
		||||
  priv = phosh_layer_surface_get_instance_private (self);
 | 
			
		||||
 | 
			
		||||
  priv = phosh_layer_surface_get_instance_private (self);
 | 
			
		||||
  if (priv->layer_surface) {
 | 
			
		||||
    zwlr_layer_surface_v1_destroy(priv->layer_surface);
 | 
			
		||||
    priv->layer_surface = NULL;
 | 
			
		||||
  }
 | 
			
		||||
  priv->wl_surface = NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
phosh_layer_surface_constructed (GObject *object)
 | 
			
		||||
{
 | 
			
		||||
  PhoshLayerSurface *self = PHOSH_LAYER_SURFACE (object);
 | 
			
		||||
 | 
			
		||||
  g_signal_connect (self, "realize",
 | 
			
		||||
                    G_CALLBACK (on_phosh_layer_surface_realized),
 | 
			
		||||
                    NULL);
 | 
			
		||||
  g_signal_connect (self, "map",
 | 
			
		||||
                    G_CALLBACK (on_phosh_layer_surface_mapped),
 | 
			
		||||
                    NULL);
 | 
			
		||||
  g_signal_connect (self, "unmap",
 | 
			
		||||
                    G_CALLBACK (on_phosh_layer_surface_unmapped),
 | 
			
		||||
                    NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
phosh_layer_surface_dispose (GObject *object)
 | 
			
		||||
{
 | 
			
		||||
@ -352,6 +406,12 @@ phosh_layer_surface_new (gpointer layer_shell,
 | 
			
		||||
                       "wl-output", wl_output);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * phosh_layer_surface_get_surface:
 | 
			
		||||
 *
 | 
			
		||||
 * Get the layer layer surface or #NULL if the window
 | 
			
		||||
 * is not yet realized.
 | 
			
		||||
 */
 | 
			
		||||
struct zwlr_layer_surface_v1 *
 | 
			
		||||
phosh_layer_surface_get_layer_surface(PhoshLayerSurface *self)
 | 
			
		||||
{
 | 
			
		||||
@ -363,6 +423,12 @@ phosh_layer_surface_get_layer_surface(PhoshLayerSurface *self)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * phosh_layer_surface_get_wl_surface:
 | 
			
		||||
 *
 | 
			
		||||
 * Get the layer wayland surface or #NULL if the window
 | 
			
		||||
 * is not yet realized.
 | 
			
		||||
 */
 | 
			
		||||
struct wl_surface *
 | 
			
		||||
phosh_layer_surface_get_wl_surface(PhoshLayerSurface *self)
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
@ -1,404 +0,0 @@
 | 
			
		||||
/* 
 | 
			
		||||
 * Copyright (C) 2011 Daiki Ueno <ueno@unixuser.org>
 | 
			
		||||
 * Copyright (C) 2011 Red Hat, Inc.
 | 
			
		||||
 * 
 | 
			
		||||
 * This program is free software: you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU General Public License as published by
 | 
			
		||||
 * the Free Software Foundation, either version 3 of the License, or
 | 
			
		||||
 * (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
 * GNU General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU General Public License
 | 
			
		||||
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * SECTION:eekboard-client
 | 
			
		||||
 * @short_description: client interface of eekboard service
 | 
			
		||||
 *
 | 
			
		||||
 * The #EekboardClient class provides a client side access to eekboard-server.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_CONFIG_H
 | 
			
		||||
#include "config.h"
 | 
			
		||||
#endif  /* HAVE_CONFIG_H */
 | 
			
		||||
 | 
			
		||||
#include "eekboard/eekboard-client.h"
 | 
			
		||||
 | 
			
		||||
enum {
 | 
			
		||||
    DESTROYED,
 | 
			
		||||
    LAST_SIGNAL
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static guint signals[LAST_SIGNAL] = { 0, };
 | 
			
		||||
 | 
			
		||||
typedef struct _EekboardClientPrivate
 | 
			
		||||
{
 | 
			
		||||
    GHashTable *context_hash;
 | 
			
		||||
} EekboardClientPrivate;
 | 
			
		||||
 | 
			
		||||
G_DEFINE_TYPE_WITH_PRIVATE (EekboardClient, eekboard_client, G_TYPE_DBUS_PROXY)
 | 
			
		||||
 | 
			
		||||
static void send_destroy_context (EekboardClient  *client,
 | 
			
		||||
                                  EekboardContext *context,
 | 
			
		||||
                                  GCancellable    *cancellable);
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
eekboard_client_real_destroyed (EekboardClient *self)
 | 
			
		||||
{
 | 
			
		||||
    EekboardClientPrivate *priv = eekboard_client_get_instance_private (self);
 | 
			
		||||
 | 
			
		||||
    // g_debug ("eekboard_client_real_destroyed");
 | 
			
		||||
    g_hash_table_remove_all (priv->context_hash);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
eekboard_client_dispose (GObject *object)
 | 
			
		||||
{
 | 
			
		||||
    EekboardClient *client = EEKBOARD_CLIENT(object);
 | 
			
		||||
    EekboardClientPrivate *priv = eekboard_client_get_instance_private (client);
 | 
			
		||||
 | 
			
		||||
    if (priv->context_hash) {
 | 
			
		||||
        GHashTableIter iter;
 | 
			
		||||
        gpointer key, value;
 | 
			
		||||
 | 
			
		||||
        g_hash_table_iter_init (&iter, priv->context_hash);
 | 
			
		||||
        while (g_hash_table_iter_next (&iter, &key, &value)) {
 | 
			
		||||
            send_destroy_context (client, (EekboardContext *)value, NULL);
 | 
			
		||||
            g_hash_table_iter_remove (&iter);
 | 
			
		||||
        }
 | 
			
		||||
        g_hash_table_destroy (priv->context_hash);
 | 
			
		||||
        priv->context_hash = NULL;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    G_OBJECT_CLASS (eekboard_client_parent_class)->dispose (object);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
eekboard_client_class_init (EekboardClientClass *klass)
 | 
			
		||||
{
 | 
			
		||||
    GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
 | 
			
		||||
 | 
			
		||||
    klass->destroyed = eekboard_client_real_destroyed;
 | 
			
		||||
 | 
			
		||||
    gobject_class->dispose = eekboard_client_dispose;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * EekboardClient::destroyed:
 | 
			
		||||
     * @eekboard: an #EekboardClient
 | 
			
		||||
     *
 | 
			
		||||
     * The ::destroyed signal is emitted each time the name of remote
 | 
			
		||||
     * end is vanished.
 | 
			
		||||
     */
 | 
			
		||||
    signals[DESTROYED] =
 | 
			
		||||
        g_signal_new (I_("destroyed"),
 | 
			
		||||
                      G_TYPE_FROM_CLASS(gobject_class),
 | 
			
		||||
                      G_SIGNAL_RUN_LAST,
 | 
			
		||||
                      G_STRUCT_OFFSET(EekboardClientClass, destroyed),
 | 
			
		||||
                      NULL,
 | 
			
		||||
                      NULL,
 | 
			
		||||
                      g_cclosure_marshal_VOID__VOID,
 | 
			
		||||
                      G_TYPE_NONE,
 | 
			
		||||
                      0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
eekboard_client_init (EekboardClient *self)
 | 
			
		||||
{
 | 
			
		||||
    EekboardClientPrivate *priv = eekboard_client_get_instance_private (self);
 | 
			
		||||
 | 
			
		||||
    priv->context_hash =
 | 
			
		||||
        g_hash_table_new_full (g_str_hash,
 | 
			
		||||
                               g_str_equal,
 | 
			
		||||
                               (GDestroyNotify)g_free,
 | 
			
		||||
                               (GDestroyNotify)g_object_unref);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
eekboard_name_vanished_callback (GDBusConnection *connection,
 | 
			
		||||
                                 const gchar     *name,
 | 
			
		||||
                                 gpointer         user_data)
 | 
			
		||||
{
 | 
			
		||||
    EekboardClient *client = user_data;
 | 
			
		||||
    g_signal_emit_by_name (client, "destroyed", NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eekboard_client_new:
 | 
			
		||||
 * @connection: a #GDBusConnection
 | 
			
		||||
 * @cancellable: a #GCancellable
 | 
			
		||||
 *
 | 
			
		||||
 * Create a client.
 | 
			
		||||
 */
 | 
			
		||||
EekboardClient *
 | 
			
		||||
eekboard_client_new (GDBusConnection *connection,
 | 
			
		||||
                     GCancellable    *cancellable)
 | 
			
		||||
{
 | 
			
		||||
    GInitable *initable;
 | 
			
		||||
    GError *error;
 | 
			
		||||
 | 
			
		||||
    g_assert (G_IS_DBUS_CONNECTION(connection));
 | 
			
		||||
 | 
			
		||||
    error = NULL;
 | 
			
		||||
    initable =
 | 
			
		||||
        g_initable_new (EEKBOARD_TYPE_CLIENT,
 | 
			
		||||
                        cancellable,
 | 
			
		||||
                        &error,
 | 
			
		||||
                        "g-connection", connection,
 | 
			
		||||
                        "g-name", "org.fedorahosted.Eekboard",
 | 
			
		||||
                        "g-interface-name", "org.fedorahosted.Eekboard",
 | 
			
		||||
                        "g-object-path", "/org/fedorahosted/Eekboard",
 | 
			
		||||
                        NULL);
 | 
			
		||||
    if (initable != NULL) {
 | 
			
		||||
        EekboardClient *client = EEKBOARD_CLIENT (initable);
 | 
			
		||||
        gchar *name_owner = g_dbus_proxy_get_name_owner (G_DBUS_PROXY(client));
 | 
			
		||||
        if (name_owner == NULL) {
 | 
			
		||||
            g_object_unref (client);
 | 
			
		||||
            return NULL;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /* the vanished callback is called when the server is disconnected */
 | 
			
		||||
        g_bus_watch_name_on_connection (connection,
 | 
			
		||||
                                        name_owner,
 | 
			
		||||
                                        G_BUS_NAME_WATCHER_FLAGS_NONE,
 | 
			
		||||
                                        NULL,
 | 
			
		||||
                                        eekboard_name_vanished_callback,
 | 
			
		||||
                                        client,
 | 
			
		||||
                                        NULL);
 | 
			
		||||
        g_free (name_owner);
 | 
			
		||||
 | 
			
		||||
        return client;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    g_warning ("can't create client: %s", error->message);
 | 
			
		||||
    g_error_free (error);
 | 
			
		||||
    return NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
on_context_destroyed (EekboardContext *context,
 | 
			
		||||
                      gpointer         user_data)
 | 
			
		||||
{
 | 
			
		||||
    EekboardClient *client = user_data;
 | 
			
		||||
    EekboardClientPrivate *priv = eekboard_client_get_instance_private (client);
 | 
			
		||||
 | 
			
		||||
    g_hash_table_remove (priv->context_hash,
 | 
			
		||||
                         g_dbus_proxy_get_object_path (G_DBUS_PROXY(context)));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eekboard_client_create_context:
 | 
			
		||||
 * @eekboard: an #EekboardClient
 | 
			
		||||
 * @client_name: name of the client
 | 
			
		||||
 * @cancellable: a #GCancellable
 | 
			
		||||
 *
 | 
			
		||||
 * Create a new input context.
 | 
			
		||||
 *
 | 
			
		||||
 * Return value: (transfer full): a newly created #EekboardContext.
 | 
			
		||||
 */
 | 
			
		||||
EekboardContext *
 | 
			
		||||
eekboard_client_create_context (EekboardClient *client,
 | 
			
		||||
                                const gchar    *client_name,
 | 
			
		||||
                                GCancellable   *cancellable)
 | 
			
		||||
{
 | 
			
		||||
    GVariant *variant;
 | 
			
		||||
    const gchar *object_path;
 | 
			
		||||
    EekboardContext *context;
 | 
			
		||||
    GError *error;
 | 
			
		||||
    GDBusConnection *connection;
 | 
			
		||||
 | 
			
		||||
    g_assert (EEKBOARD_IS_CLIENT(client));
 | 
			
		||||
    g_assert (client_name);
 | 
			
		||||
 | 
			
		||||
    error = NULL;
 | 
			
		||||
    variant = g_dbus_proxy_call_sync (G_DBUS_PROXY(client),
 | 
			
		||||
                                      "CreateContext",
 | 
			
		||||
                                      g_variant_new ("(s)", client_name),
 | 
			
		||||
                                      G_DBUS_CALL_FLAGS_NONE,
 | 
			
		||||
                                      -1,
 | 
			
		||||
                                      cancellable,
 | 
			
		||||
                                      &error);
 | 
			
		||||
    if (!variant) {
 | 
			
		||||
        g_warning ("failed to call CreateContext: %s", error->message);
 | 
			
		||||
        g_error_free (error);
 | 
			
		||||
        return NULL;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    g_variant_get (variant, "(&s)", &object_path);
 | 
			
		||||
    connection = g_dbus_proxy_get_connection (G_DBUS_PROXY(client));
 | 
			
		||||
    context = eekboard_context_new (connection, object_path, cancellable);
 | 
			
		||||
    if (!context) {
 | 
			
		||||
        g_variant_unref (variant);
 | 
			
		||||
        return NULL;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    EekboardClientPrivate *priv = eekboard_client_get_instance_private (client);
 | 
			
		||||
 | 
			
		||||
    g_hash_table_insert (priv->context_hash,
 | 
			
		||||
                         g_strdup (object_path),
 | 
			
		||||
                         g_object_ref (context));
 | 
			
		||||
    g_signal_connect (context, "destroyed",
 | 
			
		||||
                      G_CALLBACK(on_context_destroyed), client);
 | 
			
		||||
    return context;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
eekboard_async_ready_callback (GObject      *source_object,
 | 
			
		||||
                               GAsyncResult *res,
 | 
			
		||||
                               gpointer      user_data)
 | 
			
		||||
{
 | 
			
		||||
    GError *error = NULL;
 | 
			
		||||
    GVariant *result;
 | 
			
		||||
 | 
			
		||||
    result = g_dbus_proxy_call_finish (G_DBUS_PROXY(source_object),
 | 
			
		||||
                                       res,
 | 
			
		||||
                                       &error);
 | 
			
		||||
    if (result)
 | 
			
		||||
        g_variant_unref (result);
 | 
			
		||||
    else {
 | 
			
		||||
        g_warning ("error in D-Bus proxy call: %s", error->message);
 | 
			
		||||
        g_error_free (error);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eekboard_client_push_context:
 | 
			
		||||
 * @eekboard: an #EekboardClient
 | 
			
		||||
 * @context: an #EekboardContext
 | 
			
		||||
 * @cancellable: a #GCancellable
 | 
			
		||||
 *
 | 
			
		||||
 * Enable the input context @context and disable the others.
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
eekboard_client_push_context (EekboardClient  *client,
 | 
			
		||||
                              EekboardContext *context,
 | 
			
		||||
                              GCancellable    *cancellable)
 | 
			
		||||
{
 | 
			
		||||
    const gchar *object_path;
 | 
			
		||||
 | 
			
		||||
    g_return_if_fail (EEKBOARD_IS_CLIENT(client));
 | 
			
		||||
    g_return_if_fail (EEKBOARD_IS_CONTEXT(context));
 | 
			
		||||
 | 
			
		||||
    EekboardClientPrivate *priv = eekboard_client_get_instance_private (client);
 | 
			
		||||
 | 
			
		||||
    object_path = g_dbus_proxy_get_object_path (G_DBUS_PROXY(context));
 | 
			
		||||
 | 
			
		||||
    context = g_hash_table_lookup (priv->context_hash,
 | 
			
		||||
                                   object_path);
 | 
			
		||||
    if (!context)
 | 
			
		||||
        return;
 | 
			
		||||
 | 
			
		||||
    eekboard_context_set_enabled (context, TRUE);
 | 
			
		||||
    g_dbus_proxy_call (G_DBUS_PROXY(client),
 | 
			
		||||
                       "PushContext",
 | 
			
		||||
                       g_variant_new ("(s)", object_path),
 | 
			
		||||
                       G_DBUS_CALL_FLAGS_NONE,
 | 
			
		||||
                       -1,
 | 
			
		||||
                       cancellable,
 | 
			
		||||
                       eekboard_async_ready_callback,
 | 
			
		||||
                       NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eekboard_client_pop_context:
 | 
			
		||||
 * @eekboard: an #EekboardClient
 | 
			
		||||
 * @cancellable: a #GCancellable
 | 
			
		||||
 *
 | 
			
		||||
 * Disable the current input context and enable the previous one.
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
eekboard_client_pop_context (EekboardClient *client,
 | 
			
		||||
                             GCancellable   *cancellable)
 | 
			
		||||
{
 | 
			
		||||
    g_return_if_fail (EEKBOARD_IS_CLIENT(client));
 | 
			
		||||
 | 
			
		||||
    g_dbus_proxy_call (G_DBUS_PROXY(client),
 | 
			
		||||
                       "PopContext",
 | 
			
		||||
                       NULL,
 | 
			
		||||
                       G_DBUS_CALL_FLAGS_NONE,
 | 
			
		||||
                       -1,
 | 
			
		||||
                       cancellable,
 | 
			
		||||
                       eekboard_async_ready_callback,
 | 
			
		||||
                       NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
eekboard_client_show_keyboard (EekboardClient  *client,
 | 
			
		||||
                               GCancellable    *cancellable)
 | 
			
		||||
{
 | 
			
		||||
    g_return_if_fail (EEKBOARD_IS_CLIENT(client));
 | 
			
		||||
 | 
			
		||||
    g_dbus_proxy_call (G_DBUS_PROXY(client),
 | 
			
		||||
                       "ShowKeyboard",
 | 
			
		||||
                       NULL,
 | 
			
		||||
                       G_DBUS_CALL_FLAGS_NONE,
 | 
			
		||||
                       -1,
 | 
			
		||||
                       cancellable,
 | 
			
		||||
                       eekboard_async_ready_callback,
 | 
			
		||||
                       NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
eekboard_client_hide_keyboard (EekboardClient *client,
 | 
			
		||||
                               GCancellable   *cancellable)
 | 
			
		||||
{
 | 
			
		||||
    g_return_if_fail (EEKBOARD_IS_CLIENT(client));
 | 
			
		||||
 | 
			
		||||
    g_dbus_proxy_call (G_DBUS_PROXY(client),
 | 
			
		||||
                       "HideKeyboard",
 | 
			
		||||
                       NULL,
 | 
			
		||||
                       G_DBUS_CALL_FLAGS_NONE,
 | 
			
		||||
                       -1,
 | 
			
		||||
                       cancellable,
 | 
			
		||||
                       eekboard_async_ready_callback,
 | 
			
		||||
                       NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
send_destroy_context (EekboardClient  *client,
 | 
			
		||||
                      EekboardContext *context,
 | 
			
		||||
                      GCancellable    *cancellable)
 | 
			
		||||
{
 | 
			
		||||
    const gchar *object_path;
 | 
			
		||||
 | 
			
		||||
    object_path = g_dbus_proxy_get_object_path (G_DBUS_PROXY(context));
 | 
			
		||||
 | 
			
		||||
    g_dbus_proxy_call (G_DBUS_PROXY(client),
 | 
			
		||||
                       "DestroyContext",
 | 
			
		||||
                       g_variant_new ("(s)", object_path),
 | 
			
		||||
                       G_DBUS_CALL_FLAGS_NONE,
 | 
			
		||||
                       -1,
 | 
			
		||||
                       cancellable,
 | 
			
		||||
                       eekboard_async_ready_callback,
 | 
			
		||||
                       NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eekboard_client_destroy_context:
 | 
			
		||||
 * @eekboard: an #EekboardClient
 | 
			
		||||
 * @context: an #EekboardContext
 | 
			
		||||
 * @cancellable: a #GCancellable
 | 
			
		||||
 *
 | 
			
		||||
 * Remove @context from @eekboard.
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
eekboard_client_destroy_context (EekboardClient  *client,
 | 
			
		||||
                                 EekboardContext *context,
 | 
			
		||||
                                 GCancellable    *cancellable)
 | 
			
		||||
{
 | 
			
		||||
    const gchar *object_path;
 | 
			
		||||
 | 
			
		||||
    g_return_if_fail (EEKBOARD_IS_CLIENT(client));
 | 
			
		||||
    g_return_if_fail (EEKBOARD_IS_CONTEXT(context));
 | 
			
		||||
 | 
			
		||||
    EekboardClientPrivate *priv = eekboard_client_get_instance_private (client);
 | 
			
		||||
 | 
			
		||||
    object_path = g_dbus_proxy_get_object_path (G_DBUS_PROXY(context));
 | 
			
		||||
    g_hash_table_remove (priv->context_hash, object_path);
 | 
			
		||||
 | 
			
		||||
    send_destroy_context (client, context, cancellable);
 | 
			
		||||
}
 | 
			
		||||
@ -1,64 +0,0 @@
 | 
			
		||||
/* 
 | 
			
		||||
 * Copyright (C) 2010-2011 Daiki Ueno <ueno@unixuser.org>
 | 
			
		||||
 * Copyright (C) 2010-2011 Red Hat, Inc.
 | 
			
		||||
 * 
 | 
			
		||||
 * This program is free software: you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU General Public License as published by
 | 
			
		||||
 * the Free Software Foundation, either version 3 of the License, or
 | 
			
		||||
 * (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
 * GNU General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU General Public License
 | 
			
		||||
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
#ifndef EEKBOARD_CLIENT_H
 | 
			
		||||
#define EEKBOARD_CLIENT_H 1
 | 
			
		||||
 | 
			
		||||
#define __EEKBOARD_CLIENT_H_INSIDE__ 1
 | 
			
		||||
 | 
			
		||||
#include <gio/gio.h>
 | 
			
		||||
#include "eekboard/eekboard-context.h"
 | 
			
		||||
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
#define EEKBOARD_TYPE_CLIENT (eekboard_client_get_type())
 | 
			
		||||
G_DECLARE_DERIVABLE_TYPE (EekboardClient, eekboard_client, EEKBOARD, CLIENT, GDBusProxy)
 | 
			
		||||
 | 
			
		||||
struct _EekboardClientClass {
 | 
			
		||||
    /*< private >*/
 | 
			
		||||
    GDBusProxyClass parent_class;
 | 
			
		||||
 | 
			
		||||
    /* signals */
 | 
			
		||||
    void (* destroyed) (EekboardClient *self);
 | 
			
		||||
 | 
			
		||||
    /*< private >*/
 | 
			
		||||
    /* padding */
 | 
			
		||||
    gpointer pdummy[23];
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
GType            eekboard_client_get_type        (void) G_GNUC_CONST;
 | 
			
		||||
 | 
			
		||||
EekboardClient  *eekboard_client_new             (GDBusConnection *connection,
 | 
			
		||||
                                                  GCancellable    *cancellable);
 | 
			
		||||
EekboardContext *eekboard_client_create_context  (EekboardClient  *eekboard,
 | 
			
		||||
                                                  const gchar     *client_name,
 | 
			
		||||
                                                  GCancellable    *cancellable);
 | 
			
		||||
void             eekboard_client_push_context    (EekboardClient  *eekboard,
 | 
			
		||||
                                                  EekboardContext *context,
 | 
			
		||||
                                                  GCancellable    *cancellable);
 | 
			
		||||
void             eekboard_client_pop_context     (EekboardClient  *eekboard,
 | 
			
		||||
                                                  GCancellable    *cancellable);
 | 
			
		||||
void             eekboard_client_show_keyboard   (EekboardClient  *eekboard,
 | 
			
		||||
                                                  GCancellable    *cancellable);
 | 
			
		||||
void             eekboard_client_hide_keyboard   (EekboardClient  *eekboard,
 | 
			
		||||
                                                  GCancellable    *cancellable);
 | 
			
		||||
void             eekboard_client_destroy_context (EekboardClient  *eekboard,
 | 
			
		||||
                                                  EekboardContext *context,
 | 
			
		||||
                                                  GCancellable    *cancellable);
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
#endif  /* EEKBOARD_CLIENT_H */
 | 
			
		||||
@ -25,11 +25,10 @@
 | 
			
		||||
 * implementation of eekboard input context service.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_CONFIG_H
 | 
			
		||||
#include "config.h"
 | 
			
		||||
#endif  /* HAVE_CONFIG_H */
 | 
			
		||||
 | 
			
		||||
#include "eekboard/eekboard-context-service.h"
 | 
			
		||||
#include "keymap.h"
 | 
			
		||||
 | 
			
		||||
#include <fcntl.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
@ -80,11 +79,60 @@ struct _EekboardContextServicePrivate {
 | 
			
		||||
    gboolean repeat_triggered;
 | 
			
		||||
 | 
			
		||||
    GSettings *settings;
 | 
			
		||||
    uint32_t hint;
 | 
			
		||||
    uint32_t purpose;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
G_DEFINE_TYPE_WITH_PRIVATE (EekboardContextService, eekboard_context_service, G_TYPE_OBJECT);
 | 
			
		||||
 | 
			
		||||
/*static Display *display = NULL; */
 | 
			
		||||
gchar *
 | 
			
		||||
get_keymap_from_resource(const gchar *keyboard_type, gboolean fallback)
 | 
			
		||||
{
 | 
			
		||||
    g_autoptr (GFile) file = NULL;
 | 
			
		||||
    g_autoptr (GFileInfo) info = NULL;
 | 
			
		||||
    g_autoptr (GFileInputStream) stream = NULL;
 | 
			
		||||
    goffset size = 0;
 | 
			
		||||
    gsize bytes_read = 0;
 | 
			
		||||
    g_autofree gchar *contents = NULL;
 | 
			
		||||
    g_autofree gchar *path = NULL;
 | 
			
		||||
    GError *error = NULL;
 | 
			
		||||
 | 
			
		||||
    if (fallback)
 | 
			
		||||
        g_debug ("falling back to loading a %s keymap", keyboard_type);
 | 
			
		||||
 | 
			
		||||
    path = g_strconcat ("resource:///sm/puri/squeekboard/keyboards/keymaps/",
 | 
			
		||||
                        keyboard_type, ".xkb", NULL);
 | 
			
		||||
    file = g_file_new_for_uri (path);
 | 
			
		||||
    stream = g_file_read (file, NULL, &error);
 | 
			
		||||
 | 
			
		||||
    if (!stream)
 | 
			
		||||
        goto keymap_error;
 | 
			
		||||
 | 
			
		||||
    info = g_file_input_stream_query_info (stream,
 | 
			
		||||
                                           G_FILE_ATTRIBUTE_STANDARD_SIZE,
 | 
			
		||||
                                           NULL,
 | 
			
		||||
                                           &error);
 | 
			
		||||
 | 
			
		||||
    if (!info)
 | 
			
		||||
        goto keymap_error;
 | 
			
		||||
 | 
			
		||||
    size = g_file_info_get_size (info);
 | 
			
		||||
    contents = g_malloc0 (size);
 | 
			
		||||
 | 
			
		||||
    if (!g_input_stream_read_all (G_INPUT_STREAM(stream), contents, size,
 | 
			
		||||
                                  &bytes_read, NULL, &error))
 | 
			
		||||
        goto keymap_error;
 | 
			
		||||
 | 
			
		||||
    return g_utf8_make_valid (contents, -1);
 | 
			
		||||
 | 
			
		||||
keymap_error:
 | 
			
		||||
    if (fallback)
 | 
			
		||||
        g_error ("failed to load keymap from resource: %s", error->message);
 | 
			
		||||
 | 
			
		||||
    g_error_free (error);
 | 
			
		||||
    return NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static EekKeyboard *
 | 
			
		||||
eekboard_context_service_real_create_keyboard (EekboardContextService *self,
 | 
			
		||||
@ -145,18 +193,28 @@ eekboard_context_service_real_create_keyboard (EekboardContextService *self,
 | 
			
		||||
    if (!context) {
 | 
			
		||||
        g_error("No context created");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
    struct xkb_rule_names rules = { 0 };
 | 
			
		||||
    rules.layout = strdup(keyboard_type);
 | 
			
		||||
    struct xkb_keymap *keymap = xkb_keymap_new_from_names(context, &rules,
 | 
			
		||||
        XKB_KEYMAP_COMPILE_NO_FLAGS);
 | 
			
		||||
*/
 | 
			
		||||
    char *keymap_str = get_keymap_from_resource(keyboard_type, FALSE);
 | 
			
		||||
    if (!keymap_str)
 | 
			
		||||
        keymap_str = get_keymap_from_resource("us", TRUE);
 | 
			
		||||
 | 
			
		||||
    struct xkb_keymap *keymap = xkb_keymap_new_from_string(context, keymap_str,
 | 
			
		||||
        XKB_KEYMAP_FORMAT_TEXT_V1, XKB_KEYMAP_COMPILE_NO_FLAGS);
 | 
			
		||||
 | 
			
		||||
    free(keymap_str);
 | 
			
		||||
 | 
			
		||||
    xkb_context_unref(context);
 | 
			
		||||
    if (!keymap) {
 | 
			
		||||
        g_error("Bad keymap");
 | 
			
		||||
    }
 | 
			
		||||
    keyboard->keymap = keymap;
 | 
			
		||||
    char *keymap_str = xkb_keymap_get_as_string(keymap, XKB_KEYMAP_FORMAT_TEXT_V1);
 | 
			
		||||
 | 
			
		||||
    keymap_str = xkb_keymap_get_as_string(keymap, XKB_KEYMAP_FORMAT_TEXT_V1);
 | 
			
		||||
    keyboard->keymap_len = strlen(keymap_str) + 1;
 | 
			
		||||
 | 
			
		||||
    g_autofree char *path = strdup("/eek_keymap-XXXXXX");
 | 
			
		||||
    char *r = &path[strlen(path) - 6];
 | 
			
		||||
    getrandom(r, 6, GRND_NONBLOCK);
 | 
			
		||||
@ -212,12 +270,7 @@ eekboard_context_service_set_property (GObject      *object,
 | 
			
		||||
        context->priv->keyboard = g_value_get_object (value);
 | 
			
		||||
        break;
 | 
			
		||||
    case PROP_VISIBLE:
 | 
			
		||||
        /*if (context->priv->keyboard) {
 | 
			
		||||
            if (g_value_get_boolean (value))
 | 
			
		||||
                eekboard_context_service_show_keyboard (context);
 | 
			
		||||
            else
 | 
			
		||||
                eekboard_context_service_hide_keyboard (context);
 | 
			
		||||
        }*/
 | 
			
		||||
        context->priv->visible = g_value_get_boolean (value);
 | 
			
		||||
        break;
 | 
			
		||||
    case PROP_FULLSCREEN:
 | 
			
		||||
        context->priv->fullscreen = g_value_get_boolean (value);
 | 
			
		||||
@ -289,7 +342,8 @@ settings_get_layout(GSettings *settings, char **type, char **layout)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
settings_update_layout(EekboardContextService *context) {
 | 
			
		||||
settings_update_layout(EekboardContextService *context)
 | 
			
		||||
{
 | 
			
		||||
    g_autofree gchar *keyboard_type = NULL;
 | 
			
		||||
    g_autofree gchar *keyboard_layout = NULL;
 | 
			
		||||
    settings_get_layout(context->priv->settings, &keyboard_type, &keyboard_layout);
 | 
			
		||||
@ -301,6 +355,11 @@ settings_update_layout(EekboardContextService *context) {
 | 
			
		||||
        keyboard_layout = g_strdup("undefined");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    EekboardContextServicePrivate *priv = EEKBOARD_CONTEXT_SERVICE_GET_PRIVATE(context);
 | 
			
		||||
 | 
			
		||||
    if (priv->purpose == ZWP_TEXT_INPUT_V3_CONTENT_PURPOSE_PHONE)
 | 
			
		||||
        keyboard_layout = g_strdup("numbers");
 | 
			
		||||
 | 
			
		||||
    // generic part follows
 | 
			
		||||
    static guint keyboard_id = 0;
 | 
			
		||||
    EekKeyboard *keyboard = g_hash_table_lookup(context->priv->keyboard_hash,
 | 
			
		||||
@ -588,3 +647,15 @@ void eekboard_context_service_set_keymap(EekboardContextService *context,
 | 
			
		||||
        WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1,
 | 
			
		||||
        keyboard->keymap_fd, keyboard->keymap_len);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void eekboard_context_service_set_hint_purpose(EekboardContextService *context,
 | 
			
		||||
                                               uint32_t hint, uint32_t purpose)
 | 
			
		||||
{
 | 
			
		||||
    EekboardContextServicePrivate *priv = EEKBOARD_CONTEXT_SERVICE_GET_PRIVATE(context);
 | 
			
		||||
 | 
			
		||||
    if (priv->hint != hint || priv->purpose != purpose) {
 | 
			
		||||
        priv->hint = hint;
 | 
			
		||||
        priv->purpose = purpose;
 | 
			
		||||
        settings_update_layout(context);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -25,6 +25,7 @@
 | 
			
		||||
#include <eek/eek.h>
 | 
			
		||||
 | 
			
		||||
#include "virtual-keyboard-unstable-v1-client-protocol.h"
 | 
			
		||||
#include "text-input-unstable-v3-client-protocol.h"
 | 
			
		||||
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
@ -104,5 +105,9 @@ gboolean      eekboard_context_service_get_fullscreen
 | 
			
		||||
void eekboard_context_service_set_keymap(EekboardContextService *context,
 | 
			
		||||
                                         const EekKeyboard *keyboard);
 | 
			
		||||
 | 
			
		||||
void eekboard_context_service_set_hint_purpose(EekboardContextService *context,
 | 
			
		||||
                                               uint32_t hint,
 | 
			
		||||
                                               uint32_t purpose);
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
#endif  /* EEKBOARD_CONTEXT_SERVICE_H */
 | 
			
		||||
 | 
			
		||||
@ -24,9 +24,7 @@
 | 
			
		||||
 * context.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_CONFIG_H
 | 
			
		||||
#include "config.h"
 | 
			
		||||
#endif  /* HAVE_CONFIG_H */
 | 
			
		||||
 | 
			
		||||
#include "eekboard/eekboard-context.h"
 | 
			
		||||
//#include "eekboard/eekboard-marshalers.h"
 | 
			
		||||
 | 
			
		||||
@ -26,9 +26,7 @@
 | 
			
		||||
 * implementation of eekboard service.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_CONFIG_H
 | 
			
		||||
#include "config.h"
 | 
			
		||||
#endif  /* HAVE_CONFIG_H */
 | 
			
		||||
 | 
			
		||||
#include "eekboard/eekboard-service.h"
 | 
			
		||||
 | 
			
		||||
@ -135,6 +133,11 @@ eekboard_service_dispose (GObject *object)
 | 
			
		||||
        priv->introspection_data = NULL;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (priv->context) {
 | 
			
		||||
        g_signal_handlers_disconnect_by_data (priv->context, service);
 | 
			
		||||
        priv->context = NULL;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    G_OBJECT_CLASS (eekboard_service_parent_class)->dispose (object);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -166,6 +169,22 @@ handle_set_visible(SmPuriOSK0 *object, GDBusMethodInvocation *invocation,
 | 
			
		||||
    return TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void on_visible(EekboardService *service,
 | 
			
		||||
                       GParamSpec *pspec,
 | 
			
		||||
                       EekboardContextService *context)
 | 
			
		||||
{
 | 
			
		||||
    gboolean visible;
 | 
			
		||||
    EekboardServicePrivate *priv;
 | 
			
		||||
 | 
			
		||||
    g_return_if_fail (EEKBOARD_IS_SERVICE (service));
 | 
			
		||||
    g_return_if_fail (EEKBOARD_IS_CONTEXT_SERVICE (context));
 | 
			
		||||
 | 
			
		||||
    priv = eekboard_service_get_instance_private (service);
 | 
			
		||||
    g_object_get (context, "visible", &visible, NULL);
 | 
			
		||||
 | 
			
		||||
    sm_puri_osk0_set_visible(priv->dbus_interface, visible);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
eekboard_service_constructed (GObject *object)
 | 
			
		||||
{
 | 
			
		||||
@ -173,7 +192,6 @@ eekboard_service_constructed (GObject *object)
 | 
			
		||||
    EekboardServicePrivate *priv = eekboard_service_get_instance_private (service);
 | 
			
		||||
 | 
			
		||||
    priv->dbus_interface = sm_puri_osk0_skeleton_new();
 | 
			
		||||
    sm_puri_osk0_set_visible(priv->dbus_interface, FALSE); // TODO: use actual value
 | 
			
		||||
    g_signal_connect(priv->dbus_interface, "handle-set-visible",
 | 
			
		||||
                     G_CALLBACK(handle_set_visible), service);
 | 
			
		||||
 | 
			
		||||
@ -279,5 +297,12 @@ eekboard_service_set_context(EekboardService *service,
 | 
			
		||||
{
 | 
			
		||||
    EekboardServicePrivate *priv = eekboard_service_get_instance_private (service);
 | 
			
		||||
 | 
			
		||||
    g_return_if_fail (!priv->context);
 | 
			
		||||
 | 
			
		||||
    priv->context = context;
 | 
			
		||||
 | 
			
		||||
    g_signal_connect_swapped (priv->context,
 | 
			
		||||
                              "notify::visible",
 | 
			
		||||
                              G_CALLBACK(on_visible),
 | 
			
		||||
                              service);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -1,168 +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 <string.h>
 | 
			
		||||
#include "eekboard/eekboard-xklutil.h"
 | 
			
		||||
 | 
			
		||||
XklConfigRec *
 | 
			
		||||
eekboard_xkl_config_rec_from_string (const gchar *layouts)
 | 
			
		||||
{
 | 
			
		||||
    XklConfigRec *rec;
 | 
			
		||||
    gchar **strv, **l, **v;
 | 
			
		||||
    gint i;
 | 
			
		||||
 | 
			
		||||
    strv = g_strsplit (layouts, "/", -1);
 | 
			
		||||
    g_return_val_if_fail (g_strv_length (strv) == 3, NULL);
 | 
			
		||||
    
 | 
			
		||||
    l = g_strsplit (strv[1], ";", -1);
 | 
			
		||||
    v = g_strdupv (l);
 | 
			
		||||
    for (i = 0; l[i]; i++) {
 | 
			
		||||
        gchar *layout = l[i], *variant = v[i],
 | 
			
		||||
            *variant_start, *variant_end;
 | 
			
		||||
 | 
			
		||||
        variant_start = strchr (layout, '(');
 | 
			
		||||
        variant_end = strrchr (layout, ')');
 | 
			
		||||
        if (variant_start && variant_end) {
 | 
			
		||||
            *variant_start++ = '\0';
 | 
			
		||||
            g_strlcpy (variant, variant_start,
 | 
			
		||||
                       variant_end - variant_start + 1);
 | 
			
		||||
        } else
 | 
			
		||||
            *variant = '\0';
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    rec = xkl_config_rec_new ();
 | 
			
		||||
    rec->model = g_strdup (strv[0]);
 | 
			
		||||
    rec->layouts = l;
 | 
			
		||||
    rec->variants = v;
 | 
			
		||||
    rec->options = g_strsplit (strv[2], ";", -1);
 | 
			
		||||
    g_strfreev (strv);
 | 
			
		||||
 | 
			
		||||
    return rec;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
gchar *
 | 
			
		||||
eekboard_xkl_config_rec_to_string (XklConfigRec *rec)
 | 
			
		||||
{
 | 
			
		||||
    gchar **strv, **sp, **lp, **vp, *p;
 | 
			
		||||
    gint n_layouts;
 | 
			
		||||
    GString *str;
 | 
			
		||||
 | 
			
		||||
    n_layouts = g_strv_length (rec->layouts);
 | 
			
		||||
    strv = g_malloc0_n (n_layouts + 2, sizeof (gchar *));
 | 
			
		||||
    for (sp = strv, lp = rec->layouts, vp = rec->variants; *lp; sp++, lp++) {
 | 
			
		||||
        if (*vp != NULL && **vp != '\0')
 | 
			
		||||
            *sp = g_strdup_printf ("%s(%s)", *lp, *vp++);
 | 
			
		||||
        else
 | 
			
		||||
            *sp = g_strdup_printf ("%s", *lp);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* MODEL/L0(V0);L1(V1);...;Ln(Vn)/O0;O1;...;On */
 | 
			
		||||
    str = g_string_new (rec->model);
 | 
			
		||||
 | 
			
		||||
    g_string_append_c (str, '/');
 | 
			
		||||
    p = g_strjoinv (";", strv);
 | 
			
		||||
    g_strfreev (strv);
 | 
			
		||||
    g_string_append (str, p);
 | 
			
		||||
    g_free (p);
 | 
			
		||||
 | 
			
		||||
    g_string_append_c (str, '/');
 | 
			
		||||
    p = g_strjoinv (";", rec->options);
 | 
			
		||||
    g_string_append (str, p);
 | 
			
		||||
    g_free (p);
 | 
			
		||||
 | 
			
		||||
    return g_string_free (str,FALSE);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static XklConfigItem *
 | 
			
		||||
xkl_config_item_copy (const XklConfigItem *item)
 | 
			
		||||
{
 | 
			
		||||
    XklConfigItem *_item = xkl_config_item_new ();
 | 
			
		||||
    memcpy (_item->name,
 | 
			
		||||
            item->name,
 | 
			
		||||
            sizeof (item->name));
 | 
			
		||||
    memcpy (_item->short_description,
 | 
			
		||||
            item->short_description,
 | 
			
		||||
            sizeof (item->short_description));
 | 
			
		||||
    memcpy (_item->description,
 | 
			
		||||
            item->description,
 | 
			
		||||
            sizeof (item->description));
 | 
			
		||||
    return _item;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
prepend_item (XklConfigRegistry   *registry,
 | 
			
		||||
              const XklConfigItem *item,
 | 
			
		||||
              gpointer             data)
 | 
			
		||||
{
 | 
			
		||||
    GSList **list = data;
 | 
			
		||||
    XklConfigItem *_item = xkl_config_item_copy (item);
 | 
			
		||||
    *list = g_slist_prepend (*list, _item);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gint
 | 
			
		||||
compare_item_by_name (gconstpointer a, gconstpointer b)
 | 
			
		||||
{
 | 
			
		||||
    const XklConfigItem *ia = a, *ib = b;
 | 
			
		||||
    return g_strcmp0 (ia->name, ib->name);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
GSList *
 | 
			
		||||
eekboard_xkl_list_models (XklConfigRegistry *registry)
 | 
			
		||||
{
 | 
			
		||||
    GSList *list = NULL;
 | 
			
		||||
    xkl_config_registry_foreach_model (registry, prepend_item, &list);
 | 
			
		||||
    return g_slist_sort (list, compare_item_by_name);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
GSList *
 | 
			
		||||
eekboard_xkl_list_layouts (XklConfigRegistry *registry)
 | 
			
		||||
{
 | 
			
		||||
    GSList *list = NULL;
 | 
			
		||||
    xkl_config_registry_foreach_layout (registry, prepend_item, &list);
 | 
			
		||||
    return g_slist_sort (list, compare_item_by_name);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
GSList *
 | 
			
		||||
eekboard_xkl_list_option_groups (XklConfigRegistry *registry)
 | 
			
		||||
{
 | 
			
		||||
    GSList *list = NULL;
 | 
			
		||||
    xkl_config_registry_foreach_option_group (registry, prepend_item, &list);
 | 
			
		||||
    return g_slist_sort (list, compare_item_by_name);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
GSList *
 | 
			
		||||
eekboard_xkl_list_layout_variants (XklConfigRegistry *registry,
 | 
			
		||||
                                   const gchar       *layout)
 | 
			
		||||
{
 | 
			
		||||
    GSList *list = NULL;
 | 
			
		||||
    xkl_config_registry_foreach_layout_variant (registry,
 | 
			
		||||
                                                layout,
 | 
			
		||||
                                                prepend_item,
 | 
			
		||||
                                                &list);
 | 
			
		||||
    return g_slist_sort (list, compare_item_by_name);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
GSList *
 | 
			
		||||
eekboard_xkl_list_options (XklConfigRegistry *registry,
 | 
			
		||||
                           const gchar       *group)
 | 
			
		||||
{
 | 
			
		||||
    GSList *list = NULL;
 | 
			
		||||
    xkl_config_registry_foreach_option (registry, group, prepend_item, &list);
 | 
			
		||||
    return g_slist_sort (list, compare_item_by_name);
 | 
			
		||||
}
 | 
			
		||||
@ -1,39 +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 EEKBOARD_XKLUTIL_H
 | 
			
		||||
#define EEKBOARD_XKLUTIL_H 1
 | 
			
		||||
 | 
			
		||||
#include <libxklavier/xklavier.h>
 | 
			
		||||
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
XklConfigRec *eekboard_xkl_config_rec_from_string (const gchar       *layouts);
 | 
			
		||||
gchar        *eekboard_xkl_config_rec_to_string   (XklConfigRec      *rec);
 | 
			
		||||
 | 
			
		||||
GSList       *eekboard_xkl_list_models            (XklConfigRegistry *registry);
 | 
			
		||||
GSList       *eekboard_xkl_list_layouts           (XklConfigRegistry *registry);
 | 
			
		||||
GSList       *eekboard_xkl_list_option_groups     (XklConfigRegistry *registry);
 | 
			
		||||
GSList       *eekboard_xkl_list_layout_variants   (XklConfigRegistry *registry,
 | 
			
		||||
                                                   const gchar       *layout);
 | 
			
		||||
GSList       *eekboard_xkl_list_options           (XklConfigRegistry *registry,
 | 
			
		||||
                                                   const gchar       *group);
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
#endif  /* EEKBOARD_XKLUTIL_H */
 | 
			
		||||
@ -143,8 +143,8 @@ int send_virtual_keyboard_key(
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
send_fake_modifiers_events (SeatEmitter         *emitter,
 | 
			
		||||
                              EekModifierType modifiers,
 | 
			
		||||
                              uint32_t        timestamp)
 | 
			
		||||
                            EekModifierType      modifiers,
 | 
			
		||||
                            uint32_t             timestamp)
 | 
			
		||||
{
 | 
			
		||||
    (void)timestamp;
 | 
			
		||||
 | 
			
		||||
@ -284,6 +284,26 @@ update_modifier_info (SeatEmitter *client)
 | 
			
		||||
    }*/
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
send_fake_key (SeatEmitter *emitter,
 | 
			
		||||
               EekKeyboard *keyboard,
 | 
			
		||||
               guint    keycode,
 | 
			
		||||
               guint    keyboard_modifiers,
 | 
			
		||||
               gboolean pressed,
 | 
			
		||||
               uint32_t timestamp)
 | 
			
		||||
{
 | 
			
		||||
    uint32_t proto_modifiers = 0;
 | 
			
		||||
    guint level = eek_element_get_level(EEK_ELEMENT(keyboard));
 | 
			
		||||
    uint32_t group = (level / 2);
 | 
			
		||||
 | 
			
		||||
    if (keyboard_modifiers & EEK_SHIFT_MASK)
 | 
			
		||||
        proto_modifiers |= 1<<MOD_IDX_SHIFT;
 | 
			
		||||
 | 
			
		||||
    zwp_virtual_keyboard_v1_modifiers(emitter->virtual_keyboard, proto_modifiers, 0, 0, group);
 | 
			
		||||
    send_virtual_keyboard_key (emitter->virtual_keyboard, keycode - 8, (unsigned)pressed, timestamp);
 | 
			
		||||
    zwp_virtual_keyboard_v1_modifiers(emitter->virtual_keyboard, proto_modifiers, 0, 0, group);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
emit_key_activated (EekboardContextService *manager,
 | 
			
		||||
                    EekKeyboard     *keyboard,
 | 
			
		||||
@ -324,5 +344,5 @@ emit_key_activated (EekboardContextService *manager,
 | 
			
		||||
    emitter.virtual_keyboard = manager->virtual_keyboard;
 | 
			
		||||
    emitter.keymap = keyboard->keymap;
 | 
			
		||||
    update_modifier_info (&emitter);
 | 
			
		||||
    send_fake_key_events (&emitter, symbol, modifiers, pressed, timestamp);
 | 
			
		||||
    send_fake_key (&emitter, keyboard, keycode, modifiers, pressed, timestamp);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -3,7 +3,6 @@
 | 
			
		||||
 | 
			
		||||
#include <inttypes.h>
 | 
			
		||||
#include <glib.h>
 | 
			
		||||
#include <X11/XKBlib.h>
 | 
			
		||||
 | 
			
		||||
#include "eek/eek.h"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										21
									
								
								meson.build
									
									
									
									
									
								
							
							
						
						
									
										21
									
								
								meson.build
									
									
									
									
									
								
							@ -3,12 +3,18 @@ project(
 | 
			
		||||
    'c', 'rust',
 | 
			
		||||
    version: '1.0.10',
 | 
			
		||||
    license: 'GPLv3',
 | 
			
		||||
    meson_version: '>=0.43.0',
 | 
			
		||||
    default_options: [ 'warning_level=1', 'buildtype=debugoptimized', 'c_std=gnu11' ],
 | 
			
		||||
    meson_version: '>=0.49.0',
 | 
			
		||||
    default_options: [
 | 
			
		||||
        'warning_level=1',
 | 
			
		||||
        'buildtype=debugoptimized',
 | 
			
		||||
        'c_std=gnu11'
 | 
			
		||||
    ]
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
i18n = import('i18n')
 | 
			
		||||
 | 
			
		||||
conf_data = configuration_data()
 | 
			
		||||
 | 
			
		||||
if get_option('buildtype').startswith('debug')
 | 
			
		||||
    add_project_arguments('-DDEBUG=1', language : 'c')
 | 
			
		||||
endif
 | 
			
		||||
@ -26,8 +32,19 @@ else
 | 
			
		||||
endif
 | 
			
		||||
dbusdir = join_paths(depdatadir, 'dbus-1/interfaces')
 | 
			
		||||
 | 
			
		||||
summary = [
 | 
			
		||||
        '',
 | 
			
		||||
        '------------------',
 | 
			
		||||
        'squeekboard @0@'.format(meson.project_version()),
 | 
			
		||||
        '',
 | 
			
		||||
        '------------------',
 | 
			
		||||
        ''
 | 
			
		||||
]
 | 
			
		||||
message('\n'.join(summary))
 | 
			
		||||
 | 
			
		||||
subdir('data')
 | 
			
		||||
subdir('protocols')
 | 
			
		||||
subdir('eek')
 | 
			
		||||
subdir('src')
 | 
			
		||||
subdir('po')
 | 
			
		||||
subdir('tests')
 | 
			
		||||
 | 
			
		||||
@ -1 +1,8 @@
 | 
			
		||||
option('depdatadir', type : 'string', value : '', description : 'System data path. Will be searched for definitions instead of datadir when provided')
 | 
			
		||||
option('depdatadir',
 | 
			
		||||
       type : 'string',
 | 
			
		||||
       value : '',
 | 
			
		||||
       description : 'System data path. Will be searched for definitions instead of datadir when provided')
 | 
			
		||||
 | 
			
		||||
option('tests',
 | 
			
		||||
       type: 'boolean', value: true,
 | 
			
		||||
       description: 'Whether to compile unit tests')
 | 
			
		||||
 | 
			
		||||
@ -14,6 +14,7 @@ wl_protos = [
 | 
			
		||||
  'wlr-layer-shell-unstable-v1.xml',
 | 
			
		||||
  'virtual-keyboard-unstable-v1.xml',
 | 
			
		||||
  'input-method-unstable-v2.xml',
 | 
			
		||||
  'text-input-unstable-v3.xml'
 | 
			
		||||
]
 | 
			
		||||
wl_proto_sources = []
 | 
			
		||||
foreach proto: wl_protos
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										441
									
								
								protocols/text-input-unstable-v3.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										441
									
								
								protocols/text-input-unstable-v3.xml
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,441 @@
 | 
			
		||||
<?xml version="1.0" encoding="UTF-8"?>
 | 
			
		||||
 | 
			
		||||
<protocol name="text_input_unstable_v3">
 | 
			
		||||
  <copyright>
 | 
			
		||||
    Copyright © 2012, 2013 Intel Corporation
 | 
			
		||||
    Copyright © 2015, 2016 Jan Arne Petersen
 | 
			
		||||
    Copyright © 2017, 2018 Red Hat, Inc.
 | 
			
		||||
    Copyright © 2018       Purism SPC
 | 
			
		||||
 | 
			
		||||
    Permission to use, copy, modify, distribute, and sell this
 | 
			
		||||
    software and its documentation for any purpose is hereby granted
 | 
			
		||||
    without fee, provided that the above copyright notice appear in
 | 
			
		||||
    all copies and that both that copyright notice and this permission
 | 
			
		||||
    notice appear in supporting documentation, and that the name of
 | 
			
		||||
    the copyright holders not be used in advertising or publicity
 | 
			
		||||
    pertaining to distribution of the software without specific,
 | 
			
		||||
    written prior permission.  The copyright holders make no
 | 
			
		||||
    representations about the suitability of this software for any
 | 
			
		||||
    purpose.  It is provided "as is" without express or implied
 | 
			
		||||
    warranty.
 | 
			
		||||
 | 
			
		||||
    THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
 | 
			
		||||
    SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
 | 
			
		||||
    FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
 | 
			
		||||
    SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 | 
			
		||||
    WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
 | 
			
		||||
    AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
 | 
			
		||||
    ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
 | 
			
		||||
    THIS SOFTWARE.
 | 
			
		||||
  </copyright>
 | 
			
		||||
 | 
			
		||||
  <description summary="Protocol for composing text">
 | 
			
		||||
    This protocol allows compositors to act as input methods and to send text
 | 
			
		||||
    to applications. A text input object is used to manage state of what are
 | 
			
		||||
    typically text entry fields in the application.
 | 
			
		||||
 | 
			
		||||
    This document adheres to the RFC 2119 when using words like "must",
 | 
			
		||||
    "should", "may", etc.
 | 
			
		||||
 | 
			
		||||
    Warning! The protocol described in this file is experimental and
 | 
			
		||||
    backward incompatible changes may be made. Backward compatible changes
 | 
			
		||||
    may be added together with the corresponding interface version bump.
 | 
			
		||||
    Backward incompatible changes are done by bumping the version number in
 | 
			
		||||
    the protocol and interface names and resetting the interface version.
 | 
			
		||||
    Once the protocol is to be declared stable, the 'z' prefix and the
 | 
			
		||||
    version number in the protocol and interface names are removed and the
 | 
			
		||||
    interface version number is reset.
 | 
			
		||||
  </description>
 | 
			
		||||
 | 
			
		||||
  <interface name="zwp_text_input_v3" version="1">
 | 
			
		||||
    <description summary="text input">
 | 
			
		||||
      The zwp_text_input_v3 interface represents text input and input methods
 | 
			
		||||
      associated with a seat. It provides enter/leave events to follow the
 | 
			
		||||
      text input focus for a seat.
 | 
			
		||||
 | 
			
		||||
      Requests are used to enable/disable the text-input object and set
 | 
			
		||||
      state information like surrounding and selected text or the content type.
 | 
			
		||||
      The information about the entered text is sent to the text-input object
 | 
			
		||||
      via the preedit_string and commit_string events.
 | 
			
		||||
 | 
			
		||||
      Text is valid UTF-8 encoded, indices and lengths are in bytes. Indices
 | 
			
		||||
      must not point to middle bytes inside a code point: they must either
 | 
			
		||||
      point to the first byte of a code point or to the end of the buffer.
 | 
			
		||||
      Lengths must be measured between two valid indices.
 | 
			
		||||
 | 
			
		||||
      Focus moving throughout surfaces will result in the emission of
 | 
			
		||||
      zwp_text_input_v3.enter and zwp_text_input_v3.leave events. The focused
 | 
			
		||||
      surface must commit zwp_text_input_v3.enable and
 | 
			
		||||
      zwp_text_input_v3.disable requests as the keyboard focus moves across
 | 
			
		||||
      editable and non-editable elements of the UI. Those two requests are not
 | 
			
		||||
      expected to be paired with each other, the compositor must be able to
 | 
			
		||||
      handle consecutive series of the same request.
 | 
			
		||||
 | 
			
		||||
      State is sent by the state requests (set_surrounding_text,
 | 
			
		||||
      set_content_type and set_cursor_rectangle) and a commit request. After an
 | 
			
		||||
      enter event or disable request all state information is invalidated and
 | 
			
		||||
      needs to be resent by the client.
 | 
			
		||||
    </description>
 | 
			
		||||
 | 
			
		||||
    <request name="destroy" type="destructor">
 | 
			
		||||
      <description summary="Destroy the wp_text_input">
 | 
			
		||||
        Destroy the wp_text_input object. Also disables all surfaces enabled
 | 
			
		||||
        through this wp_text_input object.
 | 
			
		||||
      </description>
 | 
			
		||||
    </request>
 | 
			
		||||
 | 
			
		||||
    <request name="enable">
 | 
			
		||||
      <description summary="Request text input to be enabled">
 | 
			
		||||
        Requests text input on the surface previously obtained from the enter
 | 
			
		||||
        event.
 | 
			
		||||
 | 
			
		||||
        This request must be issued every time the active text input changes
 | 
			
		||||
        to a new one, including within the current surface. Use
 | 
			
		||||
        zwp_text_input_v3.disable when there is no longer any input focus on
 | 
			
		||||
        the current surface.
 | 
			
		||||
 | 
			
		||||
        This request resets all state associated with previous enable, disable,
 | 
			
		||||
        set_surrounding_text, set_text_change_cause, set_content_type, and
 | 
			
		||||
        set_cursor_rectangle requests, as well as the state associated with
 | 
			
		||||
        preedit_string, commit_string, and delete_surrounding_text events.
 | 
			
		||||
 | 
			
		||||
        The set_surrounding_text, set_content_type and set_cursor_rectangle
 | 
			
		||||
        requests must follow if the text input supports the necessary
 | 
			
		||||
        functionality.
 | 
			
		||||
 | 
			
		||||
        State set with this request is double-buffered. It will get applied on
 | 
			
		||||
        the next zwp_text_input_v3.commit request, and stay valid until the
 | 
			
		||||
        next committed enable or disable request.
 | 
			
		||||
 | 
			
		||||
        The changes must be applied by the compositor after issuing a
 | 
			
		||||
        zwp_text_input_v3.commit request.
 | 
			
		||||
      </description>
 | 
			
		||||
    </request>
 | 
			
		||||
 | 
			
		||||
    <request name="disable">
 | 
			
		||||
      <description summary="Disable text input on a surface">
 | 
			
		||||
        Explicitly disable text input on the current surface (typically when
 | 
			
		||||
        there is no focus on any text entry inside the surface).
 | 
			
		||||
 | 
			
		||||
        State set with this request is double-buffered. It will get applied on
 | 
			
		||||
        the next zwp_text_input_v3.commit request.
 | 
			
		||||
      </description>
 | 
			
		||||
    </request>
 | 
			
		||||
 | 
			
		||||
    <request name="set_surrounding_text">
 | 
			
		||||
      <description summary="sets the surrounding text">
 | 
			
		||||
        Sets the surrounding plain text around the input, excluding the preedit
 | 
			
		||||
        text.
 | 
			
		||||
 | 
			
		||||
        The client should notify the compositor of any changes in any of the
 | 
			
		||||
        values carried with this request, including changes caused by handling
 | 
			
		||||
        incoming text-input events as well as changes caused by other
 | 
			
		||||
        mechanisms like keyboard typing.
 | 
			
		||||
 | 
			
		||||
        If the client is unaware of the text around the cursor, it should not
 | 
			
		||||
        issue this request, to signify lack of support to the compositor.
 | 
			
		||||
 | 
			
		||||
        Text is UTF-8 encoded, and should include the cursor position, the
 | 
			
		||||
        complete selection and additional characters before and after them.
 | 
			
		||||
        There is a maximum length of wayland messages, so text can not be
 | 
			
		||||
        longer than 4000 bytes.
 | 
			
		||||
 | 
			
		||||
        Cursor is the byte offset of the cursor within text buffer.
 | 
			
		||||
 | 
			
		||||
        Anchor is the byte offset of the selection anchor within text buffer.
 | 
			
		||||
        If there is no selected text, anchor is the same as cursor.
 | 
			
		||||
 | 
			
		||||
        If any preedit text is present, it is replaced with a cursor for the
 | 
			
		||||
        purpose of this event.
 | 
			
		||||
 | 
			
		||||
        Values set with this request are double-buffered. They will get applied
 | 
			
		||||
        on the next zwp_text_input_v3.commit request, and stay valid until the
 | 
			
		||||
        next committed enable or disable request.
 | 
			
		||||
 | 
			
		||||
        The initial state for affected fields is empty, meaning that the text
 | 
			
		||||
        input does not support sending surrounding text. If the empty values
 | 
			
		||||
        get applied, subsequent attempts to change them may have no effect.
 | 
			
		||||
      </description>
 | 
			
		||||
      <arg name="text" type="string"/>
 | 
			
		||||
      <arg name="cursor" type="int"/>
 | 
			
		||||
      <arg name="anchor" type="int"/>
 | 
			
		||||
    </request>
 | 
			
		||||
 | 
			
		||||
    <enum name="change_cause">
 | 
			
		||||
      <description summary="text change reason">
 | 
			
		||||
        Reason for the change of surrounding text or cursor posision.
 | 
			
		||||
      </description>
 | 
			
		||||
      <entry name="input_method" value="0" summary="input method caused the change"/>
 | 
			
		||||
      <entry name="other" value="1" summary="something else than the input method caused the change"/>
 | 
			
		||||
    </enum>
 | 
			
		||||
 | 
			
		||||
    <request name="set_text_change_cause">
 | 
			
		||||
      <description summary="indicates the cause of surrounding text change">
 | 
			
		||||
        Tells the compositor why the text surrounding the cursor changed.
 | 
			
		||||
 | 
			
		||||
        Whenever the client detects an external change in text, cursor, or
 | 
			
		||||
        anchor posision, it must issue this request to the compositor. This
 | 
			
		||||
        request is intended to give the input method a chance to update the
 | 
			
		||||
        preedit text in an appropriate way, e.g. by removing it when the user
 | 
			
		||||
        starts typing with a keyboard.
 | 
			
		||||
 | 
			
		||||
        cause describes the source of the change.
 | 
			
		||||
 | 
			
		||||
        The value set with this request is double-buffered. It must be applied
 | 
			
		||||
        and reset to initial at the next zwp_text_input_v3.commit request.
 | 
			
		||||
 | 
			
		||||
        The initial value of cause is input_method.
 | 
			
		||||
      </description>
 | 
			
		||||
      <arg name="cause" type="uint" enum="change_cause"/>
 | 
			
		||||
    </request>
 | 
			
		||||
 | 
			
		||||
    <enum name="content_hint" bitfield="true">
 | 
			
		||||
      <description summary="content hint">
 | 
			
		||||
        Content hint is a bitmask to allow to modify the behavior of the text
 | 
			
		||||
        input.
 | 
			
		||||
      </description>
 | 
			
		||||
      <entry name="none" value="0x0" summary="no special behavior"/>
 | 
			
		||||
      <entry name="completion" value="0x1" summary="suggest word completions"/>
 | 
			
		||||
      <entry name="spellcheck" value="0x2" summary="suggest word corrections"/>
 | 
			
		||||
      <entry name="auto_capitalization" value="0x4" summary="switch to uppercase letters at the start of a sentence"/>
 | 
			
		||||
      <entry name="lowercase" value="0x8" summary="prefer lowercase letters"/>
 | 
			
		||||
      <entry name="uppercase" value="0x10" summary="prefer uppercase letters"/>
 | 
			
		||||
      <entry name="titlecase" value="0x20" summary="prefer casing for titles and headings (can be language dependent)"/>
 | 
			
		||||
      <entry name="hidden_text" value="0x40" summary="characters should be hidden"/>
 | 
			
		||||
      <entry name="sensitive_data" value="0x80" summary="typed text should not be stored"/>
 | 
			
		||||
      <entry name="latin" value="0x100" summary="just Latin characters should be entered"/>
 | 
			
		||||
      <entry name="multiline" value="0x200" summary="the text input is multiline"/>
 | 
			
		||||
    </enum>
 | 
			
		||||
 | 
			
		||||
    <enum name="content_purpose">
 | 
			
		||||
      <description summary="content purpose">
 | 
			
		||||
        The content purpose allows to specify the primary purpose of a text
 | 
			
		||||
        input.
 | 
			
		||||
 | 
			
		||||
        This allows an input method to show special purpose input panels with
 | 
			
		||||
        extra characters or to disallow some characters.
 | 
			
		||||
      </description>
 | 
			
		||||
      <entry name="normal" value="0" summary="default input, allowing all characters"/>
 | 
			
		||||
      <entry name="alpha" value="1" summary="allow only alphabetic characters"/>
 | 
			
		||||
      <entry name="digits" value="2" summary="allow only digits"/>
 | 
			
		||||
      <entry name="number" value="3" summary="input a number (including decimal separator and sign)"/>
 | 
			
		||||
      <entry name="phone" value="4" summary="input a phone number"/>
 | 
			
		||||
      <entry name="url" value="5" summary="input an URL"/>
 | 
			
		||||
      <entry name="email" value="6" summary="input an email address"/>
 | 
			
		||||
      <entry name="name" value="7" summary="input a name of a person"/>
 | 
			
		||||
      <entry name="password" value="8" summary="input a password (combine with sensitive_data hint)"/>
 | 
			
		||||
      <entry name="pin" value="9" summary="input is a numeric password (combine with sensitive_data hint)"/>
 | 
			
		||||
      <entry name="date" value="10" summary="input a date"/>
 | 
			
		||||
      <entry name="time" value="11" summary="input a time"/>
 | 
			
		||||
      <entry name="datetime" value="12" summary="input a date and time"/>
 | 
			
		||||
      <entry name="terminal" value="13" summary="input for a terminal"/>
 | 
			
		||||
    </enum>
 | 
			
		||||
 | 
			
		||||
    <request name="set_content_type">
 | 
			
		||||
      <description summary="set content purpose and hint">
 | 
			
		||||
        Sets the content purpose and content hint. While the purpose is the
 | 
			
		||||
        basic purpose of an input field, the hint flags allow to modify some of
 | 
			
		||||
        the behavior.
 | 
			
		||||
 | 
			
		||||
        Values set with this request are double-buffered. They will get applied
 | 
			
		||||
        on the next zwp_text_input_v3.commit request.
 | 
			
		||||
        Subsequent attempts to update them may have no effect. The values
 | 
			
		||||
        remain valid until the next committed enable or disable request.
 | 
			
		||||
 | 
			
		||||
        The initial value for hint is none, and the initial value for purpose
 | 
			
		||||
        is normal.
 | 
			
		||||
      </description>
 | 
			
		||||
      <arg name="hint" type="uint" enum="content_hint"/>
 | 
			
		||||
      <arg name="purpose" type="uint" enum="content_purpose"/>
 | 
			
		||||
    </request>
 | 
			
		||||
 | 
			
		||||
    <request name="set_cursor_rectangle">
 | 
			
		||||
      <description summary="set cursor position">
 | 
			
		||||
        Marks an area around the cursor as a x, y, width, height rectangle in
 | 
			
		||||
        surface local coordinates.
 | 
			
		||||
 | 
			
		||||
        Allows the compositor to put a window with word suggestions near the
 | 
			
		||||
        cursor, without obstructing the text being input.
 | 
			
		||||
 | 
			
		||||
        If the client is unaware of the position of edited text, it should not
 | 
			
		||||
        issue this request, to signify lack of support to the compositor.
 | 
			
		||||
 | 
			
		||||
        Values set with this request are double-buffered. They will get applied
 | 
			
		||||
        on the next zwp_text_input_v3.commit request, and stay valid until the
 | 
			
		||||
        next committed enable or disable request.
 | 
			
		||||
 | 
			
		||||
        The initial values describing a cursor rectangle are empty. That means
 | 
			
		||||
        the text input does not support describing the cursor area. If the
 | 
			
		||||
        empty values get applied, subsequent attempts to change them may have
 | 
			
		||||
        no effect.
 | 
			
		||||
      </description>
 | 
			
		||||
      <arg name="x" type="int"/>
 | 
			
		||||
      <arg name="y" type="int"/>
 | 
			
		||||
      <arg name="width" type="int"/>
 | 
			
		||||
      <arg name="height" type="int"/>
 | 
			
		||||
    </request>
 | 
			
		||||
 | 
			
		||||
    <request name="commit">
 | 
			
		||||
      <description summary="commit state">
 | 
			
		||||
        Atomically applies state changes recently sent to the compositor.
 | 
			
		||||
 | 
			
		||||
        The commit request establishes and updates the state of the client, and
 | 
			
		||||
        must be issued after any changes to apply them.
 | 
			
		||||
 | 
			
		||||
        Text input state (enabled status, content purpose, content hint,
 | 
			
		||||
        surrounding text and change cause, cursor rectangle) is conceptually
 | 
			
		||||
        double-buffered within the context of a text input, i.e. between a
 | 
			
		||||
        committed enable request and the following committed enable or disable
 | 
			
		||||
        request.
 | 
			
		||||
 | 
			
		||||
        Protocol requests modify the pending state, as opposed to the current
 | 
			
		||||
        state in use by the input method. A commit request atomically applies
 | 
			
		||||
        all pending state, replacing the current state. After commit, the new
 | 
			
		||||
        pending state is as documented for each related request.
 | 
			
		||||
 | 
			
		||||
        Requests are applied in the order of arrival.
 | 
			
		||||
 | 
			
		||||
        Neither current nor pending state are modified unless noted otherwise.
 | 
			
		||||
 | 
			
		||||
        The compositor must count the number of commit requests coming from
 | 
			
		||||
        each zwp_text_input_v3 object and use the count as the serial in done
 | 
			
		||||
        events.
 | 
			
		||||
      </description>
 | 
			
		||||
    </request>
 | 
			
		||||
 | 
			
		||||
    <event name="enter">
 | 
			
		||||
      <description summary="enter event">
 | 
			
		||||
        Notification that this seat's text-input focus is on a certain surface.
 | 
			
		||||
 | 
			
		||||
        When the seat has the keyboard capability the text-input focus follows
 | 
			
		||||
        the keyboard focus. This event sets the current surface for the
 | 
			
		||||
        text-input object.
 | 
			
		||||
      </description>
 | 
			
		||||
      <arg name="surface" type="object" interface="wl_surface"/>
 | 
			
		||||
    </event>
 | 
			
		||||
 | 
			
		||||
    <event name="leave">
 | 
			
		||||
      <description summary="leave event">
 | 
			
		||||
        Notification that this seat's text-input focus is no longer on a
 | 
			
		||||
        certain surface. The client should reset any preedit string previously
 | 
			
		||||
        set.
 | 
			
		||||
 | 
			
		||||
        The leave notification clears the current surface. It is sent before
 | 
			
		||||
        the enter notification for the new focus.
 | 
			
		||||
 | 
			
		||||
        When the seat has the keyboard capability the text-input focus follows
 | 
			
		||||
        the keyboard focus.
 | 
			
		||||
      </description>
 | 
			
		||||
      <arg name="surface" type="object" interface="wl_surface"/>
 | 
			
		||||
    </event>
 | 
			
		||||
 | 
			
		||||
    <event name="preedit_string">
 | 
			
		||||
      <description summary="pre-edit">
 | 
			
		||||
        Notify when a new composing text (pre-edit) should be set at the
 | 
			
		||||
        current cursor position. Any previously set composing text must be
 | 
			
		||||
        removed. Any previously existing selected text must be removed.
 | 
			
		||||
 | 
			
		||||
        The argument text contains the pre-edit string buffer.
 | 
			
		||||
 | 
			
		||||
        The parameters cursor_begin and cursor_end are counted in bytes
 | 
			
		||||
        relative to the beginning of the submitted text buffer. Cursor should
 | 
			
		||||
        be hidden when both are equal to -1.
 | 
			
		||||
 | 
			
		||||
        They could be represented by the client as a line if both values are
 | 
			
		||||
        the same, or as a text highlight otherwise.
 | 
			
		||||
 | 
			
		||||
        Values set with this event are double-buffered. They must be applied
 | 
			
		||||
        and reset to initial on the next zwp_text_input_v3.done event.
 | 
			
		||||
 | 
			
		||||
        The initial value of text is an empty string, and cursor_begin,
 | 
			
		||||
        cursor_end and cursor_hidden are all 0.
 | 
			
		||||
      </description>
 | 
			
		||||
      <arg name="text" type="string" allow-null="true"/>
 | 
			
		||||
      <arg name="cursor_begin" type="int"/>
 | 
			
		||||
      <arg name="cursor_end" type="int"/>
 | 
			
		||||
    </event>
 | 
			
		||||
 | 
			
		||||
    <event name="commit_string">
 | 
			
		||||
      <description summary="text commit">
 | 
			
		||||
        Notify when text should be inserted into the editor widget. The text to
 | 
			
		||||
        commit could be either just a single character after a key press or the
 | 
			
		||||
        result of some composing (pre-edit).
 | 
			
		||||
 | 
			
		||||
        Values set with this event are double-buffered. They must be applied
 | 
			
		||||
        and reset to initial on the next zwp_text_input_v3.done event.
 | 
			
		||||
 | 
			
		||||
        The initial value of text is an empty string.
 | 
			
		||||
      </description>
 | 
			
		||||
      <arg name="text" type="string" allow-null="true"/>
 | 
			
		||||
    </event>
 | 
			
		||||
 | 
			
		||||
    <event name="delete_surrounding_text">
 | 
			
		||||
      <description summary="delete surrounding text">
 | 
			
		||||
        Notify when the text around the current cursor position should be
 | 
			
		||||
        deleted.
 | 
			
		||||
 | 
			
		||||
        Before_length and after_length are the number of bytes before and after
 | 
			
		||||
        the current cursor index (excluding the selection) to delete.
 | 
			
		||||
 | 
			
		||||
        If a preedit text is present, in effect before_length is counted from
 | 
			
		||||
        the beginning of it, and after_length from its end (see done event
 | 
			
		||||
        sequence).
 | 
			
		||||
 | 
			
		||||
        Values set with this event are double-buffered. They must be applied
 | 
			
		||||
        and reset to initial on the next zwp_text_input_v3.done event.
 | 
			
		||||
 | 
			
		||||
        The initial values of both before_length and after_length are 0.
 | 
			
		||||
      </description>
 | 
			
		||||
      <arg name="before_length" type="uint" summary="length of text before current cursor position"/>
 | 
			
		||||
      <arg name="after_length" type="uint" summary="length of text after current cursor position"/>
 | 
			
		||||
    </event>
 | 
			
		||||
 | 
			
		||||
    <event name="done">
 | 
			
		||||
      <description summary="apply changes">
 | 
			
		||||
        Instruct the application to apply changes to state requested by the
 | 
			
		||||
        preedit_string, commit_string and delete_surrounding_text events. The
 | 
			
		||||
        state relating to these events is double-buffered, and each one
 | 
			
		||||
        modifies the pending state. This event replaces the current state with
 | 
			
		||||
        the pending state.
 | 
			
		||||
 | 
			
		||||
        The application must proceed by evaluating the changes in the following
 | 
			
		||||
        order:
 | 
			
		||||
 | 
			
		||||
        1. Replace existing preedit string with the cursor.
 | 
			
		||||
        2. Delete requested surrounding text.
 | 
			
		||||
        3. Insert commit string with the cursor at its end.
 | 
			
		||||
        4. Calculate surrounding text to send.
 | 
			
		||||
        5. Insert new preedit text in cursor position.
 | 
			
		||||
        6. Place cursor inside preedit text.
 | 
			
		||||
 | 
			
		||||
        The serial number reflects the last state of the zwp_text_input_v3
 | 
			
		||||
        object known to the compositor. The value of the serial argument must
 | 
			
		||||
        be equal to the number of commit requests already issued on that object.
 | 
			
		||||
        When the client receives a done event with a serial different than the
 | 
			
		||||
        number of past commit requests, it must proceed as normal, except it
 | 
			
		||||
        should not change the current state of the zwp_text_input_v3 object.
 | 
			
		||||
      </description>
 | 
			
		||||
      <arg name="serial" type="uint"/>
 | 
			
		||||
    </event>
 | 
			
		||||
  </interface>
 | 
			
		||||
 | 
			
		||||
  <interface name="zwp_text_input_manager_v3" version="1">
 | 
			
		||||
    <description summary="text input manager">
 | 
			
		||||
      A factory for text-input objects. This object is a global singleton.
 | 
			
		||||
    </description>
 | 
			
		||||
 | 
			
		||||
    <request name="destroy" type="destructor">
 | 
			
		||||
      <description summary="Destroy the wp_text_input_manager">
 | 
			
		||||
        Destroy the wp_text_input_manager object.
 | 
			
		||||
      </description>
 | 
			
		||||
    </request>
 | 
			
		||||
 | 
			
		||||
    <request name="get_text_input">
 | 
			
		||||
      <description summary="create a new text input object">
 | 
			
		||||
        Creates a new text-input object for a given seat.
 | 
			
		||||
      </description>
 | 
			
		||||
      <arg name="id" type="new_id" interface="zwp_text_input_v3"/>
 | 
			
		||||
      <arg name="seat" type="object" interface="wl_seat"/>
 | 
			
		||||
    </request>
 | 
			
		||||
  </interface>
 | 
			
		||||
</protocol>
 | 
			
		||||
							
								
								
									
										4
									
								
								src/config.h.in
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								src/config.h.in
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,4 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Autogenerated by the Meson build system.
 | 
			
		||||
 * Do not edit, your changes will be lost.
 | 
			
		||||
 */
 | 
			
		||||
@ -6,7 +6,15 @@
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void imservice_handle_text_change_cause(void *data, struct zwp_input_method_v2 *input_method, uint32_t cause) {}
 | 
			
		||||
void imservice_handle_content_type(void *data, struct zwp_input_method_v2 *input_method, uint32_t hint, uint32_t purpose) {}
 | 
			
		||||
 | 
			
		||||
void imservice_handle_content_type(void *data, struct zwp_input_method_v2 *input_method, uint32_t hint, uint32_t purpose)
 | 
			
		||||
{
 | 
			
		||||
    struct imservice *ims = (struct imservice*)data;
 | 
			
		||||
    EekboardContextService *context = EEKBOARD_CONTEXT_SERVICE(ims->ui_manager);
 | 
			
		||||
 | 
			
		||||
    eekboard_context_service_set_hint_purpose(context, hint, purpose);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void imservice_handle_unavailable(void *data, struct zwp_input_method_v2 *input_method) {}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -25,8 +33,11 @@ struct imservice* get_imservice(EekboardContextService *context,
 | 
			
		||||
                                struct wl_seat *seat) {
 | 
			
		||||
    struct zwp_input_method_v2 *im = zwp_input_method_manager_v2_get_input_method(manager, seat);
 | 
			
		||||
    struct imservice *imservice = imservice_new(im, context);
 | 
			
		||||
    zwp_input_method_v2_add_listener(im,
 | 
			
		||||
        &input_method_listener, imservice);
 | 
			
		||||
 | 
			
		||||
    /* Add a listener, passing the imservice instance to make it available to
 | 
			
		||||
       callbacks. */
 | 
			
		||||
    zwp_input_method_v2_add_listener(im, &input_method_listener, imservice);
 | 
			
		||||
 | 
			
		||||
    return imservice;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -4,7 +4,11 @@
 | 
			
		||||
#include "input-method-unstable-v2-client-protocol.h"
 | 
			
		||||
#include "eek/eek-types.h"
 | 
			
		||||
 | 
			
		||||
struct imservice;
 | 
			
		||||
struct imservice
 | 
			
		||||
{
 | 
			
		||||
    struct zwp_input_method_v2 *im;
 | 
			
		||||
    EekboardContextService *ui_manager;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct imservice* get_imservice(EekboardContextService *context,
 | 
			
		||||
                                struct zwp_input_method_manager_v2 *manager,
 | 
			
		||||
 | 
			
		||||
@ -4,16 +4,21 @@ dbus_src = gnome.gdbus_codegen(
 | 
			
		||||
    join_paths(meson.source_root() / 'data' / 'dbus', 'sm.puri.OSK0.xml')
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
config_h = configure_file(
 | 
			
		||||
    input: 'config.h.in',
 | 
			
		||||
    output: 'config.h',
 | 
			
		||||
    configuration: conf_data
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
sources = [
 | 
			
		||||
  config_h,
 | 
			
		||||
  'imservice.c',
 | 
			
		||||
  'server-context-service.c',
 | 
			
		||||
  'server-main.c',
 | 
			
		||||
  'wayland.c',
 | 
			
		||||
  '../eek/eek.c',
 | 
			
		||||
  '../eek/eek-container.c',
 | 
			
		||||
  '../eek/eek-element.c',
 | 
			
		||||
  '../eek/eek-gtk-keyboard.c',
 | 
			
		||||
  '../eek/eek-gtk-renderer.c',
 | 
			
		||||
  '../eek/eek-key.c',
 | 
			
		||||
  '../eek/eek-keyboard.c',
 | 
			
		||||
  '../eek/eek-keyboard-drawing.c',
 | 
			
		||||
@ -69,11 +74,25 @@ rslib = static_library(
 | 
			
		||||
  rust_crate_type: 'staticlib'
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
squeekboard = executable('squeekboard',
 | 
			
		||||
libsqueekboard = static_library('libsqueekboard',
 | 
			
		||||
  sources,
 | 
			
		||||
  link_with: rslib,
 | 
			
		||||
  include_directories: [include_directories('..'), include_directories('../eek')],
 | 
			
		||||
  dependencies: deps,
 | 
			
		||||
  c_args: [
 | 
			
		||||
    '-DTHEMESDIR="' + pkgdatadir + '/themes"',
 | 
			
		||||
    '-DKEYBOARDSDIR="' + pkgdatadir + '/keyboards"',
 | 
			
		||||
    '-DEEKBOARD_COMPILATION=1',
 | 
			
		||||
    '-DEEK_COMPILATION=1'],
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
squeekboard = executable('squeekboard',
 | 
			
		||||
  'server-main.c',
 | 
			
		||||
  wl_proto_sources,
 | 
			
		||||
  squeekboard_resources,
 | 
			
		||||
  link_with: libsqueekboard,
 | 
			
		||||
  include_directories: [include_directories('..'), include_directories('../eek')],
 | 
			
		||||
  dependencies: deps,
 | 
			
		||||
  install: true,
 | 
			
		||||
  c_args: [
 | 
			
		||||
    '-DTHEMESDIR="' + pkgdatadir + '/themes"',
 | 
			
		||||
@ -81,4 +100,3 @@ squeekboard = executable('squeekboard',
 | 
			
		||||
    '-DEEKBOARD_COMPILATION=1',
 | 
			
		||||
    '-DEEK_COMPILATION=1'],
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -15,15 +15,11 @@
 | 
			
		||||
 * You should have received a copy of the GNU General Public License
 | 
			
		||||
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
#ifdef HAVE_CONFIG_H
 | 
			
		||||
#include "config.h"
 | 
			
		||||
#endif  /* HAVE_CONFIG_H */
 | 
			
		||||
 | 
			
		||||
#include <gtk/gtk.h>
 | 
			
		||||
#include <glib/gi18n.h>
 | 
			
		||||
 | 
			
		||||
#include <gdk/gdkx.h>
 | 
			
		||||
 | 
			
		||||
#include "eek/eek-gtk.h"
 | 
			
		||||
#include "eek/layersurface.h"
 | 
			
		||||
#include "wayland.h"
 | 
			
		||||
@ -42,13 +38,9 @@ typedef struct _ServerContextServiceClass ServerContextServiceClass;
 | 
			
		||||
struct _ServerContextService {
 | 
			
		||||
    EekboardContextService parent;
 | 
			
		||||
 | 
			
		||||
    gboolean was_visible;
 | 
			
		||||
 | 
			
		||||
    GtkWidget *window;
 | 
			
		||||
    GtkWidget *widget;
 | 
			
		||||
 | 
			
		||||
    gulong notify_visible_handler;
 | 
			
		||||
 | 
			
		||||
    gdouble size_constraint_landscape[2];
 | 
			
		||||
    gdouble size_constraint_portrait[2];
 | 
			
		||||
};
 | 
			
		||||
@ -59,10 +51,7 @@ struct _ServerContextServiceClass {
 | 
			
		||||
 | 
			
		||||
G_DEFINE_TYPE (ServerContextService, server_context_service, EEKBOARD_TYPE_CONTEXT_SERVICE);
 | 
			
		||||
 | 
			
		||||
static void update_widget (ServerContextService *context);
 | 
			
		||||
static void set_geometry  (ServerContextService *context);
 | 
			
		||||
static void set_dock      (GtkWidget            *widget,
 | 
			
		||||
                           GtkAllocation        *allocation);
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
on_monitors_changed (GdkScreen            *screen,
 | 
			
		||||
@ -86,6 +75,9 @@ on_destroy (GtkWidget *widget, gpointer user_data)
 | 
			
		||||
    eekboard_context_service_destroy (EEKBOARD_CONTEXT_SERVICE (context));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
make_widget (ServerContextService *context);
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
on_notify_keyboard (GObject              *object,
 | 
			
		||||
                    GParamSpec           *spec,
 | 
			
		||||
@ -104,22 +96,16 @@ on_notify_keyboard (GObject              *object,
 | 
			
		||||
    eekboard_context_service_set_keymap(EEKBOARD_CONTEXT_SERVICE(context),
 | 
			
		||||
                                        keyboard);
 | 
			
		||||
 | 
			
		||||
    if (context->window) {
 | 
			
		||||
        if (keyboard == NULL) {
 | 
			
		||||
            gtk_widget_hide (context->window);
 | 
			
		||||
            g_clear_pointer (&context->widget, gtk_widget_destroy);
 | 
			
		||||
        } else {
 | 
			
		||||
            gboolean was_visible = gtk_widget_get_visible (context->window);
 | 
			
		||||
            /* avoid to send KeyboardVisibilityChanged */
 | 
			
		||||
            g_signal_handler_block (context->window,
 | 
			
		||||
                                    context->notify_visible_handler);
 | 
			
		||||
            update_widget (context);
 | 
			
		||||
            if (was_visible) {
 | 
			
		||||
                gtk_widget_show_all (context->window);
 | 
			
		||||
            }
 | 
			
		||||
            g_signal_handler_unblock (context->window,
 | 
			
		||||
                                      context->notify_visible_handler);
 | 
			
		||||
        }
 | 
			
		||||
    /* Recreate the keyboard widget to keep in sync with the keymap. */
 | 
			
		||||
    if (context->window)
 | 
			
		||||
        make_widget(context);
 | 
			
		||||
 | 
			
		||||
    gboolean visible;
 | 
			
		||||
    g_object_get (context, "visible", &visible, NULL);
 | 
			
		||||
 | 
			
		||||
    if (visible) {
 | 
			
		||||
        eekboard_context_service_hide_keyboard(EEKBOARD_CONTEXT_SERVICE(context));
 | 
			
		||||
        eekboard_context_service_show_keyboard(EEKBOARD_CONTEXT_SERVICE(context));
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -133,81 +119,20 @@ on_notify_fullscreen (GObject              *object,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
on_notify_visible (GObject    *object,
 | 
			
		||||
                   GParamSpec *spec,
 | 
			
		||||
                   ServerContextService *context)
 | 
			
		||||
on_notify_map (GObject    *object,
 | 
			
		||||
               ServerContextService *context)
 | 
			
		||||
{
 | 
			
		||||
    gboolean visible;
 | 
			
		||||
 | 
			
		||||
    g_object_get (object, "visible", &visible, NULL);
 | 
			
		||||
    g_object_set (context, "visible", visible, NULL);
 | 
			
		||||
    g_object_set (context, "visible", TRUE, NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
set_dock (GtkWidget *widget, GtkAllocation *allocation)
 | 
			
		||||
on_notify_unmap (GObject    *object,
 | 
			
		||||
                 ServerContextService *context)
 | 
			
		||||
{
 | 
			
		||||
#ifdef HAVE_XDOCK
 | 
			
		||||
    GdkWindow *window = gtk_widget_get_window (widget);
 | 
			
		||||
    long vals[12];
 | 
			
		||||
 | 
			
		||||
    /* set window type to dock */
 | 
			
		||||
    gdk_window_set_type_hint (window, GDK_WINDOW_TYPE_HINT_DOCK);
 | 
			
		||||
 | 
			
		||||
    vals[0] = 0;
 | 
			
		||||
    vals[1] = 0;
 | 
			
		||||
    vals[2] = 0;
 | 
			
		||||
    vals[3] = allocation->height;
 | 
			
		||||
    vals[4] = 0;
 | 
			
		||||
    vals[5] = 0;
 | 
			
		||||
    vals[6] = 0;
 | 
			
		||||
    vals[7] = 0;
 | 
			
		||||
    vals[8] = 0;
 | 
			
		||||
    vals[9] = 0;
 | 
			
		||||
    vals[10] = allocation->x;
 | 
			
		||||
    vals[11] = allocation->x + allocation->width;
 | 
			
		||||
 | 
			
		||||
    XChangeProperty (GDK_WINDOW_XDISPLAY (window),
 | 
			
		||||
                     GDK_WINDOW_XID (window),
 | 
			
		||||
                     XInternAtom (GDK_WINDOW_XDISPLAY (window),
 | 
			
		||||
                                  "_NET_WM_STRUT_PARTIAL", False),
 | 
			
		||||
                     XA_CARDINAL, 32, PropModeReplace,
 | 
			
		||||
                     (guchar *)vals, 12);
 | 
			
		||||
#endif  /* HAVE_XDOCK */
 | 
			
		||||
    g_object_set (context, "visible", FALSE, NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
on_realize_set_dock (GtkWidget *widget,
 | 
			
		||||
                     gpointer   user_data)
 | 
			
		||||
{
 | 
			
		||||
    GtkAllocation allocation;
 | 
			
		||||
 | 
			
		||||
    gtk_widget_get_allocation (widget, &allocation);
 | 
			
		||||
    set_dock (widget, &allocation);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
on_size_allocate_set_dock (GtkWidget *widget,
 | 
			
		||||
                           GdkRectangle *allocation,
 | 
			
		||||
                           gpointer user_data)
 | 
			
		||||
{
 | 
			
		||||
    if (gtk_widget_get_realized (widget))
 | 
			
		||||
        set_dock (widget, allocation);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
on_realize_set_non_maximizable (GtkWidget            *widget,
 | 
			
		||||
                                ServerContextService *context)
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
    g_assert (context && context->window == widget);
 | 
			
		||||
 | 
			
		||||
    /* make the window not maximizable */
 | 
			
		||||
    gdk_window_set_functions (gtk_widget_get_window (widget),
 | 
			
		||||
                              GDK_FUNC_RESIZE |
 | 
			
		||||
                              GDK_FUNC_MOVE |
 | 
			
		||||
                              GDK_FUNC_MINIMIZE |
 | 
			
		||||
                              GDK_FUNC_CLOSE);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
set_geometry (ServerContextService *context)
 | 
			
		||||
@ -224,13 +149,6 @@ set_geometry (ServerContextService *context)
 | 
			
		||||
    gdk_monitor_get_geometry (monitor, &rect);
 | 
			
		||||
    eek_element_get_bounds (EEK_ELEMENT(keyboard), &bounds);
 | 
			
		||||
 | 
			
		||||
    g_signal_handlers_disconnect_by_func (context->window,
 | 
			
		||||
                                          on_realize_set_dock,
 | 
			
		||||
                                          context);
 | 
			
		||||
    g_signal_handlers_disconnect_by_func (context->window,
 | 
			
		||||
                                          on_realize_set_non_maximizable,
 | 
			
		||||
                                          context);
 | 
			
		||||
 | 
			
		||||
    if (eekboard_context_service_get_fullscreen (EEKBOARD_CONTEXT_SERVICE(context))) {
 | 
			
		||||
        gint width  = rect.width;
 | 
			
		||||
        gint height = rect.height;
 | 
			
		||||
@ -256,12 +174,6 @@ set_geometry (ServerContextService *context)
 | 
			
		||||
 | 
			
		||||
        gtk_window_set_decorated (GTK_WINDOW(context->window), FALSE);
 | 
			
		||||
        gtk_window_set_resizable (GTK_WINDOW(context->window), FALSE);
 | 
			
		||||
        g_signal_connect_after (context->window, "realize",
 | 
			
		||||
                                G_CALLBACK(on_realize_set_dock),
 | 
			
		||||
                                context);
 | 
			
		||||
        g_signal_connect_after (context->window, "size-allocate",
 | 
			
		||||
                                G_CALLBACK(on_size_allocate_set_dock),
 | 
			
		||||
                                context);
 | 
			
		||||
    } else {
 | 
			
		||||
        gtk_window_resize (GTK_WINDOW(context->window),
 | 
			
		||||
                           bounds.width,
 | 
			
		||||
@ -269,12 +181,10 @@ set_geometry (ServerContextService *context)
 | 
			
		||||
        gtk_window_move (GTK_WINDOW(context->window),
 | 
			
		||||
                         MAX(rect.width - 20 - bounds.width, 0),
 | 
			
		||||
                         MAX(rect.height - 40 - bounds.height, 0));
 | 
			
		||||
        g_signal_connect_after (context->window, "realize",
 | 
			
		||||
                                G_CALLBACK(on_realize_set_non_maximizable),
 | 
			
		||||
                                context);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#define KEYBOARD_HEIGHT 210
 | 
			
		||||
static void
 | 
			
		||||
make_window (ServerContextService *context)
 | 
			
		||||
{
 | 
			
		||||
@ -285,25 +195,22 @@ make_window (ServerContextService *context)
 | 
			
		||||
        PHOSH_TYPE_LAYER_SURFACE,
 | 
			
		||||
        "layer-shell", squeek_wayland->layer_shell,
 | 
			
		||||
        "wl-output", g_ptr_array_index(squeek_wayland->outputs, 0), // TODO: select output as needed,
 | 
			
		||||
        "height", 210,
 | 
			
		||||
        "height", KEYBOARD_HEIGHT,
 | 
			
		||||
        "anchor", ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM
 | 
			
		||||
                  | ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT
 | 
			
		||||
                  | ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT,
 | 
			
		||||
        "layer", ZWLR_LAYER_SHELL_V1_LAYER_TOP,
 | 
			
		||||
        "kbd-interactivity", FALSE,
 | 
			
		||||
        "exclusive-zone", 200,
 | 
			
		||||
        //"namespace", "phosh home",
 | 
			
		||||
        "exclusive-zone", KEYBOARD_HEIGHT,
 | 
			
		||||
        "namespace", "osk",
 | 
			
		||||
        NULL
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    g_signal_connect (context->window, "destroy",
 | 
			
		||||
                      G_CALLBACK(on_destroy),
 | 
			
		||||
                      context);
 | 
			
		||||
 | 
			
		||||
    context->notify_visible_handler =
 | 
			
		||||
        g_signal_connect (context->window, "notify::visible",
 | 
			
		||||
                          G_CALLBACK(on_notify_visible),
 | 
			
		||||
                          context);
 | 
			
		||||
    g_object_connect (context->window,
 | 
			
		||||
                      "signal::destroy", G_CALLBACK(on_destroy), context,
 | 
			
		||||
                      "signal::map", G_CALLBACK(on_notify_map), context,
 | 
			
		||||
                      "signal::unmap", G_CALLBACK(on_notify_unmap), context,
 | 
			
		||||
                      NULL);
 | 
			
		||||
 | 
			
		||||
    // The properties below are just to make hacking easier.
 | 
			
		||||
    // The way we use layer-shell overrides some,
 | 
			
		||||
@ -321,17 +228,18 @@ make_window (ServerContextService *context)
 | 
			
		||||
static void
 | 
			
		||||
destroy_window (ServerContextService *context)
 | 
			
		||||
{
 | 
			
		||||
    gtk_widget_destroy (GTK_WIDGET (context->window));
 | 
			
		||||
    context->window = NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
update_widget (ServerContextService *context)
 | 
			
		||||
make_widget (ServerContextService *context)
 | 
			
		||||
{
 | 
			
		||||
    EekKeyboard *keyboard;
 | 
			
		||||
    EekTheme *theme;
 | 
			
		||||
 | 
			
		||||
    if (context->widget) {
 | 
			
		||||
        gtk_widget_destroy (context->widget);
 | 
			
		||||
        gtk_widget_destroy(context->widget);
 | 
			
		||||
        context->widget = NULL;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -348,6 +256,7 @@ update_widget (ServerContextService *context)
 | 
			
		||||
 | 
			
		||||
    gtk_widget_set_has_tooltip (context->widget, TRUE);
 | 
			
		||||
    gtk_container_add (GTK_CONTAINER(context->window), context->widget);
 | 
			
		||||
    gtk_widget_show (context->widget);
 | 
			
		||||
    set_geometry (context);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -356,11 +265,14 @@ server_context_service_real_show_keyboard (EekboardContextService *_context)
 | 
			
		||||
{
 | 
			
		||||
    ServerContextService *context = SERVER_CONTEXT_SERVICE(_context);
 | 
			
		||||
 | 
			
		||||
    make_window (context);
 | 
			
		||||
    update_widget (context);
 | 
			
		||||
    if (!context->window)
 | 
			
		||||
        make_window (context);
 | 
			
		||||
    if (!context->widget)
 | 
			
		||||
        make_widget (context);
 | 
			
		||||
 | 
			
		||||
    EEKBOARD_CONTEXT_SERVICE_CLASS (server_context_service_parent_class)->
 | 
			
		||||
        show_keyboard (_context);
 | 
			
		||||
    gtk_widget_show (context->window);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
@ -369,34 +281,11 @@ server_context_service_real_hide_keyboard (EekboardContextService *_context)
 | 
			
		||||
    ServerContextService *context = SERVER_CONTEXT_SERVICE(_context);
 | 
			
		||||
 | 
			
		||||
    gtk_widget_hide (context->window);
 | 
			
		||||
    g_clear_pointer (&context->widget, gtk_widget_destroy);
 | 
			
		||||
 | 
			
		||||
    destroy_window (context);
 | 
			
		||||
 | 
			
		||||
    EEKBOARD_CONTEXT_SERVICE_CLASS (server_context_service_parent_class)->
 | 
			
		||||
        hide_keyboard (_context);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
server_context_service_real_enabled (EekboardContextService *_context)
 | 
			
		||||
{
 | 
			
		||||
    ServerContextService *context = SERVER_CONTEXT_SERVICE(_context);
 | 
			
		||||
 | 
			
		||||
    if (context->was_visible && context->window)
 | 
			
		||||
        gtk_widget_show_all (context->window);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
server_context_service_real_disabled (EekboardContextService *_context)
 | 
			
		||||
{
 | 
			
		||||
    ServerContextService *context = SERVER_CONTEXT_SERVICE(_context);
 | 
			
		||||
 | 
			
		||||
    if (context->window) {
 | 
			
		||||
        context->was_visible = gtk_widget_get_visible (context->window);
 | 
			
		||||
        gtk_widget_hide (context->window);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
server_context_service_real_destroyed (EekboardContextService *_context)
 | 
			
		||||
{
 | 
			
		||||
@ -436,7 +325,7 @@ server_context_service_dispose (GObject *object)
 | 
			
		||||
{
 | 
			
		||||
    ServerContextService *context = SERVER_CONTEXT_SERVICE(object);
 | 
			
		||||
 | 
			
		||||
    g_clear_pointer (&context->window, gtk_widget_destroy);
 | 
			
		||||
    destroy_window (context);
 | 
			
		||||
    context->widget = NULL;
 | 
			
		||||
 | 
			
		||||
    G_OBJECT_CLASS (server_context_service_parent_class)->dispose (object);
 | 
			
		||||
@ -451,8 +340,6 @@ server_context_service_class_init (ServerContextServiceClass *klass)
 | 
			
		||||
 | 
			
		||||
    context_class->show_keyboard = server_context_service_real_show_keyboard;
 | 
			
		||||
    context_class->hide_keyboard = server_context_service_real_hide_keyboard;
 | 
			
		||||
    context_class->enabled = server_context_service_real_enabled;
 | 
			
		||||
    context_class->disabled = server_context_service_real_disabled;
 | 
			
		||||
    context_class->destroyed = server_context_service_real_destroyed;
 | 
			
		||||
 | 
			
		||||
    gobject_class->set_property = server_context_service_set_property;
 | 
			
		||||
 | 
			
		||||
@ -23,13 +23,7 @@
 | 
			
		||||
#include <gtk/gtk.h>
 | 
			
		||||
#include <glib/gi18n.h>
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_CONFIG_H
 | 
			
		||||
#include "config.h"
 | 
			
		||||
#endif  /* HAVE_CONFIG_H */
 | 
			
		||||
 | 
			
		||||
#if HAVE_CLUTTER_GTK
 | 
			
		||||
#include <clutter-gtk/clutter-gtk.h>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include "eekboard/eekboard-service.h"
 | 
			
		||||
#include "eek/eek.h"
 | 
			
		||||
 | 
			
		||||
@ -30,16 +30,15 @@ test_create (void)
 | 
			
		||||
    section = eek_keyboard_create_section (keyboard);
 | 
			
		||||
    g_assert (EEK_IS_SECTION(section));
 | 
			
		||||
    eek_section_add_row (section, 2, EEK_ORIENTATION_HORIZONTAL);
 | 
			
		||||
    key0 = eek_section_create_key (section, 1, 0, 0);
 | 
			
		||||
    key0 = eek_section_create_key (section, "key0", 1, 0, 0);
 | 
			
		||||
    g_assert (EEK_IS_KEY(key0));
 | 
			
		||||
    key1 = eek_section_create_key (section, 2, 1, 0);
 | 
			
		||||
    key1 = eek_section_create_key (section, "key1", 2, 1, 0);
 | 
			
		||||
    g_assert (EEK_IS_KEY(key1));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
main (int argc, char **argv)
 | 
			
		||||
{
 | 
			
		||||
    g_type_init ();
 | 
			
		||||
    g_test_init (&argc, &argv, NULL);
 | 
			
		||||
    g_test_add_func ("/eek-simple-test/create", test_create);
 | 
			
		||||
    return g_test_run ();
 | 
			
		||||
 | 
			
		||||
@ -21,9 +21,7 @@
 | 
			
		||||
/* For gdk_x11_display_get_xdisplay().  See main(). */
 | 
			
		||||
#include <gtk/gtk.h>
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_CONFIG_H
 | 
			
		||||
#include "config.h"
 | 
			
		||||
#endif  /* HAVE_CONFIG_H */
 | 
			
		||||
 | 
			
		||||
#include "eek/eek.h"
 | 
			
		||||
 | 
			
		||||
@ -38,7 +36,9 @@ test_output_parse (void)
 | 
			
		||||
    layout = eek_xml_layout_new ("us", &error);
 | 
			
		||||
    g_assert_no_error (error);
 | 
			
		||||
 | 
			
		||||
    keyboard = eek_keyboard_new (layout, 640, 480);
 | 
			
		||||
    /* We don't need the context service to parse an XML file, so we can pass
 | 
			
		||||
       NULL when creating a keyboard. */
 | 
			
		||||
    keyboard = eek_keyboard_new (NULL, layout, 640, 480);
 | 
			
		||||
    g_object_unref (layout);
 | 
			
		||||
    g_object_unref (keyboard);
 | 
			
		||||
}
 | 
			
		||||
@ -46,7 +46,6 @@ test_output_parse (void)
 | 
			
		||||
int
 | 
			
		||||
main (int argc, char **argv)
 | 
			
		||||
{
 | 
			
		||||
    g_type_init ();
 | 
			
		||||
    g_test_init (&argc, &argv, NULL);
 | 
			
		||||
    gtk_init (&argc, &argv);  /* for gdk_x11_display_get_xdisplay() */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										49
									
								
								tests/meson.build
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										49
									
								
								tests/meson.build
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,49 @@
 | 
			
		||||
if get_option('tests')
 | 
			
		||||
 | 
			
		||||
test_env = [
 | 
			
		||||
  'G_TEST_SRCDIR=@0@'.format(meson.current_source_dir()),
 | 
			
		||||
  'G_TEST_BUILDDIR=@0@'.format(meson.current_build_dir()),
 | 
			
		||||
  'G_DEBUG=gc-friendly,fatal-warnings',
 | 
			
		||||
  'GSETTINGS_BACKEND=memory',
 | 
			
		||||
  'MALLOC_CHECK_=2'
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
test_cflags = [
 | 
			
		||||
  '-I@0@/../src'.format(meson.current_source_dir()),
 | 
			
		||||
  '-I@0@/../src'.format(meson.current_build_dir()),
 | 
			
		||||
  '-DEEK_COMPILATION',
 | 
			
		||||
  '-DEEKBOARD_COMPILATION'
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
test_link_args = [
 | 
			
		||||
  '-fPIC',
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
tests = [
 | 
			
		||||
  'eek-simple-test',
 | 
			
		||||
  'eek-xml-test'
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
foreach name : tests
 | 
			
		||||
 | 
			
		||||
    test_sources = [name + '.c']
 | 
			
		||||
 | 
			
		||||
    t = executable(
 | 
			
		||||
        name,
 | 
			
		||||
        test_sources,
 | 
			
		||||
        squeekboard_resources,
 | 
			
		||||
        link_with: libsqueekboard,
 | 
			
		||||
        c_args : test_cflags,
 | 
			
		||||
        link_args: test_link_args,
 | 
			
		||||
        dependencies: deps,       # from src/meson.build
 | 
			
		||||
        include_directories: [
 | 
			
		||||
            include_directories('..'),
 | 
			
		||||
            include_directories('../eek')
 | 
			
		||||
        ]
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
    test(name, t, env: test_env)
 | 
			
		||||
 | 
			
		||||
endforeach
 | 
			
		||||
 | 
			
		||||
endif
 | 
			
		||||
		Reference in New Issue
	
	Block a user