1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * Copyright (C) 2005 Takuro Ashie
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2, or (at your option)
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 #define Uses_SCIM_HELPER
21 #define Uses_SCIM_CONFIG_BASE
25 #include "scim_anthy_intl.h"
26 #include "scim_anthy_helper.h"
30 #define scim_module_init anthy_imengine_helper_LTX_scim_module_init
31 #define scim_module_exit anthy_imengine_helper_LTX_scim_module_exit
32 #define scim_helper_module_number_of_helpers anthy_imengine_helper_LTX_scim_helper_module_number_of_helpers
33 #define scim_helper_module_get_helper_info anthy_imengine_helper_LTX_scim_helper_module_get_helper_info
34 #define scim_helper_module_run_helper anthy_imengine_helper_LTX_scim_helper_module_run_helper
36 static gboolean helper_agent_input_handler (GIOChannel *source,
37 GIOCondition condition,
39 static void slot_imengine_event (const HelperAgent *agent,
42 const Transaction &trans);
43 static gint timeout_func (gpointer data);
44 static void timeout_ctx_destroy_func (gpointer data);
46 static void run (const String &display,
47 const ConfigPointer &config);
49 HelperAgent helper_agent;
51 HelperInfo helper_info (SCIM_ANTHY_HELPER_UUID, // uuid
55 SCIM_HELPER_NEED_SCREEN_INFO);
57 class TimeoutContext {
59 TimeoutContext (int ic, const String &uuid, uint32 id)
64 virtual ~TimeoutContext () {}
70 typedef std::map <uint32, guint> TimeoutIDList;
71 std::map <int, TimeoutIDList> timeout_ids;
76 void scim_module_init (void)
78 bindtextdomain (GETTEXT_PACKAGE, SCIM_ANTHY_LOCALEDIR);
79 bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
81 helper_info.name = String (_("Anthy helper"));
82 helper_info.description = String (
83 _("A helper module for Anthy IMEngine."));
86 void scim_module_exit (void)
90 unsigned int scim_helper_module_number_of_helpers (void)
95 bool scim_helper_module_get_helper_info (unsigned int idx, HelperInfo &info)
104 void scim_helper_module_run_helper (const String &uuid,
105 const ConfigPointer &config,
106 const String &display)
108 SCIM_DEBUG_MAIN(1) << "anthy_imengine_helper_LTX_scim_helper_module_run_helper ()\n";
110 if (uuid == String (SCIM_ANTHY_HELPER_UUID)) {
111 run (display, config);
114 SCIM_DEBUG_MAIN(1) << "exit anthy_imengine_helper_LTX_scim_helper_module_run_helper ()\n";
120 helper_agent_input_handler (GIOChannel *source,
121 GIOCondition condition,
124 if (condition == G_IO_IN) {
125 HelperAgent *agent = static_cast<HelperAgent*> (user_data);
126 if (agent && agent->has_pending_event ())
127 agent->filter_event ();
128 } else if (condition == G_IO_ERR || condition == G_IO_HUP) {
135 slot_exit (const HelperAgent *agent, int ic, const String &uuid)
141 slot_imengine_event (const HelperAgent *agent, int ic,
142 const String &uuid, const Transaction &recv)
144 TransactionReader reader (recv);
147 if (!reader.get_command (cmd))
151 case SCIM_ANTHY_TRANS_CMD_GET_SELECTION:
153 GtkClipboard *primary_selection;
154 WideString selection;
156 primary_selection = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
157 if (primary_selection) {
158 gchar *text = gtk_clipboard_wait_for_text (primary_selection);
160 selection = utf8_mbstowcs (text);
166 send.put_command (SCIM_ANTHY_TRANS_CMD_GET_SELECTION);
167 send.put_data (selection);
168 helper_agent.send_imengine_event (ic, uuid, send);
172 case SCIM_ANTHY_TRANS_CMD_TIMEOUT_ADD:
174 uint32 id, time_msec;
175 if (!reader.get_data (id) || !reader.get_data (time_msec))
177 TimeoutContext *ctx = new TimeoutContext (ic, uuid, id);
178 guint timeout_id = gtk_timeout_add_full (time_msec,
182 timeout_ctx_destroy_func);
183 timeout_ids[ic][id] = timeout_id;
186 case SCIM_ANTHY_TRANS_CMD_TIMEOUT_REMOVE:
189 if (reader.get_data (id) &&
190 timeout_ids.find (ic) != timeout_ids.end () &&
191 timeout_ids[ic].find (id) != timeout_ids[ic].end ())
193 guint tid = timeout_ids[ic][id];
194 gtk_timeout_remove (tid);
204 timeout_func (gpointer data)
206 TimeoutContext *ctx = static_cast<TimeoutContext*> (data);
209 send.put_command (SCIM_ANTHY_TRANS_CMD_TIMEOUT_NOTIFY);
210 send.put_data (ctx->m_id);
211 helper_agent.send_imengine_event (ctx->m_ic, ctx->m_uuid, send);
217 timeout_ctx_destroy_func (gpointer data)
219 TimeoutContext *ctx = static_cast<TimeoutContext*> (data);
221 uint32 id = ctx->m_id;
223 if (timeout_ids.find (ic) != timeout_ids.end () &&
224 timeout_ids[ic].find (id) != timeout_ids[ic].end ())
226 timeout_ids[ic].erase (id);
232 run (const String &display, const ConfigPointer &config)
234 char **argv = new char * [4];
237 argv [0] = "anthy-imengine-helper";
238 argv [1] = "--display";
239 argv [2] = const_cast<char *> (display.c_str ());
242 setenv ("DISPLAY", display.c_str (), 1);
244 gtk_init (&argc, &argv);
246 helper_agent.signal_connect_exit (slot (slot_exit));
247 helper_agent.signal_connect_process_imengine_event (slot (slot_imengine_event));
250 int fd = helper_agent.open_connection (helper_info, display);
251 GIOChannel *ch = g_io_channel_unix_new (fd);
254 g_io_add_watch (ch, G_IO_IN,
255 helper_agent_input_handler,
256 (gpointer) &helper_agent);
257 g_io_add_watch (ch, G_IO_ERR,
258 helper_agent_input_handler,
259 (gpointer) &helper_agent);
260 g_io_add_watch (ch, G_IO_HUP,
261 helper_agent_input_handler,
262 (gpointer) &helper_agent);
268 helper_agent.close_connection ();