diff --git a/com.emacsos.zero.ZeroPinyinService1.ZeroPinyinServiceInterface.xml b/com.emacsos.zero.ZeroPinyinService1.ZeroPinyinServiceInterface.xml
new file mode 100644
index 0000000000000000000000000000000000000000..f0876deedd51a87de711fd636483ae0a3d60c3fd
--- /dev/null
+++ b/com.emacsos.zero.ZeroPinyinService1.ZeroPinyinServiceInterface.xml
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/com.emacsos.zero.ZeroPinyinService.service b/com.emacsos.zero.ZeroPinyinService1.service
similarity index 60%
rename from com.emacsos.zero.ZeroPinyinService.service
rename to com.emacsos.zero.ZeroPinyinService1.service
index a252a34bc44d35d81a6b9af0fd009aa9bc73b77e..29df192302b8fec9c25ffd37e5ca700a8f32290f 100644
--- a/com.emacsos.zero.ZeroPinyinService.service
+++ b/com.emacsos.zero.ZeroPinyinService1.service
@@ -1,3 +1,3 @@
[D-BUS Service]
-Name=com.emacsos.zero.ZeroPinyinService
+Name=com.emacsos.zero.ZeroPinyinService1
Exec=/home/sylecn/bin/sbin/zero-pinyin-service
diff --git a/main.c b/main.c
index fed9f0bf37d2893e76e7a38b68719109570db144..81186ad2320f0089817c685d2393d386f4f9284b 100644
--- a/main.c
+++ b/main.c
@@ -1,64 +1,42 @@
#include
#include
#include "zero-pinyin-service.h"
+#include "zero-pinyin-service-generated.h"
#include "../sqlite3_util.h"
#include
typedef struct {
GApplication *app;
- GDBusNodeInfo *introspection_data;
guint owner_id;
+ ZeroPinyinService *interface;
sqlite3 *db;
- gboolean init_done;
} AppData;
-static AppData appdata;
-
-static const gchar introspection_xml[] =
- ""
- " "
- " "
- " "
- " "
- " "
- " "
- " "
- " "
- " "
- "";
-
-static void
-handle_method_get_candidates (GDBusMethodInvocation *invocation,
- AppData *appdata,
- GVariant *parameters)
+static gboolean
+on_handle_get_candidates (ZeroPinyinService *object,
+ GDBusMethodInvocation *invocation,
+ const gchar *preedit_str,
+ guint fetch_size,
+ AppData *appdata)
{
- gchar *preedit_str = NULL;
- guint fetch_size = 0;
- GVariant *result = NULL;
- GVariantBuilder *candidates_builder = NULL;
- GVariantBuilder *matched_lengths_builder = NULL;
-
- g_variant_get (parameters, "(su)", &preedit_str, &fetch_size);
- g_return_if_fail (preedit_str != NULL);
- g_return_if_fail (fetch_size > 0);
if (preedit_str == NULL || fetch_size == 0) {
g_dbus_method_invocation_return_dbus_error (
invocation,
"org.gtk.GDBus.Failed",
"Bad param");
- if (preedit_str)
- g_free (preedit_str);
- return;
+ return TRUE;
}
-
g_message ("get_candidates for preedit_str=%s fetch_size=%u",
preedit_str, fetch_size);
- candidates_builder = g_variant_builder_new (G_VARIANT_TYPE ("as"));
- matched_lengths_builder = g_variant_builder_new (G_VARIANT_TYPE ("au"));
+ GVariant *result = NULL;
+ GVariantBuilder *candidates_builder = NULL;
+ GVariantBuilder *matched_lengths_builder = NULL;
- /* test data */
+ /* test data */
/* get_candidates_test (preedit_str, fetch_size, candidates_builder, matched_lengths_builder); */
+ candidates_builder = g_variant_builder_new (G_VARIANT_TYPE ("as"));
+ matched_lengths_builder = g_variant_builder_new (G_VARIANT_TYPE ("au"));
get_candidates (appdata->db, preedit_str, fetch_size, candidates_builder, matched_lengths_builder);
result = g_variant_new ("(asau)", candidates_builder, matched_lengths_builder);
@@ -69,102 +47,51 @@ handle_method_get_candidates (GDBusMethodInvocation *invocation,
g_variant_builder_unref (candidates_builder);
g_variant_builder_unref (matched_lengths_builder);
- g_free (preedit_str);
-}
-static void
-handle_method_call (GDBusConnection *connection,
- const gchar *sender,
- const gchar *object_path,
- const gchar *interface_name,
- const gchar *method_name,
- GVariant *parameters,
- GDBusMethodInvocation *invocation,
- gpointer user_data)
-{
- AppData *appdata;
- gchar *errmsg = NULL;
-
- appdata = (AppData*) user_data;
-
- g_message ("got method call: %s", method_name);
- if (g_strcmp0 (method_name, "GetCandidates") == 0) {
- handle_method_get_candidates (invocation, appdata, parameters);
- } else if (g_strcmp0 (method_name, "Quit") == 0) {
- g_application_quit (appdata->app);
- } else {
- g_warning ("method not found: %s", method_name);
-
- errmsg = g_strdup_printf ("Method not found: %s", method_name);
- g_dbus_method_invocation_return_dbus_error (
- invocation,
- "org.gtk.GDBus.Failed",
- errmsg);
- g_free (errmsg);
- }
-}
-
-static GVariant *
-handle_get_property (GDBusConnection *connection,
- const gchar *sender,
- const gchar *object_path,
- const gchar *interface_name,
- const gchar *property_name,
- GError **error,
- gpointer user_data)
-{
- return NULL;
+ return TRUE;
}
static gboolean
-handle_set_property (GDBusConnection *connection,
- const gchar *sender,
- const gchar *object_path,
- const gchar *interface_name,
- const gchar *property_name,
- GVariant *value,
- GError **error,
- gpointer user_data)
+on_handle_quit (ZeroPinyinService *object,
+ GDBusMethodInvocation *invocation,
+ AppData *appdata)
{
+ g_application_quit (appdata->app);
return TRUE;
}
-static const GDBusInterfaceVTable interface_vtable = {
- handle_method_call,
- handle_get_property,
- handle_set_property
-};
-
static void
on_bus_acquired (GDBusConnection *connection,
const gchar *name,
gpointer user_data)
{
- AppData *appdata = NULL;
+ AppData *appdata = (AppData*) user_data;
GError *err = NULL;
- guint registration_id = 0;
- static const gchar* object_path = "/com/emacsos/zero/ZeroPinyinService";
g_message ("on_bus_acquired() name=%s", name);
- appdata = (AppData*) user_data;
- registration_id = g_dbus_connection_register_object (
+
+ appdata->interface = zero_pinyin_service_skeleton_new ();
+ g_signal_connect (appdata->interface,
+ "handle-get-candidates",
+ G_CALLBACK (on_handle_get_candidates),
+ appdata);
+ g_signal_connect (appdata->interface,
+ "handle-quit",
+ G_CALLBACK (on_handle_quit),
+ appdata);
+ g_dbus_interface_skeleton_export (
+ G_DBUS_INTERFACE_SKELETON (appdata->interface),
connection,
- object_path,
- appdata->introspection_data->interfaces[0],
- &interface_vtable,
- appdata, /* user_data */
- NULL, /* user_data_free_func */
- &err); /* GError** */
- if (err != NULL) {
- g_warning ("object register failed: %s. exiting now", err->message);
+ ZERO_PINYIN_OBJECT_PATH,
+ &err);
+ if (err) {
+ g_warning ("export interface at %s failed: %s",
+ ZERO_PINYIN_OBJECT_PATH, err->message);
g_error_free (err);
- g_application_quit (appdata->app);
+ g_application_quit (G_APPLICATION (appdata->app));
return;
}
- if (registration_id > 0) {
- g_message ("object registered at %s", object_path);
- }
- g_assert_cmpint (registration_id, >, 0);
+ g_message ("interface exported at %s", ZERO_PINYIN_OBJECT_PATH);
}
static void
@@ -186,17 +113,15 @@ on_name_lost (GDBusConnection *connection,
static void
config_dbus_service (AppData *appdata)
{
- appdata->introspection_data = g_dbus_node_info_new_for_xml (
- introspection_xml, NULL);
- g_assert (appdata->introspection_data != NULL);
- appdata->owner_id = g_bus_own_name (G_BUS_TYPE_SESSION,
- "com.emacsos.zero.ZeroPinyinService",
- G_BUS_NAME_OWNER_FLAGS_ALLOW_REPLACEMENT|G_BUS_NAME_OWNER_FLAGS_REPLACE,
- on_bus_acquired,
- on_name_acquired,
- on_name_lost,
- appdata,
- NULL);
+ appdata->owner_id = g_bus_own_name (
+ G_BUS_TYPE_SESSION,
+ ZERO_PINYIN_WELL_KNOWN_NAME,
+ G_BUS_NAME_OWNER_FLAGS_ALLOW_REPLACEMENT|G_BUS_NAME_OWNER_FLAGS_REPLACE,
+ on_bus_acquired,
+ on_name_acquired,
+ on_name_lost,
+ appdata,
+ NULL);
g_assert_cmpint (appdata->owner_id, >, 0);
}
@@ -211,6 +136,9 @@ on_sigterm_received (gpointer user_data)
return G_SOURCE_REMOVE;
}
+/**
+ * init appdata->db
+ */
static void
config_db (AppData* appdata)
{
@@ -253,18 +181,6 @@ db_fail:
appdata->db = NULL;
}
-static void
-zero_pinyin_service_init (GApplication *app,
- AppData *appdata)
-{
- appdata->introspection_data = NULL;
- appdata->owner_id = 0;
- appdata->db = NULL;
- config_dbus_service (appdata);
- config_db (appdata);
- appdata->init_done = TRUE;
-}
-
/**
* allow graceful shutdown by Ctrl-C and SIGTERM.
*/
@@ -284,38 +200,32 @@ setup_sigint_sigterm_handler (AppData *appdata)
}
static void
-startup (GApplication* app,
- AppData* appdata)
+on_startup (GApplication* app,
+ AppData* appdata)
{
g_message ("zero-pinyin-service startup()");
+ config_db (appdata);
+ config_dbus_service (appdata);
setup_sigint_sigterm_handler (appdata);
-
- g_assert_false (appdata->init_done);
- zero_pinyin_service_init (app, appdata);
g_application_hold (app);
}
static void
-activate (GApplication *app,
- AppData *appdata)
+on_activate (GApplication *app,
+ AppData *appdata)
{
g_message ("zero-pinyin-service activate()");
- /* as a pure service, activate is a no-op. */
}
static void
-shutdown (GApplication *app,
- AppData *appdata)
+on_shutdown (GApplication *app,
+ AppData *appdata)
{
g_message ("zero-pinyin-service shutdown()");
if (appdata->owner_id > 0) {
g_bus_unown_name (appdata->owner_id);
appdata->owner_id = 0;
}
- if (appdata->introspection_data != NULL) {
- g_dbus_node_info_unref (appdata->introspection_data);
- appdata->introspection_data = NULL;
- }
if (appdata->db != NULL) {
sqlite3_close (appdata->db);
appdata->db = NULL;
@@ -323,12 +233,13 @@ shutdown (GApplication *app,
}
/**
- * provide zero-pinyin-service dbus service.
- * it's a console app based on glib and gio.
+ * provides zero-pinyin-service dbus service.
+ * it's a console app (GApplication) based on glib and gio.
*/
int
main (int argc, char *argv[])
{
+ static AppData appdata = {0};
GApplication *app = NULL;
int status = 0;
@@ -336,11 +247,10 @@ main (int argc, char *argv[])
G_APPLICATION_FLAGS_NONE);
g_assert_nonnull (app);
appdata.app = app;
- appdata.init_done = FALSE;
- g_signal_connect (app, "startup", G_CALLBACK (startup), &appdata);
- g_signal_connect (app, "activate", G_CALLBACK (activate), &appdata);
- g_signal_connect (app, "shutdown", G_CALLBACK (shutdown), &appdata);
+ g_signal_connect (app, "startup", G_CALLBACK (on_startup), &appdata);
+ g_signal_connect (app, "activate", G_CALLBACK (on_activate), &appdata);
+ g_signal_connect (app, "shutdown", G_CALLBACK (on_shutdown), &appdata);
status = g_application_run (G_APPLICATION (app), argc, argv);
g_object_unref (app);
diff --git a/meson.build b/meson.build
index 868ef807ffe57e7bcdbf28dea2886b99d283eac0..417afdf9c66549089afcd14a1a4d4f8ba19c99d9 100644
--- a/meson.build
+++ b/meson.build
@@ -1,6 +1,6 @@
# -*- mode: conf -*-
project('zero-pinyin-service', ['c', 'cpp'],
- version: '0.3.2',
+ version: '0.4.0',
license: 'GPL',
default_options: [
'warning_level=2',
@@ -30,19 +30,34 @@ if get_option('buildtype').startswith('release')
language: ['c', 'cpp'])
endif
+install_data('com.emacsos.zero.ZeroPinyinService1.ZeroPinyinServiceInterface.xml',
+ install_dir: '/usr/share/dbus-1/interfaces/')
+install_data('com.emacsos.zero.ZeroPinyinService1.service',
+ install_dir: '/usr/share/dbus-1/services/')
+
glib = dependency('glib-2.0')
gio = dependency('gio-unix-2.0')
uuid = dependency('uuid')
sqlite3 = dependency('sqlite3')
shared_dep = [glib, gio, uuid, sqlite3]
+gen_inc = include_directories('.')
+
+gdbus_codegen = find_program('gdbus-codegen')
+zero_panel_generated = custom_target('zero-panel-generated',
+ input: 'com.emacsos.zero.ZeroPinyinService1.ZeroPinyinServiceInterface.xml',
+ output: ['zero-pinyin-service-generated.h', 'zero-pinyin-service-generated.c'],
+ command: [gdbus_codegen, '--generate-c-code', 'zero-pinyin-service-generated', '@INPUT@'])
+
src = [
'../PinyinParser.cc',
'../sqlite3_util.c',
'parse-pinyin.cpp',
'zero-pinyin-service.c',
+ zero_panel_generated,
'main.c']
executable('zero-pinyin-service', src,
+ include_directories: gen_inc,
dependencies: shared_dep,
install: true, install_dir: '/home/sylecn/bin/sbin/')
diff --git a/zero-pinyin-service.h b/zero-pinyin-service.h
index 6cb75c3b7788dd6792f57f8722985cd4697a7feb..b8e88c11b519236ff483054e9d38415a82056246 100644
--- a/zero-pinyin-service.h
+++ b/zero-pinyin-service.h
@@ -5,10 +5,11 @@
#include
#include
-#ifdef __cplusplus
-extern "C"
-{
-#endif
+G_BEGIN_DECLS
+
+#define ZERO_PINYIN_WELL_KNOWN_NAME "com.emacsos.zero.ZeroPinyinService1"
+#define ZERO_PINYIN_OBJECT_PATH "/com/emacsos/zero/ZeroPinyinService1"
+#define ZERO_PINYIN_INTERFACE_NAME "com.emacsos.zero.ZeroPinyinService1.ZeroPinyinServiceInterface"
typedef struct {
gint shengmu_i;
@@ -45,8 +46,6 @@ void get_candidates (sqlite3* db,
GVariantBuilder *candidates_builder,
GVariantBuilder *matched_lengths_builder);
-#ifdef __cplusplus
-}
-#endif
+G_END_DECLS
#endif /* _ZERO_PINYIN_SERVICE_H_ */