Compare commits
	
		
			201 Commits
		
	
	
		
			eekboard-1
			...
			implement-
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 0d769838b1 | |||
| ab3bc3fb06 | |||
| 83dafd87a4 | |||
| 25a8733957 | |||
| c529e9ed9c | |||
| d6a8a85b5e | |||
| 3a945535f7 | |||
| 0fc4374193 | |||
| e350b4ab92 | |||
| 626527ee09 | |||
| c4a462c385 | |||
| 706a04dbfc | |||
| 7fd51af4de | |||
| c1af9b2ba4 | |||
| 5efb4cc58d | |||
| 4b2977d601 | |||
| 2f1c1c2fb1 | |||
| f47ef09a1f | |||
| 47041b0fac | |||
| b6111b5e00 | |||
| b8a2b2d7c8 | |||
| 0765ea1b86 | |||
| 64223704e0 | |||
| 8c14763ea4 | |||
| 10cd93022a | |||
| d006aede6a | |||
| b57e1ce660 | |||
| 1b59c4dad3 | |||
| 189c721d7e | |||
| 1ff1592f24 | |||
| 7f5f310bf0 | |||
| f999861228 | |||
| a571bd7dca | |||
| 3d0d28fa01 | |||
| 4c54b49ef5 | |||
| eb940bcf52 | |||
| be0e773879 | |||
| 056e07e80e | |||
| 83b36d07d0 | |||
| 89aaf05aff | |||
| 2f87fd46fb | |||
| e04276ee38 | |||
| 05c3061f08 | |||
| c33006bcbc | |||
| 4bf4500ae1 | |||
| e2944ff4a7 | |||
| f79b5dadbb | |||
| 4d44129b04 | |||
| b3e1d84e6c | |||
| 6702edaa9d | |||
| a3a6e5933a | |||
| 66ec95ebb0 | |||
| a944bf85b8 | |||
| 1d1829f664 | |||
| 094aa872ce | |||
| eaf925e30b | |||
| 722d3d1ad4 | |||
| b69b3e9409 | |||
| ae5eaeec93 | |||
| c393eb20be | |||
| 0e8715b4ff | |||
| b09c812579 | |||
| d6f7c271e2 | |||
| f1d97e396b | |||
| abf8f4daa8 | |||
| aba242301d | |||
| 7a52080940 | |||
| c3ffe6ab8b | |||
| 851a9185c0 | |||
| c1e1ddb73f | |||
| d530c1d6d6 | |||
| 43579b51f0 | |||
| 3d1133cdb5 | |||
| e27af9fd24 | |||
| a7c6597246 | |||
| fd6d873c01 | |||
| 89dee04cdf | |||
| 3b0a073964 | |||
| a129863a4d | |||
| 5b700f7dfc | |||
| d982bcb5e4 | |||
| 61a5e8d4fd | |||
| cb641bd221 | |||
| 2f6e9a1756 | |||
| 51b183a0f3 | |||
| d071bb04af | |||
| 14887f9c99 | |||
| 654909261e | |||
| ab2a27345d | |||
| 484eb3303c | |||
| 319d64e1e5 | |||
| 60250ca5e5 | |||
| d729bb3a89 | |||
| 4dc55635d7 | |||
| 4af49ef7b6 | |||
| 3a42e66504 | |||
| 250b196b81 | |||
| 9ba1987cab | |||
| 909b1e2a28 | |||
| e46af41abf | |||
| 17671a3b08 | |||
| b8eb7752e7 | |||
| 5e92f45111 | |||
| baf848c791 | |||
| 737d57c1f4 | |||
| 9985ad7ee1 | |||
| 025b55e1a2 | |||
| 14fbabe8d7 | |||
| b746f7a70e | |||
| 0d3b003aac | |||
| 9428927879 | |||
| 511b2f7186 | |||
| d8c83e3c65 | |||
| 050fd6f3ba | |||
| 72d6a8d4e1 | |||
| 30d35216f6 | |||
| bcd0d40912 | |||
| 4b8a6bbbe0 | |||
| 47026b669b | |||
| 752dc467a8 | |||
| bde45b262a | |||
| fc338f5723 | |||
| 346ed453ef | |||
| 664f05edba | |||
| edcff44f4b | |||
| 42ee5d2ddb | |||
| 54e421d7e6 | |||
| 9e5629d1e0 | |||
| c0fdffac28 | |||
| e94e64d204 | |||
| e503e35b84 | |||
| 752592a3d8 | |||
| 2e6d194a6f | |||
| 63dfb07b51 | |||
| 02525056d6 | |||
| 8292429648 | |||
| 765c496068 | |||
| d6feec8010 | |||
| f1fbb37547 | |||
| 5a6386dd24 | |||
| 0809db9e32 | |||
| 15a3315854 | |||
| 82d1f256b2 | |||
| e7ba2a0eb0 | |||
| eff0449b3a | |||
| 3b9e066ec8 | |||
| 260ab42b9e | |||
| a3d745edd0 | |||
| 40a92fe730 | |||
| e30bb23711 | |||
| 292c1d08d8 | |||
| be56447614 | |||
| 70fda8ba64 | |||
| 5cc407986b | |||
| 53af829f46 | |||
| 53065a6d95 | |||
| 862cfdb55d | |||
| b065b16bf1 | |||
| 6ff33b48d1 | |||
| d04020f79c | |||
| 6b15072764 | |||
| f261115ac4 | |||
| 116f130c4c | |||
| cad1b02482 | |||
| 09fe69f63a | |||
| 8ecd81d51c | |||
| 8f71b010cc | |||
| b817c6189d | |||
| a00d41930d | |||
| caee942796 | |||
| d3410fdc61 | |||
| 8087c3e5d4 | |||
| 10bd0ea09e | |||
| 5803222e68 | |||
| a243fce1ae | |||
| c8059ebf50 | |||
| ce2d270e7c | |||
| 0c945bdc7e | |||
| 60ec684853 | |||
| b159625e62 | |||
| e212262f29 | |||
| c71167d893 | |||
| 2d4e4c7a13 | |||
| 695f8df5b8 | |||
| 2e822cb6a6 | |||
| f2a90935a3 | |||
| cee741eca0 | |||
| b5b59e77d6 | |||
| cce883808e | |||
| 8faae7ef08 | |||
| 4538ef38a1 | |||
| ee12d02402 | |||
| 7050fa41a0 | |||
| 4a346211b8 | |||
| 4df2ecc8ae | |||
| 03995ec6b2 | |||
| 6059146b42 | |||
| 30811ae656 | |||
| b8015bbef5 | |||
| 157d7c57fd | |||
| 03963036d1 | 
							
								
								
									
										84
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										84
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							@ -1,84 +0,0 @@
 | 
			
		||||
*.la
 | 
			
		||||
*.lo
 | 
			
		||||
*.loT
 | 
			
		||||
*.o
 | 
			
		||||
*.so
 | 
			
		||||
*~
 | 
			
		||||
*.pyc
 | 
			
		||||
Makefile
 | 
			
		||||
Makefile.in
 | 
			
		||||
.deps
 | 
			
		||||
.libs
 | 
			
		||||
INSTALL
 | 
			
		||||
aclocal.m4
 | 
			
		||||
autom4te.cache
 | 
			
		||||
compile
 | 
			
		||||
config.guess
 | 
			
		||||
config.h
 | 
			
		||||
config.h.in
 | 
			
		||||
config.log
 | 
			
		||||
config.rpath
 | 
			
		||||
config.status
 | 
			
		||||
config.sub
 | 
			
		||||
configure
 | 
			
		||||
depcomp
 | 
			
		||||
install-sh
 | 
			
		||||
libtool
 | 
			
		||||
ltmain.sh
 | 
			
		||||
missing
 | 
			
		||||
stamp-h1
 | 
			
		||||
libkeyactor*.tar.*
 | 
			
		||||
mkinstalldirs
 | 
			
		||||
m4/*.m4
 | 
			
		||||
gtk-doc.make
 | 
			
		||||
eek/eek-special-keysym-entries.h
 | 
			
		||||
eek/eek-unicode-keysym-entries.h
 | 
			
		||||
eek/eek-xkeysym-keysym-entries.h
 | 
			
		||||
eek/eek-enumtypes.[ch]
 | 
			
		||||
eek/eek-marshalers.[ch]
 | 
			
		||||
eek/*.pc
 | 
			
		||||
eek/*.gir
 | 
			
		||||
eek/*.typelib
 | 
			
		||||
eekboard/*.pc
 | 
			
		||||
eekboard/*.gir
 | 
			
		||||
eekboard/*.typelib
 | 
			
		||||
eekboard/eekboard-marshalers.[ch]
 | 
			
		||||
tests/eek-simple-test
 | 
			
		||||
tests/eek-xkb-test
 | 
			
		||||
tests/eek-xml-test
 | 
			
		||||
src/eekboard
 | 
			
		||||
src/eekboard-server
 | 
			
		||||
docs/reference/eek/*.stamp
 | 
			
		||||
docs/reference/eek/*.txt
 | 
			
		||||
docs/reference/eek/eek.types
 | 
			
		||||
!/docs/reference/eek/eek-sections.txt
 | 
			
		||||
docs/reference/eek/xml
 | 
			
		||||
docs/reference/eek/html
 | 
			
		||||
docs/reference/eek/eek.signals
 | 
			
		||||
docs/reference/eek/eek.args
 | 
			
		||||
docs/reference/eek/eek.hierarchy
 | 
			
		||||
docs/reference/eek/eek.interfaces
 | 
			
		||||
docs/reference/eek/eek.prerequisites
 | 
			
		||||
docs/reference/eekboard/*.stamp
 | 
			
		||||
docs/reference/eekboard/*.txt
 | 
			
		||||
!/docs/reference/eekboard/eekboard-sections.txt
 | 
			
		||||
docs/reference/eekboard/xml
 | 
			
		||||
docs/reference/eekboard/html
 | 
			
		||||
docs/reference/eekboard/eekboard.signals
 | 
			
		||||
docs/reference/eekboard/eekboard.args
 | 
			
		||||
docs/reference/eekboard/eekboard.hierarchy
 | 
			
		||||
docs/reference/eekboard/eekboard.interfaces
 | 
			
		||||
docs/reference/eekboard/eekboard.prerequisites
 | 
			
		||||
po/*.gmo
 | 
			
		||||
po/Makefile.in.in
 | 
			
		||||
po/POTFILES
 | 
			
		||||
po/stamp-it
 | 
			
		||||
po/.intltool-merge-cache
 | 
			
		||||
bindings/vala/*.vapi
 | 
			
		||||
py-compile
 | 
			
		||||
data/org.fedorahosted.eekboard.gschema.xml
 | 
			
		||||
data/org.fedorahosted.eekboard.gschema.valid
 | 
			
		||||
data/eekboard-server.service
 | 
			
		||||
data/*.desktop
 | 
			
		||||
examples/eekxml/eekxml
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										17
									
								
								.gitlab-ci.yml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								.gitlab-ci.yml
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,17 @@
 | 
			
		||||
image: debian:buster
 | 
			
		||||
 | 
			
		||||
stages:
 | 
			
		||||
  - build
 | 
			
		||||
 | 
			
		||||
before_script:
 | 
			
		||||
  - apt-get -y update
 | 
			
		||||
  - apt-get -y build-dep .
 | 
			
		||||
 | 
			
		||||
build_meson:
 | 
			
		||||
  stage: build
 | 
			
		||||
  tags:
 | 
			
		||||
    - librem5
 | 
			
		||||
  script:
 | 
			
		||||
    - meson . _build/ -Ddepdatadir=/usr/share
 | 
			
		||||
    - ninja -C _build install
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										21
									
								
								Makefile.am
									
									
									
									
									
								
							
							
						
						
									
										21
									
								
								Makefile.am
									
									
									
									
									
								
							@ -1,21 +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
 | 
			
		||||
 | 
			
		||||
ACLOCAL_AMFLAGS = -I m4
 | 
			
		||||
SUBDIRS = eek eekboard src tests bindings docs po data examples
 | 
			
		||||
DISTCHECK_CONFIGURE_FLAGS = --enable-gtk-doc --enable-introspection
 | 
			
		||||
							
								
								
									
										35
									
								
								README
									
									
									
									
									
								
							
							
						
						
									
										35
									
								
								README
									
									
									
									
									
								
							@ -1,35 +0,0 @@
 | 
			
		||||
eekboard - an easy to use virtual keyboard toolkit -*- outline -*-
 | 
			
		||||
 | 
			
		||||
eekboard is a virtual keyboard software package, including a set of
 | 
			
		||||
tools to implement desktop virtual keyboards.
 | 
			
		||||
 | 
			
		||||
* Building
 | 
			
		||||
 | 
			
		||||
** Dependencies
 | 
			
		||||
 | 
			
		||||
REQUIRED: GLib2, GTK, PangoCairo, libxklavier, libcroco
 | 
			
		||||
OPTIONAL: libXtst, at-spi2-core, IBus, Clutter, Clutter-Gtk, Python, Vala, gobject-introspection, libcanberra
 | 
			
		||||
 | 
			
		||||
** Build from git repo
 | 
			
		||||
 | 
			
		||||
  $ git clone git://github.com/ueno/eekboard.git
 | 
			
		||||
  $ cd eekboard
 | 
			
		||||
  $ ./autogen.sh --prefix=/usr --enable-gtk-doc
 | 
			
		||||
  $ make
 | 
			
		||||
  $ sudo make install
 | 
			
		||||
 | 
			
		||||
** Build from tarball
 | 
			
		||||
 | 
			
		||||
  $ ./configure --prefix=/usr
 | 
			
		||||
  $ make
 | 
			
		||||
  $ sudo make install
 | 
			
		||||
 | 
			
		||||
* Running
 | 
			
		||||
 | 
			
		||||
  $ eekboard
 | 
			
		||||
  $ eekboard -f # show/hide automatically based on focus-in/focus-out events
 | 
			
		||||
 | 
			
		||||
Even though eekboard -f watches a11y events by default, it currently
 | 
			
		||||
works better with IBus.  To use IBus, do:
 | 
			
		||||
 | 
			
		||||
  $ gsettings set org.fedorahosted.eekboard focus-listener 'ibus'
 | 
			
		||||
							
								
								
									
										68
									
								
								README.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										68
									
								
								README.md
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,68 @@
 | 
			
		||||
*squeekboard* - a Wayland virtual keyboard
 | 
			
		||||
========================================
 | 
			
		||||
 | 
			
		||||
*Squeekboard* is a virtual keyboard supporting Wayland, built primarily for the *Librem 5* phone.
 | 
			
		||||
 | 
			
		||||
Features
 | 
			
		||||
--------
 | 
			
		||||
 | 
			
		||||
### Present
 | 
			
		||||
 | 
			
		||||
- GTK3
 | 
			
		||||
- Custom xml-defined keyboards
 | 
			
		||||
- DBus interface to show and hide
 | 
			
		||||
 | 
			
		||||
### Temporarily dropped
 | 
			
		||||
 | 
			
		||||
- A settings interface
 | 
			
		||||
 | 
			
		||||
### TODO
 | 
			
		||||
 | 
			
		||||
- Use Wayland virtual keyboard protocol
 | 
			
		||||
- Use Wayland text input protocol
 | 
			
		||||
- Use Wayland input method protocol
 | 
			
		||||
- Pick up DBus interface files from /usr/share
 | 
			
		||||
 | 
			
		||||
Building
 | 
			
		||||
--------
 | 
			
		||||
 | 
			
		||||
### Dependencies
 | 
			
		||||
 | 
			
		||||
See `.gitlab-ci.yml`.
 | 
			
		||||
 | 
			
		||||
### Build from git repo
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
$ git clone https://source.puri.sm/Librem5/eekboard.git
 | 
			
		||||
$ cd eekboard
 | 
			
		||||
$ mkdir ../build
 | 
			
		||||
$ meson ../build/
 | 
			
		||||
$ cd ../build
 | 
			
		||||
$ ninja install
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
For development, alter the `meson` call:
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
$ meson ../build/ --prefix=../install
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
and don't skip `ninja install` before running. The last step is necessary in order to find the keyboard definition files.
 | 
			
		||||
 | 
			
		||||
Running
 | 
			
		||||
-------
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
$ rootston
 | 
			
		||||
$ cd ../build/
 | 
			
		||||
$ src/squeekboard
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
### Testing
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
$ busctl call --user sm.puri.OSK0 /sm/puri/OSK0 sm.puri.OSK0 SetVisible b true
 | 
			
		||||
$ busctl call --user sm.puri.OSK0 /sm/puri/OSK0 sm.puri.OSK0 SetVisible b false
 | 
			
		||||
$ gsettings set org.gnome.desktop.input-sources sources "[('xkb', 'us'), ('xkb', 'ua')]"
 | 
			
		||||
$ gsettings set org.gnome.desktop.input-sources current 1
 | 
			
		||||
```
 | 
			
		||||
@ -7,17 +7,12 @@ test -z "$srcdir" && srcdir=.
 | 
			
		||||
PKG_NAME="eekboard"
 | 
			
		||||
 | 
			
		||||
(test -f $srcdir/configure.ac \
 | 
			
		||||
  && test -f $srcdir/README ) || {
 | 
			
		||||
  && test -f $srcdir/README.md ) || {
 | 
			
		||||
    echo -n "**Error**: Directory "\`$srcdir\'" does not look like the"
 | 
			
		||||
    echo " top-level $PKG_NAME directory"
 | 
			
		||||
    exit 1
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
which gnome-autogen.sh || {
 | 
			
		||||
    echo "You need to install gnome-common from the GNOME CVS"
 | 
			
		||||
    exit 1
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ACLOCAL_FLAGS="$ACLOCAL_FLAGS -I m4"
 | 
			
		||||
REQUIRED_AUTOMAKE_VERSION=1.10
 | 
			
		||||
REQUIRED_AUTOCONF_VERSION=2.60
 | 
			
		||||
 | 
			
		||||
@ -1,19 +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
 | 
			
		||||
 | 
			
		||||
SUBDIRS = vala
 | 
			
		||||
@ -1,83 +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 ENABLE_VALA
 | 
			
		||||
vapidir = $(datadir)/vala/vapi
 | 
			
		||||
dist_vapi_DATA =				\
 | 
			
		||||
	eek-$(EEK_API_VERSION).vapi		\
 | 
			
		||||
	eek-$(EEK_API_VERSION).deps		\
 | 
			
		||||
	eek-gtk-$(EEK_API_VERSION).vapi		\
 | 
			
		||||
	eek-gtk-$(EEK_API_VERSION).deps		\
 | 
			
		||||
	eek-xkl-$(EEK_API_VERSION).vapi		\
 | 
			
		||||
	eek-xkl-$(EEK_API_VERSION).deps		\
 | 
			
		||||
	$(NULL)
 | 
			
		||||
 | 
			
		||||
EXTRA_DIST =					\
 | 
			
		||||
	Eek-$(EEK_API_VERSION).metadata		\
 | 
			
		||||
	EekGtk-$(EEK_API_VERSION).metadata	\
 | 
			
		||||
	EekXkl-$(EEK_API_VERSION).metadata	\
 | 
			
		||||
	$(NULL)
 | 
			
		||||
 | 
			
		||||
maintainer-clean-local:
 | 
			
		||||
	rm -f *.vapi
 | 
			
		||||
 | 
			
		||||
eek_vapi_deps =						\
 | 
			
		||||
	$(srcdir)/Eek-$(EEK_API_VERSION).metadata	\
 | 
			
		||||
	|						\
 | 
			
		||||
	$(top_srcdir)/eek/Eek-$(EEK_API_VERSION).gir	\
 | 
			
		||||
	$(NULL)
 | 
			
		||||
 | 
			
		||||
eek-$(EEK_API_VERSION).vapi: $(eek_vapi_deps)
 | 
			
		||||
	$(VAPIGEN_V)$(VAPIGEN)					\
 | 
			
		||||
		--library eek-$(EEK_API_VERSION)		\
 | 
			
		||||
		--pkg gio-2.0					\
 | 
			
		||||
		--metadatadir=$(srcdir)				\
 | 
			
		||||
		$(top_srcdir)/eek/Eek-$(EEK_API_VERSION).gir
 | 
			
		||||
 | 
			
		||||
eek_gtk_vapi_deps =					\
 | 
			
		||||
	$(srcdir)/EekGtk-$(EEK_API_VERSION).metadata	\
 | 
			
		||||
	|						\
 | 
			
		||||
	$(top_srcdir)/eek/EekGtk-$(EEK_API_VERSION).gir	\
 | 
			
		||||
	$(NULL)
 | 
			
		||||
 | 
			
		||||
eek-gtk-$(EEK_API_VERSION).vapi: $(eek_gtk_vapi_deps)
 | 
			
		||||
	$(VAPIGEN_V)$(VAPIGEN) --vapidir=$(builddir)		\
 | 
			
		||||
		--library eek-gtk-$(EEK_API_VERSION)		\
 | 
			
		||||
		--pkg eek-$(EEK_API_VERSION)			\
 | 
			
		||||
		--pkg gtk+-3.0					\
 | 
			
		||||
		--metadatadir=$(srcdir)				\
 | 
			
		||||
		$(top_srcdir)/eek/EekGtk-$(EEK_API_VERSION).gir
 | 
			
		||||
 | 
			
		||||
eek_xkl_vapi_deps =					\
 | 
			
		||||
	$(srcdir)/EekXkl-$(EEK_API_VERSION).metadata	\
 | 
			
		||||
	|						\
 | 
			
		||||
	$(top_srcdir)/eek/EekXkl-$(EEK_API_VERSION).gir	\
 | 
			
		||||
	$(NULL)
 | 
			
		||||
 | 
			
		||||
eek-xkl-$(EEK_API_VERSION).vapi: $(eek_xkl_vapi_deps)
 | 
			
		||||
	$(VAPIGEN_V)$(VAPIGEN) --vapidir=$(builddir)		\
 | 
			
		||||
		--library eek-xkl-$(EEK_API_VERSION)		\
 | 
			
		||||
		--pkg eek-$(EEK_API_VERSION)			\
 | 
			
		||||
		--metadatadir=$(srcdir)				\
 | 
			
		||||
		$(top_srcdir)/eek/EekXkl-$(EEK_API_VERSION).gir
 | 
			
		||||
 | 
			
		||||
# set up the verbosity rules to avoid some build noise
 | 
			
		||||
VAPIGEN_V = $(VAPIGEN_V_$(V))
 | 
			
		||||
VAPIGEN_V_ = $(VAPIGEN_V_$(AM_DEFAULT_VERBOSITY))
 | 
			
		||||
VAPIGEN_V_0 = @echo "  VAPIG " $@;
 | 
			
		||||
endif
 | 
			
		||||
@ -1 +1,2 @@
 | 
			
		||||
eek-0.90
 | 
			
		||||
x11
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										245
									
								
								configure.ac
									
									
									
									
									
								
							
							
						
						
									
										245
									
								
								configure.ac
									
									
									
									
									
								
							@ -1,245 +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
 | 
			
		||||
 | 
			
		||||
AC_PREREQ(2.63)
 | 
			
		||||
dnl AC_CONFIG_SRCDIR([configure.ac])
 | 
			
		||||
AC_CONFIG_MACRO_DIR([m4])
 | 
			
		||||
 | 
			
		||||
AC_INIT([eekboard], [1.0.6], [ueno@unixuser.org])
 | 
			
		||||
 | 
			
		||||
dnl Init automake
 | 
			
		||||
AM_INIT_AUTOMAKE
 | 
			
		||||
AM_MAINTAINER_MODE([enable])
 | 
			
		||||
AC_GNU_SOURCE
 | 
			
		||||
 | 
			
		||||
dnl Support silent build
 | 
			
		||||
m4_ifdef([AM_SILENT_RULES],[AM_SILENT_RULES([yes])])
 | 
			
		||||
 | 
			
		||||
dnl Check for programs
 | 
			
		||||
AC_PROG_CC
 | 
			
		||||
AM_PROG_CC_C_O
 | 
			
		||||
AC_PROG_CC_STDC
 | 
			
		||||
AC_PROG_INSTALL
 | 
			
		||||
AC_PROG_CXX
 | 
			
		||||
 | 
			
		||||
# define PACKAGE_VERSION_* variables
 | 
			
		||||
AM_DISABLE_STATIC
 | 
			
		||||
AC_ISC_POSIX
 | 
			
		||||
AC_HEADER_STDC
 | 
			
		||||
LT_INIT
 | 
			
		||||
IT_PROG_INTLTOOL([0.35.0])
 | 
			
		||||
 | 
			
		||||
GTK_API_VERSION=3.0
 | 
			
		||||
GTK_REQUIRED=2.91.0
 | 
			
		||||
EEK_API_VERSION=0.90
 | 
			
		||||
EEK_API_MAJOR_VERSION=0
 | 
			
		||||
EEK_API_MINOR_VERSION=90
 | 
			
		||||
EEK_API_PC_VERSION=0.90
 | 
			
		||||
EEK_LIBRARY_SUFFIX="-$EEK_API_VERSION"
 | 
			
		||||
 | 
			
		||||
AC_SUBST([GTK_API_VERSION])
 | 
			
		||||
AC_SUBST([EEK_API_VERSION])
 | 
			
		||||
AC_SUBST([EEK_API_MAJOR_VERSION])
 | 
			
		||||
AC_SUBST([EEK_API_MINOR_VERSION])
 | 
			
		||||
AC_SUBST([EEK_API_PC_VERSION])
 | 
			
		||||
AC_SUBST([EEK_LIBRARY_SUFFIX])
 | 
			
		||||
AC_SUBST([EEK_LIBRARY_SUFFIX_U],[AS_TR_SH([$EEK_LIBRARY_SUFFIX])])
 | 
			
		||||
 | 
			
		||||
AM_PATH_GLIB_2_0
 | 
			
		||||
PKG_CHECK_MODULES([GLIB2], [glib-2.0 >= 2.26.0], ,
 | 
			
		||||
  [AC_MSG_ERROR([GLib2 not found])])
 | 
			
		||||
PKG_CHECK_MODULES([GIO2], [gio-2.0], ,
 | 
			
		||||
  [AC_MSG_ERROR([Gio2 not found])])
 | 
			
		||||
GLIB_GSETTINGS
 | 
			
		||||
 | 
			
		||||
PKG_CHECK_MODULES([PANGOCAIRO], [pangocairo], ,
 | 
			
		||||
  [AC_MSG_ERROR([PangoCairo not found])])
 | 
			
		||||
PKG_CHECK_MODULES([GTK], [
 | 
			
		||||
  gtk+-$GTK_API_VERSION >= $GTK_REQUIRED
 | 
			
		||||
  gdk-$GTK_API_VERSION >= $GTK_REQUIRED], ,
 | 
			
		||||
  [AC_MSG_ERROR([GTK not found])])
 | 
			
		||||
PKG_CHECK_MODULES([LIBXKLAVIER], [libxklavier x11], ,
 | 
			
		||||
  [AC_MSG_ERROR([Libxklavier not found])])
 | 
			
		||||
PKG_CHECK_MODULES([LIBCROCO], [libcroco-0.6], ,
 | 
			
		||||
  [AC_MSG_ERROR([libcroco not found])])
 | 
			
		||||
 | 
			
		||||
dnl use XTest to generate key events
 | 
			
		||||
AC_MSG_CHECKING([whether you enable XTest])
 | 
			
		||||
AC_ARG_ENABLE(xtest,
 | 
			
		||||
              AS_HELP_STRING([--enable-xtest=no/yes],
 | 
			
		||||
                             [Enable XTest default=yes]),
 | 
			
		||||
              enable_xtest=$enableval,
 | 
			
		||||
              enable_xtest=yes)
 | 
			
		||||
 | 
			
		||||
if test x$enable_xtest = xyes; then
 | 
			
		||||
  PKG_CHECK_MODULES([XTEST], [xtst], , enable_xtest=no)
 | 
			
		||||
  if test x$enable_xtest = xyes; then
 | 
			
		||||
    AC_DEFINE([HAVE_XTEST], [1], [Define if XTest is found])
 | 
			
		||||
  fi
 | 
			
		||||
fi
 | 
			
		||||
AM_CONDITIONAL(ENABLE_XTEST, [test x$enable_xtest = xyes])
 | 
			
		||||
AC_MSG_RESULT($enable_xtest)
 | 
			
		||||
 | 
			
		||||
dnl use X to mark the fullscreen window as dock
 | 
			
		||||
AC_MSG_CHECKING([whether you enable X dock])
 | 
			
		||||
AC_ARG_ENABLE(x-dock,
 | 
			
		||||
              AS_HELP_STRING([--enable-x-dock=no/yes],
 | 
			
		||||
                             [Enable X dock default=yes]),
 | 
			
		||||
              enable_x_dock=$enableval,
 | 
			
		||||
              enable_x_dock=yes)
 | 
			
		||||
 | 
			
		||||
if test x$enable_x_dock = xyes; then
 | 
			
		||||
  PKG_CHECK_MODULES([XDOCK], [x11], , enable_x_dock=no)
 | 
			
		||||
  if test x$enable_x_dock = xyes; then
 | 
			
		||||
    AC_DEFINE([HAVE_XDOCK], [1], [Define if X dock is found])
 | 
			
		||||
  fi
 | 
			
		||||
fi
 | 
			
		||||
AM_CONDITIONAL(ENABLE_XDOCK, [test x$enable_x_dock = xyes])
 | 
			
		||||
AC_MSG_RESULT($enable_x_dock)
 | 
			
		||||
 | 
			
		||||
focus_listeners="ibus"
 | 
			
		||||
keystroke_listeners=""
 | 
			
		||||
 | 
			
		||||
dnl use AT-SPI 2 to capture focus/keystroke events
 | 
			
		||||
AC_MSG_CHECKING([whether you enable AT-SPI 2 event handling])
 | 
			
		||||
AC_ARG_ENABLE(atspi,
 | 
			
		||||
              AS_HELP_STRING([--enable-atspi=no/yes],
 | 
			
		||||
                             [Enable AT-SPI 2 event handling default=yes]),
 | 
			
		||||
              enable_atspi=$enableval,
 | 
			
		||||
              enable_atspi=yes)
 | 
			
		||||
 | 
			
		||||
if test x$enable_atspi = xyes; then
 | 
			
		||||
  PKG_CHECK_MODULES([ATSPI2], [atspi-2 dbus-glib-1], , enable_atspi=no)
 | 
			
		||||
  if test x$enable_atspi = xyes; then
 | 
			
		||||
    AC_DEFINE([HAVE_ATSPI], [1], [Define if AT-SPI 2 is found])
 | 
			
		||||
    focus_listeners="atspi $focus_listeners"
 | 
			
		||||
    keystroke_listeners="atspi $keystroke_listeners"
 | 
			
		||||
  fi
 | 
			
		||||
fi
 | 
			
		||||
AC_MSG_RESULT($enable_atspi)
 | 
			
		||||
AM_CONDITIONAL(ENABLE_ATSPI, [test x$enable_atspi = xyes])
 | 
			
		||||
 | 
			
		||||
if test -n "$focus_listeners"; then
 | 
			
		||||
  AC_DEFINE(ENABLE_FOCUS_LISTENER, [1], [Define if eekboard can follow focus changes])
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
GOBJECT_INTROSPECTION_CHECK([0.9.0])
 | 
			
		||||
 | 
			
		||||
dnl Vala langauge binding
 | 
			
		||||
AC_MSG_CHECKING([whether you enable Vala language support])
 | 
			
		||||
AC_ARG_ENABLE(vala,
 | 
			
		||||
              AS_HELP_STRING([--enable-vala=no/yes],
 | 
			
		||||
                             [Enable Vala language binding default=yes]),
 | 
			
		||||
              enable_vala=$enableval,
 | 
			
		||||
              enable_vala=yes)
 | 
			
		||||
if test x$enable_vala = xyes; then
 | 
			
		||||
  if test "x$INTROSPECTION_SCANNER" = x; then
 | 
			
		||||
    enable_vala=no
 | 
			
		||||
    AC_MSG_WARN([GObject-Introspection must be enabled for Vala bindings])
 | 
			
		||||
  fi
 | 
			
		||||
 | 
			
		||||
  AM_PROG_VALAC([0.10.0])
 | 
			
		||||
  have_vala=yes
 | 
			
		||||
 | 
			
		||||
  AC_PATH_PROG(VALAC, valac, valac)
 | 
			
		||||
  AC_SUBST(VALAC)
 | 
			
		||||
  AC_SUBST(VALAFLAGS)
 | 
			
		||||
 | 
			
		||||
  AC_PATH_PROG([VAPIGEN], [vapigen], [false])
 | 
			
		||||
 | 
			
		||||
  if test "x$VAPIGEN" = "xfalse"; then
 | 
			
		||||
    enable_vala=no
 | 
			
		||||
    AC_MSG_WARN([vapigen not found. Was vala compiled with --enable-vapigen?])
 | 
			
		||||
  fi
 | 
			
		||||
 | 
			
		||||
  AC_SUBST(VAPIGEN)
 | 
			
		||||
fi
 | 
			
		||||
AC_MSG_RESULT($enable_vala)
 | 
			
		||||
AM_CONDITIONAL(ENABLE_VALA, [test x$enable_vala = xyes])
 | 
			
		||||
 | 
			
		||||
dnl libcanberra
 | 
			
		||||
AC_MSG_CHECKING([whether you enable libcanberra])
 | 
			
		||||
AC_ARG_ENABLE(libcanberra,
 | 
			
		||||
              AS_HELP_STRING([--enable-libcanberra=no/yes],
 | 
			
		||||
                             [Enable libcanberra user interface default=no]),
 | 
			
		||||
              enable_libcanberra=$enableval,
 | 
			
		||||
              enable_libcanberra=yes)
 | 
			
		||||
 | 
			
		||||
if test x$enable_libcanberra = xyes; then
 | 
			
		||||
  PKG_CHECK_MODULES([LIBCANBERRA], [libcanberra-gtk3], , enable_libcanberra=no)
 | 
			
		||||
  if test x$enable_libcanberra = xyes; then
 | 
			
		||||
    AC_DEFINE([HAVE_LIBCANBERRA], [1], [Define if libcanberra is found])
 | 
			
		||||
  fi
 | 
			
		||||
fi
 | 
			
		||||
AM_CONDITIONAL(ENABLE_LIBCANBERRA, [test x$enable_libcanberra = xyes])
 | 
			
		||||
AC_MSG_RESULT($enable_libcanberra)
 | 
			
		||||
 | 
			
		||||
GTK_DOC_CHECK([1.14],[--flavour no-tmpl])
 | 
			
		||||
 | 
			
		||||
dnl define GETTEXT_* variables
 | 
			
		||||
GETTEXT_PACKAGE=$PACKAGE
 | 
			
		||||
AC_SUBST(GETTEXT_PACKAGE)
 | 
			
		||||
AC_DEFINE_UNQUOTED(GETTEXT_PACKAGE,"$GETTEXT_PACKAGE", [Define to the read-only architecture-independent data directory.])
 | 
			
		||||
AM_GLIB_GNU_GETTEXT
 | 
			
		||||
AM_GLIB_DEFINE_LOCALEDIR(EEKBOARD_LOCALEDIR)
 | 
			
		||||
 | 
			
		||||
AC_CONFIG_HEADERS([config.h])
 | 
			
		||||
AC_CONFIG_FILES([Makefile
 | 
			
		||||
eek/Makefile
 | 
			
		||||
eekboard/Makefile
 | 
			
		||||
src/Makefile
 | 
			
		||||
tests/Makefile
 | 
			
		||||
bindings/Makefile
 | 
			
		||||
bindings/vala/Makefile
 | 
			
		||||
docs/Makefile
 | 
			
		||||
docs/reference/Makefile
 | 
			
		||||
docs/reference/eek/Makefile
 | 
			
		||||
docs/reference/eekboard/Makefile
 | 
			
		||||
po/Makefile.in
 | 
			
		||||
data/Makefile
 | 
			
		||||
data/icons/Makefile
 | 
			
		||||
data/icons/16x16/Makefile
 | 
			
		||||
data/icons/22x22/Makefile
 | 
			
		||||
data/icons/24x24/Makefile
 | 
			
		||||
data/icons/32x32/Makefile
 | 
			
		||||
data/icons/48x48/Makefile
 | 
			
		||||
data/icons/scalable/Makefile
 | 
			
		||||
data/themes/Makefile
 | 
			
		||||
data/keyboards/Makefile
 | 
			
		||||
examples/Makefile
 | 
			
		||||
examples/simple-client/Makefile
 | 
			
		||||
eek/eek-${EEK_API_VERSION}.pc
 | 
			
		||||
eek/eek-gtk-${EEK_API_VERSION}.pc
 | 
			
		||||
eek/eek-xkl-${EEK_API_VERSION}.pc
 | 
			
		||||
eekboard/eekboard-${EEK_API_VERSION}.pc])
 | 
			
		||||
AC_OUTPUT
 | 
			
		||||
AC_MSG_RESULT([
 | 
			
		||||
Build options:
 | 
			
		||||
  Version                   $VERSION
 | 
			
		||||
  Install prefix            $prefix
 | 
			
		||||
  Build shared libs         $enable_shared
 | 
			
		||||
  Build static libs         $enable_static
 | 
			
		||||
  CFLAGS                    $CFLAGS
 | 
			
		||||
  Build Vala binding        $enable_vala
 | 
			
		||||
  Sound support             $enable_libcanberra
 | 
			
		||||
  Build document            $enable_gtk_doc
 | 
			
		||||
  Focus listeners           $focus_listeners
 | 
			
		||||
  Keystroke listeners       $keystroke_listeners
 | 
			
		||||
])
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -1,34 +0,0 @@
 | 
			
		||||
SUBDIRS = icons themes keyboards
 | 
			
		||||
 | 
			
		||||
@GSETTINGS_RULES@
 | 
			
		||||
@INTLTOOL_XML_NOMERGE_RULE@
 | 
			
		||||
gsettings_schemas_in_files = org.fedorahosted.eekboard.gschema.xml.in
 | 
			
		||||
gsettings_SCHEMAS = $(gsettings_schemas_in_files:.gschema.xml.in=.gschema.xml)
 | 
			
		||||
 | 
			
		||||
servicedir       = $(datadir)/dbus-1/services
 | 
			
		||||
service_in_files = eekboard-server.service.in
 | 
			
		||||
service_DATA     = $(service_in_files:.service.in=.service)
 | 
			
		||||
 | 
			
		||||
$(service_DATA): $(service_in_files) Makefile
 | 
			
		||||
	$(AM_V_GEN) sed -e "s|\@bindir\@|$(bindir)|" $< > $@
 | 
			
		||||
 | 
			
		||||
desktopdir = $(datadir)/applications
 | 
			
		||||
desktop_in_files = eekboard.desktop.in
 | 
			
		||||
desktop_DATA = $(desktop_in_files:.desktop.in=.desktop)
 | 
			
		||||
 | 
			
		||||
if ENABLE_ATSPI
 | 
			
		||||
autostartdir	 = $(sysconfdir)/xdg/autostart
 | 
			
		||||
autostart_in_files = eekboard-autostart.desktop.in
 | 
			
		||||
autostart_DATA   = $(autostart_in_files:.desktop.in=.desktop)
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
@INTLTOOL_DESKTOP_RULE@
 | 
			
		||||
 | 
			
		||||
CLEANFILES = $(service_DATA) $(desktop_DATA) $(gsettings_SCHEMAS)
 | 
			
		||||
EXTRA_DIST = $(service_in_files) $(desktop_in_files) $(gsettings_schemas_in_files)
 | 
			
		||||
 | 
			
		||||
if ENABLE_ATSPI
 | 
			
		||||
CLEANFILES += $(autostart_DATA)
 | 
			
		||||
EXTRA_DIST += $(autostart_in_files)
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										20
									
								
								data/dbus/sm.puri.OSK0.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								data/dbus/sm.puri.OSK0.xml
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,20 @@
 | 
			
		||||
<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
 | 
			
		||||
"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
 | 
			
		||||
<node xmlns:doc="http://www.freedesktop.org/dbus/1.0/doc.dtd">
 | 
			
		||||
  <interface name="sm.puri.OSK0">
 | 
			
		||||
    <method name="SetVisible">
 | 
			
		||||
      <arg name="visible" type="b" direction="in"/>
 | 
			
		||||
      <doc:doc><doc:description>
 | 
			
		||||
        Switch keyboard visibility
 | 
			
		||||
      </doc:description></doc:doc>
 | 
			
		||||
    </method>
 | 
			
		||||
    <method name="GetVisible">
 | 
			
		||||
      <arg name="visible" type="b" direction="out"/>
 | 
			
		||||
      <doc:doc><doc:description>
 | 
			
		||||
        Get keyboard visibility
 | 
			
		||||
      </doc:description></doc:doc>
 | 
			
		||||
    </method>
 | 
			
		||||
    <property name="Visible" type="b" access="read">
 | 
			
		||||
    </property>
 | 
			
		||||
  </interface>
 | 
			
		||||
</node>
 | 
			
		||||
@ -1,16 +0,0 @@
 | 
			
		||||
size = 16x16
 | 
			
		||||
 | 
			
		||||
icondir = $(datadir)/icons/hicolor/$(size)/apps
 | 
			
		||||
dist_icon_DATA = eekboard.png
 | 
			
		||||
 | 
			
		||||
gtk_update_icon_cache = gtk-update-icon-cache -f -t $(datadir)/icons/hicolor
 | 
			
		||||
 | 
			
		||||
install-data-hook:
 | 
			
		||||
	@-if test -z "$(DESTDIR)"; then			\
 | 
			
		||||
		echo "Updating Gtk icon cache.";	\
 | 
			
		||||
		$(gtk_update_icon_cache);		\
 | 
			
		||||
	else						\
 | 
			
		||||
		echo "*** Icon cache not updated.  After install, run this:"; \
 | 
			
		||||
		echo "***   $(gtk_update_icon_cache)";	\
 | 
			
		||||
	fi
 | 
			
		||||
 | 
			
		||||
										
											Binary file not shown.
										
									
								
							| 
		 Before Width: | Height: | Size: 606 B  | 
@ -1,16 +0,0 @@
 | 
			
		||||
size = 22x22
 | 
			
		||||
 | 
			
		||||
icondir = $(datadir)/icons/hicolor/$(size)/apps
 | 
			
		||||
dist_icon_DATA = eekboard.png
 | 
			
		||||
 | 
			
		||||
gtk_update_icon_cache = gtk-update-icon-cache -f -t $(datadir)/icons/hicolor
 | 
			
		||||
 | 
			
		||||
install-data-hook:
 | 
			
		||||
	@-if test -z "$(DESTDIR)"; then			\
 | 
			
		||||
		echo "Updating Gtk icon cache.";	\
 | 
			
		||||
		$(gtk_update_icon_cache);		\
 | 
			
		||||
	else						\
 | 
			
		||||
		echo "*** Icon cache not updated.  After install, run this:"; \
 | 
			
		||||
		echo "***   $(gtk_update_icon_cache)";	\
 | 
			
		||||
	fi
 | 
			
		||||
 | 
			
		||||
										
											Binary file not shown.
										
									
								
							| 
		 Before Width: | Height: | Size: 892 B  | 
@ -1,16 +0,0 @@
 | 
			
		||||
size = 24x24
 | 
			
		||||
 | 
			
		||||
icondir = $(datadir)/icons/hicolor/$(size)/apps
 | 
			
		||||
dist_icon_DATA = eekboard.png
 | 
			
		||||
 | 
			
		||||
gtk_update_icon_cache = gtk-update-icon-cache -f -t $(datadir)/icons/hicolor
 | 
			
		||||
 | 
			
		||||
install-data-hook:
 | 
			
		||||
	@-if test -z "$(DESTDIR)"; then			\
 | 
			
		||||
		echo "Updating Gtk icon cache.";	\
 | 
			
		||||
		$(gtk_update_icon_cache);		\
 | 
			
		||||
	else						\
 | 
			
		||||
		echo "*** Icon cache not updated.  After install, run this:"; \
 | 
			
		||||
		echo "***   $(gtk_update_icon_cache)";	\
 | 
			
		||||
	fi
 | 
			
		||||
 | 
			
		||||
										
											Binary file not shown.
										
									
								
							| 
		 Before Width: | Height: | Size: 957 B  | 
@ -1,16 +0,0 @@
 | 
			
		||||
size = 32x32
 | 
			
		||||
 | 
			
		||||
icondir = $(datadir)/icons/hicolor/$(size)/apps
 | 
			
		||||
dist_icon_DATA = eekboard.png
 | 
			
		||||
 | 
			
		||||
gtk_update_icon_cache = gtk-update-icon-cache -f -t $(datadir)/icons/hicolor
 | 
			
		||||
 | 
			
		||||
install-data-hook:
 | 
			
		||||
	@-if test -z "$(DESTDIR)"; then			\
 | 
			
		||||
		echo "Updating Gtk icon cache.";	\
 | 
			
		||||
		$(gtk_update_icon_cache);		\
 | 
			
		||||
	else						\
 | 
			
		||||
		echo "*** Icon cache not updated.  After install, run this:"; \
 | 
			
		||||
		echo "***   $(gtk_update_icon_cache)";	\
 | 
			
		||||
	fi
 | 
			
		||||
 | 
			
		||||
										
											Binary file not shown.
										
									
								
							| 
		 Before Width: | Height: | Size: 1.5 KiB  | 
@ -1,16 +0,0 @@
 | 
			
		||||
size = 48x48
 | 
			
		||||
 | 
			
		||||
icondir = $(datadir)/icons/hicolor/$(size)/apps
 | 
			
		||||
dist_icon_DATA = eekboard.png
 | 
			
		||||
 | 
			
		||||
gtk_update_icon_cache = gtk-update-icon-cache -f -t $(datadir)/icons/hicolor
 | 
			
		||||
 | 
			
		||||
install-data-hook:
 | 
			
		||||
	@-if test -z "$(DESTDIR)"; then			\
 | 
			
		||||
		echo "Updating Gtk icon cache.";	\
 | 
			
		||||
		$(gtk_update_icon_cache);		\
 | 
			
		||||
	else						\
 | 
			
		||||
		echo "*** Icon cache not updated.  After install, run this:"; \
 | 
			
		||||
		echo "***   $(gtk_update_icon_cache)";	\
 | 
			
		||||
	fi
 | 
			
		||||
 | 
			
		||||
										
											Binary file not shown.
										
									
								
							| 
		 Before Width: | Height: | Size: 2.7 KiB  | 
@ -1 +0,0 @@
 | 
			
		||||
SUBDIRS = 16x16 22x22 24x24 32x32 48x48 scalable
 | 
			
		||||
@ -1,14 +0,0 @@
 | 
			
		||||
icondir = $(datadir)/icons/hicolor/scalable/apps
 | 
			
		||||
dist_icon_DATA = eekboard.svg
 | 
			
		||||
 | 
			
		||||
gtk_update_icon_cache = gtk-update-icon-cache -f -t $(datadir)/icons/hicolor
 | 
			
		||||
 | 
			
		||||
install-data-hook:
 | 
			
		||||
	@-if test -z "$(DESTDIR)"; then			\
 | 
			
		||||
		echo "Updating Gtk icon cache.";	\
 | 
			
		||||
		$(gtk_update_icon_cache);		\
 | 
			
		||||
	else						\
 | 
			
		||||
		echo "*** Icon cache not updated.  After install, run this:"; \
 | 
			
		||||
		echo "***   $(gtk_update_icon_cache)";	\
 | 
			
		||||
	fi
 | 
			
		||||
 | 
			
		||||
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							| 
		 Before Width: | Height: | Size: 472 KiB  | 
@ -1,38 +0,0 @@
 | 
			
		||||
keyboardsdir = $(pkgdatadir)/keyboards
 | 
			
		||||
 | 
			
		||||
nobase_dist_keyboards_DATA =			\
 | 
			
		||||
	keyboards.xml				\
 | 
			
		||||
	geometry/compact.xml			\
 | 
			
		||||
	symbols/ar.xml				\
 | 
			
		||||
	symbols/be.xml				\
 | 
			
		||||
	symbols/fa.xml				\
 | 
			
		||||
	symbols/he.xml				\
 | 
			
		||||
	symbols/ja-kana.xml			\
 | 
			
		||||
	symbols/kk.xml				\
 | 
			
		||||
	symbols/ks.xml				\
 | 
			
		||||
	symbols/my.xml				\
 | 
			
		||||
	symbols/ru.xml				\
 | 
			
		||||
	symbols/th.xml				\
 | 
			
		||||
	symbols/ua.xml				\
 | 
			
		||||
	symbols/ug.xml				\
 | 
			
		||||
	symbols/us.xml				\
 | 
			
		||||
	symbols/zh-bopomofo.xml			\
 | 
			
		||||
	$(inscript_symbols)			\
 | 
			
		||||
	$(NULL)
 | 
			
		||||
 | 
			
		||||
inscript_symbols =				\
 | 
			
		||||
	symbols/as-inscript.xml			\
 | 
			
		||||
	symbols/bn-inscript.xml			\
 | 
			
		||||
	symbols/gu-inscript.xml			\
 | 
			
		||||
	symbols/hi-inscript.xml			\
 | 
			
		||||
	symbols/kn-inscript.xml			\
 | 
			
		||||
	symbols/ks-inscript.xml			\
 | 
			
		||||
	symbols/mai-inscript.xml		\
 | 
			
		||||
	symbols/ml-inscript.xml			\
 | 
			
		||||
	symbols/mr-inscript.xml			\
 | 
			
		||||
	symbols/or-inscript.xml			\
 | 
			
		||||
	symbols/pa-inscript.xml			\
 | 
			
		||||
	symbols/sd-inscript.xml			\
 | 
			
		||||
	symbols/ta-inscript.xml			\
 | 
			
		||||
	symbols/te-inscript.xml			\
 | 
			
		||||
	$(NULL)
 | 
			
		||||
@ -1,307 +1,189 @@
 | 
			
		||||
<?xml version="1.0"?>
 | 
			
		||||
<geometry version="0.90">
 | 
			
		||||
  <bounds x="0.000000" y="0.000000" width="640.0000" height="296.5853"/>
 | 
			
		||||
  <bounds x="0.000000" y="10.000000" width="426.0000" height="296.5853"/>
 | 
			
		||||
  <section angle="0">
 | 
			
		||||
    <bounds x="15.60975" y="15.60975" width="640.0000" height="39.02439"/>
 | 
			
		||||
    <row columns="16" orientation="1"/>
 | 
			
		||||
    <key keycode="9" name="ESC" column="0" row="0" oref="outline2">
 | 
			
		||||
      <bounds x="3.121951" y="1.560976" width="37.46341" height="37.46341"/>
 | 
			
		||||
    </key>
 | 
			
		||||
    <key keycode="67" name="FK01" column="1" row="0" oref="outline2">
 | 
			
		||||
      <bounds x="84.29268" y="1.560976" width="37.46341" height="37.46341"/>
 | 
			
		||||
    </key>
 | 
			
		||||
    <key keycode="68" name="FK02" column="2" row="0" oref="outline2">
 | 
			
		||||
      <bounds x="124.8780" y="1.560976" width="37.46341" height="37.46341"/>
 | 
			
		||||
    </key>
 | 
			
		||||
    <key keycode="69" name="FK03" column="3" row="0" oref="outline2">
 | 
			
		||||
      <bounds x="165.4634" y="1.560976" width="37.46341" height="37.46341"/>
 | 
			
		||||
    </key>
 | 
			
		||||
    <key keycode="70" name="FK04" column="4" row="0" oref="outline2">
 | 
			
		||||
      <bounds x="206.0487" y="1.560976" width="37.46341" height="37.46341"/>
 | 
			
		||||
    </key>
 | 
			
		||||
    <key keycode="71" name="FK05" column="5" row="0" oref="outline2">
 | 
			
		||||
      <bounds x="266.9268" y="1.560976" width="37.46341" height="37.46341"/>
 | 
			
		||||
    </key>
 | 
			
		||||
    <key keycode="72" name="FK06" column="6" row="0" oref="outline2">
 | 
			
		||||
      <bounds x="307.5121" y="1.560976" width="37.46341" height="37.46341"/>
 | 
			
		||||
    </key>
 | 
			
		||||
    <key keycode="73" name="FK07" column="7" row="0" oref="outline2">
 | 
			
		||||
      <bounds x="348.0975" y="1.560976" width="37.46341" height="37.46341"/>
 | 
			
		||||
    </key>
 | 
			
		||||
    <key keycode="74" name="FK08" column="8" row="0" oref="outline2">
 | 
			
		||||
      <bounds x="388.6829" y="1.560976" width="37.46341" height="37.46341"/>
 | 
			
		||||
    </key>
 | 
			
		||||
    <key keycode="75" name="FK09" column="9" row="0" oref="outline2">
 | 
			
		||||
      <bounds x="449.5609" y="1.560976" width="37.46341" height="37.46341"/>
 | 
			
		||||
    </key>
 | 
			
		||||
    <key keycode="76" name="FK10" column="10" row="0" oref="outline2">
 | 
			
		||||
      <bounds x="490.1463" y="1.560976" width="37.46341" height="37.46341"/>
 | 
			
		||||
    </key>
 | 
			
		||||
    <key keycode="95" name="FK11" column="11" row="0" oref="outline2">
 | 
			
		||||
      <bounds x="530.7317" y="1.560976" width="37.46341" height="37.46341"/>
 | 
			
		||||
    </key>
 | 
			
		||||
    <key keycode="96" name="FK12" column="12" row="0" oref="outline2">
 | 
			
		||||
      <bounds x="571.3170" y="1.560976" width="37.46341" height="37.46341"/>
 | 
			
		||||
    </key>
 | 
			
		||||
    <bounds x="0" y="0" width="608.7804" height="201.3658"/>
 | 
			
		||||
    <row orientation="1">
 | 
			
		||||
      <key keycode="24" name="AD01" oref="outline2">
 | 
			
		||||
	<bounds x="65.56097" y="42.14634" width="37.46341" height="52.44877"/>
 | 
			
		||||
      </key>
 | 
			
		||||
      <key keycode="25" name="AD02" oref="outline2">
 | 
			
		||||
	<bounds x="106.1463" y="42.14634" width="37.46341" height="37.46341"/>
 | 
			
		||||
      </key>
 | 
			
		||||
      <key keycode="26" name="AD03" oref="outline2">
 | 
			
		||||
	<bounds x="145.1707" y="42.14634" width="37.46341" height="37.46341"/>
 | 
			
		||||
      </key>
 | 
			
		||||
      <key keycode="27" name="AD04" oref="outline2">
 | 
			
		||||
	<bounds x="185.7560" y="42.14634" width="37.46341" height="37.46341"/>
 | 
			
		||||
      </key>
 | 
			
		||||
      <key keycode="28" name="AD05" oref="outline2">
 | 
			
		||||
	<bounds x="226.3414" y="42.14634" width="37.46341" height="37.46341"/>
 | 
			
		||||
      </key>
 | 
			
		||||
      <key keycode="29" name="AD06" oref="outline2">
 | 
			
		||||
	<bounds x="266.9268" y="42.14634" width="37.46341" height="37.46341"/>
 | 
			
		||||
      </key>
 | 
			
		||||
      <key keycode="30" name="AD07" oref="outline2">
 | 
			
		||||
	<bounds x="307.5121" y="42.14634" width="37.46341" height="37.46341"/>
 | 
			
		||||
      </key>
 | 
			
		||||
      <key keycode="31" name="AD08" oref="outline2">
 | 
			
		||||
	<bounds x="348.0975" y="42.14634" width="37.46341" height="37.46341"/>
 | 
			
		||||
      </key>
 | 
			
		||||
      <key keycode="32" name="AD09" oref="outline2">
 | 
			
		||||
	<bounds x="388.6829" y="42.14634" width="37.46341" height="37.46341"/>
 | 
			
		||||
      </key>
 | 
			
		||||
      <key keycode="33" name="AD10" oref="outline2">
 | 
			
		||||
	<bounds x="429.2682" y="42.14634" width="37.46341" height="37.46341"/>
 | 
			
		||||
      </key>
 | 
			
		||||
    </row>
 | 
			
		||||
  </section>
 | 
			
		||||
  <section angle="0">
 | 
			
		||||
    <bounds x="15.60975" y="78.04878" width="608.7804" height="201.3658"/>
 | 
			
		||||
    <row columns="14" orientation="1"/>
 | 
			
		||||
    <row columns="14" orientation="1"/>
 | 
			
		||||
    <row columns="13" orientation="1"/>
 | 
			
		||||
    <row columns="12" orientation="1"/>
 | 
			
		||||
    <row columns="9" orientation="1"/>
 | 
			
		||||
    <key keycode="49" name="TLDE" column="0" row="0" oref="outline2">
 | 
			
		||||
      <bounds x="3.121951" y="1.560976" width="37.46341" height="37.46341"/>
 | 
			
		||||
    </key>
 | 
			
		||||
    <key keycode="10" name="AE01" column="1" row="0" oref="outline2">
 | 
			
		||||
      <bounds x="43.70731" y="1.560976" width="37.46341" height="37.46341"/>
 | 
			
		||||
    </key>
 | 
			
		||||
    <key keycode="11" name="AE02" column="2" row="0" oref="outline2">
 | 
			
		||||
      <bounds x="84.29268" y="1.560976" width="37.46341" height="37.46341"/>
 | 
			
		||||
    </key>
 | 
			
		||||
    <key keycode="12" name="AE03" column="3" row="0" oref="outline2">
 | 
			
		||||
      <bounds x="124.8780" y="1.560976" width="37.46341" height="37.46341"/>
 | 
			
		||||
    </key>
 | 
			
		||||
    <key keycode="13" name="AE04" column="4" row="0" oref="outline2">
 | 
			
		||||
      <bounds x="165.4634" y="1.560976" width="37.46341" height="37.46341"/>
 | 
			
		||||
    </key>
 | 
			
		||||
    <key keycode="14" name="AE05" column="5" row="0" oref="outline2">
 | 
			
		||||
      <bounds x="206.0487" y="1.560976" width="37.46341" height="37.46341"/>
 | 
			
		||||
    </key>
 | 
			
		||||
    <key keycode="15" name="AE06" column="6" row="0" oref="outline2">
 | 
			
		||||
      <bounds x="245.0731" y="1.560976" width="37.46341" height="37.46341"/>
 | 
			
		||||
    </key>
 | 
			
		||||
    <key keycode="16" name="AE07" column="7" row="0" oref="outline2">
 | 
			
		||||
      <bounds x="285.6585" y="1.560976" width="37.46341" height="37.46341"/>
 | 
			
		||||
    </key>
 | 
			
		||||
    <key keycode="17" name="AE08" column="8" row="0" oref="outline2">
 | 
			
		||||
      <bounds x="326.2439" y="1.560976" width="37.46341" height="37.46341"/>
 | 
			
		||||
    </key>
 | 
			
		||||
    <key keycode="18" name="AE09" column="9" row="0" oref="outline2">
 | 
			
		||||
      <bounds x="366.8292" y="1.560976" width="37.46341" height="37.46341"/>
 | 
			
		||||
    </key>
 | 
			
		||||
    <key keycode="19" name="AE10" column="10" row="0" oref="outline2">
 | 
			
		||||
      <bounds x="407.4146" y="1.560976" width="37.46341" height="37.46341"/>
 | 
			
		||||
    </key>
 | 
			
		||||
    <key keycode="20" name="AE11" column="11" row="0" oref="outline2">
 | 
			
		||||
      <bounds x="448.0000" y="1.560976" width="37.46341" height="37.46341"/>
 | 
			
		||||
    </key>
 | 
			
		||||
    <key keycode="21" name="AE12" column="12" row="0" oref="outline2">
 | 
			
		||||
      <bounds x="488.5853" y="1.560976" width="37.46341" height="37.46341"/>
 | 
			
		||||
    </key>
 | 
			
		||||
    <key keycode="22" name="BKSP" column="13" row="0" oref="outline13">
 | 
			
		||||
      <bounds x="529.1707" y="1.560976" width="79.60975" height="37.46341"/>
 | 
			
		||||
    </key>
 | 
			
		||||
    <key keycode="23" name="TAB" column="0" row="1" oref="outline4">
 | 
			
		||||
      <bounds x="3.121951" y="42.14634" width="59.31707" height="37.46341"/>
 | 
			
		||||
    </key>
 | 
			
		||||
    <key keycode="24" name="AD01" column="1" row="1" oref="outline2">
 | 
			
		||||
      <bounds x="65.56097" y="42.14634" width="37.46341" height="37.46341"/>
 | 
			
		||||
    </key>
 | 
			
		||||
    <key keycode="25" name="AD02" column="2" row="1" oref="outline2">
 | 
			
		||||
      <bounds x="106.1463" y="42.14634" width="37.46341" height="37.46341"/>
 | 
			
		||||
    </key>
 | 
			
		||||
    <key keycode="26" name="AD03" column="3" row="1" oref="outline2">
 | 
			
		||||
      <bounds x="145.1707" y="42.14634" width="37.46341" height="37.46341"/>
 | 
			
		||||
    </key>
 | 
			
		||||
    <key keycode="27" name="AD04" column="4" row="1" oref="outline2">
 | 
			
		||||
      <bounds x="185.7560" y="42.14634" width="37.46341" height="37.46341"/>
 | 
			
		||||
    </key>
 | 
			
		||||
    <key keycode="28" name="AD05" column="5" row="1" oref="outline2">
 | 
			
		||||
      <bounds x="226.3414" y="42.14634" width="37.46341" height="37.46341"/>
 | 
			
		||||
    </key>
 | 
			
		||||
    <key keycode="29" name="AD06" column="6" row="1" oref="outline2">
 | 
			
		||||
      <bounds x="266.9268" y="42.14634" width="37.46341" height="37.46341"/>
 | 
			
		||||
    </key>
 | 
			
		||||
    <key keycode="30" name="AD07" column="7" row="1" oref="outline2">
 | 
			
		||||
      <bounds x="307.5121" y="42.14634" width="37.46341" height="37.46341"/>
 | 
			
		||||
    </key>
 | 
			
		||||
    <key keycode="31" name="AD08" column="8" row="1" oref="outline2">
 | 
			
		||||
      <bounds x="348.0975" y="42.14634" width="37.46341" height="37.46341"/>
 | 
			
		||||
    </key>
 | 
			
		||||
    <key keycode="32" name="AD09" column="9" row="1" oref="outline2">
 | 
			
		||||
      <bounds x="388.6829" y="42.14634" width="37.46341" height="37.46341"/>
 | 
			
		||||
    </key>
 | 
			
		||||
    <key keycode="33" name="AD10" column="10" row="1" oref="outline2">
 | 
			
		||||
      <bounds x="429.2682" y="42.14634" width="37.46341" height="37.46341"/>
 | 
			
		||||
    </key>
 | 
			
		||||
    <key keycode="34" name="AD11" column="11" row="1" oref="outline2">
 | 
			
		||||
      <bounds x="468.2926" y="42.14634" width="37.46341" height="37.46341"/>
 | 
			
		||||
    </key>
 | 
			
		||||
    <key keycode="35" name="AD12" column="12" row="1" oref="outline2">
 | 
			
		||||
      <bounds x="508.8780" y="42.14634" width="37.46341" height="37.46341"/>
 | 
			
		||||
    </key>
 | 
			
		||||
    <key keycode="51" name="BKSL" column="13" row="1" oref="outline5">
 | 
			
		||||
      <bounds x="549.4634" y="42.14634" width="59.31707" height="37.46341"/>
 | 
			
		||||
    </key>
 | 
			
		||||
    <key keycode="66" name="CAPS" column="0" row="2" oref="outline6">
 | 
			
		||||
      <bounds x="3.121951" y="82.73170" width="68.68292" height="37.46341"/>
 | 
			
		||||
    </key>
 | 
			
		||||
    <key keycode="38" name="AC01" column="1" row="2" oref="outline2">
 | 
			
		||||
      <bounds x="76.48780" y="82.73170" width="37.46341" height="37.46341"/>
 | 
			
		||||
    </key>
 | 
			
		||||
    <key keycode="39" name="AC02" column="2" row="2" oref="outline2">
 | 
			
		||||
      <bounds x="115.5121" y="82.73170" width="37.46341" height="37.46341"/>
 | 
			
		||||
    </key>
 | 
			
		||||
    <key keycode="40" name="AC03" column="3" row="2" oref="outline2">
 | 
			
		||||
      <bounds x="156.0975" y="82.73170" width="37.46341" height="37.46341"/>
 | 
			
		||||
    </key>
 | 
			
		||||
    <key keycode="41" name="AC04" column="4" row="2" oref="outline2">
 | 
			
		||||
      <bounds x="196.6829" y="82.73170" width="37.46341" height="37.46341"/>
 | 
			
		||||
    </key>
 | 
			
		||||
    <key keycode="42" name="AC05" column="5" row="2" oref="outline2">
 | 
			
		||||
      <bounds x="237.2682" y="82.73170" width="37.46341" height="37.46341"/>
 | 
			
		||||
    </key>
 | 
			
		||||
    <key keycode="43" name="AC06" column="6" row="2" oref="outline2">
 | 
			
		||||
      <bounds x="277.8536" y="82.73170" width="37.46341" height="37.46341"/>
 | 
			
		||||
    </key>
 | 
			
		||||
    <key keycode="44" name="AC07" column="7" row="2" oref="outline2">
 | 
			
		||||
      <bounds x="318.4390" y="82.73170" width="37.46341" height="37.46341"/>
 | 
			
		||||
    </key>
 | 
			
		||||
    <key keycode="45" name="AC08" column="8" row="2" oref="outline2">
 | 
			
		||||
      <bounds x="359.0243" y="82.73170" width="37.46341" height="37.46341"/>
 | 
			
		||||
    </key>
 | 
			
		||||
    <key keycode="46" name="AC09" column="9" row="2" oref="outline2">
 | 
			
		||||
      <bounds x="399.6097" y="82.73170" width="37.46341" height="37.46341"/>
 | 
			
		||||
    </key>
 | 
			
		||||
    <key keycode="47" name="AC10" column="10" row="2" oref="outline2">
 | 
			
		||||
      <bounds x="438.6341" y="82.73170" width="37.46341" height="37.46341"/>
 | 
			
		||||
    </key>
 | 
			
		||||
    <key keycode="48" name="AC11" column="11" row="2" oref="outline2">
 | 
			
		||||
      <bounds x="479.2195" y="82.73170" width="37.46341" height="37.46341"/>
 | 
			
		||||
    </key>
 | 
			
		||||
    <key keycode="36" name="RTRN" column="12" row="2" oref="outline7">
 | 
			
		||||
      <bounds x="519.8048" y="82.73170" width="88.97561" height="37.46341"/>
 | 
			
		||||
    </key>
 | 
			
		||||
    <key keycode="50" name="LFSH" column="0" row="3" oref="outline8">
 | 
			
		||||
      <bounds x="3.121951" y="121.7560" width="88.97561" height="37.46341"/>
 | 
			
		||||
    </key>
 | 
			
		||||
    <key keycode="52" name="AB01" column="1" row="3" oref="outline2">
 | 
			
		||||
      <bounds x="95.21951" y="121.7560" width="37.46341" height="37.46341"/>
 | 
			
		||||
    </key>
 | 
			
		||||
    <key keycode="53" name="AB02" column="2" row="3" oref="outline2">
 | 
			
		||||
      <bounds x="135.8048" y="121.7560" width="37.46341" height="37.46341"/>
 | 
			
		||||
    </key>
 | 
			
		||||
    <key keycode="54" name="AB03" column="3" row="3" oref="outline2">
 | 
			
		||||
      <bounds x="176.3902" y="121.7560" width="37.46341" height="37.46341"/>
 | 
			
		||||
    </key>
 | 
			
		||||
    <key keycode="55" name="AB04" column="4" row="3" oref="outline2">
 | 
			
		||||
      <bounds x="215.4146" y="121.7560" width="37.46341" height="37.46341"/>
 | 
			
		||||
    </key>
 | 
			
		||||
    <key keycode="56" name="AB05" column="5" row="3" oref="outline2">
 | 
			
		||||
      <bounds x="256.0000" y="121.7560" width="37.46341" height="37.46341"/>
 | 
			
		||||
    </key>
 | 
			
		||||
    <key keycode="57" name="AB06" column="6" row="3" oref="outline2">
 | 
			
		||||
      <bounds x="296.5853" y="121.7560" width="37.46341" height="37.46341"/>
 | 
			
		||||
    </key>
 | 
			
		||||
    <key keycode="58" name="AB07" column="7" row="3" oref="outline2">
 | 
			
		||||
      <bounds x="337.1707" y="121.7560" width="37.46341" height="37.46341"/>
 | 
			
		||||
    </key>
 | 
			
		||||
    <key keycode="59" name="AB08" column="8" row="3" oref="outline2">
 | 
			
		||||
      <bounds x="377.7560" y="121.7560" width="37.46341" height="37.46341"/>
 | 
			
		||||
    </key>
 | 
			
		||||
    <key keycode="60" name="AB09" column="9" row="3" oref="outline2">
 | 
			
		||||
      <bounds x="418.3414" y="121.7560" width="37.46341" height="37.46341"/>
 | 
			
		||||
    </key>
 | 
			
		||||
    <key keycode="61" name="AB10" column="10" row="3" oref="outline2">
 | 
			
		||||
      <bounds x="458.9268" y="121.7560" width="37.46341" height="37.46341"/>
 | 
			
		||||
    </key>
 | 
			
		||||
    <key keycode="62" name="RTSH" column="11" row="3" oref="outline9">
 | 
			
		||||
      <bounds x="499.5121" y="121.7560" width="109.2682" height="37.46341"/>
 | 
			
		||||
    </key>
 | 
			
		||||
    <key keycode="149" name="I149" column="0" row="4" oref="outline10">
 | 
			
		||||
      <bounds x="3.121951" y="162.3414" width="37.46341" height="37.46341"/>
 | 
			
		||||
    </key>
 | 
			
		||||
    <key keycode="37" name="LCTL" column="1" row="4" oref="outline1">
 | 
			
		||||
      <bounds x="62.43902" y="162.3414" width="48.39024" height="37.46341"/>
 | 
			
		||||
    </key>
 | 
			
		||||
    <key keycode="64" name="LALT" column="2" row="4" oref="outline1">
 | 
			
		||||
      <bounds x="113.9512" y="162.3414" width="48.39024" height="37.46341"/>
 | 
			
		||||
    </key>
 | 
			
		||||
    <key keycode="65" name="SPCE" column="3" row="4" oref="outline3">
 | 
			
		||||
      <bounds x="165.4634" y="162.3414" width="217.5853" height="37.46341"/>
 | 
			
		||||
    </key>
 | 
			
		||||
    <key keycode="113" name="LEFT" column="4" row="4" oref="outline1">
 | 
			
		||||
      <bounds x="368.0487" y="162.3414" width="48.39024" height="37.46341"/>
 | 
			
		||||
    </key>
 | 
			
		||||
    <key keycode="111" name="UP" column="5" row="4" oref="outline1">
 | 
			
		||||
      <bounds x="419.43894" y="162.3414" width="48.39024" height="37.46341"/>
 | 
			
		||||
    </key>
 | 
			
		||||
    <key keycode="116" name="DOWN" column="6" row="4" oref="outline1">
 | 
			
		||||
      <bounds x="470.82918" y="162.3414" width="48.39024" height="37.46341"/>
 | 
			
		||||
    </key>
 | 
			
		||||
    <key keycode="114" name="RGHT" column="7" row="4" oref="outline1">
 | 
			
		||||
      <bounds x="522.21942" y="162.3414" width="48.39024" height="37.46341"/>
 | 
			
		||||
    </key>
 | 
			
		||||
    <key keycode="150" name="I150" column="8" row="4" oref="outline10">
 | 
			
		||||
      <bounds x="573.60966" y="162.3414" width="37.46341" height="37.46341"/>
 | 
			
		||||
    </key>
 | 
			
		||||
    <bounds x="0" y="0" width="608.7804" height="201.3658"/>
 | 
			
		||||
    <row orientation="1">
 | 
			
		||||
      <key keycode="38" name="AC01" oref="outline2">
 | 
			
		||||
	<bounds x="76.48780" y="82.73170" width="37.46341" height="37.46341"/>
 | 
			
		||||
      </key>
 | 
			
		||||
      <key keycode="39" name="AC02" oref="outline2">
 | 
			
		||||
	<bounds x="115.5121" y="82.73170" width="37.46341" height="37.46341"/>
 | 
			
		||||
      </key>
 | 
			
		||||
      <key keycode="40" name="AC03" oref="outline2">
 | 
			
		||||
	<bounds x="156.0975" y="82.73170" width="37.46341" height="37.46341"/>
 | 
			
		||||
      </key>
 | 
			
		||||
      <key keycode="41" name="AC04" oref="outline2">
 | 
			
		||||
	<bounds x="196.6829" y="82.73170" width="37.46341" height="37.46341"/>
 | 
			
		||||
      </key>
 | 
			
		||||
      <key keycode="42" name="AC05" oref="outline2">
 | 
			
		||||
	<bounds x="237.2682" y="82.73170" width="37.46341" height="37.46341"/>
 | 
			
		||||
      </key>
 | 
			
		||||
      <key keycode="43" name="AC06" oref="outline2">
 | 
			
		||||
	<bounds x="277.8536" y="82.73170" width="37.46341" height="37.46341"/>
 | 
			
		||||
      </key>
 | 
			
		||||
      <key keycode="44" name="AC07" oref="outline2">
 | 
			
		||||
	<bounds x="318.4390" y="82.73170" width="37.46341" height="37.46341"/>
 | 
			
		||||
      </key>
 | 
			
		||||
      <key keycode="45" name="AC08" oref="outline2">
 | 
			
		||||
	<bounds x="359.0243" y="82.73170" width="37.46341" height="37.46341"/>
 | 
			
		||||
      </key>
 | 
			
		||||
      <key keycode="46" name="AC09" oref="outline2">
 | 
			
		||||
	<bounds x="399.6097" y="82.73170" width="37.46341" height="37.46341"/>
 | 
			
		||||
      </key>
 | 
			
		||||
    </row>
 | 
			
		||||
  </section>
 | 
			
		||||
  <section angle="0">
 | 
			
		||||
    <bounds x="0" y="0" width="608.7804" height="201.3658"/>
 | 
			
		||||
    <row orientation="1">
 | 
			
		||||
      <key keycode="50" name="LFSH" oref="altline">
 | 
			
		||||
	<bounds x="3.121951" y="121.7560" width="88.97561" height="37.46341"/>
 | 
			
		||||
      </key>
 | 
			
		||||
      <key keycode="52" name="AB01" oref="outline2">
 | 
			
		||||
	<bounds x="95.21951" y="121.7560" width="37.46341" height="37.46341"/>
 | 
			
		||||
      </key>
 | 
			
		||||
      <key keycode="53" name="AB02" oref="outline2">
 | 
			
		||||
	<bounds x="135.8048" y="121.7560" width="37.46341" height="37.46341"/>
 | 
			
		||||
      </key>
 | 
			
		||||
      <key keycode="54" name="AB03" oref="outline2">
 | 
			
		||||
	<bounds x="176.3902" y="121.7560" width="37.46341" height="37.46341"/>
 | 
			
		||||
      </key>
 | 
			
		||||
      <key keycode="55" name="AB04" oref="outline2">
 | 
			
		||||
	<bounds x="215.4146" y="121.7560" width="37.46341" height="37.46341"/>
 | 
			
		||||
      </key>
 | 
			
		||||
      <key keycode="56" name="AB05" oref="outline2">
 | 
			
		||||
	<bounds x="256.0000" y="121.7560" width="37.46341" height="37.46341"/>
 | 
			
		||||
      </key>
 | 
			
		||||
      <key keycode="57" name="AB06" oref="outline2">
 | 
			
		||||
	<bounds x="296.5853" y="121.7560" width="37.46341" height="37.46341"/>
 | 
			
		||||
      </key>
 | 
			
		||||
      <key keycode="58" name="AB07" oref="outline2">
 | 
			
		||||
	<bounds x="337.1707" y="121.7560" width="37.46341" height="37.46341"/>
 | 
			
		||||
      </key>
 | 
			
		||||
      <key keycode="22" name="BKSP" oref="altline">
 | 
			
		||||
	<bounds x="529.1707" y="1.560976" width="79.60975" height="37.46341"/>
 | 
			
		||||
      </key>
 | 
			
		||||
    </row>
 | 
			
		||||
  </section>
 | 
			
		||||
  <section angle="0">
 | 
			
		||||
    <bounds x="0" y="0" width="608.7804" height="201.3658"/>
 | 
			
		||||
    <row orientation="1">
 | 
			
		||||
      <key keycode="66" name="ALTGR" oref="altline">
 | 
			
		||||
	<bounds x="62.43902" y="162.3414" width="48.39024" height="37.46341"/>
 | 
			
		||||
      </key>
 | 
			
		||||
      <key keycode="150" name="I150" oref="altline">
 | 
			
		||||
	<bounds x="113.9512" y="162.3414" width="48.39024" height="37.46341"/>
 | 
			
		||||
      </key>
 | 
			
		||||
      <key keycode="65" name="SPCE" oref="spaceline">
 | 
			
		||||
	<bounds x="165.4634" y="162.3414" width="217.5853" height="37.46341"/>
 | 
			
		||||
      </key>
 | 
			
		||||
      <key keycode="60" name="AB09" oref="outline2">
 | 
			
		||||
       <bounds x="418.3414" y="121.7560" width="37.46341" height="37.46341"/>
 | 
			
		||||
      </key>
 | 
			
		||||
      <key keycode="36" name="RTRN" oref="outline7">
 | 
			
		||||
	<bounds x="519.8048" y="82.73170" width="88.97561" height="37.46341"/>
 | 
			
		||||
      </key>
 | 
			
		||||
    </row>
 | 
			
		||||
  </section>
 | 
			
		||||
  <outline id="outline2" corner-radius="1.000000">
 | 
			
		||||
    <point x="0.000000" y="0.000000"/>
 | 
			
		||||
    <point x="37.46341" y="0.000000"/>
 | 
			
		||||
    <point x="37.46341" y="37.46341"/>
 | 
			
		||||
    <point x="0.000000" y="37.46341"/>
 | 
			
		||||
    <point x="37.46341" y="52.44877"/>
 | 
			
		||||
    <point x="0.000000" y="52.44877"/>
 | 
			
		||||
  </outline>
 | 
			
		||||
  <outline id="outline1" corner-radius="1.000000">
 | 
			
		||||
  <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="37.46341"/>
 | 
			
		||||
    <point x="0.000000" y="37.46341"/>
 | 
			
		||||
    <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="37.46341"/>
 | 
			
		||||
    <point x="0.000000" y="37.46341"/>
 | 
			
		||||
    <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="37.46341"/>
 | 
			
		||||
    <point x="0.000000" y="37.46341"/>
 | 
			
		||||
    <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="37.46341"/>
 | 
			
		||||
    <point x="0.000000" y="37.46341"/>
 | 
			
		||||
    <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="37.46341"/>
 | 
			
		||||
    <point x="0.000000" y="37.46341"/>
 | 
			
		||||
    <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="37.46341"/>
 | 
			
		||||
    <point x="0.000000" y="37.46341"/>
 | 
			
		||||
    <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="37.46341"/>
 | 
			
		||||
    <point x="0.000000" y="37.46341"/>
 | 
			
		||||
    <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="37.46341"/>
 | 
			
		||||
    <point x="0.000000" y="37.46341"/>
 | 
			
		||||
    <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="37.46341"/>
 | 
			
		||||
    <point x="0.000000" y="37.46341"/>
 | 
			
		||||
    <point x="79.60975" y="52.44877"/>
 | 
			
		||||
    <point x="0.000000" y="52.44877"/>
 | 
			
		||||
  </outline>
 | 
			
		||||
  <outline id="outline3" corner-radius="1.000000">
 | 
			
		||||
  <outline id="spaceline" corner-radius="1.000000">
 | 
			
		||||
    <point x="0.000000" y="0.000000"/>
 | 
			
		||||
    <point x="217.5853" y="0.000000"/>
 | 
			
		||||
    <point x="217.5853" y="37.46341"/>
 | 
			
		||||
    <point x="0.000000" y="37.46341"/>
 | 
			
		||||
    <point x="150.5853" y="0.000000"/>
 | 
			
		||||
    <point x="150.5853" y="52.44877"/>
 | 
			
		||||
    <point x="0.000000" y="52.44877"/>
 | 
			
		||||
  </outline>
 | 
			
		||||
</geometry>
 | 
			
		||||
 | 
			
		||||
@ -1,250 +1,154 @@
 | 
			
		||||
<?xml version="1.0"?>
 | 
			
		||||
<symbols version="0.90">
 | 
			
		||||
  <include>us</include>
 | 
			
		||||
  <key keycode="1" name="AE03" groups="2">
 | 
			
		||||
    <keysym keyval="51" label="あ">3</keysym>
 | 
			
		||||
    <keysym keyval="35" label="ぁ">numbersign</keysym>
 | 
			
		||||
    <keysym keyval="51" label="ア">3</keysym>
 | 
			
		||||
    <keysym keyval="35" label="ァ">numbersign</keysym>
 | 
			
		||||
  <key keycode="49" name="TLDE">
 | 
			
		||||
    <keysym keyval="1246">゛</keysym>
 | 
			
		||||
    <keysym keyval="1247">゜</keysym>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key keycode="2" name="AD03" groups="2">
 | 
			
		||||
    <keysym keyval="101" label="い">e</keysym>
 | 
			
		||||
    <keysym keyval="69" label="ぃ">E</keysym>
 | 
			
		||||
    <keysym keyval="101" label="イ">e</keysym>
 | 
			
		||||
    <keysym keyval="69" label="ィ">E</keysym>
 | 
			
		||||
  <key keycode="10" name="AE01">
 | 
			
		||||
    <keysym keyval="1223">ぬ</keysym>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key keycode="3" name="AE04" groups="2">
 | 
			
		||||
    <keysym keyval="52" label="う">4</keysym>
 | 
			
		||||
    <keysym keyval="36" label="ぅ">dollar</keysym>
 | 
			
		||||
    <keysym keyval="52" label="ウ">4</keysym>
 | 
			
		||||
    <keysym keyval="36" label="ゥ">dollar</keysym>
 | 
			
		||||
  <key keycode="11" name="AE02">
 | 
			
		||||
    <keysym keyval="1228">ふ</keysym>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key keycode="4" name="AE05" groups="2">
 | 
			
		||||
    <keysym keyval="53" label="え">5</keysym>
 | 
			
		||||
    <keysym keyval="37" label="ぇ">percent</keysym>
 | 
			
		||||
    <keysym keyval="53" label="エ">5</keysym>
 | 
			
		||||
    <keysym keyval="37" label="ェ">percent</keysym>
 | 
			
		||||
  <key keycode="12" name="AE03">
 | 
			
		||||
    <keysym keyval="1201">あ</keysym>
 | 
			
		||||
    <keysym keyval="1191">ぁ</keysym>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key keycode="5" name="AE06" groups="2">
 | 
			
		||||
    <keysym keyval="54" label="お">6</keysym>
 | 
			
		||||
    <keysym keyval="38" label="ぉ">ampersand</keysym>
 | 
			
		||||
    <keysym keyval="54" label="オ">6</keysym>
 | 
			
		||||
    <keysym keyval="38" label="ォ">ampersand</keysym>
 | 
			
		||||
  <key keycode="13" name="AE04">
 | 
			
		||||
    <keysym keyval="1203">う</keysym>
 | 
			
		||||
    <keysym keyval="1193">ぅ</keysym>
 | 
			
		||||
  </key>
 | 
			
		||||
 | 
			
		||||
  <key keycode="6" name="AE03" groups="2">
 | 
			
		||||
    <keysym keyval="116" label="か">t</keysym>
 | 
			
		||||
    <keysym keyval="116" label="カ">t</keysym>
 | 
			
		||||
  <key keycode="14" name="AE05">
 | 
			
		||||
    <keysym keyval="1204">え</keysym>
 | 
			
		||||
    <keysym keyval="1194">ぇ</keysym>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key keycode="7" name="AD03" groups="2">
 | 
			
		||||
    <keysym keyval="103" label="き">g</keysym>
 | 
			
		||||
    <keysym keyval="103" label="キ">g</keysym>
 | 
			
		||||
  <key keycode="15" name="AE06">
 | 
			
		||||
    <keysym keyval="1205">お</keysym>
 | 
			
		||||
    <keysym keyval="1195">ぉ</keysym>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key keycode="8" name="AE04" groups="2">
 | 
			
		||||
    <keysym keyval="104" label="く">h</keysym>
 | 
			
		||||
    <keysym keyval="104" label="ク">h</keysym>
 | 
			
		||||
  <key keycode="16" name="AE07">
 | 
			
		||||
    <keysym keyval="1236">や</keysym>
 | 
			
		||||
    <keysym keyval="1196">ゃ</keysym>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key keycode="9" name="AE05" groups="2">
 | 
			
		||||
    <keysym keyval="58" label="け">colon</keysym>
 | 
			
		||||
    <keysym keyval="58" label="ケ">colon</keysym>
 | 
			
		||||
  <key keycode="17" name="AE08">
 | 
			
		||||
    <keysym keyval="1237">ゆ</keysym>
 | 
			
		||||
    <keysym keyval="1197">ゅ</keysym>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key keycode="10" name="AE06" groups="2">
 | 
			
		||||
    <keysym keyval="98" label="こ">b</keysym>
 | 
			
		||||
    <keysym keyval="98" label="コ">b</keysym>
 | 
			
		||||
  <key keycode="18" name="AE09">
 | 
			
		||||
    <keysym keyval="1238">よ</keysym>
 | 
			
		||||
    <keysym keyval="1198">ょ</keysym>
 | 
			
		||||
  </key>
 | 
			
		||||
 | 
			
		||||
  <key keycode="11" name="AE03" groups="2">
 | 
			
		||||
    <keysym keyval="120" label="さ">x</keysym>
 | 
			
		||||
    <keysym keyval="120" label="サ">x</keysym>
 | 
			
		||||
  <key keycode="19" name="AE10">
 | 
			
		||||
    <keysym keyval="1244">わ</keysym>
 | 
			
		||||
    <keysym keyval="1190">を</keysym>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key keycode="12" name="AD03" groups="2">
 | 
			
		||||
    <keysym keyval="100" label="し">d</keysym>
 | 
			
		||||
    <keysym keyval="100" label="シ">d</keysym>
 | 
			
		||||
  <key keycode="20" name="AE11">
 | 
			
		||||
    <keysym keyval="1230">ほ</keysym>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key keycode="13" name="AE04" groups="2">
 | 
			
		||||
    <keysym keyval="114" label="す">r</keysym>
 | 
			
		||||
    <keysym keyval="114" label="ス">r</keysym>
 | 
			
		||||
  <key keycode="21" name="AE12">
 | 
			
		||||
    <keysym keyval="1229">へ</keysym>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key keycode="14" name="AE05" groups="2">
 | 
			
		||||
    <keysym keyval="112" label="せ">p</keysym>
 | 
			
		||||
    <keysym keyval="112" label="セ">p</keysym>
 | 
			
		||||
  <key keycode="24" name="AD01">
 | 
			
		||||
    <keysym keyval="1216">た</keysym>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key keycode="15" name="AE06" groups="2">
 | 
			
		||||
    <keysym keyval="99" label="そ">c</keysym>
 | 
			
		||||
    <keysym keyval="99" label="ソ">c</keysym>
 | 
			
		||||
  <key keycode="25" name="AD02">
 | 
			
		||||
    <keysym keyval="1219">て</keysym>
 | 
			
		||||
  </key>
 | 
			
		||||
 | 
			
		||||
  <key keycode="16" name="AE03" groups="2">
 | 
			
		||||
    <keysym keyval="113" label="た">q</keysym>
 | 
			
		||||
    <keysym keyval="113" label="タ">q</keysym>
 | 
			
		||||
  <key keycode="26" name="AD03">
 | 
			
		||||
    <keysym keyval="1202">い</keysym>
 | 
			
		||||
    <keysym keyval="1192">ぃ</keysym>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key keycode="17" name="AD03" groups="2">
 | 
			
		||||
    <keysym keyval="97" label="ち">a</keysym>
 | 
			
		||||
    <keysym keyval="97" label="チ">a</keysym>
 | 
			
		||||
  <key keycode="27" name="AD04">
 | 
			
		||||
    <keysym keyval="1213">す</keysym>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key keycode="18" name="AE04" groups="2">
 | 
			
		||||
    <keysym keyval="122" label="つ">z</keysym>
 | 
			
		||||
    <keysym keyval="90" label="っ">Z</keysym>
 | 
			
		||||
    <keysym keyval="122" label="ツ">z</keysym>
 | 
			
		||||
    <keysym keyval="90" label="ッ">Z</keysym>
 | 
			
		||||
  <key keycode="28" name="AD05">
 | 
			
		||||
    <keysym keyval="1206">か</keysym>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key keycode="19" name="AE05" groups="2">
 | 
			
		||||
    <keysym keyval="119" label="て">w</keysym>
 | 
			
		||||
    <keysym keyval="119" label="テ">w</keysym>
 | 
			
		||||
  <key keycode="29" name="AD06">
 | 
			
		||||
    <keysym keyval="1245">ん</keysym>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key keycode="20" name="AE06" groups="2">
 | 
			
		||||
    <keysym keyval="115" label="と">s</keysym>
 | 
			
		||||
    <keysym keyval="115" label="ト">s</keysym>
 | 
			
		||||
  <key keycode="30" name="AD07">
 | 
			
		||||
    <keysym keyval="1221">な</keysym>
 | 
			
		||||
  </key>
 | 
			
		||||
 | 
			
		||||
  <key keycode="21" name="AE03" groups="2">
 | 
			
		||||
    <keysym keyval="117" label="な">u</keysym>
 | 
			
		||||
    <keysym keyval="117" label="ナ">u</keysym>
 | 
			
		||||
  <key keycode="31" name="AD08">
 | 
			
		||||
    <keysym keyval="1222">に</keysym>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key keycode="22" name="AD03" groups="2">
 | 
			
		||||
    <keysym keyval="105" label="に">i</keysym>
 | 
			
		||||
    <keysym keyval="105" label="ニ">i</keysym>
 | 
			
		||||
  <key keycode="32" name="AD09">
 | 
			
		||||
    <keysym keyval="1239">ら</keysym>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key keycode="23" name="AE04" groups="2">
 | 
			
		||||
    <keysym keyval="33" label="ぬ">exclam</keysym>
 | 
			
		||||
    <keysym keyval="33" label="ヌ">exclam</keysym>
 | 
			
		||||
  <key keycode="33" name="AD10">
 | 
			
		||||
    <keysym keyval="1214">せ</keysym>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key keycode="24" name="AE05" groups="2">
 | 
			
		||||
    <keysym keyval="44" label="ね">comma</keysym>
 | 
			
		||||
    <keysym keyval="44" label="ネ">comma</keysym>
 | 
			
		||||
  <key keycode="34" name="AD11">
 | 
			
		||||
    <keysym keyval="1233">む</keysym>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key keycode="25" name="AE06" groups="2">
 | 
			
		||||
    <keysym keyval="107" label="の">k</keysym>
 | 
			
		||||
    <keysym keyval="107" label="ノ">k</keysym>
 | 
			
		||||
  <key keycode="35" name="AD12">
 | 
			
		||||
    <keysym keyval="1243">ろ</keysym>
 | 
			
		||||
  </key>
 | 
			
		||||
 | 
			
		||||
  <key keycode="26" name="AE03" groups="2">
 | 
			
		||||
    <keysym keyval="102" label="は">f</keysym>
 | 
			
		||||
    <keysym keyval="102" label="ハ">f</keysym>
 | 
			
		||||
  <key keycode="38" name="AC01">
 | 
			
		||||
    <keysym keyval="1217">ち</keysym>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key keycode="27" name="AD03" groups="2">
 | 
			
		||||
    <keysym keyval="118" label="ひ">v</keysym>
 | 
			
		||||
    <keysym keyval="118" label="ヒ">v</keysym>
 | 
			
		||||
  <key keycode="39" name="AC02">
 | 
			
		||||
    <keysym keyval="1220">と</keysym>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key keycode="28" name="AE04" groups="2">
 | 
			
		||||
    <keysym keyval="34" label="ふ">quotedbl</keysym>
 | 
			
		||||
    <keysym keyval="34" label="フ">quotedbl</keysym>
 | 
			
		||||
  <key keycode="40" name="AC03">
 | 
			
		||||
    <keysym keyval="1212">し</keysym>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key keycode="29" name="AE05" groups="2">
 | 
			
		||||
    <keysym keyval="94" label="へ">asciicircum</keysym>
 | 
			
		||||
    <keysym keyval="94" label="ヘ">asciicircum</keysym>
 | 
			
		||||
  <key keycode="41" name="AC04">
 | 
			
		||||
    <keysym keyval="1226">は</keysym>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key keycode="30" name="AE06" groups="2">
 | 
			
		||||
    <keysym keyval="61" label="ほ">equal</keysym>
 | 
			
		||||
    <keysym keyval="61" label="ホ">equal</keysym>
 | 
			
		||||
  <key keycode="42" name="AC05">
 | 
			
		||||
    <keysym keyval="1207">き</keysym>
 | 
			
		||||
  </key>
 | 
			
		||||
 | 
			
		||||
  <key keycode="31" name="AE03" groups="2">
 | 
			
		||||
    <keysym keyval="106" label="ま">j</keysym>
 | 
			
		||||
    <keysym keyval="106" label="マ">j</keysym>
 | 
			
		||||
  <key keycode="43" name="AC06">
 | 
			
		||||
    <keysym keyval="1208">く</keysym>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key keycode="32" name="AD03" groups="2">
 | 
			
		||||
    <keysym keyval="110" label="み">n</keysym>
 | 
			
		||||
    <keysym keyval="110" label="ミ">n</keysym>
 | 
			
		||||
  <key keycode="44" name="AC07">
 | 
			
		||||
    <keysym keyval="1231">ま</keysym>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key keycode="33" name="AE04" groups="2">
 | 
			
		||||
    <keysym keyval="93" label="む">bracketright</keysym>
 | 
			
		||||
    <keysym keyval="93" label="ム">bracketright</keysym>
 | 
			
		||||
  <key keycode="45" name="AC08">
 | 
			
		||||
    <keysym keyval="1225">の</keysym>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key keycode="34" name="AE05" groups="2">
 | 
			
		||||
    <keysym keyval="47" label="め">slash</keysym>
 | 
			
		||||
    <keysym keyval="47" label="メ">slash</keysym>
 | 
			
		||||
  <key keycode="46" name="AC09">
 | 
			
		||||
    <keysym keyval="1240">り</keysym>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key keycode="35" name="AE06" groups="2">
 | 
			
		||||
    <keysym keyval="109" label="も">m</keysym>
 | 
			
		||||
    <keysym keyval="109" label="モ">m</keysym>
 | 
			
		||||
  <key keycode="47" name="AC10">
 | 
			
		||||
    <keysym keyval="1242">れ</keysym>
 | 
			
		||||
  </key>
 | 
			
		||||
 | 
			
		||||
  <key keycode="36" name="AE03" groups="2">
 | 
			
		||||
    <keysym keyval="55" label="や">7</keysym>
 | 
			
		||||
    <keysym keyval="39" label="ゃ">quoteright</keysym>
 | 
			
		||||
    <keysym keyval="55" label="ヤ">7</keysym>
 | 
			
		||||
    <keysym keyval="39" label="ャ">quoteright</keysym>
 | 
			
		||||
  <key keycode="48" name="AC11">
 | 
			
		||||
    <keysym keyval="1209">け</keysym>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key keycode="37" name="AD03" groups="2">
 | 
			
		||||
    <keysym keyval="56" label="ゆ">8</keysym>
 | 
			
		||||
    <keysym keyval="40" label="ゅ">parenleft</keysym>
 | 
			
		||||
    <keysym keyval="56" label="ユ">8</keysym>
 | 
			
		||||
    <keysym keyval="40" label="ュ">parenleft</keysym>
 | 
			
		||||
  <key keycode="52" name="AB01">
 | 
			
		||||
    <keysym keyval="1218">つ</keysym>
 | 
			
		||||
    <keysym keyval="1199">っ</keysym>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key keycode="38" name="AE04" groups="2">
 | 
			
		||||
    <keysym keyval="57" label="よ">9</keysym>
 | 
			
		||||
    <keysym keyval="41" label="ょ">parenright</keysym>
 | 
			
		||||
    <keysym keyval="57" label="ヨ">9</keysym>
 | 
			
		||||
    <keysym keyval="41" label="ョ">parenright</keysym>
 | 
			
		||||
  <key keycode="53" name="AB02">
 | 
			
		||||
    <keysym keyval="1211">さ</keysym>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key keycode="41" name="AE03" groups="2">
 | 
			
		||||
    <keysym keyval="111" label="ら">o</keysym>
 | 
			
		||||
    <keysym keyval="111" label="ラ">o</keysym>
 | 
			
		||||
  <key keycode="54" name="AB03">
 | 
			
		||||
    <keysym keyval="1215">そ</keysym>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key keycode="42" name="AD03" groups="2">
 | 
			
		||||
    <keysym keyval="108" label="り">l</keysym>
 | 
			
		||||
    <keysym keyval="108" label="リ">l</keysym>
 | 
			
		||||
  <key keycode="55" name="AB04">
 | 
			
		||||
    <keysym keyval="1227">ひ</keysym>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key keycode="43" name="AE04" groups="2">
 | 
			
		||||
    <keysym keyval="46" label="る">period</keysym>
 | 
			
		||||
    <keysym keyval="46" label="ル">period</keysym>
 | 
			
		||||
  <key keycode="56" name="AB05">
 | 
			
		||||
    <keysym keyval="1210">こ</keysym>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key keycode="44" name="AE05" groups="2">
 | 
			
		||||
    <keysym keyval="59" label="れ">semicolon</keysym>
 | 
			
		||||
    <keysym keyval="59" label="レ">semicolon</keysym>
 | 
			
		||||
  <key keycode="57" name="AB06">
 | 
			
		||||
    <keysym keyval="1232">み</keysym>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key keycode="45" name="AE06" groups="2">
 | 
			
		||||
    <keysym keyval="92" label="ろ">backslash</keysym>
 | 
			
		||||
    <keysym keyval="92" label="ロ">backslash</keysym>
 | 
			
		||||
  <key keycode="58" name="AB07">
 | 
			
		||||
    <keysym keyval="1235">も</keysym>
 | 
			
		||||
  </key>
 | 
			
		||||
 | 
			
		||||
  <key keycode="46" name="AE03" groups="2">
 | 
			
		||||
    <keysym keyval="48" label="わ">0</keysym>
 | 
			
		||||
    <keysym keyval="48" label="ワ">0</keysym>
 | 
			
		||||
  <key keycode="59" name="AB08">
 | 
			
		||||
    <keysym keyval="1224">ね</keysym>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key keycode="47" name="AD03" groups="2">
 | 
			
		||||
    <keysym keyval="126" label="を">asciitilde</keysym>
 | 
			
		||||
    <keysym keyval="126" label="ヲ">asciitilde</keysym>
 | 
			
		||||
  <key keycode="60" name="AB09">
 | 
			
		||||
    <keysym keyval="1241">る</keysym>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key keycode="48" name="AE04" groups="2">
 | 
			
		||||
    <keysym keyval="121" label="ん">y</keysym>
 | 
			
		||||
    <keysym keyval="121" label="ン">y</keysym>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key keycode="49" name="AE05" groups="2">
 | 
			
		||||
    <keysym keyval="123" label="「">braceleft</keysym>
 | 
			
		||||
    <keysym keyval="48" label="ゐ">0</keysym>
 | 
			
		||||
    <keysym keyval="123" label="「">braceleft</keysym>
 | 
			
		||||
    <keysym keyval="48" label="ヰ">0</keysym>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key keycode="50" name="AE06" groups="2">
 | 
			
		||||
    <keysym keyval="125" label="」">braceright</keysym>
 | 
			
		||||
    <keysym keyval="48" label="ゑ">0</keysym>
 | 
			
		||||
    <keysym keyval="125" label="」">braceright</keysym>
 | 
			
		||||
    <keysym keyval="48" label="ヱ">0</keysym>
 | 
			
		||||
  </key>
 | 
			
		||||
 | 
			
		||||
  <key keycode="51" name="AE03" groups="2">
 | 
			
		||||
    <keysym keyval="64" label="゛">at</keysym>
 | 
			
		||||
    <keysym keyval="64" label="゛">at</keysym>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key keycode="52" name="AD03" groups="2">
 | 
			
		||||
    <keysym keyval="91" label="゜">bracketleft</keysym>
 | 
			
		||||
    <keysym keyval="91" label="゜">bracketleft</keysym>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key keycode="53" name="AE04" groups="2">
 | 
			
		||||
    <keysym keyval="124" label="ー">bar</keysym>
 | 
			
		||||
    <keysym keyval="124" label="ー">bar</keysym>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key keycode="54" name="AE05" groups="2">
 | 
			
		||||
    <keysym keyval="60" label="、">less</keysym>
 | 
			
		||||
    <keysym keyval="60" label="、">less</keysym>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key keycode="55" name="AE06" groups="2">
 | 
			
		||||
    <keysym keyval="62" label="。">greater</keysym>
 | 
			
		||||
    <keysym keyval="63" label="・">question</keysym>
 | 
			
		||||
    <keysym keyval="62" label="。">greater</keysym>
 | 
			
		||||
    <keysym keyval="63" label="・">question</keysym>
 | 
			
		||||
  <key keycode="61" name="AB10">
 | 
			
		||||
    <keysym keyval="1234">め</keysym>
 | 
			
		||||
  </key>
 | 
			
		||||
</symbols>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -93,7 +93,7 @@
 | 
			
		||||
    <keysym keyval="43">plus</keysym>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key keycode="22" name="BKSP">
 | 
			
		||||
    <keysym keyval="65288">BackSpace</keysym>
 | 
			
		||||
    <keysym keyval="65288" icon="edit-clear-symbolic">backspace</keysym>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key keycode="23" name="TAB">
 | 
			
		||||
    <keysym keyval="65289">Tab</keysym>
 | 
			
		||||
@ -102,42 +102,56 @@
 | 
			
		||||
  <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>
 | 
			
		||||
  <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>
 | 
			
		||||
  <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>
 | 
			
		||||
  <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>
 | 
			
		||||
  <key keycode="28" name="AD05">
 | 
			
		||||
    <keysym keyval="116">t</keysym>
 | 
			
		||||
    <keysym keyval="84">T</keysym>
 | 
			
		||||
    <keysym keyval="53">5</keysym>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key keycode="29" name="AD06">
 | 
			
		||||
    <keysym keyval="121">y</keysym>
 | 
			
		||||
    <keysym keyval="89">Y</keysym>
 | 
			
		||||
    <keysym keyval="54">6</keysym>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key keycode="30" name="AD07">
 | 
			
		||||
    <keysym keyval="117">u</keysym>
 | 
			
		||||
    <keysym keyval="85">U</keysym>
 | 
			
		||||
    <keysym keyval="55">7</keysym>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key keycode="31" name="AD08">
 | 
			
		||||
    <keysym keyval="105">i</keysym>
 | 
			
		||||
    <keysym keyval="73">I</keysym>
 | 
			
		||||
    <keysym keyval="56">8</keysym>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key keycode="32" name="AD09">
 | 
			
		||||
    <keysym keyval="111">o</keysym>
 | 
			
		||||
    <keysym keyval="79">O</keysym>
 | 
			
		||||
    <keysym keyval="57">9</keysym>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key keycode="33" name="AD10">
 | 
			
		||||
    <keysym keyval="112">p</keysym>
 | 
			
		||||
    <keysym keyval="80">P</keysym>
 | 
			
		||||
    <keysym keyval="48">0</keysym>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key keycode="34" name="AD11">
 | 
			
		||||
    <keysym keyval="91">bracketleft</keysym>
 | 
			
		||||
@ -151,44 +165,65 @@
 | 
			
		||||
    <keysym keyval="92">backslash</keysym>
 | 
			
		||||
    <keysym keyval="124">bar</keysym>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key keycode="66" name="CAPS">
 | 
			
		||||
  <key keycode="66" name="ALTGR">
 | 
			
		||||
    <keysym keyval="65027">ISO_Level3_Shift</keysym>
 | 
			
		||||
    <keysym keyval="65027">ISO_Level3_Shift</keysym>
 | 
			
		||||
    <keysym keyval="65027" label="ABC">ISO_Level3_Shift</keysym>
 | 
			
		||||
    <keysym keyval="65027" label="ABC">ISO_Level3_Shift</keysym>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key keycode="38" name="AC01">
 | 
			
		||||
    <keysym keyval="97">a</keysym>
 | 
			
		||||
    <keysym keyval="65">A</keysym>
 | 
			
		||||
    <keysym keyval="64">at</keysym>
 | 
			
		||||
    <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>
 | 
			
		||||
@ -203,34 +238,51 @@
 | 
			
		||||
  </key>
 | 
			
		||||
  <key keycode="50" name="LFSH">
 | 
			
		||||
    <keysym keyval="65505">Shift_L</keysym>
 | 
			
		||||
    <keysym keyval="65505">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>
 | 
			
		||||
  <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>
 | 
			
		||||
  <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>
 | 
			
		||||
  <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>
 | 
			
		||||
  <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>
 | 
			
		||||
  <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>
 | 
			
		||||
  <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>
 | 
			
		||||
  <key keycode="59" name="AB08">
 | 
			
		||||
    <keysym keyval="44">comma</keysym>
 | 
			
		||||
@ -248,10 +300,10 @@
 | 
			
		||||
    <keysym keyval="65506">Shift_R</keysym>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key keycode="149" name="I149">
 | 
			
		||||
    <symbol label="⌨" icon="input-keyboard-symbolic">cycle-keyboard</symbol>
 | 
			
		||||
    <symbol label="⌨" icon="input-keyboard-symbolic" tooltip="Change keyboard">cycle-keyboard</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key keycode="150" name="I150">
 | 
			
		||||
    <symbol label="☺" icon="preferences-system-symbolic">preferences</symbol>
 | 
			
		||||
    <symbol label="☺" icon="preferences-system-symbolic" tooltip="Setup">preferences</symbol>
 | 
			
		||||
  </key>
 | 
			
		||||
  <key keycode="37" name="LCTL">
 | 
			
		||||
    <keysym keyval="65507">Control_L</keysym>
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										19
									
								
								data/meson.build
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								data/meson.build
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,19 @@
 | 
			
		||||
gnome = import('gnome')
 | 
			
		||||
 | 
			
		||||
squeekboard_resources = gnome.compile_resources(
 | 
			
		||||
   'squeekboard-resources',
 | 
			
		||||
   'squeekboard.gresources.xml',
 | 
			
		||||
 | 
			
		||||
   c_name: 'squeekboard',
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
desktop_file = 'sm.puri.Squeekboard.desktop'
 | 
			
		||||
 | 
			
		||||
i18n.merge_file('desktop',
 | 
			
		||||
    input: desktop_file + '.in',
 | 
			
		||||
    output: desktop_file,
 | 
			
		||||
    po_dir: '../po',
 | 
			
		||||
    install: true,
 | 
			
		||||
    install_dir: join_paths(datadir, 'applications'),
 | 
			
		||||
    type: 'desktop'
 | 
			
		||||
)
 | 
			
		||||
@ -1,60 +0,0 @@
 | 
			
		||||
<?xml version="1.0"?>
 | 
			
		||||
<schemalist>
 | 
			
		||||
  <schema id="org.fedorahosted.eekboard" path="/org/fedorahosted/eekboard/">
 | 
			
		||||
    <key name="keyboards" type="as">
 | 
			
		||||
      <default>['us']</default>
 | 
			
		||||
      <summary>Keyboard types</summary>
 | 
			
		||||
      <description>keyboard types.</description>
 | 
			
		||||
    </key>
 | 
			
		||||
    <key name="focus-listener" type="s">
 | 
			
		||||
      <default>'atspi'</default>
 | 
			
		||||
      <summary>Use the given focus listener</summary>
 | 
			
		||||
      <description>The name of the focus listener (either 'atspi' or 'ibus') used to detect focus events.</description>
 | 
			
		||||
    </key>
 | 
			
		||||
    <key name="auto-hide" type="b">
 | 
			
		||||
      <default>true</default>
 | 
			
		||||
      <summary>Hide keyboard automatically when focus is out</summary>
 | 
			
		||||
      <description>If true, hide keyboard automatically when focus is out.</description>
 | 
			
		||||
    </key>
 | 
			
		||||
    <key name="auto-hide-delay" type="u">
 | 
			
		||||
      <default>500</default>
 | 
			
		||||
      <summary>Delay before hiding keyboard</summary>
 | 
			
		||||
      <description>Delay before hiding keyboard in milliseconds.  This is useful when focus listener is enabled.</description>
 | 
			
		||||
    </key>
 | 
			
		||||
    <key type="b" name="repeat">
 | 
			
		||||
      <default>true</default>
 | 
			
		||||
      <summary>Key repeat</summary>
 | 
			
		||||
      <description>Generate key-press/release event repeatedly while a key is held down</description>
 | 
			
		||||
    </key>
 | 
			
		||||
    <key type="u" name="repeat-interval">
 | 
			
		||||
      <default>100</default>
 | 
			
		||||
      <summary>Key repeat interval</summary>
 | 
			
		||||
      <description>Delay between repeats in milliseconds.</description>
 | 
			
		||||
    </key>
 | 
			
		||||
    <key type="u" name="repeat-delay">
 | 
			
		||||
      <default>1000</default>
 | 
			
		||||
      <summary>Initial key repeat delay</summary>
 | 
			
		||||
      <description>Initial key repeat delay in milliseconds.</description>
 | 
			
		||||
    </key>
 | 
			
		||||
    <key name="start-fullscreen" type="b">
 | 
			
		||||
      <default>false</default>
 | 
			
		||||
      <summary>Switch to fullscreen mode when startup</summary>
 | 
			
		||||
      <description>If true, switch to fullscreen mode when startup.</description>
 | 
			
		||||
    </key>
 | 
			
		||||
    <key name="size-constraint-landscape" type="(dd)">
 | 
			
		||||
      <default>(1.0, 0.3)</default>
 | 
			
		||||
      <summary>Constraint of the maximum window size on landscape screen</summary>
 | 
			
		||||
      <description>Constraint of maximum window size on landscape screen</description>
 | 
			
		||||
    </key>
 | 
			
		||||
    <key name="size-constraint-portrait" type="(dd)">
 | 
			
		||||
      <default>(1.0, 0.5)</default>
 | 
			
		||||
      <summary>Constraint of the maximum window size on portrait screen</summary>
 | 
			
		||||
      <description>Constraint of maximum window size on portrait screen</description>
 | 
			
		||||
    </key>
 | 
			
		||||
    <key name="theme" type="s">
 | 
			
		||||
      <default>'default'</default>
 | 
			
		||||
      <summary>Theme</summary>
 | 
			
		||||
      <description>Base name of the theme to apply.</description>
 | 
			
		||||
    </key>
 | 
			
		||||
  </schema>
 | 
			
		||||
</schemalist>
 | 
			
		||||
							
								
								
									
										9
									
								
								data/sm.puri.Squeekboard.desktop.in
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								data/sm.puri.Squeekboard.desktop.in
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,9 @@
 | 
			
		||||
[Desktop Entry]
 | 
			
		||||
Name=Squeekboard
 | 
			
		||||
GenericName=Squeekboard Virtual Keyboard
 | 
			
		||||
Comment=Virtual Keyboard
 | 
			
		||||
Exec=squeekboard
 | 
			
		||||
Icon=squeekboard
 | 
			
		||||
Terminal=false
 | 
			
		||||
Type=Application
 | 
			
		||||
Categories=GTK;Utility;
 | 
			
		||||
							
								
								
									
										36
									
								
								data/squeekboard.gresources.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								data/squeekboard.gresources.xml
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,36 @@
 | 
			
		||||
<?xml version="1.0" encoding="UTF-8"?>
 | 
			
		||||
<gresources>
 | 
			
		||||
  <gresource prefix="/sm/puri/squeekboard">
 | 
			
		||||
   <file compressed="true">style.css</file>
 | 
			
		||||
   <file compressed="true" preprocess="xml-stripblanks">keyboards/geometry/compact.xml</file>
 | 
			
		||||
   <file compressed="true" preprocess="xml-stripblanks">keyboards/keyboards.xml</file>
 | 
			
		||||
   <file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/ar.xml</file>
 | 
			
		||||
   <file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/as-inscript.xml</file>
 | 
			
		||||
   <file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/be.xml</file>
 | 
			
		||||
   <file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/bn-inscript.xml</file>
 | 
			
		||||
   <file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/fa.xml</file>
 | 
			
		||||
   <file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/gu-inscript.xml</file>
 | 
			
		||||
   <file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/he.xml</file>
 | 
			
		||||
   <file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/hi-inscript.xml</file>
 | 
			
		||||
   <file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/ja-kana.xml</file>
 | 
			
		||||
   <file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/kk.xml</file>
 | 
			
		||||
   <file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/kn-inscript.xml</file>
 | 
			
		||||
   <file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/ks-inscript.xml</file>
 | 
			
		||||
   <file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/ks.xml</file>
 | 
			
		||||
   <file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/mai-inscript.xml</file>
 | 
			
		||||
   <file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/ml-inscript.xml</file>
 | 
			
		||||
   <file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/mr-inscript.xml</file>
 | 
			
		||||
   <file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/my.xml</file>
 | 
			
		||||
   <file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/or-inscript.xml</file>
 | 
			
		||||
   <file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/pa-inscript.xml</file>
 | 
			
		||||
   <file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/ru.xml</file>
 | 
			
		||||
   <file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/sd-inscript.xml</file>
 | 
			
		||||
   <file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/ta-inscript.xml</file>
 | 
			
		||||
   <file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/te-inscript.xml</file>
 | 
			
		||||
   <file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/th.xml</file>
 | 
			
		||||
   <file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/ua.xml</file>
 | 
			
		||||
   <file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/ug.xml</file>
 | 
			
		||||
   <file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/us.xml</file>
 | 
			
		||||
   <file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/zh-bopomofo.xml</file>
 | 
			
		||||
  </gresource>
 | 
			
		||||
</gresources>
 | 
			
		||||
							
								
								
									
										18
									
								
								data/style.css
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								data/style.css
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,18 @@
 | 
			
		||||
.keyboard {
 | 
			
		||||
    background-color: rgba(0, 0, 0, 255);
 | 
			
		||||
    color: #ffffff;
 | 
			
		||||
    font-family: cantarell, sans-serif;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.key {
 | 
			
		||||
    color: #deddda;
 | 
			
		||||
    background: #464448;
 | 
			
		||||
    border-width: 0.5px;
 | 
			
		||||
    border-color: #5e5c64;
 | 
			
		||||
    border-radius: 2px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.key:active {
 | 
			
		||||
    background: #1c71d8;
 | 
			
		||||
    border-color: #3584e4;
 | 
			
		||||
}
 | 
			
		||||
@ -1,2 +0,0 @@
 | 
			
		||||
themedir = $(pkgdatadir)/themes
 | 
			
		||||
dist_theme_DATA = default.css
 | 
			
		||||
@ -1,22 +0,0 @@
 | 
			
		||||
.keyboard {
 | 
			
		||||
    background-color: rgba(0, 0, 0, 255);
 | 
			
		||||
    color: #ffffff;
 | 
			
		||||
    font-family: cantarell, sans-serif;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.key {
 | 
			
		||||
    color: #ffffff;
 | 
			
		||||
    background-gradient-direction: vertical;
 | 
			
		||||
    background-gradient-start: rgba(0, 0, 0, 255);
 | 
			
		||||
    background-gradient-end: rgba(64, 64, 64, 255);
 | 
			
		||||
    border-width: 2px;
 | 
			
		||||
    border-color: rgba(128, 128, 128, 255);
 | 
			
		||||
    border-radius: 3px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.key:active {
 | 
			
		||||
    background-gradient-direction: vertical;
 | 
			
		||||
    background-gradient-start: rgba(0, 0, 255, 255);
 | 
			
		||||
    background-gradient-end: rgba(64, 64, 255, 255);
 | 
			
		||||
    border-color: rgba(160, 160, 255, 255);
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										11
									
								
								debian/changelog
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								debian/changelog
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1,11 @@
 | 
			
		||||
squeekboard (1.0.10) unstable; urgency=medium
 | 
			
		||||
 | 
			
		||||
  * Use a shared DBus definition
 | 
			
		||||
 | 
			
		||||
 -- Dorota Czaplejewicz <dorota.czaplejewicz@puri.sm>  Tue, 02 Jul 2019 20:12:02 +0000
 | 
			
		||||
 | 
			
		||||
squeekboard (1.0.9) unstable; urgency=medium
 | 
			
		||||
 | 
			
		||||
  * Initial release.
 | 
			
		||||
 | 
			
		||||
 -- David Boddie <david.boddie@puri.sm>  Tue, 25 Jun 2019 19:33:00 +0200
 | 
			
		||||
							
								
								
									
										1
									
								
								debian/compat
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								debian/compat
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1 @@
 | 
			
		||||
10
 | 
			
		||||
							
								
								
									
										24
									
								
								debian/control
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								debian/control
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1,24 @@
 | 
			
		||||
Source: squeekboard
 | 
			
		||||
Section: x11
 | 
			
		||||
Priority: optional
 | 
			
		||||
Maintainer: Dorota Czaplejewicz <dorota.czaplejewicz@puri.sm>
 | 
			
		||||
Build-Depends:
 | 
			
		||||
 debhelper (>= 10),
 | 
			
		||||
 meson (>=0.43.0),
 | 
			
		||||
 pkg-config,
 | 
			
		||||
 libglib2.0-dev,
 | 
			
		||||
 libgtk-3-dev,
 | 
			
		||||
 libcroco3-dev,
 | 
			
		||||
 libwayland-dev (>= 1.16),
 | 
			
		||||
 rustc,
 | 
			
		||||
 wayland-protocols (>= 1.14)
 | 
			
		||||
Standards-Version: 4.1.3
 | 
			
		||||
Homepage: https://source.puri.sm/Librem5/squeekboard
 | 
			
		||||
 | 
			
		||||
Package: squeekboard
 | 
			
		||||
Architecture: linux-any
 | 
			
		||||
Depends:
 | 
			
		||||
 ${shlibs:Depends}
 | 
			
		||||
 ${misc:Depends}
 | 
			
		||||
Description: On-screen keyboard for Wayland
 | 
			
		||||
 Virtual keyboard supporting Wayland, built primarily for the Librem 5 phone.
 | 
			
		||||
							
								
								
									
										73
									
								
								debian/copyright
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										73
									
								
								debian/copyright
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1,73 @@
 | 
			
		||||
Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
 | 
			
		||||
Upstream-Name: evscript
 | 
			
		||||
Source: https://source.puri.sm/david.boddie/evscript
 | 
			
		||||
 | 
			
		||||
Files: *
 | 
			
		||||
Copyright: 2010-2011 Daiki Ueno <ueno@unixuser.org>
 | 
			
		||||
           2010-2011 Red Hat, Inc.
 | 
			
		||||
           2019 Purism SPC
 | 
			
		||||
License: GPL-3+
 | 
			
		||||
 | 
			
		||||
Files: eek/layersurface.c
 | 
			
		||||
       src/wayland.c
 | 
			
		||||
       src/key-emitter.c
 | 
			
		||||
       meson.build
 | 
			
		||||
       src/meson.build
 | 
			
		||||
       po/meson.build
 | 
			
		||||
Copyright: 2018-2019 Purism SPC
 | 
			
		||||
License: GPL-3+
 | 
			
		||||
 | 
			
		||||
Files: eekboard/keymap.c
 | 
			
		||||
Copyright: 2000 Red Hat, Inc.
 | 
			
		||||
           2019 Purism, SPC
 | 
			
		||||
License: LGPL-2+
 | 
			
		||||
 This library is free software; you can redistribute it and/or
 | 
			
		||||
 modify it under the terms of the GNU Lesser General Public
 | 
			
		||||
 License as published by the Free Software Foundation; either
 | 
			
		||||
 version 2 of the License, or (at your option) any later version.
 | 
			
		||||
 | 
			
		||||
 This library is distributed in the hope that it will be useful,
 | 
			
		||||
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.         See the GNU
 | 
			
		||||
 Lesser General Public License for more details.
 | 
			
		||||
 | 
			
		||||
 You should have received a copy of the GNU Lesser General Public
 | 
			
		||||
 License along with this library. If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 | 
			
		||||
Files: protocols/wlr-layer-shell-unstable-v1.xml
 | 
			
		||||
Copytight: Copyright © 2017 Drew DeVault
 | 
			
		||||
License: X11
 | 
			
		||||
 Permission to use, copy, modify, distribute, and sell this software and
 | 
			
		||||
 its documentation for any purpose is hereby granted without fee, provided
 | 
			
		||||
 that the above copyright notice appear in all copies and fthat both that
 | 
			
		||||
 copyright notice and this permission notice appear in supporting
 | 
			
		||||
 documentation, and that the name of the copyright holders not be used in
 | 
			
		||||
 advertising or publicity pertaining to distribution of the software
 | 
			
		||||
 without specific, written prior permission.  The copyright holders make
 | 
			
		||||
 no representations about the suitability of this software for any
 | 
			
		||||
 purpose.  It is provided "as is" without express or implied warranty.
 | 
			
		||||
 .
 | 
			
		||||
 THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
 | 
			
		||||
 SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
 | 
			
		||||
 FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
 | 
			
		||||
 SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
 | 
			
		||||
 RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
 | 
			
		||||
 CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
 | 
			
		||||
 CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 | 
			
		||||
 | 
			
		||||
License: GPL-3+
 | 
			
		||||
 This package is free software; you can redistribute it and/or modify
 | 
			
		||||
 it under the terms of the GNU General Public License as published by
 | 
			
		||||
 the Free Software Foundation; either version 3 of the License, or
 | 
			
		||||
 (at your option) any later version.
 | 
			
		||||
 .
 | 
			
		||||
 This package 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 <https://www.gnu.org/licenses/>
 | 
			
		||||
 .
 | 
			
		||||
 On Debian systems, the complete text of the GNU General
 | 
			
		||||
 Public License version 3 can be found in "/usr/share/common-licenses/GPL-3".
 | 
			
		||||
							
								
								
									
										8
									
								
								debian/rules
									
									
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										8
									
								
								debian/rules
									
									
									
									
										vendored
									
									
										Executable file
									
								
							@ -0,0 +1,8 @@
 | 
			
		||||
#!/usr/bin/make -f
 | 
			
		||||
 | 
			
		||||
export DEB_BUILD_MAINT_OPTIONS = hardening=+all
 | 
			
		||||
 | 
			
		||||
%:
 | 
			
		||||
	dh $@ --builddirectory=_build --buildsystem=meson
 | 
			
		||||
 | 
			
		||||
override_dh_autoreconf:
 | 
			
		||||
							
								
								
									
										1
									
								
								debian/source/format
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								debian/source/format
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1 @@
 | 
			
		||||
3.0 (native)
 | 
			
		||||
@ -1,19 +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
 | 
			
		||||
 | 
			
		||||
SUBDIRS = reference
 | 
			
		||||
@ -1,19 +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
 | 
			
		||||
 | 
			
		||||
SUBDIRS = eek eekboard
 | 
			
		||||
@ -1,131 +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
 | 
			
		||||
 | 
			
		||||
## Process this file with automake to produce Makefile.in
 | 
			
		||||
 | 
			
		||||
# We require automake 1.6 at least.
 | 
			
		||||
AUTOMAKE_OPTIONS = 1.6
 | 
			
		||||
 | 
			
		||||
# This is a blank Makefile.am for using gtk-doc.
 | 
			
		||||
# Copy this to your project's API docs directory and modify the variables to
 | 
			
		||||
# suit your project. See the GTK+ Makefiles in gtk+/docs/reference for examples
 | 
			
		||||
# of using the various options.
 | 
			
		||||
 | 
			
		||||
# The name of the module, e.g. 'glib'.
 | 
			
		||||
DOC_MODULE=eek
 | 
			
		||||
 | 
			
		||||
# Uncomment for versioned docs and specify the version of the module, e.g. '2'.
 | 
			
		||||
#DOC_MODULE_VERSION=2
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# The top-level SGML file. You can change this if you want to.
 | 
			
		||||
DOC_MAIN_SGML_FILE=$(DOC_MODULE)-docs.sgml
 | 
			
		||||
 | 
			
		||||
# The directory containing the source code. Relative to $(srcdir).
 | 
			
		||||
# gtk-doc will search all .c & .h files beneath here for inline comments
 | 
			
		||||
# documenting the functions and macros.
 | 
			
		||||
# e.g. DOC_SOURCE_DIR=../../../gtk
 | 
			
		||||
DOC_SOURCE_DIR=../../../eek
 | 
			
		||||
 | 
			
		||||
# Extra options to pass to gtkdoc-scangobj. Not normally needed.
 | 
			
		||||
SCANGOBJ_OPTIONS=
 | 
			
		||||
 | 
			
		||||
# Extra options to supply to gtkdoc-scan.
 | 
			
		||||
# e.g. SCAN_OPTIONS=--deprecated-guards="GTK_DISABLE_DEPRECATED"
 | 
			
		||||
SCAN_OPTIONS=--rebuild-types --deprecated-guards="EEK_DISABLE_DEPRECATED"
 | 
			
		||||
 | 
			
		||||
# Extra options to supply to gtkdoc-mkdb.
 | 
			
		||||
# e.g. MKDB_OPTIONS=--sgml-mode --output-format=xml
 | 
			
		||||
MKDB_OPTIONS=--sgml-mode --output-format=xml
 | 
			
		||||
 | 
			
		||||
# Extra options to supply to gtkdoc-mktmpl
 | 
			
		||||
# e.g. MKTMPL_OPTIONS=--only-section-tmpl
 | 
			
		||||
MKTMPL_OPTIONS=
 | 
			
		||||
 | 
			
		||||
# Extra options to supply to gtkdoc-mkhtml
 | 
			
		||||
MKHTML_OPTIONS=
 | 
			
		||||
 | 
			
		||||
# Extra options to supply to gtkdoc-fixref. Not normally needed.
 | 
			
		||||
# e.g. FIXXREF_OPTIONS=--extra-dir=../gdk-pixbuf/html --extra-dir=../gdk/html
 | 
			
		||||
FIXXREF_OPTIONS=
 | 
			
		||||
 | 
			
		||||
# Used for dependencies. The docs will be rebuilt if any of these change.
 | 
			
		||||
# e.g. HFILE_GLOB=$(top_srcdir)/gtk/*.h
 | 
			
		||||
# e.g. CFILE_GLOB=$(top_srcdir)/gtk/*.c
 | 
			
		||||
HFILE_GLOB=$(top_srcdir)/eek/*.h
 | 
			
		||||
CFILE_GLOB=$(top_srcdir)/eek/*.c
 | 
			
		||||
 | 
			
		||||
# Extra header to include when scanning, which are not under DOC_SOURCE_DIR
 | 
			
		||||
# e.g. EXTRA_HFILES=$(top_srcdir}/contrib/extra.h
 | 
			
		||||
EXTRA_HFILES=
 | 
			
		||||
 | 
			
		||||
# Header files to ignore when scanning. Use base file name, no paths
 | 
			
		||||
# e.g. IGNORE_HFILES=gtkdebug.h gtkintl.h
 | 
			
		||||
IGNORE_HFILES = \
 | 
			
		||||
	config.h \
 | 
			
		||||
	eek-renderer.h \
 | 
			
		||||
	eek-gtk-renderer.h \
 | 
			
		||||
	eek-theme.h \
 | 
			
		||||
	eek-theme-node.h \
 | 
			
		||||
	eek-enumtypes.h
 | 
			
		||||
 | 
			
		||||
# Images to copy into HTML directory.
 | 
			
		||||
# e.g. HTML_IMAGES=$(top_srcdir)/gtk/stock-icons/stock_about_24.png
 | 
			
		||||
HTML_IMAGES=
 | 
			
		||||
 | 
			
		||||
# Extra SGML files that are included by $(DOC_MAIN_SGML_FILE).
 | 
			
		||||
# e.g. content_files=running.sgml building.sgml changes-2.0.sgml
 | 
			
		||||
content_files=eek-overview.xml
 | 
			
		||||
 | 
			
		||||
# SGML files where gtk-doc abbrevations (#GtkWidget) are expanded
 | 
			
		||||
# These files must be listed here *and* in content_files
 | 
			
		||||
# e.g. expand_content_files=running.sgml
 | 
			
		||||
expand_content_files=eek-overview.xml
 | 
			
		||||
 | 
			
		||||
# CFLAGS and LDFLAGS for compiling gtkdoc-scangobj with your library.
 | 
			
		||||
# Only needed if you are using gtkdoc-scangobj to dynamically query widget
 | 
			
		||||
# signals and properties.
 | 
			
		||||
# e.g. GTKDOC_CFLAGS=-I$(top_srcdir) -I$(top_builddir) $(GTK_DEBUG_FLAGS)
 | 
			
		||||
# e.g. GTKDOC_LIBS=$(top_builddir)/gtk/$(gtktargetlib)
 | 
			
		||||
GTKDOC_CFLAGS = $(GIO2_CFLAGS)
 | 
			
		||||
GTKDOC_LIBS = $(top_builddir)/eek/libeek.la \
 | 
			
		||||
	$(top_builddir)/eek/libeek-gtk.la \
 | 
			
		||||
	$(top_builddir)/eek/libeek-xkl.la \
 | 
			
		||||
	$(GIO2_LIBS) \
 | 
			
		||||
	$(GTK_LIBS) \
 | 
			
		||||
	$(LIBXKLAVIER_LIBS)
 | 
			
		||||
 | 
			
		||||
# This includes the standard gtk-doc make rules, copied by gtkdocize.
 | 
			
		||||
include $(top_srcdir)/gtk-doc.make
 | 
			
		||||
 | 
			
		||||
# Other files to distribute
 | 
			
		||||
# e.g. EXTRA_DIST += version.xml.in
 | 
			
		||||
EXTRA_DIST +=
 | 
			
		||||
 | 
			
		||||
# Files not to distribute
 | 
			
		||||
# for --rebuild-types in $(SCAN_OPTIONS), e.g. $(DOC_MODULE).types
 | 
			
		||||
# for --rebuild-sections in $(SCAN_OPTIONS) e.g. $(DOC_MODULE)-sections.txt
 | 
			
		||||
#DISTCLEANFILES +=
 | 
			
		||||
 | 
			
		||||
# Comment this out if you want your docs-status tested during 'make check'
 | 
			
		||||
if ENABLE_GTK_DOC
 | 
			
		||||
#TESTS_ENVIRONMENT = cd $(srcsrc) &&
 | 
			
		||||
#TESTS = $(GTKDOC_CHECK)
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
-include $(top_srcdir)/gtk-doc.mk
 | 
			
		||||
@ -1,120 +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
 | 
			
		||||
 | 
			
		||||
## Process this file with automake to produce Makefile.in
 | 
			
		||||
 | 
			
		||||
# We require automake 1.6 at least.
 | 
			
		||||
AUTOMAKE_OPTIONS = 1.6
 | 
			
		||||
 | 
			
		||||
# This is a blank Makefile.am for using gtk-doc.
 | 
			
		||||
# Copy this to your project's API docs directory and modify the variables to
 | 
			
		||||
# suit your project. See the GTK+ Makefiles in gtk+/docs/reference for examples
 | 
			
		||||
# of using the various options.
 | 
			
		||||
 | 
			
		||||
# The name of the module, e.g. 'glib'.
 | 
			
		||||
DOC_MODULE=eekboard
 | 
			
		||||
 | 
			
		||||
# Uncomment for versioned docs and specify the version of the module, e.g. '2'.
 | 
			
		||||
#DOC_MODULE_VERSION=2
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# The top-level SGML file. You can change this if you want to.
 | 
			
		||||
DOC_MAIN_SGML_FILE=$(DOC_MODULE)-docs.sgml
 | 
			
		||||
 | 
			
		||||
# The directory containing the source code. Relative to $(srcdir).
 | 
			
		||||
# gtk-doc will search all .c & .h files beneath here for inline comments
 | 
			
		||||
# documenting the functions and macros.
 | 
			
		||||
# e.g. DOC_SOURCE_DIR=../../../gtk
 | 
			
		||||
DOC_SOURCE_DIR=../../../eekboard
 | 
			
		||||
 | 
			
		||||
# Extra options to pass to gtkdoc-scangobj. Not normally needed.
 | 
			
		||||
SCANGOBJ_OPTIONS=
 | 
			
		||||
 | 
			
		||||
# Extra options to supply to gtkdoc-scan.
 | 
			
		||||
# e.g. SCAN_OPTIONS=--deprecated-guards="GTK_DISABLE_DEPRECATED"
 | 
			
		||||
SCAN_OPTIONS=
 | 
			
		||||
 | 
			
		||||
# Extra options to supply to gtkdoc-mkdb.
 | 
			
		||||
# e.g. MKDB_OPTIONS=--sgml-mode --output-format=xml
 | 
			
		||||
MKDB_OPTIONS=--sgml-mode --output-format=xml
 | 
			
		||||
 | 
			
		||||
# Extra options to supply to gtkdoc-mktmpl
 | 
			
		||||
# e.g. MKTMPL_OPTIONS=--only-section-tmpl
 | 
			
		||||
MKTMPL_OPTIONS=
 | 
			
		||||
 | 
			
		||||
# Extra options to supply to gtkdoc-mkhtml
 | 
			
		||||
MKHTML_OPTIONS=
 | 
			
		||||
 | 
			
		||||
# Extra options to supply to gtkdoc-fixref. Not normally needed.
 | 
			
		||||
# e.g. FIXXREF_OPTIONS=--extra-dir=../gdk-pixbuf/html --extra-dir=../gdk/html
 | 
			
		||||
FIXXREF_OPTIONS=
 | 
			
		||||
 | 
			
		||||
# Used for dependencies. The docs will be rebuilt if any of these change.
 | 
			
		||||
# e.g. HFILE_GLOB=$(top_srcdir)/gtk/*.h
 | 
			
		||||
# e.g. CFILE_GLOB=$(top_srcdir)/gtk/*.c
 | 
			
		||||
HFILE_GLOB=$(top_srcdir)/eekboard/*.h
 | 
			
		||||
CFILE_GLOB=$(top_srcdir)/eekboard/*.c
 | 
			
		||||
 | 
			
		||||
# Extra header to include when scanning, which are not under DOC_SOURCE_DIR
 | 
			
		||||
# e.g. EXTRA_HFILES=$(top_srcdir}/contrib/extra.h
 | 
			
		||||
EXTRA_HFILES=
 | 
			
		||||
 | 
			
		||||
# Header files to ignore when scanning. Use base file name, no paths
 | 
			
		||||
# e.g. IGNORE_HFILES=gtkdebug.h gtkintl.h
 | 
			
		||||
IGNORE_HFILES=config.h eekboard.h
 | 
			
		||||
 | 
			
		||||
# Images to copy into HTML directory.
 | 
			
		||||
# e.g. HTML_IMAGES=$(top_srcdir)/gtk/stock-icons/stock_about_24.png
 | 
			
		||||
HTML_IMAGES=
 | 
			
		||||
 | 
			
		||||
# Extra SGML files that are included by $(DOC_MAIN_SGML_FILE).
 | 
			
		||||
# e.g. content_files=running.sgml building.sgml changes-2.0.sgml
 | 
			
		||||
# content_files=eekboard-overview.xml
 | 
			
		||||
 | 
			
		||||
# SGML files where gtk-doc abbrevations (#GtkWidget) are expanded
 | 
			
		||||
# These files must be listed here *and* in content_files
 | 
			
		||||
# e.g. expand_content_files=running.sgml
 | 
			
		||||
# expand_content_files=eekboard-overview.xml
 | 
			
		||||
 | 
			
		||||
# CFLAGS and LDFLAGS for compiling gtkdoc-scangobj with your library.
 | 
			
		||||
# Only needed if you are using gtkdoc-scangobj to dynamically query widget
 | 
			
		||||
# signals and properties.
 | 
			
		||||
# e.g. GTKDOC_CFLAGS=-I$(top_srcdir) -I$(top_builddir) $(GTK_DEBUG_FLAGS)
 | 
			
		||||
# e.g. GTKDOC_LIBS=$(top_builddir)/gtk/$(gtktargetlib)
 | 
			
		||||
GTKDOC_CFLAGS = $(GIO2_CFLAGS)
 | 
			
		||||
GTKDOC_LIBS = $(top_builddir)/eekboard/libeekboard.la $(GIO2_LIBS)
 | 
			
		||||
 | 
			
		||||
# This includes the standard gtk-doc make rules, copied by gtkdocize.
 | 
			
		||||
include $(top_srcdir)/gtk-doc.make
 | 
			
		||||
 | 
			
		||||
# Other files to distribute
 | 
			
		||||
# e.g. EXTRA_DIST += version.xml.in
 | 
			
		||||
# EXTRA_DIST +=
 | 
			
		||||
 | 
			
		||||
# Files not to distribute
 | 
			
		||||
# for --rebuild-types in $(SCAN_OPTIONS), e.g. $(DOC_MODULE).types
 | 
			
		||||
# for --rebuild-sections in $(SCAN_OPTIONS) e.g. $(DOC_MODULE)-sections.txt
 | 
			
		||||
#DISTCLEANFILES +=
 | 
			
		||||
 | 
			
		||||
# Comment this out if you want your docs-status tested during 'make check'
 | 
			
		||||
if ENABLE_GTK_DOC
 | 
			
		||||
#TESTS_ENVIRONMENT = cd $(srcsrc) &&
 | 
			
		||||
#TESTS = $(GTKDOC_CHECK)
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
-include $(top_srcdir)/gtk-doc.mk
 | 
			
		||||
							
								
								
									
										241
									
								
								eek/Makefile.am
									
									
									
									
									
								
							
							
						
						
									
										241
									
								
								eek/Makefile.am
									
									
									
									
									
								
							@ -1,241 +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
 | 
			
		||||
 | 
			
		||||
lib_LTLIBRARIES =				\
 | 
			
		||||
	libeek.la				\
 | 
			
		||||
	libeek-gtk.la				\
 | 
			
		||||
	libeek-xkl.la
 | 
			
		||||
 | 
			
		||||
libeek_public_headers =				\
 | 
			
		||||
	$(srcdir)/eek-layout.h			\
 | 
			
		||||
	$(srcdir)/eek-element.h			\
 | 
			
		||||
	$(srcdir)/eek-container.h		\
 | 
			
		||||
	$(srcdir)/eek-keyboard.h		\
 | 
			
		||||
	$(srcdir)/eek-section.h			\
 | 
			
		||||
	$(srcdir)/eek-key.h			\
 | 
			
		||||
	$(srcdir)/eek-symbol.h			\
 | 
			
		||||
	$(srcdir)/eek-keysym.h			\
 | 
			
		||||
	$(srcdir)/eek-text.h			\
 | 
			
		||||
	$(srcdir)/eek-symbol-matrix.h		\
 | 
			
		||||
	$(srcdir)/eek-types.h			\
 | 
			
		||||
	$(srcdir)/eek-xml.h			\
 | 
			
		||||
	$(srcdir)/eek-xml-layout.h		\
 | 
			
		||||
	$(srcdir)/eek-serializable.h		\
 | 
			
		||||
	$(srcdir)/eek-theme.h			\
 | 
			
		||||
	$(srcdir)/eek.h
 | 
			
		||||
 | 
			
		||||
libeek_private_headers =			\
 | 
			
		||||
	$(srcdir)/eek-renderer.h		\
 | 
			
		||||
	$(srcdir)/eek-special-keysym-entries.h	\
 | 
			
		||||
	$(srcdir)/eek-unicode-keysym-entries.h	\
 | 
			
		||||
	$(srcdir)/eek-xkeysym-keysym-entries.h	\
 | 
			
		||||
	$(srcdir)/eek-marshalers.h		\
 | 
			
		||||
	$(srcdir)/eek-theme-context.h		\
 | 
			
		||||
	$(srcdir)/eek-theme-private.h		\
 | 
			
		||||
	$(srcdir)/eek-theme-node.h
 | 
			
		||||
 | 
			
		||||
libeek_sources =				\
 | 
			
		||||
	$(srcdir)/eek.c				\
 | 
			
		||||
	$(srcdir)/eek-layout.c			\
 | 
			
		||||
	$(srcdir)/eek-element.c			\
 | 
			
		||||
	$(srcdir)/eek-container.c		\
 | 
			
		||||
	$(srcdir)/eek-keyboard.c		\
 | 
			
		||||
	$(srcdir)/eek-section.c			\
 | 
			
		||||
	$(srcdir)/eek-key.c			\
 | 
			
		||||
	$(srcdir)/eek-symbol-matrix.c		\
 | 
			
		||||
	$(srcdir)/eek-symbol.c			\
 | 
			
		||||
	$(srcdir)/eek-keysym.c			\
 | 
			
		||||
	$(srcdir)/eek-text.c			\
 | 
			
		||||
	$(srcdir)/eek-types.c			\
 | 
			
		||||
	$(srcdir)/eek-serializable.c		\
 | 
			
		||||
	$(srcdir)/eek-xml.c			\
 | 
			
		||||
	$(srcdir)/eek-xml-layout.c		\
 | 
			
		||||
	$(srcdir)/eek-renderer.c		\
 | 
			
		||||
	$(srcdir)/eek-keyboard-drawing.c	\
 | 
			
		||||
	$(srcdir)/eek-theme.c			\
 | 
			
		||||
	$(srcdir)/eek-theme-context.c		\
 | 
			
		||||
	$(srcdir)/eek-theme-node.c
 | 
			
		||||
 | 
			
		||||
libeek_keysym_sources =				\
 | 
			
		||||
	$(srcdir)/eek-special-keysym-entries.h	\
 | 
			
		||||
	$(srcdir)/eek-unicode-keysym-entries.h	\
 | 
			
		||||
	$(srcdir)/eek-xkeysym-keysym-entries.h
 | 
			
		||||
 | 
			
		||||
libeek_enumtypes_sources =			\
 | 
			
		||||
	$(srcdir)/eek-enumtypes.c		\
 | 
			
		||||
	$(srcdir)/eek-enumtypes.h
 | 
			
		||||
 | 
			
		||||
libeek_marshalers_sources =			\
 | 
			
		||||
	$(srcdir)/eek-marshalers.c		\
 | 
			
		||||
	$(srcdir)/eek-marshalers.h
 | 
			
		||||
 | 
			
		||||
BUILT_SOURCES =					\
 | 
			
		||||
	$(libeek_keysym_sources)		\
 | 
			
		||||
	$(libeek_enumtypes_sources)		\
 | 
			
		||||
	$(libeek_marshalers_sources)
 | 
			
		||||
 | 
			
		||||
libeek_la_SOURCES =				\
 | 
			
		||||
	$(libeek_sources)			\
 | 
			
		||||
	$(srcdir)/eek-enumtypes.c		\
 | 
			
		||||
	$(srcdir)/eek-marshalers.c
 | 
			
		||||
 | 
			
		||||
libeek_la_CFLAGS =					\
 | 
			
		||||
	-DEEK_COMPILATION=1				\
 | 
			
		||||
	-DKEYBOARDSDIR=\"$(pkgdatadir)/keyboards\"	\
 | 
			
		||||
	$(GIO2_CFLAGS)					\
 | 
			
		||||
	$(PANGOCAIRO_CFLAGS)				\
 | 
			
		||||
	$(LIBCROCO_CFLAGS)				\
 | 
			
		||||
	$(NULL)
 | 
			
		||||
 | 
			
		||||
libeek_la_LIBADD =				\
 | 
			
		||||
	$(GIO2_LIBS)				\
 | 
			
		||||
	$(PANGOCAIRO_LIBS)			\
 | 
			
		||||
	$(LIBCROCO_LIBS)			\
 | 
			
		||||
	-lm					\
 | 
			
		||||
	$(NULL)
 | 
			
		||||
 | 
			
		||||
libeek_gtk_public_headers =			\
 | 
			
		||||
	$(srcdir)/eek-gtk-keyboard.h		\
 | 
			
		||||
	$(srcdir)/eek-gtk.h
 | 
			
		||||
libeek_gtk_private_headers =			\
 | 
			
		||||
	$(srcdir)/eek-gtk-renderer.h
 | 
			
		||||
libeek_gtk_sources =				\
 | 
			
		||||
	$(srcdir)/eek-gtk-keyboard.c		\
 | 
			
		||||
	$(srcdir)/eek-gtk-renderer.c
 | 
			
		||||
 | 
			
		||||
libeek_gtk_la_SOURCES = $(libeek_gtk_sources)
 | 
			
		||||
libeek_gtk_la_CFLAGS = -DEEK_COMPILATION=1 $(GTK_CFLAGS) $(LIBCANBERRA_CFLAGS)
 | 
			
		||||
libeek_gtk_la_LIBADD = libeek.la $(GTK_LIBS) $(LIBCANBERRA_LIBS)
 | 
			
		||||
 | 
			
		||||
libeek_xkl_public_headers =			\
 | 
			
		||||
	$(srcdir)/eek-xkl-layout.h		\
 | 
			
		||||
	$(srcdir)/eek-xkl.h			\
 | 
			
		||||
	$(srcdir)/eek-xkb-layout.h		\
 | 
			
		||||
	$(srcdir)/eek-xkb.h
 | 
			
		||||
 | 
			
		||||
libeek_xkl_sources =				\
 | 
			
		||||
	$(srcdir)/eek-xkb-layout.c		\
 | 
			
		||||
	$(srcdir)/eek-xkl-layout.c
 | 
			
		||||
 | 
			
		||||
libeek_xkl_la_SOURCES = $(libeek_xkl_sources)
 | 
			
		||||
libeek_xkl_la_CFLAGS = -DEEK_COMPILATION=1 $(LIBXKLAVIER_CFLAGS)
 | 
			
		||||
libeek_xkl_la_LIBADD = libeek.la $(LIBXKLAVIER_LIBS)
 | 
			
		||||
 | 
			
		||||
eekdir = $(includedir)/eek-$(EEK_API_VERSION)/eek
 | 
			
		||||
eek_HEADERS =					\
 | 
			
		||||
	$(libeek_public_headers)		\
 | 
			
		||||
	$(srcdir)/eek-enumtypes.h		\
 | 
			
		||||
	$(libeek_gtk_public_headers)		\
 | 
			
		||||
	$(libeek_xkl_public_headers)
 | 
			
		||||
 | 
			
		||||
noinst_HEADERS =				\
 | 
			
		||||
	$(libeek_private_headers)		\
 | 
			
		||||
	$(libeek_gtk_private_headers)		\
 | 
			
		||||
	$(libeek_xkl_private_headers)
 | 
			
		||||
 | 
			
		||||
eek-special-keysym-entries.h: special-keysym-entries.txt
 | 
			
		||||
	$(AM_V_GEN) $(PYTHON) ./gen-keysym-entries.py special_keysym_entries \
 | 
			
		||||
		< $< > $@
 | 
			
		||||
eek-unicode-keysym-entries.h: unicode-keysym-entries.txt
 | 
			
		||||
	$(AM_V_GEN) $(PYTHON) ./gen-keysym-entries.py unicode_keysym_entries \
 | 
			
		||||
		< $< > $@
 | 
			
		||||
eek-xkeysym-keysym-entries.h: xkeysym-keysym-entries.txt
 | 
			
		||||
	$(AM_V_GEN) $(PYTHON) ./gen-keysym-entries.py xkeysym_keysym_entries \
 | 
			
		||||
		< $< > $@
 | 
			
		||||
 | 
			
		||||
eek-enumtypes.h: $(libeek_public_headers) eek-enumtypes.h.template
 | 
			
		||||
	$(AM_V_GEN) $(GLIB_MKENUMS) --template eek-enumtypes.h.template \
 | 
			
		||||
		$(libeek_public_headers) > eek-enumtypes.h.tmp && \
 | 
			
		||||
		mv eek-enumtypes.h.tmp eek-enumtypes.h
 | 
			
		||||
 | 
			
		||||
eek-enumtypes.c: $(libeek_public_headers) eek-enumtypes.c.template
 | 
			
		||||
	$(AM_V_GEN) $(GLIB_MKENUMS) --template eek-enumtypes.c.template \
 | 
			
		||||
		$(libeek_public_headers) > eek-enumtypes.c.tmp && \
 | 
			
		||||
		mv eek-enumtypes.c.tmp eek-enumtypes.c
 | 
			
		||||
 | 
			
		||||
# gen marshal
 | 
			
		||||
eek-marshalers.h: eek-marshalers.list
 | 
			
		||||
	$(AM_V_GEN) $(GLIB_GENMARSHAL) --prefix=_eek_marshal $(srcdir)/eek-marshalers.list --header --internal > $@.tmp && \
 | 
			
		||||
	mv $@.tmp $@
 | 
			
		||||
 | 
			
		||||
eek-marshalers.c: eek-marshalers.list eek-marshalers.h
 | 
			
		||||
	$(AM_V_GEN) (echo "#include \"eek-marshalers.h\""; \
 | 
			
		||||
	$(GLIB_GENMARSHAL) --prefix=_eek_marshal $(srcdir)/eek-marshalers.list --body --internal) > $@.tmp && \
 | 
			
		||||
	mv $@.tmp $@
 | 
			
		||||
 | 
			
		||||
pkgconfigdir = $(libdir)/pkgconfig
 | 
			
		||||
pkgconfig_DATA =				\
 | 
			
		||||
	eek-$(EEK_API_VERSION).pc		\
 | 
			
		||||
	eek-gtk-$(EEK_API_VERSION).pc		\
 | 
			
		||||
	eek-xkl-$(EEK_API_VERSION).pc
 | 
			
		||||
 | 
			
		||||
CLEANFILES =
 | 
			
		||||
 | 
			
		||||
DISTCLEANFILES =				\
 | 
			
		||||
	$(BUILT_SOURCES)			\
 | 
			
		||||
	$(pkgconfig_DATA)
 | 
			
		||||
 | 
			
		||||
EXTRA_DIST =					\
 | 
			
		||||
	gen-keysym-entries.py			\
 | 
			
		||||
	special-keysym-entries.txt		\
 | 
			
		||||
	unicode-keysym-entries.txt		\
 | 
			
		||||
	xkeysym-keysym-entries.txt		\
 | 
			
		||||
	eek-enumtypes.h.template		\
 | 
			
		||||
	eek-enumtypes.c.template		\
 | 
			
		||||
	eek-marshalers.list
 | 
			
		||||
 | 
			
		||||
-include $(INTROSPECTION_MAKEFILE)
 | 
			
		||||
INTROSPECTION_GIRS =
 | 
			
		||||
INTROSPECTION_SCANNER_ARGS = --add-include-path=$(builddir)
 | 
			
		||||
INTROSPECTION_COMPILER_ARGS = --includedir=$(srcdir)
 | 
			
		||||
 | 
			
		||||
if HAVE_INTROSPECTION
 | 
			
		||||
 | 
			
		||||
Eek@EEK_LIBRARY_SUFFIX@.gir: libeek.la
 | 
			
		||||
Eek@EEK_LIBRARY_SUFFIX_U@_gir_SCANNERFLAGS = --strip-prefix=Eek --pkg=glib-2.0 --pkg-export=eek-$(EEK_API_VERSION)
 | 
			
		||||
Eek@EEK_LIBRARY_SUFFIX_U@_gir_INCLUDES = GLib-2.0 GObject-2.0 Gio-2.0
 | 
			
		||||
Eek@EEK_LIBRARY_SUFFIX_U@_gir_CFLAGS = $(libeek_la_CFLAGS)
 | 
			
		||||
Eek@EEK_LIBRARY_SUFFIX_U@_gir_LIBS = libeek.la
 | 
			
		||||
Eek@EEK_LIBRARY_SUFFIX_U@_gir_FILES = $(libeek_sources) $(libeek_public_headers) $(srcdir)/eek-enumtypes.h
 | 
			
		||||
 | 
			
		||||
EekGtk@EEK_LIBRARY_SUFFIX@.gir: libeek-gtk.la Eek@EEK_LIBRARY_SUFFIX@.gir
 | 
			
		||||
EekGtk@EEK_LIBRARY_SUFFIX_U@_gir_SCANNERFLAGS = --pkg-export=eek-gtk-$(EEK_API_VERSION)
 | 
			
		||||
EekGtk@EEK_LIBRARY_SUFFIX_U@_gir_INCLUDES = GObject-2.0 Gtk-@GTK_API_VERSION@ Eek@EEK_LIBRARY_SUFFIX@
 | 
			
		||||
EekGtk@EEK_LIBRARY_SUFFIX_U@_gir_CFLAGS = $(libeek_gtk_la_CFLAGS)
 | 
			
		||||
EekGtk@EEK_LIBRARY_SUFFIX_U@_gir_LIBS = libeek-gtk.la
 | 
			
		||||
EekGtk@EEK_LIBRARY_SUFFIX_U@_gir_FILES = $(libeek_gtk_sources) $(libeek_gtk_public_headers)
 | 
			
		||||
 | 
			
		||||
EekXkl@EEK_LIBRARY_SUFFIX@.gir: libeek-xkl.la Eek@EEK_LIBRARY_SUFFIX@.gir
 | 
			
		||||
EekXkl@EEK_LIBRARY_SUFFIX_U@_gir_INCLUDES = GObject-2.0 Eek@EEK_LIBRARY_SUFFIX@
 | 
			
		||||
EekXkl@EEK_LIBRARY_SUFFIX_U@_gir_CFLAGS = $(libeek_xkl_la_CFLAGS)
 | 
			
		||||
EekXkl@EEK_LIBRARY_SUFFIX_U@_gir_LIBS = libeek-xkl.la
 | 
			
		||||
EekXkl@EEK_LIBRARY_SUFFIX_U@_gir_FILES = $(libeek_xkl_sources) $(libeek_xkl_public_headers)
 | 
			
		||||
 | 
			
		||||
INTROSPECTION_GIRS +=				\
 | 
			
		||||
	Eek@EEK_LIBRARY_SUFFIX@.gir		\
 | 
			
		||||
	EekGtk@EEK_LIBRARY_SUFFIX@.gir		\
 | 
			
		||||
	EekXkl@EEK_LIBRARY_SUFFIX@.gir
 | 
			
		||||
 | 
			
		||||
girdir = $(datadir)/gir-1.0
 | 
			
		||||
gir_DATA = $(INTROSPECTION_GIRS)
 | 
			
		||||
 | 
			
		||||
typelibdir = $(libdir)/girepository-1.0
 | 
			
		||||
typelib_DATA = $(INTROSPECTION_GIRS:.gir=.typelib)
 | 
			
		||||
 | 
			
		||||
CLEANFILES += $(gir_DATA) $(typelib_DATA)
 | 
			
		||||
endif
 | 
			
		||||
@ -40,23 +40,19 @@ enum {
 | 
			
		||||
 | 
			
		||||
static guint signals[LAST_SIGNAL] = { 0, };
 | 
			
		||||
 | 
			
		||||
G_DEFINE_ABSTRACT_TYPE (EekContainer, eek_container, EEK_TYPE_ELEMENT);
 | 
			
		||||
 | 
			
		||||
#define EEK_CONTAINER_GET_PRIVATE(obj)                                  \
 | 
			
		||||
    (G_TYPE_INSTANCE_GET_PRIVATE ((obj), EEK_TYPE_CONTAINER, EekContainerPrivate))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
struct _EekContainerPrivate
 | 
			
		||||
typedef struct _EekContainerPrivate
 | 
			
		||||
{
 | 
			
		||||
    GList *head;
 | 
			
		||||
    GList *last;
 | 
			
		||||
};
 | 
			
		||||
} EekContainerPrivate;
 | 
			
		||||
 | 
			
		||||
G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (EekContainer, eek_container, EEK_TYPE_ELEMENT)
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
eek_container_real_add_child (EekContainer *self,
 | 
			
		||||
                              EekElement   *child)
 | 
			
		||||
{
 | 
			
		||||
    EekContainerPrivate *priv = EEK_CONTAINER_GET_PRIVATE(self);
 | 
			
		||||
    EekContainerPrivate *priv = eek_container_get_instance_private (self);
 | 
			
		||||
 | 
			
		||||
    g_return_if_fail (EEK_IS_ELEMENT(child));
 | 
			
		||||
    g_object_ref (child);
 | 
			
		||||
@ -75,7 +71,7 @@ static void
 | 
			
		||||
eek_container_real_remove_child (EekContainer *self,
 | 
			
		||||
                                 EekElement   *child)
 | 
			
		||||
{
 | 
			
		||||
    EekContainerPrivate *priv = EEK_CONTAINER_GET_PRIVATE(self);
 | 
			
		||||
    EekContainerPrivate *priv = eek_container_get_instance_private (self);
 | 
			
		||||
    GList *head;
 | 
			
		||||
 | 
			
		||||
    g_return_if_fail (EEK_IS_ELEMENT(child));
 | 
			
		||||
@ -94,7 +90,7 @@ eek_container_real_foreach_child (EekContainer *self,
 | 
			
		||||
                                  EekCallback   callback,
 | 
			
		||||
                                  gpointer      user_data)
 | 
			
		||||
{
 | 
			
		||||
    EekContainerPrivate *priv = EEK_CONTAINER_GET_PRIVATE(self);
 | 
			
		||||
    EekContainerPrivate *priv = eek_container_get_instance_private (self);
 | 
			
		||||
    GList *head;
 | 
			
		||||
 | 
			
		||||
    for (head = priv->head; head; head = g_list_next (head))
 | 
			
		||||
@ -106,7 +102,7 @@ eek_container_real_find (EekContainer *self,
 | 
			
		||||
                         EekCompareFunc func,
 | 
			
		||||
                         gpointer user_data)
 | 
			
		||||
{
 | 
			
		||||
    EekContainerPrivate *priv = EEK_CONTAINER_GET_PRIVATE(self);
 | 
			
		||||
    EekContainerPrivate *priv = eek_container_get_instance_private (self);
 | 
			
		||||
    GList *head;
 | 
			
		||||
 | 
			
		||||
    head = g_list_find_custom (priv->head, user_data, (GCompareFunc)func);
 | 
			
		||||
@ -118,7 +114,8 @@ eek_container_real_find (EekContainer *self,
 | 
			
		||||
static void
 | 
			
		||||
eek_container_dispose (GObject *object)
 | 
			
		||||
{
 | 
			
		||||
    EekContainerPrivate *priv = EEK_CONTAINER_GET_PRIVATE(object);
 | 
			
		||||
    EekContainer        *self = EEK_CONTAINER (object);
 | 
			
		||||
    EekContainerPrivate *priv = eek_container_get_instance_private (self);
 | 
			
		||||
    GList *head;
 | 
			
		||||
 | 
			
		||||
    for (head = priv->head; head; head = priv->head) {
 | 
			
		||||
@ -134,9 +131,6 @@ eek_container_class_init (EekContainerClass *klass)
 | 
			
		||||
{
 | 
			
		||||
    GObjectClass      *gobject_class = G_OBJECT_CLASS (klass);
 | 
			
		||||
 | 
			
		||||
    g_type_class_add_private (gobject_class,
 | 
			
		||||
                              sizeof (EekContainerPrivate));
 | 
			
		||||
 | 
			
		||||
    klass->add_child = eek_container_real_add_child;
 | 
			
		||||
    klass->remove_child = eek_container_real_remove_child;
 | 
			
		||||
    klass->foreach_child = eek_container_real_foreach_child;
 | 
			
		||||
@ -189,7 +183,7 @@ eek_container_class_init (EekContainerClass *klass)
 | 
			
		||||
static void
 | 
			
		||||
eek_container_init (EekContainer *self)
 | 
			
		||||
{
 | 
			
		||||
    self->priv = EEK_CONTAINER_GET_PRIVATE(self);
 | 
			
		||||
    /* void */
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 | 
			
		||||
@ -30,14 +30,7 @@
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
#define EEK_TYPE_CONTAINER (eek_container_get_type())
 | 
			
		||||
#define EEK_CONTAINER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EEK_TYPE_CONTAINER, EekContainer))
 | 
			
		||||
#define EEK_CONTAINER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EEK_TYPE_CONTAINER, EekContainerClass))
 | 
			
		||||
#define EEK_IS_CONTAINER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EEK_TYPE_CONTAINER))
 | 
			
		||||
#define EEK_IS_CONTAINER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EEK_TYPE_CONTAINER))
 | 
			
		||||
#define EEK_CONTAINER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EEK_TYPE_CONTAINER, EekContainerClass))
 | 
			
		||||
 | 
			
		||||
typedef struct _EekContainerClass EekContainerClass;
 | 
			
		||||
typedef struct _EekContainerPrivate EekContainerPrivate;
 | 
			
		||||
G_DECLARE_DERIVABLE_TYPE (EekContainer, eek_container, EEK, CONTAINER, EekElement)
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * EekCallback:
 | 
			
		||||
@ -50,14 +43,6 @@ typedef struct _EekContainerPrivate EekContainerPrivate;
 | 
			
		||||
typedef void (*EekCallback) (EekElement *element, gpointer user_data);
 | 
			
		||||
typedef gint (*EekCompareFunc) (EekElement *element, gpointer user_data);
 | 
			
		||||
 | 
			
		||||
struct _EekContainer
 | 
			
		||||
{
 | 
			
		||||
    /*< private >*/
 | 
			
		||||
    EekElement parent;
 | 
			
		||||
 | 
			
		||||
    EekContainerPrivate *priv;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * EekContainerClass:
 | 
			
		||||
 * @foreach_child: virtual function for iterating over the container's children
 | 
			
		||||
 | 
			
		||||
@ -52,20 +52,16 @@ enum {
 | 
			
		||||
 | 
			
		||||
static guint signals[LAST_SIGNAL] = { 0, };
 | 
			
		||||
 | 
			
		||||
G_DEFINE_ABSTRACT_TYPE (EekElement, eek_element, G_TYPE_OBJECT);
 | 
			
		||||
 | 
			
		||||
#define EEK_ELEMENT_GET_PRIVATE(obj)                                  \
 | 
			
		||||
    (G_TYPE_INSTANCE_GET_PRIVATE ((obj), EEK_TYPE_ELEMENT, EekElementPrivate))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
struct _EekElementPrivate
 | 
			
		||||
typedef struct _EekElementPrivate
 | 
			
		||||
{
 | 
			
		||||
    gchar *name;
 | 
			
		||||
    EekBounds bounds;
 | 
			
		||||
    EekElement *parent;
 | 
			
		||||
    gint group;
 | 
			
		||||
    gint level;
 | 
			
		||||
};
 | 
			
		||||
} EekElementPrivate;
 | 
			
		||||
 | 
			
		||||
G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (EekElement, eek_element, G_TYPE_OBJECT)
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
eek_element_real_symbol_index_changed (EekElement *self,
 | 
			
		||||
@ -78,7 +74,8 @@ eek_element_real_symbol_index_changed (EekElement *self,
 | 
			
		||||
static void
 | 
			
		||||
eek_element_finalize (GObject *object)
 | 
			
		||||
{
 | 
			
		||||
    EekElementPrivate *priv = EEK_ELEMENT_GET_PRIVATE(object);
 | 
			
		||||
    EekElement        *self = EEK_ELEMENT (object);
 | 
			
		||||
    EekElementPrivate *priv = eek_element_get_instance_private (self);
 | 
			
		||||
 | 
			
		||||
    g_free (priv->name);
 | 
			
		||||
    G_OBJECT_CLASS (eek_element_parent_class)->finalize (object);
 | 
			
		||||
@ -146,9 +143,6 @@ eek_element_class_init (EekElementClass *klass)
 | 
			
		||||
    GObjectClass      *gobject_class = G_OBJECT_CLASS (klass);
 | 
			
		||||
    GParamSpec        *pspec;
 | 
			
		||||
 | 
			
		||||
    g_type_class_add_private (gobject_class,
 | 
			
		||||
                              sizeof (EekElementPrivate));
 | 
			
		||||
 | 
			
		||||
    /* signals */
 | 
			
		||||
    klass->symbol_index_changed = eek_element_real_symbol_index_changed;
 | 
			
		||||
 | 
			
		||||
@ -238,9 +232,8 @@ eek_element_class_init (EekElementClass *klass)
 | 
			
		||||
static void
 | 
			
		||||
eek_element_init (EekElement *self)
 | 
			
		||||
{
 | 
			
		||||
    EekElementPrivate *priv;
 | 
			
		||||
    EekElementPrivate *priv = eek_element_get_instance_private (self);
 | 
			
		||||
 | 
			
		||||
    priv = self->priv = EEK_ELEMENT_GET_PRIVATE(self);
 | 
			
		||||
    priv->group = -1;
 | 
			
		||||
    priv->level = -1;
 | 
			
		||||
}
 | 
			
		||||
@ -259,10 +252,12 @@ eek_element_set_parent (EekElement *element,
 | 
			
		||||
    g_return_if_fail (EEK_IS_ELEMENT(element));
 | 
			
		||||
    g_return_if_fail (parent == NULL || EEK_IS_ELEMENT(parent));
 | 
			
		||||
 | 
			
		||||
    if (element->priv->parent == parent)
 | 
			
		||||
    EekElementPrivate *priv = eek_element_get_instance_private (element);
 | 
			
		||||
 | 
			
		||||
    if (priv->parent == parent)
 | 
			
		||||
        return;
 | 
			
		||||
 | 
			
		||||
    if (element->priv->parent != NULL) {
 | 
			
		||||
    if (priv->parent != NULL) {
 | 
			
		||||
        /* release self-reference acquired when setting parent */
 | 
			
		||||
        g_object_unref (element);
 | 
			
		||||
    }
 | 
			
		||||
@ -271,7 +266,7 @@ eek_element_set_parent (EekElement *element,
 | 
			
		||||
        g_object_ref (element);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    element->priv->parent = parent;
 | 
			
		||||
    priv->parent = parent;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@ -285,7 +280,10 @@ EekElement *
 | 
			
		||||
eek_element_get_parent (EekElement *element)
 | 
			
		||||
{
 | 
			
		||||
    g_return_val_if_fail (EEK_IS_ELEMENT(element), NULL);
 | 
			
		||||
    return element->priv->parent;
 | 
			
		||||
 | 
			
		||||
    EekElementPrivate *priv = eek_element_get_instance_private (element);
 | 
			
		||||
 | 
			
		||||
    return priv->parent;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@ -300,8 +298,11 @@ eek_element_set_name (EekElement  *element,
 | 
			
		||||
                      const gchar *name)
 | 
			
		||||
{
 | 
			
		||||
    g_return_if_fail (EEK_IS_ELEMENT(element));
 | 
			
		||||
    g_free (element->priv->name);
 | 
			
		||||
    element->priv->name = g_strdup (name);
 | 
			
		||||
 | 
			
		||||
    EekElementPrivate *priv = eek_element_get_instance_private (element);
 | 
			
		||||
 | 
			
		||||
    g_free (priv->name);
 | 
			
		||||
    priv->name = g_strdup (name);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@ -311,11 +312,14 @@ eek_element_set_name (EekElement  *element,
 | 
			
		||||
 * Get the name of @element.
 | 
			
		||||
 * Returns: the name of @element or NULL when the name is not set
 | 
			
		||||
 */
 | 
			
		||||
G_CONST_RETURN gchar *
 | 
			
		||||
const gchar *
 | 
			
		||||
eek_element_get_name (EekElement  *element)
 | 
			
		||||
{
 | 
			
		||||
    g_return_val_if_fail (EEK_IS_ELEMENT(element), NULL);
 | 
			
		||||
    return element->priv->name;
 | 
			
		||||
 | 
			
		||||
    EekElementPrivate *priv = eek_element_get_instance_private (element);
 | 
			
		||||
 | 
			
		||||
    return priv->name;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@ -332,7 +336,10 @@ eek_element_set_bounds (EekElement  *element,
 | 
			
		||||
                        EekBounds   *bounds)
 | 
			
		||||
{
 | 
			
		||||
    g_return_if_fail (EEK_IS_ELEMENT(element));
 | 
			
		||||
    memcpy (&element->priv->bounds, bounds, sizeof(EekBounds));
 | 
			
		||||
 | 
			
		||||
    EekElementPrivate *priv = eek_element_get_instance_private (element);
 | 
			
		||||
 | 
			
		||||
    memcpy (&priv->bounds, bounds, sizeof(EekBounds));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@ -350,7 +357,10 @@ eek_element_get_bounds (EekElement  *element,
 | 
			
		||||
{
 | 
			
		||||
    g_return_if_fail (EEK_IS_ELEMENT(element));
 | 
			
		||||
    g_return_if_fail (bounds != NULL);
 | 
			
		||||
    memcpy (bounds, &element->priv->bounds, sizeof(EekBounds));
 | 
			
		||||
 | 
			
		||||
    EekElementPrivate *priv = eek_element_get_instance_private (element);
 | 
			
		||||
 | 
			
		||||
    memcpy (bounds, &priv->bounds, sizeof(EekBounds));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@ -486,11 +496,14 @@ eek_element_set_group (EekElement *element,
 | 
			
		||||
                       gint        group)
 | 
			
		||||
{
 | 
			
		||||
    g_return_if_fail (EEK_IS_ELEMENT(element));
 | 
			
		||||
    if (element->priv->group != group) {
 | 
			
		||||
        element->priv->group = group;
 | 
			
		||||
 | 
			
		||||
    EekElementPrivate *priv = eek_element_get_instance_private (element);
 | 
			
		||||
 | 
			
		||||
    if (priv->group != group) {
 | 
			
		||||
        priv->group = group;
 | 
			
		||||
        g_object_notify (G_OBJECT(element), "group");
 | 
			
		||||
        g_signal_emit (element, signals[SYMBOL_INDEX_CHANGED], 0,
 | 
			
		||||
                       group, element->priv->level);
 | 
			
		||||
                       group, priv->level);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -509,11 +522,14 @@ eek_element_set_level (EekElement *element,
 | 
			
		||||
                       gint        level)
 | 
			
		||||
{
 | 
			
		||||
    g_return_if_fail (EEK_IS_ELEMENT(element));
 | 
			
		||||
    if (element->priv->level != level) {
 | 
			
		||||
        element->priv->level = level;
 | 
			
		||||
 | 
			
		||||
    EekElementPrivate *priv = eek_element_get_instance_private (element);
 | 
			
		||||
 | 
			
		||||
    if (priv->level != level) {
 | 
			
		||||
        priv->level = level;
 | 
			
		||||
        g_object_notify (G_OBJECT(element), "level");
 | 
			
		||||
        g_signal_emit (element, signals[SYMBOL_INDEX_CHANGED], 0,
 | 
			
		||||
                       element->priv->group, level);
 | 
			
		||||
                       priv->group, level);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -530,7 +546,10 @@ gint
 | 
			
		||||
eek_element_get_group (EekElement *element)
 | 
			
		||||
{
 | 
			
		||||
    g_return_val_if_fail (EEK_IS_ELEMENT(element), -1);
 | 
			
		||||
    return element->priv->group;
 | 
			
		||||
 | 
			
		||||
    EekElementPrivate *priv = eek_element_get_instance_private (element);
 | 
			
		||||
 | 
			
		||||
    return priv->group;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@ -546,5 +565,8 @@ gint
 | 
			
		||||
eek_element_get_level (EekElement *element)
 | 
			
		||||
{
 | 
			
		||||
    g_return_val_if_fail (EEK_IS_ELEMENT(element), -1);
 | 
			
		||||
    return element->priv->level;
 | 
			
		||||
 | 
			
		||||
    EekElementPrivate *priv = eek_element_get_instance_private (element);
 | 
			
		||||
 | 
			
		||||
    return priv->level;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -30,22 +30,7 @@
 | 
			
		||||
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
#define EEK_TYPE_ELEMENT (eek_element_get_type())
 | 
			
		||||
#define EEK_ELEMENT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EEK_TYPE_ELEMENT, EekElement))
 | 
			
		||||
#define EEK_ELEMENT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EEK_TYPE_ELEMENT, EekElementClass))
 | 
			
		||||
#define EEK_IS_ELEMENT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EEK_TYPE_ELEMENT))
 | 
			
		||||
#define EEK_IS_ELEMENT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EEK_TYPE_ELEMENT))
 | 
			
		||||
#define EEK_ELEMENT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EEK_TYPE_ELEMENT, EekElementClass))
 | 
			
		||||
 | 
			
		||||
typedef struct _EekElementClass   EekElementClass;
 | 
			
		||||
typedef struct _EekElementPrivate EekElementPrivate;
 | 
			
		||||
 | 
			
		||||
struct _EekElement
 | 
			
		||||
{
 | 
			
		||||
    /*< private >*/
 | 
			
		||||
    GObject parent;
 | 
			
		||||
 | 
			
		||||
    EekElementPrivate *priv;
 | 
			
		||||
};
 | 
			
		||||
G_DECLARE_DERIVABLE_TYPE (EekElement, eek_element, EEK, ELEMENT, GObject)
 | 
			
		||||
 | 
			
		||||
struct _EekElementClass
 | 
			
		||||
{
 | 
			
		||||
@ -58,45 +43,45 @@ struct _EekElementClass
 | 
			
		||||
                                                    gint         level);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
GType                 eek_element_get_type              (void) G_GNUC_CONST;
 | 
			
		||||
GType        eek_element_get_type              (void) G_GNUC_CONST;
 | 
			
		||||
 | 
			
		||||
void                  eek_element_set_parent            (EekElement  *element,
 | 
			
		||||
                                                         EekElement  *parent);
 | 
			
		||||
EekElement           *eek_element_get_parent            (EekElement  *element);
 | 
			
		||||
void                  eek_element_set_name              (EekElement  *element,
 | 
			
		||||
                                                         const gchar *name);
 | 
			
		||||
void         eek_element_set_parent            (EekElement  *element,
 | 
			
		||||
                                                EekElement  *parent);
 | 
			
		||||
EekElement  *eek_element_get_parent            (EekElement  *element);
 | 
			
		||||
void         eek_element_set_name              (EekElement  *element,
 | 
			
		||||
                                                const gchar *name);
 | 
			
		||||
 | 
			
		||||
G_CONST_RETURN gchar *eek_element_get_name              (EekElement  *element);
 | 
			
		||||
const gchar *eek_element_get_name              (EekElement  *element);
 | 
			
		||||
 | 
			
		||||
void                  eek_element_set_bounds            (EekElement  *element,
 | 
			
		||||
                                                         EekBounds   *bounds);
 | 
			
		||||
void         eek_element_set_bounds            (EekElement  *element,
 | 
			
		||||
                                                EekBounds   *bounds);
 | 
			
		||||
 | 
			
		||||
void                  eek_element_get_bounds            (EekElement  *element,
 | 
			
		||||
                                                         EekBounds   *bounds);
 | 
			
		||||
void         eek_element_get_bounds            (EekElement  *element,
 | 
			
		||||
                                                EekBounds   *bounds);
 | 
			
		||||
 | 
			
		||||
void                  eek_element_set_position          (EekElement  *element,
 | 
			
		||||
                                                         gdouble      x,
 | 
			
		||||
                                                         gdouble      y);
 | 
			
		||||
void                  eek_element_set_size              (EekElement  *element,
 | 
			
		||||
                                                         gdouble      width,
 | 
			
		||||
                                                         gdouble      height);
 | 
			
		||||
void         eek_element_set_position          (EekElement  *element,
 | 
			
		||||
                                                gdouble      x,
 | 
			
		||||
                                                gdouble      y);
 | 
			
		||||
void         eek_element_set_size              (EekElement  *element,
 | 
			
		||||
                                                gdouble      width,
 | 
			
		||||
                                                gdouble      height);
 | 
			
		||||
 | 
			
		||||
void                  eek_element_get_absolute_position (EekElement  *element,
 | 
			
		||||
                                                         gdouble     *x,
 | 
			
		||||
                                                         gdouble     *y);
 | 
			
		||||
void         eek_element_get_absolute_position (EekElement  *element,
 | 
			
		||||
                                                gdouble     *x,
 | 
			
		||||
                                                gdouble     *y);
 | 
			
		||||
 | 
			
		||||
void                  eek_element_set_symbol_index      (EekElement  *element,
 | 
			
		||||
                                                         gint         group,
 | 
			
		||||
                                                         gint         level);
 | 
			
		||||
void                  eek_element_get_symbol_index      (EekElement  *element,
 | 
			
		||||
                                                         gint        *group,
 | 
			
		||||
                                                         gint        *level);
 | 
			
		||||
void                  eek_element_set_group             (EekElement  *element,
 | 
			
		||||
                                                         gint         group);
 | 
			
		||||
void                  eek_element_set_level             (EekElement  *element,
 | 
			
		||||
                                                         gint         level);
 | 
			
		||||
gint                  eek_element_get_group             (EekElement  *element);
 | 
			
		||||
gint                  eek_element_get_level             (EekElement  *element);
 | 
			
		||||
void         eek_element_set_symbol_index      (EekElement  *element,
 | 
			
		||||
                                                gint         group,
 | 
			
		||||
                                                gint         level);
 | 
			
		||||
void         eek_element_get_symbol_index      (EekElement  *element,
 | 
			
		||||
                                                gint        *group,
 | 
			
		||||
                                                gint        *level);
 | 
			
		||||
void         eek_element_set_group             (EekElement  *element,
 | 
			
		||||
                                                gint         group);
 | 
			
		||||
void         eek_element_set_level             (EekElement  *element,
 | 
			
		||||
                                                gint         level);
 | 
			
		||||
gint         eek_element_get_group             (EekElement  *element);
 | 
			
		||||
gint         eek_element_get_level             (EekElement  *element);
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
#endif  /* EEK_ELEMENT_H */
 | 
			
		||||
 | 
			
		||||
@ -1,17 +1,17 @@
 | 
			
		||||
/* 
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2010-2011 Daiki Ueno <ueno@unixuser.org>
 | 
			
		||||
 * Copyright (C) 2010-2011 Red Hat, Inc.
 | 
			
		||||
 * 
 | 
			
		||||
 *
 | 
			
		||||
 * This library is free software; you can redistribute it and/or
 | 
			
		||||
 * modify it under the terms of the GNU Lesser General Public License
 | 
			
		||||
 * as published by the Free Software Foundation; either version 2 of
 | 
			
		||||
 * the License, or (at your option) any later version.
 | 
			
		||||
 * 
 | 
			
		||||
 *
 | 
			
		||||
 * This library is distributed in the hope that it will be useful, but
 | 
			
		||||
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
			
		||||
 * Lesser General Public License for more details.
 | 
			
		||||
 * 
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General Public
 | 
			
		||||
 * License along with this library; if not, write to the Free Software
 | 
			
		||||
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 | 
			
		||||
@ -31,6 +31,7 @@
 | 
			
		||||
#include <canberra-gtk.h>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include <math.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
#include "eek-gtk-keyboard.h"
 | 
			
		||||
@ -46,46 +47,36 @@ enum {
 | 
			
		||||
    PROP_LAST
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
G_DEFINE_TYPE (EekGtkKeyboard, eek_gtk_keyboard, GTK_TYPE_DRAWING_AREA);
 | 
			
		||||
 | 
			
		||||
#define EEK_GTK_KEYBOARD_GET_PRIVATE(obj)                                  \
 | 
			
		||||
    (G_TYPE_INSTANCE_GET_PRIVATE ((obj), EEK_TYPE_GTK_KEYBOARD, EekGtkKeyboardPrivate))
 | 
			
		||||
 | 
			
		||||
/* since 2.91.5 GDK_DRAWABLE was removed and gdk_cairo_create takes
 | 
			
		||||
   GdkWindow as the argument */
 | 
			
		||||
#ifndef GDK_DRAWABLE
 | 
			
		||||
#define GDK_DRAWABLE(x) (x)
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
struct _EekGtkKeyboardPrivate
 | 
			
		||||
typedef struct _EekGtkKeyboardPrivate
 | 
			
		||||
{
 | 
			
		||||
    EekRenderer *renderer;
 | 
			
		||||
    EekKeyboard *keyboard;
 | 
			
		||||
    gulong key_pressed_handler;
 | 
			
		||||
    gulong key_released_handler;
 | 
			
		||||
    gulong key_locked_handler;
 | 
			
		||||
    gulong key_unlocked_handler;
 | 
			
		||||
    gulong key_cancelled_handler;
 | 
			
		||||
    gulong symbol_index_changed_handler;
 | 
			
		||||
    EekTheme *theme;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static EekColor * color_from_gdk_color    (GdkColor    *gdk_color);
 | 
			
		||||
static void       on_key_pressed          (EekKeyboard *keyboard,
 | 
			
		||||
                                           EekKey      *key,
 | 
			
		||||
                                           gpointer     user_data);
 | 
			
		||||
static void       on_key_released         (EekKeyboard *keyboard,
 | 
			
		||||
                                           EekKey      *key,
 | 
			
		||||
                                           gpointer     user_data);
 | 
			
		||||
    GdkEventSequence *sequence; // unowned reference
 | 
			
		||||
} EekGtkKeyboardPrivate;
 | 
			
		||||
 | 
			
		||||
G_DEFINE_TYPE_WITH_PRIVATE (EekGtkKeyboard, eek_gtk_keyboard, GTK_TYPE_DRAWING_AREA)
 | 
			
		||||
 | 
			
		||||
static void       on_key_pressed          (EekKey      *key,
 | 
			
		||||
                                           EekGtkKeyboard *self);
 | 
			
		||||
static void       on_key_released         (EekKey      *key,
 | 
			
		||||
                                           EekGtkKeyboard *self);
 | 
			
		||||
static void       on_key_locked          (EekKeyboard *keyboard,
 | 
			
		||||
                                           EekKey      *key,
 | 
			
		||||
                                           gpointer     user_data);
 | 
			
		||||
static void       on_key_unlocked         (EekKeyboard *keyboard,
 | 
			
		||||
                                           EekKey      *key,
 | 
			
		||||
                                           gpointer     user_data);
 | 
			
		||||
static void       on_key_cancelled        (EekKeyboard *keyboard,
 | 
			
		||||
                                           EekKey      *key,
 | 
			
		||||
                                           gpointer     user_data);
 | 
			
		||||
static void       on_symbol_index_changed (EekKeyboard *keyboard,
 | 
			
		||||
                                           gint         group,
 | 
			
		||||
                                           gint         level,
 | 
			
		||||
@ -100,7 +91,6 @@ static void       render_released_key     (GtkWidget   *widget,
 | 
			
		||||
static void
 | 
			
		||||
eek_gtk_keyboard_real_realize (GtkWidget      *self)
 | 
			
		||||
{
 | 
			
		||||
    gtk_widget_set_double_buffered (self, FALSE);
 | 
			
		||||
    gtk_widget_set_events (self,
 | 
			
		||||
                           GDK_EXPOSURE_MASK |
 | 
			
		||||
                           GDK_KEY_PRESS_MASK |
 | 
			
		||||
@ -116,18 +106,15 @@ static gboolean
 | 
			
		||||
eek_gtk_keyboard_real_draw (GtkWidget *self,
 | 
			
		||||
                            cairo_t   *cr)
 | 
			
		||||
{
 | 
			
		||||
    EekGtkKeyboardPrivate *priv = EEK_GTK_KEYBOARD_GET_PRIVATE(self);
 | 
			
		||||
    EekGtkKeyboardPrivate *priv =
 | 
			
		||||
	    eek_gtk_keyboard_get_instance_private (EEK_GTK_KEYBOARD (self));
 | 
			
		||||
    GtkAllocation allocation;
 | 
			
		||||
    EekColor background;
 | 
			
		||||
    GList *list, *head;
 | 
			
		||||
 | 
			
		||||
    gtk_widget_get_allocation (self, &allocation);
 | 
			
		||||
 | 
			
		||||
    if (!priv->renderer) {
 | 
			
		||||
        GtkStyle *style;
 | 
			
		||||
        GtkStateType state;
 | 
			
		||||
        PangoContext *pcontext;
 | 
			
		||||
        EekColor *color;
 | 
			
		||||
 | 
			
		||||
        pcontext = gtk_widget_get_pango_context (self);
 | 
			
		||||
        priv->renderer = eek_gtk_renderer_new (priv->keyboard, pcontext, self);
 | 
			
		||||
@ -137,30 +124,8 @@ eek_gtk_keyboard_real_draw (GtkWidget *self,
 | 
			
		||||
        eek_renderer_set_allocation_size (priv->renderer,
 | 
			
		||||
                                          allocation.width,
 | 
			
		||||
                                          allocation.height);
 | 
			
		||||
 | 
			
		||||
        style = gtk_widget_get_style (self);
 | 
			
		||||
        state = gtk_widget_get_state (self);
 | 
			
		||||
 | 
			
		||||
        color = color_from_gdk_color (&style->text[state]);
 | 
			
		||||
        eek_renderer_set_default_foreground_color (priv->renderer, color);
 | 
			
		||||
        eek_color_free (color);
 | 
			
		||||
 | 
			
		||||
        color = color_from_gdk_color (&style->base[state]);
 | 
			
		||||
        eek_renderer_set_default_background_color (priv->renderer, color);
 | 
			
		||||
        eek_color_free (color);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* blank background */
 | 
			
		||||
    eek_renderer_get_background_color (priv->renderer,
 | 
			
		||||
                                       EEK_ELEMENT(priv->keyboard),
 | 
			
		||||
                                       &background);
 | 
			
		||||
    cairo_set_source_rgba (cr,
 | 
			
		||||
                           background.red,
 | 
			
		||||
                           background.green,
 | 
			
		||||
                           background.blue,
 | 
			
		||||
                           background.alpha);
 | 
			
		||||
    cairo_paint (cr);
 | 
			
		||||
 | 
			
		||||
    eek_renderer_render_keyboard (priv->renderer, cr);
 | 
			
		||||
 | 
			
		||||
    /* redraw pressed key */
 | 
			
		||||
@ -184,7 +149,8 @@ static void
 | 
			
		||||
eek_gtk_keyboard_real_size_allocate (GtkWidget     *self,
 | 
			
		||||
                                     GtkAllocation *allocation)
 | 
			
		||||
{
 | 
			
		||||
    EekGtkKeyboardPrivate *priv = EEK_GTK_KEYBOARD_GET_PRIVATE(self);
 | 
			
		||||
    EekGtkKeyboardPrivate *priv =
 | 
			
		||||
	    eek_gtk_keyboard_get_instance_private (EEK_GTK_KEYBOARD (self));
 | 
			
		||||
 | 
			
		||||
    if (priv->renderer)
 | 
			
		||||
        eek_renderer_set_allocation_size (priv->renderer,
 | 
			
		||||
@ -195,46 +161,21 @@ eek_gtk_keyboard_real_size_allocate (GtkWidget     *self,
 | 
			
		||||
        size_allocate (self, allocation);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
eek_gtk_keyboard_real_button_press_event (GtkWidget      *self,
 | 
			
		||||
                                          GdkEventButton *event)
 | 
			
		||||
{
 | 
			
		||||
    EekGtkKeyboardPrivate *priv = EEK_GTK_KEYBOARD_GET_PRIVATE(self);
 | 
			
		||||
    EekKey *key;
 | 
			
		||||
 | 
			
		||||
    key = eek_renderer_find_key_by_position (priv->renderer,
 | 
			
		||||
                                             (gdouble)event->x,
 | 
			
		||||
                                             (gdouble)event->y);
 | 
			
		||||
    if (key)
 | 
			
		||||
        g_signal_emit_by_name (key, "pressed", priv->keyboard);
 | 
			
		||||
    return TRUE;
 | 
			
		||||
static void depress(EekGtkKeyboard *self,
 | 
			
		||||
                    gdouble x, gdouble y, guint32 time) {
 | 
			
		||||
    EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (self);
 | 
			
		||||
    EekKey *key = eek_renderer_find_key_by_position (priv->renderer, x, y);
 | 
			
		||||
    if (key) {
 | 
			
		||||
        eek_keyboard_press_key(priv->keyboard, key, time);
 | 
			
		||||
        on_key_pressed(key, self);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
eek_gtk_keyboard_real_button_release_event (GtkWidget      *self,
 | 
			
		||||
                                            GdkEventButton *event)
 | 
			
		||||
{
 | 
			
		||||
    EekGtkKeyboardPrivate *priv = EEK_GTK_KEYBOARD_GET_PRIVATE(self);
 | 
			
		||||
    GList *list, *head;
 | 
			
		||||
static void drag(EekGtkKeyboard *self,
 | 
			
		||||
                 gdouble x, gdouble y, guint32 time) {
 | 
			
		||||
    EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (self);
 | 
			
		||||
    EekKey *key = eek_renderer_find_key_by_position (priv->renderer, x, y);
 | 
			
		||||
 | 
			
		||||
    list = eek_keyboard_get_pressed_keys (priv->keyboard);
 | 
			
		||||
    for (head = list; head; head = g_list_next (head))
 | 
			
		||||
        g_signal_emit_by_name (head->data, "released", priv->keyboard);
 | 
			
		||||
    g_list_free (list);
 | 
			
		||||
 | 
			
		||||
    return TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
eek_gtk_keyboard_real_motion_notify_event (GtkWidget      *self,
 | 
			
		||||
                                           GdkEventMotion *event)
 | 
			
		||||
{
 | 
			
		||||
    EekGtkKeyboardPrivate *priv = EEK_GTK_KEYBOARD_GET_PRIVATE(self);
 | 
			
		||||
    EekKey *key;
 | 
			
		||||
 | 
			
		||||
    key = eek_renderer_find_key_by_position (priv->renderer,
 | 
			
		||||
                                             (gdouble)event->x,
 | 
			
		||||
                                             (gdouble)event->y);
 | 
			
		||||
    if (key) {
 | 
			
		||||
        GList *list, *head;
 | 
			
		||||
        gboolean found = FALSE;
 | 
			
		||||
@ -243,13 +184,93 @@ eek_gtk_keyboard_real_motion_notify_event (GtkWidget      *self,
 | 
			
		||||
        for (head = list; head; head = g_list_next (head)) {
 | 
			
		||||
            if (head->data == key)
 | 
			
		||||
                found = TRUE;
 | 
			
		||||
            else
 | 
			
		||||
                g_signal_emit_by_name (head->data, "cancelled", priv->keyboard);
 | 
			
		||||
            else {
 | 
			
		||||
                eek_keyboard_release_key(priv->keyboard, EEK_KEY(head->data), time);
 | 
			
		||||
                on_key_released(key, self);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        g_list_free (list);
 | 
			
		||||
 | 
			
		||||
        if (!found)
 | 
			
		||||
            g_signal_emit_by_name (key, "pressed", priv->keyboard);
 | 
			
		||||
        if (!found) {
 | 
			
		||||
            eek_keyboard_press_key(priv->keyboard, key, time);
 | 
			
		||||
            on_key_pressed(key, self);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void release(EekGtkKeyboard *self, guint32 time) {
 | 
			
		||||
    EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (self);
 | 
			
		||||
 | 
			
		||||
    GList *list = eek_keyboard_get_pressed_keys (priv->keyboard);
 | 
			
		||||
    for (GList *head = list; head; head = g_list_next (head)) {
 | 
			
		||||
        EekKey *key = EEK_KEY(head->data);
 | 
			
		||||
        eek_keyboard_release_key(priv->keyboard, key, time);
 | 
			
		||||
        on_key_released(key, self);
 | 
			
		||||
    }
 | 
			
		||||
    g_list_free (list);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
eek_gtk_keyboard_real_button_press_event (GtkWidget      *self,
 | 
			
		||||
                                          GdkEventButton *event)
 | 
			
		||||
{
 | 
			
		||||
    if (event->type == GDK_BUTTON_PRESS && event->button == 1) {
 | 
			
		||||
        depress(EEK_GTK_KEYBOARD(self), event->x, event->y, event->time);
 | 
			
		||||
    }
 | 
			
		||||
    return TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// TODO: this belongs more in gtk_keyboard, with a way to find out which key to re-render
 | 
			
		||||
static gboolean
 | 
			
		||||
eek_gtk_keyboard_real_button_release_event (GtkWidget      *self,
 | 
			
		||||
                                            GdkEventButton *event)
 | 
			
		||||
{
 | 
			
		||||
    if (event->type == GDK_BUTTON_RELEASE && event->button == 1) {
 | 
			
		||||
        // TODO: can the event have different coords than the previous move event?
 | 
			
		||||
        release(EEK_GTK_KEYBOARD(self), event->time);
 | 
			
		||||
    }
 | 
			
		||||
    return TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
eek_gtk_keyboard_real_motion_notify_event (GtkWidget      *self,
 | 
			
		||||
                                           GdkEventMotion *event)
 | 
			
		||||
{
 | 
			
		||||
    if (event->state & GDK_BUTTON1_MASK) {
 | 
			
		||||
        drag(EEK_GTK_KEYBOARD(self), event->x, event->y, event->time);
 | 
			
		||||
    }
 | 
			
		||||
    return TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Only one touch stream at a time allowed. Others will be completely ignored.
 | 
			
		||||
static gboolean
 | 
			
		||||
handle_touch_event (GtkWidget     *widget,
 | 
			
		||||
                    GdkEventTouch *event)
 | 
			
		||||
{
 | 
			
		||||
    EekGtkKeyboard        *self = EEK_GTK_KEYBOARD (widget);
 | 
			
		||||
    EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (self);
 | 
			
		||||
 | 
			
		||||
    if (event->type == GDK_TOUCH_BEGIN) {
 | 
			
		||||
        if (priv->sequence) {
 | 
			
		||||
            // Ignore second and following touch points
 | 
			
		||||
            return FALSE;
 | 
			
		||||
        }
 | 
			
		||||
        priv->sequence = event->sequence;
 | 
			
		||||
        depress(self, event->x, event->y, event->time);
 | 
			
		||||
        return TRUE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (priv->sequence != event->sequence) {
 | 
			
		||||
        return FALSE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (event->type == GDK_TOUCH_UPDATE) {
 | 
			
		||||
        drag(self, event->x, event->y, event->time);
 | 
			
		||||
    }
 | 
			
		||||
    if (event->type == GDK_TOUCH_END || event->type == GDK_TOUCH_CANCEL) {
 | 
			
		||||
        // TODO: can the event have different coords than the previous update event?
 | 
			
		||||
        release(self, event->time);
 | 
			
		||||
        priv->sequence = NULL;
 | 
			
		||||
    }
 | 
			
		||||
    return TRUE;
 | 
			
		||||
}
 | 
			
		||||
@ -257,7 +278,8 @@ eek_gtk_keyboard_real_motion_notify_event (GtkWidget      *self,
 | 
			
		||||
static void
 | 
			
		||||
eek_gtk_keyboard_real_unmap (GtkWidget *self)
 | 
			
		||||
{
 | 
			
		||||
    EekGtkKeyboardPrivate *priv = EEK_GTK_KEYBOARD_GET_PRIVATE(self);
 | 
			
		||||
    EekGtkKeyboardPrivate *priv =
 | 
			
		||||
	    eek_gtk_keyboard_get_instance_private (EEK_GTK_KEYBOARD (self));
 | 
			
		||||
 | 
			
		||||
    if (priv->keyboard) {
 | 
			
		||||
        GList *list, *head;
 | 
			
		||||
@ -267,36 +289,55 @@ eek_gtk_keyboard_real_unmap (GtkWidget *self)
 | 
			
		||||
           EekKeyboard::key-released signal can remove elements from its
 | 
			
		||||
           internal copy */
 | 
			
		||||
        list = eek_keyboard_get_pressed_keys (priv->keyboard);
 | 
			
		||||
        for (head = list; head; head = g_list_next (head))
 | 
			
		||||
            g_signal_emit_by_name (head->data, "released", priv->keyboard);
 | 
			
		||||
        for (head = list; head; head = g_list_next (head)) {
 | 
			
		||||
            g_log("squeek", G_LOG_LEVEL_DEBUG, "emit EekKey released");
 | 
			
		||||
            g_signal_emit_by_name (head->data, "released");
 | 
			
		||||
        }
 | 
			
		||||
        g_list_free (list);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    GTK_WIDGET_CLASS (eek_gtk_keyboard_parent_class)->unmap (self);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
eek_gtk_keyboard_real_query_tooltip (GtkWidget  *widget,
 | 
			
		||||
                                     gint        x,
 | 
			
		||||
                                     gint        y,
 | 
			
		||||
                                     gboolean    keyboard_tooltip,
 | 
			
		||||
                                     GtkTooltip *tooltip)
 | 
			
		||||
{
 | 
			
		||||
    EekGtkKeyboard        *self = EEK_GTK_KEYBOARD (widget);
 | 
			
		||||
    EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (self);
 | 
			
		||||
 | 
			
		||||
    EekKey *key;
 | 
			
		||||
 | 
			
		||||
    key = eek_renderer_find_key_by_position (priv->renderer,
 | 
			
		||||
                                             (gdouble)x,
 | 
			
		||||
                                             (gdouble)y);
 | 
			
		||||
    if (key) {
 | 
			
		||||
        EekSymbol *symbol = eek_key_get_symbol (key);
 | 
			
		||||
        const gchar *text = eek_symbol_get_tooltip (symbol);
 | 
			
		||||
        if (text) {
 | 
			
		||||
            gtk_tooltip_set_text (tooltip, text);
 | 
			
		||||
            return TRUE;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    return FALSE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
eek_gtk_keyboard_set_keyboard (EekGtkKeyboard *self,
 | 
			
		||||
                               EekKeyboard    *keyboard)
 | 
			
		||||
{
 | 
			
		||||
    EekGtkKeyboardPrivate *priv = EEK_GTK_KEYBOARD_GET_PRIVATE(self);
 | 
			
		||||
    EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (self);
 | 
			
		||||
    priv->keyboard = g_object_ref (keyboard);
 | 
			
		||||
 | 
			
		||||
    priv->key_pressed_handler =
 | 
			
		||||
        g_signal_connect (priv->keyboard, "key-pressed",
 | 
			
		||||
                          G_CALLBACK(on_key_pressed), self);
 | 
			
		||||
    priv->key_released_handler =
 | 
			
		||||
        g_signal_connect (priv->keyboard, "key-released",
 | 
			
		||||
                          G_CALLBACK(on_key_released), self);
 | 
			
		||||
    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->key_cancelled_handler =
 | 
			
		||||
        g_signal_connect (priv->keyboard, "key-cancelled",
 | 
			
		||||
                          G_CALLBACK(on_key_cancelled), self);
 | 
			
		||||
    priv->symbol_index_changed_handler =
 | 
			
		||||
        g_signal_connect (priv->keyboard, "symbol-index-changed",
 | 
			
		||||
                          G_CALLBACK(on_symbol_index_changed), self);
 | 
			
		||||
@ -324,7 +365,8 @@ eek_gtk_keyboard_set_property (GObject      *object,
 | 
			
		||||
static void
 | 
			
		||||
eek_gtk_keyboard_dispose (GObject *object)
 | 
			
		||||
{
 | 
			
		||||
    EekGtkKeyboardPrivate *priv = EEK_GTK_KEYBOARD_GET_PRIVATE(object);
 | 
			
		||||
    EekGtkKeyboard        *self = EEK_GTK_KEYBOARD (object);
 | 
			
		||||
    EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (self);
 | 
			
		||||
 | 
			
		||||
    if (priv->renderer) {
 | 
			
		||||
        g_object_unref (priv->renderer);
 | 
			
		||||
@ -332,14 +374,6 @@ eek_gtk_keyboard_dispose (GObject *object)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (priv->keyboard) {
 | 
			
		||||
        if (g_signal_handler_is_connected (priv->keyboard,
 | 
			
		||||
                                           priv->key_pressed_handler))
 | 
			
		||||
            g_signal_handler_disconnect (priv->keyboard,
 | 
			
		||||
                                         priv->key_pressed_handler);
 | 
			
		||||
        if (g_signal_handler_is_connected (priv->keyboard,
 | 
			
		||||
                                           priv->key_released_handler))
 | 
			
		||||
            g_signal_handler_disconnect (priv->keyboard,
 | 
			
		||||
                                         priv->key_released_handler);
 | 
			
		||||
        if (g_signal_handler_is_connected (priv->keyboard,
 | 
			
		||||
                                           priv->key_locked_handler))
 | 
			
		||||
            g_signal_handler_disconnect (priv->keyboard,
 | 
			
		||||
@ -348,19 +382,16 @@ eek_gtk_keyboard_dispose (GObject *object)
 | 
			
		||||
                                           priv->key_unlocked_handler))
 | 
			
		||||
            g_signal_handler_disconnect (priv->keyboard,
 | 
			
		||||
                                         priv->key_unlocked_handler);
 | 
			
		||||
        if (g_signal_handler_is_connected (priv->keyboard,
 | 
			
		||||
                                           priv->key_cancelled_handler))
 | 
			
		||||
            g_signal_handler_disconnect (priv->keyboard,
 | 
			
		||||
                                         priv->key_cancelled_handler);
 | 
			
		||||
        if (g_signal_handler_is_connected (priv->keyboard,
 | 
			
		||||
                                           priv->symbol_index_changed_handler))
 | 
			
		||||
            g_signal_handler_disconnect (priv->keyboard,
 | 
			
		||||
                                         priv->symbol_index_changed_handler);
 | 
			
		||||
            
 | 
			
		||||
 | 
			
		||||
        GList *list, *head;
 | 
			
		||||
 | 
			
		||||
        list = eek_keyboard_get_pressed_keys (priv->keyboard);
 | 
			
		||||
        for (head = list; head; head = g_list_next (head)) {
 | 
			
		||||
            g_log("squeek", G_LOG_LEVEL_DEBUG, "emit EekKey pressed");
 | 
			
		||||
            g_signal_emit_by_name (head->data, "released", priv->keyboard);
 | 
			
		||||
        }
 | 
			
		||||
        g_list_free (list);
 | 
			
		||||
@ -384,9 +415,6 @@ eek_gtk_keyboard_class_init (EekGtkKeyboardClass *klass)
 | 
			
		||||
    GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
 | 
			
		||||
    GParamSpec *pspec;
 | 
			
		||||
 | 
			
		||||
    g_type_class_add_private (gobject_class,
 | 
			
		||||
                              sizeof (EekGtkKeyboardPrivate));
 | 
			
		||||
 | 
			
		||||
    widget_class->realize = eek_gtk_keyboard_real_realize;
 | 
			
		||||
    widget_class->unmap = eek_gtk_keyboard_real_unmap;
 | 
			
		||||
    widget_class->draw = eek_gtk_keyboard_real_draw;
 | 
			
		||||
@ -397,6 +425,9 @@ eek_gtk_keyboard_class_init (EekGtkKeyboardClass *klass)
 | 
			
		||||
        eek_gtk_keyboard_real_button_release_event;
 | 
			
		||||
    widget_class->motion_notify_event =
 | 
			
		||||
        eek_gtk_keyboard_real_motion_notify_event;
 | 
			
		||||
    widget_class->query_tooltip =
 | 
			
		||||
        eek_gtk_keyboard_real_query_tooltip;
 | 
			
		||||
    widget_class->touch_event = handle_touch_event;
 | 
			
		||||
 | 
			
		||||
    gobject_class->set_property = eek_gtk_keyboard_set_property;
 | 
			
		||||
    gobject_class->dispose = eek_gtk_keyboard_dispose;
 | 
			
		||||
@ -414,7 +445,7 @@ eek_gtk_keyboard_class_init (EekGtkKeyboardClass *klass)
 | 
			
		||||
static void
 | 
			
		||||
eek_gtk_keyboard_init (EekGtkKeyboard *self)
 | 
			
		||||
{
 | 
			
		||||
    self->priv = EEK_GTK_KEYBOARD_GET_PRIVATE(self);
 | 
			
		||||
    /* void */
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@ -430,15 +461,6 @@ eek_gtk_keyboard_new (EekKeyboard *keyboard)
 | 
			
		||||
    return g_object_new (EEK_TYPE_GTK_KEYBOARD, "keyboard", keyboard, NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static EekColor *
 | 
			
		||||
color_from_gdk_color (GdkColor *gdk_color)
 | 
			
		||||
{
 | 
			
		||||
    return eek_color_new (gdk_color->red / (gdouble)0xFFFF,
 | 
			
		||||
                          gdk_color->green / (gdouble)0xFFFF,
 | 
			
		||||
                          gdk_color->blue / (gdouble)0xFFFF,
 | 
			
		||||
                          1.0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
magnify_bounds (GtkWidget *self,
 | 
			
		||||
                EekBounds *bounds,
 | 
			
		||||
@ -462,19 +484,67 @@ 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)
 | 
			
		||||
{
 | 
			
		||||
    EekGtkKeyboardPrivate *priv = EEK_GTK_KEYBOARD_GET_PRIVATE(widget);
 | 
			
		||||
    EekGtkKeyboard        *self = EEK_GTK_KEYBOARD (widget);
 | 
			
		||||
    EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (self);
 | 
			
		||||
    EekBounds bounds, large_bounds;
 | 
			
		||||
    cairo_t *cr;
 | 
			
		||||
 | 
			
		||||
    cr = gdk_cairo_create (GDK_DRAWABLE (gtk_widget_get_window (widget)));
 | 
			
		||||
    GdkWindow         *window  = gtk_widget_get_window (widget);
 | 
			
		||||
    cairo_region_t    *region  = gdk_window_get_clip_region (window);
 | 
			
		||||
    GdkDrawingContext *context = gdk_window_begin_draw_frame (window, region);
 | 
			
		||||
    cairo_t           *cr      = gdk_drawing_context_get_cairo_context (context);
 | 
			
		||||
 | 
			
		||||
    eek_renderer_get_key_bounds (priv->renderer, key, &bounds, TRUE);
 | 
			
		||||
    magnify_bounds (widget, &bounds, &large_bounds, 1.5);
 | 
			
		||||
 | 
			
		||||
    /*
 | 
			
		||||
     * 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);
 | 
			
		||||
@ -485,67 +555,89 @@ render_pressed_key (GtkWidget *widget,
 | 
			
		||||
    eek_renderer_render_key (priv->renderer, cr, key, 1.5, TRUE);
 | 
			
		||||
    cairo_restore (cr);
 | 
			
		||||
 | 
			
		||||
    cairo_destroy (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
 | 
			
		||||
render_locked_key (GtkWidget *widget,
 | 
			
		||||
                   EekKey    *key)
 | 
			
		||||
{
 | 
			
		||||
    EekGtkKeyboardPrivate *priv = EEK_GTK_KEYBOARD_GET_PRIVATE(widget);
 | 
			
		||||
    EekGtkKeyboard        *self = EEK_GTK_KEYBOARD (widget);
 | 
			
		||||
    EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (self);
 | 
			
		||||
    EekBounds bounds;
 | 
			
		||||
    cairo_t *cr;
 | 
			
		||||
 | 
			
		||||
    cr = gdk_cairo_create (GDK_DRAWABLE (gtk_widget_get_window (widget)));
 | 
			
		||||
    GdkWindow         *window  = gtk_widget_get_window (widget);
 | 
			
		||||
    cairo_region_t    *region  = gdk_window_get_clip_region (window);
 | 
			
		||||
    GdkDrawingContext *context = gdk_window_begin_draw_frame (window, region);
 | 
			
		||||
    cairo_t           *cr      = gdk_drawing_context_get_cairo_context (context);
 | 
			
		||||
 | 
			
		||||
    eek_renderer_get_key_bounds (priv->renderer, key, &bounds, TRUE);
 | 
			
		||||
 | 
			
		||||
    /*
 | 
			
		||||
     * 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);
 | 
			
		||||
 | 
			
		||||
    cairo_destroy (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
 | 
			
		||||
render_released_key (GtkWidget *widget,
 | 
			
		||||
                     EekKey    *key)
 | 
			
		||||
{
 | 
			
		||||
    EekGtkKeyboardPrivate *priv = EEK_GTK_KEYBOARD_GET_PRIVATE(widget);
 | 
			
		||||
    EekGtkKeyboard        *self = EEK_GTK_KEYBOARD (widget);
 | 
			
		||||
    EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (self);
 | 
			
		||||
    EekBounds bounds, large_bounds;
 | 
			
		||||
    cairo_t *cr;
 | 
			
		||||
 | 
			
		||||
    cr = gdk_cairo_create (GDK_DRAWABLE (gtk_widget_get_window (widget)));
 | 
			
		||||
    GdkWindow         *window  = gtk_widget_get_window (widget);
 | 
			
		||||
    cairo_region_t    *region  = gdk_window_get_clip_region (window);
 | 
			
		||||
    GdkDrawingContext *context = gdk_window_begin_draw_frame (window, region);
 | 
			
		||||
    cairo_t           *cr      = gdk_drawing_context_get_cairo_context (context);
 | 
			
		||||
 | 
			
		||||
    eek_renderer_get_key_bounds (priv->renderer, key, &bounds, TRUE);
 | 
			
		||||
    magnify_bounds (widget, &bounds, &large_bounds, 2.0);
 | 
			
		||||
    cairo_rectangle (cr,
 | 
			
		||||
                     large_bounds.x,
 | 
			
		||||
                     large_bounds.y,
 | 
			
		||||
                     large_bounds.width,
 | 
			
		||||
                     large_bounds.height);
 | 
			
		||||
    cairo_rectangle (cr,
 | 
			
		||||
                     bounds.x,
 | 
			
		||||
                     bounds.y,
 | 
			
		||||
                     bounds.width,
 | 
			
		||||
                     bounds.height);
 | 
			
		||||
    cairo_clip (cr);
 | 
			
		||||
    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);
 | 
			
		||||
    cairo_destroy (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
 | 
			
		||||
on_key_pressed (EekKeyboard *keyboard,
 | 
			
		||||
                EekKey      *key,
 | 
			
		||||
                gpointer     user_data)
 | 
			
		||||
on_key_pressed (EekKey      *key,
 | 
			
		||||
                EekGtkKeyboard *self)
 | 
			
		||||
{
 | 
			
		||||
    GtkWidget *widget = user_data;
 | 
			
		||||
    EekGtkKeyboardPrivate *priv = EEK_GTK_KEYBOARD_GET_PRIVATE(widget);
 | 
			
		||||
    EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (self);
 | 
			
		||||
 | 
			
		||||
    /* renderer may have not been set yet if the widget is a popup */
 | 
			
		||||
    if (!priv->renderer)
 | 
			
		||||
        return;
 | 
			
		||||
 | 
			
		||||
    render_pressed_key (widget, key);
 | 
			
		||||
    render_pressed_key (GTK_WIDGET(self), key);
 | 
			
		||||
 | 
			
		||||
#if HAVE_LIBCANBERRA
 | 
			
		||||
    ca_gtk_play_for_widget (widget, 0,
 | 
			
		||||
@ -557,18 +649,16 @@ on_key_pressed (EekKeyboard *keyboard,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
on_key_released (EekKeyboard *keyboard,
 | 
			
		||||
                 EekKey      *key,
 | 
			
		||||
                 gpointer     user_data)
 | 
			
		||||
on_key_released (EekKey      *key,
 | 
			
		||||
                 EekGtkKeyboard *self)
 | 
			
		||||
{
 | 
			
		||||
    GtkWidget *widget = user_data;
 | 
			
		||||
    EekGtkKeyboardPrivate *priv = EEK_GTK_KEYBOARD_GET_PRIVATE(widget);
 | 
			
		||||
    EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (self);
 | 
			
		||||
 | 
			
		||||
    /* renderer may have not been set yet if the widget is a popup */
 | 
			
		||||
    if (!priv->renderer)
 | 
			
		||||
        return;
 | 
			
		||||
 | 
			
		||||
    render_released_key (widget, key);
 | 
			
		||||
    render_released_key (GTK_WIDGET(self), key);
 | 
			
		||||
 | 
			
		||||
#if HAVE_LIBCANBERRA
 | 
			
		||||
    ca_gtk_play_for_widget (widget, 0,
 | 
			
		||||
@ -579,28 +669,13 @@ on_key_released (EekKeyboard *keyboard,
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
on_key_cancelled (EekKeyboard *keyboard,
 | 
			
		||||
                 EekKey      *key,
 | 
			
		||||
                 gpointer     user_data)
 | 
			
		||||
{
 | 
			
		||||
    GtkWidget *widget = user_data;
 | 
			
		||||
    EekGtkKeyboardPrivate *priv = EEK_GTK_KEYBOARD_GET_PRIVATE(widget);
 | 
			
		||||
 | 
			
		||||
    /* renderer may have not been set yet if the widget is a popup */
 | 
			
		||||
    if (!priv->renderer)
 | 
			
		||||
        return;
 | 
			
		||||
 | 
			
		||||
    render_released_key (widget, key);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
on_key_locked (EekKeyboard *keyboard,
 | 
			
		||||
               EekKey      *key,
 | 
			
		||||
               gpointer     user_data)
 | 
			
		||||
{
 | 
			
		||||
    GtkWidget *widget = user_data;
 | 
			
		||||
    EekGtkKeyboardPrivate *priv = EEK_GTK_KEYBOARD_GET_PRIVATE(widget);
 | 
			
		||||
    EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (user_data);
 | 
			
		||||
 | 
			
		||||
    /* renderer may have not been set yet if the widget is a popup */
 | 
			
		||||
    if (!priv->renderer)
 | 
			
		||||
@ -615,7 +690,7 @@ on_key_unlocked (EekKeyboard *keyboard,
 | 
			
		||||
                 gpointer     user_data)
 | 
			
		||||
{
 | 
			
		||||
    GtkWidget *widget = user_data;
 | 
			
		||||
    EekGtkKeyboardPrivate *priv = EEK_GTK_KEYBOARD_GET_PRIVATE(widget);
 | 
			
		||||
    EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (user_data);
 | 
			
		||||
 | 
			
		||||
    /* renderer may have not been set yet if the widget is a popup */
 | 
			
		||||
    if (!priv->renderer)
 | 
			
		||||
@ -639,11 +714,9 @@ void
 | 
			
		||||
eek_gtk_keyboard_set_theme (EekGtkKeyboard *keyboard,
 | 
			
		||||
                            EekTheme       *theme)
 | 
			
		||||
{
 | 
			
		||||
    EekGtkKeyboardPrivate *priv;
 | 
			
		||||
 | 
			
		||||
    g_return_if_fail (EEK_IS_GTK_KEYBOARD(keyboard));
 | 
			
		||||
    g_return_if_fail (EEK_IS_THEME(theme));
 | 
			
		||||
 | 
			
		||||
    priv = EEK_GTK_KEYBOARD_GET_PRIVATE(keyboard);
 | 
			
		||||
    EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (keyboard);
 | 
			
		||||
    priv->theme = g_object_ref (theme);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -32,23 +32,7 @@
 | 
			
		||||
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
#define EEK_TYPE_GTK_KEYBOARD (eek_gtk_keyboard_get_type())
 | 
			
		||||
#define EEK_GTK_KEYBOARD(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EEK_TYPE_GTK_KEYBOARD, EekGtkKeyboard))
 | 
			
		||||
#define EEK_GTK_KEYBOARD_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EEK_TYPE_GTK_KEYBOARD, EekGtkKeyboardClass))
 | 
			
		||||
#define EEK_IS_GTK_KEYBOARD(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EEK_TYPE_GTK_KEYBOARD))
 | 
			
		||||
#define EEK_IS_GTK_KEYBOARD_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EEK_TYPE_GTK_KEYBOARD))
 | 
			
		||||
#define EEK_GTK_KEYBOARD_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EEK_TYPE_GTK_KEYBOARD, EekGtkKeyboardClass))
 | 
			
		||||
 | 
			
		||||
typedef struct _EekGtkKeyboard EekGtkKeyboard;
 | 
			
		||||
typedef struct _EekGtkKeyboardClass EekGtkKeyboardClass;
 | 
			
		||||
typedef struct _EekGtkKeyboardPrivate EekGtkKeyboardPrivate;
 | 
			
		||||
 | 
			
		||||
struct _EekGtkKeyboard
 | 
			
		||||
{
 | 
			
		||||
    /*< private >*/
 | 
			
		||||
    GtkDrawingArea parent;
 | 
			
		||||
 | 
			
		||||
    EekGtkKeyboardPrivate *priv;
 | 
			
		||||
};
 | 
			
		||||
G_DECLARE_DERIVABLE_TYPE (EekGtkKeyboard, eek_gtk_keyboard, EEK, GTK_KEYBOARD, GtkDrawingArea)
 | 
			
		||||
 | 
			
		||||
struct _EekGtkKeyboardClass
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
@ -57,10 +57,9 @@ eek_gtk_renderer_real_get_icon_surface (EekRenderer *self,
 | 
			
		||||
                                        gint size)
 | 
			
		||||
{
 | 
			
		||||
    GdkPixbuf *pixbuf;
 | 
			
		||||
    GError *error;
 | 
			
		||||
    GError *error = NULL;
 | 
			
		||||
    cairo_surface_t *surface;
 | 
			
		||||
 | 
			
		||||
    error = NULL;
 | 
			
		||||
    pixbuf = gtk_icon_theme_load_icon (gtk_icon_theme_get_default (),
 | 
			
		||||
                                       icon_name,
 | 
			
		||||
                                       size,
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										194
									
								
								eek/eek-key.c
									
									
									
									
									
								
							
							
						
						
									
										194
									
								
								eek/eek-key.c
									
									
									
									
									
								
							@ -30,10 +30,6 @@
 | 
			
		||||
#endif  /* HAVE_CONFIG_H */
 | 
			
		||||
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#define DEBUG 0
 | 
			
		||||
#if DEBUG
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include "eek-key.h"
 | 
			
		||||
#include "eek-section.h"
 | 
			
		||||
@ -51,59 +47,30 @@ enum {
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
enum {
 | 
			
		||||
    PRESSED,
 | 
			
		||||
    RELEASED,
 | 
			
		||||
    LOCKED,
 | 
			
		||||
    UNLOCKED,
 | 
			
		||||
    CANCELLED,
 | 
			
		||||
    LAST_SIGNAL
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static guint signals[LAST_SIGNAL] = { 0, };
 | 
			
		||||
 | 
			
		||||
G_DEFINE_TYPE (EekKey, eek_key, EEK_TYPE_ELEMENT);
 | 
			
		||||
 | 
			
		||||
#define EEK_KEY_GET_PRIVATE(obj)                                  \
 | 
			
		||||
    (G_TYPE_INSTANCE_GET_PRIVATE ((obj), EEK_TYPE_KEY, EekKeyPrivate))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
struct _EekKeyPrivate
 | 
			
		||||
typedef struct _EekKeyPrivate
 | 
			
		||||
{
 | 
			
		||||
    guint keycode;
 | 
			
		||||
    EekSymbolMatrix *symbol_matrix;
 | 
			
		||||
    gint column;
 | 
			
		||||
    gint row;
 | 
			
		||||
    gulong oref;
 | 
			
		||||
    gulong oref; // UI outline reference
 | 
			
		||||
    gboolean is_pressed;
 | 
			
		||||
    gboolean is_locked;
 | 
			
		||||
};
 | 
			
		||||
} EekKeyPrivate;
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
eek_key_real_pressed (EekKey *self)
 | 
			
		||||
{
 | 
			
		||||
    EekKeyPrivate *priv = EEK_KEY_GET_PRIVATE(self);
 | 
			
		||||
 | 
			
		||||
    priv->is_pressed = TRUE;
 | 
			
		||||
#if DEBUG
 | 
			
		||||
    g_debug ("pressed %X", eek_key_get_keycode (self));
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
eek_key_real_released (EekKey *self)
 | 
			
		||||
{
 | 
			
		||||
    EekKeyPrivate *priv = EEK_KEY_GET_PRIVATE(self);
 | 
			
		||||
 | 
			
		||||
    priv->is_pressed = FALSE;
 | 
			
		||||
#if DEBUG
 | 
			
		||||
    g_debug ("released %X", eek_key_get_keycode (self));
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
G_DEFINE_TYPE_WITH_PRIVATE (EekKey, eek_key, EEK_TYPE_ELEMENT)
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
eek_key_real_locked (EekKey *self)
 | 
			
		||||
{
 | 
			
		||||
    EekKeyPrivate *priv = EEK_KEY_GET_PRIVATE(self);
 | 
			
		||||
    EekKeyPrivate *priv = eek_key_get_instance_private (self);
 | 
			
		||||
 | 
			
		||||
    priv->is_locked = TRUE;
 | 
			
		||||
#if DEBUG
 | 
			
		||||
@ -114,7 +81,7 @@ eek_key_real_locked (EekKey *self)
 | 
			
		||||
static void
 | 
			
		||||
eek_key_real_unlocked (EekKey *self)
 | 
			
		||||
{
 | 
			
		||||
    EekKeyPrivate *priv = EEK_KEY_GET_PRIVATE(self);
 | 
			
		||||
    EekKeyPrivate *priv = eek_key_get_instance_private (self);
 | 
			
		||||
 | 
			
		||||
    priv->is_locked = FALSE;
 | 
			
		||||
#if DEBUG
 | 
			
		||||
@ -122,22 +89,14 @@ eek_key_real_unlocked (EekKey *self)
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
eek_key_real_cancelled (EekKey *self)
 | 
			
		||||
{
 | 
			
		||||
    EekKeyPrivate *priv = EEK_KEY_GET_PRIVATE(self);
 | 
			
		||||
 | 
			
		||||
    priv->is_pressed = FALSE;
 | 
			
		||||
#if DEBUG
 | 
			
		||||
    g_debug ("cancelled %X", eek_key_get_keycode (self));
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
eek_key_finalize (GObject *object)
 | 
			
		||||
{
 | 
			
		||||
    EekKeyPrivate *priv = EEK_KEY_GET_PRIVATE(object);
 | 
			
		||||
    EekKey        *self = EEK_KEY (object);
 | 
			
		||||
    EekKeyPrivate *priv = eek_key_get_instance_private (self);
 | 
			
		||||
 | 
			
		||||
    eek_symbol_matrix_free (priv->symbol_matrix);
 | 
			
		||||
 | 
			
		||||
    G_OBJECT_CLASS (eek_key_parent_class)->finalize (object);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -214,19 +173,13 @@ eek_key_class_init (EekKeyClass *klass)
 | 
			
		||||
    GObjectClass      *gobject_class = G_OBJECT_CLASS (klass);
 | 
			
		||||
    GParamSpec        *pspec;
 | 
			
		||||
 | 
			
		||||
    g_type_class_add_private (gobject_class,
 | 
			
		||||
                              sizeof (EekKeyPrivate));
 | 
			
		||||
 | 
			
		||||
    gobject_class->set_property = eek_key_set_property;
 | 
			
		||||
    gobject_class->get_property = eek_key_get_property;
 | 
			
		||||
    gobject_class->finalize     = eek_key_finalize;
 | 
			
		||||
 | 
			
		||||
    /* signals */
 | 
			
		||||
    klass->pressed = eek_key_real_pressed;
 | 
			
		||||
    klass->released = eek_key_real_released;
 | 
			
		||||
    klass->locked = eek_key_real_locked;
 | 
			
		||||
    klass->unlocked = eek_key_real_unlocked;
 | 
			
		||||
    klass->cancelled = eek_key_real_cancelled;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * EekKey:keycode:
 | 
			
		||||
@ -288,42 +241,6 @@ eek_key_class_init (EekKeyClass *klass)
 | 
			
		||||
                                G_PARAM_READWRITE);
 | 
			
		||||
    g_object_class_install_property (gobject_class, PROP_OREF, pspec);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * EekKey::pressed:
 | 
			
		||||
     * @key: an #EekKey
 | 
			
		||||
     *
 | 
			
		||||
     * The ::pressed signal is emitted each time @key is shifted to
 | 
			
		||||
     * the pressed state.  The class handler runs before signal
 | 
			
		||||
     * handlers to allow signal handlers to read the status of @key
 | 
			
		||||
     * with eek_key_is_pressed().
 | 
			
		||||
     */
 | 
			
		||||
    signals[PRESSED] =
 | 
			
		||||
        g_signal_new (I_("pressed"),
 | 
			
		||||
                      G_TYPE_FROM_CLASS(gobject_class),
 | 
			
		||||
                      G_SIGNAL_RUN_FIRST,
 | 
			
		||||
                      G_STRUCT_OFFSET(EekKeyClass, pressed),
 | 
			
		||||
                      NULL,
 | 
			
		||||
                      NULL,
 | 
			
		||||
                      g_cclosure_marshal_VOID__VOID,
 | 
			
		||||
                      G_TYPE_NONE, 0);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * EekKey::released:
 | 
			
		||||
     * @key: an #EekKey
 | 
			
		||||
     *
 | 
			
		||||
     * The ::released signal is emitted each time @key is shifted to
 | 
			
		||||
     * the released state.
 | 
			
		||||
     */
 | 
			
		||||
   signals[RELEASED] =
 | 
			
		||||
        g_signal_new (I_("released"),
 | 
			
		||||
                      G_TYPE_FROM_CLASS(gobject_class),
 | 
			
		||||
                      G_SIGNAL_RUN_LAST,
 | 
			
		||||
                      G_STRUCT_OFFSET(EekKeyClass, released),
 | 
			
		||||
                      NULL,
 | 
			
		||||
                      NULL,
 | 
			
		||||
                      g_cclosure_marshal_VOID__VOID,
 | 
			
		||||
                      G_TYPE_NONE, 0);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * EekKey::locked:
 | 
			
		||||
     * @key: an #EekKey
 | 
			
		||||
@ -359,31 +276,12 @@ eek_key_class_init (EekKeyClass *klass)
 | 
			
		||||
                      NULL,
 | 
			
		||||
                      g_cclosure_marshal_VOID__VOID,
 | 
			
		||||
                      G_TYPE_NONE, 0);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * EekKey::cancelled:
 | 
			
		||||
     * @key: an #EekKey
 | 
			
		||||
     *
 | 
			
		||||
     * The ::cancelled signal is emitted each time @key is shifted to
 | 
			
		||||
     * the cancelled state.
 | 
			
		||||
     */
 | 
			
		||||
   signals[CANCELLED] =
 | 
			
		||||
        g_signal_new (I_("cancelled"),
 | 
			
		||||
                      G_TYPE_FROM_CLASS(gobject_class),
 | 
			
		||||
                      G_SIGNAL_RUN_LAST,
 | 
			
		||||
                      G_STRUCT_OFFSET(EekKeyClass, cancelled),
 | 
			
		||||
                      NULL,
 | 
			
		||||
                      NULL,
 | 
			
		||||
                      g_cclosure_marshal_VOID__VOID,
 | 
			
		||||
                      G_TYPE_NONE, 0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
eek_key_init (EekKey *self)
 | 
			
		||||
{
 | 
			
		||||
    EekKeyPrivate *priv;
 | 
			
		||||
 | 
			
		||||
    priv = self->priv = EEK_KEY_GET_PRIVATE(self);
 | 
			
		||||
    EekKeyPrivate *priv = eek_key_get_instance_private (self);
 | 
			
		||||
    priv->symbol_matrix = eek_symbol_matrix_new (0, 0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -403,7 +301,10 @@ eek_key_set_keycode (EekKey *key,
 | 
			
		||||
                     guint   keycode)
 | 
			
		||||
{
 | 
			
		||||
    g_return_if_fail (EEK_IS_KEY (key));
 | 
			
		||||
    key->priv->keycode = keycode;
 | 
			
		||||
 | 
			
		||||
    EekKeyPrivate *priv = eek_key_get_instance_private (key);
 | 
			
		||||
 | 
			
		||||
    priv->keycode = keycode;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@ -417,7 +318,10 @@ guint
 | 
			
		||||
eek_key_get_keycode (EekKey *key)
 | 
			
		||||
{
 | 
			
		||||
    g_return_val_if_fail (EEK_IS_KEY (key), EEK_INVALID_KEYCODE);
 | 
			
		||||
    return key->priv->keycode;
 | 
			
		||||
 | 
			
		||||
    EekKeyPrivate *priv = eek_key_get_instance_private (key);
 | 
			
		||||
 | 
			
		||||
    return priv->keycode;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@ -433,8 +337,10 @@ eek_key_set_symbol_matrix (EekKey          *key,
 | 
			
		||||
{
 | 
			
		||||
    g_return_if_fail (EEK_IS_KEY(key));
 | 
			
		||||
 | 
			
		||||
    eek_symbol_matrix_free (key->priv->symbol_matrix);
 | 
			
		||||
    key->priv->symbol_matrix = eek_symbol_matrix_copy (matrix);
 | 
			
		||||
    EekKeyPrivate *priv = eek_key_get_instance_private (key);
 | 
			
		||||
 | 
			
		||||
    eek_symbol_matrix_free (priv->symbol_matrix);
 | 
			
		||||
    priv->symbol_matrix = eek_symbol_matrix_copy (matrix);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@ -448,7 +354,10 @@ EekSymbolMatrix *
 | 
			
		||||
eek_key_get_symbol_matrix (EekKey *key)
 | 
			
		||||
{
 | 
			
		||||
    g_return_val_if_fail (EEK_IS_KEY(key), NULL);
 | 
			
		||||
    return key->priv->symbol_matrix;
 | 
			
		||||
 | 
			
		||||
    EekKeyPrivate *priv = eek_key_get_instance_private (key);
 | 
			
		||||
 | 
			
		||||
    return priv->symbol_matrix;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@ -536,7 +445,7 @@ eek_key_get_symbol_at_index (EekKey *key,
 | 
			
		||||
                             gint    fallback_group,
 | 
			
		||||
                             gint    fallback_level)
 | 
			
		||||
{
 | 
			
		||||
    EekKeyPrivate *priv = EEK_KEY_GET_PRIVATE(key);
 | 
			
		||||
    EekKeyPrivate *priv = eek_key_get_instance_private (key);
 | 
			
		||||
    gint num_symbols;
 | 
			
		||||
 | 
			
		||||
    g_return_val_if_fail (fallback_group >= 0, NULL);
 | 
			
		||||
@ -588,12 +497,14 @@ eek_key_set_index (EekKey *key,
 | 
			
		||||
    g_return_if_fail (0 <= column);
 | 
			
		||||
    g_return_if_fail (0 <= row);
 | 
			
		||||
 | 
			
		||||
    if (key->priv->column != column) {
 | 
			
		||||
        key->priv->column = column;
 | 
			
		||||
    EekKeyPrivate *priv = eek_key_get_instance_private (key);
 | 
			
		||||
 | 
			
		||||
    if (priv->column != column) {
 | 
			
		||||
        priv->column = column;
 | 
			
		||||
        g_object_notify (G_OBJECT(key), "column");
 | 
			
		||||
    }
 | 
			
		||||
    if (key->priv->row != row) {
 | 
			
		||||
        key->priv->row = row;
 | 
			
		||||
    if (priv->row != row) {
 | 
			
		||||
        priv->row = row;
 | 
			
		||||
        g_object_notify (G_OBJECT(key), "row");
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -614,10 +525,12 @@ eek_key_get_index (EekKey *key,
 | 
			
		||||
    g_return_if_fail (EEK_IS_KEY(key));
 | 
			
		||||
    g_return_if_fail (column != NULL || row != NULL);
 | 
			
		||||
 | 
			
		||||
    EekKeyPrivate *priv = eek_key_get_instance_private (key);
 | 
			
		||||
 | 
			
		||||
    if (column != NULL)
 | 
			
		||||
        *column = key->priv->column;
 | 
			
		||||
        *column = priv->column;
 | 
			
		||||
    if (row != NULL)
 | 
			
		||||
        *row = key->priv->row;
 | 
			
		||||
        *row = priv->row;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@ -632,8 +545,11 @@ eek_key_set_oref (EekKey *key,
 | 
			
		||||
                  guint   oref)
 | 
			
		||||
{
 | 
			
		||||
    g_return_if_fail (EEK_IS_KEY(key));
 | 
			
		||||
    if (key->priv->oref != oref) {
 | 
			
		||||
        key->priv->oref = oref;
 | 
			
		||||
 | 
			
		||||
    EekKeyPrivate *priv = eek_key_get_instance_private (key);
 | 
			
		||||
 | 
			
		||||
    if (priv->oref != oref) {
 | 
			
		||||
        priv->oref = oref;
 | 
			
		||||
        g_object_notify (G_OBJECT(key), "oref");
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -649,7 +565,10 @@ guint
 | 
			
		||||
eek_key_get_oref (EekKey *key)
 | 
			
		||||
{
 | 
			
		||||
    g_return_val_if_fail (EEK_IS_KEY (key), 0);
 | 
			
		||||
    return key->priv->oref;
 | 
			
		||||
 | 
			
		||||
    EekKeyPrivate *priv = eek_key_get_instance_private (key);
 | 
			
		||||
 | 
			
		||||
    return priv->oref;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@ -662,7 +581,10 @@ gboolean
 | 
			
		||||
eek_key_is_pressed (EekKey *key)
 | 
			
		||||
{
 | 
			
		||||
    g_return_val_if_fail (EEK_IS_KEY(key), FALSE);
 | 
			
		||||
    return key->priv->is_pressed;
 | 
			
		||||
 | 
			
		||||
    EekKeyPrivate *priv = eek_key_get_instance_private (key);
 | 
			
		||||
 | 
			
		||||
    return priv->is_pressed;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@ -675,5 +597,17 @@ gboolean
 | 
			
		||||
eek_key_is_locked (EekKey *key)
 | 
			
		||||
{
 | 
			
		||||
    g_return_val_if_fail (EEK_IS_KEY(key), FALSE);
 | 
			
		||||
    return key->priv->is_locked;
 | 
			
		||||
 | 
			
		||||
    EekKeyPrivate *priv = eek_key_get_instance_private (key);
 | 
			
		||||
 | 
			
		||||
    return priv->is_locked;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void eek_key_set_pressed(EekKey *key, gboolean value)
 | 
			
		||||
{
 | 
			
		||||
    g_return_if_fail (EEK_IS_KEY(key));
 | 
			
		||||
 | 
			
		||||
    EekKeyPrivate *priv = eek_key_get_instance_private (key);
 | 
			
		||||
 | 
			
		||||
    priv->is_pressed = value;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -31,28 +31,7 @@
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
#define EEK_TYPE_KEY (eek_key_get_type())
 | 
			
		||||
#define EEK_KEY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EEK_TYPE_KEY, EekKey))
 | 
			
		||||
#define EEK_KEY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EEK_TYPE_KEY, EekKeyClass))
 | 
			
		||||
#define EEK_IS_KEY(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EEK_TYPE_KEY))
 | 
			
		||||
#define EEK_IS_KEY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EEK_TYPE_KEY))
 | 
			
		||||
#define EEK_KEY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EEK_TYPE_KEY, EekKeyClass))
 | 
			
		||||
 | 
			
		||||
typedef struct _EekKeyClass EekKeyClass;
 | 
			
		||||
typedef struct _EekKeyPrivate EekKeyPrivate;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * EekKey:
 | 
			
		||||
 *
 | 
			
		||||
 * The #EekKey structure contains only private data and should only be
 | 
			
		||||
 * accessed using the provided API.
 | 
			
		||||
 */
 | 
			
		||||
struct _EekKey
 | 
			
		||||
{
 | 
			
		||||
    /*< private >*/
 | 
			
		||||
    EekElement parent;
 | 
			
		||||
 | 
			
		||||
    EekKeyPrivate *priv;
 | 
			
		||||
};
 | 
			
		||||
G_DECLARE_DERIVABLE_TYPE(EekKey, eek_key, EEK, KEY, EekElement)
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * EekKeyClass:
 | 
			
		||||
@ -71,11 +50,8 @@ struct _EekKeyClass
 | 
			
		||||
 | 
			
		||||
    /*< public >*/
 | 
			
		||||
    /* signals */
 | 
			
		||||
    void (* pressed)   (EekKey *key);
 | 
			
		||||
    void (* released)  (EekKey *key);
 | 
			
		||||
    void (* locked)    (EekKey *key);
 | 
			
		||||
    void (* unlocked)  (EekKey *key);
 | 
			
		||||
    void (* cancelled) (EekKey *key);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
GType            eek_key_get_type            (void) G_GNUC_CONST;
 | 
			
		||||
@ -110,6 +86,8 @@ guint            eek_key_get_oref            (EekKey          *key);
 | 
			
		||||
 | 
			
		||||
gboolean         eek_key_is_pressed          (EekKey          *key);
 | 
			
		||||
gboolean         eek_key_is_locked           (EekKey          *key);
 | 
			
		||||
void             eek_key_set_pressed         (EekKey          *key,
 | 
			
		||||
                                              gboolean         value);
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
#endif  /* EEK_KEY_H */
 | 
			
		||||
 | 
			
		||||
@ -199,32 +199,21 @@ void
 | 
			
		||||
_eek_rounded_polygon (cairo_t  *cr,
 | 
			
		||||
                      gdouble   radius,
 | 
			
		||||
                      EekPoint *points,
 | 
			
		||||
                      gint      num_points)
 | 
			
		||||
                      guint     num_points)
 | 
			
		||||
{
 | 
			
		||||
    gint i, j;
 | 
			
		||||
 | 
			
		||||
    cairo_move_to (cr,
 | 
			
		||||
                   (gdouble) (points[num_points - 1].x +
 | 
			
		||||
                              points[0].x) / 2,
 | 
			
		||||
                   (gdouble) (points[num_points - 1].y +
 | 
			
		||||
                              points[0].y) / 2);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#ifdef KBDRAW_DEBUG
 | 
			
		||||
    printf ("    rounded polygon of radius %f:\n", radius);
 | 
			
		||||
#endif
 | 
			
		||||
    for (i = 0; i < num_points; i++) {
 | 
			
		||||
        j = (i + 1) % num_points;
 | 
			
		||||
    for (guint i = 0; i < num_points; i++) {
 | 
			
		||||
        guint j = (i + 1) % num_points;
 | 
			
		||||
        rounded_corner (cr, (gdouble) points[i].x,
 | 
			
		||||
                        (gdouble) points[i].y,
 | 
			
		||||
                        (gdouble) (points[i].x + points[j].x) / 2,
 | 
			
		||||
                        (gdouble) (points[i].y + points[j].y) / 2,
 | 
			
		||||
                        radius);
 | 
			
		||||
#ifdef KBDRAW_DEBUG
 | 
			
		||||
        printf ("      corner (%d, %d) -> (%d, %d):\n",
 | 
			
		||||
                points[i].x, points[i].y, points[j].x,
 | 
			
		||||
                points[j].y);
 | 
			
		||||
#endif
 | 
			
		||||
    };
 | 
			
		||||
    }
 | 
			
		||||
    cairo_close_path (cr);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -32,10 +32,12 @@
 | 
			
		||||
#endif  /* HAVE_CONFIG_H */
 | 
			
		||||
 | 
			
		||||
#include "eek-keyboard.h"
 | 
			
		||||
#include "eek-marshalers.h"
 | 
			
		||||
#include "eek-section.h"
 | 
			
		||||
#include "eek-key.h"
 | 
			
		||||
#include "eek-symbol.h"
 | 
			
		||||
#include "eek-enumtypes.h"
 | 
			
		||||
#include "eekboard/key-emitter.h"
 | 
			
		||||
 | 
			
		||||
enum {
 | 
			
		||||
    PROP_0,
 | 
			
		||||
@ -45,17 +47,20 @@ enum {
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
enum {
 | 
			
		||||
    KEY_PRESSED,
 | 
			
		||||
    KEY_RELEASED,
 | 
			
		||||
    KEY_LOCKED,
 | 
			
		||||
    KEY_UNLOCKED,
 | 
			
		||||
    KEY_CANCELLED,
 | 
			
		||||
    LAST_SIGNAL
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static guint signals[LAST_SIGNAL] = { 0, };
 | 
			
		||||
enum {
 | 
			
		||||
    VIEW_LETTERS_LOWER,
 | 
			
		||||
    VIEW_LETTERS_UPPER,
 | 
			
		||||
    VIEW_NUMBERS,
 | 
			
		||||
    VIEW_SYMBOLS
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
G_DEFINE_TYPE (EekKeyboard, eek_keyboard, EEK_TYPE_CONTAINER);
 | 
			
		||||
static guint signals[LAST_SIGNAL] = { 0, };
 | 
			
		||||
 | 
			
		||||
#define EEK_KEYBOARD_GET_PRIVATE(obj)                                  \
 | 
			
		||||
    (G_TYPE_INSTANCE_GET_PRIVATE ((obj), EEK_TYPE_KEYBOARD, EekKeyboardPrivate))
 | 
			
		||||
@ -65,6 +70,7 @@ struct _EekKeyboardPrivate
 | 
			
		||||
    EekLayout *layout;
 | 
			
		||||
    EekModifierBehavior modifier_behavior;
 | 
			
		||||
    EekModifierType modifiers;
 | 
			
		||||
    EekModifierType old_level;
 | 
			
		||||
    GList *pressed_keys;
 | 
			
		||||
    GList *locked_keys;
 | 
			
		||||
    GArray *outline_array;
 | 
			
		||||
@ -75,6 +81,8 @@ struct _EekKeyboardPrivate
 | 
			
		||||
    EekModifierType alt_gr_mask;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
G_DEFINE_TYPE_WITH_PRIVATE (EekKeyboard, eek_keyboard, EEK_TYPE_CONTAINER);
 | 
			
		||||
 | 
			
		||||
G_DEFINE_BOXED_TYPE(EekModifierKey, eek_modifier_key,
 | 
			
		||||
                    eek_modifier_key_copy, eek_modifier_key_free);
 | 
			
		||||
 | 
			
		||||
@ -91,22 +99,6 @@ eek_modifier_key_free (EekModifierKey *modkey)
 | 
			
		||||
    g_slice_free (EekModifierKey, modkey);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
on_key_pressed (EekSection  *section,
 | 
			
		||||
                EekKey      *key,
 | 
			
		||||
                EekKeyboard *keyboard)
 | 
			
		||||
{
 | 
			
		||||
    g_signal_emit (keyboard, signals[KEY_PRESSED], 0, key);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
on_key_released (EekSection  *section,
 | 
			
		||||
                 EekKey      *key,
 | 
			
		||||
                 EekKeyboard *keyboard)
 | 
			
		||||
{
 | 
			
		||||
    g_signal_emit (keyboard, signals[KEY_RELEASED], 0, key);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
on_key_locked (EekSection  *section,
 | 
			
		||||
                EekKey      *key,
 | 
			
		||||
@ -123,14 +115,6 @@ on_key_unlocked (EekSection  *section,
 | 
			
		||||
    g_signal_emit (keyboard, signals[KEY_UNLOCKED], 0, key);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
on_key_cancelled (EekSection  *section,
 | 
			
		||||
                 EekKey      *key,
 | 
			
		||||
                 EekKeyboard *keyboard)
 | 
			
		||||
{
 | 
			
		||||
    g_signal_emit (keyboard, signals[KEY_CANCELLED], 0, key);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
on_symbol_index_changed (EekSection *section,
 | 
			
		||||
                         gint group,
 | 
			
		||||
@ -230,12 +214,43 @@ static void
 | 
			
		||||
set_level_from_modifiers (EekKeyboard *self)
 | 
			
		||||
{
 | 
			
		||||
    EekKeyboardPrivate *priv = EEK_KEYBOARD_GET_PRIVATE(self);
 | 
			
		||||
    gint level = 0;
 | 
			
		||||
 | 
			
		||||
    if (priv->modifiers & priv->alt_gr_mask)
 | 
			
		||||
        level |= 2;
 | 
			
		||||
    if (priv->modifiers & EEK_SHIFT_MASK)
 | 
			
		||||
        level |= 1;
 | 
			
		||||
    /* The levels are: 0 Letters, 1 Upper case letters, 2 Numbers, 3 Symbols */
 | 
			
		||||
    gint level = ((priv->modifiers & priv->alt_gr_mask) ? 2 : 0) |
 | 
			
		||||
                 ((priv->modifiers & EEK_SHIFT_MASK) ? 1 : 0);
 | 
			
		||||
 | 
			
		||||
    switch (priv->old_level) {
 | 
			
		||||
    case VIEW_LETTERS_UPPER:
 | 
			
		||||
    {
 | 
			
		||||
        /* Redirect upper case letters to numbers instead of symbols, clearing
 | 
			
		||||
           the shift modifier to keep the modifiers in sync with the level */
 | 
			
		||||
        if (level == VIEW_SYMBOLS) {
 | 
			
		||||
            level = VIEW_NUMBERS;
 | 
			
		||||
            priv->modifiers &= ~EEK_SHIFT_MASK;
 | 
			
		||||
        }
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
    case VIEW_SYMBOLS:
 | 
			
		||||
    {
 | 
			
		||||
        /* Redirect symbols to lower case letters instead of upper case,
 | 
			
		||||
           clearing the shift modifier to keep the modifiers in sync with the
 | 
			
		||||
           level */
 | 
			
		||||
        if (level == VIEW_LETTERS_UPPER) {
 | 
			
		||||
            level = VIEW_LETTERS_LOWER;
 | 
			
		||||
            priv->modifiers &= ~EEK_SHIFT_MASK;
 | 
			
		||||
        }
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
    case VIEW_LETTERS_LOWER:    /* Direct transitions between views */
 | 
			
		||||
    case VIEW_NUMBERS:
 | 
			
		||||
    default:
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (level == VIEW_NUMBERS || level == VIEW_SYMBOLS)
 | 
			
		||||
        priv->modifier_behavior = EEK_MODIFIER_BEHAVIOR_LOCK;
 | 
			
		||||
 | 
			
		||||
    priv->old_level = level;
 | 
			
		||||
    eek_element_set_level (EEK_ELEMENT(self), level);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -278,74 +293,76 @@ set_modifiers_with_key (EekKeyboard    *self,
 | 
			
		||||
    priv->modifiers = modifiers;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
eek_keyboard_real_key_pressed (EekKeyboard *self,
 | 
			
		||||
                               EekKey      *key)
 | 
			
		||||
{
 | 
			
		||||
    EekKeyboardPrivate *priv = EEK_KEYBOARD_GET_PRIVATE(self);
 | 
			
		||||
    EekSymbol *symbol;
 | 
			
		||||
    EekModifierType modifier;
 | 
			
		||||
void eek_keyboard_press_key(EekKeyboard *keyboard, EekKey *key, guint32 timestamp) {
 | 
			
		||||
    EekKeyboardPrivate *priv = EEK_KEYBOARD_GET_PRIVATE(keyboard);
 | 
			
		||||
 | 
			
		||||
    eek_key_set_pressed(key, TRUE);
 | 
			
		||||
    priv->pressed_keys = g_list_prepend (priv->pressed_keys, key);
 | 
			
		||||
 | 
			
		||||
    symbol = eek_key_get_symbol_with_fallback (key, 0, 0);
 | 
			
		||||
    EekSymbol *symbol = eek_key_get_symbol_with_fallback (key, 0, 0);
 | 
			
		||||
    if (!symbol)
 | 
			
		||||
        return;
 | 
			
		||||
 | 
			
		||||
    modifier = eek_symbol_get_modifier_mask (symbol);
 | 
			
		||||
    EekModifierType modifier = eek_symbol_get_modifier_mask (symbol);
 | 
			
		||||
    if (priv->modifier_behavior == EEK_MODIFIER_BEHAVIOR_NONE) {
 | 
			
		||||
        set_modifiers_with_key (self, key, priv->modifiers | modifier);
 | 
			
		||||
        set_level_from_modifiers (self);
 | 
			
		||||
        set_modifiers_with_key (keyboard, key, priv->modifiers | modifier);
 | 
			
		||||
        set_level_from_modifiers (keyboard);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // "Borrowed" from eek-context-service; doesn't influence the state but forwards the event
 | 
			
		||||
 | 
			
		||||
    guint keycode = eek_key_get_keycode (key);
 | 
			
		||||
    EekModifierType modifiers = eek_keyboard_get_modifiers (keyboard);
 | 
			
		||||
 | 
			
		||||
    emit_key_activated(keyboard->manager, keyboard, keycode, symbol, modifiers, TRUE, timestamp);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
eek_keyboard_real_key_released (EekKeyboard *self,
 | 
			
		||||
                                EekKey      *key)
 | 
			
		||||
{
 | 
			
		||||
    EekKeyboardPrivate *priv = EEK_KEYBOARD_GET_PRIVATE(self);
 | 
			
		||||
    EekSymbol *symbol;
 | 
			
		||||
    EekModifierType modifier;
 | 
			
		||||
void eek_keyboard_release_key( EekKeyboard *keyboard,
 | 
			
		||||
                               EekKey      *key,
 | 
			
		||||
                               guint32      timestamp) {
 | 
			
		||||
    EekKeyboardPrivate *priv = EEK_KEYBOARD_GET_PRIVATE(keyboard);
 | 
			
		||||
 | 
			
		||||
    EEK_KEYBOARD_GET_CLASS (self)->key_cancelled (self, key);
 | 
			
		||||
 | 
			
		||||
    symbol = eek_key_get_symbol_with_fallback (key, 0, 0);
 | 
			
		||||
    if (!symbol)
 | 
			
		||||
        return;
 | 
			
		||||
 | 
			
		||||
    modifier = eek_symbol_get_modifier_mask (symbol);
 | 
			
		||||
    switch (priv->modifier_behavior) {
 | 
			
		||||
    case EEK_MODIFIER_BEHAVIOR_NONE:
 | 
			
		||||
        set_modifiers_with_key (self, key, priv->modifiers & ~modifier);
 | 
			
		||||
        break;
 | 
			
		||||
    case EEK_MODIFIER_BEHAVIOR_LOCK:
 | 
			
		||||
        priv->modifiers ^= modifier;
 | 
			
		||||
        break;
 | 
			
		||||
    case EEK_MODIFIER_BEHAVIOR_LATCH:
 | 
			
		||||
        if (modifier)
 | 
			
		||||
            set_modifiers_with_key (self, key, priv->modifiers ^ modifier);
 | 
			
		||||
        else
 | 
			
		||||
            set_modifiers_with_key (self, key,
 | 
			
		||||
                                    (priv->modifiers ^ modifier) & modifier);
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
    set_level_from_modifiers (self);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
eek_keyboard_real_key_cancelled (EekKeyboard *self,
 | 
			
		||||
                                 EekKey      *key)
 | 
			
		||||
{
 | 
			
		||||
    EekKeyboardPrivate *priv = EEK_KEYBOARD_GET_PRIVATE(self);
 | 
			
		||||
    GList *head;
 | 
			
		||||
 | 
			
		||||
    for (head = priv->pressed_keys; head; head = g_list_next (head)) {
 | 
			
		||||
    for (GList *head = priv->pressed_keys; head; head = g_list_next (head)) {
 | 
			
		||||
        if (head->data == key) {
 | 
			
		||||
            priv->pressed_keys = g_list_remove_link (priv->pressed_keys, head);
 | 
			
		||||
            g_list_free1 (head);
 | 
			
		||||
            break;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    EekSymbol *symbol = eek_key_get_symbol_with_fallback (key, 0, 0);
 | 
			
		||||
    if (!symbol)
 | 
			
		||||
        return;
 | 
			
		||||
 | 
			
		||||
    EekModifierType modifier = eek_symbol_get_modifier_mask (symbol);
 | 
			
		||||
 | 
			
		||||
    if (!symbol)
 | 
			
		||||
        return;
 | 
			
		||||
 | 
			
		||||
    modifier = eek_symbol_get_modifier_mask (symbol);
 | 
			
		||||
    switch (priv->modifier_behavior) {
 | 
			
		||||
    case EEK_MODIFIER_BEHAVIOR_NONE:
 | 
			
		||||
        set_modifiers_with_key (keyboard, key, priv->modifiers & ~modifier);
 | 
			
		||||
        break;
 | 
			
		||||
    case EEK_MODIFIER_BEHAVIOR_LOCK:
 | 
			
		||||
        priv->modifiers ^= modifier;
 | 
			
		||||
        break;
 | 
			
		||||
    case EEK_MODIFIER_BEHAVIOR_LATCH:
 | 
			
		||||
        if (modifier)
 | 
			
		||||
            set_modifiers_with_key (keyboard, key, priv->modifiers ^ modifier);
 | 
			
		||||
        else
 | 
			
		||||
            set_modifiers_with_key (keyboard, key,
 | 
			
		||||
                                    (priv->modifiers ^ modifier) & modifier);
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
    set_level_from_modifiers (keyboard);
 | 
			
		||||
 | 
			
		||||
    // "Borrowed" from eek-context-service; doesn't influence the state but forwards the event
 | 
			
		||||
 | 
			
		||||
    guint keycode = eek_key_get_keycode (key);
 | 
			
		||||
    guint modifiers = eek_keyboard_get_modifiers (keyboard);
 | 
			
		||||
 | 
			
		||||
    emit_key_activated(keyboard->manager, keyboard, keycode, symbol, modifiers, FALSE, timestamp);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
@ -365,7 +382,7 @@ static void
 | 
			
		||||
eek_keyboard_finalize (GObject *object)
 | 
			
		||||
{
 | 
			
		||||
    EekKeyboardPrivate *priv = EEK_KEYBOARD_GET_PRIVATE(object);
 | 
			
		||||
    gint i;
 | 
			
		||||
    guint i;
 | 
			
		||||
 | 
			
		||||
    g_list_free (priv->pressed_keys);
 | 
			
		||||
    g_list_free_full (priv->locked_keys,
 | 
			
		||||
@ -389,16 +406,10 @@ static void
 | 
			
		||||
eek_keyboard_real_child_added (EekContainer *self,
 | 
			
		||||
                               EekElement   *element)
 | 
			
		||||
{
 | 
			
		||||
    g_signal_connect (element, "key-pressed",
 | 
			
		||||
                      G_CALLBACK(on_key_pressed), self);
 | 
			
		||||
    g_signal_connect (element, "key-released",
 | 
			
		||||
                      G_CALLBACK(on_key_released), self);
 | 
			
		||||
    g_signal_connect (element, "key-locked",
 | 
			
		||||
                      G_CALLBACK(on_key_locked), self);
 | 
			
		||||
    g_signal_connect (element, "key-unlocked",
 | 
			
		||||
                      G_CALLBACK(on_key_unlocked), self);
 | 
			
		||||
    g_signal_connect (element, "key-cancelled",
 | 
			
		||||
                      G_CALLBACK(on_key_cancelled), self);
 | 
			
		||||
    g_signal_connect (element, "symbol-index-changed",
 | 
			
		||||
                      G_CALLBACK(on_symbol_index_changed), self);
 | 
			
		||||
}
 | 
			
		||||
@ -407,11 +418,8 @@ static void
 | 
			
		||||
eek_keyboard_real_child_removed (EekContainer *self,
 | 
			
		||||
                                 EekElement   *element)
 | 
			
		||||
{
 | 
			
		||||
    g_signal_handlers_disconnect_by_func (element, on_key_pressed, self);
 | 
			
		||||
    g_signal_handlers_disconnect_by_func (element, on_key_released, self);
 | 
			
		||||
    g_signal_handlers_disconnect_by_func (element, on_key_locked, self);
 | 
			
		||||
    g_signal_handlers_disconnect_by_func (element, on_key_unlocked, self);
 | 
			
		||||
    g_signal_handlers_disconnect_by_func (element, on_key_cancelled, self);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
@ -421,16 +429,9 @@ eek_keyboard_class_init (EekKeyboardClass *klass)
 | 
			
		||||
    GObjectClass      *gobject_class = G_OBJECT_CLASS (klass);
 | 
			
		||||
    GParamSpec        *pspec;
 | 
			
		||||
 | 
			
		||||
    g_type_class_add_private (gobject_class,
 | 
			
		||||
                              sizeof (EekKeyboardPrivate));
 | 
			
		||||
 | 
			
		||||
    klass->create_section = eek_keyboard_real_create_section;
 | 
			
		||||
 | 
			
		||||
    /* signals */
 | 
			
		||||
    klass->key_pressed = eek_keyboard_real_key_pressed;
 | 
			
		||||
    klass->key_released = eek_keyboard_real_key_released;
 | 
			
		||||
    klass->key_cancelled = eek_keyboard_real_key_cancelled;
 | 
			
		||||
 | 
			
		||||
    container_class->child_added = eek_keyboard_real_child_added;
 | 
			
		||||
    container_class->child_removed = eek_keyboard_real_child_removed;
 | 
			
		||||
 | 
			
		||||
@ -468,46 +469,6 @@ eek_keyboard_class_init (EekKeyboardClass *klass)
 | 
			
		||||
                                     PROP_MODIFIER_BEHAVIOR,
 | 
			
		||||
                                     pspec);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * EekKeyboard::key-pressed:
 | 
			
		||||
     * @keyboard: an #EekKeyboard
 | 
			
		||||
     * @key: an #EekKey
 | 
			
		||||
     *
 | 
			
		||||
     * The ::key-pressed signal is emitted each time a key in @keyboard
 | 
			
		||||
     * is shifted to the pressed state.
 | 
			
		||||
     */
 | 
			
		||||
    signals[KEY_PRESSED] =
 | 
			
		||||
        g_signal_new (I_("key-pressed"),
 | 
			
		||||
                      G_TYPE_FROM_CLASS(gobject_class),
 | 
			
		||||
                      G_SIGNAL_RUN_LAST,
 | 
			
		||||
                      G_STRUCT_OFFSET(EekKeyboardClass, key_pressed),
 | 
			
		||||
                      NULL,
 | 
			
		||||
                      NULL,
 | 
			
		||||
                      g_cclosure_marshal_VOID__OBJECT,
 | 
			
		||||
                      G_TYPE_NONE,
 | 
			
		||||
                      1,
 | 
			
		||||
                      EEK_TYPE_KEY);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * EekKeyboard::key-released:
 | 
			
		||||
     * @keyboard: an #EekKeyboard
 | 
			
		||||
     * @key: an #EekKey
 | 
			
		||||
     *
 | 
			
		||||
     * The ::key-released signal is emitted each time a key in @keyboard
 | 
			
		||||
     * is shifted to the released state.
 | 
			
		||||
     */
 | 
			
		||||
    signals[KEY_RELEASED] =
 | 
			
		||||
        g_signal_new (I_("key-released"),
 | 
			
		||||
                      G_TYPE_FROM_CLASS(gobject_class),
 | 
			
		||||
                      G_SIGNAL_RUN_LAST,
 | 
			
		||||
                      G_STRUCT_OFFSET(EekKeyboardClass, key_released),
 | 
			
		||||
                      NULL,
 | 
			
		||||
                      NULL,
 | 
			
		||||
                      g_cclosure_marshal_VOID__OBJECT,
 | 
			
		||||
                      G_TYPE_NONE,
 | 
			
		||||
                      1,
 | 
			
		||||
                      EEK_TYPE_KEY);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * EekKeyboard::key-locked:
 | 
			
		||||
     * @keyboard: an #EekKeyboard
 | 
			
		||||
@ -547,26 +508,6 @@ eek_keyboard_class_init (EekKeyboardClass *klass)
 | 
			
		||||
                      G_TYPE_NONE,
 | 
			
		||||
                      1,
 | 
			
		||||
                      EEK_TYPE_KEY);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * EekKeyboard::key-cancelled:
 | 
			
		||||
     * @keyboard: an #EekKeyboard
 | 
			
		||||
     * @key: an #EekKey
 | 
			
		||||
     *
 | 
			
		||||
     * The ::key-cancelled signal is emitted each time a key in @keyboard
 | 
			
		||||
     * is shifted to the cancelled state.
 | 
			
		||||
     */
 | 
			
		||||
    signals[KEY_CANCELLED] =
 | 
			
		||||
        g_signal_new (I_("key-cancelled"),
 | 
			
		||||
                      G_TYPE_FROM_CLASS(gobject_class),
 | 
			
		||||
                      G_SIGNAL_RUN_LAST,
 | 
			
		||||
                      G_STRUCT_OFFSET(EekKeyboardClass, key_cancelled),
 | 
			
		||||
                      NULL,
 | 
			
		||||
                      NULL,
 | 
			
		||||
                      g_cclosure_marshal_VOID__OBJECT,
 | 
			
		||||
                      G_TYPE_NONE,
 | 
			
		||||
                      1,
 | 
			
		||||
                      EEK_TYPE_KEY);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
@ -833,7 +774,7 @@ eek_keyboard_get_pressed_keys (EekKeyboard *keyboard)
 | 
			
		||||
 * @keyboard: an #EekKeyboard
 | 
			
		||||
 *
 | 
			
		||||
 * Get locked keys.
 | 
			
		||||
 * Returns: (transfer container) (element-type EekModifierKey): A list
 | 
			
		||||
 * Returns: (transfer container) (element-type Eek.ModifierKey): A list
 | 
			
		||||
 * of locked keys.
 | 
			
		||||
 */
 | 
			
		||||
GList *
 | 
			
		||||
 | 
			
		||||
@ -26,6 +26,7 @@
 | 
			
		||||
#define EEK_KEYBOARD_H 1
 | 
			
		||||
 | 
			
		||||
#include <glib-object.h>
 | 
			
		||||
#include <xkbcommon/xkbcommon.h>
 | 
			
		||||
#include "eek-container.h"
 | 
			
		||||
#include "eek-types.h"
 | 
			
		||||
#include "eek-layout.h"
 | 
			
		||||
@ -45,6 +46,10 @@ typedef struct _EekKeyboardPrivate EekKeyboardPrivate;
 | 
			
		||||
/**
 | 
			
		||||
 * EekKeyboard:
 | 
			
		||||
 *
 | 
			
		||||
 * Contains the state of the physical keyboard.
 | 
			
		||||
 *
 | 
			
		||||
 * Is also a graphical element...
 | 
			
		||||
 *
 | 
			
		||||
 * The #EekKeyboard structure contains only private data and should
 | 
			
		||||
 * only be accessed using the provided API.
 | 
			
		||||
 */
 | 
			
		||||
@ -54,6 +59,11 @@ struct _EekKeyboard
 | 
			
		||||
    EekContainer parent;
 | 
			
		||||
 | 
			
		||||
    EekKeyboardPrivate *priv;
 | 
			
		||||
    struct xkb_keymap *keymap;
 | 
			
		||||
    int keymap_fd; // keymap formatted as XKB string
 | 
			
		||||
    size_t keymap_len; // length of the data inside keymap_fd
 | 
			
		||||
 | 
			
		||||
    EekboardContextService *manager; // unowned reference
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@ -82,12 +92,6 @@ struct _EekKeyboardClass
 | 
			
		||||
    EekKey     *(* find_key_by_keycode) (EekKeyboard *self,
 | 
			
		||||
                                         guint        keycode);
 | 
			
		||||
 | 
			
		||||
    /* signals */
 | 
			
		||||
    void        (* key_pressed)         (EekKeyboard *self,
 | 
			
		||||
                                         EekKey      *key);
 | 
			
		||||
    void        (* key_released)        (EekKeyboard *self,
 | 
			
		||||
                                         EekKey      *key);
 | 
			
		||||
 | 
			
		||||
    /*< private >*/
 | 
			
		||||
    /* obsolete members moved to EekElement */
 | 
			
		||||
    gpointer symbol_index_changed;
 | 
			
		||||
@ -98,8 +102,6 @@ struct _EekKeyboardClass
 | 
			
		||||
                                         EekKey      *key);
 | 
			
		||||
    void        (* key_unlocked)        (EekKeyboard *self,
 | 
			
		||||
                                         EekKey      *key);
 | 
			
		||||
    void        (* key_cancelled)        (EekKeyboard *self,
 | 
			
		||||
                                         EekKey      *key);
 | 
			
		||||
 | 
			
		||||
    /*< private >*/
 | 
			
		||||
    /* padding */
 | 
			
		||||
@ -121,12 +123,13 @@ struct _EekModifierKey {
 | 
			
		||||
};
 | 
			
		||||
typedef struct _EekModifierKey EekModifierKey;
 | 
			
		||||
 | 
			
		||||
GType               eek_keyboard_get_type
 | 
			
		||||
                                     (void) G_GNUC_CONST;
 | 
			
		||||
 | 
			
		||||
EekKeyboard        *eek_keyboard_new (EekLayout          *layout,
 | 
			
		||||
EekKeyboard        *eek_keyboard_new (EekboardContextService *manager,
 | 
			
		||||
                                      EekLayout          *layout,
 | 
			
		||||
                                      gdouble             initial_width,
 | 
			
		||||
                                      gdouble             initial_height);
 | 
			
		||||
GType               eek_keyboard_get_type
 | 
			
		||||
                                     (void) G_GNUC_CONST;
 | 
			
		||||
EekLayout          *eek_keyboard_get_layout
 | 
			
		||||
                                     (EekKeyboard        *keyboard);
 | 
			
		||||
void                eek_keyboard_get_size
 | 
			
		||||
@ -188,5 +191,8 @@ EekModifierKey     *eek_modifier_key_copy
 | 
			
		||||
void                eek_modifier_key_free
 | 
			
		||||
                                     (EekModifierKey      *modkey);
 | 
			
		||||
 | 
			
		||||
void eek_keyboard_press_key(EekKeyboard *keyboard, EekKey *key, guint32 timestamp);
 | 
			
		||||
void eek_keyboard_release_key(EekKeyboard *keyboard, EekKey *key, guint32 timestamp);
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
#endif  /* EEK_KEYBOARD_H */
 | 
			
		||||
 | 
			
		||||
@ -50,9 +50,10 @@
 | 
			
		||||
#define EEK_KEYSYM_Hyper_L 0xffed
 | 
			
		||||
#define EEK_KEYSYM_Hyper_R 0xffee
 | 
			
		||||
 | 
			
		||||
struct _EekKeysymPrivate {
 | 
			
		||||
typedef struct _EekKeysymPrivate
 | 
			
		||||
{
 | 
			
		||||
    guint xkeysym;
 | 
			
		||||
};
 | 
			
		||||
} EekKeysymPrivate;
 | 
			
		||||
 | 
			
		||||
struct _EekKeysymEntry {
 | 
			
		||||
    guint xkeysym;
 | 
			
		||||
@ -68,12 +69,11 @@ typedef struct _EekKeysymEntry EekKeysymEntry;
 | 
			
		||||
 | 
			
		||||
static void eek_serializable_iface_init (EekSerializableIface *iface);
 | 
			
		||||
 | 
			
		||||
G_DEFINE_TYPE_WITH_CODE (EekKeysym, eek_keysym, EEK_TYPE_SYMBOL,
 | 
			
		||||
                         G_IMPLEMENT_INTERFACE (EEK_TYPE_SERIALIZABLE,
 | 
			
		||||
                                                eek_serializable_iface_init));
 | 
			
		||||
 | 
			
		||||
#define EEK_KEYSYM_GET_PRIVATE(obj)                                  \
 | 
			
		||||
    (G_TYPE_INSTANCE_GET_PRIVATE ((obj), EEK_TYPE_KEYSYM, EekKeysymPrivate))
 | 
			
		||||
G_DEFINE_TYPE_EXTENDED (EekKeysym, eek_keysym, EEK_TYPE_SYMBOL,
 | 
			
		||||
			0, /* GTypeFlags */
 | 
			
		||||
			G_ADD_PRIVATE (EekKeysym)
 | 
			
		||||
                        G_IMPLEMENT_INTERFACE (EEK_TYPE_SERIALIZABLE,
 | 
			
		||||
                                               eek_serializable_iface_init))
 | 
			
		||||
 | 
			
		||||
static EekSerializableIface *eek_keysym_parent_serializable_iface;
 | 
			
		||||
 | 
			
		||||
@ -81,7 +81,8 @@ static void
 | 
			
		||||
eek_keysym_real_serialize (EekSerializable *self,
 | 
			
		||||
                           GVariantBuilder *builder)
 | 
			
		||||
{
 | 
			
		||||
    EekKeysymPrivate *priv = EEK_KEYSYM_GET_PRIVATE(self);
 | 
			
		||||
    EekKeysymPrivate *priv = eek_keysym_get_instance_private (
 | 
			
		||||
		    EEK_KEYSYM(self));
 | 
			
		||||
 | 
			
		||||
    eek_keysym_parent_serializable_iface->serialize (self, builder);
 | 
			
		||||
 | 
			
		||||
@ -93,7 +94,8 @@ eek_keysym_real_deserialize (EekSerializable *self,
 | 
			
		||||
                             GVariant        *variant,
 | 
			
		||||
                             gsize            index)
 | 
			
		||||
{
 | 
			
		||||
    EekKeysymPrivate *priv = EEK_KEYSYM_GET_PRIVATE(self);
 | 
			
		||||
    EekKeysymPrivate *priv = eek_keysym_get_instance_private (
 | 
			
		||||
		    EEK_KEYSYM(self));
 | 
			
		||||
 | 
			
		||||
    index = eek_keysym_parent_serializable_iface->deserialize (self,
 | 
			
		||||
                                                               variant,
 | 
			
		||||
@ -177,7 +179,7 @@ get_modifier_mask (guint xkeysym)
 | 
			
		||||
    case EEK_KEYSYM_Shift_Lock:
 | 
			
		||||
        return EEK_SHIFT_MASK;
 | 
			
		||||
    case EEK_KEYSYM_ISO_Level3_Shift:
 | 
			
		||||
        return EEK_MOD5_MASK;
 | 
			
		||||
        return EEK_BUTTON1_MASK;
 | 
			
		||||
    case EEK_KEYSYM_Control_L:
 | 
			
		||||
    case EEK_KEYSYM_Control_R:
 | 
			
		||||
        return EEK_CONTROL_MASK;
 | 
			
		||||
@ -200,15 +202,13 @@ get_modifier_mask (guint xkeysym)
 | 
			
		||||
static void
 | 
			
		||||
eek_keysym_class_init (EekKeysymClass *klass)
 | 
			
		||||
{
 | 
			
		||||
    GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
 | 
			
		||||
 | 
			
		||||
    g_type_class_add_private (gobject_class, sizeof (EekKeysymPrivate));
 | 
			
		||||
    /* void */
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
eek_keysym_init (EekKeysym *self)
 | 
			
		||||
{
 | 
			
		||||
    self->priv = EEK_KEYSYM_GET_PRIVATE(self);
 | 
			
		||||
    /* void */
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@ -291,7 +291,7 @@ eek_keysym_new_with_modifier (guint           xkeysym,
 | 
			
		||||
        g_slice_free (EekKeysymEntry, unichar_entry);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    priv = EEK_KEYSYM_GET_PRIVATE(keysym);
 | 
			
		||||
    priv = eek_keysym_get_instance_private (keysym);
 | 
			
		||||
    priv->xkeysym = xkeysym;
 | 
			
		||||
 | 
			
		||||
    return keysym;
 | 
			
		||||
@ -345,6 +345,6 @@ eek_keysym_get_xkeysym (EekKeysym *keysym)
 | 
			
		||||
    EekKeysymPrivate *priv;
 | 
			
		||||
 | 
			
		||||
    g_assert (EEK_IS_KEYSYM(keysym));
 | 
			
		||||
    priv = EEK_KEYSYM_GET_PRIVATE(keysym);
 | 
			
		||||
    priv = eek_keysym_get_instance_private (keysym);
 | 
			
		||||
    return priv->xkeysym;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -38,27 +38,7 @@ G_BEGIN_DECLS
 | 
			
		||||
#define EEK_INVALID_KEYSYM (0)
 | 
			
		||||
 | 
			
		||||
#define EEK_TYPE_KEYSYM (eek_keysym_get_type())
 | 
			
		||||
#define EEK_KEYSYM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EEK_TYPE_KEYSYM, EekKeysym))
 | 
			
		||||
#define EEK_KEYSYM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EEK_TYPE_KEYSYM, EekKeysymClass))
 | 
			
		||||
#define EEK_IS_KEYSYM(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EEK_TYPE_KEYSYM))
 | 
			
		||||
#define EEK_IS_KEYSYM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EEK_TYPE_KEYSYM))
 | 
			
		||||
#define EEK_KEYSYM_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EEK_TYPE_KEYSYM, EekKeysymClass))
 | 
			
		||||
 | 
			
		||||
typedef struct _EekKeysymClass EekKeysymClass;
 | 
			
		||||
typedef struct _EekKeysymPrivate EekKeysymPrivate;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * EekKeysym:
 | 
			
		||||
 *
 | 
			
		||||
 * The #EekKeysym structure contains only private data and should only
 | 
			
		||||
 * be accessed using the provided API.
 | 
			
		||||
 */
 | 
			
		||||
struct _EekKeysym {
 | 
			
		||||
    /*< private >*/
 | 
			
		||||
    EekSymbol parent;
 | 
			
		||||
 | 
			
		||||
    EekKeysymPrivate *priv;
 | 
			
		||||
};
 | 
			
		||||
G_DECLARE_DERIVABLE_TYPE (EekKeysym, eek_keysym, EEK, KEYSYM, EekSymbol)
 | 
			
		||||
 | 
			
		||||
struct _EekKeysymClass {
 | 
			
		||||
    /*< private >*/
 | 
			
		||||
 | 
			
		||||
@ -32,8 +32,9 @@
 | 
			
		||||
 | 
			
		||||
#include "eek-layout.h"
 | 
			
		||||
#include "eek-keyboard.h"
 | 
			
		||||
#include "eekboard/eekboard-context-service.h"
 | 
			
		||||
 | 
			
		||||
G_DEFINE_ABSTRACT_TYPE (EekLayout, eek_layout, G_TYPE_OBJECT);
 | 
			
		||||
G_DEFINE_ABSTRACT_TYPE (EekLayout, eek_layout, G_TYPE_OBJECT)
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
eek_layout_class_init (EekLayoutClass *klass)
 | 
			
		||||
@ -55,14 +56,16 @@ eek_layout_init (EekLayout *self)
 | 
			
		||||
 * Create a new #EekKeyboard based on @layout.
 | 
			
		||||
 */
 | 
			
		||||
EekKeyboard *
 | 
			
		||||
eek_keyboard_new (EekLayout *layout,
 | 
			
		||||
eek_keyboard_new (EekboardContextService *manager,
 | 
			
		||||
                  EekLayout *layout,
 | 
			
		||||
                  gdouble    initial_width,
 | 
			
		||||
                  gdouble    initial_height)
 | 
			
		||||
{
 | 
			
		||||
    g_assert (EEK_IS_LAYOUT(layout));
 | 
			
		||||
    g_assert (EEK_LAYOUT_GET_CLASS(layout)->create_keyboard);
 | 
			
		||||
 | 
			
		||||
    return EEK_LAYOUT_GET_CLASS(layout)->create_keyboard (layout,
 | 
			
		||||
    return EEK_LAYOUT_GET_CLASS(layout)->create_keyboard (manager,
 | 
			
		||||
                                                          layout,
 | 
			
		||||
                                                          initial_width,
 | 
			
		||||
                                                          initial_height);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -31,20 +31,7 @@
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
#define EEK_TYPE_LAYOUT (eek_layout_get_type())
 | 
			
		||||
#define EEK_LAYOUT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EEK_TYPE_LAYOUT, EekLayout))
 | 
			
		||||
#define EEK_LAYOUT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EEK_TYPE_LAYOUT, EekLayoutClass))
 | 
			
		||||
#define EEK_IS_LAYOUT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EEK_TYPE_LAYOUT))
 | 
			
		||||
#define EEK_IS_LAYOUT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EEK_TYPE_LAYOUT))
 | 
			
		||||
#define EEK_LAYOUT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EEK_TYPE_LAYOUT, EekLayoutClass))
 | 
			
		||||
 | 
			
		||||
typedef struct _EekLayoutClass EekLayoutClass;
 | 
			
		||||
typedef struct _EekLayout EekLayout;
 | 
			
		||||
 | 
			
		||||
struct _EekLayout
 | 
			
		||||
{
 | 
			
		||||
    /*< private >*/
 | 
			
		||||
    GObject parent;
 | 
			
		||||
};
 | 
			
		||||
G_DECLARE_DERIVABLE_TYPE (EekLayout, eek_layout, EEK, LAYOUT, GObject)
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * EekLayoutClass:
 | 
			
		||||
@ -56,7 +43,8 @@ struct _EekLayoutClass
 | 
			
		||||
    GObjectClass parent_class;
 | 
			
		||||
 | 
			
		||||
    /*< public >*/
 | 
			
		||||
    EekKeyboard* (* create_keyboard) (EekLayout *self,
 | 
			
		||||
    EekKeyboard* (* create_keyboard) (EekboardContextService *manager,
 | 
			
		||||
                                      EekLayout *self,
 | 
			
		||||
                                      gdouble    initial_width,
 | 
			
		||||
                                      gdouble    initial_height);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -1,17 +1,17 @@
 | 
			
		||||
/* 
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2010-2011 Daiki Ueno <ueno@unixuser.org>
 | 
			
		||||
 * Copyright (C) 2010-2011 Red Hat, Inc.
 | 
			
		||||
 * 
 | 
			
		||||
 *
 | 
			
		||||
 * This library is free software; you can redistribute it and/or
 | 
			
		||||
 * modify it under the terms of the GNU Lesser General Public License
 | 
			
		||||
 * as published by the Free Software Foundation; either version 2 of
 | 
			
		||||
 * the License, or (at your option) any later version.
 | 
			
		||||
 * 
 | 
			
		||||
 *
 | 
			
		||||
 * This library is distributed in the hope that it will be useful, but
 | 
			
		||||
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
			
		||||
 * Lesser General Public License for more details.
 | 
			
		||||
 * 
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General Public
 | 
			
		||||
 * License along with this library; if not, write to the Free Software
 | 
			
		||||
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 | 
			
		||||
@ -36,12 +36,7 @@ enum {
 | 
			
		||||
    PROP_LAST
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
G_DEFINE_TYPE (EekRenderer, eek_renderer, G_TYPE_OBJECT);
 | 
			
		||||
 | 
			
		||||
#define EEK_RENDERER_GET_PRIVATE(obj)                                  \
 | 
			
		||||
    (G_TYPE_INSTANCE_GET_PRIVATE ((obj), EEK_TYPE_RENDERER, EekRendererPrivate))
 | 
			
		||||
 | 
			
		||||
struct _EekRendererPrivate
 | 
			
		||||
typedef struct _EekRendererPrivate
 | 
			
		||||
{
 | 
			
		||||
    EekKeyboard *keyboard;
 | 
			
		||||
    PangoContext *pcontext;
 | 
			
		||||
@ -62,7 +57,9 @@ struct _EekRendererPrivate
 | 
			
		||||
    gulong symbol_index_changed_handler;
 | 
			
		||||
 | 
			
		||||
    EekTheme *theme;
 | 
			
		||||
};
 | 
			
		||||
} EekRendererPrivate;
 | 
			
		||||
 | 
			
		||||
G_DEFINE_TYPE_WITH_PRIVATE (EekRenderer, eek_renderer, G_TYPE_OBJECT)
 | 
			
		||||
 | 
			
		||||
static const EekColor DEFAULT_FOREGROUND_COLOR = {0.3, 0.3, 0.3, 1.0};
 | 
			
		||||
static const EekColor DEFAULT_BACKGROUND_COLOR = {1.0, 1.0, 1.0, 1.0};
 | 
			
		||||
@ -79,7 +76,7 @@ typedef struct _TextProperty TextProperty;
 | 
			
		||||
extern void _eek_rounded_polygon               (cairo_t     *cr,
 | 
			
		||||
                                                gdouble      radius,
 | 
			
		||||
                                                EekPoint    *points,
 | 
			
		||||
                                                gint         num_points);
 | 
			
		||||
                                                guint         num_points);
 | 
			
		||||
 | 
			
		||||
static void eek_renderer_real_render_key_label (EekRenderer *self,
 | 
			
		||||
                                                PangoLayout *layout,
 | 
			
		||||
@ -106,18 +103,18 @@ create_keyboard_surface_key_callback (EekElement *element,
 | 
			
		||||
                                      gpointer    user_data)
 | 
			
		||||
{
 | 
			
		||||
    CreateKeyboardSurfaceCallbackData *data = user_data;
 | 
			
		||||
    EekRendererPrivate *priv = EEK_RENDERER_GET_PRIVATE(data->renderer);
 | 
			
		||||
    EekRendererPrivate *priv = eek_renderer_get_instance_private (data->renderer);
 | 
			
		||||
    EekBounds bounds;
 | 
			
		||||
 | 
			
		||||
    cairo_save (data->cr);
 | 
			
		||||
 | 
			
		||||
    eek_element_get_bounds (element, &bounds);
 | 
			
		||||
    cairo_translate (data->cr, bounds.x * priv->scale, bounds.y * priv->scale); 
 | 
			
		||||
    cairo_translate (data->cr, bounds.x * priv->scale, bounds.y * priv->scale);
 | 
			
		||||
    cairo_rectangle (data->cr,
 | 
			
		||||
                     0.0,
 | 
			
		||||
                     0.0,
 | 
			
		||||
                     bounds.width * priv->scale,
 | 
			
		||||
                     bounds.height * priv->scale);
 | 
			
		||||
                     bounds.width * priv->scale + 100,
 | 
			
		||||
                     bounds.height * priv->scale + 100);
 | 
			
		||||
    cairo_clip (data->cr);
 | 
			
		||||
    render_key (data->renderer, data->cr, EEK_KEY(element), FALSE);
 | 
			
		||||
 | 
			
		||||
@ -129,7 +126,7 @@ create_keyboard_surface_section_callback (EekElement *element,
 | 
			
		||||
                                          gpointer    user_data)
 | 
			
		||||
{
 | 
			
		||||
    CreateKeyboardSurfaceCallbackData *data = user_data;
 | 
			
		||||
    EekRendererPrivate *priv = EEK_RENDERER_GET_PRIVATE(data->renderer);
 | 
			
		||||
    EekRendererPrivate *priv = eek_renderer_get_instance_private (data->renderer);
 | 
			
		||||
    EekBounds bounds;
 | 
			
		||||
    gint angle;
 | 
			
		||||
 | 
			
		||||
@ -140,7 +137,7 @@ create_keyboard_surface_section_callback (EekElement *element,
 | 
			
		||||
 | 
			
		||||
    angle = eek_section_get_angle (EEK_SECTION(element));
 | 
			
		||||
    cairo_rotate (data->cr, angle * G_PI / 180);
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
    eek_container_foreach_child (EEK_CONTAINER(element),
 | 
			
		||||
                                 create_keyboard_surface_key_callback,
 | 
			
		||||
                                 data);
 | 
			
		||||
@ -151,7 +148,7 @@ create_keyboard_surface_section_callback (EekElement *element,
 | 
			
		||||
static cairo_surface_t *
 | 
			
		||||
create_keyboard_surface (EekRenderer *renderer)
 | 
			
		||||
{
 | 
			
		||||
    EekRendererPrivate *priv = EEK_RENDERER_GET_PRIVATE(renderer);
 | 
			
		||||
    EekRendererPrivate *priv = eek_renderer_get_instance_private (renderer);
 | 
			
		||||
    EekBounds bounds;
 | 
			
		||||
    cairo_surface_t *keyboard_surface;
 | 
			
		||||
    CreateKeyboardSurfaceCallbackData data;
 | 
			
		||||
@ -166,8 +163,8 @@ create_keyboard_surface (EekRenderer *renderer)
 | 
			
		||||
 | 
			
		||||
    eek_element_get_bounds (EEK_ELEMENT(priv->keyboard), &bounds);
 | 
			
		||||
    keyboard_surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
 | 
			
		||||
                                                   bounds.width * priv->scale,
 | 
			
		||||
                                                   bounds.height * priv->scale);
 | 
			
		||||
                                                   ceil(bounds.width * priv->scale),
 | 
			
		||||
                                                   ceil(bounds.height * priv->scale));
 | 
			
		||||
    data.cr = cairo_create (keyboard_surface);
 | 
			
		||||
    data.renderer = renderer;
 | 
			
		||||
 | 
			
		||||
@ -202,11 +199,9 @@ render_key_outline (EekRenderer *renderer,
 | 
			
		||||
                    EekKey      *key,
 | 
			
		||||
                    gboolean     active)
 | 
			
		||||
{
 | 
			
		||||
    EekRendererPrivate *priv = EEK_RENDERER_GET_PRIVATE(renderer);
 | 
			
		||||
    EekRendererPrivate *priv = eek_renderer_get_instance_private (renderer);
 | 
			
		||||
    EekOutline *outline;
 | 
			
		||||
    EekBounds bounds;
 | 
			
		||||
    gdouble scale;
 | 
			
		||||
    gint i;
 | 
			
		||||
    guint oref;
 | 
			
		||||
    EekThemeNode *theme_node;
 | 
			
		||||
    EekColor foreground, background, gradient_start, gradient_end, border_color;
 | 
			
		||||
@ -218,7 +213,7 @@ render_key_outline (EekRenderer *renderer,
 | 
			
		||||
    outline = eek_keyboard_get_outline (priv->keyboard, oref);
 | 
			
		||||
    if (outline == NULL)
 | 
			
		||||
        return;
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
    theme_node = g_object_get_data (G_OBJECT(key),
 | 
			
		||||
                                    active ?
 | 
			
		||||
                                    "theme-node-pressed" :
 | 
			
		||||
@ -233,14 +228,14 @@ render_key_outline (EekRenderer *renderer,
 | 
			
		||||
        border_width = eek_theme_node_get_border_width (theme_node,
 | 
			
		||||
                                                        EEK_SIDE_TOP);
 | 
			
		||||
        border_radius = eek_theme_node_get_border_radius (theme_node,
 | 
			
		||||
                                                          EEK_SIDE_TOP);
 | 
			
		||||
                                                          EEK_CORNER_TOPLEFT);
 | 
			
		||||
        eek_theme_node_get_border_color (theme_node, EEK_SIDE_TOP,
 | 
			
		||||
                                         &border_color);
 | 
			
		||||
    } else {
 | 
			
		||||
        foreground = priv->default_foreground_color;
 | 
			
		||||
        background = priv->default_background_color;
 | 
			
		||||
        gradient_type = EEK_GRADIENT_NONE;
 | 
			
		||||
        border_width = priv->border_width;
 | 
			
		||||
        border_width = (gint)round(priv->border_width);
 | 
			
		||||
        border_radius = -1;
 | 
			
		||||
        border_color.red = ABS(background.red - foreground.red) * 0.7;
 | 
			
		||||
        border_color.green = ABS(background.green - foreground.green) * 0.7;
 | 
			
		||||
@ -248,21 +243,17 @@ render_key_outline (EekRenderer *renderer,
 | 
			
		||||
        border_color.alpha = foreground.alpha;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* need to rescale so that the border fit inside the clipping
 | 
			
		||||
       region */
 | 
			
		||||
    eek_element_get_bounds (EEK_ELEMENT(key), &bounds);
 | 
			
		||||
    scale = MIN((bounds.width - border_width * 2) / bounds.width,
 | 
			
		||||
                (bounds.height - border_width * 2) / bounds.height);
 | 
			
		||||
 | 
			
		||||
    eek_element_get_bounds(EEK_ELEMENT(key), &bounds);
 | 
			
		||||
    outline = eek_outline_copy (outline);
 | 
			
		||||
    for (i = 0; i < outline->num_points; i++) {
 | 
			
		||||
        outline->points[i].x *= priv->scale * scale;
 | 
			
		||||
        outline->points[i].y *= priv->scale * scale;
 | 
			
		||||
 | 
			
		||||
    for (guint i = 0; i < outline->num_points; i++) {
 | 
			
		||||
        outline->points[i].x *= priv->scale;
 | 
			
		||||
        outline->points[i].y *= priv->scale;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    cairo_translate (cr,
 | 
			
		||||
                     border_width * priv->scale * scale,
 | 
			
		||||
                     border_width * priv->scale * scale);
 | 
			
		||||
                     border_width * priv->scale,
 | 
			
		||||
                     border_width * priv->scale);
 | 
			
		||||
 | 
			
		||||
    if (gradient_type != EEK_GRADIENT_NONE) {
 | 
			
		||||
        cairo_pattern_t *pat;
 | 
			
		||||
@ -340,6 +331,10 @@ render_key_outline (EekRenderer *renderer,
 | 
			
		||||
                          outline->num_points);
 | 
			
		||||
    cairo_stroke (cr);
 | 
			
		||||
 | 
			
		||||
    cairo_translate (cr,
 | 
			
		||||
                     -border_width * priv->scale,
 | 
			
		||||
                     -border_width * priv->scale);
 | 
			
		||||
 | 
			
		||||
    eek_outline_free (outline);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -355,7 +350,7 @@ static void
 | 
			
		||||
calculate_font_size_key_callback (EekElement *element, gpointer user_data)
 | 
			
		||||
{
 | 
			
		||||
    CalculateFontSizeCallbackData *data = user_data;
 | 
			
		||||
    EekRendererPrivate *priv = EEK_RENDERER_GET_PRIVATE(data->renderer);
 | 
			
		||||
    EekRendererPrivate *priv = eek_renderer_get_instance_private (data->renderer);
 | 
			
		||||
    gdouble sx, sy;
 | 
			
		||||
    PangoFontDescription *font;
 | 
			
		||||
    PangoRectangle extents = { 0, };
 | 
			
		||||
@ -415,7 +410,7 @@ calculate_font_size (EekRenderer                *renderer,
 | 
			
		||||
                     const PangoFontDescription *base_font,
 | 
			
		||||
                     gboolean                    ascii)
 | 
			
		||||
{
 | 
			
		||||
    EekRendererPrivate *priv = EEK_RENDERER_GET_PRIVATE(renderer);
 | 
			
		||||
    EekRendererPrivate *priv = eek_renderer_get_instance_private (renderer);
 | 
			
		||||
    CalculateFontSizeCallbackData data;
 | 
			
		||||
 | 
			
		||||
    data.size = G_MAXDOUBLE;
 | 
			
		||||
@ -434,7 +429,7 @@ render_key (EekRenderer *self,
 | 
			
		||||
            EekKey      *key,
 | 
			
		||||
            gboolean     active)
 | 
			
		||||
{
 | 
			
		||||
    EekRendererPrivate *priv = EEK_RENDERER_GET_PRIVATE(self);
 | 
			
		||||
    EekRendererPrivate *priv = eek_renderer_get_instance_private (self);
 | 
			
		||||
    EekOutline *outline;
 | 
			
		||||
    cairo_surface_t *outline_surface;
 | 
			
		||||
    EekBounds bounds;
 | 
			
		||||
@ -464,10 +459,12 @@ render_key (EekRenderer *self,
 | 
			
		||||
    if (!outline_surface) {
 | 
			
		||||
        cairo_t *cr;
 | 
			
		||||
 | 
			
		||||
        // Outline will be drawn on the outside of the button, so the
 | 
			
		||||
        // surface needs to be bigger than the button
 | 
			
		||||
        outline_surface =
 | 
			
		||||
            cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
 | 
			
		||||
                                        bounds.width,
 | 
			
		||||
                                        bounds.height);
 | 
			
		||||
                                        (int)ceil(bounds.width) + 10,
 | 
			
		||||
                                        (int)ceil(bounds.height) + 10);
 | 
			
		||||
        cr = cairo_create (outline_surface);
 | 
			
		||||
 | 
			
		||||
        /* blank background */
 | 
			
		||||
@ -489,44 +486,38 @@ render_key (EekRenderer *self,
 | 
			
		||||
    cairo_set_source_surface (cr, outline_surface, 0.0, 0.0);
 | 
			
		||||
    cairo_paint (cr);
 | 
			
		||||
 | 
			
		||||
    eek_renderer_get_foreground_color (self, EEK_ELEMENT(key), &foreground);
 | 
			
		||||
    /* render icon (if any) */
 | 
			
		||||
    symbol = eek_key_get_symbol_with_fallback (key, 0, 0);
 | 
			
		||||
    if (!symbol)
 | 
			
		||||
        return;
 | 
			
		||||
 | 
			
		||||
 #define SCALE 0.8
 | 
			
		||||
    if (eek_symbol_get_icon_name (symbol)) {
 | 
			
		||||
 | 
			
		||||
        cairo_surface_t *icon_surface =
 | 
			
		||||
            eek_renderer_get_icon_surface (self,
 | 
			
		||||
                                           eek_symbol_get_icon_name (symbol),
 | 
			
		||||
                                           MIN(bounds.width, bounds.height) * 0.7);
 | 
			
		||||
                                           MIN(bounds.width, bounds.height));
 | 
			
		||||
        if (icon_surface) {
 | 
			
		||||
            gint width = cairo_image_surface_get_width (icon_surface);
 | 
			
		||||
            gint height = cairo_image_surface_get_height (icon_surface);
 | 
			
		||||
            gdouble scale;
 | 
			
		||||
 | 
			
		||||
            if (width < bounds.width && height < bounds.height)
 | 
			
		||||
                scale = 1;
 | 
			
		||||
            else {
 | 
			
		||||
                if (height * bounds.width / width <= bounds.height)
 | 
			
		||||
                    scale = bounds.width / width;
 | 
			
		||||
                else if (width * bounds.height / height <= bounds.width)
 | 
			
		||||
                    scale = bounds.height / height;
 | 
			
		||||
                else {
 | 
			
		||||
                    if (width * bounds.height < height * bounds.width)
 | 
			
		||||
                        scale = width / bounds.width;
 | 
			
		||||
                    else
 | 
			
		||||
                        scale = height / bounds.height;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            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);
 | 
			
		||||
            cairo_set_source_surface (cr, icon_surface, 0.0, 0.0);
 | 
			
		||||
            cairo_paint (cr);
 | 
			
		||||
            /* Draw the shape of the icon using the foreground color */
 | 
			
		||||
            cairo_set_source_rgba (cr, foreground.red,
 | 
			
		||||
                                       foreground.green,
 | 
			
		||||
                                       foreground.blue,
 | 
			
		||||
                                       foreground.alpha);
 | 
			
		||||
            cairo_mask_surface (cr, icon_surface, 0.0, 0.0);
 | 
			
		||||
            cairo_fill (cr);
 | 
			
		||||
 | 
			
		||||
            cairo_restore (cr);
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
@ -543,7 +534,6 @@ render_key (EekRenderer *self,
 | 
			
		||||
         (bounds.width - extents.width / PANGO_SCALE) / 2,
 | 
			
		||||
         (bounds.height - extents.height / PANGO_SCALE) / 2);
 | 
			
		||||
 | 
			
		||||
    eek_renderer_get_foreground_color (self, EEK_ELEMENT(key), &foreground);
 | 
			
		||||
    cairo_set_source_rgba (cr,
 | 
			
		||||
                           foreground.red,
 | 
			
		||||
                           foreground.green,
 | 
			
		||||
@ -606,7 +596,7 @@ eek_renderer_real_render_key_label (EekRenderer *self,
 | 
			
		||||
                                    PangoLayout *layout,
 | 
			
		||||
                                    EekKey      *key)
 | 
			
		||||
{
 | 
			
		||||
    EekRendererPrivate *priv = EEK_RENDERER_GET_PRIVATE(self);
 | 
			
		||||
    EekRendererPrivate *priv = eek_renderer_get_instance_private (self);
 | 
			
		||||
    EekSymbol *symbol;
 | 
			
		||||
    EekSymbolCategory category;
 | 
			
		||||
    const gchar *label;
 | 
			
		||||
@ -640,7 +630,7 @@ eek_renderer_real_render_key_label (EekRenderer *self,
 | 
			
		||||
 | 
			
		||||
        size = calculate_font_size (self, base_font, FALSE);
 | 
			
		||||
        priv->font = pango_font_description_copy (base_font);
 | 
			
		||||
        pango_font_description_set_size (priv->font, size);
 | 
			
		||||
        pango_font_description_set_size (priv->font, size * 0.6);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    eek_element_get_bounds (EEK_ELEMENT(key), &bounds);
 | 
			
		||||
@ -699,7 +689,7 @@ static void
 | 
			
		||||
eek_renderer_real_render_keyboard (EekRenderer *self,
 | 
			
		||||
                                   cairo_t     *cr)
 | 
			
		||||
{
 | 
			
		||||
    EekRendererPrivate *priv = EEK_RENDERER_GET_PRIVATE(self);
 | 
			
		||||
    EekRendererPrivate *priv = eek_renderer_get_instance_private (self);
 | 
			
		||||
    cairo_pattern_t *source;
 | 
			
		||||
 | 
			
		||||
    g_return_if_fail (priv->keyboard);
 | 
			
		||||
@ -721,7 +711,8 @@ eek_renderer_set_property (GObject      *object,
 | 
			
		||||
                           const GValue *value,
 | 
			
		||||
                           GParamSpec   *pspec)
 | 
			
		||||
{
 | 
			
		||||
    EekRendererPrivate *priv = EEK_RENDERER_GET_PRIVATE(object);
 | 
			
		||||
    EekRendererPrivate *priv = eek_renderer_get_instance_private (
 | 
			
		||||
		    EEK_RENDERER(object));
 | 
			
		||||
 | 
			
		||||
    switch (prop_id) {
 | 
			
		||||
    case PROP_KEYBOARD:
 | 
			
		||||
@ -749,7 +740,8 @@ eek_renderer_get_property (GObject    *object,
 | 
			
		||||
                           GValue     *value,
 | 
			
		||||
                           GParamSpec *pspec)
 | 
			
		||||
{
 | 
			
		||||
    EekRendererPrivate *priv = EEK_RENDERER_GET_PRIVATE(object);
 | 
			
		||||
    EekRendererPrivate *priv = eek_renderer_get_instance_private (
 | 
			
		||||
		    EEK_RENDERER(object));
 | 
			
		||||
 | 
			
		||||
    switch (prop_id) {
 | 
			
		||||
    case PROP_KEYBOARD:
 | 
			
		||||
@ -764,7 +756,8 @@ eek_renderer_get_property (GObject    *object,
 | 
			
		||||
static void
 | 
			
		||||
eek_renderer_dispose (GObject *object)
 | 
			
		||||
{
 | 
			
		||||
    EekRendererPrivate *priv = EEK_RENDERER_GET_PRIVATE(object);
 | 
			
		||||
    EekRenderer        *self = EEK_RENDERER (object);
 | 
			
		||||
    EekRendererPrivate *priv = eek_renderer_get_instance_private (self);
 | 
			
		||||
 | 
			
		||||
    if (priv->keyboard) {
 | 
			
		||||
        if (g_signal_handler_is_connected (priv->keyboard,
 | 
			
		||||
@ -788,7 +781,9 @@ eek_renderer_dispose (GObject *object)
 | 
			
		||||
static void
 | 
			
		||||
eek_renderer_finalize (GObject *object)
 | 
			
		||||
{
 | 
			
		||||
    EekRendererPrivate *priv = EEK_RENDERER_GET_PRIVATE(object);
 | 
			
		||||
    EekRenderer        *self = EEK_RENDERER(object);
 | 
			
		||||
    EekRendererPrivate *priv = eek_renderer_get_instance_private (self);
 | 
			
		||||
 | 
			
		||||
    g_hash_table_destroy (priv->outline_surface_cache);
 | 
			
		||||
    g_hash_table_destroy (priv->active_outline_surface_cache);
 | 
			
		||||
    pango_font_description_free (priv->ascii_font);
 | 
			
		||||
@ -802,9 +797,6 @@ eek_renderer_class_init (EekRendererClass *klass)
 | 
			
		||||
    GObjectClass      *gobject_class = G_OBJECT_CLASS (klass);
 | 
			
		||||
    GParamSpec        *pspec;
 | 
			
		||||
 | 
			
		||||
    g_type_class_add_private (gobject_class,
 | 
			
		||||
                              sizeof (EekRendererPrivate));
 | 
			
		||||
 | 
			
		||||
    klass->render_key_label = eek_renderer_real_render_key_label;
 | 
			
		||||
    klass->render_key_outline = eek_renderer_real_render_key_outline;
 | 
			
		||||
    klass->render_key = eek_renderer_real_render_key;
 | 
			
		||||
@ -837,9 +829,8 @@ eek_renderer_class_init (EekRendererClass *klass)
 | 
			
		||||
static void
 | 
			
		||||
eek_renderer_init (EekRenderer *self)
 | 
			
		||||
{
 | 
			
		||||
    EekRendererPrivate *priv;
 | 
			
		||||
    EekRendererPrivate *priv = eek_renderer_get_instance_private (self);
 | 
			
		||||
 | 
			
		||||
    priv = self->priv = EEK_RENDERER_GET_PRIVATE(self);
 | 
			
		||||
    priv->keyboard = NULL;
 | 
			
		||||
    priv->pcontext = NULL;
 | 
			
		||||
    priv->default_foreground_color = DEFAULT_FOREGROUND_COLOR;
 | 
			
		||||
@ -866,15 +857,17 @@ eek_renderer_init (EekRenderer *self)
 | 
			
		||||
static void
 | 
			
		||||
invalidate (EekRenderer *renderer)
 | 
			
		||||
{
 | 
			
		||||
    if (renderer->priv->outline_surface_cache)
 | 
			
		||||
        g_hash_table_remove_all (renderer->priv->outline_surface_cache);
 | 
			
		||||
    EekRendererPrivate *priv = eek_renderer_get_instance_private (renderer);
 | 
			
		||||
 | 
			
		||||
    if (renderer->priv->active_outline_surface_cache)
 | 
			
		||||
        g_hash_table_remove_all (renderer->priv->active_outline_surface_cache);
 | 
			
		||||
    if (priv->outline_surface_cache)
 | 
			
		||||
        g_hash_table_remove_all (priv->outline_surface_cache);
 | 
			
		||||
 | 
			
		||||
    if (renderer->priv->keyboard_surface) {
 | 
			
		||||
        cairo_surface_destroy (renderer->priv->keyboard_surface);
 | 
			
		||||
        renderer->priv->keyboard_surface = NULL;
 | 
			
		||||
    if (priv->active_outline_surface_cache)
 | 
			
		||||
        g_hash_table_remove_all (priv->active_outline_surface_cache);
 | 
			
		||||
 | 
			
		||||
    if (priv->keyboard_surface) {
 | 
			
		||||
        cairo_surface_destroy (priv->keyboard_surface);
 | 
			
		||||
        priv->keyboard_surface = NULL;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -909,10 +902,12 @@ eek_renderer_set_allocation_size (EekRenderer *renderer,
 | 
			
		||||
    g_return_if_fail (EEK_IS_RENDERER(renderer));
 | 
			
		||||
    g_return_if_fail (width > 0.0 && height > 0.0);
 | 
			
		||||
 | 
			
		||||
    renderer->priv->allocation_width = width;
 | 
			
		||||
    renderer->priv->allocation_height = height;
 | 
			
		||||
    EekRendererPrivate *priv = eek_renderer_get_instance_private (renderer);
 | 
			
		||||
 | 
			
		||||
    eek_element_get_bounds (EEK_ELEMENT(renderer->priv->keyboard), &bounds);
 | 
			
		||||
    priv->allocation_width = width;
 | 
			
		||||
    priv->allocation_height = height;
 | 
			
		||||
 | 
			
		||||
    eek_element_get_bounds (EEK_ELEMENT(priv->keyboard), &bounds);
 | 
			
		||||
 | 
			
		||||
    if (bounds.height * width / bounds.width <= height)
 | 
			
		||||
        scale = width / bounds.width;
 | 
			
		||||
@ -925,8 +920,8 @@ eek_renderer_set_allocation_size (EekRenderer *renderer,
 | 
			
		||||
            scale = bounds.height / height;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (scale != renderer->priv->scale) {
 | 
			
		||||
        renderer->priv->scale = scale;
 | 
			
		||||
    if (scale != priv->scale) {
 | 
			
		||||
        priv->scale = scale;
 | 
			
		||||
        invalidate (renderer);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -940,11 +935,13 @@ eek_renderer_get_size (EekRenderer *renderer,
 | 
			
		||||
 | 
			
		||||
    g_return_if_fail (EEK_IS_RENDERER(renderer));
 | 
			
		||||
 | 
			
		||||
    eek_element_get_bounds (EEK_ELEMENT(renderer->priv->keyboard), &bounds);
 | 
			
		||||
    EekRendererPrivate *priv = eek_renderer_get_instance_private (renderer);
 | 
			
		||||
 | 
			
		||||
    eek_element_get_bounds (EEK_ELEMENT(priv->keyboard), &bounds);
 | 
			
		||||
    if (width)
 | 
			
		||||
        *width = bounds.width * renderer->priv->scale;
 | 
			
		||||
        *width = bounds.width * priv->scale;
 | 
			
		||||
    if (height)
 | 
			
		||||
        *height = bounds.height * renderer->priv->scale;
 | 
			
		||||
        *height = bounds.height * priv->scale;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
@ -963,20 +960,22 @@ eek_renderer_get_key_bounds (EekRenderer *renderer,
 | 
			
		||||
    g_return_if_fail (EEK_IS_KEY(key));
 | 
			
		||||
    g_return_if_fail (bounds != NULL);
 | 
			
		||||
 | 
			
		||||
    EekRendererPrivate *priv = eek_renderer_get_instance_private (renderer);
 | 
			
		||||
 | 
			
		||||
    section = eek_element_get_parent (EEK_ELEMENT(key));
 | 
			
		||||
 | 
			
		||||
    eek_element_get_bounds (EEK_ELEMENT(key), bounds);
 | 
			
		||||
    eek_element_get_bounds (section, §ion_bounds);
 | 
			
		||||
    eek_element_get_bounds (EEK_ELEMENT(renderer->priv->keyboard),
 | 
			
		||||
    eek_element_get_bounds (EEK_ELEMENT(priv->keyboard),
 | 
			
		||||
                            &keyboard_bounds);
 | 
			
		||||
 | 
			
		||||
    if (!rotate) {
 | 
			
		||||
        bounds->x += keyboard_bounds.x + section_bounds.x;
 | 
			
		||||
        bounds->y += keyboard_bounds.y + section_bounds.y;
 | 
			
		||||
        bounds->x *= renderer->priv->scale;
 | 
			
		||||
        bounds->y *= renderer->priv->scale;
 | 
			
		||||
        bounds->width *= renderer->priv->scale;
 | 
			
		||||
        bounds->height *= renderer->priv->scale;
 | 
			
		||||
        bounds->x *= priv->scale;
 | 
			
		||||
        bounds->y *= priv->scale;
 | 
			
		||||
        bounds->width *= priv->scale;
 | 
			
		||||
        bounds->height *= priv->scale;
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
    points[0].x = bounds->x;
 | 
			
		||||
@ -1008,24 +1007,30 @@ eek_renderer_get_key_bounds (EekRenderer *renderer,
 | 
			
		||||
    bounds->y = keyboard_bounds.y + section_bounds.y + min.y;
 | 
			
		||||
    bounds->width = (max.x - min.x);
 | 
			
		||||
    bounds->height = (max.y - min.y);
 | 
			
		||||
    bounds->x *= renderer->priv->scale;
 | 
			
		||||
    bounds->y *= renderer->priv->scale;
 | 
			
		||||
    bounds->width *= renderer->priv->scale;
 | 
			
		||||
    bounds->height *= renderer->priv->scale;
 | 
			
		||||
    bounds->x *= priv->scale;
 | 
			
		||||
    bounds->y *= priv->scale;
 | 
			
		||||
    bounds->width *= priv->scale;
 | 
			
		||||
    bounds->height *= priv->scale;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
gdouble
 | 
			
		||||
eek_renderer_get_scale (EekRenderer *renderer)
 | 
			
		||||
{
 | 
			
		||||
    g_return_val_if_fail (EEK_IS_RENDERER(renderer), 0);
 | 
			
		||||
    return renderer->priv->scale;
 | 
			
		||||
 | 
			
		||||
    EekRendererPrivate *priv = eek_renderer_get_instance_private (renderer);
 | 
			
		||||
 | 
			
		||||
    return priv->scale;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
PangoLayout *
 | 
			
		||||
eek_renderer_create_pango_layout (EekRenderer  *renderer)
 | 
			
		||||
{
 | 
			
		||||
    g_return_val_if_fail (EEK_IS_RENDERER(renderer), NULL);
 | 
			
		||||
    return pango_layout_new (renderer->priv->pcontext);
 | 
			
		||||
 | 
			
		||||
    EekRendererPrivate *priv = eek_renderer_get_instance_private (renderer);
 | 
			
		||||
 | 
			
		||||
    return pango_layout_new (priv->pcontext);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
@ -1103,7 +1108,9 @@ eek_renderer_set_default_foreground_color (EekRenderer    *renderer,
 | 
			
		||||
    g_return_if_fail (EEK_IS_RENDERER(renderer));
 | 
			
		||||
    g_return_if_fail (color);
 | 
			
		||||
 | 
			
		||||
    memcpy (&renderer->priv->default_foreground_color, color, sizeof(EekColor));
 | 
			
		||||
    EekRendererPrivate *priv = eek_renderer_get_instance_private (renderer);
 | 
			
		||||
 | 
			
		||||
    memcpy (&priv->default_foreground_color, color, sizeof(EekColor));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
@ -1113,7 +1120,9 @@ eek_renderer_set_default_background_color (EekRenderer    *renderer,
 | 
			
		||||
    g_return_if_fail (EEK_IS_RENDERER(renderer));
 | 
			
		||||
    g_return_if_fail (color);
 | 
			
		||||
 | 
			
		||||
    memcpy (&renderer->priv->default_background_color, color, sizeof(EekColor));
 | 
			
		||||
    EekRendererPrivate *priv = eek_renderer_get_instance_private (renderer);
 | 
			
		||||
 | 
			
		||||
    memcpy (&priv->default_background_color, color, sizeof(EekColor));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
@ -1126,11 +1135,13 @@ eek_renderer_get_foreground_color (EekRenderer *renderer,
 | 
			
		||||
    g_return_if_fail (EEK_IS_RENDERER(renderer));
 | 
			
		||||
    g_return_if_fail (color);
 | 
			
		||||
 | 
			
		||||
    EekRendererPrivate *priv = eek_renderer_get_instance_private (renderer);
 | 
			
		||||
 | 
			
		||||
    theme_node = g_object_get_data (G_OBJECT(element), "theme-node");
 | 
			
		||||
    if (theme_node)
 | 
			
		||||
        eek_theme_node_get_foreground_color (theme_node, color);
 | 
			
		||||
    else
 | 
			
		||||
        memcpy (color, &renderer->priv->default_foreground_color,
 | 
			
		||||
        memcpy (color, &priv->default_foreground_color,
 | 
			
		||||
                sizeof(EekColor));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -1144,11 +1155,13 @@ eek_renderer_get_background_color (EekRenderer *renderer,
 | 
			
		||||
    g_return_if_fail (EEK_IS_RENDERER(renderer));
 | 
			
		||||
    g_return_if_fail (color);
 | 
			
		||||
 | 
			
		||||
    EekRendererPrivate *priv = eek_renderer_get_instance_private (renderer);
 | 
			
		||||
 | 
			
		||||
    theme_node = g_object_get_data (G_OBJECT(element), "theme-node");
 | 
			
		||||
    if (theme_node)
 | 
			
		||||
        eek_theme_node_get_background_color (theme_node, color);
 | 
			
		||||
    else
 | 
			
		||||
        memcpy (color, &renderer->priv->default_background_color,
 | 
			
		||||
        memcpy (color, &priv->default_background_color,
 | 
			
		||||
                sizeof(EekColor));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -1211,12 +1224,14 @@ find_key_by_position_key_callback (EekElement *element,
 | 
			
		||||
    points[3].x = points[0].x;
 | 
			
		||||
    points[3].y = points[2].y;
 | 
			
		||||
 | 
			
		||||
    EekRendererPrivate *priv = eek_renderer_get_instance_private (data->renderer);
 | 
			
		||||
 | 
			
		||||
    for (i = 0; i < G_N_ELEMENTS(points); i++) {
 | 
			
		||||
        eek_point_rotate (&points[i], data->angle);
 | 
			
		||||
        points[i].x += data->origin.x;
 | 
			
		||||
        points[i].y += data->origin.y;
 | 
			
		||||
        points[i].x *= data->renderer->priv->scale;
 | 
			
		||||
        points[i].y *= data->renderer->priv->scale;
 | 
			
		||||
        points[i].x *= priv->scale;
 | 
			
		||||
        points[i].y *= priv->scale;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    b1 = sign (&data->point, &points[0], &points[1]) < 0.0;
 | 
			
		||||
@ -1271,12 +1286,14 @@ eek_renderer_find_key_by_position (EekRenderer *renderer,
 | 
			
		||||
 | 
			
		||||
    g_return_val_if_fail (EEK_IS_RENDERER(renderer), NULL);
 | 
			
		||||
 | 
			
		||||
    eek_element_get_bounds (EEK_ELEMENT(renderer->priv->keyboard), &bounds);
 | 
			
		||||
    EekRendererPrivate *priv = eek_renderer_get_instance_private (renderer);
 | 
			
		||||
 | 
			
		||||
    if (x < bounds.x * renderer->priv->scale ||
 | 
			
		||||
        y < bounds.y * renderer->priv->scale ||
 | 
			
		||||
        x > bounds.width * renderer->priv->scale ||
 | 
			
		||||
        y > bounds.height * renderer->priv->scale)
 | 
			
		||||
    eek_element_get_bounds (EEK_ELEMENT(priv->keyboard), &bounds);
 | 
			
		||||
 | 
			
		||||
    if (x < bounds.x * priv->scale ||
 | 
			
		||||
        y < bounds.y * priv->scale ||
 | 
			
		||||
        x > bounds.width * priv->scale ||
 | 
			
		||||
        y > bounds.height * priv->scale)
 | 
			
		||||
        return NULL;
 | 
			
		||||
 | 
			
		||||
    data.point.x = x;
 | 
			
		||||
@ -1286,7 +1303,7 @@ eek_renderer_find_key_by_position (EekRenderer *renderer,
 | 
			
		||||
    data.key = NULL;
 | 
			
		||||
    data.renderer = renderer;
 | 
			
		||||
 | 
			
		||||
    eek_container_find (EEK_CONTAINER(renderer->priv->keyboard),
 | 
			
		||||
    eek_container_find (EEK_CONTAINER(priv->keyboard),
 | 
			
		||||
                        find_key_by_position_section_callback,
 | 
			
		||||
                        &data);
 | 
			
		||||
    return data.key;
 | 
			
		||||
@ -1306,9 +1323,11 @@ create_theme_node_key_callback (EekElement *element,
 | 
			
		||||
    CreateThemeNodeData *data = user_data;
 | 
			
		||||
    EekThemeNode *theme_node;
 | 
			
		||||
 | 
			
		||||
    EekRendererPrivate *priv = eek_renderer_get_instance_private (data->renderer);
 | 
			
		||||
 | 
			
		||||
    theme_node = eek_theme_node_new (data->context,
 | 
			
		||||
                                     data->parent,
 | 
			
		||||
                                     data->renderer->priv->theme,
 | 
			
		||||
                                     priv->theme,
 | 
			
		||||
                                     EEK_TYPE_KEY,
 | 
			
		||||
                                     eek_element_get_name (element),
 | 
			
		||||
                                     "key",
 | 
			
		||||
@ -1321,7 +1340,7 @@ create_theme_node_key_callback (EekElement *element,
 | 
			
		||||
 | 
			
		||||
    theme_node = eek_theme_node_new (data->context,
 | 
			
		||||
                                     data->parent,
 | 
			
		||||
                                     data->renderer->priv->theme,
 | 
			
		||||
                                     priv->theme,
 | 
			
		||||
                                     EEK_TYPE_KEY,
 | 
			
		||||
                                     eek_element_get_name (element),
 | 
			
		||||
                                     "key",
 | 
			
		||||
@ -1340,9 +1359,11 @@ create_theme_node_section_callback (EekElement *element,
 | 
			
		||||
    CreateThemeNodeData *data = user_data;
 | 
			
		||||
    EekThemeNode *theme_node, *parent;
 | 
			
		||||
 | 
			
		||||
    EekRendererPrivate *priv = eek_renderer_get_instance_private (data->renderer);
 | 
			
		||||
 | 
			
		||||
    theme_node = eek_theme_node_new (data->context,
 | 
			
		||||
                                     data->parent,
 | 
			
		||||
                                     data->renderer->priv->theme,
 | 
			
		||||
                                     priv->theme,
 | 
			
		||||
                                     EEK_TYPE_SECTION,
 | 
			
		||||
                                     eek_element_get_name (element),
 | 
			
		||||
                                     "section",
 | 
			
		||||
@ -1371,22 +1392,25 @@ eek_renderer_set_theme (EekRenderer *renderer,
 | 
			
		||||
 | 
			
		||||
    g_return_if_fail (EEK_IS_RENDERER(renderer));
 | 
			
		||||
    g_return_if_fail (EEK_IS_THEME(theme));
 | 
			
		||||
    g_return_if_fail (renderer->priv->keyboard);
 | 
			
		||||
 | 
			
		||||
    if (renderer->priv->theme)
 | 
			
		||||
        g_object_unref (renderer->priv->theme);
 | 
			
		||||
    renderer->priv->theme = g_object_ref (theme);
 | 
			
		||||
    EekRendererPrivate *priv = eek_renderer_get_instance_private (renderer);
 | 
			
		||||
 | 
			
		||||
    g_return_if_fail (priv->keyboard);
 | 
			
		||||
 | 
			
		||||
    if (priv->theme)
 | 
			
		||||
        g_object_unref (priv->theme);
 | 
			
		||||
    priv->theme = g_object_ref (theme);
 | 
			
		||||
 | 
			
		||||
    theme_context = eek_theme_context_new ();
 | 
			
		||||
    theme_node = eek_theme_node_new (theme_context,
 | 
			
		||||
                                     NULL,
 | 
			
		||||
                                     renderer->priv->theme,
 | 
			
		||||
                                     priv->theme,
 | 
			
		||||
                                     EEK_TYPE_KEYBOARD,
 | 
			
		||||
                                     "keyboard",
 | 
			
		||||
                                     "keyboard",
 | 
			
		||||
                                     NULL,
 | 
			
		||||
                                     NULL);
 | 
			
		||||
    g_object_set_data_full (G_OBJECT(renderer->priv->keyboard),
 | 
			
		||||
    g_object_set_data_full (G_OBJECT(priv->keyboard),
 | 
			
		||||
                            "theme-node",
 | 
			
		||||
                            theme_node,
 | 
			
		||||
                            (GDestroyNotify)g_object_unref);
 | 
			
		||||
@ -1394,7 +1418,7 @@ eek_renderer_set_theme (EekRenderer *renderer,
 | 
			
		||||
    data.context = theme_context;
 | 
			
		||||
    data.parent = theme_node;
 | 
			
		||||
    data.renderer = renderer;
 | 
			
		||||
    eek_container_foreach_child (EEK_CONTAINER(renderer->priv->keyboard),
 | 
			
		||||
    eek_container_foreach_child (EEK_CONTAINER(priv->keyboard),
 | 
			
		||||
                                 create_theme_node_section_callback,
 | 
			
		||||
                                 &data);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -31,21 +31,7 @@
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
#define EEK_TYPE_RENDERER (eek_renderer_get_type())
 | 
			
		||||
#define EEK_RENDERER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EEK_TYPE_RENDERER, EekRenderer))
 | 
			
		||||
#define EEK_RENDERER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EEK_TYPE_RENDERER, EekRendererClass))
 | 
			
		||||
#define EEK_IS_RENDERER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EEK_TYPE_RENDERER))
 | 
			
		||||
#define EEK_IS_RENDERER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EEK_TYPE_RENDERER))
 | 
			
		||||
#define EEK_RENDERER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EEK_TYPE_RENDERER, EekRendererClass))
 | 
			
		||||
 | 
			
		||||
typedef struct _EekRenderer EekRenderer;
 | 
			
		||||
typedef struct _EekRendererClass EekRendererClass;
 | 
			
		||||
typedef struct _EekRendererPrivate EekRendererPrivate;
 | 
			
		||||
 | 
			
		||||
struct _EekRenderer {
 | 
			
		||||
    GObject parent;
 | 
			
		||||
 | 
			
		||||
    EekRendererPrivate *priv;
 | 
			
		||||
};
 | 
			
		||||
G_DECLARE_DERIVABLE_TYPE (EekRenderer, eek_renderer, EEK, RENDERER, GObject)
 | 
			
		||||
 | 
			
		||||
struct _EekRendererClass
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
@ -1,17 +1,17 @@
 | 
			
		||||
/* 
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2010-2011 Daiki Ueno <ueno@unixuser.org>
 | 
			
		||||
 * Copyright (C) 2010-2011 Red Hat, Inc.
 | 
			
		||||
 * 
 | 
			
		||||
 *
 | 
			
		||||
 * This library is free software; you can redistribute it and/or
 | 
			
		||||
 * modify it under the terms of the GNU Lesser General Public License
 | 
			
		||||
 * as published by the Free Software Foundation; either version 2 of
 | 
			
		||||
 * the License, or (at your option) any later version.
 | 
			
		||||
 * 
 | 
			
		||||
 *
 | 
			
		||||
 * This library is distributed in the hope that it will be useful, but
 | 
			
		||||
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
			
		||||
 * Lesser General Public License for more details.
 | 
			
		||||
 * 
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General Public
 | 
			
		||||
 * License along with this library; if not, write to the Free Software
 | 
			
		||||
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 | 
			
		||||
@ -45,21 +45,13 @@ enum {
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
enum {
 | 
			
		||||
    KEY_PRESSED,
 | 
			
		||||
    KEY_RELEASED,
 | 
			
		||||
    KEY_LOCKED,
 | 
			
		||||
    KEY_UNLOCKED,
 | 
			
		||||
    KEY_CANCELLED,
 | 
			
		||||
    LAST_SIGNAL
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static guint signals[LAST_SIGNAL] = { 0, };
 | 
			
		||||
 | 
			
		||||
G_DEFINE_TYPE (EekSection, eek_section, EEK_TYPE_CONTAINER);
 | 
			
		||||
 | 
			
		||||
#define EEK_SECTION_GET_PRIVATE(obj)                           \
 | 
			
		||||
    (G_TYPE_INSTANCE_GET_PRIVATE ((obj), EEK_TYPE_SECTION, EekSectionPrivate))
 | 
			
		||||
 | 
			
		||||
struct _EekRow
 | 
			
		||||
{
 | 
			
		||||
    gint num_columns;
 | 
			
		||||
@ -68,17 +60,19 @@ struct _EekRow
 | 
			
		||||
 | 
			
		||||
typedef struct _EekRow EekRow;
 | 
			
		||||
 | 
			
		||||
struct _EekSectionPrivate
 | 
			
		||||
typedef struct _EekSectionPrivate
 | 
			
		||||
{
 | 
			
		||||
    gint angle;
 | 
			
		||||
    GSList *rows;
 | 
			
		||||
    EekModifierType modifiers;
 | 
			
		||||
};
 | 
			
		||||
} EekSectionPrivate;
 | 
			
		||||
 | 
			
		||||
G_DEFINE_TYPE_WITH_PRIVATE (EekSection, eek_section, EEK_TYPE_CONTAINER)
 | 
			
		||||
 | 
			
		||||
static gint
 | 
			
		||||
eek_section_real_get_n_rows (EekSection *self)
 | 
			
		||||
{
 | 
			
		||||
    EekSectionPrivate *priv = EEK_SECTION_GET_PRIVATE(self);
 | 
			
		||||
    EekSectionPrivate *priv = eek_section_get_instance_private (self);
 | 
			
		||||
 | 
			
		||||
    return g_slist_length (priv->rows);
 | 
			
		||||
}
 | 
			
		||||
@ -88,7 +82,7 @@ eek_section_real_add_row (EekSection    *self,
 | 
			
		||||
                          gint           num_columns,
 | 
			
		||||
                          EekOrientation orientation)
 | 
			
		||||
{
 | 
			
		||||
    EekSectionPrivate *priv = EEK_SECTION_GET_PRIVATE(self);
 | 
			
		||||
    EekSectionPrivate *priv = eek_section_get_instance_private (self);
 | 
			
		||||
    EekRow *row;
 | 
			
		||||
 | 
			
		||||
    row = g_slice_new (EekRow);
 | 
			
		||||
@ -103,7 +97,7 @@ eek_section_real_get_row (EekSection     *self,
 | 
			
		||||
                          gint           *num_columns,
 | 
			
		||||
                          EekOrientation *orientation)
 | 
			
		||||
{
 | 
			
		||||
    EekSectionPrivate *priv = EEK_SECTION_GET_PRIVATE(self);
 | 
			
		||||
    EekSectionPrivate *priv = eek_section_get_instance_private (self);
 | 
			
		||||
    EekRow *row;
 | 
			
		||||
 | 
			
		||||
    row = g_slist_nth_data (priv->rows, index);
 | 
			
		||||
@ -114,20 +108,6 @@ eek_section_real_get_row (EekSection     *self,
 | 
			
		||||
        *orientation = row->orientation;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
on_pressed (EekKey     *key,
 | 
			
		||||
            EekSection *section)
 | 
			
		||||
{
 | 
			
		||||
    g_signal_emit (section, signals[KEY_PRESSED], 0, key);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
on_released (EekKey     *key,
 | 
			
		||||
             EekSection *section)
 | 
			
		||||
{
 | 
			
		||||
    g_signal_emit (section, signals[KEY_RELEASED], 0, key);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
on_locked (EekKey     *key,
 | 
			
		||||
           EekSection *section)
 | 
			
		||||
@ -142,32 +122,29 @@ on_unlocked (EekKey     *key,
 | 
			
		||||
    g_signal_emit (section, signals[KEY_UNLOCKED], 0, key);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
on_cancelled (EekKey     *key,
 | 
			
		||||
             EekSection *section)
 | 
			
		||||
{
 | 
			
		||||
    g_signal_emit (section, signals[KEY_CANCELLED], 0, key);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static EekKey *
 | 
			
		||||
eek_section_real_create_key (EekSection *self,
 | 
			
		||||
                             guint       keycode,
 | 
			
		||||
                             gint        column,
 | 
			
		||||
                             gint        row)
 | 
			
		||||
                             gint        column_index,
 | 
			
		||||
                             gint        row_index)
 | 
			
		||||
{
 | 
			
		||||
    EekKey *key;
 | 
			
		||||
    gint num_columns, num_rows;
 | 
			
		||||
    EekOrientation orientation;
 | 
			
		||||
    gint num_rows;
 | 
			
		||||
    EekRow *row;
 | 
			
		||||
 | 
			
		||||
    num_rows = eek_section_get_n_rows (self);
 | 
			
		||||
    g_return_val_if_fail (0 <= row && row < num_rows, NULL);
 | 
			
		||||
    eek_section_get_row (self, row, &num_columns, &orientation);
 | 
			
		||||
    g_return_val_if_fail (column < num_columns, NULL);
 | 
			
		||||
    g_return_val_if_fail (0 <= row_index && row_index < num_rows, NULL);
 | 
			
		||||
 | 
			
		||||
    EekSectionPrivate *priv = eek_section_get_instance_private (self);
 | 
			
		||||
 | 
			
		||||
    row = g_slist_nth_data (priv->rows, row_index);
 | 
			
		||||
    if (row->num_columns < column_index + 1)
 | 
			
		||||
        row->num_columns = column_index + 1;
 | 
			
		||||
 | 
			
		||||
    key = g_object_new (EEK_TYPE_KEY,
 | 
			
		||||
                        "keycode", keycode,
 | 
			
		||||
                        "column", column,
 | 
			
		||||
                        "row", row,
 | 
			
		||||
                        "column", column_index,
 | 
			
		||||
                        "row", row_index,
 | 
			
		||||
                        NULL);
 | 
			
		||||
    g_return_val_if_fail (key, NULL);
 | 
			
		||||
 | 
			
		||||
@ -180,7 +157,7 @@ eek_section_real_create_key (EekSection *self,
 | 
			
		||||
static void
 | 
			
		||||
set_level_from_modifiers (EekSection *self)
 | 
			
		||||
{
 | 
			
		||||
    EekSectionPrivate *priv = EEK_SECTION_GET_PRIVATE(self);
 | 
			
		||||
    EekSectionPrivate *priv = eek_section_get_instance_private (self);
 | 
			
		||||
    EekKeyboard *keyboard;
 | 
			
		||||
    EekModifierType num_lock_mask;
 | 
			
		||||
    gint level = -1;
 | 
			
		||||
@ -195,7 +172,7 @@ set_level_from_modifiers (EekSection *self)
 | 
			
		||||
static void
 | 
			
		||||
eek_section_real_key_pressed (EekSection *self, EekKey *key)
 | 
			
		||||
{
 | 
			
		||||
    EekSectionPrivate *priv = EEK_SECTION_GET_PRIVATE(self);
 | 
			
		||||
    EekSectionPrivate *priv = eek_section_get_instance_private (self);
 | 
			
		||||
    EekSymbol *symbol;
 | 
			
		||||
    EekKeyboard *keyboard;
 | 
			
		||||
    EekModifierBehavior behavior;
 | 
			
		||||
@ -217,7 +194,7 @@ eek_section_real_key_pressed (EekSection *self, EekKey *key)
 | 
			
		||||
static void
 | 
			
		||||
eek_section_real_key_released (EekSection *self, EekKey *key)
 | 
			
		||||
{
 | 
			
		||||
    EekSectionPrivate *priv = EEK_SECTION_GET_PRIVATE(self);
 | 
			
		||||
    EekSectionPrivate *priv = eek_section_get_instance_private (self);
 | 
			
		||||
    EekSymbol *symbol;
 | 
			
		||||
    EekKeyboard *keyboard;
 | 
			
		||||
    EekModifierBehavior behavior;
 | 
			
		||||
@ -247,7 +224,8 @@ eek_section_real_key_released (EekSection *self, EekKey *key)
 | 
			
		||||
static void
 | 
			
		||||
eek_section_finalize (GObject *object)
 | 
			
		||||
{
 | 
			
		||||
    EekSectionPrivate *priv = EEK_SECTION_GET_PRIVATE(object);
 | 
			
		||||
    EekSection        *self = EEK_SECTION (object);
 | 
			
		||||
    EekSectionPrivate *priv = eek_section_get_instance_private (self);
 | 
			
		||||
    GSList *head;
 | 
			
		||||
 | 
			
		||||
    for (head = priv->rows; head; head = g_slist_next (head))
 | 
			
		||||
@ -294,22 +272,16 @@ static void
 | 
			
		||||
eek_section_real_child_added (EekContainer *self,
 | 
			
		||||
                              EekElement   *element)
 | 
			
		||||
{
 | 
			
		||||
    g_signal_connect (element, "pressed", G_CALLBACK(on_pressed), self);
 | 
			
		||||
    g_signal_connect (element, "released", G_CALLBACK(on_released), self);
 | 
			
		||||
    g_signal_connect (element, "locked", G_CALLBACK(on_locked), self);
 | 
			
		||||
    g_signal_connect (element, "unlocked", G_CALLBACK(on_unlocked), self);
 | 
			
		||||
    g_signal_connect (element, "cancelled", G_CALLBACK(on_cancelled), self);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
eek_section_real_child_removed (EekContainer *self,
 | 
			
		||||
                                EekElement   *element)
 | 
			
		||||
{
 | 
			
		||||
    g_signal_handlers_disconnect_by_func (element, on_pressed, self);
 | 
			
		||||
    g_signal_handlers_disconnect_by_func (element, on_released, self);
 | 
			
		||||
    g_signal_handlers_disconnect_by_func (element, on_locked, self);
 | 
			
		||||
    g_signal_handlers_disconnect_by_func (element, on_unlocked, self);
 | 
			
		||||
    g_signal_handlers_disconnect_by_func (element, on_cancelled, self);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
@ -319,8 +291,6 @@ eek_section_class_init (EekSectionClass *klass)
 | 
			
		||||
    GObjectClass      *gobject_class = G_OBJECT_CLASS (klass);
 | 
			
		||||
    GParamSpec        *pspec;
 | 
			
		||||
 | 
			
		||||
    g_type_class_add_private (gobject_class, sizeof (EekSectionPrivate));
 | 
			
		||||
 | 
			
		||||
    klass->get_n_rows = eek_section_real_get_n_rows;
 | 
			
		||||
    klass->add_row = eek_section_real_add_row;
 | 
			
		||||
    klass->get_row = eek_section_real_get_row;
 | 
			
		||||
@ -351,46 +321,6 @@ eek_section_class_init (EekSectionClass *klass)
 | 
			
		||||
                                     PROP_ANGLE,
 | 
			
		||||
                                     pspec);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * EekSection::key-pressed:
 | 
			
		||||
     * @section: an #EekSection
 | 
			
		||||
     * @key: an #EekKey
 | 
			
		||||
     *
 | 
			
		||||
     * The ::key-pressed signal is emitted each time a key in @section
 | 
			
		||||
     * is shifted to the pressed state.
 | 
			
		||||
     */
 | 
			
		||||
    signals[KEY_PRESSED] =
 | 
			
		||||
        g_signal_new (I_("key-pressed"),
 | 
			
		||||
                      G_TYPE_FROM_CLASS(gobject_class),
 | 
			
		||||
                      G_SIGNAL_RUN_LAST,
 | 
			
		||||
                      G_STRUCT_OFFSET(EekSectionClass, key_pressed),
 | 
			
		||||
                      NULL,
 | 
			
		||||
                      NULL,
 | 
			
		||||
                      g_cclosure_marshal_VOID__OBJECT,
 | 
			
		||||
                      G_TYPE_NONE,
 | 
			
		||||
                      1,
 | 
			
		||||
                      EEK_TYPE_KEY);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * EekSection::key-released:
 | 
			
		||||
     * @section: an #EekSection
 | 
			
		||||
     * @key: an #EekKey
 | 
			
		||||
     *
 | 
			
		||||
     * The ::key-released signal is emitted each time a key in @section
 | 
			
		||||
     * is shifted to the released state.
 | 
			
		||||
     */
 | 
			
		||||
    signals[KEY_RELEASED] =
 | 
			
		||||
        g_signal_new (I_("key-released"),
 | 
			
		||||
                      G_TYPE_FROM_CLASS(gobject_class),
 | 
			
		||||
                      G_SIGNAL_RUN_LAST,
 | 
			
		||||
                      G_STRUCT_OFFSET(EekSectionClass, key_released),
 | 
			
		||||
                      NULL,
 | 
			
		||||
                      NULL,
 | 
			
		||||
                      g_cclosure_marshal_VOID__OBJECT,
 | 
			
		||||
                      G_TYPE_NONE,
 | 
			
		||||
                      1,
 | 
			
		||||
                      EEK_TYPE_KEY);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * EekSection::key-locked:
 | 
			
		||||
     * @section: an #EekSection
 | 
			
		||||
@ -430,32 +360,12 @@ eek_section_class_init (EekSectionClass *klass)
 | 
			
		||||
                      G_TYPE_NONE,
 | 
			
		||||
                      1,
 | 
			
		||||
                      EEK_TYPE_KEY);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * EekSection::key-cancelled:
 | 
			
		||||
     * @section: an #EekSection
 | 
			
		||||
     * @key: an #EekKey
 | 
			
		||||
     *
 | 
			
		||||
     * The ::key-cancelled signal is emitted each time a key in @section
 | 
			
		||||
     * is shifted to the cancelled state.
 | 
			
		||||
     */
 | 
			
		||||
    signals[KEY_CANCELLED] =
 | 
			
		||||
        g_signal_new (I_("key-cancelled"),
 | 
			
		||||
                      G_TYPE_FROM_CLASS(gobject_class),
 | 
			
		||||
                      G_SIGNAL_RUN_LAST,
 | 
			
		||||
                      G_STRUCT_OFFSET(EekSectionClass, key_cancelled),
 | 
			
		||||
                      NULL,
 | 
			
		||||
                      NULL,
 | 
			
		||||
                      g_cclosure_marshal_VOID__OBJECT,
 | 
			
		||||
                      G_TYPE_NONE,
 | 
			
		||||
                      1,
 | 
			
		||||
                      EEK_TYPE_KEY);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
eek_section_init (EekSection *self)
 | 
			
		||||
{
 | 
			
		||||
    self->priv = EEK_SECTION_GET_PRIVATE (self);
 | 
			
		||||
    /* void */
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@ -470,8 +380,11 @@ eek_section_set_angle (EekSection  *section,
 | 
			
		||||
                       gint         angle)
 | 
			
		||||
{
 | 
			
		||||
    g_return_if_fail (EEK_IS_SECTION(section));
 | 
			
		||||
    if (section->priv->angle != angle) {
 | 
			
		||||
        section->priv->angle = angle;
 | 
			
		||||
 | 
			
		||||
    EekSectionPrivate *priv = eek_section_get_instance_private (section);
 | 
			
		||||
 | 
			
		||||
    if (priv->angle != angle) {
 | 
			
		||||
        priv->angle = angle;
 | 
			
		||||
        g_object_notify (G_OBJECT(section), "angle");
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -486,7 +399,10 @@ gint
 | 
			
		||||
eek_section_get_angle (EekSection *section)
 | 
			
		||||
{
 | 
			
		||||
    g_return_val_if_fail (EEK_IS_SECTION(section), -1);
 | 
			
		||||
    return section->priv->angle;
 | 
			
		||||
 | 
			
		||||
    EekSectionPrivate *priv = eek_section_get_instance_private (section);
 | 
			
		||||
 | 
			
		||||
    return priv->angle;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@ -567,3 +483,80 @@ eek_section_create_key (EekSection *section,
 | 
			
		||||
                                                       column,
 | 
			
		||||
                                                       row);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void keysizer(EekElement *element, gpointer user_data) {
 | 
			
		||||
    EekKey *key = EEK_KEY(element);
 | 
			
		||||
    EekKeyboard *keyboard = EEK_KEYBOARD(user_data);
 | 
			
		||||
    uint oref = eek_key_get_oref (key);
 | 
			
		||||
    EekOutline *outline = eek_keyboard_get_outline (keyboard, oref);
 | 
			
		||||
    if (outline && outline->num_points > 0) {
 | 
			
		||||
        double minx = outline->points[0].x;
 | 
			
		||||
        double maxx = minx;
 | 
			
		||||
        double miny = outline->points[0].y;
 | 
			
		||||
        double maxy = miny;
 | 
			
		||||
        for (uint i = 1; i < outline->num_points; i++) {
 | 
			
		||||
            EekPoint p = outline->points[i];
 | 
			
		||||
            if (p.x < minx) {
 | 
			
		||||
                minx = p.x;
 | 
			
		||||
            } else if (p.x > maxx) {
 | 
			
		||||
                maxx = p.x;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (p.y < miny) {
 | 
			
		||||
                miny = p.y;
 | 
			
		||||
            } else if (p.y > maxy) {
 | 
			
		||||
                maxy = p.y;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        EekBounds key_bounds = {0};
 | 
			
		||||
        eek_element_get_bounds(element, &key_bounds);
 | 
			
		||||
        key_bounds.height = maxy - miny;
 | 
			
		||||
        key_bounds.width = maxx - minx;
 | 
			
		||||
        eek_element_set_bounds(element, &key_bounds);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
struct keys_info {
 | 
			
		||||
    uint count;
 | 
			
		||||
    double total_width;
 | 
			
		||||
    double biggest_height;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static void keycounter (EekElement *element, gpointer user_data) {
 | 
			
		||||
    struct keys_info *data = user_data;
 | 
			
		||||
    data->count++;
 | 
			
		||||
    EekBounds key_bounds = {0};
 | 
			
		||||
    eek_element_get_bounds(element, &key_bounds);
 | 
			
		||||
    data->total_width += key_bounds.width;
 | 
			
		||||
    if (key_bounds.height > data->biggest_height) {
 | 
			
		||||
        data->biggest_height = key_bounds.height;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const double keyspacing = 4.0;
 | 
			
		||||
 | 
			
		||||
static void keyplacer(EekElement *element, gpointer user_data) {
 | 
			
		||||
    double *current_offset = user_data;
 | 
			
		||||
    EekBounds key_bounds = {0};
 | 
			
		||||
    eek_element_get_bounds(element, &key_bounds);
 | 
			
		||||
    key_bounds.x = *current_offset;
 | 
			
		||||
    key_bounds.y = 0;
 | 
			
		||||
    eek_element_set_bounds(element, &key_bounds);
 | 
			
		||||
    *current_offset += key_bounds.width + keyspacing;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void eek_section_place_keys(EekSection *section, EekKeyboard *keyboard)
 | 
			
		||||
{
 | 
			
		||||
    eek_container_foreach_child(EEK_CONTAINER(section), keysizer, keyboard);
 | 
			
		||||
 | 
			
		||||
    struct keys_info keyinfo = {0};
 | 
			
		||||
    eek_container_foreach_child(EEK_CONTAINER(section), keycounter, &keyinfo);
 | 
			
		||||
    EekBounds section_bounds = {0};
 | 
			
		||||
    eek_element_get_bounds(EEK_ELEMENT(section), §ion_bounds);
 | 
			
		||||
 | 
			
		||||
    double key_offset = (section_bounds.width - (keyinfo.total_width + (keyinfo.count - 1) * keyspacing)) / 2;
 | 
			
		||||
    eek_container_foreach_child(EEK_CONTAINER(section), keyplacer, &key_offset);
 | 
			
		||||
 | 
			
		||||
    section_bounds.height = keyinfo.biggest_height;
 | 
			
		||||
    eek_element_set_bounds(EEK_ELEMENT(section), §ion_bounds);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -32,28 +32,7 @@
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
#define EEK_TYPE_SECTION (eek_section_get_type())
 | 
			
		||||
#define EEK_SECTION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EEK_TYPE_SECTION, EekSection))
 | 
			
		||||
#define EEK_SECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EEK_TYPE_SECTION, EekSectionClass))
 | 
			
		||||
#define EEK_IS_SECTION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EEK_TYPE_SECTION))
 | 
			
		||||
#define EEK_IS_SECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EEK_TYPE_SECTION))
 | 
			
		||||
#define EEK_SECTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EEK_TYPE_SECTION, EekSectionClass))
 | 
			
		||||
 | 
			
		||||
typedef struct _EekSectionClass EekSectionClass;
 | 
			
		||||
typedef struct _EekSectionPrivate EekSectionPrivate;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * EekSection:
 | 
			
		||||
 *
 | 
			
		||||
 * The #EekSection structure contains only private data and should
 | 
			
		||||
 * only be accessed using the provided API.
 | 
			
		||||
 */
 | 
			
		||||
struct _EekSection
 | 
			
		||||
{
 | 
			
		||||
    /*< private >*/
 | 
			
		||||
    EekContainer parent;
 | 
			
		||||
 | 
			
		||||
    EekSectionPrivate *priv;
 | 
			
		||||
};
 | 
			
		||||
G_DECLARE_DERIVABLE_TYPE(EekSection, eek_section, EEK, SECTION, EekContainer)
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * EekSectionClass:
 | 
			
		||||
@ -127,5 +106,7 @@ EekKey *eek_section_create_key           (EekSection     *section,
 | 
			
		||||
EekKey *eek_section_find_key_by_keycode  (EekSection     *section,
 | 
			
		||||
                                          guint           keycode);
 | 
			
		||||
 | 
			
		||||
void eek_section_place_keys              (EekSection     *section, EekKeyboard *keyboard);
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
#endif  /* EEK_SECTION_H */
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										145
									
								
								eek/eek-symbol.c
									
									
									
									
									
								
							
							
						
						
									
										145
									
								
								eek/eek-symbol.c
									
									
									
									
									
								
							@ -40,37 +40,42 @@ enum {
 | 
			
		||||
    PROP_CATEGORY,
 | 
			
		||||
    PROP_MODIFIER_MASK,
 | 
			
		||||
    PROP_ICON_NAME,
 | 
			
		||||
    PROP_TOOLTIP,
 | 
			
		||||
    PROP_LAST
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct _EekSymbolPrivate {
 | 
			
		||||
typedef struct _EekSymbolPrivate
 | 
			
		||||
{
 | 
			
		||||
    gchar *name;
 | 
			
		||||
    gchar *label;
 | 
			
		||||
    EekSymbolCategory category;
 | 
			
		||||
    EekModifierType modifier_mask;
 | 
			
		||||
    gchar *icon_name;
 | 
			
		||||
};
 | 
			
		||||
    gchar *tooltip;
 | 
			
		||||
} EekSymbolPrivate;
 | 
			
		||||
 | 
			
		||||
static void eek_serializable_iface_init (EekSerializableIface *iface);
 | 
			
		||||
 | 
			
		||||
G_DEFINE_TYPE_WITH_CODE (EekSymbol, eek_symbol, G_TYPE_OBJECT,
 | 
			
		||||
                         G_IMPLEMENT_INTERFACE (EEK_TYPE_SERIALIZABLE,
 | 
			
		||||
                                                eek_serializable_iface_init));
 | 
			
		||||
 | 
			
		||||
#define EEK_SYMBOL_GET_PRIVATE(obj)                                  \
 | 
			
		||||
    (G_TYPE_INSTANCE_GET_PRIVATE ((obj), EEK_TYPE_SYMBOL, EekSymbolPrivate))
 | 
			
		||||
G_DEFINE_TYPE_EXTENDED (EekSymbol,
 | 
			
		||||
			eek_symbol,
 | 
			
		||||
			G_TYPE_OBJECT,
 | 
			
		||||
			0, /* GTypeFlags */
 | 
			
		||||
			G_ADD_PRIVATE (EekSymbol)
 | 
			
		||||
                        G_IMPLEMENT_INTERFACE (EEK_TYPE_SERIALIZABLE,
 | 
			
		||||
                                               eek_serializable_iface_init))
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
eek_symbol_real_serialize (EekSerializable *self,
 | 
			
		||||
                           GVariantBuilder *builder)
 | 
			
		||||
{
 | 
			
		||||
    EekSymbolPrivate *priv = EEK_SYMBOL_GET_PRIVATE(self);
 | 
			
		||||
    EekSymbolPrivate *priv = eek_symbol_get_instance_private (EEK_SYMBOL (self));
 | 
			
		||||
#define NOTNULL(s) ((s) != NULL ? (s) : "")
 | 
			
		||||
    g_variant_builder_add (builder, "s", NOTNULL(priv->name));
 | 
			
		||||
    g_variant_builder_add (builder, "s", NOTNULL(priv->label));
 | 
			
		||||
    g_variant_builder_add (builder, "u", priv->category);
 | 
			
		||||
    g_variant_builder_add (builder, "u", priv->modifier_mask);
 | 
			
		||||
    g_variant_builder_add (builder, "s", NOTNULL(priv->icon_name));
 | 
			
		||||
    g_variant_builder_add (builder, "s", NOTNULL(priv->tooltip));
 | 
			
		||||
#undef NOTNULL
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -79,13 +84,14 @@ eek_symbol_real_deserialize (EekSerializable *self,
 | 
			
		||||
                             GVariant        *variant,
 | 
			
		||||
                             gsize            index)
 | 
			
		||||
{
 | 
			
		||||
    EekSymbolPrivate *priv = EEK_SYMBOL_GET_PRIVATE(self);
 | 
			
		||||
    EekSymbolPrivate *priv = eek_symbol_get_instance_private (EEK_SYMBOL (self));
 | 
			
		||||
 | 
			
		||||
    g_variant_get_child (variant, index++, "s", &priv->name);
 | 
			
		||||
    g_variant_get_child (variant, index++, "s", &priv->label);
 | 
			
		||||
    g_variant_get_child (variant, index++, "u", &priv->category);
 | 
			
		||||
    g_variant_get_child (variant, index++, "u", &priv->modifier_mask);
 | 
			
		||||
    g_variant_get_child (variant, index++, "s", &priv->icon_name);
 | 
			
		||||
    g_variant_get_child (variant, index++, "s", &priv->tooltip);
 | 
			
		||||
 | 
			
		||||
    return index;
 | 
			
		||||
}
 | 
			
		||||
@ -121,6 +127,10 @@ eek_symbol_set_property (GObject      *object,
 | 
			
		||||
        eek_symbol_set_icon_name (EEK_SYMBOL(object),
 | 
			
		||||
                                  g_value_get_string (value));
 | 
			
		||||
        break;
 | 
			
		||||
    case PROP_TOOLTIP:
 | 
			
		||||
        eek_symbol_set_tooltip (EEK_SYMBOL(object),
 | 
			
		||||
                                g_value_get_string (value));
 | 
			
		||||
        break;
 | 
			
		||||
    default:
 | 
			
		||||
        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 | 
			
		||||
        break;
 | 
			
		||||
@ -151,6 +161,10 @@ eek_symbol_get_property (GObject    *object,
 | 
			
		||||
        g_value_set_string (value,
 | 
			
		||||
                            eek_symbol_get_icon_name (EEK_SYMBOL(object)));
 | 
			
		||||
        break;
 | 
			
		||||
    case PROP_TOOLTIP:
 | 
			
		||||
        g_value_set_string (value,
 | 
			
		||||
                            eek_symbol_get_tooltip (EEK_SYMBOL(object)));
 | 
			
		||||
        break;
 | 
			
		||||
    default:
 | 
			
		||||
        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 | 
			
		||||
        break;
 | 
			
		||||
@ -160,11 +174,13 @@ eek_symbol_get_property (GObject    *object,
 | 
			
		||||
static void
 | 
			
		||||
eek_symbol_finalize (GObject *object)
 | 
			
		||||
{
 | 
			
		||||
    EekSymbolPrivate *priv = EEK_SYMBOL_GET_PRIVATE(object);
 | 
			
		||||
    EekSymbol        *self = EEK_SYMBOL (object);
 | 
			
		||||
    EekSymbolPrivate *priv = eek_symbol_get_instance_private (self);
 | 
			
		||||
 | 
			
		||||
    g_free (priv->name);
 | 
			
		||||
    g_free (priv->label);
 | 
			
		||||
    g_free (priv->icon_name);
 | 
			
		||||
    g_free (priv->tooltip);
 | 
			
		||||
    G_OBJECT_CLASS (eek_symbol_parent_class)->finalize (object);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -174,8 +190,6 @@ eek_symbol_class_init (EekSymbolClass *klass)
 | 
			
		||||
    GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
 | 
			
		||||
    GParamSpec *pspec;
 | 
			
		||||
 | 
			
		||||
    g_type_class_add_private (gobject_class, sizeof (EekSymbolPrivate));
 | 
			
		||||
 | 
			
		||||
    gobject_class->set_property = eek_symbol_set_property;
 | 
			
		||||
    gobject_class->get_property = eek_symbol_get_property;
 | 
			
		||||
    gobject_class->finalize = eek_symbol_finalize;
 | 
			
		||||
@ -216,14 +230,20 @@ eek_symbol_class_init (EekSymbolClass *klass)
 | 
			
		||||
                                 NULL,
 | 
			
		||||
                                 G_PARAM_CONSTRUCT | G_PARAM_READWRITE);
 | 
			
		||||
    g_object_class_install_property (gobject_class, PROP_ICON_NAME, pspec);
 | 
			
		||||
 | 
			
		||||
    pspec = g_param_spec_string ("tooltip",
 | 
			
		||||
                                 "Tooltip",
 | 
			
		||||
                                 "Tooltip text",
 | 
			
		||||
                                 NULL,
 | 
			
		||||
                                 G_PARAM_CONSTRUCT | G_PARAM_READWRITE);
 | 
			
		||||
    g_object_class_install_property (gobject_class, PROP_TOOLTIP, pspec);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
eek_symbol_init (EekSymbol *self)
 | 
			
		||||
{
 | 
			
		||||
    EekSymbolPrivate *priv;
 | 
			
		||||
    EekSymbolPrivate *priv = eek_symbol_get_instance_private (self);
 | 
			
		||||
 | 
			
		||||
    priv = self->priv = EEK_SYMBOL_GET_PRIVATE(self);
 | 
			
		||||
    priv->category = EEK_SYMBOL_CATEGORY_UNKNOWN;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -250,11 +270,10 @@ void
 | 
			
		||||
eek_symbol_set_name (EekSymbol   *symbol,
 | 
			
		||||
                     const gchar *name)
 | 
			
		||||
{
 | 
			
		||||
    EekSymbolPrivate *priv;
 | 
			
		||||
 | 
			
		||||
    g_return_if_fail (EEK_IS_SYMBOL(symbol));
 | 
			
		||||
 | 
			
		||||
    priv = EEK_SYMBOL_GET_PRIVATE(symbol);
 | 
			
		||||
    EekSymbolPrivate *priv = eek_symbol_get_instance_private (symbol);
 | 
			
		||||
 | 
			
		||||
    g_free (priv->name);
 | 
			
		||||
    priv->name = g_strdup (name);
 | 
			
		||||
}
 | 
			
		||||
@ -265,14 +284,13 @@ eek_symbol_set_name (EekSymbol   *symbol,
 | 
			
		||||
 *
 | 
			
		||||
 * Get the name of @symbol.
 | 
			
		||||
 */
 | 
			
		||||
G_CONST_RETURN gchar *
 | 
			
		||||
const gchar *
 | 
			
		||||
eek_symbol_get_name (EekSymbol *symbol)
 | 
			
		||||
{
 | 
			
		||||
    EekSymbolPrivate *priv;
 | 
			
		||||
 | 
			
		||||
    g_return_val_if_fail (EEK_IS_SYMBOL(symbol), NULL);
 | 
			
		||||
 | 
			
		||||
    priv = EEK_SYMBOL_GET_PRIVATE(symbol);
 | 
			
		||||
    EekSymbolPrivate *priv = eek_symbol_get_instance_private (symbol);
 | 
			
		||||
 | 
			
		||||
    if (priv->name == NULL || *priv->name == '\0')
 | 
			
		||||
        return NULL;
 | 
			
		||||
    return priv->name;
 | 
			
		||||
@ -289,11 +307,10 @@ void
 | 
			
		||||
eek_symbol_set_label (EekSymbol   *symbol,
 | 
			
		||||
                      const gchar *label)
 | 
			
		||||
{
 | 
			
		||||
    EekSymbolPrivate *priv;
 | 
			
		||||
 | 
			
		||||
    g_return_if_fail (EEK_IS_SYMBOL(symbol));
 | 
			
		||||
 | 
			
		||||
    priv = EEK_SYMBOL_GET_PRIVATE(symbol);
 | 
			
		||||
    EekSymbolPrivate *priv = eek_symbol_get_instance_private (symbol);
 | 
			
		||||
 | 
			
		||||
    g_free (priv->label);
 | 
			
		||||
    priv->label = g_strdup (label);
 | 
			
		||||
}
 | 
			
		||||
@ -304,14 +321,13 @@ eek_symbol_set_label (EekSymbol   *symbol,
 | 
			
		||||
 *
 | 
			
		||||
 * Get the label text of @symbol.
 | 
			
		||||
 */
 | 
			
		||||
G_CONST_RETURN gchar *
 | 
			
		||||
const gchar *
 | 
			
		||||
eek_symbol_get_label (EekSymbol *symbol)
 | 
			
		||||
{
 | 
			
		||||
    EekSymbolPrivate *priv;
 | 
			
		||||
 | 
			
		||||
    g_return_val_if_fail (EEK_IS_SYMBOL(symbol), NULL);
 | 
			
		||||
 | 
			
		||||
    priv = EEK_SYMBOL_GET_PRIVATE(symbol);
 | 
			
		||||
    EekSymbolPrivate *priv = eek_symbol_get_instance_private (symbol);
 | 
			
		||||
 | 
			
		||||
    if (priv->label == NULL || *priv->label == '\0')
 | 
			
		||||
        return NULL;
 | 
			
		||||
    return priv->label;
 | 
			
		||||
@ -328,11 +344,10 @@ void
 | 
			
		||||
eek_symbol_set_category (EekSymbol        *symbol,
 | 
			
		||||
                         EekSymbolCategory category)
 | 
			
		||||
{
 | 
			
		||||
    EekSymbolPrivate *priv;
 | 
			
		||||
 | 
			
		||||
    g_return_if_fail (EEK_IS_SYMBOL(symbol));
 | 
			
		||||
 | 
			
		||||
    priv = EEK_SYMBOL_GET_PRIVATE(symbol);
 | 
			
		||||
    EekSymbolPrivate *priv = eek_symbol_get_instance_private (symbol);
 | 
			
		||||
 | 
			
		||||
    priv->category = category;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -345,11 +360,10 @@ eek_symbol_set_category (EekSymbol        *symbol,
 | 
			
		||||
EekSymbolCategory
 | 
			
		||||
eek_symbol_get_category (EekSymbol *symbol)
 | 
			
		||||
{
 | 
			
		||||
    EekSymbolPrivate *priv;
 | 
			
		||||
 | 
			
		||||
    g_return_val_if_fail (EEK_IS_SYMBOL(symbol), EEK_SYMBOL_CATEGORY_UNKNOWN);
 | 
			
		||||
 | 
			
		||||
    priv = EEK_SYMBOL_GET_PRIVATE(symbol);
 | 
			
		||||
    EekSymbolPrivate *priv = eek_symbol_get_instance_private (symbol);
 | 
			
		||||
 | 
			
		||||
    return priv->category;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -364,11 +378,10 @@ void
 | 
			
		||||
eek_symbol_set_modifier_mask (EekSymbol      *symbol,
 | 
			
		||||
                              EekModifierType mask)
 | 
			
		||||
{
 | 
			
		||||
    EekSymbolPrivate *priv;
 | 
			
		||||
 | 
			
		||||
    g_return_if_fail (EEK_IS_SYMBOL(symbol));
 | 
			
		||||
 | 
			
		||||
    priv = EEK_SYMBOL_GET_PRIVATE(symbol);
 | 
			
		||||
    EekSymbolPrivate *priv = eek_symbol_get_instance_private (symbol);
 | 
			
		||||
 | 
			
		||||
    priv->modifier_mask = mask;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -381,11 +394,10 @@ eek_symbol_set_modifier_mask (EekSymbol      *symbol,
 | 
			
		||||
EekModifierType
 | 
			
		||||
eek_symbol_get_modifier_mask (EekSymbol *symbol)
 | 
			
		||||
{
 | 
			
		||||
    EekSymbolPrivate *priv;
 | 
			
		||||
 | 
			
		||||
    g_return_val_if_fail (EEK_IS_SYMBOL(symbol), 0);
 | 
			
		||||
 | 
			
		||||
    priv = EEK_SYMBOL_GET_PRIVATE(symbol);
 | 
			
		||||
    EekSymbolPrivate *priv = eek_symbol_get_instance_private (symbol);
 | 
			
		||||
 | 
			
		||||
    return priv->modifier_mask;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -413,11 +425,10 @@ void
 | 
			
		||||
eek_symbol_set_icon_name (EekSymbol   *symbol,
 | 
			
		||||
                          const gchar *icon_name)
 | 
			
		||||
{
 | 
			
		||||
    EekSymbolPrivate *priv;
 | 
			
		||||
 | 
			
		||||
    g_return_if_fail (EEK_IS_SYMBOL(symbol));
 | 
			
		||||
 | 
			
		||||
    priv = EEK_SYMBOL_GET_PRIVATE(symbol);
 | 
			
		||||
    EekSymbolPrivate *priv = eek_symbol_get_instance_private (symbol);
 | 
			
		||||
 | 
			
		||||
    g_free (priv->icon_name);
 | 
			
		||||
    priv->icon_name = g_strdup (icon_name);
 | 
			
		||||
}
 | 
			
		||||
@ -428,19 +439,55 @@ eek_symbol_set_icon_name (EekSymbol   *symbol,
 | 
			
		||||
 *
 | 
			
		||||
 * Get the icon name of @symbol.
 | 
			
		||||
 */
 | 
			
		||||
G_CONST_RETURN gchar *
 | 
			
		||||
const gchar *
 | 
			
		||||
eek_symbol_get_icon_name (EekSymbol *symbol)
 | 
			
		||||
{
 | 
			
		||||
    EekSymbolPrivate *priv;
 | 
			
		||||
 | 
			
		||||
    g_return_val_if_fail (EEK_IS_SYMBOL(symbol), NULL);
 | 
			
		||||
 | 
			
		||||
    priv = EEK_SYMBOL_GET_PRIVATE(symbol);
 | 
			
		||||
    EekSymbolPrivate *priv = eek_symbol_get_instance_private (symbol);
 | 
			
		||||
 | 
			
		||||
    if (priv->icon_name == NULL || *priv->icon_name == '\0')
 | 
			
		||||
        return NULL;
 | 
			
		||||
    return priv->icon_name;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eek_symbol_set_tooltip:
 | 
			
		||||
 * @symbol: an #EekSymbol
 | 
			
		||||
 * @tooltip: icon name of @symbol
 | 
			
		||||
 *
 | 
			
		||||
 * Set the tooltip text of @symbol to @tooltip.
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
eek_symbol_set_tooltip (EekSymbol   *symbol,
 | 
			
		||||
                        const gchar *tooltip)
 | 
			
		||||
{
 | 
			
		||||
    g_return_if_fail (EEK_IS_SYMBOL(symbol));
 | 
			
		||||
 | 
			
		||||
    EekSymbolPrivate *priv = eek_symbol_get_instance_private (symbol);
 | 
			
		||||
 | 
			
		||||
    g_free (priv->tooltip);
 | 
			
		||||
    priv->tooltip = g_strdup (tooltip);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eek_symbol_get_tooltip:
 | 
			
		||||
 * @symbol: an #EekSymbol
 | 
			
		||||
 *
 | 
			
		||||
 * Get the tooltip text of @symbol.
 | 
			
		||||
 */
 | 
			
		||||
const gchar *
 | 
			
		||||
eek_symbol_get_tooltip (EekSymbol *symbol)
 | 
			
		||||
{
 | 
			
		||||
    g_return_val_if_fail (EEK_IS_SYMBOL(symbol), NULL);
 | 
			
		||||
 | 
			
		||||
    EekSymbolPrivate *priv = eek_symbol_get_instance_private (symbol);
 | 
			
		||||
 | 
			
		||||
    if (priv->tooltip == NULL || *priv->tooltip == '\0')
 | 
			
		||||
        return NULL;
 | 
			
		||||
    return priv->tooltip;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static const struct {
 | 
			
		||||
    EekSymbolCategory category;
 | 
			
		||||
    gchar *name;
 | 
			
		||||
@ -456,7 +503,7 @@ static const struct {
 | 
			
		||||
    { EEK_SYMBOL_CATEGORY_UNKNOWN, NULL }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
G_CONST_RETURN gchar *
 | 
			
		||||
const gchar *
 | 
			
		||||
eek_symbol_category_get_name (EekSymbolCategory category)
 | 
			
		||||
{
 | 
			
		||||
    gint i;
 | 
			
		||||
 | 
			
		||||
@ -59,27 +59,7 @@ typedef enum {
 | 
			
		||||
} EekSymbolCategory;
 | 
			
		||||
 | 
			
		||||
#define EEK_TYPE_SYMBOL (eek_symbol_get_type())
 | 
			
		||||
#define EEK_SYMBOL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EEK_TYPE_SYMBOL, EekSymbol))
 | 
			
		||||
#define EEK_SYMBOL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EEK_TYPE_SYMBOL, EekSymbolClass))
 | 
			
		||||
#define EEK_IS_SYMBOL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EEK_TYPE_SYMBOL))
 | 
			
		||||
#define EEK_IS_SYMBOL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EEK_TYPE_SYMBOL))
 | 
			
		||||
#define EEK_SYMBOL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EEK_TYPE_SYMBOL, EekSymbolClass))
 | 
			
		||||
 | 
			
		||||
typedef struct _EekSymbolClass EekSymbolClass;
 | 
			
		||||
typedef struct _EekSymbolPrivate EekSymbolPrivate;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * EekSymbol:
 | 
			
		||||
 *
 | 
			
		||||
 * The #EekSymbol structure contains only private data and should only
 | 
			
		||||
 * be accessed using the provided API.
 | 
			
		||||
 */
 | 
			
		||||
struct _EekSymbol {
 | 
			
		||||
    /*< private >*/
 | 
			
		||||
    GObject parent;
 | 
			
		||||
 | 
			
		||||
    EekSymbolPrivate *priv;
 | 
			
		||||
};
 | 
			
		||||
G_DECLARE_DERIVABLE_TYPE(EekSymbol, eek_symbol, EEK, SYMBOL, GObject)
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * EekSymbolClass:
 | 
			
		||||
@ -89,32 +69,31 @@ struct _EekSymbolClass {
 | 
			
		||||
    GObjectClass parent_class;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
GType                 eek_symbol_get_type      (void) G_GNUC_CONST;
 | 
			
		||||
GType             eek_symbol_get_type           (void) G_GNUC_CONST;
 | 
			
		||||
 | 
			
		||||
EekSymbol            *eek_symbol_new           (const gchar      *name);
 | 
			
		||||
void                  eek_symbol_set_name      (EekSymbol        *symbol,
 | 
			
		||||
                                                const gchar      *name);
 | 
			
		||||
G_CONST_RETURN gchar *eek_symbol_get_name      (EekSymbol        *symbol);
 | 
			
		||||
void                  eek_symbol_set_label     (EekSymbol        *symbol,
 | 
			
		||||
                                                const gchar      *label);
 | 
			
		||||
G_CONST_RETURN gchar *eek_symbol_get_label     (EekSymbol        *symbol);
 | 
			
		||||
void                  eek_symbol_set_category  (EekSymbol        *symbol,
 | 
			
		||||
                                                EekSymbolCategory category);
 | 
			
		||||
EekSymbolCategory     eek_symbol_get_category  (EekSymbol        *symbol);
 | 
			
		||||
EekModifierType       eek_symbol_get_modifier_mask
 | 
			
		||||
                                               (EekSymbol        *symbol);
 | 
			
		||||
void                  eek_symbol_set_modifier_mask
 | 
			
		||||
                                               (EekSymbol        *symbol,
 | 
			
		||||
                                                EekModifierType   mask);
 | 
			
		||||
gboolean              eek_symbol_is_modifier   (EekSymbol        *symbol);
 | 
			
		||||
void                  eek_symbol_set_icon_name (EekSymbol        *symbol,
 | 
			
		||||
                                                const gchar      *icon_name);
 | 
			
		||||
G_CONST_RETURN gchar *eek_symbol_get_icon_name (EekSymbol        *symbol);
 | 
			
		||||
EekSymbol        *eek_symbol_new                (const gchar      *name);
 | 
			
		||||
void              eek_symbol_set_name           (EekSymbol        *symbol,
 | 
			
		||||
                                                 const gchar      *name);
 | 
			
		||||
const gchar      *eek_symbol_get_name           (EekSymbol        *symbol);
 | 
			
		||||
void              eek_symbol_set_label          (EekSymbol        *symbol,
 | 
			
		||||
                                                 const gchar      *label);
 | 
			
		||||
const gchar      *eek_symbol_get_label          (EekSymbol        *symbol);
 | 
			
		||||
void              eek_symbol_set_category       (EekSymbol        *symbol,
 | 
			
		||||
                                                 EekSymbolCategory category);
 | 
			
		||||
EekSymbolCategory eek_symbol_get_category       (EekSymbol        *symbol);
 | 
			
		||||
EekModifierType   eek_symbol_get_modifier_mask  (EekSymbol        *symbol);
 | 
			
		||||
void              eek_symbol_set_modifier_mask  (EekSymbol        *symbol,
 | 
			
		||||
                                                 EekModifierType   mask);
 | 
			
		||||
gboolean          eek_symbol_is_modifier        (EekSymbol        *symbol);
 | 
			
		||||
void              eek_symbol_set_icon_name      (EekSymbol        *symbol,
 | 
			
		||||
                                                 const gchar      *icon_name);
 | 
			
		||||
const gchar      *eek_symbol_get_icon_name      (EekSymbol        *symbol);
 | 
			
		||||
void              eek_symbol_set_tooltip        (EekSymbol        *symbol,
 | 
			
		||||
                                                 const gchar      *tooltip);
 | 
			
		||||
const gchar *     eek_symbol_get_tooltip        (EekSymbol        *symbol);
 | 
			
		||||
 | 
			
		||||
G_CONST_RETURN gchar *eek_symbol_category_get_name
 | 
			
		||||
                                               (EekSymbolCategory category);
 | 
			
		||||
EekSymbolCategory     eek_symbol_category_from_name
 | 
			
		||||
                                               (const gchar      *name);
 | 
			
		||||
const gchar      *eek_symbol_category_get_name  (EekSymbolCategory category);
 | 
			
		||||
EekSymbolCategory eek_symbol_category_from_name (const gchar      *name);
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -36,18 +36,20 @@ enum {
 | 
			
		||||
    PROP_LAST
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct _EekTextPrivate {
 | 
			
		||||
typedef struct _EekTextPrivate
 | 
			
		||||
{
 | 
			
		||||
    gchar *text;
 | 
			
		||||
};
 | 
			
		||||
} EekTextPrivate;
 | 
			
		||||
 | 
			
		||||
static void eek_serializable_iface_init (EekSerializableIface *iface);
 | 
			
		||||
 | 
			
		||||
G_DEFINE_TYPE_WITH_CODE (EekText, eek_text, EEK_TYPE_SYMBOL,
 | 
			
		||||
                         G_IMPLEMENT_INTERFACE (EEK_TYPE_SERIALIZABLE,
 | 
			
		||||
                                                eek_serializable_iface_init));
 | 
			
		||||
 | 
			
		||||
#define EEK_TEXT_GET_PRIVATE(obj)                                  \
 | 
			
		||||
    (G_TYPE_INSTANCE_GET_PRIVATE ((obj), EEK_TYPE_TEXT, EekTextPrivate))
 | 
			
		||||
G_DEFINE_TYPE_EXTENDED (EekText,
 | 
			
		||||
			eek_text,
 | 
			
		||||
			EEK_TYPE_SYMBOL,
 | 
			
		||||
			0, /* GTypeFlags */
 | 
			
		||||
			G_ADD_PRIVATE (EekText)
 | 
			
		||||
                        G_IMPLEMENT_INTERFACE (EEK_TYPE_SERIALIZABLE,
 | 
			
		||||
                                               eek_serializable_iface_init))
 | 
			
		||||
 | 
			
		||||
static EekSerializableIface *eek_text_parent_serializable_iface;
 | 
			
		||||
 | 
			
		||||
@ -55,7 +57,7 @@ static void
 | 
			
		||||
eek_text_real_serialize (EekSerializable *self,
 | 
			
		||||
                         GVariantBuilder *builder)
 | 
			
		||||
{
 | 
			
		||||
    EekTextPrivate *priv = EEK_TEXT_GET_PRIVATE(self);
 | 
			
		||||
    EekTextPrivate *priv = eek_text_get_instance_private (EEK_TEXT (self));
 | 
			
		||||
 | 
			
		||||
    eek_text_parent_serializable_iface->serialize (self, builder);
 | 
			
		||||
 | 
			
		||||
@ -67,7 +69,7 @@ eek_text_real_deserialize (EekSerializable *self,
 | 
			
		||||
                           GVariant        *variant,
 | 
			
		||||
                           gsize            index)
 | 
			
		||||
{
 | 
			
		||||
    EekTextPrivate *priv = EEK_TEXT_GET_PRIVATE(self);
 | 
			
		||||
    EekTextPrivate *priv = eek_text_get_instance_private (EEK_TEXT (self));
 | 
			
		||||
 | 
			
		||||
    index = eek_text_parent_serializable_iface->deserialize (self,
 | 
			
		||||
                                                             variant,
 | 
			
		||||
@ -93,7 +95,9 @@ eek_text_set_property (GObject      *object,
 | 
			
		||||
                       const GValue *value,
 | 
			
		||||
                       GParamSpec   *pspec)
 | 
			
		||||
{
 | 
			
		||||
    EekTextPrivate *priv = EEK_TEXT_GET_PRIVATE(object);
 | 
			
		||||
    EekText        *self = EEK_TEXT (object);
 | 
			
		||||
    EekTextPrivate *priv = eek_text_get_instance_private (self);
 | 
			
		||||
 | 
			
		||||
    switch (prop_id) {
 | 
			
		||||
    case PROP_TEXT:
 | 
			
		||||
        g_free (priv->text);
 | 
			
		||||
@ -107,11 +111,13 @@ eek_text_set_property (GObject      *object,
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
eek_text_get_property (GObject    *object,
 | 
			
		||||
                         guint       prop_id,
 | 
			
		||||
                         GValue     *value,
 | 
			
		||||
                         GParamSpec *pspec)
 | 
			
		||||
                       guint       prop_id,
 | 
			
		||||
                       GValue     *value,
 | 
			
		||||
                       GParamSpec *pspec)
 | 
			
		||||
{
 | 
			
		||||
    EekTextPrivate *priv = EEK_TEXT_GET_PRIVATE(object);
 | 
			
		||||
    EekText        *self = EEK_TEXT (object);
 | 
			
		||||
    EekTextPrivate *priv = eek_text_get_instance_private (self);
 | 
			
		||||
 | 
			
		||||
    switch (prop_id) {
 | 
			
		||||
    case PROP_TEXT:
 | 
			
		||||
        g_value_set_string (value, priv->text);
 | 
			
		||||
@ -125,7 +131,8 @@ eek_text_get_property (GObject    *object,
 | 
			
		||||
static void
 | 
			
		||||
eek_text_finalize (GObject *object)
 | 
			
		||||
{
 | 
			
		||||
    EekTextPrivate *priv = EEK_TEXT_GET_PRIVATE(object);
 | 
			
		||||
    EekText        *self = EEK_TEXT (object);
 | 
			
		||||
    EekTextPrivate *priv = eek_text_get_instance_private (self);
 | 
			
		||||
 | 
			
		||||
    g_free (priv->text);
 | 
			
		||||
    G_OBJECT_CLASS (eek_text_parent_class)->finalize (object);
 | 
			
		||||
@ -137,8 +144,6 @@ eek_text_class_init (EekTextClass *klass)
 | 
			
		||||
    GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
 | 
			
		||||
    GParamSpec *pspec;
 | 
			
		||||
 | 
			
		||||
    g_type_class_add_private (gobject_class, sizeof (EekTextPrivate));
 | 
			
		||||
 | 
			
		||||
    gobject_class->set_property = eek_text_set_property;
 | 
			
		||||
    gobject_class->get_property = eek_text_get_property;
 | 
			
		||||
    gobject_class->finalize = eek_text_finalize;
 | 
			
		||||
@ -154,7 +159,7 @@ eek_text_class_init (EekTextClass *klass)
 | 
			
		||||
static void
 | 
			
		||||
eek_text_init (EekText *self)
 | 
			
		||||
{
 | 
			
		||||
    self->priv = EEK_TEXT_GET_PRIVATE(self);
 | 
			
		||||
    /* void */
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
EekText *
 | 
			
		||||
@ -176,7 +181,7 @@ eek_text_new (const gchar *text)
 | 
			
		||||
const gchar *
 | 
			
		||||
eek_text_get_text (EekText *text)
 | 
			
		||||
{
 | 
			
		||||
    EekTextPrivate *priv = EEK_TEXT_GET_PRIVATE(text);
 | 
			
		||||
    EekTextPrivate *priv = eek_text_get_instance_private (text);
 | 
			
		||||
 | 
			
		||||
    return priv->text;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -30,27 +30,7 @@
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
#define EEK_TYPE_TEXT (eek_text_get_type())
 | 
			
		||||
#define EEK_TEXT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EEK_TYPE_TEXT, EekText))
 | 
			
		||||
#define EEK_TEXT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EEK_TYPE_TEXT, EekTextClass))
 | 
			
		||||
#define EEK_IS_TEXT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EEK_TYPE_TEXT))
 | 
			
		||||
#define EEK_IS_TEXT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EEK_TYPE_TEXT))
 | 
			
		||||
#define EEK_TEXT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EEK_TYPE_TEXT, EekTextClass))
 | 
			
		||||
 | 
			
		||||
typedef struct _EekTextClass EekTextClass;
 | 
			
		||||
typedef struct _EekTextPrivate EekTextPrivate;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * EekText:
 | 
			
		||||
 *
 | 
			
		||||
 * The #EekText structure contains only private data and should only
 | 
			
		||||
 * be accessed using the provided API.
 | 
			
		||||
 */
 | 
			
		||||
struct _EekText {
 | 
			
		||||
    /*< private >*/
 | 
			
		||||
    EekSymbol parent;
 | 
			
		||||
 | 
			
		||||
    EekTextPrivate *priv;
 | 
			
		||||
};
 | 
			
		||||
G_DECLARE_DERIVABLE_TYPE(EekText, eek_text, EEK, TEXT, EekSymbol)
 | 
			
		||||
 | 
			
		||||
struct _EekTextClass {
 | 
			
		||||
    /*< private >*/
 | 
			
		||||
 | 
			
		||||
@ -89,9 +89,6 @@ static void eek_theme_node_finalize           (GObject                 *object);
 | 
			
		||||
 | 
			
		||||
static const EekColor BLACK_COLOR = { 0, 0, 0, 0xff };
 | 
			
		||||
static const EekColor TRANSPARENT_COLOR = { 0, 0, 0, 0 };
 | 
			
		||||
static const EekColor DEFAULT_SUCCESS_COLOR = { 0x4e, 0x9a, 0x06, 0xff };
 | 
			
		||||
static const EekColor DEFAULT_WARNING_COLOR = { 0xf5, 0x79, 0x3e, 0xff };
 | 
			
		||||
static const EekColor DEFAULT_ERROR_COLOR = { 0xcc, 0x00, 0x00, 0xff };
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
eek_theme_node_init (EekThemeNode *self)
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										138
									
								
								eek/eek-theme.c
									
									
									
									
									
								
							
							
						
						
									
										138
									
								
								eek/eek-theme.c
									
									
									
									
									
								
							@ -43,6 +43,7 @@
 | 
			
		||||
 * Copyright (C) 2003-2004 Dodji Seketeli.  All Rights Reserved.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#define G_LOG_DOMAIN "eek-theme"
 | 
			
		||||
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
@ -166,103 +167,65 @@ eek_theme_class_init (EekThemeClass *klass)
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* This is a workaround for a bug in libcroco < 0.6.2 where
 | 
			
		||||
 * function starting with 'r' (and 'u') are misparsed. We work
 | 
			
		||||
 * around this by exploiting the fact that libcroco is incomformant
 | 
			
		||||
 * with the CSS-spec and case sensitive and pre-convert all
 | 
			
		||||
 * occurrences of rgba to RGBA. Then we make our own parsing
 | 
			
		||||
 * code check for RGBA as well.
 | 
			
		||||
 */
 | 
			
		||||
#if LIBCROCO_VERSION_NUMBER < 602
 | 
			
		||||
static gboolean
 | 
			
		||||
is_identifier_character (char c)
 | 
			
		||||
{
 | 
			
		||||
  /* Actual CSS rules allow for unicode > 0x00a1 and escaped
 | 
			
		||||
   * characters, but we'll assume we won't do that in our stylesheets
 | 
			
		||||
   * or at least not next to the string 'rgba'.
 | 
			
		||||
   */
 | 
			
		||||
  return g_ascii_isalnum(c) || c == '-' || c == '_';
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
convert_rgba_RGBA (char *buf)
 | 
			
		||||
{
 | 
			
		||||
  char *p;
 | 
			
		||||
 | 
			
		||||
  p = strstr (buf, "rgba");
 | 
			
		||||
  while (p)
 | 
			
		||||
    {
 | 
			
		||||
      /* Check if this looks like a complete token; this is to
 | 
			
		||||
       * avoiding mangling, say, a selector '.rgba-entry' */
 | 
			
		||||
      if (!((p > buf && is_identifier_character (*(p - 1))) ||
 | 
			
		||||
            (is_identifier_character (*(p + 4)))))
 | 
			
		||||
        memcpy(p, "RGBA", 4);
 | 
			
		||||
      p += 4;
 | 
			
		||||
      p = strstr (p, "rgba");
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static CRStyleSheet *
 | 
			
		||||
parse_stylesheet (const char  *filename,
 | 
			
		||||
                  GError     **error)
 | 
			
		||||
{
 | 
			
		||||
  enum CRStatus status;
 | 
			
		||||
  char *contents;
 | 
			
		||||
  gsize length;
 | 
			
		||||
  CRStyleSheet *stylesheet = NULL;
 | 
			
		||||
 | 
			
		||||
  if (filename == NULL)
 | 
			
		||||
    return NULL;
 | 
			
		||||
 | 
			
		||||
  if (!g_file_get_contents (filename, &contents, &length, error))
 | 
			
		||||
    return NULL;
 | 
			
		||||
 | 
			
		||||
  convert_rgba_RGBA (contents);
 | 
			
		||||
 | 
			
		||||
  status = cr_om_parser_simply_parse_buf ((const guchar *) contents,
 | 
			
		||||
                                          length,
 | 
			
		||||
                                          CR_UTF_8,
 | 
			
		||||
                                          &stylesheet);
 | 
			
		||||
  g_free (contents);
 | 
			
		||||
 | 
			
		||||
  if (status != CR_OK)
 | 
			
		||||
    {
 | 
			
		||||
      g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
 | 
			
		||||
                   "Error parsing stylesheet '%s'; errcode:%d", filename, status);
 | 
			
		||||
      return NULL;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  return stylesheet;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
CRDeclaration *
 | 
			
		||||
_eek_theme_parse_declaration_list (const char *str)
 | 
			
		||||
{
 | 
			
		||||
  char *copy = g_strdup (str);
 | 
			
		||||
  CRDeclaration *result;
 | 
			
		||||
 | 
			
		||||
  convert_rgba_RGBA (copy);
 | 
			
		||||
 | 
			
		||||
  result = cr_declaration_parse_list_from_buf ((const guchar *)copy,
 | 
			
		||||
                                               CR_UTF_8);
 | 
			
		||||
  g_free (copy);
 | 
			
		||||
 | 
			
		||||
  return result;
 | 
			
		||||
}
 | 
			
		||||
#else /* LIBCROCO_VERSION_NUMBER >= 602 */
 | 
			
		||||
static CRStyleSheet *
 | 
			
		||||
parse_stylesheet (const char  *filename,
 | 
			
		||||
                  GError     **error)
 | 
			
		||||
{
 | 
			
		||||
  enum CRStatus status;
 | 
			
		||||
  CRStyleSheet *stylesheet;
 | 
			
		||||
  g_autoptr (GFileInputStream) stream = NULL;
 | 
			
		||||
  g_autoptr (GFileInfo) info = NULL;
 | 
			
		||||
  g_autoptr (GFile) file = NULL;
 | 
			
		||||
  g_autofree guchar* contents = NULL;
 | 
			
		||||
  goffset size;
 | 
			
		||||
  gsize out = 0;
 | 
			
		||||
  GError *err = NULL;
 | 
			
		||||
 | 
			
		||||
  if (filename == NULL)
 | 
			
		||||
    return NULL;
 | 
			
		||||
 | 
			
		||||
  status = cr_om_parser_simply_parse_file ((const guchar *) filename,
 | 
			
		||||
                                           CR_UTF_8,
 | 
			
		||||
                                           &stylesheet);
 | 
			
		||||
  g_debug ("Parsing %s", filename);
 | 
			
		||||
  if (g_strcmp0 (filename, "resource://") > 0) {
 | 
			
		||||
      file = g_file_new_for_uri (filename);
 | 
			
		||||
      stream = g_file_read (file, NULL, &err);
 | 
			
		||||
      if (!stream) {
 | 
			
		||||
          g_warning ("Failed to open %s: %s", filename, err->message);
 | 
			
		||||
          g_clear_error (&err);
 | 
			
		||||
          return NULL;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      info = g_file_input_stream_query_info (stream,
 | 
			
		||||
                                             G_FILE_ATTRIBUTE_STANDARD_SIZE,
 | 
			
		||||
                                             NULL,
 | 
			
		||||
                                             &err);
 | 
			
		||||
 | 
			
		||||
      if (!info) {
 | 
			
		||||
          g_warning ("Failed to stat %s: %s", filename, err->message);
 | 
			
		||||
          g_clear_error (&err);
 | 
			
		||||
          return NULL;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      size = g_file_info_get_size (info);
 | 
			
		||||
      contents = g_malloc0 (size);
 | 
			
		||||
      if (!g_input_stream_read_all (G_INPUT_STREAM (stream),
 | 
			
		||||
                                    contents,
 | 
			
		||||
                                    size,
 | 
			
		||||
                                    &out,
 | 
			
		||||
                                    NULL,
 | 
			
		||||
                                    &err)) {
 | 
			
		||||
          g_warning ("Failed to read %s: %s", filename, err->message);
 | 
			
		||||
          g_clear_error (&err);
 | 
			
		||||
          return NULL;
 | 
			
		||||
      }
 | 
			
		||||
      status = cr_om_parser_simply_parse_buf (contents,
 | 
			
		||||
                                              size,
 | 
			
		||||
                                              CR_UTF_8,
 | 
			
		||||
                                              &stylesheet);
 | 
			
		||||
  } else {
 | 
			
		||||
      status = cr_om_parser_simply_parse_file ((const guchar *) filename,
 | 
			
		||||
                                               CR_UTF_8,
 | 
			
		||||
                                               &stylesheet);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if (status != CR_OK)
 | 
			
		||||
    {
 | 
			
		||||
@ -280,7 +243,6 @@ _eek_theme_parse_declaration_list (const char *str)
 | 
			
		||||
  return cr_declaration_parse_list_from_buf ((const guchar *)str,
 | 
			
		||||
                                             CR_UTF_8);
 | 
			
		||||
}
 | 
			
		||||
#endif /* LIBCROCO_VERSION_NUMBER < 602 */
 | 
			
		||||
 | 
			
		||||
/* Just g_warning for now until we have something nicer to do */
 | 
			
		||||
static CRStyleSheet *
 | 
			
		||||
 | 
			
		||||
@ -150,6 +150,8 @@ typedef struct _EekBounds EekBounds;
 | 
			
		||||
typedef struct _EekOutline EekOutline;
 | 
			
		||||
typedef struct _EekColor EekColor;
 | 
			
		||||
 | 
			
		||||
typedef struct _EekboardContextService EekboardContextService;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * EekPoint:
 | 
			
		||||
 * @x: X coordinate of the point
 | 
			
		||||
@ -212,7 +214,7 @@ struct _EekOutline
 | 
			
		||||
    /*< public >*/
 | 
			
		||||
    gdouble corner_radius;
 | 
			
		||||
    EekPoint *points;
 | 
			
		||||
    gint num_points;
 | 
			
		||||
    guint num_points;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
GType       eek_outline_get_type (void) G_GNUC_CONST;
 | 
			
		||||
 | 
			
		||||
@ -31,40 +31,34 @@
 | 
			
		||||
#include "config.h"
 | 
			
		||||
#endif  /* HAVE_CONFIG_H */
 | 
			
		||||
 | 
			
		||||
#include "eek-xkb-layout.h"
 | 
			
		||||
 | 
			
		||||
#include <X11/keysym.h>
 | 
			
		||||
#include <X11/XKBlib.h>
 | 
			
		||||
#include <X11/extensions/XKBgeom.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <stdarg.h>
 | 
			
		||||
#include <gio/gio.h>
 | 
			
		||||
 | 
			
		||||
#include "eek-xkb-layout.h"
 | 
			
		||||
#include "eek-keyboard.h"
 | 
			
		||||
#include "eek-section.h"
 | 
			
		||||
#include "eek-key.h"
 | 
			
		||||
#include "eek-keysym.h"
 | 
			
		||||
 | 
			
		||||
#define noKBDRAW_DEBUG
 | 
			
		||||
#define XKB_COMPONENT_MASK (XkbGBN_GeometryMask |       \
 | 
			
		||||
                            XkbGBN_KeyNamesMask |       \
 | 
			
		||||
                            XkbGBN_OtherNamesMask |     \
 | 
			
		||||
                            XkbGBN_SymbolsMask |        \
 | 
			
		||||
                            XkbGBN_IndicatorMapMask)
 | 
			
		||||
 | 
			
		||||
static void initable_iface_init (GInitableIface *initable_iface);
 | 
			
		||||
 | 
			
		||||
G_DEFINE_TYPE_WITH_CODE (EekXkbLayout, eek_xkb_layout, EEK_TYPE_LAYOUT,
 | 
			
		||||
                         G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE,
 | 
			
		||||
                                                initable_iface_init));
 | 
			
		||||
 | 
			
		||||
#define EEK_XKB_LAYOUT_GET_PRIVATE(obj)                                  \
 | 
			
		||||
    (G_TYPE_INSTANCE_GET_PRIVATE ((obj), EEK_TYPE_XKB_LAYOUT, EekXkbLayoutPrivate))
 | 
			
		||||
 | 
			
		||||
enum {
 | 
			
		||||
    PROP_0,
 | 
			
		||||
    PROP_DISPLAY,
 | 
			
		||||
    PROP_KEYCODES,
 | 
			
		||||
    PROP_GEOMETRY,
 | 
			
		||||
    PROP_SYMBOLS,
 | 
			
		||||
    PROP_LAST
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct _EekXkbLayoutPrivate
 | 
			
		||||
typedef struct _EekXkbLayoutPrivate
 | 
			
		||||
{
 | 
			
		||||
    /* Configuration names that should synch'ed to the symbolic names
 | 
			
		||||
       in priv->xkb->names.  Since we use GLib's memory allocator,
 | 
			
		||||
@ -81,27 +75,32 @@ struct _EekXkbLayoutPrivate
 | 
			
		||||
 | 
			
		||||
    gint scale_numerator;
 | 
			
		||||
    gint scale_denominator;
 | 
			
		||||
};
 | 
			
		||||
} EekXkbLayoutPrivate;
 | 
			
		||||
 | 
			
		||||
static guint
 | 
			
		||||
find_keycode (EekXkbLayout *layout, gchar *key_name);
 | 
			
		||||
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 void
 | 
			
		||||
get_keyboard (EekXkbLayout *layout);
 | 
			
		||||
static guint    find_keycode             (EekXkbLayout *layout,
 | 
			
		||||
                                          gchar        *key_name);
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
get_names (EekXkbLayout *layout);
 | 
			
		||||
static gboolean get_keyboard_from_server (EekXkbLayout *layout,
 | 
			
		||||
                                          GError      **error);
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
setup_scaling (EekXkbLayout *layout,
 | 
			
		||||
               gdouble       width,
 | 
			
		||||
               gdouble       height);
 | 
			
		||||
static gboolean get_names_from_server    (EekXkbLayout *layout,
 | 
			
		||||
                                          GError      **error);
 | 
			
		||||
 | 
			
		||||
static void     setup_scaling            (EekXkbLayout *layout,
 | 
			
		||||
                                          gdouble       width,
 | 
			
		||||
                                          gdouble       height);
 | 
			
		||||
 | 
			
		||||
G_INLINE_FUNC gint
 | 
			
		||||
xkb_to_pixmap_coord (EekXkbLayout *layout,
 | 
			
		||||
                     gint          n)
 | 
			
		||||
{
 | 
			
		||||
    EekXkbLayoutPrivate *priv = layout->priv;
 | 
			
		||||
    EekXkbLayoutPrivate *priv = eek_xkb_layout_get_instance_private (layout);
 | 
			
		||||
    return n * priv->scale_numerator / priv->scale_denominator;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -109,7 +108,7 @@ G_INLINE_FUNC gdouble
 | 
			
		||||
xkb_to_pixmap_double (EekXkbLayout *layout,
 | 
			
		||||
                     gdouble       d)
 | 
			
		||||
{
 | 
			
		||||
    EekXkbLayoutPrivate *priv = layout->priv;
 | 
			
		||||
    EekXkbLayoutPrivate *priv = eek_xkb_layout_get_instance_private (layout);
 | 
			
		||||
    return d * priv->scale_numerator / priv->scale_denominator;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -127,7 +126,7 @@ create_key (EekXkbLayout *layout,
 | 
			
		||||
    XkbBoundsRec *xkbbounds;
 | 
			
		||||
    XkbShapeRec *xkbshape;
 | 
			
		||||
    XkbOutlineRec *xkboutline;
 | 
			
		||||
    EekXkbLayoutPrivate *priv = layout->priv;
 | 
			
		||||
    EekXkbLayoutPrivate *priv = eek_xkb_layout_get_instance_private (layout);
 | 
			
		||||
    EekKey *key;
 | 
			
		||||
    EekBounds bounds;
 | 
			
		||||
    EekSymbolMatrix *matrix = NULL;
 | 
			
		||||
@ -149,7 +148,8 @@ create_key (EekXkbLayout *layout,
 | 
			
		||||
            xkbshape->primary;
 | 
			
		||||
 | 
			
		||||
        outline = g_slice_new (EekOutline);
 | 
			
		||||
        outline->corner_radius = xkb_to_pixmap_coord(layout, xkboutline->corner_radius);
 | 
			
		||||
        outline->corner_radius = xkb_to_pixmap_coord(layout,
 | 
			
		||||
                                                     xkboutline->corner_radius);
 | 
			
		||||
 | 
			
		||||
        if (xkboutline->num_points <= 2) { /* rectangular */
 | 
			
		||||
            gdouble x1, y1, x2, y2;
 | 
			
		||||
@ -236,7 +236,7 @@ create_section (EekXkbLayout  *layout,
 | 
			
		||||
                XkbSectionRec *xkbsection)
 | 
			
		||||
{
 | 
			
		||||
    XkbGeometryRec *xkbgeometry;
 | 
			
		||||
    EekXkbLayoutPrivate *priv;
 | 
			
		||||
    EekXkbLayoutPrivate *priv = eek_xkb_layout_get_instance_private (layout);
 | 
			
		||||
    EekSection *section;
 | 
			
		||||
    EekBounds bounds;
 | 
			
		||||
    gchar *name;
 | 
			
		||||
@ -248,7 +248,6 @@ create_section (EekXkbLayout  *layout,
 | 
			
		||||
    bounds.width = xkb_to_pixmap_coord(layout, xkbsection->width);
 | 
			
		||||
    bounds.height = xkb_to_pixmap_coord(layout, xkbsection->height);
 | 
			
		||||
 | 
			
		||||
    priv = layout->priv;
 | 
			
		||||
    xkbgeometry = priv->xkb->geom;
 | 
			
		||||
    section = eek_keyboard_create_section (keyboard);
 | 
			
		||||
    name = XGetAtomName (priv->display, xkbsection->name);
 | 
			
		||||
@ -292,7 +291,7 @@ create_section (EekXkbLayout  *layout,
 | 
			
		||||
static void
 | 
			
		||||
create_keyboard (EekXkbLayout *layout, EekKeyboard *keyboard)
 | 
			
		||||
{
 | 
			
		||||
    EekXkbLayoutPrivate *priv = layout->priv;
 | 
			
		||||
    EekXkbLayoutPrivate *priv = eek_xkb_layout_get_instance_private (layout);
 | 
			
		||||
    XkbGeometryRec *xkbgeometry;
 | 
			
		||||
    EekBounds bounds;
 | 
			
		||||
    gint i;
 | 
			
		||||
@ -319,21 +318,25 @@ create_keyboard (EekXkbLayout *layout, EekKeyboard *keyboard)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static EekKeyboard *
 | 
			
		||||
eek_xkb_layout_real_create_keyboard (EekLayout *self,
 | 
			
		||||
eek_xkb_layout_real_create_keyboard (EekboardContextService *manager,
 | 
			
		||||
                                     EekLayout *self,
 | 
			
		||||
                                     gdouble    initial_width,
 | 
			
		||||
                                     gdouble    initial_height)
 | 
			
		||||
{
 | 
			
		||||
    EekXkbLayoutPrivate *priv = EEK_XKB_LAYOUT_GET_PRIVATE (self);
 | 
			
		||||
    EekBounds bounds;
 | 
			
		||||
    EekKeyboard *keyboard;
 | 
			
		||||
    EekKeyboard *keyboard = g_object_new (EEK_TYPE_KEYBOARD, "layout", self, NULL);
 | 
			
		||||
    keyboard->manager = manager;
 | 
			
		||||
 | 
			
		||||
    keyboard = g_object_new (EEK_TYPE_KEYBOARD, "layout", self, NULL);
 | 
			
		||||
    bounds.x = bounds.y = 0.0;
 | 
			
		||||
    bounds.width = initial_width;
 | 
			
		||||
    bounds.height = initial_height;
 | 
			
		||||
    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));
 | 
			
		||||
@ -354,7 +357,8 @@ eek_xkb_layout_real_create_keyboard (EekLayout *self,
 | 
			
		||||
static void
 | 
			
		||||
eek_xkb_layout_finalize (GObject *object)
 | 
			
		||||
{
 | 
			
		||||
    EekXkbLayoutPrivate *priv = EEK_XKB_LAYOUT_GET_PRIVATE (object);
 | 
			
		||||
    EekXkbLayoutPrivate *priv = eek_xkb_layout_get_instance_private (
 | 
			
		||||
		    EEK_XKB_LAYOUT (object));
 | 
			
		||||
 | 
			
		||||
    g_free (priv->names.keycodes);
 | 
			
		||||
    g_free (priv->names.geometry);
 | 
			
		||||
@ -370,23 +374,11 @@ eek_xkb_layout_set_property (GObject      *object,
 | 
			
		||||
                             GParamSpec   *pspec)
 | 
			
		||||
{
 | 
			
		||||
    EekXkbLayout *layout = EEK_XKB_LAYOUT (object);
 | 
			
		||||
    const gchar *name;
 | 
			
		||||
    EekXkbLayoutPrivate *priv = eek_xkb_layout_get_instance_private (layout);
 | 
			
		||||
 | 
			
		||||
    switch (prop_id) {
 | 
			
		||||
    case PROP_DISPLAY:
 | 
			
		||||
        layout->priv->display = g_value_get_pointer (value);
 | 
			
		||||
        break;
 | 
			
		||||
    case PROP_KEYCODES:
 | 
			
		||||
        name = g_value_get_string (value);
 | 
			
		||||
        eek_xkb_layout_set_keycodes (EEK_XKB_LAYOUT(object), name);
 | 
			
		||||
        break;
 | 
			
		||||
    case PROP_GEOMETRY:
 | 
			
		||||
        name = g_value_get_string (value);
 | 
			
		||||
        eek_xkb_layout_set_geometry (EEK_XKB_LAYOUT(object), name);
 | 
			
		||||
        break;
 | 
			
		||||
    case PROP_SYMBOLS:
 | 
			
		||||
        name = g_value_get_string (value);
 | 
			
		||||
        eek_xkb_layout_set_symbols (EEK_XKB_LAYOUT(object), name);
 | 
			
		||||
        priv->display = g_value_get_pointer (value);
 | 
			
		||||
        break;
 | 
			
		||||
    default:
 | 
			
		||||
        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 | 
			
		||||
@ -401,23 +393,11 @@ eek_xkb_layout_get_property (GObject    *object,
 | 
			
		||||
                             GParamSpec *pspec)
 | 
			
		||||
{
 | 
			
		||||
    EekXkbLayout *layout = EEK_XKB_LAYOUT (object);
 | 
			
		||||
    const gchar *name;
 | 
			
		||||
    EekXkbLayoutPrivate *priv = eek_xkb_layout_get_instance_private (layout);
 | 
			
		||||
 | 
			
		||||
    switch (prop_id) {
 | 
			
		||||
    case PROP_DISPLAY:
 | 
			
		||||
        g_value_set_pointer (value, layout->priv->display);
 | 
			
		||||
        break;
 | 
			
		||||
    case PROP_KEYCODES:
 | 
			
		||||
        name = eek_xkb_layout_get_keycodes (EEK_XKB_LAYOUT(object));
 | 
			
		||||
        g_value_set_string (value, name);
 | 
			
		||||
        break;
 | 
			
		||||
    case PROP_GEOMETRY:
 | 
			
		||||
        name = eek_xkb_layout_get_geometry (EEK_XKB_LAYOUT(object));
 | 
			
		||||
        g_value_set_string (value, name);
 | 
			
		||||
        break;
 | 
			
		||||
    case PROP_SYMBOLS:
 | 
			
		||||
        name = eek_xkb_layout_get_symbols (EEK_XKB_LAYOUT(object));
 | 
			
		||||
        g_value_set_string (value, name);
 | 
			
		||||
        g_value_set_pointer (value, priv->display);
 | 
			
		||||
        break;
 | 
			
		||||
    default:
 | 
			
		||||
        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 | 
			
		||||
@ -432,8 +412,6 @@ eek_xkb_layout_class_init (EekXkbLayoutClass *klass)
 | 
			
		||||
    GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
 | 
			
		||||
    GParamSpec *pspec;
 | 
			
		||||
 | 
			
		||||
    g_type_class_add_private (gobject_class, sizeof (EekXkbLayoutPrivate));
 | 
			
		||||
 | 
			
		||||
    layout_class->create_keyboard = eek_xkb_layout_real_create_keyboard;
 | 
			
		||||
 | 
			
		||||
    gobject_class->finalize = eek_xkb_layout_finalize;
 | 
			
		||||
@ -446,39 +424,19 @@ eek_xkb_layout_class_init (EekXkbLayoutClass *klass)
 | 
			
		||||
                                  G_PARAM_READWRITE |
 | 
			
		||||
                                  G_PARAM_CONSTRUCT_ONLY);
 | 
			
		||||
    g_object_class_install_property (gobject_class, PROP_DISPLAY, pspec);
 | 
			
		||||
 | 
			
		||||
    pspec = g_param_spec_string ("keycodes",
 | 
			
		||||
				 "Keycodes",
 | 
			
		||||
				 "XKB keycodes component name",
 | 
			
		||||
				 NULL,
 | 
			
		||||
				 G_PARAM_READWRITE);
 | 
			
		||||
    g_object_class_install_property (gobject_class, PROP_KEYCODES, pspec);
 | 
			
		||||
 | 
			
		||||
    pspec = g_param_spec_string ("geometry",
 | 
			
		||||
                                 "Geometry",
 | 
			
		||||
                                 "XKB geometry component name",
 | 
			
		||||
                                 NULL,
 | 
			
		||||
                                 G_PARAM_READWRITE);
 | 
			
		||||
    g_object_class_install_property (gobject_class, PROP_GEOMETRY, pspec);
 | 
			
		||||
 | 
			
		||||
    pspec = g_param_spec_string ("symbols",
 | 
			
		||||
                                 "Symbols",
 | 
			
		||||
                                 "XKB symbols component name",
 | 
			
		||||
                                 NULL,
 | 
			
		||||
                                 G_PARAM_READWRITE);
 | 
			
		||||
    g_object_class_install_property (gobject_class, PROP_SYMBOLS, pspec);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
eek_xkb_layout_init (EekXkbLayout *self)
 | 
			
		||||
{
 | 
			
		||||
    self->priv = EEK_XKB_LAYOUT_GET_PRIVATE (self);
 | 
			
		||||
    /* void */
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
get_names (EekXkbLayout *layout)
 | 
			
		||||
static gboolean
 | 
			
		||||
get_names_from_server (EekXkbLayout *layout,
 | 
			
		||||
                       GError      **error)
 | 
			
		||||
{
 | 
			
		||||
    EekXkbLayoutPrivate *priv = layout->priv;
 | 
			
		||||
    EekXkbLayoutPrivate *priv = eek_xkb_layout_get_instance_private (layout);
 | 
			
		||||
    gchar *name;
 | 
			
		||||
 | 
			
		||||
    XkbGetNames (priv->display, XkbAllNamesMask, priv->xkb);
 | 
			
		||||
@ -524,6 +482,8 @@ get_names (EekXkbLayout *layout)
 | 
			
		||||
            XFree (name);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@ -546,252 +506,78 @@ eek_xkb_layout_new (Display *display,
 | 
			
		||||
 * 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 any of the component names changed, %FALSE otherwise
 | 
			
		||||
 * Returns: %TRUE if the component names are successfully set, %FALSE otherwise
 | 
			
		||||
 */
 | 
			
		||||
gboolean
 | 
			
		||||
eek_xkb_layout_set_names (EekXkbLayout *layout, XkbComponentNamesRec *names)
 | 
			
		||||
eek_xkb_layout_set_names (EekXkbLayout         *layout,
 | 
			
		||||
                          XkbComponentNamesRec *names,
 | 
			
		||||
                          GError              **error)
 | 
			
		||||
{
 | 
			
		||||
    EekXkbLayoutPrivate *priv = EEK_XKB_LAYOUT_GET_PRIVATE (layout);
 | 
			
		||||
    gboolean retval;
 | 
			
		||||
 | 
			
		||||
    g_return_val_if_fail (priv, FALSE);
 | 
			
		||||
    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);
 | 
			
		||||
        retval = TRUE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (g_strcmp0 (names->geometry, priv->names.geometry)) {
 | 
			
		||||
        g_free (priv->names.geometry);
 | 
			
		||||
        priv->names.geometry = g_strdup (names->geometry);
 | 
			
		||||
        retval = TRUE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (g_strcmp0 (names->symbols, priv->names.symbols)) {
 | 
			
		||||
        g_free (priv->names.symbols);
 | 
			
		||||
        priv->names.symbols = g_strdup (names->symbols);
 | 
			
		||||
        retval = TRUE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    get_keyboard (layout);
 | 
			
		||||
    g_assert (priv->xkb);
 | 
			
		||||
 | 
			
		||||
    return retval;
 | 
			
		||||
    return get_keyboard_from_server (layout, error);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eek_xkb_layout_set_names_full:
 | 
			
		||||
 * @layout: an #EekXkbLayout
 | 
			
		||||
 * @Varargs: pairs of component name and value, terminated by NULL.
 | 
			
		||||
 *
 | 
			
		||||
 * Set the XKB component names to @layout.  This function is merely a
 | 
			
		||||
 * wrapper around eek_xkb_layout_set_names() to avoid passing a
 | 
			
		||||
 * pointer of XkbComponentNamesRec, which is not currently available
 | 
			
		||||
 * in the gobject-introspection repository.
 | 
			
		||||
 *
 | 
			
		||||
 * Available component names are: keymap, keycodes, types, compat,
 | 
			
		||||
 * symbols, geometry.
 | 
			
		||||
 *
 | 
			
		||||
 * Returns: %TRUE if the component name is successfully set, %FALSE otherwise
 | 
			
		||||
 * Since: 0.0.2
 | 
			
		||||
 */
 | 
			
		||||
gboolean
 | 
			
		||||
eek_xkb_layout_set_names_full (EekXkbLayout *layout,
 | 
			
		||||
                               ...)
 | 
			
		||||
static gboolean
 | 
			
		||||
get_keyboard_from_server (EekXkbLayout *layout,
 | 
			
		||||
                          GError      **error)
 | 
			
		||||
{
 | 
			
		||||
    va_list var_args;
 | 
			
		||||
    gboolean retval;
 | 
			
		||||
    EekXkbLayoutPrivate *priv = eek_xkb_layout_get_instance_private (layout);
 | 
			
		||||
 | 
			
		||||
    va_start (var_args, layout);
 | 
			
		||||
    retval = eek_xkb_layout_set_names_full_valist (layout, var_args);
 | 
			
		||||
    va_end (var_args);
 | 
			
		||||
 | 
			
		||||
    return retval;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eek_xkb_layout_set_names_full_valist:
 | 
			
		||||
 * @layout: an #EekXkbLayout
 | 
			
		||||
 * @var_args: <type>va_list</type> of pairs of component name and value.
 | 
			
		||||
 *
 | 
			
		||||
 * See eek_xkb_layout_set_names_full(), this version takes a
 | 
			
		||||
 * <type>va_list</type> for language bindings to use.
 | 
			
		||||
 *
 | 
			
		||||
 * Since: 0.0.5
 | 
			
		||||
 */
 | 
			
		||||
gboolean
 | 
			
		||||
eek_xkb_layout_set_names_full_valist (EekXkbLayout *layout,
 | 
			
		||||
                                      va_list       var_args)
 | 
			
		||||
{
 | 
			
		||||
    XkbComponentNamesRec names;
 | 
			
		||||
    gchar *name, *value;
 | 
			
		||||
 | 
			
		||||
    memset (&names, 0, sizeof names);
 | 
			
		||||
    name = va_arg (var_args, gchar *);
 | 
			
		||||
    while (name) {
 | 
			
		||||
        value = va_arg (var_args, gchar *);
 | 
			
		||||
        if (g_strcmp0 (name, "keymap") == 0)
 | 
			
		||||
            names.keymap = (char *)value;
 | 
			
		||||
        else if (g_strcmp0 (name, "keycodes") == 0)
 | 
			
		||||
            names.keycodes = (char *)value;
 | 
			
		||||
        else if (g_strcmp0 (name, "types") == 0)
 | 
			
		||||
            names.types = (char *)value;
 | 
			
		||||
        else if (g_strcmp0 (name, "compat") == 0)
 | 
			
		||||
            names.compat = (char *)value;
 | 
			
		||||
        else if (g_strcmp0 (name, "symbols") == 0)
 | 
			
		||||
            names.symbols = (char *)value;
 | 
			
		||||
        else if (g_strcmp0 (name, "geometry") == 0)
 | 
			
		||||
            names.geometry = (char *)value;
 | 
			
		||||
        name = va_arg (var_args, gchar *);
 | 
			
		||||
    if (priv->xkb) {
 | 
			
		||||
        XkbFreeKeyboard (priv->xkb, 0, True);
 | 
			
		||||
        priv->xkb = NULL;
 | 
			
		||||
    }
 | 
			
		||||
    return eek_xkb_layout_set_names (layout, &names);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eek_xkb_layout_set_keycodes:
 | 
			
		||||
 * @layout: an #EekXkbLayout
 | 
			
		||||
 * @keycodes: component name for keycodes
 | 
			
		||||
 *
 | 
			
		||||
 * Set the keycodes component (in the XKB terminology).
 | 
			
		||||
 * Returns: %TRUE if the component name is successfully set, %FALSE otherwise
 | 
			
		||||
 */
 | 
			
		||||
gboolean
 | 
			
		||||
eek_xkb_layout_set_keycodes (EekXkbLayout *layout, const gchar *keycodes)
 | 
			
		||||
{
 | 
			
		||||
    EekXkbLayoutPrivate *priv = EEK_XKB_LAYOUT_GET_PRIVATE (layout);
 | 
			
		||||
    XkbComponentNamesRec names;
 | 
			
		||||
 | 
			
		||||
    g_return_val_if_fail (priv, FALSE);
 | 
			
		||||
    memcpy (&names, &priv->names, sizeof names);
 | 
			
		||||
    names.keycodes = (gchar *)keycodes;
 | 
			
		||||
    return eek_xkb_layout_set_names (layout, &names);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eek_xkb_layout_set_geometry:
 | 
			
		||||
 * @layout: an #EekXkbLayout
 | 
			
		||||
 * @geometry: component name for geometry
 | 
			
		||||
 *
 | 
			
		||||
 * Returns: %TRUE if the component name is successfully set, %FALSE otherwise
 | 
			
		||||
 */
 | 
			
		||||
gboolean
 | 
			
		||||
eek_xkb_layout_set_geometry (EekXkbLayout *layout, const gchar *geometry)
 | 
			
		||||
{
 | 
			
		||||
    EekXkbLayoutPrivate *priv = EEK_XKB_LAYOUT_GET_PRIVATE (layout);
 | 
			
		||||
    XkbComponentNamesRec names;
 | 
			
		||||
 | 
			
		||||
    g_return_val_if_fail (priv, FALSE);
 | 
			
		||||
    memcpy (&names, &priv->names, sizeof names);
 | 
			
		||||
    names.geometry = (gchar *)geometry;
 | 
			
		||||
    return eek_xkb_layout_set_names (layout, &names);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eek_xkb_layout_set_symbols:
 | 
			
		||||
 * @layout: an #EekXkbLayout
 | 
			
		||||
 * @symbols: component name for symbols
 | 
			
		||||
 *
 | 
			
		||||
 * Set the symbols component (in the XKB terminology).
 | 
			
		||||
 * Returns: %TRUE if the component name is successfully set, %FALSE otherwise
 | 
			
		||||
 */
 | 
			
		||||
gboolean
 | 
			
		||||
eek_xkb_layout_set_symbols (EekXkbLayout *layout, const gchar *symbols)
 | 
			
		||||
{
 | 
			
		||||
    EekXkbLayoutPrivate *priv = EEK_XKB_LAYOUT_GET_PRIVATE (layout);
 | 
			
		||||
    XkbComponentNamesRec names;
 | 
			
		||||
 | 
			
		||||
    g_return_val_if_fail (priv, FALSE);
 | 
			
		||||
    memcpy (&names, &priv->names, sizeof names);
 | 
			
		||||
    names.symbols = (gchar *)symbols;
 | 
			
		||||
    return eek_xkb_layout_set_names (layout, &names);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eek_xkb_layout_get_keycodes:
 | 
			
		||||
 * @layout: an #EekXkbLayout
 | 
			
		||||
 *
 | 
			
		||||
 * Get the keycodes component name (in the XKB terminology).
 | 
			
		||||
 */
 | 
			
		||||
G_CONST_RETURN gchar *
 | 
			
		||||
eek_xkb_layout_get_keycodes (EekXkbLayout *layout)
 | 
			
		||||
{
 | 
			
		||||
    EekXkbLayoutPrivate *priv = EEK_XKB_LAYOUT_GET_PRIVATE (layout);
 | 
			
		||||
 | 
			
		||||
    g_return_val_if_fail (priv, NULL);
 | 
			
		||||
    return priv->names.keycodes;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eek_xkb_layout_get_geometry:
 | 
			
		||||
 * @layout: an #EekXkbLayout
 | 
			
		||||
 *
 | 
			
		||||
 * Get the geometry component name (in the XKB terminology).
 | 
			
		||||
 */
 | 
			
		||||
G_CONST_RETURN gchar *
 | 
			
		||||
eek_xkb_layout_get_geometry (EekXkbLayout *layout)
 | 
			
		||||
{
 | 
			
		||||
    EekXkbLayoutPrivate *priv = EEK_XKB_LAYOUT_GET_PRIVATE (layout);
 | 
			
		||||
 | 
			
		||||
    g_return_val_if_fail (priv, NULL);
 | 
			
		||||
    return priv->names.geometry;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eek_xkb_layout_get_symbols:
 | 
			
		||||
 * @layout: an #EekXkbLayout
 | 
			
		||||
 *
 | 
			
		||||
 * Get the symbols component name (in the XKB terminology).
 | 
			
		||||
 */
 | 
			
		||||
G_CONST_RETURN gchar *
 | 
			
		||||
eek_xkb_layout_get_symbols (EekXkbLayout *layout)
 | 
			
		||||
{
 | 
			
		||||
    EekXkbLayoutPrivate *priv = EEK_XKB_LAYOUT_GET_PRIVATE (layout);
 | 
			
		||||
 | 
			
		||||
    g_return_val_if_fail (priv, NULL);
 | 
			
		||||
    return priv->names.symbols;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
get_keyboard (EekXkbLayout *layout)
 | 
			
		||||
{
 | 
			
		||||
    EekXkbLayoutPrivate *priv = layout->priv;
 | 
			
		||||
 | 
			
		||||
    if (priv->xkb)
 | 
			
		||||
        XkbFreeKeyboard (priv->xkb, 0, TRUE);	/* free_all = TRUE */
 | 
			
		||||
    priv->xkb = NULL;
 | 
			
		||||
 | 
			
		||||
    if (priv->names.keycodes &&
 | 
			
		||||
        priv->names.geometry &&
 | 
			
		||||
        priv->names.symbols) {
 | 
			
		||||
        priv->xkb = XkbGetKeyboardByName (priv->display, XkbUseCoreKbd,
 | 
			
		||||
                                          &priv->names, 0,
 | 
			
		||||
                                          XkbGBN_GeometryMask |
 | 
			
		||||
                                          XkbGBN_KeyNamesMask |
 | 
			
		||||
                                          XkbGBN_OtherNamesMask |
 | 
			
		||||
                                          XkbGBN_ClientSymbolsMask |
 | 
			
		||||
                                          XkbGBN_IndicatorMapMask, FALSE);
 | 
			
		||||
    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,
 | 
			
		||||
                                    XkbGBN_GeometryMask |
 | 
			
		||||
                                    XkbGBN_KeyNamesMask |
 | 
			
		||||
                                    XkbGBN_OtherNamesMask |
 | 
			
		||||
                                    XkbGBN_SymbolsMask |
 | 
			
		||||
                                    XkbGBN_IndicatorMapMask,
 | 
			
		||||
                                    XKB_COMPONENT_MASK,
 | 
			
		||||
                                    XkbUseCoreKbd);
 | 
			
		||||
        get_names (layout);
 | 
			
		||||
        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;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -805,16 +591,11 @@ find_keycode (EekXkbLayout *layout, gchar *key_name)
 | 
			
		||||
    XkbKeyAliasPtr palias;
 | 
			
		||||
    guint is_name_matched;
 | 
			
		||||
    gchar *src, *dst;
 | 
			
		||||
    EekXkbLayoutPrivate *priv = layout->priv;
 | 
			
		||||
    EekXkbLayoutPrivate *priv = eek_xkb_layout_get_instance_private (layout);
 | 
			
		||||
 | 
			
		||||
    if (!priv->xkb)
 | 
			
		||||
        return EEK_INVALID_KEYCODE;
 | 
			
		||||
 | 
			
		||||
#ifdef KBDRAW_DEBUG
 | 
			
		||||
    printf ("    looking for keycode for (%c%c%c%c)\n",
 | 
			
		||||
            key_name[0], key_name[1], key_name[2], key_name[3]);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    pkey = priv->xkb->names->keys + priv->xkb->min_key_code;
 | 
			
		||||
    for (keycode = priv->xkb->min_key_code;
 | 
			
		||||
         keycode <= priv->xkb->max_key_code; keycode++) {
 | 
			
		||||
@ -829,12 +610,8 @@ find_keycode (EekXkbLayout *layout, gchar *key_name)
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        if (is_name_matched) {
 | 
			
		||||
#ifdef KBDRAW_DEBUG
 | 
			
		||||
            printf ("      found keycode %u\n", keycode);
 | 
			
		||||
#endif
 | 
			
		||||
        if (is_name_matched)
 | 
			
		||||
            return keycode;
 | 
			
		||||
        }
 | 
			
		||||
        pkey++;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -854,9 +631,6 @@ find_keycode (EekXkbLayout *layout, gchar *key_name)
 | 
			
		||||
 | 
			
		||||
        if (is_name_matched) {
 | 
			
		||||
            keycode = find_keycode (layout, palias->real);
 | 
			
		||||
#ifdef KBDRAW_DEBUG
 | 
			
		||||
            printf ("found alias keycode %u\n", keycode);
 | 
			
		||||
#endif
 | 
			
		||||
            return keycode;
 | 
			
		||||
        }
 | 
			
		||||
        palias++;
 | 
			
		||||
@ -870,7 +644,7 @@ setup_scaling (EekXkbLayout *layout,
 | 
			
		||||
               gdouble       width,
 | 
			
		||||
               gdouble       height)
 | 
			
		||||
{
 | 
			
		||||
    EekXkbLayoutPrivate *priv = layout->priv;
 | 
			
		||||
    EekXkbLayoutPrivate *priv = eek_xkb_layout_get_instance_private (layout);
 | 
			
		||||
 | 
			
		||||
    g_return_if_fail (priv->xkb);
 | 
			
		||||
 | 
			
		||||
@ -894,34 +668,11 @@ initable_init (GInitable    *initable,
 | 
			
		||||
{
 | 
			
		||||
    EekXkbLayout *layout = EEK_XKB_LAYOUT (initable);
 | 
			
		||||
 | 
			
		||||
    /* XXX: XkbClientMapMask | XkbIndicatorMapMask | XkbNamesMask |
 | 
			
		||||
       XkbGeometryMask */
 | 
			
		||||
    layout->priv->xkb = XkbGetKeyboard (layout->priv->display,
 | 
			
		||||
                                        XkbGBN_GeometryMask |
 | 
			
		||||
                                        XkbGBN_KeyNamesMask |
 | 
			
		||||
                                        XkbGBN_OtherNamesMask |
 | 
			
		||||
                                        XkbGBN_SymbolsMask |
 | 
			
		||||
                                        XkbGBN_IndicatorMapMask,
 | 
			
		||||
                                        XkbUseCoreKbd);
 | 
			
		||||
 | 
			
		||||
    if (layout->priv->xkb == NULL) {
 | 
			
		||||
        g_set_error (error,
 | 
			
		||||
                     EEK_ERROR,
 | 
			
		||||
                     EEK_ERROR_LAYOUT_ERROR,
 | 
			
		||||
                     "can't get initial XKB keyboard configuration");
 | 
			
		||||
    if (!get_keyboard_from_server (layout, error))
 | 
			
		||||
        return FALSE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    get_names (layout);
 | 
			
		||||
    get_keyboard (layout);
 | 
			
		||||
    
 | 
			
		||||
    if (layout->priv->xkb == NULL) {
 | 
			
		||||
        g_set_error (error,
 | 
			
		||||
                     EEK_ERROR,
 | 
			
		||||
                     EEK_ERROR_LAYOUT_ERROR,
 | 
			
		||||
                     "can't get XKB keyboard configuration");
 | 
			
		||||
    if (!get_names_from_server (layout, error))
 | 
			
		||||
        return FALSE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -25,30 +25,13 @@
 | 
			
		||||
#ifndef EEK_XKB_LAYOUT_H
 | 
			
		||||
#define EEK_XKB_LAYOUT_H 1
 | 
			
		||||
 | 
			
		||||
#include <X11/Xlib.h>
 | 
			
		||||
#include <X11/XKBlib.h>
 | 
			
		||||
#include "eek-layout.h"
 | 
			
		||||
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
#define EEK_TYPE_XKB_LAYOUT (eek_xkb_layout_get_type())
 | 
			
		||||
#define EEK_XKB_LAYOUT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EEK_TYPE_XKB_LAYOUT, EekXkbLayout))
 | 
			
		||||
#define EEK_XKB_LAYOUT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EEK_TYPE_XKB_LAYOUT, EekXkbLayoutClass))
 | 
			
		||||
#define EEK_IS_XKB_LAYOUT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EEK_TYPE_XKB_LAYOUT))
 | 
			
		||||
#define EEK_IS_XKB_LAYOUT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EEK_TYPE_XKB_LAYOUT))
 | 
			
		||||
#define EEK_XKB_LAYOUT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EEK_TYPE_XKB_LAYOUT, EekXkbLayoutClass))
 | 
			
		||||
 | 
			
		||||
typedef struct _EekXkbLayout        EekXkbLayout;
 | 
			
		||||
typedef struct _EekXkbLayoutClass   EekXkbLayoutClass;
 | 
			
		||||
typedef struct _EekXkbLayoutPrivate EekXkbLayoutPrivate;
 | 
			
		||||
 | 
			
		||||
struct _EekXkbLayout
 | 
			
		||||
{
 | 
			
		||||
    /*< private >*/
 | 
			
		||||
    EekLayout parent;
 | 
			
		||||
 | 
			
		||||
    EekXkbLayoutPrivate *priv;
 | 
			
		||||
};
 | 
			
		||||
G_DECLARE_DERIVABLE_TYPE (EekXkbLayout, eek_xkb_layout, EEK, XKB_LAYOUT, EekLayout)
 | 
			
		||||
 | 
			
		||||
struct _EekXkbLayoutClass
 | 
			
		||||
{
 | 
			
		||||
@ -60,29 +43,13 @@ struct _EekXkbLayoutClass
 | 
			
		||||
    gpointer pdummy[24];
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
GType        eek_xkb_layout_get_type       (void) G_GNUC_CONST;
 | 
			
		||||
EekLayout   *eek_xkb_layout_new            (Display              *display,
 | 
			
		||||
                                            GError              **error);
 | 
			
		||||
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);
 | 
			
		||||
 | 
			
		||||
gboolean     eek_xkb_layout_set_names_full (EekXkbLayout         *layout,
 | 
			
		||||
                                            ...);
 | 
			
		||||
gboolean     eek_xkb_layout_set_names_full_valist
 | 
			
		||||
                                           (EekXkbLayout         *layout,
 | 
			
		||||
                                            va_list               var_args);
 | 
			
		||||
                                        
 | 
			
		||||
gboolean     eek_xkb_layout_set_keycodes   (EekXkbLayout         *layout,
 | 
			
		||||
                                            const gchar          *keycodes);
 | 
			
		||||
gboolean     eek_xkb_layout_set_geometry   (EekXkbLayout         *layout,
 | 
			
		||||
                                            const gchar          *geometry);
 | 
			
		||||
gboolean     eek_xkb_layout_set_symbols    (EekXkbLayout         *layout,
 | 
			
		||||
                                            const gchar          *symbols);
 | 
			
		||||
 | 
			
		||||
const gchar *eek_xkb_layout_get_keycodes   (EekXkbLayout         *layout);
 | 
			
		||||
const gchar *eek_xkb_layout_get_geometry   (EekXkbLayout         *layout);
 | 
			
		||||
const gchar *eek_xkb_layout_get_symbols    (EekXkbLayout         *layout);
 | 
			
		||||
gboolean   eek_xkb_layout_set_names (EekXkbLayout         *layout,
 | 
			
		||||
                                     XkbComponentNamesRec *names,
 | 
			
		||||
                                     GError              **error);
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
#endif				/* #ifndef EEK_XKB_LAYOUT_H */
 | 
			
		||||
 | 
			
		||||
@ -42,13 +42,6 @@ static GInitableIface *parent_initable_iface;
 | 
			
		||||
 | 
			
		||||
static void initable_iface_init (GInitableIface *initable_iface);
 | 
			
		||||
 | 
			
		||||
G_DEFINE_TYPE_WITH_CODE (EekXklLayout, eek_xkl_layout, EEK_TYPE_XKB_LAYOUT,
 | 
			
		||||
                         G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE,
 | 
			
		||||
                                                initable_iface_init));
 | 
			
		||||
 | 
			
		||||
#define EEK_XKL_LAYOUT_GET_PRIVATE(obj)                                  \
 | 
			
		||||
    (G_TYPE_INSTANCE_GET_PRIVATE ((obj), EEK_TYPE_XKL_LAYOUT, EekXklLayoutPrivate))
 | 
			
		||||
 | 
			
		||||
enum {
 | 
			
		||||
    PROP_0,
 | 
			
		||||
    PROP_MODEL,
 | 
			
		||||
@ -58,11 +51,17 @@ enum {
 | 
			
		||||
    PROP_LAST
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct _EekXklLayoutPrivate
 | 
			
		||||
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
 | 
			
		||||
@ -83,7 +82,8 @@ static gboolean set_xkb_component_names (EekXklLayout *layout,
 | 
			
		||||
static void
 | 
			
		||||
eek_xkl_layout_dispose (GObject *object)
 | 
			
		||||
{
 | 
			
		||||
    EekXklLayoutPrivate *priv = EEK_XKL_LAYOUT_GET_PRIVATE (object);
 | 
			
		||||
    EekXklLayoutPrivate *priv = eek_xkl_layout_get_instance_private (
 | 
			
		||||
		    EEK_XKL_LAYOUT (object));
 | 
			
		||||
 | 
			
		||||
    if (priv->config) {
 | 
			
		||||
        g_object_unref (priv->config);
 | 
			
		||||
@ -157,8 +157,6 @@ eek_xkl_layout_class_init (EekXklLayoutClass *klass)
 | 
			
		||||
    GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
 | 
			
		||||
    GParamSpec *pspec;
 | 
			
		||||
 | 
			
		||||
    g_type_class_add_private (gobject_class, sizeof (EekXklLayoutPrivate));
 | 
			
		||||
 | 
			
		||||
    gobject_class->dispose = eek_xkl_layout_dispose;
 | 
			
		||||
    gobject_class->set_property = eek_xkl_layout_set_property;
 | 
			
		||||
    gobject_class->get_property = eek_xkl_layout_get_property;
 | 
			
		||||
@ -215,7 +213,7 @@ eek_xkl_layout_class_init (EekXklLayoutClass *klass)
 | 
			
		||||
static void
 | 
			
		||||
eek_xkl_layout_init (EekXklLayout *self)
 | 
			
		||||
{
 | 
			
		||||
    self->priv = EEK_XKL_LAYOUT_GET_PRIVATE (self);
 | 
			
		||||
    /* void */
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@ -266,7 +264,7 @@ gboolean
 | 
			
		||||
eek_xkl_layout_set_config (EekXklLayout *layout,
 | 
			
		||||
                           XklConfigRec *config)
 | 
			
		||||
{
 | 
			
		||||
    EekXklLayoutPrivate *priv = EEK_XKL_LAYOUT_GET_PRIVATE (layout);
 | 
			
		||||
    EekXklLayoutPrivate *priv = eek_xkl_layout_get_instance_private (layout);
 | 
			
		||||
    XklConfigRec *c;
 | 
			
		||||
    gboolean retval;
 | 
			
		||||
 | 
			
		||||
@ -329,7 +327,7 @@ gboolean
 | 
			
		||||
eek_xkl_layout_set_model (EekXklLayout *layout,
 | 
			
		||||
                          const gchar  *model)
 | 
			
		||||
{
 | 
			
		||||
    EekXklLayoutPrivate *priv = EEK_XKL_LAYOUT_GET_PRIVATE (layout);
 | 
			
		||||
    EekXklLayoutPrivate *priv = eek_xkl_layout_get_instance_private (layout);
 | 
			
		||||
    XklConfigRec *config;
 | 
			
		||||
    gboolean retval;
 | 
			
		||||
    
 | 
			
		||||
@ -357,7 +355,7 @@ gboolean
 | 
			
		||||
eek_xkl_layout_set_layouts (EekXklLayout *layout,
 | 
			
		||||
                            gchar       **layouts)
 | 
			
		||||
{
 | 
			
		||||
    EekXklLayoutPrivate *priv = EEK_XKL_LAYOUT_GET_PRIVATE (layout);
 | 
			
		||||
    EekXklLayoutPrivate *priv = eek_xkl_layout_get_instance_private (layout);
 | 
			
		||||
    XklConfigRec *config;
 | 
			
		||||
    gboolean retval;
 | 
			
		||||
 | 
			
		||||
@ -385,7 +383,7 @@ gboolean
 | 
			
		||||
eek_xkl_layout_set_variants (EekXklLayout *layout,
 | 
			
		||||
                             gchar       **variants)
 | 
			
		||||
{
 | 
			
		||||
    EekXklLayoutPrivate *priv = EEK_XKL_LAYOUT_GET_PRIVATE (layout);
 | 
			
		||||
    EekXklLayoutPrivate *priv = eek_xkl_layout_get_instance_private (layout);
 | 
			
		||||
    XklConfigRec *config;
 | 
			
		||||
    gboolean retval;
 | 
			
		||||
 | 
			
		||||
@ -413,7 +411,7 @@ gboolean
 | 
			
		||||
eek_xkl_layout_set_options (EekXklLayout *layout,
 | 
			
		||||
                            gchar       **options)
 | 
			
		||||
{
 | 
			
		||||
    EekXklLayoutPrivate *priv = EEK_XKL_LAYOUT_GET_PRIVATE (layout);
 | 
			
		||||
    EekXklLayoutPrivate *priv = eek_xkl_layout_get_instance_private (layout);
 | 
			
		||||
    XklConfigRec *config;
 | 
			
		||||
    gboolean retval;
 | 
			
		||||
 | 
			
		||||
@ -497,7 +495,7 @@ eek_xkl_layout_disable_option (EekXklLayout *layout,
 | 
			
		||||
gchar *
 | 
			
		||||
eek_xkl_layout_get_model (EekXklLayout *layout)
 | 
			
		||||
{
 | 
			
		||||
    EekXklLayoutPrivate *priv = EEK_XKL_LAYOUT_GET_PRIVATE (layout);
 | 
			
		||||
    EekXklLayoutPrivate *priv = eek_xkl_layout_get_instance_private (layout);
 | 
			
		||||
 | 
			
		||||
    g_return_val_if_fail (priv, NULL);
 | 
			
		||||
    return g_strdup (priv->config->model);
 | 
			
		||||
@ -513,7 +511,7 @@ eek_xkl_layout_get_model (EekXklLayout *layout)
 | 
			
		||||
gchar **
 | 
			
		||||
eek_xkl_layout_get_layouts (EekXklLayout *layout)
 | 
			
		||||
{
 | 
			
		||||
    EekXklLayoutPrivate *priv = EEK_XKL_LAYOUT_GET_PRIVATE (layout);
 | 
			
		||||
    EekXklLayoutPrivate *priv = eek_xkl_layout_get_instance_private (layout);
 | 
			
		||||
 | 
			
		||||
    g_return_val_if_fail (priv, NULL);
 | 
			
		||||
    return g_strdupv (priv->config->layouts);
 | 
			
		||||
@ -529,7 +527,7 @@ eek_xkl_layout_get_layouts (EekXklLayout *layout)
 | 
			
		||||
gchar **
 | 
			
		||||
eek_xkl_layout_get_variants (EekXklLayout *layout)
 | 
			
		||||
{
 | 
			
		||||
    EekXklLayoutPrivate *priv = EEK_XKL_LAYOUT_GET_PRIVATE (layout);
 | 
			
		||||
    EekXklLayoutPrivate *priv = eek_xkl_layout_get_instance_private (layout);
 | 
			
		||||
 | 
			
		||||
    g_return_val_if_fail (priv, NULL);
 | 
			
		||||
    return g_strdupv (priv->config->variants);
 | 
			
		||||
@ -545,7 +543,7 @@ eek_xkl_layout_get_variants (EekXklLayout *layout)
 | 
			
		||||
gchar **
 | 
			
		||||
eek_xkl_layout_get_options (EekXklLayout *layout)
 | 
			
		||||
{
 | 
			
		||||
    EekXklLayoutPrivate *priv = EEK_XKL_LAYOUT_GET_PRIVATE (layout);
 | 
			
		||||
    EekXklLayoutPrivate *priv = eek_xkl_layout_get_instance_private (layout);
 | 
			
		||||
 | 
			
		||||
    g_return_val_if_fail (priv, NULL);
 | 
			
		||||
    return g_strdupv (priv->config->options);
 | 
			
		||||
@ -554,7 +552,7 @@ eek_xkl_layout_get_options (EekXklLayout *layout)
 | 
			
		||||
static gboolean
 | 
			
		||||
set_xkb_component_names (EekXklLayout *layout, XklConfigRec *config)
 | 
			
		||||
{
 | 
			
		||||
    EekXklLayoutPrivate *priv = layout->priv;
 | 
			
		||||
    EekXklLayoutPrivate *priv = eek_xkl_layout_get_instance_private (layout);
 | 
			
		||||
    XkbComponentNamesRec names;
 | 
			
		||||
    gboolean retval = FALSE;
 | 
			
		||||
 | 
			
		||||
@ -589,7 +587,12 @@ set_xkb_component_names (EekXklLayout *layout, XklConfigRec *config)
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    if (xkl_xkb_config_native_prepare (priv->engine, config, &names)) {
 | 
			
		||||
        retval = eek_xkb_layout_set_names (EEK_XKB_LAYOUT(layout), &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;
 | 
			
		||||
@ -623,21 +626,22 @@ initable_init (GInitable    *initable,
 | 
			
		||||
               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;
 | 
			
		||||
 | 
			
		||||
    layout->priv->config = xkl_config_rec_new ();
 | 
			
		||||
    priv->config = xkl_config_rec_new ();
 | 
			
		||||
 | 
			
		||||
    g_object_get (G_OBJECT (initable),
 | 
			
		||||
                  "display", &display,
 | 
			
		||||
                  NULL);
 | 
			
		||||
 | 
			
		||||
    layout->priv->engine = xkl_engine_get_instance (display);
 | 
			
		||||
    priv->engine = xkl_engine_get_instance (display);
 | 
			
		||||
 | 
			
		||||
    if (!xkl_config_rec_get_from_server (layout->priv->config,
 | 
			
		||||
                                         layout->priv->engine)) {
 | 
			
		||||
    if (!xkl_config_rec_get_from_server (priv->config,
 | 
			
		||||
                                         priv->engine)) {
 | 
			
		||||
        g_set_error (error,
 | 
			
		||||
                     EEK_ERROR,
 | 
			
		||||
                     EEK_ERROR_LAYOUT_ERROR,
 | 
			
		||||
@ -645,7 +649,8 @@ initable_init (GInitable    *initable,
 | 
			
		||||
        return FALSE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return set_xkb_component_names (layout, layout->priv->config);
 | 
			
		||||
    set_xkb_component_names (layout, priv->config);
 | 
			
		||||
    return TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
 | 
			
		||||
@ -31,23 +31,7 @@
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
#define EEK_TYPE_XKL_LAYOUT (eek_xkl_layout_get_type())
 | 
			
		||||
#define EEK_XKL_LAYOUT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EEK_TYPE_XKL_LAYOUT, EekXklLayout))
 | 
			
		||||
#define EEK_XKL_LAYOUT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EEK_TYPE_XKL_LAYOUT, EekXklLayoutClass))
 | 
			
		||||
#define EEK_IS_XKL_LAYOUT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EEK_TYPE_XKL_LAYOUT))
 | 
			
		||||
#define EEK_IS_XKL_LAYOUT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EEK_TYPE_XKL_LAYOUT))
 | 
			
		||||
#define EEK_XKL_LAYOUT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EEK_TYPE_XKL_LAYOUT, EekXklLayoutClass))
 | 
			
		||||
 | 
			
		||||
typedef struct _EekXklLayout        EekXklLayout;
 | 
			
		||||
typedef struct _EekXklLayoutClass   EekXklLayoutClass;
 | 
			
		||||
typedef struct _EekXklLayoutPrivate EekXklLayoutPrivate;
 | 
			
		||||
 | 
			
		||||
struct _EekXklLayout
 | 
			
		||||
{
 | 
			
		||||
    /*< private >*/
 | 
			
		||||
    EekXkbLayout parent;
 | 
			
		||||
 | 
			
		||||
    EekXklLayoutPrivate *priv;
 | 
			
		||||
};
 | 
			
		||||
G_DECLARE_DERIVABLE_TYPE (EekXklLayout, eek_xkl_layout, EEK, XKL_LAYOUT, EekLayout)
 | 
			
		||||
 | 
			
		||||
struct _EekXklLayoutClass
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
@ -1,7 +1,7 @@
 | 
			
		||||
/* 
 | 
			
		||||
/*
 | 
			
		||||
 * 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
 | 
			
		||||
@ -25,6 +25,7 @@
 | 
			
		||||
#include "config.h"
 | 
			
		||||
#endif  /* HAVE_CONFIG_H */
 | 
			
		||||
 | 
			
		||||
#include <gio/gio.h> /* GResource */
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
@ -35,6 +36,8 @@
 | 
			
		||||
#include "eek-keysym.h"
 | 
			
		||||
#include "eek-text.h"
 | 
			
		||||
 | 
			
		||||
#include "squeekboard-resources.h"
 | 
			
		||||
 | 
			
		||||
enum {
 | 
			
		||||
    PROP_0,
 | 
			
		||||
    PROP_ID,
 | 
			
		||||
@ -43,19 +46,18 @@ enum {
 | 
			
		||||
 | 
			
		||||
static void initable_iface_init (GInitableIface *initable_iface);
 | 
			
		||||
 | 
			
		||||
G_DEFINE_TYPE_WITH_CODE (EekXmlLayout, eek_xml_layout, EEK_TYPE_LAYOUT,
 | 
			
		||||
                         G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE,
 | 
			
		||||
                                                initable_iface_init));
 | 
			
		||||
 | 
			
		||||
#define EEK_XML_LAYOUT_GET_PRIVATE(obj)                                  \
 | 
			
		||||
    (G_TYPE_INSTANCE_GET_PRIVATE ((obj), EEK_TYPE_XML_LAYOUT, EekXmlLayoutPrivate))
 | 
			
		||||
 | 
			
		||||
struct _EekXmlLayoutPrivate
 | 
			
		||||
typedef struct _EekXmlLayoutPrivate
 | 
			
		||||
{
 | 
			
		||||
    gchar *id;
 | 
			
		||||
    gchar *keyboards_dir;
 | 
			
		||||
    EekXmlKeyboardDesc *desc;
 | 
			
		||||
};
 | 
			
		||||
} EekXmlLayoutPrivate;
 | 
			
		||||
 | 
			
		||||
G_DEFINE_TYPE_EXTENDED (EekXmlLayout, eek_xml_layout, EEK_TYPE_LAYOUT,
 | 
			
		||||
			0, /* GTypeFlags */
 | 
			
		||||
			G_ADD_PRIVATE(EekXmlLayout)
 | 
			
		||||
                        G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE,
 | 
			
		||||
                                               initable_iface_init))
 | 
			
		||||
 | 
			
		||||
G_DEFINE_BOXED_TYPE(EekXmlKeyboardDesc, eek_xml_keyboard_desc, eek_xml_keyboard_desc_copy, eek_xml_keyboard_desc_free);
 | 
			
		||||
 | 
			
		||||
@ -240,6 +242,7 @@ struct _GeometryParseData {
 | 
			
		||||
    EekSection *section;
 | 
			
		||||
    EekKey *key;
 | 
			
		||||
    gint num_columns;
 | 
			
		||||
    gint num_rows;
 | 
			
		||||
    EekOrientation orientation;
 | 
			
		||||
    gdouble corner_radius;
 | 
			
		||||
    GSList *points;
 | 
			
		||||
@ -287,8 +290,8 @@ static const gchar *geometry_valid_path_list[] = {
 | 
			
		||||
    "outline/geometry",
 | 
			
		||||
    "bounds/section/geometry",
 | 
			
		||||
    "row/section/geometry",
 | 
			
		||||
    "key/section/geometry",
 | 
			
		||||
    "bounds/key/section/geometry",
 | 
			
		||||
    "key/row/section/geometry",
 | 
			
		||||
    "bounds/key/row/section/geometry",
 | 
			
		||||
    "point/outline/geometry",
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
@ -361,9 +364,6 @@ geometry_start_element_callback (GMarkupParseContext *pcontext,
 | 
			
		||||
            eek_element_set_bounds (EEK_ELEMENT(data->keyboard), &bounds);
 | 
			
		||||
        else if (g_strcmp0 (data->element_stack->data, "section") == 0)
 | 
			
		||||
            eek_element_set_bounds (EEK_ELEMENT(data->section), &bounds);
 | 
			
		||||
        else if (g_strcmp0 (data->element_stack->data, "key") == 0)
 | 
			
		||||
            eek_element_set_bounds (EEK_ELEMENT(data->key), &bounds);
 | 
			
		||||
 | 
			
		||||
        goto out;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -384,27 +384,21 @@ geometry_start_element_callback (GMarkupParseContext *pcontext,
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (g_strcmp0 (element_name, "row") == 0) {
 | 
			
		||||
        attribute = get_attribute (attribute_names, attribute_values,
 | 
			
		||||
                                   "columns");
 | 
			
		||||
        if (attribute == NULL) {
 | 
			
		||||
            g_set_error (error,
 | 
			
		||||
                         G_MARKUP_ERROR,
 | 
			
		||||
                         G_MARKUP_ERROR_MISSING_ATTRIBUTE,
 | 
			
		||||
                         "no \"columns\" attribute for \"row\"");
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
        data->num_columns = strtol (attribute, NULL, 10);
 | 
			
		||||
 | 
			
		||||
        attribute = get_attribute (attribute_names, attribute_values,
 | 
			
		||||
                                   "orientation");
 | 
			
		||||
        if (attribute != NULL)
 | 
			
		||||
            data->orientation = strtol (attribute, NULL, 10);
 | 
			
		||||
 | 
			
		||||
        eek_section_add_row (data->section,
 | 
			
		||||
                             data->num_columns,
 | 
			
		||||
                             data->orientation);
 | 
			
		||||
 | 
			
		||||
        data->num_rows++;
 | 
			
		||||
        goto out;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (g_strcmp0 (element_name, "key") == 0) {
 | 
			
		||||
        guint keycode;
 | 
			
		||||
        gint column, row;
 | 
			
		||||
 | 
			
		||||
        attribute = get_attribute (attribute_names, attribute_values,
 | 
			
		||||
                                   "keycode");
 | 
			
		||||
@ -417,29 +411,10 @@ geometry_start_element_callback (GMarkupParseContext *pcontext,
 | 
			
		||||
        }
 | 
			
		||||
        keycode = strtoul (attribute, NULL, 10);
 | 
			
		||||
 | 
			
		||||
        attribute = get_attribute (attribute_names, attribute_values,
 | 
			
		||||
                                   "column");
 | 
			
		||||
        if (attribute == NULL) {
 | 
			
		||||
            g_set_error (error,
 | 
			
		||||
                         G_MARKUP_ERROR,
 | 
			
		||||
                         G_MARKUP_ERROR_MISSING_ATTRIBUTE,
 | 
			
		||||
                         "no \"column\" attribute for \"key\"");
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
        column = strtol (attribute, NULL, 10);
 | 
			
		||||
        
 | 
			
		||||
        attribute = get_attribute (attribute_names, attribute_values,
 | 
			
		||||
                                   "row");
 | 
			
		||||
        if (attribute == NULL) {
 | 
			
		||||
            g_set_error (error,
 | 
			
		||||
                         G_MARKUP_ERROR,
 | 
			
		||||
                         G_MARKUP_ERROR_MISSING_ATTRIBUTE,
 | 
			
		||||
                         "no \"row\" attribute for \"row\"");
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
        row = strtol (attribute, NULL, 10);
 | 
			
		||||
 | 
			
		||||
        data->key = eek_section_create_key (data->section, keycode, column, row);
 | 
			
		||||
        data->key = eek_section_create_key (data->section,
 | 
			
		||||
                                            keycode,
 | 
			
		||||
                                            data->num_columns,
 | 
			
		||||
                                            data->num_rows - 1);
 | 
			
		||||
 | 
			
		||||
        attribute = get_attribute (attribute_names, attribute_values,
 | 
			
		||||
                                   "name");
 | 
			
		||||
@ -458,6 +433,9 @@ geometry_start_element_callback (GMarkupParseContext *pcontext,
 | 
			
		||||
        g_hash_table_insert (data->key_oref_hash,
 | 
			
		||||
                             data->key,
 | 
			
		||||
                             g_strdup (attribute));
 | 
			
		||||
 | 
			
		||||
        data->num_columns++;
 | 
			
		||||
 | 
			
		||||
        goto out;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -476,7 +454,7 @@ geometry_start_element_callback (GMarkupParseContext *pcontext,
 | 
			
		||||
                                   "corner-radius");
 | 
			
		||||
        if (attribute != NULL)
 | 
			
		||||
            data->corner_radius = g_strtod (attribute, NULL);
 | 
			
		||||
        
 | 
			
		||||
 | 
			
		||||
        goto out;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -525,7 +503,6 @@ geometry_end_element_callback (GMarkupParseContext *pcontext,
 | 
			
		||||
{
 | 
			
		||||
    GeometryParseData *data = user_data;
 | 
			
		||||
    GSList *head = data->element_stack;
 | 
			
		||||
    gint i;
 | 
			
		||||
 | 
			
		||||
    g_free (head->data);
 | 
			
		||||
    data->element_stack = g_slist_next (data->element_stack);
 | 
			
		||||
@ -533,6 +510,7 @@ geometry_end_element_callback (GMarkupParseContext *pcontext,
 | 
			
		||||
 | 
			
		||||
    if (g_strcmp0 (element_name, "section") == 0) {
 | 
			
		||||
        data->section = NULL;
 | 
			
		||||
        data->num_rows = 0;
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -541,6 +519,12 @@ geometry_end_element_callback (GMarkupParseContext *pcontext,
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (g_strcmp0 (element_name, "row") == 0) {
 | 
			
		||||
        data->num_columns = 0;
 | 
			
		||||
        data->orientation = EEK_ORIENTATION_HORIZONTAL;
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (g_strcmp0 (element_name, "outline") == 0) {
 | 
			
		||||
        EekOutline *outline = g_slice_new (EekOutline);
 | 
			
		||||
 | 
			
		||||
@ -550,7 +534,8 @@ geometry_end_element_callback (GMarkupParseContext *pcontext,
 | 
			
		||||
        outline->num_points = g_slist_length (data->points);
 | 
			
		||||
        outline->points = g_slice_alloc0 (sizeof (EekPoint) *
 | 
			
		||||
                                          outline->num_points);
 | 
			
		||||
        for (head = data->points = g_slist_reverse (data->points), i = 0;
 | 
			
		||||
        guint i;
 | 
			
		||||
        for (i = 0, head = data->points = g_slist_reverse (data->points);
 | 
			
		||||
             head && i < outline->num_points;
 | 
			
		||||
             head = g_slist_next (head), i++) {
 | 
			
		||||
            memcpy (&outline->points[i], head->data, sizeof (EekPoint));
 | 
			
		||||
@ -566,15 +551,6 @@ geometry_end_element_callback (GMarkupParseContext *pcontext,
 | 
			
		||||
        g_free (data->oref);
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (g_strcmp0 (element_name, "row") == 0) {
 | 
			
		||||
        eek_section_add_row (data->section,
 | 
			
		||||
                             data->num_columns,
 | 
			
		||||
                             data->orientation);
 | 
			
		||||
        data->num_columns = 0;
 | 
			
		||||
        data->orientation = EEK_ORIENTATION_HORIZONTAL;
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static const GMarkupParser geometry_parser = {
 | 
			
		||||
@ -594,6 +570,7 @@ struct _SymbolsParseData {
 | 
			
		||||
    GSList *symbols;
 | 
			
		||||
    gchar *label;
 | 
			
		||||
    gchar *icon;
 | 
			
		||||
    gchar *tooltip;
 | 
			
		||||
    EekSymbolCategory category;
 | 
			
		||||
    guint keyval;
 | 
			
		||||
    gint groups;
 | 
			
		||||
@ -662,13 +639,13 @@ symbols_start_element_callback (GMarkupParseContext *pcontext,
 | 
			
		||||
 | 
			
		||||
        data->key = eek_keyboard_find_key_by_keycode (data->keyboard,
 | 
			
		||||
                                                      keycode);
 | 
			
		||||
        if (data->key == NULL) {
 | 
			
		||||
        /*if (data->key == NULL) {
 | 
			
		||||
            g_set_error (error,
 | 
			
		||||
                         G_MARKUP_ERROR,
 | 
			
		||||
                         G_MARKUP_ERROR_INVALID_CONTENT,
 | 
			
		||||
                         "no such keycode %u", keycode);
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
        }*/
 | 
			
		||||
 | 
			
		||||
        attribute = get_attribute (attribute_names, attribute_values,
 | 
			
		||||
                                   "groups");
 | 
			
		||||
@ -706,6 +683,11 @@ symbols_start_element_callback (GMarkupParseContext *pcontext,
 | 
			
		||||
        if (attribute != NULL)
 | 
			
		||||
            data->icon = g_strdup (attribute);
 | 
			
		||||
 | 
			
		||||
        attribute = get_attribute (attribute_names, attribute_values,
 | 
			
		||||
                                   "tooltip");
 | 
			
		||||
        if (attribute != NULL)
 | 
			
		||||
            data->tooltip = g_strdup (attribute);
 | 
			
		||||
 | 
			
		||||
        attribute = get_attribute (attribute_names, attribute_values,
 | 
			
		||||
                                   "category");
 | 
			
		||||
        if (attribute != NULL)
 | 
			
		||||
@ -738,6 +720,10 @@ symbols_end_element_callback (GMarkupParseContext *pcontext,
 | 
			
		||||
    text = g_strndup (data->text->str, data->text->len);
 | 
			
		||||
 | 
			
		||||
    if (g_strcmp0 (element_name, "key") == 0) {
 | 
			
		||||
        if (!data->key) {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        gint num_symbols = g_slist_length (data->symbols);
 | 
			
		||||
        gint levels = num_symbols / data->groups;
 | 
			
		||||
        EekSymbolMatrix *matrix = eek_symbol_matrix_new (data->groups,
 | 
			
		||||
@ -789,6 +775,11 @@ symbols_end_element_callback (GMarkupParseContext *pcontext,
 | 
			
		||||
            g_free (data->icon);
 | 
			
		||||
            data->icon = NULL;
 | 
			
		||||
        }
 | 
			
		||||
        if (data->tooltip) {
 | 
			
		||||
            eek_symbol_set_tooltip (symbol, data->tooltip);
 | 
			
		||||
            g_free (data->tooltip);
 | 
			
		||||
            data->tooltip = NULL;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        data->symbols = g_slist_prepend (data->symbols, symbol);
 | 
			
		||||
        goto out;
 | 
			
		||||
@ -908,42 +899,41 @@ static const GMarkupParser prerequisites_parser = {
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static EekKeyboard *
 | 
			
		||||
eek_xml_layout_real_create_keyboard (EekLayout *self,
 | 
			
		||||
eek_xml_layout_real_create_keyboard (EekboardContextService *manager,
 | 
			
		||||
                                     EekLayout *self,
 | 
			
		||||
                                     gdouble    initial_width,
 | 
			
		||||
                                     gdouble    initial_height)
 | 
			
		||||
{
 | 
			
		||||
    EekXmlLayout *layout = EEK_XML_LAYOUT (self);
 | 
			
		||||
    EekKeyboard *keyboard;
 | 
			
		||||
    gchar *filename, *path;
 | 
			
		||||
    GList *loaded;
 | 
			
		||||
    GError *error;
 | 
			
		||||
    EekXmlLayoutPrivate *priv = eek_xml_layout_get_instance_private (layout);
 | 
			
		||||
    gboolean retval;
 | 
			
		||||
 | 
			
		||||
    /* Create an empty keyboard to which geometry and symbols
 | 
			
		||||
       information are applied. */
 | 
			
		||||
    keyboard = g_object_new (EEK_TYPE_KEYBOARD, "layout", layout, NULL);
 | 
			
		||||
    EekKeyboard *keyboard = g_object_new (EEK_TYPE_KEYBOARD, "layout", layout, NULL);
 | 
			
		||||
    keyboard->manager = manager;
 | 
			
		||||
 | 
			
		||||
    /* Read geometry information. */
 | 
			
		||||
    filename = g_strdup_printf ("%s.xml", layout->priv->desc->geometry);
 | 
			
		||||
    path = g_build_filename (layout->priv->keyboards_dir, "geometry", filename, NULL);
 | 
			
		||||
    gchar *filename = g_strdup_printf ("%s.xml", priv->desc->geometry);
 | 
			
		||||
    gchar *path = g_build_filename (priv->keyboards_dir, "geometry", filename, NULL);
 | 
			
		||||
    g_free (filename);
 | 
			
		||||
 | 
			
		||||
    error = NULL;
 | 
			
		||||
    GError *error = NULL;
 | 
			
		||||
    retval = parse_geometry (path, keyboard, &error);
 | 
			
		||||
    g_free (path);
 | 
			
		||||
    if (!retval) {
 | 
			
		||||
        g_object_unref (keyboard);
 | 
			
		||||
        g_warning ("can't parse geometry file %s: %s",
 | 
			
		||||
                   layout->priv->desc->geometry,
 | 
			
		||||
                   priv->desc->geometry,
 | 
			
		||||
                   error->message);
 | 
			
		||||
        g_error_free (error);
 | 
			
		||||
        return NULL;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* Read symbols information. */
 | 
			
		||||
    loaded = NULL;
 | 
			
		||||
    retval = parse_symbols_with_prerequisites (layout->priv->keyboards_dir,
 | 
			
		||||
                                               layout->priv->desc->symbols,
 | 
			
		||||
    GList *loaded = NULL;
 | 
			
		||||
    retval = parse_symbols_with_prerequisites (priv->keyboards_dir,
 | 
			
		||||
                                               priv->desc->symbols,
 | 
			
		||||
                                               keyboard,
 | 
			
		||||
                                               &loaded,
 | 
			
		||||
                                               &error);
 | 
			
		||||
@ -951,7 +941,7 @@ eek_xml_layout_real_create_keyboard (EekLayout *self,
 | 
			
		||||
    if (!retval) {
 | 
			
		||||
        g_object_unref (keyboard);
 | 
			
		||||
        g_warning ("can't parse symbols file %s: %s",
 | 
			
		||||
                   layout->priv->desc->symbols,
 | 
			
		||||
                   priv->desc->symbols,
 | 
			
		||||
                   error->message);
 | 
			
		||||
        g_error_free (error);
 | 
			
		||||
        return NULL;
 | 
			
		||||
@ -962,7 +952,7 @@ eek_xml_layout_real_create_keyboard (EekLayout *self,
 | 
			
		||||
 | 
			
		||||
    /* Use pre-defined modifier mask here. */
 | 
			
		||||
    eek_keyboard_set_num_lock_mask (keyboard, EEK_MOD2_MASK);
 | 
			
		||||
    eek_keyboard_set_alt_gr_mask (keyboard, EEK_MOD5_MASK);
 | 
			
		||||
    eek_keyboard_set_alt_gr_mask (keyboard, EEK_BUTTON1_MASK);
 | 
			
		||||
 | 
			
		||||
    return keyboard;
 | 
			
		||||
}
 | 
			
		||||
@ -974,10 +964,12 @@ eek_xml_layout_set_property (GObject      *object,
 | 
			
		||||
                             GParamSpec   *pspec)
 | 
			
		||||
{
 | 
			
		||||
    EekXmlLayout *layout = EEK_XML_LAYOUT (object);
 | 
			
		||||
    EekXmlLayoutPrivate *priv = eek_xml_layout_get_instance_private (layout);
 | 
			
		||||
 | 
			
		||||
    switch (prop_id) {
 | 
			
		||||
    case PROP_ID:
 | 
			
		||||
        g_free (layout->priv->id);
 | 
			
		||||
        layout->priv->id = g_value_dup_string (value);
 | 
			
		||||
        g_free (priv->id);
 | 
			
		||||
        priv->id = g_value_dup_string (value);
 | 
			
		||||
        break;
 | 
			
		||||
    default:
 | 
			
		||||
        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 | 
			
		||||
@ -992,9 +984,11 @@ eek_xml_layout_get_property (GObject    *object,
 | 
			
		||||
                             GParamSpec *pspec)
 | 
			
		||||
{
 | 
			
		||||
    EekXmlLayout *layout = EEK_XML_LAYOUT (object);
 | 
			
		||||
    EekXmlLayoutPrivate *priv = eek_xml_layout_get_instance_private (layout);
 | 
			
		||||
 | 
			
		||||
    switch (prop_id) {
 | 
			
		||||
    case PROP_ID:
 | 
			
		||||
        g_value_set_string (value, layout->priv->id);
 | 
			
		||||
        g_value_set_string (value, priv->id);
 | 
			
		||||
        break;
 | 
			
		||||
    default:
 | 
			
		||||
        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 | 
			
		||||
@ -1005,7 +999,8 @@ eek_xml_layout_get_property (GObject    *object,
 | 
			
		||||
static void
 | 
			
		||||
eek_xml_layout_finalize (GObject *object)
 | 
			
		||||
{
 | 
			
		||||
    EekXmlLayoutPrivate *priv = EEK_XML_LAYOUT_GET_PRIVATE (object);
 | 
			
		||||
    EekXmlLayoutPrivate *priv = eek_xml_layout_get_instance_private (
 | 
			
		||||
		    EEK_XML_LAYOUT (object));
 | 
			
		||||
 | 
			
		||||
    g_free (priv->id);
 | 
			
		||||
 | 
			
		||||
@ -1024,8 +1019,6 @@ eek_xml_layout_class_init (EekXmlLayoutClass *klass)
 | 
			
		||||
    GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
 | 
			
		||||
    GParamSpec *pspec;
 | 
			
		||||
 | 
			
		||||
    g_type_class_add_private (gobject_class, sizeof (EekXmlLayoutPrivate));
 | 
			
		||||
 | 
			
		||||
    layout_class->create_keyboard = eek_xml_layout_real_create_keyboard;
 | 
			
		||||
 | 
			
		||||
    gobject_class->set_property = eek_xml_layout_set_property;
 | 
			
		||||
@ -1044,7 +1037,7 @@ eek_xml_layout_class_init (EekXmlLayoutClass *klass)
 | 
			
		||||
static void
 | 
			
		||||
eek_xml_layout_init (EekXmlLayout *self)
 | 
			
		||||
{
 | 
			
		||||
    self->priv = EEK_XML_LAYOUT_GET_PRIVATE (self);
 | 
			
		||||
    /* void */
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
EekLayout *
 | 
			
		||||
@ -1063,16 +1056,17 @@ initable_init (GInitable    *initable,
 | 
			
		||||
               GError      **error)
 | 
			
		||||
{
 | 
			
		||||
    EekXmlLayout *layout = EEK_XML_LAYOUT (initable);
 | 
			
		||||
    EekXmlLayoutPrivate *priv = eek_xml_layout_get_instance_private (layout);
 | 
			
		||||
    GList *keyboards, *p;
 | 
			
		||||
    gchar *path;
 | 
			
		||||
    EekXmlKeyboardDesc *desc;
 | 
			
		||||
 | 
			
		||||
    layout->priv->keyboards_dir = (gchar *) g_getenv ("EEKBOARD_KEYBOARDSDIR");
 | 
			
		||||
    if (layout->priv->keyboards_dir == NULL)
 | 
			
		||||
        layout->priv->keyboards_dir = KEYBOARDSDIR;
 | 
			
		||||
    layout->priv->keyboards_dir = g_strdup (layout->priv->keyboards_dir);
 | 
			
		||||
    priv->keyboards_dir = g_strdup ((gchar *) g_getenv ("EEKBOARD_KEYBOARDSDIR"));
 | 
			
		||||
 | 
			
		||||
    path = g_build_filename (layout->priv->keyboards_dir, "keyboards.xml", NULL);
 | 
			
		||||
    if (priv->keyboards_dir == NULL)
 | 
			
		||||
        priv->keyboards_dir = g_strdup ("resource:///sm/puri/squeekboard/keyboards/");
 | 
			
		||||
 | 
			
		||||
    path = g_build_filename (priv->keyboards_dir, "keyboards.xml", NULL);
 | 
			
		||||
    keyboards = parse_keyboards (path, error);
 | 
			
		||||
    g_free (path);
 | 
			
		||||
    if (error && *error)
 | 
			
		||||
@ -1080,7 +1074,7 @@ initable_init (GInitable    *initable,
 | 
			
		||||
 | 
			
		||||
    for (p = keyboards; p; p = p->next) {
 | 
			
		||||
        desc = p->data;
 | 
			
		||||
        if (g_strcmp0 (desc->id, layout->priv->id) == 0)
 | 
			
		||||
        if (g_strcmp0 (desc->id, priv->id) == 0)
 | 
			
		||||
            break;
 | 
			
		||||
    }
 | 
			
		||||
    if (p == NULL) {
 | 
			
		||||
@ -1088,12 +1082,12 @@ initable_init (GInitable    *initable,
 | 
			
		||||
                     EEK_ERROR,
 | 
			
		||||
                     EEK_ERROR_LAYOUT_ERROR,
 | 
			
		||||
                     "no such keyboard %s",
 | 
			
		||||
                     layout->priv->id);
 | 
			
		||||
                     priv->id);
 | 
			
		||||
        return FALSE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    keyboards = g_list_remove_link (keyboards, p);
 | 
			
		||||
    layout->priv->desc = p->data;
 | 
			
		||||
    priv->desc = p->data;
 | 
			
		||||
    g_list_free_1 (p);
 | 
			
		||||
    g_list_free_full (keyboards, (GDestroyNotify) keyboard_desc_free);
 | 
			
		||||
 | 
			
		||||
@ -1106,6 +1100,12 @@ initable_iface_init (GInitableIface *initable_iface)
 | 
			
		||||
    initable_iface->init = initable_init;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eek_xml_list_keyboards:
 | 
			
		||||
 *
 | 
			
		||||
 * List available keyboards.
 | 
			
		||||
 * Returns: (transfer container) (element-type utf8): the list of keyboards
 | 
			
		||||
 */
 | 
			
		||||
GList *
 | 
			
		||||
eek_xml_list_keyboards (void)
 | 
			
		||||
{
 | 
			
		||||
@ -1115,7 +1115,7 @@ eek_xml_list_keyboards (void)
 | 
			
		||||
 | 
			
		||||
    keyboards_dir = g_getenv ("EEKBOARD_KEYBOARDSDIR");
 | 
			
		||||
    if (keyboards_dir == NULL)
 | 
			
		||||
        keyboards_dir = KEYBOARDSDIR;
 | 
			
		||||
        keyboards_dir = g_strdup ("resource:///sm/puri/squeekboard/keyboards/");
 | 
			
		||||
    path = g_build_filename (keyboards_dir, "keyboards.xml", NULL);
 | 
			
		||||
    keyboards = parse_keyboards (path, NULL);
 | 
			
		||||
    g_free (path);
 | 
			
		||||
@ -1140,6 +1140,38 @@ 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)
 | 
			
		||||
{
 | 
			
		||||
@ -1152,7 +1184,9 @@ parse_geometry (const gchar *path, EekKeyboard *keyboard, GError **error)
 | 
			
		||||
    GFileInputStream *input;
 | 
			
		||||
    gboolean retval;
 | 
			
		||||
 | 
			
		||||
    file = g_file_new_for_path (path);
 | 
			
		||||
    file = g_str_has_prefix (path, "resource://")
 | 
			
		||||
         ? g_file_new_for_uri  (path)
 | 
			
		||||
         : g_file_new_for_path (path);
 | 
			
		||||
 | 
			
		||||
    input = g_file_read (file, NULL, error);
 | 
			
		||||
    g_object_unref (file);
 | 
			
		||||
@ -1192,6 +1226,27 @@ 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;
 | 
			
		||||
}
 | 
			
		||||
@ -1257,7 +1312,9 @@ parse_symbols (const gchar *path, EekKeyboard *keyboard, GError **error)
 | 
			
		||||
    GFileInputStream *input;
 | 
			
		||||
    gboolean retval;
 | 
			
		||||
 | 
			
		||||
    file = g_file_new_for_path (path);
 | 
			
		||||
    file = g_str_has_prefix (path, "resource://")
 | 
			
		||||
         ? g_file_new_for_uri  (path)
 | 
			
		||||
         : g_file_new_for_path (path);
 | 
			
		||||
 | 
			
		||||
    input = g_file_read (file, NULL, error);
 | 
			
		||||
    g_object_unref (file);
 | 
			
		||||
@ -1290,7 +1347,9 @@ parse_prerequisites (const gchar *path, GError **error)
 | 
			
		||||
    GList *prerequisites;
 | 
			
		||||
    gboolean retval;
 | 
			
		||||
 | 
			
		||||
    file = g_file_new_for_path (path);
 | 
			
		||||
    file = g_str_has_prefix (path, "resource://")
 | 
			
		||||
         ? g_file_new_for_uri  (path)
 | 
			
		||||
         : g_file_new_for_path (path);
 | 
			
		||||
 | 
			
		||||
    input = g_file_read (file, NULL, error);
 | 
			
		||||
    g_object_unref (file);
 | 
			
		||||
@ -1325,7 +1384,9 @@ parse_keyboards (const gchar *path, GError **error)
 | 
			
		||||
    GList *keyboards;
 | 
			
		||||
    gboolean retval;
 | 
			
		||||
 | 
			
		||||
    file = g_file_new_for_path (path);
 | 
			
		||||
    file = g_str_has_prefix (path, "resource://")
 | 
			
		||||
         ? g_file_new_for_uri  (path)
 | 
			
		||||
         : g_file_new_for_path (path);
 | 
			
		||||
 | 
			
		||||
    input = g_file_read (file, NULL, error);
 | 
			
		||||
    g_object_unref (file);
 | 
			
		||||
@ -1402,7 +1463,7 @@ static void scale_keyboard (EekKeyboard *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;
 | 
			
		||||
 | 
			
		||||
@ -29,29 +29,7 @@
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
#define EEK_TYPE_XML_LAYOUT (eek_xml_layout_get_type())
 | 
			
		||||
#define EEK_XML_LAYOUT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EEK_TYPE_XML_LAYOUT, EekXmlLayout))
 | 
			
		||||
#define EEK_XML_LAYOUT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EEK_TYPE_XML_LAYOUT, EekXmlLayoutClass))
 | 
			
		||||
#define EEK_IS_XML_LAYOUT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EEK_TYPE_XML_LAYOUT))
 | 
			
		||||
#define EEK_IS_XML_LAYOUT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EEK_TYPE_XML_LAYOUT))
 | 
			
		||||
#define EEK_XML_LAYOUT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EEK_TYPE_XML_LAYOUT, EekXmlLayoutClass))
 | 
			
		||||
 | 
			
		||||
typedef struct _EekXmlLayout        EekXmlLayout;
 | 
			
		||||
typedef struct _EekXmlLayoutClass   EekXmlLayoutClass;
 | 
			
		||||
typedef struct _EekXmlLayoutPrivate EekXmlLayoutPrivate;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * EekXmlLayout:
 | 
			
		||||
 *
 | 
			
		||||
 * The #EekXmlLayout structure contains only private data and should
 | 
			
		||||
 * only be accessed using the provided API.
 | 
			
		||||
 */
 | 
			
		||||
struct _EekXmlLayout
 | 
			
		||||
{
 | 
			
		||||
    /*< private >*/
 | 
			
		||||
    EekLayout parent;
 | 
			
		||||
 | 
			
		||||
    EekXmlLayoutPrivate *priv;
 | 
			
		||||
};
 | 
			
		||||
G_DECLARE_DERIVABLE_TYPE (EekXmlLayout, eek_xml_layout, EEK, XML_LAYOUT, EekLayout)
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * EekXmlLayoutClass:
 | 
			
		||||
 | 
			
		||||
@ -38,9 +38,5 @@
 | 
			
		||||
void
 | 
			
		||||
eek_init (void)
 | 
			
		||||
{
 | 
			
		||||
    g_type_init ();
 | 
			
		||||
 | 
			
		||||
    g_type_class_ref (EEK_TYPE_SYMBOL);
 | 
			
		||||
    g_type_class_ref (EEK_TYPE_KEYSYM);
 | 
			
		||||
    g_type_class_ref (EEK_TYPE_TEXT);
 | 
			
		||||
    /* void */
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -1,7 +1,8 @@
 | 
			
		||||
#!/usr/bin/env python
 | 
			
		||||
#!/usr/bin/env python3
 | 
			
		||||
 | 
			
		||||
# Copyright (C) 2010-2011 Daiki Ueno <ueno@unixuser.org>
 | 
			
		||||
# Copyright (C) 2010-2011 Red Hat, Inc.
 | 
			
		||||
# Copyright (C) 2019      Purism, SPC
 | 
			
		||||
 | 
			
		||||
# This library is free software; you can redistribute it and/or
 | 
			
		||||
# modify it under the terms of the GNU Lesser General Public License
 | 
			
		||||
@ -21,13 +22,17 @@
 | 
			
		||||
import sys
 | 
			
		||||
import re
 | 
			
		||||
 | 
			
		||||
if len(sys.argv) != 2:
 | 
			
		||||
    print >> sys.stderr, "Usage: %s TABLE-NAME" % sys.argv[0]
 | 
			
		||||
if len(sys.argv) > 3:
 | 
			
		||||
    print("Usage: %s TABLE-NAME [INPUT_FILE]" % sys.argv[0], file=sys.stderr)
 | 
			
		||||
    sys.exit(-1)
 | 
			
		||||
 | 
			
		||||
if len(sys.argv) < 3:
 | 
			
		||||
    in_stream = sys.stdin
 | 
			
		||||
else:
 | 
			
		||||
    in_stream = open(sys.argv[2])
 | 
			
		||||
 | 
			
		||||
table = dict()
 | 
			
		||||
for line in sys.stdin:
 | 
			
		||||
    line = line.decode('UTF-8')
 | 
			
		||||
for line in in_stream:
 | 
			
		||||
    match = re.match(r'\s*(0x[0-9A-F]+)\s+(\S*)\s+(\S*)', line, re.I)
 | 
			
		||||
    if match:
 | 
			
		||||
        table[int(match.group(1), 16)] = (match.group(2), match.group(3))
 | 
			
		||||
@ -38,7 +43,7 @@ sys.stdout.write("static const EekKeysymEntry %s[] = {\n" %
 | 
			
		||||
for index, (keysym, (l, c)) in enumerate([(keysym, table[keysym])
 | 
			
		||||
                                          for keysym in sorted(table.keys())]):
 | 
			
		||||
    sys.stdout.write("    { 0x%X, %s, %s }" %
 | 
			
		||||
                     (keysym, l.encode('UTF-8'), c.encode('UTF-8')))
 | 
			
		||||
                     (keysym, l, c))
 | 
			
		||||
    if index < len(table) - 1:
 | 
			
		||||
        sys.stdout.write(",")
 | 
			
		||||
    sys.stdout.write("\n")
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										374
									
								
								eek/layersurface.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										374
									
								
								eek/layersurface.c
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,374 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2018 Purism SPC
 | 
			
		||||
 * SPDX-License-Identifier: GPL-3.0+
 | 
			
		||||
 * Author: Guido Günther <agx@sigxcpu.org>
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 | 
			
		||||
WARNING: this file is taken directly from phosh, with no modificaions apart from this message. Please update phosh instead of changing this file. Please copy the file back here afterwards, with the same notice.
 | 
			
		||||
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#define G_LOG_DOMAIN "phosh-layer-surface"
 | 
			
		||||
 | 
			
		||||
#include "config.h"
 | 
			
		||||
#include "layersurface.h"
 | 
			
		||||
 | 
			
		||||
#include <gdk/gdkwayland.h>
 | 
			
		||||
 | 
			
		||||
enum {
 | 
			
		||||
  PHOSH_LAYER_SURFACE_PROP_0,
 | 
			
		||||
  PHOSH_LAYER_SURFACE_PROP_LAYER_SHELL,
 | 
			
		||||
  PHOSH_LAYER_SURFACE_PROP_WL_OUTPUT,
 | 
			
		||||
  PHOSH_LAYER_SURFACE_PROP_ANCHOR,
 | 
			
		||||
  PHOSH_LAYER_SURFACE_PROP_LAYER,
 | 
			
		||||
  PHOSH_LAYER_SURFACE_PROP_KBD_INTERACTIVITY,
 | 
			
		||||
  PHOSH_LAYER_SURFACE_PROP_EXCLUSIVE_ZONE,
 | 
			
		||||
  PHOSH_LAYER_SURFACE_PROP_LAYER_WIDTH,
 | 
			
		||||
  PHOSH_LAYER_SURFACE_PROP_LAYER_HEIGHT,
 | 
			
		||||
  PHOSH_LAYER_SURFACE_PROP_NAMESPACE,
 | 
			
		||||
  PHOSH_LAYER_SURFACE_PROP_LAST_PROP
 | 
			
		||||
};
 | 
			
		||||
static GParamSpec *props[PHOSH_LAYER_SURFACE_PROP_LAST_PROP];
 | 
			
		||||
 | 
			
		||||
enum {
 | 
			
		||||
  CONFIGURED,
 | 
			
		||||
  N_SIGNALS
 | 
			
		||||
};
 | 
			
		||||
static guint signals [N_SIGNALS];
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
typedef struct {
 | 
			
		||||
  struct wl_surface *wl_surface;
 | 
			
		||||
  struct zwlr_layer_surface_v1 *layer_surface;
 | 
			
		||||
 | 
			
		||||
  /* Properties */
 | 
			
		||||
  guint anchor;
 | 
			
		||||
  guint layer;
 | 
			
		||||
  gboolean kbd_interactivity;
 | 
			
		||||
  gint exclusive_zone;
 | 
			
		||||
  gint width, height;
 | 
			
		||||
  gchar *namespace;
 | 
			
		||||
  struct zwlr_layer_shell_v1 *layer_shell;
 | 
			
		||||
  struct wl_output *wl_output;
 | 
			
		||||
} PhoshLayerSurfacePrivate;
 | 
			
		||||
 | 
			
		||||
G_DEFINE_TYPE_WITH_PRIVATE (PhoshLayerSurface, phosh_layer_surface, GTK_TYPE_WINDOW)
 | 
			
		||||
 | 
			
		||||
static void layer_surface_configure(void                         *data,
 | 
			
		||||
                                    struct zwlr_layer_surface_v1 *surface,
 | 
			
		||||
                                    uint32_t                      serial,
 | 
			
		||||
                                    uint32_t                      width,
 | 
			
		||||
                                    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);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static void layer_surface_closed (void                         *data,
 | 
			
		||||
                                  struct zwlr_layer_surface_v1 *surface)
 | 
			
		||||
{
 | 
			
		||||
  PhoshLayerSurface *self = data;
 | 
			
		||||
  PhoshLayerSurfacePrivate *priv = phosh_layer_surface_get_instance_private (self);
 | 
			
		||||
 | 
			
		||||
  g_return_if_fail (priv->layer_surface == surface);
 | 
			
		||||
  zwlr_layer_surface_v1_destroy(priv->layer_surface);
 | 
			
		||||
  priv->layer_surface = NULL;
 | 
			
		||||
  gtk_widget_destroy (GTK_WIDGET (self));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static struct zwlr_layer_surface_v1_listener layer_surface_listener = {
 | 
			
		||||
	.configure = layer_surface_configure,
 | 
			
		||||
	.closed = layer_surface_closed,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
phosh_layer_surface_set_property (GObject      *object,
 | 
			
		||||
                                  guint         property_id,
 | 
			
		||||
                                  const GValue *value,
 | 
			
		||||
                                  GParamSpec   *pspec)
 | 
			
		||||
{
 | 
			
		||||
  PhoshLayerSurface *self = PHOSH_LAYER_SURFACE (object);
 | 
			
		||||
  PhoshLayerSurfacePrivate *priv = phosh_layer_surface_get_instance_private (self);
 | 
			
		||||
 | 
			
		||||
  switch (property_id) {
 | 
			
		||||
  case PHOSH_LAYER_SURFACE_PROP_LAYER_SHELL:
 | 
			
		||||
    priv->layer_shell = g_value_get_pointer (value);
 | 
			
		||||
    break;
 | 
			
		||||
  case PHOSH_LAYER_SURFACE_PROP_WL_OUTPUT:
 | 
			
		||||
    priv->wl_output = g_value_get_pointer (value);
 | 
			
		||||
    break;
 | 
			
		||||
  case PHOSH_LAYER_SURFACE_PROP_ANCHOR:
 | 
			
		||||
    priv->anchor = g_value_get_uint (value);
 | 
			
		||||
    break;
 | 
			
		||||
  case PHOSH_LAYER_SURFACE_PROP_LAYER:
 | 
			
		||||
    priv->layer = g_value_get_uint (value);
 | 
			
		||||
    break;
 | 
			
		||||
  case PHOSH_LAYER_SURFACE_PROP_KBD_INTERACTIVITY:
 | 
			
		||||
    priv->kbd_interactivity = g_value_get_boolean (value);
 | 
			
		||||
    break;
 | 
			
		||||
  case PHOSH_LAYER_SURFACE_PROP_EXCLUSIVE_ZONE:
 | 
			
		||||
    priv->exclusive_zone = g_value_get_int (value);
 | 
			
		||||
    break;
 | 
			
		||||
  case PHOSH_LAYER_SURFACE_PROP_LAYER_WIDTH:
 | 
			
		||||
    priv->width = g_value_get_uint (value);
 | 
			
		||||
    break;
 | 
			
		||||
  case PHOSH_LAYER_SURFACE_PROP_LAYER_HEIGHT:
 | 
			
		||||
    priv->height = g_value_get_uint (value);
 | 
			
		||||
    break;
 | 
			
		||||
  case PHOSH_LAYER_SURFACE_PROP_NAMESPACE:
 | 
			
		||||
    g_free (priv->namespace);
 | 
			
		||||
    priv->namespace = g_value_dup_string (value);
 | 
			
		||||
    break;
 | 
			
		||||
  default:
 | 
			
		||||
    G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
 | 
			
		||||
    break;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
phosh_layer_surface_get_property (GObject    *object,
 | 
			
		||||
                                  guint       property_id,
 | 
			
		||||
                                  GValue     *value,
 | 
			
		||||
                                  GParamSpec *pspec)
 | 
			
		||||
{
 | 
			
		||||
  PhoshLayerSurface *self = PHOSH_LAYER_SURFACE (object);
 | 
			
		||||
  PhoshLayerSurfacePrivate *priv = phosh_layer_surface_get_instance_private (self);
 | 
			
		||||
 | 
			
		||||
  switch (property_id) {
 | 
			
		||||
  case PHOSH_LAYER_SURFACE_PROP_LAYER_SHELL:
 | 
			
		||||
    g_value_set_pointer (value, priv->layer_shell);
 | 
			
		||||
    break;
 | 
			
		||||
  case PHOSH_LAYER_SURFACE_PROP_WL_OUTPUT:
 | 
			
		||||
    g_value_set_pointer (value, priv->wl_output);
 | 
			
		||||
    break;
 | 
			
		||||
  case PHOSH_LAYER_SURFACE_PROP_ANCHOR:
 | 
			
		||||
    g_value_set_uint (value, priv->anchor);
 | 
			
		||||
    break;
 | 
			
		||||
  case PHOSH_LAYER_SURFACE_PROP_LAYER:
 | 
			
		||||
    g_value_set_uint (value, priv->layer);
 | 
			
		||||
    break;
 | 
			
		||||
  case PHOSH_LAYER_SURFACE_PROP_KBD_INTERACTIVITY:
 | 
			
		||||
    g_value_set_boolean (value, priv->kbd_interactivity);
 | 
			
		||||
    break;
 | 
			
		||||
  case PHOSH_LAYER_SURFACE_PROP_EXCLUSIVE_ZONE:
 | 
			
		||||
    g_value_set_boolean (value, priv->exclusive_zone);
 | 
			
		||||
    break;
 | 
			
		||||
  case PHOSH_LAYER_SURFACE_PROP_LAYER_WIDTH:
 | 
			
		||||
    g_value_set_uint (value, priv->width);
 | 
			
		||||
    break;
 | 
			
		||||
  case PHOSH_LAYER_SURFACE_PROP_LAYER_HEIGHT:
 | 
			
		||||
    g_value_set_uint (value, priv->height);
 | 
			
		||||
    break;
 | 
			
		||||
  case PHOSH_LAYER_SURFACE_PROP_NAMESPACE:
 | 
			
		||||
    g_value_set_string (value, priv->namespace);
 | 
			
		||||
    break;
 | 
			
		||||
  default:
 | 
			
		||||
    G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
 | 
			
		||||
    break;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
phosh_layer_surface_constructed (GObject *object)
 | 
			
		||||
{
 | 
			
		||||
  PhoshLayerSurface *self = PHOSH_LAYER_SURFACE (object);
 | 
			
		||||
  PhoshLayerSurfacePrivate *priv = phosh_layer_surface_get_instance_private (self);
 | 
			
		||||
  GdkWindow *gdk_window;
 | 
			
		||||
 | 
			
		||||
  G_OBJECT_CLASS (phosh_layer_surface_parent_class)->constructed (object);
 | 
			
		||||
 | 
			
		||||
  gtk_window_set_decorated (GTK_WINDOW (self), FALSE);
 | 
			
		||||
  /* Realize the window so we can get the GDK window */
 | 
			
		||||
  gtk_widget_realize(GTK_WIDGET (self));
 | 
			
		||||
 | 
			
		||||
  gdk_window = gtk_widget_get_window (GTK_WIDGET (self));
 | 
			
		||||
  gdk_wayland_window_set_use_custom_surface (gdk_window);
 | 
			
		||||
  priv->wl_surface = gdk_wayland_window_get_wl_surface (gdk_window);
 | 
			
		||||
 | 
			
		||||
  priv->layer_surface = zwlr_layer_shell_v1_get_layer_surface(priv->layer_shell,
 | 
			
		||||
                                                              priv->wl_surface,
 | 
			
		||||
                                                              priv->wl_output,
 | 
			
		||||
                                                              priv->layer,
 | 
			
		||||
                                                              priv->namespace);
 | 
			
		||||
  zwlr_layer_surface_v1_set_exclusive_zone(priv->layer_surface, priv->exclusive_zone);
 | 
			
		||||
  zwlr_layer_surface_v1_set_size(priv->layer_surface, priv->width, priv->height);
 | 
			
		||||
  zwlr_layer_surface_v1_set_anchor(priv->layer_surface, priv->anchor);
 | 
			
		||||
  zwlr_layer_surface_v1_set_keyboard_interactivity(priv->layer_surface, priv->kbd_interactivity);
 | 
			
		||||
  zwlr_layer_surface_v1_add_listener(priv->layer_surface,
 | 
			
		||||
                                     &layer_surface_listener,
 | 
			
		||||
                                     self);
 | 
			
		||||
  wl_surface_commit(priv->wl_surface);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
phosh_layer_surface_dispose (GObject *object)
 | 
			
		||||
{
 | 
			
		||||
  PhoshLayerSurface *self = PHOSH_LAYER_SURFACE (object);
 | 
			
		||||
  PhoshLayerSurfacePrivate *priv = phosh_layer_surface_get_instance_private (self);
 | 
			
		||||
 | 
			
		||||
  if (priv->layer_surface) {
 | 
			
		||||
    zwlr_layer_surface_v1_destroy(priv->layer_surface);
 | 
			
		||||
    priv->layer_surface = NULL;
 | 
			
		||||
  }
 | 
			
		||||
  g_clear_pointer (&priv->namespace, g_free);
 | 
			
		||||
 | 
			
		||||
  G_OBJECT_CLASS (phosh_layer_surface_parent_class)->dispose (object);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
phosh_layer_surface_class_init (PhoshLayerSurfaceClass *klass)
 | 
			
		||||
{
 | 
			
		||||
  GObjectClass *object_class = (GObjectClass *)klass;
 | 
			
		||||
 | 
			
		||||
  object_class->constructed = phosh_layer_surface_constructed;
 | 
			
		||||
  object_class->dispose = phosh_layer_surface_dispose;
 | 
			
		||||
 | 
			
		||||
  object_class->set_property = phosh_layer_surface_set_property;
 | 
			
		||||
  object_class->get_property = phosh_layer_surface_get_property;
 | 
			
		||||
 | 
			
		||||
  props[PHOSH_LAYER_SURFACE_PROP_LAYER_SHELL] =
 | 
			
		||||
    g_param_spec_pointer (
 | 
			
		||||
      "layer-shell",
 | 
			
		||||
      "Wayland Layer Shell Global",
 | 
			
		||||
      "The layer shell wayland global",
 | 
			
		||||
      G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
 | 
			
		||||
 | 
			
		||||
  props[PHOSH_LAYER_SURFACE_PROP_WL_OUTPUT] =
 | 
			
		||||
    g_param_spec_pointer (
 | 
			
		||||
      "wl-output",
 | 
			
		||||
      "Wayland Output",
 | 
			
		||||
      "The wl_output associated with this surface",
 | 
			
		||||
      G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
 | 
			
		||||
 | 
			
		||||
  props[PHOSH_LAYER_SURFACE_PROP_ANCHOR] =
 | 
			
		||||
    g_param_spec_uint (
 | 
			
		||||
      "anchor",
 | 
			
		||||
      "Anchor edges",
 | 
			
		||||
      "The edges to anchor the surface to",
 | 
			
		||||
      0,
 | 
			
		||||
      G_MAXUINT,
 | 
			
		||||
      0,
 | 
			
		||||
      G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
 | 
			
		||||
 | 
			
		||||
  props[PHOSH_LAYER_SURFACE_PROP_LAYER] =
 | 
			
		||||
    g_param_spec_uint (
 | 
			
		||||
      "layer",
 | 
			
		||||
      "Layer",
 | 
			
		||||
      "The layer the surface should be attached to",
 | 
			
		||||
      0,
 | 
			
		||||
      G_MAXUINT,
 | 
			
		||||
      0,
 | 
			
		||||
      G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
 | 
			
		||||
 | 
			
		||||
  props[PHOSH_LAYER_SURFACE_PROP_KBD_INTERACTIVITY] =
 | 
			
		||||
    g_param_spec_boolean (
 | 
			
		||||
      "kbd-interactivity",
 | 
			
		||||
      "Keyboard interactivity",
 | 
			
		||||
      "Whether the surface interacts with the keyboard",
 | 
			
		||||
      FALSE,
 | 
			
		||||
      G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
 | 
			
		||||
 | 
			
		||||
  props[PHOSH_LAYER_SURFACE_PROP_EXCLUSIVE_ZONE] =
 | 
			
		||||
    g_param_spec_int (
 | 
			
		||||
      "exclusive-zone",
 | 
			
		||||
      "Exclusive Zone",
 | 
			
		||||
      "Set area that is not occluded with other surfaces",
 | 
			
		||||
      -1,
 | 
			
		||||
      G_MAXINT,
 | 
			
		||||
      0,
 | 
			
		||||
      G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
 | 
			
		||||
 | 
			
		||||
  props[PHOSH_LAYER_SURFACE_PROP_LAYER_WIDTH] =
 | 
			
		||||
    g_param_spec_uint (
 | 
			
		||||
      "width",
 | 
			
		||||
      "Width",
 | 
			
		||||
      "The width of the layer surface",
 | 
			
		||||
      0,
 | 
			
		||||
      G_MAXUINT,
 | 
			
		||||
      0,
 | 
			
		||||
      G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
 | 
			
		||||
 | 
			
		||||
  props[PHOSH_LAYER_SURFACE_PROP_LAYER_HEIGHT] =
 | 
			
		||||
    g_param_spec_uint (
 | 
			
		||||
      "height",
 | 
			
		||||
      "Height",
 | 
			
		||||
      "The height of the layer surface",
 | 
			
		||||
      0,
 | 
			
		||||
      G_MAXUINT,
 | 
			
		||||
      0,
 | 
			
		||||
      G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
 | 
			
		||||
 | 
			
		||||
  props[PHOSH_LAYER_SURFACE_PROP_NAMESPACE] =
 | 
			
		||||
    g_param_spec_string (
 | 
			
		||||
      "namespace",
 | 
			
		||||
      "Namespace",
 | 
			
		||||
      "Namespace of the layer surface",
 | 
			
		||||
      "",
 | 
			
		||||
      G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
 | 
			
		||||
 | 
			
		||||
  g_object_class_install_properties (object_class, PHOSH_LAYER_SURFACE_PROP_LAST_PROP, props);
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * PhoshLayersurface::configured
 | 
			
		||||
   * @self: The #PhoshLayersurface instance.
 | 
			
		||||
   *
 | 
			
		||||
   * This signal is emitted once we received the configure event from the
 | 
			
		||||
   * compositor.
 | 
			
		||||
   */
 | 
			
		||||
  signals[CONFIGURED] =
 | 
			
		||||
    g_signal_new ("configured",
 | 
			
		||||
                  G_TYPE_FROM_CLASS (klass),
 | 
			
		||||
                  G_SIGNAL_RUN_LAST,
 | 
			
		||||
                  G_STRUCT_OFFSET (PhoshLayerSurfaceClass, configured),
 | 
			
		||||
                  NULL, NULL, NULL,
 | 
			
		||||
                  G_TYPE_NONE, 0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
phosh_layer_surface_init (PhoshLayerSurface *self)
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GtkWidget *
 | 
			
		||||
phosh_layer_surface_new (gpointer layer_shell,
 | 
			
		||||
                         gpointer wl_output)
 | 
			
		||||
{
 | 
			
		||||
  return g_object_new (PHOSH_TYPE_LAYER_SURFACE,
 | 
			
		||||
                       "layer-shell", layer_shell,
 | 
			
		||||
                       "wl-output", wl_output);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
struct zwlr_layer_surface_v1 *
 | 
			
		||||
phosh_layer_surface_get_layer_surface(PhoshLayerSurface *self)
 | 
			
		||||
{
 | 
			
		||||
  PhoshLayerSurfacePrivate *priv;
 | 
			
		||||
 | 
			
		||||
  g_return_val_if_fail (PHOSH_IS_LAYER_SURFACE (self), NULL);
 | 
			
		||||
  priv = phosh_layer_surface_get_instance_private (self);
 | 
			
		||||
  return priv->layer_surface;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
struct wl_surface *
 | 
			
		||||
phosh_layer_surface_get_wl_surface(PhoshLayerSurface *self)
 | 
			
		||||
{
 | 
			
		||||
  PhoshLayerSurfacePrivate *priv;
 | 
			
		||||
 | 
			
		||||
  g_return_val_if_fail (PHOSH_IS_LAYER_SURFACE (self), NULL);
 | 
			
		||||
  priv = phosh_layer_surface_get_instance_private (self);
 | 
			
		||||
  return priv->wl_surface;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										41
									
								
								eek/layersurface.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								eek/layersurface.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,41 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2018 Purism SPC
 | 
			
		||||
 *
 | 
			
		||||
 * SPDX-License-Identifier: GPL-3.0+
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 | 
			
		||||
WARNING: this file is taken directly from phosh, with no modificaions apart from this message. Please update phosh instead of changing this file. Please copy the file back here afterwards, with the same notice.
 | 
			
		||||
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include <gtk/gtk.h>
 | 
			
		||||
/* TODO: We use the enum constants from here, use glib-mkenums */
 | 
			
		||||
#include "wlr-layer-shell-unstable-v1-client-protocol.h"
 | 
			
		||||
 | 
			
		||||
#define PHOSH_TYPE_LAYER_SURFACE                 (phosh_layer_surface_get_type ())
 | 
			
		||||
 | 
			
		||||
G_DECLARE_DERIVABLE_TYPE (PhoshLayerSurface, phosh_layer_surface, PHOSH, LAYER_SURFACE, GtkWindow)
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * PhoshLayerSurfaceClass
 | 
			
		||||
 * @parent_class: The parent class
 | 
			
		||||
 */
 | 
			
		||||
struct _PhoshLayerSurfaceClass
 | 
			
		||||
{
 | 
			
		||||
  GtkWindowClass parent_class;
 | 
			
		||||
 | 
			
		||||
  /* Signals
 | 
			
		||||
   */
 | 
			
		||||
  void (*configured)   (PhoshLayerSurface    *self);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
GtkWidget *phosh_layer_surface_new (gpointer layer_shell,
 | 
			
		||||
                                    gpointer wl_output);
 | 
			
		||||
struct     zwlr_layer_surface_v1 *phosh_layer_surface_get_layer_surface(PhoshLayerSurface *self);
 | 
			
		||||
struct     wl_surface            *phosh_layer_surface_get_wl_surface(PhoshLayerSurface *self);
 | 
			
		||||
							
								
								
									
										44
									
								
								eek/meson.build
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								eek/meson.build
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,44 @@
 | 
			
		||||
gnome = import('gnome')
 | 
			
		||||
 | 
			
		||||
enum_headers = [
 | 
			
		||||
  'eek-symbol.h',
 | 
			
		||||
  'eek-types.h',
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
enums = gnome.mkenums_simple('eek-enumtypes', sources: enum_headers)
 | 
			
		||||
 | 
			
		||||
marshalers = gnome.genmarshal(
 | 
			
		||||
  'eek-marshalers',
 | 
			
		||||
  sources: ['eek-marshalers.list'],
 | 
			
		||||
  prefix: '_eek_marshal',
 | 
			
		||||
  internal: true,
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
python = find_program('python3')
 | 
			
		||||
 | 
			
		||||
gen_keysym_entries_special = generator(
 | 
			
		||||
  python,
 | 
			
		||||
  arguments: ['@CURRENT_SOURCE_DIR@/gen-keysym-entries.py', 'special_keysym_entries', '@INPUT@'],
 | 
			
		||||
  capture: true,
 | 
			
		||||
  output: 'eek-@BASENAME@.h',
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
gen_keysym_entries_unicode = generator(
 | 
			
		||||
  python,
 | 
			
		||||
  arguments: ['@CURRENT_SOURCE_DIR@/gen-keysym-entries.py', 'unicode_keysym_entries', '@INPUT@'],
 | 
			
		||||
  capture: true,
 | 
			
		||||
  output: 'eek-@BASENAME@.h',
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
gen_keysym_entries_xkeysym = generator(
 | 
			
		||||
  python,
 | 
			
		||||
  arguments: ['@CURRENT_SOURCE_DIR@/gen-keysym-entries.py', 'xkeysym_keysym_entries', '@INPUT@'],
 | 
			
		||||
  capture: true,
 | 
			
		||||
  output: 'eek-@BASENAME@.h',
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
keysym_entries = [
 | 
			
		||||
  gen_keysym_entries_special.process('./special-keysym-entries.txt'),
 | 
			
		||||
  gen_keysym_entries_unicode.process('./unicode-keysym-entries.txt'),
 | 
			
		||||
  gen_keysym_entries_xkeysym.process('./xkeysym-keysym-entries.txt'),
 | 
			
		||||
]
 | 
			
		||||
@ -30,7 +30,7 @@
 | 
			
		||||
0xFF9E "Ins" EEK_SYMBOL_CATEGORY_FUNCTION
 | 
			
		||||
0xFF9F "Del" EEK_SYMBOL_CATEGORY_FUNCTION
 | 
			
		||||
# aliases
 | 
			
		||||
0xFE03 "⇮" EEK_SYMBOL_CATEGORY_KEYNAME
 | 
			
		||||
0xFE03 "123" EEK_SYMBOL_CATEGORY_KEYNAME
 | 
			
		||||
0xFE04 "⇮" EEK_SYMBOL_CATEGORY_KEYNAME
 | 
			
		||||
0xFE05 "⇮" EEK_SYMBOL_CATEGORY_KEYNAME
 | 
			
		||||
0xFE08 "Next" EEK_SYMBOL_CATEGORY_KEYNAME
 | 
			
		||||
 | 
			
		||||
@ -1,105 +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
 | 
			
		||||
 | 
			
		||||
lib_LTLIBRARIES = libeekboard.la
 | 
			
		||||
 | 
			
		||||
libeekboard_headers =				\
 | 
			
		||||
	eekboard-service.h			\
 | 
			
		||||
	eekboard-context-service.h		\
 | 
			
		||||
	eekboard-client.h			\
 | 
			
		||||
	eekboard-context.h			\
 | 
			
		||||
	eekboard-xklutil.h
 | 
			
		||||
libeekboard_private_headers =			\
 | 
			
		||||
	eekboard-marshalers.h
 | 
			
		||||
libeekboard_sources =				\
 | 
			
		||||
	eekboard-service.c			\
 | 
			
		||||
	eekboard-context-service.c		\
 | 
			
		||||
	eekboard-client.c			\
 | 
			
		||||
	eekboard-context.c			\
 | 
			
		||||
	eekboard-xklutil.c
 | 
			
		||||
 | 
			
		||||
libeekboard_marshalers_sources =		\
 | 
			
		||||
	eekboard-marshalers.c			\
 | 
			
		||||
	eekboard-marshalers.h
 | 
			
		||||
 | 
			
		||||
BUILT_SOURCES =					\
 | 
			
		||||
	$(libeekboard_marshalers_sources)
 | 
			
		||||
 | 
			
		||||
libeekboard_la_SOURCES =			\
 | 
			
		||||
	$(libeekboard_sources)			\
 | 
			
		||||
	eekboard-marshalers.c
 | 
			
		||||
 | 
			
		||||
libeekboard_la_CFLAGS =					\
 | 
			
		||||
	-DEEKBOARD_COMPILATION=1			\
 | 
			
		||||
	-DKEYBOARDDIR=\"$(pkgdatadir)/keyboards\"	\
 | 
			
		||||
	-I$(top_srcdir)					\
 | 
			
		||||
	$(GIO2_CFLAGS)					\
 | 
			
		||||
	$(LIBXKLAVIER_CFLAGS)
 | 
			
		||||
libeekboard_la_LIBADD =				\
 | 
			
		||||
	$(top_builddir)/eek/libeek.la		\
 | 
			
		||||
	$(top_builddir)/eek/libeek-xkl.la	\
 | 
			
		||||
	$(GIO2_LIBS)				\
 | 
			
		||||
	$(LIBXKLAVIER_LIBS)
 | 
			
		||||
 | 
			
		||||
eekboarddir = $(includedir)/eekboard-$(EEK_API_VERSION)/eekboard
 | 
			
		||||
eekboard_HEADERS = $(libeekboard_headers)
 | 
			
		||||
 | 
			
		||||
pkgconfigdir = $(libdir)/pkgconfig
 | 
			
		||||
pkgconfig_DATA =				\
 | 
			
		||||
	eekboard-$(EEK_API_VERSION).pc
 | 
			
		||||
DISTCLEANFILES =				\
 | 
			
		||||
	$(BUILT_SOURCES)			\
 | 
			
		||||
	$(pkgconfig_DATA)
 | 
			
		||||
 | 
			
		||||
CLEANFILES =
 | 
			
		||||
 | 
			
		||||
EXTRA_DIST = eekboard-marshalers.list
 | 
			
		||||
 | 
			
		||||
# gen marshal
 | 
			
		||||
eekboard-marshalers.h: eekboard-marshalers.list
 | 
			
		||||
	$(AM_V_GEN) $(GLIB_GENMARSHAL) --prefix=_eekboard_marshal $(srcdir)/eekboard-marshalers.list --header --internal > $@.tmp && \
 | 
			
		||||
	mv $@.tmp $@
 | 
			
		||||
 | 
			
		||||
eekboard-marshalers.c: eekboard-marshalers.list eekboard-marshalers.h
 | 
			
		||||
	$(AM_V_GEN) (echo "#include \"eekboard-marshalers.h\""; \
 | 
			
		||||
	$(GLIB_GENMARSHAL) --prefix=_eekboard_marshal $(srcdir)/eekboard-marshalers.list --body --internal) > $@.tmp && \
 | 
			
		||||
	mv $@.tmp $@
 | 
			
		||||
 | 
			
		||||
-include $(INTROSPECTION_MAKEFILE)
 | 
			
		||||
INTROSPECTION_GIRS =
 | 
			
		||||
INTROSPECTION_SCANNER_ARGS = --add-include-path=$(builddir) --add-include-path=$(top_builddir)/eek
 | 
			
		||||
INTROSPECTION_COMPILER_ARGS = --includedir=$(srcdir) --includedir=$(top_srcdir)/eek
 | 
			
		||||
 | 
			
		||||
if HAVE_INTROSPECTION
 | 
			
		||||
Eekboard@EEK_LIBRARY_SUFFIX@.gir: libeekboard.la
 | 
			
		||||
Eekboard@EEK_LIBRARY_SUFFIX_U@_gir_SCANNERFLAGS = --strip-prefix=Eekboard
 | 
			
		||||
Eekboard@EEK_LIBRARY_SUFFIX_U@_gir_INCLUDES = Eek@EEK_LIBRARY_SUFFIX@
 | 
			
		||||
Eekboard@EEK_LIBRARY_SUFFIX_U@_gir_CFLAGS = $(libeekboard_la_CFLAGS)
 | 
			
		||||
Eekboard@EEK_LIBRARY_SUFFIX_U@_gir_LIBS = libeekboard.la
 | 
			
		||||
Eekboard@EEK_LIBRARY_SUFFIX_U@_gir_FILES = $(libeekboard_sources) $(libeekboard_headers)
 | 
			
		||||
 | 
			
		||||
INTROSPECTION_GIRS += Eekboard@EEK_LIBRARY_SUFFIX@.gir
 | 
			
		||||
 | 
			
		||||
girdir = $(datadir)/gir-1.0
 | 
			
		||||
gir_DATA = $(INTROSPECTION_GIRS)
 | 
			
		||||
 | 
			
		||||
typelibdir = $(libdir)/girepository-1.0
 | 
			
		||||
typelib_DATA = $(INTROSPECTION_GIRS:.gir=.typelib)
 | 
			
		||||
 | 
			
		||||
CLEANFILES += $(gir_DATA) $(typelib_DATA)
 | 
			
		||||
endif
 | 
			
		||||
@ -36,15 +36,12 @@ enum {
 | 
			
		||||
 | 
			
		||||
static guint signals[LAST_SIGNAL] = { 0, };
 | 
			
		||||
 | 
			
		||||
G_DEFINE_TYPE (EekboardClient, eekboard_client, G_TYPE_DBUS_PROXY);
 | 
			
		||||
 | 
			
		||||
#define EEKBOARD_CLIENT_GET_PRIVATE(obj)                                \
 | 
			
		||||
    (G_TYPE_INSTANCE_GET_PRIVATE ((obj), EEKBOARD_TYPE_CLIENT, EekboardClientPrivate))
 | 
			
		||||
 | 
			
		||||
struct _EekboardClientPrivate
 | 
			
		||||
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,
 | 
			
		||||
@ -53,7 +50,7 @@ static void send_destroy_context (EekboardClient  *client,
 | 
			
		||||
static void
 | 
			
		||||
eekboard_client_real_destroyed (EekboardClient *self)
 | 
			
		||||
{
 | 
			
		||||
    EekboardClientPrivate *priv = EEKBOARD_CLIENT_GET_PRIVATE(self);
 | 
			
		||||
    EekboardClientPrivate *priv = eekboard_client_get_instance_private (self);
 | 
			
		||||
 | 
			
		||||
    // g_debug ("eekboard_client_real_destroyed");
 | 
			
		||||
    g_hash_table_remove_all (priv->context_hash);
 | 
			
		||||
@ -63,7 +60,7 @@ static void
 | 
			
		||||
eekboard_client_dispose (GObject *object)
 | 
			
		||||
{
 | 
			
		||||
    EekboardClient *client = EEKBOARD_CLIENT(object);
 | 
			
		||||
    EekboardClientPrivate *priv = EEKBOARD_CLIENT_GET_PRIVATE(client);
 | 
			
		||||
    EekboardClientPrivate *priv = eekboard_client_get_instance_private (client);
 | 
			
		||||
 | 
			
		||||
    if (priv->context_hash) {
 | 
			
		||||
        GHashTableIter iter;
 | 
			
		||||
@ -86,9 +83,6 @@ eekboard_client_class_init (EekboardClientClass *klass)
 | 
			
		||||
{
 | 
			
		||||
    GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
 | 
			
		||||
 | 
			
		||||
    g_type_class_add_private (gobject_class,
 | 
			
		||||
                              sizeof (EekboardClientPrivate));
 | 
			
		||||
 | 
			
		||||
    klass->destroyed = eekboard_client_real_destroyed;
 | 
			
		||||
 | 
			
		||||
    gobject_class->dispose = eekboard_client_dispose;
 | 
			
		||||
@ -115,8 +109,9 @@ eekboard_client_class_init (EekboardClientClass *klass)
 | 
			
		||||
static void
 | 
			
		||||
eekboard_client_init (EekboardClient *self)
 | 
			
		||||
{
 | 
			
		||||
    self->priv = EEKBOARD_CLIENT_GET_PRIVATE(self);
 | 
			
		||||
    self->priv->context_hash =
 | 
			
		||||
    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,
 | 
			
		||||
@ -189,7 +184,9 @@ on_context_destroyed (EekboardContext *context,
 | 
			
		||||
                      gpointer         user_data)
 | 
			
		||||
{
 | 
			
		||||
    EekboardClient *client = user_data;
 | 
			
		||||
    g_hash_table_remove (client->priv->context_hash,
 | 
			
		||||
    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)));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -239,7 +236,9 @@ eekboard_client_create_context (EekboardClient *client,
 | 
			
		||||
        return NULL;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    g_hash_table_insert (client->priv->context_hash,
 | 
			
		||||
    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",
 | 
			
		||||
@ -284,9 +283,11 @@ eekboard_client_push_context (EekboardClient  *client,
 | 
			
		||||
    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 (client->priv->context_hash,
 | 
			
		||||
    context = g_hash_table_lookup (priv->context_hash,
 | 
			
		||||
                                   object_path);
 | 
			
		||||
    if (!context)
 | 
			
		||||
        return;
 | 
			
		||||
@ -325,6 +326,38 @@ eekboard_client_pop_context (EekboardClient *client,
 | 
			
		||||
                       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,
 | 
			
		||||
@ -362,8 +395,10 @@ eekboard_client_destroy_context (EekboardClient  *client,
 | 
			
		||||
    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 (client->priv->context_hash, object_path);
 | 
			
		||||
    g_hash_table_remove (priv->context_hash, object_path);
 | 
			
		||||
 | 
			
		||||
    send_destroy_context (client, context, cancellable);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -26,22 +26,7 @@
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
#define EEKBOARD_TYPE_CLIENT (eekboard_client_get_type())
 | 
			
		||||
#define EEKBOARD_CLIENT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EEKBOARD_TYPE_CLIENT, EekboardClient))
 | 
			
		||||
#define EEKBOARD_CLIENT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EEKBOARD_TYPE_CLIENT, EekboardClientClass))
 | 
			
		||||
#define EEKBOARD_IS_CLIENT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EEKBOARD_TYPE_CLIENT))
 | 
			
		||||
#define EEKBOARD_IS_CLIENT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EEKBOARD_TYPE_CLIENT))
 | 
			
		||||
#define EEKBOARD_CLIENT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EEKBOARD_TYPE_CLIENT, EekboardClientClass))
 | 
			
		||||
 | 
			
		||||
typedef struct _EekboardClient EekboardClient;
 | 
			
		||||
typedef struct _EekboardClientClass EekboardClientClass;
 | 
			
		||||
typedef struct _EekboardClientPrivate EekboardClientPrivate;
 | 
			
		||||
 | 
			
		||||
struct _EekboardClient {
 | 
			
		||||
    /*< private >*/
 | 
			
		||||
    GDBusProxy parent;
 | 
			
		||||
 | 
			
		||||
    EekboardClientPrivate *priv;
 | 
			
		||||
};
 | 
			
		||||
G_DECLARE_DERIVABLE_TYPE (EekboardClient, eekboard_client, EEKBOARD, CLIENT, GDBusProxy)
 | 
			
		||||
 | 
			
		||||
struct _EekboardClientClass {
 | 
			
		||||
    /*< private >*/
 | 
			
		||||
@ -67,6 +52,10 @@ void             eekboard_client_push_context    (EekboardClient  *eekboard,
 | 
			
		||||
                                                  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);
 | 
			
		||||
 | 
			
		||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@ -24,6 +24,8 @@
 | 
			
		||||
 | 
			
		||||
#include <eek/eek.h>
 | 
			
		||||
 | 
			
		||||
#include "virtual-keyboard-unstable-v1-client-protocol.h"
 | 
			
		||||
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
#define EEKBOARD_CONTEXT_SERVICE_PATH "/org/fedorahosted/Eekboard/Context_%d"
 | 
			
		||||
@ -36,13 +38,16 @@ G_BEGIN_DECLS
 | 
			
		||||
#define EEKBOARD_IS_CONTEXT_SERVICE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EEKBOARD_TYPE_CONTEXT_SERVICE))
 | 
			
		||||
#define EEKBOARD_CONTEXT_SERVICE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EEKBOARD_TYPE_CONTEXT_SERVICE, EekboardContextServiceClass))
 | 
			
		||||
 | 
			
		||||
typedef struct _EekboardContextService EekboardContextService;
 | 
			
		||||
 | 
			
		||||
typedef struct _EekboardContextServiceClass EekboardContextServiceClass;
 | 
			
		||||
typedef struct _EekboardContextServicePrivate EekboardContextServicePrivate;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * EekboardContextService:
 | 
			
		||||
 *
 | 
			
		||||
 * TODO: Restrict to managing keyboard layouts, and maybe button repeats,
 | 
			
		||||
 * and the virtual keyboard protocol.
 | 
			
		||||
 *
 | 
			
		||||
 * The #EekboardContextService structure contains only private data
 | 
			
		||||
 * and should only be accessed using the provided API.
 | 
			
		||||
 */
 | 
			
		||||
@ -50,6 +55,8 @@ struct _EekboardContextService {
 | 
			
		||||
    GObject parent;
 | 
			
		||||
 | 
			
		||||
    EekboardContextServicePrivate *priv;
 | 
			
		||||
 | 
			
		||||
    struct zwp_virtual_keyboard_v1 *virtual_keyboard;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@ -84,13 +91,18 @@ GType         eekboard_context_service_get_type
 | 
			
		||||
                                              (void) G_GNUC_CONST;
 | 
			
		||||
void          eekboard_context_service_enable (EekboardContextService *context);
 | 
			
		||||
void          eekboard_context_service_disable (EekboardContextService *context);
 | 
			
		||||
void          eekboard_context_service_show_keyboard
 | 
			
		||||
                                              (EekboardContextService *context);
 | 
			
		||||
void          eekboard_context_service_hide_keyboard
 | 
			
		||||
                                              (EekboardContextService *context);
 | 
			
		||||
void          eekboard_context_service_destroy (EekboardContextService *context);
 | 
			
		||||
EekKeyboard  *eekboard_context_service_get_keyboard
 | 
			
		||||
                                              (EekboardContextService *context);
 | 
			
		||||
gboolean      eekboard_context_service_get_fullscreen
 | 
			
		||||
                                              (EekboardContextService *context);
 | 
			
		||||
const gchar * eekboard_context_service_get_client_name
 | 
			
		||||
                                              (EekboardContextService *context);
 | 
			
		||||
 | 
			
		||||
void eekboard_context_service_set_keymap(EekboardContextService *context,
 | 
			
		||||
                                         const EekKeyboard *keyboard);
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
#endif  /* EEKBOARD_CONTEXT_SERVICE_H */
 | 
			
		||||
 | 
			
		||||
@ -29,7 +29,7 @@
 | 
			
		||||
#endif  /* HAVE_CONFIG_H */
 | 
			
		||||
 | 
			
		||||
#include "eekboard/eekboard-context.h"
 | 
			
		||||
#include "eekboard/eekboard-marshalers.h"
 | 
			
		||||
//#include "eekboard/eekboard-marshalers.h"
 | 
			
		||||
 | 
			
		||||
#define I_(string) g_intern_static_string (string)
 | 
			
		||||
 | 
			
		||||
@ -49,18 +49,15 @@ enum {
 | 
			
		||||
    PROP_LAST
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
G_DEFINE_TYPE (EekboardContext, eekboard_context, G_TYPE_DBUS_PROXY);
 | 
			
		||||
 | 
			
		||||
#define EEKBOARD_CONTEXT_GET_PRIVATE(obj)                               \
 | 
			
		||||
    (G_TYPE_INSTANCE_GET_PRIVATE ((obj), EEKBOARD_TYPE_CONTEXT, EekboardContextPrivate))
 | 
			
		||||
 | 
			
		||||
struct _EekboardContextPrivate
 | 
			
		||||
typedef struct _EekboardContextPrivate
 | 
			
		||||
{
 | 
			
		||||
    gboolean visible;
 | 
			
		||||
    gboolean enabled;
 | 
			
		||||
    gboolean fullscreen;
 | 
			
		||||
    gint group;
 | 
			
		||||
};
 | 
			
		||||
} EekboardContextPrivate;
 | 
			
		||||
 | 
			
		||||
G_DEFINE_TYPE_WITH_PRIVATE (EekboardContext, eekboard_context, G_TYPE_DBUS_PROXY)
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
eekboard_context_real_g_signal (GDBusProxy  *self,
 | 
			
		||||
@ -69,6 +66,7 @@ eekboard_context_real_g_signal (GDBusProxy  *self,
 | 
			
		||||
                                GVariant    *parameters)
 | 
			
		||||
{
 | 
			
		||||
    EekboardContext *context = EEKBOARD_CONTEXT (self);
 | 
			
		||||
    EekboardContextPrivate *priv = eekboard_context_get_instance_private (context);
 | 
			
		||||
 | 
			
		||||
    if (g_strcmp0 (signal_name, "Enabled") == 0) {
 | 
			
		||||
        g_signal_emit (context, signals[ENABLED], 0);
 | 
			
		||||
@ -111,8 +109,8 @@ eekboard_context_real_g_signal (GDBusProxy  *self,
 | 
			
		||||
        gboolean visible = FALSE;
 | 
			
		||||
 | 
			
		||||
        g_variant_get (parameters, "(b)", &visible);
 | 
			
		||||
        if (visible != context->priv->visible) {
 | 
			
		||||
            context->priv->visible = visible;
 | 
			
		||||
        if (visible != priv->visible) {
 | 
			
		||||
            priv->visible = visible;
 | 
			
		||||
            g_object_notify (G_OBJECT(context), "visible");
 | 
			
		||||
        }
 | 
			
		||||
        return;
 | 
			
		||||
@ -122,8 +120,8 @@ eekboard_context_real_g_signal (GDBusProxy  *self,
 | 
			
		||||
        gint group = 0;
 | 
			
		||||
 | 
			
		||||
        g_variant_get (parameters, "(i)", &group);
 | 
			
		||||
        if (group != context->priv->group) {
 | 
			
		||||
            context->priv->group = group;
 | 
			
		||||
        if (group != priv->group) {
 | 
			
		||||
            priv->group = group;
 | 
			
		||||
            /* g_object_notify (G_OBJECT(context), "group"); */
 | 
			
		||||
        }
 | 
			
		||||
        return;
 | 
			
		||||
@ -135,13 +133,17 @@ eekboard_context_real_g_signal (GDBusProxy  *self,
 | 
			
		||||
static void
 | 
			
		||||
eekboard_context_real_enabled (EekboardContext *self)
 | 
			
		||||
{
 | 
			
		||||
    self->priv->enabled = TRUE;
 | 
			
		||||
    EekboardContextPrivate *priv = eekboard_context_get_instance_private (self);
 | 
			
		||||
 | 
			
		||||
    priv->enabled = TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
eekboard_context_real_disabled (EekboardContext *self)
 | 
			
		||||
{
 | 
			
		||||
    self->priv->enabled = FALSE;
 | 
			
		||||
    EekboardContextPrivate *priv = eekboard_context_get_instance_private (self);
 | 
			
		||||
 | 
			
		||||
    priv->enabled = FALSE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
@ -151,7 +153,7 @@ eekboard_context_real_destroyed (EekboardContext *self)
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
eekboard_context_real_key_activated (EekboardContext *self,
 | 
			
		||||
                                     const gchar     *keyname,
 | 
			
		||||
                                     guint            keycode,
 | 
			
		||||
                                     EekSymbol       *symbol,
 | 
			
		||||
                                     guint            modifiers)
 | 
			
		||||
{
 | 
			
		||||
@ -164,9 +166,11 @@ eekboard_context_get_property (GObject    *object,
 | 
			
		||||
                               GParamSpec *pspec)
 | 
			
		||||
{
 | 
			
		||||
    EekboardContext *context = EEKBOARD_CONTEXT(object);
 | 
			
		||||
    EekboardContextPrivate *priv = eekboard_context_get_instance_private (context);
 | 
			
		||||
 | 
			
		||||
    switch (prop_id) {
 | 
			
		||||
    case PROP_VISIBLE:
 | 
			
		||||
        g_value_set_boolean (value, context->priv->visible);
 | 
			
		||||
        g_value_set_boolean (value, priv->visible);
 | 
			
		||||
        break;
 | 
			
		||||
    default:
 | 
			
		||||
        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 | 
			
		||||
@ -181,9 +185,6 @@ eekboard_context_class_init (EekboardContextClass *klass)
 | 
			
		||||
    GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
 | 
			
		||||
    GParamSpec        *pspec;
 | 
			
		||||
 | 
			
		||||
    g_type_class_add_private (gobject_class,
 | 
			
		||||
                              sizeof (EekboardContextPrivate));
 | 
			
		||||
 | 
			
		||||
    klass->enabled = eekboard_context_real_enabled;
 | 
			
		||||
    klass->disabled = eekboard_context_real_disabled;
 | 
			
		||||
    klass->destroyed = eekboard_context_real_destroyed;
 | 
			
		||||
@ -251,6 +252,7 @@ eekboard_context_class_init (EekboardContextClass *klass)
 | 
			
		||||
     * The ::key-activated signal is emitted each time a key is
 | 
			
		||||
     * pressed in @context.
 | 
			
		||||
     */
 | 
			
		||||
    /*
 | 
			
		||||
    signals[KEY_ACTIVATED] =
 | 
			
		||||
        g_signal_new (I_("key-activated"),
 | 
			
		||||
                      G_TYPE_FROM_CLASS(gobject_class),
 | 
			
		||||
@ -264,7 +266,7 @@ eekboard_context_class_init (EekboardContextClass *klass)
 | 
			
		||||
                      G_TYPE_UINT,
 | 
			
		||||
                      G_TYPE_OBJECT,
 | 
			
		||||
                      G_TYPE_UINT);
 | 
			
		||||
 | 
			
		||||
*/
 | 
			
		||||
    /**
 | 
			
		||||
     * EekboardContext::destroyed:
 | 
			
		||||
     * @context: an #EekboardContext
 | 
			
		||||
@ -287,7 +289,7 @@ eekboard_context_class_init (EekboardContextClass *klass)
 | 
			
		||||
static void
 | 
			
		||||
eekboard_context_init (EekboardContext *self)
 | 
			
		||||
{
 | 
			
		||||
    self->priv = EEKBOARD_CONTEXT_GET_PRIVATE(self);
 | 
			
		||||
    /* void */
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
@ -484,7 +486,9 @@ eekboard_context_set_group (EekboardContext *context,
 | 
			
		||||
{
 | 
			
		||||
    g_return_if_fail (EEKBOARD_IS_CONTEXT(context));
 | 
			
		||||
 | 
			
		||||
    if (context->priv->group != group) {
 | 
			
		||||
    EekboardContextPrivate *priv = eekboard_context_get_instance_private (context);
 | 
			
		||||
 | 
			
		||||
    if (priv->group != group) {
 | 
			
		||||
        g_dbus_proxy_call (G_DBUS_PROXY(context),
 | 
			
		||||
                           "SetGroup",
 | 
			
		||||
                           g_variant_new ("(i)", group),
 | 
			
		||||
@ -508,7 +512,10 @@ eekboard_context_get_group (EekboardContext *context,
 | 
			
		||||
                            GCancellable    *cancellable)
 | 
			
		||||
{
 | 
			
		||||
    g_return_val_if_fail (EEKBOARD_IS_CONTEXT(context), 0);
 | 
			
		||||
    return context->priv->group;
 | 
			
		||||
 | 
			
		||||
    EekboardContextPrivate *priv = eekboard_context_get_instance_private (context);
 | 
			
		||||
 | 
			
		||||
    return priv->group;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@ -525,7 +532,9 @@ eekboard_context_show_keyboard (EekboardContext *context,
 | 
			
		||||
{
 | 
			
		||||
    g_return_if_fail (EEKBOARD_IS_CONTEXT(context));
 | 
			
		||||
 | 
			
		||||
    if (context->priv->enabled) {
 | 
			
		||||
    EekboardContextPrivate *priv = eekboard_context_get_instance_private (context);
 | 
			
		||||
 | 
			
		||||
    if (priv->enabled) {
 | 
			
		||||
        g_dbus_proxy_call (G_DBUS_PROXY(context),
 | 
			
		||||
                           "ShowKeyboard",
 | 
			
		||||
                           NULL,
 | 
			
		||||
@ -550,7 +559,9 @@ eekboard_context_hide_keyboard (EekboardContext *context,
 | 
			
		||||
{
 | 
			
		||||
    g_return_if_fail (EEKBOARD_IS_CONTEXT(context));
 | 
			
		||||
 | 
			
		||||
    if (context->priv->enabled) {
 | 
			
		||||
    EekboardContextPrivate *priv = eekboard_context_get_instance_private (context);
 | 
			
		||||
 | 
			
		||||
    if (priv->enabled) {
 | 
			
		||||
        g_dbus_proxy_call (G_DBUS_PROXY(context),
 | 
			
		||||
                           "HideKeyboard",
 | 
			
		||||
                           NULL,
 | 
			
		||||
@ -577,7 +588,9 @@ eekboard_context_press_keycode (EekboardContext *context,
 | 
			
		||||
{
 | 
			
		||||
    g_return_if_fail (EEKBOARD_IS_CONTEXT(context));
 | 
			
		||||
 | 
			
		||||
    if (context->priv->enabled) {
 | 
			
		||||
    EekboardContextPrivate *priv = eekboard_context_get_instance_private (context);
 | 
			
		||||
 | 
			
		||||
    if (priv->enabled) {
 | 
			
		||||
        g_dbus_proxy_call (G_DBUS_PROXY(context),
 | 
			
		||||
                           "PressKeycode",
 | 
			
		||||
                           g_variant_new ("(u)", keycode),
 | 
			
		||||
@ -604,7 +617,9 @@ eekboard_context_release_keycode (EekboardContext *context,
 | 
			
		||||
{
 | 
			
		||||
    g_return_if_fail (EEKBOARD_IS_CONTEXT(context));
 | 
			
		||||
 | 
			
		||||
    if (context->priv->enabled) {
 | 
			
		||||
    EekboardContextPrivate *priv = eekboard_context_get_instance_private (context);
 | 
			
		||||
 | 
			
		||||
    if (priv->enabled) {
 | 
			
		||||
        g_dbus_proxy_call (G_DBUS_PROXY(context),
 | 
			
		||||
                           "ReleaseKeycode",
 | 
			
		||||
                           g_variant_new ("(u)", keycode),
 | 
			
		||||
@ -626,7 +641,10 @@ gboolean
 | 
			
		||||
eekboard_context_is_visible (EekboardContext *context)
 | 
			
		||||
{
 | 
			
		||||
    g_return_val_if_fail (EEKBOARD_IS_CONTEXT(context), FALSE);
 | 
			
		||||
    return context->priv->enabled && context->priv->visible;
 | 
			
		||||
 | 
			
		||||
    EekboardContextPrivate *priv = eekboard_context_get_instance_private (context);
 | 
			
		||||
 | 
			
		||||
    return priv->enabled && priv->visible;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@ -643,7 +661,10 @@ eekboard_context_set_enabled (EekboardContext *context,
 | 
			
		||||
                              gboolean         enabled)
 | 
			
		||||
{
 | 
			
		||||
    g_return_if_fail (EEKBOARD_IS_CONTEXT(context));
 | 
			
		||||
    context->priv->enabled = enabled;
 | 
			
		||||
 | 
			
		||||
    EekboardContextPrivate *priv = eekboard_context_get_instance_private (context);
 | 
			
		||||
 | 
			
		||||
    priv->enabled = enabled;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@ -656,7 +677,10 @@ gboolean
 | 
			
		||||
eekboard_context_is_enabled (EekboardContext *context)
 | 
			
		||||
{
 | 
			
		||||
    g_return_val_if_fail (EEKBOARD_IS_CONTEXT(context), FALSE);
 | 
			
		||||
    return context->priv->enabled;
 | 
			
		||||
 | 
			
		||||
    EekboardContextPrivate *priv = eekboard_context_get_instance_private (context);
 | 
			
		||||
 | 
			
		||||
    return priv->enabled;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@ -673,7 +697,10 @@ eekboard_context_set_fullscreen (EekboardContext *context,
 | 
			
		||||
                                 GCancellable    *cancellable)
 | 
			
		||||
{
 | 
			
		||||
    g_return_if_fail (EEKBOARD_IS_CONTEXT(context));
 | 
			
		||||
    if (context->priv->fullscreen != fullscreen) {
 | 
			
		||||
 | 
			
		||||
    EekboardContextPrivate *priv = eekboard_context_get_instance_private (context);
 | 
			
		||||
 | 
			
		||||
    if (priv->fullscreen != fullscreen) {
 | 
			
		||||
        g_dbus_proxy_call (G_DBUS_PROXY(context),
 | 
			
		||||
                           "SetFullscreen",
 | 
			
		||||
                           g_variant_new ("(b)", fullscreen),
 | 
			
		||||
 | 
			
		||||
@ -28,28 +28,7 @@
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
#define EEKBOARD_TYPE_CONTEXT (eekboard_context_get_type())
 | 
			
		||||
#define EEKBOARD_CONTEXT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EEKBOARD_TYPE_CONTEXT, EekboardContext))
 | 
			
		||||
#define EEKBOARD_CONTEXT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EEKBOARD_TYPE_CONTEXT, EekboardContextClass))
 | 
			
		||||
#define EEKBOARD_IS_CONTEXT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EEKBOARD_TYPE_CONTEXT))
 | 
			
		||||
#define EEKBOARD_IS_CONTEXT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EEKBOARD_TYPE_CONTEXT))
 | 
			
		||||
#define EEKBOARD_CONTEXT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EEKBOARD_TYPE_CONTEXT, EekboardContextClass))
 | 
			
		||||
 | 
			
		||||
typedef struct _EekboardContext EekboardContext;
 | 
			
		||||
typedef struct _EekboardContextClass EekboardContextClass;
 | 
			
		||||
typedef struct _EekboardContextPrivate EekboardContextPrivate;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * EekboardContext:
 | 
			
		||||
 *
 | 
			
		||||
 * The #EekboardContext structure contains only private data and
 | 
			
		||||
 * should only be accessed using the provided API.
 | 
			
		||||
 */
 | 
			
		||||
struct _EekboardContext {
 | 
			
		||||
    /*< private >*/
 | 
			
		||||
    GDBusProxy parent;
 | 
			
		||||
 | 
			
		||||
    EekboardContextPrivate *priv;
 | 
			
		||||
};
 | 
			
		||||
G_DECLARE_DERIVABLE_TYPE (EekboardContext, eekboard_context, EEKBOARD, CONTEXT, GDBusProxy)
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * EekboardContextClass:
 | 
			
		||||
 | 
			
		||||
@ -1 +0,0 @@
 | 
			
		||||
VOID:UINT,OBJECT,UINT
 | 
			
		||||
@ -1,7 +1,7 @@
 | 
			
		||||
/* 
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2010-2011 Daiki Ueno <ueno@unixuser.org>
 | 
			
		||||
 * Copyright (C) 2010-2011 Red Hat, Inc.
 | 
			
		||||
 * 
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software: you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU General Public License as published by
 | 
			
		||||
 * the Free Software Foundation, either version 3 of the License, or
 | 
			
		||||
@ -18,7 +18,9 @@
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * SECTION:eekboard-service
 | 
			
		||||
 * @short_description: base server implementation of eekboard service
 | 
			
		||||
 * @short_description: base implementation of eekboard service
 | 
			
		||||
 *
 | 
			
		||||
 * Provides a dbus object, and contains the context.
 | 
			
		||||
 *
 | 
			
		||||
 * The #EekboardService class provides a base server side
 | 
			
		||||
 * implementation of eekboard service.
 | 
			
		||||
@ -30,6 +32,10 @@
 | 
			
		||||
 | 
			
		||||
#include "eekboard/eekboard-service.h"
 | 
			
		||||
 | 
			
		||||
#include "sm.puri.OSK0.h"
 | 
			
		||||
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
 | 
			
		||||
enum {
 | 
			
		||||
    PROP_0,
 | 
			
		||||
    PROP_OBJECT_PATH,
 | 
			
		||||
@ -44,52 +50,18 @@ enum {
 | 
			
		||||
 | 
			
		||||
static guint signals[LAST_SIGNAL] = { 0, };
 | 
			
		||||
 | 
			
		||||
#define EEKBOARD_SERVICE_GET_PRIVATE(obj)                               \
 | 
			
		||||
    (G_TYPE_INSTANCE_GET_PRIVATE ((obj), EEKBOARD_TYPE_SERVICE, EekboardServicePrivate))
 | 
			
		||||
 | 
			
		||||
struct _EekboardServicePrivate {
 | 
			
		||||
typedef struct _EekboardServicePrivate
 | 
			
		||||
{
 | 
			
		||||
    GDBusConnection *connection;
 | 
			
		||||
    SmPuriOSK0 *dbus_interface;
 | 
			
		||||
    GDBusNodeInfo *introspection_data;
 | 
			
		||||
    guint registration_id;
 | 
			
		||||
    char *object_path;
 | 
			
		||||
 | 
			
		||||
    GHashTable *context_hash;
 | 
			
		||||
    GSList *context_stack;
 | 
			
		||||
};
 | 
			
		||||
    EekboardContextService *context; // unowned reference
 | 
			
		||||
} EekboardServicePrivate;
 | 
			
		||||
 | 
			
		||||
G_DEFINE_TYPE (EekboardService, eekboard_service, G_TYPE_OBJECT);
 | 
			
		||||
 | 
			
		||||
static const gchar introspection_xml[] =
 | 
			
		||||
    "<node>"
 | 
			
		||||
    "  <interface name='org.fedorahosted.Eekboard'>"
 | 
			
		||||
    "    <method name='CreateContext'>"
 | 
			
		||||
    "      <arg direction='in' type='s' name='client_name'/>"
 | 
			
		||||
    "      <arg direction='out' type='s' name='object_path'/>"
 | 
			
		||||
    "    </method>"
 | 
			
		||||
    "    <method name='PushContext'>"
 | 
			
		||||
    "      <arg direction='in' type='s' name='object_path'/>"
 | 
			
		||||
    "    </method>"
 | 
			
		||||
    "    <method name='PopContext'/>"
 | 
			
		||||
    "    <method name='Destroy'/>"
 | 
			
		||||
    /* signals */
 | 
			
		||||
    "  </interface>"
 | 
			
		||||
    "</node>";
 | 
			
		||||
 | 
			
		||||
static void handle_method_call (GDBusConnection       *connection,
 | 
			
		||||
                                const gchar           *sender,
 | 
			
		||||
                                const gchar           *object_path,
 | 
			
		||||
                                const gchar           *interface_name,
 | 
			
		||||
                                const gchar           *method_name,
 | 
			
		||||
                                GVariant              *parameters,
 | 
			
		||||
                                GDBusMethodInvocation *invocation,
 | 
			
		||||
                                gpointer               user_data);
 | 
			
		||||
 | 
			
		||||
static const GDBusInterfaceVTable interface_vtable =
 | 
			
		||||
{
 | 
			
		||||
  handle_method_call,
 | 
			
		||||
  NULL,
 | 
			
		||||
  NULL
 | 
			
		||||
};
 | 
			
		||||
G_DEFINE_TYPE_WITH_PRIVATE (EekboardService, eekboard_service, G_TYPE_OBJECT)
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
eekboard_service_set_property (GObject      *object,
 | 
			
		||||
@ -98,19 +70,20 @@ eekboard_service_set_property (GObject      *object,
 | 
			
		||||
                               GParamSpec   *pspec)
 | 
			
		||||
{
 | 
			
		||||
    EekboardService *service = EEKBOARD_SERVICE(object);
 | 
			
		||||
    EekboardServicePrivate *priv = eekboard_service_get_instance_private (service);
 | 
			
		||||
    GDBusConnection *connection;
 | 
			
		||||
 | 
			
		||||
    switch (prop_id) {
 | 
			
		||||
    case PROP_OBJECT_PATH:
 | 
			
		||||
        if (service->priv->object_path)
 | 
			
		||||
            g_free (service->priv->object_path);
 | 
			
		||||
        service->priv->object_path = g_value_dup_string (value);
 | 
			
		||||
        if (priv->object_path)
 | 
			
		||||
            g_free (priv->object_path);
 | 
			
		||||
        priv->object_path = g_value_dup_string (value);
 | 
			
		||||
        break;
 | 
			
		||||
    case PROP_CONNECTION:
 | 
			
		||||
        connection = g_value_get_object (value);
 | 
			
		||||
        if (service->priv->connection)
 | 
			
		||||
            g_object_unref (service->priv->connection);
 | 
			
		||||
        service->priv->connection = g_object_ref (connection);
 | 
			
		||||
        if (priv->connection)
 | 
			
		||||
            g_object_unref (priv->connection);
 | 
			
		||||
        priv->connection = g_object_ref (connection);
 | 
			
		||||
        break;
 | 
			
		||||
    default:
 | 
			
		||||
        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 | 
			
		||||
@ -125,13 +98,14 @@ eekboard_service_get_property (GObject    *object,
 | 
			
		||||
                               GParamSpec *pspec)
 | 
			
		||||
{
 | 
			
		||||
    EekboardService *service = EEKBOARD_SERVICE(object);
 | 
			
		||||
    EekboardServicePrivate *priv = eekboard_service_get_instance_private (service);
 | 
			
		||||
 | 
			
		||||
    switch (prop_id) {
 | 
			
		||||
    case PROP_OBJECT_PATH:
 | 
			
		||||
        g_value_set_string (value, service->priv->object_path);
 | 
			
		||||
        g_value_set_string (value, priv->object_path);
 | 
			
		||||
        break;
 | 
			
		||||
    case PROP_CONNECTION:
 | 
			
		||||
        g_value_set_object (value, service->priv->connection);
 | 
			
		||||
        g_value_set_object (value, priv->connection);
 | 
			
		||||
        break;
 | 
			
		||||
    default:
 | 
			
		||||
        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 | 
			
		||||
@ -143,33 +117,22 @@ static void
 | 
			
		||||
eekboard_service_dispose (GObject *object)
 | 
			
		||||
{
 | 
			
		||||
    EekboardService *service = EEKBOARD_SERVICE(object);
 | 
			
		||||
    GSList *head;
 | 
			
		||||
    EekboardServicePrivate *priv = eekboard_service_get_instance_private (service);
 | 
			
		||||
 | 
			
		||||
    if (service->priv->context_hash) {
 | 
			
		||||
        g_hash_table_destroy (service->priv->context_hash);
 | 
			
		||||
        service->priv->context_hash = NULL;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    for (head = service->priv->context_stack; head; head = service->priv->context_stack) {
 | 
			
		||||
        g_object_unref (head->data);
 | 
			
		||||
        service->priv->context_stack = g_slist_next (head);
 | 
			
		||||
        g_slist_free1 (head);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (service->priv->connection) {
 | 
			
		||||
        if (service->priv->registration_id > 0) {
 | 
			
		||||
            g_dbus_connection_unregister_object (service->priv->connection,
 | 
			
		||||
                                                 service->priv->registration_id);
 | 
			
		||||
            service->priv->registration_id = 0;
 | 
			
		||||
    if (priv->connection) {
 | 
			
		||||
        if (priv->registration_id > 0) {
 | 
			
		||||
            g_dbus_connection_unregister_object (priv->connection,
 | 
			
		||||
                                                 priv->registration_id);
 | 
			
		||||
            priv->registration_id = 0;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        g_object_unref (service->priv->connection);
 | 
			
		||||
        service->priv->connection = NULL;
 | 
			
		||||
        g_object_unref (priv->connection);
 | 
			
		||||
        priv->connection = NULL;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (service->priv->introspection_data) {
 | 
			
		||||
        g_dbus_node_info_unref (service->priv->introspection_data);
 | 
			
		||||
        service->priv->introspection_data = NULL;
 | 
			
		||||
    if (priv->introspection_data) {
 | 
			
		||||
        g_dbus_node_info_unref (priv->introspection_data);
 | 
			
		||||
        priv->introspection_data = NULL;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    G_OBJECT_CLASS (eekboard_service_parent_class)->dispose (object);
 | 
			
		||||
@ -179,32 +142,50 @@ static void
 | 
			
		||||
eekboard_service_finalize (GObject *object)
 | 
			
		||||
{
 | 
			
		||||
    EekboardService *service = EEKBOARD_SERVICE(object);
 | 
			
		||||
    EekboardServicePrivate *priv = eekboard_service_get_instance_private (service);
 | 
			
		||||
 | 
			
		||||
    g_free (service->priv->object_path);
 | 
			
		||||
    g_free (priv->object_path);
 | 
			
		||||
 | 
			
		||||
    G_OBJECT_CLASS (eekboard_service_parent_class)->finalize (object);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
handle_set_visible(SmPuriOSK0 *object, GDBusMethodInvocation *invocation,
 | 
			
		||||
                   gboolean arg_visible, gpointer user_data) {
 | 
			
		||||
    EekboardService *service = user_data;
 | 
			
		||||
    EekboardServicePrivate *priv = eekboard_service_get_instance_private (service);
 | 
			
		||||
 | 
			
		||||
    if (priv->context) {
 | 
			
		||||
        if (arg_visible) {
 | 
			
		||||
            eekboard_context_service_show_keyboard (priv->context);
 | 
			
		||||
        } else {
 | 
			
		||||
            eekboard_context_service_hide_keyboard (priv->context);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    sm_puri_osk0_complete_set_visible(object, invocation);
 | 
			
		||||
    return TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
eekboard_service_constructed (GObject *object)
 | 
			
		||||
{
 | 
			
		||||
    EekboardService *service = EEKBOARD_SERVICE(object);
 | 
			
		||||
    if (service->priv->connection && service->priv->object_path) {
 | 
			
		||||
    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);
 | 
			
		||||
 | 
			
		||||
    if (priv->connection && priv->object_path) {
 | 
			
		||||
        GError *error = NULL;
 | 
			
		||||
 | 
			
		||||
        service->priv->registration_id = g_dbus_connection_register_object
 | 
			
		||||
            (service->priv->connection,
 | 
			
		||||
             service->priv->object_path,
 | 
			
		||||
             service->priv->introspection_data->interfaces[0],
 | 
			
		||||
             &interface_vtable,
 | 
			
		||||
             object,
 | 
			
		||||
             NULL,
 | 
			
		||||
             &error);
 | 
			
		||||
 | 
			
		||||
        if (service->priv->registration_id == 0) {
 | 
			
		||||
            g_warning ("failed to register context object: %s",
 | 
			
		||||
                       error->message);
 | 
			
		||||
            g_error_free (error);
 | 
			
		||||
        if (!g_dbus_interface_skeleton_export(G_DBUS_INTERFACE_SKELETON(priv->dbus_interface),
 | 
			
		||||
                                              priv->connection,
 | 
			
		||||
                                              priv->object_path,
 | 
			
		||||
                                              &error)) {
 | 
			
		||||
            g_warning("Error registering dbus object: %s\n", error->message);
 | 
			
		||||
            g_clear_error(&error);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -215,9 +196,6 @@ eekboard_service_class_init (EekboardServiceClass *klass)
 | 
			
		||||
    GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
 | 
			
		||||
    GParamSpec *pspec;
 | 
			
		||||
 | 
			
		||||
    g_type_class_add_private (gobject_class,
 | 
			
		||||
                              sizeof (EekboardServicePrivate));
 | 
			
		||||
 | 
			
		||||
    klass->create_context = NULL;
 | 
			
		||||
 | 
			
		||||
    gobject_class->constructed = eekboard_service_constructed;
 | 
			
		||||
@ -275,204 +253,15 @@ eekboard_service_class_init (EekboardServiceClass *klass)
 | 
			
		||||
static void
 | 
			
		||||
eekboard_service_init (EekboardService *self)
 | 
			
		||||
{
 | 
			
		||||
    GError *error;
 | 
			
		||||
    EekboardServicePrivate *priv = eekboard_service_get_instance_private (self);
 | 
			
		||||
 | 
			
		||||
    self->priv = EEKBOARD_SERVICE_GET_PRIVATE(self);
 | 
			
		||||
 | 
			
		||||
    error = NULL;
 | 
			
		||||
    self->priv->introspection_data =
 | 
			
		||||
        g_dbus_node_info_new_for_xml (introspection_xml, &error);
 | 
			
		||||
    if (self->priv->introspection_data == NULL) {
 | 
			
		||||
        g_warning ("failed to parse D-Bus XML: %s", error->message);
 | 
			
		||||
        g_error_free (error);
 | 
			
		||||
        g_assert_not_reached ();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    self->priv->context_hash =
 | 
			
		||||
        g_hash_table_new_full (g_str_hash,
 | 
			
		||||
                               g_str_equal,
 | 
			
		||||
                               (GDestroyNotify)g_free,
 | 
			
		||||
                               (GDestroyNotify)g_object_unref);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
remove_context_from_stack (EekboardService        *service,
 | 
			
		||||
                           EekboardContextService *context)
 | 
			
		||||
{
 | 
			
		||||
    GSList *head;
 | 
			
		||||
 | 
			
		||||
    head = g_slist_find (service->priv->context_stack, context);
 | 
			
		||||
    if (head) {
 | 
			
		||||
        service->priv->context_stack = g_slist_remove_link (service->priv->context_stack, head);
 | 
			
		||||
        g_object_unref (head->data);
 | 
			
		||||
        g_slist_free1 (head);
 | 
			
		||||
    }
 | 
			
		||||
    if (service->priv->context_stack)
 | 
			
		||||
        eekboard_context_service_enable (service->priv->context_stack->data);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
service_name_vanished_callback (GDBusConnection *connection,
 | 
			
		||||
                                const gchar     *name,
 | 
			
		||||
                                gpointer         user_data)
 | 
			
		||||
{
 | 
			
		||||
    EekboardService *service = user_data;
 | 
			
		||||
    GSList *head;
 | 
			
		||||
    GHashTableIter iter;
 | 
			
		||||
    gpointer k, v;
 | 
			
		||||
 | 
			
		||||
    g_hash_table_iter_init (&iter, service->priv->context_hash);
 | 
			
		||||
    while (g_hash_table_iter_next (&iter, &k, &v)) {
 | 
			
		||||
        const gchar *owner = g_object_get_data (G_OBJECT(v), "owner");
 | 
			
		||||
        if (g_strcmp0 (owner, name) == 0)
 | 
			
		||||
            g_hash_table_iter_remove (&iter);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    for (head = service->priv->context_stack; head; ) {
 | 
			
		||||
        const gchar *owner = g_object_get_data (G_OBJECT(head->data), "owner");
 | 
			
		||||
        GSList *next = g_slist_next (head);
 | 
			
		||||
 | 
			
		||||
        if (g_strcmp0 (owner, name) == 0) {
 | 
			
		||||
            service->priv->context_stack =
 | 
			
		||||
                g_slist_remove_link (service->priv->context_stack, head);
 | 
			
		||||
            g_object_unref (head->data);
 | 
			
		||||
            g_slist_free1 (head);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        head = next;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (service->priv->context_stack)
 | 
			
		||||
        eekboard_context_service_enable (service->priv->context_stack->data);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
context_destroyed_cb (EekboardContextService *context, EekboardService *service)
 | 
			
		||||
{
 | 
			
		||||
    gchar *object_path = NULL;
 | 
			
		||||
 | 
			
		||||
    remove_context_from_stack (service, context);
 | 
			
		||||
 | 
			
		||||
    g_object_get (G_OBJECT(context), "object-path", &object_path, NULL);
 | 
			
		||||
    g_hash_table_remove (service->priv->context_hash, object_path);
 | 
			
		||||
    g_free (object_path);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
handle_method_call (GDBusConnection       *connection,
 | 
			
		||||
                    const gchar           *sender,
 | 
			
		||||
                    const gchar           *object_path,
 | 
			
		||||
                    const gchar           *interface_name,
 | 
			
		||||
                    const gchar           *method_name,
 | 
			
		||||
                    GVariant              *parameters,
 | 
			
		||||
                    GDBusMethodInvocation *invocation,
 | 
			
		||||
                    gpointer               user_data)
 | 
			
		||||
{
 | 
			
		||||
    EekboardService *service = user_data;
 | 
			
		||||
    EekboardServiceClass *klass = EEKBOARD_SERVICE_GET_CLASS(service);
 | 
			
		||||
 | 
			
		||||
    if (g_strcmp0 (method_name, "CreateContext") == 0) {
 | 
			
		||||
        const gchar *client_name;
 | 
			
		||||
        gchar *object_path;
 | 
			
		||||
        static gint context_id = 0;
 | 
			
		||||
        EekboardContextService *context;
 | 
			
		||||
 | 
			
		||||
        g_variant_get (parameters, "(&s)", &client_name);
 | 
			
		||||
        object_path = g_strdup_printf (EEKBOARD_CONTEXT_SERVICE_PATH, context_id++);
 | 
			
		||||
        g_assert (klass->create_context);
 | 
			
		||||
        context = klass->create_context (service, client_name, object_path);
 | 
			
		||||
        g_object_set_data_full (G_OBJECT(context),
 | 
			
		||||
                                "owner", g_strdup (sender),
 | 
			
		||||
                                (GDestroyNotify)g_free);
 | 
			
		||||
        g_hash_table_insert (service->priv->context_hash,
 | 
			
		||||
                             object_path,
 | 
			
		||||
                             context);
 | 
			
		||||
 | 
			
		||||
        /* the vanished callback is called when clients are disconnected */
 | 
			
		||||
        g_bus_watch_name_on_connection (service->priv->connection,
 | 
			
		||||
                                        sender,
 | 
			
		||||
                                        G_BUS_NAME_WATCHER_FLAGS_NONE,
 | 
			
		||||
                                        NULL,
 | 
			
		||||
                                        service_name_vanished_callback,
 | 
			
		||||
                                        service,
 | 
			
		||||
                                        NULL);
 | 
			
		||||
 | 
			
		||||
        g_signal_connect (G_OBJECT(context), "destroyed",
 | 
			
		||||
                          G_CALLBACK(context_destroyed_cb), service);
 | 
			
		||||
 | 
			
		||||
        g_dbus_method_invocation_return_value (invocation,
 | 
			
		||||
                                               g_variant_new ("(s)",
 | 
			
		||||
                                                              object_path));
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (g_strcmp0 (method_name, "PushContext") == 0) {
 | 
			
		||||
        const gchar *object_path;
 | 
			
		||||
        EekboardContextService *context;
 | 
			
		||||
 | 
			
		||||
        g_variant_get (parameters, "(&s)", &object_path);
 | 
			
		||||
        context = g_hash_table_lookup (service->priv->context_hash, object_path);
 | 
			
		||||
        if (!context) {
 | 
			
		||||
            g_dbus_method_invocation_return_error (invocation,
 | 
			
		||||
                                                   G_IO_ERROR,
 | 
			
		||||
                                                   G_IO_ERROR_FAILED_HANDLED,
 | 
			
		||||
                                                   "context not found");
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
        if (service->priv->context_stack)
 | 
			
		||||
            eekboard_context_service_disable (service->priv->context_stack->data);
 | 
			
		||||
        service->priv->context_stack = g_slist_prepend (service->priv->context_stack,
 | 
			
		||||
                                               g_object_ref (context));
 | 
			
		||||
        eekboard_context_service_enable (context);
 | 
			
		||||
 | 
			
		||||
        g_dbus_method_invocation_return_value (invocation, NULL);
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (g_strcmp0 (method_name, "PopContext") == 0) {
 | 
			
		||||
        if (service->priv->context_stack) {
 | 
			
		||||
            EekboardContextService *context = service->priv->context_stack->data;
 | 
			
		||||
            gchar *object_path;
 | 
			
		||||
            const gchar *owner;
 | 
			
		||||
 | 
			
		||||
            g_object_get (G_OBJECT(context), "object-path", &object_path, NULL);
 | 
			
		||||
            owner = g_object_get_data (G_OBJECT(context), "owner");
 | 
			
		||||
            if (g_strcmp0 (owner, sender) != 0) {
 | 
			
		||||
                g_dbus_method_invocation_return_error
 | 
			
		||||
                    (invocation,
 | 
			
		||||
                     G_IO_ERROR,
 | 
			
		||||
                     G_IO_ERROR_FAILED_HANDLED,
 | 
			
		||||
                     "context at %s not owned by %s",
 | 
			
		||||
                     object_path, sender);
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
            g_free (object_path);
 | 
			
		||||
                
 | 
			
		||||
            eekboard_context_service_disable (context);
 | 
			
		||||
            service->priv->context_stack = g_slist_next (service->priv->context_stack);
 | 
			
		||||
            if (service->priv->context_stack)
 | 
			
		||||
                eekboard_context_service_enable (service->priv->context_stack->data);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        g_dbus_method_invocation_return_value (invocation, NULL);
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (g_strcmp0 (method_name, "Destroy") == 0) {
 | 
			
		||||
        g_signal_emit (service, signals[DESTROYED], 0);
 | 
			
		||||
        g_dbus_method_invocation_return_value (invocation, NULL);
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    g_return_if_reached ();
 | 
			
		||||
    priv->context = NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eekboard_service_new:
 | 
			
		||||
 * @connection: a #GDBusConnection
 | 
			
		||||
 * @object_path: object path
 | 
			
		||||
 *
 | 
			
		||||
 * Create an empty server for testing purpose.
 | 
			
		||||
 */
 | 
			
		||||
EekboardService *
 | 
			
		||||
eekboard_service_new (GDBusConnection *connection,
 | 
			
		||||
@ -483,3 +272,12 @@ eekboard_service_new (GDBusConnection *connection,
 | 
			
		||||
                         "connection", connection,
 | 
			
		||||
                         NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
eekboard_service_set_context(EekboardService *service,
 | 
			
		||||
                             EekboardContextService *context)
 | 
			
		||||
{
 | 
			
		||||
    EekboardServicePrivate *priv = eekboard_service_get_instance_private (service);
 | 
			
		||||
 | 
			
		||||
    priv->context = context;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -24,32 +24,11 @@
 | 
			
		||||
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
#define EEKBOARD_SERVICE_PATH "/org/fedorahosted/Eekboard"
 | 
			
		||||
#define EEKBOARD_SERVICE_INTERFACE "org.fedorahosted.Eekboard"
 | 
			
		||||
#define EEKBOARD_SERVICE_PATH "/sm/puri/OSK0"
 | 
			
		||||
#define EEKBOARD_SERVICE_INTERFACE "sm.puri.OSK0"
 | 
			
		||||
 | 
			
		||||
#define EEKBOARD_TYPE_SERVICE (eekboard_service_get_type())
 | 
			
		||||
#define EEKBOARD_SERVICE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EEKBOARD_TYPE_SERVICE, EekboardService))
 | 
			
		||||
#define EEKBOARD_SERVICE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EEKBOARD_TYPE_SERVICE, EekboardServiceClass))
 | 
			
		||||
#define EEKBOARD_IS_SERVICE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EEKBOARD_TYPE_SERVICE))
 | 
			
		||||
#define EEKBOARD_IS_SERVICE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EEKBOARD_TYPE_SERVICE))
 | 
			
		||||
#define EEKBOARD_SERVICE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EEKBOARD_TYPE_SERVICE, EekboardServiceClass))
 | 
			
		||||
 | 
			
		||||
typedef struct _EekboardService EekboardService;
 | 
			
		||||
typedef struct _EekboardServiceClass EekboardServiceClass;
 | 
			
		||||
typedef struct _EekboardServicePrivate EekboardServicePrivate;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * EekboardService:
 | 
			
		||||
 *
 | 
			
		||||
 * The #EekboardService structure contains only private data and
 | 
			
		||||
 * should only be accessed using the provided API.
 | 
			
		||||
 */
 | 
			
		||||
struct _EekboardService {
 | 
			
		||||
    /*< private >*/
 | 
			
		||||
    GObject parent;
 | 
			
		||||
 | 
			
		||||
    EekboardServicePrivate *priv;
 | 
			
		||||
};
 | 
			
		||||
G_DECLARE_DERIVABLE_TYPE (EekboardService, eekboard_service, EEKBOARD, SERVICE, GObject)
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * EekboardServiceClass:
 | 
			
		||||
@ -60,9 +39,7 @@ struct _EekboardServiceClass {
 | 
			
		||||
    GObjectClass parent_class;
 | 
			
		||||
 | 
			
		||||
    /*< public >*/
 | 
			
		||||
    EekboardContextService *(*create_context) (EekboardService *self,
 | 
			
		||||
                                               const gchar     *client_name,
 | 
			
		||||
                                               const gchar     *object_path);
 | 
			
		||||
    EekboardContextService *(*create_context) (EekboardService *self);
 | 
			
		||||
 | 
			
		||||
    /*< private >*/
 | 
			
		||||
    /* padding */
 | 
			
		||||
@ -72,6 +49,7 @@ struct _EekboardServiceClass {
 | 
			
		||||
GType             eekboard_service_get_type (void) G_GNUC_CONST;
 | 
			
		||||
EekboardService * eekboard_service_new      (GDBusConnection *connection,
 | 
			
		||||
                                             const gchar     *object_path);
 | 
			
		||||
 | 
			
		||||
void              eekboard_service_set_context(EekboardService *service,
 | 
			
		||||
                                               EekboardContextService *context);
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
#endif  /* EEKBOARD_SERVICE_H */
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										328
									
								
								eekboard/key-emitter.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										328
									
								
								eekboard/key-emitter.c
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,328 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2011 Daiki Ueno <ueno@unixuser.org>
 | 
			
		||||
 * Copyright (C) 2011 Red Hat, Inc.
 | 
			
		||||
 * Copyright (C) 2019 Purism, SPC
 | 
			
		||||
 *
 | 
			
		||||
 * 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/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/* This file is responsible for managing keycode data and emitting keycodes. */
 | 
			
		||||
 | 
			
		||||
#include "eekboard/key-emitter.h"
 | 
			
		||||
#include "eekboard/keymap.h"
 | 
			
		||||
 | 
			
		||||
#include <gdk/gdk.h>
 | 
			
		||||
 | 
			
		||||
#include "eekboard/eekboard-context-service.h"
 | 
			
		||||
 | 
			
		||||
// TODO: decide whether it's this struct that carries the keyboard around in key-emitter or if the whole manager should be dragged around
 | 
			
		||||
// if this is the carrier, then it should be made part of the manager
 | 
			
		||||
// hint: check which fields need to be persisted between keypresses; which between keyboards
 | 
			
		||||
typedef struct {
 | 
			
		||||
    struct zwp_virtual_keyboard_v1 *virtual_keyboard; // unowned copy
 | 
			
		||||
    struct xkb_keymap *keymap; // unowned copy
 | 
			
		||||
    XkbDescRec *xkb;
 | 
			
		||||
    guint modifier_keycodes[8];
 | 
			
		||||
    guint modifier_indices[MOD_IDX_LAST];
 | 
			
		||||
    guint group;
 | 
			
		||||
} SeatEmitter;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* The following functions for keyboard mapping change are direct
 | 
			
		||||
   translation of the code in Caribou (in libcaribou/xadapter.vala):
 | 
			
		||||
 | 
			
		||||
   - get_replaced_keycode (Caribou: get_reserved_keycode)
 | 
			
		||||
   - replace_keycode
 | 
			
		||||
   - get_keycode_from_gdk_keymap (Caribou: best_keycode_keyval_match)
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
/* Find an unused keycode where a keysym can be assigned. Restricted to Level 1 */
 | 
			
		||||
static guint
 | 
			
		||||
get_replaced_keycode (SeatEmitter *client)
 | 
			
		||||
{
 | 
			
		||||
    guint keycode;
 | 
			
		||||
return 0; // FIXME: no xkb allocated yet
 | 
			
		||||
    for (keycode = client->xkb->max_key_code;
 | 
			
		||||
         keycode >= client->xkb->min_key_code;
 | 
			
		||||
         --keycode) {
 | 
			
		||||
        guint offset = client->xkb->map->key_sym_map[keycode].offset;
 | 
			
		||||
        if (client->xkb->map->key_sym_map[keycode].kt_index[0] == XkbOneLevelIndex &&
 | 
			
		||||
            client->xkb->map->syms[offset] != NoSymbol) {
 | 
			
		||||
            return keycode;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Replace keysym assigned to KEYCODE to KEYSYM.  Both args are used
 | 
			
		||||
   as in-out.  If KEYCODE points to 0, this function picks a keycode
 | 
			
		||||
   from the current map and replace the associated keysym to KEYSYM.
 | 
			
		||||
   In that case, the replaced keycode is stored in KEYCODE and the old
 | 
			
		||||
   keysym is stored in KEYSYM.  If otherwise (KEYCODE points to
 | 
			
		||||
   non-zero keycode), it simply changes the current map with the
 | 
			
		||||
   specified KEYCODE and KEYSYM. */
 | 
			
		||||
static gboolean
 | 
			
		||||
replace_keycode (SeatEmitter *emitter,
 | 
			
		||||
                 guint   keycode,
 | 
			
		||||
                 guint  *keysym)
 | 
			
		||||
{
 | 
			
		||||
/*  GdkDisplay *display = gdk_display_get_default ();
 | 
			
		||||
    Display *xdisplay = GDK_DISPLAY_XDISPLAY (display);
 | 
			
		||||
    guint old_keysym;
 | 
			
		||||
    int keysyms_per_keycode;
 | 
			
		||||
    KeySym *syms;
 | 
			
		||||
*/
 | 
			
		||||
return TRUE; // FIXME: no xkb allocated at the moment, pretending all is fine
 | 
			
		||||
    g_return_val_if_fail (emitter->xkb->min_key_code <= keycode &&
 | 
			
		||||
                          keycode <= emitter->xkb->max_key_code,
 | 
			
		||||
                          FALSE);
 | 
			
		||||
    g_return_val_if_fail (keysym != NULL, FALSE);
 | 
			
		||||
/*
 | 
			
		||||
 * Update keyboard mapping. Wayland receives keyboard mapping as a string, so XChangeKeyboardMapping needs to translate from the symbol tbale t the string. TODO.
 | 
			
		||||
 *
 | 
			
		||||
    syms = XGetKeyboardMapping (xdisplay, keycode, 1, &keysyms_per_keycode);
 | 
			
		||||
    old_keysym = syms[0];
 | 
			
		||||
    syms[0] = *keysym;
 | 
			
		||||
    XChangeKeyboardMapping (xdisplay, keycode, 1, syms, 1);
 | 
			
		||||
    XSync (xdisplay, False);
 | 
			
		||||
    XFree (syms);
 | 
			
		||||
    *keysym = old_keysym;
 | 
			
		||||
*/
 | 
			
		||||
    return TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
get_keycode_from_gdk_keymap (SeatEmitter *emitter,
 | 
			
		||||
                             guint           keysym,
 | 
			
		||||
                             guint          *keycode,
 | 
			
		||||
                             guint          *modifiers)
 | 
			
		||||
{
 | 
			
		||||
    GdkKeymapKey *keys, *best_match = NULL;
 | 
			
		||||
    guint n_keys, i;
 | 
			
		||||
 | 
			
		||||
    if (!squeek_keymap_get_entries_for_keyval (emitter->keymap, keysym, &keys, &n_keys))
 | 
			
		||||
        return FALSE;
 | 
			
		||||
 | 
			
		||||
    for (i = 0; i < n_keys; i++)
 | 
			
		||||
        if ((guint)keys[i].group == emitter->group)
 | 
			
		||||
            best_match = &keys[i];
 | 
			
		||||
 | 
			
		||||
    if (!best_match) {
 | 
			
		||||
        g_free (keys);
 | 
			
		||||
        return FALSE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    *keycode = best_match->keycode;
 | 
			
		||||
    *modifiers = best_match->level == 1 ? EEK_SHIFT_MASK : 0;
 | 
			
		||||
 | 
			
		||||
    g_free (keys);
 | 
			
		||||
    return TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int send_virtual_keyboard_key(
 | 
			
		||||
    struct zwp_virtual_keyboard_v1 *keyboard,
 | 
			
		||||
    unsigned int keycode,
 | 
			
		||||
    unsigned is_press,
 | 
			
		||||
    uint32_t timestamp
 | 
			
		||||
) {
 | 
			
		||||
    zwp_virtual_keyboard_v1_key(keyboard, timestamp, keycode, (unsigned)is_press);
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
send_fake_modifiers_events (SeatEmitter         *emitter,
 | 
			
		||||
                              EekModifierType modifiers,
 | 
			
		||||
                              uint32_t        timestamp)
 | 
			
		||||
{
 | 
			
		||||
    (void)timestamp;
 | 
			
		||||
 | 
			
		||||
    uint32_t proto_modifiers = 0;
 | 
			
		||||
    if (modifiers & EEK_SHIFT_MASK) {
 | 
			
		||||
        proto_modifiers |= 1<<MOD_IDX_SHIFT;
 | 
			
		||||
    }
 | 
			
		||||
    if (modifiers & EEK_CONTROL_MASK) {
 | 
			
		||||
        proto_modifiers |= 1<<MOD_IDX_CTRL;
 | 
			
		||||
    }
 | 
			
		||||
    if (modifiers & EEK_MOD1_MASK) {
 | 
			
		||||
        proto_modifiers |= 1<<MOD_IDX_ALT;
 | 
			
		||||
    }
 | 
			
		||||
    zwp_virtual_keyboard_v1_modifiers(emitter->virtual_keyboard, proto_modifiers, 0, 0, emitter->group);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
send_fake_key_event (SeatEmitter *emitter,
 | 
			
		||||
                     guint    xkeysym,
 | 
			
		||||
                     guint    keyboard_modifiers,
 | 
			
		||||
                     gboolean pressed,
 | 
			
		||||
                     uint32_t timestamp)
 | 
			
		||||
{
 | 
			
		||||
    EekModifierType modifiers;
 | 
			
		||||
    guint old_keysym = xkeysym;
 | 
			
		||||
 | 
			
		||||
    g_return_if_fail (xkeysym > 0);
 | 
			
		||||
 | 
			
		||||
    guint keycode;
 | 
			
		||||
    if (!get_keycode_from_gdk_keymap (emitter, xkeysym, &keycode, &modifiers)) {
 | 
			
		||||
        keycode = get_replaced_keycode (emitter);
 | 
			
		||||
        if (keycode == 0) {
 | 
			
		||||
            g_warning ("no available keycode to replace");
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (!replace_keycode (emitter, keycode, &old_keysym)) {
 | 
			
		||||
            g_warning ("failed to lookup X keysym %X", xkeysym);
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    /* Clear level shift modifiers */
 | 
			
		||||
    keyboard_modifiers &= (unsigned)~EEK_SHIFT_MASK;
 | 
			
		||||
    keyboard_modifiers &= (unsigned)~EEK_LOCK_MASK;
 | 
			
		||||
    /* FIXME: may need to remap ISO_Level3_Shift and NumLock */
 | 
			
		||||
 | 
			
		||||
    modifiers |= keyboard_modifiers;
 | 
			
		||||
 | 
			
		||||
    send_fake_modifiers_events (emitter, modifiers, timestamp);
 | 
			
		||||
 | 
			
		||||
    // There's something magical about subtracting/adding 8 to keycodes for some reason
 | 
			
		||||
    send_virtual_keyboard_key (emitter->virtual_keyboard, keycode - 8, (unsigned)pressed, timestamp);
 | 
			
		||||
    send_fake_modifiers_events (emitter, modifiers, timestamp);
 | 
			
		||||
 | 
			
		||||
    if (old_keysym != xkeysym)
 | 
			
		||||
        replace_keycode (emitter, keycode, &old_keysym);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
send_fake_key_events (SeatEmitter *emitter,
 | 
			
		||||
                      EekSymbol *symbol,
 | 
			
		||||
                      EekModifierType      keyboard_modifiers,
 | 
			
		||||
                      gboolean   pressed,
 | 
			
		||||
                      uint32_t   timestamp)
 | 
			
		||||
{
 | 
			
		||||
    /* Ignore modifier keys */
 | 
			
		||||
    if (eek_symbol_is_modifier (symbol))
 | 
			
		||||
        return;
 | 
			
		||||
 | 
			
		||||
    /* If symbol is a text, convert chars in it to keysym */
 | 
			
		||||
    if (EEK_IS_TEXT(symbol)) {
 | 
			
		||||
        const gchar *utf8 = eek_text_get_text (EEK_TEXT(symbol));
 | 
			
		||||
        printf("Attempting to send text %s\n", utf8);
 | 
			
		||||
        /* FIXME:
 | 
			
		||||
        glong items_written;
 | 
			
		||||
        gunichar *ucs4 = g_utf8_to_ucs4_fast (utf8, -1, &items_written);
 | 
			
		||||
        gint i;
 | 
			
		||||
 | 
			
		||||
        for (i = 0; i < items_written; i++) {
 | 
			
		||||
            guint xkeysym;
 | 
			
		||||
            EekKeysym *keysym;
 | 
			
		||||
            gchar *name;
 | 
			
		||||
 | 
			
		||||
            name = g_strdup_printf ("U%04X", ucs4[i]);
 | 
			
		||||
            xkeysym = XStringToKeysym (name); // TODO: use xkb_get_keysym_from_name
 | 
			
		||||
            g_free (name);
 | 
			
		||||
 | 
			
		||||
            keysym = eek_keysym_new (xkeysym);
 | 
			
		||||
            send_fake_key_events (client,
 | 
			
		||||
                                  EEK_SYMBOL(keysym),
 | 
			
		||||
                                  keyboard_modifiers);
 | 
			
		||||
        }
 | 
			
		||||
        g_free (ucs4);
 | 
			
		||||
        */
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (EEK_IS_KEYSYM(symbol)) {
 | 
			
		||||
        guint xkeysym = eek_keysym_get_xkeysym (EEK_KEYSYM(symbol));
 | 
			
		||||
        send_fake_key_event (emitter, xkeysym, keyboard_modifiers, pressed, timestamp);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* Finds the first key code for each modifier and saves it in modifier_keycodes */
 | 
			
		||||
static void
 | 
			
		||||
update_modifier_info (SeatEmitter *client)
 | 
			
		||||
{
 | 
			
		||||
    client->modifier_indices[MOD_IDX_SHIFT] = xkb_keymap_mod_get_index(client->keymap, XKB_MOD_NAME_SHIFT);
 | 
			
		||||
    client->modifier_indices[MOD_IDX_CAPS] = xkb_keymap_mod_get_index(client->keymap, XKB_MOD_NAME_CAPS);
 | 
			
		||||
    client->modifier_indices[MOD_IDX_CTRL] = xkb_keymap_mod_get_index(client->keymap, XKB_MOD_NAME_CTRL);
 | 
			
		||||
    client->modifier_indices[MOD_IDX_ALT] = xkb_keymap_mod_get_index(client->keymap, XKB_MOD_NAME_ALT);
 | 
			
		||||
    client->modifier_indices[MOD_IDX_NUM] = xkb_keymap_mod_get_index(client->keymap, XKB_MOD_NAME_NUM);
 | 
			
		||||
    client->modifier_indices[MOD_IDX_MOD3] = xkb_keymap_mod_get_index(client->keymap, "Mod3");
 | 
			
		||||
    client->modifier_indices[MOD_IDX_LOGO] = xkb_keymap_mod_get_index(client->keymap, XKB_MOD_NAME_LOGO);
 | 
			
		||||
    client->modifier_indices[MOD_IDX_ALTGR] = xkb_keymap_mod_get_index(client->keymap, "Mod5");
 | 
			
		||||
    client->modifier_indices[MOD_IDX_NUMLK] = xkb_keymap_mod_get_index(client->keymap, "NumLock");
 | 
			
		||||
    client->modifier_indices[MOD_IDX_ALSO_ALT] = xkb_keymap_mod_get_index(client->keymap, "Alt");
 | 
			
		||||
    client->modifier_indices[MOD_IDX_LVL3] = xkb_keymap_mod_get_index(client->keymap, "LevelThree");
 | 
			
		||||
    client->modifier_indices[MOD_IDX_LALT] = xkb_keymap_mod_get_index(client->keymap, "LAlt");
 | 
			
		||||
    client->modifier_indices[MOD_IDX_RALT] = xkb_keymap_mod_get_index(client->keymap, "RAlt");
 | 
			
		||||
    client->modifier_indices[MOD_IDX_RCONTROL] = xkb_keymap_mod_get_index(client->keymap, "RControl");
 | 
			
		||||
    client->modifier_indices[MOD_IDX_LCONTROL] = xkb_keymap_mod_get_index(client->keymap, "LControl");
 | 
			
		||||
    client->modifier_indices[MOD_IDX_SCROLLLK] = xkb_keymap_mod_get_index(client->keymap, "ScrollLock");
 | 
			
		||||
    client->modifier_indices[MOD_IDX_LVL5] = xkb_keymap_mod_get_index(client->keymap, "LevelFive");
 | 
			
		||||
    client->modifier_indices[MOD_IDX_ALSO_ALTGR] = xkb_keymap_mod_get_index(client->keymap, "AltGr");
 | 
			
		||||
    client->modifier_indices[MOD_IDX_META] = xkb_keymap_mod_get_index(client->keymap, "Meta");
 | 
			
		||||
    client->modifier_indices[MOD_IDX_SUPER] = xkb_keymap_mod_get_index(client->keymap, "Super");
 | 
			
		||||
    client->modifier_indices[MOD_IDX_HYPER] = xkb_keymap_mod_get_index(client->keymap, "Hyper");
 | 
			
		||||
 | 
			
		||||
    /*
 | 
			
		||||
    for (xkb_mod_index_t i = 0;
 | 
			
		||||
         i < xkb_keymap_num_mods(client->keymap);
 | 
			
		||||
         i++) {
 | 
			
		||||
        g_log("squeek", G_LOG_LEVEL_DEBUG, "%s", xkb_keymap_mod_get_name(client->keymap, i));
 | 
			
		||||
    }*/
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
emit_key_activated (EekboardContextService *manager,
 | 
			
		||||
                    EekKeyboard     *keyboard,
 | 
			
		||||
                    guint            keycode,
 | 
			
		||||
                    EekSymbol       *symbol,
 | 
			
		||||
                    EekModifierType  modifiers,
 | 
			
		||||
                    gboolean pressed,
 | 
			
		||||
                    uint32_t timestamp)
 | 
			
		||||
{
 | 
			
		||||
    /* FIXME: figure out how to deal with Client after key presses go through
 | 
			
		||||
    if (g_strcmp0 (eek_symbol_get_name (symbol), "cycle-keyboard") == 0) {
 | 
			
		||||
        client->keyboards_head = g_slist_next (client->keyboards_head);
 | 
			
		||||
        if (client->keyboards_head == NULL)
 | 
			
		||||
            client->keyboards_head = client->keyboards;
 | 
			
		||||
        eekboard_context_set_keyboard (client->context,
 | 
			
		||||
                                       GPOINTER_TO_UINT(client->keyboards_head->data),
 | 
			
		||||
                                       NULL);
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (g_strcmp0 (eek_symbol_get_name (symbol), "preferences") == 0) {
 | 
			
		||||
        gchar *argv[2];
 | 
			
		||||
        GError *error;
 | 
			
		||||
 | 
			
		||||
        argv[0] = g_build_filename (LIBEXECDIR, "eekboard-setup", NULL);
 | 
			
		||||
        argv[1] = NULL;
 | 
			
		||||
 | 
			
		||||
        error = NULL;
 | 
			
		||||
        if (!g_spawn_async (NULL, argv, NULL, 0, NULL, NULL, NULL, &error)) {
 | 
			
		||||
            g_warning ("can't spawn %s: %s", argv[0], error->message);
 | 
			
		||||
            g_error_free (error);
 | 
			
		||||
        }
 | 
			
		||||
        g_free (argv[0]);
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
*/
 | 
			
		||||
    SeatEmitter emitter = {0};
 | 
			
		||||
    emitter.virtual_keyboard = manager->virtual_keyboard;
 | 
			
		||||
    emitter.keymap = keyboard->keymap;
 | 
			
		||||
    update_modifier_info (&emitter);
 | 
			
		||||
    send_fake_key_events (&emitter, symbol, modifiers, pressed, timestamp);
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										48
									
								
								eekboard/key-emitter.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										48
									
								
								eekboard/key-emitter.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,48 @@
 | 
			
		||||
#ifndef KEYEMITTER_H
 | 
			
		||||
#define KEYEMITTER_H
 | 
			
		||||
 | 
			
		||||
#include <inttypes.h>
 | 
			
		||||
#include <glib.h>
 | 
			
		||||
#include <X11/XKBlib.h>
 | 
			
		||||
 | 
			
		||||
#include "eek/eek.h"
 | 
			
		||||
 | 
			
		||||
#include "virtual-keyboard-unstable-v1-client-protocol.h"
 | 
			
		||||
 | 
			
		||||
/// Indices obtained by xkb_keymap_mod_get_name
 | 
			
		||||
enum mod_indices {
 | 
			
		||||
    MOD_IDX_SHIFT,
 | 
			
		||||
    MOD_IDX_CAPS,
 | 
			
		||||
    MOD_IDX_CTRL,
 | 
			
		||||
    MOD_IDX_ALT,
 | 
			
		||||
    MOD_IDX_NUM,
 | 
			
		||||
    MOD_IDX_MOD3,
 | 
			
		||||
    MOD_IDX_LOGO,
 | 
			
		||||
    MOD_IDX_ALTGR,
 | 
			
		||||
    MOD_IDX_NUMLK, // Caution, not sure which is the right one
 | 
			
		||||
    MOD_IDX_ALSO_ALT, // Not sure why, alt emits the first alt on my setup
 | 
			
		||||
    MOD_IDX_LVL3,
 | 
			
		||||
 | 
			
		||||
    // Not sure if the next 4 are used at all
 | 
			
		||||
    MOD_IDX_LALT,
 | 
			
		||||
    MOD_IDX_RALT,
 | 
			
		||||
    MOD_IDX_RCONTROL,
 | 
			
		||||
    MOD_IDX_LCONTROL,
 | 
			
		||||
 | 
			
		||||
    MOD_IDX_SCROLLLK,
 | 
			
		||||
    MOD_IDX_LVL5,
 | 
			
		||||
    MOD_IDX_ALSO_ALTGR, // Not used on my layout
 | 
			
		||||
    MOD_IDX_META,
 | 
			
		||||
    MOD_IDX_SUPER,
 | 
			
		||||
    MOD_IDX_HYPER,
 | 
			
		||||
 | 
			
		||||
    MOD_IDX_LAST,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
emit_key_activated (EekboardContextService *manager, EekKeyboard *keyboard,
 | 
			
		||||
                    guint            keycode,
 | 
			
		||||
                    EekSymbol       *symbol,
 | 
			
		||||
                    guint            modifiers,
 | 
			
		||||
                    gboolean pressed, uint32_t timestamp);
 | 
			
		||||
#endif // KEYEMITTER_H
 | 
			
		||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user