Compare commits
	
		
			4 Commits
		
	
	
		
			layouts
			...
			fix-deprec
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 33662d42ae | |||
| bf8e765c89 | |||
| 36ee547506 | |||
| 8e014aaaf8 | 
							
								
								
									
										9
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						@ -1,9 +0,0 @@
 | 
				
			|||||||
.zanata-cache/
 | 
					 | 
				
			||||||
_build
 | 
					 | 
				
			||||||
TAGS
 | 
					 | 
				
			||||||
tags
 | 
					 | 
				
			||||||
vgdump
 | 
					 | 
				
			||||||
*.swp
 | 
					 | 
				
			||||||
*~
 | 
					 | 
				
			||||||
\#*#
 | 
					 | 
				
			||||||
.\#*
 | 
					 | 
				
			||||||
@ -2,30 +2,20 @@ image: debian:buster
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
stages:
 | 
					stages:
 | 
				
			||||||
  - build
 | 
					  - build
 | 
				
			||||||
  - test
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
.tags: &tags
 | 
					 | 
				
			||||||
  tags:
 | 
					 | 
				
			||||||
    - librem5
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
before_script:
 | 
					before_script:
 | 
				
			||||||
 | 
					  - apt-get -y update
 | 
				
			||||||
 | 
					  - apt-get -y install wget gnupg2
 | 
				
			||||||
 | 
					  - echo "deb http://ci.puri.sm/ scratch librem5" > /etc/apt/sources.list.d/ci.list
 | 
				
			||||||
 | 
					  - wget -O- https://ci.puri.sm/ci-repo.key | apt-key add -
 | 
				
			||||||
  - apt-get -y update
 | 
					  - apt-get -y update
 | 
				
			||||||
  - apt-get -y build-dep .
 | 
					  - apt-get -y build-dep .
 | 
				
			||||||
 | 
					
 | 
				
			||||||
build_meson:
 | 
					build_meson:
 | 
				
			||||||
  <<: *tags
 | 
					 | 
				
			||||||
  stage: build
 | 
					  stage: build
 | 
				
			||||||
  artifacts:
 | 
					  tags:
 | 
				
			||||||
    paths:
 | 
					    - librem5
 | 
				
			||||||
      - _build
 | 
					 | 
				
			||||||
  script:
 | 
					  script:
 | 
				
			||||||
    - meson . _build/ -Ddepdatadir=/usr/share
 | 
					    - meson . _build/ -Ddepdatadir=/usr/share
 | 
				
			||||||
    - ninja -C _build install
 | 
					    - ninja -C _build install
 | 
				
			||||||
 | 
					
 | 
				
			||||||
test:
 | 
					 | 
				
			||||||
  <<: *tags
 | 
					 | 
				
			||||||
  stage: test
 | 
					 | 
				
			||||||
  dependencies:
 | 
					 | 
				
			||||||
    - build_meson
 | 
					 | 
				
			||||||
  script:
 | 
					 | 
				
			||||||
    - ninja -C _build test
 | 
					 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										41
									
								
								Makefile.am
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,41 @@
 | 
				
			|||||||
 | 
					# 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
 | 
				
			||||||
 | 
					AUTOMAKE_OPTIONS = foreign # allow README.md to exist
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					GITIGNOREFILES =				\
 | 
				
			||||||
 | 
						INSTALL					\
 | 
				
			||||||
 | 
						aclocal.m4				\
 | 
				
			||||||
 | 
						compile					\
 | 
				
			||||||
 | 
						config.guess				\
 | 
				
			||||||
 | 
						config.h.in				\
 | 
				
			||||||
 | 
						config.sub				\
 | 
				
			||||||
 | 
						depcomp					\
 | 
				
			||||||
 | 
						gtk-doc.make				\
 | 
				
			||||||
 | 
						install-sh				\
 | 
				
			||||||
 | 
						ltmain.sh				\
 | 
				
			||||||
 | 
						m4					\
 | 
				
			||||||
 | 
						missing					\
 | 
				
			||||||
 | 
						mkinstalldirs				\
 | 
				
			||||||
 | 
						$(NULL)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					-include $(top_srcdir)/git.mk
 | 
				
			||||||
@ -33,8 +33,8 @@ See `.gitlab-ci.yml`.
 | 
				
			|||||||
### Build from git repo
 | 
					### Build from git repo
 | 
				
			||||||
 | 
					
 | 
				
			||||||
```
 | 
					```
 | 
				
			||||||
$ git clone https://source.puri.sm/Librem5/squeekboard.git
 | 
					$ git clone https://source.puri.sm/Librem5/eekboard.git
 | 
				
			||||||
$ cd squeekboard
 | 
					$ cd eekboard
 | 
				
			||||||
$ mkdir ../build
 | 
					$ mkdir ../build
 | 
				
			||||||
$ meson ../build/
 | 
					$ meson ../build/
 | 
				
			||||||
$ cd ../build
 | 
					$ cd ../build
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										20
									
								
								autogen.sh
									
									
									
									
									
										Executable file
									
								
							
							
						
						@ -0,0 +1,20 @@
 | 
				
			|||||||
 | 
					#!/bin/sh
 | 
				
			||||||
 | 
					# Run this to generate all the initial makefiles, etc.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					srcdir=`dirname $0`
 | 
				
			||||||
 | 
					test -z "$srcdir" && srcdir=.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					PKG_NAME="eekboard"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					(test -f $srcdir/configure.ac \
 | 
				
			||||||
 | 
					  && test -f $srcdir/README.md ) || {
 | 
				
			||||||
 | 
					    echo -n "**Error**: Directory "\`$srcdir\'" does not look like the"
 | 
				
			||||||
 | 
					    echo " top-level $PKG_NAME directory"
 | 
				
			||||||
 | 
					    exit 1
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					ACLOCAL_FLAGS="$ACLOCAL_FLAGS -I m4"
 | 
				
			||||||
 | 
					REQUIRED_AUTOMAKE_VERSION=1.10
 | 
				
			||||||
 | 
					REQUIRED_AUTOCONF_VERSION=2.60
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					. gnome-autogen.sh
 | 
				
			||||||
							
								
								
									
										21
									
								
								bindings/Makefile.am
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,21 @@
 | 
				
			|||||||
 | 
					# 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
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					-include $(top_srcdir)/git.mk
 | 
				
			||||||
							
								
								
									
										96
									
								
								bindings/vala/Makefile.am
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,96 @@
 | 
				
			|||||||
 | 
					# 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
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					NULL =
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					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)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					GITIGNOREFILES = \
 | 
				
			||||||
 | 
						eek-$(EEK_API_VERSION).vapi		\
 | 
				
			||||||
 | 
						eek-gtk-$(EEK_API_VERSION).vapi		\
 | 
				
			||||||
 | 
						eek-xkl-$(EEK_API_VERSION).vapi		\
 | 
				
			||||||
 | 
						$(NULL)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					maintainer-clean-local:
 | 
				
			||||||
 | 
						rm -f *.vapi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					eek_vapi_deps =						\
 | 
				
			||||||
 | 
						$(srcdir)/Eek-$(EEK_API_VERSION).metadata	\
 | 
				
			||||||
 | 
						|						\
 | 
				
			||||||
 | 
						$(top_builddir)/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_builddir)/eek/Eek-$(EEK_API_VERSION).gir
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					eek_gtk_vapi_deps =					\
 | 
				
			||||||
 | 
						$(srcdir)/EekGtk-$(EEK_API_VERSION).metadata	\
 | 
				
			||||||
 | 
						|						\
 | 
				
			||||||
 | 
						$(top_builddir)/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 gio-2.0 \
 | 
				
			||||||
 | 
							--pkg gtk+-3.0 \
 | 
				
			||||||
 | 
							--metadatadir=$(srcdir)	\
 | 
				
			||||||
 | 
							$(top_builddir)/eek/EekGtk-$(EEK_API_VERSION).gir
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					eek_xkl_vapi_deps =						\
 | 
				
			||||||
 | 
						$(srcdir)/EekXkl-$(EEK_API_VERSION).metadata		\
 | 
				
			||||||
 | 
						|							\
 | 
				
			||||||
 | 
						$(top_builddir)/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) \
 | 
				
			||||||
 | 
							--pkg gio-2.0 \
 | 
				
			||||||
 | 
							--metadatadir=$(srcdir) \
 | 
				
			||||||
 | 
							$(top_builddir)/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
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					-include $(top_srcdir)/git.mk
 | 
				
			||||||
							
								
								
									
										245
									
								
								configure.ac
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,245 @@
 | 
				
			|||||||
 | 
					# 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.8], [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], , 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
 | 
				
			||||||
 | 
					])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							
								
								
									
										35
									
								
								data/Makefile.am
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,35 @@
 | 
				
			|||||||
 | 
					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
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					-include $(top_srcdir)/git.mk
 | 
				
			||||||
@ -1,20 +0,0 @@
 | 
				
			|||||||
<!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>
 | 
					 | 
				
			||||||
							
								
								
									
										17
									
								
								data/icons/16x16/Makefile.am
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,17 @@
 | 
				
			|||||||
 | 
					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
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					-include $(top_srcdir)/git.mk
 | 
				
			||||||
							
								
								
									
										
											BIN
										
									
								
								data/icons/16x16/eekboard.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 606 B  | 
							
								
								
									
										17
									
								
								data/icons/22x22/Makefile.am
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,17 @@
 | 
				
			|||||||
 | 
					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
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					-include $(top_srcdir)/git.mk
 | 
				
			||||||
							
								
								
									
										
											BIN
										
									
								
								data/icons/22x22/eekboard.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 892 B  | 
							
								
								
									
										17
									
								
								data/icons/24x24/Makefile.am
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,17 @@
 | 
				
			|||||||
 | 
					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
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					-include $(top_srcdir)/git.mk
 | 
				
			||||||
							
								
								
									
										
											BIN
										
									
								
								data/icons/24x24/eekboard.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 957 B  | 
							
								
								
									
										17
									
								
								data/icons/32x32/Makefile.am
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,17 @@
 | 
				
			|||||||
 | 
					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
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					-include $(top_srcdir)/git.mk
 | 
				
			||||||
							
								
								
									
										
											BIN
										
									
								
								data/icons/32x32/eekboard.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 1.5 KiB  | 
							
								
								
									
										17
									
								
								data/icons/48x48/Makefile.am
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,17 @@
 | 
				
			|||||||
 | 
					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
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					-include $(top_srcdir)/git.mk
 | 
				
			||||||
							
								
								
									
										
											BIN
										
									
								
								data/icons/48x48/eekboard.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 2.7 KiB  | 
							
								
								
									
										3
									
								
								data/icons/Makefile.am
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,3 @@
 | 
				
			|||||||
 | 
					SUBDIRS = 16x16 22x22 24x24 32x32 48x48 scalable
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					-include $(top_srcdir)/git.mk
 | 
				
			||||||
@ -1,10 +0,0 @@
 | 
				
			|||||||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<svg xmlns="http://www.w3.org/2000/svg" height="16" width="16"
 | 
					 | 
				
			||||||
     version="1.1" viewBox="0 0 24 24">
 | 
					 | 
				
			||||||
   
 | 
					 | 
				
			||||||
    <path d="M 24,1 L 24,10 C 24,15 20,17 17,17 L 7,17 L 10,20 L 10,23
 | 
					 | 
				
			||||||
             L 7,23 L 0,15 L 7,7 L 10,7 L 10,10 L 7,13 L 17,13
 | 
					 | 
				
			||||||
             C 19,13 20,12 20,10 L 20,1 Z"
 | 
					 | 
				
			||||||
          stroke="none" fill="black" />
 | 
					 | 
				
			||||||
</svg>
 | 
					 | 
				
			||||||
| 
		 Before Width: | Height: | Size: 388 B  | 
@ -1,8 +0,0 @@
 | 
				
			|||||||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<svg xmlns="http://www.w3.org/2000/svg" height="16" width="16"
 | 
					 | 
				
			||||||
     version="1.1" viewBox="0 0 24 24">
 | 
					 | 
				
			||||||
   
 | 
					 | 
				
			||||||
    <path d="M 12,2 L 22,14 L 16,14 L 16,22 L 8,22 L 8,14 L 2,14 Z"
 | 
					 | 
				
			||||||
          stroke="none" fill="black" />
 | 
					 | 
				
			||||||
</svg>
 | 
					 | 
				
			||||||
| 
		 Before Width: | Height: | Size: 279 B  | 
@ -1,52 +0,0 @@
 | 
				
			|||||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
 | 
					 | 
				
			||||||
<svg
 | 
					 | 
				
			||||||
   xmlns:dc="http://purl.org/dc/elements/1.1/"
 | 
					 | 
				
			||||||
   xmlns:cc="http://creativecommons.org/ns#"
 | 
					 | 
				
			||||||
   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
 | 
					 | 
				
			||||||
   xmlns:svg="http://www.w3.org/2000/svg"
 | 
					 | 
				
			||||||
   xmlns="http://www.w3.org/2000/svg"
 | 
					 | 
				
			||||||
   id="svg4043"
 | 
					 | 
				
			||||||
   version="1.1"
 | 
					 | 
				
			||||||
   viewBox="0 0 4.2333331 4.2333093"
 | 
					 | 
				
			||||||
   height="4.2333093mm"
 | 
					 | 
				
			||||||
   width="4.2333331mm">
 | 
					 | 
				
			||||||
  <defs
 | 
					 | 
				
			||||||
     id="defs4037" />
 | 
					 | 
				
			||||||
  <metadata
 | 
					 | 
				
			||||||
     id="metadata4040">
 | 
					 | 
				
			||||||
    <rdf:RDF>
 | 
					 | 
				
			||||||
      <cc:Work
 | 
					 | 
				
			||||||
         rdf:about="">
 | 
					 | 
				
			||||||
        <dc:format>image/svg+xml</dc:format>
 | 
					 | 
				
			||||||
        <dc:type
 | 
					 | 
				
			||||||
           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
 | 
					 | 
				
			||||||
        <dc:title></dc:title>
 | 
					 | 
				
			||||||
      </cc:Work>
 | 
					 | 
				
			||||||
    </rdf:RDF>
 | 
					 | 
				
			||||||
  </metadata>
 | 
					 | 
				
			||||||
  <g
 | 
					 | 
				
			||||||
     transform="translate(-86.329776,-68.097636)"
 | 
					 | 
				
			||||||
     id="layer1">
 | 
					 | 
				
			||||||
    <g
 | 
					 | 
				
			||||||
       style="stroke-width:1.00004983;fill:#2e3436;fill-opacity:1"
 | 
					 | 
				
			||||||
       transform="matrix(0.99990029,0,0,1,-7.1823833,-1.8799927)"
 | 
					 | 
				
			||||||
       id="g842">
 | 
					 | 
				
			||||||
      <g
 | 
					 | 
				
			||||||
         style="stroke-width:1.00004983;fill:#2e3436;fill-opacity:1"
 | 
					 | 
				
			||||||
         id="g836">
 | 
					 | 
				
			||||||
        <path
 | 
					 | 
				
			||||||
           id="path5166"
 | 
					 | 
				
			||||||
           d="m 95.636719,69.978516 c -1.165869,0 -2.115235,0.949365 -2.115235,2.115234 0,1.165869 0.949366,2.117188 2.115235,2.117188 1.165869,0 2.117187,-0.951319 2.117187,-2.117188 0,-1.165869 -0.951318,-2.115234 -2.117187,-2.115234 z m 0,0.529296 c 0.879886,0 1.58789,0.706052 1.58789,1.585938 0,0.879886 -0.708004,1.587891 -1.58789,1.587891 -0.879886,0 -1.585938,-0.708005 -1.585938,-1.587891 0,-0.879886 0.706052,-1.585937 1.585938,-1.585938 z"
 | 
					 | 
				
			||||||
           style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#2e3436;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.52919304;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" />
 | 
					 | 
				
			||||||
      </g>
 | 
					 | 
				
			||||||
      <path
 | 
					 | 
				
			||||||
         style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#2e3436;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.26459652;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
 | 
					 | 
				
			||||||
         d="m 95.636719,70.109375 c -0.144398,0 -0.27248,0.07793 -0.373047,0.189453 -0.100567,0.111521 -0.18209,0.261405 -0.25,0.439453 -0.135821,0.356096 -0.214844,0.830395 -0.214844,1.355469 0,0.525074 0.07902,1.001326 0.214844,1.357422 0.06791,0.178048 0.149433,0.327932 0.25,0.439453 0.100567,0.111521 0.228649,0.1875 0.373047,0.1875 0.144397,0 0.27248,-0.07598 0.373047,-0.1875 0.100566,-0.111521 0.182089,-0.261405 0.25,-0.439453 0.135821,-0.356096 0.216797,-0.832348 0.216796,-1.357422 0,-0.525074 -0.08097,-0.999373 -0.216796,-1.355469 -0.06791,-0.178048 -0.149434,-0.327932 -0.25,-0.439453 -0.100567,-0.111521 -0.22865,-0.189453 -0.373047,-0.189453 z m 0,0.265625 c 0.05067,0 0.109272,0.02564 0.177734,0.101562 0.06846,0.07592 0.139293,0.198356 0.199219,0.355469 0.119851,0.314227 0.197266,0.763915 0.197266,1.261719 0,0.497804 -0.07742,0.949446 -0.197266,1.263672 -0.05993,0.157113 -0.130756,0.279549 -0.199219,0.355469 -0.06846,0.07592 -0.12706,0.101562 -0.177734,0.101562 -0.05067,0 -0.107319,-0.02564 -0.175781,-0.101562 -0.06846,-0.07592 -0.139294,-0.198356 -0.199219,-0.355469 C 95.141867,73.043196 95.0625,72.591554 95.0625,72.09375 c 0,-0.497804 0.07937,-0.947492 0.199219,-1.261719 0.05993,-0.157113 0.130756,-0.279549 0.199219,-0.355469 C 95.5294,70.400643 95.586045,70.375 95.636719,70.375 Z"
 | 
					 | 
				
			||||||
         id="circle5168" />
 | 
					 | 
				
			||||||
      <path
 | 
					 | 
				
			||||||
         style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#2e3436;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.26459652;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
 | 
					 | 
				
			||||||
         d="m 93.697266,71.962891 v 0.263671 h 3.96875 v -0.263671 z"
 | 
					 | 
				
			||||||
         id="path5170" />
 | 
					 | 
				
			||||||
    </g>
 | 
					 | 
				
			||||||
  </g>
 | 
					 | 
				
			||||||
</svg>
 | 
					 | 
				
			||||||
| 
		 Before Width: | Height: | Size: 6.6 KiB  | 
							
								
								
									
										15
									
								
								data/icons/scalable/Makefile.am
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,15 @@
 | 
				
			|||||||
 | 
					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
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					-include $(top_srcdir)/git.mk
 | 
				
			||||||
							
								
								
									
										3486
									
								
								data/icons/scalable/eekboard.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 472 KiB  | 
							
								
								
									
										40
									
								
								data/keyboards/Makefile.am
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,40 @@
 | 
				
			|||||||
 | 
					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)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					-include $(top_srcdir)/git.mk
 | 
				
			||||||
@ -1,64 +1,189 @@
 | 
				
			|||||||
<?xml version="1.0"?>
 | 
					<?xml version="1.0"?>
 | 
				
			||||||
<geometry version="0.90">
 | 
					<geometry version="0.90">
 | 
				
			||||||
  <bounds x="10" y="10" width="410.0000" height="229"/>
 | 
					  <bounds x="0.000000" y="0.000000" width="426.0000" height="296.5853"/>
 | 
				
			||||||
 | 
					  <section angle="0">
 | 
				
			||||||
  <outline id="default" corner-radius="1.000000">
 | 
					    <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="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="37" name="LCTL" oref="altline">
 | 
				
			||||||
 | 
						<bounds x="62.43902" y="162.3414" width="48.39024" height="37.46341"/>
 | 
				
			||||||
 | 
					      </key>
 | 
				
			||||||
 | 
					      <key keycode="66" name="ALTGR" 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="0.000000" y="0.000000"/>
 | 
				
			||||||
    <point x="37.46341" y="0.000000"/>
 | 
					    <point x="37.46341" y="0.000000"/>
 | 
				
			||||||
    <point x="37.46341" y="52"/>
 | 
					    <point x="37.46341" y="52.44877"/>
 | 
				
			||||||
    <point x="0.000000" y="52"/>
 | 
					    <point x="0.000000" y="52.44877"/>
 | 
				
			||||||
  </outline>
 | 
					  </outline>
 | 
				
			||||||
  <outline id="altline" corner-radius="1.000000">
 | 
					  <outline id="altline" corner-radius="1.000000">
 | 
				
			||||||
    <point x="0.000000" y="0.000000"/>
 | 
					    <point x="0.000000" y="0.000000"/>
 | 
				
			||||||
    <point x="48.39024" y="0.000000"/>
 | 
					    <point x="48.39024" y="0.000000"/>
 | 
				
			||||||
    <point x="48.39024" y="52"/>
 | 
					    <point x="48.39024" y="52.44877"/>
 | 
				
			||||||
    <point x="0.000000" y="52"/>
 | 
					    <point x="0.000000" y="52.44877"/>
 | 
				
			||||||
 | 
					  </outline>
 | 
				
			||||||
 | 
					  <outline id="outline4" corner-radius="1.000000">
 | 
				
			||||||
 | 
					    <point x="0.000000" y="0.000000"/>
 | 
				
			||||||
 | 
					    <point x="59.31707" y="0.000000"/>
 | 
				
			||||||
 | 
					    <point x="59.31707" y="52.44877"/>
 | 
				
			||||||
 | 
					    <point x="0.000000" y="52.44877"/>
 | 
				
			||||||
 | 
					  </outline>
 | 
				
			||||||
 | 
					  <outline id="outline5" corner-radius="1.000000">
 | 
				
			||||||
 | 
					    <point x="0.000000" y="0.000000"/>
 | 
				
			||||||
 | 
					    <point x="59.31707" y="0.000000"/>
 | 
				
			||||||
 | 
					    <point x="59.31707" y="52.44877"/>
 | 
				
			||||||
 | 
					    <point x="0.000000" y="52.44877"/>
 | 
				
			||||||
 | 
					  </outline>
 | 
				
			||||||
 | 
					  <outline id="outline6" corner-radius="1.000000">
 | 
				
			||||||
 | 
					    <point x="0.000000" y="0.000000"/>
 | 
				
			||||||
 | 
					    <point x="68.68292" y="0.000000"/>
 | 
				
			||||||
 | 
					    <point x="68.68292" y="52.44877"/>
 | 
				
			||||||
 | 
					    <point x="0.000000" y="52.44877"/>
 | 
				
			||||||
  </outline>
 | 
					  </outline>
 | 
				
			||||||
  <outline id="outline7" corner-radius="1.000000">
 | 
					  <outline id="outline7" corner-radius="1.000000">
 | 
				
			||||||
    <point x="0.000000" y="0.000000"/>
 | 
					    <point x="0.000000" y="0.000000"/>
 | 
				
			||||||
    <point x="88.97561" y="0.000000"/>
 | 
					    <point x="88.97561" y="0.000000"/>
 | 
				
			||||||
    <point x="88.97561" y="52"/>
 | 
					    <point x="88.97561" y="52.44877"/>
 | 
				
			||||||
    <point x="0.000000" y="52"/>
 | 
					    <point x="0.000000" y="52.44877"/>
 | 
				
			||||||
 | 
					  </outline>
 | 
				
			||||||
 | 
					  <outline id="outline8" corner-radius="1.000000">
 | 
				
			||||||
 | 
					    <point x="0.000000" y="0.000000"/>
 | 
				
			||||||
 | 
					    <point x="88.97561" y="0.000000"/>
 | 
				
			||||||
 | 
					    <point x="88.97561" y="52.44877"/>
 | 
				
			||||||
 | 
					    <point x="0.000000" y="52.44877"/>
 | 
				
			||||||
 | 
					  </outline>
 | 
				
			||||||
 | 
					  <outline id="outline9" corner-radius="1.000000">
 | 
				
			||||||
 | 
					    <point x="0.000000" y="0.000000"/>
 | 
				
			||||||
 | 
					    <point x="109.2682" y="0.000000"/>
 | 
				
			||||||
 | 
					    <point x="109.2682" y="52.44877"/>
 | 
				
			||||||
 | 
					    <point x="0.000000" y="52.44877"/>
 | 
				
			||||||
 | 
					  </outline>
 | 
				
			||||||
 | 
					  <outline id="outline10" corner-radius="1.000000">
 | 
				
			||||||
 | 
					    <point x="0.000000" y="0.000000"/>
 | 
				
			||||||
 | 
					    <point x="37.46341" y="0.000000"/>
 | 
				
			||||||
 | 
					    <point x="37.46341" y="52.44877"/>
 | 
				
			||||||
 | 
					    <point x="0.000000" y="52.44877"/>
 | 
				
			||||||
 | 
					  </outline>
 | 
				
			||||||
 | 
					  <outline id="outline13" corner-radius="1.000000">
 | 
				
			||||||
 | 
					    <point x="0.000000" y="0.000000"/>
 | 
				
			||||||
 | 
					    <point x="79.60975" y="0.000000"/>
 | 
				
			||||||
 | 
					    <point x="79.60975" y="52.44877"/>
 | 
				
			||||||
 | 
					    <point x="0.000000" y="52.44877"/>
 | 
				
			||||||
  </outline>
 | 
					  </outline>
 | 
				
			||||||
  <outline id="spaceline" corner-radius="1.000000">
 | 
					  <outline id="spaceline" corner-radius="1.000000">
 | 
				
			||||||
    <point x="0.000000" y="0.000000"/>
 | 
					    <point x="0.000000" y="0.000000"/>
 | 
				
			||||||
    <point x="150.5853" y="0.000000"/>
 | 
					    <point x="150.5853" y="0.000000"/>
 | 
				
			||||||
    <point x="150.5853" y="52"/>
 | 
					    <point x="150.5853" y="52.44877"/>
 | 
				
			||||||
    <point x="0.000000" y="52"/>
 | 
					    <point x="0.000000" y="52.44877"/>
 | 
				
			||||||
  </outline>
 | 
					  </outline>
 | 
				
			||||||
 | 
					 | 
				
			||||||
  <button name="Shift_L" oref="altline" />
 | 
					 | 
				
			||||||
  <button name="BackSpace" oref="altline" />
 | 
					 | 
				
			||||||
  <button name="preferences" oref="altline" />
 | 
					 | 
				
			||||||
  <button name="show_numbers" oref="altline" keycode="0" />
 | 
					 | 
				
			||||||
  <button name="show_letters" oref="altline" keycode="0" />
 | 
					 | 
				
			||||||
  <button name="show_symbols" oref="altline" keycode="0" />
 | 
					 | 
				
			||||||
  <button name="period" oref="altline" />
 | 
					 | 
				
			||||||
  <button name="space" oref="spaceline" />
 | 
					 | 
				
			||||||
  <button name="Return" oref="outline7" />
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  <view>
 | 
					 | 
				
			||||||
    <section angle="0">q w e r t y u i o p</section>
 | 
					 | 
				
			||||||
    <section angle="0">a s d f g h j k l</section>
 | 
					 | 
				
			||||||
    <section angle="0"> Shift_L   z x c v b n m  BackSpace </section>
 | 
					 | 
				
			||||||
    <section angle="0"> show_numbers preferences         space        period    Return    </section>
 | 
					 | 
				
			||||||
  </view>
 | 
					 | 
				
			||||||
  <view>
 | 
					 | 
				
			||||||
    <section angle="0">Q W E R T Y U I O P</section>
 | 
					 | 
				
			||||||
    <section angle="0">A S D F G H J K L</section>
 | 
					 | 
				
			||||||
    <section angle="0"> Shift_L   Z X C V B N M  BackSpace </section>
 | 
					 | 
				
			||||||
    <section angle="0"> show_numbers preferences         space        period    Return    </section>
 | 
					 | 
				
			||||||
  </view>
 | 
					 | 
				
			||||||
  <view>
 | 
					 | 
				
			||||||
    <section angle="0">1 2 3 4 5 6 7 8 9 0</section>
 | 
					 | 
				
			||||||
    <section angle="0">at numbersign dollar percent ampersand minus underscore plus parenleft parenright</section>
 | 
					 | 
				
			||||||
    <section angle="0"> show_symbols   comma quotedbl quoteright colon semicolon exclam question  BackSpace </section>
 | 
					 | 
				
			||||||
    <section angle="0"> show_letters preferences         space        period    Return    </section>
 | 
					 | 
				
			||||||
  </view>
 | 
					 | 
				
			||||||
  <view>
 | 
					 | 
				
			||||||
    <section angle="0">asciitilde quoteleft bar U00B7 squareroot Greek_pi Greek_tau division multiply paragraph</section>
 | 
					 | 
				
			||||||
    <section angle="0">copyright U00AE U00A3 EuroSign U00A5 asciicircum degree asterisk braceleft braceright</section>
 | 
					 | 
				
			||||||
    <section angle="0"> show_numbers   backslash slash less greater equal bracketleft bracketright  BackSpace </section>
 | 
					 | 
				
			||||||
    <section angle="0"> show_letters preferences         space        period    Return    </section>
 | 
					 | 
				
			||||||
  </view>
 | 
					 | 
				
			||||||
</geometry>
 | 
					</geometry>
 | 
				
			||||||
 | 
				
			|||||||
@ -1,105 +0,0 @@
 | 
				
			|||||||
<?xml version="1.0"?>
 | 
					 | 
				
			||||||
<geometry version="0.90">
 | 
					 | 
				
			||||||
  <bounds x="0" y="10.000000" width="426.0000" height="296.5853"/>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  <outline id="outline2" corner-radius="1.000000">
 | 
					 | 
				
			||||||
    <point x="0.000000" y="0.000000"/>
 | 
					 | 
				
			||||||
    <point x="32" y="0.000000"/>
 | 
					 | 
				
			||||||
    <point x="32" y="52"/>
 | 
					 | 
				
			||||||
    <point x="0.000000" y="52"/>
 | 
					 | 
				
			||||||
  </outline>
 | 
					 | 
				
			||||||
  <outline id="altline" corner-radius="1.000000">
 | 
					 | 
				
			||||||
    <point x="0.000000" y="0.000000"/>
 | 
					 | 
				
			||||||
    <point x="48.39024" y="0.000000"/>
 | 
					 | 
				
			||||||
    <point x="48.39024" y="52"/>
 | 
					 | 
				
			||||||
    <point x="0.000000" y="52"/>
 | 
					 | 
				
			||||||
  </outline>
 | 
					 | 
				
			||||||
  <outline id="outline4" corner-radius="1.000000">
 | 
					 | 
				
			||||||
    <point x="0.000000" y="0.000000"/>
 | 
					 | 
				
			||||||
    <point x="59.31707" y="0.000000"/>
 | 
					 | 
				
			||||||
    <point x="59.31707" y="52"/>
 | 
					 | 
				
			||||||
    <point x="0.000000" y="52"/>
 | 
					 | 
				
			||||||
  </outline>
 | 
					 | 
				
			||||||
  <outline id="outline5" corner-radius="1.000000">
 | 
					 | 
				
			||||||
    <point x="0.000000" y="0.000000"/>
 | 
					 | 
				
			||||||
    <point x="59.31707" y="0.000000"/>
 | 
					 | 
				
			||||||
    <point x="59.31707" y="52"/>
 | 
					 | 
				
			||||||
    <point x="0.000000" y="52"/>
 | 
					 | 
				
			||||||
  </outline>
 | 
					 | 
				
			||||||
  <outline id="outline6" corner-radius="1.000000">
 | 
					 | 
				
			||||||
    <point x="0.000000" y="0.000000"/>
 | 
					 | 
				
			||||||
    <point x="68.68292" y="0.000000"/>
 | 
					 | 
				
			||||||
    <point x="68.68292" y="52"/>
 | 
					 | 
				
			||||||
    <point x="0.000000" y="52"/>
 | 
					 | 
				
			||||||
  </outline>
 | 
					 | 
				
			||||||
  <outline id="outline7" corner-radius="1.000000">
 | 
					 | 
				
			||||||
    <point x="0.000000" y="0.000000"/>
 | 
					 | 
				
			||||||
    <point x="88.97561" y="0.000000"/>
 | 
					 | 
				
			||||||
    <point x="88.97561" y="52"/>
 | 
					 | 
				
			||||||
    <point x="0.000000" y="52"/>
 | 
					 | 
				
			||||||
  </outline>
 | 
					 | 
				
			||||||
  <outline id="outline8" corner-radius="1.000000">
 | 
					 | 
				
			||||||
    <point x="0.000000" y="0.000000"/>
 | 
					 | 
				
			||||||
    <point x="88.97561" y="0.000000"/>
 | 
					 | 
				
			||||||
    <point x="88.97561" y="52"/>
 | 
					 | 
				
			||||||
    <point x="0.000000" y="52"/>
 | 
					 | 
				
			||||||
  </outline>
 | 
					 | 
				
			||||||
  <outline id="outline9" corner-radius="1.000000">
 | 
					 | 
				
			||||||
    <point x="0.000000" y="0.000000"/>
 | 
					 | 
				
			||||||
    <point x="109.2682" y="0.000000"/>
 | 
					 | 
				
			||||||
    <point x="109.2682" y="52"/>
 | 
					 | 
				
			||||||
    <point x="0.000000" y="52"/>
 | 
					 | 
				
			||||||
  </outline>
 | 
					 | 
				
			||||||
  <outline id="outline10" corner-radius="1.000000">
 | 
					 | 
				
			||||||
    <point x="0.000000" y="0.000000"/>
 | 
					 | 
				
			||||||
    <point x="37.46341" y="0.000000"/>
 | 
					 | 
				
			||||||
    <point x="37.46341" y="52"/>
 | 
					 | 
				
			||||||
    <point x="0.000000" y="52"/>
 | 
					 | 
				
			||||||
  </outline>
 | 
					 | 
				
			||||||
  <outline id="outline13" corner-radius="1.000000">
 | 
					 | 
				
			||||||
    <point x="0.000000" y="0.000000"/>
 | 
					 | 
				
			||||||
    <point x="79.60975" y="0.000000"/>
 | 
					 | 
				
			||||||
    <point x="79.60975" y="52"/>
 | 
					 | 
				
			||||||
    <point x="0.000000" y="52"/>
 | 
					 | 
				
			||||||
  </outline>
 | 
					 | 
				
			||||||
  <outline id="spaceline" corner-radius="1.000000">
 | 
					 | 
				
			||||||
    <point x="0.000000" y="0.000000"/>
 | 
					 | 
				
			||||||
    <point x="150.5853" y="0.000000"/>
 | 
					 | 
				
			||||||
    <point x="150.5853" y="52"/>
 | 
					 | 
				
			||||||
    <point x="0.000000" y="52"/>
 | 
					 | 
				
			||||||
  </outline>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  <button name="Shift_L" oref="altline" />
 | 
					 | 
				
			||||||
  <button name="BackSpace" oref="altline" />
 | 
					 | 
				
			||||||
  <button name="preferences" oref="altline" />
 | 
					 | 
				
			||||||
  <button name="show_numbers" oref="altline" keycode="0" />
 | 
					 | 
				
			||||||
  <button name="show_letters" oref="altline" keycode="0" />
 | 
					 | 
				
			||||||
  <button name="show_symbols" oref="altline" keycode="0" />
 | 
					 | 
				
			||||||
  <button name="space" oref="spaceline" />
 | 
					 | 
				
			||||||
  <button name="return" oref="outline7" />
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  <view>
 | 
					 | 
				
			||||||
    <section angle="0">q w e r t y u i o p aring</section>
 | 
					 | 
				
			||||||
    <section angle="0">a s d f g h j k l oslash ae</section>
 | 
					 | 
				
			||||||
    <section angle="0"> Shift_L   z x c v b n m  BackSpace </section>
 | 
					 | 
				
			||||||
    <section angle="0"> show_numbers preferences         space        period    Return    </section>
 | 
					 | 
				
			||||||
  </view>
 | 
					 | 
				
			||||||
  <view>
 | 
					 | 
				
			||||||
    <section angle="0">Q W E R T Y U I O P Aring</section>
 | 
					 | 
				
			||||||
    <section angle="0">A S D F G H J K L Oslash AE</section>
 | 
					 | 
				
			||||||
    <section angle="0"> Shift_L   Z X C V B N M  BackSpace </section>
 | 
					 | 
				
			||||||
    <section angle="0"> show_numbers preferences         space        period    Return    </section>
 | 
					 | 
				
			||||||
  </view>
 | 
					 | 
				
			||||||
  <view>
 | 
					 | 
				
			||||||
    <section angle="0">1 2 3 4 5 6 7 8 9 0</section>
 | 
					 | 
				
			||||||
    <section angle="0">at numbersign dollar percent ampersand minus underscore plus parenleft parenright</section>
 | 
					 | 
				
			||||||
    <section angle="0"> show_symbols   comma quotedbl quoteright colon semicolon exclam question  BackSpace </section>
 | 
					 | 
				
			||||||
    <section angle="0"> show_letters preferences         space        period    Return    </section>
 | 
					 | 
				
			||||||
  </view>
 | 
					 | 
				
			||||||
  <view>
 | 
					 | 
				
			||||||
    <section angle="0">asciitilde quoteleft bar U00B7 squareroot Greek_pi Greek_tau division multiply paragraph</section>
 | 
					 | 
				
			||||||
    <section angle="0">copyright U00AE U00A3 EuroSign U00A5 asciicircum degree asterisk braceleft braceright</section>
 | 
					 | 
				
			||||||
    <section angle="0"> show_numbers   backslash slash less greater equal bracketleft bracketright  BackSpace </section>
 | 
					 | 
				
			||||||
    <section angle="0"> show_letters preferences         space        period    Return    </section>
 | 
					 | 
				
			||||||
  </view>
 | 
					 | 
				
			||||||
</geometry>
 | 
					 | 
				
			||||||
@ -1,40 +0,0 @@
 | 
				
			|||||||
<?xml version="1.0"?>
 | 
					 | 
				
			||||||
<geometry version="0.90">
 | 
					 | 
				
			||||||
  <bounds x="0" y="10.000000" width="426.0000" height="296.5853"/>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  <outline id="default" corner-radius="1.000000">
 | 
					 | 
				
			||||||
    <point x="0.000000" y="0.000000"/>
 | 
					 | 
				
			||||||
    <point x="37.46341" y="0.000000"/>
 | 
					 | 
				
			||||||
    <point x="37.46341" y="52.44877"/>
 | 
					 | 
				
			||||||
    <point x="0.000000" y="52.44877"/>
 | 
					 | 
				
			||||||
  </outline>
 | 
					 | 
				
			||||||
  <outline id="altline" corner-radius="1.000000">
 | 
					 | 
				
			||||||
    <point x="0.000000" y="0.000000"/>
 | 
					 | 
				
			||||||
    <point x="48.39024" y="0.000000"/>
 | 
					 | 
				
			||||||
    <point x="48.39024" y="52.44877"/>
 | 
					 | 
				
			||||||
    <point x="0.000000" y="52.44877"/>
 | 
					 | 
				
			||||||
  </outline>
 | 
					 | 
				
			||||||
  <outline id="outline7" corner-radius="1.000000">
 | 
					 | 
				
			||||||
    <point x="0.000000" y="0.000000"/>
 | 
					 | 
				
			||||||
    <point x="88.97561" y="0.000000"/>
 | 
					 | 
				
			||||||
    <point x="88.97561" y="52.44877"/>
 | 
					 | 
				
			||||||
    <point x="0.000000" y="52.44877"/>
 | 
					 | 
				
			||||||
  </outline>
 | 
					 | 
				
			||||||
  <outline id="spaceline" corner-radius="1.000000">
 | 
					 | 
				
			||||||
    <point x="0.000000" y="0.000000"/>
 | 
					 | 
				
			||||||
    <point x="120.5853" y="0.000000"/>
 | 
					 | 
				
			||||||
    <point x="120.5853" y="52.44877"/>
 | 
					 | 
				
			||||||
    <point x="0.000000" y="52.44877"/>
 | 
					 | 
				
			||||||
  </outline>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  <button name="BackSpace" oref="altline" />
 | 
					 | 
				
			||||||
  <button name="space" oref="spaceline" />
 | 
					 | 
				
			||||||
  <button name="Return" oref="outline7" />
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  <view>
 | 
					 | 
				
			||||||
    <section angle="0">1 2 3 parenleft parenright</section>
 | 
					 | 
				
			||||||
    <section angle="0">4 5 6 numbersign asterisk</section>
 | 
					 | 
				
			||||||
    <section angle="0">7 8 9 plus minus</section>
 | 
					 | 
				
			||||||
    <section angle="0">BackSpace 0 space Return</section>
 | 
					 | 
				
			||||||
  </view>
 | 
					 | 
				
			||||||
</geometry>
 | 
					 | 
				
			||||||
@ -24,9 +24,6 @@
 | 
				
			|||||||
  <keyboard id="my" name="my"
 | 
					  <keyboard id="my" name="my"
 | 
				
			||||||
	    geometry="compact" symbols="my"
 | 
						    geometry="compact" symbols="my"
 | 
				
			||||||
	    longname="Myanmar" language="my"/>
 | 
						    longname="Myanmar" language="my"/>
 | 
				
			||||||
  <keyboard id="nb" name="nb"
 | 
					 | 
				
			||||||
	    geometry="extended" symbols="nb"
 | 
					 | 
				
			||||||
	    longname="Norwegian" language="nb"/>
 | 
					 | 
				
			||||||
  <keyboard id="ru" name="ru"
 | 
					  <keyboard id="ru" name="ru"
 | 
				
			||||||
	    geometry="compact" symbols="us"
 | 
						    geometry="compact" symbols="us"
 | 
				
			||||||
	    longname="Russian" language="ru"/>
 | 
						    longname="Russian" language="ru"/>
 | 
				
			||||||
@ -88,13 +85,4 @@
 | 
				
			|||||||
  <keyboard id="te-inscript" name="te-inscript"
 | 
					  <keyboard id="te-inscript" name="te-inscript"
 | 
				
			||||||
	    geometry="compact" symbols="te-inscript"
 | 
						    geometry="compact" symbols="te-inscript"
 | 
				
			||||||
	    longname="Telugu (Inscript)" language="te"/>
 | 
						    longname="Telugu (Inscript)" language="te"/>
 | 
				
			||||||
 | 
					 | 
				
			||||||
  <!-- Common keyboards -->
 | 
					 | 
				
			||||||
  <keyboard id="number" name="number"
 | 
					 | 
				
			||||||
	    geometry="number-keypad" symbols="special/number"
 | 
					 | 
				
			||||||
	    longname="Numeric keypad" language="all"/>
 | 
					 | 
				
			||||||
  <keyboard id="phone" name="phone"
 | 
					 | 
				
			||||||
	    geometry="number-keypad" symbols="special/number"
 | 
					 | 
				
			||||||
	    longname="Phone keypad" language="all"/>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
</keyboards>
 | 
					</keyboards>
 | 
				
			||||||
 | 
				
			|||||||
@ -1,132 +0,0 @@
 | 
				
			|||||||
<?xml version='1.0' encoding='UTF-8' standalone='yes'?>
 | 
					 | 
				
			||||||
<symbols version="0.90">
 | 
					 | 
				
			||||||
  <symbol label="*">asterisk</symbol>
 | 
					 | 
				
			||||||
  <symbol label="+/=">show_symbols</symbol>
 | 
					 | 
				
			||||||
  <symbol label="τ">Greek_tau</symbol>
 | 
					 | 
				
			||||||
  <symbol label="å">aring</symbol>
 | 
					 | 
				
			||||||
  <symbol label="ø">oslash</symbol>
 | 
					 | 
				
			||||||
  <symbol label="æ">ae</symbol>
 | 
					 | 
				
			||||||
  <symbol label="Å">Aring</symbol>
 | 
					 | 
				
			||||||
  <symbol label="Ø">Oslash</symbol>
 | 
					 | 
				
			||||||
  <symbol label="Æ">AE</symbol>
 | 
					 | 
				
			||||||
  <symbol label="q">q</symbol>
 | 
					 | 
				
			||||||
  <symbol label="Q">Q</symbol>
 | 
					 | 
				
			||||||
  <symbol label="1">1</symbol>
 | 
					 | 
				
			||||||
  <symbol label="~">asciitilde</symbol>
 | 
					 | 
				
			||||||
  <symbol label="w">w</symbol>
 | 
					 | 
				
			||||||
  <symbol label="W">W</symbol>
 | 
					 | 
				
			||||||
  <symbol label="2">2</symbol>
 | 
					 | 
				
			||||||
  <symbol label="`">quoteleft</symbol>
 | 
					 | 
				
			||||||
  <symbol label="e">e</symbol>
 | 
					 | 
				
			||||||
  <symbol label="E">E</symbol>
 | 
					 | 
				
			||||||
  <symbol label="3">3</symbol>
 | 
					 | 
				
			||||||
  <symbol label="|">bar</symbol>
 | 
					 | 
				
			||||||
  <symbol label="r">r</symbol>
 | 
					 | 
				
			||||||
  <symbol label="R">R</symbol>
 | 
					 | 
				
			||||||
  <symbol label="4">4</symbol>
 | 
					 | 
				
			||||||
  <symbol label="·">U00B7</symbol>
 | 
					 | 
				
			||||||
  <symbol label="t">t</symbol>
 | 
					 | 
				
			||||||
  <symbol label="T">T</symbol>
 | 
					 | 
				
			||||||
  <symbol label="5">5</symbol>
 | 
					 | 
				
			||||||
  <symbol label="√">squareroot</symbol>
 | 
					 | 
				
			||||||
  <symbol label="y">y</symbol>
 | 
					 | 
				
			||||||
  <symbol label="Y">Y</symbol>
 | 
					 | 
				
			||||||
  <symbol label="6">6</symbol>
 | 
					 | 
				
			||||||
  <symbol label="π">Greek_pi</symbol>
 | 
					 | 
				
			||||||
  <symbol label="u">u</symbol>
 | 
					 | 
				
			||||||
  <symbol label="U">U</symbol>
 | 
					 | 
				
			||||||
  <symbol label="7">7</symbol>
 | 
					 | 
				
			||||||
  <symbol label="÷">division</symbol>
 | 
					 | 
				
			||||||
  <symbol label="i">i</symbol>
 | 
					 | 
				
			||||||
  <symbol label="I">I</symbol>
 | 
					 | 
				
			||||||
  <symbol label="8">8</symbol>
 | 
					 | 
				
			||||||
  <symbol label="×">multiply</symbol>
 | 
					 | 
				
			||||||
  <symbol label="o">o</symbol>
 | 
					 | 
				
			||||||
  <symbol label="O">O</symbol>
 | 
					 | 
				
			||||||
  <symbol label="9">9</symbol>
 | 
					 | 
				
			||||||
  <symbol label="¶">paragraph</symbol>
 | 
					 | 
				
			||||||
  <symbol label="p">p</symbol>
 | 
					 | 
				
			||||||
  <symbol label="P">P</symbol>
 | 
					 | 
				
			||||||
  <symbol label="0">0</symbol>
 | 
					 | 
				
			||||||
  <symbol label="△">U25B3</symbol>
 | 
					 | 
				
			||||||
  <symbol keyval="229" label="å">aring</symbol>
 | 
					 | 
				
			||||||
  <symbol keyval="197" label="Å">Aring</symbol>
 | 
					 | 
				
			||||||
  <symbol label="a">a</symbol>
 | 
					 | 
				
			||||||
  <symbol label="A">A</symbol>
 | 
					 | 
				
			||||||
  <symbol label="@">at</symbol>
 | 
					 | 
				
			||||||
  <symbol label="©">copyright</symbol>
 | 
					 | 
				
			||||||
  <symbol label="s">s</symbol>
 | 
					 | 
				
			||||||
  <symbol label="S">S</symbol>
 | 
					 | 
				
			||||||
  <symbol label="#">numbersign</symbol>
 | 
					 | 
				
			||||||
  <symbol label="®">U00AE</symbol>
 | 
					 | 
				
			||||||
  <symbol label="d">d</symbol>
 | 
					 | 
				
			||||||
  <symbol label="D">D</symbol>
 | 
					 | 
				
			||||||
  <symbol label="$">dollar</symbol>
 | 
					 | 
				
			||||||
  <symbol label="£">U00A3</symbol>
 | 
					 | 
				
			||||||
  <symbol label="f">f</symbol>
 | 
					 | 
				
			||||||
  <symbol label="F">F</symbol>
 | 
					 | 
				
			||||||
  <symbol label="%">percent</symbol>
 | 
					 | 
				
			||||||
  <symbol label="€">EuroSign</symbol>
 | 
					 | 
				
			||||||
  <symbol label="g">g</symbol>
 | 
					 | 
				
			||||||
  <symbol label="G">G</symbol>
 | 
					 | 
				
			||||||
  <symbol label="&">ampersand</symbol>
 | 
					 | 
				
			||||||
  <symbol label="¥">U00A5</symbol>
 | 
					 | 
				
			||||||
  <symbol label="h">h</symbol>
 | 
					 | 
				
			||||||
  <symbol label="H">H</symbol>
 | 
					 | 
				
			||||||
  <symbol label="-">minus</symbol>
 | 
					 | 
				
			||||||
  <symbol label="^">asciicircum</symbol>
 | 
					 | 
				
			||||||
  <symbol label="j">j</symbol>
 | 
					 | 
				
			||||||
  <symbol label="J">J</symbol>
 | 
					 | 
				
			||||||
  <symbol label="_">underscore</symbol>
 | 
					 | 
				
			||||||
  <symbol label="°">degree</symbol>
 | 
					 | 
				
			||||||
  <symbol label="k">k</symbol>
 | 
					 | 
				
			||||||
  <symbol label="K">K</symbol>
 | 
					 | 
				
			||||||
  <symbol label="+">plus</symbol>
 | 
					 | 
				
			||||||
  <symbol label="=">equal</symbol>
 | 
					 | 
				
			||||||
  <symbol label="l">l</symbol>
 | 
					 | 
				
			||||||
  <symbol label="L">L</symbol>
 | 
					 | 
				
			||||||
  <symbol label="(">parenleft</symbol>
 | 
					 | 
				
			||||||
  <symbol label="{">braceleft</symbol>
 | 
					 | 
				
			||||||
  <symbol keyval="248" label="ø">oslash</symbol>
 | 
					 | 
				
			||||||
  <symbol keyval="216" label="Ø">Oslash</symbol>
 | 
					 | 
				
			||||||
  <symbol label=")">parenright</symbol>
 | 
					 | 
				
			||||||
  <symbol label="}">braceright</symbol>
 | 
					 | 
				
			||||||
  <symbol keyval="230" label="æ">ae</symbol>
 | 
					 | 
				
			||||||
  <symbol keyval="198" label="Æ">AE</symbol>
 | 
					 | 
				
			||||||
  <symbol keyval="65293" icon="key-enter">Return</symbol>
 | 
					 | 
				
			||||||
  <symbol keyval="65505" icon="key-shift">Shift_L</symbol>
 | 
					 | 
				
			||||||
  <symbol label="z">z</symbol>
 | 
					 | 
				
			||||||
  <symbol label="Z">Z</symbol>
 | 
					 | 
				
			||||||
  <symbol label=",">comma</symbol>
 | 
					 | 
				
			||||||
  <symbol label="\">backslash</symbol>
 | 
					 | 
				
			||||||
  <symbol label="x">x</symbol>
 | 
					 | 
				
			||||||
  <symbol label="X">X</symbol>
 | 
					 | 
				
			||||||
  <symbol label=""">quotedbl</symbol>
 | 
					 | 
				
			||||||
  <symbol label="/">slash</symbol>
 | 
					 | 
				
			||||||
  <symbol label="c">c</symbol>
 | 
					 | 
				
			||||||
  <symbol label="C">C</symbol>
 | 
					 | 
				
			||||||
  <symbol label="'">quoteright</symbol>
 | 
					 | 
				
			||||||
  <symbol label="<">less</symbol>
 | 
					 | 
				
			||||||
  <symbol label="v">v</symbol>
 | 
					 | 
				
			||||||
  <symbol label="V">V</symbol>
 | 
					 | 
				
			||||||
  <symbol label=":">colon</symbol>
 | 
					 | 
				
			||||||
  <symbol label=">">greater</symbol>
 | 
					 | 
				
			||||||
  <symbol label="b">b</symbol>
 | 
					 | 
				
			||||||
  <symbol label="B">B</symbol>
 | 
					 | 
				
			||||||
  <symbol label=";">semicolon</symbol>
 | 
					 | 
				
			||||||
  <symbol label="=">equal</symbol>
 | 
					 | 
				
			||||||
  <symbol label="n">n</symbol>
 | 
					 | 
				
			||||||
  <symbol label="N">N</symbol>
 | 
					 | 
				
			||||||
  <symbol label="!">exclam</symbol>
 | 
					 | 
				
			||||||
  <symbol label="[">bracketleft</symbol>
 | 
					 | 
				
			||||||
  <symbol label="m">m</symbol>
 | 
					 | 
				
			||||||
  <symbol label="M">M</symbol>
 | 
					 | 
				
			||||||
  <symbol label="?">question</symbol>
 | 
					 | 
				
			||||||
  <symbol label="]">bracketright</symbol>
 | 
					 | 
				
			||||||
  <symbol label=".">period</symbol>
 | 
					 | 
				
			||||||
  <symbol label="123">show_numbers</symbol>
 | 
					 | 
				
			||||||
  <symbol label="ABC">show_letters</symbol>
 | 
					 | 
				
			||||||
  <symbol label="☺" icon="keyboard-mode-symbolic" tooltip="Setup">preferences</symbol>
 | 
					 | 
				
			||||||
  <symbol label=" ">space</symbol>
 | 
					 | 
				
			||||||
  <symbol keyval="65288" icon="edit-clear-symbolic">BackSpace</symbol>
 | 
					 | 
				
			||||||
</symbols>
 | 
					 | 
				
			||||||
@ -1,22 +0,0 @@
 | 
				
			|||||||
<?xml version='1.0' encoding='ASCII' standalone='yes'?>
 | 
					 | 
				
			||||||
<symbols version="0.90">
 | 
					 | 
				
			||||||
  <symbol label="1">1</symbol>
 | 
					 | 
				
			||||||
  <symbol label="2">2</symbol>
 | 
					 | 
				
			||||||
  <symbol label="3">3</symbol>
 | 
					 | 
				
			||||||
  <symbol label="(">parenleft</symbol>
 | 
					 | 
				
			||||||
  <symbol label=")">parenright</symbol>
 | 
					 | 
				
			||||||
  <symbol label="4">4</symbol>
 | 
					 | 
				
			||||||
  <symbol label="5">5</symbol>
 | 
					 | 
				
			||||||
  <symbol label="6">6</symbol>
 | 
					 | 
				
			||||||
  <symbol label="#">numbersign</symbol>
 | 
					 | 
				
			||||||
  <symbol label="*">asterisk</symbol>
 | 
					 | 
				
			||||||
  <symbol label="7">7</symbol>
 | 
					 | 
				
			||||||
  <symbol label="8">8</symbol>
 | 
					 | 
				
			||||||
  <symbol label="9">9</symbol>
 | 
					 | 
				
			||||||
  <symbol label="+">plus</symbol>
 | 
					 | 
				
			||||||
  <symbol label="-">minus</symbol>
 | 
					 | 
				
			||||||
  <symbol label="0">0</symbol>
 | 
					 | 
				
			||||||
  <symbol keyval="65293" icon="key-enter">Return</symbol>
 | 
					 | 
				
			||||||
  <symbol label=" ">space</symbol>
 | 
					 | 
				
			||||||
  <symbol keyval="65288" icon="edit-clear-symbolic">BackSpace</symbol>
 | 
					 | 
				
			||||||
</symbols>
 | 
					 | 
				
			||||||
@ -1,118 +1,304 @@
 | 
				
			|||||||
<?xml version='1.0' encoding='ASCII' standalone='yes'?>
 | 
					<?xml version="1.0"?>
 | 
				
			||||||
<symbols version="0.90">
 | 
					<symbols version="0.90">
 | 
				
			||||||
  <symbol label="*">asterisk</symbol>
 | 
					  <key keycode="9" name="ESC">
 | 
				
			||||||
  <symbol label="+/=">show_symbols</symbol>
 | 
					    <keysym keyval="65307">Escape</keysym>
 | 
				
			||||||
  <symbol label="q">q</symbol>
 | 
					  </key>
 | 
				
			||||||
  <symbol label="Q">Q</symbol>
 | 
					  <key keycode="67" name="FK01">
 | 
				
			||||||
  <symbol label="1">1</symbol>
 | 
					    <keysym keyval="65470">F1</keysym>
 | 
				
			||||||
  <symbol label="~">asciitilde</symbol>
 | 
					  </key>
 | 
				
			||||||
  <symbol label="w">w</symbol>
 | 
					  <key keycode="68" name="FK02">
 | 
				
			||||||
  <symbol label="W">W</symbol>
 | 
					    <keysym keyval="65471">F2</keysym>
 | 
				
			||||||
  <symbol label="2">2</symbol>
 | 
					  </key>
 | 
				
			||||||
  <symbol label="`">quoteleft</symbol>
 | 
					  <key keycode="69" name="FK03">
 | 
				
			||||||
  <symbol label="e">e</symbol>
 | 
					    <keysym keyval="65472">F3</keysym>
 | 
				
			||||||
  <symbol label="E">E</symbol>
 | 
					  </key>
 | 
				
			||||||
  <symbol label="3">3</symbol>
 | 
					  <key keycode="70" name="FK04">
 | 
				
			||||||
  <symbol label="|">bar</symbol>
 | 
					    <keysym keyval="65473">F4</keysym>
 | 
				
			||||||
  <symbol label="r">r</symbol>
 | 
					  </key>
 | 
				
			||||||
  <symbol label="R">R</symbol>
 | 
					  <key keycode="71" name="FK05">
 | 
				
			||||||
  <symbol label="4">4</symbol>
 | 
					    <keysym keyval="65474">F5</keysym>
 | 
				
			||||||
  <symbol label="·">U00B7</symbol>
 | 
					  </key>
 | 
				
			||||||
  <symbol label="t">t</symbol>
 | 
					  <key keycode="72" name="FK06">
 | 
				
			||||||
  <symbol label="T">T</symbol>
 | 
					    <keysym keyval="65475">F6</keysym>
 | 
				
			||||||
  <symbol label="5">5</symbol>
 | 
					  </key>
 | 
				
			||||||
  <symbol label="√">squareroot</symbol>
 | 
					  <key keycode="73" name="FK07">
 | 
				
			||||||
  <symbol label="y">y</symbol>
 | 
					    <keysym keyval="65476">F7</keysym>
 | 
				
			||||||
  <symbol label="Y">Y</symbol>
 | 
					  </key>
 | 
				
			||||||
  <symbol label="6">6</symbol>
 | 
					  <key keycode="74" name="FK08">
 | 
				
			||||||
  <symbol label="π">Greek_pi</symbol>
 | 
					    <keysym keyval="65477">F8</keysym>
 | 
				
			||||||
  <symbol label="u">u</symbol>
 | 
					  </key>
 | 
				
			||||||
  <symbol label="U">U</symbol>
 | 
					  <key keycode="75" name="FK09">
 | 
				
			||||||
  <symbol label="7">7</symbol>
 | 
					    <keysym keyval="65478">F9</keysym>
 | 
				
			||||||
  <symbol label="÷">division</symbol>
 | 
					  </key>
 | 
				
			||||||
  <symbol label="i">i</symbol>
 | 
					  <key keycode="76" name="FK10">
 | 
				
			||||||
  <symbol label="I">I</symbol>
 | 
					    <keysym keyval="65479">F10</keysym>
 | 
				
			||||||
  <symbol label="8">8</symbol>
 | 
					  </key>
 | 
				
			||||||
  <symbol label="×">multiply</symbol>
 | 
					  <key keycode="95" name="FK11">
 | 
				
			||||||
  <symbol label="o">o</symbol>
 | 
					    <keysym keyval="65480">F11</keysym>
 | 
				
			||||||
  <symbol label="O">O</symbol>
 | 
					  </key>
 | 
				
			||||||
  <symbol label="9">9</symbol>
 | 
					  <key keycode="96" name="FK12">
 | 
				
			||||||
  <symbol label="¶">paragraph</symbol>
 | 
					    <keysym keyval="65481">F12</keysym>
 | 
				
			||||||
  <symbol label="p">p</symbol>
 | 
					  </key>
 | 
				
			||||||
  <symbol label="P">P</symbol>
 | 
					  <key keycode="49" name="TLDE">
 | 
				
			||||||
  <symbol label="0">0</symbol>
 | 
					    <keysym keyval="96">quoteleft</keysym>
 | 
				
			||||||
  <symbol label="τ">Greek_tau</symbol>
 | 
					    <keysym keyval="126">asciitilde</keysym>
 | 
				
			||||||
  <symbol label="a">a</symbol>
 | 
					  </key>
 | 
				
			||||||
  <symbol label="A">A</symbol>
 | 
					  <key keycode="10" name="AE01">
 | 
				
			||||||
  <symbol label="@">at</symbol>
 | 
					    <keysym keyval="49">1</keysym>
 | 
				
			||||||
  <symbol label="©">copyright</symbol>
 | 
					    <keysym keyval="33">exclam</keysym>
 | 
				
			||||||
  <symbol label="s">s</symbol>
 | 
					  </key>
 | 
				
			||||||
  <symbol label="S">S</symbol>
 | 
					  <key keycode="11" name="AE02">
 | 
				
			||||||
  <symbol label="#">numbersign</symbol>
 | 
					    <keysym keyval="50">2</keysym>
 | 
				
			||||||
  <symbol label="®">U00AE</symbol>
 | 
					    <keysym keyval="64">at</keysym>
 | 
				
			||||||
  <symbol label="d">d</symbol>
 | 
					  </key>
 | 
				
			||||||
  <symbol label="D">D</symbol>
 | 
					  <key keycode="12" name="AE03">
 | 
				
			||||||
  <symbol label="$">dollar</symbol>
 | 
					    <keysym keyval="51">3</keysym>
 | 
				
			||||||
  <symbol label="£">U00A3</symbol>
 | 
					    <keysym keyval="35">numbersign</keysym>
 | 
				
			||||||
  <symbol label="f">f</symbol>
 | 
					  </key>
 | 
				
			||||||
  <symbol label="F">F</symbol>
 | 
					  <key keycode="13" name="AE04">
 | 
				
			||||||
  <symbol label="%">percent</symbol>
 | 
					    <keysym keyval="52">4</keysym>
 | 
				
			||||||
  <symbol label="€">EuroSign</symbol>
 | 
					    <keysym keyval="36">dollar</keysym>
 | 
				
			||||||
  <symbol label="g">g</symbol>
 | 
					  </key>
 | 
				
			||||||
  <symbol label="G">G</symbol>
 | 
					  <key keycode="14" name="AE05">
 | 
				
			||||||
  <symbol label="&">ampersand</symbol>
 | 
					    <keysym keyval="53">5</keysym>
 | 
				
			||||||
  <symbol label="¥">U00A5</symbol>
 | 
					    <keysym keyval="37">percent</keysym>
 | 
				
			||||||
  <symbol label="h">h</symbol>
 | 
					    <keysym keyval="8364">EuroSign</keysym>
 | 
				
			||||||
  <symbol label="H">H</symbol>
 | 
					  </key>
 | 
				
			||||||
  <symbol label="-">minus</symbol>
 | 
					  <key keycode="15" name="AE06">
 | 
				
			||||||
  <symbol label="^">asciicircum</symbol>
 | 
					    <keysym keyval="54">6</keysym>
 | 
				
			||||||
  <symbol label="j">j</symbol>
 | 
					    <keysym keyval="94">asciicircum</keysym>
 | 
				
			||||||
  <symbol label="J">J</symbol>
 | 
					  </key>
 | 
				
			||||||
  <symbol label="_">underscore</symbol>
 | 
					  <key keycode="16" name="AE07">
 | 
				
			||||||
  <symbol label="°">degree</symbol>
 | 
					    <keysym keyval="55">7</keysym>
 | 
				
			||||||
  <symbol label="k">k</symbol>
 | 
					    <keysym keyval="38">ampersand</keysym>
 | 
				
			||||||
  <symbol label="K">K</symbol>
 | 
					  </key>
 | 
				
			||||||
  <symbol label="+">plus</symbol>
 | 
					  <key keycode="17" name="AE08">
 | 
				
			||||||
  <symbol label="=">equal</symbol>
 | 
					    <keysym keyval="56">8</keysym>
 | 
				
			||||||
  <symbol label="l">l</symbol>
 | 
					    <keysym keyval="42">asterisk</keysym>
 | 
				
			||||||
  <symbol label="L">L</symbol>
 | 
					  </key>
 | 
				
			||||||
  <symbol label="(">parenleft</symbol>
 | 
					  <key keycode="18" name="AE09">
 | 
				
			||||||
  <symbol label="{">braceleft</symbol>
 | 
					    <keysym keyval="57">9</keysym>
 | 
				
			||||||
  <symbol label=")">parenright</symbol>
 | 
					    <keysym keyval="40">parenleft</keysym>
 | 
				
			||||||
  <symbol label="}">braceright</symbol>
 | 
					  </key>
 | 
				
			||||||
  <symbol keyval="65293" icon="key-enter">Return</symbol>
 | 
					  <key keycode="19" name="AE10">
 | 
				
			||||||
  <symbol keyval="65505" icon="key-shift">Shift_L</symbol>
 | 
					    <keysym keyval="48">0</keysym>
 | 
				
			||||||
  <symbol label="z">z</symbol>
 | 
					    <keysym keyval="41">parenright</keysym>
 | 
				
			||||||
  <symbol label="Z">Z</symbol>
 | 
					  </key>
 | 
				
			||||||
  <symbol label=",">comma</symbol>
 | 
					  <key keycode="20" name="AE11">
 | 
				
			||||||
  <symbol label="\">backslash</symbol>
 | 
					    <keysym keyval="45">minus</keysym>
 | 
				
			||||||
  <symbol label="x">x</symbol>
 | 
					    <keysym keyval="95">underscore</keysym>
 | 
				
			||||||
  <symbol label="X">X</symbol>
 | 
					  </key>
 | 
				
			||||||
  <symbol label=""">quotedbl</symbol>
 | 
					  <key keycode="21" name="AE12">
 | 
				
			||||||
  <symbol label="/">slash</symbol>
 | 
					    <keysym keyval="61">equal</keysym>
 | 
				
			||||||
  <symbol label="c">c</symbol>
 | 
					    <keysym keyval="43">plus</keysym>
 | 
				
			||||||
  <symbol label="C">C</symbol>
 | 
					  </key>
 | 
				
			||||||
  <symbol label="'">quoteright</symbol>
 | 
					  <key keycode="22" name="BKSP">
 | 
				
			||||||
  <symbol label="<">less</symbol>
 | 
					    <keysym keyval="65288">BackSpace</keysym>
 | 
				
			||||||
  <symbol label="v">v</symbol>
 | 
					  </key>
 | 
				
			||||||
  <symbol label="V">V</symbol>
 | 
					  <key keycode="23" name="TAB">
 | 
				
			||||||
  <symbol label=":">colon</symbol>
 | 
					    <keysym keyval="65289">Tab</keysym>
 | 
				
			||||||
  <symbol label=">">greater</symbol>
 | 
					    <keysym keyval="65056">ISO_Left_Tab</keysym>
 | 
				
			||||||
  <symbol label="b">b</symbol>
 | 
					  </key>
 | 
				
			||||||
  <symbol label="B">B</symbol>
 | 
					  <key keycode="24" name="AD01">
 | 
				
			||||||
  <symbol label=";">semicolon</symbol>
 | 
					    <keysym keyval="113">q</keysym>
 | 
				
			||||||
  <symbol label="n">n</symbol>
 | 
					    <keysym keyval="81">Q</keysym>
 | 
				
			||||||
  <symbol label="N">N</symbol>
 | 
					    <keysym keyval="49">1</keysym>
 | 
				
			||||||
  <symbol label="!">exclam</symbol>
 | 
					  </key>
 | 
				
			||||||
  <symbol label="[">bracketleft</symbol>
 | 
					  <key keycode="25" name="AD02">
 | 
				
			||||||
  <symbol label="m">m</symbol>
 | 
					    <keysym keyval="119">w</keysym>
 | 
				
			||||||
  <symbol label="M">M</symbol>
 | 
					    <keysym keyval="87">W</keysym>
 | 
				
			||||||
  <symbol label="?">question</symbol>
 | 
					    <keysym keyval="50">2</keysym>
 | 
				
			||||||
  <symbol label="]">bracketright</symbol>
 | 
					  </key>
 | 
				
			||||||
  <symbol label=".">period</symbol>
 | 
					  <key keycode="26" name="AD03">
 | 
				
			||||||
  <symbol label="123">show_numbers</symbol>
 | 
					    <keysym keyval="101">e</keysym>
 | 
				
			||||||
  <symbol label="ABC">show_letters</symbol>
 | 
					    <keysym keyval="69">E</keysym>
 | 
				
			||||||
  <symbol label="☺" icon="keyboard-mode-symbolic" tooltip="Setup">preferences</symbol>
 | 
					    <keysym keyval="51">3</keysym>
 | 
				
			||||||
  <symbol label=" ">space</symbol>
 | 
					  </key>
 | 
				
			||||||
  <symbol keyval="65288" icon="edit-clear-symbolic">BackSpace</symbol>
 | 
					  <key keycode="27" name="AD04">
 | 
				
			||||||
 | 
					    <keysym keyval="114">r</keysym>
 | 
				
			||||||
 | 
					    <keysym keyval="82">R</keysym>
 | 
				
			||||||
 | 
					    <keysym keyval="52">4</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>
 | 
				
			||||||
 | 
					    <keysym keyval="123">braceleft</keysym>
 | 
				
			||||||
 | 
					  </key>
 | 
				
			||||||
 | 
					  <key keycode="35" name="AD12">
 | 
				
			||||||
 | 
					    <keysym keyval="93">bracketright</keysym>
 | 
				
			||||||
 | 
					    <keysym keyval="125">braceright</keysym>
 | 
				
			||||||
 | 
					  </key>
 | 
				
			||||||
 | 
					  <key keycode="51" name="BKSL">
 | 
				
			||||||
 | 
					    <keysym keyval="92">backslash</keysym>
 | 
				
			||||||
 | 
					    <keysym keyval="124">bar</keysym>
 | 
				
			||||||
 | 
					  </key>
 | 
				
			||||||
 | 
					  <key keycode="66" name="ALTGR">
 | 
				
			||||||
 | 
					    <keysym keyval="65027">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>
 | 
				
			||||||
 | 
					  </key>
 | 
				
			||||||
 | 
					  <key keycode="39" name="AC02">
 | 
				
			||||||
 | 
					    <keysym keyval="115">s</keysym>
 | 
				
			||||||
 | 
					    <keysym keyval="83">S</keysym>
 | 
				
			||||||
 | 
					    <keysym keyval="35">numbersign</keysym>
 | 
				
			||||||
 | 
					  </key>
 | 
				
			||||||
 | 
					  <key keycode="40" name="AC03">
 | 
				
			||||||
 | 
					    <keysym keyval="100">d</keysym>
 | 
				
			||||||
 | 
					    <keysym keyval="68">D</keysym>
 | 
				
			||||||
 | 
					    <keysym keyval="36">dollar</keysym>
 | 
				
			||||||
 | 
					  </key>
 | 
				
			||||||
 | 
					  <key keycode="41" name="AC04">
 | 
				
			||||||
 | 
					    <keysym keyval="102">f</keysym>
 | 
				
			||||||
 | 
					    <keysym keyval="70">F</keysym>
 | 
				
			||||||
 | 
					    <keysym keyval="37">percent</keysym>
 | 
				
			||||||
 | 
					  </key>
 | 
				
			||||||
 | 
					  <key keycode="42" name="AC05">
 | 
				
			||||||
 | 
					    <keysym keyval="103">g</keysym>
 | 
				
			||||||
 | 
					    <keysym keyval="71">G</keysym>
 | 
				
			||||||
 | 
					    <keysym keyval="38">ampersand</keysym>
 | 
				
			||||||
 | 
					  </key>
 | 
				
			||||||
 | 
					  <key keycode="43" name="AC06">
 | 
				
			||||||
 | 
					    <keysym keyval="104">h</keysym>
 | 
				
			||||||
 | 
					    <keysym keyval="72">H</keysym>
 | 
				
			||||||
 | 
					    <keysym keyval="45">minus</keysym>
 | 
				
			||||||
 | 
					  </key>
 | 
				
			||||||
 | 
					  <key keycode="44" name="AC07">
 | 
				
			||||||
 | 
					    <keysym keyval="106">j</keysym>
 | 
				
			||||||
 | 
					    <keysym keyval="74">J</keysym>
 | 
				
			||||||
 | 
					    <keysym keyval="95">underscore</keysym>
 | 
				
			||||||
 | 
					  </key>
 | 
				
			||||||
 | 
					  <key keycode="45" name="AC08">
 | 
				
			||||||
 | 
					    <keysym keyval="107">k</keysym>
 | 
				
			||||||
 | 
					    <keysym keyval="75">K</keysym>
 | 
				
			||||||
 | 
					    <keysym keyval="123">braceleft</keysym>
 | 
				
			||||||
 | 
					  </key>
 | 
				
			||||||
 | 
					  <key keycode="46" name="AC09">
 | 
				
			||||||
 | 
					    <keysym keyval="108">l</keysym>
 | 
				
			||||||
 | 
					    <keysym keyval="76">L</keysym>
 | 
				
			||||||
 | 
					    <keysym keyval="125">braceright</keysym>
 | 
				
			||||||
 | 
					  </key>
 | 
				
			||||||
 | 
					  <key keycode="47" name="AC10">
 | 
				
			||||||
 | 
					    <keysym keyval="59">semicolon</keysym>
 | 
				
			||||||
 | 
					    <keysym keyval="58">colon</keysym>
 | 
				
			||||||
 | 
					  </key>
 | 
				
			||||||
 | 
					  <key keycode="48" name="AC11">
 | 
				
			||||||
 | 
					    <keysym keyval="39">quoteright</keysym>
 | 
				
			||||||
 | 
					    <keysym keyval="34">quotedbl</keysym>
 | 
				
			||||||
 | 
					  </key>
 | 
				
			||||||
 | 
					  <key keycode="36" name="RTRN">
 | 
				
			||||||
 | 
					    <keysym keyval="65293">Return</keysym>
 | 
				
			||||||
 | 
					  </key>
 | 
				
			||||||
 | 
					  <key keycode="50" name="LFSH">
 | 
				
			||||||
 | 
					    <keysym keyval="65505">Shift_L</keysym>
 | 
				
			||||||
 | 
					  </key>
 | 
				
			||||||
 | 
					  <key keycode="52" name="AB01">
 | 
				
			||||||
 | 
					    <keysym keyval="122">z</keysym>
 | 
				
			||||||
 | 
					    <keysym keyval="90">Z</keysym>
 | 
				
			||||||
 | 
					    <keysym keyval="43">plus</keysym>
 | 
				
			||||||
 | 
					  </key>
 | 
				
			||||||
 | 
					  <key keycode="53" name="AB02">
 | 
				
			||||||
 | 
					    <keysym keyval="120">x</keysym>
 | 
				
			||||||
 | 
					    <keysym keyval="88">X</keysym>
 | 
				
			||||||
 | 
					    <keysym keyval="34">quotedbl</keysym>
 | 
				
			||||||
 | 
					  </key>
 | 
				
			||||||
 | 
					  <key keycode="54" name="AB03">
 | 
				
			||||||
 | 
					    <keysym keyval="99">c</keysym>
 | 
				
			||||||
 | 
					    <keysym keyval="67">C</keysym>
 | 
				
			||||||
 | 
					    <keysym keyval="39">quoteright</keysym>
 | 
				
			||||||
 | 
					  </key>
 | 
				
			||||||
 | 
					  <key keycode="55" name="AB04">
 | 
				
			||||||
 | 
					    <keysym keyval="118">v</keysym>
 | 
				
			||||||
 | 
					    <keysym keyval="86">V</keysym>
 | 
				
			||||||
 | 
					    <keysym keyval="58">colon</keysym>
 | 
				
			||||||
 | 
					  </key>
 | 
				
			||||||
 | 
					  <key keycode="56" name="AB05">
 | 
				
			||||||
 | 
					    <keysym keyval="98">b</keysym>
 | 
				
			||||||
 | 
					    <keysym keyval="66">B</keysym>
 | 
				
			||||||
 | 
					    <keysym keyval="59">semicolon</keysym>
 | 
				
			||||||
 | 
					  </key>
 | 
				
			||||||
 | 
					  <key keycode="57" name="AB06">
 | 
				
			||||||
 | 
					    <keysym keyval="110">n</keysym>
 | 
				
			||||||
 | 
					    <keysym keyval="78">N</keysym>
 | 
				
			||||||
 | 
					    <keysym keyval="33">exclam</keysym>
 | 
				
			||||||
 | 
					  </key>
 | 
				
			||||||
 | 
					  <key keycode="58" name="AB07">
 | 
				
			||||||
 | 
					    <keysym keyval="109">m</keysym>
 | 
				
			||||||
 | 
					    <keysym keyval="77">M</keysym>
 | 
				
			||||||
 | 
					    <keysym keyval="63">question</keysym>
 | 
				
			||||||
 | 
					  </key>
 | 
				
			||||||
 | 
					  <key keycode="59" name="AB08">
 | 
				
			||||||
 | 
					    <keysym keyval="44">comma</keysym>
 | 
				
			||||||
 | 
					    <keysym keyval="60">less</keysym>
 | 
				
			||||||
 | 
					  </key>
 | 
				
			||||||
 | 
					  <key keycode="60" name="AB09">
 | 
				
			||||||
 | 
					    <keysym keyval="46">period</keysym>
 | 
				
			||||||
 | 
					    <keysym keyval="62">greater</keysym>
 | 
				
			||||||
 | 
					  </key>
 | 
				
			||||||
 | 
					  <key keycode="61" name="AB10">
 | 
				
			||||||
 | 
					    <keysym keyval="47">slash</keysym>
 | 
				
			||||||
 | 
					    <keysym keyval="63">question</keysym>
 | 
				
			||||||
 | 
					  </key>
 | 
				
			||||||
 | 
					  <key keycode="62" name="RTSH">
 | 
				
			||||||
 | 
					    <keysym keyval="65506">Shift_R</keysym>
 | 
				
			||||||
 | 
					  </key>
 | 
				
			||||||
 | 
					  <key keycode="149" name="I149">
 | 
				
			||||||
 | 
					    <symbol label="⌨" icon="input-keyboard-symbolic" tooltip="Change keyboard">cycle-keyboard</symbol>
 | 
				
			||||||
 | 
					  </key>
 | 
				
			||||||
 | 
					  <key keycode="150" name="I150">
 | 
				
			||||||
 | 
					    <symbol label="☺" icon="preferences-system-symbolic" tooltip="Setup">preferences</symbol>
 | 
				
			||||||
 | 
					  </key>
 | 
				
			||||||
 | 
					  <key keycode="37" name="LCTL">
 | 
				
			||||||
 | 
					    <keysym keyval="65507">Control_L</keysym>
 | 
				
			||||||
 | 
					  </key>
 | 
				
			||||||
 | 
					  <key keycode="64" name="LALT">
 | 
				
			||||||
 | 
					    <keysym keyval="65513">Alt_L</keysym>
 | 
				
			||||||
 | 
					    <keysym keyval="65511">Meta_L</keysym>
 | 
				
			||||||
 | 
					  </key>
 | 
				
			||||||
 | 
					  <key keycode="65" name="SPCE">
 | 
				
			||||||
 | 
					    <keysym keyval="32">space</keysym>
 | 
				
			||||||
 | 
					  </key>
 | 
				
			||||||
 | 
					  <key keycode="113" name="LEFT">
 | 
				
			||||||
 | 
					    <keysym keyval="65361">Left</keysym>
 | 
				
			||||||
 | 
					  </key>
 | 
				
			||||||
 | 
					  <key keycode="111" name="UP">
 | 
				
			||||||
 | 
					    <keysym keyval="65362">Up</keysym>
 | 
				
			||||||
 | 
					  </key>
 | 
				
			||||||
 | 
					  <key keycode="116" name="DOWN">
 | 
				
			||||||
 | 
					    <keysym keyval="65364">Down</keysym>
 | 
				
			||||||
 | 
					  </key>
 | 
				
			||||||
 | 
					  <key keycode="114" name="RGHT">
 | 
				
			||||||
 | 
					    <keysym keyval="65363">Right</keysym>
 | 
				
			||||||
 | 
					  </key>
 | 
				
			||||||
</symbols>
 | 
					</symbols>
 | 
				
			||||||
 | 
				
			|||||||
@ -1,12 +1,57 @@
 | 
				
			|||||||
gnome = import('gnome')
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
squeekboard_resources = gnome.compile_resources(
 | 
					install_data(
 | 
				
			||||||
   'squeekboard-resources',
 | 
					    'themes/default.css',
 | 
				
			||||||
   'squeekboard.gresources.xml',
 | 
					    install_dir: pkgdatadir + '/themes',
 | 
				
			||||||
 | 
					 | 
				
			||||||
   c_name: 'squeekboard',
 | 
					 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					install_data(
 | 
				
			||||||
 | 
					    'keyboards/keyboards.xml',
 | 
				
			||||||
 | 
					    install_dir: pkgdatadir + '/keyboards/',
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					install_data(
 | 
				
			||||||
 | 
					    'keyboards/geometry/compact.xml',
 | 
				
			||||||
 | 
					    install_dir: pkgdatadir + '/keyboards/geometry/',
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					symbols = [
 | 
				
			||||||
 | 
					    'ar.xml',
 | 
				
			||||||
 | 
					    'as-inscript.xml',
 | 
				
			||||||
 | 
					    'be.xml',
 | 
				
			||||||
 | 
					    'bn-inscript.xml',
 | 
				
			||||||
 | 
					    'fa.xml',
 | 
				
			||||||
 | 
					    'gu-inscript.xml',
 | 
				
			||||||
 | 
					    'he.xml',
 | 
				
			||||||
 | 
					    'hi-inscript.xml',
 | 
				
			||||||
 | 
					    'ja-kana.xml',
 | 
				
			||||||
 | 
					    'kk.xml',
 | 
				
			||||||
 | 
					    'kn-inscript.xml',
 | 
				
			||||||
 | 
					    'ks-inscript.xml',
 | 
				
			||||||
 | 
					    'ks.xml',
 | 
				
			||||||
 | 
					    'mai-inscript.xml',
 | 
				
			||||||
 | 
					    'ml-inscript.xml',
 | 
				
			||||||
 | 
					    'mr-inscript.xml',
 | 
				
			||||||
 | 
					    'my.xml',
 | 
				
			||||||
 | 
					    'or-inscript.xml',
 | 
				
			||||||
 | 
					    'pa-inscript.xml',
 | 
				
			||||||
 | 
					    'ru.xml',
 | 
				
			||||||
 | 
					    'sd-inscript.xml',
 | 
				
			||||||
 | 
					    'ta-inscript.xml',
 | 
				
			||||||
 | 
					    'te-inscript.xml',
 | 
				
			||||||
 | 
					    'th.xml',
 | 
				
			||||||
 | 
					    'ua.xml',
 | 
				
			||||||
 | 
					    'ug.xml',
 | 
				
			||||||
 | 
					    'us.xml',
 | 
				
			||||||
 | 
					    'zh-bopomofo.xml',
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					foreach symbol: symbols
 | 
				
			||||||
 | 
					    install_data(
 | 
				
			||||||
 | 
					        'keyboards/symbols/' + symbol,
 | 
				
			||||||
 | 
					        install_dir: pkgdatadir + '/keyboards/symbols/',
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					endforeach
 | 
				
			||||||
 | 
					
 | 
				
			||||||
desktop_file = 'sm.puri.Squeekboard.desktop'
 | 
					desktop_file = 'sm.puri.Squeekboard.desktop'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
i18n.merge_file('desktop',
 | 
					i18n.merge_file('desktop',
 | 
				
			||||||
 | 
				
			|||||||
@ -1,43 +0,0 @@
 | 
				
			|||||||
<?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/geometry/extended.xml</file>
 | 
					 | 
				
			||||||
   <file compressed="true" preprocess="xml-stripblanks">keyboards/geometry/number-keypad.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/nb.xml</file>
 | 
					 | 
				
			||||||
   <file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/or-inscript.xml</file>
 | 
					 | 
				
			||||||
   <file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/pa-inscript.xml</file>
 | 
					 | 
				
			||||||
   <file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/ru.xml</file>
 | 
					 | 
				
			||||||
   <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>
 | 
					 | 
				
			||||||
   <file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/special/number.xml</file>
 | 
					 | 
				
			||||||
   <file>icons/key-enter.svg</file>
 | 
					 | 
				
			||||||
   <file>icons/key-shift.svg</file>
 | 
					 | 
				
			||||||
   <file>icons/keyboard-mode-symbolic.svg</file>
 | 
					 | 
				
			||||||
  </gresource>
 | 
					 | 
				
			||||||
</gresources>
 | 
					 | 
				
			||||||
							
								
								
									
										4
									
								
								data/themes/Makefile.am
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,4 @@
 | 
				
			|||||||
 | 
					themedir = $(pkgdatadir)/themes
 | 
				
			||||||
 | 
					dist_theme_DATA = default.css
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					-include $(top_srcdir)/git.mk
 | 
				
			||||||
@ -7,8 +7,7 @@
 | 
				
			|||||||
.key {
 | 
					.key {
 | 
				
			||||||
    color: #deddda;
 | 
					    color: #deddda;
 | 
				
			||||||
    background: #464448;
 | 
					    background: #464448;
 | 
				
			||||||
    border-style: solid;
 | 
					    border-width: 0.5px;
 | 
				
			||||||
    border-width: 1px;
 | 
					 | 
				
			||||||
    border-color: #5e5c64;
 | 
					    border-color: #5e5c64;
 | 
				
			||||||
    border-radius: 2px;
 | 
					    border-radius: 2px;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
							
								
								
									
										6
									
								
								debian/control
									
									
									
									
										vendored
									
									
								
							
							
						
						@ -11,10 +11,8 @@ Build-Depends:
 | 
				
			|||||||
 libcroco3-dev,
 | 
					 libcroco3-dev,
 | 
				
			||||||
 libwayland-dev (>= 1.16),
 | 
					 libwayland-dev (>= 1.16),
 | 
				
			||||||
 rustc,
 | 
					 rustc,
 | 
				
			||||||
 wayland-protocols (>= 1.14),
 | 
					 virtboard,
 | 
				
			||||||
# for running the tests
 | 
					 wayland-protocols (>= 1.14)
 | 
				
			||||||
 xvfb,
 | 
					 | 
				
			||||||
 xauth,
 | 
					 | 
				
			||||||
Standards-Version: 4.1.3
 | 
					Standards-Version: 4.1.3
 | 
				
			||||||
Homepage: https://source.puri.sm/Librem5/squeekboard
 | 
					Homepage: https://source.puri.sm/Librem5/squeekboard
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										57
									
								
								debian/copyright
									
									
									
									
										vendored
									
									
								
							
							
						
						@ -1,60 +1,9 @@
 | 
				
			|||||||
Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
 | 
					Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
 | 
				
			||||||
Upstream-Name: squeekboard
 | 
					Upstream-Name: evscript
 | 
				
			||||||
Source: https://source.puri.sm/Librem5/squeekboard
 | 
					Source: https://source.puri.sm/david.boddie/evscript
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Files: *
 | 
					Files: *
 | 
				
			||||||
Copyright: 2010-2011 Daiki Ueno <ueno@unixuser.org>
 | 
					Copyright: 2019 Purism SPC
 | 
				
			||||||
           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+
 | 
					License: GPL-3+
 | 
				
			||||||
 This package is free software; you can redistribute it and/or modify
 | 
					 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
 | 
					 it under the terms of the GNU General Public License as published by
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										21
									
								
								docs/Makefile.am
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,21 @@
 | 
				
			|||||||
 | 
					# 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
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					-include $(top_srcdir)/git.mk
 | 
				
			||||||
							
								
								
									
										21
									
								
								docs/reference/Makefile.am
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,21 @@
 | 
				
			|||||||
 | 
					# 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
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					-include $(top_srcdir)/git.mk
 | 
				
			||||||
							
								
								
									
										133
									
								
								docs/reference/eek/Makefile.am
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,133 @@
 | 
				
			|||||||
 | 
					# 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
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					-include $(top_srcdir)/git.mk
 | 
				
			||||||
							
								
								
									
										122
									
								
								docs/reference/eekboard/Makefile.am
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,122 @@
 | 
				
			|||||||
 | 
					# 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
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					-include $(top_srcdir)/git.mk
 | 
				
			||||||
							
								
								
									
										298
									
								
								eek/Makefile.am
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,298 @@
 | 
				
			|||||||
 | 
					# 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
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					NULL =
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					lib_LTLIBRARIES =				\
 | 
				
			||||||
 | 
						libeek.la				\
 | 
				
			||||||
 | 
						libeek-gtk.la				\
 | 
				
			||||||
 | 
						libeek-xkl.la				\
 | 
				
			||||||
 | 
						$(NULL)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					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				\
 | 
				
			||||||
 | 
						$(NULL)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					libeek_private_headers =			\
 | 
				
			||||||
 | 
						$(srcdir)/eek-renderer.h		\
 | 
				
			||||||
 | 
						$(libeek_keysym_headers)		\
 | 
				
			||||||
 | 
						$(builddir)/eek-marshalers.h		\
 | 
				
			||||||
 | 
						$(srcdir)/eek-theme-context.h		\
 | 
				
			||||||
 | 
						$(srcdir)/eek-theme-private.h		\
 | 
				
			||||||
 | 
						$(srcdir)/eek-theme-node.h		\
 | 
				
			||||||
 | 
						$(NULL)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					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		\
 | 
				
			||||||
 | 
						$(NULL)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					libeek_keysym_headers =					\
 | 
				
			||||||
 | 
						$(builddir)/eek-special-keysym-entries.h	\
 | 
				
			||||||
 | 
						$(builddir)/eek-unicode-keysym-entries.h	\
 | 
				
			||||||
 | 
						$(builddir)/eek-xkeysym-keysym-entries.h	\
 | 
				
			||||||
 | 
						$(NULL)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					libeek_enumtypes_sources =			\
 | 
				
			||||||
 | 
						$(builddir)/eek-enumtypes.c		\
 | 
				
			||||||
 | 
						$(builddir)/eek-enumtypes.h		\
 | 
				
			||||||
 | 
						$(NULL)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					libeek_marshalers_sources =			\
 | 
				
			||||||
 | 
						$(builddir)/eek-marshalers.c		\
 | 
				
			||||||
 | 
						$(builddir)/eek-marshalers.h		\
 | 
				
			||||||
 | 
						$(NULL)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					BUILT_SOURCES =					\
 | 
				
			||||||
 | 
						$(libeek_keysym_headers)		\
 | 
				
			||||||
 | 
						$(libeek_enumtypes_sources)		\
 | 
				
			||||||
 | 
						$(libeek_marshalers_sources)		\
 | 
				
			||||||
 | 
						$(NULL)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					libeek_la_SOURCES =				\
 | 
				
			||||||
 | 
						$(libeek_sources)			\
 | 
				
			||||||
 | 
						$(builddir)/eek-enumtypes.c		\
 | 
				
			||||||
 | 
						$(builddir)/eek-marshalers.c		\
 | 
				
			||||||
 | 
						$(NULL)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					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			\
 | 
				
			||||||
 | 
						$(NULL)
 | 
				
			||||||
 | 
					libeek_gtk_private_headers =			\
 | 
				
			||||||
 | 
						$(srcdir)/eek-gtk-renderer.h		\
 | 
				
			||||||
 | 
						$(NULL)
 | 
				
			||||||
 | 
					libeek_gtk_sources =				\
 | 
				
			||||||
 | 
						$(srcdir)/eek-gtk-keyboard.c		\
 | 
				
			||||||
 | 
						$(srcdir)/eek-gtk-renderer.c		\
 | 
				
			||||||
 | 
						$(NULL)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					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			\
 | 
				
			||||||
 | 
						$(NULL)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					libeek_xkl_sources =				\
 | 
				
			||||||
 | 
						$(srcdir)/eek-xkb-layout.c		\
 | 
				
			||||||
 | 
						$(srcdir)/eek-xkl-layout.c		\
 | 
				
			||||||
 | 
						$(NULL)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					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)		\
 | 
				
			||||||
 | 
						$(builddir)/eek-enumtypes.h		\
 | 
				
			||||||
 | 
						$(libeek_gtk_public_headers)		\
 | 
				
			||||||
 | 
						$(libeek_xkl_public_headers)		\
 | 
				
			||||||
 | 
						$(NULL)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					noinst_HEADERS =				\
 | 
				
			||||||
 | 
						$(libeek_private_headers)		\
 | 
				
			||||||
 | 
						$(libeek_gtk_private_headers)		\
 | 
				
			||||||
 | 
						$(libeek_xkl_private_headers)		\
 | 
				
			||||||
 | 
						$(NULL)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					eek-special-keysym-entries.h: special-keysym-entries.txt
 | 
				
			||||||
 | 
						$(AM_V_GEN) $(PYTHON) $(srcdir)/gen-keysym-entries.py \
 | 
				
			||||||
 | 
							special_keysym_entries \
 | 
				
			||||||
 | 
							< $< > $@
 | 
				
			||||||
 | 
					eek-unicode-keysym-entries.h: unicode-keysym-entries.txt
 | 
				
			||||||
 | 
						$(AM_V_GEN) $(PYTHON) $(srcdir)/gen-keysym-entries.py \
 | 
				
			||||||
 | 
							unicode_keysym_entries \
 | 
				
			||||||
 | 
							< $< > $@
 | 
				
			||||||
 | 
					eek-xkeysym-keysym-entries.h: xkeysym-keysym-entries.txt
 | 
				
			||||||
 | 
						$(AM_V_GEN) $(PYTHON) $(srcdir)/gen-keysym-entries.py \
 | 
				
			||||||
 | 
							xkeysym_keysym_entries \
 | 
				
			||||||
 | 
							< $< > $@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					eek-enumtypes.h: $(libeek_public_headers) eek-enumtypes.h.template
 | 
				
			||||||
 | 
						$(AM_V_GEN) $(GLIB_MKENUMS) \
 | 
				
			||||||
 | 
							--template $(srcdir)/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 $(srcdir)/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		\
 | 
				
			||||||
 | 
						$(NULL)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					CLEANFILES =
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					DISTCLEANFILES =				\
 | 
				
			||||||
 | 
						$(BUILT_SOURCES)			\
 | 
				
			||||||
 | 
						$(pkgconfig_DATA)			\
 | 
				
			||||||
 | 
						$(NULL)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					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			\
 | 
				
			||||||
 | 
						$(NULL)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					-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 =	\
 | 
				
			||||||
 | 
						--identifier-prefix=Eek			\
 | 
				
			||||||
 | 
						--symbol-prefix=eek			\
 | 
				
			||||||
 | 
						--pkg=glib-2.0				\
 | 
				
			||||||
 | 
						--pkg-export=eek-$(EEK_API_VERSION)	\
 | 
				
			||||||
 | 
						$(NULL)
 | 
				
			||||||
 | 
					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)		\
 | 
				
			||||||
 | 
						$(builddir)/eek-enumtypes.h		\
 | 
				
			||||||
 | 
						$(NULL)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					EekGtk@EEK_LIBRARY_SUFFIX@.gir: libeek-gtk.la Eek@EEK_LIBRARY_SUFFIX@.gir
 | 
				
			||||||
 | 
					EekGtk@EEK_LIBRARY_SUFFIX_U@_gir_SCANNERFLAGS =	\
 | 
				
			||||||
 | 
						--identifier-prefix=Eek			\
 | 
				
			||||||
 | 
						--symbol-prefix=eek			\
 | 
				
			||||||
 | 
						--pkg-export=eek-gtk-$(EEK_API_VERSION)	\
 | 
				
			||||||
 | 
						$(NULL)
 | 
				
			||||||
 | 
					EekGtk@EEK_LIBRARY_SUFFIX_U@_gir_INCLUDES =	\
 | 
				
			||||||
 | 
						GObject-2.0				\
 | 
				
			||||||
 | 
						Gtk-@GTK_API_VERSION@			\
 | 
				
			||||||
 | 
						Eek@EEK_LIBRARY_SUFFIX@			\
 | 
				
			||||||
 | 
						$(NULL)
 | 
				
			||||||
 | 
					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)		\
 | 
				
			||||||
 | 
						$(NULL)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					EekXkl@EEK_LIBRARY_SUFFIX@.gir: libeek-xkl.la Eek@EEK_LIBRARY_SUFFIX@.gir
 | 
				
			||||||
 | 
					EekXkl@EEK_LIBRARY_SUFFIX_U@_gir_SCANNERFLAGS = \
 | 
				
			||||||
 | 
						--identifier-prefix=Eek			\
 | 
				
			||||||
 | 
						--symbol-prefix=eek			\
 | 
				
			||||||
 | 
						$(NULL)
 | 
				
			||||||
 | 
					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)		\
 | 
				
			||||||
 | 
						$(NULL)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					INTROSPECTION_GIRS +=				\
 | 
				
			||||||
 | 
						Eek@EEK_LIBRARY_SUFFIX@.gir		\
 | 
				
			||||||
 | 
						EekGtk@EEK_LIBRARY_SUFFIX@.gir		\
 | 
				
			||||||
 | 
						EekXkl@EEK_LIBRARY_SUFFIX@.gir		\
 | 
				
			||||||
 | 
						$(NULL)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					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
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					-include $(top_srcdir)/git.mk
 | 
				
			||||||
							
								
								
									
										0
									
								
								eek/config.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
							
								
								
									
										234
									
								
								eek/eek-container.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,234 @@
 | 
				
			|||||||
 | 
					/* 
 | 
				
			||||||
 | 
					 * Copyright (C) 2010-2011 Daiki Ueno <ueno@unixuser.org>
 | 
				
			||||||
 | 
					 * Copyright (C) 2010-2011 Red Hat, Inc.
 | 
				
			||||||
 | 
					 * 
 | 
				
			||||||
 | 
					 * This library is free software; you can redistribute it and/or
 | 
				
			||||||
 | 
					 * modify it under the terms of the GNU Lesser General Public License
 | 
				
			||||||
 | 
					 * as published by the Free Software Foundation; either version 2 of
 | 
				
			||||||
 | 
					 * the License, or (at your option) any later version.
 | 
				
			||||||
 | 
					 * 
 | 
				
			||||||
 | 
					 * This library is distributed in the hope that it will be useful, but
 | 
				
			||||||
 | 
					 * WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
				
			||||||
 | 
					 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
				
			||||||
 | 
					 * Lesser General Public License for more details.
 | 
				
			||||||
 | 
					 * 
 | 
				
			||||||
 | 
					 * You should have received a copy of the GNU Lesser General Public
 | 
				
			||||||
 | 
					 * License along with this library; if not, write to the Free Software
 | 
				
			||||||
 | 
					 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 | 
				
			||||||
 | 
					 * 02110-1301 USA
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * SECTION:eek-container
 | 
				
			||||||
 | 
					 * @short_description: Base class of a keyboard container
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * The #EekContainerClass class represents a keyboard container, which
 | 
				
			||||||
 | 
					 * shall be used to implement #EekKeyboard and #EekSection.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef HAVE_CONFIG_H
 | 
				
			||||||
 | 
					#include "config.h"
 | 
				
			||||||
 | 
					#endif  /* HAVE_CONFIG_H */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "eek-container.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					enum {
 | 
				
			||||||
 | 
					    CHILD_ADDED,
 | 
				
			||||||
 | 
					    CHILD_REMOVED,
 | 
				
			||||||
 | 
					    LAST_SIGNAL
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static guint signals[LAST_SIGNAL] = { 0, };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef struct _EekContainerPrivate
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    GList *head;
 | 
				
			||||||
 | 
					    GList *last;
 | 
				
			||||||
 | 
					} EekContainerPrivate;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (EekContainer, eek_container, EEK_TYPE_ELEMENT)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					eek_container_real_add_child (EekContainer *self,
 | 
				
			||||||
 | 
					                              EekElement   *child)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    EekContainerPrivate *priv = eek_container_get_instance_private (self);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    g_return_if_fail (EEK_IS_ELEMENT(child));
 | 
				
			||||||
 | 
					    g_object_ref (child);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (!priv->head) {
 | 
				
			||||||
 | 
					        priv->head = priv->last = g_list_prepend (priv->head, child);
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					        priv->last->next = g_list_prepend (priv->last->next, child);
 | 
				
			||||||
 | 
					        priv->last = priv->last->next;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    eek_element_set_parent (child, EEK_ELEMENT(self));
 | 
				
			||||||
 | 
					    g_signal_emit (self, signals[CHILD_ADDED], 0, child);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					eek_container_real_remove_child (EekContainer *self,
 | 
				
			||||||
 | 
					                                 EekElement   *child)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    EekContainerPrivate *priv = eek_container_get_instance_private (self);
 | 
				
			||||||
 | 
					    GList *head;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    g_return_if_fail (EEK_IS_ELEMENT(child));
 | 
				
			||||||
 | 
					    head = g_list_find (priv->head, child);
 | 
				
			||||||
 | 
					    g_return_if_fail (head);
 | 
				
			||||||
 | 
					    g_object_unref (child);
 | 
				
			||||||
 | 
					    if (head == priv->last)
 | 
				
			||||||
 | 
					        priv->last = g_list_previous (priv->last);
 | 
				
			||||||
 | 
					    priv->head = g_list_remove_link (priv->head, head);
 | 
				
			||||||
 | 
					    eek_element_set_parent (child, NULL);
 | 
				
			||||||
 | 
					    g_signal_emit (self, signals[CHILD_REMOVED], 0, child);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					eek_container_real_foreach_child (EekContainer *self,
 | 
				
			||||||
 | 
					                                  EekCallback   callback,
 | 
				
			||||||
 | 
					                                  gpointer      user_data)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    EekContainerPrivate *priv = eek_container_get_instance_private (self);
 | 
				
			||||||
 | 
					    GList *head;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for (head = priv->head; head; head = g_list_next (head))
 | 
				
			||||||
 | 
					        (*callback) (EEK_ELEMENT(head->data), user_data);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static EekElement *
 | 
				
			||||||
 | 
					eek_container_real_find (EekContainer *self,
 | 
				
			||||||
 | 
					                         EekCompareFunc func,
 | 
				
			||||||
 | 
					                         gpointer user_data)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    EekContainerPrivate *priv = eek_container_get_instance_private (self);
 | 
				
			||||||
 | 
					    GList *head;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    head = g_list_find_custom (priv->head, user_data, (GCompareFunc)func);
 | 
				
			||||||
 | 
					    if (head)
 | 
				
			||||||
 | 
					        return head->data;
 | 
				
			||||||
 | 
					    return NULL;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					eek_container_dispose (GObject *object)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    EekContainer        *self = EEK_CONTAINER (object);
 | 
				
			||||||
 | 
					    EekContainerPrivate *priv = eek_container_get_instance_private (self);
 | 
				
			||||||
 | 
					    GList *head;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for (head = priv->head; head; head = priv->head) {
 | 
				
			||||||
 | 
					        g_object_unref (head->data);
 | 
				
			||||||
 | 
					        priv->head = g_list_next (head);
 | 
				
			||||||
 | 
					        g_list_free1 (head);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    G_OBJECT_CLASS(eek_container_parent_class)->dispose (object);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					eek_container_class_init (EekContainerClass *klass)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    GObjectClass      *gobject_class = G_OBJECT_CLASS (klass);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    klass->add_child = eek_container_real_add_child;
 | 
				
			||||||
 | 
					    klass->remove_child = eek_container_real_remove_child;
 | 
				
			||||||
 | 
					    klass->foreach_child = eek_container_real_foreach_child;
 | 
				
			||||||
 | 
					    klass->find = eek_container_real_find;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* signals */
 | 
				
			||||||
 | 
					    klass->child_added = NULL;
 | 
				
			||||||
 | 
					    klass->child_removed = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    gobject_class->dispose = eek_container_dispose;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * EekContainer::child-added:
 | 
				
			||||||
 | 
					     * @container: an #EekContainer
 | 
				
			||||||
 | 
					     * @element: an #EekElement
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * The ::child-added signal is emitted each time an element is
 | 
				
			||||||
 | 
					     * added to @container.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    signals[CHILD_ADDED] =
 | 
				
			||||||
 | 
					        g_signal_new (I_("child-added"),
 | 
				
			||||||
 | 
					                      G_TYPE_FROM_CLASS(gobject_class),
 | 
				
			||||||
 | 
					                      G_SIGNAL_RUN_FIRST,
 | 
				
			||||||
 | 
					                      G_STRUCT_OFFSET(EekContainerClass, child_added),
 | 
				
			||||||
 | 
					                      NULL, NULL,
 | 
				
			||||||
 | 
					                      g_cclosure_marshal_VOID__OBJECT,
 | 
				
			||||||
 | 
					                      G_TYPE_NONE, 1,
 | 
				
			||||||
 | 
					                      EEK_TYPE_ELEMENT);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * EekContainer::child-removed:
 | 
				
			||||||
 | 
					     * @container: an #EekContainer
 | 
				
			||||||
 | 
					     * @element: an #EekElement
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * The ::child-removed signal is emitted each time an element is
 | 
				
			||||||
 | 
					     * removed from @container.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    signals[CHILD_REMOVED] =
 | 
				
			||||||
 | 
					        g_signal_new (I_("child-removed"),
 | 
				
			||||||
 | 
					                      G_TYPE_FROM_CLASS(gobject_class),
 | 
				
			||||||
 | 
					                      G_SIGNAL_RUN_FIRST,
 | 
				
			||||||
 | 
					                      G_STRUCT_OFFSET(EekContainerClass, child_removed),
 | 
				
			||||||
 | 
					                      NULL,
 | 
				
			||||||
 | 
					                      NULL,
 | 
				
			||||||
 | 
					                      g_cclosure_marshal_VOID__OBJECT,
 | 
				
			||||||
 | 
					                      G_TYPE_NONE, 1,
 | 
				
			||||||
 | 
					                      EEK_TYPE_ELEMENT);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					eek_container_init (EekContainer *self)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    /* void */
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * eek_container_foreach_child:
 | 
				
			||||||
 | 
					 * @container: an #EekContainer
 | 
				
			||||||
 | 
					 * @callback: (scope call): an #EekCallback
 | 
				
			||||||
 | 
					 * @user_data: additional data passed to @callback
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Enumerate children of @container and run @callback with each child.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					eek_container_foreach_child (EekContainer *container,
 | 
				
			||||||
 | 
					                             EekCallback   callback,
 | 
				
			||||||
 | 
					                             gpointer      user_data)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    g_return_if_fail (EEK_IS_CONTAINER(container));
 | 
				
			||||||
 | 
					    EEK_CONTAINER_GET_CLASS(container)->foreach_child (container,
 | 
				
			||||||
 | 
					                                                       callback,
 | 
				
			||||||
 | 
					                                                       user_data);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * eek_container_find:
 | 
				
			||||||
 | 
					 * @container: an #EekContainer
 | 
				
			||||||
 | 
					 * @func: function to be used to compare two children
 | 
				
			||||||
 | 
					 * @user_data: additional data passed to @func
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Find a child which matches the criteria supplied as @func, in @container.
 | 
				
			||||||
 | 
					 * Returns: an #EekElement or NULL on failure
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					EekElement *
 | 
				
			||||||
 | 
					eek_container_find (EekContainer  *container,
 | 
				
			||||||
 | 
					                    EekCompareFunc func,
 | 
				
			||||||
 | 
					                    gpointer       user_data)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    g_return_val_if_fail (EEK_IS_CONTAINER(container), NULL);
 | 
				
			||||||
 | 
					    return EEK_CONTAINER_GET_CLASS(container)->find (container,
 | 
				
			||||||
 | 
					                                                     func,
 | 
				
			||||||
 | 
					                                                     user_data);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					eek_container_add_child (EekContainer *container, EekElement *element)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    g_return_if_fail (EEK_IS_CONTAINER(container));
 | 
				
			||||||
 | 
					    g_return_if_fail (EEK_IS_ELEMENT(element));
 | 
				
			||||||
 | 
					    return EEK_CONTAINER_GET_CLASS(container)->add_child (container, element);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										94
									
								
								eek/eek-container.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,94 @@
 | 
				
			|||||||
 | 
					/* 
 | 
				
			||||||
 | 
					 * Copyright (C) 2010-2011 Daiki Ueno <ueno@unixuser.org>
 | 
				
			||||||
 | 
					 * Copyright (C) 2010-2011 Red Hat, Inc.
 | 
				
			||||||
 | 
					 * 
 | 
				
			||||||
 | 
					 * This library is free software; you can redistribute it and/or
 | 
				
			||||||
 | 
					 * modify it under the terms of the GNU Lesser General Public License
 | 
				
			||||||
 | 
					 * as published by the Free Software Foundation; either version 2 of
 | 
				
			||||||
 | 
					 * the License, or (at your option) any later version.
 | 
				
			||||||
 | 
					 * 
 | 
				
			||||||
 | 
					 * This library is distributed in the hope that it will be useful, but
 | 
				
			||||||
 | 
					 * WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
				
			||||||
 | 
					 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
				
			||||||
 | 
					 * Lesser General Public License for more details.
 | 
				
			||||||
 | 
					 * 
 | 
				
			||||||
 | 
					 * You should have received a copy of the GNU Lesser General Public
 | 
				
			||||||
 | 
					 * License along with this library; if not, write to the Free Software
 | 
				
			||||||
 | 
					 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 | 
				
			||||||
 | 
					 * 02110-1301 USA
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if !defined(__EEK_H_INSIDE__) && !defined(EEK_COMPILATION)
 | 
				
			||||||
 | 
					#error "Only <eek/eek.h> can be included directly."
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef EEK_CONTAINER_H
 | 
				
			||||||
 | 
					#define EEK_CONTAINER_H 1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "eek-element.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					G_BEGIN_DECLS
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define EEK_TYPE_CONTAINER (eek_container_get_type())
 | 
				
			||||||
 | 
					G_DECLARE_DERIVABLE_TYPE (EekContainer, eek_container, EEK, CONTAINER, EekElement)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * EekCallback:
 | 
				
			||||||
 | 
					 * @element: an #EekElement
 | 
				
			||||||
 | 
					 * @user_data: user-supplied data
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * The type of the callback function used for iterating over the
 | 
				
			||||||
 | 
					 * children of a container, see eek_container_foreach_child().
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					typedef void (*EekCallback) (EekElement *element, gpointer user_data);
 | 
				
			||||||
 | 
					typedef gint (*EekCompareFunc) (EekElement *element, gpointer user_data);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * EekContainerClass:
 | 
				
			||||||
 | 
					 * @foreach_child: virtual function for iterating over the container's children
 | 
				
			||||||
 | 
					 * @find: virtual function for looking up a child
 | 
				
			||||||
 | 
					 * @child_added: class handler for #EekContainer::child-added
 | 
				
			||||||
 | 
					 * @child_removed: class handler for #EekContainer::child-added
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					struct _EekContainerClass
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    /*< private >*/
 | 
				
			||||||
 | 
					    EekElementClass parent_class;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    void        (* add_child)      (EekContainer      *self,
 | 
				
			||||||
 | 
					                                    EekElement        *element);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    void        (* remove_child)   (EekContainer      *self,
 | 
				
			||||||
 | 
					                                    EekElement        *element);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /*< public >*/
 | 
				
			||||||
 | 
					    void        (* foreach_child)  (EekContainer      *self,
 | 
				
			||||||
 | 
					                                    EekCallback        callback,
 | 
				
			||||||
 | 
					                                    gpointer           user_data);
 | 
				
			||||||
 | 
					    EekElement *(* find)           (EekContainer      *self,
 | 
				
			||||||
 | 
					                                    EekCompareFunc     func,
 | 
				
			||||||
 | 
					                                    gpointer           data);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* signals */
 | 
				
			||||||
 | 
					    void        (* child_added)    (EekContainer      *self,
 | 
				
			||||||
 | 
					                                    EekElement        *element);
 | 
				
			||||||
 | 
					    void        (* child_removed)  (EekContainer      *self,
 | 
				
			||||||
 | 
					                                    EekElement        *element);
 | 
				
			||||||
 | 
					    /*< private >*/
 | 
				
			||||||
 | 
					    /* padding */
 | 
				
			||||||
 | 
					    gpointer pdummy[24];
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					GType       eek_container_get_type      (void) G_GNUC_CONST;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void        eek_container_foreach_child (EekContainer  *container,
 | 
				
			||||||
 | 
					                                         EekCallback    callback,
 | 
				
			||||||
 | 
					                                         gpointer       user_data);
 | 
				
			||||||
 | 
					EekElement *eek_container_find          (EekContainer  *container,
 | 
				
			||||||
 | 
					                                         EekCompareFunc func,
 | 
				
			||||||
 | 
					                                         gpointer       user_data);
 | 
				
			||||||
 | 
					void        eek_container_add_child     (EekContainer  *container,
 | 
				
			||||||
 | 
					                                         EekElement    *element);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					G_END_DECLS
 | 
				
			||||||
 | 
					#endif  /* EEK_CONTAINER_H */
 | 
				
			||||||
@ -26,28 +26,58 @@
 | 
				
			|||||||
 * shall be used to implement #EekKeyboard, #EekSection, or #EekKey.
 | 
					 * shall be used to implement #EekKeyboard, #EekSection, or #EekKey.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef HAVE_CONFIG_H
 | 
				
			||||||
#include "config.h"
 | 
					#include "config.h"
 | 
				
			||||||
 | 
					#endif  /* HAVE_CONFIG_H */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <string.h>
 | 
					#include <string.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "eek-element.h"
 | 
					#include "eek-element.h"
 | 
				
			||||||
 | 
					#include "eek-container.h"
 | 
				
			||||||
 | 
					#include "eek-marshalers.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
enum {
 | 
					enum {
 | 
				
			||||||
    PROP_0,
 | 
					    PROP_0,
 | 
				
			||||||
 | 
					    PROP_NAME,
 | 
				
			||||||
    PROP_BOUNDS,
 | 
					    PROP_BOUNDS,
 | 
				
			||||||
 | 
					    PROP_GROUP,
 | 
				
			||||||
 | 
					    PROP_LEVEL,
 | 
				
			||||||
    PROP_LAST
 | 
					    PROP_LAST
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					enum {
 | 
				
			||||||
 | 
					    SYMBOL_INDEX_CHANGED,
 | 
				
			||||||
 | 
					    LAST_SIGNAL
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static guint signals[LAST_SIGNAL] = { 0, };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef struct _EekElementPrivate
 | 
					typedef struct _EekElementPrivate
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					    gchar *name;
 | 
				
			||||||
    EekBounds bounds;
 | 
					    EekBounds bounds;
 | 
				
			||||||
 | 
					    EekElement *parent;
 | 
				
			||||||
 | 
					    gint group;
 | 
				
			||||||
 | 
					    gint level;
 | 
				
			||||||
} EekElementPrivate;
 | 
					} EekElementPrivate;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (EekElement, eek_element, G_TYPE_OBJECT)
 | 
					G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (EekElement, eek_element, G_TYPE_OBJECT)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					eek_element_real_symbol_index_changed (EekElement *self,
 | 
				
			||||||
 | 
					                                       gint        group,
 | 
				
			||||||
 | 
					                                       gint        level)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    // g_debug ("symbol-index-changed");
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void
 | 
					static void
 | 
				
			||||||
eek_element_finalize (GObject *object)
 | 
					eek_element_finalize (GObject *object)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					    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);
 | 
					    G_OBJECT_CLASS (eek_element_parent_class)->finalize (object);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -60,9 +90,18 @@ eek_element_set_property (GObject      *object,
 | 
				
			|||||||
    EekElement *element = EEK_ELEMENT(object);
 | 
					    EekElement *element = EEK_ELEMENT(object);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    switch (prop_id) {
 | 
					    switch (prop_id) {
 | 
				
			||||||
 | 
					    case PROP_NAME:
 | 
				
			||||||
 | 
					        eek_element_set_name (element,
 | 
				
			||||||
 | 
					                              g_value_dup_string (value));
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
    case PROP_BOUNDS:
 | 
					    case PROP_BOUNDS:
 | 
				
			||||||
        eek_element_set_bounds (element, g_value_get_boxed (value));
 | 
					        eek_element_set_bounds (element, g_value_get_boxed (value));
 | 
				
			||||||
        break;
 | 
					        break;
 | 
				
			||||||
 | 
					    case PROP_GROUP:
 | 
				
			||||||
 | 
					        eek_element_set_group (element, g_value_get_int (value));
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					    case PROP_LEVEL:
 | 
				
			||||||
 | 
					        eek_element_set_level (element, g_value_get_int (value));
 | 
				
			||||||
    default:
 | 
					    default:
 | 
				
			||||||
        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 | 
					        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 | 
				
			||||||
        break;
 | 
					        break;
 | 
				
			||||||
@ -79,10 +118,19 @@ eek_element_get_property (GObject    *object,
 | 
				
			|||||||
    EekBounds bounds;
 | 
					    EekBounds bounds;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    switch (prop_id) {
 | 
					    switch (prop_id) {
 | 
				
			||||||
 | 
					    case PROP_NAME:
 | 
				
			||||||
 | 
					        g_value_set_string (value, eek_element_get_name (element));
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
    case PROP_BOUNDS:
 | 
					    case PROP_BOUNDS:
 | 
				
			||||||
        eek_element_get_bounds (element, &bounds);
 | 
					        eek_element_get_bounds (element, &bounds);
 | 
				
			||||||
        g_value_set_boxed (value, &bounds);
 | 
					        g_value_set_boxed (value, &bounds);
 | 
				
			||||||
        break;
 | 
					        break;
 | 
				
			||||||
 | 
					    case PROP_GROUP:
 | 
				
			||||||
 | 
					        g_value_set_int (value, eek_element_get_group (element));
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					    case PROP_LEVEL:
 | 
				
			||||||
 | 
					        g_value_set_int (value, eek_element_get_level (element));
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
    default:
 | 
					    default:
 | 
				
			||||||
        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 | 
					        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 | 
				
			||||||
        break;
 | 
					        break;
 | 
				
			||||||
@ -96,10 +144,26 @@ eek_element_class_init (EekElementClass *klass)
 | 
				
			|||||||
    GParamSpec        *pspec;
 | 
					    GParamSpec        *pspec;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* signals */
 | 
					    /* signals */
 | 
				
			||||||
 | 
					    klass->symbol_index_changed = eek_element_real_symbol_index_changed;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    gobject_class->set_property = eek_element_set_property;
 | 
					    gobject_class->set_property = eek_element_set_property;
 | 
				
			||||||
    gobject_class->get_property = eek_element_get_property;
 | 
					    gobject_class->get_property = eek_element_get_property;
 | 
				
			||||||
    gobject_class->finalize     = eek_element_finalize;
 | 
					    gobject_class->finalize     = eek_element_finalize;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * EekElement:name:
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * The name of #EekElement.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    pspec = g_param_spec_string ("name",
 | 
				
			||||||
 | 
					                                 "Name",
 | 
				
			||||||
 | 
					                                 "Name",
 | 
				
			||||||
 | 
					                                 NULL,
 | 
				
			||||||
 | 
					                                 G_PARAM_READWRITE);
 | 
				
			||||||
 | 
					    g_object_class_install_property (gobject_class,
 | 
				
			||||||
 | 
					                                     PROP_NAME,
 | 
				
			||||||
 | 
					                                     pspec);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * EekElement:bounds:
 | 
					     * EekElement:bounds:
 | 
				
			||||||
     *
 | 
					     *
 | 
				
			||||||
@ -113,12 +177,149 @@ eek_element_class_init (EekElementClass *klass)
 | 
				
			|||||||
    g_object_class_install_property (gobject_class,
 | 
					    g_object_class_install_property (gobject_class,
 | 
				
			||||||
                                     PROP_BOUNDS,
 | 
					                                     PROP_BOUNDS,
 | 
				
			||||||
                                     pspec);
 | 
					                                     pspec);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * EekElement:group:
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * The group value of the symbol index of #EekElement.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    pspec = g_param_spec_int ("group",
 | 
				
			||||||
 | 
					                              "Group",
 | 
				
			||||||
 | 
					                              "Group value of the symbol index",
 | 
				
			||||||
 | 
					                              -1, G_MAXINT, -1,
 | 
				
			||||||
 | 
					                              G_PARAM_READWRITE);
 | 
				
			||||||
 | 
					    g_object_class_install_property (gobject_class,
 | 
				
			||||||
 | 
					                                     PROP_GROUP,
 | 
				
			||||||
 | 
					                                     pspec);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * EekElement:level:
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * The level value of the symbol index of #EekElement.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    pspec = g_param_spec_int ("level",
 | 
				
			||||||
 | 
					                              "Level",
 | 
				
			||||||
 | 
					                              "Level value of the symbol index",
 | 
				
			||||||
 | 
					                              -1, G_MAXINT, -1,
 | 
				
			||||||
 | 
					                              G_PARAM_READWRITE);
 | 
				
			||||||
 | 
					    g_object_class_install_property (gobject_class,
 | 
				
			||||||
 | 
					                                     PROP_LEVEL,
 | 
				
			||||||
 | 
					                                     pspec);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * EekElement::symbol-index-changed:
 | 
				
			||||||
 | 
					     * @element: an #EekElement
 | 
				
			||||||
 | 
					     * @group: row index of the symbol matrix of keys on @element
 | 
				
			||||||
 | 
					     * @level: column index of the symbol matrix of keys on @element
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * The ::symbol-index-changed signal is emitted each time the
 | 
				
			||||||
 | 
					     * global configuration of group/level index changes.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    signals[SYMBOL_INDEX_CHANGED] =
 | 
				
			||||||
 | 
					        g_signal_new (I_("symbol-index-changed"),
 | 
				
			||||||
 | 
					                      G_TYPE_FROM_CLASS(gobject_class),
 | 
				
			||||||
 | 
					                      G_SIGNAL_RUN_LAST,
 | 
				
			||||||
 | 
					                      G_STRUCT_OFFSET(EekElementClass, symbol_index_changed),
 | 
				
			||||||
 | 
					                      NULL,
 | 
				
			||||||
 | 
					                      NULL,
 | 
				
			||||||
 | 
					                      _eek_marshal_VOID__INT_INT,
 | 
				
			||||||
 | 
					                      G_TYPE_NONE,
 | 
				
			||||||
 | 
					                      2,
 | 
				
			||||||
 | 
					                      G_TYPE_INT,
 | 
				
			||||||
 | 
					                      G_TYPE_INT);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void
 | 
					static void
 | 
				
			||||||
eek_element_init (EekElement *self)
 | 
					eek_element_init (EekElement *self)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    (void)self;
 | 
					    EekElementPrivate *priv = eek_element_get_instance_private (self);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    priv->group = -1;
 | 
				
			||||||
 | 
					    priv->level = -1;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * eek_element_set_parent:
 | 
				
			||||||
 | 
					 * @element: an #EekElement
 | 
				
			||||||
 | 
					 * @parent: (allow-none): an #EekElement or %NULL
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Set the parent of @element to @parent.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					eek_element_set_parent (EekElement *element,
 | 
				
			||||||
 | 
					                        EekElement *parent)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    g_return_if_fail (EEK_IS_ELEMENT(element));
 | 
				
			||||||
 | 
					    g_return_if_fail (parent == NULL || EEK_IS_ELEMENT(parent));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    EekElementPrivate *priv = eek_element_get_instance_private (element);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (priv->parent == parent)
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (priv->parent != NULL) {
 | 
				
			||||||
 | 
					        /* release self-reference acquired when setting parent */
 | 
				
			||||||
 | 
					        g_object_unref (element);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (parent != NULL) {
 | 
				
			||||||
 | 
					        g_object_ref (element);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    priv->parent = parent;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * eek_element_get_parent:
 | 
				
			||||||
 | 
					 * @element: an #EekElement
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Get the parent of @element.
 | 
				
			||||||
 | 
					 * Returns: an #EekElement if the parent is set
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					EekElement *
 | 
				
			||||||
 | 
					eek_element_get_parent (EekElement *element)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    g_return_val_if_fail (EEK_IS_ELEMENT(element), NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    EekElementPrivate *priv = eek_element_get_instance_private (element);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return priv->parent;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * eek_element_set_name:
 | 
				
			||||||
 | 
					 * @element: an #EekElement
 | 
				
			||||||
 | 
					 * @name: name of @element
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Set the name of @element to @name.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					eek_element_set_name (EekElement  *element,
 | 
				
			||||||
 | 
					                      const gchar *name)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    g_return_if_fail (EEK_IS_ELEMENT(element));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    EekElementPrivate *priv = eek_element_get_instance_private (element);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    g_free (priv->name);
 | 
				
			||||||
 | 
					    priv->name = g_strdup (name);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * eek_element_get_name:
 | 
				
			||||||
 | 
					 * @element: an #EekElement
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Get the name of @element.
 | 
				
			||||||
 | 
					 * Returns: the name of @element or NULL when the name is not set
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					const gchar *
 | 
				
			||||||
 | 
					eek_element_get_name (EekElement  *element)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    g_return_val_if_fail (EEK_IS_ELEMENT(element), NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    EekElementPrivate *priv = eek_element_get_instance_private (element);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return priv->name;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
@ -161,3 +362,211 @@ eek_element_get_bounds (EekElement  *element,
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    memcpy (bounds, &priv->bounds, sizeof(EekBounds));
 | 
					    memcpy (bounds, &priv->bounds, sizeof(EekBounds));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * eek_element_get_absolute_position:
 | 
				
			||||||
 | 
					 * @element: an #EekElement
 | 
				
			||||||
 | 
					 * @x: pointer where the X coordinate of @element will be stored
 | 
				
			||||||
 | 
					 * @y: pointer where the Y coordinate of @element will be stored
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Compute the absolute position of @element.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					eek_element_get_absolute_position (EekElement *element,
 | 
				
			||||||
 | 
					                                   gdouble    *x,
 | 
				
			||||||
 | 
					                                   gdouble    *y)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    EekBounds bounds;
 | 
				
			||||||
 | 
					    gdouble ax = 0.0, ay = 0.0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    do {
 | 
				
			||||||
 | 
					        eek_element_get_bounds (element, &bounds);
 | 
				
			||||||
 | 
					        ax += bounds.x;
 | 
				
			||||||
 | 
					        ay += bounds.y;
 | 
				
			||||||
 | 
					    } while ((element = eek_element_get_parent (element)) != NULL);
 | 
				
			||||||
 | 
					    *x = ax;
 | 
				
			||||||
 | 
					    *y = ay;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * eek_element_set_position:
 | 
				
			||||||
 | 
					 * @element: an #EekElement
 | 
				
			||||||
 | 
					 * @x: X coordinate of top left corner
 | 
				
			||||||
 | 
					 * @y: Y coordinate of top left corner
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Set the relative position of @element.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					eek_element_set_position (EekElement *element,
 | 
				
			||||||
 | 
					                          gdouble     x,
 | 
				
			||||||
 | 
					                          gdouble     y)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    EekBounds bounds;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    eek_element_get_bounds (element, &bounds);
 | 
				
			||||||
 | 
					    bounds.x = x;
 | 
				
			||||||
 | 
					    bounds.y = y;
 | 
				
			||||||
 | 
					    eek_element_set_bounds (element, &bounds);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * eek_element_set_size:
 | 
				
			||||||
 | 
					 * @element: an #EekElement
 | 
				
			||||||
 | 
					 * @width: width of @element
 | 
				
			||||||
 | 
					 * @height: height of @element
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Set the size of @element.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					eek_element_set_size (EekElement  *element,
 | 
				
			||||||
 | 
					                      gdouble      width,
 | 
				
			||||||
 | 
					                      gdouble      height)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    EekBounds bounds;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    eek_element_get_bounds (element, &bounds);
 | 
				
			||||||
 | 
					    bounds.width = width;
 | 
				
			||||||
 | 
					    bounds.height = height;
 | 
				
			||||||
 | 
					    eek_element_set_bounds (element, &bounds);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * eek_element_set_symbol_index:
 | 
				
			||||||
 | 
					 * @element: an #EekElement
 | 
				
			||||||
 | 
					 * @group: row index of the symbol matrix
 | 
				
			||||||
 | 
					 * @level: column index of the symbol matrix
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Set the default index of the symbol matrices of @element.  The
 | 
				
			||||||
 | 
					 * setting affects the child, if child does not have the index set, as
 | 
				
			||||||
 | 
					 * well as this element.  To unset, pass -1 as group/level.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					eek_element_set_symbol_index (EekElement *element,
 | 
				
			||||||
 | 
					                              gint        group,
 | 
				
			||||||
 | 
					                              gint        level)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    gboolean emit_signal;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    g_return_if_fail (EEK_IS_ELEMENT(element));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    emit_signal = group != eek_element_get_group (element) ||
 | 
				
			||||||
 | 
					        level != eek_element_get_level (element);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    eek_element_set_group (element, group);
 | 
				
			||||||
 | 
					    eek_element_set_level (element, level);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (emit_signal)
 | 
				
			||||||
 | 
					        g_signal_emit (element, signals[SYMBOL_INDEX_CHANGED], 0, group, level);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * eek_element_get_symbol_index:
 | 
				
			||||||
 | 
					 * @element: an #EekElement
 | 
				
			||||||
 | 
					 * @group: a pointer where the group value of the symbol index will be stored
 | 
				
			||||||
 | 
					 * @level: a pointer where the level value of the symbol index will be stored
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Get the default index of the symbol matrices of @element.
 | 
				
			||||||
 | 
					 * If the index is not set, -1 will be returned.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					eek_element_get_symbol_index (EekElement *element,
 | 
				
			||||||
 | 
					                              gint       *group,
 | 
				
			||||||
 | 
					                              gint       *level)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    g_return_if_fail (EEK_IS_ELEMENT(element));
 | 
				
			||||||
 | 
					    g_return_if_fail (group != NULL || level != NULL);
 | 
				
			||||||
 | 
					    if (group != NULL)
 | 
				
			||||||
 | 
					        *group = eek_element_get_group (element);
 | 
				
			||||||
 | 
					    if (level != NULL)
 | 
				
			||||||
 | 
					        *level = eek_element_get_level (element);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * eek_element_set_group:
 | 
				
			||||||
 | 
					 * @element: an #EekElement
 | 
				
			||||||
 | 
					 * @group: group index of @element
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Set the group value of the default symbol index of @element.  To
 | 
				
			||||||
 | 
					 * unset, pass -1 as @group.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * See also: eek_element_set_symbol_index()
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					eek_element_set_group (EekElement *element,
 | 
				
			||||||
 | 
					                       gint        group)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    g_return_if_fail (EEK_IS_ELEMENT(element));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    EekElementPrivate *priv = eek_element_get_instance_private (element);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (priv->group != group) {
 | 
				
			||||||
 | 
					        priv->group = group;
 | 
				
			||||||
 | 
					        g_object_notify (G_OBJECT(element), "group");
 | 
				
			||||||
 | 
					        g_signal_emit (element, signals[SYMBOL_INDEX_CHANGED], 0,
 | 
				
			||||||
 | 
					                       group, priv->level);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * eek_element_set_level:
 | 
				
			||||||
 | 
					 * @element: an #EekElement
 | 
				
			||||||
 | 
					 * @level: level index of @element
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Set the level value of the default symbol index of @element.  To
 | 
				
			||||||
 | 
					 * unset, pass -1 as @level.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * See also: eek_element_set_symbol_index()
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					eek_element_set_level (EekElement *element,
 | 
				
			||||||
 | 
					                       gint        level)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    g_return_if_fail (EEK_IS_ELEMENT(element));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    EekElementPrivate *priv = eek_element_get_instance_private (element);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (priv->level != level) {
 | 
				
			||||||
 | 
					        priv->level = level;
 | 
				
			||||||
 | 
					        g_object_notify (G_OBJECT(element), "level");
 | 
				
			||||||
 | 
					        g_signal_emit (element, signals[SYMBOL_INDEX_CHANGED], 0,
 | 
				
			||||||
 | 
					                       priv->group, level);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * eek_element_get_group:
 | 
				
			||||||
 | 
					 * @element: an #EekElement
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Return the group value of the default symbol index of @element.
 | 
				
			||||||
 | 
					 * If the value is not set, -1 will be returned.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * See also: eek_element_get_symbol_index()
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					gint
 | 
				
			||||||
 | 
					eek_element_get_group (EekElement *element)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    g_return_val_if_fail (EEK_IS_ELEMENT(element), -1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    EekElementPrivate *priv = eek_element_get_instance_private (element);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return priv->group;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * eek_element_get_level:
 | 
				
			||||||
 | 
					 * @element: an #EekElement
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Return the level value of the default symbol index of @element.
 | 
				
			||||||
 | 
					 * If the value is not set, -1 will be returned.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * See also: eek_element_get_symbol_index()
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					gint
 | 
				
			||||||
 | 
					eek_element_get_level (EekElement *element)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    g_return_val_if_fail (EEK_IS_ELEMENT(element), -1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    EekElementPrivate *priv = eek_element_get_instance_private (element);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return priv->level;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -36,10 +36,18 @@ struct _EekElementClass
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
    /*< private >*/
 | 
					    /*< private >*/
 | 
				
			||||||
    GObjectClass parent_class;
 | 
					    GObjectClass parent_class;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* signals */
 | 
				
			||||||
 | 
					    void                  (* symbol_index_changed) (EekElement  *self,
 | 
				
			||||||
 | 
					                                                    gint         group,
 | 
				
			||||||
 | 
					                                                    gint         level);
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
GType        eek_element_get_type              (void) G_GNUC_CONST;
 | 
					GType        eek_element_get_type              (void) G_GNUC_CONST;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void         eek_element_set_parent            (EekElement  *element,
 | 
				
			||||||
 | 
					                                                EekElement  *parent);
 | 
				
			||||||
 | 
					EekElement  *eek_element_get_parent            (EekElement  *element);
 | 
				
			||||||
void         eek_element_set_name              (EekElement  *element,
 | 
					void         eek_element_set_name              (EekElement  *element,
 | 
				
			||||||
                                                const gchar *name);
 | 
					                                                const gchar *name);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -51,5 +59,29 @@ void         eek_element_set_bounds            (EekElement  *element,
 | 
				
			|||||||
void         eek_element_get_bounds            (EekElement  *element,
 | 
					void         eek_element_get_bounds            (EekElement  *element,
 | 
				
			||||||
                                                EekBounds   *bounds);
 | 
					                                                EekBounds   *bounds);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void         eek_element_set_position          (EekElement  *element,
 | 
				
			||||||
 | 
					                                                gdouble      x,
 | 
				
			||||||
 | 
					                                                gdouble      y);
 | 
				
			||||||
 | 
					void         eek_element_set_size              (EekElement  *element,
 | 
				
			||||||
 | 
					                                                gdouble      width,
 | 
				
			||||||
 | 
					                                                gdouble      height);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void         eek_element_get_absolute_position (EekElement  *element,
 | 
				
			||||||
 | 
					                                                gdouble     *x,
 | 
				
			||||||
 | 
					                                                gdouble     *y);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void         eek_element_set_symbol_index      (EekElement  *element,
 | 
				
			||||||
 | 
					                                                gint         group,
 | 
				
			||||||
 | 
					                                                gint         level);
 | 
				
			||||||
 | 
					void         eek_element_get_symbol_index      (EekElement  *element,
 | 
				
			||||||
 | 
					                                                gint        *group,
 | 
				
			||||||
 | 
					                                                gint        *level);
 | 
				
			||||||
 | 
					void         eek_element_set_group             (EekElement  *element,
 | 
				
			||||||
 | 
					                                                gint         group);
 | 
				
			||||||
 | 
					void         eek_element_set_level             (EekElement  *element,
 | 
				
			||||||
 | 
					                                                gint         level);
 | 
				
			||||||
 | 
					gint         eek_element_get_group             (EekElement  *element);
 | 
				
			||||||
 | 
					gint         eek_element_get_level             (EekElement  *element);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
G_END_DECLS
 | 
					G_END_DECLS
 | 
				
			||||||
#endif  /* EEK_ELEMENT_H */
 | 
					#endif  /* EEK_ELEMENT_H */
 | 
				
			||||||
 | 
				
			|||||||
@ -23,23 +23,26 @@
 | 
				
			|||||||
 * @short_description: a #GtkWidget displaying #EekKeyboard
 | 
					 * @short_description: a #GtkWidget displaying #EekKeyboard
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef HAVE_CONFIG_H
 | 
				
			||||||
#include "config.h"
 | 
					#include "config.h"
 | 
				
			||||||
 | 
					#endif  /* HAVE_CONFIG_H */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef HAVE_LIBCANBERRA
 | 
					#ifdef HAVE_LIBCANBERRA
 | 
				
			||||||
#include <canberra-gtk.h>
 | 
					#include <canberra-gtk.h>
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <math.h>
 | 
					 | 
				
			||||||
#include <string.h>
 | 
					#include <string.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "eek-renderer.h"
 | 
					 | 
				
			||||||
#include "eek-keyboard.h"
 | 
					 | 
				
			||||||
#include "src/symbol.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include "eek-gtk-keyboard.h"
 | 
					#include "eek-gtk-keyboard.h"
 | 
				
			||||||
 | 
					#include "eek-gtk-renderer.h"
 | 
				
			||||||
 | 
					#include "eek-keyboard.h"
 | 
				
			||||||
 | 
					#include "eek-section.h"
 | 
				
			||||||
 | 
					#include "eek-key.h"
 | 
				
			||||||
 | 
					#include "eek-symbol.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
enum {
 | 
					enum {
 | 
				
			||||||
    PROP_0,
 | 
					    PROP_0,
 | 
				
			||||||
 | 
					    PROP_KEYBOARD,
 | 
				
			||||||
    PROP_LAST
 | 
					    PROP_LAST
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -52,25 +55,37 @@ enum {
 | 
				
			|||||||
typedef struct _EekGtkKeyboardPrivate
 | 
					typedef struct _EekGtkKeyboardPrivate
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    EekRenderer *renderer;
 | 
					    EekRenderer *renderer;
 | 
				
			||||||
    LevelKeyboard *keyboard;
 | 
					    EekKeyboard *keyboard;
 | 
				
			||||||
    GtkCssProvider *css_provider;
 | 
					    gulong key_locked_handler;
 | 
				
			||||||
    GtkStyleContext *scontext;
 | 
					    gulong key_unlocked_handler;
 | 
				
			||||||
 | 
					    gulong symbol_index_changed_handler;
 | 
				
			||||||
 | 
					    EekTheme *theme;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    GdkEventSequence *sequence; // unowned reference
 | 
					    GdkEventSequence *sequence; // unowned reference
 | 
				
			||||||
} EekGtkKeyboardPrivate;
 | 
					} EekGtkKeyboardPrivate;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
G_DEFINE_TYPE_WITH_PRIVATE (EekGtkKeyboard, eek_gtk_keyboard, GTK_TYPE_DRAWING_AREA)
 | 
					G_DEFINE_TYPE_WITH_PRIVATE (EekGtkKeyboard, eek_gtk_keyboard, GTK_TYPE_DRAWING_AREA)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void       on_button_pressed          (struct squeek_button *button, struct squeek_view *view,
 | 
					static void       on_key_pressed          (EekKey      *key,
 | 
				
			||||||
                                           EekGtkKeyboard *self);
 | 
					                                           EekGtkKeyboard *self);
 | 
				
			||||||
static void       on_button_released         (struct squeek_button *button,
 | 
					static void       on_key_released         (EekKey      *key,
 | 
				
			||||||
                                           struct squeek_view *view,
 | 
					 | 
				
			||||||
                                           EekGtkKeyboard *self);
 | 
					                                           EekGtkKeyboard *self);
 | 
				
			||||||
static void       render_pressed_button      (GtkWidget   *widget, struct button_place *place);
 | 
					static void       on_key_locked          (EekKeyboard *keyboard,
 | 
				
			||||||
static void       render_locked_button       (GtkWidget   *widget,
 | 
					                                           EekKey      *key,
 | 
				
			||||||
                                           struct button_place *place);
 | 
					                                           gpointer     user_data);
 | 
				
			||||||
static void       render_released_button     (GtkWidget   *widget,
 | 
					static void       on_key_unlocked         (EekKeyboard *keyboard,
 | 
				
			||||||
                                           struct squeek_button *button);
 | 
					                                           EekKey      *key,
 | 
				
			||||||
 | 
					                                           gpointer     user_data);
 | 
				
			||||||
 | 
					static void       on_symbol_index_changed (EekKeyboard *keyboard,
 | 
				
			||||||
 | 
					                                           gint         group,
 | 
				
			||||||
 | 
					                                           gint         level,
 | 
				
			||||||
 | 
					                                           gpointer     user_data);
 | 
				
			||||||
 | 
					static void       render_pressed_key      (GtkWidget   *widget,
 | 
				
			||||||
 | 
					                                           EekKey      *key);
 | 
				
			||||||
 | 
					static void       render_locked_key       (GtkWidget   *widget,
 | 
				
			||||||
 | 
					                                           EekKey      *key);
 | 
				
			||||||
 | 
					static void       render_released_key     (GtkWidget   *widget,
 | 
				
			||||||
 | 
					                                           EekKey      *key);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void
 | 
					static void
 | 
				
			||||||
eek_gtk_keyboard_real_realize (GtkWidget      *self)
 | 
					eek_gtk_keyboard_real_realize (GtkWidget      *self)
 | 
				
			||||||
@ -93,45 +108,38 @@ eek_gtk_keyboard_real_draw (GtkWidget *self,
 | 
				
			|||||||
    EekGtkKeyboardPrivate *priv =
 | 
					    EekGtkKeyboardPrivate *priv =
 | 
				
			||||||
	    eek_gtk_keyboard_get_instance_private (EEK_GTK_KEYBOARD (self));
 | 
						    eek_gtk_keyboard_get_instance_private (EEK_GTK_KEYBOARD (self));
 | 
				
			||||||
    GtkAllocation allocation;
 | 
					    GtkAllocation allocation;
 | 
				
			||||||
 | 
					    GList *list, *head;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    gtk_widget_get_allocation (self, &allocation);
 | 
					    gtk_widget_get_allocation (self, &allocation);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (!priv->renderer) {
 | 
					    if (!priv->renderer) {
 | 
				
			||||||
        PangoContext *pcontext = gtk_widget_get_pango_context (self);
 | 
					        PangoContext *pcontext;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        priv->renderer = eek_renderer_new (priv->keyboard, pcontext, priv->scontext);
 | 
					        pcontext = gtk_widget_get_pango_context (self);
 | 
				
			||||||
 | 
					        priv->renderer = eek_gtk_renderer_new (priv->keyboard, pcontext, self);
 | 
				
			||||||
 | 
					        if (priv->theme)
 | 
				
			||||||
 | 
					            eek_renderer_set_theme (priv->renderer, priv->theme);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        eek_renderer_set_allocation_size (priv->renderer,
 | 
					        eek_renderer_set_allocation_size (priv->renderer,
 | 
				
			||||||
                                          allocation.width,
 | 
					                                          allocation.width,
 | 
				
			||||||
                                          allocation.height);
 | 
					                                          allocation.height);
 | 
				
			||||||
        eek_renderer_set_scale_factor (priv->renderer,
 | 
					 | 
				
			||||||
                                       gtk_widget_get_scale_factor (self));
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    eek_renderer_render_keyboard (priv->renderer, cr);
 | 
					    eek_renderer_render_keyboard (priv->renderer, cr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    struct squeek_view *view = priv->keyboard->views[priv->keyboard->level];
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /* redraw pressed key */
 | 
					    /* redraw pressed key */
 | 
				
			||||||
    const GList *list = priv->keyboard->pressed_buttons;
 | 
					    list = eek_keyboard_get_pressed_keys (priv->keyboard);
 | 
				
			||||||
    for (const GList *head = list; head; head = g_list_next (head)) {
 | 
					    for (head = list; head; head = g_list_next (head)) {
 | 
				
			||||||
        struct button_place place = squeek_view_find_key(
 | 
					        render_pressed_key (self, head->data);
 | 
				
			||||||
            view, squeek_button_get_key(head->data)
 | 
					 | 
				
			||||||
        );
 | 
					 | 
				
			||||||
        if (place.button)
 | 
					 | 
				
			||||||
            render_pressed_button (self, &place);
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					    g_list_free (list);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* redraw locked key */
 | 
					    /* redraw locked key */
 | 
				
			||||||
    list = priv->keyboard->locked_buttons;
 | 
					    list = eek_keyboard_get_locked_keys (priv->keyboard);
 | 
				
			||||||
    for (const GList *head = list; head; head = g_list_next (head)) {
 | 
					    for (head = list; head; head = g_list_next (head)) {
 | 
				
			||||||
        struct button_place place = squeek_view_find_key(
 | 
					        render_locked_key (self, ((EekModifierKey *)head->data)->key);
 | 
				
			||||||
            view, squeek_button_get_key(
 | 
					 | 
				
			||||||
                ((EekModifierKey *)head->data)->button
 | 
					 | 
				
			||||||
            )
 | 
					 | 
				
			||||||
        );
 | 
					 | 
				
			||||||
        if (place.button)
 | 
					 | 
				
			||||||
            render_locked_button (self, &place);
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					    g_list_free (list);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return FALSE;
 | 
					    return FALSE;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -153,63 +161,50 @@ eek_gtk_keyboard_real_size_allocate (GtkWidget     *self,
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void depress(EekGtkKeyboard *self,
 | 
					static void depress(EekGtkKeyboard *self,
 | 
				
			||||||
                    gdouble x, gdouble y, guint32 time)
 | 
					                    gdouble x, gdouble y, guint32 time) {
 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (self);
 | 
					    EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (self);
 | 
				
			||||||
    struct squeek_view *view = level_keyboard_current(priv->keyboard);
 | 
					    EekKey *key = eek_renderer_find_key_by_position (priv->renderer, x, y);
 | 
				
			||||||
    struct squeek_button *button = eek_renderer_find_button_by_position (priv->renderer, view, x, y);
 | 
					    if (key) {
 | 
				
			||||||
 | 
					        eek_keyboard_press_key(priv->keyboard, key, time);
 | 
				
			||||||
    if (button) {
 | 
					        on_key_pressed(key, self);
 | 
				
			||||||
        eek_keyboard_press_button(priv->keyboard, button, time);
 | 
					 | 
				
			||||||
        on_button_pressed(button, view, self);
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void drag(EekGtkKeyboard *self,
 | 
					static void drag(EekGtkKeyboard *self,
 | 
				
			||||||
                 gdouble x, gdouble y, guint32 time) {
 | 
					                 gdouble x, gdouble y, guint32 time) {
 | 
				
			||||||
    EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (self);
 | 
					    EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (self);
 | 
				
			||||||
    struct squeek_view *view = level_keyboard_current(priv->keyboard);
 | 
					    EekKey *key = eek_renderer_find_key_by_position (priv->renderer, x, y);
 | 
				
			||||||
    struct squeek_button *button = eek_renderer_find_button_by_position (priv->renderer, view, x, y);
 | 
					
 | 
				
			||||||
 | 
					    if (key) {
 | 
				
			||||||
        GList *list, *head;
 | 
					        GList *list, *head;
 | 
				
			||||||
 | 
					 | 
				
			||||||
    list = g_list_copy(priv->keyboard->pressed_buttons);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if (button) {
 | 
					 | 
				
			||||||
        gboolean found = FALSE;
 | 
					        gboolean found = FALSE;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        list = eek_keyboard_get_pressed_keys (priv->keyboard);
 | 
				
			||||||
        for (head = list; head; head = g_list_next (head)) {
 | 
					        for (head = list; head; head = g_list_next (head)) {
 | 
				
			||||||
            if (head->data == button) {
 | 
					            if (head->data == key)
 | 
				
			||||||
                found = TRUE;
 | 
					                found = TRUE;
 | 
				
			||||||
            } else {
 | 
					            else {
 | 
				
			||||||
                eek_keyboard_release_button(priv->keyboard, head->data, time);
 | 
					                eek_keyboard_release_key(priv->keyboard, EEK_KEY(head->data), time);
 | 
				
			||||||
                on_button_released(button, view, self);
 | 
					                on_key_released(key, self);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        g_list_free (list);
 | 
					        g_list_free (list);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (!found) {
 | 
					        if (!found) {
 | 
				
			||||||
            eek_keyboard_press_button(priv->keyboard, button, time);
 | 
					            eek_keyboard_press_key(priv->keyboard, key, time);
 | 
				
			||||||
            on_button_pressed(button, view, self);
 | 
					            on_key_pressed(key, self);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    } else {
 | 
					 | 
				
			||||||
        for (head = list; head; head = g_list_next (head)) {
 | 
					 | 
				
			||||||
            eek_keyboard_release_button(priv->keyboard, head->data, time);
 | 
					 | 
				
			||||||
            on_button_released(head->data, view, self);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        g_list_free (list);
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void release(EekGtkKeyboard *self, guint32 time) {
 | 
					static void release(EekGtkKeyboard *self, guint32 time) {
 | 
				
			||||||
    EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (self);
 | 
					    EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (self);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    struct squeek_view *view = level_keyboard_current(priv->keyboard);
 | 
					    GList *list = eek_keyboard_get_pressed_keys (priv->keyboard);
 | 
				
			||||||
 | 
					 | 
				
			||||||
    GList *list = g_list_copy(priv->keyboard->pressed_buttons);
 | 
					 | 
				
			||||||
    for (GList *head = list; head; head = g_list_next (head)) {
 | 
					    for (GList *head = list; head; head = g_list_next (head)) {
 | 
				
			||||||
        struct squeek_button *button = head->data;
 | 
					        EekKey *key = EEK_KEY(head->data);
 | 
				
			||||||
        eek_keyboard_release_button(priv->keyboard, button, time);
 | 
					        eek_keyboard_release_key(priv->keyboard, key, time);
 | 
				
			||||||
        on_button_released(button, view, self);
 | 
					        on_key_released(key, self);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    g_list_free (list);
 | 
					    g_list_free (list);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -292,7 +287,7 @@ eek_gtk_keyboard_real_unmap (GtkWidget *self)
 | 
				
			|||||||
           elements, so that the default handler of
 | 
					           elements, so that the default handler of
 | 
				
			||||||
           EekKeyboard::key-released signal can remove elements from its
 | 
					           EekKeyboard::key-released signal can remove elements from its
 | 
				
			||||||
           internal copy */
 | 
					           internal copy */
 | 
				
			||||||
        list = g_list_copy(priv->keyboard->pressed_buttons);
 | 
					        list = eek_keyboard_get_pressed_keys (priv->keyboard);
 | 
				
			||||||
        for (head = list; head; head = g_list_next (head)) {
 | 
					        for (head = list; head; head = g_list_next (head)) {
 | 
				
			||||||
            g_log("squeek", G_LOG_LEVEL_DEBUG, "emit EekKey released");
 | 
					            g_log("squeek", G_LOG_LEVEL_DEBUG, "emit EekKey released");
 | 
				
			||||||
            g_signal_emit_by_name (head->data, "released");
 | 
					            g_signal_emit_by_name (head->data, "released");
 | 
				
			||||||
@ -312,15 +307,15 @@ eek_gtk_keyboard_real_query_tooltip (GtkWidget  *widget,
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
    EekGtkKeyboard        *self = EEK_GTK_KEYBOARD (widget);
 | 
					    EekGtkKeyboard        *self = EEK_GTK_KEYBOARD (widget);
 | 
				
			||||||
    EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (self);
 | 
					    EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (self);
 | 
				
			||||||
    struct squeek_view *view = level_keyboard_current(priv->keyboard);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    struct squeek_button *button = eek_renderer_find_button_by_position (priv->renderer,
 | 
					    EekKey *key;
 | 
				
			||||||
                                                     view,
 | 
					
 | 
				
			||||||
 | 
					    key = eek_renderer_find_key_by_position (priv->renderer,
 | 
				
			||||||
                                             (gdouble)x,
 | 
					                                             (gdouble)x,
 | 
				
			||||||
                                             (gdouble)y);
 | 
					                                             (gdouble)y);
 | 
				
			||||||
    if (button) {
 | 
					    if (key) {
 | 
				
			||||||
        //struct squeek_symbol *symbol = eek_key_get_symbol_at_index(key, 0, priv->keyboard->level);
 | 
					        EekSymbol *symbol = eek_key_get_symbol (key);
 | 
				
			||||||
        const gchar *text = NULL; // FIXME
 | 
					        const gchar *text = eek_symbol_get_tooltip (symbol);
 | 
				
			||||||
        if (text) {
 | 
					        if (text) {
 | 
				
			||||||
            gtk_tooltip_set_text (tooltip, text);
 | 
					            gtk_tooltip_set_text (tooltip, text);
 | 
				
			||||||
            return TRUE;
 | 
					            return TRUE;
 | 
				
			||||||
@ -329,13 +324,37 @@ eek_gtk_keyboard_real_query_tooltip (GtkWidget  *widget,
 | 
				
			|||||||
    return FALSE;
 | 
					    return FALSE;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					eek_gtk_keyboard_set_keyboard (EekGtkKeyboard *self,
 | 
				
			||||||
 | 
					                               EekKeyboard    *keyboard)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (self);
 | 
				
			||||||
 | 
					    priv->keyboard = g_object_ref (keyboard);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    priv->key_locked_handler =
 | 
				
			||||||
 | 
					        g_signal_connect (priv->keyboard, "key-locked",
 | 
				
			||||||
 | 
					                          G_CALLBACK(on_key_locked), self);
 | 
				
			||||||
 | 
					    priv->key_unlocked_handler =
 | 
				
			||||||
 | 
					        g_signal_connect (priv->keyboard, "key-unlocked",
 | 
				
			||||||
 | 
					                          G_CALLBACK(on_key_unlocked), self);
 | 
				
			||||||
 | 
					    priv->symbol_index_changed_handler =
 | 
				
			||||||
 | 
					        g_signal_connect (priv->keyboard, "symbol-index-changed",
 | 
				
			||||||
 | 
					                          G_CALLBACK(on_symbol_index_changed), self);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void
 | 
					static void
 | 
				
			||||||
eek_gtk_keyboard_set_property (GObject      *object,
 | 
					eek_gtk_keyboard_set_property (GObject      *object,
 | 
				
			||||||
                               guint         prop_id,
 | 
					                               guint         prop_id,
 | 
				
			||||||
                               const GValue *value,
 | 
					                               const GValue *value,
 | 
				
			||||||
                               GParamSpec   *pspec)
 | 
					                               GParamSpec   *pspec)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					    EekKeyboard *keyboard;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    switch (prop_id) {
 | 
					    switch (prop_id) {
 | 
				
			||||||
 | 
					    case PROP_KEYBOARD:
 | 
				
			||||||
 | 
					        keyboard = g_value_get_object (value);
 | 
				
			||||||
 | 
					        eek_gtk_keyboard_set_keyboard (EEK_GTK_KEYBOARD(object), keyboard);
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
    default:
 | 
					    default:
 | 
				
			||||||
        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 | 
					        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 | 
				
			||||||
        break;
 | 
					        break;
 | 
				
			||||||
@ -354,18 +373,37 @@ eek_gtk_keyboard_dispose (GObject *object)
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (priv->keyboard) {
 | 
					    if (priv->keyboard) {
 | 
				
			||||||
 | 
					        if (g_signal_handler_is_connected (priv->keyboard,
 | 
				
			||||||
 | 
					                                           priv->key_locked_handler))
 | 
				
			||||||
 | 
					            g_signal_handler_disconnect (priv->keyboard,
 | 
				
			||||||
 | 
					                                         priv->key_locked_handler);
 | 
				
			||||||
 | 
					        if (g_signal_handler_is_connected (priv->keyboard,
 | 
				
			||||||
 | 
					                                           priv->key_unlocked_handler))
 | 
				
			||||||
 | 
					            g_signal_handler_disconnect (priv->keyboard,
 | 
				
			||||||
 | 
					                                         priv->key_unlocked_handler);
 | 
				
			||||||
 | 
					        if (g_signal_handler_is_connected (priv->keyboard,
 | 
				
			||||||
 | 
					                                           priv->symbol_index_changed_handler))
 | 
				
			||||||
 | 
					            g_signal_handler_disconnect (priv->keyboard,
 | 
				
			||||||
 | 
					                                         priv->symbol_index_changed_handler);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        GList *list, *head;
 | 
					        GList *list, *head;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        list = g_list_copy(priv->keyboard->pressed_buttons);
 | 
					        list = eek_keyboard_get_pressed_keys (priv->keyboard);
 | 
				
			||||||
        for (head = list; head; head = g_list_next (head)) {
 | 
					        for (head = list; head; head = g_list_next (head)) {
 | 
				
			||||||
            g_log("squeek", G_LOG_LEVEL_DEBUG, "emit EekKey pressed");
 | 
					            g_log("squeek", G_LOG_LEVEL_DEBUG, "emit EekKey pressed");
 | 
				
			||||||
            g_signal_emit_by_name (head->data, "released", level_keyboard_current(priv->keyboard));
 | 
					            g_signal_emit_by_name (head->data, "released", priv->keyboard);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        g_list_free (list);
 | 
					        g_list_free (list);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        g_object_unref (priv->keyboard);
 | 
				
			||||||
        priv->keyboard = NULL;
 | 
					        priv->keyboard = NULL;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (priv->theme) {
 | 
				
			||||||
 | 
					        g_object_unref (priv->theme);
 | 
				
			||||||
 | 
					        priv->theme = NULL;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    G_OBJECT_CLASS (eek_gtk_keyboard_parent_class)->dispose (object);
 | 
					    G_OBJECT_CLASS (eek_gtk_keyboard_parent_class)->dispose (object);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -374,6 +412,7 @@ eek_gtk_keyboard_class_init (EekGtkKeyboardClass *klass)
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
    GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
 | 
					    GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
 | 
				
			||||||
    GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
 | 
					    GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
 | 
				
			||||||
 | 
					    GParamSpec *pspec;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    widget_class->realize = eek_gtk_keyboard_real_realize;
 | 
					    widget_class->realize = eek_gtk_keyboard_real_realize;
 | 
				
			||||||
    widget_class->unmap = eek_gtk_keyboard_real_unmap;
 | 
					    widget_class->unmap = eek_gtk_keyboard_real_unmap;
 | 
				
			||||||
@ -391,25 +430,21 @@ eek_gtk_keyboard_class_init (EekGtkKeyboardClass *klass)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    gobject_class->set_property = eek_gtk_keyboard_set_property;
 | 
					    gobject_class->set_property = eek_gtk_keyboard_set_property;
 | 
				
			||||||
    gobject_class->dispose = eek_gtk_keyboard_dispose;
 | 
					    gobject_class->dispose = eek_gtk_keyboard_dispose;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    pspec = g_param_spec_object ("keyboard",
 | 
				
			||||||
 | 
					                                 "Keyboard",
 | 
				
			||||||
 | 
					                                 "Keyboard",
 | 
				
			||||||
 | 
					                                 EEK_TYPE_KEYBOARD,
 | 
				
			||||||
 | 
					                                 G_PARAM_CONSTRUCT_ONLY | G_PARAM_WRITABLE);
 | 
				
			||||||
 | 
					    g_object_class_install_property (gobject_class,
 | 
				
			||||||
 | 
					                                     PROP_KEYBOARD,
 | 
				
			||||||
 | 
					                                     pspec);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void
 | 
					static void
 | 
				
			||||||
eek_gtk_keyboard_init (EekGtkKeyboard *self)
 | 
					eek_gtk_keyboard_init (EekGtkKeyboard *self)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (self);
 | 
					    /* void */
 | 
				
			||||||
 | 
					 | 
				
			||||||
    /* Create a default CSS provider and load a style sheet */
 | 
					 | 
				
			||||||
    priv->css_provider = gtk_css_provider_new ();
 | 
					 | 
				
			||||||
    gtk_css_provider_load_from_resource (priv->css_provider,
 | 
					 | 
				
			||||||
        "/sm/puri/squeekboard/style.css");
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /* Apply the style to the widget */
 | 
					 | 
				
			||||||
    priv->scontext = gtk_widget_get_style_context (GTK_WIDGET(self));
 | 
					 | 
				
			||||||
    gtk_style_context_add_class (priv->scontext, "keyboard");
 | 
					 | 
				
			||||||
    gtk_style_context_add_provider (priv->scontext,
 | 
					 | 
				
			||||||
        GTK_STYLE_PROVIDER(priv->css_provider),
 | 
					 | 
				
			||||||
        GTK_STYLE_PROVIDER_PRIORITY_USER);
 | 
					 | 
				
			||||||
    gtk_style_context_set_state (priv->scontext, GTK_STATE_FLAG_NORMAL);
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
@ -420,76 +455,126 @@ eek_gtk_keyboard_init (EekGtkKeyboard *self)
 | 
				
			|||||||
 * Returns: a #GtkWidget
 | 
					 * Returns: a #GtkWidget
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
GtkWidget *
 | 
					GtkWidget *
 | 
				
			||||||
eek_gtk_keyboard_new (LevelKeyboard *keyboard)
 | 
					eek_gtk_keyboard_new (EekKeyboard *keyboard)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    EekGtkKeyboard *ret = EEK_GTK_KEYBOARD(g_object_new (EEK_TYPE_GTK_KEYBOARD, NULL));
 | 
					    return g_object_new (EEK_TYPE_GTK_KEYBOARD, "keyboard", keyboard, NULL);
 | 
				
			||||||
    EekGtkKeyboardPrivate *priv = (EekGtkKeyboardPrivate*)eek_gtk_keyboard_get_instance_private (ret);
 | 
					 | 
				
			||||||
    priv->keyboard = keyboard;
 | 
					 | 
				
			||||||
    return GTK_WIDGET(ret);
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void
 | 
					static void
 | 
				
			||||||
render_pressed_button (GtkWidget *widget,
 | 
					magnify_bounds (GtkWidget *self,
 | 
				
			||||||
                       struct button_place *place)
 | 
					                EekBounds *bounds,
 | 
				
			||||||
 | 
					                EekBounds *large_bounds,
 | 
				
			||||||
 | 
					                gdouble    scale)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    GtkAllocation allocation;
 | 
				
			||||||
 | 
					    gdouble x, y;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    g_assert (scale >= 1.0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    gtk_widget_get_allocation (self, &allocation);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    large_bounds->width = bounds->width * scale;
 | 
				
			||||||
 | 
					    large_bounds->height = bounds->height * scale;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    x = bounds->x - (large_bounds->width - bounds->width) / 2;
 | 
				
			||||||
 | 
					    y = bounds->y - large_bounds->height;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    large_bounds->x = CLAMP(x, 0, allocation.width - large_bounds->width);
 | 
				
			||||||
 | 
					    large_bounds->y = CLAMP(y, 0, allocation.height - large_bounds->height);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					render_pressed_key (GtkWidget *widget,
 | 
				
			||||||
 | 
					                    EekKey    *key)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    EekGtkKeyboard        *self = EEK_GTK_KEYBOARD (widget);
 | 
					    EekGtkKeyboard        *self = EEK_GTK_KEYBOARD (widget);
 | 
				
			||||||
    EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (self);
 | 
					    EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (self);
 | 
				
			||||||
 | 
					    EekBounds bounds, large_bounds;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    GdkWindow         *window  = gtk_widget_get_window (widget);
 | 
					    eek_renderer_get_key_bounds (priv->renderer, key, &bounds, TRUE);
 | 
				
			||||||
 | 
					    magnify_bounds (widget, &bounds, &large_bounds, 1.5);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    GdkWindow *window = GDK_DRAWABLE (gtk_widget_get_window (widget));
 | 
				
			||||||
    cairo_region_t *region = gdk_window_get_clip_region (window);
 | 
					    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_render_button (priv->renderer, cr, place, 1.0, TRUE);
 | 
					    GdkDrawingContext *context = gdk_window_begin_draw_frame(
 | 
				
			||||||
/*
 | 
					        window, region
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					    cairo_t *cr = gdk_drawing_context_get_cairo_context(context);
 | 
				
			||||||
 | 
					    cairo_save (cr);
 | 
				
			||||||
 | 
					    cairo_translate (cr, bounds.x, bounds.y);
 | 
				
			||||||
 | 
					    eek_renderer_render_key (priv->renderer, cr, key, 1.0, TRUE);
 | 
				
			||||||
 | 
					    cairo_restore (cr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    cairo_save (cr);
 | 
				
			||||||
 | 
					    cairo_translate (cr, large_bounds.x, large_bounds.y);
 | 
				
			||||||
    eek_renderer_render_key (priv->renderer, cr, key, 1.5, TRUE);
 | 
					    eek_renderer_render_key (priv->renderer, cr, key, 1.5, TRUE);
 | 
				
			||||||
*/
 | 
					    cairo_restore (cr);
 | 
				
			||||||
    gdk_window_end_draw_frame (window, context);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    cairo_region_destroy (region);
 | 
					    gdk_window_end_draw_frame(window, context);
 | 
				
			||||||
 | 
					    cairo_region_destroy(region);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void
 | 
					static void
 | 
				
			||||||
render_locked_button (GtkWidget *widget, struct button_place *place)
 | 
					render_locked_key (GtkWidget *widget,
 | 
				
			||||||
 | 
					                   EekKey    *key)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    EekGtkKeyboard        *self = EEK_GTK_KEYBOARD (widget);
 | 
					    EekGtkKeyboard        *self = EEK_GTK_KEYBOARD (widget);
 | 
				
			||||||
    EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (self);
 | 
					    EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (self);
 | 
				
			||||||
 | 
					    EekBounds bounds;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    GdkWindow         *window  = gtk_widget_get_window (widget);
 | 
					    GdkWindow         *window  = gtk_widget_get_window (widget);
 | 
				
			||||||
    cairo_region_t    *region  = gdk_window_get_clip_region (window);
 | 
					    cairo_region_t    *region  = gdk_window_get_clip_region (window);
 | 
				
			||||||
    GdkDrawingContext *context = gdk_window_begin_draw_frame (window, region);
 | 
					    GdkDrawingContext *context = gdk_window_begin_draw_frame (window, region);
 | 
				
			||||||
    cairo_t           *cr      = gdk_drawing_context_get_cairo_context (context);
 | 
					    cairo_t           *cr      = gdk_drawing_context_get_cairo_context (context);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    eek_renderer_render_button (priv->renderer, cr, place, 1.0, TRUE);
 | 
					    eek_renderer_get_key_bounds (priv->renderer, key, &bounds, TRUE);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    cairo_translate (cr, bounds.x, bounds.y);
 | 
				
			||||||
 | 
					    eek_renderer_render_key (priv->renderer, cr, key, 1.0, TRUE);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    gdk_window_end_draw_frame (window, context);
 | 
					    gdk_window_end_draw_frame (window, context);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    cairo_region_destroy (region);
 | 
					    cairo_region_destroy(region);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void
 | 
					static void
 | 
				
			||||||
render_released_button (GtkWidget *widget,
 | 
					render_released_key (GtkWidget *widget,
 | 
				
			||||||
                        struct squeek_button *button)
 | 
					                     EekKey    *key)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    (void)button;
 | 
					 | 
				
			||||||
    EekGtkKeyboard        *self = EEK_GTK_KEYBOARD (widget);
 | 
					    EekGtkKeyboard        *self = EEK_GTK_KEYBOARD (widget);
 | 
				
			||||||
    EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (self);
 | 
					    EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (self);
 | 
				
			||||||
 | 
					    EekBounds bounds, large_bounds;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    GdkWindow         *window  = gtk_widget_get_window (widget);
 | 
					    GdkWindow         *window  = gtk_widget_get_window (widget);
 | 
				
			||||||
    cairo_region_t    *region  = gdk_window_get_clip_region (window);
 | 
					    cairo_region_t    *region  = gdk_window_get_clip_region (window);
 | 
				
			||||||
    GdkDrawingContext *context = gdk_window_begin_draw_frame (window, region);
 | 
					    GdkDrawingContext *context = gdk_window_begin_draw_frame (window, region);
 | 
				
			||||||
    cairo_t           *cr      = gdk_drawing_context_get_cairo_context (context);
 | 
					    cairo_t           *cr      = gdk_drawing_context_get_cairo_context (context);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    eek_renderer_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);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    eek_renderer_render_keyboard (priv->renderer, cr);
 | 
					    eek_renderer_render_keyboard (priv->renderer, cr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    gdk_window_end_draw_frame (window, context);
 | 
					    gdk_window_end_draw_frame (window, context);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    cairo_region_destroy (region);
 | 
					    cairo_region_destroy(region);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void
 | 
					static void
 | 
				
			||||||
on_button_pressed (struct squeek_button *button,
 | 
					on_key_pressed (EekKey      *key,
 | 
				
			||||||
                struct squeek_view *view,
 | 
					 | 
				
			||||||
                EekGtkKeyboard *self)
 | 
					                EekGtkKeyboard *self)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (self);
 | 
					    EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (self);
 | 
				
			||||||
@ -498,15 +583,7 @@ on_button_pressed (struct squeek_button *button,
 | 
				
			|||||||
    if (!priv->renderer)
 | 
					    if (!priv->renderer)
 | 
				
			||||||
        return;
 | 
					        return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    struct button_place place = {
 | 
					    render_pressed_key (GTK_WIDGET(self), key);
 | 
				
			||||||
        .button = button,
 | 
					 | 
				
			||||||
        .row = squeek_view_get_row(view, button),
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
    if (!place.row) {
 | 
					 | 
				
			||||||
        return;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    render_pressed_button (GTK_WIDGET(self), &place);
 | 
					 | 
				
			||||||
    gtk_widget_queue_draw (GTK_WIDGET(self));
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
#if HAVE_LIBCANBERRA
 | 
					#if HAVE_LIBCANBERRA
 | 
				
			||||||
    ca_gtk_play_for_widget (widget, 0,
 | 
					    ca_gtk_play_for_widget (widget, 0,
 | 
				
			||||||
@ -518,19 +595,16 @@ on_button_pressed (struct squeek_button *button,
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void
 | 
					static void
 | 
				
			||||||
on_button_released (struct squeek_button *button,
 | 
					on_key_released (EekKey      *key,
 | 
				
			||||||
                 struct squeek_view *view,
 | 
					 | 
				
			||||||
                 EekGtkKeyboard *self)
 | 
					                 EekGtkKeyboard *self)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    (void)view;
 | 
					 | 
				
			||||||
    EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (self);
 | 
					    EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (self);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* renderer may have not been set yet if the widget is a popup */
 | 
					    /* renderer may have not been set yet if the widget is a popup */
 | 
				
			||||||
    if (!priv->renderer)
 | 
					    if (!priv->renderer)
 | 
				
			||||||
        return;
 | 
					        return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    render_released_button (GTK_WIDGET(self), button);
 | 
					    render_released_key (GTK_WIDGET(self), key);
 | 
				
			||||||
    gtk_widget_queue_draw (GTK_WIDGET(self));
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
#if HAVE_LIBCANBERRA
 | 
					#if HAVE_LIBCANBERRA
 | 
				
			||||||
    ca_gtk_play_for_widget (widget, 0,
 | 
					    ca_gtk_play_for_widget (widget, 0,
 | 
				
			||||||
@ -540,3 +614,55 @@ on_button_released (struct squeek_button *button,
 | 
				
			|||||||
                            NULL);
 | 
					                            NULL);
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					on_key_locked (EekKeyboard *keyboard,
 | 
				
			||||||
 | 
					               EekKey      *key,
 | 
				
			||||||
 | 
					               gpointer     user_data)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    GtkWidget *widget = user_data;
 | 
				
			||||||
 | 
					    EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (user_data);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* renderer may have not been set yet if the widget is a popup */
 | 
				
			||||||
 | 
					    if (!priv->renderer)
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    render_locked_key (widget, key);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					on_key_unlocked (EekKeyboard *keyboard,
 | 
				
			||||||
 | 
					                 EekKey      *key,
 | 
				
			||||||
 | 
					                 gpointer     user_data)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    GtkWidget *widget = user_data;
 | 
				
			||||||
 | 
					    EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (user_data);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* renderer may have not been set yet if the widget is a popup */
 | 
				
			||||||
 | 
					    if (!priv->renderer)
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    render_released_key (widget, key);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					on_symbol_index_changed (EekKeyboard *keyboard,
 | 
				
			||||||
 | 
					                         gint         group,
 | 
				
			||||||
 | 
					                         gint         level,
 | 
				
			||||||
 | 
					                         gpointer     user_data)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    GtkWidget *widget = user_data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    gtk_widget_queue_draw (widget);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					eek_gtk_keyboard_set_theme (EekGtkKeyboard *keyboard,
 | 
				
			||||||
 | 
					                            EekTheme       *theme)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    g_return_if_fail (EEK_IS_GTK_KEYBOARD(keyboard));
 | 
				
			||||||
 | 
					    g_return_if_fail (EEK_IS_THEME(theme));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (keyboard);
 | 
				
			||||||
 | 
					    priv->theme = g_object_ref (theme);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -45,7 +45,9 @@ struct _EekGtkKeyboardClass
 | 
				
			|||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
GType      eek_gtk_keyboard_get_type  (void) G_GNUC_CONST;
 | 
					GType      eek_gtk_keyboard_get_type  (void) G_GNUC_CONST;
 | 
				
			||||||
GtkWidget *eek_gtk_keyboard_new       (LevelKeyboard *keyboard);
 | 
					GtkWidget *eek_gtk_keyboard_new       (EekKeyboard    *keyboard);
 | 
				
			||||||
 | 
					void       eek_gtk_keyboard_set_theme (EekGtkKeyboard *keyboard,
 | 
				
			||||||
 | 
					                                       EekTheme       *theme);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
G_END_DECLS
 | 
					G_END_DECLS
 | 
				
			||||||
#endif  /* EEK_GTK_KEYBOARD_H */
 | 
					#endif  /* EEK_GTK_KEYBOARD_H */
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										104
									
								
								eek/eek-gtk-renderer.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,104 @@
 | 
				
			|||||||
 | 
					/* 
 | 
				
			||||||
 | 
					 * Copyright (C) 2011 Daiki Ueno <ueno@unixuser.org>
 | 
				
			||||||
 | 
					 * Copyright (C) 2011 Red Hat, Inc.
 | 
				
			||||||
 | 
					 * 
 | 
				
			||||||
 | 
					 * This library is free software; you can redistribute it and/or
 | 
				
			||||||
 | 
					 * modify it under the terms of the GNU Lesser General Public License
 | 
				
			||||||
 | 
					 * as published by the Free Software Foundation; either version 2 of
 | 
				
			||||||
 | 
					 * the License, or (at your option) any later version.
 | 
				
			||||||
 | 
					 * 
 | 
				
			||||||
 | 
					 * This library is distributed in the hope that it will be useful, but
 | 
				
			||||||
 | 
					 * WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
				
			||||||
 | 
					 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
				
			||||||
 | 
					 * Lesser General Public License for more details.
 | 
				
			||||||
 | 
					 * 
 | 
				
			||||||
 | 
					 * You should have received a copy of the GNU Lesser General Public
 | 
				
			||||||
 | 
					 * License along with this library; if not, write to the Free Software
 | 
				
			||||||
 | 
					 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 | 
				
			||||||
 | 
					 * 02110-1301 USA
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef HAVE_CONFIG_H
 | 
				
			||||||
 | 
					#include "config.h"
 | 
				
			||||||
 | 
					#endif  /* HAVE_CONFIG_H */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <string.h>
 | 
				
			||||||
 | 
					#include <gdk-pixbuf/gdk-pixbuf.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "eek-gtk-renderer.h"
 | 
				
			||||||
 | 
					#include "eek-key.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					G_DEFINE_TYPE (EekGtkRenderer, eek_gtk_renderer, EEK_TYPE_RENDERER);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static cairo_surface_t *
 | 
				
			||||||
 | 
					pixbuf_to_cairo_surface (GdkPixbuf *pixbuf)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  cairo_surface_t *dummy_surface;
 | 
				
			||||||
 | 
					  cairo_pattern_t *pattern;
 | 
				
			||||||
 | 
					  cairo_surface_t *surface;
 | 
				
			||||||
 | 
					  cairo_t *cr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  dummy_surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 1, 1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  cr = cairo_create (dummy_surface);
 | 
				
			||||||
 | 
					  gdk_cairo_set_source_pixbuf (cr, pixbuf, 0, 0);
 | 
				
			||||||
 | 
					  pattern = cairo_get_source (cr);
 | 
				
			||||||
 | 
					  cairo_pattern_get_surface (pattern, &surface);
 | 
				
			||||||
 | 
					  cairo_surface_reference (surface);
 | 
				
			||||||
 | 
					  cairo_destroy (cr);
 | 
				
			||||||
 | 
					  cairo_surface_destroy (dummy_surface);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return surface;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static cairo_surface_t *
 | 
				
			||||||
 | 
					eek_gtk_renderer_real_get_icon_surface (EekRenderer *self,
 | 
				
			||||||
 | 
					                                        const gchar *icon_name,
 | 
				
			||||||
 | 
					                                        gint size)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    GdkPixbuf *pixbuf;
 | 
				
			||||||
 | 
					    GError *error;
 | 
				
			||||||
 | 
					    cairo_surface_t *surface;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    error = NULL;
 | 
				
			||||||
 | 
					    pixbuf = gtk_icon_theme_load_icon (gtk_icon_theme_get_default (),
 | 
				
			||||||
 | 
					                                       icon_name,
 | 
				
			||||||
 | 
					                                       size,
 | 
				
			||||||
 | 
					                                       0,
 | 
				
			||||||
 | 
					                                       &error);
 | 
				
			||||||
 | 
					    if (pixbuf == NULL) {
 | 
				
			||||||
 | 
					        g_warning ("can't get icon pixbuf for %s: %s",
 | 
				
			||||||
 | 
					                   icon_name,
 | 
				
			||||||
 | 
					                   error->message);
 | 
				
			||||||
 | 
					        g_error_free (error);
 | 
				
			||||||
 | 
					        return NULL;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    surface = pixbuf_to_cairo_surface (pixbuf);
 | 
				
			||||||
 | 
					    g_object_unref (pixbuf);
 | 
				
			||||||
 | 
					    return surface;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					eek_gtk_renderer_class_init (EekGtkRendererClass *klass)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    EekRendererClass *renderer_class = EEK_RENDERER_CLASS (klass);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    renderer_class->get_icon_surface = eek_gtk_renderer_real_get_icon_surface;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					eek_gtk_renderer_init (EekGtkRenderer *self)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					EekRenderer *
 | 
				
			||||||
 | 
					eek_gtk_renderer_new (EekKeyboard  *keyboard,
 | 
				
			||||||
 | 
					                      PangoContext *pcontext,
 | 
				
			||||||
 | 
					                      GtkWidget    *widget)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return g_object_new (EEK_TYPE_GTK_RENDERER,
 | 
				
			||||||
 | 
					                         "keyboard", keyboard,
 | 
				
			||||||
 | 
					                         "pango-context", pcontext,
 | 
				
			||||||
 | 
					                         NULL);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										61
									
								
								eek/eek-gtk-renderer.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,61 @@
 | 
				
			|||||||
 | 
					/* 
 | 
				
			||||||
 | 
					 * Copyright (C) 2010-2011 Daiki Ueno <ueno@unixuser.org>
 | 
				
			||||||
 | 
					 * Copyright (C) 2010-2011 Red Hat, Inc.
 | 
				
			||||||
 | 
					 * 
 | 
				
			||||||
 | 
					 * This library is free software; you can redistribute it and/or
 | 
				
			||||||
 | 
					 * modify it under the terms of the GNU Lesser General Public License
 | 
				
			||||||
 | 
					 * as published by the Free Software Foundation; either version 2 of
 | 
				
			||||||
 | 
					 * the License, or (at your option) any later version.
 | 
				
			||||||
 | 
					 * 
 | 
				
			||||||
 | 
					 * This library is distributed in the hope that it will be useful, but
 | 
				
			||||||
 | 
					 * WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
				
			||||||
 | 
					 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
				
			||||||
 | 
					 * Lesser General Public License for more details.
 | 
				
			||||||
 | 
					 * 
 | 
				
			||||||
 | 
					 * You should have received a copy of the GNU Lesser General Public
 | 
				
			||||||
 | 
					 * License along with this library; if not, write to the Free Software
 | 
				
			||||||
 | 
					 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 | 
				
			||||||
 | 
					 * 02110-1301 USA
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef EEK_GTK_RENDERER_H
 | 
				
			||||||
 | 
					#define EEK_GTK_RENDERER_H 1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <gtk/gtk.h>
 | 
				
			||||||
 | 
					#include "eek-renderer.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					G_BEGIN_DECLS
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define EEK_TYPE_GTK_RENDERER (eek_gtk_renderer_get_type())
 | 
				
			||||||
 | 
					#define EEK_GTK_RENDERER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EEK_TYPE_GTK_RENDERER, EekGtkRenderer))
 | 
				
			||||||
 | 
					#define EEK_GTK_RENDERER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EEK_TYPE_GTK_RENDERER, EekGtkRendererClass))
 | 
				
			||||||
 | 
					#define EEK_IS_GTK_RENDERER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EEK_TYPE_GTK_RENDERER))
 | 
				
			||||||
 | 
					#define EEK_IS_GTK_RENDERER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EEK_TYPE_GTK_RENDERER))
 | 
				
			||||||
 | 
					#define EEK_GTK_RENDERER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EEK_TYPE_GTK_RENDERER, EekGtkRendererClass))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef struct _EekGtkRenderer EekGtkRenderer;
 | 
				
			||||||
 | 
					typedef struct _EekGtkRendererClass EekGtkRendererClass;
 | 
				
			||||||
 | 
					typedef struct _EekGtkRendererPrivate EekGtkRendererPrivate;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct _EekGtkRenderer {
 | 
				
			||||||
 | 
					    EekRenderer parent;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    EekGtkRendererPrivate *priv;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct _EekGtkRendererClass
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    EekRendererClass parent_class;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /*< private >*/
 | 
				
			||||||
 | 
					    /* padding */
 | 
				
			||||||
 | 
					    gpointer pdummy[24];
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					GType        eek_gtk_renderer_get_type (void) G_GNUC_CONST;
 | 
				
			||||||
 | 
					EekRenderer *eek_gtk_renderer_new      (EekKeyboard  *keyboard,
 | 
				
			||||||
 | 
					                                        PangoContext *pcontext,
 | 
				
			||||||
 | 
					                                        GtkWidget *widget);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					G_END_DECLS
 | 
				
			||||||
 | 
					#endif  /* EEK_GTK_RENDERER_H */
 | 
				
			||||||
							
								
								
									
										613
									
								
								eek/eek-key.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,613 @@
 | 
				
			|||||||
 | 
					/* 
 | 
				
			||||||
 | 
					 * Copyright (C) 2010-2011 Daiki Ueno <ueno@unixuser.org>
 | 
				
			||||||
 | 
					 * Copyright (C) 2010-2011 Red Hat, Inc.
 | 
				
			||||||
 | 
					 * 
 | 
				
			||||||
 | 
					 * This library is free software; you can redistribute it and/or
 | 
				
			||||||
 | 
					 * modify it under the terms of the GNU Lesser General Public License
 | 
				
			||||||
 | 
					 * as published by the Free Software Foundation; either version 2 of
 | 
				
			||||||
 | 
					 * the License, or (at your option) any later version.
 | 
				
			||||||
 | 
					 * 
 | 
				
			||||||
 | 
					 * This library is distributed in the hope that it will be useful, but
 | 
				
			||||||
 | 
					 * WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
				
			||||||
 | 
					 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
				
			||||||
 | 
					 * Lesser General Public License for more details.
 | 
				
			||||||
 | 
					 * 
 | 
				
			||||||
 | 
					 * You should have received a copy of the GNU Lesser General Public
 | 
				
			||||||
 | 
					 * License along with this library; if not, write to the Free Software
 | 
				
			||||||
 | 
					 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 | 
				
			||||||
 | 
					 * 02110-1301 USA
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * SECTION:eek-key
 | 
				
			||||||
 | 
					 * @short_description: Base class of a key
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * The #EekKeyClass class represents a key.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef HAVE_CONFIG_H
 | 
				
			||||||
 | 
					#include "config.h"
 | 
				
			||||||
 | 
					#endif  /* HAVE_CONFIG_H */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <string.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "eek-key.h"
 | 
				
			||||||
 | 
					#include "eek-section.h"
 | 
				
			||||||
 | 
					#include "eek-keyboard.h"
 | 
				
			||||||
 | 
					#include "eek-symbol.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					enum {
 | 
				
			||||||
 | 
					    PROP_0,
 | 
				
			||||||
 | 
					    PROP_KEYCODE,
 | 
				
			||||||
 | 
					    PROP_SYMBOL_MATRIX,
 | 
				
			||||||
 | 
					    PROP_COLUMN,
 | 
				
			||||||
 | 
					    PROP_ROW,
 | 
				
			||||||
 | 
					    PROP_OREF,
 | 
				
			||||||
 | 
					    PROP_LAST
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					enum {
 | 
				
			||||||
 | 
					    LOCKED,
 | 
				
			||||||
 | 
					    UNLOCKED,
 | 
				
			||||||
 | 
					    LAST_SIGNAL
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static guint signals[LAST_SIGNAL] = { 0, };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef struct _EekKeyPrivate
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    guint keycode;
 | 
				
			||||||
 | 
					    EekSymbolMatrix *symbol_matrix;
 | 
				
			||||||
 | 
					    gint column;
 | 
				
			||||||
 | 
					    gint row;
 | 
				
			||||||
 | 
					    gulong oref; // UI outline reference
 | 
				
			||||||
 | 
					    gboolean is_pressed;
 | 
				
			||||||
 | 
					    gboolean is_locked;
 | 
				
			||||||
 | 
					} EekKeyPrivate;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					G_DEFINE_TYPE_WITH_PRIVATE (EekKey, eek_key, EEK_TYPE_ELEMENT)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					eek_key_real_locked (EekKey *self)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    EekKeyPrivate *priv = eek_key_get_instance_private (self);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    priv->is_locked = TRUE;
 | 
				
			||||||
 | 
					#if DEBUG
 | 
				
			||||||
 | 
					    g_debug ("locked %X", eek_key_get_keycode (self));
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					eek_key_real_unlocked (EekKey *self)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    EekKeyPrivate *priv = eek_key_get_instance_private (self);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    priv->is_locked = FALSE;
 | 
				
			||||||
 | 
					#if DEBUG
 | 
				
			||||||
 | 
					    g_debug ("unlocked %X", eek_key_get_keycode (self));
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					eek_key_finalize (GObject *object)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    EekKey        *self = EEK_KEY (object);
 | 
				
			||||||
 | 
					    EekKeyPrivate *priv = eek_key_get_instance_private (self);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    eek_symbol_matrix_free (priv->symbol_matrix);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    G_OBJECT_CLASS (eek_key_parent_class)->finalize (object);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					eek_key_set_property (GObject      *object,
 | 
				
			||||||
 | 
					                      guint         prop_id,
 | 
				
			||||||
 | 
					                      const GValue *value,
 | 
				
			||||||
 | 
					                      GParamSpec   *pspec)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    EekSymbolMatrix *matrix;
 | 
				
			||||||
 | 
					    gint column, row;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    switch (prop_id) {
 | 
				
			||||||
 | 
					    case PROP_KEYCODE:
 | 
				
			||||||
 | 
					        eek_key_set_keycode (EEK_KEY(object), g_value_get_uint (value));
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					    case PROP_SYMBOL_MATRIX:
 | 
				
			||||||
 | 
					        matrix = g_value_get_boxed (value);
 | 
				
			||||||
 | 
					        eek_key_set_symbol_matrix (EEK_KEY(object), matrix);
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					    case PROP_COLUMN:
 | 
				
			||||||
 | 
					        eek_key_get_index (EEK_KEY(object), &column, &row);
 | 
				
			||||||
 | 
					        eek_key_set_index (EEK_KEY(object), g_value_get_int (value), row);
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					    case PROP_ROW:
 | 
				
			||||||
 | 
					        eek_key_get_index (EEK_KEY(object), &column, &row);
 | 
				
			||||||
 | 
					        eek_key_set_index (EEK_KEY(object), column, g_value_get_int (value));
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					    case PROP_OREF:
 | 
				
			||||||
 | 
					        eek_key_set_oref (EEK_KEY(object), g_value_get_uint (value));
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					    default:
 | 
				
			||||||
 | 
					        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					eek_key_get_property (GObject    *object,
 | 
				
			||||||
 | 
					                      guint       prop_id,
 | 
				
			||||||
 | 
					                      GValue     *value,
 | 
				
			||||||
 | 
					                      GParamSpec *pspec)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    gint column, row;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    switch (prop_id) {
 | 
				
			||||||
 | 
					    case PROP_KEYCODE:
 | 
				
			||||||
 | 
					        g_value_set_uint (value, eek_key_get_keycode (EEK_KEY(object)));
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					    case PROP_SYMBOL_MATRIX:
 | 
				
			||||||
 | 
					        g_value_set_boxed (value,
 | 
				
			||||||
 | 
					                           eek_key_get_symbol_matrix (EEK_KEY(object)));
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					    case PROP_COLUMN:
 | 
				
			||||||
 | 
					        eek_key_get_index (EEK_KEY(object), &column, &row);
 | 
				
			||||||
 | 
					        g_value_set_int (value, column);
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					    case PROP_ROW:
 | 
				
			||||||
 | 
					        eek_key_get_index (EEK_KEY(object), &column, &row);
 | 
				
			||||||
 | 
					        g_value_set_int (value, row);
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					    case PROP_OREF:
 | 
				
			||||||
 | 
					        g_value_set_uint (value, eek_key_get_oref (EEK_KEY(object)));
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					    default:
 | 
				
			||||||
 | 
					        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					eek_key_class_init (EekKeyClass *klass)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    GObjectClass      *gobject_class = G_OBJECT_CLASS (klass);
 | 
				
			||||||
 | 
					    GParamSpec        *pspec;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    gobject_class->set_property = eek_key_set_property;
 | 
				
			||||||
 | 
					    gobject_class->get_property = eek_key_get_property;
 | 
				
			||||||
 | 
					    gobject_class->finalize     = eek_key_finalize;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* signals */
 | 
				
			||||||
 | 
					    klass->locked = eek_key_real_locked;
 | 
				
			||||||
 | 
					    klass->unlocked = eek_key_real_unlocked;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * EekKey:keycode:
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * The keycode of #EekKey.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    pspec = g_param_spec_uint ("keycode",
 | 
				
			||||||
 | 
					                               "Keycode",
 | 
				
			||||||
 | 
					                               "Keycode of the key",
 | 
				
			||||||
 | 
					                               0, G_MAXUINT, 0,
 | 
				
			||||||
 | 
					                               G_PARAM_READWRITE);
 | 
				
			||||||
 | 
					    g_object_class_install_property (gobject_class, PROP_KEYCODE, pspec);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * EekKey:symbol-matrix:
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * The symbol matrix of #EekKey.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    pspec = g_param_spec_boxed ("symbol-matrix",
 | 
				
			||||||
 | 
					                                "Symbol matrix",
 | 
				
			||||||
 | 
					                                "Symbol matrix of the key",
 | 
				
			||||||
 | 
					                                EEK_TYPE_SYMBOL_MATRIX,
 | 
				
			||||||
 | 
					                                G_PARAM_READWRITE);
 | 
				
			||||||
 | 
					    g_object_class_install_property (gobject_class, PROP_SYMBOL_MATRIX, pspec);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * EekKey:column:
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * The column index of #EekKey in the parent #EekSection.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    pspec = g_param_spec_int ("column",
 | 
				
			||||||
 | 
					                              "Column",
 | 
				
			||||||
 | 
					                              "Column index of the key in section",
 | 
				
			||||||
 | 
					                              -1, G_MAXINT, -1,
 | 
				
			||||||
 | 
					                              G_PARAM_READWRITE);
 | 
				
			||||||
 | 
					    g_object_class_install_property (gobject_class, PROP_COLUMN, pspec);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * EekKey:row:
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * The row index of #EekKey in the parent #EekSection.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    pspec = g_param_spec_int ("row",
 | 
				
			||||||
 | 
					                              "Row",
 | 
				
			||||||
 | 
					                              "Row index of the key in section",
 | 
				
			||||||
 | 
					                              -1, G_MAXINT, -1,
 | 
				
			||||||
 | 
					                              G_PARAM_READWRITE);
 | 
				
			||||||
 | 
					    g_object_class_install_property (gobject_class, PROP_ROW, pspec);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * EekKey:oref:
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * The outline id of #EekKey.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    pspec = g_param_spec_ulong ("oref",
 | 
				
			||||||
 | 
					                                "Oref",
 | 
				
			||||||
 | 
					                                "Outline id of the key",
 | 
				
			||||||
 | 
					                                0, G_MAXULONG, 0,
 | 
				
			||||||
 | 
					                                G_PARAM_READWRITE);
 | 
				
			||||||
 | 
					    g_object_class_install_property (gobject_class, PROP_OREF, pspec);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * EekKey::locked:
 | 
				
			||||||
 | 
					     * @key: an #EekKey
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * The ::locked signal is emitted each time @key is shifted to
 | 
				
			||||||
 | 
					     * the locked state.  The class handler runs before signal
 | 
				
			||||||
 | 
					     * handlers to allow signal handlers to read the status of @key
 | 
				
			||||||
 | 
					     * with eek_key_is_locked().
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    signals[LOCKED] =
 | 
				
			||||||
 | 
					        g_signal_new (I_("locked"),
 | 
				
			||||||
 | 
					                      G_TYPE_FROM_CLASS(gobject_class),
 | 
				
			||||||
 | 
					                      G_SIGNAL_RUN_FIRST,
 | 
				
			||||||
 | 
					                      G_STRUCT_OFFSET(EekKeyClass, locked),
 | 
				
			||||||
 | 
					                      NULL,
 | 
				
			||||||
 | 
					                      NULL,
 | 
				
			||||||
 | 
					                      g_cclosure_marshal_VOID__VOID,
 | 
				
			||||||
 | 
					                      G_TYPE_NONE, 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * EekKey::unlocked:
 | 
				
			||||||
 | 
					     * @key: an #EekKey
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * The ::unlocked signal is emitted each time @key is shifted to
 | 
				
			||||||
 | 
					     * the unlocked state.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					   signals[UNLOCKED] =
 | 
				
			||||||
 | 
					        g_signal_new (I_("unlocked"),
 | 
				
			||||||
 | 
					                      G_TYPE_FROM_CLASS(gobject_class),
 | 
				
			||||||
 | 
					                      G_SIGNAL_RUN_LAST,
 | 
				
			||||||
 | 
					                      G_STRUCT_OFFSET(EekKeyClass, unlocked),
 | 
				
			||||||
 | 
					                      NULL,
 | 
				
			||||||
 | 
					                      NULL,
 | 
				
			||||||
 | 
					                      g_cclosure_marshal_VOID__VOID,
 | 
				
			||||||
 | 
					                      G_TYPE_NONE, 0);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					eek_key_init (EekKey *self)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    EekKeyPrivate *priv = eek_key_get_instance_private (self);
 | 
				
			||||||
 | 
					    priv->symbol_matrix = eek_symbol_matrix_new (0, 0);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * eek_key_set_keycode:
 | 
				
			||||||
 | 
					 * @key: an #EekKey
 | 
				
			||||||
 | 
					 * @keycode: keycode
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Set the keycode of @key to @keycode.  Since typically the keycode
 | 
				
			||||||
 | 
					 * value is used to find a key in a keyboard by calling
 | 
				
			||||||
 | 
					 * eek_keyboard_find_key_by_keycode, it is not necessarily the same as
 | 
				
			||||||
 | 
					 * the X keycode but it should be unique in the keyboard @key belongs
 | 
				
			||||||
 | 
					 * to.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					eek_key_set_keycode (EekKey *key,
 | 
				
			||||||
 | 
					                     guint   keycode)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    g_return_if_fail (EEK_IS_KEY (key));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    EekKeyPrivate *priv = eek_key_get_instance_private (key);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    priv->keycode = keycode;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * eek_key_get_keycode:
 | 
				
			||||||
 | 
					 * @key: an #EekKey
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Get keycode of @key.
 | 
				
			||||||
 | 
					 * Returns: keycode or %EEK_INVALID_KEYCODE on failure
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					guint
 | 
				
			||||||
 | 
					eek_key_get_keycode (EekKey *key)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    g_return_val_if_fail (EEK_IS_KEY (key), EEK_INVALID_KEYCODE);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    EekKeyPrivate *priv = eek_key_get_instance_private (key);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return priv->keycode;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * eek_key_set_symbol_matrix:
 | 
				
			||||||
 | 
					 * @key: an #EekKey
 | 
				
			||||||
 | 
					 * @matrix: an #EekSymbolMatrix
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Set the symbol matrix of @key to @matrix.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					eek_key_set_symbol_matrix (EekKey          *key,
 | 
				
			||||||
 | 
					                           EekSymbolMatrix *matrix)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    g_return_if_fail (EEK_IS_KEY(key));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    EekKeyPrivate *priv = eek_key_get_instance_private (key);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    eek_symbol_matrix_free (priv->symbol_matrix);
 | 
				
			||||||
 | 
					    priv->symbol_matrix = eek_symbol_matrix_copy (matrix);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * eek_key_get_symbol_matrix:
 | 
				
			||||||
 | 
					 * @key: an #EekKey
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Get the symbol matrix of @key.
 | 
				
			||||||
 | 
					 * Returns: (transfer none): #EekSymbolMatrix or %NULL
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					EekSymbolMatrix *
 | 
				
			||||||
 | 
					eek_key_get_symbol_matrix (EekKey *key)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    g_return_val_if_fail (EEK_IS_KEY(key), NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    EekKeyPrivate *priv = eek_key_get_instance_private (key);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return priv->symbol_matrix;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * eek_key_get_symbol:
 | 
				
			||||||
 | 
					 * @key: an #EekKey
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Get the current symbol of @key.
 | 
				
			||||||
 | 
					 * Return value: (transfer none): the current #EekSymbol or %NULL on failure
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					EekSymbol *
 | 
				
			||||||
 | 
					eek_key_get_symbol (EekKey *key)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return eek_key_get_symbol_with_fallback (key, 0, 0);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * eek_key_get_symbol_with_fallback:
 | 
				
			||||||
 | 
					 * @key: an #EekKey
 | 
				
			||||||
 | 
					 * @fallback_group: fallback group index
 | 
				
			||||||
 | 
					 * @fallback_level: fallback level index
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Get the current symbol of @key.
 | 
				
			||||||
 | 
					 * Return value: (transfer none): the current #EekSymbol or %NULL on failure
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					EekSymbol *
 | 
				
			||||||
 | 
					eek_key_get_symbol_with_fallback (EekKey *key,
 | 
				
			||||||
 | 
					                                  gint    fallback_group,
 | 
				
			||||||
 | 
					                                  gint    fallback_level)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    gint group, level;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    g_return_val_if_fail (EEK_IS_KEY (key), NULL);
 | 
				
			||||||
 | 
					    g_return_val_if_fail (fallback_group >= 0, NULL);
 | 
				
			||||||
 | 
					    g_return_val_if_fail (fallback_level >= 0, NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    eek_element_get_symbol_index (EEK_ELEMENT(key), &group, &level);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (group < 0 || level < 0) {
 | 
				
			||||||
 | 
					        EekElement *section;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        section = eek_element_get_parent (EEK_ELEMENT(key));
 | 
				
			||||||
 | 
					        g_return_val_if_fail (EEK_IS_SECTION (section), NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (group < 0)
 | 
				
			||||||
 | 
					            group = eek_element_get_group (section);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (level < 0)
 | 
				
			||||||
 | 
					            level = eek_element_get_level (section);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (group < 0 || level < 0) {
 | 
				
			||||||
 | 
					            EekElement *keyboard;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            keyboard = eek_element_get_parent (section);
 | 
				
			||||||
 | 
					            g_return_val_if_fail (EEK_IS_KEYBOARD (keyboard), NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (group < 0)
 | 
				
			||||||
 | 
					                group = eek_element_get_group (keyboard);
 | 
				
			||||||
 | 
					            if (level < 0)
 | 
				
			||||||
 | 
					                level = eek_element_get_level (keyboard);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return eek_key_get_symbol_at_index (key,
 | 
				
			||||||
 | 
					                                        group,
 | 
				
			||||||
 | 
					                                        level,
 | 
				
			||||||
 | 
					                                        fallback_group,
 | 
				
			||||||
 | 
					                                        fallback_level);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * eek_key_get_symbol_at_index:
 | 
				
			||||||
 | 
					 * @key: an #EekKey
 | 
				
			||||||
 | 
					 * @group: group index of the symbol matrix
 | 
				
			||||||
 | 
					 * @level: level index of the symbol matrix
 | 
				
			||||||
 | 
					 * @fallback_group: fallback group index
 | 
				
			||||||
 | 
					 * @fallback_level: fallback level index
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Get the symbol at (@group, @level) in the symbol matrix of @key.
 | 
				
			||||||
 | 
					 * Return value: (transfer none): an #EekSymbol at (@group, @level), or %NULL
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					EekSymbol *
 | 
				
			||||||
 | 
					eek_key_get_symbol_at_index (EekKey *key,
 | 
				
			||||||
 | 
					                             gint    group,
 | 
				
			||||||
 | 
					                             gint    level,
 | 
				
			||||||
 | 
					                             gint    fallback_group,
 | 
				
			||||||
 | 
					                             gint    fallback_level)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    EekKeyPrivate *priv = eek_key_get_instance_private (key);
 | 
				
			||||||
 | 
					    gint num_symbols;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    g_return_val_if_fail (fallback_group >= 0, NULL);
 | 
				
			||||||
 | 
					    g_return_val_if_fail (fallback_level >= 0, NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (group < 0)
 | 
				
			||||||
 | 
					        group = fallback_group;
 | 
				
			||||||
 | 
					    if (level < 0)
 | 
				
			||||||
 | 
					        level = fallback_level;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (!priv->symbol_matrix)
 | 
				
			||||||
 | 
					        return NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    num_symbols = priv->symbol_matrix->num_groups *
 | 
				
			||||||
 | 
					        priv->symbol_matrix->num_levels;
 | 
				
			||||||
 | 
					    if (num_symbols == 0)
 | 
				
			||||||
 | 
					        return NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (group >= priv->symbol_matrix->num_groups) {
 | 
				
			||||||
 | 
					        if (fallback_group < 0)
 | 
				
			||||||
 | 
					            return NULL;
 | 
				
			||||||
 | 
					        group = fallback_group;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (level >= priv->symbol_matrix->num_levels) {
 | 
				
			||||||
 | 
					        if (fallback_level < 0)
 | 
				
			||||||
 | 
					            return NULL;
 | 
				
			||||||
 | 
					        level = fallback_level;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return priv->symbol_matrix->data[group * priv->symbol_matrix->num_levels +
 | 
				
			||||||
 | 
					                                     level];
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * eek_key_set_index:
 | 
				
			||||||
 | 
					 * @key: an #EekKey
 | 
				
			||||||
 | 
					 * @column: column index of @key in #EekSection
 | 
				
			||||||
 | 
					 * @row: row index of @key in #EekSection
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Set the location of @key in #EekSection with @column and @row.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					eek_key_set_index (EekKey *key,
 | 
				
			||||||
 | 
					                   gint    column,
 | 
				
			||||||
 | 
					                   gint    row)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    g_return_if_fail (EEK_IS_KEY(key));
 | 
				
			||||||
 | 
					    g_return_if_fail (0 <= column);
 | 
				
			||||||
 | 
					    g_return_if_fail (0 <= row);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    EekKeyPrivate *priv = eek_key_get_instance_private (key);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (priv->column != column) {
 | 
				
			||||||
 | 
					        priv->column = column;
 | 
				
			||||||
 | 
					        g_object_notify (G_OBJECT(key), "column");
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if (priv->row != row) {
 | 
				
			||||||
 | 
					        priv->row = row;
 | 
				
			||||||
 | 
					        g_object_notify (G_OBJECT(key), "row");
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * eek_key_get_index:
 | 
				
			||||||
 | 
					 * @key: an #EekKey
 | 
				
			||||||
 | 
					 * @column: (allow-none): pointer where the column index of @key in #EekSection will be stored
 | 
				
			||||||
 | 
					 * @row: (allow-none): pointer where the row index of @key in #EekSection will be stored
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Get the location of @key in #EekSection.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					eek_key_get_index (EekKey *key,
 | 
				
			||||||
 | 
					                   gint   *column,
 | 
				
			||||||
 | 
					                   gint   *row)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    g_return_if_fail (EEK_IS_KEY(key));
 | 
				
			||||||
 | 
					    g_return_if_fail (column != NULL || row != NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    EekKeyPrivate *priv = eek_key_get_instance_private (key);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (column != NULL)
 | 
				
			||||||
 | 
					        *column = priv->column;
 | 
				
			||||||
 | 
					    if (row != NULL)
 | 
				
			||||||
 | 
					        *row = priv->row;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * eek_key_set_oref:
 | 
				
			||||||
 | 
					 * @key: an #EekKey
 | 
				
			||||||
 | 
					 * @oref: outline id of @key
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Set the outline id of @key to @oref.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					eek_key_set_oref (EekKey *key,
 | 
				
			||||||
 | 
					                  guint   oref)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    g_return_if_fail (EEK_IS_KEY(key));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    EekKeyPrivate *priv = eek_key_get_instance_private (key);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (priv->oref != oref) {
 | 
				
			||||||
 | 
					        priv->oref = oref;
 | 
				
			||||||
 | 
					        g_object_notify (G_OBJECT(key), "oref");
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * eek_key_get_oref:
 | 
				
			||||||
 | 
					 * @key: an #EekKey
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Get the outline id of @key.
 | 
				
			||||||
 | 
					 * Returns: unsigned integer
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					guint
 | 
				
			||||||
 | 
					eek_key_get_oref (EekKey *key)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    g_return_val_if_fail (EEK_IS_KEY (key), 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    EekKeyPrivate *priv = eek_key_get_instance_private (key);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return priv->oref;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * eek_key_is_pressed:
 | 
				
			||||||
 | 
					 * @key: an #EekKey
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Return %TRUE if key is marked as pressed.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					gboolean
 | 
				
			||||||
 | 
					eek_key_is_pressed (EekKey *key)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    g_return_val_if_fail (EEK_IS_KEY(key), FALSE);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    EekKeyPrivate *priv = eek_key_get_instance_private (key);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return priv->is_pressed;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * eek_key_is_locked:
 | 
				
			||||||
 | 
					 * @key: an #EekKey
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Return %TRUE if key is marked as locked.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					gboolean
 | 
				
			||||||
 | 
					eek_key_is_locked (EekKey *key)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    g_return_val_if_fail (EEK_IS_KEY(key), FALSE);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    EekKeyPrivate *priv = eek_key_get_instance_private (key);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return priv->is_locked;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void eek_key_set_pressed(EekKey *key, gboolean value)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    g_return_if_fail (EEK_IS_KEY(key));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    EekKeyPrivate *priv = eek_key_get_instance_private (key);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    priv->is_pressed = value;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										93
									
								
								eek/eek-key.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,93 @@
 | 
				
			|||||||
 | 
					/* 
 | 
				
			||||||
 | 
					 * Copyright (C) 2010-2011 Daiki Ueno <ueno@unixuser.org>
 | 
				
			||||||
 | 
					 * Copyright (C) 2010-2011 Red Hat, Inc.
 | 
				
			||||||
 | 
					 * 
 | 
				
			||||||
 | 
					 * This library is free software; you can redistribute it and/or
 | 
				
			||||||
 | 
					 * modify it under the terms of the GNU Lesser General Public License
 | 
				
			||||||
 | 
					 * as published by the Free Software Foundation; either version 2 of
 | 
				
			||||||
 | 
					 * the License, or (at your option) any later version.
 | 
				
			||||||
 | 
					 * 
 | 
				
			||||||
 | 
					 * This library is distributed in the hope that it will be useful, but
 | 
				
			||||||
 | 
					 * WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
				
			||||||
 | 
					 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
				
			||||||
 | 
					 * Lesser General Public License for more details.
 | 
				
			||||||
 | 
					 * 
 | 
				
			||||||
 | 
					 * You should have received a copy of the GNU Lesser General Public
 | 
				
			||||||
 | 
					 * License along with this library; if not, write to the Free Software
 | 
				
			||||||
 | 
					 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 | 
				
			||||||
 | 
					 * 02110-1301 USA
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if !defined(__EEK_H_INSIDE__) && !defined(EEK_COMPILATION)
 | 
				
			||||||
 | 
					#error "Only <eek/eek.h> can be included directly."
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef EEK_KEY_H
 | 
				
			||||||
 | 
					#define EEK_KEY_H 1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "eek-element.h"
 | 
				
			||||||
 | 
					#include "eek-symbol-matrix.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					G_BEGIN_DECLS
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define EEK_TYPE_KEY (eek_key_get_type())
 | 
				
			||||||
 | 
					G_DECLARE_DERIVABLE_TYPE(EekKey, eek_key, EEK, KEY, EekElement)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * EekKeyClass:
 | 
				
			||||||
 | 
					 * @pressed: class handler for #EekKey::pressed signal
 | 
				
			||||||
 | 
					 * @released: class handler for #EekKey::released signal
 | 
				
			||||||
 | 
					 * @locked: class handler for #EekKey::locked signal
 | 
				
			||||||
 | 
					 * @unlocked: class handler for #EekKey::unlocked signal
 | 
				
			||||||
 | 
					 * @cancelled: class handler for #EekKey::cancelled signal
 | 
				
			||||||
 | 
					 * @is_pressed: virtual function for getting whether the key is pressed
 | 
				
			||||||
 | 
					 * @is_locked: virtual function for getting whether the key is locked
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					struct _EekKeyClass
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    /*< private >*/
 | 
				
			||||||
 | 
					    EekElementClass parent_class;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /*< public >*/
 | 
				
			||||||
 | 
					    /* signals */
 | 
				
			||||||
 | 
					    void (* locked)    (EekKey *key);
 | 
				
			||||||
 | 
					    void (* unlocked)  (EekKey *key);
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					GType            eek_key_get_type            (void) G_GNUC_CONST;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void             eek_key_set_keycode         (EekKey          *key,
 | 
				
			||||||
 | 
					                                              guint            keycode);
 | 
				
			||||||
 | 
					guint            eek_key_get_keycode         (EekKey          *key);
 | 
				
			||||||
 | 
					void             eek_key_set_symbol_matrix   (EekKey          *key,
 | 
				
			||||||
 | 
					                                              EekSymbolMatrix *matrix);
 | 
				
			||||||
 | 
					EekSymbolMatrix *eek_key_get_symbol_matrix   (EekKey          *key);
 | 
				
			||||||
 | 
					EekSymbol       *eek_key_get_symbol          (EekKey          *key);
 | 
				
			||||||
 | 
					EekSymbol       *eek_key_get_symbol_with_fallback
 | 
				
			||||||
 | 
					                                             (EekKey          *key,
 | 
				
			||||||
 | 
					                                              gint             fallback_group,
 | 
				
			||||||
 | 
					                                              gint             fallback_level);
 | 
				
			||||||
 | 
					EekSymbol       *eek_key_get_symbol_at_index (EekKey          *key,
 | 
				
			||||||
 | 
					                                              gint             group,
 | 
				
			||||||
 | 
					                                              gint             level,
 | 
				
			||||||
 | 
					                                              gint             fallback_group,
 | 
				
			||||||
 | 
					                                              gint             fallback_level);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void             eek_key_set_index           (EekKey          *key,
 | 
				
			||||||
 | 
					                                              gint             column,
 | 
				
			||||||
 | 
					                                              gint             row);
 | 
				
			||||||
 | 
					void             eek_key_get_index           (EekKey          *key,
 | 
				
			||||||
 | 
					                                              gint            *column,
 | 
				
			||||||
 | 
					                                              gint            *row);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void             eek_key_set_oref            (EekKey          *key,
 | 
				
			||||||
 | 
					                                              guint            oref);
 | 
				
			||||||
 | 
					guint            eek_key_get_oref            (EekKey          *key);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					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 */
 | 
				
			||||||
@ -17,7 +17,9 @@
 | 
				
			|||||||
 * Boston, MA 02111-1307, USA.
 | 
					 * Boston, MA 02111-1307, USA.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef HAVE_CONFIG_H
 | 
				
			||||||
#include "config.h"
 | 
					#include "config.h"
 | 
				
			||||||
 | 
					#endif  /* HAVE_CONFIG_H */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <math.h>
 | 
					#include <math.h>
 | 
				
			||||||
#include <pango/pangocairo.h>
 | 
					#include <pango/pangocairo.h>
 | 
				
			||||||
 | 
				
			|||||||
@ -27,16 +27,56 @@
 | 
				
			|||||||
 * of one or more sections of the #EekSectionClass class.
 | 
					 * of one or more sections of the #EekSectionClass class.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef HAVE_CONFIG_H
 | 
				
			||||||
#include "config.h"
 | 
					#include "config.h"
 | 
				
			||||||
#include <glib/gprintf.h>
 | 
					#endif  /* HAVE_CONFIG_H */
 | 
				
			||||||
 | 
					 | 
				
			||||||
#include "eek-enumtypes.h"
 | 
					 | 
				
			||||||
#include "eekboard/key-emitter.h"
 | 
					 | 
				
			||||||
#include "keymap.h"
 | 
					 | 
				
			||||||
#include "src/keyboard.h"
 | 
					 | 
				
			||||||
#include "src/symbol.h"
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "eek-keyboard.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,
 | 
				
			||||||
 | 
					    PROP_LAYOUT,
 | 
				
			||||||
 | 
					    PROP_MODIFIER_BEHAVIOR,
 | 
				
			||||||
 | 
					    PROP_LAST
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					enum {
 | 
				
			||||||
 | 
					    KEY_RELEASED,
 | 
				
			||||||
 | 
					    KEY_LOCKED,
 | 
				
			||||||
 | 
					    KEY_UNLOCKED,
 | 
				
			||||||
 | 
					    LAST_SIGNAL
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static guint signals[LAST_SIGNAL] = { 0, };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					G_DEFINE_TYPE (EekKeyboard, eek_keyboard, EEK_TYPE_CONTAINER);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define EEK_KEYBOARD_GET_PRIVATE(obj)                                  \
 | 
				
			||||||
 | 
					    (G_TYPE_INSTANCE_GET_PRIVATE ((obj), EEK_TYPE_KEYBOARD, EekKeyboardPrivate))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct _EekKeyboardPrivate
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    EekLayout *layout;
 | 
				
			||||||
 | 
					    EekModifierBehavior modifier_behavior;
 | 
				
			||||||
 | 
					    EekModifierType modifiers;
 | 
				
			||||||
 | 
					    GList *pressed_keys;
 | 
				
			||||||
 | 
					    GList *locked_keys;
 | 
				
			||||||
 | 
					    GArray *outline_array;
 | 
				
			||||||
 | 
					    GHashTable *keycodes;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* modifiers dynamically assigned at run time */
 | 
				
			||||||
 | 
					    EekModifierType num_lock_mask;
 | 
				
			||||||
 | 
					    EekModifierType alt_gr_mask;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					G_DEFINE_BOXED_TYPE(EekModifierKey, eek_modifier_key,
 | 
				
			||||||
 | 
					                    eek_modifier_key_copy, eek_modifier_key_free);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
EekModifierKey *
 | 
					EekModifierKey *
 | 
				
			||||||
eek_modifier_key_copy (EekModifierKey *modkey)
 | 
					eek_modifier_key_copy (EekModifierKey *modkey)
 | 
				
			||||||
@ -47,162 +87,543 @@ eek_modifier_key_copy (EekModifierKey *modkey)
 | 
				
			|||||||
void
 | 
					void
 | 
				
			||||||
eek_modifier_key_free (EekModifierKey *modkey)
 | 
					eek_modifier_key_free (EekModifierKey *modkey)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					    g_object_unref (modkey->key);
 | 
				
			||||||
    g_slice_free (EekModifierKey, modkey);
 | 
					    g_slice_free (EekModifierKey, modkey);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// Updates the state of locked keys based on the key that was activated
 | 
					static void
 | 
				
			||||||
/// FIXME: make independent of what the key are named,
 | 
					on_key_locked (EekSection  *section,
 | 
				
			||||||
/// and instead refer to the contained symbols
 | 
					                EekKey      *key,
 | 
				
			||||||
static guint
 | 
					                EekKeyboard *keyboard)
 | 
				
			||||||
set_key_states (LevelKeyboard    *keyboard,
 | 
					 | 
				
			||||||
                struct squeek_button *button,
 | 
					 | 
				
			||||||
                guint new_level)
 | 
					 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    struct squeek_key *key = squeek_button_get_key(button);
 | 
					    g_signal_emit (keyboard, signals[KEY_LOCKED], 0, key);
 | 
				
			||||||
    // Keys locking rules hardcoded for the time being...
 | 
					}
 | 
				
			||||||
    const gchar *name = squeek_symbol_get_name(squeek_key_get_symbol(key));
 | 
					
 | 
				
			||||||
    // Lock the shift whenever it's pressed on the baselevel
 | 
					static void
 | 
				
			||||||
    // TODO: need to lock shift on the destination level
 | 
					on_key_unlocked (EekSection  *section,
 | 
				
			||||||
    if (g_strcmp0(name, "Shift_L") == 0 && keyboard->level == 0) {
 | 
					                 EekKey      *key,
 | 
				
			||||||
        EekModifierKey *modifier_key = g_slice_new (EekModifierKey);
 | 
					                 EekKeyboard *keyboard)
 | 
				
			||||||
        modifier_key->modifiers = 0;
 | 
					{
 | 
				
			||||||
        modifier_key->button = button;
 | 
					    g_signal_emit (keyboard, signals[KEY_UNLOCKED], 0, key);
 | 
				
			||||||
        keyboard->locked_buttons =
 | 
					}
 | 
				
			||||||
            g_list_prepend (keyboard->locked_buttons, modifier_key);
 | 
					
 | 
				
			||||||
        squeek_key_set_locked(key, true);
 | 
					static void
 | 
				
			||||||
 | 
					on_symbol_index_changed (EekSection *section,
 | 
				
			||||||
 | 
					                         gint group,
 | 
				
			||||||
 | 
					                         gint level,
 | 
				
			||||||
 | 
					                         EekKeyboard *keyboard)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    g_signal_emit_by_name (keyboard, "symbol-index-changed", group, level);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					section_child_added_cb (EekContainer *container,
 | 
				
			||||||
 | 
					                        EekElement   *element,
 | 
				
			||||||
 | 
					                        EekKeyboard  *keyboard)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    guint keycode = eek_key_get_keycode (EEK_KEY(element));
 | 
				
			||||||
 | 
					    g_hash_table_insert (keyboard->priv->keycodes,
 | 
				
			||||||
 | 
					                         GUINT_TO_POINTER(keycode),
 | 
				
			||||||
 | 
					                         element);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					section_child_removed_cb (EekContainer *container,
 | 
				
			||||||
 | 
					                          EekElement   *element,
 | 
				
			||||||
 | 
					                          EekKeyboard  *keyboard)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    guint keycode = eek_key_get_keycode (EEK_KEY(element));
 | 
				
			||||||
 | 
					    g_hash_table_remove (keyboard->priv->keycodes,
 | 
				
			||||||
 | 
					                         GUINT_TO_POINTER(keycode));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static EekSection *
 | 
				
			||||||
 | 
					eek_keyboard_real_create_section (EekKeyboard *self)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    EekSection *section;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    section = g_object_new (EEK_TYPE_SECTION, NULL);
 | 
				
			||||||
 | 
					    g_return_val_if_fail (section, NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    g_signal_connect (G_OBJECT(section), "child-added",
 | 
				
			||||||
 | 
					                      G_CALLBACK(section_child_added_cb), self);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    g_signal_connect (G_OBJECT(section), "child-removed",
 | 
				
			||||||
 | 
					                      G_CALLBACK(section_child_removed_cb), self);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    EEK_CONTAINER_GET_CLASS(self)->add_child (EEK_CONTAINER(self),
 | 
				
			||||||
 | 
					                                              EEK_ELEMENT(section));
 | 
				
			||||||
 | 
					    return section;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					eek_keyboard_set_property (GObject      *object,
 | 
				
			||||||
 | 
					                           guint         prop_id,
 | 
				
			||||||
 | 
					                           const GValue *value,
 | 
				
			||||||
 | 
					                           GParamSpec   *pspec)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    EekKeyboardPrivate *priv = EEK_KEYBOARD_GET_PRIVATE(object);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    switch (prop_id) {
 | 
				
			||||||
 | 
					    case PROP_LAYOUT:
 | 
				
			||||||
 | 
					        priv->layout = g_value_get_object (value);
 | 
				
			||||||
 | 
					        if (priv->layout)
 | 
				
			||||||
 | 
					            g_object_ref (priv->layout);
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					    case PROP_MODIFIER_BEHAVIOR:
 | 
				
			||||||
 | 
					        eek_keyboard_set_modifier_behavior (EEK_KEYBOARD(object),
 | 
				
			||||||
 | 
					                                            g_value_get_enum (value));
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					    default:
 | 
				
			||||||
 | 
					        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    if (keyboard->level == 1) {
 | 
					}
 | 
				
			||||||
        // Only shift is locked in this state, unlock on any key press
 | 
					
 | 
				
			||||||
        for (GList *head = keyboard->locked_buttons; head; ) {
 | 
					static void
 | 
				
			||||||
 | 
					eek_keyboard_get_property (GObject    *object,
 | 
				
			||||||
 | 
					                           guint       prop_id,
 | 
				
			||||||
 | 
					                           GValue     *value,
 | 
				
			||||||
 | 
					                           GParamSpec *pspec)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    EekKeyboardPrivate *priv = EEK_KEYBOARD_GET_PRIVATE(object);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    switch (prop_id) {
 | 
				
			||||||
 | 
					    case PROP_LAYOUT:
 | 
				
			||||||
 | 
					        g_value_set_object (value, priv->layout);
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					    case PROP_MODIFIER_BEHAVIOR:
 | 
				
			||||||
 | 
					        g_value_set_enum (value,
 | 
				
			||||||
 | 
					                          eek_keyboard_get_modifier_behavior (EEK_KEYBOARD(object)));
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					    default:
 | 
				
			||||||
 | 
					        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					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;
 | 
				
			||||||
 | 
					    eek_element_set_level (EEK_ELEMENT(self), level);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					set_modifiers_with_key (EekKeyboard    *self,
 | 
				
			||||||
 | 
					                        EekKey         *key,
 | 
				
			||||||
 | 
					                        EekModifierType modifiers)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    EekKeyboardPrivate *priv = EEK_KEYBOARD_GET_PRIVATE(self);
 | 
				
			||||||
 | 
					    EekModifierType enabled = (priv->modifiers ^ modifiers) & modifiers;
 | 
				
			||||||
 | 
					    EekModifierType disabled = (priv->modifiers ^ modifiers) & priv->modifiers;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (enabled != 0) {
 | 
				
			||||||
 | 
					        if (priv->modifier_behavior != EEK_MODIFIER_BEHAVIOR_NONE) {
 | 
				
			||||||
 | 
					            EekModifierKey *modifier_key = g_slice_new (EekModifierKey);
 | 
				
			||||||
 | 
					            modifier_key->modifiers = enabled;
 | 
				
			||||||
 | 
					            modifier_key->key = g_object_ref (key);
 | 
				
			||||||
 | 
					            priv->locked_keys =
 | 
				
			||||||
 | 
					                g_list_prepend (priv->locked_keys, modifier_key);
 | 
				
			||||||
 | 
					            g_signal_emit_by_name (modifier_key->key, "locked");
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					        if (priv->modifier_behavior != EEK_MODIFIER_BEHAVIOR_NONE) {
 | 
				
			||||||
 | 
					            GList *head;
 | 
				
			||||||
 | 
					            for (head = priv->locked_keys; head; ) {
 | 
				
			||||||
                EekModifierKey *modifier_key = head->data;
 | 
					                EekModifierKey *modifier_key = head->data;
 | 
				
			||||||
 | 
					                if (modifier_key->modifiers & disabled) {
 | 
				
			||||||
                    GList *next = g_list_next (head);
 | 
					                    GList *next = g_list_next (head);
 | 
				
			||||||
            keyboard->locked_buttons =
 | 
					                    priv->locked_keys =
 | 
				
			||||||
                g_list_remove_link (keyboard->locked_buttons, head);
 | 
					                        g_list_remove_link (priv->locked_keys, head);
 | 
				
			||||||
            squeek_key_set_locked(squeek_button_get_key(modifier_key->button), false);
 | 
					                    g_signal_emit_by_name (modifier_key->key, "unlocked");
 | 
				
			||||||
                    g_list_free1 (head);
 | 
					                    g_list_free1 (head);
 | 
				
			||||||
                    head = next;
 | 
					                    head = next;
 | 
				
			||||||
 | 
					                } else
 | 
				
			||||||
 | 
					                    head = g_list_next (head);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        return 0;
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    return new_level;
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    priv->modifiers = modifiers;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// FIXME: unhardcode, parse some user information as to which key triggers which view (level)
 | 
					void eek_keyboard_press_key(EekKeyboard *keyboard, EekKey *key, guint32 timestamp) {
 | 
				
			||||||
static void
 | 
					    EekKeyboardPrivate *priv = EEK_KEYBOARD_GET_PRIVATE(keyboard);
 | 
				
			||||||
set_level_from_press (LevelKeyboard *keyboard, struct squeek_button *button)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    /* The levels are: 0 Letters, 1 Upper case letters, 2 Numbers, 3 Symbols */
 | 
					 | 
				
			||||||
    guint level = keyboard->level;
 | 
					 | 
				
			||||||
    /* Handle non-emitting keys */
 | 
					 | 
				
			||||||
    if (button) {
 | 
					 | 
				
			||||||
        const gchar *name = squeek_symbol_get_name(squeek_key_get_symbol(squeek_button_get_key(button)));
 | 
					 | 
				
			||||||
        if (g_strcmp0(name, "show_numbers") == 0) {
 | 
					 | 
				
			||||||
            level = 2;
 | 
					 | 
				
			||||||
        } else if (g_strcmp0(name, "show_letters") == 0) {
 | 
					 | 
				
			||||||
            level = 0;
 | 
					 | 
				
			||||||
        } else if (g_strcmp0(name, "show_symbols") == 0) {
 | 
					 | 
				
			||||||
            level = 3;
 | 
					 | 
				
			||||||
        } else if (g_strcmp0(name, "Shift_L") == 0) {
 | 
					 | 
				
			||||||
            level ^= 1;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    keyboard->level = set_key_states(keyboard, button, level);
 | 
					    eek_key_set_pressed(key, TRUE);
 | 
				
			||||||
 | 
					    priv->pressed_keys = g_list_prepend (priv->pressed_keys, key);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    eek_layout_update_layout(keyboard);
 | 
					    EekSymbol *symbol = eek_key_get_symbol_with_fallback (key, 0, 0);
 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void eek_keyboard_press_button(LevelKeyboard *keyboard, struct squeek_button *button, guint32 timestamp) {
 | 
					 | 
				
			||||||
    struct squeek_key *key = squeek_button_get_key(button);
 | 
					 | 
				
			||||||
    squeek_key_set_pressed(key, TRUE);
 | 
					 | 
				
			||||||
    keyboard->pressed_buttons = g_list_prepend (keyboard->pressed_buttons, button);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    struct squeek_symbol *symbol = squeek_key_get_symbol(key);
 | 
					 | 
				
			||||||
    if (!symbol)
 | 
					    if (!symbol)
 | 
				
			||||||
        return;
 | 
					        return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Only take action about setting level *after* the key has taken effect, i.e. on release
 | 
					    EekModifierType modifier = eek_symbol_get_modifier_mask (symbol);
 | 
				
			||||||
    //set_level_from_press (keyboard, key);
 | 
					    if (priv->modifier_behavior == EEK_MODIFIER_BEHAVIOR_NONE) {
 | 
				
			||||||
 | 
					        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
 | 
					    // "Borrowed" from eek-context-service; doesn't influence the state but forwards the event
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    guint keycode = squeek_key_get_keycode (key);
 | 
					    guint keycode = eek_key_get_keycode (key);
 | 
				
			||||||
 | 
					    EekModifierType modifiers = eek_keyboard_get_modifiers (keyboard);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    emit_key_activated(keyboard->manager, keyboard, keycode, TRUE, timestamp);
 | 
					    emit_key_activated(keyboard->manager, keyboard, keycode, symbol, modifiers, TRUE, timestamp);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void eek_keyboard_release_button(LevelKeyboard *keyboard,
 | 
					void eek_keyboard_release_key( EekKeyboard *keyboard,
 | 
				
			||||||
                              struct squeek_button *button,
 | 
					                               EekKey      *key,
 | 
				
			||||||
                               guint32      timestamp) {
 | 
					                               guint32      timestamp) {
 | 
				
			||||||
    for (GList *head = keyboard->pressed_buttons; head; head = g_list_next (head)) {
 | 
					    EekKeyboardPrivate *priv = EEK_KEYBOARD_GET_PRIVATE(keyboard);
 | 
				
			||||||
        if (head->data == button) {
 | 
					
 | 
				
			||||||
            keyboard->pressed_buttons = g_list_remove_link (keyboard->pressed_buttons, 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);
 | 
					            g_list_free1 (head);
 | 
				
			||||||
            break;
 | 
					            break;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    struct squeek_symbol *symbol = squeek_button_get_symbol(button);
 | 
					    EekSymbol *symbol = eek_key_get_symbol_with_fallback (key, 0, 0);
 | 
				
			||||||
    if (!symbol)
 | 
					    if (!symbol)
 | 
				
			||||||
        return;
 | 
					        return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    set_level_from_press (keyboard, button);
 | 
					    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
 | 
					    // "Borrowed" from eek-context-service; doesn't influence the state but forwards the event
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    guint keycode = squeek_key_get_keycode (squeek_button_get_key(button));
 | 
					    guint keycode = eek_key_get_keycode (key);
 | 
				
			||||||
 | 
					    guint modifiers = eek_keyboard_get_modifiers (keyboard);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    emit_key_activated(keyboard->manager, keyboard, keycode, FALSE, timestamp);
 | 
					    emit_key_activated(keyboard->manager, keyboard, keycode, symbol, modifiers, FALSE, timestamp);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void level_keyboard_deinit(LevelKeyboard *self) {
 | 
					static void
 | 
				
			||||||
    g_hash_table_destroy (self->names);
 | 
					eek_keyboard_dispose (GObject *object)
 | 
				
			||||||
    for (guint i = 0; i < self->outline_array->len; i++) {
 | 
					{
 | 
				
			||||||
        EekOutline *outline = &g_array_index (self->outline_array,
 | 
					    EekKeyboardPrivate *priv = EEK_KEYBOARD_GET_PRIVATE(object);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (priv->layout) {
 | 
				
			||||||
 | 
					        g_object_unref (priv->layout);
 | 
				
			||||||
 | 
					        priv->layout = NULL;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    G_OBJECT_CLASS (eek_keyboard_parent_class)->dispose (object);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					eek_keyboard_finalize (GObject *object)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    EekKeyboardPrivate *priv = EEK_KEYBOARD_GET_PRIVATE(object);
 | 
				
			||||||
 | 
					    guint i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    g_list_free (priv->pressed_keys);
 | 
				
			||||||
 | 
					    g_list_free_full (priv->locked_keys,
 | 
				
			||||||
 | 
					                      (GDestroyNotify) eek_modifier_key_free);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    g_hash_table_destroy (priv->keycodes);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for (i = 0; i < priv->outline_array->len; i++) {
 | 
				
			||||||
 | 
					        EekOutline *outline = &g_array_index (priv->outline_array,
 | 
				
			||||||
                                              EekOutline,
 | 
					                                              EekOutline,
 | 
				
			||||||
                                              i);
 | 
					                                              i);
 | 
				
			||||||
        g_slice_free1 (sizeof (EekPoint) * outline->num_points,
 | 
					        g_slice_free1 (sizeof (EekPoint) * outline->num_points,
 | 
				
			||||||
                       outline->points);
 | 
					                       outline->points);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    g_array_free (self->outline_array, TRUE);
 | 
					    g_array_free (priv->outline_array, TRUE);
 | 
				
			||||||
    for (guint i = 0; i < 4; i++) {
 | 
					        
 | 
				
			||||||
        // free self->view[i];
 | 
					    G_OBJECT_CLASS (eek_keyboard_parent_class)->finalize (object);
 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void level_keyboard_free(LevelKeyboard *self) {
 | 
					static void
 | 
				
			||||||
    level_keyboard_deinit(self);
 | 
					eek_keyboard_real_child_added (EekContainer *self,
 | 
				
			||||||
    g_free(self);
 | 
					                               EekElement   *element)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    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, "symbol-index-changed",
 | 
				
			||||||
 | 
					                      G_CALLBACK(on_symbol_index_changed), self);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void level_keyboard_init(LevelKeyboard *self) {
 | 
					static void
 | 
				
			||||||
    self->outline_array = g_array_new (FALSE, TRUE, sizeof (EekOutline));
 | 
					eek_keyboard_real_child_removed (EekContainer *self,
 | 
				
			||||||
 | 
					                                 EekElement   *element)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    g_signal_handlers_disconnect_by_func (element, on_key_locked, self);
 | 
				
			||||||
 | 
					    g_signal_handlers_disconnect_by_func (element, on_key_unlocked, self);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
LevelKeyboard *level_keyboard_new(EekboardContextService *manager, struct squeek_view *views[4], GHashTable *name_button_hash) {
 | 
					static void
 | 
				
			||||||
    LevelKeyboard *keyboard = g_new0(LevelKeyboard, 1);
 | 
					eek_keyboard_class_init (EekKeyboardClass *klass)
 | 
				
			||||||
    level_keyboard_init(keyboard);
 | 
					{
 | 
				
			||||||
    for (uint i = 0; i < 4; i++) {
 | 
					    EekContainerClass *container_class = EEK_CONTAINER_CLASS (klass);
 | 
				
			||||||
        keyboard->views[i] = views[i];
 | 
					    GObjectClass      *gobject_class = G_OBJECT_CLASS (klass);
 | 
				
			||||||
    }
 | 
					    GParamSpec        *pspec;
 | 
				
			||||||
    keyboard->manager = manager;
 | 
					
 | 
				
			||||||
    keyboard->names = name_button_hash;
 | 
					    g_type_class_add_private (gobject_class,
 | 
				
			||||||
    return keyboard;
 | 
					                              sizeof (EekKeyboardPrivate));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    klass->create_section = eek_keyboard_real_create_section;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* signals */
 | 
				
			||||||
 | 
					    container_class->child_added = eek_keyboard_real_child_added;
 | 
				
			||||||
 | 
					    container_class->child_removed = eek_keyboard_real_child_removed;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    gobject_class->get_property = eek_keyboard_get_property;
 | 
				
			||||||
 | 
					    gobject_class->set_property = eek_keyboard_set_property;
 | 
				
			||||||
 | 
					    gobject_class->dispose = eek_keyboard_dispose;
 | 
				
			||||||
 | 
					    gobject_class->finalize = eek_keyboard_finalize;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * EekKeyboard:layout:
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * The layout used to create this #EekKeyboard.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    pspec = g_param_spec_object ("layout",
 | 
				
			||||||
 | 
					                                 "Layout",
 | 
				
			||||||
 | 
					                                 "Layout used to create the keyboard",
 | 
				
			||||||
 | 
					                                 EEK_TYPE_LAYOUT,
 | 
				
			||||||
 | 
					                                 G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE);
 | 
				
			||||||
 | 
					    g_object_class_install_property (gobject_class,
 | 
				
			||||||
 | 
					                                     PROP_LAYOUT,
 | 
				
			||||||
 | 
					                                     pspec);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * EekKeyboard:modifier-behavior:
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * The modifier handling mode of #EekKeyboard.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    pspec = g_param_spec_enum ("modifier-behavior",
 | 
				
			||||||
 | 
					                               "Modifier behavior",
 | 
				
			||||||
 | 
					                               "Modifier handling mode of the keyboard",
 | 
				
			||||||
 | 
					                               EEK_TYPE_MODIFIER_BEHAVIOR,
 | 
				
			||||||
 | 
					                               EEK_MODIFIER_BEHAVIOR_NONE,
 | 
				
			||||||
 | 
					                               G_PARAM_READWRITE);
 | 
				
			||||||
 | 
					    g_object_class_install_property (gobject_class,
 | 
				
			||||||
 | 
					                                     PROP_MODIFIER_BEHAVIOR,
 | 
				
			||||||
 | 
					                                     pspec);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * EekKeyboard::key-locked:
 | 
				
			||||||
 | 
					     * @keyboard: an #EekKeyboard
 | 
				
			||||||
 | 
					     * @key: an #EekKey
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * The ::key-locked signal is emitted each time a key in @keyboard
 | 
				
			||||||
 | 
					     * is shifted to the locked state.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    signals[KEY_LOCKED] =
 | 
				
			||||||
 | 
					        g_signal_new (I_("key-locked"),
 | 
				
			||||||
 | 
					                      G_TYPE_FROM_CLASS(gobject_class),
 | 
				
			||||||
 | 
					                      G_SIGNAL_RUN_LAST,
 | 
				
			||||||
 | 
					                      G_STRUCT_OFFSET(EekKeyboardClass, key_locked),
 | 
				
			||||||
 | 
					                      NULL,
 | 
				
			||||||
 | 
					                      NULL,
 | 
				
			||||||
 | 
					                      g_cclosure_marshal_VOID__OBJECT,
 | 
				
			||||||
 | 
					                      G_TYPE_NONE,
 | 
				
			||||||
 | 
					                      1,
 | 
				
			||||||
 | 
					                      EEK_TYPE_KEY);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * EekKeyboard::key-unlocked:
 | 
				
			||||||
 | 
					     * @keyboard: an #EekKeyboard
 | 
				
			||||||
 | 
					     * @key: an #EekKey
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * The ::key-unlocked signal is emitted each time a key in @keyboard
 | 
				
			||||||
 | 
					     * is shifted to the unlocked state.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    signals[KEY_UNLOCKED] =
 | 
				
			||||||
 | 
					        g_signal_new (I_("key-unlocked"),
 | 
				
			||||||
 | 
					                      G_TYPE_FROM_CLASS(gobject_class),
 | 
				
			||||||
 | 
					                      G_SIGNAL_RUN_LAST,
 | 
				
			||||||
 | 
					                      G_STRUCT_OFFSET(EekKeyboardClass, key_unlocked),
 | 
				
			||||||
 | 
					                      NULL,
 | 
				
			||||||
 | 
					                      NULL,
 | 
				
			||||||
 | 
					                      g_cclosure_marshal_VOID__OBJECT,
 | 
				
			||||||
 | 
					                      G_TYPE_NONE,
 | 
				
			||||||
 | 
					                      1,
 | 
				
			||||||
 | 
					                      EEK_TYPE_KEY);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					eek_keyboard_init (EekKeyboard *self)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    self->priv = EEK_KEYBOARD_GET_PRIVATE(self);
 | 
				
			||||||
 | 
					    self->priv->modifier_behavior = EEK_MODIFIER_BEHAVIOR_NONE;
 | 
				
			||||||
 | 
					    self->priv->outline_array = g_array_new (FALSE, TRUE, sizeof (EekOutline));
 | 
				
			||||||
 | 
					    self->priv->keycodes = g_hash_table_new (g_direct_hash, g_direct_equal);
 | 
				
			||||||
 | 
					    eek_element_set_symbol_index (EEK_ELEMENT(self), 0, 0);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * eek_keyboard_find_key_by_name:
 | 
					 * eek_keyboard_create_section:
 | 
				
			||||||
 * @keyboard: an #EekKeyboard
 | 
					 * @keyboard: an #EekKeyboard
 | 
				
			||||||
 * @name: a key name
 | 
					 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * Find an #EekKey whose name is @name.
 | 
					 * Create an #EekSection instance and append it to @keyboard.  This
 | 
				
			||||||
 * Return value: (transfer none): #EekKey whose name is @name
 | 
					 * function is rarely called by application but called by #EekLayout
 | 
				
			||||||
 | 
					 * implementation.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
struct squeek_button*
 | 
					EekSection *
 | 
				
			||||||
eek_keyboard_find_button_by_name (LevelKeyboard *keyboard,
 | 
					eek_keyboard_create_section (EekKeyboard *keyboard)
 | 
				
			||||||
                               const gchar *name)
 | 
					 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    return g_hash_table_lookup (keyboard->names, name);
 | 
					    g_return_val_if_fail (EEK_IS_KEYBOARD(keyboard), NULL);
 | 
				
			||||||
 | 
					    return EEK_KEYBOARD_GET_CLASS(keyboard)->create_section (keyboard);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * eek_keyboard_find_key_by_keycode:
 | 
				
			||||||
 | 
					 * @keyboard: an #EekKeyboard
 | 
				
			||||||
 | 
					 * @keycode: a keycode
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Find an #EekKey whose keycode is @keycode.
 | 
				
			||||||
 | 
					 * Return value: (transfer none): #EekKey whose keycode is @keycode
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					EekKey *
 | 
				
			||||||
 | 
					eek_keyboard_find_key_by_keycode (EekKeyboard *keyboard,
 | 
				
			||||||
 | 
					                                  guint        keycode)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    g_return_val_if_fail (EEK_IS_KEYBOARD(keyboard), NULL);
 | 
				
			||||||
 | 
					    return g_hash_table_lookup (keyboard->priv->keycodes,
 | 
				
			||||||
 | 
					                                GUINT_TO_POINTER(keycode));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * eek_keyboard_get_layout:
 | 
				
			||||||
 | 
					 * @keyboard: an #EekKeyboard
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Get the layout used to create @keyboard.
 | 
				
			||||||
 | 
					 * Returns: an #EekLayout
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					EekLayout *
 | 
				
			||||||
 | 
					eek_keyboard_get_layout (EekKeyboard *keyboard)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    g_return_val_if_fail (EEK_IS_KEYBOARD(keyboard), NULL);
 | 
				
			||||||
 | 
					    return keyboard->priv->layout;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * eek_keyboard_get_size:
 | 
				
			||||||
 | 
					 * @keyboard: an #EekKeyboard
 | 
				
			||||||
 | 
					 * @width: width of @keyboard
 | 
				
			||||||
 | 
					 * @height: height of @keyboard
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Get the size of @keyboard.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					eek_keyboard_get_size (EekKeyboard *keyboard,
 | 
				
			||||||
 | 
					                       gdouble     *width,
 | 
				
			||||||
 | 
					                       gdouble     *height)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    EekBounds bounds;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    eek_element_get_bounds (EEK_ELEMENT(keyboard), &bounds);
 | 
				
			||||||
 | 
					    *width = bounds.width;
 | 
				
			||||||
 | 
					    *height = bounds.height;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * eek_keyboard_set_modifier_behavior:
 | 
				
			||||||
 | 
					 * @keyboard: an #EekKeyboard
 | 
				
			||||||
 | 
					 * @modifier_behavior: modifier behavior of @keyboard
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Set the modifier handling mode of @keyboard.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					eek_keyboard_set_modifier_behavior (EekKeyboard        *keyboard,
 | 
				
			||||||
 | 
					                                    EekModifierBehavior modifier_behavior)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    g_return_if_fail (EEK_IS_KEYBOARD(keyboard));
 | 
				
			||||||
 | 
					    keyboard->priv->modifier_behavior = modifier_behavior;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * eek_keyboard_get_modifier_behavior:
 | 
				
			||||||
 | 
					 * @keyboard: an #EekKeyboard
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Get the modifier handling mode of @keyboard.
 | 
				
			||||||
 | 
					 * Returns: #EekModifierBehavior
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					EekModifierBehavior
 | 
				
			||||||
 | 
					eek_keyboard_get_modifier_behavior (EekKeyboard *keyboard)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    g_return_val_if_fail (EEK_IS_KEYBOARD(keyboard), 0);
 | 
				
			||||||
 | 
					    return keyboard->priv->modifier_behavior;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					eek_keyboard_set_modifiers (EekKeyboard    *keyboard,
 | 
				
			||||||
 | 
					                            EekModifierType modifiers)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    g_return_if_fail (EEK_IS_KEYBOARD(keyboard));
 | 
				
			||||||
 | 
					    keyboard->priv->modifiers = modifiers;
 | 
				
			||||||
 | 
					    set_level_from_modifiers (keyboard);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * eek_keyboard_get_modifiers:
 | 
				
			||||||
 | 
					 * @keyboard: an #EekKeyboard
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Get the current modifier status of @keyboard.
 | 
				
			||||||
 | 
					 * Returns: #EekModifierType
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					EekModifierType
 | 
				
			||||||
 | 
					eek_keyboard_get_modifiers (EekKeyboard *keyboard)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    g_return_val_if_fail (EEK_IS_KEYBOARD(keyboard), 0);
 | 
				
			||||||
 | 
					    return keyboard->priv->modifiers;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * eek_keyboard_add_outline:
 | 
				
			||||||
 | 
					 * @keyboard: an #EekKeyboard
 | 
				
			||||||
 | 
					 * @outline: an #EekOutline
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Register an outline of @keyboard.
 | 
				
			||||||
 | 
					 * Returns: an unsigned integer ID of the registered outline, for
 | 
				
			||||||
 | 
					 * later reference
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					guint
 | 
				
			||||||
 | 
					eek_keyboard_add_outline (EekKeyboard *keyboard,
 | 
				
			||||||
 | 
					                          EekOutline  *outline)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    EekOutline *_outline;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    g_return_val_if_fail (EEK_IS_KEYBOARD(keyboard), 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    _outline = eek_outline_copy (outline);
 | 
				
			||||||
 | 
					    g_array_append_val (keyboard->priv->outline_array, *_outline);
 | 
				
			||||||
 | 
					    /* don't use eek_outline_free here, so as to keep _outline->points */
 | 
				
			||||||
 | 
					    g_slice_free (EekOutline, _outline);
 | 
				
			||||||
 | 
					    return keyboard->priv->outline_array->len - 1;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
@ -214,76 +635,115 @@ eek_keyboard_find_button_by_name (LevelKeyboard *keyboard,
 | 
				
			|||||||
 * Returns: an #EekOutline, which should not be released
 | 
					 * Returns: an #EekOutline, which should not be released
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
EekOutline *
 | 
					EekOutline *
 | 
				
			||||||
level_keyboard_get_outline (LevelKeyboard *keyboard,
 | 
					eek_keyboard_get_outline (EekKeyboard *keyboard,
 | 
				
			||||||
                          guint        oref)
 | 
					                          guint        oref)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    if (oref > keyboard->outline_array->len)
 | 
					    g_return_val_if_fail (EEK_IS_KEYBOARD(keyboard), NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (oref > keyboard->priv->outline_array->len)
 | 
				
			||||||
        return NULL;
 | 
					        return NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return &g_array_index (keyboard->outline_array, EekOutline, oref);
 | 
					    return &g_array_index (keyboard->priv->outline_array, EekOutline, oref);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * eek_keyboard_get_keymap:
 | 
					 * eek_keyboard_get_n_outlines:
 | 
				
			||||||
 * @keyboard: an #EekKeyboard
 | 
					 * @keyboard: an #EekKeyboard
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * Get the keymap for the keyboard.
 | 
					 * Get the number of outlines defined in @keyboard.
 | 
				
			||||||
 * Returns: a string containing the XKB keymap.
 | 
					 * Returns: integer
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
gchar *
 | 
					gsize
 | 
				
			||||||
eek_keyboard_get_keymap(LevelKeyboard *keyboard)
 | 
					eek_keyboard_get_n_outlines (EekKeyboard *keyboard)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    /* Start the keycodes and symbols sections with their respective headers. */
 | 
					    g_return_val_if_fail (EEK_IS_KEYBOARD(keyboard), 0);
 | 
				
			||||||
    gchar *keycodes = g_strdup(keymap_keycodes_header);
 | 
					    return keyboard->priv->outline_array->len;
 | 
				
			||||||
    gchar *symbols = g_strdup(keymap_symbols_header);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /* Iterate over the keys in the name-to-key hash table. */
 | 
					 | 
				
			||||||
    GHashTableIter iter;
 | 
					 | 
				
			||||||
    gchar *button_name;
 | 
					 | 
				
			||||||
    gpointer button_ptr;
 | 
					 | 
				
			||||||
    g_hash_table_iter_init(&iter, keyboard->names);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    while (g_hash_table_iter_next(&iter, (gpointer)&button_name, &button_ptr)) {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        gchar *current, *line;
 | 
					 | 
				
			||||||
        struct squeek_button *button = button_ptr;
 | 
					 | 
				
			||||||
        struct squeek_key *key = squeek_button_get_key(button);
 | 
					 | 
				
			||||||
        guint keycode = squeek_key_get_keycode(key);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        /* Don't include invalid keycodes in the keymap. */
 | 
					 | 
				
			||||||
        if (keycode == EEK_INVALID_KEYCODE)
 | 
					 | 
				
			||||||
            continue;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        /* Append a key name-to-keycode definition to the keycodes section. */
 | 
					 | 
				
			||||||
        current = keycodes;
 | 
					 | 
				
			||||||
        line = g_strdup_printf("        <%s> = %i;\n", (char *)button_name, keycode);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        keycodes = g_strconcat(current, line, NULL);
 | 
					 | 
				
			||||||
        g_free(line);
 | 
					 | 
				
			||||||
        g_free(current);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        // FIXME: free
 | 
					 | 
				
			||||||
        const char *key_str = squeek_key_to_keymap_entry(
 | 
					 | 
				
			||||||
            (char*)button_name,
 | 
					 | 
				
			||||||
            key
 | 
					 | 
				
			||||||
        );
 | 
					 | 
				
			||||||
        current = symbols;
 | 
					 | 
				
			||||||
        symbols = g_strconcat(current, key_str, NULL);
 | 
					 | 
				
			||||||
        g_free(current);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /* Assemble the keymap file from the header, sections and footer. */
 | 
					 | 
				
			||||||
    gchar *keymap = g_strconcat(keymap_header,
 | 
					 | 
				
			||||||
                                keycodes, "    };\n\n",
 | 
					 | 
				
			||||||
                                symbols, "    };\n\n",
 | 
					 | 
				
			||||||
                                keymap_footer, NULL);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    g_free(keycodes);
 | 
					 | 
				
			||||||
    g_free(symbols);
 | 
					 | 
				
			||||||
    return keymap;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct squeek_view *level_keyboard_current(LevelKeyboard *keyboard)
 | 
					/**
 | 
				
			||||||
 | 
					 * eek_keyboard_set_num_lock_mask:
 | 
				
			||||||
 | 
					 * @keyboard: an #EekKeyboard
 | 
				
			||||||
 | 
					 * @num_lock_mask: an #EekModifierType
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Set modifier mask used as Num_Lock.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					eek_keyboard_set_num_lock_mask (EekKeyboard    *keyboard,
 | 
				
			||||||
 | 
					                                EekModifierType num_lock_mask)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    return keyboard->views[keyboard->level];
 | 
					    g_return_if_fail (EEK_IS_KEYBOARD(keyboard));
 | 
				
			||||||
 | 
					    keyboard->priv->num_lock_mask = num_lock_mask;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * eek_keyboard_get_num_lock_mask:
 | 
				
			||||||
 | 
					 * @keyboard: an #EekKeyboard
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Get modifier mask used as Num_Lock.
 | 
				
			||||||
 | 
					 * Returns: an #EekModifierType
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					EekModifierType
 | 
				
			||||||
 | 
					eek_keyboard_get_num_lock_mask (EekKeyboard *keyboard)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    g_return_val_if_fail (EEK_IS_KEYBOARD(keyboard), 0);
 | 
				
			||||||
 | 
					    return keyboard->priv->num_lock_mask;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * eek_keyboard_set_alt_gr_mask:
 | 
				
			||||||
 | 
					 * @keyboard: an #EekKeyboard
 | 
				
			||||||
 | 
					 * @alt_gr_mask: an #EekModifierType
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Set modifier mask used as Alt_Gr.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					eek_keyboard_set_alt_gr_mask (EekKeyboard    *keyboard,
 | 
				
			||||||
 | 
					                              EekModifierType alt_gr_mask)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    g_return_if_fail (EEK_IS_KEYBOARD(keyboard));
 | 
				
			||||||
 | 
					    keyboard->priv->alt_gr_mask = alt_gr_mask;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * eek_keyboard_get_alt_gr_mask:
 | 
				
			||||||
 | 
					 * @keyboard: an #EekKeyboard
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Get modifier mask used as Alt_Gr.
 | 
				
			||||||
 | 
					 * Returns: an #EekModifierType
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					EekModifierType
 | 
				
			||||||
 | 
					eek_keyboard_get_alt_gr_mask (EekKeyboard *keyboard)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    g_return_val_if_fail (EEK_IS_KEYBOARD(keyboard), 0);
 | 
				
			||||||
 | 
					    return keyboard->priv->alt_gr_mask;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * eek_keyboard_get_pressed_keys:
 | 
				
			||||||
 | 
					 * @keyboard: an #EekKeyboard
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Get pressed keys.
 | 
				
			||||||
 | 
					 * Returns: (transfer container) (element-type EekKey): A list of
 | 
				
			||||||
 | 
					 * pressed keys.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					GList *
 | 
				
			||||||
 | 
					eek_keyboard_get_pressed_keys (EekKeyboard *keyboard)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    g_return_val_if_fail (EEK_IS_KEYBOARD(keyboard), NULL);
 | 
				
			||||||
 | 
					    return g_list_copy (keyboard->priv->pressed_keys);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * eek_keyboard_get_locked_keys:
 | 
				
			||||||
 | 
					 * @keyboard: an #EekKeyboard
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Get locked keys.
 | 
				
			||||||
 | 
					 * Returns: (transfer container) (element-type Eek.ModifierKey): A list
 | 
				
			||||||
 | 
					 * of locked keys.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					GList *
 | 
				
			||||||
 | 
					eek_keyboard_get_locked_keys (EekKeyboard *keyboard)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    g_return_val_if_fail (EEK_IS_KEYBOARD(keyboard), NULL);
 | 
				
			||||||
 | 
					    return g_list_copy (keyboard->priv->locked_keys);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -27,67 +27,172 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#include <glib-object.h>
 | 
					#include <glib-object.h>
 | 
				
			||||||
#include <xkbcommon/xkbcommon.h>
 | 
					#include <xkbcommon/xkbcommon.h>
 | 
				
			||||||
 | 
					#include "eek-container.h"
 | 
				
			||||||
#include "eek-types.h"
 | 
					#include "eek-types.h"
 | 
				
			||||||
#include "eek-layout.h"
 | 
					#include "eek-layout.h"
 | 
				
			||||||
#include "src/layout.h"
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
G_BEGIN_DECLS
 | 
					G_BEGIN_DECLS
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct _EekModifierKey {
 | 
					#define EEK_TYPE_KEYBOARD (eek_keyboard_get_type())
 | 
				
			||||||
    /*< public >*/
 | 
					#define EEK_KEYBOARD(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EEK_TYPE_KEYBOARD, EekKeyboard))
 | 
				
			||||||
    EekModifierType modifiers;
 | 
					#define EEK_KEYBOARD_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EEK_TYPE_KEYBOARD, EekKeyboardClass))
 | 
				
			||||||
    struct squeek_button *button;
 | 
					#define EEK_IS_KEYBOARD(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EEK_TYPE_KEYBOARD))
 | 
				
			||||||
};
 | 
					#define EEK_IS_KEYBOARD_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EEK_TYPE_KEYBOARD))
 | 
				
			||||||
typedef struct _EekModifierKey EekModifierKey;
 | 
					#define EEK_KEYBOARD_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EEK_TYPE_KEYBOARD, EekKeyboardClass))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// Keyboard state holder
 | 
					typedef struct _EekKeyboardClass EekKeyboardClass;
 | 
				
			||||||
struct _LevelKeyboard {
 | 
					typedef struct _EekKeyboardPrivate EekKeyboardPrivate;
 | 
				
			||||||
    struct squeek_view *views[4];
 | 
					
 | 
				
			||||||
    guint level;
 | 
					/**
 | 
				
			||||||
 | 
					 * EekKeyboard:
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Contains the state of the physical keyboard.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Is also a graphical element...
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * The #EekKeyboard structure contains only private data and should
 | 
				
			||||||
 | 
					 * only be accessed using the provided API.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					struct _EekKeyboard
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    /*< private >*/
 | 
				
			||||||
 | 
					    EekContainer parent;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    EekKeyboardPrivate *priv;
 | 
				
			||||||
    struct xkb_keymap *keymap;
 | 
					    struct xkb_keymap *keymap;
 | 
				
			||||||
    int keymap_fd; // keymap formatted as XKB string
 | 
					    int keymap_fd; // keymap formatted as XKB string
 | 
				
			||||||
    size_t keymap_len; // length of the data inside keymap_fd
 | 
					    size_t keymap_len; // length of the data inside keymap_fd
 | 
				
			||||||
    GArray *outline_array;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    GList *pressed_buttons; // struct squeek_button*
 | 
					 | 
				
			||||||
    GList *locked_buttons; // struct squeek_button*
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /* Map button names to button objects: */
 | 
					 | 
				
			||||||
    GHashTable *names;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    guint id; // as a key to layout choices
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    EekboardContextService *manager; // unowned reference
 | 
					    EekboardContextService *manager; // unowned reference
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
typedef struct _LevelKeyboard LevelKeyboard;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct squeek_button *eek_keyboard_find_button_by_name(LevelKeyboard *keyboard,
 | 
					/**
 | 
				
			||||||
                                      const gchar        *name);
 | 
					 * EekKeyboardClass:
 | 
				
			||||||
 | 
					 * @create_section: virtual function for creating a section
 | 
				
			||||||
 | 
					 * @find_key_by_keycode: virtual function for finding a key in the
 | 
				
			||||||
 | 
					 * keyboard by keycode
 | 
				
			||||||
 | 
					 * @key_pressed: class handler for #EekKeyboard::key-pressed signal
 | 
				
			||||||
 | 
					 * @key_released: class handler for #EekKeyboard::key-released signal
 | 
				
			||||||
 | 
					 * @key_locked: class handler for #EekKeyboard::key-locked signal
 | 
				
			||||||
 | 
					 * @key_unlocked: class handler for #EekKeyboard::key-unlocked signal
 | 
				
			||||||
 | 
					 * @key_cancelled: class handler for #EekKeyboard::key-cancelled signal
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					struct _EekKeyboardClass
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    /*< private >*/
 | 
				
			||||||
 | 
					    EekContainerClass parent_class;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// Represents the path to the button within a view
 | 
					    /* obsolete members moved to EekElement */
 | 
				
			||||||
struct button_place {
 | 
					    gpointer set_symbol_index;
 | 
				
			||||||
    const struct squeek_row *row;
 | 
					    gpointer get_symbol_index;
 | 
				
			||||||
    const struct squeek_button *button;
 | 
					
 | 
				
			||||||
 | 
					    /*< public >*/
 | 
				
			||||||
 | 
					    EekSection *(* create_section)      (EekKeyboard *self);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    EekKey     *(* find_key_by_keycode) (EekKeyboard *self,
 | 
				
			||||||
 | 
					                                         guint        keycode);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /*< private >*/
 | 
				
			||||||
 | 
					    /* obsolete members moved to EekElement */
 | 
				
			||||||
 | 
					    gpointer symbol_index_changed;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /*< public >*/
 | 
				
			||||||
 | 
					    /* signals */
 | 
				
			||||||
 | 
					    void        (* key_locked)          (EekKeyboard *self,
 | 
				
			||||||
 | 
					                                         EekKey      *key);
 | 
				
			||||||
 | 
					    void        (* key_unlocked)        (EekKeyboard *self,
 | 
				
			||||||
 | 
					                                         EekKey      *key);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /*< private >*/
 | 
				
			||||||
 | 
					    /* padding */
 | 
				
			||||||
 | 
					    gpointer pdummy[21];
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
EekOutline         *level_keyboard_get_outline
 | 
					/**
 | 
				
			||||||
                                     (LevelKeyboard        *keyboard,
 | 
					 * EekModifierKey:
 | 
				
			||||||
 | 
					 * @modifiers: an #EekModifierType which @key triggers
 | 
				
			||||||
 | 
					 * @key: an #EekKey
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Entry which associates modifier mask to a key.  This is returned by
 | 
				
			||||||
 | 
					 * eek_keyboard_get_locked_keys().
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					struct _EekModifierKey {
 | 
				
			||||||
 | 
					    /*< public >*/
 | 
				
			||||||
 | 
					    EekModifierType modifiers;
 | 
				
			||||||
 | 
					    EekKey *key;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					typedef struct _EekModifierKey EekModifierKey;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					EekKeyboard        *eek_keyboard_new (EekboardContextService *manager,
 | 
				
			||||||
 | 
					                                      EekLayout          *layout,
 | 
				
			||||||
 | 
					                                      gdouble             initial_width,
 | 
				
			||||||
 | 
					                                      gdouble             initial_height);
 | 
				
			||||||
 | 
					GType               eek_keyboard_get_type
 | 
				
			||||||
 | 
					                                     (void) G_GNUC_CONST;
 | 
				
			||||||
 | 
					EekLayout          *eek_keyboard_get_layout
 | 
				
			||||||
 | 
					                                     (EekKeyboard        *keyboard);
 | 
				
			||||||
 | 
					void                eek_keyboard_get_size
 | 
				
			||||||
 | 
					                                     (EekKeyboard        *keyboard,
 | 
				
			||||||
 | 
					                                      gdouble            *width,
 | 
				
			||||||
 | 
					                                      gdouble            *height);
 | 
				
			||||||
 | 
					void                eek_keyboard_set_size
 | 
				
			||||||
 | 
					                                     (EekKeyboard        *keyboard,
 | 
				
			||||||
 | 
					                                      gdouble             width,
 | 
				
			||||||
 | 
					                                      gdouble             height);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void                eek_keyboard_set_modifier_behavior
 | 
				
			||||||
 | 
					                                     (EekKeyboard        *keyboard,
 | 
				
			||||||
 | 
					                                      EekModifierBehavior modifier_behavior);
 | 
				
			||||||
 | 
					EekModifierBehavior eek_keyboard_get_modifier_behavior
 | 
				
			||||||
 | 
					                                     (EekKeyboard        *keyboard);
 | 
				
			||||||
 | 
					void                eek_keyboard_set_modifiers
 | 
				
			||||||
 | 
					                                     (EekKeyboard        *keyboard,
 | 
				
			||||||
 | 
					                                      EekModifierType     modifiers);
 | 
				
			||||||
 | 
					EekModifierType     eek_keyboard_get_modifiers
 | 
				
			||||||
 | 
					                                     (EekKeyboard        *keyboard);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					EekSection         *eek_keyboard_create_section
 | 
				
			||||||
 | 
					                                     (EekKeyboard        *keyboard);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					EekKey             *eek_keyboard_find_key_by_keycode
 | 
				
			||||||
 | 
					                                     (EekKeyboard        *keyboard,
 | 
				
			||||||
 | 
					                                      guint               keycode);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					guint               eek_keyboard_add_outline
 | 
				
			||||||
 | 
					                                     (EekKeyboard        *keyboard,
 | 
				
			||||||
 | 
					                                      EekOutline         *outline);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					EekOutline         *eek_keyboard_get_outline
 | 
				
			||||||
 | 
					                                     (EekKeyboard        *keyboard,
 | 
				
			||||||
                                      guint               oref);
 | 
					                                      guint               oref);
 | 
				
			||||||
 | 
					gsize               eek_keyboard_get_n_outlines
 | 
				
			||||||
 | 
					                                     (EekKeyboard        *keyboard);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void                eek_keyboard_set_num_lock_mask
 | 
				
			||||||
 | 
					                                     (EekKeyboard        *keyboard,
 | 
				
			||||||
 | 
					                                      EekModifierType     num_lock_mask);
 | 
				
			||||||
 | 
					EekModifierType     eek_keyboard_get_num_lock_mask
 | 
				
			||||||
 | 
					                                     (EekKeyboard        *keyboard);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void                eek_keyboard_set_alt_gr_mask
 | 
				
			||||||
 | 
					                                     (EekKeyboard        *keyboard,
 | 
				
			||||||
 | 
					                                      EekModifierType     alt_gr_mask);
 | 
				
			||||||
 | 
					EekModifierType     eek_keyboard_get_alt_gr_mask
 | 
				
			||||||
 | 
					                                     (EekKeyboard        *keyboard);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					GList              *eek_keyboard_get_pressed_keys
 | 
				
			||||||
 | 
					                                     (EekKeyboard        *keyboard);
 | 
				
			||||||
 | 
					GList              *eek_keyboard_get_locked_keys
 | 
				
			||||||
 | 
					                                     (EekKeyboard        *keyboard);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
EekModifierKey     *eek_modifier_key_copy
 | 
					EekModifierKey     *eek_modifier_key_copy
 | 
				
			||||||
                                     (EekModifierKey     *modkey);
 | 
					                                     (EekModifierKey     *modkey);
 | 
				
			||||||
void                eek_modifier_key_free
 | 
					void                eek_modifier_key_free
 | 
				
			||||||
                                     (EekModifierKey      *modkey);
 | 
					                                     (EekModifierKey      *modkey);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void eek_keyboard_press_button(LevelKeyboard *keyboard, struct squeek_button *button, guint32 timestamp);
 | 
					void eek_keyboard_press_key(EekKeyboard *keyboard, EekKey *key, guint32 timestamp);
 | 
				
			||||||
void eek_keyboard_release_button(LevelKeyboard *keyboard, struct squeek_button *button, guint32 timestamp);
 | 
					void eek_keyboard_release_key(EekKeyboard *keyboard, EekKey *key, guint32 timestamp);
 | 
				
			||||||
 | 
					 | 
				
			||||||
gchar *             eek_keyboard_get_keymap
 | 
					 | 
				
			||||||
                                     (LevelKeyboard *keyboard);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct squeek_view *level_keyboard_current(LevelKeyboard *keyboard);
 | 
					 | 
				
			||||||
LevelKeyboard *level_keyboard_new(EekboardContextService *manager, struct squeek_view *views[], GHashTable *name_button_hash);
 | 
					 | 
				
			||||||
void level_keyboard_deinit(LevelKeyboard *self);
 | 
					 | 
				
			||||||
void level_keyboard_free(LevelKeyboard *self);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
G_END_DECLS
 | 
					G_END_DECLS
 | 
				
			||||||
#endif  /* EEK_KEYBOARD_H */
 | 
					#endif  /* EEK_KEYBOARD_H */
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										295
									
								
								eek/eek-keysym.c
									
									
									
									
									
								
							
							
						
						@ -23,9 +23,15 @@
 | 
				
			|||||||
 * @short_description: an #EekSymbol represents an X keysym
 | 
					 * @short_description: an #EekSymbol represents an X keysym
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef HAVE_CONFIG_H
 | 
				
			||||||
#include "config.h"
 | 
					#include "config.h"
 | 
				
			||||||
 | 
					#endif  /* HAVE_CONFIG_H */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <string.h>
 | 
				
			||||||
 | 
					#include <stdlib.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "eek-keysym.h"
 | 
					#include "eek-keysym.h"
 | 
				
			||||||
 | 
					#include "eek-serializable.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* modifier keys */
 | 
					/* modifier keys */
 | 
				
			||||||
#define EEK_KEYSYM_Shift_L 0xffe1
 | 
					#define EEK_KEYSYM_Shift_L 0xffe1
 | 
				
			||||||
@ -44,22 +50,301 @@
 | 
				
			|||||||
#define EEK_KEYSYM_Hyper_L 0xffed
 | 
					#define EEK_KEYSYM_Hyper_L 0xffed
 | 
				
			||||||
#define EEK_KEYSYM_Hyper_R 0xffee
 | 
					#define EEK_KEYSYM_Hyper_R 0xffee
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef struct _EekKeysymPrivate
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    guint xkeysym;
 | 
				
			||||||
 | 
					} EekKeysymPrivate;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct _EekKeysymEntry {
 | 
					struct _EekKeysymEntry {
 | 
				
			||||||
    guint xkeysym;
 | 
					    guint xkeysym;
 | 
				
			||||||
    const gchar *name;
 | 
					    const gchar *name;
 | 
				
			||||||
 | 
					    EekSymbolCategory category;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef struct _EekKeysymEntry EekKeysymEntry;
 | 
					typedef struct _EekKeysymEntry EekKeysymEntry;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "eek-special-keysym-entries.h"
 | 
				
			||||||
 | 
					#include "eek-unicode-keysym-entries.h"
 | 
				
			||||||
#include "eek-xkeysym-keysym-entries.h"
 | 
					#include "eek-xkeysym-keysym-entries.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
guint32
 | 
					static void eek_serializable_iface_init (EekSerializableIface *iface);
 | 
				
			||||||
eek_keysym_from_name (const gchar *name)
 | 
					
 | 
				
			||||||
 | 
					G_DEFINE_TYPE_EXTENDED (EekKeysym, eek_keysym, EEK_TYPE_SYMBOL,
 | 
				
			||||||
 | 
								0, /* GTypeFlags */
 | 
				
			||||||
 | 
								G_ADD_PRIVATE (EekKeysym)
 | 
				
			||||||
 | 
					                        G_IMPLEMENT_INTERFACE (EEK_TYPE_SERIALIZABLE,
 | 
				
			||||||
 | 
					                                               eek_serializable_iface_init))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static EekSerializableIface *eek_keysym_parent_serializable_iface;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					eek_keysym_real_serialize (EekSerializable *self,
 | 
				
			||||||
 | 
					                           GVariantBuilder *builder)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    for (uint i = 0; i < G_N_ELEMENTS(xkeysym_keysym_entries); i++) {
 | 
					    EekKeysymPrivate *priv = eek_keysym_get_instance_private (
 | 
				
			||||||
        if (g_strcmp0 (xkeysym_keysym_entries[i].name, name) == 0) {
 | 
							    EEK_KEYSYM(self));
 | 
				
			||||||
            return xkeysym_keysym_entries[i].xkeysym;
 | 
					
 | 
				
			||||||
 | 
					    eek_keysym_parent_serializable_iface->serialize (self, builder);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    g_variant_builder_add (builder, "u", priv->xkeysym);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static gsize
 | 
				
			||||||
 | 
					eek_keysym_real_deserialize (EekSerializable *self,
 | 
				
			||||||
 | 
					                             GVariant        *variant,
 | 
				
			||||||
 | 
					                             gsize            index)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    EekKeysymPrivate *priv = eek_keysym_get_instance_private (
 | 
				
			||||||
 | 
							    EEK_KEYSYM(self));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    index = eek_keysym_parent_serializable_iface->deserialize (self,
 | 
				
			||||||
 | 
					                                                               variant,
 | 
				
			||||||
 | 
					                                                               index);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    g_variant_get_child (variant, index++, "u", &priv->xkeysym);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return index;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					eek_serializable_iface_init (EekSerializableIface *iface)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    eek_keysym_parent_serializable_iface =
 | 
				
			||||||
 | 
					        g_type_interface_peek_parent (iface);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    iface->serialize = eek_keysym_real_serialize;
 | 
				
			||||||
 | 
					    iface->deserialize = eek_keysym_real_deserialize;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static gchar *
 | 
				
			||||||
 | 
					unichar_to_utf8 (gunichar uc)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    if (g_unichar_isgraph (uc)) {
 | 
				
			||||||
 | 
					        gchar *buf;
 | 
				
			||||||
 | 
					        gint len;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        len = g_unichar_to_utf8 (uc, NULL);
 | 
				
			||||||
 | 
					        buf = g_malloc0 (len + 1);
 | 
				
			||||||
 | 
					        g_unichar_to_utf8 (uc, buf);
 | 
				
			||||||
 | 
					        return buf;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					    return g_strdup ("");
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int
 | 
				
			||||||
 | 
					keysym_entry_compare_by_xkeysym (const void *key0, const void *key1)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    const EekKeysymEntry *entry0 = key0, *entry1 = key1;
 | 
				
			||||||
 | 
					    return (gint) (entry0->xkeysym - entry1->xkeysym);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static EekKeysymEntry *
 | 
				
			||||||
 | 
					find_keysym_entry_by_xkeysym (guint xkeysym,
 | 
				
			||||||
 | 
					                              const EekKeysymEntry *entries,
 | 
				
			||||||
 | 
					                              gint num_entries)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    EekKeysymEntry key;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    key.xkeysym = xkeysym;
 | 
				
			||||||
 | 
					    return bsearch (&key, entries, num_entries, sizeof (EekKeysymEntry),
 | 
				
			||||||
 | 
					                    keysym_entry_compare_by_xkeysym);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static gboolean
 | 
				
			||||||
 | 
					get_unichar (guint xkeysym, gunichar *uc) {
 | 
				
			||||||
 | 
					    /* Check for Latin-1 characters (1:1 mapping) */
 | 
				
			||||||
 | 
					    if ((xkeysym >= 0x0020 && xkeysym <= 0x007e) ||
 | 
				
			||||||
 | 
					        (xkeysym >= 0x00a0 && xkeysym <= 0x00ff)) {
 | 
				
			||||||
 | 
					        *uc = xkeysym;
 | 
				
			||||||
 | 
					        return TRUE;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* Also check for directly encoded 24-bit UCS characters:
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    if ((xkeysym & 0xff000000) == 0x01000000) {
 | 
				
			||||||
 | 
					        *uc = xkeysym & 0x00ffffff;
 | 
				
			||||||
 | 
					        return TRUE;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return FALSE;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					G_INLINE_FUNC EekModifierType
 | 
				
			||||||
 | 
					get_modifier_mask (guint xkeysym)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    switch (xkeysym) {
 | 
				
			||||||
 | 
					    case EEK_KEYSYM_Shift_L:
 | 
				
			||||||
 | 
					    case EEK_KEYSYM_Shift_R:
 | 
				
			||||||
 | 
					    case EEK_KEYSYM_Caps_Lock:
 | 
				
			||||||
 | 
					    case EEK_KEYSYM_Shift_Lock:
 | 
				
			||||||
 | 
					        return EEK_SHIFT_MASK;
 | 
				
			||||||
 | 
					    case EEK_KEYSYM_ISO_Level3_Shift:
 | 
				
			||||||
 | 
					        return EEK_BUTTON1_MASK;
 | 
				
			||||||
 | 
					    case EEK_KEYSYM_Control_L:
 | 
				
			||||||
 | 
					    case EEK_KEYSYM_Control_R:
 | 
				
			||||||
 | 
					        return EEK_CONTROL_MASK;
 | 
				
			||||||
 | 
					    case EEK_KEYSYM_Alt_L:
 | 
				
			||||||
 | 
					    case EEK_KEYSYM_Alt_R:
 | 
				
			||||||
 | 
					        return EEK_MOD1_MASK;
 | 
				
			||||||
 | 
					    case EEK_KEYSYM_Meta_L:
 | 
				
			||||||
 | 
					    case EEK_KEYSYM_Meta_R:
 | 
				
			||||||
 | 
					        return EEK_META_MASK;
 | 
				
			||||||
 | 
					    case EEK_KEYSYM_Super_L:
 | 
				
			||||||
 | 
					    case EEK_KEYSYM_Super_R:
 | 
				
			||||||
 | 
					        return EEK_SUPER_MASK;
 | 
				
			||||||
 | 
					    case EEK_KEYSYM_Hyper_L:
 | 
				
			||||||
 | 
					    case EEK_KEYSYM_Hyper_R:
 | 
				
			||||||
 | 
					        return EEK_HYPER_MASK;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    return 0;
 | 
					    return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					eek_keysym_class_init (EekKeysymClass *klass)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    /* void */
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					eek_keysym_init (EekKeysym *self)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    /* void */
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * eek_keysym_new_with_modifier:
 | 
				
			||||||
 | 
					 * @xkeysym: an X keysym value
 | 
				
			||||||
 | 
					 * @modifier_mask: modifier assigned to @xkeysym
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Create an #EekKeysym with given X keysym value @xkeysym and
 | 
				
			||||||
 | 
					 * modifier @modifier_mask.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					EekKeysym *
 | 
				
			||||||
 | 
					eek_keysym_new_with_modifier (guint           xkeysym,
 | 
				
			||||||
 | 
					                              EekModifierType modifier_mask)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    EekKeysym *keysym;
 | 
				
			||||||
 | 
					    EekKeysymPrivate *priv;
 | 
				
			||||||
 | 
					    EekKeysymEntry *special_entry, *xkeysym_entry, *unicode_entry,
 | 
				
			||||||
 | 
					        *unichar_entry;
 | 
				
			||||||
 | 
					    gchar *name, *label;
 | 
				
			||||||
 | 
					    EekSymbolCategory category;
 | 
				
			||||||
 | 
					    gunichar uc;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    special_entry =
 | 
				
			||||||
 | 
					        find_keysym_entry_by_xkeysym (xkeysym,
 | 
				
			||||||
 | 
					                                      special_keysym_entries,
 | 
				
			||||||
 | 
					                                      G_N_ELEMENTS(special_keysym_entries));
 | 
				
			||||||
 | 
					    xkeysym_entry =
 | 
				
			||||||
 | 
					        find_keysym_entry_by_xkeysym (xkeysym,
 | 
				
			||||||
 | 
					                                      xkeysym_keysym_entries,
 | 
				
			||||||
 | 
					                                      G_N_ELEMENTS(xkeysym_keysym_entries));
 | 
				
			||||||
 | 
					    unicode_entry =
 | 
				
			||||||
 | 
					        find_keysym_entry_by_xkeysym (xkeysym,
 | 
				
			||||||
 | 
					                                      unicode_keysym_entries,
 | 
				
			||||||
 | 
					                                      G_N_ELEMENTS(unicode_keysym_entries));
 | 
				
			||||||
 | 
					    unichar_entry = NULL;
 | 
				
			||||||
 | 
					    if (get_unichar (xkeysym, &uc)) {
 | 
				
			||||||
 | 
					        unichar_entry = g_slice_new (EekKeysymEntry);
 | 
				
			||||||
 | 
					        unichar_entry->xkeysym = xkeysym;
 | 
				
			||||||
 | 
					        unichar_entry->name = unichar_to_utf8 (uc);
 | 
				
			||||||
 | 
					        unichar_entry->category = EEK_SYMBOL_CATEGORY_LETTER;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* name and category */
 | 
				
			||||||
 | 
					    name = NULL;
 | 
				
			||||||
 | 
					    if (xkeysym_entry) {
 | 
				
			||||||
 | 
					        name = g_strdup (xkeysym_entry->name);
 | 
				
			||||||
 | 
					        category = xkeysym_entry->category;
 | 
				
			||||||
 | 
					    } else if (unichar_entry) {
 | 
				
			||||||
 | 
					        name = g_strdup (unichar_entry->name);
 | 
				
			||||||
 | 
					        category = unichar_entry->category;
 | 
				
			||||||
 | 
					    } else if (unicode_entry) {
 | 
				
			||||||
 | 
					        name = g_strdup (unicode_entry->name);
 | 
				
			||||||
 | 
					        category = unicode_entry->category;
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					        name = g_strdup ("");
 | 
				
			||||||
 | 
					        category = EEK_SYMBOL_CATEGORY_UNKNOWN;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* label */
 | 
				
			||||||
 | 
					    if (special_entry)
 | 
				
			||||||
 | 
					        label = g_strdup (special_entry->name);
 | 
				
			||||||
 | 
					    else if (unichar_entry)
 | 
				
			||||||
 | 
					        label = g_strdup (unichar_entry->name);
 | 
				
			||||||
 | 
					    else if (unicode_entry)
 | 
				
			||||||
 | 
					        label = g_strdup (unicode_entry->name);
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					        label = g_strdup (name);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    keysym = g_object_new (EEK_TYPE_KEYSYM,
 | 
				
			||||||
 | 
					                           "name", name,
 | 
				
			||||||
 | 
					                           "label", label,
 | 
				
			||||||
 | 
					                           "category", category,
 | 
				
			||||||
 | 
					                           "modifier-mask", modifier_mask,
 | 
				
			||||||
 | 
					                           NULL);
 | 
				
			||||||
 | 
					    g_free (name);
 | 
				
			||||||
 | 
					    g_free (label);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (unichar_entry) {
 | 
				
			||||||
 | 
					        g_free ((gpointer) unichar_entry->name);
 | 
				
			||||||
 | 
					        g_slice_free (EekKeysymEntry, unichar_entry);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    priv = eek_keysym_get_instance_private (keysym);
 | 
				
			||||||
 | 
					    priv->xkeysym = xkeysym;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return keysym;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * eek_keysym_new:
 | 
				
			||||||
 | 
					 * @xkeysym: an X keysym value
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Create an #EekKeysym with given X keysym value @xkeysym.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					EekKeysym *
 | 
				
			||||||
 | 
					eek_keysym_new (guint xkeysym)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return eek_keysym_new_with_modifier (xkeysym, get_modifier_mask (xkeysym));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * eek_keysym_new_from_name:
 | 
				
			||||||
 | 
					 * @name: an X keysym name
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Create an #EekKeysym with an X keysym value looked up by @name.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					EekKeysym *
 | 
				
			||||||
 | 
					eek_keysym_new_from_name (const gchar *name)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    gint i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for (i = 0; i < G_N_ELEMENTS(xkeysym_keysym_entries); i++)
 | 
				
			||||||
 | 
					        if (g_strcmp0 (xkeysym_keysym_entries[i].name, name) == 0)
 | 
				
			||||||
 | 
					            return eek_keysym_new (xkeysym_keysym_entries[i].xkeysym);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // g_warning ("can't find keysym entry for %s", name);
 | 
				
			||||||
 | 
					    return g_object_new (EEK_TYPE_KEYSYM,
 | 
				
			||||||
 | 
					                         "name", name,
 | 
				
			||||||
 | 
					                         "label", name,
 | 
				
			||||||
 | 
					                         "category", EEK_SYMBOL_CATEGORY_UNKNOWN,
 | 
				
			||||||
 | 
					                         "modifier-mask", 0,
 | 
				
			||||||
 | 
					                         NULL);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * eek_keysym_get_xkeysym:
 | 
				
			||||||
 | 
					 * @keysym: an #EekKeysym
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Get an X keysym value associated with @keysym
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					guint
 | 
				
			||||||
 | 
					eek_keysym_get_xkeysym (EekKeysym *keysym)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    EekKeysymPrivate *priv;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    g_assert (EEK_IS_KEYSYM(keysym));
 | 
				
			||||||
 | 
					    priv = eek_keysym_get_instance_private (keysym);
 | 
				
			||||||
 | 
					    return priv->xkeysym;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -25,8 +25,34 @@
 | 
				
			|||||||
#ifndef EEK_KEYSYM_H
 | 
					#ifndef EEK_KEYSYM_H
 | 
				
			||||||
#define EEK_KEYSYM_H 1
 | 
					#define EEK_KEYSYM_H 1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "glib.h"
 | 
					#include <X11/XKBlib.h>
 | 
				
			||||||
 | 
					#include "eek-symbol.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
guint32    eek_keysym_from_name         (const gchar    *name);
 | 
					G_BEGIN_DECLS
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * EEK_INVALID_KEYSYM:
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Pseudo keysym used for error reporting.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					#define EEK_INVALID_KEYSYM (0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define EEK_TYPE_KEYSYM (eek_keysym_get_type())
 | 
				
			||||||
 | 
					G_DECLARE_DERIVABLE_TYPE (EekKeysym, eek_keysym, EEK, KEYSYM, EekSymbol)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct _EekKeysymClass {
 | 
				
			||||||
 | 
					    /*< private >*/
 | 
				
			||||||
 | 
					    EekSymbolClass parent_class;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					GType      eek_keysym_get_type          (void) G_GNUC_CONST;
 | 
				
			||||||
 | 
					EekKeysym *eek_keysym_new               (guint           xkeysym);
 | 
				
			||||||
 | 
					guint      eek_keysym_get_xkeysym       (EekKeysym      *keysym);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					EekKeysym *eek_keysym_new_from_name     (const gchar    *name);
 | 
				
			||||||
 | 
					EekKeysym *eek_keysym_new_with_modifier (guint           xkeysym,
 | 
				
			||||||
 | 
					                                         EekModifierType modifier_mask);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					G_END_DECLS
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif  /* EEK_KEYSYM_H */
 | 
					#endif  /* EEK_KEYSYM_H */
 | 
				
			||||||
 | 
				
			|||||||
@ -26,12 +26,13 @@
 | 
				
			|||||||
 * arranges keyboard elements.
 | 
					 * arranges keyboard elements.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef HAVE_CONFIG_H
 | 
				
			||||||
#include "config.h"
 | 
					#include "config.h"
 | 
				
			||||||
 | 
					#endif  /* HAVE_CONFIG_H */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "eek-layout.h"
 | 
					#include "eek-layout.h"
 | 
				
			||||||
#include "eek-keyboard.h"
 | 
					#include "eek-keyboard.h"
 | 
				
			||||||
#include "eekboard/eekboard-context-service.h"
 | 
					#include "eekboard/eekboard-context-service.h"
 | 
				
			||||||
#include "eek-xml-layout.h"
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
G_DEFINE_ABSTRACT_TYPE (EekLayout, eek_layout, G_TYPE_OBJECT)
 | 
					G_DEFINE_ABSTRACT_TYPE (EekLayout, eek_layout, G_TYPE_OBJECT)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -46,8 +47,25 @@ eek_layout_init (EekLayout *self)
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void
 | 
					/**
 | 
				
			||||||
eek_layout_update_layout(LevelKeyboard *keyboard)
 | 
					 * eek_keyboard_new:
 | 
				
			||||||
 | 
					 * @layout: an #EekLayout
 | 
				
			||||||
 | 
					 * @initial_width: initial width of the keyboard
 | 
				
			||||||
 | 
					 * @initial_height: initial height of the keyboard
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Create a new #EekKeyboard based on @layout.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					EekKeyboard *
 | 
				
			||||||
 | 
					eek_keyboard_new (EekboardContextService *manager,
 | 
				
			||||||
 | 
					                  EekLayout *layout,
 | 
				
			||||||
 | 
					                  gdouble    initial_width,
 | 
				
			||||||
 | 
					                  gdouble    initial_height)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    squeek_view_place_contents(level_keyboard_current(keyboard), keyboard);
 | 
					    g_assert (EEK_IS_LAYOUT(layout));
 | 
				
			||||||
 | 
					    g_assert (EEK_LAYOUT_GET_CLASS(layout)->create_keyboard);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return EEK_LAYOUT_GET_CLASS(layout)->create_keyboard (manager,
 | 
				
			||||||
 | 
					                                                          layout,
 | 
				
			||||||
 | 
					                                                          initial_width,
 | 
				
			||||||
 | 
					                                                          initial_height);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -27,7 +27,6 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#include <glib-object.h>
 | 
					#include <glib-object.h>
 | 
				
			||||||
#include "eek-types.h"
 | 
					#include "eek-types.h"
 | 
				
			||||||
#include "src/layout.h"
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
G_BEGIN_DECLS
 | 
					G_BEGIN_DECLS
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -44,7 +43,7 @@ struct _EekLayoutClass
 | 
				
			|||||||
    GObjectClass parent_class;
 | 
					    GObjectClass parent_class;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /*< public >*/
 | 
					    /*< public >*/
 | 
				
			||||||
    LevelKeyboard* (* create_keyboard) (EekboardContextService *manager,
 | 
					    EekKeyboard* (* create_keyboard) (EekboardContextService *manager,
 | 
				
			||||||
                                      EekLayout *self,
 | 
					                                      EekLayout *self,
 | 
				
			||||||
                                      gdouble    initial_width,
 | 
					                                      gdouble    initial_width,
 | 
				
			||||||
                                      gdouble    initial_height);
 | 
					                                      gdouble    initial_height);
 | 
				
			||||||
@ -56,14 +55,5 @@ struct _EekLayoutClass
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
GType        eek_layout_get_type  (void) G_GNUC_CONST;
 | 
					GType        eek_layout_get_type  (void) G_GNUC_CONST;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void         eek_layout_place_rows(LevelKeyboard *keyboard, struct squeek_view *level);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void         eek_layout_update_layout(LevelKeyboard *keyboard);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
LevelKeyboard *
 | 
					 | 
				
			||||||
level_keyboard_from_layout (EekLayout *layout,
 | 
					 | 
				
			||||||
                  gdouble    initial_width,
 | 
					 | 
				
			||||||
                  gdouble    initial_height);
 | 
					 | 
				
			||||||
G_END_DECLS
 | 
					G_END_DECLS
 | 
				
			||||||
#endif  /* EEK_LAYOUT_H */
 | 
					#endif  /* EEK_LAYOUT_H */
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										1
									
								
								eek/eek-marshalers.list
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1 @@
 | 
				
			|||||||
 | 
					VOID:INT,INT
 | 
				
			||||||
							
								
								
									
										1151
									
								
								eek/eek-renderer.c
									
									
									
									
									
								
							
							
						
						@ -21,11 +21,12 @@
 | 
				
			|||||||
#ifndef EEK_RENDERER_H
 | 
					#ifndef EEK_RENDERER_H
 | 
				
			||||||
#define EEK_RENDERER_H 1
 | 
					#define EEK_RENDERER_H 1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <gtk/gtk.h>
 | 
					 | 
				
			||||||
#include <pango/pangocairo.h>
 | 
					#include <pango/pangocairo.h>
 | 
				
			||||||
 | 
					 | 
				
			||||||
#include "eek-keyboard.h"
 | 
					#include "eek-keyboard.h"
 | 
				
			||||||
 | 
					#include "eek-keysym.h"
 | 
				
			||||||
#include "eek-types.h"
 | 
					#include "eek-types.h"
 | 
				
			||||||
 | 
					#include "eek-theme.h"
 | 
				
			||||||
 | 
					#include "eek-theme-context.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
G_BEGIN_DECLS
 | 
					G_BEGIN_DECLS
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -36,9 +37,19 @@ struct _EekRendererClass
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
    GObjectClass parent_class;
 | 
					    GObjectClass parent_class;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    void             (* render_button)         (EekRenderer *self,
 | 
					    void             (* render_key_label)   (EekRenderer *self,
 | 
				
			||||||
 | 
					                                             PangoLayout *layout,
 | 
				
			||||||
 | 
					                                             EekKey      *key);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    void             (* render_key_outline) (EekRenderer *self,
 | 
				
			||||||
                                             cairo_t     *cr,
 | 
					                                             cairo_t     *cr,
 | 
				
			||||||
                                             struct button_place *place,
 | 
					                                             EekKey      *key,
 | 
				
			||||||
 | 
					                                             gdouble      scale,
 | 
				
			||||||
 | 
					                                             gboolean     rotate);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    void             (* render_key)         (EekRenderer *self,
 | 
				
			||||||
 | 
					                                             cairo_t     *cr,
 | 
				
			||||||
 | 
					                                             EekKey      *key,
 | 
				
			||||||
                                             gdouble      scale,
 | 
					                                             gdouble      scale,
 | 
				
			||||||
                                             gboolean     rotate);
 | 
					                                             gboolean     rotate);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -47,8 +58,7 @@ struct _EekRendererClass
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    cairo_surface_t *(* get_icon_surface)   (EekRenderer *self,
 | 
					    cairo_surface_t *(* get_icon_surface)   (EekRenderer *self,
 | 
				
			||||||
                                             const gchar *icon_name,
 | 
					                                             const gchar *icon_name,
 | 
				
			||||||
                                             gint         size,
 | 
					                                             gint         size);
 | 
				
			||||||
                                             gint         scale);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /*< private >*/
 | 
					    /*< private >*/
 | 
				
			||||||
    /* padding */
 | 
					    /* padding */
 | 
				
			||||||
@ -56,9 +66,8 @@ struct _EekRendererClass
 | 
				
			|||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
GType            eek_renderer_get_type         (void) G_GNUC_CONST;
 | 
					GType            eek_renderer_get_type         (void) G_GNUC_CONST;
 | 
				
			||||||
EekRenderer     *eek_renderer_new              (LevelKeyboard     *keyboard,
 | 
					EekRenderer     *eek_renderer_new              (EekKeyboard     *keyboard,
 | 
				
			||||||
                                                PangoContext    *pcontext,
 | 
					                                                PangoContext    *pcontext);
 | 
				
			||||||
                                                GtkStyleContext *scontext);
 | 
					 | 
				
			||||||
void             eek_renderer_set_allocation_size
 | 
					void             eek_renderer_set_allocation_size
 | 
				
			||||||
                                               (EekRenderer     *renderer,
 | 
					                                               (EekRenderer     *renderer,
 | 
				
			||||||
                                                gdouble          width,
 | 
					                                                gdouble          width,
 | 
				
			||||||
@ -66,27 +75,35 @@ void             eek_renderer_set_allocation_size
 | 
				
			|||||||
void             eek_renderer_get_size         (EekRenderer     *renderer,
 | 
					void             eek_renderer_get_size         (EekRenderer     *renderer,
 | 
				
			||||||
                                                gdouble         *width,
 | 
					                                                gdouble         *width,
 | 
				
			||||||
                                                gdouble         *height);
 | 
					                                                gdouble         *height);
 | 
				
			||||||
void             eek_renderer_get_button_bounds   (EekRenderer     *renderer,
 | 
					void             eek_renderer_get_key_bounds   (EekRenderer     *renderer,
 | 
				
			||||||
                                                struct button_place *button,
 | 
					                                                EekKey          *key,
 | 
				
			||||||
                                                EekBounds       *bounds,
 | 
					                                                EekBounds       *bounds,
 | 
				
			||||||
                                                gboolean         rotate);
 | 
					                                                gboolean         rotate);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
gdouble          eek_renderer_get_scale        (EekRenderer     *renderer);
 | 
					gdouble          eek_renderer_get_scale        (EekRenderer     *renderer);
 | 
				
			||||||
void             eek_renderer_set_scale_factor (EekRenderer     *renderer,
 | 
					 | 
				
			||||||
                                                gint             scale);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
PangoLayout     *eek_renderer_create_pango_layout
 | 
					PangoLayout     *eek_renderer_create_pango_layout
 | 
				
			||||||
                                               (EekRenderer     *renderer);
 | 
					                                               (EekRenderer     *renderer);
 | 
				
			||||||
void             eek_renderer_render_button       (EekRenderer     *renderer,
 | 
					void             eek_renderer_render_key_label (EekRenderer     *renderer,
 | 
				
			||||||
 | 
					                                                PangoLayout     *layout,
 | 
				
			||||||
 | 
					                                                EekKey          *key);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void             eek_renderer_render_key_outline
 | 
				
			||||||
 | 
					                                               (EekRenderer     *renderer,
 | 
				
			||||||
                                                cairo_t         *cr,
 | 
					                                                cairo_t         *cr,
 | 
				
			||||||
                                                struct button_place *place,
 | 
					                                                EekKey          *key,
 | 
				
			||||||
 | 
					                                                gdouble          scale,
 | 
				
			||||||
 | 
					                                                gboolean         rotate);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void             eek_renderer_render_key       (EekRenderer     *renderer,
 | 
				
			||||||
 | 
					                                                cairo_t         *cr,
 | 
				
			||||||
 | 
					                                                EekKey          *key,
 | 
				
			||||||
                                                gdouble          scale,
 | 
					                                                gdouble          scale,
 | 
				
			||||||
                                                gboolean         rotate);
 | 
					                                                gboolean         rotate);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
cairo_surface_t *eek_renderer_get_icon_surface (EekRenderer     *renderer,
 | 
					cairo_surface_t *eek_renderer_get_icon_surface (EekRenderer     *renderer,
 | 
				
			||||||
                                                const gchar     *icon_name,
 | 
					                                                const gchar     *icon_name,
 | 
				
			||||||
                                                gint             size,
 | 
					                                                gint             size);
 | 
				
			||||||
                                                gint             scale);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
void             eek_renderer_render_keyboard  (EekRenderer     *renderer,
 | 
					void             eek_renderer_render_keyboard  (EekRenderer     *renderer,
 | 
				
			||||||
                                                cairo_t         *cr);
 | 
					                                                cairo_t         *cr);
 | 
				
			||||||
@ -99,18 +116,33 @@ void             eek_renderer_set_default_background_color
 | 
				
			|||||||
                                                const EekColor  *color);
 | 
					                                                const EekColor  *color);
 | 
				
			||||||
void             eek_renderer_get_foreground_color
 | 
					void             eek_renderer_get_foreground_color
 | 
				
			||||||
                                               (EekRenderer     *renderer,
 | 
					                                               (EekRenderer     *renderer,
 | 
				
			||||||
                                                GtkStyleContext *context,
 | 
					                                                EekElement      *element,
 | 
				
			||||||
                                                EekColor        *color);
 | 
					                                                EekColor        *color);
 | 
				
			||||||
 | 
					void             eek_renderer_get_background_color
 | 
				
			||||||
 | 
					                                               (EekRenderer     *renderer,
 | 
				
			||||||
 | 
					                                                EekElement      *element,
 | 
				
			||||||
 | 
					                                                EekColor        *color);
 | 
				
			||||||
 | 
					void             eek_renderer_get_background_gradient
 | 
				
			||||||
 | 
					                                               (EekRenderer     *renderer,
 | 
				
			||||||
 | 
					                                                EekElement      *element,
 | 
				
			||||||
 | 
					                                                EekGradientType *type,
 | 
				
			||||||
 | 
					                                                EekColor        *start,
 | 
				
			||||||
 | 
					                                                EekColor        *end);
 | 
				
			||||||
void             eek_renderer_set_border_width (EekRenderer     *renderer,
 | 
					void             eek_renderer_set_border_width (EekRenderer     *renderer,
 | 
				
			||||||
                                                gdouble          border_width);
 | 
					                                                gdouble          border_width);
 | 
				
			||||||
struct squeek_button *eek_renderer_find_button_by_position(EekRenderer     *renderer, struct squeek_view *view,
 | 
					EekKey          *eek_renderer_find_key_by_position
 | 
				
			||||||
 | 
					                                               (EekRenderer     *renderer,
 | 
				
			||||||
                                                gdouble          x,
 | 
					                                                gdouble          x,
 | 
				
			||||||
                                                gdouble          y);
 | 
					                                                gdouble          y);
 | 
				
			||||||
void             eek_renderer_apply_transformation_for_button
 | 
					void             eek_renderer_apply_transformation_for_key
 | 
				
			||||||
                                               (EekRenderer     *renderer,
 | 
					                                               (EekRenderer     *renderer,
 | 
				
			||||||
                                                cairo_t         *cr, struct button_place *place,
 | 
					                                                cairo_t         *cr,
 | 
				
			||||||
 | 
					                                                EekKey          *key,
 | 
				
			||||||
                                                gdouble          scale,
 | 
					                                                gdouble          scale,
 | 
				
			||||||
                                                gboolean         rotate);
 | 
					                                                gboolean         rotate);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void             eek_renderer_set_theme        (EekRenderer     *renderer,
 | 
				
			||||||
 | 
					                                                EekTheme        *theme);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
G_END_DECLS
 | 
					G_END_DECLS
 | 
				
			||||||
#endif  /* EEK_RENDERER_H */
 | 
					#endif  /* EEK_RENDERER_H */
 | 
				
			||||||
 | 
				
			|||||||
@ -18,12 +18,477 @@
 | 
				
			|||||||
 * 02110-1301 USA
 | 
					 * 02110-1301 USA
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * SECTION:eek-section
 | 
				
			||||||
 | 
					 * @short_description: Base class of a section
 | 
				
			||||||
 | 
					 * @see_also: #EekKey
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * The #EekSectionClass class represents a section, which consists
 | 
				
			||||||
 | 
					 * of one or more keys of the #EekKeyClass class.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef HAVE_CONFIG_H
 | 
				
			||||||
#include "config.h"
 | 
					#include "config.h"
 | 
				
			||||||
 | 
					#endif  /* HAVE_CONFIG_H */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <string.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "eek-keyboard.h"
 | 
				
			||||||
#include "eek-section.h"
 | 
					#include "eek-section.h"
 | 
				
			||||||
 | 
					#include "eek-key.h"
 | 
				
			||||||
 | 
					#include "eek-symbol.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
EekBounds eek_get_outline_size(LevelKeyboard *keyboard, uint32_t oref) {
 | 
					enum {
 | 
				
			||||||
    EekOutline *outline = level_keyboard_get_outline (keyboard, oref);
 | 
					    PROP_0,
 | 
				
			||||||
 | 
					    PROP_ANGLE,
 | 
				
			||||||
 | 
					    PROP_LAST
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					enum {
 | 
				
			||||||
 | 
					    KEY_LOCKED,
 | 
				
			||||||
 | 
					    KEY_UNLOCKED,
 | 
				
			||||||
 | 
					    LAST_SIGNAL
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static guint signals[LAST_SIGNAL] = { 0, };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct _EekRow
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    gint num_columns;
 | 
				
			||||||
 | 
					    EekOrientation orientation;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef struct _EekRow EekRow;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef struct _EekSectionPrivate
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    gint angle;
 | 
				
			||||||
 | 
					    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_instance_private (self);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return g_slist_length (priv->rows);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					eek_section_real_add_row (EekSection    *self,
 | 
				
			||||||
 | 
					                          gint           num_columns,
 | 
				
			||||||
 | 
					                          EekOrientation orientation)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    EekSectionPrivate *priv = eek_section_get_instance_private (self);
 | 
				
			||||||
 | 
					    EekRow *row;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    row = g_slice_new (EekRow);
 | 
				
			||||||
 | 
					    row->num_columns = num_columns;
 | 
				
			||||||
 | 
					    row->orientation = orientation;
 | 
				
			||||||
 | 
					    priv->rows = g_slist_append (priv->rows, row);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					eek_section_real_get_row (EekSection     *self,
 | 
				
			||||||
 | 
					                          gint            index,
 | 
				
			||||||
 | 
					                          gint           *num_columns,
 | 
				
			||||||
 | 
					                          EekOrientation *orientation)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    EekSectionPrivate *priv = eek_section_get_instance_private (self);
 | 
				
			||||||
 | 
					    EekRow *row;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    row = g_slist_nth_data (priv->rows, index);
 | 
				
			||||||
 | 
					    g_return_if_fail (row);
 | 
				
			||||||
 | 
					    if (num_columns)
 | 
				
			||||||
 | 
					        *num_columns = row->num_columns;
 | 
				
			||||||
 | 
					    if (orientation)
 | 
				
			||||||
 | 
					        *orientation = row->orientation;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					on_locked (EekKey     *key,
 | 
				
			||||||
 | 
					           EekSection *section)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    g_signal_emit (section, signals[KEY_LOCKED], 0, key);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					on_unlocked (EekKey     *key,
 | 
				
			||||||
 | 
					             EekSection *section)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    g_signal_emit (section, signals[KEY_UNLOCKED], 0, key);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static EekKey *
 | 
				
			||||||
 | 
					eek_section_real_create_key (EekSection *self,
 | 
				
			||||||
 | 
					                             guint       keycode,
 | 
				
			||||||
 | 
					                             gint        column_index,
 | 
				
			||||||
 | 
					                             guint        row_index)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    EekKey *key;
 | 
				
			||||||
 | 
					    gint num_rows;
 | 
				
			||||||
 | 
					    EekRow *row;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    num_rows = eek_section_get_n_rows (self);
 | 
				
			||||||
 | 
					    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_index,
 | 
				
			||||||
 | 
					                        "row", row_index,
 | 
				
			||||||
 | 
					                        NULL);
 | 
				
			||||||
 | 
					    g_return_val_if_fail (key, NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    EEK_CONTAINER_GET_CLASS(self)->add_child (EEK_CONTAINER(self),
 | 
				
			||||||
 | 
					                                              EEK_ELEMENT(key));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return key;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					set_level_from_modifiers (EekSection *self)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    EekSectionPrivate *priv = eek_section_get_instance_private (self);
 | 
				
			||||||
 | 
					    EekKeyboard *keyboard;
 | 
				
			||||||
 | 
					    EekModifierType num_lock_mask;
 | 
				
			||||||
 | 
					    gint level = -1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    keyboard = EEK_KEYBOARD(eek_element_get_parent (EEK_ELEMENT(self)));
 | 
				
			||||||
 | 
					    num_lock_mask = eek_keyboard_get_num_lock_mask (keyboard);
 | 
				
			||||||
 | 
					    if (priv->modifiers & num_lock_mask)
 | 
				
			||||||
 | 
					        level = 1;
 | 
				
			||||||
 | 
					    eek_element_set_level (EEK_ELEMENT(self), level);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					eek_section_real_key_pressed (EekSection *self, EekKey *key)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    EekSectionPrivate *priv = eek_section_get_instance_private (self);
 | 
				
			||||||
 | 
					    EekSymbol *symbol;
 | 
				
			||||||
 | 
					    EekKeyboard *keyboard;
 | 
				
			||||||
 | 
					    EekModifierBehavior behavior;
 | 
				
			||||||
 | 
					    EekModifierType modifier;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    symbol = eek_key_get_symbol_with_fallback (key, 0, 0);
 | 
				
			||||||
 | 
					    if (!symbol)
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    keyboard = EEK_KEYBOARD(eek_element_get_parent (EEK_ELEMENT(self)));
 | 
				
			||||||
 | 
					    behavior = eek_keyboard_get_modifier_behavior (keyboard);
 | 
				
			||||||
 | 
					    modifier = eek_symbol_get_modifier_mask (symbol);
 | 
				
			||||||
 | 
					    if (behavior == EEK_MODIFIER_BEHAVIOR_NONE) {
 | 
				
			||||||
 | 
					        priv->modifiers |= modifier;
 | 
				
			||||||
 | 
					        set_level_from_modifiers (self);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					eek_section_real_key_released (EekSection *self, EekKey *key)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    EekSectionPrivate *priv = eek_section_get_instance_private (self);
 | 
				
			||||||
 | 
					    EekSymbol *symbol;
 | 
				
			||||||
 | 
					    EekKeyboard *keyboard;
 | 
				
			||||||
 | 
					    EekModifierBehavior behavior;
 | 
				
			||||||
 | 
					    EekModifierType modifier;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    symbol = eek_key_get_symbol_with_fallback (key, 0, 0);
 | 
				
			||||||
 | 
					    if (!symbol)
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    keyboard = EEK_KEYBOARD(eek_element_get_parent (EEK_ELEMENT(self)));
 | 
				
			||||||
 | 
					    behavior = eek_keyboard_get_modifier_behavior (keyboard);
 | 
				
			||||||
 | 
					    modifier = eek_symbol_get_modifier_mask (symbol);
 | 
				
			||||||
 | 
					    switch (behavior) {
 | 
				
			||||||
 | 
					    case EEK_MODIFIER_BEHAVIOR_NONE:
 | 
				
			||||||
 | 
					        priv->modifiers &= ~modifier;
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					    case EEK_MODIFIER_BEHAVIOR_LOCK:
 | 
				
			||||||
 | 
					        priv->modifiers ^= modifier;
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					    case EEK_MODIFIER_BEHAVIOR_LATCH:
 | 
				
			||||||
 | 
					        priv->modifiers = (priv->modifiers ^ modifier) & modifier;
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    set_level_from_modifiers (self);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					eek_section_finalize (GObject *object)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    EekSection        *self = EEK_SECTION (object);
 | 
				
			||||||
 | 
					    EekSectionPrivate *priv = eek_section_get_instance_private (self);
 | 
				
			||||||
 | 
					    GSList *head;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for (head = priv->rows; head; head = g_slist_next (head))
 | 
				
			||||||
 | 
					        g_slice_free (EekRow, head->data);
 | 
				
			||||||
 | 
					    g_slist_free (priv->rows);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    G_OBJECT_CLASS (eek_section_parent_class)->finalize (object);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					eek_section_set_property (GObject      *object,
 | 
				
			||||||
 | 
					                          guint         prop_id,
 | 
				
			||||||
 | 
					                          const GValue *value,
 | 
				
			||||||
 | 
					                          GParamSpec   *pspec)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    switch (prop_id) {
 | 
				
			||||||
 | 
					    case PROP_ANGLE:
 | 
				
			||||||
 | 
					        eek_section_set_angle (EEK_SECTION(object),
 | 
				
			||||||
 | 
					                               g_value_get_int (value));
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					    default:
 | 
				
			||||||
 | 
					        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					eek_section_get_property (GObject    *object,
 | 
				
			||||||
 | 
					                          guint       prop_id,
 | 
				
			||||||
 | 
					                          GValue     *value,
 | 
				
			||||||
 | 
					                          GParamSpec *pspec)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    switch (prop_id) {
 | 
				
			||||||
 | 
					    case PROP_ANGLE:
 | 
				
			||||||
 | 
					        g_value_set_int (value, eek_section_get_angle (EEK_SECTION(object)));
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					    default:
 | 
				
			||||||
 | 
					        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					eek_section_real_child_added (EekContainer *self,
 | 
				
			||||||
 | 
					                              EekElement   *element)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    g_signal_connect (element, "locked", G_CALLBACK(on_locked), self);
 | 
				
			||||||
 | 
					    g_signal_connect (element, "unlocked", G_CALLBACK(on_unlocked), self);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					eek_section_real_child_removed (EekContainer *self,
 | 
				
			||||||
 | 
					                                EekElement   *element)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    g_signal_handlers_disconnect_by_func (element, on_locked, self);
 | 
				
			||||||
 | 
					    g_signal_handlers_disconnect_by_func (element, on_unlocked, self);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					eek_section_class_init (EekSectionClass *klass)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    EekContainerClass *container_class = EEK_CONTAINER_CLASS (klass);
 | 
				
			||||||
 | 
					    GObjectClass      *gobject_class = G_OBJECT_CLASS (klass);
 | 
				
			||||||
 | 
					    GParamSpec        *pspec;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    klass->get_n_rows = eek_section_real_get_n_rows;
 | 
				
			||||||
 | 
					    klass->add_row = eek_section_real_add_row;
 | 
				
			||||||
 | 
					    klass->get_row = eek_section_real_get_row;
 | 
				
			||||||
 | 
					    klass->create_key = eek_section_real_create_key;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* signals */
 | 
				
			||||||
 | 
					    klass->key_pressed = eek_section_real_key_pressed;
 | 
				
			||||||
 | 
					    klass->key_released = eek_section_real_key_released;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    container_class->child_added = eek_section_real_child_added;
 | 
				
			||||||
 | 
					    container_class->child_removed = eek_section_real_child_removed;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    gobject_class->set_property = eek_section_set_property;
 | 
				
			||||||
 | 
					    gobject_class->get_property = eek_section_get_property;
 | 
				
			||||||
 | 
					    gobject_class->finalize     = eek_section_finalize;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * EekSection:angle:
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * The rotation angle of #EekSection.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    pspec = g_param_spec_int ("angle",
 | 
				
			||||||
 | 
					                              "Angle",
 | 
				
			||||||
 | 
					                              "Rotation angle of the section",
 | 
				
			||||||
 | 
					                              -360, 360, 0,
 | 
				
			||||||
 | 
					                              G_PARAM_READWRITE);
 | 
				
			||||||
 | 
					    g_object_class_install_property (gobject_class,
 | 
				
			||||||
 | 
					                                     PROP_ANGLE,
 | 
				
			||||||
 | 
					                                     pspec);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * EekSection::key-locked:
 | 
				
			||||||
 | 
					     * @section: an #EekSection
 | 
				
			||||||
 | 
					     * @key: an #EekKey
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * The ::key-locked signal is emitted each time a key in @section
 | 
				
			||||||
 | 
					     * is shifted to the locked state.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    signals[KEY_LOCKED] =
 | 
				
			||||||
 | 
					        g_signal_new (I_("key-locked"),
 | 
				
			||||||
 | 
					                      G_TYPE_FROM_CLASS(gobject_class),
 | 
				
			||||||
 | 
					                      G_SIGNAL_RUN_LAST,
 | 
				
			||||||
 | 
					                      G_STRUCT_OFFSET(EekSectionClass, key_locked),
 | 
				
			||||||
 | 
					                      NULL,
 | 
				
			||||||
 | 
					                      NULL,
 | 
				
			||||||
 | 
					                      g_cclosure_marshal_VOID__OBJECT,
 | 
				
			||||||
 | 
					                      G_TYPE_NONE,
 | 
				
			||||||
 | 
					                      1,
 | 
				
			||||||
 | 
					                      EEK_TYPE_KEY);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * EekSection::key-unlocked:
 | 
				
			||||||
 | 
					     * @section: an #EekSection
 | 
				
			||||||
 | 
					     * @key: an #EekKey
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * The ::key-unlocked signal is emitted each time a key in @section
 | 
				
			||||||
 | 
					     * is shifted to the unlocked state.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    signals[KEY_UNLOCKED] =
 | 
				
			||||||
 | 
					        g_signal_new (I_("key-unlocked"),
 | 
				
			||||||
 | 
					                      G_TYPE_FROM_CLASS(gobject_class),
 | 
				
			||||||
 | 
					                      G_SIGNAL_RUN_LAST,
 | 
				
			||||||
 | 
					                      G_STRUCT_OFFSET(EekSectionClass, key_unlocked),
 | 
				
			||||||
 | 
					                      NULL,
 | 
				
			||||||
 | 
					                      NULL,
 | 
				
			||||||
 | 
					                      g_cclosure_marshal_VOID__OBJECT,
 | 
				
			||||||
 | 
					                      G_TYPE_NONE,
 | 
				
			||||||
 | 
					                      1,
 | 
				
			||||||
 | 
					                      EEK_TYPE_KEY);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					eek_section_init (EekSection *self)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    /* void */
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * eek_section_set_angle:
 | 
				
			||||||
 | 
					 * @section: an #EekSection
 | 
				
			||||||
 | 
					 * @angle: rotation angle
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Set rotation angle of @section to @angle.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					eek_section_set_angle (EekSection  *section,
 | 
				
			||||||
 | 
					                       gint         angle)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    g_return_if_fail (EEK_IS_SECTION(section));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    EekSectionPrivate *priv = eek_section_get_instance_private (section);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (priv->angle != angle) {
 | 
				
			||||||
 | 
					        priv->angle = angle;
 | 
				
			||||||
 | 
					        g_object_notify (G_OBJECT(section), "angle");
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * eek_section_get_angle:
 | 
				
			||||||
 | 
					 * @section: an #EekSection
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Get rotation angle of @section.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					gint
 | 
				
			||||||
 | 
					eek_section_get_angle (EekSection *section)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    g_return_val_if_fail (EEK_IS_SECTION(section), -1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    EekSectionPrivate *priv = eek_section_get_instance_private (section);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return priv->angle;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * eek_section_get_n_rows:
 | 
				
			||||||
 | 
					 * @section: an #EekSection
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Get the number of rows in @section.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					gint
 | 
				
			||||||
 | 
					eek_section_get_n_rows (EekSection *section)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    g_return_val_if_fail (EEK_IS_SECTION(section), -1);
 | 
				
			||||||
 | 
					    return EEK_SECTION_GET_CLASS(section)->get_n_rows (section);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * eek_section_add_row:
 | 
				
			||||||
 | 
					 * @section: an #EekSection
 | 
				
			||||||
 | 
					 * @num_columns: the number of column in the row
 | 
				
			||||||
 | 
					 * @orientation: #EekOrientation of the row
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Add a row which has @num_columns columns and whose orientation is
 | 
				
			||||||
 | 
					 * @orientation to @section.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					eek_section_add_row (EekSection    *section,
 | 
				
			||||||
 | 
					                     gint           num_columns,
 | 
				
			||||||
 | 
					                     EekOrientation orientation)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    g_return_if_fail (EEK_IS_SECTION(section));
 | 
				
			||||||
 | 
					    EEK_SECTION_GET_CLASS(section)->add_row (section,
 | 
				
			||||||
 | 
					                                             num_columns,
 | 
				
			||||||
 | 
					                                             orientation);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * eek_section_get_row:
 | 
				
			||||||
 | 
					 * @section: an #EekSection
 | 
				
			||||||
 | 
					 * @index: the index of row
 | 
				
			||||||
 | 
					 * @num_columns: pointer where the number of column in the row will be stored
 | 
				
			||||||
 | 
					 * @orientation: pointer where #EekOrientation of the row will be stored
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Get the information about the @index-th row in @section.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					eek_section_get_row (EekSection     *section,
 | 
				
			||||||
 | 
					                     gint            index,
 | 
				
			||||||
 | 
					                     gint           *num_columns,
 | 
				
			||||||
 | 
					                     EekOrientation *orientation)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    g_return_if_fail (EEK_IS_SECTION(section));
 | 
				
			||||||
 | 
					    EEK_SECTION_GET_CLASS(section)->get_row (section,
 | 
				
			||||||
 | 
					                                             index,
 | 
				
			||||||
 | 
					                                             num_columns,
 | 
				
			||||||
 | 
					                                             orientation);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * eek_section_create_key:
 | 
				
			||||||
 | 
					 * @section: an #EekSection
 | 
				
			||||||
 | 
					 * @keycode: a keycode
 | 
				
			||||||
 | 
					 * @column: the column index of the key
 | 
				
			||||||
 | 
					 * @row: the row index of the key
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Create an #EekKey instance and append it to @section.  This
 | 
				
			||||||
 | 
					 * function is rarely called by application but called by #EekLayout
 | 
				
			||||||
 | 
					 * implementation.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					EekKey *
 | 
				
			||||||
 | 
					eek_section_create_key (EekSection *section,
 | 
				
			||||||
 | 
					                        guint       keycode,
 | 
				
			||||||
 | 
					                        gint        column,
 | 
				
			||||||
 | 
					                        gint        row)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    g_return_val_if_fail (EEK_IS_SECTION(section), NULL);
 | 
				
			||||||
 | 
					    return EEK_SECTION_GET_CLASS(section)->create_key (section,
 | 
				
			||||||
 | 
					                                                       keycode,
 | 
				
			||||||
 | 
					                                                       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) {
 | 
					    if (outline && outline->num_points > 0) {
 | 
				
			||||||
        double minx = outline->points[0].x;
 | 
					        double minx = outline->points[0].x;
 | 
				
			||||||
        double maxx = minx;
 | 
					        double maxx = minx;
 | 
				
			||||||
@ -43,14 +508,55 @@ EekBounds eek_get_outline_size(LevelKeyboard *keyboard, uint32_t oref) {
 | 
				
			|||||||
                maxy = p.y;
 | 
					                maxy = p.y;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        EekBounds key_bounds = {
 | 
					        EekBounds key_bounds = {0};
 | 
				
			||||||
            .height = maxy - miny,
 | 
					        eek_element_get_bounds(element, &key_bounds);
 | 
				
			||||||
            .width = maxx - minx,
 | 
					        key_bounds.height = maxy - miny;
 | 
				
			||||||
            .x = 0,
 | 
					        key_bounds.width = maxx - minx;
 | 
				
			||||||
            .y = 0,
 | 
					        eek_element_set_bounds(element, &key_bounds);
 | 
				
			||||||
        };
 | 
					 | 
				
			||||||
        return key_bounds;
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    EekBounds bounds = {0, 0, 0, 0};
 | 
					}
 | 
				
			||||||
    return 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);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -25,10 +25,88 @@
 | 
				
			|||||||
#ifndef EEK_SECTION_H
 | 
					#ifndef EEK_SECTION_H
 | 
				
			||||||
#define EEK_SECTION_H 1
 | 
					#define EEK_SECTION_H 1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Contains row-related functions that couldn't be done in Rust easily. */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include <glib-object.h>
 | 
					#include <glib-object.h>
 | 
				
			||||||
#include "eek-keyboard.h"
 | 
					#include "eek-container.h"
 | 
				
			||||||
#include "src/layout.h"
 | 
					#include "eek-types.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					G_BEGIN_DECLS
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define EEK_TYPE_SECTION (eek_section_get_type())
 | 
				
			||||||
 | 
					G_DECLARE_DERIVABLE_TYPE(EekSection, eek_section, EEK, SECTION, EekContainer)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * EekSectionClass:
 | 
				
			||||||
 | 
					 * @get_n_rows: virtual function for getting the number of rows in the section
 | 
				
			||||||
 | 
					 * @add_row: virtual function for adding a new row to the section
 | 
				
			||||||
 | 
					 * @get_row: virtual function for accessing a row in the section
 | 
				
			||||||
 | 
					 * @create_key: virtual function for creating key in the section
 | 
				
			||||||
 | 
					 * @key_pressed: class handler for #EekSection::key-pressed signal
 | 
				
			||||||
 | 
					 * @key_released: class handler for #EekSection::key-released signal
 | 
				
			||||||
 | 
					 * @key_locked: class handler for #EekSection::key-locked signal
 | 
				
			||||||
 | 
					 * @key_unlocked: class handler for #EekSection::key-unlocked signal
 | 
				
			||||||
 | 
					 * @key_cancelled: class handler for #EekSection::key-cancelled signal
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					struct _EekSectionClass
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    /*< private >*/
 | 
				
			||||||
 | 
					    EekContainerClass parent_class;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /*< public >*/
 | 
				
			||||||
 | 
					    gint    (* get_n_rows)          (EekSection     *self);
 | 
				
			||||||
 | 
					    void    (* add_row)             (EekSection     *self,
 | 
				
			||||||
 | 
					                                     gint            num_columns,
 | 
				
			||||||
 | 
					                                     EekOrientation  orientation);
 | 
				
			||||||
 | 
					    void    (* get_row)             (EekSection     *self,
 | 
				
			||||||
 | 
					                                     gint            index,
 | 
				
			||||||
 | 
					                                     gint           *num_columns,
 | 
				
			||||||
 | 
					                                     EekOrientation *orientation);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    EekKey *(* create_key)          (EekSection     *self,
 | 
				
			||||||
 | 
					                                     guint           keycode,
 | 
				
			||||||
 | 
					                                     gint            row,
 | 
				
			||||||
 | 
					                                     gint            column);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* signals */
 | 
				
			||||||
 | 
					    void    (* key_pressed)         (EekSection     *self,
 | 
				
			||||||
 | 
					                                     EekKey         *key);
 | 
				
			||||||
 | 
					    void    (* key_released)        (EekSection     *self,
 | 
				
			||||||
 | 
					                                     EekKey         *key);
 | 
				
			||||||
 | 
					    void    (* key_locked)          (EekSection     *self,
 | 
				
			||||||
 | 
					                                     EekKey         *key);
 | 
				
			||||||
 | 
					    void    (* key_unlocked)        (EekSection     *self,
 | 
				
			||||||
 | 
					                                     EekKey         *key);
 | 
				
			||||||
 | 
					    void    (* key_cancelled)       (EekSection     *self,
 | 
				
			||||||
 | 
					                                     EekKey         *key);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /*< private >*/
 | 
				
			||||||
 | 
					    /* padding */
 | 
				
			||||||
 | 
					    gpointer pdummy[19];
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					GType   eek_section_get_type             (void) G_GNUC_CONST;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void    eek_section_set_angle            (EekSection     *section,
 | 
				
			||||||
 | 
					                                          gint            angle);
 | 
				
			||||||
 | 
					gint    eek_section_get_angle            (EekSection     *section);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					gint    eek_section_get_n_rows           (EekSection     *section);
 | 
				
			||||||
 | 
					void    eek_section_add_row              (EekSection     *section,
 | 
				
			||||||
 | 
					                                          gint            num_columns,
 | 
				
			||||||
 | 
					                                          EekOrientation  orientation);
 | 
				
			||||||
 | 
					void    eek_section_get_row              (EekSection     *section,
 | 
				
			||||||
 | 
					                                          gint            index,
 | 
				
			||||||
 | 
					                                          gint           *num_columns,
 | 
				
			||||||
 | 
					                                          EekOrientation *orientation);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					EekKey *eek_section_create_key           (EekSection     *section,
 | 
				
			||||||
 | 
					                                          guint           keycode,
 | 
				
			||||||
 | 
					                                          gint            column,
 | 
				
			||||||
 | 
					                                          gint            row);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					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 */
 | 
					#endif  /* EEK_SECTION_H */
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										93
									
								
								eek/eek-serializable.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,93 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright (C) 2008-2010 Peng Huang <shawn.p.huang@gmail.com>
 | 
				
			||||||
 | 
					 * Copyright (C) 2008-2010 Red Hat, Inc.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * This library is free software; you can redistribute it and/or
 | 
				
			||||||
 | 
					 * modify it under the terms of the GNU Lesser General Public
 | 
				
			||||||
 | 
					 * License as published by the Free Software Foundation; either
 | 
				
			||||||
 | 
					 * version 2 of the License, or (at your option) any later version.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * This library is distributed in the hope that it will be useful,
 | 
				
			||||||
 | 
					 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
				
			||||||
 | 
					 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the GNU
 | 
				
			||||||
 | 
					 * Lesser General Public License for more details.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * You should have received a copy of the GNU Lesser General Public
 | 
				
			||||||
 | 
					 * License along with this library; if not, write to the
 | 
				
			||||||
 | 
					 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 | 
				
			||||||
 | 
					 * Boston, MA 02111-1307, USA.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * SECTION:eek-serializable
 | 
				
			||||||
 | 
					 * @short_description: Interface which provides object serialization
 | 
				
			||||||
 | 
					 * into #GVariant
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * The #EekSerializableIface interface defines serialize/deserialize
 | 
				
			||||||
 | 
					 * method.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef HAVE_CONFIG_H
 | 
				
			||||||
 | 
					#include "config.h"
 | 
				
			||||||
 | 
					#endif  /* HAVE_CONFIG_H */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "eek-serializable.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					GType
 | 
				
			||||||
 | 
					eek_serializable_get_type (void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    static GType iface_type = 0;
 | 
				
			||||||
 | 
					    if (iface_type == 0) {
 | 
				
			||||||
 | 
					        static const GTypeInfo info = {
 | 
				
			||||||
 | 
					            sizeof (EekSerializableIface),
 | 
				
			||||||
 | 
					            NULL,
 | 
				
			||||||
 | 
					            NULL,
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					        iface_type = g_type_register_static (G_TYPE_INTERFACE,
 | 
				
			||||||
 | 
					                                             "EekSerializable",
 | 
				
			||||||
 | 
					                                             &info, 0);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return iface_type;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					GVariant *
 | 
				
			||||||
 | 
					eek_serializable_serialize (EekSerializable *object)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    GVariantBuilder builder;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    g_return_val_if_fail (EEK_IS_SERIALIZABLE (object), FALSE);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    g_variant_builder_init (&builder, G_VARIANT_TYPE_TUPLE);
 | 
				
			||||||
 | 
					    g_variant_builder_add (&builder, "s", g_type_name (G_OBJECT_TYPE (object)));
 | 
				
			||||||
 | 
					    EEK_SERIALIZABLE_GET_IFACE (object)->serialize (object, &builder);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return g_variant_builder_end (&builder);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					EekSerializable *
 | 
				
			||||||
 | 
					eek_serializable_deserialize (GVariant *variant)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    gchar *type_name = NULL;
 | 
				
			||||||
 | 
					    GType type;
 | 
				
			||||||
 | 
					    EekSerializable *object;
 | 
				
			||||||
 | 
					    gsize index = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    g_return_val_if_fail (variant != NULL, NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    g_variant_get_child (variant, index++, "&s", &type_name);
 | 
				
			||||||
 | 
					    type = g_type_from_name (type_name);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    g_return_val_if_fail (g_type_is_a (type, EEK_TYPE_SERIALIZABLE), NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    object = g_object_new (type, NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    index = EEK_SERIALIZABLE_GET_IFACE (object)->deserialize (object,
 | 
				
			||||||
 | 
					                                                              variant,
 | 
				
			||||||
 | 
					                                                              index);
 | 
				
			||||||
 | 
					    if (index < 0) {
 | 
				
			||||||
 | 
					        g_object_unref (object);
 | 
				
			||||||
 | 
					        g_return_val_if_reached (NULL);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return object;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										66
									
								
								eek/eek-serializable.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,66 @@
 | 
				
			|||||||
 | 
					/* 
 | 
				
			||||||
 | 
					 * Copyright (C) 2011 Daiki Ueno <ueno@unixuser.org>
 | 
				
			||||||
 | 
					 * Copyright (C) 2011 Red Hat, Inc.
 | 
				
			||||||
 | 
					 * 
 | 
				
			||||||
 | 
					 * This program is free software: you can redistribute it and/or modify
 | 
				
			||||||
 | 
					 * it under the terms of the GNU General Public License as published by
 | 
				
			||||||
 | 
					 * the Free Software Foundation, either version 3 of the License, or
 | 
				
			||||||
 | 
					 * (at your option) any later version.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * This program is distributed in the hope that it will be useful,
 | 
				
			||||||
 | 
					 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
				
			||||||
 | 
					 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
				
			||||||
 | 
					 * GNU General Public License for more details.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * You should have received a copy of the GNU General Public License
 | 
				
			||||||
 | 
					 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if !defined(__EEK_H_INSIDE__) && !defined(EEK_COMPILATION)
 | 
				
			||||||
 | 
					#error "Only <eek/eek.h> can be included directly."
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef EEK_SERIALIZABLE_H
 | 
				
			||||||
 | 
					#define EEK_SERIALIZABLE_H 1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <glib-object.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					G_BEGIN_DECLS
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define EEK_TYPE_SERIALIZABLE (eek_serializable_get_type())
 | 
				
			||||||
 | 
					#define EEK_SERIALIZABLE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EEK_TYPE_SERIALIZABLE, EekSerializable))
 | 
				
			||||||
 | 
					#define EEK_IS_SERIALIZABLE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EEK_TYPE_SERIALIZABLE))
 | 
				
			||||||
 | 
					#define EEK_SERIALIZABLE_GET_IFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), EEK_TYPE_SERIALIZABLE, EekSerializableIface))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef struct _EekSerializable EekSerializable;
 | 
				
			||||||
 | 
					typedef struct _EekSerializableIface EekSerializableIface;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * EekSerializableIface:
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @serialize: virtual function for serializing object into #GVariant
 | 
				
			||||||
 | 
					 * @deserialize: virtual function for deserializing object from #GVariant
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					struct _EekSerializableIface
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    /*< private >*/
 | 
				
			||||||
 | 
					    GTypeInterface parent_iface;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    void  (* serialize)   (EekSerializable       *object,
 | 
				
			||||||
 | 
					                           GVariantBuilder       *builder);
 | 
				
			||||||
 | 
					    gsize (* deserialize) (EekSerializable       *object,
 | 
				
			||||||
 | 
					                           GVariant              *variant,
 | 
				
			||||||
 | 
					                           gsize                  index);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /*< private >*/
 | 
				
			||||||
 | 
					    /* padding */
 | 
				
			||||||
 | 
					    gpointer pdummy[24];
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					GType            eek_serializable_get_type    (void);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					GVariant        *eek_serializable_serialize   (EekSerializable *object);
 | 
				
			||||||
 | 
					EekSerializable *eek_serializable_deserialize (GVariant        *variant);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					G_END_DECLS
 | 
				
			||||||
 | 
					#endif  /* EEK_SERIALIZABLE_H */
 | 
				
			||||||
							
								
								
									
										105
									
								
								eek/eek-symbol-matrix.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,105 @@
 | 
				
			|||||||
 | 
					/* 
 | 
				
			||||||
 | 
					 * Copyright (C) 2011 Daiki Ueno <ueno@unixuser.org>
 | 
				
			||||||
 | 
					 * Copyright (C) 2011 Red Hat, Inc.
 | 
				
			||||||
 | 
					 * 
 | 
				
			||||||
 | 
					 * This library is free software; you can redistribute it and/or
 | 
				
			||||||
 | 
					 * modify it under the terms of the GNU Lesser General Public License
 | 
				
			||||||
 | 
					 * as published by the Free Software Foundation; either version 2 of
 | 
				
			||||||
 | 
					 * the License, or (at your option) any later version.
 | 
				
			||||||
 | 
					 * 
 | 
				
			||||||
 | 
					 * This library is distributed in the hope that it will be useful, but
 | 
				
			||||||
 | 
					 * WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
				
			||||||
 | 
					 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
				
			||||||
 | 
					 * Lesser General Public License for more details.
 | 
				
			||||||
 | 
					 * 
 | 
				
			||||||
 | 
					 * You should have received a copy of the GNU Lesser General Public
 | 
				
			||||||
 | 
					 * License along with this library; if not, write to the Free Software
 | 
				
			||||||
 | 
					 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 | 
				
			||||||
 | 
					 * 02110-1301 USA
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					#include "eek-symbol-matrix.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					EekSymbolMatrix *
 | 
				
			||||||
 | 
					eek_symbol_matrix_new (gint num_groups,
 | 
				
			||||||
 | 
					                       gint num_levels)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    EekSymbolMatrix *matrix = g_slice_new (EekSymbolMatrix);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    matrix->num_groups = num_groups;
 | 
				
			||||||
 | 
					    matrix->num_levels = num_levels;
 | 
				
			||||||
 | 
					    matrix->data = g_slice_alloc0 (sizeof (EekSymbol *) *
 | 
				
			||||||
 | 
					                                   num_groups * num_levels);
 | 
				
			||||||
 | 
					    return matrix;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					EekSymbolMatrix *
 | 
				
			||||||
 | 
					eek_symbol_matrix_copy (const EekSymbolMatrix *matrix)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    EekSymbolMatrix *retval;
 | 
				
			||||||
 | 
					    gint i, num_symbols = matrix->num_groups * matrix->num_levels;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    retval = g_slice_dup (EekSymbolMatrix, matrix);
 | 
				
			||||||
 | 
					    retval->data = g_slice_copy (sizeof (EekSymbol *) * num_symbols,
 | 
				
			||||||
 | 
					                                 matrix->data);
 | 
				
			||||||
 | 
					    for (i = 0; i < num_symbols; i++)
 | 
				
			||||||
 | 
					        if (retval->data[i])
 | 
				
			||||||
 | 
					            g_object_ref (retval->data[i]);
 | 
				
			||||||
 | 
					    return retval;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					eek_symbol_matrix_free (EekSymbolMatrix *matrix)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    gint i, num_symbols = matrix->num_groups * matrix->num_levels;
 | 
				
			||||||
 | 
					    for (i = 0; i < num_symbols; i++)
 | 
				
			||||||
 | 
					        if (matrix->data[i])
 | 
				
			||||||
 | 
					            g_object_unref (matrix->data[i]);
 | 
				
			||||||
 | 
					    g_slice_free1 (sizeof (EekSymbol *) * num_symbols, matrix->data);
 | 
				
			||||||
 | 
					    g_slice_free (EekSymbolMatrix, matrix);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					GType
 | 
				
			||||||
 | 
					eek_symbol_matrix_get_type (void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    static GType our_type = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (our_type == 0)
 | 
				
			||||||
 | 
					        our_type =
 | 
				
			||||||
 | 
					            g_boxed_type_register_static ("EekSymbolMatrix",
 | 
				
			||||||
 | 
					                                          (GBoxedCopyFunc)eek_symbol_matrix_copy,
 | 
				
			||||||
 | 
					                                          (GBoxedFreeFunc)eek_symbol_matrix_free);
 | 
				
			||||||
 | 
					    return our_type;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					eek_symbol_matrix_set_symbol (EekSymbolMatrix *matrix,
 | 
				
			||||||
 | 
					                              gint             group,
 | 
				
			||||||
 | 
					                              gint             level,
 | 
				
			||||||
 | 
					                              EekSymbol       *symbol)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    g_return_if_fail (group >= 0 && group < matrix->num_groups);
 | 
				
			||||||
 | 
					    g_return_if_fail (level >= 0 && level < matrix->num_levels);
 | 
				
			||||||
 | 
					    g_return_if_fail (EEK_IS_SYMBOL(symbol));
 | 
				
			||||||
 | 
					    matrix->data[group * matrix->num_levels + level] = g_object_ref (symbol);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * eek_symbol_matrix_get_symbol:
 | 
				
			||||||
 | 
					 * @matrix: an #EekSymbolMatrix
 | 
				
			||||||
 | 
					 * @group: group index of @matrix
 | 
				
			||||||
 | 
					 * @level: level index of @matrix
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Get an #EekSymbol stored in the cell selected by (@group, @level)
 | 
				
			||||||
 | 
					 * in @matrix.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Return value: (transfer none): an #EekSymbol.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					EekSymbol *
 | 
				
			||||||
 | 
					eek_symbol_matrix_get_symbol (EekSymbolMatrix *matrix,
 | 
				
			||||||
 | 
					                              gint             group,
 | 
				
			||||||
 | 
					                              gint             level)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    g_return_val_if_fail (group >= 0 && group < matrix->num_groups, NULL);
 | 
				
			||||||
 | 
					    g_return_val_if_fail (level >= 0 && level < matrix->num_levels, NULL);
 | 
				
			||||||
 | 
					    return matrix->data[group * matrix->num_levels + level];
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										62
									
								
								eek/eek-symbol-matrix.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,62 @@
 | 
				
			|||||||
 | 
					/* 
 | 
				
			||||||
 | 
					 * Copyright (C) 2011 Daiki Ueno <ueno@unixuser.org>
 | 
				
			||||||
 | 
					 * Copyright (C) 2011 Red Hat, Inc.
 | 
				
			||||||
 | 
					 * 
 | 
				
			||||||
 | 
					 * This library is free software; you can redistribute it and/or
 | 
				
			||||||
 | 
					 * modify it under the terms of the GNU Lesser General Public License
 | 
				
			||||||
 | 
					 * as published by the Free Software Foundation; either version 2 of
 | 
				
			||||||
 | 
					 * the License, or (at your option) any later version.
 | 
				
			||||||
 | 
					 * 
 | 
				
			||||||
 | 
					 * This library is distributed in the hope that it will be useful, but
 | 
				
			||||||
 | 
					 * WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
				
			||||||
 | 
					 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
				
			||||||
 | 
					 * Lesser General Public License for more details.
 | 
				
			||||||
 | 
					 * 
 | 
				
			||||||
 | 
					 * You should have received a copy of the GNU Lesser General Public
 | 
				
			||||||
 | 
					 * License along with this library; if not, write to the Free Software
 | 
				
			||||||
 | 
					 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 | 
				
			||||||
 | 
					 * 02110-1301 USA
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					#ifndef EEK_SYMBOL_MATRIX_H
 | 
				
			||||||
 | 
					#define EEK_SYMBOL_MATRIX_H 1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "eek-symbol.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					G_BEGIN_DECLS
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * EekSymbolMatrix:
 | 
				
			||||||
 | 
					 * @data: array of symbols
 | 
				
			||||||
 | 
					 * @num_groups: the number of groups (rows)
 | 
				
			||||||
 | 
					 * @num_levels: the number of levels (columns)
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Symbol matrix of a key.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					struct _EekSymbolMatrix
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    /*< public >*/
 | 
				
			||||||
 | 
					    gint num_groups;
 | 
				
			||||||
 | 
					    gint num_levels;
 | 
				
			||||||
 | 
					    EekSymbol **data;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define EEK_TYPE_SYMBOL_MATRIX (eek_symbol_matrix_get_type ())
 | 
				
			||||||
 | 
					GType            eek_symbol_matrix_get_type (void) G_GNUC_CONST;
 | 
				
			||||||
 | 
					EekSymbolMatrix *eek_symbol_matrix_new      (gint                   num_groups,
 | 
				
			||||||
 | 
					                                             gint                   num_levels);
 | 
				
			||||||
 | 
					EekSymbolMatrix *eek_symbol_matrix_copy     (const EekSymbolMatrix *matrix);
 | 
				
			||||||
 | 
					void             eek_symbol_matrix_free     (EekSymbolMatrix       *matrix);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void             eek_symbol_matrix_set_symbol
 | 
				
			||||||
 | 
					                                            (EekSymbolMatrix       *matrix,
 | 
				
			||||||
 | 
					                                             gint                   group,
 | 
				
			||||||
 | 
					                                             gint                   level,
 | 
				
			||||||
 | 
					                                             EekSymbol             *symbol);
 | 
				
			||||||
 | 
					EekSymbol       *eek_symbol_matrix_get_symbol
 | 
				
			||||||
 | 
					                                            (EekSymbolMatrix       *matrix,
 | 
				
			||||||
 | 
					                                             gint                   group,
 | 
				
			||||||
 | 
					                                             gint                   level);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					G_END_DECLS
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif  /* EEK_SYMBOL_MATRIX_H */
 | 
				
			||||||
							
								
								
									
										443
									
								
								eek/eek-symbol.c
									
									
									
									
									
								
							
							
						
						@ -25,18 +25,275 @@
 | 
				
			|||||||
 * The #EekSymbolClass class represents a symbol assigned to a key.
 | 
					 * The #EekSymbolClass class represents a symbol assigned to a key.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef HAVE_CONFIG_H
 | 
				
			||||||
#include "config.h"
 | 
					#include "config.h"
 | 
				
			||||||
 | 
					#endif  /* HAVE_CONFIG_H */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "eek-symbol.h"
 | 
					#include "eek-symbol.h"
 | 
				
			||||||
 | 
					#include "eek-serializable.h"
 | 
				
			||||||
#include "eek-enumtypes.h"
 | 
					#include "eek-enumtypes.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					enum {
 | 
				
			||||||
 | 
					    PROP_0,
 | 
				
			||||||
 | 
					    PROP_NAME,
 | 
				
			||||||
 | 
					    PROP_LABEL,
 | 
				
			||||||
 | 
					    PROP_CATEGORY,
 | 
				
			||||||
 | 
					    PROP_MODIFIER_MASK,
 | 
				
			||||||
 | 
					    PROP_ICON_NAME,
 | 
				
			||||||
 | 
					    PROP_TOOLTIP,
 | 
				
			||||||
 | 
					    PROP_LAST
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef struct _EekSymbolPrivate
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    gchar *name;
 | 
				
			||||||
 | 
					    gchar *label;
 | 
				
			||||||
 | 
					    EekSymbolCategory category;
 | 
				
			||||||
 | 
					    EekModifierType modifier_mask;
 | 
				
			||||||
 | 
					    gchar *icon_name;
 | 
				
			||||||
 | 
					    gchar *tooltip;
 | 
				
			||||||
 | 
					} EekSymbolPrivate;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void eek_serializable_iface_init (EekSerializableIface *iface);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					G_DEFINE_TYPE_EXTENDED (EekSymbol,
 | 
				
			||||||
 | 
								eek_symbol,
 | 
				
			||||||
 | 
								G_TYPE_OBJECT,
 | 
				
			||||||
 | 
								0, /* GTypeFlags */
 | 
				
			||||||
 | 
								G_ADD_PRIVATE (EekSymbol)
 | 
				
			||||||
 | 
					                        G_IMPLEMENT_INTERFACE (EEK_TYPE_SERIALIZABLE,
 | 
				
			||||||
 | 
					                                               eek_serializable_iface_init))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					eek_symbol_real_serialize (EekSerializable *self,
 | 
				
			||||||
 | 
					                           GVariantBuilder *builder)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    EekSymbolPrivate *priv = eek_symbol_get_instance_private (EEK_SYMBOL (self));
 | 
				
			||||||
 | 
					#define NOTNULL(s) ((s) != NULL ? (s) : "")
 | 
				
			||||||
 | 
					    g_variant_builder_add (builder, "s", NOTNULL(priv->name));
 | 
				
			||||||
 | 
					    g_variant_builder_add (builder, "s", NOTNULL(priv->label));
 | 
				
			||||||
 | 
					    g_variant_builder_add (builder, "u", priv->category);
 | 
				
			||||||
 | 
					    g_variant_builder_add (builder, "u", priv->modifier_mask);
 | 
				
			||||||
 | 
					    g_variant_builder_add (builder, "s", NOTNULL(priv->icon_name));
 | 
				
			||||||
 | 
					    g_variant_builder_add (builder, "s", NOTNULL(priv->tooltip));
 | 
				
			||||||
 | 
					#undef NOTNULL
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static gsize
 | 
				
			||||||
 | 
					eek_symbol_real_deserialize (EekSerializable *self,
 | 
				
			||||||
 | 
					                             GVariant        *variant,
 | 
				
			||||||
 | 
					                             gsize            index)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    EekSymbolPrivate *priv = eek_symbol_get_instance_private (EEK_SYMBOL (self));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    g_variant_get_child (variant, index++, "s", &priv->name);
 | 
				
			||||||
 | 
					    g_variant_get_child (variant, index++, "s", &priv->label);
 | 
				
			||||||
 | 
					    g_variant_get_child (variant, index++, "u", &priv->category);
 | 
				
			||||||
 | 
					    g_variant_get_child (variant, index++, "u", &priv->modifier_mask);
 | 
				
			||||||
 | 
					    g_variant_get_child (variant, index++, "s", &priv->icon_name);
 | 
				
			||||||
 | 
					    g_variant_get_child (variant, index++, "s", &priv->tooltip);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return index;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					eek_serializable_iface_init (EekSerializableIface *iface)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    iface->serialize = eek_symbol_real_serialize;
 | 
				
			||||||
 | 
					    iface->deserialize = eek_symbol_real_deserialize;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					eek_symbol_set_property (GObject      *object,
 | 
				
			||||||
 | 
					                         guint         prop_id,
 | 
				
			||||||
 | 
					                         const GValue *value,
 | 
				
			||||||
 | 
					                         GParamSpec   *pspec)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    switch (prop_id) {
 | 
				
			||||||
 | 
					    case PROP_NAME:
 | 
				
			||||||
 | 
					        eek_symbol_set_name (EEK_SYMBOL(object), g_value_get_string (value));
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					    case PROP_LABEL:
 | 
				
			||||||
 | 
					        eek_symbol_set_label (EEK_SYMBOL(object), g_value_get_string (value));
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					    case PROP_CATEGORY:
 | 
				
			||||||
 | 
					        eek_symbol_set_category (EEK_SYMBOL(object), g_value_get_enum (value));
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					    case PROP_MODIFIER_MASK:
 | 
				
			||||||
 | 
					        eek_symbol_set_modifier_mask (EEK_SYMBOL(object),
 | 
				
			||||||
 | 
					                                      g_value_get_flags (value));
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					    case PROP_ICON_NAME:
 | 
				
			||||||
 | 
					        eek_symbol_set_icon_name (EEK_SYMBOL(object),
 | 
				
			||||||
 | 
					                                  g_value_get_string (value));
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					    case PROP_TOOLTIP:
 | 
				
			||||||
 | 
					        eek_symbol_set_tooltip (EEK_SYMBOL(object),
 | 
				
			||||||
 | 
					                                g_value_get_string (value));
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					    default:
 | 
				
			||||||
 | 
					        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					eek_symbol_get_property (GObject    *object,
 | 
				
			||||||
 | 
					                         guint       prop_id,
 | 
				
			||||||
 | 
					                         GValue     *value,
 | 
				
			||||||
 | 
					                         GParamSpec *pspec)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    switch (prop_id) {
 | 
				
			||||||
 | 
					    case PROP_NAME:
 | 
				
			||||||
 | 
					        g_value_set_string (value, eek_symbol_get_name (EEK_SYMBOL(object)));
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					    case PROP_LABEL:
 | 
				
			||||||
 | 
					        g_value_set_string (value, eek_symbol_get_label (EEK_SYMBOL(object)));
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					    case PROP_CATEGORY:
 | 
				
			||||||
 | 
					        g_value_set_enum (value, eek_symbol_get_category (EEK_SYMBOL(object)));
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					    case PROP_MODIFIER_MASK:
 | 
				
			||||||
 | 
					        g_value_set_flags (value,
 | 
				
			||||||
 | 
					                           eek_symbol_get_modifier_mask (EEK_SYMBOL(object)));
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					    case PROP_ICON_NAME:
 | 
				
			||||||
 | 
					        g_value_set_string (value,
 | 
				
			||||||
 | 
					                            eek_symbol_get_icon_name (EEK_SYMBOL(object)));
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					    case PROP_TOOLTIP:
 | 
				
			||||||
 | 
					        g_value_set_string (value,
 | 
				
			||||||
 | 
					                            eek_symbol_get_tooltip (EEK_SYMBOL(object)));
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					    default:
 | 
				
			||||||
 | 
					        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					eek_symbol_finalize (GObject *object)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    EekSymbol        *self = EEK_SYMBOL (object);
 | 
				
			||||||
 | 
					    EekSymbolPrivate *priv = eek_symbol_get_instance_private (self);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    g_free (priv->name);
 | 
				
			||||||
 | 
					    g_free (priv->label);
 | 
				
			||||||
 | 
					    g_free (priv->icon_name);
 | 
				
			||||||
 | 
					    g_free (priv->tooltip);
 | 
				
			||||||
 | 
					    G_OBJECT_CLASS (eek_symbol_parent_class)->finalize (object);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					eek_symbol_class_init (EekSymbolClass *klass)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
 | 
				
			||||||
 | 
					    GParamSpec *pspec;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    gobject_class->set_property = eek_symbol_set_property;
 | 
				
			||||||
 | 
					    gobject_class->get_property = eek_symbol_get_property;
 | 
				
			||||||
 | 
					    gobject_class->finalize = eek_symbol_finalize;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    pspec = g_param_spec_string ("name",
 | 
				
			||||||
 | 
					                                 "Name",
 | 
				
			||||||
 | 
					                                 "Canonical name of the symbol",
 | 
				
			||||||
 | 
					                                 NULL,
 | 
				
			||||||
 | 
					                                 G_PARAM_CONSTRUCT | G_PARAM_READWRITE);
 | 
				
			||||||
 | 
					    g_object_class_install_property (gobject_class, PROP_NAME, pspec);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    pspec = g_param_spec_string ("label",
 | 
				
			||||||
 | 
					                                 "Label",
 | 
				
			||||||
 | 
					                                 "Text used to display the symbol",
 | 
				
			||||||
 | 
					                                 NULL,
 | 
				
			||||||
 | 
					                                 G_PARAM_CONSTRUCT | G_PARAM_READWRITE);
 | 
				
			||||||
 | 
					    g_object_class_install_property (gobject_class, PROP_LABEL, pspec);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    pspec = g_param_spec_enum ("category",
 | 
				
			||||||
 | 
					                               "Category",
 | 
				
			||||||
 | 
					                               "Category of the symbol",
 | 
				
			||||||
 | 
					                               EEK_TYPE_SYMBOL_CATEGORY,
 | 
				
			||||||
 | 
					                               EEK_SYMBOL_CATEGORY_UNKNOWN,
 | 
				
			||||||
 | 
					                               G_PARAM_CONSTRUCT | G_PARAM_READWRITE);
 | 
				
			||||||
 | 
					    g_object_class_install_property (gobject_class, PROP_CATEGORY, pspec);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    pspec = g_param_spec_flags ("modifier-mask",
 | 
				
			||||||
 | 
					                                "Modifier mask",
 | 
				
			||||||
 | 
					                                "Modifier mask of the symbol",
 | 
				
			||||||
 | 
					                                EEK_TYPE_MODIFIER_TYPE,
 | 
				
			||||||
 | 
					                                0,
 | 
				
			||||||
 | 
					                                G_PARAM_CONSTRUCT | G_PARAM_READWRITE);
 | 
				
			||||||
 | 
					    g_object_class_install_property (gobject_class, PROP_MODIFIER_MASK, pspec);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    pspec = g_param_spec_string ("icon-name",
 | 
				
			||||||
 | 
					                                 "Icon name",
 | 
				
			||||||
 | 
					                                 "Icon name used to render the symbol",
 | 
				
			||||||
 | 
					                                 NULL,
 | 
				
			||||||
 | 
					                                 G_PARAM_CONSTRUCT | G_PARAM_READWRITE);
 | 
				
			||||||
 | 
					    g_object_class_install_property (gobject_class, PROP_ICON_NAME, pspec);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    pspec = g_param_spec_string ("tooltip",
 | 
				
			||||||
 | 
					                                 "Tooltip",
 | 
				
			||||||
 | 
					                                 "Tooltip text",
 | 
				
			||||||
 | 
					                                 NULL,
 | 
				
			||||||
 | 
					                                 G_PARAM_CONSTRUCT | G_PARAM_READWRITE);
 | 
				
			||||||
 | 
					    g_object_class_install_property (gobject_class, PROP_TOOLTIP, pspec);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					eek_symbol_init (EekSymbol *self)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    EekSymbolPrivate *priv = eek_symbol_get_instance_private (self);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    priv->category = EEK_SYMBOL_CATEGORY_UNKNOWN;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * eek_symbol_new:
 | 
				
			||||||
 | 
					 * @name: name of the symbol
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Create a new #EekSymbol with @name.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
EekSymbol *
 | 
					EekSymbol *
 | 
				
			||||||
eek_symbol_new (const gchar *name)
 | 
					eek_symbol_new (const gchar *name)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    EekSymbol *self = g_new0(EekSymbol, 1);
 | 
					    return g_object_new (EEK_TYPE_SYMBOL, "name", name, NULL);
 | 
				
			||||||
    self->name = g_strdup (name);
 | 
					}
 | 
				
			||||||
    self->category = EEK_SYMBOL_CATEGORY_UNKNOWN;
 | 
					
 | 
				
			||||||
    return self;
 | 
					/**
 | 
				
			||||||
 | 
					 * eek_symbol_set_name:
 | 
				
			||||||
 | 
					 * @symbol: an #EekSymbol
 | 
				
			||||||
 | 
					 * @name: name of the symbol
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Set the name of @symbol to @name.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					eek_symbol_set_name (EekSymbol   *symbol,
 | 
				
			||||||
 | 
					                     const gchar *name)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    g_return_if_fail (EEK_IS_SYMBOL(symbol));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    EekSymbolPrivate *priv = eek_symbol_get_instance_private (symbol);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    g_free (priv->name);
 | 
				
			||||||
 | 
					    priv->name = g_strdup (name);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * eek_symbol_get_name:
 | 
				
			||||||
 | 
					 * @symbol: an #EekSymbol
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Get the name of @symbol.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					const gchar *
 | 
				
			||||||
 | 
					eek_symbol_get_name (EekSymbol *symbol)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    g_return_val_if_fail (EEK_IS_SYMBOL(symbol), NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    EekSymbolPrivate *priv = eek_symbol_get_instance_private (symbol);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (priv->name == NULL || *priv->name == '\0')
 | 
				
			||||||
 | 
					        return NULL;
 | 
				
			||||||
 | 
					    return priv->name;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
@ -50,8 +307,64 @@ void
 | 
				
			|||||||
eek_symbol_set_label (EekSymbol   *symbol,
 | 
					eek_symbol_set_label (EekSymbol   *symbol,
 | 
				
			||||||
                      const gchar *label)
 | 
					                      const gchar *label)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    g_free (symbol->label);
 | 
					    g_return_if_fail (EEK_IS_SYMBOL(symbol));
 | 
				
			||||||
    symbol->label = g_strdup (label);
 | 
					
 | 
				
			||||||
 | 
					    EekSymbolPrivate *priv = eek_symbol_get_instance_private (symbol);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    g_free (priv->label);
 | 
				
			||||||
 | 
					    priv->label = g_strdup (label);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * eek_symbol_get_label:
 | 
				
			||||||
 | 
					 * @symbol: an #EekSymbol
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Get the label text of @symbol.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					const gchar *
 | 
				
			||||||
 | 
					eek_symbol_get_label (EekSymbol *symbol)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    g_return_val_if_fail (EEK_IS_SYMBOL(symbol), NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    EekSymbolPrivate *priv = eek_symbol_get_instance_private (symbol);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (priv->label == NULL || *priv->label == '\0')
 | 
				
			||||||
 | 
					        return NULL;
 | 
				
			||||||
 | 
					    return priv->label;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * eek_symbol_set_category:
 | 
				
			||||||
 | 
					 * @symbol: an #EekSymbol
 | 
				
			||||||
 | 
					 * @category: an #EekSymbolCategory
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Set symbol category of @symbol to @category.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					eek_symbol_set_category (EekSymbol        *symbol,
 | 
				
			||||||
 | 
					                         EekSymbolCategory category)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    g_return_if_fail (EEK_IS_SYMBOL(symbol));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    EekSymbolPrivate *priv = eek_symbol_get_instance_private (symbol);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    priv->category = category;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * eek_symbol_get_category:
 | 
				
			||||||
 | 
					 * @symbol: an #EekSymbol
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Get symbol category of @symbol.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					EekSymbolCategory
 | 
				
			||||||
 | 
					eek_symbol_get_category (EekSymbol *symbol)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    g_return_val_if_fail (EEK_IS_SYMBOL(symbol), EEK_SYMBOL_CATEGORY_UNKNOWN);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    EekSymbolPrivate *priv = eek_symbol_get_instance_private (symbol);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return priv->category;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
@ -65,7 +378,11 @@ void
 | 
				
			|||||||
eek_symbol_set_modifier_mask (EekSymbol      *symbol,
 | 
					eek_symbol_set_modifier_mask (EekSymbol      *symbol,
 | 
				
			||||||
                              EekModifierType mask)
 | 
					                              EekModifierType mask)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    symbol->modifier_mask = mask;
 | 
					    g_return_if_fail (EEK_IS_SYMBOL(symbol));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    EekSymbolPrivate *priv = eek_symbol_get_instance_private (symbol);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    priv->modifier_mask = mask;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
@ -77,37 +394,131 @@ eek_symbol_set_modifier_mask (EekSymbol      *symbol,
 | 
				
			|||||||
EekModifierType
 | 
					EekModifierType
 | 
				
			||||||
eek_symbol_get_modifier_mask (EekSymbol *symbol)
 | 
					eek_symbol_get_modifier_mask (EekSymbol *symbol)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    return 0;
 | 
					    g_return_val_if_fail (EEK_IS_SYMBOL(symbol), 0);
 | 
				
			||||||
    return symbol->modifier_mask;
 | 
					
 | 
				
			||||||
 | 
					    EekSymbolPrivate *priv = eek_symbol_get_instance_private (symbol);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return priv->modifier_mask;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * eek_symbol_is_modifier:
 | 
				
			||||||
 | 
					 * @symbol: an #EekSymbol
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Check if @symbol is a modifier.
 | 
				
			||||||
 | 
					 * Returns: %TRUE if @symbol is a modifier.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					gboolean
 | 
				
			||||||
 | 
					eek_symbol_is_modifier (EekSymbol *symbol)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return eek_symbol_get_modifier_mask (symbol) != 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * eek_symbol_set_icon_name:
 | 
				
			||||||
 | 
					 * @symbol: an #EekSymbol
 | 
				
			||||||
 | 
					 * @icon_name: icon name of @symbol
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Set the icon name of @symbol to @icon_name.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
void
 | 
					void
 | 
				
			||||||
eek_symbol_set_icon_name (EekSymbol   *symbol,
 | 
					eek_symbol_set_icon_name (EekSymbol   *symbol,
 | 
				
			||||||
                          const gchar *icon_name)
 | 
					                          const gchar *icon_name)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    g_free (symbol->icon_name);
 | 
					    g_return_if_fail (EEK_IS_SYMBOL(symbol));
 | 
				
			||||||
    symbol->icon_name = g_strdup (icon_name);
 | 
					
 | 
				
			||||||
 | 
					    EekSymbolPrivate *priv = eek_symbol_get_instance_private (symbol);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    g_free (priv->icon_name);
 | 
				
			||||||
 | 
					    priv->icon_name = g_strdup (icon_name);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * eek_symbol_get_icon_name:
 | 
				
			||||||
 | 
					 * @symbol: an #EekSymbol
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Get the icon name of @symbol.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
const gchar *
 | 
					const gchar *
 | 
				
			||||||
eek_symbol_get_icon_name (EekSymbol *symbol)
 | 
					eek_symbol_get_icon_name (EekSymbol *symbol)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					    g_return_val_if_fail (EEK_IS_SYMBOL(symbol), NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    EekSymbolPrivate *priv = eek_symbol_get_instance_private (symbol);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (priv->icon_name == NULL || *priv->icon_name == '\0')
 | 
				
			||||||
        return NULL;
 | 
					        return 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
 | 
					void
 | 
				
			||||||
eek_symbol_set_tooltip (EekSymbol   *symbol,
 | 
					eek_symbol_set_tooltip (EekSymbol   *symbol,
 | 
				
			||||||
                        const gchar *tooltip)
 | 
					                        const gchar *tooltip)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    g_free (symbol->tooltip);
 | 
					    g_return_if_fail (EEK_IS_SYMBOL(symbol));
 | 
				
			||||||
    symbol->tooltip = g_strdup (tooltip);
 | 
					
 | 
				
			||||||
 | 
					    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 *
 | 
					const gchar *
 | 
				
			||||||
eek_symbol_get_tooltip (EekSymbol *symbol)
 | 
					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 NULL;
 | 
				
			||||||
    if (symbol->tooltip == NULL || *symbol->tooltip == '\0')
 | 
					    return priv->tooltip;
 | 
				
			||||||
        return NULL;
 | 
					}
 | 
				
			||||||
    return symbol->tooltip;
 | 
					
 | 
				
			||||||
 | 
					static const struct {
 | 
				
			||||||
 | 
					    EekSymbolCategory category;
 | 
				
			||||||
 | 
					    gchar *name;
 | 
				
			||||||
 | 
					} category_names[] = {
 | 
				
			||||||
 | 
					    { EEK_SYMBOL_CATEGORY_LETTER, "letter" },
 | 
				
			||||||
 | 
					    { EEK_SYMBOL_CATEGORY_FUNCTION, "function" },
 | 
				
			||||||
 | 
					    { EEK_SYMBOL_CATEGORY_KEYNAME, "keyname" },
 | 
				
			||||||
 | 
					    { EEK_SYMBOL_CATEGORY_USER0, "user0" },
 | 
				
			||||||
 | 
					    { EEK_SYMBOL_CATEGORY_USER1, "user1" },
 | 
				
			||||||
 | 
					    { EEK_SYMBOL_CATEGORY_USER2, "user2" },
 | 
				
			||||||
 | 
					    { EEK_SYMBOL_CATEGORY_USER3, "user3" },
 | 
				
			||||||
 | 
					    { EEK_SYMBOL_CATEGORY_USER4, "user4" },
 | 
				
			||||||
 | 
					    { EEK_SYMBOL_CATEGORY_UNKNOWN, NULL }
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const gchar *
 | 
				
			||||||
 | 
					eek_symbol_category_get_name (EekSymbolCategory category)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    gint i;
 | 
				
			||||||
 | 
					    for (i = 0; i < G_N_ELEMENTS(category_names); i++)
 | 
				
			||||||
 | 
					        if (category_names[i].category == category)
 | 
				
			||||||
 | 
					            return category_names[i].name;
 | 
				
			||||||
 | 
					    return NULL;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					EekSymbolCategory
 | 
				
			||||||
 | 
					eek_symbol_category_from_name (const gchar *name)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    gint i;
 | 
				
			||||||
 | 
					    for (i = 0; i < G_N_ELEMENTS(category_names); i++)
 | 
				
			||||||
 | 
					        if (g_strcmp0 (category_names[i].name, name) == 0)
 | 
				
			||||||
 | 
					            return category_names[i].category;
 | 
				
			||||||
 | 
					    return EEK_SYMBOL_CATEGORY_UNKNOWN;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										100
									
								
								eek/eek-symbol.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,100 @@
 | 
				
			|||||||
 | 
					/* 
 | 
				
			||||||
 | 
					 * Copyright (C) 2011 Daiki Ueno <ueno@unixuser.org>
 | 
				
			||||||
 | 
					 * Copyright (C) 2011 Red Hat, Inc.
 | 
				
			||||||
 | 
					 * 
 | 
				
			||||||
 | 
					 * This library is free software; you can redistribute it and/or
 | 
				
			||||||
 | 
					 * modify it under the terms of the GNU Lesser General Public License
 | 
				
			||||||
 | 
					 * as published by the Free Software Foundation; either version 2 of
 | 
				
			||||||
 | 
					 * the License, or (at your option) any later version.
 | 
				
			||||||
 | 
					 * 
 | 
				
			||||||
 | 
					 * This library is distributed in the hope that it will be useful, but
 | 
				
			||||||
 | 
					 * WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
				
			||||||
 | 
					 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
				
			||||||
 | 
					 * Lesser General Public License for more details.
 | 
				
			||||||
 | 
					 * 
 | 
				
			||||||
 | 
					 * You should have received a copy of the GNU Lesser General Public
 | 
				
			||||||
 | 
					 * License along with this library; if not, write to the Free Software
 | 
				
			||||||
 | 
					 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 | 
				
			||||||
 | 
					 * 02110-1301 USA
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if !defined(__EEK_H_INSIDE__) && !defined(EEK_COMPILATION)
 | 
				
			||||||
 | 
					#error "Only <eek/eek.h> can be included directly."
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef EEK_SYMBOL_H
 | 
				
			||||||
 | 
					#define EEK_SYMBOL_H 1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "eek-types.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					G_BEGIN_DECLS
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * EekSymbolCategory:
 | 
				
			||||||
 | 
					 * @EEK_SYMBOL_CATEGORY_LETTER: the symbol represents an alphabet letter
 | 
				
			||||||
 | 
					 * @EEK_SYMBOL_CATEGORY_FUNCTION: the symbol represents a function
 | 
				
			||||||
 | 
					 * @EEK_SYMBOL_CATEGORY_KEYNAME: the symbol does not have meaning but
 | 
				
			||||||
 | 
					 * have a name
 | 
				
			||||||
 | 
					 * @EEK_SYMBOL_CATEGORY_USER0: reserved for future use
 | 
				
			||||||
 | 
					 * @EEK_SYMBOL_CATEGORY_USER1: reserved for future use
 | 
				
			||||||
 | 
					 * @EEK_SYMBOL_CATEGORY_USER2: reserved for future use
 | 
				
			||||||
 | 
					 * @EEK_SYMBOL_CATEGORY_USER3: reserved for future use
 | 
				
			||||||
 | 
					 * @EEK_SYMBOL_CATEGORY_USER4: reserved for future use
 | 
				
			||||||
 | 
					 * @EEK_SYMBOL_CATEGORY_UNKNOWN: used for error reporting
 | 
				
			||||||
 | 
					 * @EEK_SYMBOL_CATEGORY_LAST: the last symbol category
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Category of the key symbols.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					typedef enum {
 | 
				
			||||||
 | 
					    EEK_SYMBOL_CATEGORY_LETTER,
 | 
				
			||||||
 | 
					    EEK_SYMBOL_CATEGORY_FUNCTION,
 | 
				
			||||||
 | 
					    EEK_SYMBOL_CATEGORY_KEYNAME,
 | 
				
			||||||
 | 
					    EEK_SYMBOL_CATEGORY_USER0,
 | 
				
			||||||
 | 
					    EEK_SYMBOL_CATEGORY_USER1,
 | 
				
			||||||
 | 
					    EEK_SYMBOL_CATEGORY_USER2,
 | 
				
			||||||
 | 
					    EEK_SYMBOL_CATEGORY_USER3,
 | 
				
			||||||
 | 
					    EEK_SYMBOL_CATEGORY_USER4,
 | 
				
			||||||
 | 
					    EEK_SYMBOL_CATEGORY_UNKNOWN,
 | 
				
			||||||
 | 
					    EEK_SYMBOL_CATEGORY_LAST = EEK_SYMBOL_CATEGORY_UNKNOWN
 | 
				
			||||||
 | 
					} EekSymbolCategory;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define EEK_TYPE_SYMBOL (eek_symbol_get_type())
 | 
				
			||||||
 | 
					G_DECLARE_DERIVABLE_TYPE(EekSymbol, eek_symbol, EEK, SYMBOL, GObject)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * EekSymbolClass:
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					struct _EekSymbolClass {
 | 
				
			||||||
 | 
					    /*< private >*/
 | 
				
			||||||
 | 
					    GObjectClass parent_class;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					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);
 | 
				
			||||||
 | 
					const gchar      *eek_symbol_get_name           (EekSymbol        *symbol);
 | 
				
			||||||
 | 
					void              eek_symbol_set_label          (EekSymbol        *symbol,
 | 
				
			||||||
 | 
					                                                 const gchar      *label);
 | 
				
			||||||
 | 
					const gchar      *eek_symbol_get_label          (EekSymbol        *symbol);
 | 
				
			||||||
 | 
					void              eek_symbol_set_category       (EekSymbol        *symbol,
 | 
				
			||||||
 | 
					                                                 EekSymbolCategory category);
 | 
				
			||||||
 | 
					EekSymbolCategory eek_symbol_get_category       (EekSymbol        *symbol);
 | 
				
			||||||
 | 
					EekModifierType   eek_symbol_get_modifier_mask  (EekSymbol        *symbol);
 | 
				
			||||||
 | 
					void              eek_symbol_set_modifier_mask  (EekSymbol        *symbol,
 | 
				
			||||||
 | 
					                                                 EekModifierType   mask);
 | 
				
			||||||
 | 
					gboolean          eek_symbol_is_modifier        (EekSymbol        *symbol);
 | 
				
			||||||
 | 
					void              eek_symbol_set_icon_name      (EekSymbol        *symbol,
 | 
				
			||||||
 | 
					                                                 const gchar      *icon_name);
 | 
				
			||||||
 | 
					const gchar      *eek_symbol_get_icon_name      (EekSymbol        *symbol);
 | 
				
			||||||
 | 
					void              eek_symbol_set_tooltip        (EekSymbol        *symbol,
 | 
				
			||||||
 | 
					                                                 const gchar      *tooltip);
 | 
				
			||||||
 | 
					const gchar *     eek_symbol_get_tooltip        (EekSymbol        *symbol);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const gchar      *eek_symbol_category_get_name  (EekSymbolCategory category);
 | 
				
			||||||
 | 
					EekSymbolCategory eek_symbol_category_from_name (const gchar      *name);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					G_END_DECLS
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif  /* EEK_SYMBOL_H */
 | 
				
			||||||
							
								
								
									
										187
									
								
								eek/eek-text.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,187 @@
 | 
				
			|||||||
 | 
					/* 
 | 
				
			||||||
 | 
					 * Copyright (C) 2011 Daiki Ueno <ueno@unixuser.org>
 | 
				
			||||||
 | 
					 * Copyright (C) 2011 Red Hat, Inc.
 | 
				
			||||||
 | 
					 * 
 | 
				
			||||||
 | 
					 * This library is free software; you can redistribute it and/or
 | 
				
			||||||
 | 
					 * modify it under the terms of the GNU Lesser General Public License
 | 
				
			||||||
 | 
					 * as published by the Free Software Foundation; either version 2 of
 | 
				
			||||||
 | 
					 * the License, or (at your option) any later version.
 | 
				
			||||||
 | 
					 * 
 | 
				
			||||||
 | 
					 * This library is distributed in the hope that it will be useful, but
 | 
				
			||||||
 | 
					 * WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
				
			||||||
 | 
					 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
				
			||||||
 | 
					 * Lesser General Public License for more details.
 | 
				
			||||||
 | 
					 * 
 | 
				
			||||||
 | 
					 * You should have received a copy of the GNU Lesser General Public
 | 
				
			||||||
 | 
					 * License along with this library; if not, write to the Free Software
 | 
				
			||||||
 | 
					 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 | 
				
			||||||
 | 
					 * 02110-1301 USA
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * SECTION:eek-text
 | 
				
			||||||
 | 
					 * @short_description: an #EekText represents a text symbol
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef HAVE_CONFIG_H
 | 
				
			||||||
 | 
					#include "config.h"
 | 
				
			||||||
 | 
					#endif  /* HAVE_CONFIG_H */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "eek-text.h"
 | 
				
			||||||
 | 
					#include "eek-serializable.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					enum {
 | 
				
			||||||
 | 
					    PROP_0,
 | 
				
			||||||
 | 
					    PROP_TEXT,
 | 
				
			||||||
 | 
					    PROP_LAST
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef struct _EekTextPrivate
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    gchar *text;
 | 
				
			||||||
 | 
					} EekTextPrivate;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void eek_serializable_iface_init (EekSerializableIface *iface);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					G_DEFINE_TYPE_EXTENDED (EekText,
 | 
				
			||||||
 | 
								eek_text,
 | 
				
			||||||
 | 
								EEK_TYPE_SYMBOL,
 | 
				
			||||||
 | 
								0, /* GTypeFlags */
 | 
				
			||||||
 | 
								G_ADD_PRIVATE (EekText)
 | 
				
			||||||
 | 
					                        G_IMPLEMENT_INTERFACE (EEK_TYPE_SERIALIZABLE,
 | 
				
			||||||
 | 
					                                               eek_serializable_iface_init))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static EekSerializableIface *eek_text_parent_serializable_iface;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					eek_text_real_serialize (EekSerializable *self,
 | 
				
			||||||
 | 
					                         GVariantBuilder *builder)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    EekTextPrivate *priv = eek_text_get_instance_private (EEK_TEXT (self));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    eek_text_parent_serializable_iface->serialize (self, builder);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    g_variant_builder_add (builder, "s", priv->text);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static gsize
 | 
				
			||||||
 | 
					eek_text_real_deserialize (EekSerializable *self,
 | 
				
			||||||
 | 
					                           GVariant        *variant,
 | 
				
			||||||
 | 
					                           gsize            index)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    EekTextPrivate *priv = eek_text_get_instance_private (EEK_TEXT (self));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    index = eek_text_parent_serializable_iface->deserialize (self,
 | 
				
			||||||
 | 
					                                                             variant,
 | 
				
			||||||
 | 
					                                                             index);
 | 
				
			||||||
 | 
					    g_variant_get_child (variant, index++, "s", &priv->text);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return index;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					eek_serializable_iface_init (EekSerializableIface *iface)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    eek_text_parent_serializable_iface =
 | 
				
			||||||
 | 
					        g_type_interface_peek_parent (iface);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    iface->serialize = eek_text_real_serialize;
 | 
				
			||||||
 | 
					    iface->deserialize = eek_text_real_deserialize;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					eek_text_set_property (GObject      *object,
 | 
				
			||||||
 | 
					                       guint         prop_id,
 | 
				
			||||||
 | 
					                       const GValue *value,
 | 
				
			||||||
 | 
					                       GParamSpec   *pspec)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    EekText        *self = EEK_TEXT (object);
 | 
				
			||||||
 | 
					    EekTextPrivate *priv = eek_text_get_instance_private (self);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    switch (prop_id) {
 | 
				
			||||||
 | 
					    case PROP_TEXT:
 | 
				
			||||||
 | 
					        g_free (priv->text);
 | 
				
			||||||
 | 
					        priv->text = g_strdup (g_value_get_string (value));
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					    default:
 | 
				
			||||||
 | 
					        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					eek_text_get_property (GObject    *object,
 | 
				
			||||||
 | 
					                       guint       prop_id,
 | 
				
			||||||
 | 
					                       GValue     *value,
 | 
				
			||||||
 | 
					                       GParamSpec *pspec)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    EekText        *self = EEK_TEXT (object);
 | 
				
			||||||
 | 
					    EekTextPrivate *priv = eek_text_get_instance_private (self);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    switch (prop_id) {
 | 
				
			||||||
 | 
					    case PROP_TEXT:
 | 
				
			||||||
 | 
					        g_value_set_string (value, priv->text);
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					    default:
 | 
				
			||||||
 | 
					        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					eek_text_finalize (GObject *object)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    EekText        *self = EEK_TEXT (object);
 | 
				
			||||||
 | 
					    EekTextPrivate *priv = eek_text_get_instance_private (self);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    g_free (priv->text);
 | 
				
			||||||
 | 
					    G_OBJECT_CLASS (eek_text_parent_class)->finalize (object);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					eek_text_class_init (EekTextClass *klass)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
 | 
				
			||||||
 | 
					    GParamSpec *pspec;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    gobject_class->set_property = eek_text_set_property;
 | 
				
			||||||
 | 
					    gobject_class->get_property = eek_text_get_property;
 | 
				
			||||||
 | 
					    gobject_class->finalize = eek_text_finalize;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    pspec = g_param_spec_string ("text",
 | 
				
			||||||
 | 
					                                 "Text",
 | 
				
			||||||
 | 
					                                 "Text",
 | 
				
			||||||
 | 
					                                 NULL,
 | 
				
			||||||
 | 
					                                 G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE);
 | 
				
			||||||
 | 
					    g_object_class_install_property (gobject_class, PROP_TEXT, pspec);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					eek_text_init (EekText *self)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    /* void */
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					EekText *
 | 
				
			||||||
 | 
					eek_text_new (const gchar *text)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return g_object_new (EEK_TYPE_TEXT,
 | 
				
			||||||
 | 
					                         "label", text,
 | 
				
			||||||
 | 
					                         "category", EEK_SYMBOL_CATEGORY_FUNCTION,
 | 
				
			||||||
 | 
					                         "text", text,
 | 
				
			||||||
 | 
					                         NULL);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * eek_text_get_text:
 | 
				
			||||||
 | 
					 * @text: an #EekText
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Get a text value associated with @text
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					const gchar *
 | 
				
			||||||
 | 
					eek_text_get_text (EekText *text)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    EekTextPrivate *priv = eek_text_get_instance_private (text);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return priv->text;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										46
									
								
								eek/eek-text.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,46 @@
 | 
				
			|||||||
 | 
					/* 
 | 
				
			||||||
 | 
					 * Copyright (C) 2011 Daiki Ueno <ueno@unixuser.org>
 | 
				
			||||||
 | 
					 * Copyright (C) 2011 Red Hat, Inc.
 | 
				
			||||||
 | 
					 * 
 | 
				
			||||||
 | 
					 * This library is free software; you can redistribute it and/or
 | 
				
			||||||
 | 
					 * modify it under the terms of the GNU Lesser General Public License
 | 
				
			||||||
 | 
					 * as published by the Free Software Foundation; either version 2 of
 | 
				
			||||||
 | 
					 * the License, or (at your option) any later version.
 | 
				
			||||||
 | 
					 * 
 | 
				
			||||||
 | 
					 * This library is distributed in the hope that it will be useful, but
 | 
				
			||||||
 | 
					 * WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
				
			||||||
 | 
					 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
				
			||||||
 | 
					 * Lesser General Public License for more details.
 | 
				
			||||||
 | 
					 * 
 | 
				
			||||||
 | 
					 * You should have received a copy of the GNU Lesser General Public
 | 
				
			||||||
 | 
					 * License along with this library; if not, write to the Free Software
 | 
				
			||||||
 | 
					 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 | 
				
			||||||
 | 
					 * 02110-1301 USA
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if !defined(__EEK_H_INSIDE__) && !defined(EEK_COMPILATION)
 | 
				
			||||||
 | 
					#error "Only <eek/eek.h> can be included directly."
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef EEK_TEXT_H
 | 
				
			||||||
 | 
					#define EEK_TEXT_H 1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "eek-symbol.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					G_BEGIN_DECLS
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define EEK_TYPE_TEXT (eek_text_get_type())
 | 
				
			||||||
 | 
					G_DECLARE_DERIVABLE_TYPE(EekText, eek_text, EEK, TEXT, EekSymbol)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct _EekTextClass {
 | 
				
			||||||
 | 
					    /*< private >*/
 | 
				
			||||||
 | 
					    EekSymbolClass parent_class;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					GType        eek_text_get_type (void) G_GNUC_CONST;
 | 
				
			||||||
 | 
					EekText     *eek_text_new      (const gchar *text);
 | 
				
			||||||
 | 
					const gchar *eek_text_get_text (EekText     *text);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					G_END_DECLS
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif  /* EEK_TEXT_H */
 | 
				
			||||||
							
								
								
									
										289
									
								
								eek/eek-theme-context.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,289 @@
 | 
				
			|||||||
 | 
					/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; c-basic-offset: 2; -*- */
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * eek-theme-context.c: holds global information about a tree of styled objects
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Copyright 2009, 2010 Red Hat, Inc.
 | 
				
			||||||
 | 
					 * Copyright 2009 Florian Müllner
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * This program is free software; you can redistribute it and/or modify
 | 
				
			||||||
 | 
					 * it under the terms of the GNU Lesser General Public License as
 | 
				
			||||||
 | 
					 * published by the Free Software Foundation, either version 2.1 of
 | 
				
			||||||
 | 
					 * the License, or (at your option) any later version.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * This program is distributed in the hope it will be useful, but WITHOUT ANY
 | 
				
			||||||
 | 
					 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 | 
				
			||||||
 | 
					 * FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for
 | 
				
			||||||
 | 
					 * more details.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * You should have received a copy of the GNU Lesser General Public License
 | 
				
			||||||
 | 
					 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef HAVE_CONFIG_H
 | 
				
			||||||
 | 
					#include "config.h"
 | 
				
			||||||
 | 
					#endif  /* HAVE_CONFIG_H */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "eek-theme.h"
 | 
				
			||||||
 | 
					#include "eek-theme-context.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct _EekThemeContext {
 | 
				
			||||||
 | 
					  GObject parent;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  double resolution;
 | 
				
			||||||
 | 
					  PangoFontDescription *font;
 | 
				
			||||||
 | 
					  EekThemeNode *root_node;
 | 
				
			||||||
 | 
					  EekTheme *theme;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct _EekThemeContextClass {
 | 
				
			||||||
 | 
					  GObjectClass parent_class;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define DEFAULT_RESOLUTION 96.
 | 
				
			||||||
 | 
					#define DEFAULT_FONT "sans-serif 10"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					enum
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  CHANGED,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  LAST_SIGNAL
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static guint signals[LAST_SIGNAL] = { 0, };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					G_DEFINE_TYPE (EekThemeContext, eek_theme_context, G_TYPE_OBJECT)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					eek_theme_context_finalize (GObject *object)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  EekThemeContext *context = EEK_THEME_CONTEXT (object);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (context->root_node)
 | 
				
			||||||
 | 
					    g_object_unref (context->root_node);
 | 
				
			||||||
 | 
					  if (context->theme)
 | 
				
			||||||
 | 
					    g_object_unref (context->theme);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  pango_font_description_free (context->font);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  G_OBJECT_CLASS (eek_theme_context_parent_class)->finalize (object);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					eek_theme_context_class_init (EekThemeContextClass *klass)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  GObjectClass *object_class = G_OBJECT_CLASS (klass);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  object_class->finalize = eek_theme_context_finalize;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  signals[CHANGED] =
 | 
				
			||||||
 | 
					    g_signal_new ("changed",
 | 
				
			||||||
 | 
					                  G_TYPE_FROM_CLASS (klass),
 | 
				
			||||||
 | 
					                  G_SIGNAL_RUN_LAST,
 | 
				
			||||||
 | 
					                  0, /* no default handler slot */
 | 
				
			||||||
 | 
					                  NULL, NULL,
 | 
				
			||||||
 | 
					                  g_cclosure_marshal_VOID__VOID,
 | 
				
			||||||
 | 
					                  G_TYPE_NONE, 0);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					eek_theme_context_init (EekThemeContext *context)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  context->resolution = DEFAULT_RESOLUTION;
 | 
				
			||||||
 | 
					  context->font = pango_font_description_from_string (DEFAULT_FONT);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * eek_theme_context_new:
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Create a new theme context.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					EekThemeContext *
 | 
				
			||||||
 | 
					eek_theme_context_new (void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  EekThemeContext *context;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  context = g_object_new (EEK_TYPE_THEME_CONTEXT, NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return context;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					eek_theme_context_changed (EekThemeContext *context)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  EekThemeNode *old_root = context->root_node;
 | 
				
			||||||
 | 
					  context->root_node = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  g_signal_emit (context, signals[CHANGED], 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (old_root)
 | 
				
			||||||
 | 
					    g_object_unref (old_root);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * eek_theme_context_set_theme:
 | 
				
			||||||
 | 
					 * @context: an #EekThemeContext
 | 
				
			||||||
 | 
					 * @theme: an #EekTheme
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Sets the default set of theme stylesheets for the context. This theme will
 | 
				
			||||||
 | 
					 * be used for the root node and for nodes descending from it, unless some other
 | 
				
			||||||
 | 
					 * style is explicitely specified.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					eek_theme_context_set_theme (EekThemeContext          *context,
 | 
				
			||||||
 | 
					                            EekTheme                 *theme)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  g_return_if_fail (EEK_IS_THEME_CONTEXT (context));
 | 
				
			||||||
 | 
					  g_return_if_fail (theme == NULL || EEK_IS_THEME (theme));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (context->theme != theme)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      if (context->theme)
 | 
				
			||||||
 | 
					        g_object_unref (context->theme);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      context->theme = theme;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      if (context->theme)
 | 
				
			||||||
 | 
					        g_object_ref (context->theme);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      eek_theme_context_changed (context);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * eek_theme_context_get_theme:
 | 
				
			||||||
 | 
					 * @context: a #EekThemeContext
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Gets the default theme for the context. See eek_theme_context_set_theme()
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Return value: (transfer none): the default theme for the context
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					EekTheme *
 | 
				
			||||||
 | 
					eek_theme_context_get_theme (EekThemeContext *context)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  g_return_val_if_fail (EEK_IS_THEME_CONTEXT (context), NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return context->theme;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * eek_theme_context_set_resolution:
 | 
				
			||||||
 | 
					 * @context: a #EekThemeContext
 | 
				
			||||||
 | 
					 * @resolution: resolution of the context (number of pixels in an "inch")
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Sets the resolution of the theme context. This is the scale factor
 | 
				
			||||||
 | 
					 * used to convert between points and the length units pt, in, and cm.
 | 
				
			||||||
 | 
					 * This does not necessarily need to correspond to the actual number
 | 
				
			||||||
 | 
					 * resolution of the device. A value of 72. means that points and
 | 
				
			||||||
 | 
					 * pixels are identical. The default value is 96.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					eek_theme_context_set_resolution (EekThemeContext *context,
 | 
				
			||||||
 | 
					                                 double          resolution)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  g_return_if_fail (EEK_IS_THEME_CONTEXT (context));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (resolution == context->resolution)
 | 
				
			||||||
 | 
					    return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  context->resolution = resolution;
 | 
				
			||||||
 | 
					  eek_theme_context_changed (context);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * eek_theme_context_set_default_resolution:
 | 
				
			||||||
 | 
					 * @context: a #EekThemeContext
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Sets the resolution of the theme context to the default value of 96.
 | 
				
			||||||
 | 
					 * See eek_theme_context_set_resolution().
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					eek_theme_context_set_default_resolution (EekThemeContext *context)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  g_return_if_fail (EEK_IS_THEME_CONTEXT (context));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (context->resolution == DEFAULT_RESOLUTION)
 | 
				
			||||||
 | 
					    return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  context->resolution = DEFAULT_RESOLUTION;
 | 
				
			||||||
 | 
					  eek_theme_context_changed (context);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * eek_theme_context_get_resolution:
 | 
				
			||||||
 | 
					 * @context: a #EekThemeContext
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Gets the current resolution of the theme context.
 | 
				
			||||||
 | 
					 * See eek_theme_context_set_resolution().
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Return value: the resolution (in dots-per-"inch")
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					double
 | 
				
			||||||
 | 
					eek_theme_context_get_resolution (EekThemeContext *context)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  g_return_val_if_fail (EEK_IS_THEME_CONTEXT (context), DEFAULT_RESOLUTION);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return context->resolution;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * eek_theme_context_set_font:
 | 
				
			||||||
 | 
					 * @context: a #EekThemeContext
 | 
				
			||||||
 | 
					 * @font: the default font for theme context
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Sets the default font for the theme context. This is the font that
 | 
				
			||||||
 | 
					 * is inherited by the root node of the tree of theme nodes. If the
 | 
				
			||||||
 | 
					 * font is not overriden, then this font will be used. If the font is
 | 
				
			||||||
 | 
					 * partially modified (for example, with 'font-size: 110%', then that
 | 
				
			||||||
 | 
					 * modification is based on this font.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					eek_theme_context_set_font (EekThemeContext             *context,
 | 
				
			||||||
 | 
					                           const PangoFontDescription *font)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  g_return_if_fail (EEK_IS_THEME_CONTEXT (context));
 | 
				
			||||||
 | 
					  g_return_if_fail (font != NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (context->font == font ||
 | 
				
			||||||
 | 
					      pango_font_description_equal (context->font, font))
 | 
				
			||||||
 | 
					    return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  pango_font_description_free (context->font);
 | 
				
			||||||
 | 
					  context->font = pango_font_description_copy (font);
 | 
				
			||||||
 | 
					  eek_theme_context_changed (context);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * eek_theme_context_get_font:
 | 
				
			||||||
 | 
					 * @context: a #EekThemeContext
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Gets the default font for the theme context. See eek_theme_context_set_font().
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Return value: the default font for the theme context.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					const PangoFontDescription *
 | 
				
			||||||
 | 
					eek_theme_context_get_font (EekThemeContext *context)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  g_return_val_if_fail (EEK_IS_THEME_CONTEXT (context), NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return context->font;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * eek_theme_context_get_root_node:
 | 
				
			||||||
 | 
					 * @context: a #EekThemeContext
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Gets the root node of the tree of theme style nodes that associated with this
 | 
				
			||||||
 | 
					 * context. For the node tree associated with a stage, this node represents
 | 
				
			||||||
 | 
					 * styles applied to the stage itself.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Return value: (transfer none): the root node of the context's style tree
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					EekThemeNode *
 | 
				
			||||||
 | 
					eek_theme_context_get_root_node (EekThemeContext *context)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  if (context->root_node == NULL)
 | 
				
			||||||
 | 
					    context->root_node = eek_theme_node_new (context, NULL, context->theme,
 | 
				
			||||||
 | 
					                                             G_TYPE_NONE, NULL, NULL, NULL, NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return context->root_node;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										78
									
								
								eek/eek-theme-context.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,78 @@
 | 
				
			|||||||
 | 
					/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * eek-theme-context.c: holds global information about a tree of styled objects
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Copyright 2009, 2010 Red Hat, Inc.
 | 
				
			||||||
 | 
					 * Copyright 2009 Florian Müllner
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * This program is free software; you can redistribute it and/or modify
 | 
				
			||||||
 | 
					 * it under the terms of the GNU Lesser General Public License as
 | 
				
			||||||
 | 
					 * published by the Free Software Foundation, either version 2.1 of
 | 
				
			||||||
 | 
					 * the License, or (at your option) any later version.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * This program is distributed in the hope it will be useful, but WITHOUT ANY
 | 
				
			||||||
 | 
					 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 | 
				
			||||||
 | 
					 * FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for
 | 
				
			||||||
 | 
					 * more details.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * You should have received a copy of the GNU Lesser General Public License
 | 
				
			||||||
 | 
					 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef __EEK_THEME_CONTEXT_H__
 | 
				
			||||||
 | 
					#define __EEK_THEME_CONTEXT_H__
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <pango/pango.h>
 | 
				
			||||||
 | 
					#include "eek-theme-node.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					G_BEGIN_DECLS
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * SECTION:eek-theme-context
 | 
				
			||||||
 | 
					 * @short_description: holds global information about a tree of styled objects
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * #EekThemeContext is responsible for managing information global to
 | 
				
			||||||
 | 
					 * a tree of styled objects, such as the set of stylesheets or the
 | 
				
			||||||
 | 
					 * default font.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef struct _EekThemeContextClass EekThemeContextClass;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define EEK_TYPE_THEME_CONTEXT             (eek_theme_context_get_type ())
 | 
				
			||||||
 | 
					#define EEK_THEME_CONTEXT(object)          (G_TYPE_CHECK_INSTANCE_CAST ((object), EEK_TYPE_THEME_CONTEXT, EekThemeContext))
 | 
				
			||||||
 | 
					#define EEK_THEME_CONTEXT_CLASS(klass)     (G_TYPE_CHECK_CLASS_CAST ((klass), EEK_TYPE_THEME_CONTEXT, EekThemeContextClass))
 | 
				
			||||||
 | 
					#define EEK_IS_THEME_CONTEXT(object)       (G_TYPE_CHECK_INSTANCE_TYPE ((object), EEK_TYPE_THEME_CONTEXT))
 | 
				
			||||||
 | 
					#define EEK_IS_THEME_CONTEXT_CLASS(klass)  (G_TYPE_CHECK_CLASS_TYPE ((klass), EEK_TYPE_THEME_CONTEXT))
 | 
				
			||||||
 | 
					#define EEK_THEME_CONTEXT_GET_CLASS(obj)   (G_TYPE_INSTANCE_GET_CLASS ((obj), EEK_TYPE_THEME_CONTEXT, EekThemeContextClass))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					GType                       eek_theme_context_get_type
 | 
				
			||||||
 | 
					                            (void) G_GNUC_CONST;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					EekThemeContext            *eek_theme_context_new
 | 
				
			||||||
 | 
					                            (void);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void                        eek_theme_context_set_theme
 | 
				
			||||||
 | 
					                            (EekThemeContext            *context,
 | 
				
			||||||
 | 
					                             EekTheme                   *theme);
 | 
				
			||||||
 | 
					EekTheme *                  eek_theme_context_get_theme
 | 
				
			||||||
 | 
					                            (EekThemeContext            *context);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void                        eek_theme_context_set_resolution
 | 
				
			||||||
 | 
					                            (EekThemeContext            *context,
 | 
				
			||||||
 | 
					                             gdouble                     resolution);
 | 
				
			||||||
 | 
					void                        eek_theme_context_set_default_resolution
 | 
				
			||||||
 | 
					                            (EekThemeContext            *context);
 | 
				
			||||||
 | 
					double                      eek_theme_context_get_resolution
 | 
				
			||||||
 | 
					                            (EekThemeContext            *context);
 | 
				
			||||||
 | 
					void                        eek_theme_context_set_font
 | 
				
			||||||
 | 
					                            (EekThemeContext            *context,
 | 
				
			||||||
 | 
					                             const PangoFontDescription *font);
 | 
				
			||||||
 | 
					const PangoFontDescription *eek_theme_context_get_font
 | 
				
			||||||
 | 
					                            (EekThemeContext            *context);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					EekThemeNode *              eek_theme_context_get_root_node
 | 
				
			||||||
 | 
					                            (EekThemeContext            *context);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					G_END_DECLS
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif /* __EEK_THEME_CONTEXT_H__ */
 | 
				
			||||||
							
								
								
									
										1869
									
								
								eek/eek-theme-node.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
							
								
								
									
										141
									
								
								eek/eek-theme-node.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,141 @@
 | 
				
			|||||||
 | 
					/* 
 | 
				
			||||||
 | 
					 * Copyright (C) 2010-2011 Daiki Ueno <ueno@unixuser.org>
 | 
				
			||||||
 | 
					 * Copyright (C) 2010-2011 Red Hat, Inc.
 | 
				
			||||||
 | 
					 * 
 | 
				
			||||||
 | 
					 * This library is free software; you can redistribute it and/or
 | 
				
			||||||
 | 
					 * modify it under the terms of the GNU Lesser General Public License
 | 
				
			||||||
 | 
					 * as published by the Free Software Foundation; either version 2 of
 | 
				
			||||||
 | 
					 * the License, or (at your option) any later version.
 | 
				
			||||||
 | 
					 * 
 | 
				
			||||||
 | 
					 * This library is distributed in the hope that it will be useful, but
 | 
				
			||||||
 | 
					 * WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
				
			||||||
 | 
					 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
				
			||||||
 | 
					 * Lesser General Public License for more details.
 | 
				
			||||||
 | 
					 * 
 | 
				
			||||||
 | 
					 * You should have received a copy of the GNU Lesser General Public
 | 
				
			||||||
 | 
					 * License along with this library; if not, write to the Free Software
 | 
				
			||||||
 | 
					 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 | 
				
			||||||
 | 
					 * 02110-1301 USA
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					#ifndef __EEK_THEME_NODE_H__
 | 
				
			||||||
 | 
					#define __EEK_THEME_NODE_H__
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <pango/pango.h>
 | 
				
			||||||
 | 
					#include "eek-types.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					G_BEGIN_DECLS
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * SECTION:eek-theme-node
 | 
				
			||||||
 | 
					 * @short_description: style information for one node in a tree of
 | 
				
			||||||
 | 
					 * themed objects
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * The #EekThemeNode class represents the CSS style information (the
 | 
				
			||||||
 | 
					 * set of CSS properties) for one node in a tree of themed objects. In
 | 
				
			||||||
 | 
					 * typical usage, it represents the style information for a single
 | 
				
			||||||
 | 
					 * #EekElement. A #EekThemeNode is immutable: attributes such as the
 | 
				
			||||||
 | 
					 * CSS classes for the node are passed in at construction. If the
 | 
				
			||||||
 | 
					 * attributes of the node or any parent node change, the node should
 | 
				
			||||||
 | 
					 * be discarded and a new node created.  #EekThemeNode has generic
 | 
				
			||||||
 | 
					 * accessors to look up properties by name and specific accessors for
 | 
				
			||||||
 | 
					 * standard CSS properties that add caching and handling of various
 | 
				
			||||||
 | 
					 * details of the CSS specification. #EekThemeNode also has
 | 
				
			||||||
 | 
					 * convenience functions to help in implementing a #EekElement with
 | 
				
			||||||
 | 
					 * borders and padding.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef enum {
 | 
				
			||||||
 | 
					    EEK_SIDE_TOP,
 | 
				
			||||||
 | 
					    EEK_SIDE_RIGHT,
 | 
				
			||||||
 | 
					    EEK_SIDE_BOTTOM,
 | 
				
			||||||
 | 
					    EEK_SIDE_LEFT
 | 
				
			||||||
 | 
					} EekSide;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef enum {
 | 
				
			||||||
 | 
					    EEK_CORNER_TOPLEFT,
 | 
				
			||||||
 | 
					    EEK_CORNER_TOPRIGHT,
 | 
				
			||||||
 | 
					    EEK_CORNER_BOTTOMRIGHT,
 | 
				
			||||||
 | 
					    EEK_CORNER_BOTTOMLEFT
 | 
				
			||||||
 | 
					} EekCorner;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define EEK_TYPE_THEME_NODE (eek_theme_node_get_type())
 | 
				
			||||||
 | 
					#define EEK_THEME_NODE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EEK_TYPE_THEME_NODE, EekThemeNode))
 | 
				
			||||||
 | 
					#define EEK_THEME_NODE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EEK_TYPE_THEME_NODE, EekThemeNodeClass))
 | 
				
			||||||
 | 
					#define EEK_IS_THEME_NODE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EEK_TYPE_THEME_NODE))
 | 
				
			||||||
 | 
					#define EEK_IS_THEME_NODE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EEK_TYPE_THEME_NODE))
 | 
				
			||||||
 | 
					#define EEK_THEME_NODE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EEK_TYPE_THEME_NODE, EekThemeNodeClass))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef struct _EekThemeNodeClass EekThemeNodeClass;
 | 
				
			||||||
 | 
					typedef struct _EekThemeNodePrivate EekThemeNodePrivate;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					GType         eek_theme_node_get_type
 | 
				
			||||||
 | 
					                                 (void) G_GNUC_CONST;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					EekThemeNode *eek_theme_node_new (EekThemeContext            *context,
 | 
				
			||||||
 | 
					                                  EekThemeNode               *parent_node,
 | 
				
			||||||
 | 
					                                  /* can be null */ EekTheme *theme,
 | 
				
			||||||
 | 
					                                  /* can be null */ GType     element_type,
 | 
				
			||||||
 | 
					                                  const char                 *element_id,
 | 
				
			||||||
 | 
					                                  const char                 *element_class,
 | 
				
			||||||
 | 
					                                  const char                 *pseudo_class,
 | 
				
			||||||
 | 
					                                  const char                 *inline_style);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					EekThemeNode *eek_theme_node_get_parent
 | 
				
			||||||
 | 
					                                 (EekThemeNode               *node);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					EekTheme     *eek_theme_node_get_theme
 | 
				
			||||||
 | 
					                                 (EekThemeNode               *node);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					GType         eek_theme_node_get_element_type
 | 
				
			||||||
 | 
					                                 (EekThemeNode               *node);
 | 
				
			||||||
 | 
					const char   *eek_theme_node_get_element_id
 | 
				
			||||||
 | 
					                                 (EekThemeNode               *node);
 | 
				
			||||||
 | 
					const char   *eek_theme_node_get_element_class
 | 
				
			||||||
 | 
					                                 (EekThemeNode               *node);
 | 
				
			||||||
 | 
					const char   *eek_theme_node_get_pseudo_class
 | 
				
			||||||
 | 
					                                 (EekThemeNode               *node);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Generic getters ... these are not cached so are less efficient. The other
 | 
				
			||||||
 | 
					 * reason for adding the more specific version is that we can handle the
 | 
				
			||||||
 | 
					 * details of the actual CSS rules, which can be complicated, especially
 | 
				
			||||||
 | 
					 * for fonts
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void          eek_theme_node_get_color
 | 
				
			||||||
 | 
					                                 (EekThemeNode               *node,
 | 
				
			||||||
 | 
					                                  const char                 *property_name,
 | 
				
			||||||
 | 
					                                  EekColor                   *color);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Specific getters for particular properties: cached
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void          eek_theme_node_get_background_color
 | 
				
			||||||
 | 
					                                 (EekThemeNode               *node,
 | 
				
			||||||
 | 
					                                  EekColor                   *color);
 | 
				
			||||||
 | 
					void          eek_theme_node_get_foreground_color
 | 
				
			||||||
 | 
					                                 (EekThemeNode               *node,
 | 
				
			||||||
 | 
					                                  EekColor                   *color);
 | 
				
			||||||
 | 
					void          eek_theme_node_get_background_gradient
 | 
				
			||||||
 | 
					                                 (EekThemeNode               *node,
 | 
				
			||||||
 | 
					                                  EekGradientType            *type,
 | 
				
			||||||
 | 
					                                  EekColor                   *start,
 | 
				
			||||||
 | 
					                                  EekColor                   *end);
 | 
				
			||||||
 | 
					int           eek_theme_node_get_border_width
 | 
				
			||||||
 | 
					                                 (EekThemeNode               *node,
 | 
				
			||||||
 | 
					                                  EekSide                     side);
 | 
				
			||||||
 | 
					int           eek_theme_node_get_border_radius
 | 
				
			||||||
 | 
					                                 (EekThemeNode               *node,
 | 
				
			||||||
 | 
					                                  EekCorner                   corner);
 | 
				
			||||||
 | 
					void          eek_theme_node_get_border_color
 | 
				
			||||||
 | 
					                                 (EekThemeNode               *node,
 | 
				
			||||||
 | 
					                                  EekSide                     side,
 | 
				
			||||||
 | 
					                                  EekColor                   *color);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Font rule processing is pretty complicated, so we just hardcode it
 | 
				
			||||||
 | 
					 * under the standard font/font-family/font-size/etc names. This means
 | 
				
			||||||
 | 
					 * you can't have multiple separate styled fonts for a single item,
 | 
				
			||||||
 | 
					 * but that should be OK.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					const PangoFontDescription *eek_theme_node_get_font (EekThemeNode *node);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					G_END_DECLS
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif /* __EEK_THEME_NODE_H__ */
 | 
				
			||||||
							
								
								
									
										22
									
								
								eek/eek-theme-private.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,22 @@
 | 
				
			|||||||
 | 
					/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
 | 
				
			||||||
 | 
					#ifndef __EEK_THEME_PRIVATE_H__
 | 
				
			||||||
 | 
					#define __EEK_THEME_PRIVATE_H__
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <libcroco/libcroco.h>
 | 
				
			||||||
 | 
					#include "eek-theme.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					G_BEGIN_DECLS
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					GPtrArray *_eek_theme_get_matched_properties (EekTheme       *theme,
 | 
				
			||||||
 | 
					                                             EekThemeNode   *node);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Resolve an URL from the stylesheet to a filename */
 | 
				
			||||||
 | 
					char *_eek_theme_resolve_url (EekTheme      *theme,
 | 
				
			||||||
 | 
					                             CRStyleSheet *base_stylesheet,
 | 
				
			||||||
 | 
					                             const char   *url);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					CRDeclaration *_eek_theme_parse_declaration_list (const char *str);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					G_END_DECLS
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif /* __EEK_THEME_PRIVATE_H__ */
 | 
				
			||||||
							
								
								
									
										1133
									
								
								eek/eek-theme.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
							
								
								
									
										49
									
								
								eek/eek-theme.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,49 @@
 | 
				
			|||||||
 | 
					/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if !defined(__EEK_H_INSIDE__) && !defined(EEK_COMPILATION)
 | 
				
			||||||
 | 
					#error "Only <eek/eek.h> can be included directly."
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef __EEK_THEME_H__
 | 
				
			||||||
 | 
					#define __EEK_THEME_H__
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <glib-object.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "eek-types.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					G_BEGIN_DECLS
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * SECTION:EekTheme
 | 
				
			||||||
 | 
					 * @short_description: a set of stylesheets
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * #EekTheme holds a set of stylesheets. (The "cascade" of the name
 | 
				
			||||||
 | 
					 * Cascading Stylesheets.) An #EekTheme can be set to apply to all the
 | 
				
			||||||
 | 
					 * keyboard elements.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef struct _EekThemeClass EekThemeClass;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define EEK_TYPE_THEME (eek_theme_get_type())
 | 
				
			||||||
 | 
					#define EEK_THEME(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EEK_TYPE_THEME, EekTheme))
 | 
				
			||||||
 | 
					#define EEK_THEME_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EEK_TYPE_THEME, EekThemeClass))
 | 
				
			||||||
 | 
					#define EEK_IS_THEME(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EEK_TYPE_THEME))
 | 
				
			||||||
 | 
					#define EEK_IS_THEME_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EEK_TYPE_THEME))
 | 
				
			||||||
 | 
					#define EEK_THEME_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EEK_TYPE_THEME, EekThemeClass))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					GType     eek_theme_get_type          (void) G_GNUC_CONST;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					EekTheme *eek_theme_new               (const char *application_stylesheet,
 | 
				
			||||||
 | 
					                                       const char *theme_stylesheet,
 | 
				
			||||||
 | 
					                                       const char *default_stylesheet);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					gboolean  eek_theme_load_stylesheet   (EekTheme   *theme,
 | 
				
			||||||
 | 
					                                       const char *path,
 | 
				
			||||||
 | 
					                                       GError    **error);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void      eek_theme_unload_stylesheet (EekTheme   *theme,
 | 
				
			||||||
 | 
					                                       const char *path);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					G_END_DECLS
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif /* __EEK_THEME_H__ */
 | 
				
			||||||
@ -24,7 +24,9 @@
 | 
				
			|||||||
 * @short_description: Miscellaneous types used in Libeek
 | 
					 * @short_description: Miscellaneous types used in Libeek
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef HAVE_CONFIG_H
 | 
				
			||||||
#include "config.h"
 | 
					#include "config.h"
 | 
				
			||||||
 | 
					#endif  /* HAVE_CONFIG_H */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <string.h>
 | 
					#include <string.h>
 | 
				
			||||||
#include <math.h>
 | 
					#include <math.h>
 | 
				
			||||||
 | 
				
			|||||||
@ -134,7 +134,12 @@ typedef enum
 | 
				
			|||||||
#define EEK_INVALID_KEYCODE (0)
 | 
					#define EEK_INVALID_KEYCODE (0)
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
typedef struct _EekElement EekElement;
 | 
					typedef struct _EekElement EekElement;
 | 
				
			||||||
 | 
					typedef struct _EekContainer EekContainer;
 | 
				
			||||||
 | 
					typedef struct _EekKey EekKey;
 | 
				
			||||||
 | 
					typedef struct _EekSection EekSection;
 | 
				
			||||||
 | 
					typedef struct _EekKeyboard EekKeyboard;
 | 
				
			||||||
typedef struct _EekSymbol EekSymbol;
 | 
					typedef struct _EekSymbol EekSymbol;
 | 
				
			||||||
 | 
					typedef struct _EekKeysym EekKeysym;
 | 
				
			||||||
typedef struct _EekText EekText;
 | 
					typedef struct _EekText EekText;
 | 
				
			||||||
typedef struct _EekTheme EekTheme;
 | 
					typedef struct _EekTheme EekTheme;
 | 
				
			||||||
typedef struct _EekThemeContext EekThemeContext;
 | 
					typedef struct _EekThemeContext EekThemeContext;
 | 
				
			||||||
@ -146,7 +151,6 @@ typedef struct _EekOutline EekOutline;
 | 
				
			|||||||
typedef struct _EekColor EekColor;
 | 
					typedef struct _EekColor EekColor;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef struct _EekboardContextService EekboardContextService;
 | 
					typedef struct _EekboardContextService EekboardContextService;
 | 
				
			||||||
typedef struct _LevelKeyboard LevelKeyboard;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * EekPoint:
 | 
					 * EekPoint:
 | 
				
			||||||
@ -191,6 +195,12 @@ GType      eek_bounds_get_type (void) G_GNUC_CONST;
 | 
				
			|||||||
EekBounds *eek_bounds_copy     (const EekBounds *bounds);
 | 
					EekBounds *eek_bounds_copy     (const EekBounds *bounds);
 | 
				
			||||||
void       eek_bounds_free     (EekBounds       *bounds);
 | 
					void       eek_bounds_free     (EekBounds       *bounds);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					G_INLINE_FUNC gdouble
 | 
				
			||||||
 | 
					eek_bounds_long_side (EekBounds *bounds)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return bounds->width > bounds->height ? bounds->width : bounds->height;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * EekOutline:
 | 
					 * EekOutline:
 | 
				
			||||||
 * @corner_radius: radius of corners of rounded polygon
 | 
					 * @corner_radius: radius of corners of rounded polygon
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										30
									
								
								eek/eek-xkb-0.90.pc.in
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,30 @@
 | 
				
			|||||||
 | 
					# Copyright (C) 2010-2011 Daiki Ueno <ueno@unixuser.org>
 | 
				
			||||||
 | 
					# Copyright (C) 2010-2011 Red Hat, Inc.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# This library is free software; you can redistribute it and/or
 | 
				
			||||||
 | 
					# modify it under the terms of the GNU Lesser General Public License
 | 
				
			||||||
 | 
					# as published by the Free Software Foundation; either version 2 of
 | 
				
			||||||
 | 
					# the License, or (at your option) any later version.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# This library is distributed in the hope that it will be useful, but
 | 
				
			||||||
 | 
					# WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
				
			||||||
 | 
					# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
				
			||||||
 | 
					# Lesser General Public License for more details.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# You should have received a copy of the GNU Lesser General Public
 | 
				
			||||||
 | 
					# License along with this library; if not, write to the Free Software
 | 
				
			||||||
 | 
					# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 | 
				
			||||||
 | 
					# 02110-1301 USA
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					prefix=@prefix@
 | 
				
			||||||
 | 
					exec_prefix=@exec_prefix@
 | 
				
			||||||
 | 
					libdir=@libdir@
 | 
				
			||||||
 | 
					includedir=@includedir@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Name: libeek-xkb
 | 
				
			||||||
 | 
					Description: A Library to Create Keyboard-like UI (XKB Support)
 | 
				
			||||||
 | 
					URL: http://fedorahosted.org/eekboard/
 | 
				
			||||||
 | 
					Version: @VERSION@
 | 
				
			||||||
 | 
					Requires: eek-@EEK_API_VERSION@ gtk+-x11-@GTK_API_VERSION@
 | 
				
			||||||
 | 
					Libs: -L${libdir} -leek-xkb
 | 
				
			||||||
 | 
					Cflags: -I${includedir}/eek-@EEK_API_VERSION@
 | 
				
			||||||
							
								
								
									
										684
									
								
								eek/eek-xkb-layout.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,684 @@
 | 
				
			|||||||
 | 
					/* 
 | 
				
			||||||
 | 
					 * Copyright (C) 2006 Sergey V. Udaltsov <svu@gnome.org>
 | 
				
			||||||
 | 
					 * Copyright (C) 2010-2011 Daiki Ueno <ueno@unixuser.org>
 | 
				
			||||||
 | 
					 * Copyright (C) 2010-2011 Red Hat, Inc.
 | 
				
			||||||
 | 
					 * 
 | 
				
			||||||
 | 
					 * This library is free software; you can redistribute it and/or
 | 
				
			||||||
 | 
					 * modify it under the terms of the GNU Lesser General Public License
 | 
				
			||||||
 | 
					 * as published by the Free Software Foundation; either version 2 of
 | 
				
			||||||
 | 
					 * the License, or (at your option) any later version.
 | 
				
			||||||
 | 
					 * 
 | 
				
			||||||
 | 
					 * This library is distributed in the hope that it will be useful, but
 | 
				
			||||||
 | 
					 * WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
				
			||||||
 | 
					 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
				
			||||||
 | 
					 * Lesser General Public License for more details.
 | 
				
			||||||
 | 
					 * 
 | 
				
			||||||
 | 
					 * You should have received a copy of the GNU Lesser General Public
 | 
				
			||||||
 | 
					 * License along with this library; if not, write to the Free Software
 | 
				
			||||||
 | 
					 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 | 
				
			||||||
 | 
					 * 02110-1301 USA
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * SECTION:eek-xkb-layout
 | 
				
			||||||
 | 
					 * @short_description: Layout engine using XKB configuration
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * The #EekXkbLayout inherits #EekLayout class and arranges keyboard
 | 
				
			||||||
 | 
					 * elements using XKB.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef HAVE_CONFIG_H
 | 
				
			||||||
 | 
					#include "config.h"
 | 
				
			||||||
 | 
					#endif  /* HAVE_CONFIG_H */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "eek-xkb-layout.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <X11/keysym.h>
 | 
				
			||||||
 | 
					#include <X11/extensions/XKBgeom.h>
 | 
				
			||||||
 | 
					#include <string.h>
 | 
				
			||||||
 | 
					#include <stdarg.h>
 | 
				
			||||||
 | 
					#include <gio/gio.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "eek-keyboard.h"
 | 
				
			||||||
 | 
					#include "eek-section.h"
 | 
				
			||||||
 | 
					#include "eek-key.h"
 | 
				
			||||||
 | 
					#include "eek-keysym.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define XKB_COMPONENT_MASK (XkbGBN_GeometryMask |       \
 | 
				
			||||||
 | 
					                            XkbGBN_KeyNamesMask |       \
 | 
				
			||||||
 | 
					                            XkbGBN_OtherNamesMask |     \
 | 
				
			||||||
 | 
					                            XkbGBN_SymbolsMask |        \
 | 
				
			||||||
 | 
					                            XkbGBN_IndicatorMapMask)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void initable_iface_init (GInitableIface *initable_iface);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					enum {
 | 
				
			||||||
 | 
					    PROP_0,
 | 
				
			||||||
 | 
					    PROP_DISPLAY,
 | 
				
			||||||
 | 
					    PROP_LAST
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef struct _EekXkbLayoutPrivate
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    /* Configuration names that should synch'ed to the symbolic names
 | 
				
			||||||
 | 
					       in priv->xkb->names.  Since we use GLib's memory allocator,
 | 
				
			||||||
 | 
					       don't store any address returned from the X server here. */
 | 
				
			||||||
 | 
					    XkbComponentNamesRec names;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Display *display;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* Actual XKB configuration of DISPLAY. */
 | 
				
			||||||
 | 
					    XkbDescRec *xkb;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* Hash table to cache orefs by shape address. */
 | 
				
			||||||
 | 
					    GHashTable *shape_oref_hash;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    gint scale_numerator;
 | 
				
			||||||
 | 
					    gint scale_denominator;
 | 
				
			||||||
 | 
					} EekXkbLayoutPrivate;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					G_DEFINE_TYPE_EXTENDED (EekXkbLayout, eek_xkb_layout, EEK_TYPE_LAYOUT,
 | 
				
			||||||
 | 
								0, /* GTypeFlags */
 | 
				
			||||||
 | 
								G_ADD_PRIVATE(EekXkbLayout)
 | 
				
			||||||
 | 
					                        G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE,
 | 
				
			||||||
 | 
					                                               initable_iface_init))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static guint    find_keycode             (EekXkbLayout *layout,
 | 
				
			||||||
 | 
					                                          gchar        *key_name);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static gboolean get_keyboard_from_server (EekXkbLayout *layout,
 | 
				
			||||||
 | 
					                                          GError      **error);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static gboolean get_names_from_server    (EekXkbLayout *layout,
 | 
				
			||||||
 | 
					                                          GError      **error);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void     setup_scaling            (EekXkbLayout *layout,
 | 
				
			||||||
 | 
					                                          gdouble       width,
 | 
				
			||||||
 | 
					                                          gdouble       height);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					G_INLINE_FUNC gint
 | 
				
			||||||
 | 
					xkb_to_pixmap_coord (EekXkbLayout *layout,
 | 
				
			||||||
 | 
					                     gint          n)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    EekXkbLayoutPrivate *priv = eek_xkb_layout_get_instance_private (layout);
 | 
				
			||||||
 | 
					    return n * priv->scale_numerator / priv->scale_denominator;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					G_INLINE_FUNC gdouble
 | 
				
			||||||
 | 
					xkb_to_pixmap_double (EekXkbLayout *layout,
 | 
				
			||||||
 | 
					                     gdouble       d)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    EekXkbLayoutPrivate *priv = eek_xkb_layout_get_instance_private (layout);
 | 
				
			||||||
 | 
					    return d * priv->scale_numerator / priv->scale_denominator;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					create_key (EekXkbLayout *layout,
 | 
				
			||||||
 | 
					            EekKeyboard  *keyboard,
 | 
				
			||||||
 | 
					            EekSection   *section,
 | 
				
			||||||
 | 
					            gint          column,
 | 
				
			||||||
 | 
					            gint          row,
 | 
				
			||||||
 | 
					            gdouble       x,
 | 
				
			||||||
 | 
					            gdouble       y,
 | 
				
			||||||
 | 
					            XkbKeyRec    *xkbkey)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    XkbGeometryRec *xkbgeometry;
 | 
				
			||||||
 | 
					    XkbBoundsRec *xkbbounds;
 | 
				
			||||||
 | 
					    XkbShapeRec *xkbshape;
 | 
				
			||||||
 | 
					    XkbOutlineRec *xkboutline;
 | 
				
			||||||
 | 
					    EekXkbLayoutPrivate *priv = eek_xkb_layout_get_instance_private (layout);
 | 
				
			||||||
 | 
					    EekKey *key;
 | 
				
			||||||
 | 
					    EekBounds bounds;
 | 
				
			||||||
 | 
					    EekSymbolMatrix *matrix = NULL;
 | 
				
			||||||
 | 
					    gchar name[XkbKeyNameLength + 1];
 | 
				
			||||||
 | 
					    KeyCode keycode;
 | 
				
			||||||
 | 
					    gint num_groups, num_levels;
 | 
				
			||||||
 | 
					    guint oref;
 | 
				
			||||||
 | 
					    gpointer v;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    xkbgeometry = priv->xkb->geom;
 | 
				
			||||||
 | 
					    xkbshape = &xkbgeometry->shapes[xkbkey->shape_ndx];
 | 
				
			||||||
 | 
					    if (g_hash_table_lookup_extended (priv->shape_oref_hash, xkbshape,
 | 
				
			||||||
 | 
					                                      NULL, &v)) {
 | 
				
			||||||
 | 
					        oref = GPOINTER_TO_UINT(v);
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					        EekOutline *outline;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        xkboutline = xkbshape->primary == NULL ? &xkbshape->outlines[0] :
 | 
				
			||||||
 | 
					            xkbshape->primary;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        outline = g_slice_new (EekOutline);
 | 
				
			||||||
 | 
					        outline->corner_radius = xkb_to_pixmap_coord(layout,
 | 
				
			||||||
 | 
					                                                     xkboutline->corner_radius);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (xkboutline->num_points <= 2) { /* rectangular */
 | 
				
			||||||
 | 
					            gdouble x1, y1, x2, y2;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            outline->num_points = 4;
 | 
				
			||||||
 | 
					            outline->points = g_slice_alloc0 (sizeof (EekPoint) *
 | 
				
			||||||
 | 
					                                              outline->num_points);
 | 
				
			||||||
 | 
					            if (xkboutline->num_points == 1) {
 | 
				
			||||||
 | 
					                x1 = xkb_to_pixmap_coord(layout, xkbshape->bounds.x1);
 | 
				
			||||||
 | 
					                y1 = xkb_to_pixmap_coord(layout, xkbshape->bounds.y1);
 | 
				
			||||||
 | 
					                x2 = xkb_to_pixmap_coord(layout, xkboutline->points[0].x);
 | 
				
			||||||
 | 
					                y2 = xkb_to_pixmap_coord(layout, xkboutline->points[0].y);
 | 
				
			||||||
 | 
					            } else {
 | 
				
			||||||
 | 
					                x1 = xkb_to_pixmap_coord(layout, xkboutline->points[0].x);
 | 
				
			||||||
 | 
					                y1 = xkb_to_pixmap_coord(layout, xkboutline->points[0].y);
 | 
				
			||||||
 | 
					                x2 = xkb_to_pixmap_coord(layout, xkboutline->points[1].x);
 | 
				
			||||||
 | 
					                y2 = xkb_to_pixmap_coord(layout, xkboutline->points[1].y);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            outline->points[0].x = outline->points[3].x = x1;
 | 
				
			||||||
 | 
					            outline->points[0].y = outline->points[1].y = y1;
 | 
				
			||||||
 | 
					            outline->points[1].x = outline->points[2].x = x2;
 | 
				
			||||||
 | 
					            outline->points[2].y = outline->points[3].y = y2;
 | 
				
			||||||
 | 
					        } else {                /* polygon */
 | 
				
			||||||
 | 
					            gint i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            outline->num_points = xkboutline->num_points;
 | 
				
			||||||
 | 
					            outline->points = g_new0 (EekPoint, outline->num_points);
 | 
				
			||||||
 | 
					            for (i = 0; i < xkboutline->num_points; i++) {
 | 
				
			||||||
 | 
					                outline->points[i].x =
 | 
				
			||||||
 | 
					                    xkb_to_pixmap_coord(layout, xkboutline->points[i].x);
 | 
				
			||||||
 | 
					                outline->points[i].y =
 | 
				
			||||||
 | 
					                    xkb_to_pixmap_coord(layout, xkboutline->points[i].y);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        oref = eek_keyboard_add_outline (keyboard, outline);
 | 
				
			||||||
 | 
					        eek_outline_free (outline);
 | 
				
			||||||
 | 
					        g_hash_table_insert (priv->shape_oref_hash, xkbshape,
 | 
				
			||||||
 | 
					                             GUINT_TO_POINTER(oref));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    memset (name, 0, sizeof name);
 | 
				
			||||||
 | 
					    memcpy (name, xkbkey->name.name, sizeof name - 1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    xkbbounds = &xkbgeometry->shapes[xkbkey->shape_ndx].bounds;
 | 
				
			||||||
 | 
					    bounds.x = xkb_to_pixmap_coord(layout, xkbbounds->x1 + x);
 | 
				
			||||||
 | 
					    bounds.y = xkb_to_pixmap_coord(layout, xkbbounds->y1 + y);
 | 
				
			||||||
 | 
					    bounds.width = xkb_to_pixmap_coord(layout, xkbbounds->x2 - xkbbounds->x1);
 | 
				
			||||||
 | 
					    bounds.height = xkb_to_pixmap_coord(layout, xkbbounds->y2 - xkbbounds->y1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    keycode = find_keycode (layout, name);
 | 
				
			||||||
 | 
					    if (keycode == EEK_INVALID_KEYCODE) {
 | 
				
			||||||
 | 
					        num_groups = num_levels = 0;
 | 
				
			||||||
 | 
					        matrix = eek_symbol_matrix_new (0, 0);
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					        KeySym keysym;
 | 
				
			||||||
 | 
					        gint i, j;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        num_groups = XkbKeyNumGroups (priv->xkb, keycode);
 | 
				
			||||||
 | 
					        num_levels = XkbKeyGroupsWidth (priv->xkb, keycode);
 | 
				
			||||||
 | 
					        matrix = eek_symbol_matrix_new (num_groups, num_levels);
 | 
				
			||||||
 | 
					        for (i = 0; i < num_groups; i++)
 | 
				
			||||||
 | 
					            for (j = 0; j < num_levels; j++) {
 | 
				
			||||||
 | 
					                EekModifierType modifier;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                keysym = XkbKeySymEntry (priv->xkb, keycode, j, i);
 | 
				
			||||||
 | 
					                modifier = XkbKeysymToModifiers (priv->display, keysym);
 | 
				
			||||||
 | 
					                matrix->data[i * num_levels + j] =
 | 
				
			||||||
 | 
					                    EEK_SYMBOL(eek_keysym_new_with_modifier (keysym,
 | 
				
			||||||
 | 
					                                                             modifier));
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    key = eek_section_create_key (section, keycode, column, row);
 | 
				
			||||||
 | 
					    eek_element_set_name (EEK_ELEMENT(key), name);
 | 
				
			||||||
 | 
					    eek_element_set_bounds (EEK_ELEMENT(key), &bounds);
 | 
				
			||||||
 | 
					    eek_key_set_symbol_matrix (key, matrix);
 | 
				
			||||||
 | 
					    eek_symbol_matrix_free (matrix);
 | 
				
			||||||
 | 
					    eek_key_set_oref (key, oref);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					create_section (EekXkbLayout  *layout,
 | 
				
			||||||
 | 
					                EekKeyboard   *keyboard,
 | 
				
			||||||
 | 
					                XkbSectionRec *xkbsection)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    XkbGeometryRec *xkbgeometry;
 | 
				
			||||||
 | 
					    EekXkbLayoutPrivate *priv = eek_xkb_layout_get_instance_private (layout);
 | 
				
			||||||
 | 
					    EekSection *section;
 | 
				
			||||||
 | 
					    EekBounds bounds;
 | 
				
			||||||
 | 
					    gchar *name;
 | 
				
			||||||
 | 
					    gfloat left, top;
 | 
				
			||||||
 | 
					    gint i, j;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    bounds.x = xkb_to_pixmap_coord(layout, xkbsection->left);
 | 
				
			||||||
 | 
					    bounds.y = xkb_to_pixmap_coord(layout, xkbsection->top);
 | 
				
			||||||
 | 
					    bounds.width = xkb_to_pixmap_coord(layout, xkbsection->width);
 | 
				
			||||||
 | 
					    bounds.height = xkb_to_pixmap_coord(layout, xkbsection->height);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    xkbgeometry = priv->xkb->geom;
 | 
				
			||||||
 | 
					    section = eek_keyboard_create_section (keyboard);
 | 
				
			||||||
 | 
					    name = XGetAtomName (priv->display, xkbsection->name);
 | 
				
			||||||
 | 
					    eek_element_set_name (EEK_ELEMENT(section), name);
 | 
				
			||||||
 | 
					    XFree (name);
 | 
				
			||||||
 | 
					    eek_element_set_bounds (EEK_ELEMENT(section), &bounds);
 | 
				
			||||||
 | 
					    eek_section_set_angle (section,
 | 
				
			||||||
 | 
					                           /* angle is in tenth of degree */
 | 
				
			||||||
 | 
					                           xkbsection->angle / 10);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for (i = 0; i < xkbsection->num_rows; i++) {
 | 
				
			||||||
 | 
					        XkbRowRec *xkbrow;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        xkbrow = &xkbsection->rows[i];
 | 
				
			||||||
 | 
					        left = xkbrow->left;
 | 
				
			||||||
 | 
					        top = xkbrow->top;
 | 
				
			||||||
 | 
					        eek_section_add_row (section,
 | 
				
			||||||
 | 
					                             xkbrow->num_keys,
 | 
				
			||||||
 | 
					                             xkbrow->vertical ?
 | 
				
			||||||
 | 
					                             EEK_ORIENTATION_VERTICAL :
 | 
				
			||||||
 | 
					                             EEK_ORIENTATION_HORIZONTAL);
 | 
				
			||||||
 | 
					        for (j = 0; j < xkbrow->num_keys; j++) {
 | 
				
			||||||
 | 
					            XkbKeyRec *xkbkey;
 | 
				
			||||||
 | 
					            XkbBoundsRec *xkbbounds;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            xkbkey = &xkbrow->keys[j];
 | 
				
			||||||
 | 
					            if (xkbrow->vertical)
 | 
				
			||||||
 | 
					                top += xkbkey->gap;
 | 
				
			||||||
 | 
					            else
 | 
				
			||||||
 | 
					                left += xkbkey->gap;
 | 
				
			||||||
 | 
					            create_key (layout, keyboard, section, j, i, left, top, xkbkey);
 | 
				
			||||||
 | 
					            xkbbounds = &xkbgeometry->shapes[xkbkey->shape_ndx].bounds;
 | 
				
			||||||
 | 
					            if (xkbrow->vertical)
 | 
				
			||||||
 | 
					                top += xkbbounds->y2 - xkbbounds->y1;
 | 
				
			||||||
 | 
					            else
 | 
				
			||||||
 | 
					                left += xkbbounds->x2 - xkbbounds->x1;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					create_keyboard (EekXkbLayout *layout, EekKeyboard *keyboard)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    EekXkbLayoutPrivate *priv = eek_xkb_layout_get_instance_private (layout);
 | 
				
			||||||
 | 
					    XkbGeometryRec *xkbgeometry;
 | 
				
			||||||
 | 
					    EekBounds bounds;
 | 
				
			||||||
 | 
					    gint i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    g_return_if_fail (priv->xkb);
 | 
				
			||||||
 | 
					    g_return_if_fail (priv->xkb->geom);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    xkbgeometry = priv->xkb->geom;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    eek_element_get_bounds (EEK_ELEMENT(keyboard), &bounds);
 | 
				
			||||||
 | 
					    setup_scaling (EEK_XKB_LAYOUT(layout), bounds.width, bounds.height);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    bounds.x = bounds.y = 0;
 | 
				
			||||||
 | 
					    bounds.width = xkb_to_pixmap_coord(layout, xkbgeometry->width_mm);
 | 
				
			||||||
 | 
					    bounds.height = xkb_to_pixmap_coord(layout, xkbgeometry->height_mm);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for (i = 0; i < xkbgeometry->num_sections; i++) {
 | 
				
			||||||
 | 
					        XkbSectionRec *xkbsection;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        xkbsection = &xkbgeometry->sections[i];
 | 
				
			||||||
 | 
					        create_section (layout, keyboard, xkbsection);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    eek_element_set_bounds (EEK_ELEMENT(keyboard), &bounds);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static EekKeyboard *
 | 
				
			||||||
 | 
					eek_xkb_layout_real_create_keyboard (EekboardContextService *manager,
 | 
				
			||||||
 | 
					                                     EekLayout *self,
 | 
				
			||||||
 | 
					                                     gdouble    initial_width,
 | 
				
			||||||
 | 
					                                     gdouble    initial_height)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    EekKeyboard *keyboard = g_object_new (EEK_TYPE_KEYBOARD, "layout", self, NULL);
 | 
				
			||||||
 | 
					    keyboard->manager = manager;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    EekBounds bounds = {
 | 
				
			||||||
 | 
					        .x = 0.0,
 | 
				
			||||||
 | 
					        .y = 0.0,
 | 
				
			||||||
 | 
					        .width = initial_width,
 | 
				
			||||||
 | 
					        .height = initial_height
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					    eek_element_set_bounds (EEK_ELEMENT(keyboard), &bounds);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* resolve modifiers dynamically assigned at run time */
 | 
				
			||||||
 | 
					    EekXkbLayoutPrivate *priv = eek_xkb_layout_get_instance_private (
 | 
				
			||||||
 | 
							    EEK_XKB_LAYOUT(self));
 | 
				
			||||||
 | 
					    eek_keyboard_set_num_lock_mask (keyboard,
 | 
				
			||||||
 | 
					                                    XkbKeysymToModifiers (priv->display,
 | 
				
			||||||
 | 
					                                                          XK_Num_Lock));
 | 
				
			||||||
 | 
					    eek_keyboard_set_alt_gr_mask (keyboard,
 | 
				
			||||||
 | 
					                                  XkbKeysymToModifiers (priv->display,
 | 
				
			||||||
 | 
					                                                        XK_ISO_Level3_Shift));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (priv->shape_oref_hash)
 | 
				
			||||||
 | 
					        g_hash_table_destroy (priv->shape_oref_hash);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    priv->shape_oref_hash = g_hash_table_new (g_direct_hash, g_direct_equal);
 | 
				
			||||||
 | 
					    create_keyboard (EEK_XKB_LAYOUT(self), keyboard);
 | 
				
			||||||
 | 
					    g_hash_table_destroy (priv->shape_oref_hash);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return keyboard;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					eek_xkb_layout_finalize (GObject *object)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    EekXkbLayoutPrivate *priv = eek_xkb_layout_get_instance_private (
 | 
				
			||||||
 | 
							    EEK_XKB_LAYOUT (object));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    g_free (priv->names.keycodes);
 | 
				
			||||||
 | 
					    g_free (priv->names.geometry);
 | 
				
			||||||
 | 
					    g_free (priv->names.symbols);
 | 
				
			||||||
 | 
					    XkbFreeKeyboard (priv->xkb, 0, TRUE);	/* free_all = TRUE */
 | 
				
			||||||
 | 
					    G_OBJECT_CLASS (eek_xkb_layout_parent_class)->finalize (object);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void 
 | 
				
			||||||
 | 
					eek_xkb_layout_set_property (GObject      *object,
 | 
				
			||||||
 | 
					                             guint         prop_id,
 | 
				
			||||||
 | 
					                             const GValue *value,
 | 
				
			||||||
 | 
					                             GParamSpec   *pspec)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    EekXkbLayout *layout = EEK_XKB_LAYOUT (object);
 | 
				
			||||||
 | 
					    EekXkbLayoutPrivate *priv = eek_xkb_layout_get_instance_private (layout);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    switch (prop_id) {
 | 
				
			||||||
 | 
					    case PROP_DISPLAY:
 | 
				
			||||||
 | 
					        priv->display = g_value_get_pointer (value);
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					    default:
 | 
				
			||||||
 | 
					        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void 
 | 
				
			||||||
 | 
					eek_xkb_layout_get_property (GObject    *object,
 | 
				
			||||||
 | 
					                             guint       prop_id,
 | 
				
			||||||
 | 
					                             GValue     *value,
 | 
				
			||||||
 | 
					                             GParamSpec *pspec)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    EekXkbLayout *layout = EEK_XKB_LAYOUT (object);
 | 
				
			||||||
 | 
					    EekXkbLayoutPrivate *priv = eek_xkb_layout_get_instance_private (layout);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    switch (prop_id) {
 | 
				
			||||||
 | 
					    case PROP_DISPLAY:
 | 
				
			||||||
 | 
					        g_value_set_pointer (value, priv->display);
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					    default:
 | 
				
			||||||
 | 
					        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					eek_xkb_layout_class_init (EekXkbLayoutClass *klass)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    EekLayoutClass *layout_class = EEK_LAYOUT_CLASS (klass);
 | 
				
			||||||
 | 
					    GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
 | 
				
			||||||
 | 
					    GParamSpec *pspec;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    layout_class->create_keyboard = eek_xkb_layout_real_create_keyboard;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    gobject_class->finalize = eek_xkb_layout_finalize;
 | 
				
			||||||
 | 
					    gobject_class->set_property = eek_xkb_layout_set_property;
 | 
				
			||||||
 | 
					    gobject_class->get_property = eek_xkb_layout_get_property;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    pspec = g_param_spec_pointer ("display",
 | 
				
			||||||
 | 
					                                  "Display",
 | 
				
			||||||
 | 
					                                  "X Display",
 | 
				
			||||||
 | 
					                                  G_PARAM_READWRITE |
 | 
				
			||||||
 | 
					                                  G_PARAM_CONSTRUCT_ONLY);
 | 
				
			||||||
 | 
					    g_object_class_install_property (gobject_class, PROP_DISPLAY, pspec);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					eek_xkb_layout_init (EekXkbLayout *self)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    /* void */
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static gboolean
 | 
				
			||||||
 | 
					get_names_from_server (EekXkbLayout *layout,
 | 
				
			||||||
 | 
					                       GError      **error)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    EekXkbLayoutPrivate *priv = eek_xkb_layout_get_instance_private (layout);
 | 
				
			||||||
 | 
					    gchar *name;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    XkbGetNames (priv->display, XkbAllNamesMask, priv->xkb);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (priv->xkb->names->keycodes <= 0)
 | 
				
			||||||
 | 
					        g_warning ("XKB keycodes setting is not loaded properly");
 | 
				
			||||||
 | 
					    else {
 | 
				
			||||||
 | 
					        name = XGetAtomName (priv->display, priv->xkb->names->keycodes);
 | 
				
			||||||
 | 
					        if (!name)
 | 
				
			||||||
 | 
					            g_warning ("Can't get the name of keycodes");
 | 
				
			||||||
 | 
					        else if (!priv->names.keycodes ||
 | 
				
			||||||
 | 
					                 g_strcmp0 (name, priv->names.keycodes)) {
 | 
				
			||||||
 | 
					            g_free (priv->names.keycodes);
 | 
				
			||||||
 | 
					            priv->names.keycodes = g_strdup (name);
 | 
				
			||||||
 | 
					            XFree (name);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (priv->xkb->names->geometry <= 0)
 | 
				
			||||||
 | 
					        g_warning ("XKB geometry setting is not loaded");
 | 
				
			||||||
 | 
					    else {
 | 
				
			||||||
 | 
					        name = XGetAtomName (priv->display, priv->xkb->names->geometry);
 | 
				
			||||||
 | 
					        if (!name)
 | 
				
			||||||
 | 
					            g_warning ("Can't get the name of geometry");
 | 
				
			||||||
 | 
					        else if (!priv->names.geometry ||
 | 
				
			||||||
 | 
					                 g_strcmp0 (name, priv->names.geometry)) {
 | 
				
			||||||
 | 
					            g_free (priv->names.geometry);
 | 
				
			||||||
 | 
					            priv->names.geometry = g_strdup (name);
 | 
				
			||||||
 | 
					            XFree (name);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (priv->xkb->names->symbols <= 0)
 | 
				
			||||||
 | 
					        g_warning ("XKB symbols setting is not loaded");
 | 
				
			||||||
 | 
					    else {
 | 
				
			||||||
 | 
					        name = XGetAtomName (priv->display, priv->xkb->names->symbols);
 | 
				
			||||||
 | 
					        if (!name)
 | 
				
			||||||
 | 
					            g_warning ("Can't get the name of symbols");
 | 
				
			||||||
 | 
					        else if (!priv->names.symbols ||
 | 
				
			||||||
 | 
					                 g_strcmp0 (name, priv->names.symbols)) {
 | 
				
			||||||
 | 
					            g_free (priv->names.symbols);
 | 
				
			||||||
 | 
					            priv->names.symbols = g_strdup (name);
 | 
				
			||||||
 | 
					            XFree (name);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return TRUE;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * eek_xkb_layout_new:
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Create a new #EekXkbLayout.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					EekLayout *
 | 
				
			||||||
 | 
					eek_xkb_layout_new (Display *display,
 | 
				
			||||||
 | 
					                    GError **error)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return (EekLayout *) g_initable_new (EEK_TYPE_XKB_LAYOUT,
 | 
				
			||||||
 | 
					                                         NULL,
 | 
				
			||||||
 | 
					                                         error,
 | 
				
			||||||
 | 
					                                         "display", display,
 | 
				
			||||||
 | 
					                                         NULL);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * eek_xkb_layout_set_names: (skip)
 | 
				
			||||||
 | 
					 * @layout: an #EekXkbLayout
 | 
				
			||||||
 | 
					 * @names: XKB component names
 | 
				
			||||||
 | 
					 * @error: a #GError
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Set the XKB component names to @layout.
 | 
				
			||||||
 | 
					 * Returns: %TRUE if the component names are successfully set, %FALSE otherwise
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					gboolean
 | 
				
			||||||
 | 
					eek_xkb_layout_set_names (EekXkbLayout         *layout,
 | 
				
			||||||
 | 
					                          XkbComponentNamesRec *names,
 | 
				
			||||||
 | 
					                          GError              **error)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    EekXkbLayoutPrivate *priv = eek_xkb_layout_get_instance_private (layout);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (g_strcmp0 (names->keycodes, priv->names.keycodes)) {
 | 
				
			||||||
 | 
					        g_free (priv->names.keycodes);
 | 
				
			||||||
 | 
					        priv->names.keycodes = g_strdup (names->keycodes);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (g_strcmp0 (names->geometry, priv->names.geometry)) {
 | 
				
			||||||
 | 
					        g_free (priv->names.geometry);
 | 
				
			||||||
 | 
					        priv->names.geometry = g_strdup (names->geometry);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (g_strcmp0 (names->symbols, priv->names.symbols)) {
 | 
				
			||||||
 | 
					        g_free (priv->names.symbols);
 | 
				
			||||||
 | 
					        priv->names.symbols = g_strdup (names->symbols);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return get_keyboard_from_server (layout, error);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static gboolean
 | 
				
			||||||
 | 
					get_keyboard_from_server (EekXkbLayout *layout,
 | 
				
			||||||
 | 
					                          GError      **error)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    EekXkbLayoutPrivate *priv = eek_xkb_layout_get_instance_private (layout);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (priv->xkb) {
 | 
				
			||||||
 | 
					        XkbFreeKeyboard (priv->xkb, 0, True);
 | 
				
			||||||
 | 
					        priv->xkb = NULL;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (priv->names.keycodes && priv->names.geometry && priv->names.symbols) {
 | 
				
			||||||
 | 
					        priv->xkb = XkbGetKeyboardByName (priv->display,
 | 
				
			||||||
 | 
					                                          XkbUseCoreKbd,
 | 
				
			||||||
 | 
					                                          &priv->names,
 | 
				
			||||||
 | 
					                                          0,
 | 
				
			||||||
 | 
					                                          XKB_COMPONENT_MASK,
 | 
				
			||||||
 | 
					                                          False);
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					        priv->xkb = XkbGetKeyboard (priv->display,
 | 
				
			||||||
 | 
					                                    XKB_COMPONENT_MASK,
 | 
				
			||||||
 | 
					                                    XkbUseCoreKbd);
 | 
				
			||||||
 | 
					        if (!get_names_from_server (layout, error)) {
 | 
				
			||||||
 | 
					            XkbFreeKeyboard (priv->xkb, 0, True);
 | 
				
			||||||
 | 
					            priv->xkb = NULL;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (priv->xkb == NULL) {
 | 
				
			||||||
 | 
					        g_set_error (error,
 | 
				
			||||||
 | 
					                     EEK_ERROR,
 | 
				
			||||||
 | 
					                     EEK_ERROR_LAYOUT_ERROR,
 | 
				
			||||||
 | 
					                     "can't get keyboard from server");
 | 
				
			||||||
 | 
					        g_free (priv->names.keycodes);
 | 
				
			||||||
 | 
					        priv->names.keycodes = NULL;
 | 
				
			||||||
 | 
					        g_free (priv->names.geometry);
 | 
				
			||||||
 | 
					        priv->names.geometry = NULL;
 | 
				
			||||||
 | 
					        g_free (priv->names.symbols);
 | 
				
			||||||
 | 
					        priv->names.symbols = NULL;
 | 
				
			||||||
 | 
					        return FALSE;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return TRUE;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static guint
 | 
				
			||||||
 | 
					find_keycode (EekXkbLayout *layout, gchar *key_name)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					#define KEYSYM_NAME_MAX_LENGTH 4
 | 
				
			||||||
 | 
					    guint keycode;
 | 
				
			||||||
 | 
					    gint i, j;
 | 
				
			||||||
 | 
					    XkbKeyNamePtr pkey;
 | 
				
			||||||
 | 
					    XkbKeyAliasPtr palias;
 | 
				
			||||||
 | 
					    guint is_name_matched;
 | 
				
			||||||
 | 
					    gchar *src, *dst;
 | 
				
			||||||
 | 
					    EekXkbLayoutPrivate *priv = eek_xkb_layout_get_instance_private (layout);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (!priv->xkb)
 | 
				
			||||||
 | 
					        return EEK_INVALID_KEYCODE;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    pkey = priv->xkb->names->keys + priv->xkb->min_key_code;
 | 
				
			||||||
 | 
					    for (keycode = priv->xkb->min_key_code;
 | 
				
			||||||
 | 
					         keycode <= priv->xkb->max_key_code; keycode++) {
 | 
				
			||||||
 | 
					        is_name_matched = 1;
 | 
				
			||||||
 | 
					        src = key_name;
 | 
				
			||||||
 | 
					        dst = pkey->name;
 | 
				
			||||||
 | 
					        for (i = KEYSYM_NAME_MAX_LENGTH; --i >= 0;) {
 | 
				
			||||||
 | 
					            if ('\0' == *src)
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					            if (*src++ != *dst++) {
 | 
				
			||||||
 | 
					                is_name_matched = 0;
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        if (is_name_matched)
 | 
				
			||||||
 | 
					            return keycode;
 | 
				
			||||||
 | 
					        pkey++;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    palias = priv->xkb->names->key_aliases;
 | 
				
			||||||
 | 
					    for (j = priv->xkb->names->num_key_aliases; --j >= 0;) {
 | 
				
			||||||
 | 
					        is_name_matched = 1;
 | 
				
			||||||
 | 
					        src = key_name;
 | 
				
			||||||
 | 
					        dst = palias->alias;
 | 
				
			||||||
 | 
					        for (i = KEYSYM_NAME_MAX_LENGTH; --i >= 0;) {
 | 
				
			||||||
 | 
					            if ('\0' == *src)
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					            if (*src++ != *dst++) {
 | 
				
			||||||
 | 
					                is_name_matched = 0;
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (is_name_matched) {
 | 
				
			||||||
 | 
					            keycode = find_keycode (layout, palias->real);
 | 
				
			||||||
 | 
					            return keycode;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        palias++;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return EEK_INVALID_KEYCODE;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					setup_scaling (EekXkbLayout *layout,
 | 
				
			||||||
 | 
					               gdouble       width,
 | 
				
			||||||
 | 
					               gdouble       height)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    EekXkbLayoutPrivate *priv = eek_xkb_layout_get_instance_private (layout);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    g_return_if_fail (priv->xkb);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    g_return_if_fail (priv->xkb->geom->width_mm > 0);
 | 
				
			||||||
 | 
					    g_return_if_fail (priv->xkb->geom->height_mm > 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (width * priv->xkb->geom->height_mm <
 | 
				
			||||||
 | 
					        height * priv->xkb->geom->width_mm) {
 | 
				
			||||||
 | 
					        priv->scale_numerator = width;
 | 
				
			||||||
 | 
					        priv->scale_denominator = priv->xkb->geom->width_mm;
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					        priv->scale_numerator = height;
 | 
				
			||||||
 | 
					        priv->scale_denominator = priv->xkb->geom->height_mm;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static gboolean
 | 
				
			||||||
 | 
					initable_init (GInitable    *initable,
 | 
				
			||||||
 | 
					               GCancellable *cancellable,
 | 
				
			||||||
 | 
					               GError      **error)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    EekXkbLayout *layout = EEK_XKB_LAYOUT (initable);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (!get_keyboard_from_server (layout, error))
 | 
				
			||||||
 | 
					        return FALSE;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (!get_names_from_server (layout, error))
 | 
				
			||||||
 | 
					        return FALSE;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return TRUE;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					initable_iface_init (GInitableIface *initable_iface)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  initable_iface->init = initable_init;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										55
									
								
								eek/eek-xkb-layout.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,55 @@
 | 
				
			|||||||
 | 
					/* 
 | 
				
			||||||
 | 
					 * Copyright (C) 2010-2011 Daiki Ueno <ueno@unixuser.org>
 | 
				
			||||||
 | 
					 * Copyright (C) 2010-2011 Red Hat, Inc.
 | 
				
			||||||
 | 
					 * 
 | 
				
			||||||
 | 
					 * This library is free software; you can redistribute it and/or
 | 
				
			||||||
 | 
					 * modify it under the terms of the GNU Lesser General Public License
 | 
				
			||||||
 | 
					 * as published by the Free Software Foundation; either version 2 of
 | 
				
			||||||
 | 
					 * the License, or (at your option) any later version.
 | 
				
			||||||
 | 
					 * 
 | 
				
			||||||
 | 
					 * This library is distributed in the hope that it will be useful, but
 | 
				
			||||||
 | 
					 * WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
				
			||||||
 | 
					 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
				
			||||||
 | 
					 * Lesser General Public License for more details.
 | 
				
			||||||
 | 
					 * 
 | 
				
			||||||
 | 
					 * You should have received a copy of the GNU Lesser General Public
 | 
				
			||||||
 | 
					 * License along with this library; if not, write to the Free Software
 | 
				
			||||||
 | 
					 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 | 
				
			||||||
 | 
					 * 02110-1301 USA
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if !defined(__EEK_H_INSIDE__) && !defined(EEK_COMPILATION)
 | 
				
			||||||
 | 
					#error "Only <eek/eek-xkb.h> can be included directly."
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef EEK_XKB_LAYOUT_H
 | 
				
			||||||
 | 
					#define EEK_XKB_LAYOUT_H 1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <X11/XKBlib.h>
 | 
				
			||||||
 | 
					#include "eek-layout.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					G_BEGIN_DECLS
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define EEK_TYPE_XKB_LAYOUT (eek_xkb_layout_get_type())
 | 
				
			||||||
 | 
					G_DECLARE_DERIVABLE_TYPE (EekXkbLayout, eek_xkb_layout, EEK, XKB_LAYOUT, EekLayout)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct _EekXkbLayoutClass
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    /*< private >*/
 | 
				
			||||||
 | 
					    EekLayoutClass parent_class;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /*< private >*/
 | 
				
			||||||
 | 
					    /* padding */
 | 
				
			||||||
 | 
					    gpointer pdummy[24];
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					GType      eek_xkb_layout_get_type  (void) G_GNUC_CONST;
 | 
				
			||||||
 | 
					EekLayout *eek_xkb_layout_new       (Display              *display,
 | 
				
			||||||
 | 
					                                     GError              **error);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					gboolean   eek_xkb_layout_set_names (EekXkbLayout         *layout,
 | 
				
			||||||
 | 
					                                     XkbComponentNamesRec *names,
 | 
				
			||||||
 | 
					                                     GError              **error);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					G_END_DECLS
 | 
				
			||||||
 | 
					#endif				/* #ifndef EEK_XKB_LAYOUT_H */
 | 
				
			||||||
							
								
								
									
										26
									
								
								eek/eek-xkb.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,26 @@
 | 
				
			|||||||
 | 
					/* 
 | 
				
			||||||
 | 
					 * Copyright (C) 2010-2011 Daiki Ueno <ueno@unixuser.org>
 | 
				
			||||||
 | 
					 * Copyright (C) 2010-2011 Red Hat, Inc.
 | 
				
			||||||
 | 
					 * 
 | 
				
			||||||
 | 
					 * This library is free software; you can redistribute it and/or
 | 
				
			||||||
 | 
					 * modify it under the terms of the GNU Lesser General Public License
 | 
				
			||||||
 | 
					 * as published by the Free Software Foundation; either version 2 of
 | 
				
			||||||
 | 
					 * the License, or (at your option) any later version.
 | 
				
			||||||
 | 
					 * 
 | 
				
			||||||
 | 
					 * This library is distributed in the hope that it will be useful, but
 | 
				
			||||||
 | 
					 * WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
				
			||||||
 | 
					 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
				
			||||||
 | 
					 * Lesser General Public License for more details.
 | 
				
			||||||
 | 
					 * 
 | 
				
			||||||
 | 
					 * You should have received a copy of the GNU Lesser General Public
 | 
				
			||||||
 | 
					 * License along with this library; if not, write to the Free Software
 | 
				
			||||||
 | 
					 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 | 
				
			||||||
 | 
					 * 02110-1301 USA
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					#ifndef EEK_XKB_H
 | 
				
			||||||
 | 
					#define EEK_XKB_H 1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "eek.h"
 | 
				
			||||||
 | 
					#include "eek-xkb-layout.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif  /* EEK_XKB_H */
 | 
				
			||||||
							
								
								
									
										30
									
								
								eek/eek-xkl-0.90.pc.in
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,30 @@
 | 
				
			|||||||
 | 
					# Copyright (C) 2010-2011 Daiki Ueno <ueno@unixuser.org>
 | 
				
			||||||
 | 
					# Copyright (C) 2010-2011 Red Hat, Inc.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# This library is free software; you can redistribute it and/or
 | 
				
			||||||
 | 
					# modify it under the terms of the GNU Lesser General Public License
 | 
				
			||||||
 | 
					# as published by the Free Software Foundation; either version 2 of
 | 
				
			||||||
 | 
					# the License, or (at your option) any later version.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# This library is distributed in the hope that it will be useful, but
 | 
				
			||||||
 | 
					# WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
				
			||||||
 | 
					# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
				
			||||||
 | 
					# Lesser General Public License for more details.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# You should have received a copy of the GNU Lesser General Public
 | 
				
			||||||
 | 
					# License along with this library; if not, write to the Free Software
 | 
				
			||||||
 | 
					# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 | 
				
			||||||
 | 
					# 02110-1301 USA
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					prefix=@prefix@
 | 
				
			||||||
 | 
					exec_prefix=@exec_prefix@
 | 
				
			||||||
 | 
					libdir=@libdir@
 | 
				
			||||||
 | 
					includedir=@includedir@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Name: libeek-xkl
 | 
				
			||||||
 | 
					Description: A Library to Create Keyboard-like UI (Libxklavier Support)
 | 
				
			||||||
 | 
					URL: http://fedorahosted.org/eekboard/
 | 
				
			||||||
 | 
					Version: @VERSION@
 | 
				
			||||||
 | 
					Requires: eek-@EEK_API_VERSION@ libxklavier
 | 
				
			||||||
 | 
					Libs: -L${libdir} -leek-xkl
 | 
				
			||||||
 | 
					Cflags: -I${includedir}/eek-@EEK_API_VERSION@
 | 
				
			||||||
							
								
								
									
										662
									
								
								eek/eek-xkl-layout.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,662 @@
 | 
				
			|||||||
 | 
					/* 
 | 
				
			||||||
 | 
					 * Copyright (C) 2010-2011 Daiki Ueno <ueno@unixuser.org>
 | 
				
			||||||
 | 
					 * Copyright (C) 2010-2011 Red Hat, Inc.
 | 
				
			||||||
 | 
					 * 
 | 
				
			||||||
 | 
					 * This library is free software; you can redistribute it and/or
 | 
				
			||||||
 | 
					 * modify it under the terms of the GNU Lesser General Public License
 | 
				
			||||||
 | 
					 * as published by the Free Software Foundation; either version 2 of
 | 
				
			||||||
 | 
					 * the License, or (at your option) any later version.
 | 
				
			||||||
 | 
					 * 
 | 
				
			||||||
 | 
					 * This library is distributed in the hope that it will be useful, but
 | 
				
			||||||
 | 
					 * WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
				
			||||||
 | 
					 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
				
			||||||
 | 
					 * Lesser General Public License for more details.
 | 
				
			||||||
 | 
					 * 
 | 
				
			||||||
 | 
					 * You should have received a copy of the GNU Lesser General Public
 | 
				
			||||||
 | 
					 * License along with this library; if not, write to the Free Software
 | 
				
			||||||
 | 
					 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 | 
				
			||||||
 | 
					 * 02110-1301 USA
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * SECTION:eek-xkl-layout
 | 
				
			||||||
 | 
					 * @short_description: Layout engine using Libxklavier configuration
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * The #EekXklLayout is a simple wrapper around #EekXkbLayout class
 | 
				
			||||||
 | 
					 * to use Libxklavier configuration.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef HAVE_CONFIG_H
 | 
				
			||||||
 | 
					#include "config.h"
 | 
				
			||||||
 | 
					#endif  /* HAVE_CONFIG_H */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <libxklavier/xklavier.h>
 | 
				
			||||||
 | 
					#include <gio/gio.h>
 | 
				
			||||||
 | 
					#include <string.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "eek-xkl-layout.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define noKBDRAW_DEBUG
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static GInitableIface *parent_initable_iface;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void initable_iface_init (GInitableIface *initable_iface);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					enum {
 | 
				
			||||||
 | 
					    PROP_0,
 | 
				
			||||||
 | 
					    PROP_MODEL,
 | 
				
			||||||
 | 
					    PROP_LAYOUTS,
 | 
				
			||||||
 | 
					    PROP_VARIANTS,
 | 
				
			||||||
 | 
					    PROP_OPTIONS,
 | 
				
			||||||
 | 
					    PROP_LAST
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef struct _EekXklLayoutPrivate
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    XklEngine *engine;
 | 
				
			||||||
 | 
					    XklConfigRec *config;
 | 
				
			||||||
 | 
					} EekXklLayoutPrivate;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					G_DEFINE_TYPE_EXTENDED (EekXklLayout, eek_xkl_layout, EEK_TYPE_XKB_LAYOUT,
 | 
				
			||||||
 | 
								0, /* GTypeFlags */
 | 
				
			||||||
 | 
								G_ADD_PRIVATE (EekXklLayout)
 | 
				
			||||||
 | 
					                        G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE,
 | 
				
			||||||
 | 
					                                               initable_iface_init))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* from gnome-keyboard-properties-xkbpv.c:
 | 
				
			||||||
 | 
					 *  BAD STYLE: Taken from xklavier_private_xkb.h
 | 
				
			||||||
 | 
					 *  Any ideas on architectural improvements are WELCOME
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					extern gboolean xkl_xkb_config_native_prepare (XklEngine * engine,
 | 
				
			||||||
 | 
										       const XklConfigRec * data,
 | 
				
			||||||
 | 
										       XkbComponentNamesPtr
 | 
				
			||||||
 | 
										       component_names);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					extern void xkl_xkb_config_native_cleanup (XklEngine * engine,
 | 
				
			||||||
 | 
										   XkbComponentNamesPtr
 | 
				
			||||||
 | 
										   component_names);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static gboolean set_xkb_component_names (EekXklLayout *layout,
 | 
				
			||||||
 | 
					                                         XklConfigRec *config);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					eek_xkl_layout_dispose (GObject *object)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    EekXklLayoutPrivate *priv = eek_xkl_layout_get_instance_private (
 | 
				
			||||||
 | 
							    EEK_XKL_LAYOUT (object));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (priv->config) {
 | 
				
			||||||
 | 
					        g_object_unref (priv->config);
 | 
				
			||||||
 | 
					        priv->config = NULL;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    G_OBJECT_CLASS (eek_xkl_layout_parent_class)->dispose (object);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void 
 | 
				
			||||||
 | 
					eek_xkl_layout_set_property (GObject      *object,
 | 
				
			||||||
 | 
					                             guint         prop_id,
 | 
				
			||||||
 | 
					                             const GValue *value,
 | 
				
			||||||
 | 
					                             GParamSpec   *pspec)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    EekXklLayout *layout = EEK_XKL_LAYOUT(object);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    switch (prop_id) {
 | 
				
			||||||
 | 
					    case PROP_MODEL:
 | 
				
			||||||
 | 
					        eek_xkl_layout_set_model (layout, g_value_get_string (value));
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					    case PROP_LAYOUTS:
 | 
				
			||||||
 | 
					        eek_xkl_layout_set_layouts (layout, g_value_get_boxed (value));
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					    case PROP_VARIANTS:
 | 
				
			||||||
 | 
					        eek_xkl_layout_set_variants (layout, g_value_get_boxed (value));
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					    case PROP_OPTIONS:
 | 
				
			||||||
 | 
					        eek_xkl_layout_set_options (layout, g_value_get_boxed (value));
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					    default:
 | 
				
			||||||
 | 
					        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void 
 | 
				
			||||||
 | 
					eek_xkl_layout_get_property (GObject    *object,
 | 
				
			||||||
 | 
					                             guint       prop_id,
 | 
				
			||||||
 | 
					                             GValue     *value,
 | 
				
			||||||
 | 
					                             GParamSpec *pspec)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    EekXklLayout *layout = EEK_XKL_LAYOUT(object);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    switch (prop_id) {
 | 
				
			||||||
 | 
					    case PROP_MODEL:
 | 
				
			||||||
 | 
					        g_value_set_string (value,
 | 
				
			||||||
 | 
					                            eek_xkl_layout_get_model (layout));
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					    case PROP_LAYOUTS:
 | 
				
			||||||
 | 
					        g_value_set_boxed (value,
 | 
				
			||||||
 | 
					                           eek_xkl_layout_get_layouts (layout));
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					    case PROP_VARIANTS:
 | 
				
			||||||
 | 
					        g_value_set_boxed (value,
 | 
				
			||||||
 | 
					                           eek_xkl_layout_get_variants (layout));
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					    case PROP_OPTIONS:
 | 
				
			||||||
 | 
					        g_value_set_boxed (value,
 | 
				
			||||||
 | 
					                           eek_xkl_layout_get_options (layout));
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					    default:
 | 
				
			||||||
 | 
					        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					eek_xkl_layout_class_init (EekXklLayoutClass *klass)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
 | 
				
			||||||
 | 
					    GParamSpec *pspec;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    gobject_class->dispose = eek_xkl_layout_dispose;
 | 
				
			||||||
 | 
					    gobject_class->set_property = eek_xkl_layout_set_property;
 | 
				
			||||||
 | 
					    gobject_class->get_property = eek_xkl_layout_get_property;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * EekXklLayout:model:
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * The libxklavier model name of #EekXklLayout.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    pspec = g_param_spec_string ("model",
 | 
				
			||||||
 | 
					                                 "Model",
 | 
				
			||||||
 | 
					                                 "Libxklavier model",
 | 
				
			||||||
 | 
					                                 NULL,
 | 
				
			||||||
 | 
					                                 G_PARAM_READWRITE);
 | 
				
			||||||
 | 
					    g_object_class_install_property (gobject_class, PROP_MODEL, pspec);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * EekXklLayout:layouts:
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * The libxklavier layout names of #EekXklLayout.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    pspec = g_param_spec_boxed ("layouts",
 | 
				
			||||||
 | 
					                                "Layouts",
 | 
				
			||||||
 | 
					                                "Libxklavier layouts",
 | 
				
			||||||
 | 
					                                G_TYPE_STRV,
 | 
				
			||||||
 | 
					                                G_PARAM_READWRITE);
 | 
				
			||||||
 | 
					    g_object_class_install_property (gobject_class, PROP_LAYOUTS, pspec);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * EekXklLayout:variants:
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * The libxklavier variant names of #EekXklLayout.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    pspec = g_param_spec_boxed ("variants",
 | 
				
			||||||
 | 
					                                "Variants",
 | 
				
			||||||
 | 
					                                "Libxklavier variants",
 | 
				
			||||||
 | 
					                                G_TYPE_STRV,
 | 
				
			||||||
 | 
					                                G_PARAM_READWRITE);
 | 
				
			||||||
 | 
					    g_object_class_install_property (gobject_class, PROP_VARIANTS, pspec);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * EekXklLayout:options:
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * The libxklavier option names of #EekXklLayout.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    pspec = g_param_spec_boxed ("options",
 | 
				
			||||||
 | 
					                                "Options",
 | 
				
			||||||
 | 
					                                "Libxklavier options",
 | 
				
			||||||
 | 
					                                G_TYPE_STRV,
 | 
				
			||||||
 | 
					                                G_PARAM_READWRITE);
 | 
				
			||||||
 | 
					    g_object_class_install_property (gobject_class, PROP_OPTIONS, pspec);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					eek_xkl_layout_init (EekXklLayout *self)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    /* void */
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * eek_xkl_layout_new:
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Create a new #EekXklLayout.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					EekLayout *
 | 
				
			||||||
 | 
					eek_xkl_layout_new (Display *display, GError **error)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return (EekLayout *) g_initable_new (EEK_TYPE_XKL_LAYOUT,
 | 
				
			||||||
 | 
					                                         NULL,
 | 
				
			||||||
 | 
					                                         error,
 | 
				
			||||||
 | 
					                                         "display", display,
 | 
				
			||||||
 | 
					                                         NULL);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					G_INLINE_FUNC void
 | 
				
			||||||
 | 
					merge_xkl_config_rec (XklConfigRec *dst, XklConfigRec *src)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    if (src->model) {
 | 
				
			||||||
 | 
					        g_free (dst->model);
 | 
				
			||||||
 | 
					        dst->model = g_strdup (src->model);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if (src->layouts) {
 | 
				
			||||||
 | 
					        g_strfreev (dst->layouts);
 | 
				
			||||||
 | 
					        dst->layouts = g_strdupv (src->layouts);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if (src->variants) {
 | 
				
			||||||
 | 
					        g_strfreev (dst->variants);
 | 
				
			||||||
 | 
					        dst->variants = g_strdupv (src->variants);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if (src->options) {
 | 
				
			||||||
 | 
					        g_strfreev (dst->options);
 | 
				
			||||||
 | 
					        dst->options = g_strdupv (src->options);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * eek_xkl_layout_set_config: (skip)
 | 
				
			||||||
 | 
					 * @layout: an #EekXklLayout
 | 
				
			||||||
 | 
					 * @config: Libxklavier configuration
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Reconfigure @layout with @config.
 | 
				
			||||||
 | 
					 * Returns: %TRUE if the current layout changed, %FALSE otherwise
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					gboolean
 | 
				
			||||||
 | 
					eek_xkl_layout_set_config (EekXklLayout *layout,
 | 
				
			||||||
 | 
					                           XklConfigRec *config)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    EekXklLayoutPrivate *priv = eek_xkl_layout_get_instance_private (layout);
 | 
				
			||||||
 | 
					    XklConfigRec *c;
 | 
				
			||||||
 | 
					    gboolean retval;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    g_return_val_if_fail (priv, FALSE);
 | 
				
			||||||
 | 
					    c = xkl_config_rec_new ();
 | 
				
			||||||
 | 
					    merge_xkl_config_rec (c, priv->config);
 | 
				
			||||||
 | 
					    merge_xkl_config_rec (c, config);
 | 
				
			||||||
 | 
					    retval = set_xkb_component_names (layout, c);
 | 
				
			||||||
 | 
					    g_object_unref (c);
 | 
				
			||||||
 | 
					    merge_xkl_config_rec (priv->config, config);
 | 
				
			||||||
 | 
					    return retval;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * eek_xkl_layout_set_config_full:
 | 
				
			||||||
 | 
					 * @layout: an #EekXklLayout
 | 
				
			||||||
 | 
					 * @model: Libxklavier model name
 | 
				
			||||||
 | 
					 * @layouts: Libxklavier layouts
 | 
				
			||||||
 | 
					 * @variants: Libxklavier variants
 | 
				
			||||||
 | 
					 * @options: Libxklavier options
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Reconfigure @layout with @model, @layouts, @variants, and @options.
 | 
				
			||||||
 | 
					 * This function is merely a wrapper around
 | 
				
			||||||
 | 
					 * eek_xkl_layout_set_config() to avoid passing a pointer of
 | 
				
			||||||
 | 
					 * XklConfigRec, which is not currently available in the
 | 
				
			||||||
 | 
					 * gobject-introspection repository.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Returns: %TRUE if the current layout changed, %FALSE otherwise
 | 
				
			||||||
 | 
					 * Since: 0.0.2
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					gboolean
 | 
				
			||||||
 | 
					eek_xkl_layout_set_config_full (EekXklLayout *layout,
 | 
				
			||||||
 | 
					                                gchar *model,
 | 
				
			||||||
 | 
					                                gchar **layouts,
 | 
				
			||||||
 | 
					                                gchar **variants,
 | 
				
			||||||
 | 
					                                gchar **options)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    XklConfigRec *config;
 | 
				
			||||||
 | 
					    gboolean retval;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    config = xkl_config_rec_new ();
 | 
				
			||||||
 | 
					    config->model = g_strdup (model);
 | 
				
			||||||
 | 
					    config->layouts = g_strdupv (layouts);
 | 
				
			||||||
 | 
					    config->variants = g_strdupv (variants);
 | 
				
			||||||
 | 
					    config->options = g_strdupv (options);
 | 
				
			||||||
 | 
					    retval = eek_xkl_layout_set_config (layout, config);
 | 
				
			||||||
 | 
					    g_object_unref (config);
 | 
				
			||||||
 | 
					    return retval;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * eek_xkl_layout_set_model:
 | 
				
			||||||
 | 
					 * @layout: an #EekXklLayout
 | 
				
			||||||
 | 
					 * @model: model name
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Set the model name of @layout configuration (in the Libxklavier terminology).
 | 
				
			||||||
 | 
					 * Returns: %TRUE if the current layout changed, %FALSE otherwise
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					gboolean
 | 
				
			||||||
 | 
					eek_xkl_layout_set_model (EekXklLayout *layout,
 | 
				
			||||||
 | 
					                          const gchar  *model)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    EekXklLayoutPrivate *priv = eek_xkl_layout_get_instance_private (layout);
 | 
				
			||||||
 | 
					    XklConfigRec *config;
 | 
				
			||||||
 | 
					    gboolean retval;
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    g_return_val_if_fail (priv, FALSE);
 | 
				
			||||||
 | 
					    config = xkl_config_rec_new ();
 | 
				
			||||||
 | 
					    /* config->model will be freed on g_object_unref (config) */
 | 
				
			||||||
 | 
					    if (model)
 | 
				
			||||||
 | 
					        config->model = g_strdup (model);
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					        config->model = NULL;
 | 
				
			||||||
 | 
					    retval = eek_xkl_layout_set_config (layout, config);
 | 
				
			||||||
 | 
					    g_object_unref (config);
 | 
				
			||||||
 | 
					    return retval;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * eek_xkl_layout_set_layouts:
 | 
				
			||||||
 | 
					 * @layout: an #EekXklLayout
 | 
				
			||||||
 | 
					 * @layouts: layout names
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Set the layout names of @layout (in the Libxklavier terminology).
 | 
				
			||||||
 | 
					 * Returns: %TRUE if the current layout changed, %FALSE otherwise
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					gboolean
 | 
				
			||||||
 | 
					eek_xkl_layout_set_layouts (EekXklLayout *layout,
 | 
				
			||||||
 | 
					                            gchar       **layouts)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    EekXklLayoutPrivate *priv = eek_xkl_layout_get_instance_private (layout);
 | 
				
			||||||
 | 
					    XklConfigRec *config;
 | 
				
			||||||
 | 
					    gboolean retval;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    g_return_val_if_fail (priv, FALSE);
 | 
				
			||||||
 | 
					    config = xkl_config_rec_new ();
 | 
				
			||||||
 | 
					    /* config->layouts will be freed on g_object_unref (config) */
 | 
				
			||||||
 | 
					    if (layouts)
 | 
				
			||||||
 | 
					        config->layouts = g_strdupv (layouts);
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					        config->layouts = layouts;
 | 
				
			||||||
 | 
					    retval = eek_xkl_layout_set_config (layout, config);
 | 
				
			||||||
 | 
					    g_object_unref (config);
 | 
				
			||||||
 | 
					    return retval;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * eek_xkl_layout_set_variants:
 | 
				
			||||||
 | 
					 * @layout: an #EekXklLayout
 | 
				
			||||||
 | 
					 * @variants: variant names
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Set the variant names of @layout (in the Libxklavier terminology).
 | 
				
			||||||
 | 
					 * Returns: %TRUE if the current layout changed, %FALSE otherwise
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					gboolean
 | 
				
			||||||
 | 
					eek_xkl_layout_set_variants (EekXklLayout *layout,
 | 
				
			||||||
 | 
					                             gchar       **variants)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    EekXklLayoutPrivate *priv = eek_xkl_layout_get_instance_private (layout);
 | 
				
			||||||
 | 
					    XklConfigRec *config;
 | 
				
			||||||
 | 
					    gboolean retval;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    g_return_val_if_fail (priv, FALSE);
 | 
				
			||||||
 | 
					    config = xkl_config_rec_new ();
 | 
				
			||||||
 | 
					    /* config->variants will be freed on g_object_unref (config) */
 | 
				
			||||||
 | 
					    if (variants)
 | 
				
			||||||
 | 
					        config->variants = g_strdupv (variants);
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					        config->variants = NULL;
 | 
				
			||||||
 | 
					    retval = eek_xkl_layout_set_config (layout, config);
 | 
				
			||||||
 | 
					    g_object_unref (config);
 | 
				
			||||||
 | 
					    return retval;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * eek_xkl_layout_set_options:
 | 
				
			||||||
 | 
					 * @layout: an #EekXklLayout
 | 
				
			||||||
 | 
					 * @options: option names
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Set the option names of @layout (in the Libxklavier terminology).
 | 
				
			||||||
 | 
					 * Returns: %TRUE if the current layout changed, %FALSE otherwise
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					gboolean
 | 
				
			||||||
 | 
					eek_xkl_layout_set_options (EekXklLayout *layout,
 | 
				
			||||||
 | 
					                            gchar       **options)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    EekXklLayoutPrivate *priv = eek_xkl_layout_get_instance_private (layout);
 | 
				
			||||||
 | 
					    XklConfigRec *config;
 | 
				
			||||||
 | 
					    gboolean retval;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    g_return_val_if_fail (priv, FALSE);
 | 
				
			||||||
 | 
					    config = xkl_config_rec_new ();
 | 
				
			||||||
 | 
					    /* config->options will be freed on g_object_unref (config) */
 | 
				
			||||||
 | 
					    if (options)
 | 
				
			||||||
 | 
					        config->options = options;
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					        config->options = NULL;
 | 
				
			||||||
 | 
					    retval = eek_xkl_layout_set_config (layout, config);
 | 
				
			||||||
 | 
					    g_object_unref (config);
 | 
				
			||||||
 | 
					    return retval;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * eek_xkl_layout_enable_option:
 | 
				
			||||||
 | 
					 * @layout: an #EekXklLayout
 | 
				
			||||||
 | 
					 * @option: option name
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Set the option of @layout (in the Libxklavier terminology).
 | 
				
			||||||
 | 
					 * Returns: %TRUE if the current layout changed, %FALSE otherwise
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					gboolean
 | 
				
			||||||
 | 
					eek_xkl_layout_enable_option  (EekXklLayout *layout,
 | 
				
			||||||
 | 
					                               const gchar  *option)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    gchar **options, **_options;
 | 
				
			||||||
 | 
					    gint i, j;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    options = eek_xkl_layout_get_options (layout);
 | 
				
			||||||
 | 
					    for (i = 0; options && options[i]; i++)
 | 
				
			||||||
 | 
					        if (g_strcmp0 (options[i], option) == 0)
 | 
				
			||||||
 | 
					            return TRUE;
 | 
				
			||||||
 | 
					    _options = g_new0 (gchar *, (i + 2));
 | 
				
			||||||
 | 
					    for (j = 0; j < i; j++)
 | 
				
			||||||
 | 
					        _options[j] = g_strdup (options[j]);
 | 
				
			||||||
 | 
					    _options[i] = g_strdup (option);
 | 
				
			||||||
 | 
					    /* eek_xkl_layout_set_options() will free _options and its elements. */
 | 
				
			||||||
 | 
					    return eek_xkl_layout_set_options (layout, _options);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * eek_xkl_layout_disable_option:
 | 
				
			||||||
 | 
					 * @layout: an #EekXklLayout
 | 
				
			||||||
 | 
					 * @option: option name
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Unset the option of @layout (in the Libxklavier terminology).
 | 
				
			||||||
 | 
					 * Returns: %TRUE if the current layout changed, %FALSE otherwise
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					gboolean
 | 
				
			||||||
 | 
					eek_xkl_layout_disable_option (EekXklLayout *layout,
 | 
				
			||||||
 | 
					                               const gchar  *option)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    gchar **options, **_options;
 | 
				
			||||||
 | 
					    gint i, j, k;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    options = eek_xkl_layout_get_options (layout);
 | 
				
			||||||
 | 
					    if (!options)
 | 
				
			||||||
 | 
					        return TRUE;
 | 
				
			||||||
 | 
					    for (i = 0, k = 0; options[i]; i++)
 | 
				
			||||||
 | 
					        if (g_strcmp0 (options[i], option) == 0)
 | 
				
			||||||
 | 
					            k = i;
 | 
				
			||||||
 | 
					    if (options[k] == NULL)
 | 
				
			||||||
 | 
					        return TRUE;
 | 
				
			||||||
 | 
					    _options = g_new0 (gchar *, i);
 | 
				
			||||||
 | 
					    for (j = 0; j < k; j++)
 | 
				
			||||||
 | 
					        _options[j] = g_strdup (options[j]);
 | 
				
			||||||
 | 
					    for (j = k + 1; j < i; j++)
 | 
				
			||||||
 | 
					        _options[j] = g_strdup (options[j]);
 | 
				
			||||||
 | 
					    /* eek_xkl_layout_set_options() will free _options and its elements. */
 | 
				
			||||||
 | 
					    return eek_xkl_layout_set_options (layout, _options);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * eek_xkl_layout_get_model:
 | 
				
			||||||
 | 
					 * @layout: an #EekXklLayout
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Get the model name of @layout configuration (in the Libxklavier terminology).
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					gchar *
 | 
				
			||||||
 | 
					eek_xkl_layout_get_model (EekXklLayout *layout)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    EekXklLayoutPrivate *priv = eek_xkl_layout_get_instance_private (layout);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    g_return_val_if_fail (priv, NULL);
 | 
				
			||||||
 | 
					    return g_strdup (priv->config->model);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * eek_xkl_layout_get_layouts:
 | 
				
			||||||
 | 
					 * @layout: an #EekXklLayout
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Get the layout names of @layout configuration (in the Libxklavier
 | 
				
			||||||
 | 
					 * terminology).
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					gchar **
 | 
				
			||||||
 | 
					eek_xkl_layout_get_layouts (EekXklLayout *layout)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    EekXklLayoutPrivate *priv = eek_xkl_layout_get_instance_private (layout);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    g_return_val_if_fail (priv, NULL);
 | 
				
			||||||
 | 
					    return g_strdupv (priv->config->layouts);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * eek_xkl_layout_get_variants:
 | 
				
			||||||
 | 
					 * @layout: an #EekXklLayout
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Get the variant names of @layout configuration (in the Libxklavier
 | 
				
			||||||
 | 
					 * terminology).
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					gchar **
 | 
				
			||||||
 | 
					eek_xkl_layout_get_variants (EekXklLayout *layout)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    EekXklLayoutPrivate *priv = eek_xkl_layout_get_instance_private (layout);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    g_return_val_if_fail (priv, NULL);
 | 
				
			||||||
 | 
					    return g_strdupv (priv->config->variants);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * eek_xkl_layout_get_options:
 | 
				
			||||||
 | 
					 * @layout: an #EekXklLayout
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Get the option names of @layout configuration (in the Libxklavier
 | 
				
			||||||
 | 
					 * terminology).
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					gchar **
 | 
				
			||||||
 | 
					eek_xkl_layout_get_options (EekXklLayout *layout)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    EekXklLayoutPrivate *priv = eek_xkl_layout_get_instance_private (layout);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    g_return_val_if_fail (priv, NULL);
 | 
				
			||||||
 | 
					    return g_strdupv (priv->config->options);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static gboolean
 | 
				
			||||||
 | 
					set_xkb_component_names (EekXklLayout *layout, XklConfigRec *config)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    EekXklLayoutPrivate *priv = eek_xkl_layout_get_instance_private (layout);
 | 
				
			||||||
 | 
					    XkbComponentNamesRec names;
 | 
				
			||||||
 | 
					    gboolean retval = FALSE;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if DEBUG
 | 
				
			||||||
 | 
					    if (config->layouts) {
 | 
				
			||||||
 | 
					        gint i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        fprintf (stderr, "layout = ");
 | 
				
			||||||
 | 
					        for (i = 0; config->layouts[i] != NULL; i++)
 | 
				
			||||||
 | 
					            fprintf (stderr, "\"%s\" ", config->layouts[i]);
 | 
				
			||||||
 | 
					        fputc ('\n', stderr);
 | 
				
			||||||
 | 
					    } else
 | 
				
			||||||
 | 
					        fprintf (stderr, "layouts = NULL\n");
 | 
				
			||||||
 | 
					    if (config->variants) {
 | 
				
			||||||
 | 
					        gint i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        fprintf (stderr, "variant = ");
 | 
				
			||||||
 | 
					        for (i = 0; config->variants[i]; i++)
 | 
				
			||||||
 | 
					            fprintf (stderr, "\"%s\" ", config->variants[i]);
 | 
				
			||||||
 | 
					        fputc ('\n', stderr);
 | 
				
			||||||
 | 
					    } else
 | 
				
			||||||
 | 
					        fprintf (stderr, "variants = NULL\n");
 | 
				
			||||||
 | 
					    if (config->options) {
 | 
				
			||||||
 | 
					        gint i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        fprintf (stderr, "option = ");
 | 
				
			||||||
 | 
					        for (i = 0; config->options[i]; i++)
 | 
				
			||||||
 | 
					            fprintf (stderr, "\"%s\" ", config->options[i]);
 | 
				
			||||||
 | 
					        fputc ('\n', stderr);
 | 
				
			||||||
 | 
					    } else
 | 
				
			||||||
 | 
					        fprintf (stderr, "options = NULL\n");
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (xkl_xkb_config_native_prepare (priv->engine, config, &names)) {
 | 
				
			||||||
 | 
					        GError *error = NULL;
 | 
				
			||||||
 | 
					        retval = eek_xkb_layout_set_names (EEK_XKB_LAYOUT(layout),
 | 
				
			||||||
 | 
					                                           &names,
 | 
				
			||||||
 | 
					                                           &error);
 | 
				
			||||||
 | 
					        if (!retval)
 | 
				
			||||||
 | 
					            g_warning ("can't set XKB layout");
 | 
				
			||||||
 | 
					        xkl_xkb_config_native_cleanup (priv->engine, &names);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return retval;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * eek_xkl_layout_get_option:
 | 
				
			||||||
 | 
					 * @layout: an #EekXklLayout
 | 
				
			||||||
 | 
					 * @option: option name
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Tell if the option of @layout (in the Libxklavier terminology) is set.
 | 
				
			||||||
 | 
					 * Returns: %TRUE if the option is set, %FALSE otherwise
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					gboolean
 | 
				
			||||||
 | 
					eek_xkl_layout_get_option (EekXklLayout *layout,
 | 
				
			||||||
 | 
					                           const gchar  *option)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    gchar **options;
 | 
				
			||||||
 | 
					    gint i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    options = eek_xkl_layout_get_options (layout);
 | 
				
			||||||
 | 
					    for (i = 0; options && options[i]; i++)
 | 
				
			||||||
 | 
					        if (g_strcmp0 (options[i], option) == 0)
 | 
				
			||||||
 | 
					            return TRUE;
 | 
				
			||||||
 | 
					    return FALSE;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static gboolean
 | 
				
			||||||
 | 
					initable_init (GInitable    *initable,
 | 
				
			||||||
 | 
					               GCancellable *cancellable,
 | 
				
			||||||
 | 
					               GError      **error)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    EekXklLayout *layout = EEK_XKL_LAYOUT (initable);
 | 
				
			||||||
 | 
					    EekXklLayoutPrivate *priv = eek_xkl_layout_get_instance_private (layout);
 | 
				
			||||||
 | 
					    Display *display;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (!parent_initable_iface->init (initable, cancellable, error))
 | 
				
			||||||
 | 
					        return FALSE;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    priv->config = xkl_config_rec_new ();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    g_object_get (G_OBJECT (initable),
 | 
				
			||||||
 | 
					                  "display", &display,
 | 
				
			||||||
 | 
					                  NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    priv->engine = xkl_engine_get_instance (display);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (!xkl_config_rec_get_from_server (priv->config,
 | 
				
			||||||
 | 
					                                         priv->engine)) {
 | 
				
			||||||
 | 
					        g_set_error (error,
 | 
				
			||||||
 | 
					                     EEK_ERROR,
 | 
				
			||||||
 | 
					                     EEK_ERROR_LAYOUT_ERROR,
 | 
				
			||||||
 | 
					                     "can't load libxklavier configuration");
 | 
				
			||||||
 | 
					        return FALSE;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    set_xkb_component_names (layout, priv->config);
 | 
				
			||||||
 | 
					    return TRUE;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					initable_iface_init (GInitableIface *initable_iface)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    parent_initable_iface = g_type_interface_peek_parent (initable_iface);
 | 
				
			||||||
 | 
					    initable_iface->init = initable_init;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							
								
								
									
										81
									
								
								eek/eek-xkl-layout.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,81 @@
 | 
				
			|||||||
 | 
					/* 
 | 
				
			||||||
 | 
					 * Copyright (C) 2010-2011 Daiki Ueno <ueno@unixuser.org>
 | 
				
			||||||
 | 
					 * Copyright (C) 2010-2011 Red Hat, Inc.
 | 
				
			||||||
 | 
					 * 
 | 
				
			||||||
 | 
					 * This library is free software; you can redistribute it and/or
 | 
				
			||||||
 | 
					 * modify it under the terms of the GNU Lesser General Public License
 | 
				
			||||||
 | 
					 * as published by the Free Software Foundation; either version 2 of
 | 
				
			||||||
 | 
					 * the License, or (at your option) any later version.
 | 
				
			||||||
 | 
					 * 
 | 
				
			||||||
 | 
					 * This library is distributed in the hope that it will be useful, but
 | 
				
			||||||
 | 
					 * WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
				
			||||||
 | 
					 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
				
			||||||
 | 
					 * Lesser General Public License for more details.
 | 
				
			||||||
 | 
					 * 
 | 
				
			||||||
 | 
					 * You should have received a copy of the GNU Lesser General Public
 | 
				
			||||||
 | 
					 * License along with this library; if not, write to the Free Software
 | 
				
			||||||
 | 
					 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 | 
				
			||||||
 | 
					 * 02110-1301 USA
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if !defined(__EEK_H_INSIDE__) && !defined(EEK_COMPILATION)
 | 
				
			||||||
 | 
					#error "Only <eek/eek-xkl.h> can be included directly."
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef EEK_XKL_LAYOUT_H
 | 
				
			||||||
 | 
					#define EEK_XKL_LAYOUT_H 1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <libxklavier/xklavier.h>
 | 
				
			||||||
 | 
					#include "eek-xkb-layout.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					G_BEGIN_DECLS
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define EEK_TYPE_XKL_LAYOUT (eek_xkl_layout_get_type())
 | 
				
			||||||
 | 
					G_DECLARE_DERIVABLE_TYPE (EekXklLayout, eek_xkl_layout, EEK, XKL_LAYOUT, EekLayout)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct _EekXklLayoutClass
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    /*< private >*/
 | 
				
			||||||
 | 
					    EekXkbLayoutClass parent_class;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /*< private >*/
 | 
				
			||||||
 | 
					    /* padding */
 | 
				
			||||||
 | 
					    gpointer pdummy[24];
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					GType      eek_xkl_layout_get_type        (void) G_GNUC_CONST;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					EekLayout *eek_xkl_layout_new             (Display      *display,
 | 
				
			||||||
 | 
					                                           GError      **error);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					gboolean   eek_xkl_layout_set_config      (EekXklLayout *layout,
 | 
				
			||||||
 | 
					                                           XklConfigRec *config);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					gboolean   eek_xkl_layout_set_config_full (EekXklLayout *layout,
 | 
				
			||||||
 | 
					                                           gchar        *model,
 | 
				
			||||||
 | 
					                                           gchar       **layouts,
 | 
				
			||||||
 | 
					                                           gchar       **variants,
 | 
				
			||||||
 | 
					                                           gchar       **options);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					gboolean   eek_xkl_layout_set_model       (EekXklLayout *layout,
 | 
				
			||||||
 | 
					                                           const gchar  *model);
 | 
				
			||||||
 | 
					gboolean   eek_xkl_layout_set_layouts     (EekXklLayout *layout,
 | 
				
			||||||
 | 
					                                           gchar       **layouts);
 | 
				
			||||||
 | 
					gboolean   eek_xkl_layout_set_variants    (EekXklLayout *layout,
 | 
				
			||||||
 | 
					                                           gchar       **variants);
 | 
				
			||||||
 | 
					gboolean   eek_xkl_layout_set_options     (EekXklLayout *layout,
 | 
				
			||||||
 | 
					                                           gchar       **options);
 | 
				
			||||||
 | 
					gboolean   eek_xkl_layout_enable_option   (EekXklLayout *layout,
 | 
				
			||||||
 | 
					                                           const gchar  *option);
 | 
				
			||||||
 | 
					gboolean   eek_xkl_layout_disable_option  (EekXklLayout *layout,
 | 
				
			||||||
 | 
					                                           const gchar  *option);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					gchar     *eek_xkl_layout_get_model       (EekXklLayout *layout);
 | 
				
			||||||
 | 
					gchar    **eek_xkl_layout_get_layouts     (EekXklLayout *layout);
 | 
				
			||||||
 | 
					gchar    **eek_xkl_layout_get_variants    (EekXklLayout *layout);
 | 
				
			||||||
 | 
					gchar    **eek_xkl_layout_get_options     (EekXklLayout *layout);
 | 
				
			||||||
 | 
					gboolean   eek_xkl_layout_get_option      (EekXklLayout *layout,
 | 
				
			||||||
 | 
					                                           const gchar  *option);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					G_END_DECLS
 | 
				
			||||||
 | 
					#endif				/* #ifndef EEK_XKL_LAYOUT_H */
 | 
				
			||||||
							
								
								
									
										26
									
								
								eek/eek-xkl.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,26 @@
 | 
				
			|||||||
 | 
					/* 
 | 
				
			||||||
 | 
					 * Copyright (C) 2010-2011 Daiki Ueno <ueno@unixuser.org>
 | 
				
			||||||
 | 
					 * Copyright (C) 2010-2011 Red Hat, Inc.
 | 
				
			||||||
 | 
					 * 
 | 
				
			||||||
 | 
					 * This library is free software; you can redistribute it and/or
 | 
				
			||||||
 | 
					 * modify it under the terms of the GNU Lesser General Public License
 | 
				
			||||||
 | 
					 * as published by the Free Software Foundation; either version 2 of
 | 
				
			||||||
 | 
					 * the License, or (at your option) any later version.
 | 
				
			||||||
 | 
					 * 
 | 
				
			||||||
 | 
					 * This library is distributed in the hope that it will be useful, but
 | 
				
			||||||
 | 
					 * WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
				
			||||||
 | 
					 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
				
			||||||
 | 
					 * Lesser General Public License for more details.
 | 
				
			||||||
 | 
					 * 
 | 
				
			||||||
 | 
					 * You should have received a copy of the GNU Lesser General Public
 | 
				
			||||||
 | 
					 * License along with this library; if not, write to the Free Software
 | 
				
			||||||
 | 
					 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 | 
				
			||||||
 | 
					 * 02110-1301 USA
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					#ifndef EEK_XKL_H
 | 
				
			||||||
 | 
					#define EEK_XKL_H 1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "eek.h"
 | 
				
			||||||
 | 
					#include "eek-xkl-layout.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif  /* EEK_XKL_H */
 | 
				
			||||||
@ -21,19 +21,19 @@
 | 
				
			|||||||
 * @short_description: Layout engine which loads layout information from XML
 | 
					 * @short_description: Layout engine which loads layout information from XML
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef HAVE_CONFIG_H
 | 
				
			||||||
#include "config.h"
 | 
					#include "config.h"
 | 
				
			||||||
 | 
					#endif  /* HAVE_CONFIG_H */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <gio/gio.h> /* GResource */
 | 
					 | 
				
			||||||
#include <stdlib.h>
 | 
					#include <stdlib.h>
 | 
				
			||||||
#include <string.h>
 | 
					#include <string.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "eek-keyboard.h"
 | 
					 | 
				
			||||||
#include "src/keyboard.h"
 | 
					 | 
				
			||||||
#include "src/symbol.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include "squeekboard-resources.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include "eek-xml-layout.h"
 | 
					#include "eek-xml-layout.h"
 | 
				
			||||||
 | 
					#include "eek-keyboard.h"
 | 
				
			||||||
 | 
					#include "eek-section.h"
 | 
				
			||||||
 | 
					#include "eek-key.h"
 | 
				
			||||||
 | 
					#include "eek-keysym.h"
 | 
				
			||||||
 | 
					#include "eek-text.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
enum {
 | 
					enum {
 | 
				
			||||||
    PROP_0,
 | 
					    PROP_0,
 | 
				
			||||||
@ -66,18 +66,22 @@ static GList        *parse_prerequisites
 | 
				
			|||||||
                                     (const gchar         *path,
 | 
					                                     (const gchar         *path,
 | 
				
			||||||
                                      GError             **error);
 | 
					                                      GError             **error);
 | 
				
			||||||
static gboolean      parse_geometry  (const gchar         *path,
 | 
					static gboolean      parse_geometry  (const gchar         *path,
 | 
				
			||||||
                                      struct squeek_view **views, GArray *outline_array, GHashTable *name_button_hash,
 | 
					                                      EekKeyboard         *keyboard,
 | 
				
			||||||
                                      GError             **error);
 | 
					                                      GError             **error);
 | 
				
			||||||
static gboolean      parse_symbols_with_prerequisites
 | 
					static gboolean      parse_symbols_with_prerequisites
 | 
				
			||||||
                                     (const gchar         *keyboards_dir,
 | 
					                                     (const gchar         *keyboards_dir,
 | 
				
			||||||
                                      const gchar         *name,
 | 
					                                      const gchar         *name,
 | 
				
			||||||
                                      LevelKeyboard *keyboard,
 | 
					                                      EekKeyboard         *keyboard,
 | 
				
			||||||
                                      GList             **loaded,
 | 
					                                      GList             **loaded,
 | 
				
			||||||
                                      GError             **error);
 | 
					                                      GError             **error);
 | 
				
			||||||
static gboolean      parse_symbols   (const gchar         *path,
 | 
					static gboolean      parse_symbols   (const gchar         *path,
 | 
				
			||||||
                                      LevelKeyboard *keyboard,
 | 
					                                      EekKeyboard         *keyboard,
 | 
				
			||||||
                                      GError             **error);
 | 
					                                      GError             **error);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void          scale_keyboard  (EekKeyboard         *keyboard,
 | 
				
			||||||
 | 
					                                      gdouble              width,
 | 
				
			||||||
 | 
					                                      gdouble              height);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static gboolean      validate        (const gchar        **valid_path_list,
 | 
					static gboolean      validate        (const gchar        **valid_path_list,
 | 
				
			||||||
                                      gsize                valid_path_list_len,
 | 
					                                      gsize                valid_path_list_len,
 | 
				
			||||||
                                      const gchar         *element_name,
 | 
					                                      const gchar         *element_name,
 | 
				
			||||||
@ -231,68 +235,60 @@ struct _GeometryParseData {
 | 
				
			|||||||
    GSList *element_stack;
 | 
					    GSList *element_stack;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    EekBounds bounds;
 | 
					    EekBounds bounds;
 | 
				
			||||||
    struct squeek_view **views;
 | 
					    EekKeyboard *keyboard;
 | 
				
			||||||
    guint view_idx;
 | 
					    EekSection *section;
 | 
				
			||||||
    struct squeek_row *row;
 | 
					    EekKey *key;
 | 
				
			||||||
 | 
					    gint num_columns;
 | 
				
			||||||
    gint num_rows;
 | 
					    gint num_rows;
 | 
				
			||||||
    EekOrientation orientation;
 | 
					    EekOrientation orientation;
 | 
				
			||||||
    gdouble corner_radius;
 | 
					    gdouble corner_radius;
 | 
				
			||||||
    GSList *points;
 | 
					    GSList *points;
 | 
				
			||||||
    gchar *name;
 | 
					    gchar *name;
 | 
				
			||||||
    EekOutline outline;
 | 
					    EekOutline outline;
 | 
				
			||||||
    gchar *outline_id;
 | 
					    gchar *oref;
 | 
				
			||||||
    guint keycode;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    GString *text;
 | 
					    GHashTable *key_oref_hash;
 | 
				
			||||||
 | 
					    GHashTable *oref_outline_hash;
 | 
				
			||||||
    GArray *outline_array;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    GHashTable *name_button_hash; // char* -> struct squeek_button*
 | 
					 | 
				
			||||||
    GHashTable *keyname_oref_hash; // char* -> guint
 | 
					 | 
				
			||||||
    GHashTable *outlineid_oref_hash; // char* -> guint
 | 
					 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
typedef struct _GeometryParseData GeometryParseData;
 | 
					typedef struct _GeometryParseData GeometryParseData;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static GeometryParseData *
 | 
					static GeometryParseData *
 | 
				
			||||||
geometry_parse_data_new (struct squeek_view **views, GHashTable *name_button_hash, GArray *outline_array)
 | 
					geometry_parse_data_new (EekKeyboard *keyboard)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    GeometryParseData *data = g_slice_new0 (GeometryParseData);
 | 
					    GeometryParseData *data = g_slice_new0 (GeometryParseData);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    data->views = views;
 | 
					    data->keyboard = g_object_ref (keyboard);
 | 
				
			||||||
    data->outline_array = outline_array;
 | 
					    data->key_oref_hash =
 | 
				
			||||||
    data->keyname_oref_hash =
 | 
					        g_hash_table_new_full (g_direct_hash,
 | 
				
			||||||
 | 
					                               g_direct_equal,
 | 
				
			||||||
 | 
					                               NULL,
 | 
				
			||||||
 | 
					                               g_free);
 | 
				
			||||||
 | 
					    data->oref_outline_hash =
 | 
				
			||||||
        g_hash_table_new_full (g_str_hash,
 | 
					        g_hash_table_new_full (g_str_hash,
 | 
				
			||||||
                               g_str_equal,
 | 
					                               g_str_equal,
 | 
				
			||||||
                               g_free,
 | 
					                               g_free,
 | 
				
			||||||
                               NULL);
 | 
					                               (GDestroyNotify)eek_outline_free);
 | 
				
			||||||
    data->outlineid_oref_hash =
 | 
					 | 
				
			||||||
        g_hash_table_new_full (g_str_hash,
 | 
					 | 
				
			||||||
                               g_str_equal,
 | 
					 | 
				
			||||||
                               g_free,
 | 
					 | 
				
			||||||
                               NULL);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    data->name_button_hash = name_button_hash;
 | 
					 | 
				
			||||||
    data->text = g_string_sized_new (BUFSIZE);
 | 
					 | 
				
			||||||
    data->keycode = 8;
 | 
					 | 
				
			||||||
    return data;
 | 
					    return data;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void
 | 
					static void
 | 
				
			||||||
geometry_parse_data_free (GeometryParseData *data)
 | 
					geometry_parse_data_free (GeometryParseData *data)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    g_hash_table_destroy (data->keyname_oref_hash);
 | 
					    g_object_unref (data->keyboard);
 | 
				
			||||||
    g_hash_table_destroy (data->outlineid_oref_hash);
 | 
					    g_hash_table_destroy (data->key_oref_hash);
 | 
				
			||||||
    g_string_free (data->text, TRUE);
 | 
					    g_hash_table_destroy (data->oref_outline_hash);
 | 
				
			||||||
    g_slice_free (GeometryParseData, data);
 | 
					    g_slice_free (GeometryParseData, data);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static const gchar *geometry_valid_path_list[] = {
 | 
					static const gchar *geometry_valid_path_list[] = {
 | 
				
			||||||
    "geometry",
 | 
					    "geometry",
 | 
				
			||||||
    "button/geometry",
 | 
					 | 
				
			||||||
    "bounds/geometry",
 | 
					    "bounds/geometry",
 | 
				
			||||||
    "view/geometry",
 | 
					    "section/geometry",
 | 
				
			||||||
    "section/view/geometry",
 | 
					 | 
				
			||||||
    "outline/geometry",
 | 
					    "outline/geometry",
 | 
				
			||||||
 | 
					    "bounds/section/geometry",
 | 
				
			||||||
 | 
					    "row/section/geometry",
 | 
				
			||||||
 | 
					    "key/row/section/geometry",
 | 
				
			||||||
 | 
					    "bounds/key/row/section/geometry",
 | 
				
			||||||
    "point/outline/geometry",
 | 
					    "point/outline/geometry",
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -360,67 +356,82 @@ geometry_start_element_callback (GMarkupParseContext *pcontext,
 | 
				
			|||||||
            return;
 | 
					            return;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        bounds.height = g_strtod (attribute, NULL);
 | 
					        bounds.height = g_strtod (attribute, NULL);
 | 
				
			||||||
        data->bounds = bounds;
 | 
					 | 
				
			||||||
        goto out;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (g_strcmp0 (element_name, "view") == 0) {
 | 
					        if (g_strcmp0 (data->element_stack->data, "geometry") == 0)
 | 
				
			||||||
        /* Create an empty keyboard to which geometry and symbols
 | 
					            eek_element_set_bounds (EEK_ELEMENT(data->keyboard), &bounds);
 | 
				
			||||||
           information are applied. */
 | 
					        else if (g_strcmp0 (data->element_stack->data, "section") == 0)
 | 
				
			||||||
        struct squeek_view *view = squeek_view_new(data->bounds);
 | 
					            eek_element_set_bounds (EEK_ELEMENT(data->section), &bounds);
 | 
				
			||||||
        data->views[data->view_idx] = view;
 | 
					        goto out;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (g_strcmp0 (element_name, "section") == 0) {
 | 
					    if (g_strcmp0 (element_name, "section") == 0) {
 | 
				
			||||||
        gint angle = 0;
 | 
					        data->section = eek_keyboard_create_section (data->keyboard);
 | 
				
			||||||
 | 
					        attribute = get_attribute (attribute_names, attribute_values,
 | 
				
			||||||
 | 
					                                   "id");
 | 
				
			||||||
 | 
					        if (attribute != NULL)
 | 
				
			||||||
 | 
					            eek_element_set_name (EEK_ELEMENT(data->section), attribute);
 | 
				
			||||||
        attribute = get_attribute (attribute_names, attribute_values,
 | 
					        attribute = get_attribute (attribute_names, attribute_values,
 | 
				
			||||||
                                   "angle");
 | 
					                                   "angle");
 | 
				
			||||||
        if (attribute != NULL) {
 | 
					        if (attribute != NULL) {
 | 
				
			||||||
 | 
					            gint angle;
 | 
				
			||||||
            angle = strtol (attribute, NULL, 10);
 | 
					            angle = strtol (attribute, NULL, 10);
 | 
				
			||||||
 | 
					            eek_section_set_angle (data->section, angle);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        data->row = squeek_view_create_row(data->views[data->view_idx], angle);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        goto out;
 | 
					        goto out;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (g_strcmp0 (element_name, "button") == 0) {
 | 
					    if (g_strcmp0 (element_name, "row") == 0) {
 | 
				
			||||||
        const gchar *base_name = get_attribute (attribute_names, attribute_values,
 | 
					        attribute = get_attribute (attribute_names, attribute_values,
 | 
				
			||||||
                                   "name");
 | 
					                                   "orientation");
 | 
				
			||||||
        if (base_name == NULL) {
 | 
					        if (attribute != NULL)
 | 
				
			||||||
 | 
					            data->orientation = strtol (attribute, NULL, 10);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        eek_section_add_row (data->section,
 | 
				
			||||||
 | 
					                             data->num_columns,
 | 
				
			||||||
 | 
					                             data->orientation);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        data->num_rows++;
 | 
				
			||||||
 | 
					        goto out;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (g_strcmp0 (element_name, "key") == 0) {
 | 
				
			||||||
 | 
					        guint keycode;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        attribute = get_attribute (attribute_names, attribute_values,
 | 
				
			||||||
 | 
					                                   "keycode");
 | 
				
			||||||
 | 
					        if (attribute == NULL) {
 | 
				
			||||||
            g_set_error (error,
 | 
					            g_set_error (error,
 | 
				
			||||||
                         G_MARKUP_ERROR,
 | 
					                         G_MARKUP_ERROR,
 | 
				
			||||||
                         G_MARKUP_ERROR_MISSING_ATTRIBUTE,
 | 
					                         G_MARKUP_ERROR_MISSING_ATTRIBUTE,
 | 
				
			||||||
                         "no \"name\" attribute for \"button\"");
 | 
					                         "no \"keycode\" attribute for \"key\"");
 | 
				
			||||||
            return;
 | 
					            return;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					        keycode = strtoul (attribute, NULL, 10);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        const gchar *oref_name = get_attribute (attribute_names, attribute_values,
 | 
					        data->key = eek_section_create_key (data->section,
 | 
				
			||||||
 | 
					                                            keycode,
 | 
				
			||||||
 | 
					                                            data->num_columns,
 | 
				
			||||||
 | 
					                                            data->num_rows - 1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        attribute = get_attribute (attribute_names, attribute_values,
 | 
				
			||||||
 | 
					                                   "name");
 | 
				
			||||||
 | 
					        if (attribute != NULL)
 | 
				
			||||||
 | 
					            eek_element_set_name (EEK_ELEMENT(data->key), attribute);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        attribute = get_attribute (attribute_names, attribute_values,
 | 
				
			||||||
                                   "oref");
 | 
					                                   "oref");
 | 
				
			||||||
        if (oref_name == NULL) {
 | 
					        if (attribute == NULL) {
 | 
				
			||||||
            oref_name = "default";
 | 
					            g_set_error (error,
 | 
				
			||||||
 | 
					                         G_MARKUP_ERROR,
 | 
				
			||||||
 | 
					                         G_MARKUP_ERROR_MISSING_ATTRIBUTE,
 | 
				
			||||||
 | 
					                         "no \"oref\" attribute for \"key\"");
 | 
				
			||||||
 | 
					            return;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        const gchar *keycode_name = get_attribute (attribute_names, attribute_values,
 | 
					        g_hash_table_insert (data->key_oref_hash,
 | 
				
			||||||
                                   "keycode");
 | 
					                             data->key,
 | 
				
			||||||
 | 
					                             g_strdup (attribute));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        guint oref = GPOINTER_TO_UINT(g_hash_table_lookup(data->outlineid_oref_hash,
 | 
					        data->num_columns++;
 | 
				
			||||||
                                      oref_name));
 | 
					 | 
				
			||||||
        const gchar *name = base_name;
 | 
					 | 
				
			||||||
        g_hash_table_insert (data->keyname_oref_hash,
 | 
					 | 
				
			||||||
                             g_strdup(name),
 | 
					 | 
				
			||||||
                             GUINT_TO_POINTER(oref));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        struct squeek_button *button = g_hash_table_lookup(data->name_button_hash, name);
 | 
					 | 
				
			||||||
        // never gets used! this section gets executed before any buttons get defined
 | 
					 | 
				
			||||||
        if (button) {
 | 
					 | 
				
			||||||
            if (keycode_name != NULL) {
 | 
					 | 
				
			||||||
                // This sets the keycode for all buttons,
 | 
					 | 
				
			||||||
                // since they share state
 | 
					 | 
				
			||||||
                // TODO: get rid of this in the parser;
 | 
					 | 
				
			||||||
                // this belongs after keymap is defined
 | 
					 | 
				
			||||||
                struct squeek_key *key = squeek_button_get_key(button);
 | 
					 | 
				
			||||||
                squeek_key_set_keycode(key, strtol (keycode_name, NULL, 10));
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        goto out;
 | 
					        goto out;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@ -434,7 +445,7 @@ geometry_start_element_callback (GMarkupParseContext *pcontext,
 | 
				
			|||||||
                         "no \"id\" attribute for \"outline\"");
 | 
					                         "no \"id\" attribute for \"outline\"");
 | 
				
			||||||
            return;
 | 
					            return;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        data->outline_id = g_strdup (attribute);
 | 
					        data->oref = g_strdup (attribute);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        attribute = get_attribute (attribute_names, attribute_values,
 | 
					        attribute = get_attribute (attribute_names, attribute_values,
 | 
				
			||||||
                                   "corner-radius");
 | 
					                                   "corner-radius");
 | 
				
			||||||
@ -479,30 +490,6 @@ geometry_start_element_callback (GMarkupParseContext *pcontext,
 | 
				
			|||||||
 out:
 | 
					 out:
 | 
				
			||||||
    data->element_stack = g_slist_prepend (data->element_stack,
 | 
					    data->element_stack = g_slist_prepend (data->element_stack,
 | 
				
			||||||
                                           g_strdup (element_name));
 | 
					                                           g_strdup (element_name));
 | 
				
			||||||
    data->text->len = 0;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * eek_keyboard_add_outline:
 | 
					 | 
				
			||||||
 * @keyboard: an #EekKeyboard
 | 
					 | 
				
			||||||
 * @outline: an #EekOutline
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * Register an outline of @keyboard.
 | 
					 | 
				
			||||||
 * Returns: an unsigned integer ID of the registered outline, for
 | 
					 | 
				
			||||||
 * later reference
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
static guint
 | 
					 | 
				
			||||||
add_outline (GArray *outline_array,
 | 
					 | 
				
			||||||
                          EekOutline  *outline)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    EekOutline *_outline;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    _outline = eek_outline_copy (outline);
 | 
					 | 
				
			||||||
    g_array_append_val (outline_array, *_outline);
 | 
					 | 
				
			||||||
    /* don't use eek_outline_free here, so as to keep _outline->points */
 | 
					 | 
				
			||||||
    g_slice_free (EekOutline, _outline);
 | 
					 | 
				
			||||||
    return outline_array->len - 1;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void
 | 
					static void
 | 
				
			||||||
@ -518,65 +505,20 @@ geometry_end_element_callback (GMarkupParseContext *pcontext,
 | 
				
			|||||||
    data->element_stack = g_slist_next (data->element_stack);
 | 
					    data->element_stack = g_slist_next (data->element_stack);
 | 
				
			||||||
    g_slist_free1 (head);
 | 
					    g_slist_free1 (head);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const gchar *text = g_strndup (data->text->str, data->text->len);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if (g_strcmp0 (element_name, "view") == 0) {
 | 
					 | 
				
			||||||
        data->view_idx++;
 | 
					 | 
				
			||||||
        return;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if (g_strcmp0 (element_name, "section") == 0) {
 | 
					    if (g_strcmp0 (element_name, "section") == 0) {
 | 
				
			||||||
        // Split text on spaces and process each part
 | 
					        data->section = NULL;
 | 
				
			||||||
        unsigned head = 0;
 | 
					        data->num_rows = 0;
 | 
				
			||||||
        while (head < strlen(text)) {
 | 
					 | 
				
			||||||
            // Skip to the first non-space character
 | 
					 | 
				
			||||||
            for (; head < strlen(text); head++) {
 | 
					 | 
				
			||||||
                if (text[head] != ' ') {
 | 
					 | 
				
			||||||
                    break;
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            unsigned start = head;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            // Skip to the first space character
 | 
					 | 
				
			||||||
            for (; head < strlen(text); head++) {
 | 
					 | 
				
			||||||
                if (text[head] == ' ') {
 | 
					 | 
				
			||||||
                    break;
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            unsigned end = head;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            /// Reached the end
 | 
					 | 
				
			||||||
            if (start == end) {
 | 
					 | 
				
			||||||
                break;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            gchar *name = g_strndup (&text[start], end - start);
 | 
					 | 
				
			||||||
            struct squeek_button *button = g_hash_table_lookup(data->name_button_hash, name);
 | 
					 | 
				
			||||||
            if (!button) {
 | 
					 | 
				
			||||||
                // Save button name together with its level,
 | 
					 | 
				
			||||||
                // to account for buttons with the same name in multiple levels
 | 
					 | 
				
			||||||
                guint keycode = data->keycode++;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                guint oref = GPOINTER_TO_UINT(g_hash_table_lookup(data->keyname_oref_hash, name));
 | 
					 | 
				
			||||||
                // default value gives idx 0, which is guaranteed to be occupied
 | 
					 | 
				
			||||||
                button = squeek_row_create_button (data->row, keycode, oref);
 | 
					 | 
				
			||||||
                g_hash_table_insert (data->name_button_hash,
 | 
					 | 
				
			||||||
                                     g_strdup(name),
 | 
					 | 
				
			||||||
                                     button);
 | 
					 | 
				
			||||||
            } else {
 | 
					 | 
				
			||||||
                struct squeek_button *new_button = squeek_row_create_button_with_state(data->row, button);
 | 
					 | 
				
			||||||
                if (!new_button) {
 | 
					 | 
				
			||||||
                    g_set_error (error,
 | 
					 | 
				
			||||||
                                 G_MARKUP_ERROR,
 | 
					 | 
				
			||||||
                                 G_MARKUP_ERROR_MISSING_ATTRIBUTE,
 | 
					 | 
				
			||||||
                                 "Couldn't create a shared button");
 | 
					 | 
				
			||||||
        return;
 | 
					        return;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
            }
 | 
					
 | 
				
			||||||
 | 
					    if (g_strcmp0 (element_name, "key") == 0) {
 | 
				
			||||||
 | 
					        data->key = NULL;
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        data->row = NULL;
 | 
					    if (g_strcmp0 (element_name, "row") == 0) {
 | 
				
			||||||
        data->num_rows = 0;
 | 
					        data->num_columns = 0;
 | 
				
			||||||
 | 
					        data->orientation = EEK_ORIENTATION_HORIZONTAL;
 | 
				
			||||||
        return;
 | 
					        return;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -599,30 +541,19 @@ geometry_end_element_callback (GMarkupParseContext *pcontext,
 | 
				
			|||||||
        g_slist_free (data->points);
 | 
					        g_slist_free (data->points);
 | 
				
			||||||
        data->points = NULL;
 | 
					        data->points = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        guint oref = add_outline (data->outline_array, outline);
 | 
					        g_hash_table_insert (data->oref_outline_hash,
 | 
				
			||||||
 | 
					                             g_strdup (data->oref),
 | 
				
			||||||
 | 
					                             outline);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        g_hash_table_insert (data->outlineid_oref_hash,
 | 
					        g_free (data->oref);
 | 
				
			||||||
                             data->outline_id,
 | 
					 | 
				
			||||||
                             GUINT_TO_POINTER(oref));
 | 
					 | 
				
			||||||
        return;
 | 
					        return;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void
 | 
					 | 
				
			||||||
geometry_text_callback (GMarkupParseContext *pcontext,
 | 
					 | 
				
			||||||
                       const gchar         *text,
 | 
					 | 
				
			||||||
                       gsize                text_len,
 | 
					 | 
				
			||||||
                       gpointer             user_data,
 | 
					 | 
				
			||||||
                       GError             **error)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    GeometryParseData *data = user_data;
 | 
					 | 
				
			||||||
    g_string_append_len (data->text, text, (gssize)text_len);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static const GMarkupParser geometry_parser = {
 | 
					static const GMarkupParser geometry_parser = {
 | 
				
			||||||
    geometry_start_element_callback,
 | 
					    geometry_start_element_callback,
 | 
				
			||||||
    geometry_end_element_callback,
 | 
					    geometry_end_element_callback,
 | 
				
			||||||
    geometry_text_callback,
 | 
					    0,
 | 
				
			||||||
    0,
 | 
					    0,
 | 
				
			||||||
    0
 | 
					    0
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
@ -631,22 +562,24 @@ struct _SymbolsParseData {
 | 
				
			|||||||
    GSList *element_stack;
 | 
					    GSList *element_stack;
 | 
				
			||||||
    GString *text;
 | 
					    GString *text;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    LevelKeyboard *keyboard;
 | 
					    EekKeyboard *keyboard;
 | 
				
			||||||
    struct squeek_view *view;
 | 
					    EekKey *key;
 | 
				
			||||||
 | 
					    GSList *symbols;
 | 
				
			||||||
    gchar *label;
 | 
					    gchar *label;
 | 
				
			||||||
    gchar *icon;
 | 
					    gchar *icon;
 | 
				
			||||||
    gchar *tooltip;
 | 
					    gchar *tooltip;
 | 
				
			||||||
 | 
					    EekSymbolCategory category;
 | 
				
			||||||
    guint keyval;
 | 
					    guint keyval;
 | 
				
			||||||
 | 
					    gint groups;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
typedef struct _SymbolsParseData SymbolsParseData;
 | 
					typedef struct _SymbolsParseData SymbolsParseData;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static SymbolsParseData *
 | 
					static SymbolsParseData *
 | 
				
			||||||
symbols_parse_data_new (LevelKeyboard *keyboard)
 | 
					symbols_parse_data_new (EekKeyboard *keyboard)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    SymbolsParseData *data = g_slice_new0 (SymbolsParseData);
 | 
					    SymbolsParseData *data = g_slice_new0 (SymbolsParseData);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    data->keyboard = keyboard;
 | 
					    data->keyboard = g_object_ref (keyboard);
 | 
				
			||||||
    data->text = g_string_sized_new (BUFSIZE);
 | 
					    data->text = g_string_sized_new (BUFSIZE);
 | 
				
			||||||
    return data;
 | 
					    return data;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -654,14 +587,19 @@ symbols_parse_data_new (LevelKeyboard *keyboard)
 | 
				
			|||||||
static void
 | 
					static void
 | 
				
			||||||
symbols_parse_data_free (SymbolsParseData *data)
 | 
					symbols_parse_data_free (SymbolsParseData *data)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					    g_object_unref (data->keyboard);
 | 
				
			||||||
    g_string_free (data->text, TRUE);
 | 
					    g_string_free (data->text, TRUE);
 | 
				
			||||||
    g_slice_free (SymbolsParseData, data);
 | 
					    g_slice_free (SymbolsParseData, data);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static const gchar *symbols_valid_path_list[] = {
 | 
					static const gchar *symbols_valid_path_list[] = {
 | 
				
			||||||
    "symbols",
 | 
					    "symbols",
 | 
				
			||||||
    "symbol/symbols",
 | 
					 | 
				
			||||||
    "include/symbols",
 | 
					    "include/symbols",
 | 
				
			||||||
 | 
					    "key/symbols",
 | 
				
			||||||
 | 
					    "text/key/symbols",
 | 
				
			||||||
 | 
					    "keysym/key/symbols",
 | 
				
			||||||
 | 
					    "symbol/key/symbols",
 | 
				
			||||||
 | 
					    "invalid/key/symbols",
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void
 | 
					static void
 | 
				
			||||||
@ -682,7 +620,56 @@ symbols_start_element_callback (GMarkupParseContext *pcontext,
 | 
				
			|||||||
                   error))
 | 
					                   error))
 | 
				
			||||||
        return;
 | 
					        return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (g_strcmp0 (element_name, "symbol") == 0) {
 | 
					    if (g_strcmp0 (element_name, "key") == 0) {
 | 
				
			||||||
 | 
					        guint keycode;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        attribute = get_attribute (attribute_names, attribute_values,
 | 
				
			||||||
 | 
					                                   "keycode");
 | 
				
			||||||
 | 
					        if (attribute == NULL) {
 | 
				
			||||||
 | 
					            g_set_error (error,
 | 
				
			||||||
 | 
					                         G_MARKUP_ERROR,
 | 
				
			||||||
 | 
					                         G_MARKUP_ERROR_MISSING_ATTRIBUTE,
 | 
				
			||||||
 | 
					                         "no \"keycode\" attribute for \"key\"");
 | 
				
			||||||
 | 
					            return;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        keycode = strtoul (attribute, NULL, 10);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        data->key = eek_keyboard_find_key_by_keycode (data->keyboard,
 | 
				
			||||||
 | 
					                                                      keycode);
 | 
				
			||||||
 | 
					        /*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");
 | 
				
			||||||
 | 
					        if (attribute != NULL)
 | 
				
			||||||
 | 
					            data->groups = strtol (attribute, NULL, 10);
 | 
				
			||||||
 | 
					        else
 | 
				
			||||||
 | 
					            data->groups = 1;
 | 
				
			||||||
 | 
					        data->symbols = NULL;
 | 
				
			||||||
 | 
					        goto out;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (g_strcmp0 (element_name, "keysym") == 0) {
 | 
				
			||||||
 | 
					        attribute = get_attribute (attribute_names, attribute_values,
 | 
				
			||||||
 | 
					                                   "keyval");
 | 
				
			||||||
 | 
					        if (attribute == NULL) {
 | 
				
			||||||
 | 
					            g_set_error (error,
 | 
				
			||||||
 | 
					                         G_MARKUP_ERROR,
 | 
				
			||||||
 | 
					                         G_MARKUP_ERROR_MISSING_ATTRIBUTE,
 | 
				
			||||||
 | 
					                         "no \"keyval\" attribute for \"keysym\"");
 | 
				
			||||||
 | 
					            return;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        data->keyval = strtoul (attribute, NULL, 0);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (g_strcmp0 (element_name, "symbol") == 0 ||
 | 
				
			||||||
 | 
					        g_strcmp0 (element_name, "keysym") == 0 ||
 | 
				
			||||||
 | 
					        g_strcmp0 (element_name, "text") == 0) {
 | 
				
			||||||
        attribute = get_attribute (attribute_names, attribute_values,
 | 
					        attribute = get_attribute (attribute_names, attribute_values,
 | 
				
			||||||
                                   "label");
 | 
					                                   "label");
 | 
				
			||||||
        if (attribute != NULL)
 | 
					        if (attribute != NULL)
 | 
				
			||||||
@ -697,8 +684,16 @@ symbols_start_element_callback (GMarkupParseContext *pcontext,
 | 
				
			|||||||
                                   "tooltip");
 | 
					                                   "tooltip");
 | 
				
			||||||
        if (attribute != NULL)
 | 
					        if (attribute != NULL)
 | 
				
			||||||
            data->tooltip = g_strdup (attribute);
 | 
					            data->tooltip = g_strdup (attribute);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        attribute = get_attribute (attribute_names, attribute_values,
 | 
				
			||||||
 | 
					                                   "category");
 | 
				
			||||||
 | 
					        if (attribute != NULL)
 | 
				
			||||||
 | 
					            data->category = strtoul (attribute, NULL, 10);
 | 
				
			||||||
 | 
					        else
 | 
				
			||||||
 | 
					            data->category = EEK_SYMBOL_CATEGORY_KEYNAME;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 out:
 | 
				
			||||||
    data->element_stack = g_slist_prepend (data->element_stack,
 | 
					    data->element_stack = g_slist_prepend (data->element_stack,
 | 
				
			||||||
                                           g_strdup (element_name));
 | 
					                                           g_strdup (element_name));
 | 
				
			||||||
    data->text->len = 0;
 | 
					    data->text->len = 0;
 | 
				
			||||||
@ -713,42 +708,82 @@ symbols_end_element_callback (GMarkupParseContext *pcontext,
 | 
				
			|||||||
    SymbolsParseData *data = user_data;
 | 
					    SymbolsParseData *data = user_data;
 | 
				
			||||||
    GSList *head = data->element_stack;
 | 
					    GSList *head = data->element_stack;
 | 
				
			||||||
    gchar *text;
 | 
					    gchar *text;
 | 
				
			||||||
 | 
					    gint i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    g_free (head->data);
 | 
					    g_free (head->data);
 | 
				
			||||||
    data->element_stack = g_slist_next (data->element_stack);
 | 
					    data->element_stack = g_slist_next (data->element_stack);
 | 
				
			||||||
    g_slist_free1 (head);
 | 
					    g_slist_free1 (head);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // TODO: this could all be moved to text handler
 | 
					 | 
				
			||||||
    text = g_strndup (data->text->str, data->text->len);
 | 
					    text = g_strndup (data->text->str, data->text->len);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (g_strcmp0 (element_name, "symbol") == 0) {
 | 
					    if (g_strcmp0 (element_name, "key") == 0) {
 | 
				
			||||||
 | 
					        if (!data->key) {
 | 
				
			||||||
        gchar *name = text;
 | 
					            return;
 | 
				
			||||||
        struct squeek_button *button = eek_keyboard_find_button_by_name (data->keyboard,
 | 
					 | 
				
			||||||
                                                   name);
 | 
					 | 
				
			||||||
        if (button) {
 | 
					 | 
				
			||||||
            squeek_key_add_symbol(
 | 
					 | 
				
			||||||
                squeek_button_get_key(button),
 | 
					 | 
				
			||||||
                element_name,
 | 
					 | 
				
			||||||
                text,
 | 
					 | 
				
			||||||
                data->keyval,
 | 
					 | 
				
			||||||
                data->label,
 | 
					 | 
				
			||||||
                data->icon,
 | 
					 | 
				
			||||||
                data->tooltip
 | 
					 | 
				
			||||||
            );
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        data->keyval = 0;
 | 
					        gint num_symbols = g_slist_length (data->symbols);
 | 
				
			||||||
        g_free(data->label);
 | 
					        gint levels = num_symbols / data->groups;
 | 
				
			||||||
 | 
					        EekSymbolMatrix *matrix = eek_symbol_matrix_new (data->groups,
 | 
				
			||||||
 | 
					                                                         levels);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        head = data->symbols = g_slist_reverse (data->symbols);
 | 
				
			||||||
 | 
					        for (i = 0; i < num_symbols; i++) {
 | 
				
			||||||
 | 
					            if (head && head->data) {
 | 
				
			||||||
 | 
					                matrix->data[i] = head->data;
 | 
				
			||||||
 | 
					                head = g_slist_next (head);
 | 
				
			||||||
 | 
					            } else
 | 
				
			||||||
 | 
					                matrix->data[i] = NULL;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        g_slist_free (data->symbols);
 | 
				
			||||||
 | 
					        data->symbols = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        eek_key_set_symbol_matrix (data->key, matrix);
 | 
				
			||||||
 | 
					        eek_symbol_matrix_free (matrix);
 | 
				
			||||||
 | 
					        data->key = NULL;
 | 
				
			||||||
 | 
					        goto out;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (g_strcmp0 (element_name, "symbol") == 0 ||
 | 
				
			||||||
 | 
					        g_strcmp0 (element_name, "keysym") == 0 ||
 | 
				
			||||||
 | 
					        g_strcmp0 (element_name, "text") == 0) {
 | 
				
			||||||
 | 
					        EekSymbol *symbol;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (g_strcmp0 (element_name, "keysym") == 0) {
 | 
				
			||||||
 | 
					            EekKeysym *keysym;
 | 
				
			||||||
 | 
					            if (data->keyval != EEK_INVALID_KEYSYM)
 | 
				
			||||||
 | 
					                keysym = eek_keysym_new (data->keyval);
 | 
				
			||||||
 | 
					            else
 | 
				
			||||||
 | 
					                keysym = eek_keysym_new_from_name (text);
 | 
				
			||||||
 | 
					            symbol = EEK_SYMBOL(keysym);
 | 
				
			||||||
 | 
					        } else if (g_strcmp0 (element_name, "text") == 0) {
 | 
				
			||||||
 | 
					            symbol = EEK_SYMBOL(eek_text_new (text));
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            symbol = eek_symbol_new (text);
 | 
				
			||||||
 | 
					            eek_symbol_set_category (symbol, EEK_SYMBOL_CATEGORY_KEYNAME);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (data->label) {
 | 
				
			||||||
 | 
					            eek_symbol_set_label (symbol, data->label);
 | 
				
			||||||
 | 
					            g_free (data->label);
 | 
				
			||||||
            data->label = NULL;
 | 
					            data->label = NULL;
 | 
				
			||||||
        g_free(data->icon);
 | 
					        }
 | 
				
			||||||
 | 
					        if (data->icon) {
 | 
				
			||||||
 | 
					            eek_symbol_set_icon_name (symbol, data->icon);
 | 
				
			||||||
 | 
					            g_free (data->icon);
 | 
				
			||||||
            data->icon = NULL;
 | 
					            data->icon = NULL;
 | 
				
			||||||
        g_free(data->tooltip);
 | 
					        }
 | 
				
			||||||
 | 
					        if (data->tooltip) {
 | 
				
			||||||
 | 
					            eek_symbol_set_tooltip (symbol, data->tooltip);
 | 
				
			||||||
 | 
					            g_free (data->tooltip);
 | 
				
			||||||
            data->tooltip = NULL;
 | 
					            data->tooltip = NULL;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        data->symbols = g_slist_prepend (data->symbols, symbol);
 | 
				
			||||||
        goto out;
 | 
					        goto out;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (g_strcmp0 (element_name, "invalid") == 0) {
 | 
					    if (g_strcmp0 (element_name, "invalid") == 0) {
 | 
				
			||||||
 | 
					        data->symbols = g_slist_prepend (data->symbols, NULL);
 | 
				
			||||||
        goto out;
 | 
					        goto out;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -860,37 +895,31 @@ static const GMarkupParser prerequisites_parser = {
 | 
				
			|||||||
    0
 | 
					    0
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
LevelKeyboard *
 | 
					static EekKeyboard *
 | 
				
			||||||
eek_xml_layout_real_create_keyboard (EekLayout *self,
 | 
					eek_xml_layout_real_create_keyboard (EekboardContextService *manager,
 | 
				
			||||||
                                     EekboardContextService *manager)
 | 
					                                     EekLayout *self,
 | 
				
			||||||
 | 
					                                     gdouble    initial_width,
 | 
				
			||||||
 | 
					                                     gdouble    initial_height)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    EekXmlLayout *layout = EEK_XML_LAYOUT (self);
 | 
					    EekXmlLayout *layout = EEK_XML_LAYOUT (self);
 | 
				
			||||||
    EekXmlLayoutPrivate *priv = eek_xml_layout_get_instance_private (layout);
 | 
					    EekXmlLayoutPrivate *priv = eek_xml_layout_get_instance_private (layout);
 | 
				
			||||||
    gboolean retval;
 | 
					    gboolean retval;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* Create an empty keyboard to which geometry and symbols
 | 
				
			||||||
 | 
					       information are applied. */
 | 
				
			||||||
 | 
					    EekKeyboard *keyboard = g_object_new (EEK_TYPE_KEYBOARD, "layout", layout, NULL);
 | 
				
			||||||
 | 
					    keyboard->manager = manager;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* Read geometry information. */
 | 
					    /* Read geometry information. */
 | 
				
			||||||
    gchar *filename = g_strdup_printf ("%s.xml", priv->desc->geometry);
 | 
					    gchar *filename = g_strdup_printf ("%s.xml", priv->desc->geometry);
 | 
				
			||||||
    gchar *path = g_build_filename (priv->keyboards_dir, "geometry", filename, NULL);
 | 
					    gchar *path = g_build_filename (priv->keyboards_dir, "geometry", filename, NULL);
 | 
				
			||||||
    g_free (filename);
 | 
					    g_free (filename);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    GArray *outline_array = g_array_new (FALSE, TRUE, sizeof (EekOutline));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    // char* -> struct squeek_button*
 | 
					 | 
				
			||||||
    GHashTable *name_button_hash =
 | 
					 | 
				
			||||||
            g_hash_table_new_full (g_str_hash,
 | 
					 | 
				
			||||||
                                   g_str_equal,
 | 
					 | 
				
			||||||
                                   g_free,
 | 
					 | 
				
			||||||
                                   NULL);
 | 
					 | 
				
			||||||
    // One view for each level
 | 
					 | 
				
			||||||
    struct squeek_view *views[4] = {0};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    GError *error = NULL;
 | 
					    GError *error = NULL;
 | 
				
			||||||
    retval = parse_geometry (path, views, outline_array, name_button_hash, &error);
 | 
					    retval = parse_geometry (path, keyboard, &error);
 | 
				
			||||||
    g_free (path);
 | 
					    g_free (path);
 | 
				
			||||||
    if (!retval) {
 | 
					    if (!retval) {
 | 
				
			||||||
        for (uint i = 0; i < 4; i++) {
 | 
					        g_object_unref (keyboard);
 | 
				
			||||||
            g_object_unref (views[i]);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        g_warning ("can't parse geometry file %s: %s",
 | 
					        g_warning ("can't parse geometry file %s: %s",
 | 
				
			||||||
                   priv->desc->geometry,
 | 
					                   priv->desc->geometry,
 | 
				
			||||||
                   error->message);
 | 
					                   error->message);
 | 
				
			||||||
@ -898,12 +927,6 @@ eek_xml_layout_real_create_keyboard (EekLayout *self,
 | 
				
			|||||||
        return NULL;
 | 
					        return NULL;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
    LevelKeyboard *keyboard = level_keyboard_new(manager, views, name_button_hash);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    keyboard->outline_array = outline_array;
 | 
					 | 
				
			||||||
    // FIXME: are symbols shared betwen views?
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /* Read symbols information. */
 | 
					    /* Read symbols information. */
 | 
				
			||||||
    GList *loaded = NULL;
 | 
					    GList *loaded = NULL;
 | 
				
			||||||
    retval = parse_symbols_with_prerequisites (priv->keyboards_dir,
 | 
					    retval = parse_symbols_with_prerequisites (priv->keyboards_dir,
 | 
				
			||||||
@ -913,13 +936,7 @@ eek_xml_layout_real_create_keyboard (EekLayout *self,
 | 
				
			|||||||
                                               &error);
 | 
					                                               &error);
 | 
				
			||||||
    g_list_free_full (loaded, g_free);
 | 
					    g_list_free_full (loaded, g_free);
 | 
				
			||||||
    if (!retval) {
 | 
					    if (!retval) {
 | 
				
			||||||
        for (uint i = 0; i < 4; i++) {
 | 
					        g_object_unref (keyboard);
 | 
				
			||||||
            if (views[i]) {
 | 
					 | 
				
			||||||
                g_object_unref(views[i]);
 | 
					 | 
				
			||||||
                views[i] = NULL;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        //g_object_unref (view);
 | 
					 | 
				
			||||||
        g_warning ("can't parse symbols file %s: %s",
 | 
					        g_warning ("can't parse symbols file %s: %s",
 | 
				
			||||||
                   priv->desc->symbols,
 | 
					                   priv->desc->symbols,
 | 
				
			||||||
                   error->message);
 | 
					                   error->message);
 | 
				
			||||||
@ -927,11 +944,12 @@ eek_xml_layout_real_create_keyboard (EekLayout *self,
 | 
				
			|||||||
        return NULL;
 | 
					        return NULL;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    for (uint i = 0; i < 4; i++) {
 | 
					    /* Fit keyboard in the given width and hight. */
 | 
				
			||||||
        if (views[i]) {
 | 
					    scale_keyboard (keyboard, initial_width, initial_height);
 | 
				
			||||||
            squeek_view_place_contents(views[i], keyboard);
 | 
					
 | 
				
			||||||
        }
 | 
					    /* Use pre-defined modifier mask here. */
 | 
				
			||||||
    }
 | 
					    eek_keyboard_set_num_lock_mask (keyboard, EEK_MOD2_MASK);
 | 
				
			||||||
 | 
					    eek_keyboard_set_alt_gr_mask (keyboard, EEK_BUTTON1_MASK);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return keyboard;
 | 
					    return keyboard;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -994,9 +1012,12 @@ eek_xml_layout_finalize (GObject *object)
 | 
				
			|||||||
static void
 | 
					static void
 | 
				
			||||||
eek_xml_layout_class_init (EekXmlLayoutClass *klass)
 | 
					eek_xml_layout_class_init (EekXmlLayoutClass *klass)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					    EekLayoutClass *layout_class = EEK_LAYOUT_CLASS (klass);
 | 
				
			||||||
    GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
 | 
					    GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
 | 
				
			||||||
    GParamSpec *pspec;
 | 
					    GParamSpec *pspec;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    layout_class->create_keyboard = eek_xml_layout_real_create_keyboard;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    gobject_class->set_property = eek_xml_layout_set_property;
 | 
					    gobject_class->set_property = eek_xml_layout_set_property;
 | 
				
			||||||
    gobject_class->get_property = eek_xml_layout_get_property;
 | 
					    gobject_class->get_property = eek_xml_layout_get_property;
 | 
				
			||||||
    gobject_class->finalize = eek_xml_layout_finalize;
 | 
					    gobject_class->finalize = eek_xml_layout_finalize;
 | 
				
			||||||
@ -1037,10 +1058,10 @@ initable_init (GInitable    *initable,
 | 
				
			|||||||
    gchar *path;
 | 
					    gchar *path;
 | 
				
			||||||
    EekXmlKeyboardDesc *desc;
 | 
					    EekXmlKeyboardDesc *desc;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    priv->keyboards_dir = g_strdup ((gchar *) g_getenv ("EEKBOARD_KEYBOARDSDIR"));
 | 
					    priv->keyboards_dir = (gchar *) g_getenv ("EEKBOARD_KEYBOARDSDIR");
 | 
				
			||||||
 | 
					 | 
				
			||||||
    if (priv->keyboards_dir == NULL)
 | 
					    if (priv->keyboards_dir == NULL)
 | 
				
			||||||
        priv->keyboards_dir = g_strdup ("resource:///sm/puri/squeekboard/keyboards/");
 | 
					        priv->keyboards_dir = KEYBOARDSDIR;
 | 
				
			||||||
 | 
					    priv->keyboards_dir = g_strdup (priv->keyboards_dir);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    path = g_build_filename (priv->keyboards_dir, "keyboards.xml", NULL);
 | 
					    path = g_build_filename (priv->keyboards_dir, "keyboards.xml", NULL);
 | 
				
			||||||
    keyboards = parse_keyboards (path, error);
 | 
					    keyboards = parse_keyboards (path, error);
 | 
				
			||||||
@ -1091,7 +1112,7 @@ eek_xml_list_keyboards (void)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    keyboards_dir = g_getenv ("EEKBOARD_KEYBOARDSDIR");
 | 
					    keyboards_dir = g_getenv ("EEKBOARD_KEYBOARDSDIR");
 | 
				
			||||||
    if (keyboards_dir == NULL)
 | 
					    if (keyboards_dir == NULL)
 | 
				
			||||||
        keyboards_dir = g_strdup ("resource:///sm/puri/squeekboard/keyboards/");
 | 
					        keyboards_dir = KEYBOARDSDIR;
 | 
				
			||||||
    path = g_build_filename (keyboards_dir, "keyboards.xml", NULL);
 | 
					    path = g_build_filename (keyboards_dir, "keyboards.xml", NULL);
 | 
				
			||||||
    keyboards = parse_keyboards (path, NULL);
 | 
					    keyboards = parse_keyboards (path, NULL);
 | 
				
			||||||
    g_free (path);
 | 
					    g_free (path);
 | 
				
			||||||
@ -1116,25 +1137,58 @@ eek_xml_keyboard_desc_free (EekXmlKeyboardDesc *desc)
 | 
				
			|||||||
    g_slice_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
 | 
					static gboolean
 | 
				
			||||||
parse_geometry (const gchar *path, struct squeek_view **views, GArray *outline_array, GHashTable *name_button_hash, GError **error)
 | 
					parse_geometry (const gchar *path, EekKeyboard *keyboard, GError **error)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    GeometryParseData *data;
 | 
					    GeometryParseData *data;
 | 
				
			||||||
    GMarkupParseContext *pcontext;
 | 
					    GMarkupParseContext *pcontext;
 | 
				
			||||||
 | 
					    GHashTable *oref_hash;
 | 
				
			||||||
 | 
					    GHashTableIter iter;
 | 
				
			||||||
 | 
					    gpointer k, v;
 | 
				
			||||||
    GFile *file;
 | 
					    GFile *file;
 | 
				
			||||||
    GFileInputStream *input;
 | 
					    GFileInputStream *input;
 | 
				
			||||||
    gboolean retval;
 | 
					    gboolean retval;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    file = g_str_has_prefix (path, "resource://")
 | 
					    file = g_file_new_for_path (path);
 | 
				
			||||||
         ? g_file_new_for_uri  (path)
 | 
					 | 
				
			||||||
         : g_file_new_for_path (path);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    input = g_file_read (file, NULL, error);
 | 
					    input = g_file_read (file, NULL, error);
 | 
				
			||||||
    g_object_unref (file);
 | 
					    g_object_unref (file);
 | 
				
			||||||
    if (input == NULL)
 | 
					    if (input == NULL)
 | 
				
			||||||
        return FALSE;
 | 
					        return FALSE;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    data = geometry_parse_data_new (views, name_button_hash, outline_array);
 | 
					    data = geometry_parse_data_new (keyboard);
 | 
				
			||||||
    pcontext = g_markup_parse_context_new (&geometry_parser,
 | 
					    pcontext = g_markup_parse_context_new (&geometry_parser,
 | 
				
			||||||
                                           0,
 | 
					                                           0,
 | 
				
			||||||
                                           data,
 | 
					                                           data,
 | 
				
			||||||
@ -1149,29 +1203,44 @@ parse_geometry (const gchar *path, struct squeek_view **views, GArray *outline_a
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* Resolve outline references. */
 | 
					    /* Resolve outline references. */
 | 
				
			||||||
    /*
 | 
					 | 
				
			||||||
     * GHashTable *oref_hash;
 | 
					 | 
				
			||||||
    GHashTableIter iter;
 | 
					 | 
				
			||||||
    gpointer k, v;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    oref_hash = g_hash_table_new (g_str_hash, g_str_equal);
 | 
					    oref_hash = g_hash_table_new (g_str_hash, g_str_equal);
 | 
				
			||||||
    g_hash_table_iter_init (&iter, data->oref_outline_hash);
 | 
					    g_hash_table_iter_init (&iter, data->oref_outline_hash);
 | 
				
			||||||
    while (g_hash_table_iter_next (&iter, &k, &v)) {
 | 
					    while (g_hash_table_iter_next (&iter, &k, &v)) {
 | 
				
			||||||
        EekOutline *outline = v;
 | 
					        EekOutline *outline = v;
 | 
				
			||||||
        gulong oref;
 | 
					        gulong oref;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        oref = add_outline (outline_array, outline);
 | 
					        oref = eek_keyboard_add_outline (data->keyboard, outline);
 | 
				
			||||||
        g_hash_table_insert (oref_hash, k, GUINT_TO_POINTER(oref));
 | 
					        g_hash_table_insert (oref_hash, k, GUINT_TO_POINTER(oref));
 | 
				
			||||||
    }*/
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /*
 | 
					 | 
				
			||||||
    g_hash_table_iter_init (&iter, data->key_oref_hash);
 | 
					    g_hash_table_iter_init (&iter, data->key_oref_hash);
 | 
				
			||||||
    while (g_hash_table_iter_next (&iter, &k, &v)) {
 | 
					    while (g_hash_table_iter_next (&iter, &k, &v)) {
 | 
				
			||||||
        gpointer oref;
 | 
					        gpointer oref;
 | 
				
			||||||
        if (g_hash_table_lookup_extended (oref_hash, v, NULL, &oref))
 | 
					        if (g_hash_table_lookup_extended (oref_hash, v, NULL, &oref))
 | 
				
			||||||
            eek_key_set_oref (EEK_KEY(k), GPOINTER_TO_UINT(oref));
 | 
					            eek_key_set_oref (EEK_KEY(k), GPOINTER_TO_UINT(oref));
 | 
				
			||||||
    }*/
 | 
					    }
 | 
				
			||||||
//    g_hash_table_destroy (oref_hash);
 | 
					    g_hash_table_destroy (oref_hash);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* 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);
 | 
					    geometry_parse_data_free (data);
 | 
				
			||||||
    return TRUE;
 | 
					    return TRUE;
 | 
				
			||||||
@ -1180,7 +1249,7 @@ parse_geometry (const gchar *path, struct squeek_view **views, GArray *outline_a
 | 
				
			|||||||
static gboolean
 | 
					static gboolean
 | 
				
			||||||
parse_symbols_with_prerequisites (const gchar *keyboards_dir,
 | 
					parse_symbols_with_prerequisites (const gchar *keyboards_dir,
 | 
				
			||||||
                                  const gchar *name,
 | 
					                                  const gchar *name,
 | 
				
			||||||
                                  LevelKeyboard *keyboard,
 | 
					                                  EekKeyboard *keyboard,
 | 
				
			||||||
                                  GList     **loaded,
 | 
					                                  GList     **loaded,
 | 
				
			||||||
                                  GError     **error)
 | 
					                                  GError     **error)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
@ -1230,7 +1299,7 @@ parse_symbols_with_prerequisites (const gchar *keyboards_dir,
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static gboolean
 | 
					static gboolean
 | 
				
			||||||
parse_symbols (const gchar *path, LevelKeyboard *keyboard, GError **error)
 | 
					parse_symbols (const gchar *path, EekKeyboard *keyboard, GError **error)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    SymbolsParseData *data;
 | 
					    SymbolsParseData *data;
 | 
				
			||||||
    GMarkupParseContext *pcontext;
 | 
					    GMarkupParseContext *pcontext;
 | 
				
			||||||
@ -1238,9 +1307,7 @@ parse_symbols (const gchar *path, LevelKeyboard *keyboard, GError **error)
 | 
				
			|||||||
    GFileInputStream *input;
 | 
					    GFileInputStream *input;
 | 
				
			||||||
    gboolean retval;
 | 
					    gboolean retval;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    file = g_str_has_prefix (path, "resource://")
 | 
					    file = g_file_new_for_path (path);
 | 
				
			||||||
         ? g_file_new_for_uri  (path)
 | 
					 | 
				
			||||||
         : g_file_new_for_path (path);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    input = g_file_read (file, NULL, error);
 | 
					    input = g_file_read (file, NULL, error);
 | 
				
			||||||
    g_object_unref (file);
 | 
					    g_object_unref (file);
 | 
				
			||||||
@ -1273,9 +1340,7 @@ parse_prerequisites (const gchar *path, GError **error)
 | 
				
			|||||||
    GList *prerequisites;
 | 
					    GList *prerequisites;
 | 
				
			||||||
    gboolean retval;
 | 
					    gboolean retval;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    file = g_str_has_prefix (path, "resource://")
 | 
					    file = g_file_new_for_path (path);
 | 
				
			||||||
         ? g_file_new_for_uri  (path)
 | 
					 | 
				
			||||||
         : g_file_new_for_path (path);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    input = g_file_read (file, NULL, error);
 | 
					    input = g_file_read (file, NULL, error);
 | 
				
			||||||
    g_object_unref (file);
 | 
					    g_object_unref (file);
 | 
				
			||||||
@ -1310,9 +1375,7 @@ parse_keyboards (const gchar *path, GError **error)
 | 
				
			|||||||
    GList *keyboards;
 | 
					    GList *keyboards;
 | 
				
			||||||
    gboolean retval;
 | 
					    gboolean retval;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    file = g_str_has_prefix (path, "resource://")
 | 
					    file = g_file_new_for_path (path);
 | 
				
			||||||
         ? g_file_new_for_uri  (path)
 | 
					 | 
				
			||||||
         : g_file_new_for_path (path);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    input = g_file_read (file, NULL, error);
 | 
					    input = g_file_read (file, NULL, error);
 | 
				
			||||||
    g_object_unref (file);
 | 
					    g_object_unref (file);
 | 
				
			||||||
@ -1338,6 +1401,65 @@ parse_keyboards (const gchar *path, GError **error)
 | 
				
			|||||||
    return keyboards;
 | 
					    return keyboards;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void scale_bounds_callback (EekElement *element,
 | 
				
			||||||
 | 
					                                   gpointer    user_data);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					scale_bounds (EekElement *element,
 | 
				
			||||||
 | 
					              gdouble     scale)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    EekBounds bounds;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    eek_element_get_bounds (element, &bounds);
 | 
				
			||||||
 | 
					    bounds.x *= scale;
 | 
				
			||||||
 | 
					    bounds.y *= scale;
 | 
				
			||||||
 | 
					    bounds.width *= scale;
 | 
				
			||||||
 | 
					    bounds.height *= scale;
 | 
				
			||||||
 | 
					    eek_element_set_bounds (element, &bounds);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (EEK_IS_CONTAINER(element))
 | 
				
			||||||
 | 
					        eek_container_foreach_child (EEK_CONTAINER(element),
 | 
				
			||||||
 | 
					                                     scale_bounds_callback,
 | 
				
			||||||
 | 
					                                     &scale);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					scale_bounds_callback (EekElement *element,
 | 
				
			||||||
 | 
					                       gpointer    user_data)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    scale_bounds (element, *(gdouble *)user_data);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void scale_keyboard (EekKeyboard *keyboard,
 | 
				
			||||||
 | 
					                            gdouble      width,
 | 
				
			||||||
 | 
					                            gdouble      height)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    gdouble scale;
 | 
				
			||||||
 | 
					    EekBounds bounds;
 | 
				
			||||||
 | 
					    gsize n_outlines;
 | 
				
			||||||
 | 
					    guint i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    eek_element_get_bounds (EEK_ELEMENT(keyboard), &bounds);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (width * bounds.height < height * bounds.width)
 | 
				
			||||||
 | 
					        scale = width / bounds.width;
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					        scale = height / bounds.height;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    scale_bounds (EEK_ELEMENT(keyboard), scale);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    n_outlines = eek_keyboard_get_n_outlines (keyboard);
 | 
				
			||||||
 | 
					    for (i = 0; i < n_outlines; i++) {
 | 
				
			||||||
 | 
					        EekOutline *outline = eek_keyboard_get_outline (keyboard, i);
 | 
				
			||||||
 | 
					        gint j;
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					        for (j = 0; j < outline->num_points; j++) {
 | 
				
			||||||
 | 
					            outline->points[j].x *= scale;
 | 
				
			||||||
 | 
					            outline->points[j].y *= scale;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static gboolean
 | 
					static gboolean
 | 
				
			||||||
validate (const gchar **valid_path_list,
 | 
					validate (const gchar **valid_path_list,
 | 
				
			||||||
          gsize         valid_path_list_len,
 | 
					          gsize         valid_path_list_len,
 | 
				
			||||||
@ -1345,7 +1467,7 @@ validate (const gchar **valid_path_list,
 | 
				
			|||||||
          GSList       *element_stack,
 | 
					          GSList       *element_stack,
 | 
				
			||||||
          GError      **error)
 | 
					          GError      **error)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    guint i;
 | 
					    gint i;
 | 
				
			||||||
    gchar *element_path;
 | 
					    gchar *element_path;
 | 
				
			||||||
    GSList *head, *p;
 | 
					    GSList *head, *p;
 | 
				
			||||||
    GString *string;
 | 
					    GString *string;
 | 
				
			||||||
 | 
				
			|||||||
@ -62,8 +62,5 @@ GList              *eek_xml_list_keyboards     (void);
 | 
				
			|||||||
EekXmlKeyboardDesc *eek_xml_keyboard_desc_copy (EekXmlKeyboardDesc *desc);
 | 
					EekXmlKeyboardDesc *eek_xml_keyboard_desc_copy (EekXmlKeyboardDesc *desc);
 | 
				
			||||||
void                eek_xml_keyboard_desc_free (EekXmlKeyboardDesc *desc);
 | 
					void                eek_xml_keyboard_desc_free (EekXmlKeyboardDesc *desc);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
LevelKeyboard *
 | 
					 | 
				
			||||||
eek_xml_layout_real_create_keyboard (EekLayout *self,
 | 
					 | 
				
			||||||
                                     EekboardContextService *manager);
 | 
					 | 
				
			||||||
G_END_DECLS
 | 
					G_END_DECLS
 | 
				
			||||||
#endif  /* EEK_XML_LAYOUT_H */
 | 
					#endif  /* EEK_XML_LAYOUT_H */
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										317
									
								
								eek/eek-xml.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,317 @@
 | 
				
			|||||||
 | 
					/* 
 | 
				
			||||||
 | 
					 * Copyright (C) 2011 Daiki Ueno <ueno@unixuser.org>
 | 
				
			||||||
 | 
					 * Copyright (C) 2011 Red Hat, Inc.
 | 
				
			||||||
 | 
					 * 
 | 
				
			||||||
 | 
					 * This program is free software: you can redistribute it and/or modify
 | 
				
			||||||
 | 
					 * it under the terms of the GNU General Public License as published by
 | 
				
			||||||
 | 
					 * the Free Software Foundation, either version 3 of the License, or
 | 
				
			||||||
 | 
					 * (at your option) any later version.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * This program is distributed in the hope that it will be useful,
 | 
				
			||||||
 | 
					 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
				
			||||||
 | 
					 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
				
			||||||
 | 
					 * GNU General Public License for more details.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * You should have received a copy of the GNU General Public License
 | 
				
			||||||
 | 
					 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * SECTION: eek-xml
 | 
				
			||||||
 | 
					 * @title: XML Conversion Utilities
 | 
				
			||||||
 | 
					 * @short_description: #EekKeyboard to XML conversion utilities
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef HAVE_CONFIG_H
 | 
				
			||||||
 | 
					#include "config.h"
 | 
				
			||||||
 | 
					#endif  /* HAVE_CONFIG_H */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <stdio.h>
 | 
				
			||||||
 | 
					#include <stdarg.h>
 | 
				
			||||||
 | 
					#include <glib/gprintf.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "eek-section.h"
 | 
				
			||||||
 | 
					#include "eek-key.h"
 | 
				
			||||||
 | 
					#include "eek-xml.h"
 | 
				
			||||||
 | 
					#include "eek-keysym.h"
 | 
				
			||||||
 | 
					#include "eek-text.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define g_string_append_indent(string, indent)  \
 | 
				
			||||||
 | 
					    {                                           \
 | 
				
			||||||
 | 
					        gint i;                                 \
 | 
				
			||||||
 | 
					        for (i = 0; i < (indent); i++) {        \
 | 
				
			||||||
 | 
					            g_string_append (string, "    ");   \
 | 
				
			||||||
 | 
					        }                                       \
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					g_string_markup_printf (GString *output, const gchar *format, ...)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    gchar *escaped_text;
 | 
				
			||||||
 | 
					    va_list ap;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    va_start (ap, format);
 | 
				
			||||||
 | 
					    escaped_text = g_markup_vprintf_escaped (format, ap);
 | 
				
			||||||
 | 
					    va_end (ap);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    g_string_append (output, escaped_text);
 | 
				
			||||||
 | 
					    g_free (escaped_text);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct _OutputCallbackData {
 | 
				
			||||||
 | 
					    GString *output;
 | 
				
			||||||
 | 
					    gint indent;
 | 
				
			||||||
 | 
					    GHashTable *oref_hash;
 | 
				
			||||||
 | 
					    gint key_serial;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					typedef struct _OutputCallbackData OutputCallbackData;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					output_bounds (GString *output, EekBounds *bounds)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    g_string_markup_printf (output,
 | 
				
			||||||
 | 
					                            "<bounds>%lf,%lf,%lf,%lf</bounds>\n",
 | 
				
			||||||
 | 
					                            bounds->x,
 | 
				
			||||||
 | 
					                            bounds->y,
 | 
				
			||||||
 | 
					                            bounds->width,
 | 
				
			||||||
 | 
					                            bounds->height);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					output_symbol_attributes (GString   *output,
 | 
				
			||||||
 | 
					                          EekSymbol *symbol)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    if (eek_symbol_get_name (symbol) != NULL)
 | 
				
			||||||
 | 
					        g_string_markup_printf (output, " name=\"%s\"",
 | 
				
			||||||
 | 
					                                eek_symbol_get_name (symbol));
 | 
				
			||||||
 | 
					    if (eek_symbol_get_label (symbol) != NULL)
 | 
				
			||||||
 | 
					        g_string_markup_printf (output, " label=\"%s\"",
 | 
				
			||||||
 | 
					                                eek_symbol_get_label (symbol));
 | 
				
			||||||
 | 
					    if (eek_symbol_get_category (symbol) != EEK_SYMBOL_CATEGORY_UNKNOWN)
 | 
				
			||||||
 | 
					        g_string_markup_printf (output, " category=\"%s\"",
 | 
				
			||||||
 | 
					                                eek_symbol_category_get_name (eek_symbol_get_category (symbol)));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					output_key_callback (EekElement *element, gpointer user_data)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    OutputCallbackData *data = user_data;
 | 
				
			||||||
 | 
					    EekBounds bounds;
 | 
				
			||||||
 | 
					    gint i, num_symbols;
 | 
				
			||||||
 | 
					    EekSymbolMatrix *matrix;
 | 
				
			||||||
 | 
					    gint column, row;
 | 
				
			||||||
 | 
					    guint keycode;
 | 
				
			||||||
 | 
					    gchar *id;
 | 
				
			||||||
 | 
					    gulong oref;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    keycode = eek_key_get_keycode (EEK_KEY(element));
 | 
				
			||||||
 | 
					    if (keycode == EEK_INVALID_KEYCODE)
 | 
				
			||||||
 | 
					        id = g_strdup_printf ("key%d", data->key_serial);
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					        id = g_strdup_printf ("keycode%d", keycode);
 | 
				
			||||||
 | 
					    data->key_serial++;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    eek_key_get_index (EEK_KEY(element), &column, &row);
 | 
				
			||||||
 | 
					    g_string_append_indent (data->output, data->indent);
 | 
				
			||||||
 | 
					    if (eek_element_get_name (element))
 | 
				
			||||||
 | 
					        g_string_markup_printf (data->output,
 | 
				
			||||||
 | 
					                                "<key id=\"%s\" name=\"%s\" "
 | 
				
			||||||
 | 
					                                "column=\"%d\" row=\"%d\">\n",
 | 
				
			||||||
 | 
					                                id,
 | 
				
			||||||
 | 
					                                eek_element_get_name (element),
 | 
				
			||||||
 | 
					                                column,
 | 
				
			||||||
 | 
					                                row);
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					        g_string_markup_printf (data->output,
 | 
				
			||||||
 | 
					                                "<key id=\"%s\" "
 | 
				
			||||||
 | 
					                                "column=\"%d\" row=\"%d\">\n",
 | 
				
			||||||
 | 
					                                id,
 | 
				
			||||||
 | 
					                                column,
 | 
				
			||||||
 | 
					                                row);
 | 
				
			||||||
 | 
					    g_free (id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    eek_element_get_bounds (element, &bounds);
 | 
				
			||||||
 | 
					    g_string_append_indent (data->output, data->indent + 1);
 | 
				
			||||||
 | 
					    output_bounds (data->output, &bounds);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    oref = eek_key_get_oref (EEK_KEY(element));
 | 
				
			||||||
 | 
					    if (oref != 0) {
 | 
				
			||||||
 | 
					        g_string_append_indent (data->output, data->indent + 1);
 | 
				
			||||||
 | 
					        g_string_markup_printf (data->output,
 | 
				
			||||||
 | 
					                                "<oref>outline%u</oref>\n",
 | 
				
			||||||
 | 
					                                oref);
 | 
				
			||||||
 | 
					        if (!g_hash_table_lookup (data->oref_hash, (gpointer)oref))
 | 
				
			||||||
 | 
					            g_hash_table_insert (data->oref_hash,
 | 
				
			||||||
 | 
					                                 (gpointer)oref,
 | 
				
			||||||
 | 
					                                 (gpointer)TRUE);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    matrix = eek_key_get_symbol_matrix (EEK_KEY(element));
 | 
				
			||||||
 | 
					    num_symbols = matrix->num_groups * matrix->num_levels;
 | 
				
			||||||
 | 
					    if (num_symbols > 0) {
 | 
				
			||||||
 | 
					        g_string_append_indent (data->output, data->indent + 1);
 | 
				
			||||||
 | 
					        g_string_markup_printf (data->output,
 | 
				
			||||||
 | 
					                                "<symbols groups=\"%d\" levels=\"%d\">\n",
 | 
				
			||||||
 | 
					                                matrix->num_groups, matrix->num_levels);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        for (i = 0; i < num_symbols; i++) {
 | 
				
			||||||
 | 
					            EekSymbol *symbol = matrix->data[i];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            g_string_append_indent (data->output, data->indent + 2);
 | 
				
			||||||
 | 
					            if (EEK_IS_KEYSYM(symbol)) {
 | 
				
			||||||
 | 
					                guint xkeysym = eek_keysym_get_xkeysym (EEK_KEYSYM(symbol));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                g_string_markup_printf (data->output, "<keysym");
 | 
				
			||||||
 | 
					                output_symbol_attributes (data->output, symbol);
 | 
				
			||||||
 | 
					                if (xkeysym != EEK_INVALID_KEYSYM)
 | 
				
			||||||
 | 
					                    g_string_markup_printf (data->output, " keyval=\"%u\"",
 | 
				
			||||||
 | 
					                                            xkeysym);
 | 
				
			||||||
 | 
					                g_string_markup_printf (data->output, ">%s</keysym>\n",
 | 
				
			||||||
 | 
					                                        eek_symbol_get_name (symbol));
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            else if (EEK_IS_TEXT(symbol)) {
 | 
				
			||||||
 | 
					                g_string_markup_printf (data->output, "<text");
 | 
				
			||||||
 | 
					                output_symbol_attributes (data->output, symbol);
 | 
				
			||||||
 | 
					                g_string_markup_printf (data->output,
 | 
				
			||||||
 | 
					                                        ">%s</text>\n",
 | 
				
			||||||
 | 
					                                        eek_text_get_text (EEK_TEXT(symbol)));
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            else {
 | 
				
			||||||
 | 
					                g_string_markup_printf (data->output, "<symbol");
 | 
				
			||||||
 | 
					                output_symbol_attributes (data->output, symbol);
 | 
				
			||||||
 | 
					                g_string_markup_printf (data->output,
 | 
				
			||||||
 | 
					                                        ">%s</symbol>\n",
 | 
				
			||||||
 | 
					                                        eek_symbol_get_name (symbol));
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        g_string_append_indent (data->output, data->indent + 1);
 | 
				
			||||||
 | 
					        g_string_markup_printf (data->output, "</symbols>\n");
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    g_string_append_indent (data->output, data->indent);
 | 
				
			||||||
 | 
					    g_string_markup_printf (data->output, "</key>\n");
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					output_section_callback (EekElement *element, gpointer user_data)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    OutputCallbackData *data = user_data;
 | 
				
			||||||
 | 
					    EekBounds bounds;
 | 
				
			||||||
 | 
					    gint angle, n_rows, i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    g_string_append_indent (data->output, data->indent);
 | 
				
			||||||
 | 
					    if (eek_element_get_name (element))
 | 
				
			||||||
 | 
					        g_string_markup_printf (data->output, "<section name=\"%s\">\n",
 | 
				
			||||||
 | 
					                                eek_element_get_name (element));
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					        g_string_markup_printf (data->output, "<section>\n");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    eek_element_get_bounds (element, &bounds);
 | 
				
			||||||
 | 
					    g_string_append_indent (data->output, data->indent + 1);
 | 
				
			||||||
 | 
					    output_bounds (data->output, &bounds);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    angle = eek_section_get_angle (EEK_SECTION(element));
 | 
				
			||||||
 | 
					    g_string_append_indent (data->output, data->indent + 1);
 | 
				
			||||||
 | 
					    g_string_markup_printf (data->output, "<angle>%d</angle>\n", angle);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    n_rows = eek_section_get_n_rows (EEK_SECTION(element));
 | 
				
			||||||
 | 
					    for (i = 0; i < n_rows; i++) {
 | 
				
			||||||
 | 
					        gint num_columns;
 | 
				
			||||||
 | 
					        EekOrientation orientation;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        eek_section_get_row (EEK_SECTION(element),
 | 
				
			||||||
 | 
					                             i,
 | 
				
			||||||
 | 
					                             &num_columns,
 | 
				
			||||||
 | 
					                             &orientation);
 | 
				
			||||||
 | 
					        g_string_append_indent (data->output, data->indent + 1);
 | 
				
			||||||
 | 
					        g_string_markup_printf (data->output, "<row>\n");
 | 
				
			||||||
 | 
					        g_string_append_indent (data->output, data->indent + 2);
 | 
				
			||||||
 | 
					        g_string_markup_printf (data->output, "<columns>%d</columns>\n",
 | 
				
			||||||
 | 
					                                num_columns);
 | 
				
			||||||
 | 
					        g_string_append_indent (data->output, data->indent + 2);
 | 
				
			||||||
 | 
					        g_string_markup_printf (data->output, "<orientation>%d</orientation>\n",
 | 
				
			||||||
 | 
					                                orientation);
 | 
				
			||||||
 | 
					        g_string_append_indent (data->output, data->indent + 1);
 | 
				
			||||||
 | 
					        g_string_markup_printf (data->output, "</row>\n");
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    data->indent++;
 | 
				
			||||||
 | 
					    eek_container_foreach_child (EEK_CONTAINER(element),
 | 
				
			||||||
 | 
					                                 output_key_callback,
 | 
				
			||||||
 | 
					                                 data);
 | 
				
			||||||
 | 
					    data->indent--;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    g_string_append_indent (data->output, data->indent);
 | 
				
			||||||
 | 
					    g_string_markup_printf (data->output, "</section>\n");
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * eek_keyboard_output:
 | 
				
			||||||
 | 
					 * @keyboard: an #EekKeyboard
 | 
				
			||||||
 | 
					 * @output: a GString
 | 
				
			||||||
 | 
					 * @indent: an integer
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Convert @keyboard into the XML format and store it into @output.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					eek_keyboard_output (EekKeyboard *keyboard, GString *output, gint indent)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    OutputCallbackData data;
 | 
				
			||||||
 | 
					    EekBounds bounds;
 | 
				
			||||||
 | 
					    gulong oref;
 | 
				
			||||||
 | 
					    GHashTableIter iter;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    g_assert (EEK_IS_KEYBOARD(keyboard));
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					    g_string_append_indent (output, indent);
 | 
				
			||||||
 | 
					    if (eek_element_get_name (EEK_ELEMENT(keyboard)))
 | 
				
			||||||
 | 
					        g_string_markup_printf (output, "<?xml version=\"1.0\"?>\n"
 | 
				
			||||||
 | 
					                                "<keyboard version=\"%s\" id=\"%s\">\n",
 | 
				
			||||||
 | 
					                                EEK_XML_SCHEMA_VERSION,
 | 
				
			||||||
 | 
					                                eek_element_get_name (EEK_ELEMENT(keyboard)));
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					        g_string_markup_printf (output, "<?xml version=\"1.0\"?>\n"
 | 
				
			||||||
 | 
					                                "<keyboard version=\"%s\">\n",
 | 
				
			||||||
 | 
					                                EEK_XML_SCHEMA_VERSION);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    eek_element_get_bounds (EEK_ELEMENT(keyboard), &bounds);
 | 
				
			||||||
 | 
					    g_string_append_indent (output, indent + 1);
 | 
				
			||||||
 | 
					    output_bounds (output, &bounds);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    data.output = output;
 | 
				
			||||||
 | 
					    data.indent = indent;
 | 
				
			||||||
 | 
					    data.oref_hash = g_hash_table_new (g_direct_hash, g_direct_equal);
 | 
				
			||||||
 | 
					    data.key_serial = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    data.indent++;
 | 
				
			||||||
 | 
					    eek_container_foreach_child (EEK_CONTAINER(keyboard),
 | 
				
			||||||
 | 
					                                 output_section_callback,
 | 
				
			||||||
 | 
					                                 &data);
 | 
				
			||||||
 | 
					    data.indent--;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    g_hash_table_iter_init (&iter, data.oref_hash);
 | 
				
			||||||
 | 
					    while (g_hash_table_iter_next (&iter, (gpointer *)&oref, NULL)) {
 | 
				
			||||||
 | 
					        EekOutline *outline;
 | 
				
			||||||
 | 
					        gint j;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        outline = eek_keyboard_get_outline (keyboard, oref);
 | 
				
			||||||
 | 
					        g_string_append_indent (output, indent + 1);
 | 
				
			||||||
 | 
					        g_string_markup_printf (output, "<outline id=\"outline%u\">\n", oref);
 | 
				
			||||||
 | 
					        g_string_append_indent (output, indent + 2);
 | 
				
			||||||
 | 
					        g_string_markup_printf (output, "<corner-radius>%lf</corner-radius>\n",
 | 
				
			||||||
 | 
					                                outline->corner_radius);
 | 
				
			||||||
 | 
					        for (j = 0; j < outline->num_points; j++) {
 | 
				
			||||||
 | 
					            g_string_append_indent (output, indent + 2);
 | 
				
			||||||
 | 
					            g_string_markup_printf (output, "<point>%lf,%lf</point>\n",
 | 
				
			||||||
 | 
					                                    outline->points[j].x,
 | 
				
			||||||
 | 
					                                    outline->points[j].y);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        g_string_append_indent (output, indent + 1);
 | 
				
			||||||
 | 
					        g_string_markup_printf (output, "</outline>\n");
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    g_hash_table_destroy (data.oref_hash);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    g_string_append_indent (output, indent);
 | 
				
			||||||
 | 
					    g_string_markup_printf (output, "</keyboard>\n");
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										39
									
								
								eek/eek-xml.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,39 @@
 | 
				
			|||||||
 | 
					/* 
 | 
				
			||||||
 | 
					 * Copyright (C) 2011 Daiki Ueno <ueno@unixuser.org>
 | 
				
			||||||
 | 
					 * Copyright (C) 2011 Red Hat, Inc.
 | 
				
			||||||
 | 
					 * 
 | 
				
			||||||
 | 
					 * This program is free software: you can redistribute it and/or modify
 | 
				
			||||||
 | 
					 * it under the terms of the GNU General Public License as published by
 | 
				
			||||||
 | 
					 * the Free Software Foundation, either version 3 of the License, or
 | 
				
			||||||
 | 
					 * (at your option) any later version.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * This program is distributed in the hope that it will be useful,
 | 
				
			||||||
 | 
					 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
				
			||||||
 | 
					 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
				
			||||||
 | 
					 * GNU General Public License for more details.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * You should have received a copy of the GNU General Public License
 | 
				
			||||||
 | 
					 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if !defined(__EEK_H_INSIDE__) && !defined(EEK_COMPILATION)
 | 
				
			||||||
 | 
					#error "Only <eek/eek.h> can be included directly."
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef EEK_XML_H
 | 
				
			||||||
 | 
					#define EEK_XML_H 1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <glib-object.h>
 | 
				
			||||||
 | 
					#include "eek-keyboard.h"
 | 
				
			||||||
 | 
					#include "eek-xml-layout.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					G_BEGIN_DECLS
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define EEK_XML_SCHEMA_VERSION "0.90"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void eek_keyboard_output (EekKeyboard *keyboard,
 | 
				
			||||||
 | 
					                          GString     *output,
 | 
				
			||||||
 | 
					                          gint         indent);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					G_END_DECLS
 | 
				
			||||||
 | 
					#endif  /* EEK_XML_H */
 | 
				
			||||||