Compare commits
	
		
			85 Commits
		
	
	
		
			eekboard-0
			...
			eekboard-0
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 76d1b8f7fb | |||
| 2bbc65958a | |||
| cbdd0fd2ba | |||
| 2f7aa77c11 | |||
| bed39570ff | |||
| 8bc3b204b4 | |||
| fa030ebcbb | |||
| af365024b7 | |||
| c742877b77 | |||
| ace4391b79 | |||
| 627cbf2898 | |||
| baae80fa41 | |||
| 9be07710dd | |||
| 163e005561 | |||
| d8e691d3f5 | |||
| 85a1a6ba24 | |||
| 828a59b298 | |||
| f1b91c0223 | |||
| cadb0f18a9 | |||
| 2a8d7cf0a8 | |||
| c9b54ba87f | |||
| d57ae91995 | |||
| dd86b132ce | |||
| 3967558bae | |||
| 668ce51f3c | |||
| 1db2a4aeea | |||
| e20425f385 | |||
| a20224f969 | |||
| d66318a031 | |||
| 37c2579253 | |||
| 23ab2a343f | |||
| e6dfc595ab | |||
| 98e15d7741 | |||
| 38b226b46f | |||
| c53b4d398e | |||
| fbcf6b6c65 | |||
| 09c95b20da | |||
| a7f81c3cfb | |||
| a66256f390 | |||
| 8b7da18641 | |||
| a9c0356611 | |||
| b25a9a5407 | |||
| 8b632356e9 | |||
| b8a01d794e | |||
| cfd33921a1 | |||
| 979aa010b9 | |||
| de064ba0c0 | |||
| ff200d9562 | |||
| a8148683d3 | |||
| 838a15d31a | |||
| 2d66bf24fb | |||
| 64bc7cc955 | |||
| 362f8ec0cb | |||
| d99a40df94 | |||
| ab08955a5f | |||
| 577fcd7f9e | |||
| 7da92bf04c | |||
| f7caf6fe49 | |||
| d111edd76a | |||
| b2657c06a8 | |||
| fccf9e8805 | |||
| 7fc80705dd | |||
| 9007f31c0a | |||
| 18f8e5b98b | |||
| 0087f74178 | |||
| 639ad8df91 | |||
| e8af3dacf1 | |||
| 5d42fb8294 | |||
| 4440a2f1ac | |||
| c9cee89d7e | |||
| 1c3d20ad6f | |||
| 40862fcf12 | |||
| 110b25a64b | |||
| f1a44ddebb | |||
| fc00d86c7e | |||
| 4a822fe52c | |||
| 6587f00c2a | |||
| 3b77502b97 | |||
| d7554b9735 | |||
| 798df5c136 | |||
| 22c70976db | |||
| 3eeb7cd8ab | |||
| 7ef245d739 | |||
| 9a6b3b3e2d | |||
| 715c9ca022 | 
							
								
								
									
										38
									
								
								AUTHORS
									
									
									
									
									
								
							
							
						
						
									
										38
									
								
								AUTHORS
									
									
									
									
									
								
							@ -1,6 +1,36 @@
 | 
			
		||||
eekboard is written by Daiki Ueno <ueno@unixuser.org>
 | 
			
		||||
eekboard is written by Daiki Ueno <ueno@unixuser.org>.  The following
 | 
			
		||||
files contain code derived from other free software packages:
 | 
			
		||||
 | 
			
		||||
Cairo keyboard drawing functions are borrowed from the libgnomekbd
 | 
			
		||||
library by Sergey V. Udaltsov <svu@gnome.org>.  See the comments in
 | 
			
		||||
eek/eek-drawing.c for detail.
 | 
			
		||||
eek/eek-keyboard-drawing.h
 | 
			
		||||
eek/eek-keyboard-drawing.c
 | 
			
		||||
 | 
			
		||||
  These files contain code derived from the libgnomekbd library.
 | 
			
		||||
  Copyright (C) 2006 Sergey V. Udaltsov <svu@gnome.org>
 | 
			
		||||
 | 
			
		||||
eek/eek-theme.h
 | 
			
		||||
eek/eek-theme.c
 | 
			
		||||
eek/eek-theme-context.h
 | 
			
		||||
eek/eek-theme-context.c
 | 
			
		||||
eek/eek-theme-node.h
 | 
			
		||||
eek/eek-theme-node.c
 | 
			
		||||
 | 
			
		||||
  These files contain code derived from gnome-shell.
 | 
			
		||||
 | 
			
		||||
  Copyright 2008-2010 Red Hat, Inc.
 | 
			
		||||
  Copyright 2009 Steve Frécinaux
 | 
			
		||||
  Copyright 2009, 2010 Florian Müllner
 | 
			
		||||
  Copyright 2010 Adel Gadllah
 | 
			
		||||
  Copyright 2010 Giovanni Campagna
 | 
			
		||||
  Copyright 2003-2004 Dodji Seketeli
 | 
			
		||||
 | 
			
		||||
data/icons/8x8/Makefile.am
 | 
			
		||||
data/icons/16x16/Makefile.am
 | 
			
		||||
data/icons/22x22/Makefile.am
 | 
			
		||||
data/icons/24x24/Makefile.am
 | 
			
		||||
data/icons/32x32/Makefile.am
 | 
			
		||||
data/icons/48x48/Makefile.am
 | 
			
		||||
data/icons/scalable/Makefile.am
 | 
			
		||||
 | 
			
		||||
  These files contain code derived from im-chooser.
 | 
			
		||||
 | 
			
		||||
  Copyright (C) 2006-2008 Red Hat, Inc. All rights reserved.
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										2
									
								
								README
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								README
									
									
									
									
									
								
							@ -7,7 +7,7 @@ tools to implement desktop virtual keyboards.
 | 
			
		||||
 | 
			
		||||
** Dependencies
 | 
			
		||||
 | 
			
		||||
REQUIRED: GLib2, GTK, GConf2, PangoCairo, libxklavier
 | 
			
		||||
REQUIRED: GLib2, GTK, GConf2, PangoCairo, libxklavier, libcroco
 | 
			
		||||
OPTIONAL: fakekey, CSPI, Clutter, Clutter-Gtk, Vala, gobject-introspection
 | 
			
		||||
 | 
			
		||||
** Build from git repo
 | 
			
		||||
 | 
			
		||||
@ -16,8 +16,12 @@
 | 
			
		||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 | 
			
		||||
# 02110-1301 USA
 | 
			
		||||
 | 
			
		||||
if ENABLE_VALA
 | 
			
		||||
SUBDIRS = vala
 | 
			
		||||
else
 | 
			
		||||
SUBDIRS =
 | 
			
		||||
 | 
			
		||||
if ENABLE_PYTHON
 | 
			
		||||
SUBDIRS += python
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
if ENABLE_VALA
 | 
			
		||||
SUBDIRS += vala
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										18
									
								
								bindings/python/Makefile.am
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								bindings/python/Makefile.am
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,18 @@
 | 
			
		||||
# 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/>.
 | 
			
		||||
 | 
			
		||||
SUBDIRS = eekboard
 | 
			
		||||
							
								
								
									
										21
									
								
								bindings/python/eekboard/Makefile.am
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								bindings/python/eekboard/Makefile.am
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,21 @@
 | 
			
		||||
# 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/>.
 | 
			
		||||
 | 
			
		||||
pkgpython_PYTHON = \
 | 
			
		||||
	__init__.py \
 | 
			
		||||
	eekboard.py \
 | 
			
		||||
	context.py
 | 
			
		||||
							
								
								
									
										63
									
								
								bindings/python/eekboard/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										63
									
								
								bindings/python/eekboard/__init__.py
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,63 @@
 | 
			
		||||
# 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/>.
 | 
			
		||||
 | 
			
		||||
from gi.repository import Eek, EekXkl, Gio
 | 
			
		||||
 | 
			
		||||
from eekboard import Eekboard
 | 
			
		||||
from context import Context
 | 
			
		||||
 | 
			
		||||
Keyboard = Eek.Keyboard
 | 
			
		||||
Section = Eek.Section
 | 
			
		||||
Key = Eek.Key
 | 
			
		||||
Symbol = Eek.Symbol
 | 
			
		||||
Keysym = Eek.Keysym
 | 
			
		||||
 | 
			
		||||
MODIFIER_BEHAVIOR_NONE, \
 | 
			
		||||
MODIFIER_BEHAVIOR_LOCK, \
 | 
			
		||||
MODIFIER_BEHAVIOR_LATCH = \
 | 
			
		||||
(Eek.ModifierBehavior.NONE,
 | 
			
		||||
 Eek.ModifierBehavior.LOCK,
 | 
			
		||||
 Eek.ModifierBehavior.LATCH)
 | 
			
		||||
 | 
			
		||||
CSW = 640
 | 
			
		||||
CSH = 480
 | 
			
		||||
 | 
			
		||||
def XmlKeyboard(path, modifier_behavior=MODIFIER_BEHAVIOR_NONE):
 | 
			
		||||
    _file = Gio.file_new_for_path(path)
 | 
			
		||||
    layout = Eek.XmlLayout.new(_file.read())
 | 
			
		||||
    keyboard = Eek.Keyboard.new(layout, CSW, CSH)
 | 
			
		||||
    keyboard.set_modifier_behavior(modifier_behavior)
 | 
			
		||||
    return keyboard
 | 
			
		||||
 | 
			
		||||
def XklKeyboard(modifier_behavior=MODIFIER_BEHAVIOR_NONE):
 | 
			
		||||
    layout = EekXkl.Layout.new()
 | 
			
		||||
    keyboard = Eek.Keyboard.new(layout, CSW, CSH)
 | 
			
		||||
    keyboard.set_modifier_behavior(modifier_behavior)
 | 
			
		||||
    return keyboard
 | 
			
		||||
 | 
			
		||||
__all__ = ['Eekboard',
 | 
			
		||||
           'Context',
 | 
			
		||||
           'Keyboard',
 | 
			
		||||
           'Section',
 | 
			
		||||
           'Key',
 | 
			
		||||
           'Symbol',
 | 
			
		||||
           'Keysym',
 | 
			
		||||
           'MODIFIER_BEHAVIOR_NONE',
 | 
			
		||||
           'MODIFIER_BEHAVIOR_LOCK',
 | 
			
		||||
           'MODIFIER_BEHAVIOR_LATCH',
 | 
			
		||||
           'XmlKeyboard',
 | 
			
		||||
           'XklKeyboard']
 | 
			
		||||
							
								
								
									
										79
									
								
								bindings/python/eekboard/context.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										79
									
								
								bindings/python/eekboard/context.py
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,79 @@
 | 
			
		||||
# 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/>.
 | 
			
		||||
 | 
			
		||||
from gi.repository import Eekboard
 | 
			
		||||
import gobject
 | 
			
		||||
 | 
			
		||||
class Context(gobject.GObject):
 | 
			
		||||
    __gtype_name__ = "PYEekboardContext"
 | 
			
		||||
    __gsignals__ = {
 | 
			
		||||
        'enabled': (
 | 
			
		||||
            gobject.SIGNAL_RUN_LAST,
 | 
			
		||||
            gobject.TYPE_NONE,
 | 
			
		||||
            ()),
 | 
			
		||||
        'disabled': (
 | 
			
		||||
            gobject.SIGNAL_RUN_LAST,
 | 
			
		||||
            gobject.TYPE_NONE,
 | 
			
		||||
            ()),
 | 
			
		||||
        'key-pressed': (
 | 
			
		||||
            gobject.SIGNAL_RUN_LAST,
 | 
			
		||||
            gobject.TYPE_NONE,
 | 
			
		||||
            (gobject.TYPE_UINT,)),
 | 
			
		||||
        'key-released': (
 | 
			
		||||
            gobject.SIGNAL_RUN_LAST,
 | 
			
		||||
            gobject.TYPE_NONE,
 | 
			
		||||
            (gobject.TYPE_UINT,))
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    def __init__(self, giobject):
 | 
			
		||||
        super(Context, self).__init__()
 | 
			
		||||
        import sys
 | 
			
		||||
        self.__giobject = giobject
 | 
			
		||||
        self.__giobject.connect('enabled', lambda *args: self.emit('enabled'))
 | 
			
		||||
        self.__giobject.connect('disabled', lambda *args: self.emit('disabled'))
 | 
			
		||||
        self.__giobject.connect('key-pressed', lambda *args: self.emit('key-pressed', args[1]))
 | 
			
		||||
        self.__giobject.connect('key-released', lambda *args: self.emit('key-released', args[1]))
 | 
			
		||||
 | 
			
		||||
    def get_giobject(self):
 | 
			
		||||
        return self.__giobject
 | 
			
		||||
 | 
			
		||||
    def add_keyboard(self, keyboard):
 | 
			
		||||
        return self.__giobject.add_keyboard(keyboard, None)
 | 
			
		||||
 | 
			
		||||
    def remove_keyboard(self, keyboard_id):
 | 
			
		||||
        return self.__giobject.remove_keyboard(keyboard_id, None)
 | 
			
		||||
        
 | 
			
		||||
    def set_keyboard(self, keyboard_id):
 | 
			
		||||
        self.__giobject.set_keyboard(keyboard_id, None)
 | 
			
		||||
 | 
			
		||||
    def show_keyboard(self):
 | 
			
		||||
        self.__giobject.show_keyboard(None)
 | 
			
		||||
 | 
			
		||||
    def hide_keyboard(self):
 | 
			
		||||
        self.__giobject.hide_keyboard(None)
 | 
			
		||||
 | 
			
		||||
    def set_group(self, group):
 | 
			
		||||
        self.__giobject.set_group(group, None)
 | 
			
		||||
 | 
			
		||||
    def press_key(self, keycode):
 | 
			
		||||
        self.__giobject.press_key(keycode, None)
 | 
			
		||||
 | 
			
		||||
    def release_key(self, keycode):
 | 
			
		||||
        self.__giobject.release_key(keycode, None)
 | 
			
		||||
 | 
			
		||||
    def is_enabled(self):
 | 
			
		||||
        return self.__giobject.is_enabled()
 | 
			
		||||
							
								
								
									
										42
									
								
								bindings/python/eekboard/eekboard.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								bindings/python/eekboard/eekboard.py
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,42 @@
 | 
			
		||||
# 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/>.
 | 
			
		||||
 | 
			
		||||
from gi.repository import Gio
 | 
			
		||||
import gi.repository
 | 
			
		||||
import gobject
 | 
			
		||||
from context import Context
 | 
			
		||||
 | 
			
		||||
class Eekboard(gobject.GObject):
 | 
			
		||||
    __gtype_name__ = "PYEekboardEekboard"
 | 
			
		||||
 | 
			
		||||
    def __init__(self):
 | 
			
		||||
        super(Eekboard, self).__init__()
 | 
			
		||||
        self.__connection = Gio.bus_get_sync(Gio.BusType.SESSION, None)
 | 
			
		||||
        self.__eekboard = gi.repository.Eekboard.Eekboard.new(self.__connection, None);
 | 
			
		||||
 | 
			
		||||
    def create_context(self, client_name):
 | 
			
		||||
        context = self.__eekboard.create_context(client_name, None)
 | 
			
		||||
        return Context(context)
 | 
			
		||||
 | 
			
		||||
    def push_context(self, context):
 | 
			
		||||
        self.__eekboard.push_context(context.get_giobject(), None)
 | 
			
		||||
 | 
			
		||||
    def pop_context(self):
 | 
			
		||||
        self.__eekboard.pop_context(None)
 | 
			
		||||
 | 
			
		||||
    def destroy_context(self, context):
 | 
			
		||||
        self.__eekboard.destroy_context(context.get_giobject(), None)
 | 
			
		||||
							
								
								
									
										40
									
								
								configure.ac
									
									
									
									
									
								
							
							
						
						
									
										40
									
								
								configure.ac
									
									
									
									
									
								
							@ -20,7 +20,7 @@ AC_PREREQ(2.63)
 | 
			
		||||
dnl AC_CONFIG_SRCDIR([configure.ac])
 | 
			
		||||
AC_CONFIG_MACRO_DIR([m4])
 | 
			
		||||
 | 
			
		||||
AC_INIT([eekboard], [0.90.1], [ueno@unixuser.org])
 | 
			
		||||
AC_INIT([eekboard], [0.90.4], [ueno@unixuser.org])
 | 
			
		||||
 | 
			
		||||
dnl Init automake
 | 
			
		||||
AM_INIT_AUTOMAKE
 | 
			
		||||
@ -101,6 +101,8 @@ PKG_CHECK_MODULES([XKB], [x11], ,
 | 
			
		||||
  [AC_MSG_ERROR([XKB support 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 libfakekey to generate key events
 | 
			
		||||
AC_MSG_CHECKING([whether you enable fakekey])
 | 
			
		||||
@ -132,6 +134,37 @@ fi
 | 
			
		||||
AC_MSG_RESULT($enable_cspi)
 | 
			
		||||
AM_CONDITIONAL(ENABLE_CSPI, [test x$enable_cspi = xyes])
 | 
			
		||||
 | 
			
		||||
dnl Python language binding
 | 
			
		||||
AC_MSG_CHECKING([whether you enable Python language support])
 | 
			
		||||
AC_ARG_ENABLE(python,
 | 
			
		||||
              AS_HELP_STRING([--enable-python=no/yes],
 | 
			
		||||
                             [Enable Python language binding default=yes]),,
 | 
			
		||||
              enable_python=yes)
 | 
			
		||||
AC_MSG_RESULT($enable_python)
 | 
			
		||||
AM_CONDITIONAL(ENABLE_PYTHON, [test x$enable_python = xyes])
 | 
			
		||||
 | 
			
		||||
if test x"$enable_python" = x"yes"; then
 | 
			
		||||
    # check python
 | 
			
		||||
    AM_PATH_PYTHON([2.5])
 | 
			
		||||
    AC_PATH_PROG(PYTHON_CONFIG, python$PYTHON_VERSION-config)
 | 
			
		||||
    if test x"$PYTHON_CONFIG" = x""; then
 | 
			
		||||
        AC_PATH_PROG(PYTHON_CONFIG, python-config)
 | 
			
		||||
    fi
 | 
			
		||||
    if test x"$PYTHON_CONFIG" != x""; then
 | 
			
		||||
        PYTHON_CFLAGS=`$PYTHON_CONFIG --includes`
 | 
			
		||||
        PYTHON_LIBS=`$PYTHON_CONFIG --libs`
 | 
			
		||||
    else
 | 
			
		||||
        PYTHON_CFLAGS=`$PYTHON $srcdir/python-config.py --includes`
 | 
			
		||||
        PYTHON_LIBS=`$PYTHON $srcdir/python-config.py --libs`
 | 
			
		||||
    fi
 | 
			
		||||
    PYTHON_INCLUDES="$PYTHON_CFLAGS"
 | 
			
		||||
    AC_SUBST(PYTHON_CFLAGS)
 | 
			
		||||
    AC_SUBST(PYTHON_INCLUDES)
 | 
			
		||||
    AC_SUBST(PYTHON_LIBS)
 | 
			
		||||
else
 | 
			
		||||
    enable_python="no (disabled, use --enable-python to enable)"
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
dnl Vala langauge binding
 | 
			
		||||
AC_MSG_CHECKING([whether you enable Vala language support])
 | 
			
		||||
AC_ARG_ENABLE(vala,
 | 
			
		||||
@ -186,7 +219,7 @@ AC_DEFINE_UNQUOTED(GETTEXT_PACKAGE,"$GETTEXT_PACKAGE", [Define to the read-only
 | 
			
		||||
AM_GLIB_GNU_GETTEXT
 | 
			
		||||
AM_GLIB_DEFINE_LOCALEDIR(EEKBOARD_LOCALEDIR)
 | 
			
		||||
 | 
			
		||||
GOBJECT_INTROSPECTION_CHECK([0.6.7])
 | 
			
		||||
GOBJECT_INTROSPECTION_CHECK([0.9.0])
 | 
			
		||||
 | 
			
		||||
AC_CONFIG_HEADERS([config.h])
 | 
			
		||||
AC_CONFIG_FILES([Makefile
 | 
			
		||||
@ -195,6 +228,8 @@ eekboard/Makefile
 | 
			
		||||
src/Makefile
 | 
			
		||||
tests/Makefile
 | 
			
		||||
bindings/Makefile
 | 
			
		||||
bindings/python/Makefile
 | 
			
		||||
bindings/python/eekboard/Makefile
 | 
			
		||||
bindings/vala/Makefile
 | 
			
		||||
docs/Makefile
 | 
			
		||||
docs/reference/Makefile
 | 
			
		||||
@ -209,6 +244,7 @@ data/icons/24x24/Makefile
 | 
			
		||||
data/icons/32x32/Makefile
 | 
			
		||||
data/icons/48x48/Makefile
 | 
			
		||||
data/icons/scalable/Makefile
 | 
			
		||||
data/themes/Makefile
 | 
			
		||||
eek/eek-${EEK_API_VERSION}.pc
 | 
			
		||||
eek/eek-clutter-${EEK_API_VERSION}.pc
 | 
			
		||||
eek/eek-gtk-${EEK_API_VERSION}.pc
 | 
			
		||||
 | 
			
		||||
@ -1 +1 @@
 | 
			
		||||
SUBDIRS = icons
 | 
			
		||||
SUBDIRS = icons themes
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										2
									
								
								data/themes/Makefile.am
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								data/themes/Makefile.am
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,2 @@
 | 
			
		||||
themedir = $(pkgdatadir)/themes
 | 
			
		||||
dist_theme_DATA = default.css
 | 
			
		||||
							
								
								
									
										22
									
								
								data/themes/default.css
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										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);
 | 
			
		||||
}
 | 
			
		||||
@ -47,7 +47,7 @@ SCANGOBJ_OPTIONS=
 | 
			
		||||
 | 
			
		||||
# Extra options to supply to gtkdoc-scan.
 | 
			
		||||
# e.g. SCAN_OPTIONS=--deprecated-guards="GTK_DISABLE_DEPRECATED"
 | 
			
		||||
SCAN_OPTIONS=
 | 
			
		||||
SCAN_OPTIONS=--rebuild-types
 | 
			
		||||
 | 
			
		||||
# Extra options to supply to gtkdoc-mkdb.
 | 
			
		||||
# e.g. MKDB_OPTIONS=--sgml-mode --output-format=xml
 | 
			
		||||
@ -76,7 +76,16 @@ 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
 | 
			
		||||
IGNORE_HFILES = \
 | 
			
		||||
	config.h \
 | 
			
		||||
	eek-renderer.h \
 | 
			
		||||
	eek-clutter-renderer.h \
 | 
			
		||||
	eek-clutter-section.h \
 | 
			
		||||
	eek-clutter-key.h \
 | 
			
		||||
	eek-gtk-renderer.h
 | 
			
		||||
if !ENABLE_CLUTTER
 | 
			
		||||
IGNORE_HFILES += eek-clutter-keyboard.h eek-clutter.h
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
# Images to copy into HTML directory.
 | 
			
		||||
# e.g. HTML_IMAGES=$(top_srcdir)/gtk/stock-icons/stock_about_24.png
 | 
			
		||||
@ -97,15 +106,18 @@ expand_content_files=eek-overview.xml
 | 
			
		||||
# 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_srcdir)/eek/libeek.la \
 | 
			
		||||
	$(top_srcdir)/eek/libeek-gtk.la \
 | 
			
		||||
	$(top_srcdir)/eek/libeek-xkb.la \
 | 
			
		||||
	$(top_srcdir)/eek/libeek-xkl.la \
 | 
			
		||||
GTKDOC_LIBS = $(top_builddir)/eek/libeek.la \
 | 
			
		||||
	$(top_builddir)/eek/libeek-gtk.la \
 | 
			
		||||
	$(top_builddir)/eek/libeek-xkb.la \
 | 
			
		||||
	$(top_builddir)/eek/libeek-xkl.la \
 | 
			
		||||
	$(GIO2_LIBS) \
 | 
			
		||||
	$(GTK_LIBS) \
 | 
			
		||||
	$(XKB_LIBS)
 | 
			
		||||
 | 
			
		||||
if ENABLE_CLUTTER
 | 
			
		||||
GTKDOC_LIBS += $(top_srcdir)/eek/libeek-clutter.la $(CLUTTER_LIBS)
 | 
			
		||||
GTKDOC_LIBS += \
 | 
			
		||||
	$(top_builddir)/eek/libeek-clutter.la \
 | 
			
		||||
	$(CLUTTER_LIBS)
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
# This includes the standard gtk-doc make rules, copied by gtkdocize.
 | 
			
		||||
 | 
			
		||||
@ -37,14 +37,16 @@
 | 
			
		||||
    <title>API Manual</title>
 | 
			
		||||
    <chapter>
 | 
			
		||||
      <title>Base Classes, Interfaces, and Utilities</title>
 | 
			
		||||
      <xi:include href="xml/eek-serializable.xml"/>
 | 
			
		||||
      <xi:include href="xml/eek-element.xml"/>
 | 
			
		||||
      <xi:include href="xml/eek-container.xml"/>
 | 
			
		||||
      <xi:include href="xml/eek-keyboard.xml"/>
 | 
			
		||||
      <xi:include href="xml/eek-section.xml"/>
 | 
			
		||||
      <xi:include href="xml/eek-key.xml"/>
 | 
			
		||||
      <xi:include href="xml/eek-symbol.xml"/>
 | 
			
		||||
      <xi:include href="xml/eek-keysym.xml"/>
 | 
			
		||||
      <xi:include href="xml/eek-layout.xml"/>
 | 
			
		||||
      <xi:include href="xml/eek-types.xml"/>
 | 
			
		||||
      <xi:include href="xml/eek-keysym.xml"/>
 | 
			
		||||
    </chapter>
 | 
			
		||||
    <chapter>
 | 
			
		||||
      <title>Clutter Keyboard</title>
 | 
			
		||||
@ -62,6 +64,11 @@
 | 
			
		||||
      <title>XKB Layout Engine</title>
 | 
			
		||||
      <xi:include href="xml/eek-xkb-layout.xml"/>
 | 
			
		||||
    </chapter>
 | 
			
		||||
    <chapter>
 | 
			
		||||
      <title>XML Layout Engine</title>
 | 
			
		||||
      <xi:include href="xml/eek-xml-layout.xml"/>
 | 
			
		||||
      <xi:include href="xml/eek-xml.xml"/>
 | 
			
		||||
    </chapter>
 | 
			
		||||
    <chapter id="object-tree">
 | 
			
		||||
      <title>Object Hierarchy</title>
 | 
			
		||||
      <xi:include href="xml/tree_index.sgml"/>
 | 
			
		||||
 | 
			
		||||
@ -43,19 +43,14 @@ clutter_group_add (CLUTTER_GROUP(stage), actor);
 | 
			
		||||
      </programlisting>
 | 
			
		||||
    </informalexample>
 | 
			
		||||
 | 
			
		||||
    <para>The most interesting feature of libeek is that developer can
 | 
			
		||||
    choose arbitrary combination of UI toolkits and layout engine
 | 
			
		||||
    supported by libeek.  For example, to create a keyboard-like
 | 
			
		||||
    #GtkWidget instead of #ClutterActor, all you need is to replace
 | 
			
		||||
    eek_clutter_keyboard_new() with eek_gtk_keyboard_new() and
 | 
			
		||||
    eek_clutter_keyboard_get_actor() with
 | 
			
		||||
    eek_gtk_keyboard_get_widget().  Similarly, if you want to use XKB
 | 
			
		||||
    configuration directly (without libxklavier), you will only need to
 | 
			
		||||
    replace eek_xkl_layout_new () with eek_xkb_layout_new().</para>
 | 
			
		||||
    <para>libeek currently supports GTK+ and Clutter as UI toolkits.
 | 
			
		||||
    To create a keyboard-like #GtkWidget instead of #ClutterActor,
 | 
			
		||||
    replace eek_clutter_keyboard_new() with eek_gtk_keyboard_new().
 | 
			
		||||
    Similarly, if you want to use XKB configuration directly (without
 | 
			
		||||
    libxklavier), you will only need to replace eek_xkl_layout_new ()
 | 
			
		||||
    with eek_xkb_layout_new().</para>
 | 
			
		||||
 | 
			
		||||
    <para>To achieve portability across different UI toolkits,
 | 
			
		||||
    there is a seperate represention of keyboard elements apart from
 | 
			
		||||
    the actual UI widgets.  For example, a keyboard is represented as a tree of
 | 
			
		||||
    <para>In the above example, a keyboard is represented as a tree of
 | 
			
		||||
    #EekElement -- #EekKeyboard contains one or more #EekSection's and
 | 
			
		||||
    #EekSection contains one or more #EekKey's.  Each element may emit
 | 
			
		||||
    events when user pushes the corresponding UI widget.</para>
 | 
			
		||||
 | 
			
		||||
@ -2,21 +2,25 @@
 | 
			
		||||
<FILE>eek-keyboard</FILE>
 | 
			
		||||
<TITLE>EekKeyboard</TITLE>
 | 
			
		||||
EekKeyboardClass
 | 
			
		||||
EekKeyboardPrivate
 | 
			
		||||
EekKeyboard
 | 
			
		||||
eek_keyboard_new
 | 
			
		||||
eek_keyboard_get_layout
 | 
			
		||||
eek_keyboard_get_size
 | 
			
		||||
eek_keyboard_set_size
 | 
			
		||||
eek_keyboard_set_symbol_index
 | 
			
		||||
eek_keyboard_get_symbol_index
 | 
			
		||||
eek_keyboard_get_group
 | 
			
		||||
eek_keyboard_get_level
 | 
			
		||||
eek_keyboard_set_group
 | 
			
		||||
eek_keyboard_set_level
 | 
			
		||||
eek_keyboard_get_size
 | 
			
		||||
eek_keyboard_get_modifier_behavior
 | 
			
		||||
eek_keyboard_get_group
 | 
			
		||||
eek_keyboard_get_level
 | 
			
		||||
eek_keyboard_set_modifier_behavior
 | 
			
		||||
eek_keyboard_get_modifier_behavior
 | 
			
		||||
eek_keyboard_get_modifiers
 | 
			
		||||
eek_keyboard_create_section
 | 
			
		||||
eek_keyboard_find_key_by_keycode
 | 
			
		||||
eek_keyboard_add_outline
 | 
			
		||||
eek_keyboard_get_outline
 | 
			
		||||
<SUBSECTION Standard>
 | 
			
		||||
EEK_KEYBOARD
 | 
			
		||||
EEK_IS_KEYBOARD
 | 
			
		||||
@ -38,6 +42,7 @@ EEK_IS_LAYOUT
 | 
			
		||||
EEK_TYPE_LAYOUT
 | 
			
		||||
eek_layout_get_type
 | 
			
		||||
EEK_LAYOUT_CLASS
 | 
			
		||||
EEK_IS_LAYOUT_CLASS
 | 
			
		||||
EEK_LAYOUT_GET_CLASS
 | 
			
		||||
</SECTION>
 | 
			
		||||
 | 
			
		||||
@ -46,6 +51,7 @@ EEK_LAYOUT_GET_CLASS
 | 
			
		||||
<TITLE>EekGtkKeyboard</TITLE>
 | 
			
		||||
EekGtkKeyboard
 | 
			
		||||
EekGtkKeyboardClass
 | 
			
		||||
EekGtkKeyboardPrivate
 | 
			
		||||
eek_gtk_keyboard_new
 | 
			
		||||
<SUBSECTION Standard>
 | 
			
		||||
EEK_GTK_KEYBOARD
 | 
			
		||||
@ -61,6 +67,7 @@ EEK_GTK_KEYBOARD_GET_CLASS
 | 
			
		||||
<FILE>eek-section</FILE>
 | 
			
		||||
<TITLE>EekSection</TITLE>
 | 
			
		||||
EekSectionClass
 | 
			
		||||
EekSectionPrivate
 | 
			
		||||
EekSection
 | 
			
		||||
eek_section_set_angle
 | 
			
		||||
eek_section_get_angle
 | 
			
		||||
@ -83,11 +90,13 @@ EEK_SECTION_GET_CLASS
 | 
			
		||||
<FILE>eek-container</FILE>
 | 
			
		||||
<TITLE>EekContainer</TITLE>
 | 
			
		||||
EekContainerClass
 | 
			
		||||
EekContainerPrivate
 | 
			
		||||
EekCallback
 | 
			
		||||
EekCompareFunc
 | 
			
		||||
EekContainer
 | 
			
		||||
eek_container_foreach_child
 | 
			
		||||
eek_container_find
 | 
			
		||||
eek_container_add_child
 | 
			
		||||
<SUBSECTION Standard>
 | 
			
		||||
EEK_CONTAINER
 | 
			
		||||
EEK_IS_CONTAINER
 | 
			
		||||
@ -99,19 +108,32 @@ EEK_CONTAINER_GET_CLASS
 | 
			
		||||
</SECTION>
 | 
			
		||||
 | 
			
		||||
<SECTION>
 | 
			
		||||
<FILE>eek-clutter-keyboard</FILE>
 | 
			
		||||
<TITLE>EekClutterKeyboard</TITLE>
 | 
			
		||||
EekClutterKeyboard
 | 
			
		||||
EekClutterKeyboardClass
 | 
			
		||||
eek_clutter_keyboard_new
 | 
			
		||||
<FILE>eek-symbol</FILE>
 | 
			
		||||
<TITLE>EekSymbol</TITLE>
 | 
			
		||||
EekSymbolCategory
 | 
			
		||||
EekSymbolClass
 | 
			
		||||
EekSymbolPrivate
 | 
			
		||||
EekSymbol
 | 
			
		||||
eek_symbol_new
 | 
			
		||||
eek_symbol_set_name
 | 
			
		||||
eek_symbol_get_name
 | 
			
		||||
eek_symbol_set_label
 | 
			
		||||
eek_symbol_get_label
 | 
			
		||||
eek_symbol_set_category
 | 
			
		||||
eek_symbol_get_category
 | 
			
		||||
eek_symbol_get_modifier_mask
 | 
			
		||||
eek_symbol_set_modifier_mask
 | 
			
		||||
eek_symbol_is_modifier
 | 
			
		||||
eek_symbol_set_icon_name
 | 
			
		||||
eek_symbol_get_icon_name
 | 
			
		||||
<SUBSECTION Standard>
 | 
			
		||||
EEK_CLUTTER_KEYBOARD
 | 
			
		||||
EEK_IS_CLUTTER_KEYBOARD
 | 
			
		||||
EEK_TYPE_CLUTTER_KEYBOARD
 | 
			
		||||
eek_clutter_keyboard_get_type
 | 
			
		||||
EEK_CLUTTER_KEYBOARD_CLASS
 | 
			
		||||
EEK_IS_CLUTTER_KEYBOARD_CLASS
 | 
			
		||||
EEK_CLUTTER_KEYBOARD_GET_CLASS
 | 
			
		||||
EEK_SYMBOL
 | 
			
		||||
EEK_IS_SYMBOL
 | 
			
		||||
EEK_TYPE_SYMBOL
 | 
			
		||||
eek_symbol_get_type
 | 
			
		||||
EEK_SYMBOL_CLASS
 | 
			
		||||
EEK_IS_SYMBOL_CLASS
 | 
			
		||||
EEK_SYMBOL_GET_CLASS
 | 
			
		||||
</SECTION>
 | 
			
		||||
 | 
			
		||||
<SECTION>
 | 
			
		||||
@ -119,6 +141,7 @@ EEK_CLUTTER_KEYBOARD_GET_CLASS
 | 
			
		||||
<TITLE>EekXklLayout</TITLE>
 | 
			
		||||
EekXklLayout
 | 
			
		||||
EekXklLayoutClass
 | 
			
		||||
EekXklLayoutPrivate
 | 
			
		||||
eek_xkl_layout_new
 | 
			
		||||
eek_xkl_layout_set_config
 | 
			
		||||
eek_xkl_layout_set_config_full
 | 
			
		||||
@ -126,12 +149,12 @@ eek_xkl_layout_set_model
 | 
			
		||||
eek_xkl_layout_set_layouts
 | 
			
		||||
eek_xkl_layout_set_variants
 | 
			
		||||
eek_xkl_layout_set_options
 | 
			
		||||
eek_xkl_layout_enable_option
 | 
			
		||||
eek_xkl_layout_disable_option
 | 
			
		||||
eek_xkl_layout_get_model
 | 
			
		||||
eek_xkl_layout_get_layouts
 | 
			
		||||
eek_xkl_layout_get_variants
 | 
			
		||||
eek_xkl_layout_get_options
 | 
			
		||||
eek_xkl_layout_disable_option
 | 
			
		||||
eek_xkl_layout_enable_option
 | 
			
		||||
eek_xkl_layout_get_option
 | 
			
		||||
<SUBSECTION Standard>
 | 
			
		||||
EEK_XKL_LAYOUT
 | 
			
		||||
@ -143,30 +166,16 @@ EEK_IS_XKL_LAYOUT_CLASS
 | 
			
		||||
EEK_XKL_LAYOUT_GET_CLASS
 | 
			
		||||
</SECTION>
 | 
			
		||||
 | 
			
		||||
<SECTION>
 | 
			
		||||
<FILE>eek-xml-layout</FILE>
 | 
			
		||||
<TITLE>EekXmlLayout</TITLE>
 | 
			
		||||
eek_xml_layout_get_source
 | 
			
		||||
eek_xml_layout_new
 | 
			
		||||
eek_xml_layout_set_source
 | 
			
		||||
<SUBSECTION Standard>
 | 
			
		||||
EEK_XML_LAYOUT
 | 
			
		||||
EEK_IS_XML_LAYOUT
 | 
			
		||||
EEK_TYPE_XML_LAYOUT
 | 
			
		||||
eek_xml_layout_get_type
 | 
			
		||||
EEK_XML_LAYOUT_CLASS
 | 
			
		||||
EEK_IS_XML_LAYOUT_CLASS
 | 
			
		||||
EEK_XML_LAYOUT_GET_CLASS
 | 
			
		||||
</SECTION>
 | 
			
		||||
 | 
			
		||||
<SECTION>
 | 
			
		||||
<FILE>eek-xkb-layout</FILE>
 | 
			
		||||
<TITLE>EekXkbLayout</TITLE>
 | 
			
		||||
EekXkbLayout
 | 
			
		||||
EekXkbLayoutClass
 | 
			
		||||
EekXkbLayoutPrivate
 | 
			
		||||
eek_xkb_layout_new
 | 
			
		||||
eek_xkb_layout_set_names
 | 
			
		||||
eek_xkb_layout_set_names_full
 | 
			
		||||
eek_xkb_layout_set_names_full_valist
 | 
			
		||||
eek_xkb_layout_set_keycodes
 | 
			
		||||
eek_xkb_layout_set_geometry
 | 
			
		||||
eek_xkb_layout_set_symbols
 | 
			
		||||
@ -187,18 +196,19 @@ EEK_XKB_LAYOUT_GET_CLASS
 | 
			
		||||
<FILE>eek-key</FILE>
 | 
			
		||||
<TITLE>EekKey</TITLE>
 | 
			
		||||
EekKeyClass
 | 
			
		||||
EekKeyPrivate
 | 
			
		||||
EekKey
 | 
			
		||||
eek_key_set_keycode
 | 
			
		||||
eek_key_get_keycode
 | 
			
		||||
eek_key_set_symbol_matrix
 | 
			
		||||
eek_key_get_symbol_matrix
 | 
			
		||||
eek_key_get_symbol
 | 
			
		||||
eek_key_get_symbol_at_index
 | 
			
		||||
eek_key_get_symbol_with_fallback
 | 
			
		||||
eek_key_get_symbol_at_index
 | 
			
		||||
eek_key_set_index
 | 
			
		||||
eek_key_get_index
 | 
			
		||||
eek_key_set_outline
 | 
			
		||||
eek_key_get_outline
 | 
			
		||||
eek_key_set_oref
 | 
			
		||||
eek_key_get_oref
 | 
			
		||||
eek_key_is_pressed
 | 
			
		||||
<SUBSECTION Standard>
 | 
			
		||||
EEK_KEY
 | 
			
		||||
@ -210,10 +220,26 @@ EEK_IS_KEY_CLASS
 | 
			
		||||
EEK_KEY_GET_CLASS
 | 
			
		||||
</SECTION>
 | 
			
		||||
 | 
			
		||||
<SECTION>
 | 
			
		||||
<FILE>eek-serializable</FILE>
 | 
			
		||||
<TITLE>EekSerializable</TITLE>
 | 
			
		||||
EekSerializable
 | 
			
		||||
EekSerializableIface
 | 
			
		||||
eek_serializable_serialize
 | 
			
		||||
eek_serializable_deserialize
 | 
			
		||||
<SUBSECTION Standard>
 | 
			
		||||
EEK_SERIALIZABLE
 | 
			
		||||
EEK_IS_SERIALIZABLE
 | 
			
		||||
EEK_TYPE_SERIALIZABLE
 | 
			
		||||
eek_serializable_get_type
 | 
			
		||||
EEK_SERIALIZABLE_GET_IFACE
 | 
			
		||||
</SECTION>
 | 
			
		||||
 | 
			
		||||
<SECTION>
 | 
			
		||||
<FILE>eek-element</FILE>
 | 
			
		||||
<TITLE>EekElement</TITLE>
 | 
			
		||||
EekElementClass
 | 
			
		||||
EekElementPrivate
 | 
			
		||||
EekElement
 | 
			
		||||
eek_element_set_parent
 | 
			
		||||
eek_element_get_parent
 | 
			
		||||
@ -221,7 +247,15 @@ eek_element_set_name
 | 
			
		||||
eek_element_get_name
 | 
			
		||||
eek_element_set_bounds
 | 
			
		||||
eek_element_get_bounds
 | 
			
		||||
eek_element_set_position
 | 
			
		||||
eek_element_set_size
 | 
			
		||||
eek_element_get_absolute_position
 | 
			
		||||
eek_element_set_symbol_index
 | 
			
		||||
eek_element_get_symbol_index
 | 
			
		||||
eek_element_set_group
 | 
			
		||||
eek_element_set_level
 | 
			
		||||
eek_element_get_group
 | 
			
		||||
eek_element_get_level
 | 
			
		||||
<SUBSECTION Standard>
 | 
			
		||||
EEK_ELEMENT
 | 
			
		||||
EEK_IS_ELEMENT
 | 
			
		||||
@ -233,72 +267,36 @@ EEK_ELEMENT_GET_CLASS
 | 
			
		||||
</SECTION>
 | 
			
		||||
 | 
			
		||||
<SECTION>
 | 
			
		||||
<FILE>eek-symbol</FILE>
 | 
			
		||||
<TITLE>EekSymbol</TITLE>
 | 
			
		||||
EekSymbolClass
 | 
			
		||||
EekSymbol
 | 
			
		||||
eek_symbol_new
 | 
			
		||||
eek_symbol_set_name
 | 
			
		||||
eek_symbol_get_name
 | 
			
		||||
eek_symbol_set_label
 | 
			
		||||
eek_symbol_get_label
 | 
			
		||||
eek_symbol_set_category
 | 
			
		||||
eek_symbol_get_category
 | 
			
		||||
eek_symbol_set_modifier_mask
 | 
			
		||||
eek_symbol_get_modifier_mask
 | 
			
		||||
eek_symbol_is_modifier
 | 
			
		||||
<FILE>eek-xml-layout</FILE>
 | 
			
		||||
<TITLE>EekXmlLayout</TITLE>
 | 
			
		||||
EekXmlLayout
 | 
			
		||||
EekXmlLayoutClass
 | 
			
		||||
EekXmlLayoutPrivate
 | 
			
		||||
eek_xml_layout_new
 | 
			
		||||
eek_xml_layout_set_source
 | 
			
		||||
eek_xml_layout_get_source
 | 
			
		||||
<SUBSECTION Standard>
 | 
			
		||||
EEK_SYMBOL
 | 
			
		||||
EEK_IS_SYMBOL
 | 
			
		||||
EEK_TYPE_SYMBOL
 | 
			
		||||
eek_symbol_get_type
 | 
			
		||||
EEK_SYMBOL_CLASS
 | 
			
		||||
EEK_IS_SYMBOL_CLASS
 | 
			
		||||
EEK_SYMBOL_GET_CLASS
 | 
			
		||||
</SECTION>
 | 
			
		||||
 | 
			
		||||
<SECTION>
 | 
			
		||||
<FILE>eek-types</FILE>
 | 
			
		||||
<TITLE>Basic Types</TITLE>
 | 
			
		||||
EekOrientation
 | 
			
		||||
EekModifierBehavior
 | 
			
		||||
EekModifierType
 | 
			
		||||
EekSymbolMatrix
 | 
			
		||||
EekSymbolCategory
 | 
			
		||||
EEK_TYPE_SYMBOL_MATRIX
 | 
			
		||||
eek_symbol_matrix_copy
 | 
			
		||||
eek_symbol_matrix_free
 | 
			
		||||
eek_symbol_matrix_get_type
 | 
			
		||||
eek_symbol_matrix_new
 | 
			
		||||
EekPoint
 | 
			
		||||
EEK_TYPE_POINT
 | 
			
		||||
eek_point_get_type
 | 
			
		||||
eek_point_rotate
 | 
			
		||||
EekBounds
 | 
			
		||||
EEK_TYPE_BOUNDS
 | 
			
		||||
eek_bounds_get_type
 | 
			
		||||
eek_bounds_long_side
 | 
			
		||||
EekOutline
 | 
			
		||||
EEK_TYPE_OUTLINE
 | 
			
		||||
eek_outline_get_type
 | 
			
		||||
EekColor
 | 
			
		||||
EEK_TYPE_COLOR
 | 
			
		||||
eek_color_get_type
 | 
			
		||||
eek_color_new
 | 
			
		||||
EEK_XML_LAYOUT
 | 
			
		||||
EEK_IS_XML_LAYOUT
 | 
			
		||||
EEK_TYPE_XML_LAYOUT
 | 
			
		||||
eek_xml_layout_get_type
 | 
			
		||||
EEK_XML_LAYOUT_CLASS
 | 
			
		||||
EEK_IS_XML_LAYOUT_CLASS
 | 
			
		||||
EEK_XML_LAYOUT_GET_CLASS
 | 
			
		||||
</SECTION>
 | 
			
		||||
 | 
			
		||||
<SECTION>
 | 
			
		||||
<FILE>eek-keysym</FILE>
 | 
			
		||||
<TITLE>EekKeysym</TITLE>
 | 
			
		||||
EEK_KEYSYM
 | 
			
		||||
EekKeysymClass
 | 
			
		||||
EekKeysymPrivate
 | 
			
		||||
EekKeysym
 | 
			
		||||
EEK_INVALID_KEYSYM
 | 
			
		||||
EEK_INVALID_KEYCODE
 | 
			
		||||
eek_keysym_get_xkeysym
 | 
			
		||||
eek_keysym_new
 | 
			
		||||
eek_keysym_get_xkeysym
 | 
			
		||||
eek_keysym_new_from_name
 | 
			
		||||
<SUBSECTION Standard>
 | 
			
		||||
EEK_KEYSYM
 | 
			
		||||
EEK_INVALID_KEYSYM
 | 
			
		||||
EEK_IS_KEYSYM
 | 
			
		||||
EEK_TYPE_KEYSYM
 | 
			
		||||
eek_keysym_get_type
 | 
			
		||||
@ -306,3 +304,42 @@ EEK_KEYSYM_CLASS
 | 
			
		||||
EEK_IS_KEYSYM_CLASS
 | 
			
		||||
EEK_KEYSYM_GET_CLASS
 | 
			
		||||
</SECTION>
 | 
			
		||||
 | 
			
		||||
<SECTION>
 | 
			
		||||
<FILE>eek-xml</FILE>
 | 
			
		||||
EEK_XML_SCHEMA_VERSION
 | 
			
		||||
eek_keyboard_output
 | 
			
		||||
</SECTION>
 | 
			
		||||
 | 
			
		||||
<SECTION>
 | 
			
		||||
<FILE>eek-types</FILE>
 | 
			
		||||
I_
 | 
			
		||||
EEK_TYPE_SYMBOL_MATRIX
 | 
			
		||||
EEK_TYPE_POINT
 | 
			
		||||
EEK_TYPE_BOUNDS
 | 
			
		||||
EEK_TYPE_OUTLINE
 | 
			
		||||
EEK_TYPE_COLOR
 | 
			
		||||
EekOrientation
 | 
			
		||||
EekModifierBehavior
 | 
			
		||||
EekModifierType
 | 
			
		||||
EEK_INVALID_KEYCODE
 | 
			
		||||
EekSymbolMatrix
 | 
			
		||||
EekPoint
 | 
			
		||||
EekBounds
 | 
			
		||||
EekOutline
 | 
			
		||||
EekColor
 | 
			
		||||
eek_symbol_matrix_get_type
 | 
			
		||||
eek_symbol_matrix_new
 | 
			
		||||
eek_symbol_matrix_copy
 | 
			
		||||
eek_symbol_matrix_free
 | 
			
		||||
eek_point_get_type
 | 
			
		||||
eek_point_rotate
 | 
			
		||||
eek_bounds_get_type
 | 
			
		||||
eek_bounds_long_side
 | 
			
		||||
eek_outline_get_type
 | 
			
		||||
eek_outline_copy
 | 
			
		||||
eek_outline_free
 | 
			
		||||
eek_color_get_type
 | 
			
		||||
eek_color_new
 | 
			
		||||
</SECTION>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -76,7 +76,7 @@ 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
 | 
			
		||||
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
 | 
			
		||||
@ -104,7 +104,7 @@ include $(top_srcdir)/gtk-doc.make
 | 
			
		||||
 | 
			
		||||
# Other files to distribute
 | 
			
		||||
# e.g. EXTRA_DIST += version.xml.in
 | 
			
		||||
EXTRA_DIST +=
 | 
			
		||||
# EXTRA_DIST +=
 | 
			
		||||
 | 
			
		||||
# Files not to distribute
 | 
			
		||||
# for --rebuild-types in $(SCAN_OPTIONS), e.g. $(DOC_MODULE).types
 | 
			
		||||
 | 
			
		||||
@ -35,8 +35,8 @@
 | 
			
		||||
  <part id="apireference">
 | 
			
		||||
    <title>API Manual</title>
 | 
			
		||||
    <chapter>
 | 
			
		||||
      <title>D-Bus proxy to eekboard-server</title>
 | 
			
		||||
      <xi:include href="xml/eekboard-server.xml"/>
 | 
			
		||||
      <title>D-Bus client interface to eekboard-server</title>
 | 
			
		||||
      <xi:include href="xml/eekboard-eekboard.xml"/>
 | 
			
		||||
      <xi:include href="xml/eekboard-context.xml"/>
 | 
			
		||||
    </chapter>
 | 
			
		||||
    <chapter id="object-tree">
 | 
			
		||||
 | 
			
		||||
@ -1,22 +1,22 @@
 | 
			
		||||
<SECTION>
 | 
			
		||||
<FILE>eekboard-server</FILE>
 | 
			
		||||
<TITLE>EekboardServer</TITLE>
 | 
			
		||||
EekboardServer
 | 
			
		||||
EekboardServerClass
 | 
			
		||||
EekboardServerPrivate
 | 
			
		||||
eekboard_server_new
 | 
			
		||||
eekboard_server_create_context
 | 
			
		||||
eekboard_server_push_context
 | 
			
		||||
eekboard_server_pop_context
 | 
			
		||||
eekboard_server_destroy_context
 | 
			
		||||
<FILE>eekboard-eekboard</FILE>
 | 
			
		||||
<TITLE>EekboardEekboard</TITLE>
 | 
			
		||||
EekboardEekboard
 | 
			
		||||
EekboardEekboardClass
 | 
			
		||||
EekboardEekboardPrivate
 | 
			
		||||
eekboard_eekboard_new
 | 
			
		||||
eekboard_eekboard_create_context
 | 
			
		||||
eekboard_eekboard_push_context
 | 
			
		||||
eekboard_eekboard_pop_context
 | 
			
		||||
eekboard_eekboard_destroy_context
 | 
			
		||||
<SUBSECTION Standard>
 | 
			
		||||
EEKBOARD_SERVER
 | 
			
		||||
EEKBOARD_IS_SERVER
 | 
			
		||||
EEKBOARD_TYPE_SERVER
 | 
			
		||||
eekboard_server_get_type
 | 
			
		||||
EEKBOARD_SERVER_CLASS
 | 
			
		||||
EEKBOARD_IS_SERVER_CLASS
 | 
			
		||||
EEKBOARD_SERVER_GET_CLASS
 | 
			
		||||
EEKBOARD_EEKBOARD
 | 
			
		||||
EEKBOARD_IS_EEKBOARD
 | 
			
		||||
EEKBOARD_TYPE_EEKBOARD
 | 
			
		||||
eekboard_eekboard_get_type
 | 
			
		||||
EEKBOARD_EEKBOARD_CLASS
 | 
			
		||||
EEKBOARD_IS_EEKBOARD_CLASS
 | 
			
		||||
EEKBOARD_EEKBOARD_GET_CLASS
 | 
			
		||||
</SECTION>
 | 
			
		||||
 | 
			
		||||
<SECTION>
 | 
			
		||||
 | 
			
		||||
@ -0,0 +1,2 @@
 | 
			
		||||
eekboard_context_get_type
 | 
			
		||||
eekboard_eekboard_get_type
 | 
			
		||||
 | 
			
		||||
@ -39,6 +39,7 @@ libeek_public_headers =				\
 | 
			
		||||
	$(srcdir)/eek-xml.h			\
 | 
			
		||||
	$(srcdir)/eek-xml-layout.h		\
 | 
			
		||||
	$(srcdir)/eek-serializable.h		\
 | 
			
		||||
	$(srcdir)/eek-theme.h			\
 | 
			
		||||
	$(srcdir)/eek.h
 | 
			
		||||
 | 
			
		||||
libeek_private_headers =			\
 | 
			
		||||
@ -46,7 +47,10 @@ libeek_private_headers =			\
 | 
			
		||||
	$(srcdir)/eek-special-keysym-entries.h	\
 | 
			
		||||
	$(srcdir)/eek-unicode-keysym-entries.h	\
 | 
			
		||||
	$(srcdir)/eek-xkeysym-keysym-entries.h	\
 | 
			
		||||
	$(srcdir)/eek-marshalers.h
 | 
			
		||||
	$(srcdir)/eek-marshalers.h		\
 | 
			
		||||
	$(srcdir)/eek-theme-context.h		\
 | 
			
		||||
	$(srcdir)/eek-theme-private.h		\
 | 
			
		||||
	$(srcdir)/eek-theme-node.h
 | 
			
		||||
 | 
			
		||||
libeek_sources =				\
 | 
			
		||||
	$(srcdir)/eek-layout.c			\
 | 
			
		||||
@ -62,7 +66,10 @@ libeek_sources =				\
 | 
			
		||||
	$(srcdir)/eek-xml.c			\
 | 
			
		||||
	$(srcdir)/eek-xml-layout.c		\
 | 
			
		||||
	$(srcdir)/eek-renderer.c		\
 | 
			
		||||
	$(srcdir)/eek-keyboard-drawing.c
 | 
			
		||||
	$(srcdir)/eek-keyboard-drawing.c	\
 | 
			
		||||
	$(srcdir)/eek-theme.c			\
 | 
			
		||||
	$(srcdir)/eek-theme-context.c		\
 | 
			
		||||
	$(srcdir)/eek-theme-node.c
 | 
			
		||||
 | 
			
		||||
libeek_keysym_sources =				\
 | 
			
		||||
	$(srcdir)/eek-special-keysym-entries.h	\
 | 
			
		||||
@ -85,8 +92,8 @@ libeek_la_SOURCES =				\
 | 
			
		||||
	$(libeek_sources)			\
 | 
			
		||||
	$(srcdir)/eek-marshalers.c
 | 
			
		||||
 | 
			
		||||
libeek_la_CFLAGS = $(GIO2_CFLAGS) $(PANGOCAIRO_CFLAGS)
 | 
			
		||||
libeek_la_LIBADD = $(GIO2_LIBS) $(PANGOCAIRO_LIBS) -lm
 | 
			
		||||
libeek_la_CFLAGS = $(GIO2_CFLAGS) $(PANGOCAIRO_CFLAGS) $(LIBCROCO_CFLAGS)
 | 
			
		||||
libeek_la_LIBADD = $(GIO2_LIBS) $(PANGOCAIRO_LIBS) $(LIBCROCO_LIBS) -lm
 | 
			
		||||
 | 
			
		||||
if ENABLE_CLUTTER
 | 
			
		||||
libeek_clutter_public_headers =			\
 | 
			
		||||
@ -112,8 +119,11 @@ endif
 | 
			
		||||
libeek_gtk_public_headers =			\
 | 
			
		||||
	$(srcdir)/eek-gtk-keyboard.h		\
 | 
			
		||||
	$(srcdir)/eek-gtk.h
 | 
			
		||||
libeek_gtk_private_headers =			\
 | 
			
		||||
	$(srcdir)/eek-gtk-renderer.h
 | 
			
		||||
libeek_gtk_sources =				\
 | 
			
		||||
	$(srcdir)/eek-gtk-keyboard.c
 | 
			
		||||
	$(srcdir)/eek-gtk-keyboard.c		\
 | 
			
		||||
	$(srcdir)/eek-gtk-renderer.c
 | 
			
		||||
 | 
			
		||||
libeek_gtk_la_SOURCES = $(libeek_gtk_sources)
 | 
			
		||||
libeek_gtk_la_CFLAGS = $(GTK_CFLAGS)
 | 
			
		||||
 | 
			
		||||
@ -22,13 +22,14 @@
 | 
			
		||||
 * SECTION:eek-clutter-keyboard
 | 
			
		||||
 * @short_description: a #ClutterActor displaying #EekKeyboard
 | 
			
		||||
 */
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <gdk-pixbuf/gdk-pixbuf.h>
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_CONFIG_H
 | 
			
		||||
#include "config.h"
 | 
			
		||||
#endif  /* HAVE_CONFIG_H */
 | 
			
		||||
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <gdk-pixbuf/gdk-pixbuf.h>
 | 
			
		||||
 | 
			
		||||
#include "eek-clutter-keyboard.h"
 | 
			
		||||
#include "eek-clutter-section.h"
 | 
			
		||||
#include "eek-clutter-renderer.h"
 | 
			
		||||
@ -49,6 +50,7 @@ struct _EekClutterKeyboardPrivate
 | 
			
		||||
{
 | 
			
		||||
    EekKeyboard *keyboard;
 | 
			
		||||
    EekClutterRenderer *renderer;
 | 
			
		||||
    EekTheme *theme;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct _CreateSectionCallbackData {
 | 
			
		||||
@ -77,6 +79,9 @@ eek_clutter_keyboard_real_realize (ClutterActor *self)
 | 
			
		||||
 | 
			
		||||
    priv = EEK_CLUTTER_KEYBOARD_GET_PRIVATE(self);
 | 
			
		||||
 | 
			
		||||
    if (priv->theme)
 | 
			
		||||
        eek_renderer_set_theme (EEK_RENDERER(priv->renderer), priv->theme);
 | 
			
		||||
 | 
			
		||||
    scale = eek_renderer_get_scale (EEK_RENDERER(priv->renderer));
 | 
			
		||||
    clutter_actor_set_position (CLUTTER_ACTOR(self),
 | 
			
		||||
                                bounds.x * scale,
 | 
			
		||||
@ -125,7 +130,6 @@ eek_clutter_keyboard_real_allocate (ClutterActor          *self,
 | 
			
		||||
{
 | 
			
		||||
    EekClutterKeyboardPrivate *priv = EEK_CLUTTER_KEYBOARD_GET_PRIVATE(self);
 | 
			
		||||
 | 
			
		||||
    g_assert (priv->renderer);
 | 
			
		||||
    eek_renderer_set_allocation_size (EEK_RENDERER(priv->renderer),
 | 
			
		||||
                                      box->x2 - box->x1,
 | 
			
		||||
                                      box->y2 - box->y1);
 | 
			
		||||
@ -192,6 +196,11 @@ eek_clutter_keyboard_dispose (GObject *object)
 | 
			
		||||
        priv->keyboard = NULL;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (priv->theme) {
 | 
			
		||||
        g_object_unref (priv->theme);
 | 
			
		||||
        priv->keyboard = NULL;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    G_OBJECT_CLASS (eek_clutter_keyboard_parent_class)->dispose (object);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -248,3 +257,16 @@ eek_clutter_keyboard_new (EekKeyboard *keyboard)
 | 
			
		||||
{
 | 
			
		||||
    return g_object_new (EEK_TYPE_CLUTTER_KEYBOARD, "keyboard", keyboard, NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
eek_clutter_keyboard_set_theme (EekClutterKeyboard *keyboard,
 | 
			
		||||
                                EekTheme           *theme)
 | 
			
		||||
{
 | 
			
		||||
    EekClutterKeyboardPrivate *priv;
 | 
			
		||||
 | 
			
		||||
    g_return_if_fail (EEK_IS_CLUTTER_KEYBOARD(keyboard));
 | 
			
		||||
    g_return_if_fail (EEK_IS_THEME(theme));
 | 
			
		||||
 | 
			
		||||
    priv = EEK_CLUTTER_KEYBOARD_GET_PRIVATE(keyboard);
 | 
			
		||||
    priv->theme = g_object_ref (theme);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -55,6 +55,8 @@ struct _EekClutterKeyboardClass
 | 
			
		||||
 | 
			
		||||
GType         eek_clutter_keyboard_get_type  (void) G_GNUC_CONST;
 | 
			
		||||
ClutterActor *eek_clutter_keyboard_new       (EekKeyboard        *keyboard);
 | 
			
		||||
void          eek_clutter_keyboard_set_theme (EekClutterKeyboard *keyboard,
 | 
			
		||||
                                              EekTheme           *theme);
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
#endif  /* EEK_CLUTTER_KEYBOARD_H */
 | 
			
		||||
 | 
			
		||||
@ -18,16 +18,16 @@
 | 
			
		||||
 * 02110-1301 USA
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_CONFIG_H
 | 
			
		||||
#include "config.h"
 | 
			
		||||
#endif  /* HAVE_CONFIG_H */
 | 
			
		||||
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <gdk-pixbuf/gdk-pixbuf.h>
 | 
			
		||||
#include <cogl/cogl.h>
 | 
			
		||||
#include <cogl/cogl-pango.h>
 | 
			
		||||
#include <clutter/clutter.h>
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_CONFIG_H
 | 
			
		||||
#include "config.h"
 | 
			
		||||
#endif  /* HAVE_CONFIG_H */
 | 
			
		||||
 | 
			
		||||
#include "eek-clutter-renderer.h"
 | 
			
		||||
#include "eek-key.h"
 | 
			
		||||
 | 
			
		||||
@ -77,6 +77,14 @@ cairo_pixels_to_pixbuf (guint8 *pixels,
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
eek_clutter_renderer_finalize (GObject *object)
 | 
			
		||||
{
 | 
			
		||||
    EekClutterRendererPrivate *priv = EEK_CLUTTER_RENDERER_GET_PRIVATE(object);
 | 
			
		||||
    g_hash_table_destroy (priv->outline_texture_cache);
 | 
			
		||||
    G_OBJECT_CLASS (eek_clutter_renderer_parent_class)->finalize (object);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
eek_clutter_renderer_class_init (EekClutterRendererClass *klass)
 | 
			
		||||
{
 | 
			
		||||
@ -84,6 +92,8 @@ eek_clutter_renderer_class_init (EekClutterRendererClass *klass)
 | 
			
		||||
 | 
			
		||||
    g_type_class_add_private (gobject_class,
 | 
			
		||||
                              sizeof (EekClutterRendererPrivate));
 | 
			
		||||
 | 
			
		||||
    gobject_class->finalize = eek_clutter_renderer_finalize;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
@ -109,17 +119,22 @@ eek_clutter_renderer_render_key (EekClutterRenderer *renderer,
 | 
			
		||||
    CoglHandle *outline_texture;
 | 
			
		||||
    PangoLayout *layout;
 | 
			
		||||
    PangoRectangle extents = { 0, };
 | 
			
		||||
    CoglColor color = { 0x00, 0x00, 0x00, 0xFF };
 | 
			
		||||
    EekColor foreground;
 | 
			
		||||
    CoglColor color;
 | 
			
		||||
    ClutterGeometry geom;
 | 
			
		||||
    gulong oref;
 | 
			
		||||
    EekKeyboard *keyboard;
 | 
			
		||||
 | 
			
		||||
    g_assert (EEK_IS_CLUTTER_RENDERER(renderer));
 | 
			
		||||
    g_assert (CLUTTER_IS_ACTOR(actor));
 | 
			
		||||
    g_assert (EEK_IS_KEY(key));
 | 
			
		||||
 | 
			
		||||
    oref = eek_key_get_oref (key);
 | 
			
		||||
    g_object_get (renderer, "keyboard", &keyboard, NULL);
 | 
			
		||||
    outline = eek_keyboard_get_outline (keyboard, oref);
 | 
			
		||||
    g_object_unref (keyboard);
 | 
			
		||||
 | 
			
		||||
    priv = EEK_CLUTTER_RENDERER_GET_PRIVATE(renderer);
 | 
			
		||||
 | 
			
		||||
    outline = eek_key_get_outline (key);
 | 
			
		||||
 | 
			
		||||
    outline_texture = g_hash_table_lookup (priv->outline_texture_cache,
 | 
			
		||||
                                           outline);
 | 
			
		||||
    if (!outline_texture) {
 | 
			
		||||
@ -186,6 +201,17 @@ eek_clutter_renderer_render_key (EekClutterRenderer *renderer,
 | 
			
		||||
    layout = eek_renderer_create_pango_layout (EEK_RENDERER(renderer));
 | 
			
		||||
    eek_renderer_render_key_label (EEK_RENDERER(renderer), layout, key);
 | 
			
		||||
    pango_layout_get_extents (layout, NULL, &extents);
 | 
			
		||||
 | 
			
		||||
    eek_renderer_get_foreground_color (EEK_RENDERER(renderer),
 | 
			
		||||
                                       EEK_ELEMENT(key),
 | 
			
		||||
                                       &foreground);
 | 
			
		||||
 | 
			
		||||
    cogl_color_set_from_4f (&color,
 | 
			
		||||
                            foreground.red,
 | 
			
		||||
                            foreground.green,
 | 
			
		||||
                            foreground.blue,
 | 
			
		||||
                            foreground.alpha);
 | 
			
		||||
 | 
			
		||||
    cogl_pango_render_layout (layout,
 | 
			
		||||
                              (geom.width - extents.width / PANGO_SCALE) / 2,
 | 
			
		||||
                              (geom.height - extents.height / PANGO_SCALE) / 2,
 | 
			
		||||
 | 
			
		||||
@ -208,7 +208,7 @@ eek_container_class_init (EekContainerClass *klass)
 | 
			
		||||
     * added to @container.
 | 
			
		||||
     */
 | 
			
		||||
    signals[CHILD_ADDED] =
 | 
			
		||||
        g_signal_new ("child-added",
 | 
			
		||||
        g_signal_new (I_("child-added"),
 | 
			
		||||
                      G_TYPE_FROM_CLASS(gobject_class),
 | 
			
		||||
                      G_SIGNAL_RUN_FIRST,
 | 
			
		||||
                      G_STRUCT_OFFSET(EekContainerClass, child_added),
 | 
			
		||||
@ -226,7 +226,7 @@ eek_container_class_init (EekContainerClass *klass)
 | 
			
		||||
     * removed from @container.
 | 
			
		||||
     */
 | 
			
		||||
    signals[CHILD_REMOVED] =
 | 
			
		||||
        g_signal_new ("child-removed",
 | 
			
		||||
        g_signal_new (I_("child-removed"),
 | 
			
		||||
                      G_TYPE_FROM_CLASS(gobject_class),
 | 
			
		||||
                      G_SIGNAL_RUN_FIRST,
 | 
			
		||||
                      G_STRUCT_OFFSET(EekContainerClass, child_removed),
 | 
			
		||||
 | 
			
		||||
@ -26,23 +26,33 @@
 | 
			
		||||
 * shall be used to implement #EekKeyboard, #EekSection, or #EekKey.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_CONFIG_H
 | 
			
		||||
#include "config.h"
 | 
			
		||||
#endif  /* HAVE_CONFIG_H */
 | 
			
		||||
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
#include "eek-element.h"
 | 
			
		||||
#include "eek-container.h"
 | 
			
		||||
#include "eek-marshalers.h"
 | 
			
		||||
#include "eek-serializable.h"
 | 
			
		||||
 | 
			
		||||
enum {
 | 
			
		||||
    PROP_0,
 | 
			
		||||
    PROP_NAME,
 | 
			
		||||
    PROP_BOUNDS,
 | 
			
		||||
    PROP_GROUP,
 | 
			
		||||
    PROP_LEVEL,
 | 
			
		||||
    PROP_LAST
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
enum {
 | 
			
		||||
    SYMBOL_INDEX_CHANGED,
 | 
			
		||||
    LAST_SIGNAL
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static guint signals[LAST_SIGNAL] = { 0, };
 | 
			
		||||
 | 
			
		||||
static void eek_serializable_iface_init (EekSerializableIface *iface);
 | 
			
		||||
 | 
			
		||||
G_DEFINE_ABSTRACT_TYPE_WITH_CODE (EekElement, eek_element, G_TYPE_OBJECT,
 | 
			
		||||
@ -58,6 +68,8 @@ struct _EekElementPrivate
 | 
			
		||||
    gchar *name;
 | 
			
		||||
    EekBounds bounds;
 | 
			
		||||
    EekElement *parent;
 | 
			
		||||
    gint group;
 | 
			
		||||
    gint level;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static GVariant *
 | 
			
		||||
@ -182,6 +194,41 @@ eek_element_real_get_bounds (EekElement *self,
 | 
			
		||||
    g_object_notify (G_OBJECT(self), "bounds");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
eek_element_real_set_symbol_index (EekElement *self,
 | 
			
		||||
                                   gint        group,
 | 
			
		||||
                                   gint        level)
 | 
			
		||||
{
 | 
			
		||||
    EekElementPrivate *priv = EEK_ELEMENT_GET_PRIVATE(self);
 | 
			
		||||
 | 
			
		||||
    if (priv->group != group || priv->level != level) {
 | 
			
		||||
        priv->group = group;
 | 
			
		||||
        priv->level = level;
 | 
			
		||||
        g_signal_emit_by_name (self, "symbol-index-changed", group, level);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
eek_element_real_get_symbol_index (EekElement *self,
 | 
			
		||||
                                   gint       *group,
 | 
			
		||||
                                   gint       *level)
 | 
			
		||||
{
 | 
			
		||||
    EekElementPrivate *priv = EEK_ELEMENT_GET_PRIVATE(self);
 | 
			
		||||
 | 
			
		||||
    if (group)
 | 
			
		||||
        *group = priv->group;
 | 
			
		||||
    if (level)
 | 
			
		||||
        *level = priv->level;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
eek_element_real_symbol_index_changed (EekElement *self,
 | 
			
		||||
                                       gint        group,
 | 
			
		||||
                                       gint        level)
 | 
			
		||||
{
 | 
			
		||||
    // g_debug ("symbol-index-changed");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
eek_element_finalize (GObject *object)
 | 
			
		||||
{
 | 
			
		||||
@ -206,6 +253,13 @@ eek_element_set_property (GObject      *object,
 | 
			
		||||
        eek_element_set_bounds (EEK_ELEMENT(object),
 | 
			
		||||
                                g_value_get_boxed (value));
 | 
			
		||||
        break;
 | 
			
		||||
    case PROP_GROUP:
 | 
			
		||||
        eek_element_set_group (EEK_ELEMENT(object),
 | 
			
		||||
                               g_value_get_int (value));
 | 
			
		||||
        break;
 | 
			
		||||
    case PROP_LEVEL:
 | 
			
		||||
        eek_element_set_level (EEK_ELEMENT(object),
 | 
			
		||||
                               g_value_get_int (value));
 | 
			
		||||
    default:
 | 
			
		||||
        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 | 
			
		||||
        break;
 | 
			
		||||
@ -228,6 +282,12 @@ eek_element_get_property (GObject    *object,
 | 
			
		||||
        eek_element_get_bounds (EEK_ELEMENT(object), &bounds);
 | 
			
		||||
        g_value_set_boxed (value, &bounds);
 | 
			
		||||
        break;
 | 
			
		||||
    case PROP_GROUP:
 | 
			
		||||
        g_value_set_int (value, eek_element_get_group (EEK_ELEMENT(object)));
 | 
			
		||||
        break;
 | 
			
		||||
    case PROP_LEVEL:
 | 
			
		||||
        g_value_set_int (value, eek_element_get_level (EEK_ELEMENT(object)));
 | 
			
		||||
        break;
 | 
			
		||||
    default:
 | 
			
		||||
        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 | 
			
		||||
        break;
 | 
			
		||||
@ -249,6 +309,11 @@ eek_element_class_init (EekElementClass *klass)
 | 
			
		||||
    klass->get_name = eek_element_real_get_name;
 | 
			
		||||
    klass->set_bounds = eek_element_real_set_bounds;
 | 
			
		||||
    klass->get_bounds = eek_element_real_get_bounds;
 | 
			
		||||
    klass->set_symbol_index = eek_element_real_set_symbol_index;
 | 
			
		||||
    klass->get_symbol_index = eek_element_real_get_symbol_index;
 | 
			
		||||
 | 
			
		||||
    /* signals */
 | 
			
		||||
    klass->symbol_index_changed = eek_element_real_symbol_index_changed;
 | 
			
		||||
 | 
			
		||||
    gobject_class->set_property = eek_element_set_property;
 | 
			
		||||
    gobject_class->get_property = eek_element_get_property;
 | 
			
		||||
@ -281,6 +346,56 @@ eek_element_class_init (EekElementClass *klass)
 | 
			
		||||
    g_object_class_install_property (gobject_class,
 | 
			
		||||
                                     PROP_BOUNDS,
 | 
			
		||||
                                     pspec);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * EekElement:group:
 | 
			
		||||
     *
 | 
			
		||||
     * The group value of the symbol index of #EekElement.
 | 
			
		||||
     */
 | 
			
		||||
    pspec = g_param_spec_int ("group",
 | 
			
		||||
                              "Group",
 | 
			
		||||
                              "Group value of the symbol index",
 | 
			
		||||
                              -1, G_MAXINT, -1,
 | 
			
		||||
                              G_PARAM_READWRITE);
 | 
			
		||||
    g_object_class_install_property (gobject_class,
 | 
			
		||||
                                     PROP_GROUP,
 | 
			
		||||
                                     pspec);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * EekElement:level:
 | 
			
		||||
     *
 | 
			
		||||
     * The level value of the symbol index of #EekElement.
 | 
			
		||||
     */
 | 
			
		||||
    pspec = g_param_spec_int ("level",
 | 
			
		||||
                              "Level",
 | 
			
		||||
                              "Level value of the symbol index",
 | 
			
		||||
                              -1, G_MAXINT, -1,
 | 
			
		||||
                              G_PARAM_READWRITE);
 | 
			
		||||
    g_object_class_install_property (gobject_class,
 | 
			
		||||
                                     PROP_LEVEL,
 | 
			
		||||
                                     pspec);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * EekElement::symbol-index-changed:
 | 
			
		||||
     * @element: an #EekElement
 | 
			
		||||
     * @group: row index of the symbol matrix of keys on @element
 | 
			
		||||
     * @level: column index of the symbol matrix of keys on @element
 | 
			
		||||
     *
 | 
			
		||||
     * The ::symbol-index-changed signal is emitted each time the
 | 
			
		||||
     * global configuration of group/level index changes.
 | 
			
		||||
     */
 | 
			
		||||
    signals[SYMBOL_INDEX_CHANGED] =
 | 
			
		||||
        g_signal_new (I_("symbol-index-changed"),
 | 
			
		||||
                      G_TYPE_FROM_CLASS(gobject_class),
 | 
			
		||||
                      G_SIGNAL_RUN_LAST,
 | 
			
		||||
                      G_STRUCT_OFFSET(EekElementClass, symbol_index_changed),
 | 
			
		||||
                      NULL,
 | 
			
		||||
                      NULL,
 | 
			
		||||
                      _eek_marshal_VOID__INT_INT,
 | 
			
		||||
                      G_TYPE_NONE,
 | 
			
		||||
                      2,
 | 
			
		||||
                      G_TYPE_INT,
 | 
			
		||||
                      G_TYPE_INT);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
@ -291,6 +406,8 @@ eek_element_init (EekElement *self)
 | 
			
		||||
    priv = self->priv = EEK_ELEMENT_GET_PRIVATE(self);
 | 
			
		||||
    priv->name = NULL;
 | 
			
		||||
    memset (&priv->bounds, 0, sizeof priv->bounds);
 | 
			
		||||
    priv->group = -1;
 | 
			
		||||
    priv->level = -1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@ -452,3 +569,117 @@ eek_element_set_size (EekElement  *element,
 | 
			
		||||
    bounds.height = height;
 | 
			
		||||
    eek_element_set_bounds (element, &bounds);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eek_element_set_symbol_index:
 | 
			
		||||
 * @element: an #EekElement
 | 
			
		||||
 * @group: row index of the symbol matrix
 | 
			
		||||
 * @level: column index of the symbol matrix
 | 
			
		||||
 *
 | 
			
		||||
 * Set the default index of the symbol matrices of @element.  The
 | 
			
		||||
 * setting affects the child, if child does not have the index set, as
 | 
			
		||||
 * well as this element.  To unset, pass -1 as group/level.
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
eek_element_set_symbol_index (EekElement *element,
 | 
			
		||||
                              gint        group,
 | 
			
		||||
                              gint        level)
 | 
			
		||||
{
 | 
			
		||||
    g_return_if_fail (EEK_IS_ELEMENT(element));
 | 
			
		||||
    EEK_ELEMENT_GET_CLASS(element)->set_symbol_index (element, group, level);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eek_element_get_symbol_index:
 | 
			
		||||
 * @element: an #EekElement
 | 
			
		||||
 * @group: a pointer where the group value of the symbol index will be stored
 | 
			
		||||
 * @level: a pointer where the level value of the symbol index will be stored
 | 
			
		||||
 *
 | 
			
		||||
 * Get the default index of the symbol matrices of @element.
 | 
			
		||||
 * If the index is not set, -1 will be returned.
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
eek_element_get_symbol_index (EekElement *element,
 | 
			
		||||
                              gint       *group,
 | 
			
		||||
                              gint       *level)
 | 
			
		||||
{
 | 
			
		||||
    g_return_if_fail (EEK_IS_ELEMENT(element));
 | 
			
		||||
    g_return_if_fail (group || level);
 | 
			
		||||
    EEK_ELEMENT_GET_CLASS(element)->get_symbol_index (element, group, level);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eek_element_set_group:
 | 
			
		||||
 * @element: an #EekElement
 | 
			
		||||
 * @group: group index of @element
 | 
			
		||||
 *
 | 
			
		||||
 * Set the group value of the default symbol index of @element.  To
 | 
			
		||||
 * unset, pass -1 as @group.
 | 
			
		||||
 *
 | 
			
		||||
 * See also: eek_element_set_symbol_index()
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
eek_element_set_group (EekElement *element,
 | 
			
		||||
                       gint        group)
 | 
			
		||||
{
 | 
			
		||||
    gint level;
 | 
			
		||||
 | 
			
		||||
    level = eek_element_get_level (element);
 | 
			
		||||
    eek_element_set_symbol_index (element, group, level);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eek_element_set_level:
 | 
			
		||||
 * @element: an #EekElement
 | 
			
		||||
 * @level: level index of @element
 | 
			
		||||
 *
 | 
			
		||||
 * Set the level value of the default symbol index of @element.  To
 | 
			
		||||
 * unset, pass -1 as @level.
 | 
			
		||||
 *
 | 
			
		||||
 * See also: eek_element_set_symbol_index()
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
eek_element_set_level (EekElement *element,
 | 
			
		||||
                       gint        level)
 | 
			
		||||
{
 | 
			
		||||
    gint group;
 | 
			
		||||
 | 
			
		||||
    group = eek_element_get_group (element);
 | 
			
		||||
    eek_element_set_symbol_index (element, group, level);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eek_element_get_group:
 | 
			
		||||
 * @element: an #EekElement
 | 
			
		||||
 *
 | 
			
		||||
 * Return the group value of the default symbol index of @element.
 | 
			
		||||
 * If the value is not set, -1 will be returned.
 | 
			
		||||
 *
 | 
			
		||||
 * See also: eek_element_get_symbol_index()
 | 
			
		||||
 */
 | 
			
		||||
gint
 | 
			
		||||
eek_element_get_group (EekElement *element)
 | 
			
		||||
{
 | 
			
		||||
    gint group;
 | 
			
		||||
 | 
			
		||||
    eek_element_get_symbol_index (element, &group, NULL);
 | 
			
		||||
    return group;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eek_element_get_level:
 | 
			
		||||
 * @element: an #EekElement
 | 
			
		||||
 *
 | 
			
		||||
 * Return the level value of the default symbol index of @element.
 | 
			
		||||
 * If the value is not set, -1 will be returned.
 | 
			
		||||
 *
 | 
			
		||||
 * See also: eek_element_get_symbol_index()
 | 
			
		||||
 */
 | 
			
		||||
gint
 | 
			
		||||
eek_element_get_level (EekElement *element)
 | 
			
		||||
{
 | 
			
		||||
    gint level;
 | 
			
		||||
 | 
			
		||||
    eek_element_get_symbol_index (element, NULL, &level);
 | 
			
		||||
    return level;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -60,9 +60,21 @@ struct _EekElementClass
 | 
			
		||||
    void                  (* get_bounds)           (EekElement  *self,
 | 
			
		||||
                                                    EekBounds   *bounds);
 | 
			
		||||
 | 
			
		||||
    void                  (* set_symbol_index)     (EekElement  *self,
 | 
			
		||||
                                                    gint         group,
 | 
			
		||||
                                                    gint         level);
 | 
			
		||||
    void                  (* get_symbol_index)     (EekElement  *self,
 | 
			
		||||
                                                    gint        *group,
 | 
			
		||||
                                                    gint        *level);
 | 
			
		||||
 | 
			
		||||
    /* signals */
 | 
			
		||||
    void                  (* symbol_index_changed) (EekElement  *self,
 | 
			
		||||
                                                    gint         group,
 | 
			
		||||
                                                    gint         level);
 | 
			
		||||
 | 
			
		||||
    /*< private >*/
 | 
			
		||||
    /* padding */
 | 
			
		||||
    gpointer pdummy[24];
 | 
			
		||||
    gpointer pdummy[21];
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
GType                 eek_element_get_type              (void) G_GNUC_CONST;
 | 
			
		||||
@ -92,5 +104,18 @@ void                  eek_element_get_absolute_position (EekElement  *element,
 | 
			
		||||
                                                         gdouble     *x,
 | 
			
		||||
                                                         gdouble     *y);
 | 
			
		||||
 | 
			
		||||
void                  eek_element_set_symbol_index      (EekElement  *element,
 | 
			
		||||
                                                         gint         group,
 | 
			
		||||
                                                         gint         level);
 | 
			
		||||
void                  eek_element_get_symbol_index      (EekElement  *element,
 | 
			
		||||
                                                         gint        *group,
 | 
			
		||||
                                                         gint        *level);
 | 
			
		||||
void                  eek_element_set_group             (EekElement  *element,
 | 
			
		||||
                                                         gint         group);
 | 
			
		||||
void                  eek_element_set_level             (EekElement  *element,
 | 
			
		||||
                                                         gint         level);
 | 
			
		||||
gint                  eek_element_get_group             (EekElement  *element);
 | 
			
		||||
gint                  eek_element_get_level             (EekElement  *element);
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
#endif  /* EEK_ELEMENT_H */
 | 
			
		||||
 | 
			
		||||
@ -22,14 +22,15 @@
 | 
			
		||||
 * SECTION:eek-gtk-keyboard
 | 
			
		||||
 * @short_description: a #GtkWidget displaying #EekKeyboard
 | 
			
		||||
 */
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_CONFIG_H
 | 
			
		||||
#include "config.h"
 | 
			
		||||
#endif  /* HAVE_CONFIG_H */
 | 
			
		||||
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
#include "eek-gtk-keyboard.h"
 | 
			
		||||
#include "eek-renderer.h"
 | 
			
		||||
#include "eek-gtk-renderer.h"
 | 
			
		||||
#include "eek-keyboard.h"
 | 
			
		||||
#include "eek-section.h"
 | 
			
		||||
#include "eek-key.h"
 | 
			
		||||
@ -60,6 +61,7 @@ struct _EekGtkKeyboardPrivate
 | 
			
		||||
    gulong key_pressed_handler;
 | 
			
		||||
    gulong key_released_handler;
 | 
			
		||||
    gulong symbol_index_changed_handler;
 | 
			
		||||
    EekTheme *theme;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static EekColor * color_from_gdk_color    (GdkColor    *gdk_color);
 | 
			
		||||
@ -96,6 +98,7 @@ eek_gtk_keyboard_real_draw (GtkWidget *self,
 | 
			
		||||
{
 | 
			
		||||
    EekGtkKeyboardPrivate *priv = EEK_GTK_KEYBOARD_GET_PRIVATE(self);
 | 
			
		||||
    GtkAllocation allocation;
 | 
			
		||||
    EekColor background;
 | 
			
		||||
 | 
			
		||||
    gtk_widget_get_allocation (self, &allocation);
 | 
			
		||||
 | 
			
		||||
@ -103,9 +106,12 @@ eek_gtk_keyboard_real_draw (GtkWidget *self,
 | 
			
		||||
        GtkStyle *style;
 | 
			
		||||
        GtkStateType state;
 | 
			
		||||
        PangoContext *pcontext;
 | 
			
		||||
        EekColor *color;
 | 
			
		||||
 | 
			
		||||
        pcontext = gtk_widget_get_pango_context (self);
 | 
			
		||||
        priv->renderer = eek_renderer_new (priv->keyboard, pcontext);
 | 
			
		||||
        priv->renderer = eek_gtk_renderer_new (priv->keyboard, pcontext, self);
 | 
			
		||||
        if (priv->theme)
 | 
			
		||||
            eek_renderer_set_theme (priv->renderer, priv->theme);
 | 
			
		||||
 | 
			
		||||
        eek_renderer_set_allocation_size (priv->renderer,
 | 
			
		||||
                                          allocation.width,
 | 
			
		||||
@ -114,14 +120,26 @@ eek_gtk_keyboard_real_draw (GtkWidget *self,
 | 
			
		||||
        style = gtk_widget_get_style (self);
 | 
			
		||||
        state = gtk_widget_get_state (self);
 | 
			
		||||
 | 
			
		||||
        eek_renderer_set_foreground
 | 
			
		||||
            (priv->renderer,
 | 
			
		||||
             color_from_gdk_color (&style->fg[state]));
 | 
			
		||||
        eek_renderer_set_background
 | 
			
		||||
            (priv->renderer,
 | 
			
		||||
             color_from_gdk_color (&style->bg[state]));
 | 
			
		||||
        color = color_from_gdk_color (&style->fg[state]);
 | 
			
		||||
        eek_renderer_set_default_foreground_color (priv->renderer, color);
 | 
			
		||||
        eek_color_free (color);
 | 
			
		||||
 | 
			
		||||
        color = color_from_gdk_color (&style->bg[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 dragged key */
 | 
			
		||||
@ -260,10 +278,22 @@ eek_gtk_keyboard_dispose (GObject *object)
 | 
			
		||||
            g_signal_handler_disconnect (priv->keyboard,
 | 
			
		||||
                                         priv->symbol_index_changed_handler);
 | 
			
		||||
            
 | 
			
		||||
        if (priv->dragged_key) {
 | 
			
		||||
            g_signal_emit_by_name (priv->dragged_key,
 | 
			
		||||
                                   "released",
 | 
			
		||||
                                   priv->keyboard);
 | 
			
		||||
            priv->dragged_key = NULL;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        g_object_unref (priv->keyboard);
 | 
			
		||||
        priv->keyboard = NULL;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (priv->theme) {
 | 
			
		||||
        g_object_unref (priv->theme);
 | 
			
		||||
        priv->theme = NULL;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    G_OBJECT_CLASS (eek_gtk_keyboard_parent_class)->dispose (object);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -329,14 +359,10 @@ eek_gtk_keyboard_new (EekKeyboard *keyboard)
 | 
			
		||||
static EekColor *
 | 
			
		||||
color_from_gdk_color (GdkColor *gdk_color)
 | 
			
		||||
{
 | 
			
		||||
    EekColor *color;
 | 
			
		||||
 | 
			
		||||
    color = g_slice_new (EekColor);
 | 
			
		||||
    color->red = gdk_color->red / (gdouble)0xFFFF;
 | 
			
		||||
    color->green = gdk_color->green / (gdouble)0xFFFF;
 | 
			
		||||
    color->blue = gdk_color->blue / (gdouble)0xFFFF;
 | 
			
		||||
    color->alpha = 1.0;
 | 
			
		||||
    return color;
 | 
			
		||||
    return eek_color_new (gdk_color->red / (gdouble)0xFFFF,
 | 
			
		||||
                          gdk_color->green / (gdouble)0xFFFF,
 | 
			
		||||
                          gdk_color->blue / (gdouble)0xFFFF,
 | 
			
		||||
                          1.0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
@ -409,6 +435,7 @@ on_key_released (EekKeyboard *keyboard,
 | 
			
		||||
                     large_bounds.height);
 | 
			
		||||
    cairo_clip (cr);
 | 
			
		||||
    eek_renderer_render_keyboard (priv->renderer, cr);
 | 
			
		||||
    cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR);
 | 
			
		||||
    cairo_destroy (cr);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -422,3 +449,16 @@ on_symbol_index_changed (EekKeyboard *keyboard,
 | 
			
		||||
 | 
			
		||||
    gtk_widget_queue_draw (widget);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
eek_gtk_keyboard_set_theme (EekGtkKeyboard *keyboard,
 | 
			
		||||
                            EekTheme       *theme)
 | 
			
		||||
{
 | 
			
		||||
    EekGtkKeyboardPrivate *priv;
 | 
			
		||||
 | 
			
		||||
    g_return_if_fail (EEK_IS_GTK_KEYBOARD(keyboard));
 | 
			
		||||
    g_return_if_fail (EEK_IS_THEME(theme));
 | 
			
		||||
 | 
			
		||||
    priv = EEK_GTK_KEYBOARD_GET_PRIVATE(keyboard);
 | 
			
		||||
    priv->theme = g_object_ref (theme);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -57,6 +57,8 @@ struct _EekGtkKeyboardClass
 | 
			
		||||
 | 
			
		||||
GType      eek_gtk_keyboard_get_type  (void) G_GNUC_CONST;
 | 
			
		||||
GtkWidget *eek_gtk_keyboard_new       (EekKeyboard    *keyboard);
 | 
			
		||||
void       eek_gtk_keyboard_set_theme (EekGtkKeyboard *keyboard,
 | 
			
		||||
                                       EekTheme       *theme);
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
#endif  /* EEK_GTK_KEYBOARD_H */
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										134
									
								
								eek/eek-gtk-renderer.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										134
									
								
								eek/eek-gtk-renderer.c
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,134 @@
 | 
			
		||||
/* 
 | 
			
		||||
 * Copyright (C) 2011 Daiki Ueno <ueno@unixuser.org>
 | 
			
		||||
 * Copyright (C) 2011 Red Hat, Inc.
 | 
			
		||||
 * 
 | 
			
		||||
 * This library is free software; you can redistribute it and/or
 | 
			
		||||
 * modify it under the terms of the GNU Lesser General Public License
 | 
			
		||||
 * as published by the Free Software Foundation; either version 2 of
 | 
			
		||||
 * the License, or (at your option) any later version.
 | 
			
		||||
 * 
 | 
			
		||||
 * This library is distributed in the hope that it will be useful, but
 | 
			
		||||
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
			
		||||
 * Lesser General Public License for more details.
 | 
			
		||||
 * 
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General Public
 | 
			
		||||
 * License along with this library; if not, write to the Free Software
 | 
			
		||||
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 | 
			
		||||
 * 02110-1301 USA
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_CONFIG_H
 | 
			
		||||
#include "config.h"
 | 
			
		||||
#endif  /* HAVE_CONFIG_H */
 | 
			
		||||
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <gdk-pixbuf/gdk-pixbuf.h>
 | 
			
		||||
 | 
			
		||||
#include "eek-gtk-renderer.h"
 | 
			
		||||
#include "eek-key.h"
 | 
			
		||||
 | 
			
		||||
G_DEFINE_TYPE (EekGtkRenderer, eek_gtk_renderer, EEK_TYPE_RENDERER);
 | 
			
		||||
 | 
			
		||||
static cairo_surface_t *
 | 
			
		||||
pixbuf_to_cairo_surface (GdkPixbuf *pixbuf)
 | 
			
		||||
{
 | 
			
		||||
  cairo_surface_t *dummy_surface;
 | 
			
		||||
  cairo_pattern_t *pattern;
 | 
			
		||||
  cairo_surface_t *surface;
 | 
			
		||||
  cairo_t *cr;
 | 
			
		||||
 | 
			
		||||
  dummy_surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 1, 1);
 | 
			
		||||
 | 
			
		||||
  cr = cairo_create (dummy_surface);
 | 
			
		||||
  gdk_cairo_set_source_pixbuf (cr, pixbuf, 0, 0);
 | 
			
		||||
  pattern = cairo_get_source (cr);
 | 
			
		||||
  cairo_pattern_get_surface (pattern, &surface);
 | 
			
		||||
  cairo_surface_reference (surface);
 | 
			
		||||
  cairo_destroy (cr);
 | 
			
		||||
  cairo_surface_destroy (dummy_surface);
 | 
			
		||||
 | 
			
		||||
  return surface;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
eek_gtk_renderer_real_render_key_icon (EekRenderer *self,
 | 
			
		||||
                                       cairo_t     *cr,
 | 
			
		||||
                                       EekKey      *key,
 | 
			
		||||
                                       gdouble      scale,
 | 
			
		||||
                                       gboolean     rotate)
 | 
			
		||||
{
 | 
			
		||||
    EekBounds bounds;
 | 
			
		||||
    EekSymbol *symbol;
 | 
			
		||||
    const gchar *icon_name;
 | 
			
		||||
    GdkPixbuf *pixbuf;
 | 
			
		||||
    cairo_surface_t *surface;
 | 
			
		||||
    GError *error;
 | 
			
		||||
    gint width, height;
 | 
			
		||||
 | 
			
		||||
    symbol = eek_key_get_symbol_with_fallback (key, 0, 0);
 | 
			
		||||
    g_return_if_fail (symbol);
 | 
			
		||||
 | 
			
		||||
    icon_name = eek_symbol_get_icon_name (symbol);
 | 
			
		||||
    g_return_if_fail (icon_name);
 | 
			
		||||
 | 
			
		||||
    eek_element_get_bounds (EEK_ELEMENT(key), &bounds);
 | 
			
		||||
    bounds.width *= scale;
 | 
			
		||||
    bounds.height *= scale;
 | 
			
		||||
 | 
			
		||||
    error = NULL;
 | 
			
		||||
    pixbuf = gtk_icon_theme_load_icon (gtk_icon_theme_get_default (),
 | 
			
		||||
                                       icon_name,
 | 
			
		||||
                                       MIN(bounds.width, bounds.height),
 | 
			
		||||
                                       0,
 | 
			
		||||
                                       &error);
 | 
			
		||||
    g_return_if_fail (pixbuf);
 | 
			
		||||
 | 
			
		||||
    width = gdk_pixbuf_get_width (pixbuf);
 | 
			
		||||
    height = gdk_pixbuf_get_height (pixbuf);
 | 
			
		||||
 | 
			
		||||
    if (bounds.width * height < bounds.height * width)
 | 
			
		||||
        scale = bounds.width / width;
 | 
			
		||||
    else
 | 
			
		||||
        scale = bounds.height / height;
 | 
			
		||||
 | 
			
		||||
    cairo_save (cr);
 | 
			
		||||
    cairo_translate (cr,
 | 
			
		||||
                     (bounds.width - width * scale) / 2,
 | 
			
		||||
                     (bounds.height - height * scale) / 2);
 | 
			
		||||
 | 
			
		||||
    eek_renderer_apply_transformation_for_key (self, cr, key, scale, rotate);
 | 
			
		||||
    surface = pixbuf_to_cairo_surface (pixbuf);
 | 
			
		||||
    g_object_unref (pixbuf);
 | 
			
		||||
    cairo_set_source_surface (cr, surface, 0.0, 0.0);
 | 
			
		||||
    cairo_paint (cr);
 | 
			
		||||
    cairo_restore (cr);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
eek_gtk_renderer_class_init (EekGtkRendererClass *klass)
 | 
			
		||||
{
 | 
			
		||||
    EekRendererClass *renderer_class = EEK_RENDERER_CLASS (klass);
 | 
			
		||||
 | 
			
		||||
    renderer_class->render_key_icon = eek_gtk_renderer_real_render_key_icon;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
eek_gtk_renderer_init (EekGtkRenderer *self)
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
EekRenderer *
 | 
			
		||||
eek_gtk_renderer_new (EekKeyboard  *keyboard,
 | 
			
		||||
                      PangoContext *pcontext,
 | 
			
		||||
                      GtkWidget    *widget)
 | 
			
		||||
{
 | 
			
		||||
    EekRenderer *renderer;
 | 
			
		||||
 | 
			
		||||
    renderer = g_object_new (EEK_TYPE_GTK_RENDERER,
 | 
			
		||||
                             "keyboard", keyboard,
 | 
			
		||||
                             "pango-context", pcontext,
 | 
			
		||||
                             NULL);
 | 
			
		||||
 | 
			
		||||
    return renderer;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										61
									
								
								eek/eek-gtk-renderer.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										61
									
								
								eek/eek-gtk-renderer.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,61 @@
 | 
			
		||||
/* 
 | 
			
		||||
 * Copyright (C) 2010-2011 Daiki Ueno <ueno@unixuser.org>
 | 
			
		||||
 * Copyright (C) 2010-2011 Red Hat, Inc.
 | 
			
		||||
 * 
 | 
			
		||||
 * This library is free software; you can redistribute it and/or
 | 
			
		||||
 * modify it under the terms of the GNU Lesser General Public License
 | 
			
		||||
 * as published by the Free Software Foundation; either version 2 of
 | 
			
		||||
 * the License, or (at your option) any later version.
 | 
			
		||||
 * 
 | 
			
		||||
 * This library is distributed in the hope that it will be useful, but
 | 
			
		||||
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
			
		||||
 * Lesser General Public License for more details.
 | 
			
		||||
 * 
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General Public
 | 
			
		||||
 * License along with this library; if not, write to the Free Software
 | 
			
		||||
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 | 
			
		||||
 * 02110-1301 USA
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef EEK_GTK_RENDERER_H
 | 
			
		||||
#define EEK_GTK_RENDERER_H 1
 | 
			
		||||
 | 
			
		||||
#include <gtk/gtk.h>
 | 
			
		||||
#include "eek-renderer.h"
 | 
			
		||||
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
#define EEK_TYPE_GTK_RENDERER (eek_gtk_renderer_get_type())
 | 
			
		||||
#define EEK_GTK_RENDERER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EEK_TYPE_GTK_RENDERER, EekGtkRenderer))
 | 
			
		||||
#define EEK_GTK_RENDERER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EEK_TYPE_GTK_RENDERER, EekGtkRendererClass))
 | 
			
		||||
#define EEK_IS_GTK_RENDERER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EEK_TYPE_GTK_RENDERER))
 | 
			
		||||
#define EEK_IS_GTK_RENDERER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EEK_TYPE_GTK_RENDERER))
 | 
			
		||||
#define EEK_GTK_RENDERER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EEK_TYPE_GTK_RENDERER, EekGtkRendererClass))
 | 
			
		||||
 | 
			
		||||
typedef struct _EekGtkRenderer EekGtkRenderer;
 | 
			
		||||
typedef struct _EekGtkRendererClass EekGtkRendererClass;
 | 
			
		||||
typedef struct _EekGtkRendererPrivate EekGtkRendererPrivate;
 | 
			
		||||
 | 
			
		||||
struct _EekGtkRenderer {
 | 
			
		||||
    EekRenderer parent;
 | 
			
		||||
 | 
			
		||||
    EekGtkRendererPrivate *priv;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct _EekGtkRendererClass
 | 
			
		||||
{
 | 
			
		||||
    EekRendererClass parent_class;
 | 
			
		||||
 | 
			
		||||
    /*< private >*/
 | 
			
		||||
    /* padding */
 | 
			
		||||
    gpointer pdummy[24];
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
GType        eek_gtk_renderer_get_type (void) G_GNUC_CONST;
 | 
			
		||||
EekRenderer *eek_gtk_renderer_new      (EekKeyboard  *keyboard,
 | 
			
		||||
                                        PangoContext *pcontext,
 | 
			
		||||
                                        GtkWidget *widget);
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
#endif  /* EEK_GTK_RENDERER_H */
 | 
			
		||||
@ -25,15 +25,16 @@
 | 
			
		||||
 * The #EekKeyClass class represents a key.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_CONFIG_H
 | 
			
		||||
#include "config.h"
 | 
			
		||||
#endif  /* HAVE_CONFIG_H */
 | 
			
		||||
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#define DEBUG 0
 | 
			
		||||
#if DEBUG
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_CONFIG_H
 | 
			
		||||
#include "config.h"
 | 
			
		||||
#endif  /* HAVE_CONFIG_H */
 | 
			
		||||
#include "eek-key.h"
 | 
			
		||||
#include "eek-section.h"
 | 
			
		||||
#include "eek-keyboard.h"
 | 
			
		||||
@ -157,6 +158,7 @@ eek_key_real_deserialize (EekSerializable *self,
 | 
			
		||||
 | 
			
		||||
    g_variant_get_child (variant, index++, "u", &priv->keycode);
 | 
			
		||||
    g_variant_get_child (variant, index++, "v", &symbol_matrix);
 | 
			
		||||
    eek_symbol_matrix_free (priv->symbol_matrix);
 | 
			
		||||
    priv->symbol_matrix = _g_variant_get_symbol_matrix (symbol_matrix);
 | 
			
		||||
    g_variant_get_child (variant, index++, "i", &priv->column);
 | 
			
		||||
    g_variant_get_child (variant, index++, "i", &priv->row);
 | 
			
		||||
@ -446,10 +448,12 @@ eek_key_class_init (EekKeyClass *klass)
 | 
			
		||||
     * @key: an #EekKey
 | 
			
		||||
     *
 | 
			
		||||
     * The ::pressed signal is emitted each time @key is shifted to
 | 
			
		||||
     * the pressed state.
 | 
			
		||||
     * 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 ("pressed",
 | 
			
		||||
        g_signal_new (I_("pressed"),
 | 
			
		||||
                      G_TYPE_FROM_CLASS(gobject_class),
 | 
			
		||||
                      G_SIGNAL_RUN_FIRST,
 | 
			
		||||
                      G_STRUCT_OFFSET(EekKeyClass, pressed),
 | 
			
		||||
@ -466,9 +470,9 @@ eek_key_class_init (EekKeyClass *klass)
 | 
			
		||||
     * the released state.
 | 
			
		||||
     */
 | 
			
		||||
   signals[RELEASED] =
 | 
			
		||||
        g_signal_new ("released",
 | 
			
		||||
        g_signal_new (I_("released"),
 | 
			
		||||
                      G_TYPE_FROM_CLASS(gobject_class),
 | 
			
		||||
                      G_SIGNAL_RUN_FIRST,
 | 
			
		||||
                      G_SIGNAL_RUN_LAST,
 | 
			
		||||
                      G_STRUCT_OFFSET(EekKeyClass, released),
 | 
			
		||||
                      NULL,
 | 
			
		||||
                      NULL,
 | 
			
		||||
@ -550,20 +554,6 @@ eek_key_get_symbol_matrix (EekKey *key)
 | 
			
		||||
    return EEK_KEY_GET_CLASS(key)->get_symbol_matrix (key);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static EekKeyboard *
 | 
			
		||||
get_keyboard (EekKey *key)
 | 
			
		||||
{
 | 
			
		||||
    EekElement *parent;
 | 
			
		||||
 | 
			
		||||
    parent = eek_element_get_parent (EEK_ELEMENT(key));
 | 
			
		||||
    g_return_val_if_fail (EEK_IS_SECTION(parent), NULL);
 | 
			
		||||
 | 
			
		||||
    parent = eek_element_get_parent (parent);
 | 
			
		||||
    g_return_val_if_fail (EEK_IS_KEYBOARD(parent), NULL);
 | 
			
		||||
 | 
			
		||||
    return EEK_KEYBOARD(parent);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eek_key_get_symbol:
 | 
			
		||||
 * @key: an #EekKey
 | 
			
		||||
@ -592,14 +582,38 @@ eek_key_get_symbol_with_fallback (EekKey *key,
 | 
			
		||||
                                  gint    fallback_level)
 | 
			
		||||
{
 | 
			
		||||
    gint group, level;
 | 
			
		||||
    EekKeyboard *keyboard;
 | 
			
		||||
 | 
			
		||||
    g_return_val_if_fail (EEK_IS_KEY (key), NULL);
 | 
			
		||||
    g_return_val_if_fail (fallback_group >= 0, NULL);
 | 
			
		||||
    g_return_val_if_fail (fallback_level >= 0, NULL);
 | 
			
		||||
 | 
			
		||||
    keyboard = get_keyboard (key);
 | 
			
		||||
    g_return_val_if_fail (keyboard, NULL);
 | 
			
		||||
    eek_element_get_symbol_index (EEK_ELEMENT(key), &group, &level);
 | 
			
		||||
 | 
			
		||||
    if (group < 0 || level < 0) {
 | 
			
		||||
        EekElement *section;
 | 
			
		||||
 | 
			
		||||
        section = eek_element_get_parent (EEK_ELEMENT(key));
 | 
			
		||||
        g_return_val_if_fail (EEK_IS_SECTION (section), NULL);
 | 
			
		||||
 | 
			
		||||
        if (group < 0)
 | 
			
		||||
            group = eek_element_get_group (section);
 | 
			
		||||
 | 
			
		||||
        if (level < 0)
 | 
			
		||||
            level = eek_element_get_level (section);
 | 
			
		||||
 | 
			
		||||
        if (group < 0 || level < 0) {
 | 
			
		||||
            EekElement *keyboard;
 | 
			
		||||
 | 
			
		||||
            keyboard = eek_element_get_parent (section);
 | 
			
		||||
            g_return_val_if_fail (EEK_IS_KEYBOARD (keyboard), NULL);
 | 
			
		||||
 | 
			
		||||
            if (group < 0)
 | 
			
		||||
                group = eek_element_get_group (keyboard);
 | 
			
		||||
            if (level < 0)
 | 
			
		||||
                level = eek_element_get_level (keyboard);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    eek_keyboard_get_symbol_index (keyboard, &group, &level);
 | 
			
		||||
    return eek_key_get_symbol_at_index (key,
 | 
			
		||||
                                        group,
 | 
			
		||||
                                        level,
 | 
			
		||||
@ -628,8 +642,13 @@ eek_key_get_symbol_at_index (EekKey *key,
 | 
			
		||||
    EekKeyPrivate *priv = EEK_KEY_GET_PRIVATE(key);
 | 
			
		||||
    gint num_symbols;
 | 
			
		||||
 | 
			
		||||
    g_return_val_if_fail (group >= 0, NULL);
 | 
			
		||||
    g_return_val_if_fail (level >= 0, NULL);
 | 
			
		||||
    g_return_val_if_fail (fallback_group >= 0, NULL);
 | 
			
		||||
    g_return_val_if_fail (fallback_level >= 0, NULL);
 | 
			
		||||
 | 
			
		||||
    if (group < 0)
 | 
			
		||||
        group = fallback_group;
 | 
			
		||||
    if (level < 0)
 | 
			
		||||
        level = fallback_level;
 | 
			
		||||
 | 
			
		||||
    if (!priv->symbol_matrix)
 | 
			
		||||
        return NULL;
 | 
			
		||||
 | 
			
		||||
@ -17,13 +17,13 @@
 | 
			
		||||
 * Boston, MA 02111-1307, USA.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <math.h>
 | 
			
		||||
#include <pango/pangocairo.h>
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_CONFIG_H
 | 
			
		||||
#include "config.h"
 | 
			
		||||
#endif  /* HAVE_CONFIG_H */
 | 
			
		||||
 | 
			
		||||
#include <math.h>
 | 
			
		||||
#include <pango/pangocairo.h>
 | 
			
		||||
 | 
			
		||||
#include "eek-types.h"
 | 
			
		||||
 | 
			
		||||
static gdouble
 | 
			
		||||
 | 
			
		||||
@ -35,13 +35,10 @@
 | 
			
		||||
#include "eek-section.h"
 | 
			
		||||
#include "eek-key.h"
 | 
			
		||||
#include "eek-symbol.h"
 | 
			
		||||
#include "eek-marshalers.h"
 | 
			
		||||
#include "eek-serializable.h"
 | 
			
		||||
 | 
			
		||||
enum {
 | 
			
		||||
    PROP_0,
 | 
			
		||||
    PROP_GROUP,
 | 
			
		||||
    PROP_LEVEL,
 | 
			
		||||
    PROP_LAYOUT,
 | 
			
		||||
    PROP_MODIFIER_BEHAVIOR,
 | 
			
		||||
    PROP_LAST
 | 
			
		||||
@ -50,7 +47,6 @@ enum {
 | 
			
		||||
enum {
 | 
			
		||||
    KEY_PRESSED,
 | 
			
		||||
    KEY_RELEASED,
 | 
			
		||||
    SYMBOL_INDEX_CHANGED,
 | 
			
		||||
    LAST_SIGNAL
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
@ -68,12 +64,14 @@ G_DEFINE_TYPE_WITH_CODE (EekKeyboard, eek_keyboard, EEK_TYPE_CONTAINER,
 | 
			
		||||
 | 
			
		||||
struct _EekKeyboardPrivate
 | 
			
		||||
{
 | 
			
		||||
    gint group;
 | 
			
		||||
    gint level;
 | 
			
		||||
    EekLayout *layout;
 | 
			
		||||
    EekModifierBehavior modifier_behavior;
 | 
			
		||||
    EekModifierType modifiers;
 | 
			
		||||
    GArray *outline_array;
 | 
			
		||||
 | 
			
		||||
    /* modifiers dynamically assigned at run time */
 | 
			
		||||
    EekModifierType num_lock_mask;
 | 
			
		||||
    EekModifierType alt_gr_mask;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static EekSerializableIface *eek_keyboard_parent_serializable_iface;
 | 
			
		||||
@ -148,6 +146,7 @@ eek_keyboard_real_serialize (EekSerializable *self,
 | 
			
		||||
                               _g_variant_new_outline (outline));
 | 
			
		||||
    }
 | 
			
		||||
    g_variant_builder_add (builder, "v", g_variant_builder_end (&array));
 | 
			
		||||
    g_variant_builder_add (builder, "u", priv->num_lock_mask);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gsize
 | 
			
		||||
@ -169,7 +168,10 @@ eek_keyboard_real_deserialize (EekSerializable *self,
 | 
			
		||||
    while (g_variant_iter_next (&iter, "v", &outline)) {
 | 
			
		||||
        EekOutline *_outline = _g_variant_get_outline (outline);
 | 
			
		||||
        g_array_append_val (priv->outline_array, *_outline);
 | 
			
		||||
        /* don't use eek_outline_free here, so as to keep _outline->points */
 | 
			
		||||
        g_slice_free (EekOutline, _outline);
 | 
			
		||||
    }
 | 
			
		||||
    g_variant_get_child (variant, index++, "u", &priv->num_lock_mask);
 | 
			
		||||
 | 
			
		||||
    return index;
 | 
			
		||||
}
 | 
			
		||||
@ -184,35 +186,6 @@ eek_serializable_iface_init (EekSerializableIface *iface)
 | 
			
		||||
    iface->deserialize = eek_keyboard_real_deserialize;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
eek_keyboard_real_set_symbol_index (EekKeyboard *self,
 | 
			
		||||
                                    gint         group,
 | 
			
		||||
                                    gint         level)
 | 
			
		||||
{
 | 
			
		||||
    EekKeyboardPrivate *priv = EEK_KEYBOARD_GET_PRIVATE(self);
 | 
			
		||||
 | 
			
		||||
    if (priv->group != group || priv->level != level) {
 | 
			
		||||
        priv->group = group;
 | 
			
		||||
        priv->level = level;
 | 
			
		||||
 | 
			
		||||
        g_signal_emit_by_name (self, "symbol-index-changed", group, level);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
eek_keyboard_real_get_symbol_index (EekKeyboard *self,
 | 
			
		||||
                                    gint        *group,
 | 
			
		||||
                                    gint        *level)
 | 
			
		||||
{
 | 
			
		||||
    EekKeyboardPrivate *priv = EEK_KEYBOARD_GET_PRIVATE(self);
 | 
			
		||||
 | 
			
		||||
    g_return_if_fail (group || level);
 | 
			
		||||
    if (group)
 | 
			
		||||
        *group = priv->group;
 | 
			
		||||
    if (level)
 | 
			
		||||
        *level = priv->level;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
on_key_pressed (EekSection  *section,
 | 
			
		||||
                EekKey      *key,
 | 
			
		||||
@ -229,6 +202,15 @@ on_key_released (EekSection  *section,
 | 
			
		||||
    g_signal_emit_by_name (keyboard, "key-released", key);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
on_symbol_index_changed (EekSection *section,
 | 
			
		||||
                         gint group,
 | 
			
		||||
                         gint level,
 | 
			
		||||
                         EekKeyboard *keyboard)
 | 
			
		||||
{
 | 
			
		||||
    g_signal_emit_by_name (keyboard, "symbol-index-changed", group, level);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static EekSection *
 | 
			
		||||
eek_keyboard_real_create_section (EekKeyboard *self)
 | 
			
		||||
{
 | 
			
		||||
@ -283,12 +265,6 @@ eek_keyboard_set_property (GObject      *object,
 | 
			
		||||
    EekKeyboardPrivate *priv = EEK_KEYBOARD_GET_PRIVATE(object);
 | 
			
		||||
 | 
			
		||||
    switch (prop_id) {
 | 
			
		||||
    case PROP_GROUP:
 | 
			
		||||
        eek_keyboard_set_group (EEK_KEYBOARD(object), g_value_get_int (value));
 | 
			
		||||
        break;
 | 
			
		||||
    case PROP_LEVEL:
 | 
			
		||||
        eek_keyboard_set_level (EEK_KEYBOARD(object), g_value_get_int (value));
 | 
			
		||||
        break;
 | 
			
		||||
    case PROP_LAYOUT:
 | 
			
		||||
        priv->layout = g_value_get_object (value);
 | 
			
		||||
        if (priv->layout)
 | 
			
		||||
@ -315,14 +291,6 @@ eek_keyboard_get_property (GObject    *object,
 | 
			
		||||
    EekKeyboardPrivate *priv = EEK_KEYBOARD_GET_PRIVATE(object);
 | 
			
		||||
 | 
			
		||||
    switch (prop_id) {
 | 
			
		||||
    case PROP_GROUP:
 | 
			
		||||
        g_value_set_int (value,
 | 
			
		||||
                         eek_keyboard_get_group (EEK_KEYBOARD(object)));
 | 
			
		||||
        break;
 | 
			
		||||
    case PROP_LEVEL:
 | 
			
		||||
        g_value_set_int (value,
 | 
			
		||||
                         eek_keyboard_get_level (EEK_KEYBOARD(object)));
 | 
			
		||||
        break;
 | 
			
		||||
    case PROP_LAYOUT:
 | 
			
		||||
        g_value_set_object (value, priv->layout);
 | 
			
		||||
        break;
 | 
			
		||||
@ -338,25 +306,17 @@ eek_keyboard_get_property (GObject    *object,
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
eek_keyboard_real_symbol_index_changed (EekKeyboard *self,
 | 
			
		||||
                                        gint         group,
 | 
			
		||||
                                        gint         level)
 | 
			
		||||
{
 | 
			
		||||
    /* g_debug ("symbol-index-changed"); */
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
set_level_from_modifiers (EekKeyboard *self)
 | 
			
		||||
{
 | 
			
		||||
    EekKeyboardPrivate *priv = EEK_KEYBOARD_GET_PRIVATE(self);
 | 
			
		||||
    guint level = 0;
 | 
			
		||||
    gint level = 0;
 | 
			
		||||
 | 
			
		||||
    if (priv->modifiers & EEK_MOD5_MASK)
 | 
			
		||||
    if (priv->modifiers & priv->alt_gr_mask)
 | 
			
		||||
        level |= 2;
 | 
			
		||||
    if (priv->modifiers & EEK_SHIFT_MASK)
 | 
			
		||||
        level |= 1;
 | 
			
		||||
    eek_keyboard_set_level (self, level);
 | 
			
		||||
    eek_element_set_level (EEK_ELEMENT(self), level);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
@ -367,27 +327,15 @@ eek_keyboard_real_key_pressed (EekKeyboard *self,
 | 
			
		||||
    EekSymbol *symbol;
 | 
			
		||||
    EekModifierType modifier;
 | 
			
		||||
 | 
			
		||||
    symbol = eek_key_get_symbol_at_index (key,
 | 
			
		||||
                                          priv->group,
 | 
			
		||||
                                          priv->level,
 | 
			
		||||
                                          0,
 | 
			
		||||
                                          0);
 | 
			
		||||
    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:
 | 
			
		||||
    if (priv->modifier_behavior == EEK_MODIFIER_BEHAVIOR_NONE) {
 | 
			
		||||
        priv->modifiers |= modifier;
 | 
			
		||||
        break;
 | 
			
		||||
    case EEK_MODIFIER_BEHAVIOR_LOCK:
 | 
			
		||||
        priv->modifiers ^= modifier;
 | 
			
		||||
        break;
 | 
			
		||||
    case EEK_MODIFIER_BEHAVIOR_LATCH:
 | 
			
		||||
        priv->modifiers = (priv->modifiers ^ modifier) & modifier;
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
        set_level_from_modifiers (self);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
@ -398,18 +346,21 @@ eek_keyboard_real_key_released (EekKeyboard *self,
 | 
			
		||||
    EekSymbol *symbol;
 | 
			
		||||
    EekModifierType modifier;
 | 
			
		||||
 | 
			
		||||
    symbol = eek_key_get_symbol_at_index (key,
 | 
			
		||||
                                          priv->group,
 | 
			
		||||
                                          priv->level,
 | 
			
		||||
                                          0,
 | 
			
		||||
                                          0);
 | 
			
		||||
    symbol = eek_key_get_symbol_with_fallback (key, 0, 0);
 | 
			
		||||
    if (!symbol)
 | 
			
		||||
        return;
 | 
			
		||||
 | 
			
		||||
    modifier = eek_symbol_get_modifier_mask (symbol);
 | 
			
		||||
    if (modifier != 0) {
 | 
			
		||||
        if (priv->modifier_behavior == EEK_MODIFIER_BEHAVIOR_NONE)
 | 
			
		||||
    switch (priv->modifier_behavior) {
 | 
			
		||||
    case EEK_MODIFIER_BEHAVIOR_NONE:
 | 
			
		||||
        priv->modifiers &= ~modifier;
 | 
			
		||||
        break;
 | 
			
		||||
    case EEK_MODIFIER_BEHAVIOR_LOCK:
 | 
			
		||||
        priv->modifiers ^= modifier;
 | 
			
		||||
        break;
 | 
			
		||||
    case EEK_MODIFIER_BEHAVIOR_LATCH:
 | 
			
		||||
        priv->modifiers = (priv->modifiers ^ modifier) & modifier;
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
    set_level_from_modifiers (self);
 | 
			
		||||
}
 | 
			
		||||
@ -453,6 +404,8 @@ eek_keyboard_real_child_added (EekContainer *self,
 | 
			
		||||
                      G_CALLBACK(on_key_pressed), self);
 | 
			
		||||
    g_signal_connect (element, "key-released",
 | 
			
		||||
                      G_CALLBACK(on_key_released), self);
 | 
			
		||||
    g_signal_connect (element, "symbol-index-changed",
 | 
			
		||||
                      G_CALLBACK(on_symbol_index_changed), self);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
@ -473,15 +426,12 @@ eek_keyboard_class_init (EekKeyboardClass *klass)
 | 
			
		||||
    g_type_class_add_private (gobject_class,
 | 
			
		||||
                              sizeof (EekKeyboardPrivate));
 | 
			
		||||
 | 
			
		||||
    klass->set_symbol_index = eek_keyboard_real_set_symbol_index;
 | 
			
		||||
    klass->get_symbol_index = eek_keyboard_real_get_symbol_index;
 | 
			
		||||
    klass->create_section = eek_keyboard_real_create_section;
 | 
			
		||||
    klass->find_key_by_keycode = eek_keyboard_real_find_key_by_keycode;
 | 
			
		||||
 | 
			
		||||
    /* signals */
 | 
			
		||||
    klass->key_pressed = eek_keyboard_real_key_pressed;
 | 
			
		||||
    klass->key_released = eek_keyboard_real_key_released;
 | 
			
		||||
    klass->symbol_index_changed = eek_keyboard_real_symbol_index_changed;
 | 
			
		||||
 | 
			
		||||
    container_class->child_added = eek_keyboard_real_child_added;
 | 
			
		||||
    container_class->child_removed = eek_keyboard_real_child_removed;
 | 
			
		||||
@ -491,34 +441,6 @@ eek_keyboard_class_init (EekKeyboardClass *klass)
 | 
			
		||||
    gobject_class->dispose = eek_keyboard_dispose;
 | 
			
		||||
    gobject_class->finalize = eek_keyboard_finalize;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * EekKeyboard:group:
 | 
			
		||||
     *
 | 
			
		||||
     * The group (row) index of symbol matrix of #EekKeyboard.
 | 
			
		||||
     */
 | 
			
		||||
    pspec = g_param_spec_int ("group",
 | 
			
		||||
                              "Group",
 | 
			
		||||
                              "Group index of symbol matrix of the keyboard",
 | 
			
		||||
                              0, G_MAXINT, 0,
 | 
			
		||||
                              G_PARAM_READWRITE);
 | 
			
		||||
    g_object_class_install_property (gobject_class,
 | 
			
		||||
                                     PROP_GROUP,
 | 
			
		||||
                                     pspec);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * EekKeyboard:level:
 | 
			
		||||
     *
 | 
			
		||||
     * The level (row) index of symbol matrix of #EekKeyboard.
 | 
			
		||||
     */
 | 
			
		||||
    pspec = g_param_spec_int ("level",
 | 
			
		||||
                              "Level",
 | 
			
		||||
                              "Level index of symbol matrix of the keyboard",
 | 
			
		||||
                              0, G_MAXINT, 0,
 | 
			
		||||
                              G_PARAM_READWRITE);
 | 
			
		||||
    g_object_class_install_property (gobject_class,
 | 
			
		||||
                                     PROP_LEVEL,
 | 
			
		||||
                                     pspec);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * EekKeyboard:layout:
 | 
			
		||||
     *
 | 
			
		||||
@ -556,7 +478,7 @@ eek_keyboard_class_init (EekKeyboardClass *klass)
 | 
			
		||||
     * is shifted to the pressed state.
 | 
			
		||||
     */
 | 
			
		||||
    signals[KEY_PRESSED] =
 | 
			
		||||
        g_signal_new ("key-pressed",
 | 
			
		||||
        g_signal_new (I_("key-pressed"),
 | 
			
		||||
                      G_TYPE_FROM_CLASS(gobject_class),
 | 
			
		||||
                      G_SIGNAL_RUN_LAST,
 | 
			
		||||
                      G_STRUCT_OFFSET(EekKeyboardClass, key_pressed),
 | 
			
		||||
@ -576,7 +498,7 @@ eek_keyboard_class_init (EekKeyboardClass *klass)
 | 
			
		||||
     * is shifted to the released state.
 | 
			
		||||
     */
 | 
			
		||||
    signals[KEY_RELEASED] =
 | 
			
		||||
        g_signal_new ("key-released",
 | 
			
		||||
        g_signal_new (I_("key-released"),
 | 
			
		||||
                      G_TYPE_FROM_CLASS(gobject_class),
 | 
			
		||||
                      G_SIGNAL_RUN_LAST,
 | 
			
		||||
                      G_STRUCT_OFFSET(EekKeyboardClass, key_released),
 | 
			
		||||
@ -586,28 +508,6 @@ eek_keyboard_class_init (EekKeyboardClass *klass)
 | 
			
		||||
                      G_TYPE_NONE,
 | 
			
		||||
                      1,
 | 
			
		||||
                      EEK_TYPE_KEY);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * EekKeyboard::symbol-index-changed:
 | 
			
		||||
     * @keyboard: an #EekKeyboard
 | 
			
		||||
     * @group: row index of the symbol matrix of keys on @keyboard
 | 
			
		||||
     * @level: column index of the symbol matrix of keys on @keyboard
 | 
			
		||||
     *
 | 
			
		||||
     * The ::symbol-index-changed signal is emitted each time the
 | 
			
		||||
     * global configuration of group/level index changes.
 | 
			
		||||
     */
 | 
			
		||||
    signals[SYMBOL_INDEX_CHANGED] =
 | 
			
		||||
        g_signal_new ("symbol-index-changed",
 | 
			
		||||
                      G_TYPE_FROM_CLASS(gobject_class),
 | 
			
		||||
                      G_SIGNAL_RUN_LAST,
 | 
			
		||||
                      G_STRUCT_OFFSET(EekKeyboardClass, symbol_index_changed),
 | 
			
		||||
                      NULL,
 | 
			
		||||
                      NULL,
 | 
			
		||||
                      _eek_marshal_VOID__INT_INT,
 | 
			
		||||
                      G_TYPE_NONE,
 | 
			
		||||
                      2,
 | 
			
		||||
                      G_TYPE_INT,
 | 
			
		||||
                      G_TYPE_INT);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
@ -616,11 +516,12 @@ eek_keyboard_init (EekKeyboard *self)
 | 
			
		||||
    EekKeyboardPrivate *priv;
 | 
			
		||||
 | 
			
		||||
    priv = self->priv = EEK_KEYBOARD_GET_PRIVATE(self);
 | 
			
		||||
    priv->group = priv->level = 0;
 | 
			
		||||
    priv->layout = NULL;
 | 
			
		||||
    priv->modifier_behavior = EEK_MODIFIER_BEHAVIOR_NONE;
 | 
			
		||||
    priv->modifiers = 0;
 | 
			
		||||
    priv->outline_array = g_array_new (FALSE, TRUE, sizeof (EekOutline));
 | 
			
		||||
    priv->num_lock_mask = 0;
 | 
			
		||||
    eek_element_set_symbol_index (EEK_ELEMENT(self), 0, 0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@ -629,7 +530,10 @@ eek_keyboard_init (EekKeyboard *self)
 | 
			
		||||
 * @group: row index of the symbol matrix of keys on @keyboard
 | 
			
		||||
 * @level: column index of the symbol matrix of keys on @keyboard
 | 
			
		||||
 *
 | 
			
		||||
 * Select a cell of the symbol matrix of each key on @keyboard.
 | 
			
		||||
 * Set the default index of the symbol matrices of keys in @keyboard.
 | 
			
		||||
 * To unset, pass -1 as group/level.
 | 
			
		||||
 *
 | 
			
		||||
 * Deprecated: 1.0: Use eek_element_set_symbol_index()
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
eek_keyboard_set_symbol_index (EekKeyboard *keyboard,
 | 
			
		||||
@ -637,18 +541,19 @@ eek_keyboard_set_symbol_index (EekKeyboard *keyboard,
 | 
			
		||||
                               gint         level)
 | 
			
		||||
{
 | 
			
		||||
    g_return_if_fail (EEK_IS_KEYBOARD(keyboard));
 | 
			
		||||
    EEK_KEYBOARD_GET_CLASS(keyboard)->set_symbol_index (keyboard, group, level);
 | 
			
		||||
    eek_element_set_symbol_index (EEK_ELEMENT(keyboard), group, level);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eek_keyboard_get_symbol_index:
 | 
			
		||||
 * @keyboard: an #EekKeyboard
 | 
			
		||||
 * @group: a pointer where row index of the symbol matrix of keys on
 | 
			
		||||
 * @keyboard will be stored
 | 
			
		||||
 * @level: a pointer where column index of the symbol matrix of keys
 | 
			
		||||
 * on @keyboard will be stored
 | 
			
		||||
 * @group: a pointer where the group value of the symbol index will be stored
 | 
			
		||||
 * @level: a pointer where the level value of the symbol index will be stored
 | 
			
		||||
 *
 | 
			
		||||
 * Get the current cell position of the symbol matrix of each key on @keyboard.
 | 
			
		||||
 * Get the default index of the symbol matrices of keys in @keyboard.
 | 
			
		||||
 * If the index is not set, -1 will be returned.
 | 
			
		||||
 *
 | 
			
		||||
 * Deprecated: 1.0: Use eek_element_get_symbol_index()
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
eek_keyboard_get_symbol_index (EekKeyboard *keyboard,
 | 
			
		||||
@ -656,7 +561,7 @@ eek_keyboard_get_symbol_index (EekKeyboard *keyboard,
 | 
			
		||||
                               gint        *level)
 | 
			
		||||
{
 | 
			
		||||
    g_return_if_fail (EEK_IS_KEYBOARD(keyboard));
 | 
			
		||||
    EEK_KEYBOARD_GET_CLASS(keyboard)->get_symbol_index (keyboard, group, level);
 | 
			
		||||
    eek_element_get_symbol_index(EEK_ELEMENT(keyboard), group, level);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@ -664,14 +569,17 @@ eek_keyboard_get_symbol_index (EekKeyboard *keyboard,
 | 
			
		||||
 * @keyboard: an #EekKeyboard
 | 
			
		||||
 * @group: group index of @keyboard
 | 
			
		||||
 *
 | 
			
		||||
 * Set the group index of symbol matrix of @keyboard.
 | 
			
		||||
 * Set the group value of the default symbol index of @keyboard.  To
 | 
			
		||||
 * unset, pass -1 as @group.
 | 
			
		||||
 *
 | 
			
		||||
 * See also: eek_keyboard_set_symbol_index()
 | 
			
		||||
 * Deprecated: 1.0: Use eek_element_set_group()
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
eek_keyboard_set_group (EekKeyboard *keyboard,
 | 
			
		||||
                        gint         group)
 | 
			
		||||
{
 | 
			
		||||
    gint level = eek_keyboard_get_level (keyboard);
 | 
			
		||||
    eek_keyboard_set_symbol_index (keyboard, group, level);
 | 
			
		||||
    eek_element_set_group (EEK_ELEMENT(keyboard), group);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@ -679,42 +587,49 @@ eek_keyboard_set_group (EekKeyboard *keyboard,
 | 
			
		||||
 * @keyboard: an #EekKeyboard
 | 
			
		||||
 * @level: level index of @keyboard
 | 
			
		||||
 *
 | 
			
		||||
 * Set the level index of symbol matrix of @keyboard.
 | 
			
		||||
 * Set the level value of the default symbol index of @keyboard.  To
 | 
			
		||||
 * unset, pass -1 as @level.
 | 
			
		||||
 *
 | 
			
		||||
 * See also: eek_keyboard_set_symbol_index()
 | 
			
		||||
 * Deprecated: 1.0: Use eek_element_set_level()
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
eek_keyboard_set_level (EekKeyboard *keyboard,
 | 
			
		||||
                        gint         level)
 | 
			
		||||
{
 | 
			
		||||
    gint group = eek_keyboard_get_group (keyboard);
 | 
			
		||||
    eek_keyboard_set_symbol_index (keyboard, group, level);
 | 
			
		||||
    eek_element_set_level (EEK_ELEMENT(keyboard), level);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eek_keyboard_get_group:
 | 
			
		||||
 * @keyboard: an #EekKeyboard
 | 
			
		||||
 *
 | 
			
		||||
 * Return the group index of @keyboard.
 | 
			
		||||
 * Return the group value of the default symbol index of @keyboard.
 | 
			
		||||
 * If the value is not set, -1 will be returned.
 | 
			
		||||
 *
 | 
			
		||||
 * See also: eek_keyboard_get_symbol_index()
 | 
			
		||||
 * Deprecated: 1.0: Use eek_element_get_group()
 | 
			
		||||
 */
 | 
			
		||||
gint
 | 
			
		||||
eek_keyboard_get_group (EekKeyboard *keyboard)
 | 
			
		||||
{
 | 
			
		||||
    gint group;
 | 
			
		||||
    eek_keyboard_get_symbol_index (keyboard, &group, NULL);
 | 
			
		||||
    return group;
 | 
			
		||||
    return eek_element_get_group (EEK_ELEMENT(keyboard));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eek_keyboard_get_level:
 | 
			
		||||
 * @keyboard: an #EekKeyboard
 | 
			
		||||
 *
 | 
			
		||||
 * Return the level index of @keyboard.
 | 
			
		||||
 * Return the level value of the default symbol index of @keyboard.
 | 
			
		||||
 * If the value is not set, -1 will be returned.
 | 
			
		||||
 *
 | 
			
		||||
 * See also: eek_keyboard_get_symbol_index()
 | 
			
		||||
 * Deprecated: 1.0: Use eek_element_get_level()
 | 
			
		||||
 */
 | 
			
		||||
gint
 | 
			
		||||
eek_keyboard_get_level (EekKeyboard *keyboard)
 | 
			
		||||
{
 | 
			
		||||
    gint level;
 | 
			
		||||
    eek_keyboard_get_symbol_index (keyboard, NULL, &level);
 | 
			
		||||
    return level;
 | 
			
		||||
    return eek_element_get_level (EEK_ELEMENT(keyboard));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@ -738,7 +653,7 @@ eek_keyboard_create_section (EekKeyboard *keyboard)
 | 
			
		||||
 * eek_keyboard_find_key_by_keycode:
 | 
			
		||||
 * @keyboard: an #EekKeyboard
 | 
			
		||||
 * @keycode: a keycode
 | 
			
		||||
 * @returns: (transfer none): #EeekKey whose keycode is @keycode
 | 
			
		||||
 * @returns: (transfer none): #EekKey whose keycode is @keycode
 | 
			
		||||
 *
 | 
			
		||||
 * Find an #EekKey whose keycode is @keycode.
 | 
			
		||||
 */
 | 
			
		||||
@ -864,6 +779,8 @@ eek_keyboard_add_outline (EekKeyboard *keyboard,
 | 
			
		||||
 | 
			
		||||
    _outline = eek_outline_copy (outline);
 | 
			
		||||
    g_array_append_val (priv->outline_array, *_outline);
 | 
			
		||||
    /* don't use eek_outline_free here, so as to keep _outline->points */
 | 
			
		||||
    g_slice_free (EekOutline, _outline);
 | 
			
		||||
    return priv->outline_array->len;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -889,3 +806,77 @@ eek_keyboard_get_outline (EekKeyboard *keyboard,
 | 
			
		||||
 | 
			
		||||
    return &g_array_index (priv->outline_array, EekOutline, oref - 1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eek_keyboard_set_num_lock_mask:
 | 
			
		||||
 * @keyboard: an #EekKeyboard
 | 
			
		||||
 * @num_lock_mask: an #EekModifierType
 | 
			
		||||
 *
 | 
			
		||||
 * Set modifier mask used as Num_Lock.
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
eek_keyboard_set_num_lock_mask (EekKeyboard    *keyboard,
 | 
			
		||||
                                EekModifierType num_lock_mask)
 | 
			
		||||
{
 | 
			
		||||
    EekKeyboardPrivate *priv;
 | 
			
		||||
 | 
			
		||||
    g_assert (EEK_IS_KEYBOARD(keyboard));
 | 
			
		||||
    priv = EEK_KEYBOARD_GET_PRIVATE(keyboard);
 | 
			
		||||
 | 
			
		||||
    priv->num_lock_mask = num_lock_mask;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eek_keyboard_get_num_lock_mask:
 | 
			
		||||
 * @keyboard: an #EekKeyboard
 | 
			
		||||
 *
 | 
			
		||||
 * Get modifier mask used as Num_Lock.
 | 
			
		||||
 * Returns: an #EekModifierType
 | 
			
		||||
 */
 | 
			
		||||
EekModifierType
 | 
			
		||||
eek_keyboard_get_num_lock_mask (EekKeyboard *keyboard)
 | 
			
		||||
{
 | 
			
		||||
    EekKeyboardPrivate *priv;
 | 
			
		||||
 | 
			
		||||
    g_assert (EEK_IS_KEYBOARD(keyboard));
 | 
			
		||||
    priv = EEK_KEYBOARD_GET_PRIVATE(keyboard);
 | 
			
		||||
 | 
			
		||||
    return priv->num_lock_mask;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eek_keyboard_set_alt_gr_mask:
 | 
			
		||||
 * @keyboard: an #EekKeyboard
 | 
			
		||||
 * @alt_gr_mask: an #EekModifierType
 | 
			
		||||
 *
 | 
			
		||||
 * Set modifier mask used as Alt_Gr.
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
eek_keyboard_set_alt_gr_mask (EekKeyboard    *keyboard,
 | 
			
		||||
                              EekModifierType alt_gr_mask)
 | 
			
		||||
{
 | 
			
		||||
    EekKeyboardPrivate *priv;
 | 
			
		||||
 | 
			
		||||
    g_assert (EEK_IS_KEYBOARD(keyboard));
 | 
			
		||||
    priv = EEK_KEYBOARD_GET_PRIVATE(keyboard);
 | 
			
		||||
 | 
			
		||||
    priv->alt_gr_mask = alt_gr_mask;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eek_keyboard_get_alt_gr_mask:
 | 
			
		||||
 * @keyboard: an #EekKeyboard
 | 
			
		||||
 *
 | 
			
		||||
 * Get modifier mask used as Alt_Gr.
 | 
			
		||||
 * Returns: an #EekModifierType
 | 
			
		||||
 */
 | 
			
		||||
EekModifierType
 | 
			
		||||
eek_keyboard_get_alt_gr_mask (EekKeyboard *keyboard)
 | 
			
		||||
{
 | 
			
		||||
    EekKeyboardPrivate *priv;
 | 
			
		||||
 | 
			
		||||
    g_assert (EEK_IS_KEYBOARD(keyboard));
 | 
			
		||||
    priv = EEK_KEYBOARD_GET_PRIVATE(keyboard);
 | 
			
		||||
 | 
			
		||||
    return priv->alt_gr_mask;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -37,6 +37,12 @@ G_BEGIN_DECLS
 | 
			
		||||
typedef struct _EekKeyboardClass EekKeyboardClass;
 | 
			
		||||
typedef struct _EekKeyboardPrivate EekKeyboardPrivate;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * EekKeyboard:
 | 
			
		||||
 *
 | 
			
		||||
 * The #EekKeyboard structure contains only private data and should
 | 
			
		||||
 * only be accessed using the provided API.
 | 
			
		||||
 */
 | 
			
		||||
struct _EekKeyboard
 | 
			
		||||
{
 | 
			
		||||
    /*< private >*/
 | 
			
		||||
@ -47,30 +53,22 @@ struct _EekKeyboard
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * EekKeyboardClass:
 | 
			
		||||
 * @set_keysym_index: virtual function for setting group and level of
 | 
			
		||||
 * the entire keyboard
 | 
			
		||||
 * @get_keysym_index: virtual function for getting group and level of
 | 
			
		||||
 * the entire keyboard
 | 
			
		||||
 * @create_section: virtual function for creating a section
 | 
			
		||||
 * @find_key_by_keycode: virtual function for finding a key in the
 | 
			
		||||
 * keyboard by keycode
 | 
			
		||||
 * @key_pressed: class handler for #EekKeyboard::key-pressed signal
 | 
			
		||||
 * @key_released: class handler for #EekKeyboard::key-released signal
 | 
			
		||||
 * @keysym_index_changed: class handler for #EekKeyboard::keysym-index-changed signal
 | 
			
		||||
 */
 | 
			
		||||
struct _EekKeyboardClass
 | 
			
		||||
{
 | 
			
		||||
    /*< private >*/
 | 
			
		||||
    EekContainerClass parent_class;
 | 
			
		||||
 | 
			
		||||
    /*< public >*/
 | 
			
		||||
    void        (* set_symbol_index)     (EekKeyboard *self,
 | 
			
		||||
                                          gint         group,
 | 
			
		||||
                                          gint         level);
 | 
			
		||||
    void        (* get_symbol_index)     (EekKeyboard *self,
 | 
			
		||||
                                          gint        *group,
 | 
			
		||||
                                          gint        *level);
 | 
			
		||||
    /* obsolete members moved to EekElement */
 | 
			
		||||
    gpointer set_symbol_index;
 | 
			
		||||
    gpointer get_symbol_index;
 | 
			
		||||
 | 
			
		||||
    /*< public >*/
 | 
			
		||||
    EekSection *(* create_section)       (EekKeyboard *self);
 | 
			
		||||
 | 
			
		||||
    EekKey     *(* find_key_by_keycode)  (EekKeyboard *self,
 | 
			
		||||
@ -81,11 +79,11 @@ struct _EekKeyboardClass
 | 
			
		||||
                                          EekKey      *key);
 | 
			
		||||
    void        (* key_released)         (EekKeyboard *self,
 | 
			
		||||
                                          EekKey      *key);
 | 
			
		||||
    void        (* symbol_index_changed) (EekKeyboard *self,
 | 
			
		||||
                                          gint         group,
 | 
			
		||||
                                          gint         level);
 | 
			
		||||
 | 
			
		||||
    /*< private >*/
 | 
			
		||||
    /* obsolete members moved to EekElement */
 | 
			
		||||
    gpointer symbol_index_changed;
 | 
			
		||||
 | 
			
		||||
    /* padding */
 | 
			
		||||
    gpointer pdummy[24];
 | 
			
		||||
};
 | 
			
		||||
@ -149,5 +147,17 @@ EekOutline         *eek_keyboard_get_outline
 | 
			
		||||
                                     (EekKeyboard        *keyboard,
 | 
			
		||||
                                      gulong              oref);
 | 
			
		||||
 | 
			
		||||
void                eek_keyboard_set_num_lock_mask
 | 
			
		||||
                                     (EekKeyboard        *keyboard,
 | 
			
		||||
                                      EekModifierType     num_lock_mask);
 | 
			
		||||
EekModifierType     eek_keyboard_get_num_lock_mask
 | 
			
		||||
                                     (EekKeyboard        *keyboard);
 | 
			
		||||
 | 
			
		||||
void                eek_keyboard_set_alt_gr_mask
 | 
			
		||||
                                     (EekKeyboard        *keyboard,
 | 
			
		||||
                                      EekModifierType     alt_gr_mask);
 | 
			
		||||
EekModifierType     eek_keyboard_get_alt_gr_mask
 | 
			
		||||
                                     (EekKeyboard        *keyboard);
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
#endif  /* EEK_KEYBOARD_H */
 | 
			
		||||
 | 
			
		||||
@ -23,13 +23,13 @@
 | 
			
		||||
 * @short_description: an #EekSymbol represents an X keysym
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_CONFIG_H
 | 
			
		||||
#include "config.h"
 | 
			
		||||
#endif  /* HAVE_CONFIG_H */
 | 
			
		||||
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
 | 
			
		||||
#include "eek-keysym.h"
 | 
			
		||||
#include "eek-serializable.h"
 | 
			
		||||
 | 
			
		||||
@ -214,8 +214,16 @@ eek_keysym_init (EekKeysym *self)
 | 
			
		||||
    priv->xkeysym = EEK_INVALID_KEYSYM;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eek_keysym_new_with_modifier:
 | 
			
		||||
 * @xkeysym: an X keysym value
 | 
			
		||||
 * @modifier_mask: modifier assigned to @xkeysym
 | 
			
		||||
 *
 | 
			
		||||
 * Create an #EekKeysym with given X keysym value @xkeysym and
 | 
			
		||||
 * modifier @modifier_mask.
 | 
			
		||||
 */
 | 
			
		||||
EekKeysym *
 | 
			
		||||
eek_keysym_new (guint xkeysym)
 | 
			
		||||
eek_keysym_new_with_modifier (guint xkeysym, EekModifierType modifier_mask)
 | 
			
		||||
{
 | 
			
		||||
    EekKeysym *keysym;
 | 
			
		||||
    EekKeysymPrivate *priv;
 | 
			
		||||
@ -223,7 +231,6 @@ eek_keysym_new (guint xkeysym)
 | 
			
		||||
        *unichar_entry;
 | 
			
		||||
    gchar *name, *label;
 | 
			
		||||
    EekSymbolCategory category;
 | 
			
		||||
    EekModifierType modifier_mask;
 | 
			
		||||
    gunichar uc;
 | 
			
		||||
 | 
			
		||||
    special_entry =
 | 
			
		||||
@ -272,8 +279,6 @@ eek_keysym_new (guint xkeysym)
 | 
			
		||||
    else
 | 
			
		||||
        label = g_strdup (name);
 | 
			
		||||
 | 
			
		||||
    modifier_mask = get_modifier_mask (xkeysym);
 | 
			
		||||
 | 
			
		||||
    keysym = g_object_new (EEK_TYPE_KEYSYM,
 | 
			
		||||
                           "name", name,
 | 
			
		||||
                           "label", label,
 | 
			
		||||
@ -294,6 +299,24 @@ eek_keysym_new (guint xkeysym)
 | 
			
		||||
    return keysym;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eek_keysym_new:
 | 
			
		||||
 * @xkeysym: an X keysym value
 | 
			
		||||
 *
 | 
			
		||||
 * Create an #EekKeysym with given X keysym value @xkeysym.
 | 
			
		||||
 */
 | 
			
		||||
EekKeysym *
 | 
			
		||||
eek_keysym_new (guint xkeysym)
 | 
			
		||||
{
 | 
			
		||||
    return eek_keysym_new_with_modifier (xkeysym, get_modifier_mask (xkeysym));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eek_keysym_new_from_name:
 | 
			
		||||
 * @name: an X keysym name
 | 
			
		||||
 *
 | 
			
		||||
 * Create an #EekKeysym with an X keysym value looked up by @name.
 | 
			
		||||
 */
 | 
			
		||||
EekKeysym *
 | 
			
		||||
eek_keysym_new_from_name (const gchar *name)
 | 
			
		||||
{
 | 
			
		||||
@ -312,6 +335,12 @@ eek_keysym_new_from_name (const gchar *name)
 | 
			
		||||
                         NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eek_keysym_get_xkeysym:
 | 
			
		||||
 * @keysym: an #EekKeysym
 | 
			
		||||
 *
 | 
			
		||||
 * Get an X keysym value associated with @keysym
 | 
			
		||||
 */
 | 
			
		||||
guint
 | 
			
		||||
eek_keysym_get_xkeysym (EekKeysym *keysym)
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
@ -20,6 +20,7 @@
 | 
			
		||||
#ifndef EEK_KEYSYM_H
 | 
			
		||||
#define EEK_KEYSYM_H 1
 | 
			
		||||
 | 
			
		||||
#include <X11/XKBlib.h>
 | 
			
		||||
#include "eek-symbol.h"
 | 
			
		||||
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
@ -58,6 +59,8 @@ EekKeysym *eek_keysym_new           (guint        xkeysym);
 | 
			
		||||
guint      eek_keysym_get_xkeysym       (EekKeysym      *keysym);
 | 
			
		||||
 | 
			
		||||
EekKeysym *eek_keysym_new_from_name     (const gchar    *name);
 | 
			
		||||
EekKeysym *eek_keysym_new_with_modifier (guint           xkeysym,
 | 
			
		||||
                                         EekModifierType modifier);
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -18,12 +18,12 @@
 | 
			
		||||
 * 02110-1301 USA
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <math.h>
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_CONFIG_H
 | 
			
		||||
#include "config.h"
 | 
			
		||||
#endif  /* HAVE_CONFIG_H */
 | 
			
		||||
 | 
			
		||||
#include <math.h>
 | 
			
		||||
 | 
			
		||||
#include "eek-key.h"
 | 
			
		||||
#include "eek-section.h"
 | 
			
		||||
#include "eek-renderer.h"
 | 
			
		||||
@ -45,17 +45,26 @@ struct _EekRendererPrivate
 | 
			
		||||
    EekKeyboard *keyboard;
 | 
			
		||||
    PangoContext *pcontext;
 | 
			
		||||
 | 
			
		||||
    EekColor *foreground;
 | 
			
		||||
    EekColor *background;
 | 
			
		||||
    EekColor default_foreground_color;
 | 
			
		||||
    EekColor default_background_color;
 | 
			
		||||
    gdouble border_width;
 | 
			
		||||
 | 
			
		||||
    gdouble allocation_width;
 | 
			
		||||
    gdouble allocation_height;
 | 
			
		||||
    gdouble scale;
 | 
			
		||||
 | 
			
		||||
    PangoFontDescription *font;
 | 
			
		||||
    GHashTable *outline_surface_cache;
 | 
			
		||||
    GHashTable *active_outline_surface_cache;
 | 
			
		||||
    cairo_surface_t *keyboard_surface;
 | 
			
		||||
    gulong symbol_index_changed_handler;
 | 
			
		||||
 | 
			
		||||
    EekTheme *theme;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
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};
 | 
			
		||||
 | 
			
		||||
struct {
 | 
			
		||||
    gint category;
 | 
			
		||||
    gdouble scale;
 | 
			
		||||
@ -144,6 +153,14 @@ create_keyboard_surface (EekRenderer *renderer)
 | 
			
		||||
    EekBounds bounds;
 | 
			
		||||
    cairo_surface_t *keyboard_surface;
 | 
			
		||||
    CreateKeyboardSurfaceCallbackData data;
 | 
			
		||||
    EekColor foreground, background;
 | 
			
		||||
 | 
			
		||||
    eek_renderer_get_foreground_color (renderer,
 | 
			
		||||
                                       EEK_ELEMENT(priv->keyboard),
 | 
			
		||||
                                       &foreground);
 | 
			
		||||
    eek_renderer_get_background_color (renderer,
 | 
			
		||||
                                       EEK_ELEMENT(priv->keyboard),
 | 
			
		||||
                                       &background);
 | 
			
		||||
 | 
			
		||||
    eek_element_get_bounds (EEK_ELEMENT(priv->keyboard), &bounds);
 | 
			
		||||
    keyboard_surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
 | 
			
		||||
@ -156,22 +173,24 @@ create_keyboard_surface (EekRenderer *renderer)
 | 
			
		||||
 | 
			
		||||
    /* blank background */
 | 
			
		||||
    cairo_set_source_rgba (data.cr,
 | 
			
		||||
                           priv->background->red,
 | 
			
		||||
                           priv->background->green,
 | 
			
		||||
                           priv->background->blue,
 | 
			
		||||
                           priv->background->alpha);
 | 
			
		||||
    cairo_rectangle (data.cr,
 | 
			
		||||
                     0.0,
 | 
			
		||||
                     0.0,
 | 
			
		||||
                     cairo_image_surface_get_width (keyboard_surface),
 | 
			
		||||
                     cairo_image_surface_get_height (keyboard_surface));
 | 
			
		||||
    cairo_fill (data.cr);
 | 
			
		||||
                           background.red,
 | 
			
		||||
                           background.green,
 | 
			
		||||
                           background.blue,
 | 
			
		||||
                           background.alpha);
 | 
			
		||||
    cairo_paint (data.cr);
 | 
			
		||||
 | 
			
		||||
    cairo_set_source_rgba (data.cr,
 | 
			
		||||
                           foreground.red,
 | 
			
		||||
                           foreground.green,
 | 
			
		||||
                           foreground.blue,
 | 
			
		||||
                           foreground.alpha);
 | 
			
		||||
 | 
			
		||||
    /* draw sections */
 | 
			
		||||
    eek_container_foreach_child (EEK_CONTAINER(priv->keyboard),
 | 
			
		||||
                                 create_keyboard_surface_section_callback,
 | 
			
		||||
                                 &data);
 | 
			
		||||
    cairo_destroy (data.cr);
 | 
			
		||||
 | 
			
		||||
    return keyboard_surface;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -183,21 +202,54 @@ render_key_outline (EekRenderer *renderer,
 | 
			
		||||
    EekRendererPrivate *priv = EEK_RENDERER_GET_PRIVATE(renderer);
 | 
			
		||||
    EekOutline *outline;
 | 
			
		||||
    EekBounds bounds;
 | 
			
		||||
    cairo_pattern_t *pat;
 | 
			
		||||
    gdouble scale;
 | 
			
		||||
    gint i;
 | 
			
		||||
    gulong oref;
 | 
			
		||||
 | 
			
		||||
    /* need to rescale so that the border fit inside the clipping
 | 
			
		||||
       region */
 | 
			
		||||
    eek_element_get_bounds (EEK_ELEMENT(key), &bounds);
 | 
			
		||||
    scale = MIN((bounds.width - priv->border_width) / bounds.width,
 | 
			
		||||
                (bounds.height - priv->border_width) / bounds.height);
 | 
			
		||||
    EekThemeNode *theme_node;
 | 
			
		||||
    EekColor foreground, background, gradient_start, gradient_end, border_color;
 | 
			
		||||
    EekGradientType gradient_type;
 | 
			
		||||
    gint border_width;
 | 
			
		||||
    gint border_radius;
 | 
			
		||||
 | 
			
		||||
    oref = eek_key_get_oref (key);
 | 
			
		||||
    if (oref == 0)
 | 
			
		||||
        return;
 | 
			
		||||
 | 
			
		||||
    if (eek_key_is_pressed (key))
 | 
			
		||||
        theme_node = g_object_get_data (G_OBJECT(key), "theme-node-pressed");
 | 
			
		||||
    else
 | 
			
		||||
        theme_node = g_object_get_data (G_OBJECT(key), "theme-node");
 | 
			
		||||
    if (theme_node) {
 | 
			
		||||
        eek_theme_node_get_foreground_color (theme_node, &foreground);
 | 
			
		||||
        eek_theme_node_get_background_color (theme_node, &background);
 | 
			
		||||
        eek_theme_node_get_background_gradient (theme_node,
 | 
			
		||||
                                                &gradient_type,
 | 
			
		||||
                                                &gradient_start,
 | 
			
		||||
                                                &gradient_end);
 | 
			
		||||
        border_width = eek_theme_node_get_border_width (theme_node,
 | 
			
		||||
                                                        EEK_SIDE_TOP);
 | 
			
		||||
        border_radius = eek_theme_node_get_border_radius (theme_node,
 | 
			
		||||
                                                          EEK_SIDE_TOP);
 | 
			
		||||
        eek_theme_node_get_border_color (theme_node, EEK_SIDE_TOP,
 | 
			
		||||
                                         &border_color);
 | 
			
		||||
    } else {
 | 
			
		||||
        foreground = priv->default_foreground_color;
 | 
			
		||||
        background = priv->default_background_color;
 | 
			
		||||
        gradient_type = EEK_GRADIENT_NONE;
 | 
			
		||||
        border_width = priv->border_width;
 | 
			
		||||
        border_radius = -1;
 | 
			
		||||
        border_color.red = ABS(background.red - foreground.red) * 0.7;
 | 
			
		||||
        border_color.green = ABS(background.green - foreground.green) * 0.7;
 | 
			
		||||
        border_color.blue = ABS(background.blue - foreground.blue) * 0.7;
 | 
			
		||||
        border_color.alpha = foreground.alpha;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* need to rescale so that the border fit inside the clipping
 | 
			
		||||
       region */
 | 
			
		||||
    eek_element_get_bounds (EEK_ELEMENT(key), &bounds);
 | 
			
		||||
    scale = MIN((bounds.width - border_width) / bounds.width,
 | 
			
		||||
                (bounds.height - border_width) / bounds.height);
 | 
			
		||||
 | 
			
		||||
    outline = eek_keyboard_get_outline (priv->keyboard, oref);
 | 
			
		||||
    outline = eek_outline_copy (outline);
 | 
			
		||||
    for (i = 0; i < outline->num_points; i++) {
 | 
			
		||||
@ -206,49 +258,81 @@ render_key_outline (EekRenderer *renderer,
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    cairo_translate (cr,
 | 
			
		||||
                     priv->border_width / 2 * priv->scale,
 | 
			
		||||
                     priv->border_width / 2 * priv->scale);
 | 
			
		||||
                     border_width / 2 * priv->scale,
 | 
			
		||||
                     border_width / 2 * priv->scale);
 | 
			
		||||
 | 
			
		||||
    /* paint the background with gradient */
 | 
			
		||||
    if (gradient_type != EEK_GRADIENT_NONE) {
 | 
			
		||||
        cairo_pattern_t *pat;
 | 
			
		||||
        gdouble cx, cy;
 | 
			
		||||
 | 
			
		||||
        switch (gradient_type) {
 | 
			
		||||
        case EEK_GRADIENT_VERTICAL:
 | 
			
		||||
            pat = cairo_pattern_create_linear (0.0,
 | 
			
		||||
                                               0.0,
 | 
			
		||||
                                               0.0,
 | 
			
		||||
                                       bounds.height * priv->scale * 5.0);
 | 
			
		||||
                                               bounds.height * priv->scale);
 | 
			
		||||
            break;
 | 
			
		||||
        case EEK_GRADIENT_HORIZONTAL:
 | 
			
		||||
            pat = cairo_pattern_create_linear (0.0,
 | 
			
		||||
                                               0.0,
 | 
			
		||||
                                               bounds.width * priv->scale,
 | 
			
		||||
                                               0.0);
 | 
			
		||||
            break;
 | 
			
		||||
        case EEK_GRADIENT_RADIAL:
 | 
			
		||||
            cx = bounds.width / 2 * priv->scale;
 | 
			
		||||
            cy = bounds.height / 2 * priv->scale;
 | 
			
		||||
            pat = cairo_pattern_create_radial (cx,
 | 
			
		||||
                                               cy,
 | 
			
		||||
                                               0,
 | 
			
		||||
                                               cx,
 | 
			
		||||
                                               cy,
 | 
			
		||||
                                               MIN(cx, cy));
 | 
			
		||||
            break;
 | 
			
		||||
        default:
 | 
			
		||||
            g_assert_not_reached ();
 | 
			
		||||
            break;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        cairo_pattern_add_color_stop_rgba (pat,
 | 
			
		||||
                                           1,
 | 
			
		||||
                                       priv->background->red * 0.5,
 | 
			
		||||
                                       priv->background->green * 0.5,
 | 
			
		||||
                                       priv->background->blue * 0.5,
 | 
			
		||||
                                       priv->background->alpha);
 | 
			
		||||
                                           gradient_start.red * 0.5,
 | 
			
		||||
                                           gradient_start.green * 0.5,
 | 
			
		||||
                                           gradient_start.blue * 0.5,
 | 
			
		||||
                                           gradient_start.alpha);
 | 
			
		||||
        cairo_pattern_add_color_stop_rgba (pat,
 | 
			
		||||
                                           0,
 | 
			
		||||
                                       priv->background->red,
 | 
			
		||||
                                       priv->background->green,
 | 
			
		||||
                                       priv->background->blue,
 | 
			
		||||
                                       priv->background->alpha);
 | 
			
		||||
 | 
			
		||||
                                           gradient_end.red,
 | 
			
		||||
                                           gradient_end.green,
 | 
			
		||||
                                           gradient_end.blue,
 | 
			
		||||
                                           gradient_end.alpha);
 | 
			
		||||
        cairo_set_source (cr, pat);
 | 
			
		||||
        cairo_pattern_destroy (pat);
 | 
			
		||||
    } else {
 | 
			
		||||
        cairo_set_source_rgba (cr,
 | 
			
		||||
                               background.red,
 | 
			
		||||
                               background.green,
 | 
			
		||||
                               background.blue,
 | 
			
		||||
                               background.alpha);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _eek_rounded_polygon (cr,
 | 
			
		||||
                          outline->corner_radius,
 | 
			
		||||
                          border_radius >= 0 ? border_radius : outline->corner_radius,
 | 
			
		||||
                          outline->points,
 | 
			
		||||
                          outline->num_points);
 | 
			
		||||
    cairo_fill (cr);
 | 
			
		||||
 | 
			
		||||
    cairo_pattern_destroy (pat);
 | 
			
		||||
 | 
			
		||||
    /* paint the border */
 | 
			
		||||
    cairo_set_line_width (cr, priv->border_width);
 | 
			
		||||
    cairo_set_line_width (cr, border_width);
 | 
			
		||||
    cairo_set_line_join (cr, CAIRO_LINE_JOIN_ROUND);
 | 
			
		||||
 | 
			
		||||
    cairo_set_source_rgba
 | 
			
		||||
        (cr, 
 | 
			
		||||
         ABS(priv->background->red - priv->foreground->red) * 0.7,
 | 
			
		||||
         ABS(priv->background->green - priv->foreground->green) * 0.7,
 | 
			
		||||
         ABS(priv->background->blue - priv->foreground->blue) * 0.7,
 | 
			
		||||
         priv->foreground->alpha);
 | 
			
		||||
    cairo_set_source_rgba (cr,
 | 
			
		||||
                           border_color.red,
 | 
			
		||||
                           border_color.green,
 | 
			
		||||
                           border_color.blue,
 | 
			
		||||
                           border_color.alpha);
 | 
			
		||||
 | 
			
		||||
    _eek_rounded_polygon (cr,
 | 
			
		||||
                          outline->corner_radius,
 | 
			
		||||
                          border_radius >= 0 ? border_radius : outline->corner_radius,
 | 
			
		||||
                          outline->points,
 | 
			
		||||
                          outline->num_points);
 | 
			
		||||
    cairo_stroke (cr);
 | 
			
		||||
@ -260,6 +344,7 @@ struct _CalculateFontSizeCallbackData {
 | 
			
		||||
    gdouble size;
 | 
			
		||||
    gdouble em_size;
 | 
			
		||||
    EekRenderer *renderer;
 | 
			
		||||
    const PangoFontDescription *base_font;
 | 
			
		||||
};
 | 
			
		||||
typedef struct _CalculateFontSizeCallbackData CalculateFontSizeCallbackData;
 | 
			
		||||
 | 
			
		||||
@ -270,23 +355,21 @@ calculate_font_size_key_callback (EekElement *element, gpointer user_data)
 | 
			
		||||
    EekRendererPrivate *priv = EEK_RENDERER_GET_PRIVATE(data->renderer);
 | 
			
		||||
    gdouble sx, sy;
 | 
			
		||||
    PangoFontDescription *font;
 | 
			
		||||
    const PangoFontDescription *base_font;
 | 
			
		||||
    PangoRectangle extents = { 0, };
 | 
			
		||||
    PangoLayout *layout;
 | 
			
		||||
    gdouble size;
 | 
			
		||||
    EekSymbol *symbol;
 | 
			
		||||
    EekBounds bounds;
 | 
			
		||||
    gchar *label = NULL;
 | 
			
		||||
    const gchar *label = NULL;
 | 
			
		||||
 | 
			
		||||
    symbol = eek_key_get_symbol (EEK_KEY(element));
 | 
			
		||||
    if (symbol &&
 | 
			
		||||
        eek_symbol_get_category (symbol) == EEK_SYMBOL_CATEGORY_LETTER)
 | 
			
		||||
        label = eek_symbol_get_label (symbol);
 | 
			
		||||
    if (!label)
 | 
			
		||||
        label = g_strdup ("M");
 | 
			
		||||
        label = "M";
 | 
			
		||||
 | 
			
		||||
    base_font = pango_context_get_font_description (priv->pcontext);
 | 
			
		||||
    font = pango_font_description_copy (base_font);
 | 
			
		||||
    font = pango_font_description_copy (data->base_font);
 | 
			
		||||
 | 
			
		||||
    eek_element_get_bounds (element, &bounds);
 | 
			
		||||
    size = eek_bounds_long_side (&bounds) * PANGO_SCALE;
 | 
			
		||||
@ -296,7 +379,6 @@ calculate_font_size_key_callback (EekElement *element, gpointer user_data)
 | 
			
		||||
    pango_font_description_free (font);
 | 
			
		||||
 | 
			
		||||
    pango_layout_set_text (layout, label, -1);
 | 
			
		||||
    g_free (label);
 | 
			
		||||
 | 
			
		||||
    pango_layout_get_extents (layout, NULL, &extents);
 | 
			
		||||
    g_object_unref (layout);
 | 
			
		||||
@ -308,7 +390,7 @@ calculate_font_size_key_callback (EekElement *element, gpointer user_data)
 | 
			
		||||
        sy = bounds.height * PANGO_SCALE / extents.height;
 | 
			
		||||
 | 
			
		||||
    size *= MIN(sx, sy);
 | 
			
		||||
    if (size >= pango_font_description_get_size (base_font)) {
 | 
			
		||||
    if (size >= pango_font_description_get_size (data->base_font)) {
 | 
			
		||||
        if (size < data->size)
 | 
			
		||||
            data->size = size;
 | 
			
		||||
        if (size < data->em_size)
 | 
			
		||||
@ -325,36 +407,21 @@ calculate_font_size_section_callback (EekElement *element, gpointer user_data)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gdouble
 | 
			
		||||
calculate_font_size (EekRenderer *renderer)
 | 
			
		||||
calculate_font_size (EekRenderer *renderer, const PangoFontDescription *base_font)
 | 
			
		||||
{
 | 
			
		||||
    EekRendererPrivate *priv = EEK_RENDERER_GET_PRIVATE(renderer);
 | 
			
		||||
    CalculateFontSizeCallbackData data;
 | 
			
		||||
    PangoFontDescription *base_font;
 | 
			
		||||
 | 
			
		||||
    base_font = pango_context_get_font_description (priv->pcontext);
 | 
			
		||||
    data.size = G_MAXDOUBLE;
 | 
			
		||||
    data.em_size = G_MAXDOUBLE;
 | 
			
		||||
    data.renderer = renderer;
 | 
			
		||||
    data.base_font = base_font;
 | 
			
		||||
    eek_container_foreach_child (EEK_CONTAINER(priv->keyboard),
 | 
			
		||||
                                 calculate_font_size_section_callback,
 | 
			
		||||
                                 &data);
 | 
			
		||||
    return data.size > 0 ? data.size : data.em_size;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static EekKeyboard *
 | 
			
		||||
get_keyboard (EekKey *key)
 | 
			
		||||
{
 | 
			
		||||
    EekElement *parent;
 | 
			
		||||
 | 
			
		||||
    parent = eek_element_get_parent (EEK_ELEMENT(key));
 | 
			
		||||
    g_return_val_if_fail (EEK_IS_SECTION(parent), NULL);
 | 
			
		||||
 | 
			
		||||
    parent = eek_element_get_parent (parent);
 | 
			
		||||
    g_return_val_if_fail (EEK_IS_KEYBOARD(parent), NULL);
 | 
			
		||||
 | 
			
		||||
    return EEK_KEYBOARD(parent);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
render_key (EekRenderer *self,
 | 
			
		||||
            cairo_t     *cr,
 | 
			
		||||
@ -364,20 +431,22 @@ render_key (EekRenderer *self,
 | 
			
		||||
    EekOutline *outline;
 | 
			
		||||
    cairo_surface_t *outline_surface;
 | 
			
		||||
    EekBounds bounds;
 | 
			
		||||
    PangoLayout *layout;
 | 
			
		||||
    PangoRectangle extents = { 0, };
 | 
			
		||||
    gulong oref;
 | 
			
		||||
    EekKeyboard *keyboard;
 | 
			
		||||
    EekSymbol *symbol;
 | 
			
		||||
    GHashTable *outline_surface_cache;
 | 
			
		||||
 | 
			
		||||
    eek_element_get_bounds (EEK_ELEMENT(key), &bounds);
 | 
			
		||||
    oref = eek_key_get_oref (key);
 | 
			
		||||
    if (oref == 0)
 | 
			
		||||
        return;
 | 
			
		||||
 | 
			
		||||
    keyboard = get_keyboard (key);
 | 
			
		||||
    outline = eek_keyboard_get_outline (keyboard, oref);
 | 
			
		||||
    outline_surface = g_hash_table_lookup (priv->outline_surface_cache,
 | 
			
		||||
                                           outline);
 | 
			
		||||
    if (eek_key_is_pressed (key))
 | 
			
		||||
        outline_surface_cache = priv->active_outline_surface_cache;
 | 
			
		||||
    else
 | 
			
		||||
        outline_surface_cache = priv->outline_surface_cache;
 | 
			
		||||
 | 
			
		||||
    outline = eek_keyboard_get_outline (priv->keyboard, oref);
 | 
			
		||||
    outline_surface = g_hash_table_lookup (outline_surface_cache, outline);
 | 
			
		||||
    if (!outline_surface) {
 | 
			
		||||
        cairo_t *cr;
 | 
			
		||||
 | 
			
		||||
@ -388,18 +457,13 @@ render_key (EekRenderer *self,
 | 
			
		||||
        cr = cairo_create (outline_surface);
 | 
			
		||||
 | 
			
		||||
        /* blank background */
 | 
			
		||||
        eek_element_get_bounds (EEK_ELEMENT(key), &bounds);
 | 
			
		||||
        cairo_set_source_rgba (cr, 0.0, 0.0, 0.0, 0.0);
 | 
			
		||||
        cairo_rectangle (cr,
 | 
			
		||||
                         0.0,
 | 
			
		||||
                         0.0,
 | 
			
		||||
                         bounds.width * priv->scale,
 | 
			
		||||
                         bounds.height * priv->scale);
 | 
			
		||||
        cairo_fill (cr);
 | 
			
		||||
        cairo_paint (cr);
 | 
			
		||||
 | 
			
		||||
        render_key_outline (self, cr, key);
 | 
			
		||||
        eek_renderer_render_key_outline (self, cr, key, 1.0, 0);
 | 
			
		||||
        cairo_destroy (cr);
 | 
			
		||||
 | 
			
		||||
        g_hash_table_insert (priv->outline_surface_cache,
 | 
			
		||||
        g_hash_table_insert (outline_surface_cache,
 | 
			
		||||
                             outline,
 | 
			
		||||
                             outline_surface);
 | 
			
		||||
    }
 | 
			
		||||
@ -407,8 +471,18 @@ render_key (EekRenderer *self,
 | 
			
		||||
    cairo_set_source_surface (cr, outline_surface, 0.0, 0.0);
 | 
			
		||||
    cairo_paint (cr);
 | 
			
		||||
 | 
			
		||||
    symbol = eek_key_get_symbol_with_fallback (key, 0, 0);
 | 
			
		||||
    if (EEK_RENDERER_GET_CLASS(self)->render_key_icon &&
 | 
			
		||||
        symbol && eek_symbol_get_icon_name (symbol)) {
 | 
			
		||||
        eek_renderer_render_key_icon (self, cr, key, 1.0, 0);
 | 
			
		||||
    } else {
 | 
			
		||||
        PangoLayout *layout;
 | 
			
		||||
        PangoRectangle extents = { 0, };
 | 
			
		||||
        EekColor foreground;
 | 
			
		||||
        EekThemeNode *theme_node;
 | 
			
		||||
 | 
			
		||||
        layout = pango_cairo_create_layout (cr);
 | 
			
		||||
    eek_renderer_real_render_key_label (self, layout, key);
 | 
			
		||||
        eek_renderer_render_key_label (self, layout, key);
 | 
			
		||||
        pango_layout_get_extents (layout, NULL, &extents);
 | 
			
		||||
 | 
			
		||||
        cairo_save (cr);
 | 
			
		||||
@ -416,18 +490,27 @@ render_key (EekRenderer *self,
 | 
			
		||||
            (cr,
 | 
			
		||||
             (bounds.width * priv->scale - extents.width / PANGO_SCALE) / 2,
 | 
			
		||||
             (bounds.height * priv->scale - extents.height / PANGO_SCALE) / 2);
 | 
			
		||||
 | 
			
		||||
        if (eek_key_is_pressed (key))
 | 
			
		||||
            theme_node = g_object_get_data (G_OBJECT(key), "theme-node-pressed");
 | 
			
		||||
        else
 | 
			
		||||
            theme_node = g_object_get_data (G_OBJECT(key), "theme-node");
 | 
			
		||||
 | 
			
		||||
        eek_renderer_get_foreground_color (self, EEK_ELEMENT(key), &foreground);
 | 
			
		||||
        cairo_set_source_rgba (cr,
 | 
			
		||||
                           priv->foreground->red,
 | 
			
		||||
                           priv->foreground->green,
 | 
			
		||||
                           priv->foreground->blue,
 | 
			
		||||
                           priv->foreground->alpha);
 | 
			
		||||
                               foreground.red,
 | 
			
		||||
                               foreground.green,
 | 
			
		||||
                               foreground.blue,
 | 
			
		||||
                               foreground.alpha);
 | 
			
		||||
 | 
			
		||||
        pango_cairo_show_layout (cr, layout);
 | 
			
		||||
        cairo_restore (cr);
 | 
			
		||||
        g_object_unref (layout);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
prepare_render_key (EekRenderer *self,
 | 
			
		||||
void
 | 
			
		||||
eek_renderer_apply_transformation_for_key (EekRenderer *self,
 | 
			
		||||
                                           cairo_t     *cr,
 | 
			
		||||
                                           EekKey      *key,
 | 
			
		||||
                                           gdouble      scale,
 | 
			
		||||
@ -463,7 +546,7 @@ eek_renderer_real_render_key_label (EekRenderer *self,
 | 
			
		||||
    EekRendererPrivate *priv = EEK_RENDERER_GET_PRIVATE(self);
 | 
			
		||||
    EekSymbol *symbol;
 | 
			
		||||
    EekSymbolCategory category;
 | 
			
		||||
    gchar *label;
 | 
			
		||||
    const gchar *label;
 | 
			
		||||
    EekBounds bounds;
 | 
			
		||||
    PangoFontDescription *font;
 | 
			
		||||
    gdouble size, scale;
 | 
			
		||||
@ -478,11 +561,16 @@ eek_renderer_real_render_key_label (EekRenderer *self,
 | 
			
		||||
        return;
 | 
			
		||||
 | 
			
		||||
    if (!priv->font) {
 | 
			
		||||
        PangoFontDescription *base_font;
 | 
			
		||||
        const PangoFontDescription *base_font;
 | 
			
		||||
        gdouble size;
 | 
			
		||||
        EekThemeNode *theme_node;
 | 
			
		||||
 | 
			
		||||
        size = calculate_font_size (self);
 | 
			
		||||
        theme_node = g_object_get_data (G_OBJECT(key), "theme-node");
 | 
			
		||||
        if (theme_node)
 | 
			
		||||
            base_font = eek_theme_node_get_font (theme_node);
 | 
			
		||||
        else
 | 
			
		||||
            base_font = pango_context_get_font_description (priv->pcontext);
 | 
			
		||||
        size = calculate_font_size (self, base_font);
 | 
			
		||||
        priv->font = pango_font_description_copy (base_font);
 | 
			
		||||
        pango_font_description_set_size (priv->font, size);
 | 
			
		||||
    }
 | 
			
		||||
@ -501,8 +589,8 @@ eek_renderer_real_render_key_label (EekRenderer *self,
 | 
			
		||||
        }
 | 
			
		||||
    pango_font_description_set_size (font, size * priv->scale * scale);
 | 
			
		||||
    pango_layout_set_font_description (layout, font);
 | 
			
		||||
    pango_font_description_free (font);
 | 
			
		||||
    pango_layout_set_text (layout, label, -1);
 | 
			
		||||
    g_free (label);
 | 
			
		||||
    pango_layout_set_width (layout,
 | 
			
		||||
                            PANGO_SCALE * bounds.width * priv->scale * scale);
 | 
			
		||||
    pango_layout_set_ellipsize (layout, PANGO_ELLIPSIZE_END);
 | 
			
		||||
@ -516,7 +604,7 @@ eek_renderer_real_render_key_outline (EekRenderer *self,
 | 
			
		||||
                                      gboolean     rotate)
 | 
			
		||||
{
 | 
			
		||||
    cairo_save (cr);
 | 
			
		||||
    prepare_render_key (self, cr, key, scale, rotate);
 | 
			
		||||
    eek_renderer_apply_transformation_for_key (self, cr, key, scale, rotate);
 | 
			
		||||
    render_key_outline (self, cr, key);
 | 
			
		||||
    cairo_restore (cr);
 | 
			
		||||
}
 | 
			
		||||
@ -529,7 +617,7 @@ eek_renderer_real_render_key (EekRenderer *self,
 | 
			
		||||
                              gboolean     rotate)
 | 
			
		||||
{
 | 
			
		||||
    cairo_save (cr);
 | 
			
		||||
    prepare_render_key (self, cr, key, scale, rotate);
 | 
			
		||||
    eek_renderer_apply_transformation_for_key (self, cr, key, scale, rotate);
 | 
			
		||||
    render_key (self, cr, key);
 | 
			
		||||
    cairo_restore (cr);
 | 
			
		||||
}
 | 
			
		||||
@ -540,6 +628,10 @@ eek_renderer_real_render_keyboard (EekRenderer *self,
 | 
			
		||||
{
 | 
			
		||||
    EekRendererPrivate *priv = EEK_RENDERER_GET_PRIVATE(self);
 | 
			
		||||
 | 
			
		||||
    g_return_if_fail (priv->keyboard);
 | 
			
		||||
    g_return_if_fail (priv->allocation_width > 0.0);
 | 
			
		||||
    g_return_if_fail (priv->allocation_height > 0.0);
 | 
			
		||||
 | 
			
		||||
    if (!priv->keyboard_surface)
 | 
			
		||||
        priv->keyboard_surface = create_keyboard_surface (self);
 | 
			
		||||
 | 
			
		||||
@ -569,6 +661,31 @@ eek_renderer_set_property (GObject      *object,
 | 
			
		||||
        priv->pcontext = g_value_get_object (value);
 | 
			
		||||
        g_object_ref (priv->pcontext);
 | 
			
		||||
        break;
 | 
			
		||||
    default:
 | 
			
		||||
        g_object_set_property (object,
 | 
			
		||||
                               g_param_spec_get_name (pspec),
 | 
			
		||||
                               value);
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
eek_renderer_get_property (GObject    *object,
 | 
			
		||||
                           guint       prop_id,
 | 
			
		||||
                           GValue     *value,
 | 
			
		||||
                           GParamSpec *pspec)
 | 
			
		||||
{
 | 
			
		||||
    EekRendererPrivate *priv = EEK_RENDERER_GET_PRIVATE(object);
 | 
			
		||||
 | 
			
		||||
    switch (prop_id) {
 | 
			
		||||
    case PROP_KEYBOARD:
 | 
			
		||||
        g_value_set_object (value, priv->keyboard);
 | 
			
		||||
        break;
 | 
			
		||||
    default:
 | 
			
		||||
        g_object_get_property (object,
 | 
			
		||||
                               g_param_spec_get_name (pspec),
 | 
			
		||||
                               value);
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -601,6 +718,8 @@ eek_renderer_finalize (GObject *object)
 | 
			
		||||
{
 | 
			
		||||
    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->font);
 | 
			
		||||
    G_OBJECT_CLASS (eek_renderer_parent_class)->finalize (object);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -619,6 +738,7 @@ eek_renderer_class_init (EekRendererClass *klass)
 | 
			
		||||
    klass->render_keyboard = eek_renderer_real_render_keyboard;
 | 
			
		||||
 | 
			
		||||
    gobject_class->set_property = eek_renderer_set_property;
 | 
			
		||||
    gobject_class->get_property = eek_renderer_get_property;
 | 
			
		||||
    gobject_class->dispose = eek_renderer_dispose;
 | 
			
		||||
    gobject_class->finalize = eek_renderer_finalize;
 | 
			
		||||
 | 
			
		||||
@ -626,7 +746,7 @@ eek_renderer_class_init (EekRendererClass *klass)
 | 
			
		||||
                                 "Keyboard",
 | 
			
		||||
                                 "Keyboard",
 | 
			
		||||
                                 EEK_TYPE_KEYBOARD,
 | 
			
		||||
                                 G_PARAM_WRITABLE);
 | 
			
		||||
                                 G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE);
 | 
			
		||||
    g_object_class_install_property (gobject_class,
 | 
			
		||||
                                     PROP_KEYBOARD,
 | 
			
		||||
                                     pspec);
 | 
			
		||||
@ -635,18 +755,12 @@ eek_renderer_class_init (EekRendererClass *klass)
 | 
			
		||||
                                 "Pango Context",
 | 
			
		||||
                                 "Pango Context",
 | 
			
		||||
                                 PANGO_TYPE_CONTEXT,
 | 
			
		||||
                                 G_PARAM_WRITABLE);
 | 
			
		||||
                                 G_PARAM_CONSTRUCT_ONLY | G_PARAM_WRITABLE);
 | 
			
		||||
    g_object_class_install_property (gobject_class,
 | 
			
		||||
                                     PROP_PCONTEXT,
 | 
			
		||||
                                     pspec);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
free_surface (gpointer data)
 | 
			
		||||
{
 | 
			
		||||
    cairo_surface_destroy (data);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
eek_renderer_init (EekRenderer *self)
 | 
			
		||||
{
 | 
			
		||||
@ -655,16 +769,23 @@ eek_renderer_init (EekRenderer *self)
 | 
			
		||||
    priv = self->priv = EEK_RENDERER_GET_PRIVATE(self);
 | 
			
		||||
    priv->keyboard = NULL;
 | 
			
		||||
    priv->pcontext = NULL;
 | 
			
		||||
    priv->foreground = eek_color_new (0.3, 0.3, 0.3, 1.0);
 | 
			
		||||
    priv->background = eek_color_new (1.0, 1.0, 1.0, 1.0);
 | 
			
		||||
    priv->default_foreground_color = DEFAULT_FOREGROUND_COLOR;
 | 
			
		||||
    priv->default_background_color = DEFAULT_BACKGROUND_COLOR;
 | 
			
		||||
    priv->border_width = 1.0;
 | 
			
		||||
    priv->allocation_width = 0.0;
 | 
			
		||||
    priv->allocation_height = 0.0;
 | 
			
		||||
    priv->scale = 1.0;
 | 
			
		||||
    priv->font = NULL;
 | 
			
		||||
    priv->outline_surface_cache =
 | 
			
		||||
        g_hash_table_new_full (g_direct_hash,
 | 
			
		||||
                               g_direct_equal,
 | 
			
		||||
                               NULL,
 | 
			
		||||
                               free_surface);
 | 
			
		||||
                               (GDestroyNotify)cairo_surface_destroy);
 | 
			
		||||
    priv->active_outline_surface_cache =
 | 
			
		||||
        g_hash_table_new_full (g_direct_hash,
 | 
			
		||||
                               g_direct_equal,
 | 
			
		||||
                               NULL,
 | 
			
		||||
                               (GDestroyNotify)cairo_surface_destroy);
 | 
			
		||||
    priv->keyboard_surface = NULL;
 | 
			
		||||
    priv->symbol_index_changed_handler = 0;
 | 
			
		||||
}
 | 
			
		||||
@ -677,6 +798,9 @@ invalidate (EekRenderer *renderer)
 | 
			
		||||
    if (priv->outline_surface_cache)
 | 
			
		||||
        g_hash_table_remove_all (priv->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;
 | 
			
		||||
@ -721,6 +845,9 @@ eek_renderer_set_allocation_size (EekRenderer *renderer,
 | 
			
		||||
 | 
			
		||||
    priv = EEK_RENDERER_GET_PRIVATE(renderer);
 | 
			
		||||
 | 
			
		||||
    priv->allocation_width = width;
 | 
			
		||||
    priv->allocation_height = height;
 | 
			
		||||
 | 
			
		||||
    eek_element_get_bounds (EEK_ELEMENT(priv->keyboard), &bounds);
 | 
			
		||||
    scale = width > height ? height / bounds.height :
 | 
			
		||||
        width / bounds.width;
 | 
			
		||||
@ -873,6 +1000,24 @@ eek_renderer_render_key_outline (EekRenderer *renderer,
 | 
			
		||||
                                                          rotate);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
eek_renderer_render_key_icon (EekRenderer *renderer,
 | 
			
		||||
                                 cairo_t     *cr,
 | 
			
		||||
                                 EekKey      *key,
 | 
			
		||||
                                 gdouble      scale,
 | 
			
		||||
                                 gboolean     rotate)
 | 
			
		||||
{
 | 
			
		||||
    g_return_if_fail (EEK_IS_RENDERER(renderer));
 | 
			
		||||
    g_return_if_fail (EEK_IS_KEY(key));
 | 
			
		||||
    g_return_if_fail (scale >= 0.0);
 | 
			
		||||
 | 
			
		||||
    EEK_RENDERER_GET_CLASS(renderer)->render_key_icon (renderer,
 | 
			
		||||
                                                       cr,
 | 
			
		||||
                                                       key,
 | 
			
		||||
                                                       scale,
 | 
			
		||||
                                                       rotate);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
eek_renderer_render_key (EekRenderer *renderer,
 | 
			
		||||
                         cairo_t     *cr,
 | 
			
		||||
@ -897,55 +1042,94 @@ eek_renderer_render_keyboard (EekRenderer *renderer,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
eek_renderer_set_foreground (EekRenderer *renderer,
 | 
			
		||||
                             EekColor    *foreground)
 | 
			
		||||
eek_renderer_set_default_foreground_color (EekRenderer    *renderer,
 | 
			
		||||
                                           const EekColor *color)
 | 
			
		||||
{
 | 
			
		||||
    EekRendererPrivate *priv;
 | 
			
		||||
 | 
			
		||||
    g_return_if_fail (EEK_IS_RENDERER(renderer));
 | 
			
		||||
    g_return_if_fail (foreground);
 | 
			
		||||
    g_return_if_fail (color);
 | 
			
		||||
 | 
			
		||||
    priv = EEK_RENDERER_GET_PRIVATE(renderer);
 | 
			
		||||
    priv->foreground = g_boxed_copy (EEK_TYPE_COLOR, foreground);
 | 
			
		||||
    priv->default_foreground_color = *color;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
eek_renderer_set_background (EekRenderer *renderer,
 | 
			
		||||
                             EekColor    *background)
 | 
			
		||||
eek_renderer_set_default_background_color (EekRenderer    *renderer,
 | 
			
		||||
                                           const EekColor *color)
 | 
			
		||||
{
 | 
			
		||||
    EekRendererPrivate *priv;
 | 
			
		||||
 | 
			
		||||
    g_return_if_fail (EEK_IS_RENDERER(renderer));
 | 
			
		||||
    g_return_if_fail (background);
 | 
			
		||||
    g_return_if_fail (color);
 | 
			
		||||
 | 
			
		||||
    priv = EEK_RENDERER_GET_PRIVATE(renderer);
 | 
			
		||||
    priv->background = g_boxed_copy (EEK_TYPE_COLOR, background);
 | 
			
		||||
    priv->default_background_color = *color;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
eek_renderer_get_foreground (EekRenderer *renderer,
 | 
			
		||||
                             EekColor    *foreground)
 | 
			
		||||
eek_renderer_get_foreground_color (EekRenderer *renderer,
 | 
			
		||||
                                   EekElement  *element,
 | 
			
		||||
                                   EekColor    *color)
 | 
			
		||||
{
 | 
			
		||||
    EekRendererPrivate *priv;
 | 
			
		||||
    EekThemeNode *theme_node;
 | 
			
		||||
 | 
			
		||||
    g_return_if_fail (EEK_IS_RENDERER(renderer));
 | 
			
		||||
    g_return_if_fail (foreground);
 | 
			
		||||
    g_return_if_fail (color);
 | 
			
		||||
 | 
			
		||||
    priv = EEK_RENDERER_GET_PRIVATE(renderer);
 | 
			
		||||
    *foreground = *priv->foreground;
 | 
			
		||||
 | 
			
		||||
    theme_node = g_object_get_data (G_OBJECT(element), "theme-node");
 | 
			
		||||
    if (theme_node)
 | 
			
		||||
        eek_theme_node_get_foreground_color (theme_node, color);
 | 
			
		||||
    else
 | 
			
		||||
        *color = priv->default_foreground_color;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
eek_renderer_get_background (EekRenderer *renderer,
 | 
			
		||||
                             EekColor    *background)
 | 
			
		||||
eek_renderer_get_background_color (EekRenderer *renderer,
 | 
			
		||||
                                   EekElement  *element,
 | 
			
		||||
                                   EekColor    *color)
 | 
			
		||||
{
 | 
			
		||||
    EekRendererPrivate *priv;
 | 
			
		||||
    EekThemeNode *theme_node;
 | 
			
		||||
 | 
			
		||||
    g_return_if_fail (EEK_IS_RENDERER(renderer));
 | 
			
		||||
    g_return_if_fail (background);
 | 
			
		||||
    g_return_if_fail (color);
 | 
			
		||||
 | 
			
		||||
    priv = EEK_RENDERER_GET_PRIVATE(renderer);
 | 
			
		||||
    *background = *priv->background;
 | 
			
		||||
 | 
			
		||||
    theme_node = g_object_get_data (G_OBJECT(element), "theme-node");
 | 
			
		||||
    if (theme_node)
 | 
			
		||||
        eek_theme_node_get_background_color (theme_node, color);
 | 
			
		||||
    else
 | 
			
		||||
        *color = priv->default_background_color;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
eek_renderer_get_background_gradient (EekRenderer     *renderer,
 | 
			
		||||
                                      EekElement      *element,
 | 
			
		||||
                                      EekGradientType *type,
 | 
			
		||||
                                      EekColor        *start,
 | 
			
		||||
                                      EekColor        *end)
 | 
			
		||||
{
 | 
			
		||||
    EekRendererPrivate *priv;
 | 
			
		||||
    EekThemeNode *theme_node;
 | 
			
		||||
 | 
			
		||||
    g_return_if_fail (EEK_IS_RENDERER(renderer));
 | 
			
		||||
    g_return_if_fail (EEK_IS_ELEMENT(element));
 | 
			
		||||
    g_return_if_fail (type);
 | 
			
		||||
    g_return_if_fail (start);
 | 
			
		||||
    g_return_if_fail (end);
 | 
			
		||||
 | 
			
		||||
    priv = EEK_RENDERER_GET_PRIVATE(renderer);
 | 
			
		||||
 | 
			
		||||
    theme_node = g_object_get_data (G_OBJECT(element), "theme-node");
 | 
			
		||||
    if (theme_node)
 | 
			
		||||
        eek_theme_node_get_background_gradient (theme_node, type, start, end);
 | 
			
		||||
    else
 | 
			
		||||
        *type = EEK_GRADIENT_NONE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
struct _FindKeyByPositionCallbackData {
 | 
			
		||||
@ -1073,3 +1257,119 @@ eek_renderer_find_key_by_position (EekRenderer *renderer,
 | 
			
		||||
                        &data);
 | 
			
		||||
    return data.key;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
struct _CreateThemeNodeData {
 | 
			
		||||
    EekThemeContext *context;
 | 
			
		||||
    EekThemeNode *parent;
 | 
			
		||||
    EekRenderer *renderer;
 | 
			
		||||
};
 | 
			
		||||
typedef struct _CreateThemeNodeData CreateThemeNodeData;
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
create_theme_node_key_callback (EekElement *element,
 | 
			
		||||
                                gpointer    user_data)
 | 
			
		||||
{
 | 
			
		||||
    CreateThemeNodeData *data = user_data;
 | 
			
		||||
    EekRendererPrivate *priv;
 | 
			
		||||
    EekThemeNode *theme_node;
 | 
			
		||||
 | 
			
		||||
    priv = EEK_RENDERER_GET_PRIVATE(data->renderer);
 | 
			
		||||
 | 
			
		||||
    theme_node = eek_theme_node_new (data->context,
 | 
			
		||||
                                     data->parent,
 | 
			
		||||
                                     priv->theme,
 | 
			
		||||
                                     EEK_TYPE_KEY,
 | 
			
		||||
                                     eek_element_get_name (element),
 | 
			
		||||
                                     "key",
 | 
			
		||||
                                     NULL,
 | 
			
		||||
                                     NULL);
 | 
			
		||||
    g_object_set_data_full (G_OBJECT(element),
 | 
			
		||||
                            "theme-node",
 | 
			
		||||
                            theme_node,
 | 
			
		||||
                            (GDestroyNotify)g_object_unref);
 | 
			
		||||
 | 
			
		||||
    theme_node = eek_theme_node_new (data->context,
 | 
			
		||||
                                     data->parent,
 | 
			
		||||
                                     priv->theme,
 | 
			
		||||
                                     EEK_TYPE_KEY,
 | 
			
		||||
                                     eek_element_get_name (element),
 | 
			
		||||
                                     "key",
 | 
			
		||||
                                     "active",
 | 
			
		||||
                                     NULL);
 | 
			
		||||
    g_object_set_data_full (G_OBJECT(element),
 | 
			
		||||
                            "theme-node-pressed",
 | 
			
		||||
                            theme_node,
 | 
			
		||||
                            (GDestroyNotify)g_object_unref);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
create_theme_node_section_callback (EekElement *element,
 | 
			
		||||
                                    gpointer    user_data)
 | 
			
		||||
{
 | 
			
		||||
    CreateThemeNodeData *data = user_data;
 | 
			
		||||
    EekRendererPrivate *priv;
 | 
			
		||||
    EekThemeNode *theme_node, *parent;
 | 
			
		||||
 | 
			
		||||
    priv = EEK_RENDERER_GET_PRIVATE(data->renderer);
 | 
			
		||||
 | 
			
		||||
    theme_node = eek_theme_node_new (data->context,
 | 
			
		||||
                                     data->parent,
 | 
			
		||||
                                     priv->theme,
 | 
			
		||||
                                     EEK_TYPE_SECTION,
 | 
			
		||||
                                     eek_element_get_name (element),
 | 
			
		||||
                                     "section",
 | 
			
		||||
                                     NULL,
 | 
			
		||||
                                     NULL);
 | 
			
		||||
    g_object_set_data_full (G_OBJECT(element),
 | 
			
		||||
                            "theme-node",
 | 
			
		||||
                            theme_node,
 | 
			
		||||
                            (GDestroyNotify)g_object_unref);
 | 
			
		||||
 | 
			
		||||
    parent = data->parent;
 | 
			
		||||
    data->parent = theme_node;
 | 
			
		||||
    eek_container_foreach_child (EEK_CONTAINER(element),
 | 
			
		||||
                                 create_theme_node_key_callback,
 | 
			
		||||
                                 data);
 | 
			
		||||
    data->parent = parent;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
eek_renderer_set_theme (EekRenderer *renderer,
 | 
			
		||||
                        EekTheme    *theme)
 | 
			
		||||
{
 | 
			
		||||
    EekRendererPrivate *priv;
 | 
			
		||||
    EekThemeContext *theme_context;
 | 
			
		||||
    EekThemeNode *theme_node;
 | 
			
		||||
    CreateThemeNodeData data;
 | 
			
		||||
 | 
			
		||||
    g_assert (EEK_IS_RENDERER(renderer));
 | 
			
		||||
    g_assert (EEK_IS_THEME(theme));
 | 
			
		||||
 | 
			
		||||
    priv = EEK_RENDERER_GET_PRIVATE(renderer);
 | 
			
		||||
    g_assert (priv->keyboard);
 | 
			
		||||
 | 
			
		||||
    if (priv->theme)
 | 
			
		||||
        g_object_unref (priv->theme);
 | 
			
		||||
    priv->theme = g_object_ref (theme);
 | 
			
		||||
 | 
			
		||||
    theme_context = eek_theme_context_new ();
 | 
			
		||||
    theme_node = eek_theme_node_new (theme_context,
 | 
			
		||||
                                     NULL,
 | 
			
		||||
                                     priv->theme,
 | 
			
		||||
                                     EEK_TYPE_KEYBOARD,
 | 
			
		||||
                                     "keyboard",
 | 
			
		||||
                                     "keyboard",
 | 
			
		||||
                                     NULL,
 | 
			
		||||
                                     NULL);
 | 
			
		||||
    g_object_set_data_full (G_OBJECT(priv->keyboard),
 | 
			
		||||
                            "theme-node",
 | 
			
		||||
                            theme_node,
 | 
			
		||||
                            (GDestroyNotify)g_object_unref);
 | 
			
		||||
 | 
			
		||||
    data.context = theme_context;
 | 
			
		||||
    data.parent = theme_node;
 | 
			
		||||
    data.renderer = renderer;
 | 
			
		||||
    eek_container_foreach_child (EEK_CONTAINER(priv->keyboard),
 | 
			
		||||
                                 create_theme_node_section_callback,
 | 
			
		||||
                                 &data);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -25,6 +25,8 @@
 | 
			
		||||
#include "eek-keyboard.h"
 | 
			
		||||
#include "eek-keysym.h"
 | 
			
		||||
#include "eek-types.h"
 | 
			
		||||
#include "eek-theme.h"
 | 
			
		||||
#include "eek-theme-context.h"
 | 
			
		||||
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
@ -68,9 +70,15 @@ struct _EekRendererClass
 | 
			
		||||
    void (* render_keyboard)    (EekRenderer *self,
 | 
			
		||||
                                 cairo_t     *cr);
 | 
			
		||||
 | 
			
		||||
    void (* render_key_icon)    (EekRenderer *self,
 | 
			
		||||
                                 cairo_t     *cr,
 | 
			
		||||
                                 EekKey      *key,
 | 
			
		||||
                                 gdouble      scale,
 | 
			
		||||
                                 gboolean     rotate);
 | 
			
		||||
 | 
			
		||||
    /*< private >*/
 | 
			
		||||
    /* padding */
 | 
			
		||||
    gpointer pdummy[24];
 | 
			
		||||
    gpointer pdummy[23];
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
GType        eek_renderer_get_type             (void) G_GNUC_CONST;
 | 
			
		||||
@ -106,22 +114,47 @@ void         eek_renderer_render_key           (EekRenderer  *renderer,
 | 
			
		||||
                                                gdouble          scale,
 | 
			
		||||
                                                gboolean         rotate);
 | 
			
		||||
 | 
			
		||||
void         eek_renderer_render_key_icon      (EekRenderer     *renderer,
 | 
			
		||||
                                                cairo_t         *cr,
 | 
			
		||||
                                                EekKey          *key,
 | 
			
		||||
                                                gdouble          scale,
 | 
			
		||||
                                                gboolean         rotate);
 | 
			
		||||
 | 
			
		||||
void         eek_renderer_render_keyboard      (EekRenderer     *renderer,
 | 
			
		||||
                                                cairo_t         *cr);
 | 
			
		||||
 | 
			
		||||
void         eek_renderer_set_foreground       (EekRenderer  *renderer,
 | 
			
		||||
                                                EekColor     *foreground);
 | 
			
		||||
void         eek_renderer_set_background       (EekRenderer  *renderer,
 | 
			
		||||
                                                EekColor     *background);
 | 
			
		||||
void         eek_renderer_get_foreground       (EekRenderer  *renderer,
 | 
			
		||||
                                                EekColor     *foreground);
 | 
			
		||||
void         eek_renderer_get_background       (EekRenderer  *renderer,
 | 
			
		||||
                                                EekColor     *background);
 | 
			
		||||
void         eek_renderer_set_default_foreground_color
 | 
			
		||||
                                               (EekRenderer     *renderer,
 | 
			
		||||
                                                const EekColor  *color);
 | 
			
		||||
void         eek_renderer_set_default_background_color
 | 
			
		||||
                                               (EekRenderer     *renderer,
 | 
			
		||||
                                                const EekColor  *color);
 | 
			
		||||
void         eek_renderer_get_foreground_color (EekRenderer     *renderer,
 | 
			
		||||
                                                EekElement      *element,
 | 
			
		||||
                                                EekColor        *color);
 | 
			
		||||
void         eek_renderer_get_background_color (EekRenderer     *renderer,
 | 
			
		||||
                                                EekElement      *element,
 | 
			
		||||
                                                EekColor        *color);
 | 
			
		||||
void         eek_renderer_get_background_gradient
 | 
			
		||||
                                               (EekRenderer     *renderer,
 | 
			
		||||
                                                EekElement      *element,
 | 
			
		||||
                                                EekGradientType *type,
 | 
			
		||||
                                                EekColor        *start,
 | 
			
		||||
                                                EekColor        *end);
 | 
			
		||||
void         eek_renderer_set_border_width     (EekRenderer     *renderer,
 | 
			
		||||
                                                gdouble          border_width);
 | 
			
		||||
EekKey      *eek_renderer_find_key_by_position (EekRenderer     *renderer,
 | 
			
		||||
                                                gdouble          x,
 | 
			
		||||
                                                gdouble          y);
 | 
			
		||||
void         eek_renderer_apply_transformation_for_key
 | 
			
		||||
                                               (EekRenderer     *renderer,
 | 
			
		||||
                                                cairo_t         *cr,
 | 
			
		||||
                                                EekKey          *key,
 | 
			
		||||
                                                gdouble          scale,
 | 
			
		||||
                                                gboolean         rotate);
 | 
			
		||||
 | 
			
		||||
void         eek_renderer_set_theme            (EekRenderer     *renderer,
 | 
			
		||||
                                                EekTheme        *theme);
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
#endif  /* EEK_RENDERER_H */
 | 
			
		||||
 | 
			
		||||
@ -27,13 +27,16 @@
 | 
			
		||||
 * of one or more keys of the #EekKeyClass class.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_CONFIG_H
 | 
			
		||||
#include "config.h"
 | 
			
		||||
#endif  /* HAVE_CONFIG_H */
 | 
			
		||||
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
#include "eek-keyboard.h"
 | 
			
		||||
#include "eek-section.h"
 | 
			
		||||
#include "eek-key.h"
 | 
			
		||||
#include "eek-symbol.h"
 | 
			
		||||
#include "eek-serializable.h"
 | 
			
		||||
 | 
			
		||||
enum {
 | 
			
		||||
@ -71,6 +74,7 @@ struct _EekSectionPrivate
 | 
			
		||||
{
 | 
			
		||||
    gint angle;
 | 
			
		||||
    GSList *rows;
 | 
			
		||||
    EekModifierType modifiers;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static EekSerializableIface *eek_section_parent_serializable_iface;
 | 
			
		||||
@ -262,6 +266,73 @@ eek_section_real_find_key_by_keycode (EekSection *self,
 | 
			
		||||
                                         (gpointer)(long)keycode);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
set_level_from_modifiers (EekSection *self)
 | 
			
		||||
{
 | 
			
		||||
    EekSectionPrivate *priv = EEK_SECTION_GET_PRIVATE(self);
 | 
			
		||||
    EekKeyboard *keyboard;
 | 
			
		||||
    EekModifierType num_lock_mask;
 | 
			
		||||
    gint level = -1;
 | 
			
		||||
 | 
			
		||||
    keyboard = EEK_KEYBOARD(eek_element_get_parent (EEK_ELEMENT(self)));
 | 
			
		||||
    num_lock_mask = eek_keyboard_get_num_lock_mask (keyboard);
 | 
			
		||||
    if (priv->modifiers & num_lock_mask)
 | 
			
		||||
        level = 1;
 | 
			
		||||
    eek_element_set_level (EEK_ELEMENT(self), level);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
eek_section_real_key_pressed (EekSection *self, EekKey *key)
 | 
			
		||||
{
 | 
			
		||||
    EekSectionPrivate *priv = EEK_SECTION_GET_PRIVATE(self);
 | 
			
		||||
    EekSymbol *symbol;
 | 
			
		||||
    EekKeyboard *keyboard;
 | 
			
		||||
    EekModifierBehavior behavior;
 | 
			
		||||
    EekModifierType modifier;
 | 
			
		||||
 | 
			
		||||
    symbol = eek_key_get_symbol_with_fallback (key, 0, 0);
 | 
			
		||||
    if (!symbol)
 | 
			
		||||
        return;
 | 
			
		||||
 | 
			
		||||
    keyboard = EEK_KEYBOARD(eek_element_get_parent (EEK_ELEMENT(self)));
 | 
			
		||||
    behavior = eek_keyboard_get_modifier_behavior (keyboard);
 | 
			
		||||
    modifier = eek_symbol_get_modifier_mask (symbol);
 | 
			
		||||
    if (behavior == EEK_MODIFIER_BEHAVIOR_NONE) {
 | 
			
		||||
        priv->modifiers |= modifier;
 | 
			
		||||
        set_level_from_modifiers (self);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
eek_section_real_key_released (EekSection *self, EekKey *key)
 | 
			
		||||
{
 | 
			
		||||
    EekSectionPrivate *priv = EEK_SECTION_GET_PRIVATE(self);
 | 
			
		||||
    EekSymbol *symbol;
 | 
			
		||||
    EekKeyboard *keyboard;
 | 
			
		||||
    EekModifierBehavior behavior;
 | 
			
		||||
    EekModifierType modifier;
 | 
			
		||||
 | 
			
		||||
    symbol = eek_key_get_symbol_with_fallback (key, 0, 0);
 | 
			
		||||
    if (!symbol)
 | 
			
		||||
        return;
 | 
			
		||||
 | 
			
		||||
    keyboard = EEK_KEYBOARD(eek_element_get_parent (EEK_ELEMENT(self)));
 | 
			
		||||
    behavior = eek_keyboard_get_modifier_behavior (keyboard);
 | 
			
		||||
    modifier = eek_symbol_get_modifier_mask (symbol);
 | 
			
		||||
    switch (behavior) {
 | 
			
		||||
    case EEK_MODIFIER_BEHAVIOR_NONE:
 | 
			
		||||
        priv->modifiers &= ~modifier;
 | 
			
		||||
        break;
 | 
			
		||||
    case EEK_MODIFIER_BEHAVIOR_LOCK:
 | 
			
		||||
        priv->modifiers ^= modifier;
 | 
			
		||||
        break;
 | 
			
		||||
    case EEK_MODIFIER_BEHAVIOR_LATCH:
 | 
			
		||||
        priv->modifiers = (priv->modifiers ^ modifier) & modifier;
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
    set_level_from_modifiers (self);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
eek_section_finalize (GObject *object)
 | 
			
		||||
{
 | 
			
		||||
@ -346,6 +417,9 @@ eek_section_class_init (EekSectionClass *klass)
 | 
			
		||||
    klass->find_key_by_keycode = eek_section_real_find_key_by_keycode;
 | 
			
		||||
 | 
			
		||||
    /* signals */
 | 
			
		||||
    klass->key_pressed = eek_section_real_key_pressed;
 | 
			
		||||
    klass->key_released = eek_section_real_key_released;
 | 
			
		||||
 | 
			
		||||
    container_class->child_added = eek_section_real_child_added;
 | 
			
		||||
    container_class->child_removed = eek_section_real_child_removed;
 | 
			
		||||
 | 
			
		||||
@ -376,10 +450,10 @@ eek_section_class_init (EekSectionClass *klass)
 | 
			
		||||
     * is shifted to the pressed state.
 | 
			
		||||
     */
 | 
			
		||||
    signals[KEY_PRESSED] =
 | 
			
		||||
        g_signal_new ("key-pressed",
 | 
			
		||||
        g_signal_new (I_("key-pressed"),
 | 
			
		||||
                      G_TYPE_FROM_CLASS(gobject_class),
 | 
			
		||||
                      G_SIGNAL_RUN_FIRST,
 | 
			
		||||
                      0,
 | 
			
		||||
                      G_SIGNAL_RUN_LAST,
 | 
			
		||||
                      G_STRUCT_OFFSET(EekSectionClass, key_pressed),
 | 
			
		||||
                      NULL,
 | 
			
		||||
                      NULL,
 | 
			
		||||
                      g_cclosure_marshal_VOID__OBJECT,
 | 
			
		||||
@ -396,10 +470,10 @@ eek_section_class_init (EekSectionClass *klass)
 | 
			
		||||
     * is shifted to the released state.
 | 
			
		||||
     */
 | 
			
		||||
    signals[KEY_RELEASED] =
 | 
			
		||||
        g_signal_new ("key-released",
 | 
			
		||||
        g_signal_new (I_("key-released"),
 | 
			
		||||
                      G_TYPE_FROM_CLASS(gobject_class),
 | 
			
		||||
                      G_SIGNAL_RUN_FIRST,
 | 
			
		||||
                      0,
 | 
			
		||||
                      G_SIGNAL_RUN_LAST,
 | 
			
		||||
                      G_STRUCT_OFFSET(EekSectionClass, key_released),
 | 
			
		||||
                      NULL,
 | 
			
		||||
                      NULL,
 | 
			
		||||
                      g_cclosure_marshal_VOID__OBJECT,
 | 
			
		||||
@ -416,6 +490,7 @@ eek_section_init (EekSection *self)
 | 
			
		||||
    priv = self->priv = EEK_SECTION_GET_PRIVATE (self);
 | 
			
		||||
    priv->angle = 0;
 | 
			
		||||
    priv->rows = NULL;
 | 
			
		||||
    priv->modifiers = 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 | 
			
		||||
@ -81,9 +81,15 @@ struct _EekSectionClass
 | 
			
		||||
    EekKey *(* find_key_by_keycode) (EekSection     *self,
 | 
			
		||||
                                     guint           keycode);
 | 
			
		||||
 | 
			
		||||
    /* signals */
 | 
			
		||||
    void    (* key_pressed)         (EekSection     *self,
 | 
			
		||||
                                     EekKey         *key);
 | 
			
		||||
    void    (* key_released)        (EekSection     *self,
 | 
			
		||||
                                     EekKey         *key);
 | 
			
		||||
 | 
			
		||||
    /*< private >*/
 | 
			
		||||
    /* padding */
 | 
			
		||||
    gpointer pdummy[24];
 | 
			
		||||
    gpointer pdummy[22];
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
GType   eek_section_get_type             (void) G_GNUC_CONST;
 | 
			
		||||
 | 
			
		||||
@ -17,6 +17,20 @@
 | 
			
		||||
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 | 
			
		||||
 * Boston, MA 02111-1307, USA.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * SECTION:eek-serializable
 | 
			
		||||
 * @short_description: Interface implemented by #EekElement to
 | 
			
		||||
 * serialize it to #GVariant
 | 
			
		||||
 *
 | 
			
		||||
 * The #EekSerializableIface interface defines serialize/deserialize
 | 
			
		||||
 * method of #EekElement.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_CONFIG_H
 | 
			
		||||
#include "config.h"
 | 
			
		||||
#endif  /* HAVE_CONFIG_H */
 | 
			
		||||
 | 
			
		||||
#include "eek-serializable.h"
 | 
			
		||||
 | 
			
		||||
GType
 | 
			
		||||
 | 
			
		||||
@ -31,6 +31,12 @@ G_BEGIN_DECLS
 | 
			
		||||
typedef struct _EekSerializable EekSerializable;
 | 
			
		||||
typedef struct _EekSerializableIface EekSerializableIface;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * EekSerializableIface:
 | 
			
		||||
 *
 | 
			
		||||
 * @serialize: virtual function for serializing object into #GVariant
 | 
			
		||||
 * @deserialize: virtual function for deserializing object from #GVariant
 | 
			
		||||
 */
 | 
			
		||||
struct _EekSerializableIface
 | 
			
		||||
{
 | 
			
		||||
    /*< private >*/
 | 
			
		||||
@ -41,8 +47,6 @@ struct _EekSerializableIface
 | 
			
		||||
    gsize (* deserialize) (EekSerializable       *object,
 | 
			
		||||
                           GVariant              *variant,
 | 
			
		||||
                           gsize                  index);
 | 
			
		||||
    void  (* copy)        (EekSerializable       *dest,
 | 
			
		||||
                           const EekSerializable *src);
 | 
			
		||||
 | 
			
		||||
    /*< private >*/
 | 
			
		||||
    /* padding */
 | 
			
		||||
@ -51,7 +55,6 @@ struct _EekSerializableIface
 | 
			
		||||
 | 
			
		||||
GType            eek_serializable_get_type    (void);
 | 
			
		||||
 | 
			
		||||
EekSerializable *eek_serializable_copy        (EekSerializable *object);
 | 
			
		||||
GVariant        *eek_serializable_serialize   (EekSerializable *object);
 | 
			
		||||
EekSerializable *eek_serializable_deserialize (GVariant        *variant);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										139
									
								
								eek/eek-symbol.c
									
									
									
									
									
								
							
							
						
						
									
										139
									
								
								eek/eek-symbol.c
									
									
									
									
									
								
							@ -18,6 +18,13 @@
 | 
			
		||||
 * 02110-1301 USA
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * SECTION:eek-symbol
 | 
			
		||||
 * @short_description: Base class of a symbol
 | 
			
		||||
 *
 | 
			
		||||
 * The #EekSymbolClass class represents a symbol assigned to a key.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_CONFIG_H
 | 
			
		||||
#include "config.h"
 | 
			
		||||
#endif  /* HAVE_CONFIG_H */
 | 
			
		||||
@ -31,6 +38,7 @@ enum {
 | 
			
		||||
    PROP_LABEL,
 | 
			
		||||
    PROP_CATEGORY,
 | 
			
		||||
    PROP_MODIFIER_MASK,
 | 
			
		||||
    PROP_ICON_NAME,
 | 
			
		||||
    PROP_LAST
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
@ -39,6 +47,7 @@ struct _EekSymbolPrivate {
 | 
			
		||||
    gchar *label;
 | 
			
		||||
    EekSymbolCategory category;
 | 
			
		||||
    EekModifierType modifier_mask;
 | 
			
		||||
    gchar *icon_name;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static void eek_serializable_iface_init (EekSerializableIface *iface);
 | 
			
		||||
@ -55,11 +64,13 @@ eek_symbol_real_serialize (EekSerializable *self,
 | 
			
		||||
                           GVariantBuilder *builder)
 | 
			
		||||
{
 | 
			
		||||
    EekSymbolPrivate *priv = EEK_SYMBOL_GET_PRIVATE(self);
 | 
			
		||||
 | 
			
		||||
    g_variant_builder_add (builder, "s", priv->name);
 | 
			
		||||
    g_variant_builder_add (builder, "s", priv->label);
 | 
			
		||||
#define NOTNULL(s) ((s) != NULL ? (s) : "")
 | 
			
		||||
    g_variant_builder_add (builder, "s", NOTNULL(priv->name));
 | 
			
		||||
    g_variant_builder_add (builder, "s", NOTNULL(priv->label));
 | 
			
		||||
    g_variant_builder_add (builder, "u", priv->category);
 | 
			
		||||
    g_variant_builder_add (builder, "u", priv->modifier_mask);
 | 
			
		||||
    g_variant_builder_add (builder, "s", NOTNULL(priv->icon_name));
 | 
			
		||||
#undef NOTNULL
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gsize
 | 
			
		||||
@ -73,6 +84,7 @@ eek_symbol_real_deserialize (EekSerializable *self,
 | 
			
		||||
    g_variant_get_child (variant, index++, "s", &priv->label);
 | 
			
		||||
    g_variant_get_child (variant, index++, "u", &priv->category);
 | 
			
		||||
    g_variant_get_child (variant, index++, "u", &priv->modifier_mask);
 | 
			
		||||
    g_variant_get_child (variant, index++, "s", &priv->icon_name);
 | 
			
		||||
 | 
			
		||||
    return index;
 | 
			
		||||
}
 | 
			
		||||
@ -104,6 +116,10 @@ eek_symbol_set_property (GObject      *object,
 | 
			
		||||
        eek_symbol_set_modifier_mask (EEK_SYMBOL(object),
 | 
			
		||||
                                      g_value_get_uint (value));
 | 
			
		||||
        break;
 | 
			
		||||
    case PROP_ICON_NAME:
 | 
			
		||||
        eek_symbol_set_icon_name (EEK_SYMBOL(object),
 | 
			
		||||
                                  g_value_get_string (value));
 | 
			
		||||
        break;
 | 
			
		||||
    default:
 | 
			
		||||
        g_object_set_property (object,
 | 
			
		||||
                               g_param_spec_get_name (pspec),
 | 
			
		||||
@ -132,6 +148,10 @@ eek_symbol_get_property (GObject    *object,
 | 
			
		||||
        g_value_set_uint (value,
 | 
			
		||||
                          eek_symbol_get_modifier_mask (EEK_SYMBOL(object)));
 | 
			
		||||
        break;
 | 
			
		||||
    case PROP_ICON_NAME:
 | 
			
		||||
        g_value_set_string (value,
 | 
			
		||||
                            eek_symbol_get_icon_name (EEK_SYMBOL(object)));
 | 
			
		||||
        break;
 | 
			
		||||
    default:
 | 
			
		||||
        g_object_get_property (object,
 | 
			
		||||
                               g_param_spec_get_name (pspec),
 | 
			
		||||
@ -146,6 +166,8 @@ eek_symbol_finalize (GObject *object)
 | 
			
		||||
    EekSymbolPrivate *priv = EEK_SYMBOL_GET_PRIVATE(object);
 | 
			
		||||
 | 
			
		||||
    g_free (priv->name);
 | 
			
		||||
    g_free (priv->label);
 | 
			
		||||
    g_free (priv->icon_name);
 | 
			
		||||
    G_OBJECT_CLASS (eek_symbol_parent_class)->finalize (object);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -188,6 +210,13 @@ eek_symbol_class_init (EekSymbolClass *klass)
 | 
			
		||||
                               0, G_MAXUINT, 0,
 | 
			
		||||
                               G_PARAM_CONSTRUCT | G_PARAM_READWRITE);
 | 
			
		||||
    g_object_class_install_property (gobject_class, PROP_MODIFIER_MASK, pspec);
 | 
			
		||||
 | 
			
		||||
    pspec = g_param_spec_string ("icon-name",
 | 
			
		||||
                                 "Icon name",
 | 
			
		||||
                                 "Icon name used to render the symbol",
 | 
			
		||||
                                 NULL,
 | 
			
		||||
                                 G_PARAM_CONSTRUCT | G_PARAM_READWRITE);
 | 
			
		||||
    g_object_class_install_property (gobject_class, PROP_ICON_NAME, pspec);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
@ -198,16 +227,30 @@ eek_symbol_init (EekSymbol *self)
 | 
			
		||||
    priv = self->priv = EEK_SYMBOL_GET_PRIVATE(self);
 | 
			
		||||
    priv->name = NULL;
 | 
			
		||||
    priv->label = NULL;
 | 
			
		||||
    priv->icon_name = NULL;
 | 
			
		||||
    priv->category = EEK_SYMBOL_CATEGORY_UNKNOWN;
 | 
			
		||||
    priv->modifier_mask = 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eek_symbol_new:
 | 
			
		||||
 * @name: name of the symbol
 | 
			
		||||
 *
 | 
			
		||||
 * Create a new #EekSymbol with @name.
 | 
			
		||||
 */
 | 
			
		||||
EekSymbol *
 | 
			
		||||
eek_symbol_new (const gchar *name)
 | 
			
		||||
{
 | 
			
		||||
    return g_object_new (EEK_TYPE_SYMBOL, "name", name);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eek_symbol_set_name:
 | 
			
		||||
 * @symbol: an #EekSymbol
 | 
			
		||||
 * @name: name of the symbol
 | 
			
		||||
 *
 | 
			
		||||
 * Set the name of @symbol to @name.
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
eek_symbol_set_name (EekSymbol   *symbol,
 | 
			
		||||
                     const gchar *name)
 | 
			
		||||
@ -221,6 +264,12 @@ eek_symbol_set_name (EekSymbol   *symbol,
 | 
			
		||||
    priv->name = g_strdup (name);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eek_symbol_get_name:
 | 
			
		||||
 * @symbol: an #EekSymbol
 | 
			
		||||
 *
 | 
			
		||||
 * Get the name of @symbol.
 | 
			
		||||
 */
 | 
			
		||||
G_CONST_RETURN gchar *
 | 
			
		||||
eek_symbol_get_name (EekSymbol *symbol)
 | 
			
		||||
{
 | 
			
		||||
@ -229,9 +278,18 @@ eek_symbol_get_name (EekSymbol *symbol)
 | 
			
		||||
    g_return_val_if_fail (EEK_IS_SYMBOL(symbol), NULL);
 | 
			
		||||
 | 
			
		||||
    priv = EEK_SYMBOL_GET_PRIVATE(symbol);
 | 
			
		||||
    if (priv->name == NULL || *priv->name == '\0')
 | 
			
		||||
        return NULL;
 | 
			
		||||
    return priv->name;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eek_symbol_set_label:
 | 
			
		||||
 * @symbol: an #EekSymbol
 | 
			
		||||
 * @label: label text of @symbol
 | 
			
		||||
 *
 | 
			
		||||
 * Set the label text of @symbol to @label.
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
eek_symbol_set_label (EekSymbol   *symbol,
 | 
			
		||||
                      const gchar *label)
 | 
			
		||||
@ -245,7 +303,13 @@ eek_symbol_set_label (EekSymbol   *symbol,
 | 
			
		||||
    priv->label = g_strdup (label);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
gchar *
 | 
			
		||||
/**
 | 
			
		||||
 * eek_symbol_get_label:
 | 
			
		||||
 * @symbol: an #EekSymbol
 | 
			
		||||
 *
 | 
			
		||||
 * Get the label text of @symbol.
 | 
			
		||||
 */
 | 
			
		||||
G_CONST_RETURN gchar *
 | 
			
		||||
eek_symbol_get_label (EekSymbol *symbol)
 | 
			
		||||
{
 | 
			
		||||
    EekSymbolPrivate *priv;
 | 
			
		||||
@ -253,9 +317,18 @@ eek_symbol_get_label (EekSymbol *symbol)
 | 
			
		||||
    g_return_val_if_fail (EEK_IS_SYMBOL(symbol), NULL);
 | 
			
		||||
 | 
			
		||||
    priv = EEK_SYMBOL_GET_PRIVATE(symbol);
 | 
			
		||||
    return g_strdup (priv->label);
 | 
			
		||||
    if (priv->label == NULL || *priv->label == '\0')
 | 
			
		||||
        return NULL;
 | 
			
		||||
    return priv->label;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eek_symbol_set_category:
 | 
			
		||||
 * @symbol: an #EekSymbol
 | 
			
		||||
 * @category: an #EekSymbolCategory
 | 
			
		||||
 *
 | 
			
		||||
 * Set symbol category of @symbol to @category.
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
eek_symbol_set_category (EekSymbol        *symbol,
 | 
			
		||||
                         EekSymbolCategory category)
 | 
			
		||||
@ -268,6 +341,12 @@ eek_symbol_set_category (EekSymbol        *symbol,
 | 
			
		||||
    priv->category = category;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eek_symbol_get_category:
 | 
			
		||||
 * @symbol: an #EekSymbol
 | 
			
		||||
 *
 | 
			
		||||
 * Get symbol category of @symbol.
 | 
			
		||||
 */
 | 
			
		||||
EekSymbolCategory
 | 
			
		||||
eek_symbol_get_category (EekSymbol *symbol)
 | 
			
		||||
{
 | 
			
		||||
@ -279,6 +358,12 @@ eek_symbol_get_category (EekSymbol *symbol)
 | 
			
		||||
    return priv->category;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eek_symbol_set_modifier_mask:
 | 
			
		||||
 * @symbol: an #EekSymbol
 | 
			
		||||
 *
 | 
			
		||||
 * Set modifier mask @symbol can trigger.
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
eek_symbol_set_modifier_mask (EekSymbol      *symbol,
 | 
			
		||||
                              EekModifierType mask)
 | 
			
		||||
@ -291,6 +376,12 @@ eek_symbol_set_modifier_mask (EekSymbol      *symbol,
 | 
			
		||||
    priv->modifier_mask = mask;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eek_symbol_get_modifier_mask:
 | 
			
		||||
 * @symbol: an #EekSymbol
 | 
			
		||||
 *
 | 
			
		||||
 * Get modifier mask @symbol can trigger.
 | 
			
		||||
 */
 | 
			
		||||
EekModifierType
 | 
			
		||||
eek_symbol_get_modifier_mask (EekSymbol *symbol)
 | 
			
		||||
{
 | 
			
		||||
@ -315,3 +406,41 @@ eek_symbol_is_modifier (EekSymbol *symbol)
 | 
			
		||||
    return eek_symbol_get_modifier_mask (symbol) != 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eek_symbol_set_icon_name:
 | 
			
		||||
 * @symbol: an #EekSymbol
 | 
			
		||||
 * @icon_name: icon name of @symbol
 | 
			
		||||
 *
 | 
			
		||||
 * Set the icon name of @symbol to @icon_name.
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
eek_symbol_set_icon_name (EekSymbol   *symbol,
 | 
			
		||||
                          const gchar *icon_name)
 | 
			
		||||
{
 | 
			
		||||
    EekSymbolPrivate *priv;
 | 
			
		||||
 | 
			
		||||
    g_return_if_fail (EEK_IS_SYMBOL(symbol));
 | 
			
		||||
 | 
			
		||||
    priv = EEK_SYMBOL_GET_PRIVATE(symbol);
 | 
			
		||||
    g_free (priv->icon_name);
 | 
			
		||||
    priv->icon_name = g_strdup (icon_name);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eek_symbol_get_icon_name:
 | 
			
		||||
 * @symbol: an #EekSymbol
 | 
			
		||||
 *
 | 
			
		||||
 * Get the icon name of @symbol.
 | 
			
		||||
 */
 | 
			
		||||
G_CONST_RETURN gchar *
 | 
			
		||||
eek_symbol_get_icon_name (EekSymbol *symbol)
 | 
			
		||||
{
 | 
			
		||||
    EekSymbolPrivate *priv;
 | 
			
		||||
 | 
			
		||||
    g_return_val_if_fail (EEK_IS_SYMBOL(symbol), NULL);
 | 
			
		||||
 | 
			
		||||
    priv = EEK_SYMBOL_GET_PRIVATE(symbol);
 | 
			
		||||
    if (priv->icon_name == NULL || *priv->icon_name == '\0')
 | 
			
		||||
        return NULL;
 | 
			
		||||
    return priv->icon_name;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -31,6 +31,11 @@ G_BEGIN_DECLS
 | 
			
		||||
 * @EEK_SYMBOL_CATEGORY_FUNCTION: the symbol represents a function
 | 
			
		||||
 * @EEK_SYMBOL_CATEGORY_KEYNAME: the symbol does not have meaning but
 | 
			
		||||
 * have a name
 | 
			
		||||
 * @EEK_SYMBOL_CATEGORY_USER0: reserved for future use
 | 
			
		||||
 * @EEK_SYMBOL_CATEGORY_USER1: reserved for future use
 | 
			
		||||
 * @EEK_SYMBOL_CATEGORY_USER2: reserved for future use
 | 
			
		||||
 * @EEK_SYMBOL_CATEGORY_USER3: reserved for future use
 | 
			
		||||
 * @EEK_SYMBOL_CATEGORY_USER4: reserved for future use
 | 
			
		||||
 * @EEK_SYMBOL_CATEGORY_UNKNOWN: used for error reporting
 | 
			
		||||
 *
 | 
			
		||||
 * Category of the key symbols.
 | 
			
		||||
@ -59,6 +64,12 @@ typedef enum {
 | 
			
		||||
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;
 | 
			
		||||
@ -66,6 +77,9 @@ struct _EekSymbol {
 | 
			
		||||
    EekSymbolPrivate *priv;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * EekSymbolClass:
 | 
			
		||||
 */
 | 
			
		||||
struct _EekSymbolClass {
 | 
			
		||||
    /*< private >*/
 | 
			
		||||
    GObjectClass parent_class;
 | 
			
		||||
@ -79,14 +93,19 @@ void                  eek_symbol_set_name          (EekSymbol        *symbol,
 | 
			
		||||
G_CONST_RETURN gchar *eek_symbol_get_name      (EekSymbol        *symbol);
 | 
			
		||||
void                  eek_symbol_set_label     (EekSymbol        *symbol,
 | 
			
		||||
                                                const gchar      *label);
 | 
			
		||||
gchar                *eek_symbol_get_label         (EekSymbol        *symbol);
 | 
			
		||||
G_CONST_RETURN gchar *eek_symbol_get_label     (EekSymbol        *symbol);
 | 
			
		||||
void                  eek_symbol_set_category  (EekSymbol        *symbol,
 | 
			
		||||
                                                EekSymbolCategory category);
 | 
			
		||||
EekSymbolCategory     eek_symbol_get_category  (EekSymbol        *symbol);
 | 
			
		||||
EekModifierType       eek_symbol_get_modifier_mask (EekSymbol        *keysym);
 | 
			
		||||
void                  eek_symbol_set_modifier_mask (EekSymbol        *keysym,
 | 
			
		||||
EekModifierType       eek_symbol_get_modifier_mask
 | 
			
		||||
                                               (EekSymbol        *keysym);
 | 
			
		||||
void                  eek_symbol_set_modifier_mask
 | 
			
		||||
                                               (EekSymbol        *keysym,
 | 
			
		||||
                                                EekModifierType   mask);
 | 
			
		||||
gboolean              eek_symbol_is_modifier   (EekSymbol        *symbol);
 | 
			
		||||
void                  eek_symbol_set_icon_name (EekSymbol        *symbol,
 | 
			
		||||
                                                const gchar      *icon_name);
 | 
			
		||||
G_CONST_RETURN gchar *eek_symbol_get_icon_name (EekSymbol        *symbol);
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										288
									
								
								eek/eek-theme-context.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										288
									
								
								eek/eek-theme-context.c
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,288 @@
 | 
			
		||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; c-basic-offset: 2; -*- */
 | 
			
		||||
/*
 | 
			
		||||
 * eek-theme-context.c: holds global information about a tree of styled objects
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright 2009, 2010 Red Hat, Inc.
 | 
			
		||||
 * Copyright 2009 Florian Müllner
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU Lesser General Public License as
 | 
			
		||||
 * published by the Free Software Foundation, either version 2.1 of
 | 
			
		||||
 * the License, or (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is distributed in the hope it will be useful, but WITHOUT ANY
 | 
			
		||||
 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 | 
			
		||||
 * FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for
 | 
			
		||||
 * more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General Public License
 | 
			
		||||
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_CONFIG_H
 | 
			
		||||
#include "config.h"
 | 
			
		||||
#endif  /* HAVE_CONFIG_H */
 | 
			
		||||
 | 
			
		||||
#include "eek-theme.h"
 | 
			
		||||
#include "eek-theme-context.h"
 | 
			
		||||
 | 
			
		||||
struct _EekThemeContext {
 | 
			
		||||
  GObject parent;
 | 
			
		||||
 | 
			
		||||
  double resolution;
 | 
			
		||||
  PangoFontDescription *font;
 | 
			
		||||
  EekThemeNode *root_node;
 | 
			
		||||
  EekTheme *theme;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct _EekThemeContextClass {
 | 
			
		||||
  GObjectClass parent_class;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#define DEFAULT_RESOLUTION 96.
 | 
			
		||||
#define DEFAULT_FONT "sans-serif 10"
 | 
			
		||||
 | 
			
		||||
enum
 | 
			
		||||
{
 | 
			
		||||
  CHANGED,
 | 
			
		||||
 | 
			
		||||
  LAST_SIGNAL
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static guint signals[LAST_SIGNAL] = { 0, };
 | 
			
		||||
 | 
			
		||||
G_DEFINE_TYPE (EekThemeContext, eek_theme_context, G_TYPE_OBJECT)
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
eek_theme_context_finalize (GObject *object)
 | 
			
		||||
{
 | 
			
		||||
  EekThemeContext *context = EEK_THEME_CONTEXT (object);
 | 
			
		||||
 | 
			
		||||
  if (context->root_node)
 | 
			
		||||
    g_object_unref (context->root_node);
 | 
			
		||||
  if (context->theme)
 | 
			
		||||
    g_object_unref (context->theme);
 | 
			
		||||
 | 
			
		||||
  pango_font_description_free (context->font);
 | 
			
		||||
 | 
			
		||||
  G_OBJECT_CLASS (eek_theme_context_parent_class)->finalize (object);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
eek_theme_context_class_init (EekThemeContextClass *klass)
 | 
			
		||||
{
 | 
			
		||||
  GObjectClass *object_class = G_OBJECT_CLASS (klass);
 | 
			
		||||
 | 
			
		||||
  object_class->finalize = eek_theme_context_finalize;
 | 
			
		||||
 | 
			
		||||
  signals[CHANGED] =
 | 
			
		||||
    g_signal_new ("changed",
 | 
			
		||||
                  G_TYPE_FROM_CLASS (klass),
 | 
			
		||||
                  G_SIGNAL_RUN_LAST,
 | 
			
		||||
                  0, /* no default handler slot */
 | 
			
		||||
                  NULL, NULL,
 | 
			
		||||
                  g_cclosure_marshal_VOID__VOID,
 | 
			
		||||
                  G_TYPE_NONE, 0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
eek_theme_context_init (EekThemeContext *context)
 | 
			
		||||
{
 | 
			
		||||
  context->resolution = DEFAULT_RESOLUTION;
 | 
			
		||||
  context->font = pango_font_description_from_string (DEFAULT_FONT);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eek_theme_context_new:
 | 
			
		||||
 *
 | 
			
		||||
 * Create a new theme context.
 | 
			
		||||
 */
 | 
			
		||||
EekThemeContext *
 | 
			
		||||
eek_theme_context_new (void)
 | 
			
		||||
{
 | 
			
		||||
  EekThemeContext *context;
 | 
			
		||||
 | 
			
		||||
  context = g_object_new (EEK_TYPE_THEME_CONTEXT, NULL);
 | 
			
		||||
 | 
			
		||||
  return context;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
eek_theme_context_changed (EekThemeContext *context)
 | 
			
		||||
{
 | 
			
		||||
  EekThemeNode *old_root = context->root_node;
 | 
			
		||||
  context->root_node = NULL;
 | 
			
		||||
 | 
			
		||||
  g_signal_emit (context, signals[CHANGED], 0);
 | 
			
		||||
 | 
			
		||||
  if (old_root)
 | 
			
		||||
    g_object_unref (old_root);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eek_theme_context_set_theme:
 | 
			
		||||
 * @context: a #EekThemeContext
 | 
			
		||||
 *
 | 
			
		||||
 * Sets the default set of theme stylesheets for the context. This theme will
 | 
			
		||||
 * be used for the root node and for nodes descending from it, unless some other
 | 
			
		||||
 * style is explicitely specified.
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
eek_theme_context_set_theme (EekThemeContext          *context,
 | 
			
		||||
                            EekTheme                 *theme)
 | 
			
		||||
{
 | 
			
		||||
  g_return_if_fail (EEK_IS_THEME_CONTEXT (context));
 | 
			
		||||
  g_return_if_fail (theme == NULL || EEK_IS_THEME (theme));
 | 
			
		||||
 | 
			
		||||
  if (context->theme != theme)
 | 
			
		||||
    {
 | 
			
		||||
      if (context->theme)
 | 
			
		||||
        g_object_unref (context->theme);
 | 
			
		||||
 | 
			
		||||
      context->theme = theme;
 | 
			
		||||
 | 
			
		||||
      if (context->theme)
 | 
			
		||||
        g_object_ref (context->theme);
 | 
			
		||||
 | 
			
		||||
      eek_theme_context_changed (context);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eek_theme_context_get_theme:
 | 
			
		||||
 * @context: a #EekThemeContext
 | 
			
		||||
 *
 | 
			
		||||
 * Gets the default theme for the context. See eek_theme_context_set_theme()
 | 
			
		||||
 *
 | 
			
		||||
 * Return value: (transfer none): the default theme for the context
 | 
			
		||||
 */
 | 
			
		||||
EekTheme *
 | 
			
		||||
eek_theme_context_get_theme (EekThemeContext *context)
 | 
			
		||||
{
 | 
			
		||||
  g_return_val_if_fail (EEK_IS_THEME_CONTEXT (context), NULL);
 | 
			
		||||
 | 
			
		||||
  return context->theme;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eek_theme_context_set_resolution:
 | 
			
		||||
 * @context: a #EekThemeContext
 | 
			
		||||
 * @resolution: resolution of the context (number of pixels in an "inch")
 | 
			
		||||
 *
 | 
			
		||||
 * Sets the resolution of the theme context. This is the scale factor
 | 
			
		||||
 * used to convert between points and the length units pt, in, and cm.
 | 
			
		||||
 * This does not necessarily need to correspond to the actual number
 | 
			
		||||
 * resolution of the device. A value of 72. means that points and
 | 
			
		||||
 * pixels are identical. The default value is 96.
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
eek_theme_context_set_resolution (EekThemeContext *context,
 | 
			
		||||
                                 double          resolution)
 | 
			
		||||
{
 | 
			
		||||
  g_return_if_fail (EEK_IS_THEME_CONTEXT (context));
 | 
			
		||||
 | 
			
		||||
  if (resolution == context->resolution)
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  context->resolution = resolution;
 | 
			
		||||
  eek_theme_context_changed (context);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eek_theme_context_set_default_resolution:
 | 
			
		||||
 * @context: a #EekThemeContext
 | 
			
		||||
 *
 | 
			
		||||
 * Sets the resolution of the theme context to the default value of 96.
 | 
			
		||||
 * See eek_theme_context_set_resolution().
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
eek_theme_context_set_default_resolution (EekThemeContext *context)
 | 
			
		||||
{
 | 
			
		||||
  g_return_if_fail (EEK_IS_THEME_CONTEXT (context));
 | 
			
		||||
 | 
			
		||||
  if (context->resolution == DEFAULT_RESOLUTION)
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  context->resolution = DEFAULT_RESOLUTION;
 | 
			
		||||
  eek_theme_context_changed (context);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eek_theme_context_get_resolution:
 | 
			
		||||
 * @context: a #EekThemeContext
 | 
			
		||||
 *
 | 
			
		||||
 * Gets the current resolution of the theme context.
 | 
			
		||||
 * See eek_theme_context_set_resolution().
 | 
			
		||||
 *
 | 
			
		||||
 * Return value: the resolution (in dots-per-"inch")
 | 
			
		||||
 */
 | 
			
		||||
double
 | 
			
		||||
eek_theme_context_get_resolution (EekThemeContext *context)
 | 
			
		||||
{
 | 
			
		||||
  g_return_val_if_fail (EEK_IS_THEME_CONTEXT (context), DEFAULT_RESOLUTION);
 | 
			
		||||
 | 
			
		||||
  return context->resolution;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eek_theme_context_set_font:
 | 
			
		||||
 * @context: a #EekThemeContext
 | 
			
		||||
 * @font: the default font for theme context
 | 
			
		||||
 *
 | 
			
		||||
 * Sets the default font for the theme context. This is the font that
 | 
			
		||||
 * is inherited by the root node of the tree of theme nodes. If the
 | 
			
		||||
 * font is not overriden, then this font will be used. If the font is
 | 
			
		||||
 * partially modified (for example, with 'font-size: 110%', then that
 | 
			
		||||
 * modification is based on this font.
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
eek_theme_context_set_font (EekThemeContext             *context,
 | 
			
		||||
                           const PangoFontDescription *font)
 | 
			
		||||
{
 | 
			
		||||
  g_return_if_fail (EEK_IS_THEME_CONTEXT (context));
 | 
			
		||||
  g_return_if_fail (font != NULL);
 | 
			
		||||
 | 
			
		||||
  if (context->font == font ||
 | 
			
		||||
      pango_font_description_equal (context->font, font))
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  pango_font_description_free (context->font);
 | 
			
		||||
  context->font = pango_font_description_copy (font);
 | 
			
		||||
  eek_theme_context_changed (context);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eek_theme_context_get_font:
 | 
			
		||||
 * @context: a #EekThemeContext
 | 
			
		||||
 *
 | 
			
		||||
 * Gets the default font for the theme context. See eek_theme_context_set_font().
 | 
			
		||||
 *
 | 
			
		||||
 * Return value: the default font for the theme context.
 | 
			
		||||
 */
 | 
			
		||||
const PangoFontDescription *
 | 
			
		||||
eek_theme_context_get_font (EekThemeContext *context)
 | 
			
		||||
{
 | 
			
		||||
  g_return_val_if_fail (EEK_IS_THEME_CONTEXT (context), NULL);
 | 
			
		||||
 | 
			
		||||
  return context->font;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eek_theme_context_get_root_node:
 | 
			
		||||
 * @context: a #EekThemeContext
 | 
			
		||||
 *
 | 
			
		||||
 * Gets the root node of the tree of theme style nodes that associated with this
 | 
			
		||||
 * context. For the node tree associated with a stage, this node represents
 | 
			
		||||
 * styles applied to the stage itself.
 | 
			
		||||
 *
 | 
			
		||||
 * Return value: (transfer none): the root node of the context's style tree
 | 
			
		||||
 */
 | 
			
		||||
EekThemeNode *
 | 
			
		||||
eek_theme_context_get_root_node (EekThemeContext *context)
 | 
			
		||||
{
 | 
			
		||||
  if (context->root_node == NULL)
 | 
			
		||||
    context->root_node = eek_theme_node_new (context, NULL, context->theme,
 | 
			
		||||
                                             G_TYPE_NONE, NULL, NULL, NULL, NULL);
 | 
			
		||||
 | 
			
		||||
  return context->root_node;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										78
									
								
								eek/eek-theme-context.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										78
									
								
								eek/eek-theme-context.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,78 @@
 | 
			
		||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
 | 
			
		||||
/*
 | 
			
		||||
 * eek-theme-context.c: holds global information about a tree of styled objects
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright 2009, 2010 Red Hat, Inc.
 | 
			
		||||
 * Copyright 2009 Florian Müllner
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU Lesser General Public License as
 | 
			
		||||
 * published by the Free Software Foundation, either version 2.1 of
 | 
			
		||||
 * the License, or (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is distributed in the hope it will be useful, but WITHOUT ANY
 | 
			
		||||
 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 | 
			
		||||
 * FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for
 | 
			
		||||
 * more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General Public License
 | 
			
		||||
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef __EEK_THEME_CONTEXT_H__
 | 
			
		||||
#define __EEK_THEME_CONTEXT_H__
 | 
			
		||||
 | 
			
		||||
#include <pango/pango.h>
 | 
			
		||||
#include "eek-theme-node.h"
 | 
			
		||||
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * SECTION:EekThemeContext
 | 
			
		||||
 * @short_description: holds global information about a tree of styled objects
 | 
			
		||||
 *
 | 
			
		||||
 * #EekThemeContext is responsible for managing information global to
 | 
			
		||||
 * a tree of styled objects, such as the set of stylesheets or the
 | 
			
		||||
 * default font.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
typedef struct _EekThemeContextClass EekThemeContextClass;
 | 
			
		||||
 | 
			
		||||
#define EEK_TYPE_THEME_CONTEXT             (eek_theme_context_get_type ())
 | 
			
		||||
#define EEK_THEME_CONTEXT(object)          (G_TYPE_CHECK_INSTANCE_CAST ((object), EEK_TYPE_THEME_CONTEXT, EekThemeContext))
 | 
			
		||||
#define EEK_THEME_CONTEXT_CLASS(klass)     (G_TYPE_CHECK_CLASS_CAST ((klass), EEK_TYPE_THEME_CONTEXT, EekThemeContextClass))
 | 
			
		||||
#define EEK_IS_THEME_CONTEXT(object)       (G_TYPE_CHECK_INSTANCE_TYPE ((object), EEK_TYPE_THEME_CONTEXT))
 | 
			
		||||
#define EEK_IS_THEME_CONTEXT_CLASS(klass)  (G_TYPE_CHECK_CLASS_TYPE ((klass), EEK_TYPE_THEME_CONTEXT))
 | 
			
		||||
#define EEK_THEME_CONTEXT_GET_CLASS(obj)   (G_TYPE_INSTANCE_GET_CLASS ((obj), EEK_TYPE_THEME_CONTEXT, EekThemeContextClass))
 | 
			
		||||
 | 
			
		||||
GType                       eek_theme_context_get_type
 | 
			
		||||
                            (void) G_GNUC_CONST;
 | 
			
		||||
 | 
			
		||||
EekThemeContext            *eek_theme_context_new
 | 
			
		||||
                            (void);
 | 
			
		||||
 | 
			
		||||
void                        eek_theme_context_set_theme
 | 
			
		||||
                            (EekThemeContext            *context,
 | 
			
		||||
                             EekTheme                   *theme);
 | 
			
		||||
EekTheme *                  eek_theme_context_get_theme
 | 
			
		||||
                            (EekThemeContext            *context);
 | 
			
		||||
 | 
			
		||||
void                        eek_theme_context_set_resolution
 | 
			
		||||
                            (EekThemeContext            *context,
 | 
			
		||||
                             gdouble                     resolution);
 | 
			
		||||
void                        eek_theme_context_set_default_resolution
 | 
			
		||||
                            (EekThemeContext            *context);
 | 
			
		||||
double                      eek_theme_context_get_resolution
 | 
			
		||||
                            (EekThemeContext            *context);
 | 
			
		||||
void                        eek_theme_context_set_font
 | 
			
		||||
                            (EekThemeContext            *context,
 | 
			
		||||
                             const PangoFontDescription *font);
 | 
			
		||||
const PangoFontDescription *eek_theme_context_get_font
 | 
			
		||||
                            (EekThemeContext            *context);
 | 
			
		||||
 | 
			
		||||
EekThemeNode *              eek_theme_context_get_root_node
 | 
			
		||||
                            (EekThemeContext            *context);
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
 | 
			
		||||
#endif /* __EEK_THEME_CONTEXT_H__ */
 | 
			
		||||
							
								
								
									
										1869
									
								
								eek/eek-theme-node.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1869
									
								
								eek/eek-theme-node.c
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										141
									
								
								eek/eek-theme-node.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										141
									
								
								eek/eek-theme-node.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,141 @@
 | 
			
		||||
/* 
 | 
			
		||||
 * Copyright (C) 2010-2011 Daiki Ueno <ueno@unixuser.org>
 | 
			
		||||
 * Copyright (C) 2010-2011 Red Hat, Inc.
 | 
			
		||||
 * 
 | 
			
		||||
 * This library is free software; you can redistribute it and/or
 | 
			
		||||
 * modify it under the terms of the GNU Lesser General Public License
 | 
			
		||||
 * as published by the Free Software Foundation; either version 2 of
 | 
			
		||||
 * the License, or (at your option) any later version.
 | 
			
		||||
 * 
 | 
			
		||||
 * This library is distributed in the hope that it will be useful, but
 | 
			
		||||
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
			
		||||
 * Lesser General Public License for more details.
 | 
			
		||||
 * 
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General Public
 | 
			
		||||
 * License along with this library; if not, write to the Free Software
 | 
			
		||||
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 | 
			
		||||
 * 02110-1301 USA
 | 
			
		||||
 */
 | 
			
		||||
#ifndef __EEK_THEME_NODE_H__
 | 
			
		||||
#define __EEK_THEME_NODE_H__
 | 
			
		||||
 | 
			
		||||
#include <pango/pango.h>
 | 
			
		||||
#include "eek-types.h"
 | 
			
		||||
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * SECTION:EekThemeNode
 | 
			
		||||
 * @short_description: style information for one node in a tree of
 | 
			
		||||
 * themed objects
 | 
			
		||||
 *
 | 
			
		||||
 * A #EekThemeNode represents the CSS style information (the set of
 | 
			
		||||
 * CSS properties) for one node in a tree of themed objects. In
 | 
			
		||||
 * typical usage, it represents the style information for a single
 | 
			
		||||
 * #EekElement. A #EekThemeNode is immutable: attributes such as the
 | 
			
		||||
 * CSS classes for the node are passed in at construction. If the
 | 
			
		||||
 * attributes of the node or any parent node change, the node should
 | 
			
		||||
 * be discarded and a new node created.  #EekThemeNode has generic
 | 
			
		||||
 * accessors to look up properties by name and specific accessors for
 | 
			
		||||
 * standard CSS properties that add caching and handling of various
 | 
			
		||||
 * details of the CSS specification. #EekThemeNode also has
 | 
			
		||||
 * convenience functions to help in implementing a #EekElement with
 | 
			
		||||
 * borders and padding.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
typedef enum {
 | 
			
		||||
    EEK_SIDE_TOP,
 | 
			
		||||
    EEK_SIDE_RIGHT,
 | 
			
		||||
    EEK_SIDE_BOTTOM,
 | 
			
		||||
    EEK_SIDE_LEFT
 | 
			
		||||
} EekSide;
 | 
			
		||||
 | 
			
		||||
typedef enum {
 | 
			
		||||
    EEK_CORNER_TOPLEFT,
 | 
			
		||||
    EEK_CORNER_TOPRIGHT,
 | 
			
		||||
    EEK_CORNER_BOTTOMRIGHT,
 | 
			
		||||
    EEK_CORNER_BOTTOMLEFT
 | 
			
		||||
} EekCorner;
 | 
			
		||||
 | 
			
		||||
#define EEK_TYPE_THEME_NODE (eek_theme_node_get_type())
 | 
			
		||||
#define EEK_THEME_NODE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EEK_TYPE_THEME_NODE, EekThemeNode))
 | 
			
		||||
#define EEK_THEME_NODE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EEK_TYPE_THEME_NODE, EekThemeNodeClass))
 | 
			
		||||
#define EEK_IS_THEME_NODE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EEK_TYPE_THEME_NODE))
 | 
			
		||||
#define EEK_IS_THEME_NODE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EEK_TYPE_THEME_NODE))
 | 
			
		||||
#define EEK_THEME_NODE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EEK_TYPE_THEME_NODE, EekThemeNodeClass))
 | 
			
		||||
 | 
			
		||||
typedef struct _EekThemeNodeClass EekThemeNodeClass;
 | 
			
		||||
typedef struct _EekThemeNodePrivate EekThemeNodePrivate;
 | 
			
		||||
 | 
			
		||||
GType         eek_theme_node_get_type
 | 
			
		||||
                                 (void) G_GNUC_CONST;
 | 
			
		||||
 | 
			
		||||
EekThemeNode *eek_theme_node_new (EekThemeContext            *context,
 | 
			
		||||
                                  EekThemeNode               *parent_node,
 | 
			
		||||
                                  /* can be null */ EekTheme *theme,
 | 
			
		||||
                                  /* can be null */ GType     element_type,
 | 
			
		||||
                                  const char                 *element_id,
 | 
			
		||||
                                  const char                 *element_class,
 | 
			
		||||
                                  const char                 *pseudo_class,
 | 
			
		||||
                                  const char                 *inline_style);
 | 
			
		||||
 | 
			
		||||
EekThemeNode *eek_theme_node_get_parent
 | 
			
		||||
                                 (EekThemeNode               *node);
 | 
			
		||||
 | 
			
		||||
EekTheme     *eek_theme_node_get_theme
 | 
			
		||||
                                 (EekThemeNode               *node);
 | 
			
		||||
 | 
			
		||||
GType         eek_theme_node_get_element_type
 | 
			
		||||
                                 (EekThemeNode               *node);
 | 
			
		||||
const char   *eek_theme_node_get_element_id
 | 
			
		||||
                                 (EekThemeNode               *node);
 | 
			
		||||
const char   *eek_theme_node_get_element_class
 | 
			
		||||
                                 (EekThemeNode               *node);
 | 
			
		||||
const char   *eek_theme_node_get_pseudo_class
 | 
			
		||||
                                 (EekThemeNode               *node);
 | 
			
		||||
 | 
			
		||||
/* Generic getters ... these are not cached so are less efficient. The other
 | 
			
		||||
 * reason for adding the more specific version is that we can handle the
 | 
			
		||||
 * details of the actual CSS rules, which can be complicated, especially
 | 
			
		||||
 * for fonts
 | 
			
		||||
 */
 | 
			
		||||
void          eek_theme_node_get_color
 | 
			
		||||
                                 (EekThemeNode               *node,
 | 
			
		||||
                                  const char                 *property_name,
 | 
			
		||||
                                  EekColor                   *color);
 | 
			
		||||
 | 
			
		||||
/* Specific getters for particular properties: cached
 | 
			
		||||
 */
 | 
			
		||||
void          eek_theme_node_get_background_color
 | 
			
		||||
                                 (EekThemeNode               *node,
 | 
			
		||||
                                  EekColor                   *color);
 | 
			
		||||
void          eek_theme_node_get_foreground_color
 | 
			
		||||
                                 (EekThemeNode               *node,
 | 
			
		||||
                                  EekColor                   *color);
 | 
			
		||||
void          eek_theme_node_get_background_gradient
 | 
			
		||||
                                 (EekThemeNode               *node,
 | 
			
		||||
                                  EekGradientType            *type,
 | 
			
		||||
                                  EekColor                   *start,
 | 
			
		||||
                                  EekColor                   *end);
 | 
			
		||||
int           eek_theme_node_get_border_width
 | 
			
		||||
                                 (EekThemeNode               *node,
 | 
			
		||||
                                  EekSide                     side);
 | 
			
		||||
int           eek_theme_node_get_border_radius
 | 
			
		||||
                                 (EekThemeNode               *node,
 | 
			
		||||
                                  EekCorner                   corner);
 | 
			
		||||
void          eek_theme_node_get_border_color
 | 
			
		||||
                                 (EekThemeNode               *node,
 | 
			
		||||
                                  EekSide                     side,
 | 
			
		||||
                                  EekColor                   *color);
 | 
			
		||||
 | 
			
		||||
/* Font rule processing is pretty complicated, so we just hardcode it
 | 
			
		||||
 * under the standard font/font-family/font-size/etc names. This means
 | 
			
		||||
 * you can't have multiple separate styled fonts for a single item,
 | 
			
		||||
 * but that should be OK.
 | 
			
		||||
 */
 | 
			
		||||
const PangoFontDescription *eek_theme_node_get_font (EekThemeNode *node);
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
 | 
			
		||||
#endif /* __EEK_THEME_NODE_H__ */
 | 
			
		||||
							
								
								
									
										22
									
								
								eek/eek-theme-private.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								eek/eek-theme-private.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,22 @@
 | 
			
		||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
 | 
			
		||||
#ifndef __EEK_THEME_PRIVATE_H__
 | 
			
		||||
#define __EEK_THEME_PRIVATE_H__
 | 
			
		||||
 | 
			
		||||
#include <libcroco/libcroco.h>
 | 
			
		||||
#include "eek-theme.h"
 | 
			
		||||
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
GPtrArray *_eek_theme_get_matched_properties (EekTheme       *theme,
 | 
			
		||||
                                             EekThemeNode   *node);
 | 
			
		||||
 | 
			
		||||
/* Resolve an URL from the stylesheet to a filename */
 | 
			
		||||
char *_eek_theme_resolve_url (EekTheme      *theme,
 | 
			
		||||
                             CRStyleSheet *base_stylesheet,
 | 
			
		||||
                             const char   *url);
 | 
			
		||||
 | 
			
		||||
CRDeclaration *_eek_theme_parse_declaration_list (const char *str);
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
 | 
			
		||||
#endif /* __EEK_THEME_PRIVATE_H__ */
 | 
			
		||||
							
								
								
									
										1133
									
								
								eek/eek-theme.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1133
									
								
								eek/eek-theme.c
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										44
									
								
								eek/eek-theme.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								eek/eek-theme.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,44 @@
 | 
			
		||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
 | 
			
		||||
#ifndef __EEK_THEME_H__
 | 
			
		||||
#define __EEK_THEME_H__
 | 
			
		||||
 | 
			
		||||
#include <glib-object.h>
 | 
			
		||||
 | 
			
		||||
#include "eek-types.h"
 | 
			
		||||
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * SECTION:EekTheme
 | 
			
		||||
 * @short_description: a set of stylesheets
 | 
			
		||||
 *
 | 
			
		||||
 * #EekTheme holds a set of stylesheets. (The "cascade" of the name
 | 
			
		||||
 * Cascading Stylesheets.) An #EekTheme can be set to apply to all the
 | 
			
		||||
 * keyboard elements.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
typedef struct _EekThemeClass EekThemeClass;
 | 
			
		||||
 | 
			
		||||
#define EEK_TYPE_THEME (eek_theme_get_type())
 | 
			
		||||
#define EEK_THEME(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EEK_TYPE_THEME, EekTheme))
 | 
			
		||||
#define EEK_THEME_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EEK_TYPE_THEME, EekThemeClass))
 | 
			
		||||
#define EEK_IS_THEME(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EEK_TYPE_THEME))
 | 
			
		||||
#define EEK_IS_THEME_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EEK_TYPE_THEME))
 | 
			
		||||
#define EEK_THEME_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EEK_TYPE_THEME, EekThemeClass))
 | 
			
		||||
 | 
			
		||||
GType     eek_theme_get_type          (void) G_GNUC_CONST;
 | 
			
		||||
 | 
			
		||||
EekTheme *eek_theme_new               (const char *application_stylesheet,
 | 
			
		||||
                                       const char *theme_stylesheet,
 | 
			
		||||
                                       const char *default_stylesheet);
 | 
			
		||||
 | 
			
		||||
gboolean  eek_theme_load_stylesheet   (EekTheme   *theme,
 | 
			
		||||
                                       const char *path,
 | 
			
		||||
                                       GError    **error);
 | 
			
		||||
 | 
			
		||||
void      eek_theme_unload_stylesheet (EekTheme   *theme,
 | 
			
		||||
                                       const char *path);
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
 | 
			
		||||
#endif /* __EEK_THEME_H__ */
 | 
			
		||||
@ -153,6 +153,7 @@ EekOutline *
 | 
			
		||||
eek_outline_copy (const EekOutline *outline)
 | 
			
		||||
{
 | 
			
		||||
    EekOutline *_outline = g_slice_dup (EekOutline, outline);
 | 
			
		||||
    _outline->corner_radius = outline->corner_radius;
 | 
			
		||||
    _outline->num_points = outline->num_points;
 | 
			
		||||
    _outline->points = g_slice_alloc0 (sizeof (EekPoint) * outline->num_points);
 | 
			
		||||
    memcpy (_outline->points, outline->points, sizeof (EekPoint) * outline->num_points);
 | 
			
		||||
@ -180,13 +181,13 @@ eek_outline_get_type (void)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* EekColor */
 | 
			
		||||
static EekColor *
 | 
			
		||||
EekColor *
 | 
			
		||||
eek_color_copy (const EekColor *color)
 | 
			
		||||
{
 | 
			
		||||
    return g_slice_dup (EekColor, color);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
void
 | 
			
		||||
eek_color_free (EekColor *color)
 | 
			
		||||
{
 | 
			
		||||
    g_slice_free (EekColor, color);
 | 
			
		||||
 | 
			
		||||
@ -24,6 +24,8 @@
 | 
			
		||||
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
#define I_(string) g_intern_static_string (string)
 | 
			
		||||
 | 
			
		||||
#define EEK_TYPE_SYMBOL_MATRIX (eek_symbol_matrix_get_type ())
 | 
			
		||||
#define EEK_TYPE_POINT (eek_point_get_type ())
 | 
			
		||||
#define EEK_TYPE_BOUNDS (eek_bounds_get_type ())
 | 
			
		||||
@ -62,6 +64,35 @@ typedef enum {
 | 
			
		||||
    EEK_MODIFIER_BEHAVIOR_LATCH
 | 
			
		||||
} EekModifierBehavior;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * EekModifierType:
 | 
			
		||||
 * @EEK_SHIFT_MASK: the Shift key.
 | 
			
		||||
 * @EEK_LOCK_MASK: a Lock key (depending on the modifier mapping of the
 | 
			
		||||
 *  X server this may either be CapsLock or ShiftLock).
 | 
			
		||||
 * @EEK_CONTROL_MASK: the Control key.
 | 
			
		||||
 * @EEK_MOD1_MASK: the fourth modifier key (it depends on the modifier
 | 
			
		||||
 *  mapping of the X server which key is interpreted as this modifier, but
 | 
			
		||||
 *  normally it is the Alt key).
 | 
			
		||||
 * @EEK_MOD2_MASK: the fifth modifier key (it depends on the modifier
 | 
			
		||||
 *  mapping of the X server which key is interpreted as this modifier).
 | 
			
		||||
 * @EEK_MOD3_MASK: the sixth modifier key (it depends on the modifier
 | 
			
		||||
 *  mapping of the X server which key is interpreted as this modifier).
 | 
			
		||||
 * @EEK_MOD4_MASK: the seventh modifier key (it depends on the modifier
 | 
			
		||||
 *  mapping of the X server which key is interpreted as this modifier).
 | 
			
		||||
 * @EEK_MOD5_MASK: the eighth modifier key (it depends on the modifier
 | 
			
		||||
 *  mapping of the X server which key is interpreted as this modifier).
 | 
			
		||||
 * @EEK_BUTTON1_MASK: the first mouse button.
 | 
			
		||||
 * @EEK_BUTTON2_MASK: the second mouse button.
 | 
			
		||||
 * @EEK_BUTTON3_MASK: the third mouse button.
 | 
			
		||||
 * @EEK_BUTTON4_MASK: the fourth mouse button.
 | 
			
		||||
 * @EEK_BUTTON5_MASK: the fifth mouse button.
 | 
			
		||||
 * @EEK_SUPER_MASK: the Super modifier. Since 2.10
 | 
			
		||||
 * @EEK_HYPER_MASK: the Hyper modifier. Since 2.10
 | 
			
		||||
 * @EEK_META_MASK: the Meta modifier. Since 2.10
 | 
			
		||||
 * @EEK_RELEASE_MASK: not used in EEK itself. GTK+ uses it to differentiate
 | 
			
		||||
 *  between (keyval, modifiers) pairs from key press and release events.
 | 
			
		||||
 * @EEK_MODIFIER_MASK: a mask covering all modifier types.
 | 
			
		||||
 */
 | 
			
		||||
typedef enum
 | 
			
		||||
{
 | 
			
		||||
  EEK_SHIFT_MASK    = 1 << 0,
 | 
			
		||||
@ -105,6 +136,9 @@ typedef struct _EekSection EekSection;
 | 
			
		||||
typedef struct _EekKeyboard EekKeyboard;
 | 
			
		||||
typedef struct _EekSymbol EekSymbol;
 | 
			
		||||
typedef struct _EekKeysym EekKeysym;
 | 
			
		||||
typedef struct _EekTheme EekTheme;
 | 
			
		||||
typedef struct _EekThemeContext EekThemeContext;
 | 
			
		||||
typedef struct _EekThemeNode EekThemeNode;
 | 
			
		||||
 | 
			
		||||
typedef struct _EekSymbolMatrix EekSymbolMatrix;
 | 
			
		||||
typedef struct _EekPoint EekPoint;
 | 
			
		||||
@ -219,6 +253,15 @@ EekColor *eek_color_new      (gdouble red,
 | 
			
		||||
                              gdouble         green,
 | 
			
		||||
                              gdouble         blue,
 | 
			
		||||
                              gdouble         alpha);
 | 
			
		||||
EekColor *eek_color_copy     (const EekColor *color);
 | 
			
		||||
void      eek_color_free     (EekColor       *color);
 | 
			
		||||
 | 
			
		||||
typedef enum {
 | 
			
		||||
  EEK_GRADIENT_NONE,
 | 
			
		||||
  EEK_GRADIENT_VERTICAL,
 | 
			
		||||
  EEK_GRADIENT_HORIZONTAL,
 | 
			
		||||
  EEK_GRADIENT_RADIAL
 | 
			
		||||
} EekGradientType;
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
#endif  /* EEK_TYPES_H */
 | 
			
		||||
 | 
			
		||||
@ -27,16 +27,16 @@
 | 
			
		||||
 * elements using XKB.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_CONFIG_H
 | 
			
		||||
#include "config.h"
 | 
			
		||||
#endif  /* HAVE_CONFIG_H */
 | 
			
		||||
 | 
			
		||||
#include <gdk/gdkx.h>
 | 
			
		||||
#include <X11/XKBlib.h>
 | 
			
		||||
#include <X11/extensions/XKBgeom.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <stdarg.h>
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_CONFIG_H
 | 
			
		||||
#include "config.h"
 | 
			
		||||
#endif  /* HAVE_CONFIG_H */
 | 
			
		||||
 | 
			
		||||
#include "eek-xkb-layout.h"
 | 
			
		||||
#include "eek-keyboard.h"
 | 
			
		||||
#include "eek-section.h"
 | 
			
		||||
@ -176,6 +176,7 @@ create_key (EekXkbLayout *layout,
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        oref = eek_keyboard_add_outline (keyboard, outline);
 | 
			
		||||
        eek_outline_free (outline);
 | 
			
		||||
        g_hash_table_insert (priv->shape_oref_hash, xkbshape, (gpointer)oref);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -202,9 +203,13 @@ create_key (EekXkbLayout *layout,
 | 
			
		||||
        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 (keysym));
 | 
			
		||||
                    EEK_SYMBOL(eek_keysym_new_with_modifier (keysym,
 | 
			
		||||
                                                             modifier));
 | 
			
		||||
            }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -320,6 +325,14 @@ eek_xkb_layout_real_create_keyboard (EekLayout *self,
 | 
			
		||||
    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);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -26,14 +26,14 @@
 | 
			
		||||
 * to use Libxklavier configuration.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <libxklavier/xklavier.h>
 | 
			
		||||
#include <gdk/gdkx.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_CONFIG_H
 | 
			
		||||
#include "config.h"
 | 
			
		||||
#endif  /* HAVE_CONFIG_H */
 | 
			
		||||
 | 
			
		||||
#include <libxklavier/xklavier.h>
 | 
			
		||||
#include <gdk/gdkx.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
#include "eek-xkl-layout.h"
 | 
			
		||||
 | 
			
		||||
#define noKBDRAW_DEBUG
 | 
			
		||||
 | 
			
		||||
@ -21,13 +21,13 @@
 | 
			
		||||
 * @short_description: Layout engine which loads layout information from XML
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_CONFIG_H
 | 
			
		||||
#include "config.h"
 | 
			
		||||
#endif  /* HAVE_CONFIG_H */
 | 
			
		||||
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
#include "eek-xml-layout.h"
 | 
			
		||||
#include "eek-keyboard.h"
 | 
			
		||||
#include "eek-section.h"
 | 
			
		||||
@ -62,12 +62,16 @@ struct _ParseCallbackData {
 | 
			
		||||
    EekKey *key;
 | 
			
		||||
    gint num_columns;
 | 
			
		||||
    EekOrientation orientation;
 | 
			
		||||
    gdouble corner_radius;
 | 
			
		||||
    GSList *points;
 | 
			
		||||
    GSList *symbols;
 | 
			
		||||
    gchar *label;
 | 
			
		||||
    gchar *icon;
 | 
			
		||||
    guint keyval;
 | 
			
		||||
    gint groups, levels;
 | 
			
		||||
    EekOutline outline;
 | 
			
		||||
    gchar *oref;
 | 
			
		||||
 | 
			
		||||
    GHashTable *key_oref_hash;
 | 
			
		||||
    GHashTable *oref_outline_hash;
 | 
			
		||||
};
 | 
			
		||||
@ -95,7 +99,8 @@ static const gchar *valid_path_list[] = {
 | 
			
		||||
    "icon/symbols/key/section/keyboard",
 | 
			
		||||
    "invalid/symbols/key/section/keyboard",
 | 
			
		||||
    "index/key/section/keyboard",
 | 
			
		||||
    "point/outline/keyboard"
 | 
			
		||||
    "point/outline/keyboard",
 | 
			
		||||
    "corner-radius/outline/keyboard",
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static gchar *
 | 
			
		||||
@ -160,7 +165,7 @@ start_element_callback (GMarkupParseContext *pcontext,
 | 
			
		||||
    const gchar **values = attribute_values;
 | 
			
		||||
    gint column = -1, row = -1, groups = -1, levels = -1;
 | 
			
		||||
    guint keyval = EEK_INVALID_KEYSYM;
 | 
			
		||||
    gchar *name = NULL, *id = NULL, *version = NULL;
 | 
			
		||||
    gchar *name = NULL, *label = NULL, *icon = NULL, *id = NULL, *version = NULL;
 | 
			
		||||
 | 
			
		||||
    validate (element_name, data->element_stack, error);
 | 
			
		||||
    if (error && *error)
 | 
			
		||||
@ -175,6 +180,10 @@ start_element_callback (GMarkupParseContext *pcontext,
 | 
			
		||||
            id = g_strdup (*values);
 | 
			
		||||
        else if (g_strcmp0 (*names, "name") == 0)
 | 
			
		||||
            name = g_strdup (*values);
 | 
			
		||||
        else if (g_strcmp0 (*names, "label") == 0)
 | 
			
		||||
            label = g_strdup (*values);
 | 
			
		||||
        else if (g_strcmp0 (*names, "icon") == 0)
 | 
			
		||||
            icon = g_strdup (*values);
 | 
			
		||||
        else if (g_strcmp0 (*names, "keyval") == 0)
 | 
			
		||||
            keyval = strtoul (*values, NULL, 10);
 | 
			
		||||
        else if (g_strcmp0 (*names, "version") == 0)
 | 
			
		||||
@ -220,8 +229,11 @@ start_element_callback (GMarkupParseContext *pcontext,
 | 
			
		||||
        goto out;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (g_strcmp0 (element_name, "keysym") == 0)
 | 
			
		||||
    if (g_strcmp0 (element_name, "keysym") == 0) {
 | 
			
		||||
        data->label = g_strdup (label);
 | 
			
		||||
        data->icon = g_strdup (icon);
 | 
			
		||||
        data->keyval = keyval;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (g_strcmp0 (element_name, "outline") == 0) {
 | 
			
		||||
        data->oref = g_strdup (id);
 | 
			
		||||
@ -229,6 +241,8 @@ start_element_callback (GMarkupParseContext *pcontext,
 | 
			
		||||
    }
 | 
			
		||||
 out:
 | 
			
		||||
    g_free (name);
 | 
			
		||||
    g_free (label);
 | 
			
		||||
    g_free (icon);
 | 
			
		||||
    g_free (id);
 | 
			
		||||
    g_free (version);
 | 
			
		||||
 | 
			
		||||
@ -288,6 +302,9 @@ end_element_callback (GMarkupParseContext *pcontext,
 | 
			
		||||
    if (g_strcmp0 (element_name, "outline") == 0) {
 | 
			
		||||
        EekOutline *outline = g_slice_new (EekOutline);
 | 
			
		||||
 | 
			
		||||
        outline->corner_radius = data->corner_radius;
 | 
			
		||||
        data->corner_radius = 0.0;
 | 
			
		||||
 | 
			
		||||
        outline->num_points = g_slist_length (data->points);
 | 
			
		||||
        outline->points = g_slice_alloc0 (sizeof (EekPoint) *
 | 
			
		||||
                                          outline->num_points);
 | 
			
		||||
@ -307,6 +324,11 @@ end_element_callback (GMarkupParseContext *pcontext,
 | 
			
		||||
        goto out;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (g_strcmp0 (element_name, "corner-radius") == 0) {
 | 
			
		||||
        data->corner_radius = g_strtod (text, NULL);
 | 
			
		||||
        goto out;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (g_strcmp0 (element_name, "point") == 0) {
 | 
			
		||||
        EekPoint *point;
 | 
			
		||||
 | 
			
		||||
@ -396,6 +418,14 @@ end_element_callback (GMarkupParseContext *pcontext,
 | 
			
		||||
            //g_debug ("%u %s", data->keyval, eek_symbol_get_label (EEK_SYMBOL(keysym)));
 | 
			
		||||
        } else
 | 
			
		||||
            keysym = eek_keysym_new_from_name (text);
 | 
			
		||||
        if (data->label) {
 | 
			
		||||
            eek_symbol_set_label (EEK_SYMBOL(keysym), data->label);
 | 
			
		||||
            g_free (data->label);
 | 
			
		||||
        }
 | 
			
		||||
        if (data->icon) {
 | 
			
		||||
            eek_symbol_set_icon_name (EEK_SYMBOL(keysym), data->icon);
 | 
			
		||||
            g_free (data->icon);
 | 
			
		||||
        }
 | 
			
		||||
        data->symbols = g_slist_prepend (data->symbols, keysym);
 | 
			
		||||
        goto out;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -35,6 +35,12 @@ 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 >*/
 | 
			
		||||
@ -43,6 +49,9 @@ struct _EekXmlLayout
 | 
			
		||||
    EekXmlLayoutPrivate *priv;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * EekXmlLayoutClass:
 | 
			
		||||
 */
 | 
			
		||||
struct _EekXmlLayoutClass
 | 
			
		||||
{
 | 
			
		||||
    /*< private >*/
 | 
			
		||||
 | 
			
		||||
@ -16,14 +16,19 @@
 | 
			
		||||
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <stdarg.h>
 | 
			
		||||
#include <glib/gprintf.h>
 | 
			
		||||
/**
 | 
			
		||||
 * SECTION: eek-xml
 | 
			
		||||
 * @short_description: #EekKeyboard to XML conversion utilities
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_CONFIG_H
 | 
			
		||||
#include "config.h"
 | 
			
		||||
#endif  /* HAVE_CONFIG_H */
 | 
			
		||||
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <stdarg.h>
 | 
			
		||||
#include <glib/gprintf.h>
 | 
			
		||||
 | 
			
		||||
#include "eek-section.h"
 | 
			
		||||
#include "eek-key.h"
 | 
			
		||||
#include "eek-xml.h"
 | 
			
		||||
@ -216,6 +221,14 @@ output_section_callback (EekElement *element, gpointer user_data)
 | 
			
		||||
    g_string_markup_printf (data->output, "</section>\n");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eek_keyboard_output:
 | 
			
		||||
 * @keyboard: an #EekKeyboard
 | 
			
		||||
 * @output: a GString
 | 
			
		||||
 * @indent: an integer
 | 
			
		||||
 *
 | 
			
		||||
 * Convert @keyboard into the XML format and store it into @output.
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
eek_keyboard_output (EekKeyboard *keyboard, GString *output, gint indent)
 | 
			
		||||
{
 | 
			
		||||
@ -260,6 +273,9 @@ eek_keyboard_output (EekKeyboard *keyboard, GString *output, gint indent)
 | 
			
		||||
        outline = eek_keyboard_get_outline (keyboard, oref);
 | 
			
		||||
        g_string_append_indent (output, indent + 1);
 | 
			
		||||
        g_string_markup_printf (output, "<outline id=\"outline%u\">\n", oref);
 | 
			
		||||
        g_string_append_indent (output, indent + 2);
 | 
			
		||||
        g_string_markup_printf (output, "<corner-radius>%lf</corner-radius>\n",
 | 
			
		||||
                                outline->corner_radius);
 | 
			
		||||
        for (j = 0; j < outline->num_points; j++) {
 | 
			
		||||
            g_string_append_indent (output, indent + 2);
 | 
			
		||||
            g_string_markup_printf (output, "<point>%lf,%lf</point>\n",
 | 
			
		||||
 | 
			
		||||
@ -27,7 +27,9 @@ G_BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
#define EEK_XML_SCHEMA_VERSION "0.90"
 | 
			
		||||
 | 
			
		||||
void eek_keyboard_output (EekKeyboard *keyboard, GString *output, gint indent);
 | 
			
		||||
void eek_keyboard_output (EekKeyboard *keyboard,
 | 
			
		||||
                          GString     *output,
 | 
			
		||||
                          gint         indent);
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
#endif  /* EEK_XML_H */
 | 
			
		||||
 | 
			
		||||
@ -28,5 +28,6 @@
 | 
			
		||||
#include "eek-keysym.h"
 | 
			
		||||
#include "eek-xml.h"
 | 
			
		||||
#include "eek-serializable.h"
 | 
			
		||||
#include "eek-theme.h"
 | 
			
		||||
 | 
			
		||||
#endif  /* EEK_H */
 | 
			
		||||
 | 
			
		||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@ -20,10 +20,10 @@ lib_LTLIBRARIES = libeekboard.la
 | 
			
		||||
 | 
			
		||||
libeekboard_headers =					\
 | 
			
		||||
	eekboard.h					\
 | 
			
		||||
	eekboard-server.h				\
 | 
			
		||||
	eekboard-eekboard.h				\
 | 
			
		||||
	eekboard-context.h			
 | 
			
		||||
libeekboard_sources =				\
 | 
			
		||||
	eekboard-server.c			\
 | 
			
		||||
	eekboard-eekboard.c			\
 | 
			
		||||
	eekboard-context.c
 | 
			
		||||
 | 
			
		||||
libeekboard_la_SOURCES = $(libeekboard_sources)
 | 
			
		||||
 | 
			
		||||
@ -30,11 +30,14 @@
 | 
			
		||||
 | 
			
		||||
#include "eekboard/eekboard-context.h"
 | 
			
		||||
 | 
			
		||||
#define I_(string) g_intern_static_string (string)
 | 
			
		||||
 | 
			
		||||
enum {
 | 
			
		||||
    ENABLED,
 | 
			
		||||
    DISABLED,
 | 
			
		||||
    KEY_PRESSED,
 | 
			
		||||
    KEY_RELEASED,
 | 
			
		||||
    DESTROYED,
 | 
			
		||||
    LAST_SIGNAL
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
@ -54,8 +57,10 @@ G_DEFINE_TYPE (EekboardContext, eekboard_context, G_TYPE_DBUS_PROXY);
 | 
			
		||||
struct _EekboardContextPrivate
 | 
			
		||||
{
 | 
			
		||||
    EekKeyboard *keyboard;
 | 
			
		||||
    GHashTable *keyboard_hash;
 | 
			
		||||
    gboolean keyboard_visible;
 | 
			
		||||
    gboolean enabled;
 | 
			
		||||
    gboolean fullscreen;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
@ -143,6 +148,12 @@ eekboard_context_real_key_released (EekboardContext *self,
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
eekboard_context_real_destroyed (EekboardContext *self)
 | 
			
		||||
{
 | 
			
		||||
    // g_debug ("eekboard_context_real_destroyed");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
eekboard_context_get_property (GObject    *object,
 | 
			
		||||
                               guint       prop_id,
 | 
			
		||||
@ -171,6 +182,11 @@ eekboard_context_dispose (GObject *self)
 | 
			
		||||
        g_object_unref (priv->keyboard);
 | 
			
		||||
        priv->keyboard = NULL;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (priv->keyboard_hash) {
 | 
			
		||||
        g_hash_table_destroy (priv->keyboard_hash);
 | 
			
		||||
        priv->keyboard_hash = NULL;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
@ -187,6 +203,7 @@ eekboard_context_class_init (EekboardContextClass *klass)
 | 
			
		||||
    klass->disabled = eekboard_context_real_disabled;
 | 
			
		||||
    klass->key_pressed = eekboard_context_real_key_pressed;
 | 
			
		||||
    klass->key_released = eekboard_context_real_key_released;
 | 
			
		||||
    klass->destroyed = eekboard_context_real_destroyed;
 | 
			
		||||
 | 
			
		||||
    proxy_class->g_signal = eekboard_context_real_g_signal;
 | 
			
		||||
 | 
			
		||||
@ -211,10 +228,10 @@ eekboard_context_class_init (EekboardContextClass *klass)
 | 
			
		||||
     * EekboardContext::enabled:
 | 
			
		||||
     * @context: an #EekboardContext
 | 
			
		||||
     *
 | 
			
		||||
     * The ::enabled signal is emitted each time @context is enabled.
 | 
			
		||||
     * Emitted when @context is enabled.
 | 
			
		||||
     */
 | 
			
		||||
    signals[ENABLED] =
 | 
			
		||||
        g_signal_new ("enabled",
 | 
			
		||||
        g_signal_new (I_("enabled"),
 | 
			
		||||
                      G_TYPE_FROM_CLASS(gobject_class),
 | 
			
		||||
                      G_SIGNAL_RUN_LAST,
 | 
			
		||||
                      G_STRUCT_OFFSET(EekboardContextClass, enabled),
 | 
			
		||||
@ -231,7 +248,7 @@ eekboard_context_class_init (EekboardContextClass *klass)
 | 
			
		||||
     * The ::disabled signal is emitted each time @context is disabled.
 | 
			
		||||
     */
 | 
			
		||||
    signals[DISABLED] =
 | 
			
		||||
        g_signal_new ("disabled",
 | 
			
		||||
        g_signal_new (I_("disabled"),
 | 
			
		||||
                      G_TYPE_FROM_CLASS(gobject_class),
 | 
			
		||||
                      G_SIGNAL_RUN_LAST,
 | 
			
		||||
                      G_STRUCT_OFFSET(EekboardContextClass, disabled),
 | 
			
		||||
@ -250,7 +267,7 @@ eekboard_context_class_init (EekboardContextClass *klass)
 | 
			
		||||
     * in @context.
 | 
			
		||||
     */
 | 
			
		||||
    signals[KEY_PRESSED] =
 | 
			
		||||
        g_signal_new ("key-pressed",
 | 
			
		||||
        g_signal_new (I_("key-pressed"),
 | 
			
		||||
                      G_TYPE_FROM_CLASS(gobject_class),
 | 
			
		||||
                      G_SIGNAL_RUN_LAST,
 | 
			
		||||
                      G_STRUCT_OFFSET(EekboardContextClass, key_pressed),
 | 
			
		||||
@ -270,7 +287,7 @@ eekboard_context_class_init (EekboardContextClass *klass)
 | 
			
		||||
     * in @context.
 | 
			
		||||
     */
 | 
			
		||||
    signals[KEY_RELEASED] =
 | 
			
		||||
        g_signal_new ("key-released",
 | 
			
		||||
        g_signal_new (I_("key-released"),
 | 
			
		||||
                      G_TYPE_FROM_CLASS(gobject_class),
 | 
			
		||||
                      G_SIGNAL_RUN_LAST,
 | 
			
		||||
                      G_STRUCT_OFFSET(EekboardContextClass, key_released),
 | 
			
		||||
@ -280,6 +297,24 @@ eekboard_context_class_init (EekboardContextClass *klass)
 | 
			
		||||
                      G_TYPE_NONE,
 | 
			
		||||
                      1,
 | 
			
		||||
                      G_TYPE_UINT);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * EekboardContext::destroyed:
 | 
			
		||||
     * @context: an #EekboardContext
 | 
			
		||||
     *
 | 
			
		||||
     * 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(EekboardContextClass, destroyed),
 | 
			
		||||
                      NULL,
 | 
			
		||||
                      NULL,
 | 
			
		||||
                      g_cclosure_marshal_VOID__VOID,
 | 
			
		||||
                      G_TYPE_NONE,
 | 
			
		||||
                      0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
@ -291,6 +326,20 @@ eekboard_context_init (EekboardContext *self)
 | 
			
		||||
    priv->keyboard = NULL;
 | 
			
		||||
    priv->keyboard_visible = FALSE;
 | 
			
		||||
    priv->enabled = FALSE;
 | 
			
		||||
    priv->keyboard_hash =
 | 
			
		||||
        g_hash_table_new_full (g_direct_hash,
 | 
			
		||||
                               g_direct_equal,
 | 
			
		||||
                               NULL,
 | 
			
		||||
                               (GDestroyNotify)g_object_unref);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
context_name_vanished_callback (GDBusConnection *connection,
 | 
			
		||||
                                const gchar     *name,
 | 
			
		||||
                                gpointer         user_data)
 | 
			
		||||
{
 | 
			
		||||
    EekboardContext *context = user_data;
 | 
			
		||||
    g_signal_emit_by_name (context, "destroyed", NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@ -324,8 +373,27 @@ eekboard_context_new (GDBusConnection *connection,
 | 
			
		||||
                        "g-interface-name", "com.redhat.Eekboard.Context",
 | 
			
		||||
                        "g-object-path", object_path,
 | 
			
		||||
                        NULL);
 | 
			
		||||
    if (initable != NULL)
 | 
			
		||||
        return EEKBOARD_CONTEXT (initable);
 | 
			
		||||
    if (initable != NULL) {
 | 
			
		||||
        EekboardContext *context = EEKBOARD_CONTEXT (initable);
 | 
			
		||||
        gchar *name_owner = g_dbus_proxy_get_name_owner (G_DBUS_PROXY(context));
 | 
			
		||||
 | 
			
		||||
        if (name_owner == NULL) {
 | 
			
		||||
            g_object_unref (context);
 | 
			
		||||
            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,
 | 
			
		||||
                                        context_name_vanished_callback,
 | 
			
		||||
                                        context,
 | 
			
		||||
                                        NULL);
 | 
			
		||||
        g_free (name_owner);
 | 
			
		||||
 | 
			
		||||
        return context;
 | 
			
		||||
    }
 | 
			
		||||
    return NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -345,39 +413,129 @@ context_async_ready_callback (GObject      *source_object,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eekboard_context_set_keyboard:
 | 
			
		||||
 * eekboard_context_add_keyboard:
 | 
			
		||||
 * @context: an #EekboardContext
 | 
			
		||||
 * @keyboard: an #EekKeyboard
 | 
			
		||||
 * @cancellable: a #GCancellable
 | 
			
		||||
 *
 | 
			
		||||
 * Set the keyboard description of @context to @keyboard.
 | 
			
		||||
 * Register @keyboard in @context.
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
eekboard_context_set_keyboard (EekboardContext *context,
 | 
			
		||||
guint
 | 
			
		||||
eekboard_context_add_keyboard (EekboardContext *context,
 | 
			
		||||
                               EekKeyboard     *keyboard,
 | 
			
		||||
                               GCancellable    *cancellable)
 | 
			
		||||
{
 | 
			
		||||
    EekboardContextPrivate *priv;
 | 
			
		||||
    GVariant *variant;
 | 
			
		||||
    GVariant *variant, *result;
 | 
			
		||||
    GError *error;
 | 
			
		||||
 | 
			
		||||
    g_return_val_if_fail (EEKBOARD_IS_CONTEXT(context), 0);
 | 
			
		||||
    g_return_val_if_fail (EEK_IS_KEYBOARD(keyboard), 0);
 | 
			
		||||
 | 
			
		||||
    priv = EEKBOARD_CONTEXT_GET_PRIVATE (context);
 | 
			
		||||
 | 
			
		||||
    variant = eek_serializable_serialize (EEK_SERIALIZABLE(keyboard));
 | 
			
		||||
    if (g_variant_is_floating (variant))
 | 
			
		||||
        g_variant_ref_sink (variant);
 | 
			
		||||
 | 
			
		||||
    error = NULL;
 | 
			
		||||
    result = g_dbus_proxy_call_sync (G_DBUS_PROXY(context),
 | 
			
		||||
                                     "AddKeyboard",
 | 
			
		||||
                                     g_variant_new ("(v)", variant),
 | 
			
		||||
                                     G_DBUS_CALL_FLAGS_NONE,
 | 
			
		||||
                                     -1,
 | 
			
		||||
                                     cancellable,
 | 
			
		||||
                                     &error);
 | 
			
		||||
    g_variant_unref (variant);
 | 
			
		||||
 | 
			
		||||
    if (result) {
 | 
			
		||||
        guint keyboard_id;
 | 
			
		||||
 | 
			
		||||
        g_variant_get (result, "(u)", &keyboard_id);
 | 
			
		||||
        g_variant_unref (result);
 | 
			
		||||
 | 
			
		||||
        if (keyboard_id != 0) {
 | 
			
		||||
            g_hash_table_insert (priv->keyboard_hash,
 | 
			
		||||
                                 GUINT_TO_POINTER(keyboard_id),
 | 
			
		||||
                                 g_object_ref (keyboard));
 | 
			
		||||
        }
 | 
			
		||||
        return keyboard_id;
 | 
			
		||||
    }
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eekboard_context_remove_keyboard:
 | 
			
		||||
 * @context: an #EekboardContext
 | 
			
		||||
 * @keyboard_id: keyboard ID
 | 
			
		||||
 * @cancellable: a #GCancellable
 | 
			
		||||
 *
 | 
			
		||||
 * Unregister the keyboard with @keyboard_id in @context.
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
eekboard_context_remove_keyboard (EekboardContext *context,
 | 
			
		||||
                                  guint            keyboard_id,
 | 
			
		||||
                                  GCancellable    *cancellable)
 | 
			
		||||
{
 | 
			
		||||
    EekboardContextPrivate *priv;
 | 
			
		||||
    EekKeyboard *keyboard;
 | 
			
		||||
 | 
			
		||||
    g_return_if_fail (EEKBOARD_IS_CONTEXT(context));
 | 
			
		||||
    g_return_if_fail (EEK_IS_KEYBOARD(keyboard));
 | 
			
		||||
 | 
			
		||||
    priv = EEKBOARD_CONTEXT_GET_PRIVATE(context);
 | 
			
		||||
    if (priv->keyboard)
 | 
			
		||||
        g_object_unref (priv->keyboard);
 | 
			
		||||
    priv->keyboard = g_object_ref (keyboard);
 | 
			
		||||
    priv = EEKBOARD_CONTEXT_GET_PRIVATE (context);
 | 
			
		||||
 | 
			
		||||
    keyboard = g_hash_table_lookup (priv->keyboard_hash,
 | 
			
		||||
                                    GUINT_TO_POINTER(keyboard_id));
 | 
			
		||||
    if (keyboard == priv->keyboard)
 | 
			
		||||
        priv->keyboard = NULL;
 | 
			
		||||
 | 
			
		||||
    g_hash_table_remove (priv->keyboard_hash, GUINT_TO_POINTER(keyboard_id));
 | 
			
		||||
 | 
			
		||||
    variant = eek_serializable_serialize (EEK_SERIALIZABLE(priv->keyboard));
 | 
			
		||||
    g_dbus_proxy_call (G_DBUS_PROXY(context),
 | 
			
		||||
                       "SetKeyboard",
 | 
			
		||||
                       g_variant_new ("(v)", variant),
 | 
			
		||||
                       "RemoveKeyboard",
 | 
			
		||||
                       g_variant_new ("(u)", keyboard_id),
 | 
			
		||||
                       G_DBUS_CALL_FLAGS_NONE,
 | 
			
		||||
                       -1,
 | 
			
		||||
                       cancellable,
 | 
			
		||||
                       context_async_ready_callback,
 | 
			
		||||
                       NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eekboard_context_set_keyboard:
 | 
			
		||||
 * @context: an #EekboardContext
 | 
			
		||||
 * @keyboard_id: keyboard ID
 | 
			
		||||
 * @cancellable: a #GCancellable
 | 
			
		||||
 *
 | 
			
		||||
 * Select a keyboard with ID @keyboard_id in @context.
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
eekboard_context_set_keyboard (EekboardContext *context,
 | 
			
		||||
                               guint            keyboard_id,
 | 
			
		||||
                               GCancellable    *cancellable)
 | 
			
		||||
{
 | 
			
		||||
    EekboardContextPrivate *priv;
 | 
			
		||||
    EekKeyboard *keyboard;
 | 
			
		||||
 | 
			
		||||
    g_return_if_fail (EEKBOARD_IS_CONTEXT(context));
 | 
			
		||||
 | 
			
		||||
    priv = EEKBOARD_CONTEXT_GET_PRIVATE (context);
 | 
			
		||||
 | 
			
		||||
    keyboard = g_hash_table_lookup (priv->keyboard_hash,
 | 
			
		||||
                                    GUINT_TO_POINTER(keyboard_id));
 | 
			
		||||
    if (!keyboard || keyboard == priv->keyboard)
 | 
			
		||||
        return;
 | 
			
		||||
 | 
			
		||||
    priv->keyboard = keyboard;
 | 
			
		||||
 | 
			
		||||
    g_dbus_proxy_call (G_DBUS_PROXY(context),
 | 
			
		||||
                       "SetKeyboard",
 | 
			
		||||
                       g_variant_new ("(u)", keyboard_id),
 | 
			
		||||
                       G_DBUS_CALL_FLAGS_NONE,
 | 
			
		||||
                       -1,
 | 
			
		||||
                       cancellable,
 | 
			
		||||
                       context_async_ready_callback,
 | 
			
		||||
                       NULL);
 | 
			
		||||
    g_variant_unref (variant);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@ -400,9 +558,9 @@ eekboard_context_set_group (EekboardContext *context,
 | 
			
		||||
    priv = EEKBOARD_CONTEXT_GET_PRIVATE (context);
 | 
			
		||||
 | 
			
		||||
    g_return_if_fail (priv->keyboard);
 | 
			
		||||
    g_return_if_fail (group >= 0);
 | 
			
		||||
 | 
			
		||||
    eek_keyboard_set_group (priv->keyboard, group);
 | 
			
		||||
    if (eek_element_get_group (EEK_ELEMENT(priv->keyboard)) != group) {
 | 
			
		||||
        eek_element_set_group (EEK_ELEMENT(priv->keyboard), group);
 | 
			
		||||
        g_dbus_proxy_call (G_DBUS_PROXY(context),
 | 
			
		||||
                           "SetGroup",
 | 
			
		||||
                           g_variant_new ("(i)", group),
 | 
			
		||||
@ -411,6 +569,7 @@ eekboard_context_set_group (EekboardContext *context,
 | 
			
		||||
                           cancellable,
 | 
			
		||||
                           context_async_ready_callback,
 | 
			
		||||
                           NULL);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@ -588,3 +747,33 @@ eekboard_context_is_enabled (EekboardContext *context)
 | 
			
		||||
    priv = EEKBOARD_CONTEXT_GET_PRIVATE (context);
 | 
			
		||||
    return priv->enabled;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eekboard_context_set_fullscreen:
 | 
			
		||||
 * @context: an #EekboardContext
 | 
			
		||||
 * @fullscreen: a flag to indicate fullscreen mode
 | 
			
		||||
 * @cancellable: a #GCancellable
 | 
			
		||||
 *
 | 
			
		||||
 * Set the fullscreen mode of @context.
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
eekboard_context_set_fullscreen (EekboardContext *context,
 | 
			
		||||
                                 gboolean         fullscreen,
 | 
			
		||||
                                 GCancellable    *cancellable)
 | 
			
		||||
{
 | 
			
		||||
    EekboardContextPrivate *priv;
 | 
			
		||||
 | 
			
		||||
    g_return_if_fail (EEKBOARD_IS_CONTEXT(context));
 | 
			
		||||
 | 
			
		||||
    priv = EEKBOARD_CONTEXT_GET_PRIVATE (context);
 | 
			
		||||
    if (priv->fullscreen != fullscreen) {
 | 
			
		||||
        g_dbus_proxy_call (G_DBUS_PROXY(context),
 | 
			
		||||
                           "SetFullscreen",
 | 
			
		||||
                           g_variant_new ("(b)", fullscreen),
 | 
			
		||||
                           G_DBUS_CALL_FLAGS_NONE,
 | 
			
		||||
                           -1,
 | 
			
		||||
                           cancellable,
 | 
			
		||||
                           context_async_ready_callback,
 | 
			
		||||
                           NULL);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -34,21 +34,43 @@ 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:
 | 
			
		||||
 * @enabled: class handler for #EekboardContext::enabled signal
 | 
			
		||||
 * @disabled: class handler for #EekboardContext::disabled signal
 | 
			
		||||
 * @key_pressed: class handler for #EekboardContext::key-pressed signal
 | 
			
		||||
 * @key_released: class handler for #EekboardContext::key-released signal
 | 
			
		||||
 */
 | 
			
		||||
struct _EekboardContextClass {
 | 
			
		||||
    /*< private >*/
 | 
			
		||||
    GDBusProxyClass parent_class;
 | 
			
		||||
 | 
			
		||||
    /*< public >*/
 | 
			
		||||
    /* signals */
 | 
			
		||||
    void (*enabled)      (EekboardContext *self);
 | 
			
		||||
    void (*disabled)     (EekboardContext *self);
 | 
			
		||||
    void (*key_pressed)  (EekboardContext *self,
 | 
			
		||||
                          guint            keycode);
 | 
			
		||||
    void (*key_released) (EekboardContext *self,
 | 
			
		||||
                          guint            keycode);
 | 
			
		||||
    void (*destroyed)    (EekboardContext *self);
 | 
			
		||||
 | 
			
		||||
    /*< private >*/
 | 
			
		||||
    /* padding */
 | 
			
		||||
    gpointer pdummy[23];
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
GType            eekboard_context_get_type       (void) G_GNUC_CONST;
 | 
			
		||||
@ -56,9 +78,15 @@ GType            eekboard_context_get_type      (void) G_GNUC_CONST;
 | 
			
		||||
EekboardContext *eekboard_context_new            (GDBusConnection *connection,
 | 
			
		||||
                                                  const gchar     *object_path,
 | 
			
		||||
                                                  GCancellable    *cancellable);
 | 
			
		||||
void             eekboard_context_set_keyboard  (EekboardContext *context,
 | 
			
		||||
guint            eekboard_context_add_keyboard   (EekboardContext *context,
 | 
			
		||||
                                                  EekKeyboard     *keyboard,
 | 
			
		||||
                                                  GCancellable    *cancellable);
 | 
			
		||||
void             eekboard_context_remove_keyboard (EekboardContext *context,
 | 
			
		||||
                                                   guint            keyboard_id,
 | 
			
		||||
                                                   GCancellable    *cancellable);
 | 
			
		||||
void             eekboard_context_set_keyboard   (EekboardContext *context,
 | 
			
		||||
                                                  guint            keyboard_id,
 | 
			
		||||
                                                  GCancellable    *cancellable);
 | 
			
		||||
void             eekboard_context_show_keyboard  (EekboardContext *context,
 | 
			
		||||
                                                  GCancellable    *cancellable);
 | 
			
		||||
void             eekboard_context_hide_keyboard  (EekboardContext *context,
 | 
			
		||||
@ -77,6 +105,9 @@ gboolean         eekboard_context_is_keyboard_visible
 | 
			
		||||
void             eekboard_context_set_enabled    (EekboardContext *context,
 | 
			
		||||
                                                  gboolean         enabled);
 | 
			
		||||
gboolean         eekboard_context_is_enabled     (EekboardContext *context);
 | 
			
		||||
void             eekboard_context_set_fullscreen (EekboardContext *context,
 | 
			
		||||
                                                  gboolean         fullscreen,
 | 
			
		||||
                                                  GCancellable    *cancellable);
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
#endif  /* EEKBOARD_CONTEXT_H */
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										342
									
								
								eekboard/eekboard-eekboard.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										342
									
								
								eekboard/eekboard-eekboard.c
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,342 @@
 | 
			
		||||
/* 
 | 
			
		||||
 * 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-eekboard
 | 
			
		||||
 * @short_description: D-Bus proxy of eekboard-server
 | 
			
		||||
 *
 | 
			
		||||
 * The #EekboardEekboard class provides a client side access to eekboard-server.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_CONFIG_H
 | 
			
		||||
#include "config.h"
 | 
			
		||||
#endif  /* HAVE_CONFIG_H */
 | 
			
		||||
 | 
			
		||||
#include "eekboard/eekboard-eekboard.h"
 | 
			
		||||
 | 
			
		||||
enum {
 | 
			
		||||
    DESTROYED,
 | 
			
		||||
    LAST_SIGNAL
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static guint signals[LAST_SIGNAL] = { 0, };
 | 
			
		||||
 | 
			
		||||
G_DEFINE_TYPE (EekboardEekboard, eekboard_eekboard, G_TYPE_DBUS_PROXY);
 | 
			
		||||
 | 
			
		||||
#define EEKBOARD_EEKBOARD_GET_PRIVATE(obj)                               \
 | 
			
		||||
    (G_TYPE_INSTANCE_GET_PRIVATE ((obj), EEKBOARD_TYPE_EEKBOARD, EekboardEekboardPrivate))
 | 
			
		||||
 | 
			
		||||
struct _EekboardEekboardPrivate
 | 
			
		||||
{
 | 
			
		||||
    GHashTable *context_hash;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
eekboard_eekboard_real_destroyed (EekboardEekboard *self)
 | 
			
		||||
{
 | 
			
		||||
    EekboardEekboardPrivate *priv = EEKBOARD_EEKBOARD_GET_PRIVATE(self);
 | 
			
		||||
 | 
			
		||||
    // g_debug ("eekboard_eekboard_real_destroyed");
 | 
			
		||||
    g_hash_table_remove_all (priv->context_hash);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
eekboard_eekboard_dispose (GObject *object)
 | 
			
		||||
{
 | 
			
		||||
    EekboardEekboardPrivate *priv = EEKBOARD_EEKBOARD_GET_PRIVATE(object);
 | 
			
		||||
 | 
			
		||||
    if (priv->context_hash) {
 | 
			
		||||
        g_hash_table_destroy (priv->context_hash);
 | 
			
		||||
        priv->context_hash = NULL;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    G_OBJECT_CLASS (eekboard_eekboard_parent_class)->dispose (object);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
eekboard_eekboard_class_init (EekboardEekboardClass *klass)
 | 
			
		||||
{
 | 
			
		||||
    GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
 | 
			
		||||
 | 
			
		||||
    g_type_class_add_private (gobject_class,
 | 
			
		||||
                              sizeof (EekboardEekboardPrivate));
 | 
			
		||||
 | 
			
		||||
    klass->destroyed = eekboard_eekboard_real_destroyed;
 | 
			
		||||
 | 
			
		||||
    gobject_class->dispose = eekboard_eekboard_dispose;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * EekboardEekboard::destroyed:
 | 
			
		||||
     * @eekboard: an #EekboardEekboard
 | 
			
		||||
     *
 | 
			
		||||
     * 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(EekboardEekboardClass, destroyed),
 | 
			
		||||
                      NULL,
 | 
			
		||||
                      NULL,
 | 
			
		||||
                      g_cclosure_marshal_VOID__VOID,
 | 
			
		||||
                      G_TYPE_NONE,
 | 
			
		||||
                      0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
eekboard_eekboard_init (EekboardEekboard *self)
 | 
			
		||||
{
 | 
			
		||||
    EekboardEekboardPrivate *priv;
 | 
			
		||||
 | 
			
		||||
    priv = self->priv = EEKBOARD_EEKBOARD_GET_PRIVATE(self);
 | 
			
		||||
    priv->context_hash =
 | 
			
		||||
        g_hash_table_new_full (g_str_hash,
 | 
			
		||||
                               g_str_equal,
 | 
			
		||||
                               (GDestroyNotify)g_free,
 | 
			
		||||
                               (GDestroyNotify)g_object_unref);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
eekboard_name_vanished_callback (GDBusConnection *connection,
 | 
			
		||||
                                 const gchar     *name,
 | 
			
		||||
                                 gpointer         user_data)
 | 
			
		||||
{
 | 
			
		||||
    EekboardEekboard *eekboard = user_data;
 | 
			
		||||
    g_signal_emit_by_name (eekboard, "destroyed", NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eekboard_eekboard_new:
 | 
			
		||||
 * @connection: a #GDBusConnection
 | 
			
		||||
 * @cancellable: a #GCancellable
 | 
			
		||||
 *
 | 
			
		||||
 * Create a D-Bus proxy of eekboard-eekboard.
 | 
			
		||||
 */
 | 
			
		||||
EekboardEekboard *
 | 
			
		||||
eekboard_eekboard_new (GDBusConnection *connection,
 | 
			
		||||
                       GCancellable    *cancellable)
 | 
			
		||||
{
 | 
			
		||||
    GInitable *initable;
 | 
			
		||||
    GError *error;
 | 
			
		||||
 | 
			
		||||
    g_assert (G_IS_DBUS_CONNECTION(connection));
 | 
			
		||||
 | 
			
		||||
    error = NULL;
 | 
			
		||||
    initable =
 | 
			
		||||
        g_initable_new (EEKBOARD_TYPE_EEKBOARD,
 | 
			
		||||
                        cancellable,
 | 
			
		||||
                        &error,
 | 
			
		||||
                        "g-connection", connection,
 | 
			
		||||
                        "g-name", "com.redhat.Eekboard.Server",
 | 
			
		||||
                        "g-interface-name", "com.redhat.Eekboard.Server",
 | 
			
		||||
                        "g-object-path", "/com/redhat/Eekboard/Server",
 | 
			
		||||
                        NULL);
 | 
			
		||||
    if (initable != NULL) {
 | 
			
		||||
        EekboardEekboard *eekboard = EEKBOARD_EEKBOARD (initable);
 | 
			
		||||
        gchar *name_owner = g_dbus_proxy_get_name_owner (G_DBUS_PROXY(eekboard));
 | 
			
		||||
        if (name_owner == NULL) {
 | 
			
		||||
            g_object_unref (eekboard);
 | 
			
		||||
            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,
 | 
			
		||||
                                        eekboard,
 | 
			
		||||
                                        NULL);
 | 
			
		||||
        g_free (name_owner);
 | 
			
		||||
 | 
			
		||||
        return eekboard;
 | 
			
		||||
    }
 | 
			
		||||
    return NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
on_context_destroyed (EekboardContext *context,
 | 
			
		||||
                      gpointer         user_data)
 | 
			
		||||
{
 | 
			
		||||
    EekboardEekboard *eekboard = user_data;
 | 
			
		||||
    EekboardEekboardPrivate *priv = EEKBOARD_EEKBOARD_GET_PRIVATE(eekboard);
 | 
			
		||||
 | 
			
		||||
    g_hash_table_remove (priv->context_hash,
 | 
			
		||||
                         g_dbus_proxy_get_object_path (G_DBUS_PROXY(context)));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eekboard_eekboard_create_context:
 | 
			
		||||
 * @eekboard: an #EekboardEekboard
 | 
			
		||||
 * @client_name: name of the client
 | 
			
		||||
 * @cancellable: a #GCancellable
 | 
			
		||||
 *
 | 
			
		||||
 * Create a new input context.
 | 
			
		||||
 */
 | 
			
		||||
EekboardContext *
 | 
			
		||||
eekboard_eekboard_create_context (EekboardEekboard *eekboard,
 | 
			
		||||
                                  const gchar      *client_name,
 | 
			
		||||
                                  GCancellable     *cancellable)
 | 
			
		||||
{
 | 
			
		||||
    GVariant *variant;
 | 
			
		||||
    const gchar *object_path;
 | 
			
		||||
    EekboardContext *context;
 | 
			
		||||
    EekboardEekboardPrivate *priv;
 | 
			
		||||
    GError *error;
 | 
			
		||||
    GDBusConnection *connection;
 | 
			
		||||
 | 
			
		||||
    g_assert (EEKBOARD_IS_EEKBOARD(eekboard));
 | 
			
		||||
    g_assert (client_name);
 | 
			
		||||
 | 
			
		||||
    error = NULL;
 | 
			
		||||
    variant = g_dbus_proxy_call_sync (G_DBUS_PROXY(eekboard),
 | 
			
		||||
                                      "CreateContext",
 | 
			
		||||
                                      g_variant_new ("(s)", client_name),
 | 
			
		||||
                                      G_DBUS_CALL_FLAGS_NONE,
 | 
			
		||||
                                      -1,
 | 
			
		||||
                                      cancellable,
 | 
			
		||||
                                      &error);
 | 
			
		||||
    if (!variant)
 | 
			
		||||
        return NULL;
 | 
			
		||||
 | 
			
		||||
    g_variant_get (variant, "(&s)", &object_path);
 | 
			
		||||
    connection = g_dbus_proxy_get_connection (G_DBUS_PROXY(eekboard));
 | 
			
		||||
    context = eekboard_context_new (connection, object_path, cancellable);
 | 
			
		||||
    if (!context) {
 | 
			
		||||
        g_variant_unref (variant);
 | 
			
		||||
        return NULL;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    priv = EEKBOARD_EEKBOARD_GET_PRIVATE(eekboard);
 | 
			
		||||
    g_hash_table_insert (priv->context_hash,
 | 
			
		||||
                         g_strdup (object_path),
 | 
			
		||||
                         g_object_ref (context));
 | 
			
		||||
    g_signal_connect (context, "destroyed",
 | 
			
		||||
                      G_CALLBACK(on_context_destroyed), eekboard);
 | 
			
		||||
    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);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eekboard_eekboard_push_context:
 | 
			
		||||
 * @eekboard: an #EekboardEekboard
 | 
			
		||||
 * @context: an #EekboardContext
 | 
			
		||||
 * @cancellable: a #GCancellable
 | 
			
		||||
 *
 | 
			
		||||
 * Enable the input context @context and disable the others.
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
eekboard_eekboard_push_context (EekboardEekboard *eekboard,
 | 
			
		||||
                                EekboardContext  *context,
 | 
			
		||||
                                GCancellable     *cancellable)
 | 
			
		||||
{
 | 
			
		||||
    EekboardEekboardPrivate *priv;
 | 
			
		||||
    const gchar *object_path;
 | 
			
		||||
 | 
			
		||||
    g_return_if_fail (EEKBOARD_IS_EEKBOARD(eekboard));
 | 
			
		||||
    g_return_if_fail (EEKBOARD_IS_CONTEXT(context));
 | 
			
		||||
 | 
			
		||||
    object_path = g_dbus_proxy_get_object_path (G_DBUS_PROXY(context));
 | 
			
		||||
 | 
			
		||||
    priv = EEKBOARD_EEKBOARD_GET_PRIVATE(eekboard);
 | 
			
		||||
    context = g_hash_table_lookup (priv->context_hash, object_path);
 | 
			
		||||
    if (!context)
 | 
			
		||||
        return;
 | 
			
		||||
 | 
			
		||||
    eekboard_context_set_enabled (context, TRUE);
 | 
			
		||||
    g_dbus_proxy_call (G_DBUS_PROXY(eekboard),
 | 
			
		||||
                       "PushContext",
 | 
			
		||||
                       g_variant_new ("(s)", object_path),
 | 
			
		||||
                       G_DBUS_CALL_FLAGS_NONE,
 | 
			
		||||
                       -1,
 | 
			
		||||
                       cancellable,
 | 
			
		||||
                       eekboard_async_ready_callback,
 | 
			
		||||
                       NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eekboard_eekboard_pop_context:
 | 
			
		||||
 * @eekboard: an #EekboardEekboard
 | 
			
		||||
 * @cancellable: a #GCancellable
 | 
			
		||||
 *
 | 
			
		||||
 * Disable the current input context and enable the previous one.
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
eekboard_eekboard_pop_context (EekboardEekboard *eekboard,
 | 
			
		||||
                               GCancellable     *cancellable)
 | 
			
		||||
{
 | 
			
		||||
    g_return_if_fail (EEKBOARD_IS_EEKBOARD(eekboard));
 | 
			
		||||
 | 
			
		||||
    g_dbus_proxy_call (G_DBUS_PROXY(eekboard),
 | 
			
		||||
                       "PopContext",
 | 
			
		||||
                       NULL,
 | 
			
		||||
                       G_DBUS_CALL_FLAGS_NONE,
 | 
			
		||||
                       -1,
 | 
			
		||||
                       cancellable,
 | 
			
		||||
                       eekboard_async_ready_callback,
 | 
			
		||||
                       NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eekboard_eekboard_destroy_context:
 | 
			
		||||
 * @eekboard: an #EekboardEekboard
 | 
			
		||||
 * @context: an #EekboardContext
 | 
			
		||||
 * @cancellable: a #GCancellable
 | 
			
		||||
 *
 | 
			
		||||
 * Remove @context from @eekboard.
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
eekboard_eekboard_destroy_context (EekboardEekboard *eekboard,
 | 
			
		||||
                                   EekboardContext  *context,
 | 
			
		||||
                                   GCancellable     *cancellable)
 | 
			
		||||
{
 | 
			
		||||
    EekboardEekboardPrivate *priv;
 | 
			
		||||
    const gchar *object_path;
 | 
			
		||||
 | 
			
		||||
    g_return_if_fail (EEKBOARD_IS_EEKBOARD(eekboard));
 | 
			
		||||
    g_return_if_fail (EEKBOARD_IS_CONTEXT(context));
 | 
			
		||||
 | 
			
		||||
    priv = EEKBOARD_EEKBOARD_GET_PRIVATE(eekboard);
 | 
			
		||||
 | 
			
		||||
    object_path = g_dbus_proxy_get_object_path (G_DBUS_PROXY(context));
 | 
			
		||||
    g_hash_table_remove (priv->context_hash, object_path);
 | 
			
		||||
 | 
			
		||||
    g_dbus_proxy_call (G_DBUS_PROXY(eekboard),
 | 
			
		||||
                       "DestroyContext",
 | 
			
		||||
                       g_variant_new ("(s)", object_path),
 | 
			
		||||
                       G_DBUS_CALL_FLAGS_NONE,
 | 
			
		||||
                       -1,
 | 
			
		||||
                       cancellable,
 | 
			
		||||
                       eekboard_async_ready_callback,
 | 
			
		||||
                       NULL);
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										76
									
								
								eekboard/eekboard-eekboard.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										76
									
								
								eekboard/eekboard-eekboard.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,76 @@
 | 
			
		||||
/* 
 | 
			
		||||
 * 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_EEKBOARD_H
 | 
			
		||||
#define EEKBOARD_EEKBOARD_H 1
 | 
			
		||||
 | 
			
		||||
#include <gio/gio.h>
 | 
			
		||||
#include "eekboard/eekboard-context.h"
 | 
			
		||||
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
#define EEKBOARD_TYPE_EEKBOARD (eekboard_eekboard_get_type())
 | 
			
		||||
#define EEKBOARD_EEKBOARD(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EEKBOARD_TYPE_EEKBOARD, EekboardEekboard))
 | 
			
		||||
#define EEKBOARD_EEKBOARD_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EEKBOARD_TYPE_EEKBOARD, EekboardEekboardClass))
 | 
			
		||||
#define EEKBOARD_IS_EEKBOARD(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EEKBOARD_TYPE_EEKBOARD))
 | 
			
		||||
#define EEKBOARD_IS_EEKBOARD_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EEKBOARD_TYPE_EEKBOARD))
 | 
			
		||||
#define EEKBOARD_EEKBOARD_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EEKBOARD_TYPE_EEKBOARD, EekboardEekboardClass))
 | 
			
		||||
 | 
			
		||||
typedef struct _EekboardEekboard EekboardEekboard;
 | 
			
		||||
typedef struct _EekboardEekboardClass EekboardEekboardClass;
 | 
			
		||||
typedef struct _EekboardEekboardPrivate EekboardEekboardPrivate;
 | 
			
		||||
 | 
			
		||||
struct _EekboardEekboard {
 | 
			
		||||
    /*< private >*/
 | 
			
		||||
    GDBusProxy parent;
 | 
			
		||||
 | 
			
		||||
    EekboardEekboardPrivate *priv;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct _EekboardEekboardClass {
 | 
			
		||||
    /*< private >*/
 | 
			
		||||
    GDBusProxyClass parent_class;
 | 
			
		||||
 | 
			
		||||
    /* signals */
 | 
			
		||||
    void (* destroyed) (EekboardEekboard *self);
 | 
			
		||||
 | 
			
		||||
    /*< private >*/
 | 
			
		||||
    /* padding */
 | 
			
		||||
    gpointer pdummy[23];
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
GType             eekboard_eekboard_get_type    (void) G_GNUC_CONST;
 | 
			
		||||
 | 
			
		||||
EekboardEekboard *eekboard_eekboard_new         (GDBusConnection  *connection,
 | 
			
		||||
                                                 GCancellable     *cancellable);
 | 
			
		||||
EekboardContext  *eekboard_eekboard_create_context
 | 
			
		||||
                                                (EekboardEekboard *eekboard,
 | 
			
		||||
                                                 const gchar      *client_name,
 | 
			
		||||
                                                 GCancellable     *cancellable);
 | 
			
		||||
void              eekboard_eekboard_push_context
 | 
			
		||||
                                                (EekboardEekboard *eekboard,
 | 
			
		||||
                                                 EekboardContext  *context,
 | 
			
		||||
                                                 GCancellable     *cancellable);
 | 
			
		||||
void              eekboard_eekboard_pop_context (EekboardEekboard *eekboard,
 | 
			
		||||
                                                 GCancellable     *cancellable);
 | 
			
		||||
void              eekboard_eekboard_destroy_context
 | 
			
		||||
                                                (EekboardEekboard *eekboard,
 | 
			
		||||
                                                 EekboardContext  *context,
 | 
			
		||||
                                                 GCancellable     *cancellable);
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
#endif  /* EEKBOARD_EEKBOARD_H */
 | 
			
		||||
@ -1,266 +0,0 @@
 | 
			
		||||
/* 
 | 
			
		||||
 * Copyright (C) 2011 Daiki Ueno <ueno@unixuser.org>
 | 
			
		||||
 * Copyright (C) 2011 Red Hat, Inc.
 | 
			
		||||
 * 
 | 
			
		||||
 * This program is free software: you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU General Public License as published by
 | 
			
		||||
 * the Free Software Foundation, either version 3 of the License, or
 | 
			
		||||
 * (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
 * GNU General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU General Public License
 | 
			
		||||
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * SECTION:eekboard-server
 | 
			
		||||
 * @short_description: D-Bus proxy of eekboard-server
 | 
			
		||||
 *
 | 
			
		||||
 * The #EekboardServer class provides a client side access to eekboard-server.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_CONFIG_H
 | 
			
		||||
#include "config.h"
 | 
			
		||||
#endif  /* HAVE_CONFIG_H */
 | 
			
		||||
 | 
			
		||||
#include "eekboard/eekboard-server.h"
 | 
			
		||||
 | 
			
		||||
G_DEFINE_TYPE (EekboardServer, eekboard_server, G_TYPE_DBUS_PROXY);
 | 
			
		||||
 | 
			
		||||
#define EEKBOARD_SERVER_GET_PRIVATE(obj)                               \
 | 
			
		||||
    (G_TYPE_INSTANCE_GET_PRIVATE ((obj), EEKBOARD_TYPE_SERVER, EekboardServerPrivate))
 | 
			
		||||
 | 
			
		||||
struct _EekboardServerPrivate
 | 
			
		||||
{
 | 
			
		||||
    GHashTable *context_hash;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
eekboard_server_dispose (GObject *object)
 | 
			
		||||
{
 | 
			
		||||
    EekboardServerPrivate *priv = EEKBOARD_SERVER_GET_PRIVATE(object);
 | 
			
		||||
 | 
			
		||||
    if (priv->context_hash) {
 | 
			
		||||
        g_hash_table_destroy (priv->context_hash);
 | 
			
		||||
        priv->context_hash = NULL;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    G_OBJECT_CLASS (eekboard_server_parent_class)->dispose (object);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
eekboard_server_class_init (EekboardServerClass *klass)
 | 
			
		||||
{
 | 
			
		||||
    GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
 | 
			
		||||
 | 
			
		||||
    g_type_class_add_private (gobject_class,
 | 
			
		||||
                              sizeof (EekboardServerPrivate));
 | 
			
		||||
 | 
			
		||||
    gobject_class->dispose = eekboard_server_dispose;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
eekboard_server_init (EekboardServer *self)
 | 
			
		||||
{
 | 
			
		||||
    EekboardServerPrivate *priv;
 | 
			
		||||
 | 
			
		||||
    priv = self->priv = EEKBOARD_SERVER_GET_PRIVATE(self);
 | 
			
		||||
    priv->context_hash =
 | 
			
		||||
        g_hash_table_new_full (g_str_hash,
 | 
			
		||||
                               g_str_equal,
 | 
			
		||||
                               (GDestroyNotify)g_free,
 | 
			
		||||
                               (GDestroyNotify)g_object_unref);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eekboard_server_new:
 | 
			
		||||
 * @connection: a #GDBusConnection
 | 
			
		||||
 * @cancellable: a #GCancellable
 | 
			
		||||
 *
 | 
			
		||||
 * Create a D-Bus proxy of eekboard-server.
 | 
			
		||||
 */
 | 
			
		||||
EekboardServer *
 | 
			
		||||
eekboard_server_new (GDBusConnection *connection,
 | 
			
		||||
                     GCancellable    *cancellable)
 | 
			
		||||
{
 | 
			
		||||
    GInitable *initable;
 | 
			
		||||
    GError *error;
 | 
			
		||||
 | 
			
		||||
    g_assert (G_IS_DBUS_CONNECTION(connection));
 | 
			
		||||
 | 
			
		||||
    error = NULL;
 | 
			
		||||
    initable =
 | 
			
		||||
        g_initable_new (EEKBOARD_TYPE_SERVER,
 | 
			
		||||
                        cancellable,
 | 
			
		||||
                        &error,
 | 
			
		||||
                        "g-connection", connection,
 | 
			
		||||
                        "g-name", "com.redhat.Eekboard.Server",
 | 
			
		||||
                        "g-interface-name", "com.redhat.Eekboard.Server",
 | 
			
		||||
                        "g-object-path", "/com/redhat/Eekboard/Server",
 | 
			
		||||
                        NULL);
 | 
			
		||||
    if (initable != NULL)
 | 
			
		||||
        return EEKBOARD_SERVER (initable);
 | 
			
		||||
    return NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eekboard_server_create_context:
 | 
			
		||||
 * @server: an #EekboardServer
 | 
			
		||||
 * @client_name: name of the client
 | 
			
		||||
 * @cancellable: a #GCancellable
 | 
			
		||||
 *
 | 
			
		||||
 * Create a new input context.
 | 
			
		||||
 */
 | 
			
		||||
EekboardContext *
 | 
			
		||||
eekboard_server_create_context (EekboardServer *server,
 | 
			
		||||
                                const gchar    *client_name,
 | 
			
		||||
                                GCancellable   *cancellable)
 | 
			
		||||
{
 | 
			
		||||
    GVariant *variant;
 | 
			
		||||
    const gchar *object_path;
 | 
			
		||||
    EekboardContext *context;
 | 
			
		||||
    EekboardServerPrivate *priv;
 | 
			
		||||
    GError *error;
 | 
			
		||||
    GDBusConnection *connection;
 | 
			
		||||
 | 
			
		||||
    g_assert (EEKBOARD_IS_SERVER(server));
 | 
			
		||||
    g_assert (client_name);
 | 
			
		||||
 | 
			
		||||
    error = NULL;
 | 
			
		||||
    variant = g_dbus_proxy_call_sync (G_DBUS_PROXY(server),
 | 
			
		||||
                                      "CreateContext",
 | 
			
		||||
                                      g_variant_new ("(s)", client_name),
 | 
			
		||||
                                      G_DBUS_CALL_FLAGS_NONE,
 | 
			
		||||
                                      -1,
 | 
			
		||||
                                      cancellable,
 | 
			
		||||
                                      &error);
 | 
			
		||||
    if (!variant)
 | 
			
		||||
        return NULL;
 | 
			
		||||
 | 
			
		||||
    g_variant_get (variant, "(&s)", &object_path);
 | 
			
		||||
    connection = g_dbus_proxy_get_connection (G_DBUS_PROXY(server));
 | 
			
		||||
    context = eekboard_context_new (connection, object_path, cancellable);
 | 
			
		||||
    if (!context) {
 | 
			
		||||
        g_variant_unref (variant);
 | 
			
		||||
        return NULL;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    priv = EEKBOARD_SERVER_GET_PRIVATE(server);
 | 
			
		||||
    g_hash_table_insert (priv->context_hash,
 | 
			
		||||
                         g_strdup (object_path),
 | 
			
		||||
                         g_object_ref (context));
 | 
			
		||||
    return context;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
server_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);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eekboard_server_push_context:
 | 
			
		||||
 * @server: an #EekboardServer
 | 
			
		||||
 * @context: an #EekboardContext
 | 
			
		||||
 * @cancellable: a #GCancellable
 | 
			
		||||
 *
 | 
			
		||||
 * Enable the input context @context and disable the others.
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
eekboard_server_push_context (EekboardServer  *server,
 | 
			
		||||
                              EekboardContext *context,
 | 
			
		||||
                              GCancellable    *cancellable)
 | 
			
		||||
{
 | 
			
		||||
    EekboardServerPrivate *priv;
 | 
			
		||||
    const gchar *object_path;
 | 
			
		||||
 | 
			
		||||
    g_return_if_fail (EEKBOARD_IS_SERVER(server));
 | 
			
		||||
    g_return_if_fail (EEKBOARD_IS_CONTEXT(context));
 | 
			
		||||
 | 
			
		||||
    object_path = g_dbus_proxy_get_object_path (G_DBUS_PROXY(context));
 | 
			
		||||
 | 
			
		||||
    priv = EEKBOARD_SERVER_GET_PRIVATE(server);
 | 
			
		||||
    context = g_hash_table_lookup (priv->context_hash, object_path);
 | 
			
		||||
    if (!context)
 | 
			
		||||
        return;
 | 
			
		||||
 | 
			
		||||
    eekboard_context_set_enabled (context, TRUE);
 | 
			
		||||
    g_dbus_proxy_call (G_DBUS_PROXY(server),
 | 
			
		||||
                       "PushContext",
 | 
			
		||||
                       g_variant_new ("(s)", object_path),
 | 
			
		||||
                       G_DBUS_CALL_FLAGS_NONE,
 | 
			
		||||
                       -1,
 | 
			
		||||
                       cancellable,
 | 
			
		||||
                       server_async_ready_callback,
 | 
			
		||||
                       NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eekboard_server_pop_context:
 | 
			
		||||
 * @server: an #EekboardServer
 | 
			
		||||
 * @cancellable: a #GCancellable
 | 
			
		||||
 *
 | 
			
		||||
 * Disable the current input context and enable the previous one.
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
eekboard_server_pop_context (EekboardServer  *server,
 | 
			
		||||
                             GCancellable    *cancellable)
 | 
			
		||||
{
 | 
			
		||||
    g_return_if_fail (EEKBOARD_IS_SERVER(server));
 | 
			
		||||
 | 
			
		||||
    g_dbus_proxy_call (G_DBUS_PROXY(server),
 | 
			
		||||
                       "PopContext",
 | 
			
		||||
                       NULL,
 | 
			
		||||
                       G_DBUS_CALL_FLAGS_NONE,
 | 
			
		||||
                       -1,
 | 
			
		||||
                       cancellable,
 | 
			
		||||
                       server_async_ready_callback,
 | 
			
		||||
                       NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * eekboard_server_destroy_context:
 | 
			
		||||
 * @server: an #EekboardServer
 | 
			
		||||
 * @context: an #EekboardContext
 | 
			
		||||
 * @cancellable: a #GCancellable
 | 
			
		||||
 *
 | 
			
		||||
 * Remove @context from @server.
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
eekboard_server_destroy_context (EekboardServer  *server,
 | 
			
		||||
                                 EekboardContext *context,
 | 
			
		||||
                                 GCancellable    *cancellable)
 | 
			
		||||
{
 | 
			
		||||
    EekboardServerPrivate *priv;
 | 
			
		||||
    const gchar *object_path;
 | 
			
		||||
 | 
			
		||||
    g_return_if_fail (EEKBOARD_IS_SERVER(server));
 | 
			
		||||
    g_return_if_fail (EEKBOARD_IS_CONTEXT(context));
 | 
			
		||||
 | 
			
		||||
    priv = EEKBOARD_SERVER_GET_PRIVATE(server);
 | 
			
		||||
 | 
			
		||||
    object_path = g_dbus_proxy_get_object_path (G_DBUS_PROXY(context));
 | 
			
		||||
    g_hash_table_remove (priv->context_hash, object_path);
 | 
			
		||||
 | 
			
		||||
    g_dbus_proxy_call (G_DBUS_PROXY(server),
 | 
			
		||||
                       "DestroyContext",
 | 
			
		||||
                       g_variant_new ("(s)", object_path),
 | 
			
		||||
                       G_DBUS_CALL_FLAGS_NONE,
 | 
			
		||||
                       -1,
 | 
			
		||||
                       cancellable,
 | 
			
		||||
                       server_async_ready_callback,
 | 
			
		||||
                       NULL);
 | 
			
		||||
}
 | 
			
		||||
@ -1,64 +0,0 @@
 | 
			
		||||
/* 
 | 
			
		||||
 * Copyright (C) 2010-2011 Daiki Ueno <ueno@unixuser.org>
 | 
			
		||||
 * Copyright (C) 2010-2011 Red Hat, Inc.
 | 
			
		||||
 * 
 | 
			
		||||
 * This program is free software: you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU General Public License as published by
 | 
			
		||||
 * the Free Software Foundation, either version 3 of the License, or
 | 
			
		||||
 * (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
 * GNU General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU General Public License
 | 
			
		||||
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
#ifndef EEKBOARD_SERVER_H
 | 
			
		||||
#define EEKBOARD_SERVER_H 1
 | 
			
		||||
 | 
			
		||||
#include <gio/gio.h>
 | 
			
		||||
#include "eekboard/eekboard-context.h"
 | 
			
		||||
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
#define EEKBOARD_TYPE_SERVER (eekboard_server_get_type())
 | 
			
		||||
#define EEKBOARD_SERVER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EEKBOARD_TYPE_SERVER, EekboardServer))
 | 
			
		||||
#define EEKBOARD_SERVER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EEKBOARD_TYPE_SERVER, EekboardServerClass))
 | 
			
		||||
#define EEKBOARD_IS_SERVER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EEKBOARD_TYPE_SERVER))
 | 
			
		||||
#define EEKBOARD_IS_SERVER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EEKBOARD_TYPE_SERVER))
 | 
			
		||||
#define EEKBOARD_SERVER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EEKBOARD_TYPE_SERVER, EekboardServerClass))
 | 
			
		||||
 | 
			
		||||
typedef struct _EekboardServer EekboardServer;
 | 
			
		||||
typedef struct _EekboardServerClass EekboardServerClass;
 | 
			
		||||
typedef struct _EekboardServerPrivate EekboardServerPrivate;
 | 
			
		||||
 | 
			
		||||
struct _EekboardServer {
 | 
			
		||||
    GDBusProxy parent;
 | 
			
		||||
 | 
			
		||||
    EekboardServerPrivate *priv;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct _EekboardServerClass {
 | 
			
		||||
    GDBusProxyClass parent_class;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
GType            eekboard_server_get_type        (void) G_GNUC_CONST;
 | 
			
		||||
 | 
			
		||||
EekboardServer  *eekboard_server_new             (GDBusConnection *connection,
 | 
			
		||||
                                                  GCancellable    *cancellable);
 | 
			
		||||
EekboardContext *eekboard_server_create_context  (EekboardServer  *server,
 | 
			
		||||
                                                  const gchar     *client_name,
 | 
			
		||||
                                                  GCancellable    *cancellable);
 | 
			
		||||
void             eekboard_server_push_context    (EekboardServer  *server,
 | 
			
		||||
                                                  EekboardContext *context,
 | 
			
		||||
                                                  GCancellable    *cancellable);
 | 
			
		||||
void             eekboard_server_pop_context     (EekboardServer  *server,
 | 
			
		||||
                                                  GCancellable    *cancellable);
 | 
			
		||||
void             eekboard_server_destroy_context (EekboardServer  *server,
 | 
			
		||||
                                                  EekboardContext *context,
 | 
			
		||||
                                                  GCancellable    *cancellable);
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
#endif  /* EEKBOARD_SERVER_H */
 | 
			
		||||
@ -18,7 +18,7 @@
 | 
			
		||||
#ifndef EEKBOARD_H
 | 
			
		||||
#define EEKBOARD_H 1
 | 
			
		||||
 | 
			
		||||
#include "eekboard/eekboard-server.h"
 | 
			
		||||
#include "eekboard/eekboard-eekboard.h"
 | 
			
		||||
#include "eekboard/eekboard-context.h"
 | 
			
		||||
 | 
			
		||||
#endif  /* EEKBOARD_H */
 | 
			
		||||
 | 
			
		||||
@ -4,3 +4,4 @@ src/client-main.c
 | 
			
		||||
src/desktop-client.c
 | 
			
		||||
src/desktop-client-main.c
 | 
			
		||||
src/xml-main.c
 | 
			
		||||
src/server-main.c
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										7
									
								
								po/POTFILES.skip
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								po/POTFILES.skip
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,7 @@
 | 
			
		||||
eek/eek-element.c
 | 
			
		||||
eek/eek-container.c
 | 
			
		||||
eek/eek-key.c
 | 
			
		||||
eek/eek-keyboard.c
 | 
			
		||||
eek/eek-section.c
 | 
			
		||||
eekboard/eekboard-eekboard.c
 | 
			
		||||
eekboard/eekboard-context.c
 | 
			
		||||
							
								
								
									
										119
									
								
								po/ja.po
									
									
									
									
									
								
							
							
						
						
									
										119
									
								
								po/ja.po
									
									
									
									
									
								
							@ -6,85 +6,90 @@
 | 
			
		||||
#
 | 
			
		||||
msgid ""
 | 
			
		||||
msgstr ""
 | 
			
		||||
"Project-Id-Version: eekboard 0.0.3\n"
 | 
			
		||||
"Project-Id-Version: eekboard 0.90.2\n"
 | 
			
		||||
"Report-Msgid-Bugs-To: \n"
 | 
			
		||||
"POT-Creation-Date: 2010-06-23 16:52+0900\n"
 | 
			
		||||
"PO-Revision-Date: 2010-06-23 16:55+0900\n"
 | 
			
		||||
"POT-Creation-Date: 2011-02-25 13:13+0900\n"
 | 
			
		||||
"PO-Revision-Date: 2011-02-25 13:14+0900\n"
 | 
			
		||||
"Last-Translator: Daiki Ueno <ueno@unixuser.org>\n"
 | 
			
		||||
"Language-Team: Japanese\n"
 | 
			
		||||
"Language: \n"
 | 
			
		||||
"MIME-Version: 1.0\n"
 | 
			
		||||
"Content-Type: text/plain; charset=UTF-8\n"
 | 
			
		||||
"Content-Transfer-Encoding: 8bit\n"
 | 
			
		||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
 | 
			
		||||
 | 
			
		||||
#: ../src/eekboard.c:198
 | 
			
		||||
msgid "_File"
 | 
			
		||||
msgstr "ファイル"
 | 
			
		||||
 | 
			
		||||
#: ../src/eekboard.c:199
 | 
			
		||||
msgid "_Keyboard"
 | 
			
		||||
#: ../src/server-context.c:216
 | 
			
		||||
msgid "Keyboard"
 | 
			
		||||
msgstr "キーボード"
 | 
			
		||||
 | 
			
		||||
#: ../src/eekboard.c:200
 | 
			
		||||
msgid "_Help"
 | 
			
		||||
msgstr "ヘルプ"
 | 
			
		||||
#: ../src/client-main.c:41 ../src/desktop-client-main.c:41
 | 
			
		||||
msgid "Connect to the system bus"
 | 
			
		||||
msgstr "システムバスに接続"
 | 
			
		||||
 | 
			
		||||
#: ../src/eekboard.c:202
 | 
			
		||||
msgid "Country"
 | 
			
		||||
msgstr "国"
 | 
			
		||||
#: ../src/client-main.c:43 ../src/desktop-client-main.c:43
 | 
			
		||||
msgid "Connect to the session bus"
 | 
			
		||||
msgstr "セッションバスに接続"
 | 
			
		||||
 | 
			
		||||
#: ../src/eekboard.c:204
 | 
			
		||||
msgid "Language"
 | 
			
		||||
msgstr "言語"
 | 
			
		||||
#: ../src/client-main.c:45 ../src/desktop-client-main.c:45
 | 
			
		||||
msgid "Connect to the given D-Bus address"
 | 
			
		||||
msgstr "与えられた D-Bus アドレスに接続"
 | 
			
		||||
 | 
			
		||||
#: ../src/eekboard.c:206
 | 
			
		||||
msgid "Model"
 | 
			
		||||
msgstr "モデル"
 | 
			
		||||
#: ../src/client-main.c:47
 | 
			
		||||
msgid "Upload keyboard description from an XML file"
 | 
			
		||||
msgstr "XML ファイルから読み込んだキーボード記述をアップロード"
 | 
			
		||||
 | 
			
		||||
#: ../src/eekboard.c:208
 | 
			
		||||
msgid "Layout"
 | 
			
		||||
msgstr "レイアウト"
 | 
			
		||||
#: ../src/client-main.c:49
 | 
			
		||||
msgid "Set group of the keyboard"
 | 
			
		||||
msgstr "キーボードのグループを設定"
 | 
			
		||||
 | 
			
		||||
#: ../src/eekboard.c:210
 | 
			
		||||
msgid "Option"
 | 
			
		||||
msgstr "オプション"
 | 
			
		||||
#: ../src/client-main.c:51
 | 
			
		||||
msgid "Show keyboard"
 | 
			
		||||
msgstr "キーボードを表示"
 | 
			
		||||
 | 
			
		||||
#: ../src/eekboard.c:217
 | 
			
		||||
msgid "Monitor Key Typing"
 | 
			
		||||
msgstr "打鍵をモニタ"
 | 
			
		||||
#: ../src/client-main.c:53
 | 
			
		||||
msgid "Hide keyboard"
 | 
			
		||||
msgstr "キーボードを隠す"
 | 
			
		||||
 | 
			
		||||
#: ../src/eekboard.c:232
 | 
			
		||||
msgid "Keyboard model to display"
 | 
			
		||||
msgstr "表示するキーボードのモデル"
 | 
			
		||||
#: ../src/client-main.c:55
 | 
			
		||||
msgid "Press key"
 | 
			
		||||
msgstr "キーを押す"
 | 
			
		||||
 | 
			
		||||
#: ../src/eekboard.c:234
 | 
			
		||||
msgid "Keyboard layouts to display, separated with commas"
 | 
			
		||||
msgstr "表示するキーボードのレイアウト,カンマ区切り"
 | 
			
		||||
#: ../src/client-main.c:57
 | 
			
		||||
msgid "Release key"
 | 
			
		||||
msgstr "キーを離す"
 | 
			
		||||
 | 
			
		||||
#: ../src/eekboard.c:236
 | 
			
		||||
msgid "Keyboard layout options to display, separated with commas"
 | 
			
		||||
msgstr "表示するキーボードのオプション,カンマ区切り"
 | 
			
		||||
#: ../src/client-main.c:59
 | 
			
		||||
msgid "Listen events"
 | 
			
		||||
msgstr "イベントの通知を受ける"
 | 
			
		||||
 | 
			
		||||
#: ../src/eekboard.c:238
 | 
			
		||||
msgid "List keyboard models"
 | 
			
		||||
msgstr "キーボードのモデルを一覧"
 | 
			
		||||
#: ../src/desktop-client-main.c:48
 | 
			
		||||
msgid "Listen focus change events with AT-SPI"
 | 
			
		||||
msgstr "AT-SPI によるフォーカス変更イベントの通知を受ける"
 | 
			
		||||
 | 
			
		||||
#: ../src/eekboard.c:240
 | 
			
		||||
msgid "List all available keyboard layouts and variants"
 | 
			
		||||
msgstr "利用可能なキーボードのレイアウトとバリアントを一覧"
 | 
			
		||||
#: ../src/desktop-client-main.c:50
 | 
			
		||||
msgid "Listen keystroke events with AT-SPI"
 | 
			
		||||
msgstr "AT-SPI による打鍵イベントの通知を受ける"
 | 
			
		||||
 | 
			
		||||
#: ../src/eekboard.c:242
 | 
			
		||||
msgid "List all available keyboard layout options"
 | 
			
		||||
msgstr "利用可能なキーボードのレイアウトオプションを一覧"
 | 
			
		||||
#: ../src/xml-main.c:46
 | 
			
		||||
msgid "Show the keyboard loaded from an XML file"
 | 
			
		||||
msgstr "XML ファイルから読み込んだキーボードを表示"
 | 
			
		||||
 | 
			
		||||
#: ../src/eekboard.c:244
 | 
			
		||||
msgid "Display version"
 | 
			
		||||
msgstr "バージョンを表示"
 | 
			
		||||
#: ../src/xml-main.c:48
 | 
			
		||||
msgid "Output the current layout into an XML file"
 | 
			
		||||
msgstr "現在のレイアウトを XML ファイルに出力"
 | 
			
		||||
 | 
			
		||||
#: ../src/eekboard.c:261
 | 
			
		||||
msgid "A virtual keyboard for GNOME"
 | 
			
		||||
msgstr "GNOME 向け仮想キーボード"
 | 
			
		||||
#: ../src/xml-main.c:50
 | 
			
		||||
msgid "List configuration items for given spec"
 | 
			
		||||
msgstr "与えられたスペックのための設定項目を一覧"
 | 
			
		||||
 | 
			
		||||
#: ../src/eekboard.c:265
 | 
			
		||||
msgid "Eekboard web site"
 | 
			
		||||
msgstr "Eekboard のウェブサイト"
 | 
			
		||||
#: ../src/xml-main.c:52
 | 
			
		||||
msgid "Specify model"
 | 
			
		||||
msgstr "モデルを指定"
 | 
			
		||||
 | 
			
		||||
#: ../src/xml-main.c:54
 | 
			
		||||
msgid "Specify layouts"
 | 
			
		||||
msgstr "レイアウトを指定"
 | 
			
		||||
 | 
			
		||||
#: ../src/xml-main.c:56
 | 
			
		||||
msgid "Specify options"
 | 
			
		||||
msgstr "オプションを指定"
 | 
			
		||||
 | 
			
		||||
@ -23,6 +23,8 @@ bin_PROGRAMS = \
 | 
			
		||||
	eekboard-server \
 | 
			
		||||
	eekboard-xml
 | 
			
		||||
 | 
			
		||||
noinst_LTLIBRARIES = libxklutil.la
 | 
			
		||||
 | 
			
		||||
eekboard_desktop_client_CFLAGS = \
 | 
			
		||||
	-I$(top_srcdir) \
 | 
			
		||||
	$(GIO2_CFLAGS) \
 | 
			
		||||
@ -32,6 +34,7 @@ eekboard_desktop_client_CFLAGS = \
 | 
			
		||||
	$(LIBXKLAVIER_CFLAGS)
 | 
			
		||||
 | 
			
		||||
eekboard_desktop_client_LDADD = \
 | 
			
		||||
	$(builddir)/libxklutil.la \
 | 
			
		||||
	$(top_builddir)/eekboard/libeekboard.la \
 | 
			
		||||
	$(top_builddir)/eek/libeek.la \
 | 
			
		||||
	$(top_builddir)/eek/libeek-xkl.la \
 | 
			
		||||
@ -61,7 +64,8 @@ eekboard_desktop_client_SOURCES = desktop-client.c desktop-client-main.c
 | 
			
		||||
eekboard_server_CFLAGS = \
 | 
			
		||||
	-I$(top_srcdir) \
 | 
			
		||||
	$(GIO2_CFLAGS) \
 | 
			
		||||
	$(GTK_CFLAGS)
 | 
			
		||||
	$(GTK_CFLAGS) \
 | 
			
		||||
	-DTHEMEDIR=\"$(pkgdatadir)/themes\"
 | 
			
		||||
 | 
			
		||||
eekboard_server_LDADD = \
 | 
			
		||||
	$(top_builddir)/eekboard/libeekboard.la \
 | 
			
		||||
@ -70,14 +74,14 @@ eekboard_server_LDADD = \
 | 
			
		||||
	$(GIO2_LIBS) \
 | 
			
		||||
	$(GTK_LIBS)
 | 
			
		||||
 | 
			
		||||
eekboard_server_headers = server-server.h server-context.h
 | 
			
		||||
eekboard_server_SOURCES = server-server.c server-context.c server-main.c
 | 
			
		||||
 | 
			
		||||
if ENABLE_CLUTTER
 | 
			
		||||
eekboard_server_CFLAGS += $(CLUTTER_CFLAGS) $(CLUTTER_GTK_CFLAGS)
 | 
			
		||||
eekboard_server_LDADD += $(CLUTTER_LIBS) $(top_builddir)/eek/libeek-clutter.la $(CLUTTER_GTK_LIBS)
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
eekboard_server_headers = server-server.h server-context.h
 | 
			
		||||
eekboard_server_SOURCES = server-server.c server-context.c server-main.c
 | 
			
		||||
 | 
			
		||||
eekboard_client_CFLAGS = \
 | 
			
		||||
	-I$(top_srcdir) \
 | 
			
		||||
	$(GIO2_CFLAGS)
 | 
			
		||||
@ -96,6 +100,7 @@ eekboard_xml_CFLAGS = \
 | 
			
		||||
	$(LIBXKLAVIER_CFLAGS)
 | 
			
		||||
 | 
			
		||||
eekboard_xml_LDADD = \
 | 
			
		||||
	$(builddir)/libxklutil.la \
 | 
			
		||||
	$(top_builddir)/eek/libeek.la \
 | 
			
		||||
	$(top_builddir)/eek/libeek-xkl.la \
 | 
			
		||||
	$(top_builddir)/eek/libeek-gtk.la \
 | 
			
		||||
@ -103,8 +108,17 @@ eekboard_xml_LDADD = \
 | 
			
		||||
	$(GTK_LIBS) \
 | 
			
		||||
	$(LIBXKLAVIER_LIBS)
 | 
			
		||||
 | 
			
		||||
eekboard_xml_headers = xklutil.h
 | 
			
		||||
eekboard_xml_SOURCES = xklutil.c xml-main.c
 | 
			
		||||
if ENABLE_CLUTTER
 | 
			
		||||
eekboard_xml_CFLAGS += $(CLUTTER_CFLAGS) $(CLUTTER_GTK_CFLAGS)
 | 
			
		||||
eekboard_xml_LDADD += $(CLUTTER_LIBS) $(top_builddir)/eek/libeek-clutter.la $(CLUTTER_GTK_LIBS)
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
eekboard_xml_SOURCES = xml-main.c
 | 
			
		||||
 | 
			
		||||
libxklutil_la_headers = xklutil.h
 | 
			
		||||
libxklutil_la_SOURCES = xklutil.c
 | 
			
		||||
libxklutil_la_CFLAGS = $(LIBXKLAVIER_CFLAGS)
 | 
			
		||||
libxklutil_la_LIBADD = $(LIBXKLAVIER_LIBS)
 | 
			
		||||
 | 
			
		||||
eekboarddir = $(includedir)/eekboard-$(EEK_API_VERSION)/eekboard
 | 
			
		||||
eekboard_HEADERS =				\
 | 
			
		||||
@ -114,7 +128,8 @@ noinst_HEADERS = \
 | 
			
		||||
	$(eekboard_desktop_client_headers) \
 | 
			
		||||
	$(eekboard_client_headers) \
 | 
			
		||||
	$(eekboard_server_headers) \
 | 
			
		||||
	$(eekboard_xml_headers)
 | 
			
		||||
	$(eekboard_xml_headers) \
 | 
			
		||||
	$(libxklutil_la_headers)
 | 
			
		||||
 | 
			
		||||
EXTRA_DIST = $(service_in_files)
 | 
			
		||||
DISTCLEANFILES = $(service_DATA)
 | 
			
		||||
 | 
			
		||||
@ -19,8 +19,15 @@
 | 
			
		||||
#include "config.h"
 | 
			
		||||
#endif  /* HAVE_CONFIG_H */
 | 
			
		||||
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <glib/gi18n.h>
 | 
			
		||||
 | 
			
		||||
#include "eekboard/eekboard.h"
 | 
			
		||||
 | 
			
		||||
static gboolean opt_system = FALSE;
 | 
			
		||||
static gboolean opt_session = FALSE;
 | 
			
		||||
static gchar *opt_address = NULL;
 | 
			
		||||
 | 
			
		||||
static gchar *opt_set_keyboard = NULL;
 | 
			
		||||
static gint opt_set_group = -1;
 | 
			
		||||
static gboolean opt_show_keyboard = FALSE;
 | 
			
		||||
@ -30,20 +37,26 @@ static gint opt_release_key = -1;
 | 
			
		||||
static gboolean opt_listen = FALSE;
 | 
			
		||||
 | 
			
		||||
static const GOptionEntry options[] = {
 | 
			
		||||
    {"system", 'y', 0, G_OPTION_ARG_NONE, &opt_system,
 | 
			
		||||
     N_("Connect to the system bus")},
 | 
			
		||||
    {"session", 'e', 0, G_OPTION_ARG_NONE, &opt_session,
 | 
			
		||||
     N_("Connect to the session bus")},
 | 
			
		||||
    {"address", 'a', 0, G_OPTION_ARG_STRING, &opt_address,
 | 
			
		||||
     N_("Connect to the given D-Bus address")},
 | 
			
		||||
    {"set-keyboard", '\0', 0, G_OPTION_ARG_STRING, &opt_set_keyboard,
 | 
			
		||||
     "Set keyboard keyboard from an XML file"},
 | 
			
		||||
     N_("Upload keyboard description from an XML file")},
 | 
			
		||||
    {"set-group", '\0', 0, G_OPTION_ARG_INT, &opt_set_group,
 | 
			
		||||
     "Set group of the keyboard"},
 | 
			
		||||
     N_("Set group of the keyboard")},
 | 
			
		||||
    {"show-keyboard", '\0', 0, G_OPTION_ARG_NONE, &opt_show_keyboard,
 | 
			
		||||
     "Show keyboard"},
 | 
			
		||||
     N_("Show keyboard")},
 | 
			
		||||
    {"hide-keyboard", '\0', 0, G_OPTION_ARG_NONE, &opt_hide_keyboard,
 | 
			
		||||
     "Hide keyboard"},
 | 
			
		||||
     N_("Hide keyboard")},
 | 
			
		||||
    {"press-key", '\0', 0, G_OPTION_ARG_INT, &opt_press_key,
 | 
			
		||||
     "Press key"},
 | 
			
		||||
     N_("Press key")},
 | 
			
		||||
    {"release-key", '\0', 0, G_OPTION_ARG_INT, &opt_release_key,
 | 
			
		||||
     "Release key"},
 | 
			
		||||
     N_("Release key")},
 | 
			
		||||
    {"listen", '\0', 0, G_OPTION_ARG_NONE, &opt_listen,
 | 
			
		||||
     "Listen events"},
 | 
			
		||||
     N_("Listen events")},
 | 
			
		||||
    {NULL}
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
@ -62,8 +75,9 @@ on_key_released (guint keycode, gpointer user_data)
 | 
			
		||||
int
 | 
			
		||||
main (int argc, char **argv)
 | 
			
		||||
{
 | 
			
		||||
    EekboardServer *server = NULL;
 | 
			
		||||
    EekboardEekboard *eekboard = NULL;
 | 
			
		||||
    EekboardContext *context = NULL;
 | 
			
		||||
    GBusType bus_type;
 | 
			
		||||
    GDBusConnection *connection = NULL;
 | 
			
		||||
    GError *error;
 | 
			
		||||
    GOptionContext *option_context;
 | 
			
		||||
@ -78,37 +92,66 @@ main (int argc, char **argv)
 | 
			
		||||
    g_option_context_parse (option_context, &argc, &argv, NULL);
 | 
			
		||||
    g_option_context_free (option_context);
 | 
			
		||||
 | 
			
		||||
    if (opt_system)
 | 
			
		||||
        bus_type = G_BUS_TYPE_SYSTEM;
 | 
			
		||||
    else if (opt_address)
 | 
			
		||||
        bus_type = G_BUS_TYPE_NONE;
 | 
			
		||||
    else
 | 
			
		||||
        bus_type = G_BUS_TYPE_SESSION;
 | 
			
		||||
 | 
			
		||||
    switch (bus_type) {
 | 
			
		||||
    case G_BUS_TYPE_SYSTEM:
 | 
			
		||||
    case G_BUS_TYPE_SESSION:
 | 
			
		||||
        error = NULL;
 | 
			
		||||
        connection = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &error);
 | 
			
		||||
    if (error) {
 | 
			
		||||
        g_printerr ("%s\n", error->message);
 | 
			
		||||
        if (connection == NULL) {
 | 
			
		||||
            g_printerr ("Can't connect to the bus: %s\n", error->message);
 | 
			
		||||
            exit (1);
 | 
			
		||||
        }
 | 
			
		||||
        break;
 | 
			
		||||
    case G_BUS_TYPE_NONE:
 | 
			
		||||
        error = NULL;
 | 
			
		||||
        connection = g_dbus_connection_new_for_address_sync (opt_address,
 | 
			
		||||
                                                             0,
 | 
			
		||||
                                                             NULL,
 | 
			
		||||
                                                             NULL,
 | 
			
		||||
                                                             &error);
 | 
			
		||||
        if (connection == NULL) {
 | 
			
		||||
            g_printerr ("Can't connect to the bus at %s: %s\n",
 | 
			
		||||
                        opt_address,
 | 
			
		||||
                        error->message);
 | 
			
		||||
            exit (1);
 | 
			
		||||
        }
 | 
			
		||||
        break;
 | 
			
		||||
    default:
 | 
			
		||||
        g_assert_not_reached ();
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    eekboard = eekboard_eekboard_new (connection, NULL);
 | 
			
		||||
    if (eekboard == NULL) {
 | 
			
		||||
        g_printerr ("Can't create eekboard proxy\n");
 | 
			
		||||
        retval = 1;
 | 
			
		||||
        goto out;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    server = eekboard_server_new (connection, NULL);
 | 
			
		||||
    if (!server) {
 | 
			
		||||
        g_printerr ("Can't create server\n");
 | 
			
		||||
        retval = 1;
 | 
			
		||||
        goto out;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    context = eekboard_server_create_context (server,
 | 
			
		||||
    context = eekboard_eekboard_create_context (eekboard,
 | 
			
		||||
                                                "eekboard-client",
 | 
			
		||||
                                                NULL);
 | 
			
		||||
    if (!context) {
 | 
			
		||||
    if (context == NULL) {
 | 
			
		||||
        g_printerr ("Can't create context\n");
 | 
			
		||||
        retval = 1;
 | 
			
		||||
        goto out;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    eekboard_server_push_context (server, context, NULL);
 | 
			
		||||
    eekboard_eekboard_push_context (eekboard, context, NULL);
 | 
			
		||||
 | 
			
		||||
    if (opt_set_keyboard) {
 | 
			
		||||
        GFile *file;
 | 
			
		||||
        GFileInputStream *input;
 | 
			
		||||
        EekLayout *layout;
 | 
			
		||||
        EekKeyboard *keyboard;
 | 
			
		||||
        guint keyboard_id;
 | 
			
		||||
 | 
			
		||||
        file = g_file_new_for_path (opt_set_keyboard);
 | 
			
		||||
 | 
			
		||||
@ -126,8 +169,10 @@ main (int argc, char **argv)
 | 
			
		||||
        keyboard = eek_keyboard_new (layout, 640, 480);
 | 
			
		||||
        g_object_unref (layout);
 | 
			
		||||
 | 
			
		||||
        eekboard_context_set_keyboard (context, keyboard, NULL);
 | 
			
		||||
        keyboard_id = eekboard_context_add_keyboard (context, keyboard, NULL);
 | 
			
		||||
        g_object_unref (keyboard);
 | 
			
		||||
 | 
			
		||||
        eekboard_context_set_keyboard (context, keyboard_id, NULL);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (opt_set_group >= 0) {
 | 
			
		||||
 | 
			
		||||
@ -22,22 +22,47 @@
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <cspi/spi.h>
 | 
			
		||||
#include <gtk/gtk.h>
 | 
			
		||||
#include <glib/gi18n.h>
 | 
			
		||||
#include <gconf/gconf-client.h>
 | 
			
		||||
#include "eekboard/eekboard.h"
 | 
			
		||||
#include "desktop-client.h"
 | 
			
		||||
 | 
			
		||||
static gboolean opt_system = FALSE;
 | 
			
		||||
static gboolean opt_session = FALSE;
 | 
			
		||||
static gchar *opt_address = NULL;
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_CSPI
 | 
			
		||||
gboolean opt_focus = FALSE;
 | 
			
		||||
gboolean opt_keystroke = FALSE;
 | 
			
		||||
static gboolean opt_focus = FALSE;
 | 
			
		||||
static gboolean opt_keystroke = FALSE;
 | 
			
		||||
#endif  /* HAVE_CSPI */
 | 
			
		||||
 | 
			
		||||
static gchar *opt_model = NULL;
 | 
			
		||||
static gchar *opt_layouts = NULL;
 | 
			
		||||
static gchar *opt_options = NULL;
 | 
			
		||||
 | 
			
		||||
static gboolean opt_fullscreen = FALSE;
 | 
			
		||||
 | 
			
		||||
static const GOptionEntry options[] = {
 | 
			
		||||
    {"system", 'y', 0, G_OPTION_ARG_NONE, &opt_system,
 | 
			
		||||
     N_("Connect to the system bus")},
 | 
			
		||||
    {"session", 'e', 0, G_OPTION_ARG_NONE, &opt_session,
 | 
			
		||||
     N_("Connect to the session bus")},
 | 
			
		||||
    {"address", 'a', 0, G_OPTION_ARG_STRING, &opt_address,
 | 
			
		||||
     N_("Connect to the given D-Bus address")},
 | 
			
		||||
#ifdef HAVE_CSPI
 | 
			
		||||
    {"listen-focus", 'f', 0, G_OPTION_ARG_NONE, &opt_focus,
 | 
			
		||||
     "Listen focus change events with AT-SPI"},
 | 
			
		||||
     N_("Listen focus change events with AT-SPI")},
 | 
			
		||||
    {"listen-keystroke", 's', 0, G_OPTION_ARG_NONE, &opt_keystroke,
 | 
			
		||||
     "Listen keystroke events with AT-SPI"},
 | 
			
		||||
     N_("Listen keystroke events with AT-SPI")},
 | 
			
		||||
#endif  /* HAVE_CSPI */
 | 
			
		||||
    {"model", '\0', 0, G_OPTION_ARG_STRING, &opt_model,
 | 
			
		||||
     N_("Specify model")},
 | 
			
		||||
    {"layouts", '\0', 0, G_OPTION_ARG_STRING, &opt_layouts,
 | 
			
		||||
     N_("Specify layouts")},
 | 
			
		||||
    {"options", '\0', 0, G_OPTION_ARG_STRING, &opt_options,
 | 
			
		||||
     N_("Specify options")},
 | 
			
		||||
    {"fullscreen", 'F', 0, G_OPTION_ARG_NONE, &opt_fullscreen,
 | 
			
		||||
     N_("Create window in fullscreen mode")},
 | 
			
		||||
    {NULL}
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
@ -56,11 +81,31 @@ on_notify_keyboard_visible (GObject    *object,
 | 
			
		||||
        g_main_loop_quit (loop);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
on_context_destroyed (EekboardContext *context,
 | 
			
		||||
                      gpointer         user_data)
 | 
			
		||||
{
 | 
			
		||||
    GMainLoop *loop = user_data;
 | 
			
		||||
 | 
			
		||||
    g_main_loop_quit (loop);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
on_destroyed (EekboardEekboard *eekboard,
 | 
			
		||||
              gpointer          user_data)
 | 
			
		||||
{
 | 
			
		||||
    GMainLoop *loop = user_data;
 | 
			
		||||
 | 
			
		||||
    g_main_loop_quit (loop);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
main (int argc, char **argv)
 | 
			
		||||
{
 | 
			
		||||
    EekboardDesktopClient *client;
 | 
			
		||||
    EekboardEekboard *eekboard;
 | 
			
		||||
    EekboardContext *context;
 | 
			
		||||
    GBusType bus_type;
 | 
			
		||||
    GDBusConnection *connection;
 | 
			
		||||
    GError *error;
 | 
			
		||||
    GConfClient *gconfc;
 | 
			
		||||
@ -77,13 +122,47 @@ main (int argc, char **argv)
 | 
			
		||||
    g_option_context_parse (option_context, &argc, &argv, NULL);
 | 
			
		||||
    g_option_context_free (option_context);
 | 
			
		||||
 | 
			
		||||
    if (opt_system)
 | 
			
		||||
        bus_type = G_BUS_TYPE_SYSTEM;
 | 
			
		||||
    else if (opt_address)
 | 
			
		||||
        bus_type = G_BUS_TYPE_NONE;
 | 
			
		||||
    else
 | 
			
		||||
        bus_type = G_BUS_TYPE_SESSION;
 | 
			
		||||
 | 
			
		||||
    switch (bus_type) {
 | 
			
		||||
    case G_BUS_TYPE_SYSTEM:
 | 
			
		||||
    case G_BUS_TYPE_SESSION:
 | 
			
		||||
        error = NULL;
 | 
			
		||||
        connection = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &error);
 | 
			
		||||
    if (error) {
 | 
			
		||||
        g_printerr ("%s\n", error->message);
 | 
			
		||||
        if (connection == NULL) {
 | 
			
		||||
            g_printerr ("Can't connect to the bus: %s\n", error->message);
 | 
			
		||||
            exit (1);
 | 
			
		||||
        }
 | 
			
		||||
        break;
 | 
			
		||||
    case G_BUS_TYPE_NONE:
 | 
			
		||||
        error = NULL;
 | 
			
		||||
        connection = g_dbus_connection_new_for_address_sync (opt_address,
 | 
			
		||||
                                                             0,
 | 
			
		||||
                                                             NULL,
 | 
			
		||||
                                                             NULL,
 | 
			
		||||
                                                             &error);
 | 
			
		||||
        if (connection == NULL) {
 | 
			
		||||
            g_printerr ("Can't connect to the bus at %s: %s\n",
 | 
			
		||||
                        opt_address,
 | 
			
		||||
                        error->message);
 | 
			
		||||
            exit (1);
 | 
			
		||||
        }
 | 
			
		||||
        break;
 | 
			
		||||
    default:
 | 
			
		||||
        g_assert_not_reached ();
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    client = eekboard_desktop_client_new (connection);
 | 
			
		||||
    if (client == NULL) {
 | 
			
		||||
        g_printerr ("Can't create a client\n");
 | 
			
		||||
        exit (1);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    gconfc = gconf_client_get_default ();
 | 
			
		||||
 | 
			
		||||
@ -113,13 +192,21 @@ main (int argc, char **argv)
 | 
			
		||||
                exit (1);
 | 
			
		||||
            }
 | 
			
		||||
        } else {
 | 
			
		||||
            g_printerr ("Desktop accessibility support is disabled");
 | 
			
		||||
            g_printerr ("Desktop accessibility support is disabled\n");
 | 
			
		||||
            exit (1);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
#endif  /* HAVE_CSPI */
 | 
			
		||||
 | 
			
		||||
    if (!eekboard_desktop_client_enable_xkl (client)) {
 | 
			
		||||
    if (opt_model || opt_layouts || opt_options) {
 | 
			
		||||
        if (!eekboard_desktop_client_set_xkl_config (client,
 | 
			
		||||
                                                     opt_model,
 | 
			
		||||
                                                     opt_layouts,
 | 
			
		||||
                                                     opt_options)) {
 | 
			
		||||
            g_printerr ("Can't set xklavier config\n");
 | 
			
		||||
            exit (1);
 | 
			
		||||
        }
 | 
			
		||||
    } else if (!eekboard_desktop_client_enable_xkl (client)) {
 | 
			
		||||
        g_printerr ("Can't register xklavier event listeners\n");
 | 
			
		||||
        exit (1);
 | 
			
		||||
    }
 | 
			
		||||
@ -136,9 +223,21 @@ main (int argc, char **argv)
 | 
			
		||||
        g_object_get (client, "context", &context, NULL);
 | 
			
		||||
        g_signal_connect (context, "notify::keyboard-visible",
 | 
			
		||||
                          G_CALLBACK(on_notify_keyboard_visible), loop);
 | 
			
		||||
        g_signal_connect (context, "destroyed",
 | 
			
		||||
                          G_CALLBACK(on_context_destroyed), loop);
 | 
			
		||||
        g_object_unref (context);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (opt_fullscreen) {
 | 
			
		||||
        g_object_get (client, "context", &context, NULL);
 | 
			
		||||
        eekboard_context_set_fullscreen (context, TRUE, NULL);
 | 
			
		||||
        g_object_unref (context);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    g_object_get (client, "eekboard", &eekboard, NULL);
 | 
			
		||||
    g_signal_connect (eekboard, "destroyed",
 | 
			
		||||
                      G_CALLBACK(on_destroyed), loop);
 | 
			
		||||
 | 
			
		||||
    g_main_loop_run (loop);
 | 
			
		||||
    g_main_loop_unref (loop);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -35,6 +35,7 @@
 | 
			
		||||
#include "eek/eek-xkl.h"
 | 
			
		||||
#include "eekboard/eekboard.h"
 | 
			
		||||
#include "desktop-client.h"
 | 
			
		||||
#include "xklutil.h"
 | 
			
		||||
 | 
			
		||||
#define CSW 640
 | 
			
		||||
#define CSH 480
 | 
			
		||||
@ -42,6 +43,7 @@
 | 
			
		||||
enum {
 | 
			
		||||
    PROP_0,
 | 
			
		||||
    PROP_CONNECTION,
 | 
			
		||||
    PROP_EEKBOARD,
 | 
			
		||||
    PROP_CONTEXT,
 | 
			
		||||
    PROP_LAST
 | 
			
		||||
};
 | 
			
		||||
@ -51,7 +53,7 @@ typedef struct _EekboardDesktopClientClass EekboardDesktopClientClass;
 | 
			
		||||
struct _EekboardDesktopClient {
 | 
			
		||||
    GObject parent;
 | 
			
		||||
 | 
			
		||||
    EekboardServer *server;
 | 
			
		||||
    EekboardEekboard *eekboard;
 | 
			
		||||
    EekboardContext *context;
 | 
			
		||||
 | 
			
		||||
    EekKeyboard *keyboard;
 | 
			
		||||
@ -66,6 +68,7 @@ struct _EekboardDesktopClient {
 | 
			
		||||
    gulong key_released_handler;
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_CSPI
 | 
			
		||||
    Accessible *acc;
 | 
			
		||||
    AccessibleEventListener *focus_listener;
 | 
			
		||||
    AccessibleEventListener *keystroke_listener;
 | 
			
		||||
#endif  /* HAVE_CSPI */
 | 
			
		||||
@ -103,8 +106,11 @@ static SPIBoolean      keystroke_listener_cb
 | 
			
		||||
                                         (const AccessibleKeystroke *stroke,
 | 
			
		||||
                                          void                      *user_data);
 | 
			
		||||
#endif  /* HAVE_CSPI */
 | 
			
		||||
static void            set_keyboard      (EekboardDesktopClient      *client,
 | 
			
		||||
                                          gboolean                   show);
 | 
			
		||||
static gboolean        set_keyboard      (EekboardDesktopClient     *client,
 | 
			
		||||
                                          gboolean                   show,
 | 
			
		||||
                                          const gchar               *model,
 | 
			
		||||
                                          const gchar               *layouts,
 | 
			
		||||
                                          const gchar               *options);
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
eekboard_desktop_client_set_property (GObject      *object,
 | 
			
		||||
@ -119,16 +125,20 @@ eekboard_desktop_client_set_property (GObject      *object,
 | 
			
		||||
    case PROP_CONNECTION:
 | 
			
		||||
        connection = g_value_get_object (value);
 | 
			
		||||
 | 
			
		||||
        client->server = eekboard_server_new (connection, NULL);
 | 
			
		||||
        g_assert (client->server);
 | 
			
		||||
 | 
			
		||||
        client->eekboard = eekboard_eekboard_new (connection, NULL);
 | 
			
		||||
        if (client->eekboard != NULL) {
 | 
			
		||||
            client->context =
 | 
			
		||||
            eekboard_server_create_context (client->server,
 | 
			
		||||
                eekboard_eekboard_create_context (client->eekboard,
 | 
			
		||||
                                                  "eekboard-desktop-client",
 | 
			
		||||
                                                  NULL);
 | 
			
		||||
        g_assert (client->context);
 | 
			
		||||
 | 
			
		||||
        eekboard_server_push_context (client->server, client->context, NULL);
 | 
			
		||||
            if (client->context == NULL) {
 | 
			
		||||
                g_object_unref (client->eekboard);
 | 
			
		||||
                client->eekboard = NULL;
 | 
			
		||||
            } else
 | 
			
		||||
                eekboard_eekboard_push_context (client->eekboard,
 | 
			
		||||
                                                client->context,
 | 
			
		||||
                                                NULL);
 | 
			
		||||
        }
 | 
			
		||||
        break;
 | 
			
		||||
    default:
 | 
			
		||||
        g_object_set_property (object,
 | 
			
		||||
@ -147,6 +157,9 @@ eekboard_desktop_client_get_property (GObject    *object,
 | 
			
		||||
    EekboardDesktopClient *client = EEKBOARD_DESKTOP_CLIENT(object);
 | 
			
		||||
 | 
			
		||||
    switch (prop_id) {
 | 
			
		||||
    case PROP_EEKBOARD:
 | 
			
		||||
        g_value_set_object (value, client->eekboard);
 | 
			
		||||
        break;
 | 
			
		||||
    case PROP_CONTEXT:
 | 
			
		||||
        g_value_set_object (value, client->context);
 | 
			
		||||
        break;
 | 
			
		||||
@ -175,17 +188,17 @@ eekboard_desktop_client_dispose (GObject *object)
 | 
			
		||||
#endif  /* HAVE_FAKEKEY */
 | 
			
		||||
 | 
			
		||||
    if (client->context) {
 | 
			
		||||
        if (client->server) {
 | 
			
		||||
            eekboard_server_pop_context (client->server, NULL);
 | 
			
		||||
        if (client->eekboard) {
 | 
			
		||||
            eekboard_eekboard_pop_context (client->eekboard, NULL);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        g_object_unref (client->context);
 | 
			
		||||
        client->context = NULL;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (client->server) {
 | 
			
		||||
        g_object_unref (client->server);
 | 
			
		||||
        client->server = NULL;
 | 
			
		||||
    if (client->eekboard) {
 | 
			
		||||
        g_object_unref (client->eekboard);
 | 
			
		||||
        client->eekboard = NULL;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (client->keyboard) {
 | 
			
		||||
@ -226,6 +239,15 @@ eekboard_desktop_client_class_init (EekboardDesktopClientClass *klass)
 | 
			
		||||
                                     PROP_CONNECTION,
 | 
			
		||||
                                     pspec);
 | 
			
		||||
 | 
			
		||||
    pspec = g_param_spec_object ("eekboard",
 | 
			
		||||
                                 "Eekboard",
 | 
			
		||||
                                 "Eekboard",
 | 
			
		||||
                                 EEKBOARD_TYPE_EEKBOARD,
 | 
			
		||||
                                 G_PARAM_READABLE);
 | 
			
		||||
    g_object_class_install_property (gobject_class,
 | 
			
		||||
                                     PROP_EEKBOARD,
 | 
			
		||||
                                     pspec);
 | 
			
		||||
 | 
			
		||||
    pspec = g_param_spec_object ("context",
 | 
			
		||||
                                 "Context",
 | 
			
		||||
                                 "Context",
 | 
			
		||||
@ -239,7 +261,7 @@ eekboard_desktop_client_class_init (EekboardDesktopClientClass *klass)
 | 
			
		||||
static void
 | 
			
		||||
eekboard_desktop_client_init (EekboardDesktopClient *client)
 | 
			
		||||
{
 | 
			
		||||
    client->server = NULL;
 | 
			
		||||
    client->eekboard = NULL;
 | 
			
		||||
    client->context = NULL;
 | 
			
		||||
    client->display = NULL;
 | 
			
		||||
    client->xkl_engine = NULL;
 | 
			
		||||
@ -258,6 +280,27 @@ eekboard_desktop_client_init (EekboardDesktopClient *client)
 | 
			
		||||
#endif  /* HAVE_FAKEKEY */
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
gboolean
 | 
			
		||||
eekboard_desktop_client_set_xkl_config (EekboardDesktopClient *client,
 | 
			
		||||
                                        const gchar *model,
 | 
			
		||||
                                        const gchar *layouts,
 | 
			
		||||
                                        const gchar *options)
 | 
			
		||||
{
 | 
			
		||||
#ifdef HAVE_CSPI
 | 
			
		||||
    return set_keyboard (client,
 | 
			
		||||
                         client->focus_listener ? FALSE : TRUE,
 | 
			
		||||
                         model,
 | 
			
		||||
                         layouts,
 | 
			
		||||
                         options);
 | 
			
		||||
#else
 | 
			
		||||
    return set_keyboard (client,
 | 
			
		||||
                         TRUE,
 | 
			
		||||
                         model,
 | 
			
		||||
                         layouts,
 | 
			
		||||
                         options);
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
gboolean
 | 
			
		||||
eekboard_desktop_client_enable_xkl (EekboardDesktopClient *client)
 | 
			
		||||
{
 | 
			
		||||
@ -295,12 +338,11 @@ eekboard_desktop_client_enable_xkl (EekboardDesktopClient *client)
 | 
			
		||||
    xkl_engine_start_listen (client->xkl_engine, XKLL_TRACK_KEYBOARD_STATE);
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_CSPI
 | 
			
		||||
    set_keyboard (client, client->focus_listener ? FALSE : TRUE);
 | 
			
		||||
    return set_keyboard (client, client->focus_listener ? FALSE : TRUE,
 | 
			
		||||
                         NULL, NULL, NULL);
 | 
			
		||||
#else
 | 
			
		||||
    set_keyboard (client, TRUE);
 | 
			
		||||
    return set_keyboard (client, TRUE, NULL, NULL, NULL);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    return TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
@ -392,10 +434,24 @@ focus_listener_cb (const AccessibleEvent *event,
 | 
			
		||||
        case SPI_ROLE_PARAGRAPH:
 | 
			
		||||
        case SPI_ROLE_PASSWORD_TEXT:
 | 
			
		||||
        case SPI_ROLE_TERMINAL:
 | 
			
		||||
        case SPI_ROLE_ENTRY:
 | 
			
		||||
            if (g_strcmp0 (event->type, "focus") == 0 || event->detail1 == 1) {
 | 
			
		||||
            if (strncmp (event->type, "focus", 5) == 0 || event->detail1 == 1) {
 | 
			
		||||
                client->acc = accessible;
 | 
			
		||||
                eekboard_context_show_keyboard (client->context, NULL);
 | 
			
		||||
            } else if (event->detail1 == 0 && accessible == client->acc) {
 | 
			
		||||
                client->acc = NULL;
 | 
			
		||||
                eekboard_context_hide_keyboard (client->context, NULL);
 | 
			
		||||
            }
 | 
			
		||||
            break;
 | 
			
		||||
        case SPI_ROLE_ENTRY:
 | 
			
		||||
            if (strncmp (event->type, "focus", 5) == 0 || event->detail1 == 1) {
 | 
			
		||||
                client->acc = accessible;
 | 
			
		||||
                eekboard_context_show_keyboard (client->context, NULL);
 | 
			
		||||
            } else if (event->detail1 == 0) {
 | 
			
		||||
                client->acc = NULL;
 | 
			
		||||
                eekboard_context_hide_keyboard (client->context, NULL);
 | 
			
		||||
            }
 | 
			
		||||
            break;
 | 
			
		||||
            
 | 
			
		||||
        default:
 | 
			
		||||
            ;
 | 
			
		||||
        }
 | 
			
		||||
@ -436,9 +492,12 @@ keystroke_listener_cb (const AccessibleKeystroke *stroke,
 | 
			
		||||
EekboardDesktopClient *
 | 
			
		||||
eekboard_desktop_client_new (GDBusConnection *connection)
 | 
			
		||||
{
 | 
			
		||||
    return g_object_new (EEKBOARD_TYPE_DESKTOP_CLIENT,
 | 
			
		||||
    EekboardDesktopClient *client = g_object_new (EEKBOARD_TYPE_DESKTOP_CLIENT,
 | 
			
		||||
                                                  "connection", connection,
 | 
			
		||||
                                                  NULL);
 | 
			
		||||
    if (client->context)
 | 
			
		||||
        return client;
 | 
			
		||||
    return NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static GdkFilterReturn
 | 
			
		||||
@ -458,8 +517,10 @@ on_xkl_config_changed (XklEngine *xklengine,
 | 
			
		||||
                       gpointer   user_data)
 | 
			
		||||
{
 | 
			
		||||
    EekboardDesktopClient *client = user_data;
 | 
			
		||||
    gboolean retval;
 | 
			
		||||
 | 
			
		||||
    set_keyboard (client, FALSE);
 | 
			
		||||
    retval = set_keyboard (client, FALSE, NULL, NULL, NULL);
 | 
			
		||||
    g_return_if_fail (retval);
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_FAKEKEY
 | 
			
		||||
    if (client->fakekey)
 | 
			
		||||
@ -467,27 +528,77 @@ on_xkl_config_changed (XklEngine *xklengine,
 | 
			
		||||
#endif  /* HAVE_FAKEKEY */
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
static gboolean
 | 
			
		||||
set_keyboard (EekboardDesktopClient *client,
 | 
			
		||||
              gboolean              show)
 | 
			
		||||
              gboolean               show,
 | 
			
		||||
              const gchar           *model,
 | 
			
		||||
              const gchar           *layouts,
 | 
			
		||||
              const gchar           *options)
 | 
			
		||||
{
 | 
			
		||||
    EekLayout *layout;
 | 
			
		||||
    gchar *keyboard_name;
 | 
			
		||||
    static gint keyboard_serial = 0;
 | 
			
		||||
    guint keyboard_id;
 | 
			
		||||
 | 
			
		||||
    if (client->keyboard)
 | 
			
		||||
        g_object_unref (client->keyboard);
 | 
			
		||||
    layout = eek_xkl_layout_new ();
 | 
			
		||||
 | 
			
		||||
    if (model) {
 | 
			
		||||
        if (!eek_xkl_layout_set_model (EEK_XKL_LAYOUT(layout), model)) {
 | 
			
		||||
            g_object_unref (layout);
 | 
			
		||||
            return FALSE;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (layouts) {
 | 
			
		||||
        XklConfigRec *rec;
 | 
			
		||||
 | 
			
		||||
        rec = eekboard_xkl_config_rec_new_from_string (layouts);
 | 
			
		||||
        if (!eek_xkl_layout_set_layouts (EEK_XKL_LAYOUT(layout),
 | 
			
		||||
                                         rec->layouts)) {
 | 
			
		||||
            g_object_unref (rec);
 | 
			
		||||
            g_object_unref (layout);
 | 
			
		||||
            return FALSE;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (!eek_xkl_layout_set_variants (EEK_XKL_LAYOUT(layout),
 | 
			
		||||
                                          rec->variants)) {
 | 
			
		||||
            g_object_unref (rec);
 | 
			
		||||
            g_object_unref (layout);
 | 
			
		||||
            return FALSE;
 | 
			
		||||
        }            
 | 
			
		||||
 | 
			
		||||
        g_object_unref (rec);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (options) {
 | 
			
		||||
        gchar **_options;
 | 
			
		||||
 | 
			
		||||
        _options = g_strsplit (options, ",", -1);
 | 
			
		||||
        if (!eek_xkl_layout_set_options (EEK_XKL_LAYOUT(layout), _options)) {
 | 
			
		||||
            g_strfreev (_options);
 | 
			
		||||
            g_object_unref (layout);
 | 
			
		||||
            return FALSE;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    client->keyboard = eek_keyboard_new (layout, CSW, CSH);
 | 
			
		||||
    eek_keyboard_set_modifier_behavior (client->keyboard,
 | 
			
		||||
                                        EEK_MODIFIER_BEHAVIOR_LATCH);
 | 
			
		||||
 | 
			
		||||
    keyboard_name = g_strdup_printf ("keyboard%d", keyboard_serial++);
 | 
			
		||||
    eek_element_set_name (EEK_ELEMENT(client->keyboard), keyboard_name);
 | 
			
		||||
    g_free (keyboard_name);
 | 
			
		||||
 | 
			
		||||
    eekboard_context_set_keyboard (client->context, client->keyboard, NULL);
 | 
			
		||||
    keyboard_id = eekboard_context_add_keyboard (client->context,
 | 
			
		||||
                                                 client->keyboard,
 | 
			
		||||
                                                 NULL);
 | 
			
		||||
    eekboard_context_set_keyboard (client->context, keyboard_id, NULL);
 | 
			
		||||
    if (show)
 | 
			
		||||
        eekboard_context_show_keyboard (client->context, NULL);
 | 
			
		||||
 | 
			
		||||
    return TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
@ -500,7 +611,7 @@ on_xkl_state_changed (XklEngine           *xklengine,
 | 
			
		||||
    EekboardDesktopClient *client = user_data;
 | 
			
		||||
 | 
			
		||||
    if (type == GROUP_CHANGED && client->keyboard) {
 | 
			
		||||
        gint group = eek_keyboard_get_group (client->keyboard);
 | 
			
		||||
        gint group = eek_element_get_group (EEK_ELEMENT(client->keyboard));
 | 
			
		||||
        if (group != value) {
 | 
			
		||||
            eekboard_context_set_group (client->context, value, NULL);
 | 
			
		||||
        }
 | 
			
		||||
@ -532,19 +643,26 @@ on_key_pressed (EekKeyboard *keyboard,
 | 
			
		||||
{
 | 
			
		||||
    EekboardDesktopClient *client = user_data;
 | 
			
		||||
    EekSymbol *symbol;
 | 
			
		||||
    EekModifierType modifiers;
 | 
			
		||||
    FakeKeyModifier fakekey_modifiers;
 | 
			
		||||
    guint keycode;
 | 
			
		||||
 | 
			
		||||
    g_assert (client->fakekey);
 | 
			
		||||
 | 
			
		||||
    modifiers = eek_keyboard_get_modifiers (client->keyboard);
 | 
			
		||||
    fakekey_modifiers = get_fakekey_modifiers (modifiers);
 | 
			
		||||
    symbol = eek_key_get_symbol_with_fallback (key, 0, 0);
 | 
			
		||||
    keycode = eek_key_get_keycode (key);
 | 
			
		||||
    if (EEK_IS_KEYSYM(symbol) && !eek_symbol_is_modifier (symbol)) {
 | 
			
		||||
        fakekey_send_keyevent (client->fakekey, keycode, True, fakekey_modifiers);
 | 
			
		||||
        fakekey_send_keyevent (client->fakekey, keycode, False, fakekey_modifiers);
 | 
			
		||||
        guint xkeysym = eek_keysym_get_xkeysym (EEK_KEYSYM(symbol));
 | 
			
		||||
        guint keycode =
 | 
			
		||||
            XKeysymToKeycode (GDK_DISPLAY_XDISPLAY (client->display), xkeysym);
 | 
			
		||||
        EekModifierType modifiers =
 | 
			
		||||
            eek_keyboard_get_modifiers (client->keyboard);
 | 
			
		||||
        FakeKeyModifier fakekey_modifiers = get_fakekey_modifiers (modifiers);
 | 
			
		||||
 | 
			
		||||
        fakekey_send_keyevent (client->fakekey,
 | 
			
		||||
                               keycode,
 | 
			
		||||
                               TRUE,
 | 
			
		||||
                               fakekey_modifiers);
 | 
			
		||||
        fakekey_send_keyevent (client->fakekey,
 | 
			
		||||
                               keycode,
 | 
			
		||||
                               FALSE,
 | 
			
		||||
                               fakekey_modifiers);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -34,6 +34,12 @@ typedef struct _EekboardDesktopClient EekboardDesktopClient;
 | 
			
		||||
EekboardDesktopClient * eekboard_desktop_client_new
 | 
			
		||||
                        (GDBusConnection       *connection);
 | 
			
		||||
 | 
			
		||||
gboolean                eekboard_desktop_client_set_xkl_config
 | 
			
		||||
                        (EekboardDesktopClient *client,
 | 
			
		||||
                         const gchar           *model,
 | 
			
		||||
                         const gchar           *layouts,
 | 
			
		||||
                         const gchar           *options);
 | 
			
		||||
 | 
			
		||||
gboolean                eekboard_desktop_client_enable_xkl
 | 
			
		||||
                        (EekboardDesktopClient *client);
 | 
			
		||||
void                    eekboard_desktop_client_disable_xkl
 | 
			
		||||
 | 
			
		||||
@ -15,12 +15,13 @@
 | 
			
		||||
 * You should have received a copy of the GNU General Public License
 | 
			
		||||
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
#include <gtk/gtk.h>
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_CONFIG_H
 | 
			
		||||
#include "config.h"
 | 
			
		||||
#endif  /* HAVE_CONFIG_H */
 | 
			
		||||
 | 
			
		||||
#include <gtk/gtk.h>
 | 
			
		||||
#include <glib/gi18n.h>
 | 
			
		||||
 | 
			
		||||
#include "eek/eek.h"
 | 
			
		||||
 | 
			
		||||
#if HAVE_CLUTTER_GTK
 | 
			
		||||
@ -45,8 +46,18 @@ enum {
 | 
			
		||||
static const gchar introspection_xml[] =
 | 
			
		||||
    "<node>"
 | 
			
		||||
    "  <interface name='com.redhat.Eekboard.Context'>"
 | 
			
		||||
    "    <method name='AddKeyboard'>"
 | 
			
		||||
    "      <arg direction='in' type='v' name='keyboard'/>"
 | 
			
		||||
    "      <arg direction='out' type='u' name='keyboard_id'/>"
 | 
			
		||||
    "    </method>"
 | 
			
		||||
    "    <method name='RemoveKeyboard'>"
 | 
			
		||||
    "      <arg direction='in' type='u' name='keyboard_id'/>"
 | 
			
		||||
    "    </method>"
 | 
			
		||||
    "    <method name='SetKeyboard'>"
 | 
			
		||||
    "      <arg type='v' name='keyboard'/>"
 | 
			
		||||
    "      <arg type='u' name='keyboard_id'/>"
 | 
			
		||||
    "    </method>"
 | 
			
		||||
    "    <method name='SetFullscreen'>"
 | 
			
		||||
    "      <arg type='b' name='fullscreen'/>"
 | 
			
		||||
    "    </method>"
 | 
			
		||||
    "    <method name='ShowKeyboard'/>"
 | 
			
		||||
    "    <method name='HideKeyboard'/>"
 | 
			
		||||
@ -86,10 +97,13 @@ struct _ServerContext {
 | 
			
		||||
 | 
			
		||||
    gboolean enabled;
 | 
			
		||||
    gboolean last_keyboard_visible;
 | 
			
		||||
    gboolean fullscreen;
 | 
			
		||||
 | 
			
		||||
    GtkWidget *window;
 | 
			
		||||
    GtkWidget *widget;
 | 
			
		||||
    guint keyboard_id;
 | 
			
		||||
    EekKeyboard *keyboard;
 | 
			
		||||
    GHashTable *keyboard_hash;
 | 
			
		||||
 | 
			
		||||
    gulong key_pressed_handler;
 | 
			
		||||
    gulong key_released_handler;
 | 
			
		||||
@ -166,32 +180,52 @@ on_notify_visible (GObject *object, GParamSpec *spec, gpointer user_data)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
update_widget (ServerContext *context)
 | 
			
		||||
on_realize (GtkWidget *widget,
 | 
			
		||||
            gpointer   user_data)
 | 
			
		||||
{
 | 
			
		||||
    ServerContext *context = user_data;
 | 
			
		||||
 | 
			
		||||
    g_assert (context && context->window == widget);
 | 
			
		||||
 | 
			
		||||
    /* make the window not maximizable */
 | 
			
		||||
    gdk_window_set_functions (gtk_widget_get_window (widget),
 | 
			
		||||
                              GDK_FUNC_RESIZE |
 | 
			
		||||
                              GDK_FUNC_MOVE |
 | 
			
		||||
                              GDK_FUNC_MINIMIZE |
 | 
			
		||||
                              GDK_FUNC_CLOSE);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#define DEFAULT_THEME (THEMEDIR "/default.css")
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
set_geometry (ServerContext *context)
 | 
			
		||||
{
 | 
			
		||||
    GdkScreen *screen;
 | 
			
		||||
    GdkWindow *root;
 | 
			
		||||
    gint monitor;
 | 
			
		||||
    GdkRectangle rect;
 | 
			
		||||
    EekBounds bounds;
 | 
			
		||||
#if HAVE_CLUTTER_GTK
 | 
			
		||||
    ClutterActor *stage, *actor;
 | 
			
		||||
    ClutterColor stage_color = { 0xff, 0xff, 0xff, 0xff };
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    if (context->widget)
 | 
			
		||||
        gtk_widget_destroy (context->widget);
 | 
			
		||||
 | 
			
		||||
    if (context->window)
 | 
			
		||||
        gtk_widget_destroy (context->window);
 | 
			
		||||
 | 
			
		||||
    screen = gdk_screen_get_default ();
 | 
			
		||||
    root = gtk_widget_get_root_window (context->window);
 | 
			
		||||
    monitor = gdk_screen_get_monitor_at_window (screen, root);
 | 
			
		||||
    gdk_screen_get_monitor_geometry (screen, monitor, &rect);
 | 
			
		||||
    eek_element_get_bounds (EEK_ELEMENT(context->keyboard), &bounds);
 | 
			
		||||
#if HAVE_CLUTTER_GTK
 | 
			
		||||
    context->widget = gtk_clutter_embed_new ();
 | 
			
		||||
    stage = gtk_clutter_embed_get_stage (GTK_CLUTTER_EMBED(context->widget));
 | 
			
		||||
    actor = eek_clutter_context_new (context->keyboard);
 | 
			
		||||
    clutter_container_add_actor (CLUTTER_CONTAINER(stage), actor);
 | 
			
		||||
 | 
			
		||||
    clutter_stage_set_color (CLUTTER_STAGE(stage), &stage_color);
 | 
			
		||||
    if (context->fullscreen) {
 | 
			
		||||
        gtk_window_set_decorated (GTK_WINDOW(context->window), FALSE);
 | 
			
		||||
        gtk_window_set_resizable (GTK_WINDOW(context->window), FALSE);
 | 
			
		||||
        gtk_widget_set_size_request (context->widget,
 | 
			
		||||
                                     rect.width,
 | 
			
		||||
                                     rect.height / 2);
 | 
			
		||||
        gtk_window_move (GTK_WINDOW(context->window),
 | 
			
		||||
                         0,
 | 
			
		||||
                         rect.height / 2);
 | 
			
		||||
        gtk_window_set_opacity (GTK_WINDOW(context->window), 0.8);
 | 
			
		||||
    } else {
 | 
			
		||||
#if HAVE_CLUTTER_GTK
 | 
			
		||||
        ClutterActor *stage =
 | 
			
		||||
            gtk_clutter_embed_get_stage (GTK_CLUTTER_EMBED(context->widget));
 | 
			
		||||
        clutter_stage_set_user_resizable (CLUTTER_STAGE(stage), TRUE);
 | 
			
		||||
        clutter_stage_set_minimum_size (CLUTTER_STAGE(stage),
 | 
			
		||||
                                        bounds.width / 3,
 | 
			
		||||
@ -201,31 +235,66 @@ update_widget (ServerContext *context)
 | 
			
		||||
                          G_CALLBACK(on_allocation_changed),
 | 
			
		||||
                          actor);
 | 
			
		||||
#else
 | 
			
		||||
    context->widget = eek_gtk_keyboard_new (context->keyboard);
 | 
			
		||||
        gtk_widget_set_size_request (context->widget,
 | 
			
		||||
                                     bounds.width,
 | 
			
		||||
                                     bounds.height);
 | 
			
		||||
#endif
 | 
			
		||||
    gtk_widget_set_size_request (context->widget, bounds.width, bounds.height);
 | 
			
		||||
        gtk_window_move (GTK_WINDOW(context->window),
 | 
			
		||||
                         MAX(rect.width - 20 - bounds.width, 0),
 | 
			
		||||
                         MAX(rect.height - 40 - bounds.height, 0));
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
update_widget (ServerContext *context)
 | 
			
		||||
{
 | 
			
		||||
    EekBounds bounds;
 | 
			
		||||
    EekTheme *theme;
 | 
			
		||||
#if HAVE_CLUTTER_GTK
 | 
			
		||||
    ClutterActor *stage, *actor;
 | 
			
		||||
    ClutterColor stage_color = { 0xff, 0xff, 0xff, 0xff };
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    if (context->widget)
 | 
			
		||||
        gtk_widget_destroy (context->widget);
 | 
			
		||||
 | 
			
		||||
    theme = eek_theme_new (DEFAULT_THEME, NULL, NULL);
 | 
			
		||||
    eek_element_get_bounds (EEK_ELEMENT(context->keyboard), &bounds);
 | 
			
		||||
#if HAVE_CLUTTER_GTK
 | 
			
		||||
    context->widget = gtk_clutter_embed_new ();
 | 
			
		||||
    stage = gtk_clutter_embed_get_stage (GTK_CLUTTER_EMBED(context->widget));
 | 
			
		||||
    actor = eek_clutter_keyboard_new (context->keyboard);
 | 
			
		||||
    if (theme)
 | 
			
		||||
        eek_clutter_keyboard_set_theme (EEK_CLUTTER_KEYBOARD(actor), theme);
 | 
			
		||||
    clutter_container_add_actor (CLUTTER_CONTAINER(stage), actor);
 | 
			
		||||
 | 
			
		||||
    clutter_stage_set_color (CLUTTER_STAGE(stage), &stage_color);
 | 
			
		||||
#else
 | 
			
		||||
    context->widget = eek_gtk_keyboard_new (context->keyboard);
 | 
			
		||||
    if (theme)
 | 
			
		||||
        eek_gtk_keyboard_set_theme (EEK_GTK_KEYBOARD(context->widget), theme);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    if (!context->window) {
 | 
			
		||||
        context->window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
 | 
			
		||||
        g_signal_connect (context->window, "destroy",
 | 
			
		||||
                          G_CALLBACK(on_destroy), context);
 | 
			
		||||
        context->notify_visible_handler =
 | 
			
		||||
            g_signal_connect (context->window, "notify::visible",
 | 
			
		||||
                              G_CALLBACK(on_notify_visible), context);
 | 
			
		||||
    gtk_container_add (GTK_CONTAINER(context->window), context->widget);
 | 
			
		||||
 | 
			
		||||
        gtk_widget_set_can_focus (context->window, FALSE);
 | 
			
		||||
        g_object_set (G_OBJECT(context->window), "accept_focus", FALSE, NULL);
 | 
			
		||||
    gtk_window_set_title (GTK_WINDOW(context->window), "Keyboard");
 | 
			
		||||
        gtk_window_set_title (GTK_WINDOW(context->window), _("Keyboard"));
 | 
			
		||||
        gtk_window_set_icon_name (GTK_WINDOW(context->window), "eekboard");
 | 
			
		||||
        gtk_window_set_keep_above (GTK_WINDOW(context->window), TRUE);
 | 
			
		||||
 | 
			
		||||
    screen = gdk_screen_get_default ();
 | 
			
		||||
    root = gtk_widget_get_root_window (context->window);
 | 
			
		||||
    monitor = gdk_screen_get_monitor_at_window (screen, root);
 | 
			
		||||
    gdk_screen_get_monitor_geometry (screen, monitor, &rect);
 | 
			
		||||
    gtk_window_move (GTK_WINDOW(context->window),
 | 
			
		||||
                     MAX(rect.width - 20 - bounds.width, 0),
 | 
			
		||||
                     MAX(rect.height - 40 - bounds.height, 0));
 | 
			
		||||
        g_signal_connect (context->window, "realize",
 | 
			
		||||
                          G_CALLBACK(on_realize), context);
 | 
			
		||||
 | 
			
		||||
        set_geometry (context);
 | 
			
		||||
    }
 | 
			
		||||
    gtk_container_add (GTK_CONTAINER(context->window), context->widget);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
@ -264,10 +333,14 @@ server_context_dispose (GObject *object)
 | 
			
		||||
 | 
			
		||||
    if (context->keyboard) {
 | 
			
		||||
        disconnect_keyboard_signals (context);
 | 
			
		||||
        g_object_unref (context->keyboard);
 | 
			
		||||
        context->keyboard = NULL;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (context->keyboard_hash) {
 | 
			
		||||
        g_hash_table_destroy (context->keyboard_hash);
 | 
			
		||||
        context->keyboard_hash = NULL;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (context->window) {
 | 
			
		||||
        gtk_widget_destroy (context->window);
 | 
			
		||||
        context->window = NULL;
 | 
			
		||||
@ -297,6 +370,7 @@ server_context_finalize (GObject *object)
 | 
			
		||||
{
 | 
			
		||||
    ServerContext *context = SERVER_CONTEXT(object);
 | 
			
		||||
 | 
			
		||||
    g_free (context->object_path);
 | 
			
		||||
    g_free (context->client_connection);
 | 
			
		||||
 | 
			
		||||
    G_OBJECT_CLASS (server_context_parent_class)->finalize (object);
 | 
			
		||||
@ -367,6 +441,12 @@ server_context_init (ServerContext *context)
 | 
			
		||||
    context->last_keyboard_visible = FALSE;
 | 
			
		||||
 | 
			
		||||
    context->keyboard = NULL;
 | 
			
		||||
    context->keyboard_hash =
 | 
			
		||||
        g_hash_table_new_full (g_direct_hash,
 | 
			
		||||
                               g_direct_equal,
 | 
			
		||||
                               NULL,
 | 
			
		||||
                               (GDestroyNotify)g_object_unref);
 | 
			
		||||
 | 
			
		||||
    context->widget = NULL;
 | 
			
		||||
    context->window = NULL;
 | 
			
		||||
    context->key_pressed_handler = 0;
 | 
			
		||||
@ -444,11 +524,13 @@ handle_method_call (GDBusConnection       *connection,
 | 
			
		||||
{
 | 
			
		||||
    ServerContext *context = user_data;
 | 
			
		||||
 | 
			
		||||
    if (g_strcmp0 (method_name, "SetKeyboard") == 0) {
 | 
			
		||||
        EekSerializable *serializable;
 | 
			
		||||
    if (g_strcmp0 (method_name, "AddKeyboard") == 0) {
 | 
			
		||||
        GVariant *variant;
 | 
			
		||||
        EekSerializable *serializable;
 | 
			
		||||
        static guint keyboard_id = 0;
 | 
			
		||||
 | 
			
		||||
        g_variant_get (parameters, "(v)", &variant);
 | 
			
		||||
 | 
			
		||||
        serializable = eek_serializable_deserialize (variant);
 | 
			
		||||
        if (!EEK_IS_KEYBOARD(serializable)) {
 | 
			
		||||
            g_dbus_method_invocation_return_error (invocation,
 | 
			
		||||
@ -457,9 +539,65 @@ handle_method_call (GDBusConnection       *connection,
 | 
			
		||||
                                                   "not a keyboard");
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
        eek_keyboard_set_modifier_behavior (EEK_KEYBOARD(serializable),
 | 
			
		||||
                                            EEK_MODIFIER_BEHAVIOR_LATCH);
 | 
			
		||||
 | 
			
		||||
        context->keyboard = EEK_KEYBOARD(serializable);
 | 
			
		||||
        g_hash_table_insert (context->keyboard_hash,
 | 
			
		||||
                             GUINT_TO_POINTER(++keyboard_id),
 | 
			
		||||
                             serializable);
 | 
			
		||||
        g_dbus_method_invocation_return_value (invocation,
 | 
			
		||||
                                               g_variant_new ("(u)",
 | 
			
		||||
                                                              keyboard_id));
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (g_strcmp0 (method_name, "RemoveKeyboard") == 0) {
 | 
			
		||||
        guint keyboard_id;
 | 
			
		||||
 | 
			
		||||
        g_variant_get (parameters, "(u)", &keyboard_id);
 | 
			
		||||
 | 
			
		||||
        if (keyboard_id == context->keyboard_id) {
 | 
			
		||||
            disconnect_keyboard_signals (context);
 | 
			
		||||
            if (context->window) {
 | 
			
		||||
                gtk_widget_hide (context->window);
 | 
			
		||||
                gtk_widget_destroy (context->widget);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            context->keyboard = NULL;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        g_hash_table_remove (context->keyboard_hash,
 | 
			
		||||
                             GUINT_TO_POINTER(keyboard_id));
 | 
			
		||||
        g_dbus_method_invocation_return_value (invocation, NULL);
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (g_strcmp0 (method_name, "SetKeyboard") == 0) {
 | 
			
		||||
        EekKeyboard *keyboard;
 | 
			
		||||
        guint keyboard_id;
 | 
			
		||||
 | 
			
		||||
        g_variant_get (parameters, "(u)", &keyboard_id);
 | 
			
		||||
 | 
			
		||||
        keyboard = g_hash_table_lookup (context->keyboard_hash,
 | 
			
		||||
                                        GUINT_TO_POINTER(keyboard_id));
 | 
			
		||||
        if (!keyboard) {
 | 
			
		||||
            g_dbus_method_invocation_return_error (invocation,
 | 
			
		||||
                                                   G_IO_ERROR,
 | 
			
		||||
                                                   G_IO_ERROR_FAILED_HANDLED,
 | 
			
		||||
                                                   "no such keyboard");
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (keyboard == context->keyboard) {
 | 
			
		||||
            g_dbus_method_invocation_return_value (invocation, NULL);
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (context->keyboard)
 | 
			
		||||
            disconnect_keyboard_signals (context);
 | 
			
		||||
 | 
			
		||||
        context->keyboard = keyboard;
 | 
			
		||||
 | 
			
		||||
        context->key_pressed_handler =
 | 
			
		||||
            g_signal_connect (context->keyboard, "key-pressed",
 | 
			
		||||
                              G_CALLBACK(on_key_pressed),
 | 
			
		||||
@ -468,8 +606,6 @@ handle_method_call (GDBusConnection       *connection,
 | 
			
		||||
            g_signal_connect (context->keyboard, "key-released",
 | 
			
		||||
                              G_CALLBACK(on_key_released),
 | 
			
		||||
                              context);
 | 
			
		||||
        eek_keyboard_set_modifier_behavior (context->keyboard,
 | 
			
		||||
                                            EEK_MODIFIER_BEHAVIOR_LATCH);
 | 
			
		||||
        
 | 
			
		||||
        if (context->window) {
 | 
			
		||||
            gboolean was_visible = gtk_widget_get_visible (context->window);
 | 
			
		||||
@ -487,6 +623,23 @@ handle_method_call (GDBusConnection       *connection,
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (g_strcmp0 (method_name, "SetFullscreen") == 0) {
 | 
			
		||||
        gboolean fullscreen;
 | 
			
		||||
 | 
			
		||||
        g_variant_get (parameters, "(b)", &fullscreen);
 | 
			
		||||
 | 
			
		||||
        if (context->fullscreen == fullscreen) {
 | 
			
		||||
            g_dbus_method_invocation_return_value (invocation, NULL);
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
        context->fullscreen = fullscreen;
 | 
			
		||||
        if (context->window)
 | 
			
		||||
            set_geometry (context);
 | 
			
		||||
 | 
			
		||||
        g_dbus_method_invocation_return_value (invocation, NULL);
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (g_strcmp0 (method_name, "SetGroup") == 0) {
 | 
			
		||||
        gint group;
 | 
			
		||||
 | 
			
		||||
@ -499,7 +652,7 @@ handle_method_call (GDBusConnection       *connection,
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        g_variant_get (parameters, "(i)", &group);
 | 
			
		||||
        eek_keyboard_set_group (context->keyboard, group);
 | 
			
		||||
        eek_element_set_group (EEK_ELEMENT(context->keyboard), group);
 | 
			
		||||
 | 
			
		||||
        if (context->window) {
 | 
			
		||||
            gboolean was_visible = gtk_widget_get_visible (context->window);
 | 
			
		||||
@ -609,6 +762,7 @@ server_context_set_enabled (ServerContext *context, gboolean enabled)
 | 
			
		||||
    if (context->enabled == enabled)
 | 
			
		||||
        return;
 | 
			
		||||
 | 
			
		||||
    context->enabled = enabled;
 | 
			
		||||
    if (enabled) {
 | 
			
		||||
        error = NULL;
 | 
			
		||||
        g_dbus_connection_emit_signal (context->connection,
 | 
			
		||||
@ -637,7 +791,6 @@ server_context_set_enabled (ServerContext *context, gboolean enabled)
 | 
			
		||||
            gtk_widget_hide (context->window);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    context->enabled = enabled;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
 | 
			
		||||
@ -18,6 +18,7 @@
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <gio/gio.h>
 | 
			
		||||
#include <gtk/gtk.h>
 | 
			
		||||
#include <glib/gi18n.h>
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_CONFIG_H
 | 
			
		||||
#include "config.h"
 | 
			
		||||
@ -30,6 +31,20 @@
 | 
			
		||||
#include "server-server.h"
 | 
			
		||||
#include "eek/eek.h"
 | 
			
		||||
 | 
			
		||||
static gboolean opt_system = FALSE;
 | 
			
		||||
static gboolean opt_session = FALSE;
 | 
			
		||||
static gchar *opt_address = NULL;
 | 
			
		||||
 | 
			
		||||
static const GOptionEntry options[] = {
 | 
			
		||||
    {"system", 'y', 0, G_OPTION_ARG_NONE, &opt_system,
 | 
			
		||||
     N_("Connect to the system bus")},
 | 
			
		||||
    {"session", 'e', 0, G_OPTION_ARG_NONE, &opt_session,
 | 
			
		||||
     N_("Connect to the session bus")},
 | 
			
		||||
    {"address", 'a', 0, G_OPTION_ARG_STRING, &opt_address,
 | 
			
		||||
     N_("Connect to the given D-Bus address")},
 | 
			
		||||
    {NULL}
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
on_name_acquired (GDBusConnection *connection,
 | 
			
		||||
                  const gchar     *name,
 | 
			
		||||
@ -45,10 +60,20 @@ on_name_lost (GDBusConnection *connection,
 | 
			
		||||
  exit (1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
on_destroyed (ServerServer *server,
 | 
			
		||||
              gpointer      user_data)
 | 
			
		||||
{
 | 
			
		||||
    GMainLoop *loop = user_data;
 | 
			
		||||
 | 
			
		||||
    g_main_loop_quit (loop);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
main (int argc, char **argv)
 | 
			
		||||
{
 | 
			
		||||
    ServerServer *server;
 | 
			
		||||
    GBusType bus_type;
 | 
			
		||||
    GDBusConnection *connection;
 | 
			
		||||
    GError *error;
 | 
			
		||||
    GMainLoop *loop;
 | 
			
		||||
@ -68,23 +93,53 @@ main (int argc, char **argv)
 | 
			
		||||
 | 
			
		||||
    g_log_set_always_fatal (G_LOG_LEVEL_CRITICAL);
 | 
			
		||||
 | 
			
		||||
    /* preload Eek* types for EekKeyboard deserialization */
 | 
			
		||||
    g_type_class_ref (EEK_TYPE_KEYBOARD);
 | 
			
		||||
    g_type_class_ref (EEK_TYPE_SECTION);
 | 
			
		||||
    g_type_class_ref (EEK_TYPE_KEY);
 | 
			
		||||
    g_type_class_ref (EEK_TYPE_SYMBOL);
 | 
			
		||||
    g_type_class_ref (EEK_TYPE_KEYSYM);
 | 
			
		||||
 | 
			
		||||
    if (opt_system)
 | 
			
		||||
        bus_type = G_BUS_TYPE_SYSTEM;
 | 
			
		||||
    else if (opt_address)
 | 
			
		||||
        bus_type = G_BUS_TYPE_NONE;
 | 
			
		||||
    else
 | 
			
		||||
        bus_type = G_BUS_TYPE_SESSION;
 | 
			
		||||
 | 
			
		||||
    switch (bus_type) {
 | 
			
		||||
    case G_BUS_TYPE_SYSTEM:
 | 
			
		||||
    case G_BUS_TYPE_SESSION:
 | 
			
		||||
        error = NULL;
 | 
			
		||||
        connection = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &error);
 | 
			
		||||
    if (error) {
 | 
			
		||||
        g_printerr ("%s\n", error->message);
 | 
			
		||||
        if (connection == NULL) {
 | 
			
		||||
            g_printerr ("Can't connect to the bus: %s\n", error->message);
 | 
			
		||||
            exit (1);
 | 
			
		||||
        }
 | 
			
		||||
        break;
 | 
			
		||||
    case G_BUS_TYPE_NONE:
 | 
			
		||||
        error = NULL;
 | 
			
		||||
        connection = g_dbus_connection_new_for_address_sync (opt_address,
 | 
			
		||||
                                                             0,
 | 
			
		||||
                                                             NULL,
 | 
			
		||||
                                                             NULL,
 | 
			
		||||
                                                             &error);
 | 
			
		||||
        if (connection == NULL) {
 | 
			
		||||
            g_printerr ("Can't connect to the bus at %s: %s\n",
 | 
			
		||||
                        opt_address,
 | 
			
		||||
                        error->message);
 | 
			
		||||
            exit (1);
 | 
			
		||||
        }
 | 
			
		||||
        break;
 | 
			
		||||
    default:
 | 
			
		||||
        g_assert_not_reached ();
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    server = server_server_new (SERVER_SERVER_PATH, connection);
 | 
			
		||||
 | 
			
		||||
    if (server == NULL) {
 | 
			
		||||
        g_printerr ("Can't create server server\n");
 | 
			
		||||
        g_printerr ("Can't create server\n");
 | 
			
		||||
        exit (1);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -101,6 +156,9 @@ main (int argc, char **argv)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    loop = g_main_loop_new (NULL, FALSE);
 | 
			
		||||
 | 
			
		||||
    g_signal_connect (server, "destroyed", G_CALLBACK(on_destroyed), loop);
 | 
			
		||||
 | 
			
		||||
    g_main_loop_run (loop);
 | 
			
		||||
 | 
			
		||||
    g_bus_unown_name (owner_id);
 | 
			
		||||
 | 
			
		||||
@ -22,6 +22,8 @@
 | 
			
		||||
#include "server-server.h"
 | 
			
		||||
#include "server-context.h"
 | 
			
		||||
 | 
			
		||||
#define I_(string) g_intern_static_string (string)
 | 
			
		||||
 | 
			
		||||
enum {
 | 
			
		||||
    PROP_0,
 | 
			
		||||
    PROP_OBJECT_PATH,
 | 
			
		||||
@ -29,6 +31,13 @@ enum {
 | 
			
		||||
    PROP_LAST
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
enum {
 | 
			
		||||
    DESTROYED,
 | 
			
		||||
    LAST_SIGNAL
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static guint signals[LAST_SIGNAL] = { 0, };
 | 
			
		||||
 | 
			
		||||
static const gchar introspection_xml[] =
 | 
			
		||||
    "<node>"
 | 
			
		||||
    "  <interface name='com.redhat.Eekboard.Server'>"
 | 
			
		||||
@ -43,6 +52,7 @@ static const gchar introspection_xml[] =
 | 
			
		||||
    "    <method name='DestroyContext'>"
 | 
			
		||||
    "      <arg direction='in' type='s' name='object_path'/>"
 | 
			
		||||
    "    </method>"
 | 
			
		||||
    "    <method name='Destroy'/>"
 | 
			
		||||
    /* signals */
 | 
			
		||||
    "  </interface>"
 | 
			
		||||
    "</node>";
 | 
			
		||||
@ -147,6 +157,16 @@ server_server_dispose (GObject *object)
 | 
			
		||||
    G_OBJECT_CLASS (server_server_parent_class)->dispose (object);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
server_server_finalize (GObject *object)
 | 
			
		||||
{
 | 
			
		||||
    ServerServer *server = SERVER_SERVER(object);
 | 
			
		||||
 | 
			
		||||
    g_free (server->object_path);
 | 
			
		||||
 | 
			
		||||
    G_OBJECT_CLASS (server_server_parent_class)->dispose (object);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
server_server_constructed (GObject *object)
 | 
			
		||||
{
 | 
			
		||||
@ -174,6 +194,18 @@ server_server_class_init (ServerServerClass *klass)
 | 
			
		||||
    gobject_class->constructed = server_server_constructed;
 | 
			
		||||
    gobject_class->set_property = server_server_set_property;
 | 
			
		||||
    gobject_class->dispose = server_server_dispose;
 | 
			
		||||
    gobject_class->finalize = server_server_finalize;
 | 
			
		||||
 | 
			
		||||
    signals[DESTROYED] =
 | 
			
		||||
        g_signal_new (I_("destroyed"),
 | 
			
		||||
                      G_TYPE_FROM_CLASS(gobject_class),
 | 
			
		||||
                      G_SIGNAL_RUN_LAST,
 | 
			
		||||
                      0,
 | 
			
		||||
                      NULL,
 | 
			
		||||
                      NULL,
 | 
			
		||||
                      g_cclosure_marshal_VOID__VOID,
 | 
			
		||||
                      G_TYPE_NONE,
 | 
			
		||||
                      0);
 | 
			
		||||
 | 
			
		||||
    pspec = g_param_spec_string ("object-path",
 | 
			
		||||
                                 "Object-path",
 | 
			
		||||
@ -248,16 +280,21 @@ server_name_vanished_callback (GDBusConnection *connection,
 | 
			
		||||
            g_hash_table_iter_remove (&iter);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    for (head = server->context_stack; head; head = server->context_stack) {
 | 
			
		||||
    for (head = server->context_stack; head; ) {
 | 
			
		||||
        const gchar *client_connection =
 | 
			
		||||
            server_context_get_client_connection (head->data);
 | 
			
		||||
        GSList *next = g_slist_next (head);
 | 
			
		||||
 | 
			
		||||
        if (g_strcmp0 (client_connection, name) == 0) {
 | 
			
		||||
            server->context_stack = g_slist_remove_link (server->context_stack,
 | 
			
		||||
                                                         head);
 | 
			
		||||
            g_object_unref (head->data);
 | 
			
		||||
            g_slist_free1 (head);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        head = next;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (server->context_stack)
 | 
			
		||||
        server_context_set_enabled (server->context_stack->data, TRUE);
 | 
			
		||||
}
 | 
			
		||||
@ -287,6 +324,8 @@ handle_method_call (GDBusConnection       *connection,
 | 
			
		||||
        g_hash_table_insert (server->context_hash,
 | 
			
		||||
                             object_path,
 | 
			
		||||
                             context);
 | 
			
		||||
 | 
			
		||||
        /* the vanished callback is called when clients are disconnected */
 | 
			
		||||
        g_bus_watch_name_on_connection (server->connection,
 | 
			
		||||
                                        sender,
 | 
			
		||||
                                        G_BUS_NAME_WATCHER_FLAGS_NONE,
 | 
			
		||||
@ -358,6 +397,12 @@ handle_method_call (GDBusConnection       *connection,
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (g_strcmp0 (method_name, "Destroy") == 0) {
 | 
			
		||||
        g_signal_emit_by_name (server, "destroyed", NULL);
 | 
			
		||||
        g_dbus_method_invocation_return_value (invocation, NULL);
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    g_return_if_reached ();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -24,10 +24,17 @@
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <gdk/gdkx.h>
 | 
			
		||||
#include <glib/gi18n.h>
 | 
			
		||||
 | 
			
		||||
#include "eek/eek-xml.h"
 | 
			
		||||
#include "eek/eek-xkl.h"
 | 
			
		||||
 | 
			
		||||
#if HAVE_CLUTTER_GTK
 | 
			
		||||
#include <clutter-gtk/clutter-gtk.h>
 | 
			
		||||
#include "eek/eek-clutter.h"
 | 
			
		||||
#else  /* HAVE_CLUTTER_GTK */
 | 
			
		||||
#include "eek/eek-gtk.h"
 | 
			
		||||
#endif  /* !HAVE_CLUTTER_GTK */
 | 
			
		||||
 | 
			
		||||
#include "xklutil.h"
 | 
			
		||||
 | 
			
		||||
@ -39,23 +46,43 @@ static gchar *opt_model = NULL;
 | 
			
		||||
static gchar *opt_layouts = NULL;
 | 
			
		||||
static gchar *opt_options = NULL;
 | 
			
		||||
static gchar *opt_list = NULL;
 | 
			
		||||
static guint opt_group = 0;
 | 
			
		||||
static gchar *opt_theme = NULL;
 | 
			
		||||
 | 
			
		||||
static const GOptionEntry options[] = {
 | 
			
		||||
    {"load", 'l', 0, G_OPTION_ARG_STRING, &opt_load,
 | 
			
		||||
     "Show the keyboard loaded from an XML file"},
 | 
			
		||||
     N_("Show the keyboard loaded from an XML file")},
 | 
			
		||||
    {"dump", 'd', 0, G_OPTION_ARG_NONE, &opt_dump,
 | 
			
		||||
     "Dump the current layout as XML"},
 | 
			
		||||
     N_("Output the current layout into an XML file")},
 | 
			
		||||
    {"list", 'L', 0, G_OPTION_ARG_STRING, &opt_list,
 | 
			
		||||
     "List configuration items for given spec"},
 | 
			
		||||
     N_("List configuration items for given spec")},
 | 
			
		||||
    {"model", '\0', 0, G_OPTION_ARG_STRING, &opt_model,
 | 
			
		||||
     "Specify model"},
 | 
			
		||||
     N_("Specify model")},
 | 
			
		||||
    {"layouts", '\0', 0, G_OPTION_ARG_STRING, &opt_layouts,
 | 
			
		||||
     "Specify layouts"},
 | 
			
		||||
     N_("Specify layouts")},
 | 
			
		||||
    {"options", '\0', 0, G_OPTION_ARG_STRING, &opt_options,
 | 
			
		||||
     "Specify options"},
 | 
			
		||||
     N_("Specify options")},
 | 
			
		||||
    {"group", 'g', 0, G_OPTION_ARG_INT, &opt_group,
 | 
			
		||||
     N_("Specify group")},
 | 
			
		||||
    {"theme", 't', 0, G_OPTION_ARG_STRING, &opt_theme,
 | 
			
		||||
     N_("Specify theme")},
 | 
			
		||||
    {NULL}
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#if HAVE_CLUTTER_GTK
 | 
			
		||||
static void
 | 
			
		||||
on_allocation_changed (ClutterActor          *stage,
 | 
			
		||||
                       ClutterActorBox       *box,
 | 
			
		||||
                       ClutterAllocationFlags flags,
 | 
			
		||||
                       gpointer               user_data)
 | 
			
		||||
{
 | 
			
		||||
    ClutterActor *actor = user_data;
 | 
			
		||||
    clutter_actor_set_size (actor,
 | 
			
		||||
                            box->x2 - box->x1,
 | 
			
		||||
                            box->y2 - box->y1);
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
on_destroy (gpointer user_data)
 | 
			
		||||
{
 | 
			
		||||
@ -76,10 +103,19 @@ main (int argc, char **argv)
 | 
			
		||||
{
 | 
			
		||||
    GOptionContext *context;
 | 
			
		||||
 | 
			
		||||
#if HAVE_CLUTTER_GTK
 | 
			
		||||
    if (gtk_clutter_init (&argc, &argv) != CLUTTER_INIT_SUCCESS) {
 | 
			
		||||
        g_printerr ("Can't init GTK with Clutter\n");
 | 
			
		||||
        exit (1);
 | 
			
		||||
    }
 | 
			
		||||
#else
 | 
			
		||||
    if (!gtk_init_check (&argc, &argv)) {
 | 
			
		||||
        g_printerr ("Can't init GTK\n");
 | 
			
		||||
        exit (1);
 | 
			
		||||
    }
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    g_log_set_always_fatal (G_LOG_LEVEL_CRITICAL);
 | 
			
		||||
 | 
			
		||||
    context = g_option_context_new ("eek-example-xml");
 | 
			
		||||
    g_option_context_add_main_entries (context, options, NULL);
 | 
			
		||||
@ -94,6 +130,10 @@ main (int argc, char **argv)
 | 
			
		||||
        EekBounds bounds;
 | 
			
		||||
        GtkWidget *widget, *window;
 | 
			
		||||
        GError *error;
 | 
			
		||||
#if HAVE_CLUTTER_GTK
 | 
			
		||||
        ClutterActor *stage, *actor;
 | 
			
		||||
        ClutterColor stage_color = { 0xff, 0xff, 0xff, 0xff };
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
        file = g_file_new_for_path (opt_load);
 | 
			
		||||
 | 
			
		||||
@ -109,10 +149,41 @@ main (int argc, char **argv)
 | 
			
		||||
        keyboard = eek_keyboard_new (layout, 640, 480);
 | 
			
		||||
        g_object_unref (layout);
 | 
			
		||||
 | 
			
		||||
        eek_element_set_group (EEK_ELEMENT(keyboard), opt_group);
 | 
			
		||||
        eek_element_get_bounds (EEK_ELEMENT(keyboard), &bounds);
 | 
			
		||||
 | 
			
		||||
#if HAVE_CLUTTER_GTK
 | 
			
		||||
        widget = gtk_clutter_embed_new ();
 | 
			
		||||
        stage = gtk_clutter_embed_get_stage (GTK_CLUTTER_EMBED(widget));
 | 
			
		||||
        actor = eek_clutter_keyboard_new (keyboard);
 | 
			
		||||
        if (opt_theme) {
 | 
			
		||||
            EekTheme *theme = eek_theme_new (opt_theme, NULL, NULL);
 | 
			
		||||
 | 
			
		||||
            eek_clutter_keyboard_set_theme (EEK_CLUTTER_KEYBOARD(actor), theme);
 | 
			
		||||
            g_object_unref (theme);
 | 
			
		||||
        }
 | 
			
		||||
        clutter_container_add_actor (CLUTTER_CONTAINER(stage), actor);
 | 
			
		||||
 | 
			
		||||
        clutter_stage_set_color (CLUTTER_STAGE(stage), &stage_color);
 | 
			
		||||
        clutter_stage_set_user_resizable (CLUTTER_STAGE(stage), TRUE);
 | 
			
		||||
        clutter_stage_set_minimum_size (CLUTTER_STAGE(stage),
 | 
			
		||||
                                        bounds.width / 3,
 | 
			
		||||
                                        bounds.height / 3);
 | 
			
		||||
        g_signal_connect (stage,
 | 
			
		||||
                          "allocation-changed",
 | 
			
		||||
                          G_CALLBACK(on_allocation_changed),
 | 
			
		||||
                          actor);
 | 
			
		||||
#else
 | 
			
		||||
        widget = eek_gtk_keyboard_new (keyboard);
 | 
			
		||||
        if (opt_theme) {
 | 
			
		||||
            EekTheme *theme = eek_theme_new (opt_theme, NULL, NULL);
 | 
			
		||||
 | 
			
		||||
            eek_gtk_keyboard_set_theme (EEK_GTK_KEYBOARD(widget), theme);
 | 
			
		||||
            g_object_unref (theme);
 | 
			
		||||
        }
 | 
			
		||||
#endif
 | 
			
		||||
        g_object_unref (keyboard);
 | 
			
		||||
 | 
			
		||||
        eek_element_get_bounds (EEK_ELEMENT(keyboard), &bounds);
 | 
			
		||||
        gtk_widget_set_size_request (widget, bounds.width, bounds.height);
 | 
			
		||||
 | 
			
		||||
        window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user