Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
Menu
Open sidebar
Dorota Czaplejewicz
squeekboard
Commits
134faacb
Commit
134faacb
authored
Feb 01, 2011
by
Daiki Ueno
Browse files
Reimplement eekboard as a D-Bus server.
parent
b2ad88bd
Changes
10
Hide whitespace changes
Inline
Side-by-side
README
View file @
134faacb
...
...
@@ -6,7 +6,7 @@ create keyboard-like UI ("libeek").
* Requirements
* GLib2, GTK, GConf2, PangoCairo, libxklavier, libfakekey,
libnotify,
CSPI
* GLib2, GTK, GConf2, PangoCairo, libxklavier, libfakekey, CSPI
* Clutter (optional)
* Clutter-Gtk (optional)
* Vala (optional)
...
...
@@ -19,15 +19,26 @@ Build from git repo:
$ git clone git://github.com/ueno/eekboard.git
$ cd eekboard
$ ./autogen.sh --prefix=/usr --enable-gtk-doc
Build from tarball:
$ ./configure
$ make
$ sudo make install
$ eekboard
How to test (dump/load the current layout):
$ ./tests/eek-example-xml -d > keyboard.xml
$ ./tests/eek-example-xml -l keyboard.xml
NOTE: eekboard is now being heavily rewritten and it may behave
wrongly. Make sure to close windows where you are doing any important
work, before running eekboard.
$ ./src/eekboard-server &
$ ./src/eekboard-system-client --xklavier --accessibility --fakekey
Where --xklavier is to monitor system keyboard layout change,
--accessibility is to track focus/key events via AT-SPI, and --fakekey
generates X key events when eekboard-server signals virtual
key-press/key-release events.
* Documentation
<file:docs/reference/eek/html/index.html>
src/Makefile.am
View file @
134faacb
...
...
@@ -17,8 +17,18 @@
# 02110-1301 USA
if
ENABLE_EEKBOARD
bin_PROGRAMS
=
eekboard
eekboard_CFLAGS
=
\
bin_PROGRAMS
=
eekboard-system-client eekboard-server
noinst_LIBRARIES
=
libeekboard.a
libeekboard_a_headers
=
proxy.h
libeekboard_a_CFLAGS
=
\
-I
$(top_srcdir)
\
$(GIO2_CFLAGS)
libeekboard_a_SOURCES
=
proxy.c
eekboard_system_client_CFLAGS
=
\
-I
$(top_srcdir)
\
$(GIO2_CFLAGS)
\
$(GTK_CFLAGS)
\
...
...
@@ -26,24 +36,45 @@ eekboard_CFLAGS = \
$(XKB_CFLAGS)
\
$(LIBXKLAVIER_CFLAGS)
\
$(LIBFAKEKEY_CFLAGS)
\
$(CSPI_CFLAGS)
\
$(NOTIFY_CFLAGS)
$(CSPI_CFLAGS)
eekboard_LDFLAGS
=
\
eekboard_system_client_LDADD
=
\
libeekboard.a
\
$(top_builddir)
/eek/libeek.la
\
$(top_builddir)
/eek/libeek-xkl.la
\
$(top_builddir)
/eek/libeek-gtk.la
\
$(GIO2_LIBS)
\
$(GTK_LIBS)
\
$(GCONF2_LIBS)
\
$(XKB_LIBS)
\
$(LIBXKLAVIER_LIBS)
\
$(LIBFAKEKEY_LIBS)
\
$(CSPI_LIBS)
\
$(NOTIFY_LIBS)
$(CSPI_LIBS)
eekboard_system_client_headers
=
system-client.h
eekboard_system_client_SOURCES
=
system-client.c system-client-main.c
eekboard_server_CFLAGS
=
\
-I
$(top_srcdir)
\
$(GIO2_CFLAGS)
\
$(GTK_CFLAGS)
eekboard_server_LDADD
=
\
libeekboard.a
\
$(top_builddir)
/eek/libeek.la
\
$(top_builddir)
/eek/libeek-gtk.la
\
$(GIO2_LIBS)
\
$(GTK_LIBS)
eekboard_server_headers
=
server.h
eekboard_server_SOURCES
=
server.c server-main.c
if
HAVE_CLUTTER
eekboard_CFLAGS
+=
$(CLUTTER_CFLAGS)
$(CLUTTER_GTK_CFLAGS)
eekboard_
LDFLAGS
+=
$(CLUTTER_LIBS)
$(top_builddir)
/eek/libeek-clutter.la
$(CLUTTER_GTK_LIBS)
eekboard_
server_
CFLAGS
+=
$(CLUTTER_CFLAGS)
$(CLUTTER_GTK_CFLAGS)
eekboard_
server_LDADD
+=
$(CLUTTER_LIBS)
$(top_builddir)
/eek/libeek-clutter.la
$(CLUTTER_GTK_LIBS)
endif
noinst_HEADERS
=
\
$(libeekboard_a_headers)
\
$(eekboard_system_client_headers)
\
$(eekboard_server_headers)
endif
src/proxy.c
0 → 100644
View file @
134faacb
/*
* 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/>.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
/* HAVE_CONFIG_H */
#include "proxy.h"
#define BUFSIZE 8192
enum
{
KEY_PRESSED
,
KEY_RELEASED
,
LAST_SIGNAL
};
static
guint
signals
[
LAST_SIGNAL
]
=
{
0
,
};
struct
_EekboardProxy
{
GDBusProxy
parent
;
};
struct
_EekboardProxyClass
{
GDBusProxyClass
parent_class
;
};
G_DEFINE_TYPE
(
EekboardProxy
,
eekboard_proxy
,
G_TYPE_DBUS_PROXY
);
static
void
eekboard_proxy_real_g_signal
(
GDBusProxy
*
self
,
const
gchar
*
sender_name
,
const
gchar
*
signal_name
,
GVariant
*
parameters
)
{
EekboardProxy
*
proxy
=
EEKBOARD_PROXY
(
self
);
guint
*
keycode
;
g_debug
(
"%s %s"
,
sender_name
,
signal_name
);
if
(
g_strcmp0
(
signal_name
,
"KeyPressed"
)
==
0
)
{
g_variant_get
(
parameters
,
"(u)"
,
&
keycode
);
g_signal_emit_by_name
(
proxy
,
"key-pressed"
,
keycode
);
return
;
}
if
(
g_strcmp0
(
signal_name
,
"KeyReleased"
)
==
0
)
{
g_variant_get
(
parameters
,
"(u)"
,
&
keycode
);
g_signal_emit_by_name
(
proxy
,
"key-released"
,
keycode
);
return
;
}
g_return_if_reached
();
}
static
void
eekboard_proxy_class_init
(
EekboardProxyClass
*
klass
)
{
GDBusProxyClass
*
proxy_class
=
G_DBUS_PROXY_CLASS
(
klass
);
GObjectClass
*
gobject_class
=
G_OBJECT_CLASS
(
klass
);
proxy_class
->
g_signal
=
eekboard_proxy_real_g_signal
;
signals
[
KEY_PRESSED
]
=
g_signal_new
(
"key-pressed"
,
G_TYPE_FROM_CLASS
(
gobject_class
),
G_SIGNAL_RUN_LAST
,
0
,
NULL
,
NULL
,
g_cclosure_marshal_VOID__UINT
,
G_TYPE_NONE
,
1
,
G_TYPE_UINT
);
signals
[
KEY_RELEASED
]
=
g_signal_new
(
"key-released"
,
G_TYPE_FROM_CLASS
(
gobject_class
),
G_SIGNAL_RUN_LAST
,
0
,
NULL
,
NULL
,
g_cclosure_marshal_VOID__UINT
,
G_TYPE_NONE
,
1
,
G_TYPE_UINT
);
}
static
void
eekboard_proxy_init
(
EekboardProxy
*
proxy
)
{
}
EekboardProxy
*
eekboard_proxy_new
(
const
gchar
*
path
,
GDBusConnection
*
connection
,
GCancellable
*
cancellable
,
GError
**
error
)
{
GInitable
*
initable
;
g_assert
(
path
!=
NULL
);
g_assert
(
G_IS_DBUS_CONNECTION
(
connection
));
initable
=
g_initable_new
(
EEKBOARD_TYPE_PROXY
,
cancellable
,
error
,
"g-connection"
,
connection
,
"g-name"
,
"com.redhat.eekboard.Keyboard"
,
"g-flags"
,
G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START
|
G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES
,
"g-interface-name"
,
"com.redhat.eekboard.Keyboard"
,
"g-object-path"
,
path
,
NULL
);
if
(
initable
!=
NULL
)
return
EEKBOARD_PROXY
(
initable
);
return
NULL
;
}
static
void
proxy_call_async_ready_cb
(
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
);
g_assert_no_error
(
error
);
g_assert
(
result
!=
NULL
);
g_variant_unref
(
result
);
}
void
eekboard_proxy_set_keyboard
(
EekboardProxy
*
proxy
,
EekKeyboard
*
keyboard
)
{
GString
*
output
;
GVariant
*
variant
;
gchar
*
data
;
output
=
g_string_sized_new
(
BUFSIZE
);
eek_keyboard_output
(
keyboard
,
output
,
0
);
data
=
g_string_free
(
output
,
FALSE
);
variant
=
g_variant_new
(
"(s)"
,
data
);
g_free
(
data
);
g_dbus_proxy_call
(
G_DBUS_PROXY
(
proxy
),
"SetKeyboard"
,
g_variant_new
(
"(v)"
,
variant
),
G_DBUS_CALL_FLAGS_NONE
,
-
1
,
NULL
,
proxy_call_async_ready_cb
,
NULL
);
g_variant_unref
(
variant
);
}
void
eekboard_proxy_set_group
(
EekboardProxy
*
proxy
,
gint
group
)
{
g_dbus_proxy_call
(
G_DBUS_PROXY
(
proxy
),
"SetGroup"
,
g_variant_new
(
"(i)"
,
group
),
G_DBUS_CALL_FLAGS_NONE
,
-
1
,
NULL
,
proxy_call_async_ready_cb
,
NULL
);
}
void
eekboard_proxy_show
(
EekboardProxy
*
proxy
)
{
g_dbus_proxy_call
(
G_DBUS_PROXY
(
proxy
),
"Show"
,
NULL
,
G_DBUS_CALL_FLAGS_NONE
,
-
1
,
NULL
,
proxy_call_async_ready_cb
,
NULL
);
}
void
eekboard_proxy_hide
(
EekboardProxy
*
proxy
)
{
g_dbus_proxy_call
(
G_DBUS_PROXY
(
proxy
),
"Hide"
,
NULL
,
G_DBUS_CALL_FLAGS_NONE
,
-
1
,
NULL
,
proxy_call_async_ready_cb
,
NULL
);
}
src/proxy.h
0 → 100644
View file @
134faacb
/*
* 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_PROXY_H
#define EEKBOARD_PROXY_H 1
#include <gio/gio.h>
#include "eek/eek.h"
G_BEGIN_DECLS
#define EEKBOARD_TYPE_PROXY (eekboard_proxy_get_type())
#define EEKBOARD_PROXY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EEKBOARD_TYPE_PROXY, EekboardProxy))
#define EEKBOARD_PROXY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EEKBOARD_TYPE_PROXY, EekboardProxyClass))
#define EEKBOARD_IS_PROXY(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EEKBOARD_TYPE_PROXY))
#define EEKBOARD_IS_PROXY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EEKBOARD_TYPE_PROXY))
#define EEKBOARD_PROXY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EEKBOARD_TYPE_PROXY, EekboardProxyClass))
typedef
struct
_EekboardProxy
EekboardProxy
;
typedef
struct
_EekboardProxyClass
EekboardProxyClass
;
EekboardProxy
*
eekboard_proxy_new
(
const
gchar
*
path
,
GDBusConnection
*
connection
,
GCancellable
*
cancellable
,
GError
**
error
);
void
eekboard_proxy_set_keyboard
(
EekboardProxy
*
proxy
,
EekKeyboard
*
keyboard
);
void
eekboard_proxy_set_group
(
EekboardProxy
*
proxy
,
gint
group
);
void
eekboard_proxy_show
(
EekboardProxy
*
proxy
);
void
eekboard_proxy_hide
(
EekboardProxy
*
proxy
);
G_END_DECLS
#endif
/* EEKBOARD_PROXY_H */
src/server-main.c
0 → 100644
View file @
134faacb
/*
* 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/>.
*/
#include <stdlib.h>
#include <gio/gio.h>
#include <gtk/gtk.h>
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
/* HAVE_CONFIG_H */
#include "server.h"
#include "eek/eek.h"
int
main
(
int
argc
,
char
**
argv
)
{
EekboardServer
*
server
;
GDBusConnection
*
connection
;
GError
*
error
;
GMainLoop
*
loop
;
if
(
!
gtk_init_check
(
&
argc
,
&
argv
))
{
g_warning
(
"Can't init GTK"
);
exit
(
1
);
}
error
=
NULL
;
connection
=
g_bus_get_sync
(
G_BUS_TYPE_SESSION
,
NULL
,
&
error
);
if
(
error
)
{
g_printerr
(
"%s
\n
"
,
error
->
message
);
exit
(
1
);
}
server
=
eekboard_server_new
(
connection
);
loop
=
g_main_loop_new
(
NULL
,
FALSE
);
if
(
!
eekboard_server_start
(
server
))
{
g_printerr
(
"Can't start server
\n
"
);
exit
(
1
);
}
g_main_loop_run
(
loop
);
eekboard_server_stop
(
server
);
g_object_unref
(
server
);
g_object_unref
(
connection
);
g_main_loop_unref
(
loop
);
return
0
;
}
src/server.c
0 → 100644
View file @
134faacb
/*
* 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/>.
*/
#include <gtk/gtk.h>
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
/* HAVE_CONFIG_H */
#include "eek/eek.h"
#include "eek/eek-gtk.h"
#include "server.h"
#define CSW 640
#define CSH 480
enum
{
PROP_0
,
PROP_CONNECTION
,
PROP_LAST
};
static
const
gchar
introspection_xml
[]
=
"<node>"
" <interface name='com.redhat.eekboard.Keyboard'>"
" <method name='SetKeyboard'>"
" <arg type='v' name='keyboard'/>"
" </method>"
" <method name='SetGroup'>"
" <arg type='i' name='group'/>"
" </method>"
" <method name='Show'/>"
" <method name='Hide'/>"
" <method name='PressKey'>"
" <arg type='s' name='key_id' direction='in'/>"
" </method>"
" <method name='ReleaseKey'>"
" <arg type='s' name='key_id' direction='in'/>"
" </method>"
" <signal name='KeyPressed'>"
" <arg type='u' name='keycode'/>"
" </signal>"
" <signal name='KeyReleased'>"
" <arg type='u' name='keycode'/>"
" </signal>"
" </interface>"
"</node>"
;
typedef
struct
_EekboardServerClass
EekboardServerClass
;
struct
_EekboardServer
{
GObject
parent
;
GDBusConnection
*
connection
;
guint
owner_id
;
GDBusNodeInfo
*
introspection_data
;
GtkWidget
*
window
;
GtkWidget
*
widget
;
EekKeyboard
*
keyboard
;
};
struct
_EekboardServerClass
{
GObjectClass
parent_class
;
};
G_DEFINE_TYPE
(
EekboardServer
,
eekboard_server
,
G_TYPE_OBJECT
);
static
void
update_widget
(
EekboardServer
*
server
)
{
GdkScreen
*
screen
;
GdkWindow
*
root
;
gint
monitor
;
GdkRectangle
rect
;
EekBounds
bounds
;
if
(
server
->
widget
)
gtk_widget_destroy
(
server
->
widget
);
if
(
server
->
window
)
gtk_widget_destroy
(
server
->
window
);
server
->
widget
=
eek_gtk_keyboard_new
(
server
->
keyboard
);
eek_element_get_bounds
(
EEK_ELEMENT
(
server
->
keyboard
),
&
bounds
);
gtk_widget_set_size_request
(
server
->
widget
,
bounds
.
width
,
bounds
.
height
);
server
->
window
=
gtk_window_new
(
GTK_WINDOW_TOPLEVEL
);
gtk_container_add
(
GTK_CONTAINER
(
server
->
window
),
server
->
widget
);
gtk_widget_set_can_focus
(
server
->
window
,
FALSE
);
g_object_set
(
G_OBJECT
(
server
->
window
),
"accept_focus"
,
FALSE
,
NULL
);
gtk_window_set_title
(
GTK_WINDOW
(
server
->
window
),
"Keyboard"
);
screen
=
gdk_screen_get_default
();
root
=
gtk_widget_get_root_window
(
server
->
window
);
monitor
=
gdk_screen_get_monitor_at_window
(
screen
,
root
);
gdk_screen_get_monitor_geometry
(
screen
,
monitor
,
&
rect
);
gtk_window_move
(
GTK_WINDOW
(
server
->
window
),
MAX
(
rect
.
width
-
20
-
bounds
.
width
,
0
),
MAX
(
rect
.
height
-
40
-
bounds
.
height
,
0
));
}
static
void
eekboard_server_set_property
(
GObject
*
object
,
guint
prop_id
,
const
GValue
*
value
,
GParamSpec
*
pspec
)
{
EekboardServer
*
server
=
EEKBOARD_SERVER
(
object
);
GDBusConnection
*
connection
;
switch
(
prop_id
)
{
case
PROP_CONNECTION
:
connection
=
g_value_get_object
(
value
);
if
(
server
->
connection
)
g_object_unref
(
server
->
connection
);
server
->
connection
=
g_object_ref
(
connection
);
break
;
default:
g_object_set_property
(
object
,
g_param_spec_get_name
(
pspec
),
value
);
break
;
}
}
static
void
eekboard_server_dispose
(
GObject
*
object
)
{
EekboardServer
*
server
=
EEKBOARD_SERVER
(
object
);
if
(
server
->
connection
)
{
g_object_unref
(
server
->
connection
);
server
->
connection
=
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
);
GParamSpec
*
pspec
;
gobject_class
->
set_property
=
eekboard_server_set_property
;
gobject_class
->
dispose
=
eekboard_server_dispose
;
pspec
=
g_param_spec_object
(
"connection"
,
"Connection"
,
"Connection"
,
G_TYPE_DBUS_CONNECTION
,
G_PARAM_CONSTRUCT_ONLY
|
G_PARAM_WRITABLE
);
g_object_class_install_property
(
gobject_class
,
PROP_CONNECTION
,
pspec
);
}
static
void
eekboard_server_init
(
EekboardServer
*
server
)
{
GError
*
error
;
error
=
NULL
;
server
->
introspection_data
=
g_dbus_node_info_new_for_xml
(
introspection_xml
,
&
error
);
g_assert
(
server
->
introspection_data
!=
NULL
);
server
->
owner_id
=
0
;
server
->
keyboard
=
NULL
;
server
->
widget
=
NULL
;
server
->
window
=
NULL
;
}
static
void
on_key_pressed
(
EekKeyboard
*
keyboard
,
EekKey
*
key
,
gpointer
user_data
)
{
EekboardServer
*
server
=
user_data
;
GError
*
error
;
error
=
NULL
;
g_dbus_connection_emit_signal
(
server
->
connection
,
"com.redhat.eekboard.Keyboard"
,