Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| be7154f287 |
@ -1,17 +0,0 @@
|
||||
image: debian:buster
|
||||
|
||||
stages:
|
||||
- build
|
||||
|
||||
before_script:
|
||||
- apt-get -y update
|
||||
- apt-get -y build-dep .
|
||||
|
||||
build_meson:
|
||||
stage: build
|
||||
tags:
|
||||
- librem5
|
||||
script:
|
||||
- meson . _build/ -Ddepdatadir=/usr/share
|
||||
- ninja -C _build install
|
||||
|
||||
39
Makefile.am
Normal file
@ -0,0 +1,39 @@
|
||||
# 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
|
||||
|
||||
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
|
||||
35
README
Normal file
@ -0,0 +1,35 @@
|
||||
eekboard - an easy to use virtual keyboard toolkit -*- outline -*-
|
||||
|
||||
eekboard is a virtual keyboard software package, including a set of
|
||||
tools to implement desktop virtual keyboards.
|
||||
|
||||
* Building
|
||||
|
||||
** Dependencies
|
||||
|
||||
REQUIRED: GLib2, GTK, PangoCairo, libxklavier, libcroco
|
||||
OPTIONAL: libXtst, at-spi2-core, IBus, Clutter, Clutter-Gtk, Python, Vala, gobject-introspection, libcanberra
|
||||
|
||||
** Build from git repo
|
||||
|
||||
$ git clone git://github.com/ueno/eekboard.git
|
||||
$ cd eekboard
|
||||
$ ./autogen.sh --prefix=/usr --enable-gtk-doc
|
||||
$ make
|
||||
$ sudo make install
|
||||
|
||||
** Build from tarball
|
||||
|
||||
$ ./configure --prefix=/usr
|
||||
$ make
|
||||
$ sudo make install
|
||||
|
||||
* Running
|
||||
|
||||
$ eekboard
|
||||
$ eekboard -f # show/hide automatically based on focus-in/focus-out events
|
||||
|
||||
Even though eekboard -f watches a11y events by default, it currently
|
||||
works better with IBus. To use IBus, do:
|
||||
|
||||
$ gsettings set org.fedorahosted.eekboard focus-listener 'ibus'
|
||||
68
README.md
@ -1,68 +0,0 @@
|
||||
*squeekboard* - a Wayland virtual keyboard
|
||||
========================================
|
||||
|
||||
*Squeekboard* is a virtual keyboard supporting Wayland, built primarily for the *Librem 5* phone.
|
||||
|
||||
Features
|
||||
--------
|
||||
|
||||
### Present
|
||||
|
||||
- GTK3
|
||||
- Custom xml-defined keyboards
|
||||
- DBus interface to show and hide
|
||||
|
||||
### Temporarily dropped
|
||||
|
||||
- A settings interface
|
||||
|
||||
### TODO
|
||||
|
||||
- Use Wayland virtual keyboard protocol
|
||||
- Use Wayland text input protocol
|
||||
- Use Wayland input method protocol
|
||||
- Pick up DBus interface files from /usr/share
|
||||
|
||||
Building
|
||||
--------
|
||||
|
||||
### Dependencies
|
||||
|
||||
See `.gitlab-ci.yml`.
|
||||
|
||||
### Build from git repo
|
||||
|
||||
```
|
||||
$ git clone https://source.puri.sm/Librem5/eekboard.git
|
||||
$ cd eekboard
|
||||
$ mkdir ../build
|
||||
$ meson ../build/
|
||||
$ cd ../build
|
||||
$ ninja install
|
||||
```
|
||||
|
||||
For development, alter the `meson` call:
|
||||
|
||||
```
|
||||
$ meson ../build/ --prefix=../install
|
||||
```
|
||||
|
||||
and don't skip `ninja install` before running. The last step is necessary in order to find the keyboard definition files.
|
||||
|
||||
Running
|
||||
-------
|
||||
|
||||
```
|
||||
$ rootston
|
||||
$ cd ../build/
|
||||
$ src/squeekboard
|
||||
```
|
||||
|
||||
### Testing
|
||||
|
||||
```
|
||||
$ busctl call --user sm.puri.OSK0 /sm/puri/OSK0 sm.puri.OSK0 SetVisible b true
|
||||
$ busctl call --user sm.puri.OSK0 /sm/puri/OSK0 sm.puri.OSK0 SetVisible b false
|
||||
$ gsettings set org.gnome.desktop.input-sources sources "[('xkb', 'us'), ('xkb', 'ua')]"
|
||||
$ gsettings set org.gnome.desktop.input-sources current 1
|
||||
```
|
||||
25
autogen.sh
Executable file
@ -0,0 +1,25 @@
|
||||
#!/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 ) || {
|
||||
echo -n "**Error**: Directory "\`$srcdir\'" does not look like the"
|
||||
echo " top-level $PKG_NAME directory"
|
||||
exit 1
|
||||
}
|
||||
|
||||
which gnome-autogen.sh || {
|
||||
echo "You need to install gnome-common from the GNOME CVS"
|
||||
exit 1
|
||||
}
|
||||
|
||||
ACLOCAL_FLAGS="$ACLOCAL_FLAGS -I m4"
|
||||
REQUIRED_AUTOMAKE_VERSION=1.10
|
||||
REQUIRED_AUTOCONF_VERSION=2.60
|
||||
|
||||
. 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="24" width="24"
|
||||
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="24" width="24"
|
||||
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,119 +1,313 @@
|
||||
<?xml version="1.0"?>
|
||||
<geometry version="0.90">
|
||||
<bounds x="0" y="10.000000" width="426.0000" height="296.5853"/>
|
||||
<bounds x="0.000000" y="0.000000" width="640.0000" height="296.5853"/>
|
||||
<section angle="0">
|
||||
<bounds x="15.60975" y="15.60975" width="640.0000" height="39.02439"/>
|
||||
<row orientation="1">
|
||||
<key keycode="24" name="AD01" oref="outline2" />
|
||||
<key keycode="25" name="AD02" oref="outline2" />
|
||||
<key keycode="26" name="AD03" oref="outline2" />
|
||||
<key keycode="27" name="AD04" oref="outline2" />
|
||||
<key keycode="28" name="AD05" oref="outline2" />
|
||||
<key keycode="29" name="AD06" oref="outline2" />
|
||||
<key keycode="30" name="AD07" oref="outline2" />
|
||||
<key keycode="31" name="AD08" oref="outline2" />
|
||||
<key keycode="32" name="AD09" oref="outline2" />
|
||||
<key keycode="33" name="AD10" oref="outline2" />
|
||||
<key keycode="9" name="ESC" oref="outline2">
|
||||
<bounds x="3.121951" y="1.560976" width="37.46341" height="37.46341"/>
|
||||
</key>
|
||||
<key keycode="67" name="FK01" oref="outline2">
|
||||
<bounds x="84.29268" y="1.560976" width="37.46341" height="37.46341"/>
|
||||
</key>
|
||||
<key keycode="68" name="FK02" oref="outline2">
|
||||
<bounds x="124.8780" y="1.560976" width="37.46341" height="37.46341"/>
|
||||
</key>
|
||||
<key keycode="69" name="FK03" oref="outline2">
|
||||
<bounds x="165.4634" y="1.560976" width="37.46341" height="37.46341"/>
|
||||
</key>
|
||||
<key keycode="70" name="FK04" oref="outline2">
|
||||
<bounds x="206.0487" y="1.560976" width="37.46341" height="37.46341"/>
|
||||
</key>
|
||||
<key keycode="71" name="FK05" oref="outline2">
|
||||
<bounds x="266.9268" y="1.560976" width="37.46341" height="37.46341"/>
|
||||
</key>
|
||||
<key keycode="72" name="FK06" oref="outline2">
|
||||
<bounds x="307.5121" y="1.560976" width="37.46341" height="37.46341"/>
|
||||
</key>
|
||||
<key keycode="73" name="FK07" oref="outline2">
|
||||
<bounds x="348.0975" y="1.560976" width="37.46341" height="37.46341"/>
|
||||
</key>
|
||||
<key keycode="74" name="FK08" oref="outline2">
|
||||
<bounds x="388.6829" y="1.560976" width="37.46341" height="37.46341"/>
|
||||
</key>
|
||||
<key keycode="75" name="FK09" oref="outline2">
|
||||
<bounds x="449.5609" y="1.560976" width="37.46341" height="37.46341"/>
|
||||
</key>
|
||||
<key keycode="76" name="FK10" oref="outline2">
|
||||
<bounds x="490.1463" y="1.560976" width="37.46341" height="37.46341"/>
|
||||
</key>
|
||||
<key keycode="95" name="FK11" oref="outline2">
|
||||
<bounds x="530.7317" y="1.560976" width="37.46341" height="37.46341"/>
|
||||
</key>
|
||||
<key keycode="96" name="FK12" oref="outline2">
|
||||
<bounds x="571.3170" y="1.560976" width="37.46341" height="37.46341"/>
|
||||
</key>
|
||||
</row>
|
||||
</section>
|
||||
<section angle="0">
|
||||
<bounds x="15.60975" y="78.04878" width="608.7804" height="201.3658"/>
|
||||
<row orientation="1">
|
||||
<key keycode="38" name="AC01" oref="outline2" />
|
||||
<key keycode="39" name="AC02" oref="outline2" />
|
||||
<key keycode="40" name="AC03" oref="outline2" />
|
||||
<key keycode="41" name="AC04" oref="outline2" />
|
||||
<key keycode="42" name="AC05" oref="outline2" />
|
||||
<key keycode="43" name="AC06" oref="outline2" />
|
||||
<key keycode="44" name="AC07" oref="outline2" />
|
||||
<key keycode="45" name="AC08" oref="outline2" />
|
||||
<key keycode="46" name="AC09" oref="outline2" />
|
||||
<key keycode="49" name="TLDE" oref="outline2">
|
||||
<bounds x="3.121951" y="1.560976" width="37.46341" height="37.46341"/>
|
||||
</key>
|
||||
<key keycode="10" name="AE01" oref="outline2">
|
||||
<bounds x="43.70731" y="1.560976" width="37.46341" height="37.46341"/>
|
||||
</key>
|
||||
<key keycode="11" name="AE02" oref="outline2">
|
||||
<bounds x="84.29268" y="1.560976" width="37.46341" height="37.46341"/>
|
||||
</key>
|
||||
<key keycode="12" name="AE03" oref="outline2">
|
||||
<bounds x="124.8780" y="1.560976" width="37.46341" height="37.46341"/>
|
||||
</key>
|
||||
<key keycode="13" name="AE04" oref="outline2">
|
||||
<bounds x="165.4634" y="1.560976" width="37.46341" height="37.46341"/>
|
||||
</key>
|
||||
<key keycode="14" name="AE05" oref="outline2">
|
||||
<bounds x="206.0487" y="1.560976" width="37.46341" height="37.46341"/>
|
||||
</key>
|
||||
<key keycode="15" name="AE06" oref="outline2">
|
||||
<bounds x="245.0731" y="1.560976" width="37.46341" height="37.46341"/>
|
||||
</key>
|
||||
<key keycode="16" name="AE07" oref="outline2">
|
||||
<bounds x="285.6585" y="1.560976" width="37.46341" height="37.46341"/>
|
||||
</key>
|
||||
<key keycode="17" name="AE08" oref="outline2">
|
||||
<bounds x="326.2439" y="1.560976" width="37.46341" height="37.46341"/>
|
||||
</key>
|
||||
<key keycode="18" name="AE09" oref="outline2">
|
||||
<bounds x="366.8292" y="1.560976" width="37.46341" height="37.46341"/>
|
||||
</key>
|
||||
<key keycode="19" name="AE10" oref="outline2">
|
||||
<bounds x="407.4146" y="1.560976" width="37.46341" height="37.46341"/>
|
||||
</key>
|
||||
<key keycode="20" name="AE11" oref="outline2">
|
||||
<bounds x="448.0000" y="1.560976" width="37.46341" height="37.46341"/>
|
||||
</key>
|
||||
<key keycode="21" name="AE12" oref="outline2">
|
||||
<bounds x="488.5853" y="1.560976" width="37.46341" height="37.46341"/>
|
||||
</key>
|
||||
<key keycode="22" name="BKSP" oref="outline13">
|
||||
<bounds x="529.1707" y="1.560976" width="79.60975" height="37.46341"/>
|
||||
</key>
|
||||
</row>
|
||||
</section>
|
||||
<section angle="0">
|
||||
<row orientation="1">
|
||||
<key keycode="50" name="LFSH" oref="altline" />
|
||||
<key keycode="52" name="AB01" oref="outline2" />
|
||||
<key keycode="53" name="AB02" oref="outline2" />
|
||||
<key keycode="54" name="AB03" oref="outline2" />
|
||||
<key keycode="55" name="AB04" oref="outline2" />
|
||||
<key keycode="56" name="AB05" oref="outline2" />
|
||||
<key keycode="57" name="AB06" oref="outline2" />
|
||||
<key keycode="58" name="AB07" oref="outline2" />
|
||||
<key keycode="22" name="BKSP" oref="altline" />
|
||||
<key keycode="23" name="TAB" oref="outline4">
|
||||
<bounds x="3.121951" y="42.14634" width="59.31707" height="37.46341"/>
|
||||
</key>
|
||||
<key keycode="24" name="AD01" oref="outline2">
|
||||
<bounds x="65.56097" y="42.14634" width="37.46341" height="37.46341"/>
|
||||
</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>
|
||||
<key keycode="34" name="AD11" oref="outline2">
|
||||
<bounds x="468.2926" y="42.14634" width="37.46341" height="37.46341"/>
|
||||
</key>
|
||||
<key keycode="35" name="AD12" oref="outline2">
|
||||
<bounds x="508.8780" y="42.14634" width="37.46341" height="37.46341"/>
|
||||
</key>
|
||||
<key keycode="51" name="BKSL" oref="outline5">
|
||||
<bounds x="549.4634" y="42.14634" width="59.31707" height="37.46341"/>
|
||||
</key>
|
||||
</row>
|
||||
</section>
|
||||
<section angle="0">
|
||||
<row orientation="1">
|
||||
<key keycode="0" name="ABC123" oref="altline" />
|
||||
<key keycode="150" name="I150" oref="altline" />
|
||||
<key keycode="65" name="SPCE" oref="spaceline" />
|
||||
<key keycode="60" name="AB09" oref="outline2" />
|
||||
<key keycode="36" name="RTRN" oref="outline7" />
|
||||
<key keycode="66" name="CAPS" oref="outline6">
|
||||
<bounds x="3.121951" y="82.73170" width="68.68292" height="37.46341"/>
|
||||
</key>
|
||||
<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>
|
||||
<key keycode="47" name="AC10" oref="outline2">
|
||||
<bounds x="438.6341" y="82.73170" width="37.46341" height="37.46341"/>
|
||||
</key>
|
||||
<key keycode="48" name="AC11" oref="outline2">
|
||||
<bounds x="479.2195" y="82.73170" 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>
|
||||
<row orientation="1">
|
||||
<key keycode="50" name="LFSH" oref="outline8">
|
||||
<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="59" name="AB08" oref="outline2">
|
||||
<bounds x="377.7560" y="121.7560" width="37.46341" 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="61" name="AB10" oref="outline2">
|
||||
<bounds x="458.9268" y="121.7560" width="37.46341" height="37.46341"/>
|
||||
</key>
|
||||
<key keycode="62" name="RTSH" oref="outline9">
|
||||
<bounds x="499.5121" y="121.7560" width="109.2682" height="37.46341"/>
|
||||
</key>
|
||||
</row>
|
||||
<row orientation="1">
|
||||
<key keycode="149" name="I149" oref="outline10">
|
||||
<bounds x="3.121951" y="162.3414" width="37.46341" height="37.46341"/>
|
||||
</key>
|
||||
<key keycode="37" name="LCTL" oref="outline1">
|
||||
<bounds x="62.43902" y="162.3414" width="48.39024" height="37.46341"/>
|
||||
</key>
|
||||
<key keycode="64" name="LALT" oref="outline1">
|
||||
<bounds x="113.9512" y="162.3414" width="48.39024" height="37.46341"/>
|
||||
</key>
|
||||
<key keycode="65" name="SPCE" oref="outline3">
|
||||
<bounds x="165.4634" y="162.3414" width="217.5853" height="37.46341"/>
|
||||
</key>
|
||||
<key keycode="113" name="LEFT" oref="outline1">
|
||||
<bounds x="368.0487" y="162.3414" width="48.39024" height="37.46341"/>
|
||||
</key>
|
||||
<key keycode="111" name="UP" oref="outline1">
|
||||
<bounds x="419.43894" y="162.3414" width="48.39024" height="37.46341"/>
|
||||
</key>
|
||||
<key keycode="116" name="DOWN" oref="outline1">
|
||||
<bounds x="470.82918" y="162.3414" width="48.39024" height="37.46341"/>
|
||||
</key>
|
||||
<key keycode="114" name="RGHT" oref="outline1">
|
||||
<bounds x="522.21942" y="162.3414" width="48.39024" height="37.46341"/>
|
||||
</key>
|
||||
<key keycode="150" name="I150" oref="outline10">
|
||||
<bounds x="573.60966" y="162.3414" width="37.46341" height="37.46341"/>
|
||||
</key>
|
||||
</row>
|
||||
</section>
|
||||
<outline id="outline2" corner-radius="1.000000">
|
||||
<point x="0.000000" y="0.000000"/>
|
||||
<point x="37.46341" y="0.000000"/>
|
||||
<point x="37.46341" y="52.44877"/>
|
||||
<point x="0.000000" y="52.44877"/>
|
||||
<point x="37.46341" y="37.46341"/>
|
||||
<point x="0.000000" y="37.46341"/>
|
||||
</outline>
|
||||
<outline id="altline" corner-radius="1.000000">
|
||||
<outline id="outline1" 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"/>
|
||||
<point x="48.39024" y="37.46341"/>
|
||||
<point x="0.000000" y="37.46341"/>
|
||||
</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"/>
|
||||
<point x="59.31707" y="37.46341"/>
|
||||
<point x="0.000000" y="37.46341"/>
|
||||
</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"/>
|
||||
<point x="59.31707" y="37.46341"/>
|
||||
<point x="0.000000" y="37.46341"/>
|
||||
</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"/>
|
||||
<point x="68.68292" y="37.46341"/>
|
||||
<point x="0.000000" y="37.46341"/>
|
||||
</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"/>
|
||||
<point x="88.97561" y="37.46341"/>
|
||||
<point x="0.000000" y="37.46341"/>
|
||||
</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"/>
|
||||
<point x="88.97561" y="37.46341"/>
|
||||
<point x="0.000000" y="37.46341"/>
|
||||
</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"/>
|
||||
<point x="109.2682" y="37.46341"/>
|
||||
<point x="0.000000" y="37.46341"/>
|
||||
</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"/>
|
||||
<point x="37.46341" y="37.46341"/>
|
||||
<point x="0.000000" y="37.46341"/>
|
||||
</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"/>
|
||||
<point x="79.60975" y="37.46341"/>
|
||||
<point x="0.000000" y="37.46341"/>
|
||||
</outline>
|
||||
<outline id="spaceline" corner-radius="1.000000">
|
||||
<outline id="outline3" corner-radius="1.000000">
|
||||
<point x="0.000000" y="0.000000"/>
|
||||
<point x="150.5853" y="0.000000"/>
|
||||
<point x="150.5853" y="52.44877"/>
|
||||
<point x="0.000000" y="52.44877"/>
|
||||
<point x="217.5853" y="0.000000"/>
|
||||
<point x="217.5853" y="37.46341"/>
|
||||
<point x="0.000000" y="37.46341"/>
|
||||
</outline>
|
||||
</geometry>
|
||||
|
||||
@ -39,8 +39,61 @@
|
||||
<key keycode="96" name="FK12">
|
||||
<keysym keyval="65481">F12</keysym>
|
||||
</key>
|
||||
<key keycode="49" name="TLDE">
|
||||
<keysym keyval="96">quoteleft</keysym>
|
||||
<keysym keyval="126">asciitilde</keysym>
|
||||
</key>
|
||||
<key keycode="10" name="AE01">
|
||||
<keysym keyval="49">1</keysym>
|
||||
<keysym keyval="33">exclam</keysym>
|
||||
</key>
|
||||
<key keycode="11" name="AE02">
|
||||
<keysym keyval="50">2</keysym>
|
||||
<keysym keyval="64">at</keysym>
|
||||
</key>
|
||||
<key keycode="12" name="AE03">
|
||||
<keysym keyval="51">3</keysym>
|
||||
<keysym keyval="35">numbersign</keysym>
|
||||
</key>
|
||||
<key keycode="13" name="AE04">
|
||||
<keysym keyval="52">4</keysym>
|
||||
<keysym keyval="36">dollar</keysym>
|
||||
</key>
|
||||
<key keycode="14" name="AE05">
|
||||
<keysym keyval="53">5</keysym>
|
||||
<keysym keyval="37">percent</keysym>
|
||||
<keysym keyval="8364">EuroSign</keysym>
|
||||
</key>
|
||||
<key keycode="15" name="AE06">
|
||||
<keysym keyval="54">6</keysym>
|
||||
<keysym keyval="94">asciicircum</keysym>
|
||||
</key>
|
||||
<key keycode="16" name="AE07">
|
||||
<keysym keyval="55">7</keysym>
|
||||
<keysym keyval="38">ampersand</keysym>
|
||||
</key>
|
||||
<key keycode="17" name="AE08">
|
||||
<keysym keyval="56">8</keysym>
|
||||
<keysym keyval="42">asterisk</keysym>
|
||||
</key>
|
||||
<key keycode="18" name="AE09">
|
||||
<keysym keyval="57">9</keysym>
|
||||
<keysym keyval="40">parenleft</keysym>
|
||||
</key>
|
||||
<key keycode="19" name="AE10">
|
||||
<keysym keyval="48">0</keysym>
|
||||
<keysym keyval="41">parenright</keysym>
|
||||
</key>
|
||||
<key keycode="20" name="AE11">
|
||||
<keysym keyval="45">minus</keysym>
|
||||
<keysym keyval="95">underscore</keysym>
|
||||
</key>
|
||||
<key keycode="21" name="AE12">
|
||||
<keysym keyval="61">equal</keysym>
|
||||
<keysym keyval="43">plus</keysym>
|
||||
</key>
|
||||
<key keycode="22" name="BKSP">
|
||||
<keysym keyval="65288" icon="edit-clear-symbolic">backspace</keysym>
|
||||
<keysym keyval="65288">BackSpace</keysym>
|
||||
</key>
|
||||
<key keycode="23" name="TAB">
|
||||
<keysym keyval="65289">Tab</keysym>
|
||||
@ -49,56 +102,42 @@
|
||||
<key keycode="24" name="AD01">
|
||||
<keysym keyval="113">q</keysym>
|
||||
<keysym keyval="81">Q</keysym>
|
||||
<keysym keyval="49">1</keysym>
|
||||
<keysym keyval="126">asciitilde</keysym>
|
||||
</key>
|
||||
<key keycode="25" name="AD02">
|
||||
<keysym keyval="119">w</keysym>
|
||||
<keysym keyval="87">W</keysym>
|
||||
<keysym keyval="50">2</keysym>
|
||||
<keysym keyval="96">quoteleft</keysym>
|
||||
</key>
|
||||
<key keycode="26" name="AD03">
|
||||
<keysym keyval="101">e</keysym>
|
||||
<keysym keyval="69">E</keysym>
|
||||
<keysym keyval="51">3</keysym>
|
||||
<keysym keyval="124">bar</keysym>
|
||||
</key>
|
||||
<key keycode="27" name="AD04">
|
||||
<keysym keyval="114">r</keysym>
|
||||
<keysym keyval="82">R</keysym>
|
||||
<keysym keyval="52">4</keysym>
|
||||
<keysym keyval="183">middledot</keysym>
|
||||
</key>
|
||||
<key keycode="28" name="AD05">
|
||||
<keysym keyval="116">t</keysym>
|
||||
<keysym keyval="84">T</keysym>
|
||||
<keysym keyval="53">5</keysym>
|
||||
</key>
|
||||
<key keycode="29" name="AD06">
|
||||
<keysym keyval="121">y</keysym>
|
||||
<keysym keyval="89">Y</keysym>
|
||||
<keysym keyval="54">6</keysym>
|
||||
</key>
|
||||
<key keycode="30" name="AD07">
|
||||
<keysym keyval="117">u</keysym>
|
||||
<keysym keyval="85">U</keysym>
|
||||
<keysym keyval="55">7</keysym>
|
||||
</key>
|
||||
<key keycode="31" name="AD08">
|
||||
<keysym keyval="105">i</keysym>
|
||||
<keysym keyval="73">I</keysym>
|
||||
<keysym keyval="56">8</keysym>
|
||||
</key>
|
||||
<key keycode="32" name="AD09">
|
||||
<keysym keyval="111">o</keysym>
|
||||
<keysym keyval="79">O</keysym>
|
||||
<keysym keyval="57">9</keysym>
|
||||
</key>
|
||||
<key keycode="33" name="AD10">
|
||||
<keysym keyval="112">p</keysym>
|
||||
<keysym keyval="80">P</keysym>
|
||||
<keysym keyval="48">0</keysym>
|
||||
</key>
|
||||
<key keycode="34" name="AD11">
|
||||
<keysym keyval="91">bracketleft</keysym>
|
||||
@ -112,65 +151,44 @@
|
||||
<keysym keyval="92">backslash</keysym>
|
||||
<keysym keyval="124">bar</keysym>
|
||||
</key>
|
||||
<key keycode="0" name="ABC123">
|
||||
<symbol label="123">show-numbers</symbol>
|
||||
<symbol label="123">show-numbers</symbol>
|
||||
<symbol label="ABC">show-letters</symbol>
|
||||
<symbol label="ABC">show-letters</symbol>
|
||||
<key keycode="66" name="CAPS">
|
||||
<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>
|
||||
<keysym keyval="169">copyright</keysym>
|
||||
</key>
|
||||
<key keycode="39" name="AC02">
|
||||
<keysym keyval="115">s</keysym>
|
||||
<keysym keyval="83">S</keysym>
|
||||
<keysym keyval="35">numbersign</keysym>
|
||||
<keysym keyval="174">registeredtrademark</keysym>
|
||||
</key>
|
||||
<key keycode="40" name="AC03">
|
||||
<keysym keyval="100">d</keysym>
|
||||
<keysym keyval="68">D</keysym>
|
||||
<keysym keyval="36">dollar</keysym>
|
||||
<keysym keyval="163">poundsign</keysym>
|
||||
</key>
|
||||
<key keycode="41" name="AC04">
|
||||
<keysym keyval="102">f</keysym>
|
||||
<keysym keyval="70">F</keysym>
|
||||
<keysym keyval="37">percent</keysym>
|
||||
<text>€</text>
|
||||
</key>
|
||||
<key keycode="42" name="AC05">
|
||||
<keysym keyval="103">g</keysym>
|
||||
<keysym keyval="71">G</keysym>
|
||||
<keysym keyval="38">ampersand</keysym>
|
||||
<keysym keyval="165">yensign</keysym>
|
||||
</key>
|
||||
<key keycode="43" name="AC06">
|
||||
<keysym keyval="104">h</keysym>
|
||||
<keysym keyval="72">H</keysym>
|
||||
<keysym keyval="45">minus</keysym>
|
||||
<keysym keyval="94">asciicircum</keysym>
|
||||
</key>
|
||||
<key keycode="44" name="AC07">
|
||||
<keysym keyval="106">j</keysym>
|
||||
<keysym keyval="74">J</keysym>
|
||||
<keysym keyval="43">plus</keysym>
|
||||
<keysym keyval="176">degreesign</keysym>
|
||||
</key>
|
||||
<key keycode="45" name="AC08">
|
||||
<keysym keyval="107">k</keysym>
|
||||
<keysym keyval="75">K</keysym>
|
||||
<keysym keyval="40">parenleft</keysym>
|
||||
<keysym keyval="123">braceleft</keysym>
|
||||
</key>
|
||||
<key keycode="46" name="AC09">
|
||||
<keysym keyval="108">l</keysym>
|
||||
<keysym keyval="76">L</keysym>
|
||||
<keysym keyval="41">parenright</keysym>
|
||||
<keysym keyval="125">braceright</keysym>
|
||||
</key>
|
||||
<key keycode="47" name="AC10">
|
||||
<keysym keyval="59">semicolon</keysym>
|
||||
@ -181,55 +199,38 @@
|
||||
<keysym keyval="34">quotedbl</keysym>
|
||||
</key>
|
||||
<key keycode="36" name="RTRN">
|
||||
<keysym keyval="65293" icon="key-enter">Return</keysym>
|
||||
<keysym keyval="65293">Return</keysym>
|
||||
</key>
|
||||
<key keycode="50" name="LFSH">
|
||||
<keysym keyval="65505" icon="key-shift">Shift_L</keysym>
|
||||
<keysym keyval="65505" icon="key-shift">Shift_L</keysym>
|
||||
<keysym keyval="65505" label="=/+">Shift_L</keysym>
|
||||
<keysym keyval="65505" label="123">Shift_L</keysym>
|
||||
<keysym keyval="65505">Shift_L</keysym>
|
||||
</key>
|
||||
<key keycode="52" name="AB01">
|
||||
<keysym keyval="122">z</keysym>
|
||||
<keysym keyval="90">Z</keysym>
|
||||
<keysym keyval="44">comma</keysym>
|
||||
<keysym keyval="92">backslash</keysym>
|
||||
</key>
|
||||
<key keycode="53" name="AB02">
|
||||
<keysym keyval="120">x</keysym>
|
||||
<keysym keyval="88">X</keysym>
|
||||
<keysym keyval="34">quotedbl</keysym>
|
||||
<keysym keyval="47">slash</keysym>
|
||||
</key>
|
||||
<key keycode="54" name="AB03">
|
||||
<keysym keyval="99">c</keysym>
|
||||
<keysym keyval="67">C</keysym>
|
||||
<keysym keyval="39">quoteright</keysym>
|
||||
<keysym keyval="60">less</keysym>
|
||||
</key>
|
||||
<key keycode="55" name="AB04">
|
||||
<keysym keyval="118">v</keysym>
|
||||
<keysym keyval="86">V</keysym>
|
||||
<keysym keyval="58">colon</keysym>
|
||||
<keysym keyval="62">greater</keysym>
|
||||
</key>
|
||||
<key keycode="56" name="AB05">
|
||||
<keysym keyval="98">b</keysym>
|
||||
<keysym keyval="66">B</keysym>
|
||||
<keysym keyval="59">semicolon</keysym>
|
||||
<keysym keyval="61">equal</keysym>
|
||||
</key>
|
||||
<key keycode="57" name="AB06">
|
||||
<keysym keyval="110">n</keysym>
|
||||
<keysym keyval="78">N</keysym>
|
||||
<keysym keyval="33">exclam</keysym>
|
||||
<keysym keyval="91">bracketleft</keysym>
|
||||
</key>
|
||||
<key keycode="58" name="AB07">
|
||||
<keysym keyval="109">m</keysym>
|
||||
<keysym keyval="77">M</keysym>
|
||||
<keysym keyval="63">question</keysym>
|
||||
<keysym keyval="93">bracketright</keysym>
|
||||
</key>
|
||||
<key keycode="59" name="AB08">
|
||||
<keysym keyval="44">comma</keysym>
|
||||
@ -237,6 +238,7 @@
|
||||
</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>
|
||||
@ -249,7 +251,7 @@
|
||||
<symbol label="⌨" icon="input-keyboard-symbolic" tooltip="Change keyboard">cycle-keyboard</symbol>
|
||||
</key>
|
||||
<key keycode="150" name="I150">
|
||||
<symbol label="☺" icon="keyboard-mode-symbolic" tooltip="Setup">preferences</symbol>
|
||||
<symbol label="☺" icon="preferences-system-symbolic" tooltip="Setup">preferences</symbol>
|
||||
</key>
|
||||
<key keycode="37" name="LCTL">
|
||||
<keysym keyval="65507">Control_L</keysym>
|
||||
|
||||
@ -1,19 +0,0 @@
|
||||
gnome = import('gnome')
|
||||
|
||||
squeekboard_resources = gnome.compile_resources(
|
||||
'squeekboard-resources',
|
||||
'squeekboard.gresources.xml',
|
||||
|
||||
c_name: 'squeekboard',
|
||||
)
|
||||
|
||||
desktop_file = 'sm.puri.Squeekboard.desktop'
|
||||
|
||||
i18n.merge_file('desktop',
|
||||
input: desktop_file + '.in',
|
||||
output: desktop_file,
|
||||
po_dir: '../po',
|
||||
install: true,
|
||||
install_dir: join_paths(datadir, 'applications'),
|
||||
type: 'desktop'
|
||||
)
|
||||
60
data/org.fedorahosted.eekboard.gschema.xml.in
Normal file
@ -0,0 +1,60 @@
|
||||
<?xml version="1.0"?>
|
||||
<schemalist>
|
||||
<schema id="org.fedorahosted.eekboard" path="/org/fedorahosted/eekboard/">
|
||||
<key name="keyboards" type="as">
|
||||
<default>['us']</default>
|
||||
<summary>Keyboard types</summary>
|
||||
<description>keyboard types.</description>
|
||||
</key>
|
||||
<key name="focus-listener" type="s">
|
||||
<default>'atspi'</default>
|
||||
<summary>Use the given focus listener</summary>
|
||||
<description>The name of the focus listener (either 'atspi' or 'ibus') used to detect focus events.</description>
|
||||
</key>
|
||||
<key name="auto-hide" type="b">
|
||||
<default>true</default>
|
||||
<summary>Hide keyboard automatically when focus is out</summary>
|
||||
<description>If true, hide keyboard automatically when focus is out.</description>
|
||||
</key>
|
||||
<key name="auto-hide-delay" type="u">
|
||||
<default>500</default>
|
||||
<summary>Delay before hiding keyboard</summary>
|
||||
<description>Delay before hiding keyboard in milliseconds. This is useful when focus listener is enabled.</description>
|
||||
</key>
|
||||
<key type="b" name="repeat">
|
||||
<default>true</default>
|
||||
<summary>Key repeat</summary>
|
||||
<description>Generate key-press/release event repeatedly while a key is held down</description>
|
||||
</key>
|
||||
<key type="u" name="repeat-interval">
|
||||
<default>100</default>
|
||||
<summary>Key repeat interval</summary>
|
||||
<description>Delay between repeats in milliseconds.</description>
|
||||
</key>
|
||||
<key type="u" name="repeat-delay">
|
||||
<default>1000</default>
|
||||
<summary>Initial key repeat delay</summary>
|
||||
<description>Initial key repeat delay in milliseconds.</description>
|
||||
</key>
|
||||
<key name="start-fullscreen" type="b">
|
||||
<default>false</default>
|
||||
<summary>Switch to fullscreen mode when startup</summary>
|
||||
<description>If true, switch to fullscreen mode when startup.</description>
|
||||
</key>
|
||||
<key name="size-constraint-landscape" type="(dd)">
|
||||
<default>(1.0, 0.3)</default>
|
||||
<summary>Constraint of the maximum window size on landscape screen</summary>
|
||||
<description>Constraint of maximum window size on landscape screen</description>
|
||||
</key>
|
||||
<key name="size-constraint-portrait" type="(dd)">
|
||||
<default>(1.0, 0.5)</default>
|
||||
<summary>Constraint of the maximum window size on portrait screen</summary>
|
||||
<description>Constraint of maximum window size on portrait screen</description>
|
||||
</key>
|
||||
<key name="theme" type="s">
|
||||
<default>'default'</default>
|
||||
<summary>Theme</summary>
|
||||
<description>Base name of the theme to apply.</description>
|
||||
</key>
|
||||
</schema>
|
||||
</schemalist>
|
||||
@ -1,9 +0,0 @@
|
||||
[Desktop Entry]
|
||||
Name=Squeekboard
|
||||
GenericName=Squeekboard Virtual Keyboard
|
||||
Comment=Virtual Keyboard
|
||||
Exec=squeekboard
|
||||
Icon=squeekboard
|
||||
Terminal=false
|
||||
Type=Application
|
||||
Categories=GTK;Utility;
|
||||
@ -1,39 +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/keyboards.xml</file>
|
||||
<file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/ar.xml</file>
|
||||
<file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/as-inscript.xml</file>
|
||||
<file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/be.xml</file>
|
||||
<file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/bn-inscript.xml</file>
|
||||
<file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/fa.xml</file>
|
||||
<file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/gu-inscript.xml</file>
|
||||
<file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/he.xml</file>
|
||||
<file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/hi-inscript.xml</file>
|
||||
<file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/ja-kana.xml</file>
|
||||
<file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/kk.xml</file>
|
||||
<file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/kn-inscript.xml</file>
|
||||
<file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/ks-inscript.xml</file>
|
||||
<file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/ks.xml</file>
|
||||
<file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/mai-inscript.xml</file>
|
||||
<file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/ml-inscript.xml</file>
|
||||
<file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/mr-inscript.xml</file>
|
||||
<file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/my.xml</file>
|
||||
<file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/or-inscript.xml</file>
|
||||
<file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/pa-inscript.xml</file>
|
||||
<file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/ru.xml</file>
|
||||
<file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/sd-inscript.xml</file>
|
||||
<file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/ta-inscript.xml</file>
|
||||
<file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/te-inscript.xml</file>
|
||||
<file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/th.xml</file>
|
||||
<file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/ua.xml</file>
|
||||
<file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/ug.xml</file>
|
||||
<file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/us.xml</file>
|
||||
<file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/zh-bopomofo.xml</file>
|
||||
<file>icons/key-enter.svg</file>
|
||||
<file>icons/key-shift.svg</file>
|
||||
<file>icons/keyboard-mode-symbolic.svg</file>
|
||||
</gresource>
|
||||
</gresources>
|
||||
@ -1,18 +0,0 @@
|
||||
.keyboard {
|
||||
background-color: rgba(0, 0, 0, 255);
|
||||
color: #ffffff;
|
||||
font-family: cantarell, sans-serif;
|
||||
}
|
||||
|
||||
.key {
|
||||
color: #deddda;
|
||||
background: #464448;
|
||||
border-width: 0.5px;
|
||||
border-color: #5e5c64;
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
.key:active {
|
||||
background: #1c71d8;
|
||||
border-color: #3584e4;
|
||||
}
|
||||
4
data/themes/Makefile.am
Normal file
@ -0,0 +1,4 @@
|
||||
themedir = $(pkgdatadir)/themes
|
||||
dist_theme_DATA = default.css
|
||||
|
||||
-include $(top_srcdir)/git.mk
|
||||
22
data/themes/default.css
Normal file
@ -0,0 +1,22 @@
|
||||
.keyboard {
|
||||
background-color: rgba(0, 0, 0, 255);
|
||||
color: #ffffff;
|
||||
font-family: cantarell, sans-serif;
|
||||
}
|
||||
|
||||
.key {
|
||||
color: #ffffff;
|
||||
background-gradient-direction: vertical;
|
||||
background-gradient-start: rgba(0, 0, 0, 255);
|
||||
background-gradient-end: rgba(64, 64, 64, 255);
|
||||
border-width: 2px;
|
||||
border-color: rgba(128, 128, 128, 255);
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
.key:active {
|
||||
background-gradient-direction: vertical;
|
||||
background-gradient-start: rgba(0, 0, 255, 255);
|
||||
background-gradient-end: rgba(64, 64, 255, 255);
|
||||
border-color: rgba(160, 160, 255, 255);
|
||||
}
|
||||
11
debian/changelog
vendored
@ -1,11 +0,0 @@
|
||||
squeekboard (1.0.10) unstable; urgency=medium
|
||||
|
||||
* Use a shared DBus definition
|
||||
|
||||
-- Dorota Czaplejewicz <dorota.czaplejewicz@puri.sm> Tue, 02 Jul 2019 20:12:02 +0000
|
||||
|
||||
squeekboard (1.0.9) unstable; urgency=medium
|
||||
|
||||
* Initial release.
|
||||
|
||||
-- David Boddie <david.boddie@puri.sm> Tue, 25 Jun 2019 19:33:00 +0200
|
||||
1
debian/compat
vendored
@ -1 +0,0 @@
|
||||
10
|
||||
24
debian/control
vendored
@ -1,24 +0,0 @@
|
||||
Source: squeekboard
|
||||
Section: x11
|
||||
Priority: optional
|
||||
Maintainer: Dorota Czaplejewicz <dorota.czaplejewicz@puri.sm>
|
||||
Build-Depends:
|
||||
debhelper (>= 10),
|
||||
meson (>=0.43.0),
|
||||
pkg-config,
|
||||
libglib2.0-dev,
|
||||
libgtk-3-dev,
|
||||
libcroco3-dev,
|
||||
libwayland-dev (>= 1.16),
|
||||
rustc,
|
||||
wayland-protocols (>= 1.14)
|
||||
Standards-Version: 4.1.3
|
||||
Homepage: https://source.puri.sm/Librem5/squeekboard
|
||||
|
||||
Package: squeekboard
|
||||
Architecture: linux-any
|
||||
Depends:
|
||||
${shlibs:Depends}
|
||||
${misc:Depends}
|
||||
Description: On-screen keyboard for Wayland
|
||||
Virtual keyboard supporting Wayland, built primarily for the Librem 5 phone.
|
||||
73
debian/copyright
vendored
@ -1,73 +0,0 @@
|
||||
Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
|
||||
Upstream-Name: evscript
|
||||
Source: https://source.puri.sm/david.boddie/evscript
|
||||
|
||||
Files: *
|
||||
Copyright: 2010-2011 Daiki Ueno <ueno@unixuser.org>
|
||||
2010-2011 Red Hat, Inc.
|
||||
2019 Purism SPC
|
||||
License: GPL-3+
|
||||
|
||||
Files: eek/layersurface.c
|
||||
src/wayland.c
|
||||
src/key-emitter.c
|
||||
meson.build
|
||||
src/meson.build
|
||||
po/meson.build
|
||||
Copyright: 2018-2019 Purism SPC
|
||||
License: GPL-3+
|
||||
|
||||
Files: eekboard/keymap.c
|
||||
Copyright: 2000 Red Hat, Inc.
|
||||
2019 Purism, SPC
|
||||
License: LGPL-2+
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Files: protocols/wlr-layer-shell-unstable-v1.xml
|
||||
Copytight: Copyright © 2017 Drew DeVault
|
||||
License: X11
|
||||
Permission to use, copy, modify, distribute, and sell this software and
|
||||
its documentation for any purpose is hereby granted without fee, provided
|
||||
that the above copyright notice appear in all copies and fthat both that
|
||||
copyright notice and this permission notice appear in supporting
|
||||
documentation, and that the name of the copyright holders not be used in
|
||||
advertising or publicity pertaining to distribution of the software
|
||||
without specific, written prior permission. The copyright holders make
|
||||
no representations about the suitability of this software for any
|
||||
purpose. It is provided "as is" without express or implied warranty.
|
||||
.
|
||||
THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
|
||||
SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
|
||||
RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
|
||||
CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
License: GPL-3+
|
||||
This package is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
.
|
||||
This package is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
.
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>
|
||||
.
|
||||
On Debian systems, the complete text of the GNU General
|
||||
Public License version 3 can be found in "/usr/share/common-licenses/GPL-3".
|
||||
8
debian/rules
vendored
@ -1,8 +0,0 @@
|
||||
#!/usr/bin/make -f
|
||||
|
||||
export DEB_BUILD_MAINT_OPTIONS = hardening=+all
|
||||
|
||||
%:
|
||||
dh $@ --builddirectory=_build --buildsystem=meson
|
||||
|
||||
override_dh_autoreconf:
|
||||
1
debian/source/format
vendored
@ -1 +0,0 @@
|
||||
3.0 (native)
|
||||
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
|
||||
@ -40,19 +40,23 @@ enum {
|
||||
|
||||
static guint signals[LAST_SIGNAL] = { 0, };
|
||||
|
||||
typedef struct _EekContainerPrivate
|
||||
G_DEFINE_ABSTRACT_TYPE (EekContainer, eek_container, EEK_TYPE_ELEMENT);
|
||||
|
||||
#define EEK_CONTAINER_GET_PRIVATE(obj) \
|
||||
(G_TYPE_INSTANCE_GET_PRIVATE ((obj), EEK_TYPE_CONTAINER, EekContainerPrivate))
|
||||
|
||||
|
||||
struct _EekContainerPrivate
|
||||
{
|
||||
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);
|
||||
EekContainerPrivate *priv = EEK_CONTAINER_GET_PRIVATE(self);
|
||||
|
||||
g_return_if_fail (EEK_IS_ELEMENT(child));
|
||||
g_object_ref (child);
|
||||
@ -71,7 +75,7 @@ static void
|
||||
eek_container_real_remove_child (EekContainer *self,
|
||||
EekElement *child)
|
||||
{
|
||||
EekContainerPrivate *priv = eek_container_get_instance_private (self);
|
||||
EekContainerPrivate *priv = EEK_CONTAINER_GET_PRIVATE(self);
|
||||
GList *head;
|
||||
|
||||
g_return_if_fail (EEK_IS_ELEMENT(child));
|
||||
@ -90,7 +94,7 @@ eek_container_real_foreach_child (EekContainer *self,
|
||||
EekCallback callback,
|
||||
gpointer user_data)
|
||||
{
|
||||
EekContainerPrivate *priv = eek_container_get_instance_private (self);
|
||||
EekContainerPrivate *priv = EEK_CONTAINER_GET_PRIVATE(self);
|
||||
GList *head;
|
||||
|
||||
for (head = priv->head; head; head = g_list_next (head))
|
||||
@ -102,7 +106,7 @@ eek_container_real_find (EekContainer *self,
|
||||
EekCompareFunc func,
|
||||
gpointer user_data)
|
||||
{
|
||||
EekContainerPrivate *priv = eek_container_get_instance_private (self);
|
||||
EekContainerPrivate *priv = EEK_CONTAINER_GET_PRIVATE(self);
|
||||
GList *head;
|
||||
|
||||
head = g_list_find_custom (priv->head, user_data, (GCompareFunc)func);
|
||||
@ -114,8 +118,7 @@ eek_container_real_find (EekContainer *self,
|
||||
static void
|
||||
eek_container_dispose (GObject *object)
|
||||
{
|
||||
EekContainer *self = EEK_CONTAINER (object);
|
||||
EekContainerPrivate *priv = eek_container_get_instance_private (self);
|
||||
EekContainerPrivate *priv = EEK_CONTAINER_GET_PRIVATE(object);
|
||||
GList *head;
|
||||
|
||||
for (head = priv->head; head; head = priv->head) {
|
||||
@ -131,6 +134,9 @@ eek_container_class_init (EekContainerClass *klass)
|
||||
{
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
g_type_class_add_private (gobject_class,
|
||||
sizeof (EekContainerPrivate));
|
||||
|
||||
klass->add_child = eek_container_real_add_child;
|
||||
klass->remove_child = eek_container_real_remove_child;
|
||||
klass->foreach_child = eek_container_real_foreach_child;
|
||||
@ -183,7 +189,7 @@ eek_container_class_init (EekContainerClass *klass)
|
||||
static void
|
||||
eek_container_init (EekContainer *self)
|
||||
{
|
||||
/* void */
|
||||
self->priv = EEK_CONTAINER_GET_PRIVATE(self);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -30,7 +30,14 @@
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define EEK_TYPE_CONTAINER (eek_container_get_type())
|
||||
G_DECLARE_DERIVABLE_TYPE (EekContainer, eek_container, EEK, CONTAINER, EekElement)
|
||||
#define EEK_CONTAINER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EEK_TYPE_CONTAINER, EekContainer))
|
||||
#define EEK_CONTAINER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EEK_TYPE_CONTAINER, EekContainerClass))
|
||||
#define EEK_IS_CONTAINER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EEK_TYPE_CONTAINER))
|
||||
#define EEK_IS_CONTAINER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EEK_TYPE_CONTAINER))
|
||||
#define EEK_CONTAINER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EEK_TYPE_CONTAINER, EekContainerClass))
|
||||
|
||||
typedef struct _EekContainerClass EekContainerClass;
|
||||
typedef struct _EekContainerPrivate EekContainerPrivate;
|
||||
|
||||
/**
|
||||
* EekCallback:
|
||||
@ -43,6 +50,14 @@ G_DECLARE_DERIVABLE_TYPE (EekContainer, eek_container, EEK, CONTAINER, EekElemen
|
||||
typedef void (*EekCallback) (EekElement *element, gpointer user_data);
|
||||
typedef gint (*EekCompareFunc) (EekElement *element, gpointer user_data);
|
||||
|
||||
struct _EekContainer
|
||||
{
|
||||
/*< private >*/
|
||||
EekElement parent;
|
||||
|
||||
EekContainerPrivate *priv;
|
||||
};
|
||||
|
||||
/**
|
||||
* EekContainerClass:
|
||||
* @foreach_child: virtual function for iterating over the container's children
|
||||
|
||||
@ -52,16 +52,20 @@ enum {
|
||||
|
||||
static guint signals[LAST_SIGNAL] = { 0, };
|
||||
|
||||
typedef struct _EekElementPrivate
|
||||
G_DEFINE_ABSTRACT_TYPE (EekElement, eek_element, G_TYPE_OBJECT);
|
||||
|
||||
#define EEK_ELEMENT_GET_PRIVATE(obj) \
|
||||
(G_TYPE_INSTANCE_GET_PRIVATE ((obj), EEK_TYPE_ELEMENT, EekElementPrivate))
|
||||
|
||||
|
||||
struct _EekElementPrivate
|
||||
{
|
||||
gchar *name;
|
||||
EekBounds bounds;
|
||||
EekElement *parent;
|
||||
gint group;
|
||||
gint level;
|
||||
} EekElementPrivate;
|
||||
|
||||
G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (EekElement, eek_element, G_TYPE_OBJECT)
|
||||
};
|
||||
|
||||
static void
|
||||
eek_element_real_symbol_index_changed (EekElement *self,
|
||||
@ -74,8 +78,7 @@ eek_element_real_symbol_index_changed (EekElement *self,
|
||||
static void
|
||||
eek_element_finalize (GObject *object)
|
||||
{
|
||||
EekElement *self = EEK_ELEMENT (object);
|
||||
EekElementPrivate *priv = eek_element_get_instance_private (self);
|
||||
EekElementPrivate *priv = EEK_ELEMENT_GET_PRIVATE(object);
|
||||
|
||||
g_free (priv->name);
|
||||
G_OBJECT_CLASS (eek_element_parent_class)->finalize (object);
|
||||
@ -143,6 +146,9 @@ eek_element_class_init (EekElementClass *klass)
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||
GParamSpec *pspec;
|
||||
|
||||
g_type_class_add_private (gobject_class,
|
||||
sizeof (EekElementPrivate));
|
||||
|
||||
/* signals */
|
||||
klass->symbol_index_changed = eek_element_real_symbol_index_changed;
|
||||
|
||||
@ -232,8 +238,9 @@ eek_element_class_init (EekElementClass *klass)
|
||||
static void
|
||||
eek_element_init (EekElement *self)
|
||||
{
|
||||
EekElementPrivate *priv = eek_element_get_instance_private (self);
|
||||
EekElementPrivate *priv;
|
||||
|
||||
priv = self->priv = EEK_ELEMENT_GET_PRIVATE(self);
|
||||
priv->group = -1;
|
||||
priv->level = -1;
|
||||
}
|
||||
@ -252,12 +259,10 @@ eek_element_set_parent (EekElement *element,
|
||||
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)
|
||||
if (element->priv->parent == parent)
|
||||
return;
|
||||
|
||||
if (priv->parent != NULL) {
|
||||
if (element->priv->parent != NULL) {
|
||||
/* release self-reference acquired when setting parent */
|
||||
g_object_unref (element);
|
||||
}
|
||||
@ -266,7 +271,7 @@ eek_element_set_parent (EekElement *element,
|
||||
g_object_ref (element);
|
||||
}
|
||||
|
||||
priv->parent = parent;
|
||||
element->priv->parent = parent;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -280,10 +285,7 @@ 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;
|
||||
return element->priv->parent;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -298,11 +300,8 @@ 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);
|
||||
g_free (element->priv->name);
|
||||
element->priv->name = g_strdup (name);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -316,10 +315,7 @@ 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;
|
||||
return element->priv->name;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -336,10 +332,7 @@ eek_element_set_bounds (EekElement *element,
|
||||
EekBounds *bounds)
|
||||
{
|
||||
g_return_if_fail (EEK_IS_ELEMENT(element));
|
||||
|
||||
EekElementPrivate *priv = eek_element_get_instance_private (element);
|
||||
|
||||
memcpy (&priv->bounds, bounds, sizeof(EekBounds));
|
||||
memcpy (&element->priv->bounds, bounds, sizeof(EekBounds));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -357,10 +350,7 @@ eek_element_get_bounds (EekElement *element,
|
||||
{
|
||||
g_return_if_fail (EEK_IS_ELEMENT(element));
|
||||
g_return_if_fail (bounds != NULL);
|
||||
|
||||
EekElementPrivate *priv = eek_element_get_instance_private (element);
|
||||
|
||||
memcpy (bounds, &priv->bounds, sizeof(EekBounds));
|
||||
memcpy (bounds, &element->priv->bounds, sizeof(EekBounds));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -496,14 +486,11 @@ 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;
|
||||
if (element->priv->group != group) {
|
||||
element->priv->group = group;
|
||||
g_object_notify (G_OBJECT(element), "group");
|
||||
g_signal_emit (element, signals[SYMBOL_INDEX_CHANGED], 0,
|
||||
group, priv->level);
|
||||
group, element->priv->level);
|
||||
}
|
||||
}
|
||||
|
||||
@ -522,14 +509,11 @@ 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;
|
||||
if (element->priv->level != level) {
|
||||
element->priv->level = level;
|
||||
g_object_notify (G_OBJECT(element), "level");
|
||||
g_signal_emit (element, signals[SYMBOL_INDEX_CHANGED], 0,
|
||||
priv->group, level);
|
||||
element->priv->group, level);
|
||||
}
|
||||
}
|
||||
|
||||
@ -546,10 +530,7 @@ 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;
|
||||
return element->priv->group;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -565,8 +546,5 @@ 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;
|
||||
return element->priv->level;
|
||||
}
|
||||
|
||||
@ -30,7 +30,22 @@
|
||||
|
||||
G_BEGIN_DECLS
|
||||
#define EEK_TYPE_ELEMENT (eek_element_get_type())
|
||||
G_DECLARE_DERIVABLE_TYPE (EekElement, eek_element, EEK, ELEMENT, GObject)
|
||||
#define EEK_ELEMENT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EEK_TYPE_ELEMENT, EekElement))
|
||||
#define EEK_ELEMENT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EEK_TYPE_ELEMENT, EekElementClass))
|
||||
#define EEK_IS_ELEMENT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EEK_TYPE_ELEMENT))
|
||||
#define EEK_IS_ELEMENT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EEK_TYPE_ELEMENT))
|
||||
#define EEK_ELEMENT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EEK_TYPE_ELEMENT, EekElementClass))
|
||||
|
||||
typedef struct _EekElementClass EekElementClass;
|
||||
typedef struct _EekElementPrivate EekElementPrivate;
|
||||
|
||||
struct _EekElement
|
||||
{
|
||||
/*< private >*/
|
||||
GObject parent;
|
||||
|
||||
EekElementPrivate *priv;
|
||||
};
|
||||
|
||||
struct _EekElementClass
|
||||
{
|
||||
|
||||
@ -23,13 +23,14 @@
|
||||
* @short_description: a #GtkWidget displaying #EekKeyboard
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
|
||||
#ifdef HAVE_GSOUND
|
||||
#include <gsound.h>
|
||||
#ifdef HAVE_LIBCANBERRA
|
||||
#include <canberra-gtk.h>
|
||||
#endif
|
||||
|
||||
#include <math.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "eek-gtk-keyboard.h"
|
||||
@ -45,36 +46,46 @@ enum {
|
||||
PROP_LAST
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (EekGtkKeyboard, eek_gtk_keyboard, GTK_TYPE_DRAWING_AREA);
|
||||
|
||||
#define EEK_GTK_KEYBOARD_GET_PRIVATE(obj) \
|
||||
(G_TYPE_INSTANCE_GET_PRIVATE ((obj), EEK_TYPE_GTK_KEYBOARD, EekGtkKeyboardPrivate))
|
||||
|
||||
/* since 2.91.5 GDK_DRAWABLE was removed and gdk_cairo_create takes
|
||||
GdkWindow as the argument */
|
||||
#ifndef GDK_DRAWABLE
|
||||
#define GDK_DRAWABLE(x) (x)
|
||||
#endif
|
||||
|
||||
typedef struct _EekGtkKeyboardPrivate
|
||||
struct _EekGtkKeyboardPrivate
|
||||
{
|
||||
EekRenderer *renderer;
|
||||
EekKeyboard *keyboard;
|
||||
gulong key_pressed_handler;
|
||||
gulong key_released_handler;
|
||||
gulong key_locked_handler;
|
||||
gulong key_unlocked_handler;
|
||||
gulong key_cancelled_handler;
|
||||
gulong symbol_index_changed_handler;
|
||||
EekTheme *theme;
|
||||
#ifdef HAVE_GSOUND
|
||||
GSoundContext *sound_ctx;
|
||||
#endif
|
||||
};
|
||||
|
||||
GdkEventSequence *sequence; // unowned reference
|
||||
} EekGtkKeyboardPrivate;
|
||||
|
||||
G_DEFINE_TYPE_WITH_PRIVATE (EekGtkKeyboard, eek_gtk_keyboard, GTK_TYPE_DRAWING_AREA)
|
||||
|
||||
static void on_key_pressed (EekKey *key,
|
||||
EekGtkKeyboard *self);
|
||||
static void on_key_released (EekKey *key,
|
||||
EekGtkKeyboard *self);
|
||||
static EekColor * color_from_gdk_color (GdkColor *gdk_color);
|
||||
static void on_key_pressed (EekKeyboard *keyboard,
|
||||
EekKey *key,
|
||||
gpointer user_data);
|
||||
static void on_key_released (EekKeyboard *keyboard,
|
||||
EekKey *key,
|
||||
gpointer user_data);
|
||||
static void on_key_locked (EekKeyboard *keyboard,
|
||||
EekKey *key,
|
||||
gpointer user_data);
|
||||
static void on_key_unlocked (EekKeyboard *keyboard,
|
||||
EekKey *key,
|
||||
gpointer user_data);
|
||||
static void on_key_cancelled (EekKeyboard *keyboard,
|
||||
EekKey *key,
|
||||
gpointer user_data);
|
||||
static void on_symbol_index_changed (EekKeyboard *keyboard,
|
||||
gint group,
|
||||
gint level,
|
||||
@ -89,6 +100,7 @@ static void render_released_key (GtkWidget *widget,
|
||||
static void
|
||||
eek_gtk_keyboard_real_realize (GtkWidget *self)
|
||||
{
|
||||
gtk_widget_set_double_buffered (self, FALSE);
|
||||
gtk_widget_set_events (self,
|
||||
GDK_EXPOSURE_MASK |
|
||||
GDK_KEY_PRESS_MASK |
|
||||
@ -104,15 +116,18 @@ static gboolean
|
||||
eek_gtk_keyboard_real_draw (GtkWidget *self,
|
||||
cairo_t *cr)
|
||||
{
|
||||
EekGtkKeyboardPrivate *priv =
|
||||
eek_gtk_keyboard_get_instance_private (EEK_GTK_KEYBOARD (self));
|
||||
EekGtkKeyboardPrivate *priv = EEK_GTK_KEYBOARD_GET_PRIVATE(self);
|
||||
GtkAllocation allocation;
|
||||
EekColor background;
|
||||
GList *list, *head;
|
||||
|
||||
gtk_widget_get_allocation (self, &allocation);
|
||||
|
||||
if (!priv->renderer) {
|
||||
GtkStyle *style;
|
||||
GtkStateType state;
|
||||
PangoContext *pcontext;
|
||||
EekColor *color;
|
||||
|
||||
pcontext = gtk_widget_get_pango_context (self);
|
||||
priv->renderer = eek_gtk_renderer_new (priv->keyboard, pcontext, self);
|
||||
@ -122,10 +137,30 @@ eek_gtk_keyboard_real_draw (GtkWidget *self,
|
||||
eek_renderer_set_allocation_size (priv->renderer,
|
||||
allocation.width,
|
||||
allocation.height);
|
||||
eek_renderer_set_scale_factor (priv->renderer,
|
||||
gtk_widget_get_scale_factor (self));
|
||||
|
||||
style = gtk_widget_get_style (self);
|
||||
state = gtk_widget_get_state (self);
|
||||
|
||||
color = color_from_gdk_color (&style->text[state]);
|
||||
eek_renderer_set_default_foreground_color (priv->renderer, color);
|
||||
eek_color_free (color);
|
||||
|
||||
color = color_from_gdk_color (&style->base[state]);
|
||||
eek_renderer_set_default_background_color (priv->renderer, color);
|
||||
eek_color_free (color);
|
||||
}
|
||||
|
||||
/* blank background */
|
||||
eek_renderer_get_background_color (priv->renderer,
|
||||
EEK_ELEMENT(priv->keyboard),
|
||||
&background);
|
||||
cairo_set_source_rgba (cr,
|
||||
background.red,
|
||||
background.green,
|
||||
background.blue,
|
||||
background.alpha);
|
||||
cairo_paint (cr);
|
||||
|
||||
eek_renderer_render_keyboard (priv->renderer, cr);
|
||||
|
||||
/* redraw pressed key */
|
||||
@ -149,8 +184,7 @@ static void
|
||||
eek_gtk_keyboard_real_size_allocate (GtkWidget *self,
|
||||
GtkAllocation *allocation)
|
||||
{
|
||||
EekGtkKeyboardPrivate *priv =
|
||||
eek_gtk_keyboard_get_instance_private (EEK_GTK_KEYBOARD (self));
|
||||
EekGtkKeyboardPrivate *priv = EEK_GTK_KEYBOARD_GET_PRIVATE(self);
|
||||
|
||||
if (priv->renderer)
|
||||
eek_renderer_set_allocation_size (priv->renderer,
|
||||
@ -161,21 +195,49 @@ eek_gtk_keyboard_real_size_allocate (GtkWidget *self,
|
||||
size_allocate (self, allocation);
|
||||
}
|
||||
|
||||
static void depress(EekGtkKeyboard *self,
|
||||
gdouble x, gdouble y, guint32 time) {
|
||||
EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (self);
|
||||
EekKey *key = eek_renderer_find_key_by_position (priv->renderer, x, y);
|
||||
if (key) {
|
||||
eek_keyboard_press_key(priv->keyboard, key, time);
|
||||
on_key_pressed(key, self);
|
||||
}
|
||||
static gboolean
|
||||
eek_gtk_keyboard_real_button_press_event (GtkWidget *self,
|
||||
GdkEventButton *event)
|
||||
{
|
||||
EekGtkKeyboardPrivate *priv = EEK_GTK_KEYBOARD_GET_PRIVATE(self);
|
||||
EekKey *key;
|
||||
|
||||
key = eek_renderer_find_key_by_position (priv->renderer,
|
||||
(gdouble)event->x,
|
||||
(gdouble)event->y);
|
||||
if (key)
|
||||
g_signal_emit_by_name (key, "pressed", priv->keyboard);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void drag(EekGtkKeyboard *self,
|
||||
gdouble x, gdouble y, guint32 time) {
|
||||
EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (self);
|
||||
EekKey *key = eek_renderer_find_key_by_position (priv->renderer, x, y);
|
||||
static gboolean
|
||||
eek_gtk_keyboard_real_button_release_event (GtkWidget *self,
|
||||
GdkEventButton *event)
|
||||
{
|
||||
EekGtkKeyboardPrivate *priv = EEK_GTK_KEYBOARD_GET_PRIVATE(self);
|
||||
GList *list, *head;
|
||||
|
||||
list = eek_keyboard_get_pressed_keys (priv->keyboard);
|
||||
for (head = list; head; head = g_list_next (head))
|
||||
g_signal_emit_by_name (head->data, "released", priv->keyboard);
|
||||
g_list_free (list);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
eek_gtk_keyboard_real_motion_notify_event (GtkWidget *self,
|
||||
GdkEventMotion *event)
|
||||
{
|
||||
EekGtkKeyboardPrivate *priv = EEK_GTK_KEYBOARD_GET_PRIVATE(self);
|
||||
EekKey *key;
|
||||
|
||||
if (event->state == 0)
|
||||
return FALSE;
|
||||
|
||||
key = eek_renderer_find_key_by_position (priv->renderer,
|
||||
(gdouble)event->x,
|
||||
(gdouble)event->y);
|
||||
if (key) {
|
||||
GList *list, *head;
|
||||
gboolean found = FALSE;
|
||||
@ -184,93 +246,13 @@ static void drag(EekGtkKeyboard *self,
|
||||
for (head = list; head; head = g_list_next (head)) {
|
||||
if (head->data == key)
|
||||
found = TRUE;
|
||||
else {
|
||||
eek_keyboard_release_key(priv->keyboard, EEK_KEY(head->data), time);
|
||||
on_key_released(key, self);
|
||||
}
|
||||
else
|
||||
g_signal_emit_by_name (head->data, "cancelled", priv->keyboard);
|
||||
}
|
||||
g_list_free (list);
|
||||
|
||||
if (!found) {
|
||||
eek_keyboard_press_key(priv->keyboard, key, time);
|
||||
on_key_pressed(key, self);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void release(EekGtkKeyboard *self, guint32 time) {
|
||||
EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (self);
|
||||
|
||||
GList *list = eek_keyboard_get_pressed_keys (priv->keyboard);
|
||||
for (GList *head = list; head; head = g_list_next (head)) {
|
||||
EekKey *key = EEK_KEY(head->data);
|
||||
eek_keyboard_release_key(priv->keyboard, key, time);
|
||||
on_key_released(key, self);
|
||||
}
|
||||
g_list_free (list);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
eek_gtk_keyboard_real_button_press_event (GtkWidget *self,
|
||||
GdkEventButton *event)
|
||||
{
|
||||
if (event->type == GDK_BUTTON_PRESS && event->button == 1) {
|
||||
depress(EEK_GTK_KEYBOARD(self), event->x, event->y, event->time);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// TODO: this belongs more in gtk_keyboard, with a way to find out which key to re-render
|
||||
static gboolean
|
||||
eek_gtk_keyboard_real_button_release_event (GtkWidget *self,
|
||||
GdkEventButton *event)
|
||||
{
|
||||
if (event->type == GDK_BUTTON_RELEASE && event->button == 1) {
|
||||
// TODO: can the event have different coords than the previous move event?
|
||||
release(EEK_GTK_KEYBOARD(self), event->time);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
eek_gtk_keyboard_real_motion_notify_event (GtkWidget *self,
|
||||
GdkEventMotion *event)
|
||||
{
|
||||
if (event->state & GDK_BUTTON1_MASK) {
|
||||
drag(EEK_GTK_KEYBOARD(self), event->x, event->y, event->time);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// Only one touch stream at a time allowed. Others will be completely ignored.
|
||||
static gboolean
|
||||
handle_touch_event (GtkWidget *widget,
|
||||
GdkEventTouch *event)
|
||||
{
|
||||
EekGtkKeyboard *self = EEK_GTK_KEYBOARD (widget);
|
||||
EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (self);
|
||||
|
||||
if (event->type == GDK_TOUCH_BEGIN) {
|
||||
if (priv->sequence) {
|
||||
// Ignore second and following touch points
|
||||
return FALSE;
|
||||
}
|
||||
priv->sequence = event->sequence;
|
||||
depress(self, event->x, event->y, event->time);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (priv->sequence != event->sequence) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (event->type == GDK_TOUCH_UPDATE) {
|
||||
drag(self, event->x, event->y, event->time);
|
||||
}
|
||||
if (event->type == GDK_TOUCH_END || event->type == GDK_TOUCH_CANCEL) {
|
||||
// TODO: can the event have different coords than the previous update event?
|
||||
release(self, event->time);
|
||||
priv->sequence = NULL;
|
||||
if (!found)
|
||||
g_signal_emit_by_name (key, "pressed", priv->keyboard);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
@ -278,8 +260,7 @@ handle_touch_event (GtkWidget *widget,
|
||||
static void
|
||||
eek_gtk_keyboard_real_unmap (GtkWidget *self)
|
||||
{
|
||||
EekGtkKeyboardPrivate *priv =
|
||||
eek_gtk_keyboard_get_instance_private (EEK_GTK_KEYBOARD (self));
|
||||
EekGtkKeyboardPrivate *priv = EEK_GTK_KEYBOARD_GET_PRIVATE(self);
|
||||
|
||||
if (priv->keyboard) {
|
||||
GList *list, *head;
|
||||
@ -289,10 +270,8 @@ eek_gtk_keyboard_real_unmap (GtkWidget *self)
|
||||
EekKeyboard::key-released signal can remove elements from its
|
||||
internal copy */
|
||||
list = eek_keyboard_get_pressed_keys (priv->keyboard);
|
||||
for (head = list; head; head = g_list_next (head)) {
|
||||
g_log("squeek", G_LOG_LEVEL_DEBUG, "emit EekKey released");
|
||||
g_signal_emit_by_name (head->data, "released");
|
||||
}
|
||||
for (head = list; head; head = g_list_next (head))
|
||||
g_signal_emit_by_name (head->data, "released", priv->keyboard);
|
||||
g_list_free (list);
|
||||
}
|
||||
|
||||
@ -306,9 +285,7 @@ eek_gtk_keyboard_real_query_tooltip (GtkWidget *widget,
|
||||
gboolean keyboard_tooltip,
|
||||
GtkTooltip *tooltip)
|
||||
{
|
||||
EekGtkKeyboard *self = EEK_GTK_KEYBOARD (widget);
|
||||
EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (self);
|
||||
|
||||
EekGtkKeyboardPrivate *priv = EEK_GTK_KEYBOARD_GET_PRIVATE(widget);
|
||||
EekKey *key;
|
||||
|
||||
key = eek_renderer_find_key_by_position (priv->renderer,
|
||||
@ -329,22 +306,25 @@ static void
|
||||
eek_gtk_keyboard_set_keyboard (EekGtkKeyboard *self,
|
||||
EekKeyboard *keyboard)
|
||||
{
|
||||
EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (self);
|
||||
|
||||
if (priv->keyboard == keyboard)
|
||||
return;
|
||||
|
||||
if (priv->keyboard) {
|
||||
g_signal_handlers_disconnect_by_data(priv->keyboard, self);
|
||||
g_object_unref (priv->keyboard);
|
||||
}
|
||||
|
||||
EekGtkKeyboardPrivate *priv = EEK_GTK_KEYBOARD_GET_PRIVATE(self);
|
||||
priv->keyboard = g_object_ref (keyboard);
|
||||
|
||||
priv->key_pressed_handler =
|
||||
g_signal_connect (priv->keyboard, "key-pressed",
|
||||
G_CALLBACK(on_key_pressed), self);
|
||||
priv->key_released_handler =
|
||||
g_signal_connect (priv->keyboard, "key-released",
|
||||
G_CALLBACK(on_key_released), self);
|
||||
priv->key_locked_handler =
|
||||
g_signal_connect (priv->keyboard, "key-locked",
|
||||
G_CALLBACK(on_key_locked), self);
|
||||
priv->key_unlocked_handler =
|
||||
g_signal_connect (priv->keyboard, "key-unlocked",
|
||||
G_CALLBACK(on_key_unlocked), self);
|
||||
priv->key_cancelled_handler =
|
||||
g_signal_connect (priv->keyboard, "key-cancelled",
|
||||
G_CALLBACK(on_key_cancelled), self);
|
||||
priv->symbol_index_changed_handler =
|
||||
g_signal_connect (priv->keyboard, "symbol-index-changed",
|
||||
G_CALLBACK(on_symbol_index_changed), self);
|
||||
}
|
||||
@ -371,8 +351,7 @@ eek_gtk_keyboard_set_property (GObject *object,
|
||||
static void
|
||||
eek_gtk_keyboard_dispose (GObject *object)
|
||||
{
|
||||
EekGtkKeyboard *self = EEK_GTK_KEYBOARD (object);
|
||||
EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (self);
|
||||
EekGtkKeyboardPrivate *priv = EEK_GTK_KEYBOARD_GET_PRIVATE(object);
|
||||
|
||||
if (priv->renderer) {
|
||||
g_object_unref (priv->renderer);
|
||||
@ -380,12 +359,35 @@ eek_gtk_keyboard_dispose (GObject *object)
|
||||
}
|
||||
|
||||
if (priv->keyboard) {
|
||||
if (g_signal_handler_is_connected (priv->keyboard,
|
||||
priv->key_pressed_handler))
|
||||
g_signal_handler_disconnect (priv->keyboard,
|
||||
priv->key_pressed_handler);
|
||||
if (g_signal_handler_is_connected (priv->keyboard,
|
||||
priv->key_released_handler))
|
||||
g_signal_handler_disconnect (priv->keyboard,
|
||||
priv->key_released_handler);
|
||||
if (g_signal_handler_is_connected (priv->keyboard,
|
||||
priv->key_locked_handler))
|
||||
g_signal_handler_disconnect (priv->keyboard,
|
||||
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->key_cancelled_handler))
|
||||
g_signal_handler_disconnect (priv->keyboard,
|
||||
priv->key_cancelled_handler);
|
||||
if (g_signal_handler_is_connected (priv->keyboard,
|
||||
priv->symbol_index_changed_handler))
|
||||
g_signal_handler_disconnect (priv->keyboard,
|
||||
priv->symbol_index_changed_handler);
|
||||
|
||||
GList *list, *head;
|
||||
|
||||
g_signal_handlers_disconnect_by_data(priv->keyboard, self);
|
||||
list = eek_keyboard_get_pressed_keys (priv->keyboard);
|
||||
for (head = list; head; head = g_list_next (head)) {
|
||||
g_log("squeek", G_LOG_LEVEL_DEBUG, "emit EekKey pressed");
|
||||
g_signal_emit_by_name (head->data, "released", priv->keyboard);
|
||||
}
|
||||
g_list_free (list);
|
||||
@ -409,6 +411,9 @@ eek_gtk_keyboard_class_init (EekGtkKeyboardClass *klass)
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||
GParamSpec *pspec;
|
||||
|
||||
g_type_class_add_private (gobject_class,
|
||||
sizeof (EekGtkKeyboardPrivate));
|
||||
|
||||
widget_class->realize = eek_gtk_keyboard_real_realize;
|
||||
widget_class->unmap = eek_gtk_keyboard_real_unmap;
|
||||
widget_class->draw = eek_gtk_keyboard_real_draw;
|
||||
@ -421,7 +426,6 @@ eek_gtk_keyboard_class_init (EekGtkKeyboardClass *klass)
|
||||
eek_gtk_keyboard_real_motion_notify_event;
|
||||
widget_class->query_tooltip =
|
||||
eek_gtk_keyboard_real_query_tooltip;
|
||||
widget_class->touch_event = handle_touch_event;
|
||||
|
||||
gobject_class->set_property = eek_gtk_keyboard_set_property;
|
||||
gobject_class->dispose = eek_gtk_keyboard_dispose;
|
||||
@ -439,16 +443,7 @@ eek_gtk_keyboard_class_init (EekGtkKeyboardClass *klass)
|
||||
static void
|
||||
eek_gtk_keyboard_init (EekGtkKeyboard *self)
|
||||
{
|
||||
#if HAVE_GSOUND
|
||||
EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (self);
|
||||
GError *err = NULL;
|
||||
|
||||
priv->sound_ctx = gsound_context_new(NULL, &err);
|
||||
if (!priv->sound_ctx) {
|
||||
g_warning ("GSound init failed: %s", err->message);
|
||||
g_clear_error (&err);
|
||||
}
|
||||
#endif
|
||||
self->priv = EEK_GTK_KEYBOARD_GET_PRIVATE(self);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -464,6 +459,15 @@ eek_gtk_keyboard_new (EekKeyboard *keyboard)
|
||||
return g_object_new (EEK_TYPE_GTK_KEYBOARD, "keyboard", keyboard, NULL);
|
||||
}
|
||||
|
||||
static EekColor *
|
||||
color_from_gdk_color (GdkColor *gdk_color)
|
||||
{
|
||||
return eek_color_new (gdk_color->red / (gdouble)0xFFFF,
|
||||
gdk_color->green / (gdouble)0xFFFF,
|
||||
gdk_color->blue / (gdouble)0xFFFF,
|
||||
1.0);
|
||||
}
|
||||
|
||||
static void
|
||||
magnify_bounds (GtkWidget *self,
|
||||
EekBounds *bounds,
|
||||
@ -491,14 +495,11 @@ static void
|
||||
render_pressed_key (GtkWidget *widget,
|
||||
EekKey *key)
|
||||
{
|
||||
EekGtkKeyboard *self = EEK_GTK_KEYBOARD (widget);
|
||||
EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (self);
|
||||
EekGtkKeyboardPrivate *priv = EEK_GTK_KEYBOARD_GET_PRIVATE(widget);
|
||||
EekBounds bounds, large_bounds;
|
||||
cairo_t *cr;
|
||||
|
||||
GdkWindow *window = gtk_widget_get_window (widget);
|
||||
cairo_region_t *region = gdk_window_get_clip_region (window);
|
||||
GdkDrawingContext *context = gdk_window_begin_draw_frame (window, region);
|
||||
cairo_t *cr = gdk_drawing_context_get_cairo_context (context);
|
||||
cr = gdk_cairo_create (GDK_DRAWABLE (gtk_widget_get_window (widget)));
|
||||
|
||||
eek_renderer_get_key_bounds (priv->renderer, key, &bounds, TRUE);
|
||||
magnify_bounds (widget, &bounds, &large_bounds, 1.5);
|
||||
@ -507,121 +508,134 @@ render_pressed_key (GtkWidget *widget,
|
||||
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);
|
||||
cairo_restore (cr);
|
||||
*/
|
||||
gdk_window_end_draw_frame (window, context);
|
||||
|
||||
cairo_region_destroy (region);
|
||||
cairo_destroy (cr);
|
||||
}
|
||||
|
||||
static void
|
||||
render_locked_key (GtkWidget *widget,
|
||||
EekKey *key)
|
||||
{
|
||||
EekGtkKeyboard *self = EEK_GTK_KEYBOARD (widget);
|
||||
EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (self);
|
||||
EekGtkKeyboardPrivate *priv = EEK_GTK_KEYBOARD_GET_PRIVATE(widget);
|
||||
EekBounds bounds;
|
||||
cairo_t *cr;
|
||||
|
||||
GdkWindow *window = gtk_widget_get_window (widget);
|
||||
cairo_region_t *region = gdk_window_get_clip_region (window);
|
||||
GdkDrawingContext *context = gdk_window_begin_draw_frame (window, region);
|
||||
cairo_t *cr = gdk_drawing_context_get_cairo_context (context);
|
||||
cr = gdk_cairo_create (GDK_DRAWABLE (gtk_widget_get_window (widget)));
|
||||
|
||||
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);
|
||||
|
||||
cairo_region_destroy (region);
|
||||
cairo_destroy (cr);
|
||||
}
|
||||
|
||||
static void
|
||||
render_released_key (GtkWidget *widget,
|
||||
EekKey *key)
|
||||
{
|
||||
EekGtkKeyboard *self = EEK_GTK_KEYBOARD (widget);
|
||||
EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (self);
|
||||
EekGtkKeyboardPrivate *priv = EEK_GTK_KEYBOARD_GET_PRIVATE(widget);
|
||||
EekBounds bounds, large_bounds;
|
||||
cairo_t *cr;
|
||||
|
||||
GdkWindow *window = gtk_widget_get_window (widget);
|
||||
cairo_region_t *region = gdk_window_get_clip_region (window);
|
||||
GdkDrawingContext *context = gdk_window_begin_draw_frame (window, region);
|
||||
cairo_t *cr = gdk_drawing_context_get_cairo_context (context);
|
||||
cr = gdk_cairo_create (GDK_DRAWABLE (gtk_widget_get_window (widget)));
|
||||
|
||||
eek_renderer_get_key_bounds (priv->renderer, key, &bounds, TRUE);
|
||||
magnify_bounds (widget, &bounds, &large_bounds, 1.5);
|
||||
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);
|
||||
|
||||
gdk_window_end_draw_frame (window, context);
|
||||
|
||||
cairo_region_destroy (region);
|
||||
cairo_destroy (cr);
|
||||
}
|
||||
|
||||
static void
|
||||
on_key_pressed (EekKey *key,
|
||||
EekGtkKeyboard *self)
|
||||
on_key_pressed (EekKeyboard *keyboard,
|
||||
EekKey *key,
|
||||
gpointer user_data)
|
||||
{
|
||||
EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (self);
|
||||
GtkWidget *widget = user_data;
|
||||
EekGtkKeyboardPrivate *priv = EEK_GTK_KEYBOARD_GET_PRIVATE(widget);
|
||||
|
||||
/* renderer may have not been set yet if the widget is a popup */
|
||||
if (!priv->renderer)
|
||||
return;
|
||||
|
||||
render_pressed_key (GTK_WIDGET(self), key);
|
||||
gtk_widget_queue_draw (GTK_WIDGET(self));
|
||||
render_pressed_key (widget, key);
|
||||
|
||||
#if HAVE_GSOUND
|
||||
g_return_if_fail (GSOUND_IS_CONTEXT (priv->sound_ctx));
|
||||
gsound_context_play_simple(priv->sound_ctx, NULL, NULL,
|
||||
GSOUND_ATTR_EVENT_ID, "button-pressed",
|
||||
GSOUND_ATTR_EVENT_DESCRIPTION, "Button pressed",
|
||||
#if HAVE_LIBCANBERRA
|
||||
ca_gtk_play_for_widget (widget, 0,
|
||||
CA_PROP_EVENT_ID, "button-pressed",
|
||||
CA_PROP_EVENT_DESCRIPTION, "virtual key pressed",
|
||||
CA_PROP_APPLICATION_ID, "org.fedorahosted.Eekboard",
|
||||
NULL);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
on_key_released (EekKey *key,
|
||||
EekGtkKeyboard *self)
|
||||
on_key_released (EekKeyboard *keyboard,
|
||||
EekKey *key,
|
||||
gpointer user_data)
|
||||
{
|
||||
EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (self);
|
||||
GtkWidget *widget = user_data;
|
||||
EekGtkKeyboardPrivate *priv = EEK_GTK_KEYBOARD_GET_PRIVATE(widget);
|
||||
|
||||
/* renderer may have not been set yet if the widget is a popup */
|
||||
if (!priv->renderer)
|
||||
return;
|
||||
|
||||
render_released_key (GTK_WIDGET(self), key);
|
||||
gtk_widget_queue_draw (GTK_WIDGET(self));
|
||||
render_released_key (widget, key);
|
||||
|
||||
#if HAVE_GSOUND
|
||||
g_return_if_fail (GSOUND_IS_CONTEXT (priv->sound_ctx));
|
||||
gsound_context_play_simple(priv->sound_ctx, NULL, NULL,
|
||||
GSOUND_ATTR_EVENT_ID, "button-released",
|
||||
GSOUND_ATTR_EVENT_DESCRIPTION, "Button released",
|
||||
#if HAVE_LIBCANBERRA
|
||||
ca_gtk_play_for_widget (widget, 0,
|
||||
CA_PROP_EVENT_ID, "button-released",
|
||||
CA_PROP_EVENT_DESCRIPTION, "virtual key pressed",
|
||||
CA_PROP_APPLICATION_ID, "org.fedorahosted.Eekboard",
|
||||
NULL);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
on_key_cancelled (EekKeyboard *keyboard,
|
||||
EekKey *key,
|
||||
gpointer user_data)
|
||||
{
|
||||
GtkWidget *widget = user_data;
|
||||
EekGtkKeyboardPrivate *priv = EEK_GTK_KEYBOARD_GET_PRIVATE(widget);
|
||||
|
||||
/* renderer may have not been set yet if the widget is a popup */
|
||||
if (!priv->renderer)
|
||||
return;
|
||||
|
||||
render_released_key (widget, key);
|
||||
}
|
||||
|
||||
static void
|
||||
on_key_locked (EekKeyboard *keyboard,
|
||||
EekKey *key,
|
||||
gpointer user_data)
|
||||
{
|
||||
GtkWidget *widget = user_data;
|
||||
EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (user_data);
|
||||
EekGtkKeyboardPrivate *priv = EEK_GTK_KEYBOARD_GET_PRIVATE(widget);
|
||||
|
||||
/* renderer may have not been set yet if the widget is a popup */
|
||||
if (!priv->renderer)
|
||||
return;
|
||||
|
||||
render_locked_key (widget, key);
|
||||
gtk_widget_queue_draw (widget);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -630,14 +644,13 @@ on_key_unlocked (EekKeyboard *keyboard,
|
||||
gpointer user_data)
|
||||
{
|
||||
GtkWidget *widget = user_data;
|
||||
EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (user_data);
|
||||
EekGtkKeyboardPrivate *priv = EEK_GTK_KEYBOARD_GET_PRIVATE(widget);
|
||||
|
||||
/* renderer may have not been set yet if the widget is a popup */
|
||||
if (!priv->renderer)
|
||||
return;
|
||||
|
||||
render_released_key (widget, key);
|
||||
gtk_widget_queue_draw (GTK_WIDGET(widget));
|
||||
}
|
||||
|
||||
static void
|
||||
@ -655,9 +668,11 @@ void
|
||||
eek_gtk_keyboard_set_theme (EekGtkKeyboard *keyboard,
|
||||
EekTheme *theme)
|
||||
{
|
||||
EekGtkKeyboardPrivate *priv;
|
||||
|
||||
g_return_if_fail (EEK_IS_GTK_KEYBOARD(keyboard));
|
||||
g_return_if_fail (EEK_IS_THEME(theme));
|
||||
|
||||
EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (keyboard);
|
||||
priv = EEK_GTK_KEYBOARD_GET_PRIVATE(keyboard);
|
||||
priv->theme = g_object_ref (theme);
|
||||
}
|
||||
|
||||
@ -32,7 +32,23 @@
|
||||
|
||||
G_BEGIN_DECLS
|
||||
#define EEK_TYPE_GTK_KEYBOARD (eek_gtk_keyboard_get_type())
|
||||
G_DECLARE_DERIVABLE_TYPE (EekGtkKeyboard, eek_gtk_keyboard, EEK, GTK_KEYBOARD, GtkDrawingArea)
|
||||
#define EEK_GTK_KEYBOARD(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EEK_TYPE_GTK_KEYBOARD, EekGtkKeyboard))
|
||||
#define EEK_GTK_KEYBOARD_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EEK_TYPE_GTK_KEYBOARD, EekGtkKeyboardClass))
|
||||
#define EEK_IS_GTK_KEYBOARD(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EEK_TYPE_GTK_KEYBOARD))
|
||||
#define EEK_IS_GTK_KEYBOARD_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EEK_TYPE_GTK_KEYBOARD))
|
||||
#define EEK_GTK_KEYBOARD_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EEK_TYPE_GTK_KEYBOARD, EekGtkKeyboardClass))
|
||||
|
||||
typedef struct _EekGtkKeyboard EekGtkKeyboard;
|
||||
typedef struct _EekGtkKeyboardClass EekGtkKeyboardClass;
|
||||
typedef struct _EekGtkKeyboardPrivate EekGtkKeyboardPrivate;
|
||||
|
||||
struct _EekGtkKeyboard
|
||||
{
|
||||
/*< private >*/
|
||||
GtkDrawingArea parent;
|
||||
|
||||
EekGtkKeyboardPrivate *priv;
|
||||
};
|
||||
|
||||
struct _EekGtkKeyboardClass
|
||||
{
|
||||
|
||||
@ -30,29 +30,52 @@
|
||||
|
||||
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,
|
||||
gint scale)
|
||||
gint size)
|
||||
{
|
||||
GError *error = NULL;
|
||||
GdkPixbuf *pixbuf;
|
||||
GError *error;
|
||||
cairo_surface_t *surface;
|
||||
|
||||
surface = gtk_icon_theme_load_surface (gtk_icon_theme_get_default (),
|
||||
error = NULL;
|
||||
pixbuf = gtk_icon_theme_load_icon (gtk_icon_theme_get_default (),
|
||||
icon_name,
|
||||
size,
|
||||
scale,
|
||||
NULL,
|
||||
0,
|
||||
&error);
|
||||
if (surface == NULL) {
|
||||
g_warning ("can't get icon surface for %s: %s",
|
||||
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;
|
||||
}
|
||||
|
||||
@ -67,9 +90,6 @@ eek_gtk_renderer_class_init (EekGtkRendererClass *klass)
|
||||
static void
|
||||
eek_gtk_renderer_init (EekGtkRenderer *self)
|
||||
{
|
||||
GtkIconTheme *theme = gtk_icon_theme_get_default ();
|
||||
|
||||
gtk_icon_theme_add_resource_path (theme, "/sm/puri/squeekboard/icons");
|
||||
}
|
||||
|
||||
EekRenderer *
|
||||
|
||||
194
eek/eek-key.c
@ -30,6 +30,10 @@
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
|
||||
#include <string.h>
|
||||
#define DEBUG 0
|
||||
#if DEBUG
|
||||
#include <stdio.h>
|
||||
#endif
|
||||
|
||||
#include "eek-key.h"
|
||||
#include "eek-section.h"
|
||||
@ -47,30 +51,59 @@ enum {
|
||||
};
|
||||
|
||||
enum {
|
||||
PRESSED,
|
||||
RELEASED,
|
||||
LOCKED,
|
||||
UNLOCKED,
|
||||
CANCELLED,
|
||||
LAST_SIGNAL
|
||||
};
|
||||
|
||||
static guint signals[LAST_SIGNAL] = { 0, };
|
||||
|
||||
typedef struct _EekKeyPrivate
|
||||
G_DEFINE_TYPE (EekKey, eek_key, EEK_TYPE_ELEMENT);
|
||||
|
||||
#define EEK_KEY_GET_PRIVATE(obj) \
|
||||
(G_TYPE_INSTANCE_GET_PRIVATE ((obj), EEK_TYPE_KEY, EekKeyPrivate))
|
||||
|
||||
|
||||
struct _EekKeyPrivate
|
||||
{
|
||||
guint keycode;
|
||||
EekSymbolMatrix *symbol_matrix;
|
||||
gint column;
|
||||
gint row;
|
||||
gulong oref; // UI outline reference
|
||||
gulong oref;
|
||||
gboolean is_pressed;
|
||||
gboolean is_locked;
|
||||
} EekKeyPrivate;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE_WITH_PRIVATE (EekKey, eek_key, EEK_TYPE_ELEMENT)
|
||||
static void
|
||||
eek_key_real_pressed (EekKey *self)
|
||||
{
|
||||
EekKeyPrivate *priv = EEK_KEY_GET_PRIVATE(self);
|
||||
|
||||
priv->is_pressed = TRUE;
|
||||
#if DEBUG
|
||||
g_debug ("pressed %X", eek_key_get_keycode (self));
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
eek_key_real_released (EekKey *self)
|
||||
{
|
||||
EekKeyPrivate *priv = EEK_KEY_GET_PRIVATE(self);
|
||||
|
||||
priv->is_pressed = FALSE;
|
||||
#if DEBUG
|
||||
g_debug ("released %X", eek_key_get_keycode (self));
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
eek_key_real_locked (EekKey *self)
|
||||
{
|
||||
EekKeyPrivate *priv = eek_key_get_instance_private (self);
|
||||
EekKeyPrivate *priv = EEK_KEY_GET_PRIVATE(self);
|
||||
|
||||
priv->is_locked = TRUE;
|
||||
#if DEBUG
|
||||
@ -81,7 +114,7 @@ eek_key_real_locked (EekKey *self)
|
||||
static void
|
||||
eek_key_real_unlocked (EekKey *self)
|
||||
{
|
||||
EekKeyPrivate *priv = eek_key_get_instance_private (self);
|
||||
EekKeyPrivate *priv = EEK_KEY_GET_PRIVATE(self);
|
||||
|
||||
priv->is_locked = FALSE;
|
||||
#if DEBUG
|
||||
@ -89,14 +122,22 @@ eek_key_real_unlocked (EekKey *self)
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
eek_key_real_cancelled (EekKey *self)
|
||||
{
|
||||
EekKeyPrivate *priv = EEK_KEY_GET_PRIVATE(self);
|
||||
|
||||
priv->is_pressed = FALSE;
|
||||
#if DEBUG
|
||||
g_debug ("cancelled %X", eek_key_get_keycode (self));
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
eek_key_finalize (GObject *object)
|
||||
{
|
||||
EekKey *self = EEK_KEY (object);
|
||||
EekKeyPrivate *priv = eek_key_get_instance_private (self);
|
||||
|
||||
EekKeyPrivate *priv = EEK_KEY_GET_PRIVATE(object);
|
||||
eek_symbol_matrix_free (priv->symbol_matrix);
|
||||
|
||||
G_OBJECT_CLASS (eek_key_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
@ -173,13 +214,19 @@ eek_key_class_init (EekKeyClass *klass)
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||
GParamSpec *pspec;
|
||||
|
||||
g_type_class_add_private (gobject_class,
|
||||
sizeof (EekKeyPrivate));
|
||||
|
||||
gobject_class->set_property = eek_key_set_property;
|
||||
gobject_class->get_property = eek_key_get_property;
|
||||
gobject_class->finalize = eek_key_finalize;
|
||||
|
||||
/* signals */
|
||||
klass->pressed = eek_key_real_pressed;
|
||||
klass->released = eek_key_real_released;
|
||||
klass->locked = eek_key_real_locked;
|
||||
klass->unlocked = eek_key_real_unlocked;
|
||||
klass->cancelled = eek_key_real_cancelled;
|
||||
|
||||
/**
|
||||
* EekKey:keycode:
|
||||
@ -241,6 +288,42 @@ eek_key_class_init (EekKeyClass *klass)
|
||||
G_PARAM_READWRITE);
|
||||
g_object_class_install_property (gobject_class, PROP_OREF, pspec);
|
||||
|
||||
/**
|
||||
* EekKey::pressed:
|
||||
* @key: an #EekKey
|
||||
*
|
||||
* The ::pressed signal is emitted each time @key is shifted to
|
||||
* the pressed state. The class handler runs before signal
|
||||
* handlers to allow signal handlers to read the status of @key
|
||||
* with eek_key_is_pressed().
|
||||
*/
|
||||
signals[PRESSED] =
|
||||
g_signal_new (I_("pressed"),
|
||||
G_TYPE_FROM_CLASS(gobject_class),
|
||||
G_SIGNAL_RUN_FIRST,
|
||||
G_STRUCT_OFFSET(EekKeyClass, pressed),
|
||||
NULL,
|
||||
NULL,
|
||||
g_cclosure_marshal_VOID__VOID,
|
||||
G_TYPE_NONE, 0);
|
||||
|
||||
/**
|
||||
* EekKey::released:
|
||||
* @key: an #EekKey
|
||||
*
|
||||
* The ::released signal is emitted each time @key is shifted to
|
||||
* the released state.
|
||||
*/
|
||||
signals[RELEASED] =
|
||||
g_signal_new (I_("released"),
|
||||
G_TYPE_FROM_CLASS(gobject_class),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET(EekKeyClass, released),
|
||||
NULL,
|
||||
NULL,
|
||||
g_cclosure_marshal_VOID__VOID,
|
||||
G_TYPE_NONE, 0);
|
||||
|
||||
/**
|
||||
* EekKey::locked:
|
||||
* @key: an #EekKey
|
||||
@ -276,12 +359,31 @@ eek_key_class_init (EekKeyClass *klass)
|
||||
NULL,
|
||||
g_cclosure_marshal_VOID__VOID,
|
||||
G_TYPE_NONE, 0);
|
||||
|
||||
/**
|
||||
* EekKey::cancelled:
|
||||
* @key: an #EekKey
|
||||
*
|
||||
* The ::cancelled signal is emitted each time @key is shifted to
|
||||
* the cancelled state.
|
||||
*/
|
||||
signals[CANCELLED] =
|
||||
g_signal_new (I_("cancelled"),
|
||||
G_TYPE_FROM_CLASS(gobject_class),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET(EekKeyClass, cancelled),
|
||||
NULL,
|
||||
NULL,
|
||||
g_cclosure_marshal_VOID__VOID,
|
||||
G_TYPE_NONE, 0);
|
||||
}
|
||||
|
||||
static void
|
||||
eek_key_init (EekKey *self)
|
||||
{
|
||||
EekKeyPrivate *priv = eek_key_get_instance_private (self);
|
||||
EekKeyPrivate *priv;
|
||||
|
||||
priv = self->priv = EEK_KEY_GET_PRIVATE(self);
|
||||
priv->symbol_matrix = eek_symbol_matrix_new (0, 0);
|
||||
}
|
||||
|
||||
@ -301,10 +403,7 @@ 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;
|
||||
key->priv->keycode = keycode;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -318,10 +417,7 @@ 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;
|
||||
return key->priv->keycode;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -337,10 +433,8 @@ eek_key_set_symbol_matrix (EekKey *key,
|
||||
{
|
||||
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_symbol_matrix_free (key->priv->symbol_matrix);
|
||||
key->priv->symbol_matrix = eek_symbol_matrix_copy (matrix);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -354,10 +448,7 @@ 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;
|
||||
return key->priv->symbol_matrix;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -445,7 +536,7 @@ eek_key_get_symbol_at_index (EekKey *key,
|
||||
gint fallback_group,
|
||||
gint fallback_level)
|
||||
{
|
||||
EekKeyPrivate *priv = eek_key_get_instance_private (key);
|
||||
EekKeyPrivate *priv = EEK_KEY_GET_PRIVATE(key);
|
||||
gint num_symbols;
|
||||
|
||||
g_return_val_if_fail (fallback_group >= 0, NULL);
|
||||
@ -497,14 +588,12 @@ eek_key_set_index (EekKey *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;
|
||||
if (key->priv->column != column) {
|
||||
key->priv->column = column;
|
||||
g_object_notify (G_OBJECT(key), "column");
|
||||
}
|
||||
if (priv->row != row) {
|
||||
priv->row = row;
|
||||
if (key->priv->row != row) {
|
||||
key->priv->row = row;
|
||||
g_object_notify (G_OBJECT(key), "row");
|
||||
}
|
||||
}
|
||||
@ -525,12 +614,10 @@ eek_key_get_index (EekKey *key,
|
||||
g_return_if_fail (EEK_IS_KEY(key));
|
||||
g_return_if_fail (column != NULL || row != NULL);
|
||||
|
||||
EekKeyPrivate *priv = eek_key_get_instance_private (key);
|
||||
|
||||
if (column != NULL)
|
||||
*column = priv->column;
|
||||
*column = key->priv->column;
|
||||
if (row != NULL)
|
||||
*row = priv->row;
|
||||
*row = key->priv->row;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -545,11 +632,8 @@ 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;
|
||||
if (key->priv->oref != oref) {
|
||||
key->priv->oref = oref;
|
||||
g_object_notify (G_OBJECT(key), "oref");
|
||||
}
|
||||
}
|
||||
@ -565,10 +649,7 @@ 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;
|
||||
return key->priv->oref;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -581,10 +662,7 @@ 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;
|
||||
return key->priv->is_pressed;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -597,17 +675,5 @@ 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;
|
||||
return key->priv->is_locked;
|
||||
}
|
||||
|
||||
@ -31,7 +31,28 @@
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define EEK_TYPE_KEY (eek_key_get_type())
|
||||
G_DECLARE_DERIVABLE_TYPE(EekKey, eek_key, EEK, KEY, EekElement)
|
||||
#define EEK_KEY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EEK_TYPE_KEY, EekKey))
|
||||
#define EEK_KEY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EEK_TYPE_KEY, EekKeyClass))
|
||||
#define EEK_IS_KEY(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EEK_TYPE_KEY))
|
||||
#define EEK_IS_KEY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EEK_TYPE_KEY))
|
||||
#define EEK_KEY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EEK_TYPE_KEY, EekKeyClass))
|
||||
|
||||
typedef struct _EekKeyClass EekKeyClass;
|
||||
typedef struct _EekKeyPrivate EekKeyPrivate;
|
||||
|
||||
/**
|
||||
* EekKey:
|
||||
*
|
||||
* The #EekKey structure contains only private data and should only be
|
||||
* accessed using the provided API.
|
||||
*/
|
||||
struct _EekKey
|
||||
{
|
||||
/*< private >*/
|
||||
EekElement parent;
|
||||
|
||||
EekKeyPrivate *priv;
|
||||
};
|
||||
|
||||
/**
|
||||
* EekKeyClass:
|
||||
@ -50,8 +71,11 @@ struct _EekKeyClass
|
||||
|
||||
/*< public >*/
|
||||
/* signals */
|
||||
void (* pressed) (EekKey *key);
|
||||
void (* released) (EekKey *key);
|
||||
void (* locked) (EekKey *key);
|
||||
void (* unlocked) (EekKey *key);
|
||||
void (* cancelled) (EekKey *key);
|
||||
};
|
||||
|
||||
GType eek_key_get_type (void) G_GNUC_CONST;
|
||||
@ -86,8 +110,6 @@ guint eek_key_get_oref (EekKey *key);
|
||||
|
||||
gboolean eek_key_is_pressed (EekKey *key);
|
||||
gboolean eek_key_is_locked (EekKey *key);
|
||||
void eek_key_set_pressed (EekKey *key,
|
||||
gboolean value);
|
||||
|
||||
G_END_DECLS
|
||||
#endif /* EEK_KEY_H */
|
||||
|
||||
@ -199,21 +199,32 @@ void
|
||||
_eek_rounded_polygon (cairo_t *cr,
|
||||
gdouble radius,
|
||||
EekPoint *points,
|
||||
guint num_points)
|
||||
gint num_points)
|
||||
{
|
||||
gint i, j;
|
||||
|
||||
cairo_move_to (cr,
|
||||
(gdouble) (points[num_points - 1].x +
|
||||
points[0].x) / 2,
|
||||
(gdouble) (points[num_points - 1].y +
|
||||
points[0].y) / 2);
|
||||
|
||||
for (guint i = 0; i < num_points; i++) {
|
||||
guint j = (i + 1) % num_points;
|
||||
|
||||
#ifdef KBDRAW_DEBUG
|
||||
printf (" rounded polygon of radius %f:\n", radius);
|
||||
#endif
|
||||
for (i = 0; i < num_points; i++) {
|
||||
j = (i + 1) % num_points;
|
||||
rounded_corner (cr, (gdouble) points[i].x,
|
||||
(gdouble) points[i].y,
|
||||
(gdouble) (points[i].x + points[j].x) / 2,
|
||||
(gdouble) (points[i].y + points[j].y) / 2,
|
||||
radius);
|
||||
}
|
||||
#ifdef KBDRAW_DEBUG
|
||||
printf (" corner (%d, %d) -> (%d, %d):\n",
|
||||
points[i].x, points[i].y, points[j].x,
|
||||
points[j].y);
|
||||
#endif
|
||||
};
|
||||
cairo_close_path (cr);
|
||||
}
|
||||
|
||||
@ -32,12 +32,10 @@
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
|
||||
#include "eek-keyboard.h"
|
||||
#include "eek-marshalers.h"
|
||||
#include "eek-section.h"
|
||||
#include "eek-key.h"
|
||||
#include "eek-symbol.h"
|
||||
#include "eek-enumtypes.h"
|
||||
#include "eekboard/key-emitter.h"
|
||||
|
||||
enum {
|
||||
PROP_0,
|
||||
@ -47,21 +45,18 @@ enum {
|
||||
};
|
||||
|
||||
enum {
|
||||
KEY_PRESSED,
|
||||
KEY_RELEASED,
|
||||
KEY_LOCKED,
|
||||
KEY_UNLOCKED,
|
||||
KEY_CANCELLED,
|
||||
LAST_SIGNAL
|
||||
};
|
||||
|
||||
enum {
|
||||
VIEW_LETTERS_LOWER,
|
||||
VIEW_LETTERS_UPPER,
|
||||
VIEW_NUMBERS,
|
||||
VIEW_SYMBOLS
|
||||
};
|
||||
|
||||
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))
|
||||
|
||||
@ -70,7 +65,6 @@ struct _EekKeyboardPrivate
|
||||
EekLayout *layout;
|
||||
EekModifierBehavior modifier_behavior;
|
||||
EekModifierType modifiers;
|
||||
unsigned int old_level;
|
||||
GList *pressed_keys;
|
||||
GList *locked_keys;
|
||||
GArray *outline_array;
|
||||
@ -81,8 +75,6 @@ struct _EekKeyboardPrivate
|
||||
EekModifierType alt_gr_mask;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE_WITH_PRIVATE (EekKeyboard, eek_keyboard, EEK_TYPE_CONTAINER);
|
||||
|
||||
G_DEFINE_BOXED_TYPE(EekModifierKey, eek_modifier_key,
|
||||
eek_modifier_key_copy, eek_modifier_key_free);
|
||||
|
||||
@ -99,6 +91,22 @@ eek_modifier_key_free (EekModifierKey *modkey)
|
||||
g_slice_free (EekModifierKey, modkey);
|
||||
}
|
||||
|
||||
static void
|
||||
on_key_pressed (EekSection *section,
|
||||
EekKey *key,
|
||||
EekKeyboard *keyboard)
|
||||
{
|
||||
g_signal_emit (keyboard, signals[KEY_PRESSED], 0, key);
|
||||
}
|
||||
|
||||
static void
|
||||
on_key_released (EekSection *section,
|
||||
EekKey *key,
|
||||
EekKeyboard *keyboard)
|
||||
{
|
||||
g_signal_emit (keyboard, signals[KEY_RELEASED], 0, key);
|
||||
}
|
||||
|
||||
static void
|
||||
on_key_locked (EekSection *section,
|
||||
EekKey *key,
|
||||
@ -115,6 +123,14 @@ on_key_unlocked (EekSection *section,
|
||||
g_signal_emit (keyboard, signals[KEY_UNLOCKED], 0, key);
|
||||
}
|
||||
|
||||
static void
|
||||
on_key_cancelled (EekSection *section,
|
||||
EekKey *key,
|
||||
EekKeyboard *keyboard)
|
||||
{
|
||||
g_signal_emit (keyboard, signals[KEY_CANCELLED], 0, key);
|
||||
}
|
||||
|
||||
static void
|
||||
on_symbol_index_changed (EekSection *section,
|
||||
gint group,
|
||||
@ -211,58 +227,15 @@ eek_keyboard_get_property (GObject *object,
|
||||
}
|
||||
|
||||
static void
|
||||
set_level_from_modifiers (EekKeyboard *self, EekKey *key)
|
||||
set_level_from_modifiers (EekKeyboard *self)
|
||||
{
|
||||
EekKeyboardPrivate *priv = EEK_KEYBOARD_GET_PRIVATE(self);
|
||||
gint level = 0;
|
||||
|
||||
/* The levels are: 0 Letters, 1 Upper case letters, 2 Numbers, 3 Symbols */
|
||||
|
||||
/* Use the numbers/letters bit from the old level */
|
||||
gint level = priv->old_level & 2;
|
||||
|
||||
/* Handle non-emitting keys */
|
||||
if (key && (eek_key_get_keycode(key) == 0)) {
|
||||
const gchar *name = eek_element_get_name(EEK_ELEMENT(key));
|
||||
if (g_strcmp0(name, "ABC123") == 0)
|
||||
level ^= 2;
|
||||
}
|
||||
|
||||
level |= ((priv->modifiers & EEK_SHIFT_MASK) ? 1 : 0);
|
||||
|
||||
switch (priv->old_level) {
|
||||
case VIEW_LETTERS_UPPER:
|
||||
{
|
||||
/* Redirect upper case letters to numbers instead of symbols, clearing
|
||||
the shift modifier to keep the modifiers in sync with the level */
|
||||
if (level == VIEW_SYMBOLS) {
|
||||
level = VIEW_NUMBERS;
|
||||
priv->modifiers &= ~EEK_SHIFT_MASK;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case VIEW_SYMBOLS:
|
||||
{
|
||||
/* Redirect symbols to lower case letters instead of upper case,
|
||||
clearing the shift modifier to keep the modifiers in sync with the
|
||||
level */
|
||||
if (level == VIEW_LETTERS_UPPER) {
|
||||
level = VIEW_LETTERS_LOWER;
|
||||
priv->modifiers &= ~EEK_SHIFT_MASK;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case VIEW_LETTERS_LOWER: /* Direct transitions between views */
|
||||
case VIEW_NUMBERS:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (level == VIEW_NUMBERS || level == VIEW_SYMBOLS)
|
||||
priv->modifier_behavior = EEK_MODIFIER_BEHAVIOR_LOCK;
|
||||
else
|
||||
priv->modifier_behavior = EEK_MODIFIER_BEHAVIOR_LATCH;
|
||||
|
||||
priv->old_level = level;
|
||||
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);
|
||||
}
|
||||
|
||||
@ -305,76 +278,74 @@ set_modifiers_with_key (EekKeyboard *self,
|
||||
priv->modifiers = modifiers;
|
||||
}
|
||||
|
||||
void eek_keyboard_press_key(EekKeyboard *keyboard, EekKey *key, guint32 timestamp) {
|
||||
EekKeyboardPrivate *priv = EEK_KEYBOARD_GET_PRIVATE(keyboard);
|
||||
static void
|
||||
eek_keyboard_real_key_pressed (EekKeyboard *self,
|
||||
EekKey *key)
|
||||
{
|
||||
EekKeyboardPrivate *priv = EEK_KEYBOARD_GET_PRIVATE(self);
|
||||
EekSymbol *symbol;
|
||||
EekModifierType modifier;
|
||||
|
||||
eek_key_set_pressed(key, TRUE);
|
||||
priv->pressed_keys = g_list_prepend (priv->pressed_keys, key);
|
||||
|
||||
EekSymbol *symbol = eek_key_get_symbol_with_fallback (key, 0, 0);
|
||||
symbol = eek_key_get_symbol_with_fallback (key, 0, 0);
|
||||
if (!symbol)
|
||||
return;
|
||||
|
||||
EekModifierType modifier = eek_symbol_get_modifier_mask (symbol);
|
||||
modifier = eek_symbol_get_modifier_mask (symbol);
|
||||
if (priv->modifier_behavior == EEK_MODIFIER_BEHAVIOR_NONE) {
|
||||
set_modifiers_with_key (keyboard, key, priv->modifiers | modifier);
|
||||
set_level_from_modifiers (keyboard, key);
|
||||
set_modifiers_with_key (self, key, priv->modifiers | modifier);
|
||||
set_level_from_modifiers (self);
|
||||
}
|
||||
|
||||
// "Borrowed" from eek-context-service; doesn't influence the state but forwards the event
|
||||
|
||||
guint keycode = eek_key_get_keycode (key);
|
||||
EekModifierType modifiers = eek_keyboard_get_modifiers (keyboard);
|
||||
|
||||
emit_key_activated(keyboard->manager, keyboard, keycode, symbol, modifiers, TRUE, timestamp);
|
||||
}
|
||||
|
||||
void eek_keyboard_release_key( EekKeyboard *keyboard,
|
||||
EekKey *key,
|
||||
guint32 timestamp) {
|
||||
EekKeyboardPrivate *priv = EEK_KEYBOARD_GET_PRIVATE(keyboard);
|
||||
static void
|
||||
eek_keyboard_real_key_released (EekKeyboard *self,
|
||||
EekKey *key)
|
||||
{
|
||||
EekKeyboardPrivate *priv = EEK_KEYBOARD_GET_PRIVATE(self);
|
||||
EekSymbol *symbol;
|
||||
EekModifierType modifier;
|
||||
|
||||
for (GList *head = priv->pressed_keys; head; head = g_list_next (head)) {
|
||||
if (head->data == key) {
|
||||
priv->pressed_keys = g_list_remove_link (priv->pressed_keys, head);
|
||||
g_list_free1 (head);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
EekSymbol *symbol = eek_key_get_symbol_with_fallback (key, 0, 0);
|
||||
if (!symbol)
|
||||
return;
|
||||
|
||||
EekModifierType modifier = eek_symbol_get_modifier_mask (symbol);
|
||||
EEK_KEYBOARD_GET_CLASS (self)->key_cancelled (self, key);
|
||||
|
||||
symbol = eek_key_get_symbol_with_fallback (key, 0, 0);
|
||||
if (!symbol)
|
||||
return;
|
||||
|
||||
modifier = eek_symbol_get_modifier_mask (symbol);
|
||||
switch (priv->modifier_behavior) {
|
||||
case EEK_MODIFIER_BEHAVIOR_NONE:
|
||||
set_modifiers_with_key (keyboard, key, priv->modifiers & ~modifier);
|
||||
set_modifiers_with_key (self, key, priv->modifiers & ~modifier);
|
||||
break;
|
||||
case EEK_MODIFIER_BEHAVIOR_LOCK:
|
||||
priv->modifiers ^= modifier;
|
||||
break;
|
||||
case EEK_MODIFIER_BEHAVIOR_LATCH:
|
||||
if (modifier)
|
||||
set_modifiers_with_key (keyboard, key, priv->modifiers ^ modifier);
|
||||
set_modifiers_with_key (self, key, priv->modifiers ^ modifier);
|
||||
else
|
||||
set_modifiers_with_key (keyboard, key,
|
||||
set_modifiers_with_key (self, key,
|
||||
(priv->modifiers ^ modifier) & modifier);
|
||||
break;
|
||||
}
|
||||
set_level_from_modifiers (keyboard, key);
|
||||
set_level_from_modifiers (self);
|
||||
}
|
||||
|
||||
// "Borrowed" from eek-context-service; doesn't influence the state but forwards the event
|
||||
static void
|
||||
eek_keyboard_real_key_cancelled (EekKeyboard *self,
|
||||
EekKey *key)
|
||||
{
|
||||
EekKeyboardPrivate *priv = EEK_KEYBOARD_GET_PRIVATE(self);
|
||||
GList *head;
|
||||
|
||||
guint keycode = eek_key_get_keycode (key);
|
||||
guint modifiers = eek_keyboard_get_modifiers (keyboard);
|
||||
|
||||
emit_key_activated(keyboard->manager, keyboard, keycode, symbol, modifiers, FALSE, timestamp);
|
||||
for (head = priv->pressed_keys; head; head = g_list_next (head)) {
|
||||
if (head->data == key) {
|
||||
priv->pressed_keys = g_list_remove_link (priv->pressed_keys, head);
|
||||
g_list_free1 (head);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
@ -394,7 +365,7 @@ static void
|
||||
eek_keyboard_finalize (GObject *object)
|
||||
{
|
||||
EekKeyboardPrivate *priv = EEK_KEYBOARD_GET_PRIVATE(object);
|
||||
guint i;
|
||||
gint i;
|
||||
|
||||
g_list_free (priv->pressed_keys);
|
||||
g_list_free_full (priv->locked_keys,
|
||||
@ -418,10 +389,16 @@ static void
|
||||
eek_keyboard_real_child_added (EekContainer *self,
|
||||
EekElement *element)
|
||||
{
|
||||
g_signal_connect (element, "key-pressed",
|
||||
G_CALLBACK(on_key_pressed), self);
|
||||
g_signal_connect (element, "key-released",
|
||||
G_CALLBACK(on_key_released), self);
|
||||
g_signal_connect (element, "key-locked",
|
||||
G_CALLBACK(on_key_locked), self);
|
||||
g_signal_connect (element, "key-unlocked",
|
||||
G_CALLBACK(on_key_unlocked), self);
|
||||
g_signal_connect (element, "key-cancelled",
|
||||
G_CALLBACK(on_key_cancelled), self);
|
||||
g_signal_connect (element, "symbol-index-changed",
|
||||
G_CALLBACK(on_symbol_index_changed), self);
|
||||
}
|
||||
@ -430,8 +407,11 @@ static void
|
||||
eek_keyboard_real_child_removed (EekContainer *self,
|
||||
EekElement *element)
|
||||
{
|
||||
g_signal_handlers_disconnect_by_func (element, on_key_pressed, self);
|
||||
g_signal_handlers_disconnect_by_func (element, on_key_released, self);
|
||||
g_signal_handlers_disconnect_by_func (element, on_key_locked, self);
|
||||
g_signal_handlers_disconnect_by_func (element, on_key_unlocked, self);
|
||||
g_signal_handlers_disconnect_by_func (element, on_key_cancelled, self);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -441,9 +421,16 @@ eek_keyboard_class_init (EekKeyboardClass *klass)
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||
GParamSpec *pspec;
|
||||
|
||||
g_type_class_add_private (gobject_class,
|
||||
sizeof (EekKeyboardPrivate));
|
||||
|
||||
klass->create_section = eek_keyboard_real_create_section;
|
||||
|
||||
/* signals */
|
||||
klass->key_pressed = eek_keyboard_real_key_pressed;
|
||||
klass->key_released = eek_keyboard_real_key_released;
|
||||
klass->key_cancelled = eek_keyboard_real_key_cancelled;
|
||||
|
||||
container_class->child_added = eek_keyboard_real_child_added;
|
||||
container_class->child_removed = eek_keyboard_real_child_removed;
|
||||
|
||||
@ -481,6 +468,46 @@ eek_keyboard_class_init (EekKeyboardClass *klass)
|
||||
PROP_MODIFIER_BEHAVIOR,
|
||||
pspec);
|
||||
|
||||
/**
|
||||
* EekKeyboard::key-pressed:
|
||||
* @keyboard: an #EekKeyboard
|
||||
* @key: an #EekKey
|
||||
*
|
||||
* The ::key-pressed signal is emitted each time a key in @keyboard
|
||||
* is shifted to the pressed state.
|
||||
*/
|
||||
signals[KEY_PRESSED] =
|
||||
g_signal_new (I_("key-pressed"),
|
||||
G_TYPE_FROM_CLASS(gobject_class),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET(EekKeyboardClass, key_pressed),
|
||||
NULL,
|
||||
NULL,
|
||||
g_cclosure_marshal_VOID__OBJECT,
|
||||
G_TYPE_NONE,
|
||||
1,
|
||||
EEK_TYPE_KEY);
|
||||
|
||||
/**
|
||||
* EekKeyboard::key-released:
|
||||
* @keyboard: an #EekKeyboard
|
||||
* @key: an #EekKey
|
||||
*
|
||||
* The ::key-released signal is emitted each time a key in @keyboard
|
||||
* is shifted to the released state.
|
||||
*/
|
||||
signals[KEY_RELEASED] =
|
||||
g_signal_new (I_("key-released"),
|
||||
G_TYPE_FROM_CLASS(gobject_class),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET(EekKeyboardClass, key_released),
|
||||
NULL,
|
||||
NULL,
|
||||
g_cclosure_marshal_VOID__OBJECT,
|
||||
G_TYPE_NONE,
|
||||
1,
|
||||
EEK_TYPE_KEY);
|
||||
|
||||
/**
|
||||
* EekKeyboard::key-locked:
|
||||
* @keyboard: an #EekKeyboard
|
||||
@ -520,6 +547,26 @@ eek_keyboard_class_init (EekKeyboardClass *klass)
|
||||
G_TYPE_NONE,
|
||||
1,
|
||||
EEK_TYPE_KEY);
|
||||
|
||||
/**
|
||||
* EekKeyboard::key-cancelled:
|
||||
* @keyboard: an #EekKeyboard
|
||||
* @key: an #EekKey
|
||||
*
|
||||
* The ::key-cancelled signal is emitted each time a key in @keyboard
|
||||
* is shifted to the cancelled state.
|
||||
*/
|
||||
signals[KEY_CANCELLED] =
|
||||
g_signal_new (I_("key-cancelled"),
|
||||
G_TYPE_FROM_CLASS(gobject_class),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET(EekKeyboardClass, key_cancelled),
|
||||
NULL,
|
||||
NULL,
|
||||
g_cclosure_marshal_VOID__OBJECT,
|
||||
G_TYPE_NONE,
|
||||
1,
|
||||
EEK_TYPE_KEY);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -633,7 +680,7 @@ eek_keyboard_set_modifiers (EekKeyboard *keyboard,
|
||||
{
|
||||
g_return_if_fail (EEK_IS_KEYBOARD(keyboard));
|
||||
keyboard->priv->modifiers = modifiers;
|
||||
set_level_from_modifiers (keyboard, NULL);
|
||||
set_level_from_modifiers (keyboard);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -26,7 +26,6 @@
|
||||
#define EEK_KEYBOARD_H 1
|
||||
|
||||
#include <glib-object.h>
|
||||
#include <xkbcommon/xkbcommon.h>
|
||||
#include "eek-container.h"
|
||||
#include "eek-types.h"
|
||||
#include "eek-layout.h"
|
||||
@ -46,10 +45,6 @@ typedef struct _EekKeyboardPrivate EekKeyboardPrivate;
|
||||
/**
|
||||
* EekKeyboard:
|
||||
*
|
||||
* Contains the state of the physical keyboard.
|
||||
*
|
||||
* Is also a graphical element...
|
||||
*
|
||||
* The #EekKeyboard structure contains only private data and should
|
||||
* only be accessed using the provided API.
|
||||
*/
|
||||
@ -59,11 +54,6 @@ struct _EekKeyboard
|
||||
EekContainer parent;
|
||||
|
||||
EekKeyboardPrivate *priv;
|
||||
struct xkb_keymap *keymap;
|
||||
int keymap_fd; // keymap formatted as XKB string
|
||||
size_t keymap_len; // length of the data inside keymap_fd
|
||||
|
||||
EekboardContextService *manager; // unowned reference
|
||||
};
|
||||
|
||||
/**
|
||||
@ -92,6 +82,12 @@ struct _EekKeyboardClass
|
||||
EekKey *(* find_key_by_keycode) (EekKeyboard *self,
|
||||
guint keycode);
|
||||
|
||||
/* signals */
|
||||
void (* key_pressed) (EekKeyboard *self,
|
||||
EekKey *key);
|
||||
void (* key_released) (EekKeyboard *self,
|
||||
EekKey *key);
|
||||
|
||||
/*< private >*/
|
||||
/* obsolete members moved to EekElement */
|
||||
gpointer symbol_index_changed;
|
||||
@ -102,6 +98,8 @@ struct _EekKeyboardClass
|
||||
EekKey *key);
|
||||
void (* key_unlocked) (EekKeyboard *self,
|
||||
EekKey *key);
|
||||
void (* key_cancelled) (EekKeyboard *self,
|
||||
EekKey *key);
|
||||
|
||||
/*< private >*/
|
||||
/* padding */
|
||||
@ -123,13 +121,12 @@ struct _EekModifierKey {
|
||||
};
|
||||
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;
|
||||
|
||||
EekKeyboard *eek_keyboard_new (EekLayout *layout,
|
||||
gdouble initial_width,
|
||||
gdouble initial_height);
|
||||
EekLayout *eek_keyboard_get_layout
|
||||
(EekKeyboard *keyboard);
|
||||
void eek_keyboard_get_size
|
||||
@ -191,8 +188,5 @@ EekModifierKey *eek_modifier_key_copy
|
||||
void eek_modifier_key_free
|
||||
(EekModifierKey *modkey);
|
||||
|
||||
void eek_keyboard_press_key(EekKeyboard *keyboard, EekKey *key, guint32 timestamp);
|
||||
void eek_keyboard_release_key(EekKeyboard *keyboard, EekKey *key, guint32 timestamp);
|
||||
|
||||
G_END_DECLS
|
||||
#endif /* EEK_KEYBOARD_H */
|
||||
|
||||
@ -50,10 +50,9 @@
|
||||
#define EEK_KEYSYM_Hyper_L 0xffed
|
||||
#define EEK_KEYSYM_Hyper_R 0xffee
|
||||
|
||||
typedef struct _EekKeysymPrivate
|
||||
{
|
||||
struct _EekKeysymPrivate {
|
||||
guint xkeysym;
|
||||
} EekKeysymPrivate;
|
||||
};
|
||||
|
||||
struct _EekKeysymEntry {
|
||||
guint xkeysym;
|
||||
@ -69,11 +68,12 @@ typedef struct _EekKeysymEntry EekKeysymEntry;
|
||||
|
||||
static void eek_serializable_iface_init (EekSerializableIface *iface);
|
||||
|
||||
G_DEFINE_TYPE_EXTENDED (EekKeysym, eek_keysym, EEK_TYPE_SYMBOL,
|
||||
0, /* GTypeFlags */
|
||||
G_ADD_PRIVATE (EekKeysym)
|
||||
G_DEFINE_TYPE_WITH_CODE (EekKeysym, eek_keysym, EEK_TYPE_SYMBOL,
|
||||
G_IMPLEMENT_INTERFACE (EEK_TYPE_SERIALIZABLE,
|
||||
eek_serializable_iface_init))
|
||||
eek_serializable_iface_init));
|
||||
|
||||
#define EEK_KEYSYM_GET_PRIVATE(obj) \
|
||||
(G_TYPE_INSTANCE_GET_PRIVATE ((obj), EEK_TYPE_KEYSYM, EekKeysymPrivate))
|
||||
|
||||
static EekSerializableIface *eek_keysym_parent_serializable_iface;
|
||||
|
||||
@ -81,8 +81,7 @@ static void
|
||||
eek_keysym_real_serialize (EekSerializable *self,
|
||||
GVariantBuilder *builder)
|
||||
{
|
||||
EekKeysymPrivate *priv = eek_keysym_get_instance_private (
|
||||
EEK_KEYSYM(self));
|
||||
EekKeysymPrivate *priv = EEK_KEYSYM_GET_PRIVATE(self);
|
||||
|
||||
eek_keysym_parent_serializable_iface->serialize (self, builder);
|
||||
|
||||
@ -94,8 +93,7 @@ eek_keysym_real_deserialize (EekSerializable *self,
|
||||
GVariant *variant,
|
||||
gsize index)
|
||||
{
|
||||
EekKeysymPrivate *priv = eek_keysym_get_instance_private (
|
||||
EEK_KEYSYM(self));
|
||||
EekKeysymPrivate *priv = EEK_KEYSYM_GET_PRIVATE(self);
|
||||
|
||||
index = eek_keysym_parent_serializable_iface->deserialize (self,
|
||||
variant,
|
||||
@ -179,7 +177,7 @@ get_modifier_mask (guint xkeysym)
|
||||
case EEK_KEYSYM_Shift_Lock:
|
||||
return EEK_SHIFT_MASK;
|
||||
case EEK_KEYSYM_ISO_Level3_Shift:
|
||||
return EEK_BUTTON1_MASK;
|
||||
return EEK_MOD5_MASK;
|
||||
case EEK_KEYSYM_Control_L:
|
||||
case EEK_KEYSYM_Control_R:
|
||||
return EEK_CONTROL_MASK;
|
||||
@ -202,13 +200,15 @@ get_modifier_mask (guint xkeysym)
|
||||
static void
|
||||
eek_keysym_class_init (EekKeysymClass *klass)
|
||||
{
|
||||
/* void */
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
g_type_class_add_private (gobject_class, sizeof (EekKeysymPrivate));
|
||||
}
|
||||
|
||||
static void
|
||||
eek_keysym_init (EekKeysym *self)
|
||||
{
|
||||
/* void */
|
||||
self->priv = EEK_KEYSYM_GET_PRIVATE(self);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -291,7 +291,7 @@ eek_keysym_new_with_modifier (guint xkeysym,
|
||||
g_slice_free (EekKeysymEntry, unichar_entry);
|
||||
}
|
||||
|
||||
priv = eek_keysym_get_instance_private (keysym);
|
||||
priv = EEK_KEYSYM_GET_PRIVATE(keysym);
|
||||
priv->xkeysym = xkeysym;
|
||||
|
||||
return keysym;
|
||||
@ -345,6 +345,6 @@ eek_keysym_get_xkeysym (EekKeysym *keysym)
|
||||
EekKeysymPrivate *priv;
|
||||
|
||||
g_assert (EEK_IS_KEYSYM(keysym));
|
||||
priv = eek_keysym_get_instance_private (keysym);
|
||||
priv = EEK_KEYSYM_GET_PRIVATE(keysym);
|
||||
return priv->xkeysym;
|
||||
}
|
||||
|
||||
@ -38,7 +38,27 @@ G_BEGIN_DECLS
|
||||
#define EEK_INVALID_KEYSYM (0)
|
||||
|
||||
#define EEK_TYPE_KEYSYM (eek_keysym_get_type())
|
||||
G_DECLARE_DERIVABLE_TYPE (EekKeysym, eek_keysym, EEK, KEYSYM, EekSymbol)
|
||||
#define EEK_KEYSYM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EEK_TYPE_KEYSYM, EekKeysym))
|
||||
#define EEK_KEYSYM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EEK_TYPE_KEYSYM, EekKeysymClass))
|
||||
#define EEK_IS_KEYSYM(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EEK_TYPE_KEYSYM))
|
||||
#define EEK_IS_KEYSYM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EEK_TYPE_KEYSYM))
|
||||
#define EEK_KEYSYM_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EEK_TYPE_KEYSYM, EekKeysymClass))
|
||||
|
||||
typedef struct _EekKeysymClass EekKeysymClass;
|
||||
typedef struct _EekKeysymPrivate EekKeysymPrivate;
|
||||
|
||||
/**
|
||||
* EekKeysym:
|
||||
*
|
||||
* The #EekKeysym structure contains only private data and should only
|
||||
* be accessed using the provided API.
|
||||
*/
|
||||
struct _EekKeysym {
|
||||
/*< private >*/
|
||||
EekSymbol parent;
|
||||
|
||||
EekKeysymPrivate *priv;
|
||||
};
|
||||
|
||||
struct _EekKeysymClass {
|
||||
/*< private >*/
|
||||
|
||||
@ -32,9 +32,8 @@
|
||||
|
||||
#include "eek-layout.h"
|
||||
#include "eek-keyboard.h"
|
||||
#include "eekboard/eekboard-context-service.h"
|
||||
|
||||
G_DEFINE_ABSTRACT_TYPE (EekLayout, eek_layout, G_TYPE_OBJECT)
|
||||
G_DEFINE_ABSTRACT_TYPE (EekLayout, eek_layout, G_TYPE_OBJECT);
|
||||
|
||||
static void
|
||||
eek_layout_class_init (EekLayoutClass *klass)
|
||||
@ -56,16 +55,14 @@ eek_layout_init (EekLayout *self)
|
||||
* Create a new #EekKeyboard based on @layout.
|
||||
*/
|
||||
EekKeyboard *
|
||||
eek_keyboard_new (EekboardContextService *manager,
|
||||
EekLayout *layout,
|
||||
eek_keyboard_new (EekLayout *layout,
|
||||
gdouble initial_width,
|
||||
gdouble initial_height)
|
||||
{
|
||||
g_assert (EEK_IS_LAYOUT(layout));
|
||||
g_assert (EEK_LAYOUT_GET_CLASS(layout)->create_keyboard);
|
||||
|
||||
return EEK_LAYOUT_GET_CLASS(layout)->create_keyboard (manager,
|
||||
layout,
|
||||
return EEK_LAYOUT_GET_CLASS(layout)->create_keyboard (layout,
|
||||
initial_width,
|
||||
initial_height);
|
||||
}
|
||||
|
||||
@ -31,7 +31,20 @@
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define EEK_TYPE_LAYOUT (eek_layout_get_type())
|
||||
G_DECLARE_DERIVABLE_TYPE (EekLayout, eek_layout, EEK, LAYOUT, GObject)
|
||||
#define EEK_LAYOUT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EEK_TYPE_LAYOUT, EekLayout))
|
||||
#define EEK_LAYOUT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EEK_TYPE_LAYOUT, EekLayoutClass))
|
||||
#define EEK_IS_LAYOUT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EEK_TYPE_LAYOUT))
|
||||
#define EEK_IS_LAYOUT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EEK_TYPE_LAYOUT))
|
||||
#define EEK_LAYOUT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EEK_TYPE_LAYOUT, EekLayoutClass))
|
||||
|
||||
typedef struct _EekLayoutClass EekLayoutClass;
|
||||
typedef struct _EekLayout EekLayout;
|
||||
|
||||
struct _EekLayout
|
||||
{
|
||||
/*< private >*/
|
||||
GObject parent;
|
||||
};
|
||||
|
||||
/**
|
||||
* EekLayoutClass:
|
||||
@ -43,8 +56,7 @@ struct _EekLayoutClass
|
||||
GObjectClass parent_class;
|
||||
|
||||
/*< public >*/
|
||||
EekKeyboard* (* create_keyboard) (EekboardContextService *manager,
|
||||
EekLayout *self,
|
||||
EekKeyboard* (* create_keyboard) (EekLayout *self,
|
||||
gdouble initial_width,
|
||||
gdouble initial_height);
|
||||
|
||||
|
||||
@ -36,7 +36,12 @@ enum {
|
||||
PROP_LAST
|
||||
};
|
||||
|
||||
typedef struct _EekRendererPrivate
|
||||
G_DEFINE_TYPE (EekRenderer, eek_renderer, G_TYPE_OBJECT);
|
||||
|
||||
#define EEK_RENDERER_GET_PRIVATE(obj) \
|
||||
(G_TYPE_INSTANCE_GET_PRIVATE ((obj), EEK_TYPE_RENDERER, EekRendererPrivate))
|
||||
|
||||
struct _EekRendererPrivate
|
||||
{
|
||||
EekKeyboard *keyboard;
|
||||
PangoContext *pcontext;
|
||||
@ -48,7 +53,6 @@ typedef struct _EekRendererPrivate
|
||||
gdouble allocation_width;
|
||||
gdouble allocation_height;
|
||||
gdouble scale;
|
||||
gint scale_factor; /* the outputs scale factor */
|
||||
|
||||
PangoFontDescription *ascii_font;
|
||||
PangoFontDescription *font;
|
||||
@ -58,9 +62,7 @@ typedef struct _EekRendererPrivate
|
||||
gulong symbol_index_changed_handler;
|
||||
|
||||
EekTheme *theme;
|
||||
} EekRendererPrivate;
|
||||
|
||||
G_DEFINE_TYPE_WITH_PRIVATE (EekRenderer, eek_renderer, G_TYPE_OBJECT)
|
||||
};
|
||||
|
||||
static const EekColor DEFAULT_FOREGROUND_COLOR = {0.3, 0.3, 0.3, 1.0};
|
||||
static const EekColor DEFAULT_BACKGROUND_COLOR = {1.0, 1.0, 1.0, 1.0};
|
||||
@ -77,7 +79,7 @@ typedef struct _TextProperty TextProperty;
|
||||
extern void _eek_rounded_polygon (cairo_t *cr,
|
||||
gdouble radius,
|
||||
EekPoint *points,
|
||||
guint num_points);
|
||||
gint num_points);
|
||||
|
||||
static void eek_renderer_real_render_key_label (EekRenderer *self,
|
||||
PangoLayout *layout,
|
||||
@ -104,7 +106,7 @@ create_keyboard_surface_key_callback (EekElement *element,
|
||||
gpointer user_data)
|
||||
{
|
||||
CreateKeyboardSurfaceCallbackData *data = user_data;
|
||||
EekRendererPrivate *priv = eek_renderer_get_instance_private (data->renderer);
|
||||
EekRendererPrivate *priv = EEK_RENDERER_GET_PRIVATE(data->renderer);
|
||||
EekBounds bounds;
|
||||
|
||||
cairo_save (data->cr);
|
||||
@ -114,8 +116,8 @@ create_keyboard_surface_key_callback (EekElement *element,
|
||||
cairo_rectangle (data->cr,
|
||||
0.0,
|
||||
0.0,
|
||||
bounds.width * priv->scale + 100,
|
||||
bounds.height * priv->scale + 100);
|
||||
bounds.width * priv->scale,
|
||||
bounds.height * priv->scale);
|
||||
cairo_clip (data->cr);
|
||||
render_key (data->renderer, data->cr, EEK_KEY(element), FALSE);
|
||||
|
||||
@ -127,7 +129,7 @@ create_keyboard_surface_section_callback (EekElement *element,
|
||||
gpointer user_data)
|
||||
{
|
||||
CreateKeyboardSurfaceCallbackData *data = user_data;
|
||||
EekRendererPrivate *priv = eek_renderer_get_instance_private (data->renderer);
|
||||
EekRendererPrivate *priv = EEK_RENDERER_GET_PRIVATE(data->renderer);
|
||||
EekBounds bounds;
|
||||
gint angle;
|
||||
|
||||
@ -149,7 +151,7 @@ create_keyboard_surface_section_callback (EekElement *element,
|
||||
static cairo_surface_t *
|
||||
create_keyboard_surface (EekRenderer *renderer)
|
||||
{
|
||||
EekRendererPrivate *priv = eek_renderer_get_instance_private (renderer);
|
||||
EekRendererPrivate *priv = EEK_RENDERER_GET_PRIVATE(renderer);
|
||||
EekBounds bounds;
|
||||
cairo_surface_t *keyboard_surface;
|
||||
CreateKeyboardSurfaceCallbackData data;
|
||||
@ -163,14 +165,9 @@ create_keyboard_surface (EekRenderer *renderer)
|
||||
&background);
|
||||
|
||||
eek_element_get_bounds (EEK_ELEMENT(priv->keyboard), &bounds);
|
||||
|
||||
/* Create a surface that encompasses the dimensions of the keyboard as well
|
||||
as the margin around the edge. */
|
||||
keyboard_surface = cairo_image_surface_create (
|
||||
CAIRO_FORMAT_ARGB32,
|
||||
ceil(((bounds.x * 2) + bounds.width) * priv->scale),
|
||||
ceil(((bounds.y * 2) + bounds.height) * priv->scale));
|
||||
|
||||
keyboard_surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
|
||||
bounds.width * priv->scale,
|
||||
bounds.height * priv->scale);
|
||||
data.cr = cairo_create (keyboard_surface);
|
||||
data.renderer = renderer;
|
||||
|
||||
@ -205,9 +202,11 @@ render_key_outline (EekRenderer *renderer,
|
||||
EekKey *key,
|
||||
gboolean active)
|
||||
{
|
||||
EekRendererPrivate *priv = eek_renderer_get_instance_private (renderer);
|
||||
EekRendererPrivate *priv = EEK_RENDERER_GET_PRIVATE(renderer);
|
||||
EekOutline *outline;
|
||||
EekBounds bounds;
|
||||
gdouble scale;
|
||||
gint i;
|
||||
guint oref;
|
||||
EekThemeNode *theme_node;
|
||||
EekColor foreground, background, gradient_start, gradient_end, border_color;
|
||||
@ -234,14 +233,14 @@ render_key_outline (EekRenderer *renderer,
|
||||
border_width = eek_theme_node_get_border_width (theme_node,
|
||||
EEK_SIDE_TOP);
|
||||
border_radius = eek_theme_node_get_border_radius (theme_node,
|
||||
EEK_CORNER_TOPLEFT);
|
||||
EEK_SIDE_TOP);
|
||||
eek_theme_node_get_border_color (theme_node, EEK_SIDE_TOP,
|
||||
&border_color);
|
||||
} else {
|
||||
foreground = priv->default_foreground_color;
|
||||
background = priv->default_background_color;
|
||||
gradient_type = EEK_GRADIENT_NONE;
|
||||
border_width = (gint)round(priv->border_width);
|
||||
border_width = priv->border_width;
|
||||
border_radius = -1;
|
||||
border_color.red = ABS(background.red - foreground.red) * 0.7;
|
||||
border_color.green = ABS(background.green - foreground.green) * 0.7;
|
||||
@ -249,17 +248,21 @@ render_key_outline (EekRenderer *renderer,
|
||||
border_color.alpha = foreground.alpha;
|
||||
}
|
||||
|
||||
eek_element_get_bounds(EEK_ELEMENT(key), &bounds);
|
||||
outline = eek_outline_copy (outline);
|
||||
/* need to rescale so that the border fit inside the clipping
|
||||
region */
|
||||
eek_element_get_bounds (EEK_ELEMENT(key), &bounds);
|
||||
scale = MIN((bounds.width - border_width * 2) / bounds.width,
|
||||
(bounds.height - border_width * 2) / bounds.height);
|
||||
|
||||
for (guint i = 0; i < outline->num_points; i++) {
|
||||
outline->points[i].x *= priv->scale;
|
||||
outline->points[i].y *= priv->scale;
|
||||
outline = eek_outline_copy (outline);
|
||||
for (i = 0; i < outline->num_points; i++) {
|
||||
outline->points[i].x *= priv->scale * scale;
|
||||
outline->points[i].y *= priv->scale * scale;
|
||||
}
|
||||
|
||||
cairo_translate (cr,
|
||||
border_width * priv->scale,
|
||||
border_width * priv->scale);
|
||||
border_width * priv->scale * scale,
|
||||
border_width * priv->scale * scale);
|
||||
|
||||
if (gradient_type != EEK_GRADIENT_NONE) {
|
||||
cairo_pattern_t *pat;
|
||||
@ -337,10 +340,6 @@ render_key_outline (EekRenderer *renderer,
|
||||
outline->num_points);
|
||||
cairo_stroke (cr);
|
||||
|
||||
cairo_translate (cr,
|
||||
-border_width * priv->scale,
|
||||
-border_width * priv->scale);
|
||||
|
||||
eek_outline_free (outline);
|
||||
}
|
||||
|
||||
@ -356,7 +355,7 @@ static void
|
||||
calculate_font_size_key_callback (EekElement *element, gpointer user_data)
|
||||
{
|
||||
CalculateFontSizeCallbackData *data = user_data;
|
||||
EekRendererPrivate *priv = eek_renderer_get_instance_private (data->renderer);
|
||||
EekRendererPrivate *priv = EEK_RENDERER_GET_PRIVATE(data->renderer);
|
||||
gdouble sx, sy;
|
||||
PangoFontDescription *font;
|
||||
PangoRectangle extents = { 0, };
|
||||
@ -416,7 +415,7 @@ calculate_font_size (EekRenderer *renderer,
|
||||
const PangoFontDescription *base_font,
|
||||
gboolean ascii)
|
||||
{
|
||||
EekRendererPrivate *priv = eek_renderer_get_instance_private (renderer);
|
||||
EekRendererPrivate *priv = EEK_RENDERER_GET_PRIVATE(renderer);
|
||||
CalculateFontSizeCallbackData data;
|
||||
|
||||
data.size = G_MAXDOUBLE;
|
||||
@ -435,7 +434,7 @@ render_key (EekRenderer *self,
|
||||
EekKey *key,
|
||||
gboolean active)
|
||||
{
|
||||
EekRendererPrivate *priv = eek_renderer_get_instance_private (self);
|
||||
EekRendererPrivate *priv = EEK_RENDERER_GET_PRIVATE(self);
|
||||
EekOutline *outline;
|
||||
cairo_surface_t *outline_surface;
|
||||
EekBounds bounds;
|
||||
@ -465,12 +464,10 @@ render_key (EekRenderer *self,
|
||||
if (!outline_surface) {
|
||||
cairo_t *cr;
|
||||
|
||||
// Outline will be drawn on the outside of the button, so the
|
||||
// surface needs to be bigger than the button
|
||||
outline_surface =
|
||||
cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
|
||||
(int)ceil(bounds.width) + 10,
|
||||
(int)ceil(bounds.height) + 10);
|
||||
bounds.width,
|
||||
bounds.height);
|
||||
cr = cairo_create (outline_surface);
|
||||
|
||||
/* blank background */
|
||||
@ -492,38 +489,44 @@ render_key (EekRenderer *self,
|
||||
cairo_set_source_surface (cr, outline_surface, 0.0, 0.0);
|
||||
cairo_paint (cr);
|
||||
|
||||
eek_renderer_get_foreground_color (self, EEK_ELEMENT(key), &foreground);
|
||||
/* render icon (if any) */
|
||||
symbol = eek_key_get_symbol_with_fallback (key, 0, 0);
|
||||
if (!symbol)
|
||||
return;
|
||||
|
||||
#define SCALE 0.4
|
||||
if (eek_symbol_get_icon_name (symbol)) {
|
||||
gint scale = priv->scale_factor;
|
||||
cairo_surface_t *icon_surface =
|
||||
eek_renderer_get_icon_surface (self,
|
||||
eek_symbol_get_icon_name (symbol),
|
||||
SCALE * MIN(bounds.width, bounds.height),
|
||||
scale);
|
||||
MIN(bounds.width, bounds.height) * 0.7);
|
||||
if (icon_surface) {
|
||||
gint width = cairo_image_surface_get_width (icon_surface);
|
||||
gint height = cairo_image_surface_get_height (icon_surface);
|
||||
gdouble scale;
|
||||
|
||||
if (width < bounds.width && height < bounds.height)
|
||||
scale = 1;
|
||||
else {
|
||||
if (height * bounds.width / width <= bounds.height)
|
||||
scale = bounds.width / width;
|
||||
else if (width * bounds.height / height <= bounds.width)
|
||||
scale = bounds.height / height;
|
||||
else {
|
||||
if (width * bounds.height < height * bounds.width)
|
||||
scale = width / bounds.width;
|
||||
else
|
||||
scale = height / bounds.height;
|
||||
}
|
||||
}
|
||||
|
||||
cairo_save (cr);
|
||||
cairo_translate (cr,
|
||||
(bounds.width - width / scale) / 2,
|
||||
(bounds.height - height / scale) / 2);
|
||||
(bounds.width - width * scale) / 2,
|
||||
(bounds.height - height * scale) / 2);
|
||||
cairo_rectangle (cr, 0, 0, width, height);
|
||||
cairo_clip (cr);
|
||||
/* Draw the shape of the icon using the foreground color */
|
||||
cairo_set_source_rgba (cr, foreground.red,
|
||||
foreground.green,
|
||||
foreground.blue,
|
||||
foreground.alpha);
|
||||
cairo_mask_surface (cr, icon_surface, 0.0, 0.0);
|
||||
cairo_fill (cr);
|
||||
|
||||
cairo_set_source_surface (cr, icon_surface, 0.0, 0.0);
|
||||
cairo_paint (cr);
|
||||
cairo_restore (cr);
|
||||
return;
|
||||
}
|
||||
@ -540,6 +543,7 @@ render_key (EekRenderer *self,
|
||||
(bounds.width - extents.width / PANGO_SCALE) / 2,
|
||||
(bounds.height - extents.height / PANGO_SCALE) / 2);
|
||||
|
||||
eek_renderer_get_foreground_color (self, EEK_ELEMENT(key), &foreground);
|
||||
cairo_set_source_rgba (cr,
|
||||
foreground.red,
|
||||
foreground.green,
|
||||
@ -602,7 +606,7 @@ eek_renderer_real_render_key_label (EekRenderer *self,
|
||||
PangoLayout *layout,
|
||||
EekKey *key)
|
||||
{
|
||||
EekRendererPrivate *priv = eek_renderer_get_instance_private (self);
|
||||
EekRendererPrivate *priv = EEK_RENDERER_GET_PRIVATE(self);
|
||||
EekSymbol *symbol;
|
||||
EekSymbolCategory category;
|
||||
const gchar *label;
|
||||
@ -636,7 +640,7 @@ eek_renderer_real_render_key_label (EekRenderer *self,
|
||||
|
||||
size = calculate_font_size (self, base_font, FALSE);
|
||||
priv->font = pango_font_description_copy (base_font);
|
||||
pango_font_description_set_size (priv->font, size * 0.6);
|
||||
pango_font_description_set_size (priv->font, size);
|
||||
}
|
||||
|
||||
eek_element_get_bounds (EEK_ELEMENT(key), &bounds);
|
||||
@ -695,7 +699,7 @@ static void
|
||||
eek_renderer_real_render_keyboard (EekRenderer *self,
|
||||
cairo_t *cr)
|
||||
{
|
||||
EekRendererPrivate *priv = eek_renderer_get_instance_private (self);
|
||||
EekRendererPrivate *priv = EEK_RENDERER_GET_PRIVATE(self);
|
||||
cairo_pattern_t *source;
|
||||
|
||||
g_return_if_fail (priv->keyboard);
|
||||
@ -717,8 +721,7 @@ eek_renderer_set_property (GObject *object,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
EekRendererPrivate *priv = eek_renderer_get_instance_private (
|
||||
EEK_RENDERER(object));
|
||||
EekRendererPrivate *priv = EEK_RENDERER_GET_PRIVATE(object);
|
||||
|
||||
switch (prop_id) {
|
||||
case PROP_KEYBOARD:
|
||||
@ -746,8 +749,7 @@ eek_renderer_get_property (GObject *object,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
EekRendererPrivate *priv = eek_renderer_get_instance_private (
|
||||
EEK_RENDERER(object));
|
||||
EekRendererPrivate *priv = EEK_RENDERER_GET_PRIVATE(object);
|
||||
|
||||
switch (prop_id) {
|
||||
case PROP_KEYBOARD:
|
||||
@ -762,8 +764,7 @@ eek_renderer_get_property (GObject *object,
|
||||
static void
|
||||
eek_renderer_dispose (GObject *object)
|
||||
{
|
||||
EekRenderer *self = EEK_RENDERER (object);
|
||||
EekRendererPrivate *priv = eek_renderer_get_instance_private (self);
|
||||
EekRendererPrivate *priv = EEK_RENDERER_GET_PRIVATE(object);
|
||||
|
||||
if (priv->keyboard) {
|
||||
if (g_signal_handler_is_connected (priv->keyboard,
|
||||
@ -787,9 +788,7 @@ eek_renderer_dispose (GObject *object)
|
||||
static void
|
||||
eek_renderer_finalize (GObject *object)
|
||||
{
|
||||
EekRenderer *self = EEK_RENDERER(object);
|
||||
EekRendererPrivate *priv = eek_renderer_get_instance_private (self);
|
||||
|
||||
EekRendererPrivate *priv = EEK_RENDERER_GET_PRIVATE(object);
|
||||
g_hash_table_destroy (priv->outline_surface_cache);
|
||||
g_hash_table_destroy (priv->active_outline_surface_cache);
|
||||
pango_font_description_free (priv->ascii_font);
|
||||
@ -803,6 +802,9 @@ eek_renderer_class_init (EekRendererClass *klass)
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||
GParamSpec *pspec;
|
||||
|
||||
g_type_class_add_private (gobject_class,
|
||||
sizeof (EekRendererPrivate));
|
||||
|
||||
klass->render_key_label = eek_renderer_real_render_key_label;
|
||||
klass->render_key_outline = eek_renderer_real_render_key_outline;
|
||||
klass->render_key = eek_renderer_real_render_key;
|
||||
@ -835,8 +837,9 @@ eek_renderer_class_init (EekRendererClass *klass)
|
||||
static void
|
||||
eek_renderer_init (EekRenderer *self)
|
||||
{
|
||||
EekRendererPrivate *priv = eek_renderer_get_instance_private (self);
|
||||
EekRendererPrivate *priv;
|
||||
|
||||
priv = self->priv = EEK_RENDERER_GET_PRIVATE(self);
|
||||
priv->keyboard = NULL;
|
||||
priv->pcontext = NULL;
|
||||
priv->default_foreground_color = DEFAULT_FOREGROUND_COLOR;
|
||||
@ -845,7 +848,6 @@ eek_renderer_init (EekRenderer *self)
|
||||
priv->allocation_width = 0.0;
|
||||
priv->allocation_height = 0.0;
|
||||
priv->scale = 1.0;
|
||||
priv->scale_factor = 1;
|
||||
priv->font = NULL;
|
||||
priv->outline_surface_cache =
|
||||
g_hash_table_new_full (g_direct_hash,
|
||||
@ -864,17 +866,15 @@ eek_renderer_init (EekRenderer *self)
|
||||
static void
|
||||
invalidate (EekRenderer *renderer)
|
||||
{
|
||||
EekRendererPrivate *priv = eek_renderer_get_instance_private (renderer);
|
||||
if (renderer->priv->outline_surface_cache)
|
||||
g_hash_table_remove_all (renderer->priv->outline_surface_cache);
|
||||
|
||||
if (priv->outline_surface_cache)
|
||||
g_hash_table_remove_all (priv->outline_surface_cache);
|
||||
if (renderer->priv->active_outline_surface_cache)
|
||||
g_hash_table_remove_all (renderer->priv->active_outline_surface_cache);
|
||||
|
||||
if (priv->active_outline_surface_cache)
|
||||
g_hash_table_remove_all (priv->active_outline_surface_cache);
|
||||
|
||||
if (priv->keyboard_surface) {
|
||||
cairo_surface_destroy (priv->keyboard_surface);
|
||||
priv->keyboard_surface = NULL;
|
||||
if (renderer->priv->keyboard_surface) {
|
||||
cairo_surface_destroy (renderer->priv->keyboard_surface);
|
||||
renderer->priv->keyboard_surface = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
@ -909,12 +909,10 @@ eek_renderer_set_allocation_size (EekRenderer *renderer,
|
||||
g_return_if_fail (EEK_IS_RENDERER(renderer));
|
||||
g_return_if_fail (width > 0.0 && height > 0.0);
|
||||
|
||||
EekRendererPrivate *priv = eek_renderer_get_instance_private (renderer);
|
||||
renderer->priv->allocation_width = width;
|
||||
renderer->priv->allocation_height = height;
|
||||
|
||||
priv->allocation_width = width;
|
||||
priv->allocation_height = height;
|
||||
|
||||
eek_element_get_bounds (EEK_ELEMENT(priv->keyboard), &bounds);
|
||||
eek_element_get_bounds (EEK_ELEMENT(renderer->priv->keyboard), &bounds);
|
||||
|
||||
if (bounds.height * width / bounds.width <= height)
|
||||
scale = width / bounds.width;
|
||||
@ -927,8 +925,8 @@ eek_renderer_set_allocation_size (EekRenderer *renderer,
|
||||
scale = bounds.height / height;
|
||||
}
|
||||
|
||||
if (scale != priv->scale) {
|
||||
priv->scale = scale;
|
||||
if (scale != renderer->priv->scale) {
|
||||
renderer->priv->scale = scale;
|
||||
invalidate (renderer);
|
||||
}
|
||||
}
|
||||
@ -942,13 +940,11 @@ eek_renderer_get_size (EekRenderer *renderer,
|
||||
|
||||
g_return_if_fail (EEK_IS_RENDERER(renderer));
|
||||
|
||||
EekRendererPrivate *priv = eek_renderer_get_instance_private (renderer);
|
||||
|
||||
eek_element_get_bounds (EEK_ELEMENT(priv->keyboard), &bounds);
|
||||
eek_element_get_bounds (EEK_ELEMENT(renderer->priv->keyboard), &bounds);
|
||||
if (width)
|
||||
*width = bounds.width * priv->scale;
|
||||
*width = bounds.width * renderer->priv->scale;
|
||||
if (height)
|
||||
*height = bounds.height * priv->scale;
|
||||
*height = bounds.height * renderer->priv->scale;
|
||||
}
|
||||
|
||||
void
|
||||
@ -967,22 +963,20 @@ eek_renderer_get_key_bounds (EekRenderer *renderer,
|
||||
g_return_if_fail (EEK_IS_KEY(key));
|
||||
g_return_if_fail (bounds != NULL);
|
||||
|
||||
EekRendererPrivate *priv = eek_renderer_get_instance_private (renderer);
|
||||
|
||||
section = eek_element_get_parent (EEK_ELEMENT(key));
|
||||
|
||||
eek_element_get_bounds (EEK_ELEMENT(key), bounds);
|
||||
eek_element_get_bounds (section, §ion_bounds);
|
||||
eek_element_get_bounds (EEK_ELEMENT(priv->keyboard),
|
||||
eek_element_get_bounds (EEK_ELEMENT(renderer->priv->keyboard),
|
||||
&keyboard_bounds);
|
||||
|
||||
if (!rotate) {
|
||||
bounds->x += keyboard_bounds.x + section_bounds.x;
|
||||
bounds->y += keyboard_bounds.y + section_bounds.y;
|
||||
bounds->x *= priv->scale;
|
||||
bounds->y *= priv->scale;
|
||||
bounds->width *= priv->scale;
|
||||
bounds->height *= priv->scale;
|
||||
bounds->x *= renderer->priv->scale;
|
||||
bounds->y *= renderer->priv->scale;
|
||||
bounds->width *= renderer->priv->scale;
|
||||
bounds->height *= renderer->priv->scale;
|
||||
return;
|
||||
}
|
||||
points[0].x = bounds->x;
|
||||
@ -1014,39 +1008,24 @@ eek_renderer_get_key_bounds (EekRenderer *renderer,
|
||||
bounds->y = keyboard_bounds.y + section_bounds.y + min.y;
|
||||
bounds->width = (max.x - min.x);
|
||||
bounds->height = (max.y - min.y);
|
||||
bounds->x *= priv->scale;
|
||||
bounds->y *= priv->scale;
|
||||
bounds->width *= priv->scale;
|
||||
bounds->height *= priv->scale;
|
||||
bounds->x *= renderer->priv->scale;
|
||||
bounds->y *= renderer->priv->scale;
|
||||
bounds->width *= renderer->priv->scale;
|
||||
bounds->height *= renderer->priv->scale;
|
||||
}
|
||||
|
||||
gdouble
|
||||
eek_renderer_get_scale (EekRenderer *renderer)
|
||||
{
|
||||
g_return_val_if_fail (EEK_IS_RENDERER(renderer), 0);
|
||||
|
||||
EekRendererPrivate *priv = eek_renderer_get_instance_private (renderer);
|
||||
|
||||
return priv->scale;
|
||||
}
|
||||
|
||||
void
|
||||
eek_renderer_set_scale_factor (EekRenderer *renderer, gint scale)
|
||||
{
|
||||
g_return_if_fail (EEK_IS_RENDERER(renderer));
|
||||
|
||||
EekRendererPrivate *priv = eek_renderer_get_instance_private (renderer);
|
||||
priv->scale_factor = scale;
|
||||
return renderer->priv->scale;
|
||||
}
|
||||
|
||||
PangoLayout *
|
||||
eek_renderer_create_pango_layout (EekRenderer *renderer)
|
||||
{
|
||||
g_return_val_if_fail (EEK_IS_RENDERER(renderer), NULL);
|
||||
|
||||
EekRendererPrivate *priv = eek_renderer_get_instance_private (renderer);
|
||||
|
||||
return pango_layout_new (priv->pcontext);
|
||||
return pango_layout_new (renderer->priv->pcontext);
|
||||
}
|
||||
|
||||
void
|
||||
@ -1082,8 +1061,7 @@ eek_renderer_render_key_outline (EekRenderer *renderer,
|
||||
cairo_surface_t *
|
||||
eek_renderer_get_icon_surface (EekRenderer *renderer,
|
||||
const gchar *icon_name,
|
||||
gint size,
|
||||
gint scale)
|
||||
gint size)
|
||||
{
|
||||
EekRendererClass *klass;
|
||||
|
||||
@ -1091,7 +1069,7 @@ eek_renderer_get_icon_surface (EekRenderer *renderer,
|
||||
|
||||
klass = EEK_RENDERER_GET_CLASS(renderer);
|
||||
if (klass->get_icon_surface)
|
||||
return klass->get_icon_surface (renderer, icon_name, size, scale);
|
||||
return klass->get_icon_surface (renderer, icon_name, size);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -1125,9 +1103,7 @@ eek_renderer_set_default_foreground_color (EekRenderer *renderer,
|
||||
g_return_if_fail (EEK_IS_RENDERER(renderer));
|
||||
g_return_if_fail (color);
|
||||
|
||||
EekRendererPrivate *priv = eek_renderer_get_instance_private (renderer);
|
||||
|
||||
memcpy (&priv->default_foreground_color, color, sizeof(EekColor));
|
||||
memcpy (&renderer->priv->default_foreground_color, color, sizeof(EekColor));
|
||||
}
|
||||
|
||||
void
|
||||
@ -1137,9 +1113,7 @@ eek_renderer_set_default_background_color (EekRenderer *renderer,
|
||||
g_return_if_fail (EEK_IS_RENDERER(renderer));
|
||||
g_return_if_fail (color);
|
||||
|
||||
EekRendererPrivate *priv = eek_renderer_get_instance_private (renderer);
|
||||
|
||||
memcpy (&priv->default_background_color, color, sizeof(EekColor));
|
||||
memcpy (&renderer->priv->default_background_color, color, sizeof(EekColor));
|
||||
}
|
||||
|
||||
void
|
||||
@ -1152,13 +1126,11 @@ eek_renderer_get_foreground_color (EekRenderer *renderer,
|
||||
g_return_if_fail (EEK_IS_RENDERER(renderer));
|
||||
g_return_if_fail (color);
|
||||
|
||||
EekRendererPrivate *priv = eek_renderer_get_instance_private (renderer);
|
||||
|
||||
theme_node = g_object_get_data (G_OBJECT(element), "theme-node");
|
||||
if (theme_node)
|
||||
eek_theme_node_get_foreground_color (theme_node, color);
|
||||
else
|
||||
memcpy (color, &priv->default_foreground_color,
|
||||
memcpy (color, &renderer->priv->default_foreground_color,
|
||||
sizeof(EekColor));
|
||||
}
|
||||
|
||||
@ -1172,13 +1144,11 @@ eek_renderer_get_background_color (EekRenderer *renderer,
|
||||
g_return_if_fail (EEK_IS_RENDERER(renderer));
|
||||
g_return_if_fail (color);
|
||||
|
||||
EekRendererPrivate *priv = eek_renderer_get_instance_private (renderer);
|
||||
|
||||
theme_node = g_object_get_data (G_OBJECT(element), "theme-node");
|
||||
if (theme_node)
|
||||
eek_theme_node_get_background_color (theme_node, color);
|
||||
else
|
||||
memcpy (color, &priv->default_background_color,
|
||||
memcpy (color, &renderer->priv->default_background_color,
|
||||
sizeof(EekColor));
|
||||
}
|
||||
|
||||
@ -1241,14 +1211,12 @@ find_key_by_position_key_callback (EekElement *element,
|
||||
points[3].x = points[0].x;
|
||||
points[3].y = points[2].y;
|
||||
|
||||
EekRendererPrivate *priv = eek_renderer_get_instance_private (data->renderer);
|
||||
|
||||
for (i = 0; i < G_N_ELEMENTS(points); i++) {
|
||||
eek_point_rotate (&points[i], data->angle);
|
||||
points[i].x += data->origin.x;
|
||||
points[i].y += data->origin.y;
|
||||
points[i].x *= priv->scale;
|
||||
points[i].y *= priv->scale;
|
||||
points[i].x *= data->renderer->priv->scale;
|
||||
points[i].y *= data->renderer->priv->scale;
|
||||
}
|
||||
|
||||
b1 = sign (&data->point, &points[0], &points[1]) < 0.0;
|
||||
@ -1303,14 +1271,12 @@ eek_renderer_find_key_by_position (EekRenderer *renderer,
|
||||
|
||||
g_return_val_if_fail (EEK_IS_RENDERER(renderer), NULL);
|
||||
|
||||
EekRendererPrivate *priv = eek_renderer_get_instance_private (renderer);
|
||||
eek_element_get_bounds (EEK_ELEMENT(renderer->priv->keyboard), &bounds);
|
||||
|
||||
eek_element_get_bounds (EEK_ELEMENT(priv->keyboard), &bounds);
|
||||
|
||||
if (x < bounds.x * priv->scale ||
|
||||
y < bounds.y * priv->scale ||
|
||||
x > bounds.width * priv->scale ||
|
||||
y > bounds.height * priv->scale)
|
||||
if (x < bounds.x * renderer->priv->scale ||
|
||||
y < bounds.y * renderer->priv->scale ||
|
||||
x > bounds.width * renderer->priv->scale ||
|
||||
y > bounds.height * renderer->priv->scale)
|
||||
return NULL;
|
||||
|
||||
data.point.x = x;
|
||||
@ -1320,7 +1286,7 @@ eek_renderer_find_key_by_position (EekRenderer *renderer,
|
||||
data.key = NULL;
|
||||
data.renderer = renderer;
|
||||
|
||||
eek_container_find (EEK_CONTAINER(priv->keyboard),
|
||||
eek_container_find (EEK_CONTAINER(renderer->priv->keyboard),
|
||||
find_key_by_position_section_callback,
|
||||
&data);
|
||||
return data.key;
|
||||
@ -1340,11 +1306,9 @@ create_theme_node_key_callback (EekElement *element,
|
||||
CreateThemeNodeData *data = user_data;
|
||||
EekThemeNode *theme_node;
|
||||
|
||||
EekRendererPrivate *priv = eek_renderer_get_instance_private (data->renderer);
|
||||
|
||||
theme_node = eek_theme_node_new (data->context,
|
||||
data->parent,
|
||||
priv->theme,
|
||||
data->renderer->priv->theme,
|
||||
EEK_TYPE_KEY,
|
||||
eek_element_get_name (element),
|
||||
"key",
|
||||
@ -1357,7 +1321,7 @@ create_theme_node_key_callback (EekElement *element,
|
||||
|
||||
theme_node = eek_theme_node_new (data->context,
|
||||
data->parent,
|
||||
priv->theme,
|
||||
data->renderer->priv->theme,
|
||||
EEK_TYPE_KEY,
|
||||
eek_element_get_name (element),
|
||||
"key",
|
||||
@ -1376,11 +1340,9 @@ create_theme_node_section_callback (EekElement *element,
|
||||
CreateThemeNodeData *data = user_data;
|
||||
EekThemeNode *theme_node, *parent;
|
||||
|
||||
EekRendererPrivate *priv = eek_renderer_get_instance_private (data->renderer);
|
||||
|
||||
theme_node = eek_theme_node_new (data->context,
|
||||
data->parent,
|
||||
priv->theme,
|
||||
data->renderer->priv->theme,
|
||||
EEK_TYPE_SECTION,
|
||||
eek_element_get_name (element),
|
||||
"section",
|
||||
@ -1409,25 +1371,22 @@ eek_renderer_set_theme (EekRenderer *renderer,
|
||||
|
||||
g_return_if_fail (EEK_IS_RENDERER(renderer));
|
||||
g_return_if_fail (EEK_IS_THEME(theme));
|
||||
g_return_if_fail (renderer->priv->keyboard);
|
||||
|
||||
EekRendererPrivate *priv = eek_renderer_get_instance_private (renderer);
|
||||
|
||||
g_return_if_fail (priv->keyboard);
|
||||
|
||||
if (priv->theme)
|
||||
g_object_unref (priv->theme);
|
||||
priv->theme = g_object_ref (theme);
|
||||
if (renderer->priv->theme)
|
||||
g_object_unref (renderer->priv->theme);
|
||||
renderer->priv->theme = g_object_ref (theme);
|
||||
|
||||
theme_context = eek_theme_context_new ();
|
||||
theme_node = eek_theme_node_new (theme_context,
|
||||
NULL,
|
||||
priv->theme,
|
||||
renderer->priv->theme,
|
||||
EEK_TYPE_KEYBOARD,
|
||||
"keyboard",
|
||||
"keyboard",
|
||||
NULL,
|
||||
NULL);
|
||||
g_object_set_data_full (G_OBJECT(priv->keyboard),
|
||||
g_object_set_data_full (G_OBJECT(renderer->priv->keyboard),
|
||||
"theme-node",
|
||||
theme_node,
|
||||
(GDestroyNotify)g_object_unref);
|
||||
@ -1435,7 +1394,7 @@ eek_renderer_set_theme (EekRenderer *renderer,
|
||||
data.context = theme_context;
|
||||
data.parent = theme_node;
|
||||
data.renderer = renderer;
|
||||
eek_container_foreach_child (EEK_CONTAINER(priv->keyboard),
|
||||
eek_container_foreach_child (EEK_CONTAINER(renderer->priv->keyboard),
|
||||
create_theme_node_section_callback,
|
||||
&data);
|
||||
}
|
||||
|
||||
@ -31,7 +31,21 @@
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define EEK_TYPE_RENDERER (eek_renderer_get_type())
|
||||
G_DECLARE_DERIVABLE_TYPE (EekRenderer, eek_renderer, EEK, RENDERER, GObject)
|
||||
#define EEK_RENDERER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EEK_TYPE_RENDERER, EekRenderer))
|
||||
#define EEK_RENDERER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EEK_TYPE_RENDERER, EekRendererClass))
|
||||
#define EEK_IS_RENDERER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EEK_TYPE_RENDERER))
|
||||
#define EEK_IS_RENDERER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EEK_TYPE_RENDERER))
|
||||
#define EEK_RENDERER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EEK_TYPE_RENDERER, EekRendererClass))
|
||||
|
||||
typedef struct _EekRenderer EekRenderer;
|
||||
typedef struct _EekRendererClass EekRendererClass;
|
||||
typedef struct _EekRendererPrivate EekRendererPrivate;
|
||||
|
||||
struct _EekRenderer {
|
||||
GObject parent;
|
||||
|
||||
EekRendererPrivate *priv;
|
||||
};
|
||||
|
||||
struct _EekRendererClass
|
||||
{
|
||||
@ -58,8 +72,7 @@ struct _EekRendererClass
|
||||
|
||||
cairo_surface_t *(* get_icon_surface) (EekRenderer *self,
|
||||
const gchar *icon_name,
|
||||
gint size,
|
||||
gint scale);
|
||||
gint size);
|
||||
|
||||
/*< private >*/
|
||||
/* padding */
|
||||
@ -82,8 +95,6 @@ void eek_renderer_get_key_bounds (EekRenderer *renderer,
|
||||
gboolean rotate);
|
||||
|
||||
gdouble eek_renderer_get_scale (EekRenderer *renderer);
|
||||
void eek_renderer_set_scale_factor (EekRenderer *renderer,
|
||||
gint scale);
|
||||
|
||||
PangoLayout *eek_renderer_create_pango_layout
|
||||
(EekRenderer *renderer);
|
||||
@ -106,8 +117,7 @@ void eek_renderer_render_key (EekRenderer *renderer,
|
||||
|
||||
cairo_surface_t *eek_renderer_get_icon_surface (EekRenderer *renderer,
|
||||
const gchar *icon_name,
|
||||
gint size,
|
||||
gint scale);
|
||||
gint size);
|
||||
|
||||
void eek_renderer_render_keyboard (EekRenderer *renderer,
|
||||
cairo_t *cr);
|
||||
|
||||
@ -45,13 +45,21 @@ enum {
|
||||
};
|
||||
|
||||
enum {
|
||||
KEY_PRESSED,
|
||||
KEY_RELEASED,
|
||||
KEY_LOCKED,
|
||||
KEY_UNLOCKED,
|
||||
KEY_CANCELLED,
|
||||
LAST_SIGNAL
|
||||
};
|
||||
|
||||
static guint signals[LAST_SIGNAL] = { 0, };
|
||||
|
||||
G_DEFINE_TYPE (EekSection, eek_section, EEK_TYPE_CONTAINER);
|
||||
|
||||
#define EEK_SECTION_GET_PRIVATE(obj) \
|
||||
(G_TYPE_INSTANCE_GET_PRIVATE ((obj), EEK_TYPE_SECTION, EekSectionPrivate))
|
||||
|
||||
struct _EekRow
|
||||
{
|
||||
gint num_columns;
|
||||
@ -60,19 +68,17 @@ struct _EekRow
|
||||
|
||||
typedef struct _EekRow EekRow;
|
||||
|
||||
typedef struct _EekSectionPrivate
|
||||
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);
|
||||
EekSectionPrivate *priv = EEK_SECTION_GET_PRIVATE(self);
|
||||
|
||||
return g_slist_length (priv->rows);
|
||||
}
|
||||
@ -82,7 +88,7 @@ eek_section_real_add_row (EekSection *self,
|
||||
gint num_columns,
|
||||
EekOrientation orientation)
|
||||
{
|
||||
EekSectionPrivate *priv = eek_section_get_instance_private (self);
|
||||
EekSectionPrivate *priv = EEK_SECTION_GET_PRIVATE(self);
|
||||
EekRow *row;
|
||||
|
||||
row = g_slice_new (EekRow);
|
||||
@ -97,7 +103,7 @@ eek_section_real_get_row (EekSection *self,
|
||||
gint *num_columns,
|
||||
EekOrientation *orientation)
|
||||
{
|
||||
EekSectionPrivate *priv = eek_section_get_instance_private (self);
|
||||
EekSectionPrivate *priv = EEK_SECTION_GET_PRIVATE(self);
|
||||
EekRow *row;
|
||||
|
||||
row = g_slist_nth_data (priv->rows, index);
|
||||
@ -108,6 +114,20 @@ eek_section_real_get_row (EekSection *self,
|
||||
*orientation = row->orientation;
|
||||
}
|
||||
|
||||
static void
|
||||
on_pressed (EekKey *key,
|
||||
EekSection *section)
|
||||
{
|
||||
g_signal_emit (section, signals[KEY_PRESSED], 0, key);
|
||||
}
|
||||
|
||||
static void
|
||||
on_released (EekKey *key,
|
||||
EekSection *section)
|
||||
{
|
||||
g_signal_emit (section, signals[KEY_RELEASED], 0, key);
|
||||
}
|
||||
|
||||
static void
|
||||
on_locked (EekKey *key,
|
||||
EekSection *section)
|
||||
@ -122,6 +142,13 @@ on_unlocked (EekKey *key,
|
||||
g_signal_emit (section, signals[KEY_UNLOCKED], 0, key);
|
||||
}
|
||||
|
||||
static void
|
||||
on_cancelled (EekKey *key,
|
||||
EekSection *section)
|
||||
{
|
||||
g_signal_emit (section, signals[KEY_CANCELLED], 0, key);
|
||||
}
|
||||
|
||||
static EekKey *
|
||||
eek_section_real_create_key (EekSection *self,
|
||||
guint keycode,
|
||||
@ -135,9 +162,7 @@ eek_section_real_create_key (EekSection *self,
|
||||
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);
|
||||
row = g_slist_nth_data (self->priv->rows, row_index);
|
||||
if (row->num_columns < column_index + 1)
|
||||
row->num_columns = column_index + 1;
|
||||
|
||||
@ -157,7 +182,7 @@ eek_section_real_create_key (EekSection *self,
|
||||
static void
|
||||
set_level_from_modifiers (EekSection *self)
|
||||
{
|
||||
EekSectionPrivate *priv = eek_section_get_instance_private (self);
|
||||
EekSectionPrivate *priv = EEK_SECTION_GET_PRIVATE(self);
|
||||
EekKeyboard *keyboard;
|
||||
EekModifierType num_lock_mask;
|
||||
gint level = -1;
|
||||
@ -172,7 +197,7 @@ set_level_from_modifiers (EekSection *self)
|
||||
static void
|
||||
eek_section_real_key_pressed (EekSection *self, EekKey *key)
|
||||
{
|
||||
EekSectionPrivate *priv = eek_section_get_instance_private (self);
|
||||
EekSectionPrivate *priv = EEK_SECTION_GET_PRIVATE(self);
|
||||
EekSymbol *symbol;
|
||||
EekKeyboard *keyboard;
|
||||
EekModifierBehavior behavior;
|
||||
@ -194,7 +219,7 @@ eek_section_real_key_pressed (EekSection *self, EekKey *key)
|
||||
static void
|
||||
eek_section_real_key_released (EekSection *self, EekKey *key)
|
||||
{
|
||||
EekSectionPrivate *priv = eek_section_get_instance_private (self);
|
||||
EekSectionPrivate *priv = EEK_SECTION_GET_PRIVATE(self);
|
||||
EekSymbol *symbol;
|
||||
EekKeyboard *keyboard;
|
||||
EekModifierBehavior behavior;
|
||||
@ -224,8 +249,7 @@ eek_section_real_key_released (EekSection *self, EekKey *key)
|
||||
static void
|
||||
eek_section_finalize (GObject *object)
|
||||
{
|
||||
EekSection *self = EEK_SECTION (object);
|
||||
EekSectionPrivate *priv = eek_section_get_instance_private (self);
|
||||
EekSectionPrivate *priv = EEK_SECTION_GET_PRIVATE(object);
|
||||
GSList *head;
|
||||
|
||||
for (head = priv->rows; head; head = g_slist_next (head))
|
||||
@ -272,16 +296,22 @@ static void
|
||||
eek_section_real_child_added (EekContainer *self,
|
||||
EekElement *element)
|
||||
{
|
||||
g_signal_connect (element, "pressed", G_CALLBACK(on_pressed), self);
|
||||
g_signal_connect (element, "released", G_CALLBACK(on_released), self);
|
||||
g_signal_connect (element, "locked", G_CALLBACK(on_locked), self);
|
||||
g_signal_connect (element, "unlocked", G_CALLBACK(on_unlocked), self);
|
||||
g_signal_connect (element, "cancelled", G_CALLBACK(on_cancelled), self);
|
||||
}
|
||||
|
||||
static void
|
||||
eek_section_real_child_removed (EekContainer *self,
|
||||
EekElement *element)
|
||||
{
|
||||
g_signal_handlers_disconnect_by_func (element, on_pressed, self);
|
||||
g_signal_handlers_disconnect_by_func (element, on_released, self);
|
||||
g_signal_handlers_disconnect_by_func (element, on_locked, self);
|
||||
g_signal_handlers_disconnect_by_func (element, on_unlocked, self);
|
||||
g_signal_handlers_disconnect_by_func (element, on_cancelled, self);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -291,6 +321,8 @@ eek_section_class_init (EekSectionClass *klass)
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||
GParamSpec *pspec;
|
||||
|
||||
g_type_class_add_private (gobject_class, sizeof (EekSectionPrivate));
|
||||
|
||||
klass->get_n_rows = eek_section_real_get_n_rows;
|
||||
klass->add_row = eek_section_real_add_row;
|
||||
klass->get_row = eek_section_real_get_row;
|
||||
@ -321,6 +353,46 @@ eek_section_class_init (EekSectionClass *klass)
|
||||
PROP_ANGLE,
|
||||
pspec);
|
||||
|
||||
/**
|
||||
* EekSection::key-pressed:
|
||||
* @section: an #EekSection
|
||||
* @key: an #EekKey
|
||||
*
|
||||
* The ::key-pressed signal is emitted each time a key in @section
|
||||
* is shifted to the pressed state.
|
||||
*/
|
||||
signals[KEY_PRESSED] =
|
||||
g_signal_new (I_("key-pressed"),
|
||||
G_TYPE_FROM_CLASS(gobject_class),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET(EekSectionClass, key_pressed),
|
||||
NULL,
|
||||
NULL,
|
||||
g_cclosure_marshal_VOID__OBJECT,
|
||||
G_TYPE_NONE,
|
||||
1,
|
||||
EEK_TYPE_KEY);
|
||||
|
||||
/**
|
||||
* EekSection::key-released:
|
||||
* @section: an #EekSection
|
||||
* @key: an #EekKey
|
||||
*
|
||||
* The ::key-released signal is emitted each time a key in @section
|
||||
* is shifted to the released state.
|
||||
*/
|
||||
signals[KEY_RELEASED] =
|
||||
g_signal_new (I_("key-released"),
|
||||
G_TYPE_FROM_CLASS(gobject_class),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET(EekSectionClass, key_released),
|
||||
NULL,
|
||||
NULL,
|
||||
g_cclosure_marshal_VOID__OBJECT,
|
||||
G_TYPE_NONE,
|
||||
1,
|
||||
EEK_TYPE_KEY);
|
||||
|
||||
/**
|
||||
* EekSection::key-locked:
|
||||
* @section: an #EekSection
|
||||
@ -360,12 +432,32 @@ eek_section_class_init (EekSectionClass *klass)
|
||||
G_TYPE_NONE,
|
||||
1,
|
||||
EEK_TYPE_KEY);
|
||||
|
||||
/**
|
||||
* EekSection::key-cancelled:
|
||||
* @section: an #EekSection
|
||||
* @key: an #EekKey
|
||||
*
|
||||
* The ::key-cancelled signal is emitted each time a key in @section
|
||||
* is shifted to the cancelled state.
|
||||
*/
|
||||
signals[KEY_CANCELLED] =
|
||||
g_signal_new (I_("key-cancelled"),
|
||||
G_TYPE_FROM_CLASS(gobject_class),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET(EekSectionClass, key_cancelled),
|
||||
NULL,
|
||||
NULL,
|
||||
g_cclosure_marshal_VOID__OBJECT,
|
||||
G_TYPE_NONE,
|
||||
1,
|
||||
EEK_TYPE_KEY);
|
||||
}
|
||||
|
||||
static void
|
||||
eek_section_init (EekSection *self)
|
||||
{
|
||||
/* void */
|
||||
self->priv = EEK_SECTION_GET_PRIVATE (self);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -380,11 +472,8 @@ 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;
|
||||
if (section->priv->angle != angle) {
|
||||
section->priv->angle = angle;
|
||||
g_object_notify (G_OBJECT(section), "angle");
|
||||
}
|
||||
}
|
||||
@ -399,10 +488,7 @@ 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;
|
||||
return section->priv->angle;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -483,80 +569,3 @@ eek_section_create_key (EekSection *section,
|
||||
column,
|
||||
row);
|
||||
}
|
||||
|
||||
static void keysizer(EekElement *element, gpointer user_data) {
|
||||
EekKey *key = EEK_KEY(element);
|
||||
EekKeyboard *keyboard = EEK_KEYBOARD(user_data);
|
||||
uint oref = eek_key_get_oref (key);
|
||||
EekOutline *outline = eek_keyboard_get_outline (keyboard, oref);
|
||||
if (outline && outline->num_points > 0) {
|
||||
double minx = outline->points[0].x;
|
||||
double maxx = minx;
|
||||
double miny = outline->points[0].y;
|
||||
double maxy = miny;
|
||||
for (uint i = 1; i < outline->num_points; i++) {
|
||||
EekPoint p = outline->points[i];
|
||||
if (p.x < minx) {
|
||||
minx = p.x;
|
||||
} else if (p.x > maxx) {
|
||||
maxx = p.x;
|
||||
}
|
||||
|
||||
if (p.y < miny) {
|
||||
miny = p.y;
|
||||
} else if (p.y > maxy) {
|
||||
maxy = p.y;
|
||||
}
|
||||
}
|
||||
EekBounds key_bounds = {0};
|
||||
eek_element_get_bounds(element, &key_bounds);
|
||||
key_bounds.height = maxy - miny;
|
||||
key_bounds.width = maxx - minx;
|
||||
eek_element_set_bounds(element, &key_bounds);
|
||||
}
|
||||
}
|
||||
|
||||
struct keys_info {
|
||||
uint count;
|
||||
double total_width;
|
||||
double biggest_height;
|
||||
};
|
||||
|
||||
static void keycounter (EekElement *element, gpointer user_data) {
|
||||
struct keys_info *data = user_data;
|
||||
data->count++;
|
||||
EekBounds key_bounds = {0};
|
||||
eek_element_get_bounds(element, &key_bounds);
|
||||
data->total_width += key_bounds.width;
|
||||
if (key_bounds.height > data->biggest_height) {
|
||||
data->biggest_height = key_bounds.height;
|
||||
}
|
||||
}
|
||||
|
||||
const double keyspacing = 4.0;
|
||||
|
||||
static void keyplacer(EekElement *element, gpointer user_data) {
|
||||
double *current_offset = user_data;
|
||||
EekBounds key_bounds = {0};
|
||||
eek_element_get_bounds(element, &key_bounds);
|
||||
key_bounds.x = *current_offset;
|
||||
key_bounds.y = 0;
|
||||
eek_element_set_bounds(element, &key_bounds);
|
||||
*current_offset += key_bounds.width + keyspacing;
|
||||
}
|
||||
|
||||
void eek_section_place_keys(EekSection *section, EekKeyboard *keyboard)
|
||||
{
|
||||
eek_container_foreach_child(EEK_CONTAINER(section), keysizer, keyboard);
|
||||
|
||||
struct keys_info keyinfo = {0};
|
||||
eek_container_foreach_child(EEK_CONTAINER(section), keycounter, &keyinfo);
|
||||
EekBounds section_bounds = {0};
|
||||
eek_element_get_bounds(EEK_ELEMENT(section), §ion_bounds);
|
||||
|
||||
double key_offset = (section_bounds.width - (keyinfo.total_width + (keyinfo.count - 1) * keyspacing)) / 2;
|
||||
eek_container_foreach_child(EEK_CONTAINER(section), keyplacer, &key_offset);
|
||||
|
||||
section_bounds.height = keyinfo.biggest_height;
|
||||
eek_element_set_bounds(EEK_ELEMENT(section), §ion_bounds);
|
||||
}
|
||||
|
||||
@ -32,7 +32,28 @@
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define EEK_TYPE_SECTION (eek_section_get_type())
|
||||
G_DECLARE_DERIVABLE_TYPE(EekSection, eek_section, EEK, SECTION, EekContainer)
|
||||
#define EEK_SECTION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EEK_TYPE_SECTION, EekSection))
|
||||
#define EEK_SECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EEK_TYPE_SECTION, EekSectionClass))
|
||||
#define EEK_IS_SECTION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EEK_TYPE_SECTION))
|
||||
#define EEK_IS_SECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EEK_TYPE_SECTION))
|
||||
#define EEK_SECTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EEK_TYPE_SECTION, EekSectionClass))
|
||||
|
||||
typedef struct _EekSectionClass EekSectionClass;
|
||||
typedef struct _EekSectionPrivate EekSectionPrivate;
|
||||
|
||||
/**
|
||||
* EekSection:
|
||||
*
|
||||
* The #EekSection structure contains only private data and should
|
||||
* only be accessed using the provided API.
|
||||
*/
|
||||
struct _EekSection
|
||||
{
|
||||
/*< private >*/
|
||||
EekContainer parent;
|
||||
|
||||
EekSectionPrivate *priv;
|
||||
};
|
||||
|
||||
/**
|
||||
* EekSectionClass:
|
||||
@ -106,7 +127,5 @@ EekKey *eek_section_create_key (EekSection *section,
|
||||
EekKey *eek_section_find_key_by_keycode (EekSection *section,
|
||||
guint keycode);
|
||||
|
||||
void eek_section_place_keys (EekSection *section, EekKeyboard *keyboard);
|
||||
|
||||
G_END_DECLS
|
||||
#endif /* EEK_SECTION_H */
|
||||
|
||||
@ -44,31 +44,29 @@ enum {
|
||||
PROP_LAST
|
||||
};
|
||||
|
||||
typedef struct _EekSymbolPrivate
|
||||
{
|
||||
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_DEFINE_TYPE_WITH_CODE (EekSymbol, eek_symbol, G_TYPE_OBJECT,
|
||||
G_IMPLEMENT_INTERFACE (EEK_TYPE_SERIALIZABLE,
|
||||
eek_serializable_iface_init))
|
||||
eek_serializable_iface_init));
|
||||
|
||||
#define EEK_SYMBOL_GET_PRIVATE(obj) \
|
||||
(G_TYPE_INSTANCE_GET_PRIVATE ((obj), EEK_TYPE_SYMBOL, EekSymbolPrivate))
|
||||
|
||||
static void
|
||||
eek_symbol_real_serialize (EekSerializable *self,
|
||||
GVariantBuilder *builder)
|
||||
{
|
||||
EekSymbolPrivate *priv = eek_symbol_get_instance_private (EEK_SYMBOL (self));
|
||||
EekSymbolPrivate *priv = EEK_SYMBOL_GET_PRIVATE(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));
|
||||
@ -84,7 +82,7 @@ eek_symbol_real_deserialize (EekSerializable *self,
|
||||
GVariant *variant,
|
||||
gsize index)
|
||||
{
|
||||
EekSymbolPrivate *priv = eek_symbol_get_instance_private (EEK_SYMBOL (self));
|
||||
EekSymbolPrivate *priv = EEK_SYMBOL_GET_PRIVATE(self);
|
||||
|
||||
g_variant_get_child (variant, index++, "s", &priv->name);
|
||||
g_variant_get_child (variant, index++, "s", &priv->label);
|
||||
@ -174,8 +172,7 @@ eek_symbol_get_property (GObject *object,
|
||||
static void
|
||||
eek_symbol_finalize (GObject *object)
|
||||
{
|
||||
EekSymbol *self = EEK_SYMBOL (object);
|
||||
EekSymbolPrivate *priv = eek_symbol_get_instance_private (self);
|
||||
EekSymbolPrivate *priv = EEK_SYMBOL_GET_PRIVATE(object);
|
||||
|
||||
g_free (priv->name);
|
||||
g_free (priv->label);
|
||||
@ -190,6 +187,8 @@ eek_symbol_class_init (EekSymbolClass *klass)
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||
GParamSpec *pspec;
|
||||
|
||||
g_type_class_add_private (gobject_class, sizeof (EekSymbolPrivate));
|
||||
|
||||
gobject_class->set_property = eek_symbol_set_property;
|
||||
gobject_class->get_property = eek_symbol_get_property;
|
||||
gobject_class->finalize = eek_symbol_finalize;
|
||||
@ -242,8 +241,9 @@ eek_symbol_class_init (EekSymbolClass *klass)
|
||||
static void
|
||||
eek_symbol_init (EekSymbol *self)
|
||||
{
|
||||
EekSymbolPrivate *priv = eek_symbol_get_instance_private (self);
|
||||
EekSymbolPrivate *priv;
|
||||
|
||||
priv = self->priv = EEK_SYMBOL_GET_PRIVATE(self);
|
||||
priv->category = EEK_SYMBOL_CATEGORY_UNKNOWN;
|
||||
}
|
||||
|
||||
@ -270,10 +270,11 @@ void
|
||||
eek_symbol_set_name (EekSymbol *symbol,
|
||||
const gchar *name)
|
||||
{
|
||||
EekSymbolPrivate *priv;
|
||||
|
||||
g_return_if_fail (EEK_IS_SYMBOL(symbol));
|
||||
|
||||
EekSymbolPrivate *priv = eek_symbol_get_instance_private (symbol);
|
||||
|
||||
priv = EEK_SYMBOL_GET_PRIVATE(symbol);
|
||||
g_free (priv->name);
|
||||
priv->name = g_strdup (name);
|
||||
}
|
||||
@ -287,10 +288,11 @@ eek_symbol_set_name (EekSymbol *symbol,
|
||||
const gchar *
|
||||
eek_symbol_get_name (EekSymbol *symbol)
|
||||
{
|
||||
EekSymbolPrivate *priv;
|
||||
|
||||
g_return_val_if_fail (EEK_IS_SYMBOL(symbol), NULL);
|
||||
|
||||
EekSymbolPrivate *priv = eek_symbol_get_instance_private (symbol);
|
||||
|
||||
priv = EEK_SYMBOL_GET_PRIVATE(symbol);
|
||||
if (priv->name == NULL || *priv->name == '\0')
|
||||
return NULL;
|
||||
return priv->name;
|
||||
@ -307,10 +309,11 @@ void
|
||||
eek_symbol_set_label (EekSymbol *symbol,
|
||||
const gchar *label)
|
||||
{
|
||||
EekSymbolPrivate *priv;
|
||||
|
||||
g_return_if_fail (EEK_IS_SYMBOL(symbol));
|
||||
|
||||
EekSymbolPrivate *priv = eek_symbol_get_instance_private (symbol);
|
||||
|
||||
priv = EEK_SYMBOL_GET_PRIVATE(symbol);
|
||||
g_free (priv->label);
|
||||
priv->label = g_strdup (label);
|
||||
}
|
||||
@ -324,10 +327,11 @@ eek_symbol_set_label (EekSymbol *symbol,
|
||||
const gchar *
|
||||
eek_symbol_get_label (EekSymbol *symbol)
|
||||
{
|
||||
EekSymbolPrivate *priv;
|
||||
|
||||
g_return_val_if_fail (EEK_IS_SYMBOL(symbol), NULL);
|
||||
|
||||
EekSymbolPrivate *priv = eek_symbol_get_instance_private (symbol);
|
||||
|
||||
priv = EEK_SYMBOL_GET_PRIVATE(symbol);
|
||||
if (priv->label == NULL || *priv->label == '\0')
|
||||
return NULL;
|
||||
return priv->label;
|
||||
@ -344,10 +348,11 @@ void
|
||||
eek_symbol_set_category (EekSymbol *symbol,
|
||||
EekSymbolCategory category)
|
||||
{
|
||||
EekSymbolPrivate *priv;
|
||||
|
||||
g_return_if_fail (EEK_IS_SYMBOL(symbol));
|
||||
|
||||
EekSymbolPrivate *priv = eek_symbol_get_instance_private (symbol);
|
||||
|
||||
priv = EEK_SYMBOL_GET_PRIVATE(symbol);
|
||||
priv->category = category;
|
||||
}
|
||||
|
||||
@ -360,10 +365,11 @@ eek_symbol_set_category (EekSymbol *symbol,
|
||||
EekSymbolCategory
|
||||
eek_symbol_get_category (EekSymbol *symbol)
|
||||
{
|
||||
EekSymbolPrivate *priv;
|
||||
|
||||
g_return_val_if_fail (EEK_IS_SYMBOL(symbol), EEK_SYMBOL_CATEGORY_UNKNOWN);
|
||||
|
||||
EekSymbolPrivate *priv = eek_symbol_get_instance_private (symbol);
|
||||
|
||||
priv = EEK_SYMBOL_GET_PRIVATE(symbol);
|
||||
return priv->category;
|
||||
}
|
||||
|
||||
@ -378,10 +384,11 @@ void
|
||||
eek_symbol_set_modifier_mask (EekSymbol *symbol,
|
||||
EekModifierType mask)
|
||||
{
|
||||
EekSymbolPrivate *priv;
|
||||
|
||||
g_return_if_fail (EEK_IS_SYMBOL(symbol));
|
||||
|
||||
EekSymbolPrivate *priv = eek_symbol_get_instance_private (symbol);
|
||||
|
||||
priv = EEK_SYMBOL_GET_PRIVATE(symbol);
|
||||
priv->modifier_mask = mask;
|
||||
}
|
||||
|
||||
@ -394,10 +401,11 @@ eek_symbol_set_modifier_mask (EekSymbol *symbol,
|
||||
EekModifierType
|
||||
eek_symbol_get_modifier_mask (EekSymbol *symbol)
|
||||
{
|
||||
EekSymbolPrivate *priv;
|
||||
|
||||
g_return_val_if_fail (EEK_IS_SYMBOL(symbol), 0);
|
||||
|
||||
EekSymbolPrivate *priv = eek_symbol_get_instance_private (symbol);
|
||||
|
||||
priv = EEK_SYMBOL_GET_PRIVATE(symbol);
|
||||
return priv->modifier_mask;
|
||||
}
|
||||
|
||||
@ -425,10 +433,11 @@ void
|
||||
eek_symbol_set_icon_name (EekSymbol *symbol,
|
||||
const gchar *icon_name)
|
||||
{
|
||||
EekSymbolPrivate *priv;
|
||||
|
||||
g_return_if_fail (EEK_IS_SYMBOL(symbol));
|
||||
|
||||
EekSymbolPrivate *priv = eek_symbol_get_instance_private (symbol);
|
||||
|
||||
priv = EEK_SYMBOL_GET_PRIVATE(symbol);
|
||||
g_free (priv->icon_name);
|
||||
priv->icon_name = g_strdup (icon_name);
|
||||
}
|
||||
@ -442,10 +451,11 @@ eek_symbol_set_icon_name (EekSymbol *symbol,
|
||||
const gchar *
|
||||
eek_symbol_get_icon_name (EekSymbol *symbol)
|
||||
{
|
||||
EekSymbolPrivate *priv;
|
||||
|
||||
g_return_val_if_fail (EEK_IS_SYMBOL(symbol), NULL);
|
||||
|
||||
EekSymbolPrivate *priv = eek_symbol_get_instance_private (symbol);
|
||||
|
||||
priv = EEK_SYMBOL_GET_PRIVATE(symbol);
|
||||
if (priv->icon_name == NULL || *priv->icon_name == '\0')
|
||||
return NULL;
|
||||
return priv->icon_name;
|
||||
@ -462,10 +472,11 @@ void
|
||||
eek_symbol_set_tooltip (EekSymbol *symbol,
|
||||
const gchar *tooltip)
|
||||
{
|
||||
EekSymbolPrivate *priv;
|
||||
|
||||
g_return_if_fail (EEK_IS_SYMBOL(symbol));
|
||||
|
||||
EekSymbolPrivate *priv = eek_symbol_get_instance_private (symbol);
|
||||
|
||||
priv = EEK_SYMBOL_GET_PRIVATE(symbol);
|
||||
g_free (priv->tooltip);
|
||||
priv->tooltip = g_strdup (tooltip);
|
||||
}
|
||||
@ -479,10 +490,11 @@ eek_symbol_set_tooltip (EekSymbol *symbol,
|
||||
const gchar *
|
||||
eek_symbol_get_tooltip (EekSymbol *symbol)
|
||||
{
|
||||
EekSymbolPrivate *priv;
|
||||
|
||||
g_return_val_if_fail (EEK_IS_SYMBOL(symbol), NULL);
|
||||
|
||||
EekSymbolPrivate *priv = eek_symbol_get_instance_private (symbol);
|
||||
|
||||
priv = EEK_SYMBOL_GET_PRIVATE(symbol);
|
||||
if (priv->tooltip == NULL || *priv->tooltip == '\0')
|
||||
return NULL;
|
||||
return priv->tooltip;
|
||||
|
||||
@ -59,7 +59,27 @@ typedef enum {
|
||||
} EekSymbolCategory;
|
||||
|
||||
#define EEK_TYPE_SYMBOL (eek_symbol_get_type())
|
||||
G_DECLARE_DERIVABLE_TYPE(EekSymbol, eek_symbol, EEK, SYMBOL, GObject)
|
||||
#define EEK_SYMBOL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EEK_TYPE_SYMBOL, EekSymbol))
|
||||
#define EEK_SYMBOL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EEK_TYPE_SYMBOL, EekSymbolClass))
|
||||
#define EEK_IS_SYMBOL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EEK_TYPE_SYMBOL))
|
||||
#define EEK_IS_SYMBOL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EEK_TYPE_SYMBOL))
|
||||
#define EEK_SYMBOL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EEK_TYPE_SYMBOL, EekSymbolClass))
|
||||
|
||||
typedef struct _EekSymbolClass EekSymbolClass;
|
||||
typedef struct _EekSymbolPrivate EekSymbolPrivate;
|
||||
|
||||
/**
|
||||
* EekSymbol:
|
||||
*
|
||||
* The #EekSymbol structure contains only private data and should only
|
||||
* be accessed using the provided API.
|
||||
*/
|
||||
struct _EekSymbol {
|
||||
/*< private >*/
|
||||
GObject parent;
|
||||
|
||||
EekSymbolPrivate *priv;
|
||||
};
|
||||
|
||||
/**
|
||||
* EekSymbolClass:
|
||||
|
||||
@ -36,20 +36,18 @@ enum {
|
||||
PROP_LAST
|
||||
};
|
||||
|
||||
typedef struct _EekTextPrivate
|
||||
{
|
||||
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_DEFINE_TYPE_WITH_CODE (EekText, eek_text, EEK_TYPE_SYMBOL,
|
||||
G_IMPLEMENT_INTERFACE (EEK_TYPE_SERIALIZABLE,
|
||||
eek_serializable_iface_init))
|
||||
eek_serializable_iface_init));
|
||||
|
||||
#define EEK_TEXT_GET_PRIVATE(obj) \
|
||||
(G_TYPE_INSTANCE_GET_PRIVATE ((obj), EEK_TYPE_TEXT, EekTextPrivate))
|
||||
|
||||
static EekSerializableIface *eek_text_parent_serializable_iface;
|
||||
|
||||
@ -57,7 +55,7 @@ static void
|
||||
eek_text_real_serialize (EekSerializable *self,
|
||||
GVariantBuilder *builder)
|
||||
{
|
||||
EekTextPrivate *priv = eek_text_get_instance_private (EEK_TEXT (self));
|
||||
EekTextPrivate *priv = EEK_TEXT_GET_PRIVATE(self);
|
||||
|
||||
eek_text_parent_serializable_iface->serialize (self, builder);
|
||||
|
||||
@ -69,7 +67,7 @@ eek_text_real_deserialize (EekSerializable *self,
|
||||
GVariant *variant,
|
||||
gsize index)
|
||||
{
|
||||
EekTextPrivate *priv = eek_text_get_instance_private (EEK_TEXT (self));
|
||||
EekTextPrivate *priv = EEK_TEXT_GET_PRIVATE(self);
|
||||
|
||||
index = eek_text_parent_serializable_iface->deserialize (self,
|
||||
variant,
|
||||
@ -95,9 +93,7 @@ eek_text_set_property (GObject *object,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
EekText *self = EEK_TEXT (object);
|
||||
EekTextPrivate *priv = eek_text_get_instance_private (self);
|
||||
|
||||
EekTextPrivate *priv = EEK_TEXT_GET_PRIVATE(object);
|
||||
switch (prop_id) {
|
||||
case PROP_TEXT:
|
||||
g_free (priv->text);
|
||||
@ -115,9 +111,7 @@ eek_text_get_property (GObject *object,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
EekText *self = EEK_TEXT (object);
|
||||
EekTextPrivate *priv = eek_text_get_instance_private (self);
|
||||
|
||||
EekTextPrivate *priv = EEK_TEXT_GET_PRIVATE(object);
|
||||
switch (prop_id) {
|
||||
case PROP_TEXT:
|
||||
g_value_set_string (value, priv->text);
|
||||
@ -131,8 +125,7 @@ eek_text_get_property (GObject *object,
|
||||
static void
|
||||
eek_text_finalize (GObject *object)
|
||||
{
|
||||
EekText *self = EEK_TEXT (object);
|
||||
EekTextPrivate *priv = eek_text_get_instance_private (self);
|
||||
EekTextPrivate *priv = EEK_TEXT_GET_PRIVATE(object);
|
||||
|
||||
g_free (priv->text);
|
||||
G_OBJECT_CLASS (eek_text_parent_class)->finalize (object);
|
||||
@ -144,6 +137,8 @@ eek_text_class_init (EekTextClass *klass)
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||
GParamSpec *pspec;
|
||||
|
||||
g_type_class_add_private (gobject_class, sizeof (EekTextPrivate));
|
||||
|
||||
gobject_class->set_property = eek_text_set_property;
|
||||
gobject_class->get_property = eek_text_get_property;
|
||||
gobject_class->finalize = eek_text_finalize;
|
||||
@ -159,7 +154,7 @@ eek_text_class_init (EekTextClass *klass)
|
||||
static void
|
||||
eek_text_init (EekText *self)
|
||||
{
|
||||
/* void */
|
||||
self->priv = EEK_TEXT_GET_PRIVATE(self);
|
||||
}
|
||||
|
||||
EekText *
|
||||
@ -181,7 +176,7 @@ eek_text_new (const gchar *text)
|
||||
const gchar *
|
||||
eek_text_get_text (EekText *text)
|
||||
{
|
||||
EekTextPrivate *priv = eek_text_get_instance_private (text);
|
||||
EekTextPrivate *priv = EEK_TEXT_GET_PRIVATE(text);
|
||||
|
||||
return priv->text;
|
||||
}
|
||||
|
||||
@ -30,7 +30,27 @@
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define EEK_TYPE_TEXT (eek_text_get_type())
|
||||
G_DECLARE_DERIVABLE_TYPE(EekText, eek_text, EEK, TEXT, EekSymbol)
|
||||
#define EEK_TEXT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EEK_TYPE_TEXT, EekText))
|
||||
#define EEK_TEXT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EEK_TYPE_TEXT, EekTextClass))
|
||||
#define EEK_IS_TEXT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EEK_TYPE_TEXT))
|
||||
#define EEK_IS_TEXT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EEK_TYPE_TEXT))
|
||||
#define EEK_TEXT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EEK_TYPE_TEXT, EekTextClass))
|
||||
|
||||
typedef struct _EekTextClass EekTextClass;
|
||||
typedef struct _EekTextPrivate EekTextPrivate;
|
||||
|
||||
/**
|
||||
* EekText:
|
||||
*
|
||||
* The #EekText structure contains only private data and should only
|
||||
* be accessed using the provided API.
|
||||
*/
|
||||
struct _EekText {
|
||||
/*< private >*/
|
||||
EekSymbol parent;
|
||||
|
||||
EekTextPrivate *priv;
|
||||
};
|
||||
|
||||
struct _EekTextClass {
|
||||
/*< private >*/
|
||||
|
||||
@ -89,6 +89,9 @@ static void eek_theme_node_finalize (GObject *object);
|
||||
|
||||
static const EekColor BLACK_COLOR = { 0, 0, 0, 0xff };
|
||||
static const EekColor TRANSPARENT_COLOR = { 0, 0, 0, 0 };
|
||||
static const EekColor DEFAULT_SUCCESS_COLOR = { 0x4e, 0x9a, 0x06, 0xff };
|
||||
static const EekColor DEFAULT_WARNING_COLOR = { 0xf5, 0x79, 0x3e, 0xff };
|
||||
static const EekColor DEFAULT_ERROR_COLOR = { 0xcc, 0x00, 0x00, 0xff };
|
||||
|
||||
static void
|
||||
eek_theme_node_init (EekThemeNode *self)
|
||||
|
||||
132
eek/eek-theme.c
@ -43,7 +43,6 @@
|
||||
* Copyright (C) 2003-2004 Dodji Seketeli. All Rights Reserved.
|
||||
*/
|
||||
|
||||
#define G_LOG_DOMAIN "eek-theme"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
@ -167,65 +166,103 @@ eek_theme_class_init (EekThemeClass *klass)
|
||||
|
||||
}
|
||||
|
||||
/* This is a workaround for a bug in libcroco < 0.6.2 where
|
||||
* function starting with 'r' (and 'u') are misparsed. We work
|
||||
* around this by exploiting the fact that libcroco is incomformant
|
||||
* with the CSS-spec and case sensitive and pre-convert all
|
||||
* occurrences of rgba to RGBA. Then we make our own parsing
|
||||
* code check for RGBA as well.
|
||||
*/
|
||||
#if LIBCROCO_VERSION_NUMBER < 602
|
||||
static gboolean
|
||||
is_identifier_character (char c)
|
||||
{
|
||||
/* Actual CSS rules allow for unicode > 0x00a1 and escaped
|
||||
* characters, but we'll assume we won't do that in our stylesheets
|
||||
* or at least not next to the string 'rgba'.
|
||||
*/
|
||||
return g_ascii_isalnum(c) || c == '-' || c == '_';
|
||||
}
|
||||
|
||||
static void
|
||||
convert_rgba_RGBA (char *buf)
|
||||
{
|
||||
char *p;
|
||||
|
||||
p = strstr (buf, "rgba");
|
||||
while (p)
|
||||
{
|
||||
/* Check if this looks like a complete token; this is to
|
||||
* avoiding mangling, say, a selector '.rgba-entry' */
|
||||
if (!((p > buf && is_identifier_character (*(p - 1))) ||
|
||||
(is_identifier_character (*(p + 4)))))
|
||||
memcpy(p, "RGBA", 4);
|
||||
p += 4;
|
||||
p = strstr (p, "rgba");
|
||||
}
|
||||
}
|
||||
|
||||
static CRStyleSheet *
|
||||
parse_stylesheet (const char *filename,
|
||||
GError **error)
|
||||
{
|
||||
enum CRStatus status;
|
||||
char *contents;
|
||||
gsize length;
|
||||
CRStyleSheet *stylesheet = NULL;
|
||||
|
||||
if (filename == NULL)
|
||||
return NULL;
|
||||
|
||||
if (!g_file_get_contents (filename, &contents, &length, error))
|
||||
return NULL;
|
||||
|
||||
convert_rgba_RGBA (contents);
|
||||
|
||||
status = cr_om_parser_simply_parse_buf ((const guchar *) contents,
|
||||
length,
|
||||
CR_UTF_8,
|
||||
&stylesheet);
|
||||
g_free (contents);
|
||||
|
||||
if (status != CR_OK)
|
||||
{
|
||||
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
|
||||
"Error parsing stylesheet '%s'; errcode:%d", filename, status);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return stylesheet;
|
||||
}
|
||||
|
||||
CRDeclaration *
|
||||
_eek_theme_parse_declaration_list (const char *str)
|
||||
{
|
||||
char *copy = g_strdup (str);
|
||||
CRDeclaration *result;
|
||||
|
||||
convert_rgba_RGBA (copy);
|
||||
|
||||
result = cr_declaration_parse_list_from_buf ((const guchar *)copy,
|
||||
CR_UTF_8);
|
||||
g_free (copy);
|
||||
|
||||
return result;
|
||||
}
|
||||
#else /* LIBCROCO_VERSION_NUMBER >= 602 */
|
||||
static CRStyleSheet *
|
||||
parse_stylesheet (const char *filename,
|
||||
GError **error)
|
||||
{
|
||||
enum CRStatus status;
|
||||
CRStyleSheet *stylesheet;
|
||||
g_autoptr (GFileInputStream) stream = NULL;
|
||||
g_autoptr (GFileInfo) info = NULL;
|
||||
g_autoptr (GFile) file = NULL;
|
||||
g_autofree guchar* contents = NULL;
|
||||
goffset size;
|
||||
gsize out = 0;
|
||||
GError *err = NULL;
|
||||
|
||||
if (filename == NULL)
|
||||
return NULL;
|
||||
|
||||
g_debug ("Parsing %s", filename);
|
||||
if (g_strcmp0 (filename, "resource://") > 0) {
|
||||
file = g_file_new_for_uri (filename);
|
||||
stream = g_file_read (file, NULL, &err);
|
||||
if (!stream) {
|
||||
g_warning ("Failed to open %s: %s", filename, err->message);
|
||||
g_clear_error (&err);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
info = g_file_input_stream_query_info (stream,
|
||||
G_FILE_ATTRIBUTE_STANDARD_SIZE,
|
||||
NULL,
|
||||
&err);
|
||||
|
||||
if (!info) {
|
||||
g_warning ("Failed to stat %s: %s", filename, err->message);
|
||||
g_clear_error (&err);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
size = g_file_info_get_size (info);
|
||||
contents = g_malloc0 (size);
|
||||
if (!g_input_stream_read_all (G_INPUT_STREAM (stream),
|
||||
contents,
|
||||
size,
|
||||
&out,
|
||||
NULL,
|
||||
&err)) {
|
||||
g_warning ("Failed to read %s: %s", filename, err->message);
|
||||
g_clear_error (&err);
|
||||
return NULL;
|
||||
}
|
||||
status = cr_om_parser_simply_parse_buf (contents,
|
||||
size,
|
||||
CR_UTF_8,
|
||||
&stylesheet);
|
||||
} else {
|
||||
status = cr_om_parser_simply_parse_file ((const guchar *) filename,
|
||||
CR_UTF_8,
|
||||
&stylesheet);
|
||||
}
|
||||
|
||||
if (status != CR_OK)
|
||||
{
|
||||
@ -243,6 +280,7 @@ _eek_theme_parse_declaration_list (const char *str)
|
||||
return cr_declaration_parse_list_from_buf ((const guchar *)str,
|
||||
CR_UTF_8);
|
||||
}
|
||||
#endif /* LIBCROCO_VERSION_NUMBER < 602 */
|
||||
|
||||
/* Just g_warning for now until we have something nicer to do */
|
||||
static CRStyleSheet *
|
||||
|
||||
@ -150,8 +150,6 @@ typedef struct _EekBounds EekBounds;
|
||||
typedef struct _EekOutline EekOutline;
|
||||
typedef struct _EekColor EekColor;
|
||||
|
||||
typedef struct _EekboardContextService EekboardContextService;
|
||||
|
||||
/**
|
||||
* EekPoint:
|
||||
* @x: X coordinate of the point
|
||||
@ -214,7 +212,7 @@ struct _EekOutline
|
||||
/*< public >*/
|
||||
gdouble corner_radius;
|
||||
EekPoint *points;
|
||||
guint num_points;
|
||||
gint num_points;
|
||||
};
|
||||
|
||||
GType eek_outline_get_type (void) G_GNUC_CONST;
|
||||
|
||||
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@
|
||||
679
eek/eek-xkb-layout.c
Normal file
@ -0,0 +1,679 @@
|
||||
/*
|
||||
* 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 <X11/keysym.h>
|
||||
#include <X11/XKBlib.h>
|
||||
#include <X11/extensions/XKBgeom.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
#include <gio/gio.h>
|
||||
|
||||
#include "eek-xkb-layout.h"
|
||||
#include "eek-keyboard.h"
|
||||
#include "eek-section.h"
|
||||
#include "eek-key.h"
|
||||
#include "eek-keysym.h"
|
||||
|
||||
#define XKB_COMPONENT_MASK (XkbGBN_GeometryMask | \
|
||||
XkbGBN_KeyNamesMask | \
|
||||
XkbGBN_OtherNamesMask | \
|
||||
XkbGBN_SymbolsMask | \
|
||||
XkbGBN_IndicatorMapMask)
|
||||
|
||||
static void initable_iface_init (GInitableIface *initable_iface);
|
||||
|
||||
G_DEFINE_TYPE_WITH_CODE (EekXkbLayout, eek_xkb_layout, EEK_TYPE_LAYOUT,
|
||||
G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE,
|
||||
initable_iface_init));
|
||||
|
||||
#define EEK_XKB_LAYOUT_GET_PRIVATE(obj) \
|
||||
(G_TYPE_INSTANCE_GET_PRIVATE ((obj), EEK_TYPE_XKB_LAYOUT, EekXkbLayoutPrivate))
|
||||
|
||||
enum {
|
||||
PROP_0,
|
||||
PROP_DISPLAY,
|
||||
PROP_LAST
|
||||
};
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
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 = layout->priv;
|
||||
return n * priv->scale_numerator / priv->scale_denominator;
|
||||
}
|
||||
|
||||
G_INLINE_FUNC gdouble
|
||||
xkb_to_pixmap_double (EekXkbLayout *layout,
|
||||
gdouble d)
|
||||
{
|
||||
EekXkbLayoutPrivate *priv = layout->priv;
|
||||
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 = layout->priv;
|
||||
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;
|
||||
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);
|
||||
|
||||
priv = layout->priv;
|
||||
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 = layout->priv;
|
||||
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 (EekLayout *self,
|
||||
gdouble initial_width,
|
||||
gdouble initial_height)
|
||||
{
|
||||
EekXkbLayoutPrivate *priv = EEK_XKB_LAYOUT_GET_PRIVATE (self);
|
||||
EekBounds bounds;
|
||||
EekKeyboard *keyboard;
|
||||
|
||||
keyboard = g_object_new (EEK_TYPE_KEYBOARD, "layout", self, NULL);
|
||||
bounds.x = bounds.y = 0.0;
|
||||
bounds.width = initial_width;
|
||||
bounds.height = initial_height;
|
||||
eek_element_set_bounds (EEK_ELEMENT(keyboard), &bounds);
|
||||
|
||||
/* resolve modifiers dynamically assigned at run time */
|
||||
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_PRIVATE (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);
|
||||
|
||||
switch (prop_id) {
|
||||
case PROP_DISPLAY:
|
||||
layout->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);
|
||||
|
||||
switch (prop_id) {
|
||||
case PROP_DISPLAY:
|
||||
g_value_set_pointer (value, layout->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;
|
||||
|
||||
g_type_class_add_private (gobject_class, sizeof (EekXkbLayoutPrivate));
|
||||
|
||||
layout_class->create_keyboard = eek_xkb_layout_real_create_keyboard;
|
||||
|
||||
gobject_class->finalize = eek_xkb_layout_finalize;
|
||||
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)
|
||||
{
|
||||
self->priv = EEK_XKB_LAYOUT_GET_PRIVATE (self);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
get_names_from_server (EekXkbLayout *layout,
|
||||
GError **error)
|
||||
{
|
||||
EekXkbLayoutPrivate *priv = layout->priv;
|
||||
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)
|
||||
{
|
||||
if (g_strcmp0 (names->keycodes, layout->priv->names.keycodes)) {
|
||||
g_free (layout->priv->names.keycodes);
|
||||
layout->priv->names.keycodes = g_strdup (names->keycodes);
|
||||
}
|
||||
|
||||
if (g_strcmp0 (names->geometry, layout->priv->names.geometry)) {
|
||||
g_free (layout->priv->names.geometry);
|
||||
layout->priv->names.geometry = g_strdup (names->geometry);
|
||||
}
|
||||
|
||||
if (g_strcmp0 (names->symbols, layout->priv->names.symbols)) {
|
||||
g_free (layout->priv->names.symbols);
|
||||
layout->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 = layout->priv;
|
||||
|
||||
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 = layout->priv;
|
||||
|
||||
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 = layout->priv;
|
||||
|
||||
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;
|
||||
}
|
||||
72
eek/eek-xkb-layout.h
Normal file
@ -0,0 +1,72 @@
|
||||
/*
|
||||
* 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/Xlib.h>
|
||||
#include <X11/XKBlib.h>
|
||||
#include "eek-layout.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define EEK_TYPE_XKB_LAYOUT (eek_xkb_layout_get_type())
|
||||
#define EEK_XKB_LAYOUT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EEK_TYPE_XKB_LAYOUT, EekXkbLayout))
|
||||
#define EEK_XKB_LAYOUT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EEK_TYPE_XKB_LAYOUT, EekXkbLayoutClass))
|
||||
#define EEK_IS_XKB_LAYOUT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EEK_TYPE_XKB_LAYOUT))
|
||||
#define EEK_IS_XKB_LAYOUT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EEK_TYPE_XKB_LAYOUT))
|
||||
#define EEK_XKB_LAYOUT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EEK_TYPE_XKB_LAYOUT, EekXkbLayoutClass))
|
||||
|
||||
typedef struct _EekXkbLayout EekXkbLayout;
|
||||
typedef struct _EekXkbLayoutClass EekXkbLayoutClass;
|
||||
typedef struct _EekXkbLayoutPrivate EekXkbLayoutPrivate;
|
||||
|
||||
struct _EekXkbLayout
|
||||
{
|
||||
/*< private >*/
|
||||
EekLayout parent;
|
||||
|
||||
EekXkbLayoutPrivate *priv;
|
||||
};
|
||||
|
||||
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@
|
||||
663
eek/eek-xkl-layout.c
Normal file
@ -0,0 +1,663 @@
|
||||
/*
|
||||
* 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);
|
||||
|
||||
G_DEFINE_TYPE_WITH_CODE (EekXklLayout, eek_xkl_layout, EEK_TYPE_XKB_LAYOUT,
|
||||
G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE,
|
||||
initable_iface_init));
|
||||
|
||||
#define EEK_XKL_LAYOUT_GET_PRIVATE(obj) \
|
||||
(G_TYPE_INSTANCE_GET_PRIVATE ((obj), EEK_TYPE_XKL_LAYOUT, EekXklLayoutPrivate))
|
||||
|
||||
enum {
|
||||
PROP_0,
|
||||
PROP_MODEL,
|
||||
PROP_LAYOUTS,
|
||||
PROP_VARIANTS,
|
||||
PROP_OPTIONS,
|
||||
PROP_LAST
|
||||
};
|
||||
|
||||
struct _EekXklLayoutPrivate
|
||||
{
|
||||
XklEngine *engine;
|
||||
XklConfigRec *config;
|
||||
};
|
||||
|
||||
/* 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_PRIVATE (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;
|
||||
|
||||
g_type_class_add_private (gobject_class, sizeof (EekXklLayoutPrivate));
|
||||
|
||||
gobject_class->dispose = eek_xkl_layout_dispose;
|
||||
gobject_class->set_property = eek_xkl_layout_set_property;
|
||||
gobject_class->get_property = eek_xkl_layout_get_property;
|
||||
|
||||
/**
|
||||
* 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)
|
||||
{
|
||||
self->priv = EEK_XKL_LAYOUT_GET_PRIVATE (self);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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_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_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_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_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_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_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_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_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_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 = layout->priv;
|
||||
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);
|
||||
Display *display;
|
||||
|
||||
if (!parent_initable_iface->init (initable, cancellable, error))
|
||||
return FALSE;
|
||||
|
||||
layout->priv->config = xkl_config_rec_new ();
|
||||
|
||||
g_object_get (G_OBJECT (initable),
|
||||
"display", &display,
|
||||
NULL);
|
||||
|
||||
layout->priv->engine = xkl_engine_get_instance (display);
|
||||
|
||||
if (!xkl_config_rec_get_from_server (layout->priv->config,
|
||||
layout->priv->engine)) {
|
||||
g_set_error (error,
|
||||
EEK_ERROR,
|
||||
EEK_ERROR_LAYOUT_ERROR,
|
||||
"can't load libxklavier configuration");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
set_xkb_component_names (layout, 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;
|
||||
}
|
||||
|
||||
97
eek/eek-xkl-layout.h
Normal file
@ -0,0 +1,97 @@
|
||||
/*
|
||||
* 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())
|
||||
#define EEK_XKL_LAYOUT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EEK_TYPE_XKL_LAYOUT, EekXklLayout))
|
||||
#define EEK_XKL_LAYOUT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EEK_TYPE_XKL_LAYOUT, EekXklLayoutClass))
|
||||
#define EEK_IS_XKL_LAYOUT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EEK_TYPE_XKL_LAYOUT))
|
||||
#define EEK_IS_XKL_LAYOUT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EEK_TYPE_XKL_LAYOUT))
|
||||
#define EEK_XKL_LAYOUT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EEK_TYPE_XKL_LAYOUT, EekXklLayoutClass))
|
||||
|
||||
typedef struct _EekXklLayout EekXklLayout;
|
||||
typedef struct _EekXklLayoutClass EekXklLayoutClass;
|
||||
typedef struct _EekXklLayoutPrivate EekXklLayoutPrivate;
|
||||
|
||||
struct _EekXklLayout
|
||||
{
|
||||
/*< private >*/
|
||||
EekXkbLayout parent;
|
||||
|
||||
EekXklLayoutPrivate *priv;
|
||||
};
|
||||
|
||||
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 */
|
||||
@ -25,7 +25,6 @@
|
||||
#include "config.h"
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
|
||||
#include <gio/gio.h> /* GResource */
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
@ -36,8 +35,6 @@
|
||||
#include "eek-keysym.h"
|
||||
#include "eek-text.h"
|
||||
|
||||
#include "squeekboard-resources.h"
|
||||
|
||||
enum {
|
||||
PROP_0,
|
||||
PROP_ID,
|
||||
@ -46,18 +43,19 @@ enum {
|
||||
|
||||
static void initable_iface_init (GInitableIface *initable_iface);
|
||||
|
||||
typedef struct _EekXmlLayoutPrivate
|
||||
G_DEFINE_TYPE_WITH_CODE (EekXmlLayout, eek_xml_layout, EEK_TYPE_LAYOUT,
|
||||
G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE,
|
||||
initable_iface_init));
|
||||
|
||||
#define EEK_XML_LAYOUT_GET_PRIVATE(obj) \
|
||||
(G_TYPE_INSTANCE_GET_PRIVATE ((obj), EEK_TYPE_XML_LAYOUT, EekXmlLayoutPrivate))
|
||||
|
||||
struct _EekXmlLayoutPrivate
|
||||
{
|
||||
gchar *id;
|
||||
gchar *keyboards_dir;
|
||||
EekXmlKeyboardDesc *desc;
|
||||
} EekXmlLayoutPrivate;
|
||||
|
||||
G_DEFINE_TYPE_EXTENDED (EekXmlLayout, eek_xml_layout, EEK_TYPE_LAYOUT,
|
||||
0, /* GTypeFlags */
|
||||
G_ADD_PRIVATE(EekXmlLayout)
|
||||
G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE,
|
||||
initable_iface_init))
|
||||
};
|
||||
|
||||
G_DEFINE_BOXED_TYPE(EekXmlKeyboardDesc, eek_xml_keyboard_desc, eek_xml_keyboard_desc_copy, eek_xml_keyboard_desc_free);
|
||||
|
||||
@ -362,6 +360,11 @@ geometry_start_element_callback (GMarkupParseContext *pcontext,
|
||||
|
||||
if (g_strcmp0 (data->element_stack->data, "geometry") == 0)
|
||||
eek_element_set_bounds (EEK_ELEMENT(data->keyboard), &bounds);
|
||||
else if (g_strcmp0 (data->element_stack->data, "section") == 0)
|
||||
eek_element_set_bounds (EEK_ELEMENT(data->section), &bounds);
|
||||
else if (g_strcmp0 (data->element_stack->data, "key") == 0)
|
||||
eek_element_set_bounds (EEK_ELEMENT(data->key), &bounds);
|
||||
|
||||
goto out;
|
||||
}
|
||||
|
||||
@ -501,6 +504,7 @@ geometry_end_element_callback (GMarkupParseContext *pcontext,
|
||||
{
|
||||
GeometryParseData *data = user_data;
|
||||
GSList *head = data->element_stack;
|
||||
gint i;
|
||||
|
||||
g_free (head->data);
|
||||
data->element_stack = g_slist_next (data->element_stack);
|
||||
@ -532,8 +536,7 @@ geometry_end_element_callback (GMarkupParseContext *pcontext,
|
||||
outline->num_points = g_slist_length (data->points);
|
||||
outline->points = g_slice_alloc0 (sizeof (EekPoint) *
|
||||
outline->num_points);
|
||||
guint i;
|
||||
for (i = 0, head = data->points = g_slist_reverse (data->points);
|
||||
for (head = data->points = g_slist_reverse (data->points), i = 0;
|
||||
head && i < outline->num_points;
|
||||
head = g_slist_next (head), i++) {
|
||||
memcpy (&outline->points[i], head->data, sizeof (EekPoint));
|
||||
@ -637,13 +640,13 @@ symbols_start_element_callback (GMarkupParseContext *pcontext,
|
||||
|
||||
data->key = eek_keyboard_find_key_by_keycode (data->keyboard,
|
||||
keycode);
|
||||
/*if (data->key == NULL) {
|
||||
if (data->key == NULL) {
|
||||
g_set_error (error,
|
||||
G_MARKUP_ERROR,
|
||||
G_MARKUP_ERROR_INVALID_CONTENT,
|
||||
"no such keycode %u", keycode);
|
||||
return;
|
||||
}*/
|
||||
}
|
||||
|
||||
attribute = get_attribute (attribute_names, attribute_values,
|
||||
"groups");
|
||||
@ -718,10 +721,6 @@ symbols_end_element_callback (GMarkupParseContext *pcontext,
|
||||
text = g_strndup (data->text->str, data->text->len);
|
||||
|
||||
if (g_strcmp0 (element_name, "key") == 0) {
|
||||
if (!data->key) {
|
||||
return;
|
||||
}
|
||||
|
||||
gint num_symbols = g_slist_length (data->symbols);
|
||||
gint levels = num_symbols / data->groups;
|
||||
EekSymbolMatrix *matrix = eek_symbol_matrix_new (data->groups,
|
||||
@ -897,41 +896,42 @@ static const GMarkupParser prerequisites_parser = {
|
||||
};
|
||||
|
||||
static EekKeyboard *
|
||||
eek_xml_layout_real_create_keyboard (EekboardContextService *manager,
|
||||
EekLayout *self,
|
||||
eek_xml_layout_real_create_keyboard (EekLayout *self,
|
||||
gdouble initial_width,
|
||||
gdouble initial_height)
|
||||
{
|
||||
EekXmlLayout *layout = EEK_XML_LAYOUT (self);
|
||||
EekXmlLayoutPrivate *priv = eek_xml_layout_get_instance_private (layout);
|
||||
EekKeyboard *keyboard;
|
||||
gchar *filename, *path;
|
||||
GList *loaded;
|
||||
GError *error;
|
||||
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;
|
||||
keyboard = g_object_new (EEK_TYPE_KEYBOARD, "layout", layout, NULL);
|
||||
|
||||
/* Read geometry information. */
|
||||
gchar *filename = g_strdup_printf ("%s.xml", priv->desc->geometry);
|
||||
gchar *path = g_build_filename (priv->keyboards_dir, "geometry", filename, NULL);
|
||||
filename = g_strdup_printf ("%s.xml", layout->priv->desc->geometry);
|
||||
path = g_build_filename (layout->priv->keyboards_dir, "geometry", filename, NULL);
|
||||
g_free (filename);
|
||||
|
||||
GError *error = NULL;
|
||||
error = NULL;
|
||||
retval = parse_geometry (path, keyboard, &error);
|
||||
g_free (path);
|
||||
if (!retval) {
|
||||
g_object_unref (keyboard);
|
||||
g_warning ("can't parse geometry file %s: %s",
|
||||
priv->desc->geometry,
|
||||
layout->priv->desc->geometry,
|
||||
error->message);
|
||||
g_error_free (error);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Read symbols information. */
|
||||
GList *loaded = NULL;
|
||||
retval = parse_symbols_with_prerequisites (priv->keyboards_dir,
|
||||
priv->desc->symbols,
|
||||
loaded = NULL;
|
||||
retval = parse_symbols_with_prerequisites (layout->priv->keyboards_dir,
|
||||
layout->priv->desc->symbols,
|
||||
keyboard,
|
||||
&loaded,
|
||||
&error);
|
||||
@ -939,7 +939,7 @@ eek_xml_layout_real_create_keyboard (EekboardContextService *manager,
|
||||
if (!retval) {
|
||||
g_object_unref (keyboard);
|
||||
g_warning ("can't parse symbols file %s: %s",
|
||||
priv->desc->symbols,
|
||||
layout->priv->desc->symbols,
|
||||
error->message);
|
||||
g_error_free (error);
|
||||
return NULL;
|
||||
@ -950,7 +950,7 @@ eek_xml_layout_real_create_keyboard (EekboardContextService *manager,
|
||||
|
||||
/* 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);
|
||||
eek_keyboard_set_alt_gr_mask (keyboard, EEK_MOD5_MASK);
|
||||
|
||||
return keyboard;
|
||||
}
|
||||
@ -962,12 +962,10 @@ eek_xml_layout_set_property (GObject *object,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
EekXmlLayout *layout = EEK_XML_LAYOUT (object);
|
||||
EekXmlLayoutPrivate *priv = eek_xml_layout_get_instance_private (layout);
|
||||
|
||||
switch (prop_id) {
|
||||
case PROP_ID:
|
||||
g_free (priv->id);
|
||||
priv->id = g_value_dup_string (value);
|
||||
g_free (layout->priv->id);
|
||||
layout->priv->id = g_value_dup_string (value);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
@ -982,11 +980,9 @@ eek_xml_layout_get_property (GObject *object,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
EekXmlLayout *layout = EEK_XML_LAYOUT (object);
|
||||
EekXmlLayoutPrivate *priv = eek_xml_layout_get_instance_private (layout);
|
||||
|
||||
switch (prop_id) {
|
||||
case PROP_ID:
|
||||
g_value_set_string (value, priv->id);
|
||||
g_value_set_string (value, layout->priv->id);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
@ -997,8 +993,7 @@ eek_xml_layout_get_property (GObject *object,
|
||||
static void
|
||||
eek_xml_layout_finalize (GObject *object)
|
||||
{
|
||||
EekXmlLayoutPrivate *priv = eek_xml_layout_get_instance_private (
|
||||
EEK_XML_LAYOUT (object));
|
||||
EekXmlLayoutPrivate *priv = EEK_XML_LAYOUT_GET_PRIVATE (object);
|
||||
|
||||
g_free (priv->id);
|
||||
|
||||
@ -1017,6 +1012,8 @@ eek_xml_layout_class_init (EekXmlLayoutClass *klass)
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||
GParamSpec *pspec;
|
||||
|
||||
g_type_class_add_private (gobject_class, sizeof (EekXmlLayoutPrivate));
|
||||
|
||||
layout_class->create_keyboard = eek_xml_layout_real_create_keyboard;
|
||||
|
||||
gobject_class->set_property = eek_xml_layout_set_property;
|
||||
@ -1035,7 +1032,7 @@ eek_xml_layout_class_init (EekXmlLayoutClass *klass)
|
||||
static void
|
||||
eek_xml_layout_init (EekXmlLayout *self)
|
||||
{
|
||||
/* void */
|
||||
self->priv = EEK_XML_LAYOUT_GET_PRIVATE (self);
|
||||
}
|
||||
|
||||
EekLayout *
|
||||
@ -1054,17 +1051,16 @@ initable_init (GInitable *initable,
|
||||
GError **error)
|
||||
{
|
||||
EekXmlLayout *layout = EEK_XML_LAYOUT (initable);
|
||||
EekXmlLayoutPrivate *priv = eek_xml_layout_get_instance_private (layout);
|
||||
GList *keyboards, *p;
|
||||
gchar *path;
|
||||
EekXmlKeyboardDesc *desc;
|
||||
|
||||
priv->keyboards_dir = g_strdup ((gchar *) g_getenv ("EEKBOARD_KEYBOARDSDIR"));
|
||||
layout->priv->keyboards_dir = (gchar *) g_getenv ("EEKBOARD_KEYBOARDSDIR");
|
||||
if (layout->priv->keyboards_dir == NULL)
|
||||
layout->priv->keyboards_dir = KEYBOARDSDIR;
|
||||
layout->priv->keyboards_dir = g_strdup (layout->priv->keyboards_dir);
|
||||
|
||||
if (priv->keyboards_dir == NULL)
|
||||
priv->keyboards_dir = g_strdup ("resource:///sm/puri/squeekboard/keyboards/");
|
||||
|
||||
path = g_build_filename (priv->keyboards_dir, "keyboards.xml", NULL);
|
||||
path = g_build_filename (layout->priv->keyboards_dir, "keyboards.xml", NULL);
|
||||
keyboards = parse_keyboards (path, error);
|
||||
g_free (path);
|
||||
if (error && *error)
|
||||
@ -1072,7 +1068,7 @@ initable_init (GInitable *initable,
|
||||
|
||||
for (p = keyboards; p; p = p->next) {
|
||||
desc = p->data;
|
||||
if (g_strcmp0 (desc->id, priv->id) == 0)
|
||||
if (g_strcmp0 (desc->id, layout->priv->id) == 0)
|
||||
break;
|
||||
}
|
||||
if (p == NULL) {
|
||||
@ -1080,12 +1076,12 @@ initable_init (GInitable *initable,
|
||||
EEK_ERROR,
|
||||
EEK_ERROR_LAYOUT_ERROR,
|
||||
"no such keyboard %s",
|
||||
priv->id);
|
||||
layout->priv->id);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
keyboards = g_list_remove_link (keyboards, p);
|
||||
priv->desc = p->data;
|
||||
layout->priv->desc = p->data;
|
||||
g_list_free_1 (p);
|
||||
g_list_free_full (keyboards, (GDestroyNotify) keyboard_desc_free);
|
||||
|
||||
@ -1113,7 +1109,7 @@ eek_xml_list_keyboards (void)
|
||||
|
||||
keyboards_dir = g_getenv ("EEKBOARD_KEYBOARDSDIR");
|
||||
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);
|
||||
keyboards = parse_keyboards (path, NULL);
|
||||
g_free (path);
|
||||
@ -1138,38 +1134,6 @@ eek_xml_keyboard_desc_free (EekXmlKeyboardDesc *desc)
|
||||
g_slice_free (EekXmlKeyboardDesc, desc);
|
||||
}
|
||||
|
||||
struct place_data {
|
||||
double desired_width;
|
||||
double current_offset;
|
||||
EekKeyboard *keyboard;
|
||||
};
|
||||
|
||||
const double section_spacing = 7.0;
|
||||
|
||||
static void section_placer(EekElement *element, gpointer user_data) {
|
||||
struct place_data *data = (struct place_data*)user_data;
|
||||
|
||||
EekBounds section_bounds = {0};
|
||||
eek_element_get_bounds(element, §ion_bounds);
|
||||
section_bounds.width = data->desired_width;
|
||||
eek_element_set_bounds(element, §ion_bounds);
|
||||
|
||||
// Sections are rows now. Gather up all the keys and adjust their bounds.
|
||||
eek_section_place_keys(EEK_SECTION(element), EEK_KEYBOARD(data->keyboard));
|
||||
|
||||
eek_element_get_bounds(element, §ion_bounds);
|
||||
section_bounds.y = data->current_offset;
|
||||
eek_element_set_bounds(element, §ion_bounds);
|
||||
data->current_offset += section_bounds.height + section_spacing;
|
||||
}
|
||||
|
||||
static void section_counter(EekElement *element, gpointer user_data) {
|
||||
double *total_height = user_data;
|
||||
EekBounds section_bounds = {0};
|
||||
eek_element_get_bounds(element, §ion_bounds);
|
||||
*total_height += section_bounds.height + section_spacing;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
parse_geometry (const gchar *path, EekKeyboard *keyboard, GError **error)
|
||||
{
|
||||
@ -1182,9 +1146,7 @@ parse_geometry (const gchar *path, EekKeyboard *keyboard, GError **error)
|
||||
GFileInputStream *input;
|
||||
gboolean retval;
|
||||
|
||||
file = g_str_has_prefix (path, "resource://")
|
||||
? g_file_new_for_uri (path)
|
||||
: g_file_new_for_path (path);
|
||||
file = g_file_new_for_path (path);
|
||||
|
||||
input = g_file_read (file, NULL, error);
|
||||
g_object_unref (file);
|
||||
@ -1224,27 +1186,6 @@ parse_geometry (const gchar *path, EekKeyboard *keyboard, GError **error)
|
||||
}
|
||||
g_hash_table_destroy (oref_hash);
|
||||
|
||||
/* Order rows */
|
||||
// This needs to be done after outlines, because outlines define key sizes
|
||||
// TODO: do this only for rows without bounds
|
||||
|
||||
// The keyboard width is given by the user via screen size. The height will be given dynamically.
|
||||
// TODO: calculate max line width beforehand for button centering. Leave keyboard centering to the renderer later
|
||||
EekBounds keyboard_bounds = {0};
|
||||
eek_element_get_bounds(EEK_ELEMENT(keyboard), &keyboard_bounds);
|
||||
|
||||
struct place_data placer_data = {
|
||||
.desired_width = keyboard_bounds.width,
|
||||
.current_offset = 0,
|
||||
.keyboard = keyboard,
|
||||
};
|
||||
eek_container_foreach_child(EEK_CONTAINER(keyboard), section_placer, &placer_data);
|
||||
|
||||
double total_height = 0;
|
||||
eek_container_foreach_child(EEK_CONTAINER(keyboard), section_counter, &total_height);
|
||||
keyboard_bounds.height = total_height;
|
||||
eek_element_set_bounds(EEK_ELEMENT(keyboard), &keyboard_bounds);
|
||||
|
||||
geometry_parse_data_free (data);
|
||||
return TRUE;
|
||||
}
|
||||
@ -1310,9 +1251,7 @@ parse_symbols (const gchar *path, EekKeyboard *keyboard, GError **error)
|
||||
GFileInputStream *input;
|
||||
gboolean retval;
|
||||
|
||||
file = g_str_has_prefix (path, "resource://")
|
||||
? g_file_new_for_uri (path)
|
||||
: g_file_new_for_path (path);
|
||||
file = g_file_new_for_path (path);
|
||||
|
||||
input = g_file_read (file, NULL, error);
|
||||
g_object_unref (file);
|
||||
@ -1345,9 +1284,7 @@ parse_prerequisites (const gchar *path, GError **error)
|
||||
GList *prerequisites;
|
||||
gboolean retval;
|
||||
|
||||
file = g_str_has_prefix (path, "resource://")
|
||||
? g_file_new_for_uri (path)
|
||||
: g_file_new_for_path (path);
|
||||
file = g_file_new_for_path (path);
|
||||
|
||||
input = g_file_read (file, NULL, error);
|
||||
g_object_unref (file);
|
||||
@ -1382,9 +1319,7 @@ parse_keyboards (const gchar *path, GError **error)
|
||||
GList *keyboards;
|
||||
gboolean retval;
|
||||
|
||||
file = g_str_has_prefix (path, "resource://")
|
||||
? g_file_new_for_uri (path)
|
||||
: g_file_new_for_path (path);
|
||||
file = g_file_new_for_path (path);
|
||||
|
||||
input = g_file_read (file, NULL, error);
|
||||
g_object_unref (file);
|
||||
|
||||
@ -29,7 +29,29 @@
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define EEK_TYPE_XML_LAYOUT (eek_xml_layout_get_type())
|
||||
G_DECLARE_DERIVABLE_TYPE (EekXmlLayout, eek_xml_layout, EEK, XML_LAYOUT, EekLayout)
|
||||
#define EEK_XML_LAYOUT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EEK_TYPE_XML_LAYOUT, EekXmlLayout))
|
||||
#define EEK_XML_LAYOUT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EEK_TYPE_XML_LAYOUT, EekXmlLayoutClass))
|
||||
#define EEK_IS_XML_LAYOUT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EEK_TYPE_XML_LAYOUT))
|
||||
#define EEK_IS_XML_LAYOUT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EEK_TYPE_XML_LAYOUT))
|
||||
#define EEK_XML_LAYOUT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EEK_TYPE_XML_LAYOUT, EekXmlLayoutClass))
|
||||
|
||||
typedef struct _EekXmlLayout EekXmlLayout;
|
||||
typedef struct _EekXmlLayoutClass EekXmlLayoutClass;
|
||||
typedef struct _EekXmlLayoutPrivate EekXmlLayoutPrivate;
|
||||
|
||||
/**
|
||||
* EekXmlLayout:
|
||||
*
|
||||
* The #EekXmlLayout structure contains only private data and should
|
||||
* only be accessed using the provided API.
|
||||
*/
|
||||
struct _EekXmlLayout
|
||||
{
|
||||
/*< private >*/
|
||||
EekLayout parent;
|
||||
|
||||
EekXmlLayoutPrivate *priv;
|
||||
};
|
||||
|
||||
/**
|
||||
* EekXmlLayoutClass:
|
||||
|
||||
@ -38,5 +38,9 @@
|
||||
void
|
||||
eek_init (void)
|
||||
{
|
||||
/* void */
|
||||
g_type_init ();
|
||||
|
||||
g_type_class_ref (EEK_TYPE_SYMBOL);
|
||||
g_type_class_ref (EEK_TYPE_KEYSYM);
|
||||
g_type_class_ref (EEK_TYPE_TEXT);
|
||||
}
|
||||
|
||||
@ -1,8 +1,7 @@
|
||||
#!/usr/bin/env python3
|
||||
#!/usr/bin/env python
|
||||
|
||||
# Copyright (C) 2010-2011 Daiki Ueno <ueno@unixuser.org>
|
||||
# Copyright (C) 2010-2011 Red Hat, Inc.
|
||||
# Copyright (C) 2019 Purism, SPC
|
||||
|
||||
# This library is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU Lesser General Public License
|
||||
@ -22,17 +21,13 @@
|
||||
import sys
|
||||
import re
|
||||
|
||||
if len(sys.argv) > 3:
|
||||
print("Usage: %s TABLE-NAME [INPUT_FILE]" % sys.argv[0], file=sys.stderr)
|
||||
if len(sys.argv) != 2:
|
||||
print >> sys.stderr, "Usage: %s TABLE-NAME" % sys.argv[0]
|
||||
sys.exit(-1)
|
||||
|
||||
if len(sys.argv) < 3:
|
||||
in_stream = sys.stdin
|
||||
else:
|
||||
in_stream = open(sys.argv[2])
|
||||
|
||||
table = dict()
|
||||
for line in in_stream:
|
||||
for line in sys.stdin:
|
||||
line = line.decode('UTF-8')
|
||||
match = re.match(r'\s*(0x[0-9A-F]+)\s+(\S*)\s+(\S*)', line, re.I)
|
||||
if match:
|
||||
table[int(match.group(1), 16)] = (match.group(2), match.group(3))
|
||||
@ -43,7 +38,7 @@ sys.stdout.write("static const EekKeysymEntry %s[] = {\n" %
|
||||
for index, (keysym, (l, c)) in enumerate([(keysym, table[keysym])
|
||||
for keysym in sorted(table.keys())]):
|
||||
sys.stdout.write(" { 0x%X, %s, %s }" %
|
||||
(keysym, l, c))
|
||||
(keysym, l.encode('UTF-8'), c.encode('UTF-8')))
|
||||
if index < len(table) - 1:
|
||||
sys.stdout.write(",")
|
||||
sys.stdout.write("\n")
|
||||
|
||||
@ -1,374 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2018 Purism SPC
|
||||
* SPDX-License-Identifier: GPL-3.0+
|
||||
* Author: Guido Günther <agx@sigxcpu.org>
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
|
||||
WARNING: this file is taken directly from phosh, with no modificaions apart from this message. Please update phosh instead of changing this file. Please copy the file back here afterwards, with the same notice.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
#define G_LOG_DOMAIN "phosh-layer-surface"
|
||||
|
||||
#include "config.h"
|
||||
#include "layersurface.h"
|
||||
|
||||
#include <gdk/gdkwayland.h>
|
||||
|
||||
enum {
|
||||
PHOSH_LAYER_SURFACE_PROP_0,
|
||||
PHOSH_LAYER_SURFACE_PROP_LAYER_SHELL,
|
||||
PHOSH_LAYER_SURFACE_PROP_WL_OUTPUT,
|
||||
PHOSH_LAYER_SURFACE_PROP_ANCHOR,
|
||||
PHOSH_LAYER_SURFACE_PROP_LAYER,
|
||||
PHOSH_LAYER_SURFACE_PROP_KBD_INTERACTIVITY,
|
||||
PHOSH_LAYER_SURFACE_PROP_EXCLUSIVE_ZONE,
|
||||
PHOSH_LAYER_SURFACE_PROP_LAYER_WIDTH,
|
||||
PHOSH_LAYER_SURFACE_PROP_LAYER_HEIGHT,
|
||||
PHOSH_LAYER_SURFACE_PROP_NAMESPACE,
|
||||
PHOSH_LAYER_SURFACE_PROP_LAST_PROP
|
||||
};
|
||||
static GParamSpec *props[PHOSH_LAYER_SURFACE_PROP_LAST_PROP];
|
||||
|
||||
enum {
|
||||
CONFIGURED,
|
||||
N_SIGNALS
|
||||
};
|
||||
static guint signals [N_SIGNALS];
|
||||
|
||||
|
||||
typedef struct {
|
||||
struct wl_surface *wl_surface;
|
||||
struct zwlr_layer_surface_v1 *layer_surface;
|
||||
|
||||
/* Properties */
|
||||
guint anchor;
|
||||
guint layer;
|
||||
gboolean kbd_interactivity;
|
||||
gint exclusive_zone;
|
||||
gint width, height;
|
||||
gchar *namespace;
|
||||
struct zwlr_layer_shell_v1 *layer_shell;
|
||||
struct wl_output *wl_output;
|
||||
} PhoshLayerSurfacePrivate;
|
||||
|
||||
G_DEFINE_TYPE_WITH_PRIVATE (PhoshLayerSurface, phosh_layer_surface, GTK_TYPE_WINDOW)
|
||||
|
||||
static void layer_surface_configure(void *data,
|
||||
struct zwlr_layer_surface_v1 *surface,
|
||||
uint32_t serial,
|
||||
uint32_t width,
|
||||
uint32_t height)
|
||||
{
|
||||
PhoshLayerSurface *self = data;
|
||||
gtk_window_resize (GTK_WINDOW (self), width, height);
|
||||
zwlr_layer_surface_v1_ack_configure(surface, serial);
|
||||
gtk_widget_show_all (GTK_WIDGET (self));
|
||||
|
||||
g_signal_emit (self, signals[CONFIGURED], 0);
|
||||
}
|
||||
|
||||
|
||||
static void layer_surface_closed (void *data,
|
||||
struct zwlr_layer_surface_v1 *surface)
|
||||
{
|
||||
PhoshLayerSurface *self = data;
|
||||
PhoshLayerSurfacePrivate *priv = phosh_layer_surface_get_instance_private (self);
|
||||
|
||||
g_return_if_fail (priv->layer_surface == surface);
|
||||
zwlr_layer_surface_v1_destroy(priv->layer_surface);
|
||||
priv->layer_surface = NULL;
|
||||
gtk_widget_destroy (GTK_WIDGET (self));
|
||||
}
|
||||
|
||||
static struct zwlr_layer_surface_v1_listener layer_surface_listener = {
|
||||
.configure = layer_surface_configure,
|
||||
.closed = layer_surface_closed,
|
||||
};
|
||||
|
||||
static void
|
||||
phosh_layer_surface_set_property (GObject *object,
|
||||
guint property_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
PhoshLayerSurface *self = PHOSH_LAYER_SURFACE (object);
|
||||
PhoshLayerSurfacePrivate *priv = phosh_layer_surface_get_instance_private (self);
|
||||
|
||||
switch (property_id) {
|
||||
case PHOSH_LAYER_SURFACE_PROP_LAYER_SHELL:
|
||||
priv->layer_shell = g_value_get_pointer (value);
|
||||
break;
|
||||
case PHOSH_LAYER_SURFACE_PROP_WL_OUTPUT:
|
||||
priv->wl_output = g_value_get_pointer (value);
|
||||
break;
|
||||
case PHOSH_LAYER_SURFACE_PROP_ANCHOR:
|
||||
priv->anchor = g_value_get_uint (value);
|
||||
break;
|
||||
case PHOSH_LAYER_SURFACE_PROP_LAYER:
|
||||
priv->layer = g_value_get_uint (value);
|
||||
break;
|
||||
case PHOSH_LAYER_SURFACE_PROP_KBD_INTERACTIVITY:
|
||||
priv->kbd_interactivity = g_value_get_boolean (value);
|
||||
break;
|
||||
case PHOSH_LAYER_SURFACE_PROP_EXCLUSIVE_ZONE:
|
||||
priv->exclusive_zone = g_value_get_int (value);
|
||||
break;
|
||||
case PHOSH_LAYER_SURFACE_PROP_LAYER_WIDTH:
|
||||
priv->width = g_value_get_uint (value);
|
||||
break;
|
||||
case PHOSH_LAYER_SURFACE_PROP_LAYER_HEIGHT:
|
||||
priv->height = g_value_get_uint (value);
|
||||
break;
|
||||
case PHOSH_LAYER_SURFACE_PROP_NAMESPACE:
|
||||
g_free (priv->namespace);
|
||||
priv->namespace = g_value_dup_string (value);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
phosh_layer_surface_get_property (GObject *object,
|
||||
guint property_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
PhoshLayerSurface *self = PHOSH_LAYER_SURFACE (object);
|
||||
PhoshLayerSurfacePrivate *priv = phosh_layer_surface_get_instance_private (self);
|
||||
|
||||
switch (property_id) {
|
||||
case PHOSH_LAYER_SURFACE_PROP_LAYER_SHELL:
|
||||
g_value_set_pointer (value, priv->layer_shell);
|
||||
break;
|
||||
case PHOSH_LAYER_SURFACE_PROP_WL_OUTPUT:
|
||||
g_value_set_pointer (value, priv->wl_output);
|
||||
break;
|
||||
case PHOSH_LAYER_SURFACE_PROP_ANCHOR:
|
||||
g_value_set_uint (value, priv->anchor);
|
||||
break;
|
||||
case PHOSH_LAYER_SURFACE_PROP_LAYER:
|
||||
g_value_set_uint (value, priv->layer);
|
||||
break;
|
||||
case PHOSH_LAYER_SURFACE_PROP_KBD_INTERACTIVITY:
|
||||
g_value_set_boolean (value, priv->kbd_interactivity);
|
||||
break;
|
||||
case PHOSH_LAYER_SURFACE_PROP_EXCLUSIVE_ZONE:
|
||||
g_value_set_boolean (value, priv->exclusive_zone);
|
||||
break;
|
||||
case PHOSH_LAYER_SURFACE_PROP_LAYER_WIDTH:
|
||||
g_value_set_uint (value, priv->width);
|
||||
break;
|
||||
case PHOSH_LAYER_SURFACE_PROP_LAYER_HEIGHT:
|
||||
g_value_set_uint (value, priv->height);
|
||||
break;
|
||||
case PHOSH_LAYER_SURFACE_PROP_NAMESPACE:
|
||||
g_value_set_string (value, priv->namespace);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
phosh_layer_surface_constructed (GObject *object)
|
||||
{
|
||||
PhoshLayerSurface *self = PHOSH_LAYER_SURFACE (object);
|
||||
PhoshLayerSurfacePrivate *priv = phosh_layer_surface_get_instance_private (self);
|
||||
GdkWindow *gdk_window;
|
||||
|
||||
G_OBJECT_CLASS (phosh_layer_surface_parent_class)->constructed (object);
|
||||
|
||||
gtk_window_set_decorated (GTK_WINDOW (self), FALSE);
|
||||
/* Realize the window so we can get the GDK window */
|
||||
gtk_widget_realize(GTK_WIDGET (self));
|
||||
|
||||
gdk_window = gtk_widget_get_window (GTK_WIDGET (self));
|
||||
gdk_wayland_window_set_use_custom_surface (gdk_window);
|
||||
priv->wl_surface = gdk_wayland_window_get_wl_surface (gdk_window);
|
||||
|
||||
priv->layer_surface = zwlr_layer_shell_v1_get_layer_surface(priv->layer_shell,
|
||||
priv->wl_surface,
|
||||
priv->wl_output,
|
||||
priv->layer,
|
||||
priv->namespace);
|
||||
zwlr_layer_surface_v1_set_exclusive_zone(priv->layer_surface, priv->exclusive_zone);
|
||||
zwlr_layer_surface_v1_set_size(priv->layer_surface, priv->width, priv->height);
|
||||
zwlr_layer_surface_v1_set_anchor(priv->layer_surface, priv->anchor);
|
||||
zwlr_layer_surface_v1_set_keyboard_interactivity(priv->layer_surface, priv->kbd_interactivity);
|
||||
zwlr_layer_surface_v1_add_listener(priv->layer_surface,
|
||||
&layer_surface_listener,
|
||||
self);
|
||||
wl_surface_commit(priv->wl_surface);
|
||||
}
|
||||
|
||||
static void
|
||||
phosh_layer_surface_dispose (GObject *object)
|
||||
{
|
||||
PhoshLayerSurface *self = PHOSH_LAYER_SURFACE (object);
|
||||
PhoshLayerSurfacePrivate *priv = phosh_layer_surface_get_instance_private (self);
|
||||
|
||||
if (priv->layer_surface) {
|
||||
zwlr_layer_surface_v1_destroy(priv->layer_surface);
|
||||
priv->layer_surface = NULL;
|
||||
}
|
||||
g_clear_pointer (&priv->namespace, g_free);
|
||||
|
||||
G_OBJECT_CLASS (phosh_layer_surface_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
phosh_layer_surface_class_init (PhoshLayerSurfaceClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = (GObjectClass *)klass;
|
||||
|
||||
object_class->constructed = phosh_layer_surface_constructed;
|
||||
object_class->dispose = phosh_layer_surface_dispose;
|
||||
|
||||
object_class->set_property = phosh_layer_surface_set_property;
|
||||
object_class->get_property = phosh_layer_surface_get_property;
|
||||
|
||||
props[PHOSH_LAYER_SURFACE_PROP_LAYER_SHELL] =
|
||||
g_param_spec_pointer (
|
||||
"layer-shell",
|
||||
"Wayland Layer Shell Global",
|
||||
"The layer shell wayland global",
|
||||
G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
|
||||
|
||||
props[PHOSH_LAYER_SURFACE_PROP_WL_OUTPUT] =
|
||||
g_param_spec_pointer (
|
||||
"wl-output",
|
||||
"Wayland Output",
|
||||
"The wl_output associated with this surface",
|
||||
G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
|
||||
|
||||
props[PHOSH_LAYER_SURFACE_PROP_ANCHOR] =
|
||||
g_param_spec_uint (
|
||||
"anchor",
|
||||
"Anchor edges",
|
||||
"The edges to anchor the surface to",
|
||||
0,
|
||||
G_MAXUINT,
|
||||
0,
|
||||
G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
|
||||
|
||||
props[PHOSH_LAYER_SURFACE_PROP_LAYER] =
|
||||
g_param_spec_uint (
|
||||
"layer",
|
||||
"Layer",
|
||||
"The layer the surface should be attached to",
|
||||
0,
|
||||
G_MAXUINT,
|
||||
0,
|
||||
G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
|
||||
|
||||
props[PHOSH_LAYER_SURFACE_PROP_KBD_INTERACTIVITY] =
|
||||
g_param_spec_boolean (
|
||||
"kbd-interactivity",
|
||||
"Keyboard interactivity",
|
||||
"Whether the surface interacts with the keyboard",
|
||||
FALSE,
|
||||
G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
|
||||
|
||||
props[PHOSH_LAYER_SURFACE_PROP_EXCLUSIVE_ZONE] =
|
||||
g_param_spec_int (
|
||||
"exclusive-zone",
|
||||
"Exclusive Zone",
|
||||
"Set area that is not occluded with other surfaces",
|
||||
-1,
|
||||
G_MAXINT,
|
||||
0,
|
||||
G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
|
||||
|
||||
props[PHOSH_LAYER_SURFACE_PROP_LAYER_WIDTH] =
|
||||
g_param_spec_uint (
|
||||
"width",
|
||||
"Width",
|
||||
"The width of the layer surface",
|
||||
0,
|
||||
G_MAXUINT,
|
||||
0,
|
||||
G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
|
||||
|
||||
props[PHOSH_LAYER_SURFACE_PROP_LAYER_HEIGHT] =
|
||||
g_param_spec_uint (
|
||||
"height",
|
||||
"Height",
|
||||
"The height of the layer surface",
|
||||
0,
|
||||
G_MAXUINT,
|
||||
0,
|
||||
G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
|
||||
|
||||
props[PHOSH_LAYER_SURFACE_PROP_NAMESPACE] =
|
||||
g_param_spec_string (
|
||||
"namespace",
|
||||
"Namespace",
|
||||
"Namespace of the layer surface",
|
||||
"",
|
||||
G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
|
||||
|
||||
g_object_class_install_properties (object_class, PHOSH_LAYER_SURFACE_PROP_LAST_PROP, props);
|
||||
|
||||
/**
|
||||
* PhoshLayersurface::configured
|
||||
* @self: The #PhoshLayersurface instance.
|
||||
*
|
||||
* This signal is emitted once we received the configure event from the
|
||||
* compositor.
|
||||
*/
|
||||
signals[CONFIGURED] =
|
||||
g_signal_new ("configured",
|
||||
G_TYPE_FROM_CLASS (klass),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET (PhoshLayerSurfaceClass, configured),
|
||||
NULL, NULL, NULL,
|
||||
G_TYPE_NONE, 0);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
phosh_layer_surface_init (PhoshLayerSurface *self)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
GtkWidget *
|
||||
phosh_layer_surface_new (gpointer layer_shell,
|
||||
gpointer wl_output)
|
||||
{
|
||||
return g_object_new (PHOSH_TYPE_LAYER_SURFACE,
|
||||
"layer-shell", layer_shell,
|
||||
"wl-output", wl_output);
|
||||
}
|
||||
|
||||
struct zwlr_layer_surface_v1 *
|
||||
phosh_layer_surface_get_layer_surface(PhoshLayerSurface *self)
|
||||
{
|
||||
PhoshLayerSurfacePrivate *priv;
|
||||
|
||||
g_return_val_if_fail (PHOSH_IS_LAYER_SURFACE (self), NULL);
|
||||
priv = phosh_layer_surface_get_instance_private (self);
|
||||
return priv->layer_surface;
|
||||
}
|
||||
|
||||
|
||||
struct wl_surface *
|
||||
phosh_layer_surface_get_wl_surface(PhoshLayerSurface *self)
|
||||
{
|
||||
PhoshLayerSurfacePrivate *priv;
|
||||
|
||||
g_return_val_if_fail (PHOSH_IS_LAYER_SURFACE (self), NULL);
|
||||
priv = phosh_layer_surface_get_instance_private (self);
|
||||
return priv->wl_surface;
|
||||
}
|
||||
@ -1,41 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2018 Purism SPC
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-3.0+
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
|
||||
WARNING: this file is taken directly from phosh, with no modificaions apart from this message. Please update phosh instead of changing this file. Please copy the file back here afterwards, with the same notice.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
/* TODO: We use the enum constants from here, use glib-mkenums */
|
||||
#include "wlr-layer-shell-unstable-v1-client-protocol.h"
|
||||
|
||||
#define PHOSH_TYPE_LAYER_SURFACE (phosh_layer_surface_get_type ())
|
||||
|
||||
G_DECLARE_DERIVABLE_TYPE (PhoshLayerSurface, phosh_layer_surface, PHOSH, LAYER_SURFACE, GtkWindow)
|
||||
|
||||
/**
|
||||
* PhoshLayerSurfaceClass
|
||||
* @parent_class: The parent class
|
||||
*/
|
||||
struct _PhoshLayerSurfaceClass
|
||||
{
|
||||
GtkWindowClass parent_class;
|
||||
|
||||
/* Signals
|
||||
*/
|
||||
void (*configured) (PhoshLayerSurface *self);
|
||||
};
|
||||
|
||||
GtkWidget *phosh_layer_surface_new (gpointer layer_shell,
|
||||
gpointer wl_output);
|
||||
struct zwlr_layer_surface_v1 *phosh_layer_surface_get_layer_surface(PhoshLayerSurface *self);
|
||||
struct wl_surface *phosh_layer_surface_get_wl_surface(PhoshLayerSurface *self);
|
||||
@ -1,44 +0,0 @@
|
||||
gnome = import('gnome')
|
||||
|
||||
enum_headers = [
|
||||
'eek-symbol.h',
|
||||
'eek-types.h',
|
||||
]
|
||||
|
||||
enums = gnome.mkenums_simple('eek-enumtypes', sources: enum_headers)
|
||||
|
||||
marshalers = gnome.genmarshal(
|
||||
'eek-marshalers',
|
||||
sources: ['eek-marshalers.list'],
|
||||
prefix: '_eek_marshal',
|
||||
internal: true,
|
||||
)
|
||||
|
||||
python = find_program('python3')
|
||||
|
||||
gen_keysym_entries_special = generator(
|
||||
python,
|
||||
arguments: ['@CURRENT_SOURCE_DIR@/gen-keysym-entries.py', 'special_keysym_entries', '@INPUT@'],
|
||||
capture: true,
|
||||
output: 'eek-@BASENAME@.h',
|
||||
)
|
||||
|
||||
gen_keysym_entries_unicode = generator(
|
||||
python,
|
||||
arguments: ['@CURRENT_SOURCE_DIR@/gen-keysym-entries.py', 'unicode_keysym_entries', '@INPUT@'],
|
||||
capture: true,
|
||||
output: 'eek-@BASENAME@.h',
|
||||
)
|
||||
|
||||
gen_keysym_entries_xkeysym = generator(
|
||||
python,
|
||||
arguments: ['@CURRENT_SOURCE_DIR@/gen-keysym-entries.py', 'xkeysym_keysym_entries', '@INPUT@'],
|
||||
capture: true,
|
||||
output: 'eek-@BASENAME@.h',
|
||||
)
|
||||
|
||||
keysym_entries = [
|
||||
gen_keysym_entries_special.process('./special-keysym-entries.txt'),
|
||||
gen_keysym_entries_unicode.process('./unicode-keysym-entries.txt'),
|
||||
gen_keysym_entries_xkeysym.process('./xkeysym-keysym-entries.txt'),
|
||||
]
|
||||
@ -30,7 +30,7 @@
|
||||
0xFF9E "Ins" EEK_SYMBOL_CATEGORY_FUNCTION
|
||||
0xFF9F "Del" EEK_SYMBOL_CATEGORY_FUNCTION
|
||||
# aliases
|
||||
0xFE03 "123" EEK_SYMBOL_CATEGORY_KEYNAME
|
||||
0xFE03 "⇮" EEK_SYMBOL_CATEGORY_KEYNAME
|
||||
0xFE04 "⇮" EEK_SYMBOL_CATEGORY_KEYNAME
|
||||
0xFE05 "⇮" EEK_SYMBOL_CATEGORY_KEYNAME
|
||||
0xFE08 "Next" EEK_SYMBOL_CATEGORY_KEYNAME
|
||||
|
||||
136
eekboard/Makefile.am
Normal file
@ -0,0 +1,136 @@
|
||||
# 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
|
||||
|
||||
NULL =
|
||||
|
||||
lib_LTLIBRARIES = libeekboard.la
|
||||
|
||||
libeekboard_headers = \
|
||||
$(srcdir)/eekboard-service.h \
|
||||
$(srcdir)/eekboard-context-service.h \
|
||||
$(srcdir)/eekboard-client.h \
|
||||
$(srcdir)/eekboard-context.h \
|
||||
$(srcdir)/eekboard-xklutil.h \
|
||||
$(NULL)
|
||||
|
||||
libeekboard_private_headers = \
|
||||
$(builddir)/eekboard-marshalers.h \
|
||||
$(NULL)
|
||||
|
||||
libeekboard_sources = \
|
||||
$(srcdir)/eekboard-service.c \
|
||||
$(srcdir)/eekboard-context-service.c \
|
||||
$(srcdir)/eekboard-client.c \
|
||||
$(srcdir)/eekboard-context.c \
|
||||
$(srcdir)/eekboard-xklutil.c \
|
||||
$(NULL)
|
||||
|
||||
libeekboard_marshalers_sources = \
|
||||
$(builddir)/eekboard-marshalers.c \
|
||||
$(builddir)/eekboard-marshalers.h \
|
||||
$(NULL)
|
||||
|
||||
BUILT_SOURCES = \
|
||||
$(libeekboard_marshalers_sources) \
|
||||
$(NULL)
|
||||
|
||||
libeekboard_la_SOURCES = \
|
||||
$(libeekboard_sources) \
|
||||
$(builddir)/eekboard-marshalers.c \
|
||||
$(NULL)
|
||||
|
||||
libeekboard_la_CFLAGS = \
|
||||
-DEEKBOARD_COMPILATION=1 \
|
||||
-DKEYBOARDDIR=\"$(pkgdatadir)/keyboards\" \
|
||||
-I$(top_srcdir) \
|
||||
$(GIO2_CFLAGS) \
|
||||
$(LIBXKLAVIER_CFLAGS) \
|
||||
$(NULL)
|
||||
libeekboard_la_LIBADD = \
|
||||
$(top_builddir)/eek/libeek.la \
|
||||
$(top_builddir)/eek/libeek-xkl.la \
|
||||
$(GIO2_LIBS) \
|
||||
$(LIBXKLAVIER_LIBS) \
|
||||
$(NULL)
|
||||
|
||||
eekboarddir = $(includedir)/eekboard-$(EEK_API_VERSION)/eekboard
|
||||
eekboard_HEADERS = $(libeekboard_headers)
|
||||
|
||||
pkgconfigdir = $(libdir)/pkgconfig
|
||||
pkgconfig_DATA = \
|
||||
eekboard-$(EEK_API_VERSION).pc \
|
||||
$(NULL)
|
||||
DISTCLEANFILES = \
|
||||
$(BUILT_SOURCES) \
|
||||
$(pkgconfig_DATA) \
|
||||
$(NULL)
|
||||
|
||||
CLEANFILES =
|
||||
|
||||
EXTRA_DIST = eekboard-marshalers.list
|
||||
|
||||
# gen marshal
|
||||
eekboard-marshalers.h: eekboard-marshalers.list
|
||||
$(AM_V_GEN) $(GLIB_GENMARSHAL) \
|
||||
--prefix=_eekboard_marshal \
|
||||
$(srcdir)/eekboard-marshalers.list --header --internal \
|
||||
> $@.tmp && \
|
||||
mv $@.tmp $@
|
||||
|
||||
eekboard-marshalers.c: eekboard-marshalers.list eekboard-marshalers.h
|
||||
$(AM_V_GEN) (echo "#include \"eekboard-marshalers.h\""; \
|
||||
$(GLIB_GENMARSHAL) \
|
||||
--prefix=_eekboard_marshal \
|
||||
$(srcdir)/eekboard-marshalers.list --body --internal) \
|
||||
> $@.tmp && \
|
||||
mv $@.tmp $@
|
||||
|
||||
-include $(INTROSPECTION_MAKEFILE)
|
||||
INTROSPECTION_GIRS =
|
||||
INTROSPECTION_SCANNER_ARGS = \
|
||||
--add-include-path=$(builddir) \
|
||||
--add-include-path=$(top_builddir)/eek \
|
||||
$(NULL)
|
||||
INTROSPECTION_COMPILER_ARGS = \
|
||||
--includedir=$(builddir) \
|
||||
--includedir=$(top_builddir)/eek \
|
||||
$(NULL)
|
||||
|
||||
if HAVE_INTROSPECTION
|
||||
Eekboard@EEK_LIBRARY_SUFFIX@.gir: libeekboard.la
|
||||
Eekboard@EEK_LIBRARY_SUFFIX_U@_gir_SCANNERFLAGS = \
|
||||
--identifier-prefix=Eekboard \
|
||||
--symbol-prefix=eekboard \
|
||||
$(NULL)
|
||||
Eekboard@EEK_LIBRARY_SUFFIX_U@_gir_INCLUDES = Eek@EEK_LIBRARY_SUFFIX@
|
||||
Eekboard@EEK_LIBRARY_SUFFIX_U@_gir_CFLAGS = $(libeekboard_la_CFLAGS)
|
||||
Eekboard@EEK_LIBRARY_SUFFIX_U@_gir_LIBS = libeekboard.la
|
||||
Eekboard@EEK_LIBRARY_SUFFIX_U@_gir_FILES = $(libeekboard_sources) $(libeekboard_headers)
|
||||
|
||||
INTROSPECTION_GIRS += Eekboard@EEK_LIBRARY_SUFFIX@.gir
|
||||
|
||||
girdir = $(datadir)/gir-1.0
|
||||
gir_DATA = $(INTROSPECTION_GIRS)
|
||||
|
||||
typelibdir = $(libdir)/girepository-1.0
|
||||
typelib_DATA = $(INTROSPECTION_GIRS:.gir=.typelib)
|
||||
|
||||
CLEANFILES += $(gir_DATA) $(typelib_DATA)
|
||||
endif
|
||||
|
||||
-include $(top_srcdir)/git.mk
|
||||
401
eekboard/eekboard-client.c
Normal file
@ -0,0 +1,401 @@
|
||||
/*
|
||||
* Copyright (C) 2011 Daiki Ueno <ueno@unixuser.org>
|
||||
* Copyright (C) 2011 Red Hat, Inc.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* SECTION:eekboard-client
|
||||
* @short_description: client interface of eekboard service
|
||||
*
|
||||
* The #EekboardClient class provides a client side access to eekboard-server.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
|
||||
#include "eekboard/eekboard-client.h"
|
||||
|
||||
enum {
|
||||
DESTROYED,
|
||||
LAST_SIGNAL
|
||||
};
|
||||
|
||||
static guint signals[LAST_SIGNAL] = { 0, };
|
||||
|
||||
G_DEFINE_TYPE (EekboardClient, eekboard_client, G_TYPE_DBUS_PROXY);
|
||||
|
||||
#define EEKBOARD_CLIENT_GET_PRIVATE(obj) \
|
||||
(G_TYPE_INSTANCE_GET_PRIVATE ((obj), EEKBOARD_TYPE_CLIENT, EekboardClientPrivate))
|
||||
|
||||
struct _EekboardClientPrivate
|
||||
{
|
||||
GHashTable *context_hash;
|
||||
};
|
||||
|
||||
static void send_destroy_context (EekboardClient *client,
|
||||
EekboardContext *context,
|
||||
GCancellable *cancellable);
|
||||
|
||||
static void
|
||||
eekboard_client_real_destroyed (EekboardClient *self)
|
||||
{
|
||||
EekboardClientPrivate *priv = EEKBOARD_CLIENT_GET_PRIVATE(self);
|
||||
|
||||
// g_debug ("eekboard_client_real_destroyed");
|
||||
g_hash_table_remove_all (priv->context_hash);
|
||||
}
|
||||
|
||||
static void
|
||||
eekboard_client_dispose (GObject *object)
|
||||
{
|
||||
EekboardClient *client = EEKBOARD_CLIENT(object);
|
||||
EekboardClientPrivate *priv = EEKBOARD_CLIENT_GET_PRIVATE(client);
|
||||
|
||||
if (priv->context_hash) {
|
||||
GHashTableIter iter;
|
||||
gpointer key, value;
|
||||
|
||||
g_hash_table_iter_init (&iter, priv->context_hash);
|
||||
while (g_hash_table_iter_next (&iter, &key, &value)) {
|
||||
send_destroy_context (client, (EekboardContext *)value, NULL);
|
||||
g_hash_table_iter_remove (&iter);
|
||||
}
|
||||
g_hash_table_destroy (priv->context_hash);
|
||||
priv->context_hash = NULL;
|
||||
}
|
||||
|
||||
G_OBJECT_CLASS (eekboard_client_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
eekboard_client_class_init (EekboardClientClass *klass)
|
||||
{
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
g_type_class_add_private (gobject_class,
|
||||
sizeof (EekboardClientPrivate));
|
||||
|
||||
klass->destroyed = eekboard_client_real_destroyed;
|
||||
|
||||
gobject_class->dispose = eekboard_client_dispose;
|
||||
|
||||
/**
|
||||
* EekboardClient::destroyed:
|
||||
* @eekboard: an #EekboardClient
|
||||
*
|
||||
* The ::destroyed signal is emitted each time the name of remote
|
||||
* end is vanished.
|
||||
*/
|
||||
signals[DESTROYED] =
|
||||
g_signal_new (I_("destroyed"),
|
||||
G_TYPE_FROM_CLASS(gobject_class),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET(EekboardClientClass, destroyed),
|
||||
NULL,
|
||||
NULL,
|
||||
g_cclosure_marshal_VOID__VOID,
|
||||
G_TYPE_NONE,
|
||||
0);
|
||||
}
|
||||
|
||||
static void
|
||||
eekboard_client_init (EekboardClient *self)
|
||||
{
|
||||
self->priv = EEKBOARD_CLIENT_GET_PRIVATE(self);
|
||||
self->priv->context_hash =
|
||||
g_hash_table_new_full (g_str_hash,
|
||||
g_str_equal,
|
||||
(GDestroyNotify)g_free,
|
||||
(GDestroyNotify)g_object_unref);
|
||||
}
|
||||
|
||||
static void
|
||||
eekboard_name_vanished_callback (GDBusConnection *connection,
|
||||
const gchar *name,
|
||||
gpointer user_data)
|
||||
{
|
||||
EekboardClient *client = user_data;
|
||||
g_signal_emit_by_name (client, "destroyed", NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* eekboard_client_new:
|
||||
* @connection: a #GDBusConnection
|
||||
* @cancellable: a #GCancellable
|
||||
*
|
||||
* Create a client.
|
||||
*/
|
||||
EekboardClient *
|
||||
eekboard_client_new (GDBusConnection *connection,
|
||||
GCancellable *cancellable)
|
||||
{
|
||||
GInitable *initable;
|
||||
GError *error;
|
||||
|
||||
g_assert (G_IS_DBUS_CONNECTION(connection));
|
||||
|
||||
error = NULL;
|
||||
initable =
|
||||
g_initable_new (EEKBOARD_TYPE_CLIENT,
|
||||
cancellable,
|
||||
&error,
|
||||
"g-connection", connection,
|
||||
"g-name", "org.fedorahosted.Eekboard",
|
||||
"g-interface-name", "org.fedorahosted.Eekboard",
|
||||
"g-object-path", "/org/fedorahosted/Eekboard",
|
||||
NULL);
|
||||
if (initable != NULL) {
|
||||
EekboardClient *client = EEKBOARD_CLIENT (initable);
|
||||
gchar *name_owner = g_dbus_proxy_get_name_owner (G_DBUS_PROXY(client));
|
||||
if (name_owner == NULL) {
|
||||
g_object_unref (client);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* the vanished callback is called when the server is disconnected */
|
||||
g_bus_watch_name_on_connection (connection,
|
||||
name_owner,
|
||||
G_BUS_NAME_WATCHER_FLAGS_NONE,
|
||||
NULL,
|
||||
eekboard_name_vanished_callback,
|
||||
client,
|
||||
NULL);
|
||||
g_free (name_owner);
|
||||
|
||||
return client;
|
||||
}
|
||||
|
||||
g_warning ("can't create client: %s", error->message);
|
||||
g_error_free (error);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
on_context_destroyed (EekboardContext *context,
|
||||
gpointer user_data)
|
||||
{
|
||||
EekboardClient *client = user_data;
|
||||
g_hash_table_remove (client->priv->context_hash,
|
||||
g_dbus_proxy_get_object_path (G_DBUS_PROXY(context)));
|
||||
}
|
||||
|
||||
/**
|
||||
* eekboard_client_create_context:
|
||||
* @eekboard: an #EekboardClient
|
||||
* @client_name: name of the client
|
||||
* @cancellable: a #GCancellable
|
||||
*
|
||||
* Create a new input context.
|
||||
*
|
||||
* Return value: (transfer full): a newly created #EekboardContext.
|
||||
*/
|
||||
EekboardContext *
|
||||
eekboard_client_create_context (EekboardClient *client,
|
||||
const gchar *client_name,
|
||||
GCancellable *cancellable)
|
||||
{
|
||||
GVariant *variant;
|
||||
const gchar *object_path;
|
||||
EekboardContext *context;
|
||||
GError *error;
|
||||
GDBusConnection *connection;
|
||||
|
||||
g_assert (EEKBOARD_IS_CLIENT(client));
|
||||
g_assert (client_name);
|
||||
|
||||
error = NULL;
|
||||
variant = g_dbus_proxy_call_sync (G_DBUS_PROXY(client),
|
||||
"CreateContext",
|
||||
g_variant_new ("(s)", client_name),
|
||||
G_DBUS_CALL_FLAGS_NONE,
|
||||
-1,
|
||||
cancellable,
|
||||
&error);
|
||||
if (!variant) {
|
||||
g_warning ("failed to call CreateContext: %s", error->message);
|
||||
g_error_free (error);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
g_variant_get (variant, "(&s)", &object_path);
|
||||
connection = g_dbus_proxy_get_connection (G_DBUS_PROXY(client));
|
||||
context = eekboard_context_new (connection, object_path, cancellable);
|
||||
if (!context) {
|
||||
g_variant_unref (variant);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
g_hash_table_insert (client->priv->context_hash,
|
||||
g_strdup (object_path),
|
||||
g_object_ref (context));
|
||||
g_signal_connect (context, "destroyed",
|
||||
G_CALLBACK(on_context_destroyed), client);
|
||||
return context;
|
||||
}
|
||||
|
||||
static void
|
||||
eekboard_async_ready_callback (GObject *source_object,
|
||||
GAsyncResult *res,
|
||||
gpointer user_data)
|
||||
{
|
||||
GError *error = NULL;
|
||||
GVariant *result;
|
||||
|
||||
result = g_dbus_proxy_call_finish (G_DBUS_PROXY(source_object),
|
||||
res,
|
||||
&error);
|
||||
if (result)
|
||||
g_variant_unref (result);
|
||||
else {
|
||||
g_warning ("error in D-Bus proxy call: %s", error->message);
|
||||
g_error_free (error);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* eekboard_client_push_context:
|
||||
* @eekboard: an #EekboardClient
|
||||
* @context: an #EekboardContext
|
||||
* @cancellable: a #GCancellable
|
||||
*
|
||||
* Enable the input context @context and disable the others.
|
||||
*/
|
||||
void
|
||||
eekboard_client_push_context (EekboardClient *client,
|
||||
EekboardContext *context,
|
||||
GCancellable *cancellable)
|
||||
{
|
||||
const gchar *object_path;
|
||||
|
||||
g_return_if_fail (EEKBOARD_IS_CLIENT(client));
|
||||
g_return_if_fail (EEKBOARD_IS_CONTEXT(context));
|
||||
|
||||
object_path = g_dbus_proxy_get_object_path (G_DBUS_PROXY(context));
|
||||
|
||||
context = g_hash_table_lookup (client->priv->context_hash,
|
||||
object_path);
|
||||
if (!context)
|
||||
return;
|
||||
|
||||
eekboard_context_set_enabled (context, TRUE);
|
||||
g_dbus_proxy_call (G_DBUS_PROXY(client),
|
||||
"PushContext",
|
||||
g_variant_new ("(s)", object_path),
|
||||
G_DBUS_CALL_FLAGS_NONE,
|
||||
-1,
|
||||
cancellable,
|
||||
eekboard_async_ready_callback,
|
||||
NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* eekboard_client_pop_context:
|
||||
* @eekboard: an #EekboardClient
|
||||
* @cancellable: a #GCancellable
|
||||
*
|
||||
* Disable the current input context and enable the previous one.
|
||||
*/
|
||||
void
|
||||
eekboard_client_pop_context (EekboardClient *client,
|
||||
GCancellable *cancellable)
|
||||
{
|
||||
g_return_if_fail (EEKBOARD_IS_CLIENT(client));
|
||||
|
||||
g_dbus_proxy_call (G_DBUS_PROXY(client),
|
||||
"PopContext",
|
||||
NULL,
|
||||
G_DBUS_CALL_FLAGS_NONE,
|
||||
-1,
|
||||
cancellable,
|
||||
eekboard_async_ready_callback,
|
||||
NULL);
|
||||
}
|
||||
|
||||
void
|
||||
eekboard_client_show_keyboard (EekboardClient *client,
|
||||
GCancellable *cancellable)
|
||||
{
|
||||
g_return_if_fail (EEKBOARD_IS_CLIENT(client));
|
||||
|
||||
g_dbus_proxy_call (G_DBUS_PROXY(client),
|
||||
"ShowKeyboard",
|
||||
NULL,
|
||||
G_DBUS_CALL_FLAGS_NONE,
|
||||
-1,
|
||||
cancellable,
|
||||
eekboard_async_ready_callback,
|
||||
NULL);
|
||||
}
|
||||
|
||||
void
|
||||
eekboard_client_hide_keyboard (EekboardClient *client,
|
||||
GCancellable *cancellable)
|
||||
{
|
||||
g_return_if_fail (EEKBOARD_IS_CLIENT(client));
|
||||
|
||||
g_dbus_proxy_call (G_DBUS_PROXY(client),
|
||||
"HideKeyboard",
|
||||
NULL,
|
||||
G_DBUS_CALL_FLAGS_NONE,
|
||||
-1,
|
||||
cancellable,
|
||||
eekboard_async_ready_callback,
|
||||
NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
send_destroy_context (EekboardClient *client,
|
||||
EekboardContext *context,
|
||||
GCancellable *cancellable)
|
||||
{
|
||||
const gchar *object_path;
|
||||
|
||||
object_path = g_dbus_proxy_get_object_path (G_DBUS_PROXY(context));
|
||||
|
||||
g_dbus_proxy_call (G_DBUS_PROXY(client),
|
||||
"DestroyContext",
|
||||
g_variant_new ("(s)", object_path),
|
||||
G_DBUS_CALL_FLAGS_NONE,
|
||||
-1,
|
||||
cancellable,
|
||||
eekboard_async_ready_callback,
|
||||
NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* eekboard_client_destroy_context:
|
||||
* @eekboard: an #EekboardClient
|
||||
* @context: an #EekboardContext
|
||||
* @cancellable: a #GCancellable
|
||||
*
|
||||
* Remove @context from @eekboard.
|
||||
*/
|
||||
void
|
||||
eekboard_client_destroy_context (EekboardClient *client,
|
||||
EekboardContext *context,
|
||||
GCancellable *cancellable)
|
||||
{
|
||||
const gchar *object_path;
|
||||
|
||||
g_return_if_fail (EEKBOARD_IS_CLIENT(client));
|
||||
g_return_if_fail (EEKBOARD_IS_CONTEXT(context));
|
||||
|
||||
object_path = g_dbus_proxy_get_object_path (G_DBUS_PROXY(context));
|
||||
g_hash_table_remove (client->priv->context_hash, object_path);
|
||||
|
||||
send_destroy_context (client, context, cancellable);
|
||||
}
|
||||
79
eekboard/eekboard-client.h
Normal file
@ -0,0 +1,79 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2011 Daiki Ueno <ueno@unixuser.org>
|
||||
* Copyright (C) 2010-2011 Red Hat, Inc.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef EEKBOARD_CLIENT_H
|
||||
#define EEKBOARD_CLIENT_H 1
|
||||
|
||||
#define __EEKBOARD_CLIENT_H_INSIDE__ 1
|
||||
|
||||
#include <gio/gio.h>
|
||||
#include "eekboard/eekboard-context.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define EEKBOARD_TYPE_CLIENT (eekboard_client_get_type())
|
||||
#define EEKBOARD_CLIENT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EEKBOARD_TYPE_CLIENT, EekboardClient))
|
||||
#define EEKBOARD_CLIENT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EEKBOARD_TYPE_CLIENT, EekboardClientClass))
|
||||
#define EEKBOARD_IS_CLIENT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EEKBOARD_TYPE_CLIENT))
|
||||
#define EEKBOARD_IS_CLIENT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EEKBOARD_TYPE_CLIENT))
|
||||
#define EEKBOARD_CLIENT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EEKBOARD_TYPE_CLIENT, EekboardClientClass))
|
||||
|
||||
typedef struct _EekboardClient EekboardClient;
|
||||
typedef struct _EekboardClientClass EekboardClientClass;
|
||||
typedef struct _EekboardClientPrivate EekboardClientPrivate;
|
||||
|
||||
struct _EekboardClient {
|
||||
/*< private >*/
|
||||
GDBusProxy parent;
|
||||
|
||||
EekboardClientPrivate *priv;
|
||||
};
|
||||
|
||||
struct _EekboardClientClass {
|
||||
/*< private >*/
|
||||
GDBusProxyClass parent_class;
|
||||
|
||||
/* signals */
|
||||
void (* destroyed) (EekboardClient *self);
|
||||
|
||||
/*< private >*/
|
||||
/* padding */
|
||||
gpointer pdummy[23];
|
||||
};
|
||||
|
||||
GType eekboard_client_get_type (void) G_GNUC_CONST;
|
||||
|
||||
EekboardClient *eekboard_client_new (GDBusConnection *connection,
|
||||
GCancellable *cancellable);
|
||||
EekboardContext *eekboard_client_create_context (EekboardClient *eekboard,
|
||||
const gchar *client_name,
|
||||
GCancellable *cancellable);
|
||||
void eekboard_client_push_context (EekboardClient *eekboard,
|
||||
EekboardContext *context,
|
||||
GCancellable *cancellable);
|
||||
void eekboard_client_pop_context (EekboardClient *eekboard,
|
||||
GCancellable *cancellable);
|
||||
void eekboard_client_show_keyboard (EekboardClient *eekboard,
|
||||
GCancellable *cancellable);
|
||||
void eekboard_client_hide_keyboard (EekboardClient *eekboard,
|
||||
GCancellable *cancellable);
|
||||
void eekboard_client_destroy_context (EekboardClient *eekboard,
|
||||
EekboardContext *context,
|
||||
GCancellable *cancellable);
|
||||
|
||||
G_END_DECLS
|
||||
#endif /* EEKBOARD_CLIENT_H */
|
||||
@ -24,8 +24,6 @@
|
||||
|
||||
#include <eek/eek.h>
|
||||
|
||||
#include "virtual-keyboard-unstable-v1-client-protocol.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define EEKBOARD_CONTEXT_SERVICE_PATH "/org/fedorahosted/Eekboard/Context_%d"
|
||||
@ -38,16 +36,13 @@ G_BEGIN_DECLS
|
||||
#define EEKBOARD_IS_CONTEXT_SERVICE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EEKBOARD_TYPE_CONTEXT_SERVICE))
|
||||
#define EEKBOARD_CONTEXT_SERVICE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EEKBOARD_TYPE_CONTEXT_SERVICE, EekboardContextServiceClass))
|
||||
|
||||
|
||||
typedef struct _EekboardContextService EekboardContextService;
|
||||
typedef struct _EekboardContextServiceClass EekboardContextServiceClass;
|
||||
typedef struct _EekboardContextServicePrivate EekboardContextServicePrivate;
|
||||
|
||||
/**
|
||||
* EekboardContextService:
|
||||
*
|
||||
* TODO: Restrict to managing keyboard layouts, and maybe button repeats,
|
||||
* and the virtual keyboard protocol.
|
||||
*
|
||||
* The #EekboardContextService structure contains only private data
|
||||
* and should only be accessed using the provided API.
|
||||
*/
|
||||
@ -55,8 +50,6 @@ struct _EekboardContextService {
|
||||
GObject parent;
|
||||
|
||||
EekboardContextServicePrivate *priv;
|
||||
|
||||
struct zwp_virtual_keyboard_v1 *virtual_keyboard;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -100,9 +93,8 @@ EekKeyboard *eekboard_context_service_get_keyboard
|
||||
(EekboardContextService *context);
|
||||
gboolean eekboard_context_service_get_fullscreen
|
||||
(EekboardContextService *context);
|
||||
|
||||
void eekboard_context_service_set_keymap(EekboardContextService *context,
|
||||
const EekKeyboard *keyboard);
|
||||
const gchar * eekboard_context_service_get_client_name
|
||||
(EekboardContextService *context);
|
||||
|
||||
G_END_DECLS
|
||||
#endif /* EEKBOARD_CONTEXT_SERVICE_H */
|
||||
|
||||
@ -29,7 +29,7 @@
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
|
||||
#include "eekboard/eekboard-context.h"
|
||||
//#include "eekboard/eekboard-marshalers.h"
|
||||
#include "eekboard/eekboard-marshalers.h"
|
||||
|
||||
#define I_(string) g_intern_static_string (string)
|
||||
|
||||
@ -49,15 +49,18 @@ enum {
|
||||
PROP_LAST
|
||||
};
|
||||
|
||||
typedef struct _EekboardContextPrivate
|
||||
G_DEFINE_TYPE (EekboardContext, eekboard_context, G_TYPE_DBUS_PROXY);
|
||||
|
||||
#define EEKBOARD_CONTEXT_GET_PRIVATE(obj) \
|
||||
(G_TYPE_INSTANCE_GET_PRIVATE ((obj), EEKBOARD_TYPE_CONTEXT, EekboardContextPrivate))
|
||||
|
||||
struct _EekboardContextPrivate
|
||||
{
|
||||
gboolean visible;
|
||||
gboolean enabled;
|
||||
gboolean fullscreen;
|
||||
gint group;
|
||||
} EekboardContextPrivate;
|
||||
|
||||
G_DEFINE_TYPE_WITH_PRIVATE (EekboardContext, eekboard_context, G_TYPE_DBUS_PROXY)
|
||||
};
|
||||
|
||||
static void
|
||||
eekboard_context_real_g_signal (GDBusProxy *self,
|
||||
@ -66,7 +69,6 @@ eekboard_context_real_g_signal (GDBusProxy *self,
|
||||
GVariant *parameters)
|
||||
{
|
||||
EekboardContext *context = EEKBOARD_CONTEXT (self);
|
||||
EekboardContextPrivate *priv = eekboard_context_get_instance_private (context);
|
||||
|
||||
if (g_strcmp0 (signal_name, "Enabled") == 0) {
|
||||
g_signal_emit (context, signals[ENABLED], 0);
|
||||
@ -109,8 +111,8 @@ eekboard_context_real_g_signal (GDBusProxy *self,
|
||||
gboolean visible = FALSE;
|
||||
|
||||
g_variant_get (parameters, "(b)", &visible);
|
||||
if (visible != priv->visible) {
|
||||
priv->visible = visible;
|
||||
if (visible != context->priv->visible) {
|
||||
context->priv->visible = visible;
|
||||
g_object_notify (G_OBJECT(context), "visible");
|
||||
}
|
||||
return;
|
||||
@ -120,8 +122,8 @@ eekboard_context_real_g_signal (GDBusProxy *self,
|
||||
gint group = 0;
|
||||
|
||||
g_variant_get (parameters, "(i)", &group);
|
||||
if (group != priv->group) {
|
||||
priv->group = group;
|
||||
if (group != context->priv->group) {
|
||||
context->priv->group = group;
|
||||
/* g_object_notify (G_OBJECT(context), "group"); */
|
||||
}
|
||||
return;
|
||||
@ -133,17 +135,13 @@ eekboard_context_real_g_signal (GDBusProxy *self,
|
||||
static void
|
||||
eekboard_context_real_enabled (EekboardContext *self)
|
||||
{
|
||||
EekboardContextPrivate *priv = eekboard_context_get_instance_private (self);
|
||||
|
||||
priv->enabled = TRUE;
|
||||
self->priv->enabled = TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
eekboard_context_real_disabled (EekboardContext *self)
|
||||
{
|
||||
EekboardContextPrivate *priv = eekboard_context_get_instance_private (self);
|
||||
|
||||
priv->enabled = FALSE;
|
||||
self->priv->enabled = FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
@ -166,11 +164,9 @@ eekboard_context_get_property (GObject *object,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
EekboardContext *context = EEKBOARD_CONTEXT(object);
|
||||
EekboardContextPrivate *priv = eekboard_context_get_instance_private (context);
|
||||
|
||||
switch (prop_id) {
|
||||
case PROP_VISIBLE:
|
||||
g_value_set_boolean (value, priv->visible);
|
||||
g_value_set_boolean (value, context->priv->visible);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
@ -185,6 +181,9 @@ eekboard_context_class_init (EekboardContextClass *klass)
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||
GParamSpec *pspec;
|
||||
|
||||
g_type_class_add_private (gobject_class,
|
||||
sizeof (EekboardContextPrivate));
|
||||
|
||||
klass->enabled = eekboard_context_real_enabled;
|
||||
klass->disabled = eekboard_context_real_disabled;
|
||||
klass->destroyed = eekboard_context_real_destroyed;
|
||||
@ -252,7 +251,6 @@ eekboard_context_class_init (EekboardContextClass *klass)
|
||||
* The ::key-activated signal is emitted each time a key is
|
||||
* pressed in @context.
|
||||
*/
|
||||
/*
|
||||
signals[KEY_ACTIVATED] =
|
||||
g_signal_new (I_("key-activated"),
|
||||
G_TYPE_FROM_CLASS(gobject_class),
|
||||
@ -266,7 +264,7 @@ eekboard_context_class_init (EekboardContextClass *klass)
|
||||
G_TYPE_UINT,
|
||||
G_TYPE_OBJECT,
|
||||
G_TYPE_UINT);
|
||||
*/
|
||||
|
||||
/**
|
||||
* EekboardContext::destroyed:
|
||||
* @context: an #EekboardContext
|
||||
@ -289,7 +287,7 @@ eekboard_context_class_init (EekboardContextClass *klass)
|
||||
static void
|
||||
eekboard_context_init (EekboardContext *self)
|
||||
{
|
||||
/* void */
|
||||
self->priv = EEKBOARD_CONTEXT_GET_PRIVATE(self);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -486,9 +484,7 @@ eekboard_context_set_group (EekboardContext *context,
|
||||
{
|
||||
g_return_if_fail (EEKBOARD_IS_CONTEXT(context));
|
||||
|
||||
EekboardContextPrivate *priv = eekboard_context_get_instance_private (context);
|
||||
|
||||
if (priv->group != group) {
|
||||
if (context->priv->group != group) {
|
||||
g_dbus_proxy_call (G_DBUS_PROXY(context),
|
||||
"SetGroup",
|
||||
g_variant_new ("(i)", group),
|
||||
@ -512,10 +508,7 @@ eekboard_context_get_group (EekboardContext *context,
|
||||
GCancellable *cancellable)
|
||||
{
|
||||
g_return_val_if_fail (EEKBOARD_IS_CONTEXT(context), 0);
|
||||
|
||||
EekboardContextPrivate *priv = eekboard_context_get_instance_private (context);
|
||||
|
||||
return priv->group;
|
||||
return context->priv->group;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -532,9 +525,7 @@ eekboard_context_show_keyboard (EekboardContext *context,
|
||||
{
|
||||
g_return_if_fail (EEKBOARD_IS_CONTEXT(context));
|
||||
|
||||
EekboardContextPrivate *priv = eekboard_context_get_instance_private (context);
|
||||
|
||||
if (priv->enabled) {
|
||||
if (context->priv->enabled) {
|
||||
g_dbus_proxy_call (G_DBUS_PROXY(context),
|
||||
"ShowKeyboard",
|
||||
NULL,
|
||||
@ -559,9 +550,7 @@ eekboard_context_hide_keyboard (EekboardContext *context,
|
||||
{
|
||||
g_return_if_fail (EEKBOARD_IS_CONTEXT(context));
|
||||
|
||||
EekboardContextPrivate *priv = eekboard_context_get_instance_private (context);
|
||||
|
||||
if (priv->enabled) {
|
||||
if (context->priv->enabled) {
|
||||
g_dbus_proxy_call (G_DBUS_PROXY(context),
|
||||
"HideKeyboard",
|
||||
NULL,
|
||||
@ -588,9 +577,7 @@ eekboard_context_press_keycode (EekboardContext *context,
|
||||
{
|
||||
g_return_if_fail (EEKBOARD_IS_CONTEXT(context));
|
||||
|
||||
EekboardContextPrivate *priv = eekboard_context_get_instance_private (context);
|
||||
|
||||
if (priv->enabled) {
|
||||
if (context->priv->enabled) {
|
||||
g_dbus_proxy_call (G_DBUS_PROXY(context),
|
||||
"PressKeycode",
|
||||
g_variant_new ("(u)", keycode),
|
||||
@ -617,9 +604,7 @@ eekboard_context_release_keycode (EekboardContext *context,
|
||||
{
|
||||
g_return_if_fail (EEKBOARD_IS_CONTEXT(context));
|
||||
|
||||
EekboardContextPrivate *priv = eekboard_context_get_instance_private (context);
|
||||
|
||||
if (priv->enabled) {
|
||||
if (context->priv->enabled) {
|
||||
g_dbus_proxy_call (G_DBUS_PROXY(context),
|
||||
"ReleaseKeycode",
|
||||
g_variant_new ("(u)", keycode),
|
||||
@ -641,10 +626,7 @@ gboolean
|
||||
eekboard_context_is_visible (EekboardContext *context)
|
||||
{
|
||||
g_return_val_if_fail (EEKBOARD_IS_CONTEXT(context), FALSE);
|
||||
|
||||
EekboardContextPrivate *priv = eekboard_context_get_instance_private (context);
|
||||
|
||||
return priv->enabled && priv->visible;
|
||||
return context->priv->enabled && context->priv->visible;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -661,10 +643,7 @@ eekboard_context_set_enabled (EekboardContext *context,
|
||||
gboolean enabled)
|
||||
{
|
||||
g_return_if_fail (EEKBOARD_IS_CONTEXT(context));
|
||||
|
||||
EekboardContextPrivate *priv = eekboard_context_get_instance_private (context);
|
||||
|
||||
priv->enabled = enabled;
|
||||
context->priv->enabled = enabled;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -677,10 +656,7 @@ gboolean
|
||||
eekboard_context_is_enabled (EekboardContext *context)
|
||||
{
|
||||
g_return_val_if_fail (EEKBOARD_IS_CONTEXT(context), FALSE);
|
||||
|
||||
EekboardContextPrivate *priv = eekboard_context_get_instance_private (context);
|
||||
|
||||
return priv->enabled;
|
||||
return context->priv->enabled;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -697,10 +673,7 @@ eekboard_context_set_fullscreen (EekboardContext *context,
|
||||
GCancellable *cancellable)
|
||||
{
|
||||
g_return_if_fail (EEKBOARD_IS_CONTEXT(context));
|
||||
|
||||
EekboardContextPrivate *priv = eekboard_context_get_instance_private (context);
|
||||
|
||||
if (priv->fullscreen != fullscreen) {
|
||||
if (context->priv->fullscreen != fullscreen) {
|
||||
g_dbus_proxy_call (G_DBUS_PROXY(context),
|
||||
"SetFullscreen",
|
||||
g_variant_new ("(b)", fullscreen),
|
||||
|
||||
@ -28,7 +28,28 @@
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define EEKBOARD_TYPE_CONTEXT (eekboard_context_get_type())
|
||||
G_DECLARE_DERIVABLE_TYPE (EekboardContext, eekboard_context, EEKBOARD, CONTEXT, GDBusProxy)
|
||||
#define EEKBOARD_CONTEXT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EEKBOARD_TYPE_CONTEXT, EekboardContext))
|
||||
#define EEKBOARD_CONTEXT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EEKBOARD_TYPE_CONTEXT, EekboardContextClass))
|
||||
#define EEKBOARD_IS_CONTEXT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EEKBOARD_TYPE_CONTEXT))
|
||||
#define EEKBOARD_IS_CONTEXT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EEKBOARD_TYPE_CONTEXT))
|
||||
#define EEKBOARD_CONTEXT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EEKBOARD_TYPE_CONTEXT, EekboardContextClass))
|
||||
|
||||
typedef struct _EekboardContext EekboardContext;
|
||||
typedef struct _EekboardContextClass EekboardContextClass;
|
||||
typedef struct _EekboardContextPrivate EekboardContextPrivate;
|
||||
|
||||
/**
|
||||
* EekboardContext:
|
||||
*
|
||||
* The #EekboardContext structure contains only private data and
|
||||
* should only be accessed using the provided API.
|
||||
*/
|
||||
struct _EekboardContext {
|
||||
/*< private >*/
|
||||
GDBusProxy parent;
|
||||
|
||||
EekboardContextPrivate *priv;
|
||||
};
|
||||
|
||||
/**
|
||||
* EekboardContextClass:
|
||||
|
||||