1 /* -*- Mode: C; indent-tabs-mode: nil; c-basic-offset: 2; tab-width: 2 -*- */
2 /*
3  * nimf-nim-ic.c
4  * This file is part of Nimf.
5  *
6  * Copyright (C) 2015-2019 Hodong Kim <cogniti@gmail.com>
7  *
8  * Nimf is free software: you can redistribute it and/or modify it
9  * under the terms of the GNU Lesser General Public License as published
10  * by the Free Software Foundation, either version 3 of the License, or
11  * (at your option) any later version.
12  *
13  * Nimf is distributed in the hope that it will be useful, but
14  * WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
16  * See the GNU Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public License
19  * along with this program;  If not, see <http://www.gnu.org/licenses/>.
20  */
21 
22 #include "nimf-nim-ic.h"
23 #include <string.h>
24 #include "nimf-connection.h"
25 #include "nimf-message-private.h"
26 
27 G_DEFINE_TYPE (NimfNimIC, nimf_nim_ic, NIMF_TYPE_SERVICE_IC);
28 
29 void
nimf_nim_ic_emit_commit(NimfServiceIC * ic,const gchar * text)30 nimf_nim_ic_emit_commit (NimfServiceIC *ic,
31                          const gchar   *text)
32 {
33   g_debug (G_STRLOC ": %s", G_STRFUNC);
34 
35   NimfNimIC *nic = NIMF_NIM_IC (ic);
36 
37   nimf_send_message (nic->connection->socket, nic->icid, NIMF_MESSAGE_COMMIT,
38                      (gchar *) text, strlen (text) + 1, NULL);
39   nimf_result_iteration_until (nic->connection->result, NULL, nic->icid,
40                                NIMF_MESSAGE_COMMIT_REPLY);
41 }
42 
nimf_nim_ic_emit_preedit_start(NimfServiceIC * ic)43 void nimf_nim_ic_emit_preedit_start (NimfServiceIC *ic)
44 {
45   g_debug (G_STRLOC ": %s", G_STRFUNC);
46 
47   NimfNimIC *nic = NIMF_NIM_IC (ic);
48 
49   nimf_send_message (nic->connection->socket, nic->icid,
50                      NIMF_MESSAGE_PREEDIT_START, NULL, 0, NULL);
51   nimf_result_iteration_until (nic->connection->result, NULL, nic->icid,
52                                NIMF_MESSAGE_PREEDIT_START_REPLY);
53 }
54 
55 void
nimf_nim_ic_emit_preedit_changed(NimfServiceIC * ic,const gchar * preedit_string,NimfPreeditAttr ** attrs,gint cursor_pos)56 nimf_nim_ic_emit_preedit_changed (NimfServiceIC    *ic,
57                                   const gchar      *preedit_string,
58                                   NimfPreeditAttr **attrs,
59                                   gint              cursor_pos)
60 {
61   g_debug (G_STRLOC ": %s", G_STRFUNC);
62 
63   NimfNimIC *nic = NIMF_NIM_IC (ic);
64   gchar *data;
65   gsize  data_len;
66   gint   str_len = strlen (preedit_string);
67   gint   n_attr = 0;
68   gint   i;
69 
70   while (attrs[n_attr] != NULL)
71     n_attr++;
72 
73   data_len = str_len + 1 + n_attr * sizeof (NimfPreeditAttr) + sizeof (gint);
74   data = g_strndup (preedit_string, data_len - 1);
75 
76   for (i = 0; attrs[i] != NULL; i++)
77     *(NimfPreeditAttr *)
78       (data + str_len + 1 + i * sizeof (NimfPreeditAttr)) = *attrs[i];
79 
80   *(gint *) (data + data_len - sizeof (gint)) = cursor_pos;
81 
82   nimf_send_message (nic->connection->socket, nic->icid,
83                      NIMF_MESSAGE_PREEDIT_CHANGED, data, data_len, g_free);
84   nimf_result_iteration_until (nic->connection->result, NULL, nic->icid,
85                                NIMF_MESSAGE_PREEDIT_CHANGED_REPLY);
86 }
87 
nimf_nim_ic_emit_preedit_end(NimfServiceIC * ic)88 void nimf_nim_ic_emit_preedit_end (NimfServiceIC *ic)
89 {
90   g_debug (G_STRLOC ": %s", G_STRFUNC);
91 
92   NimfNimIC *nic = NIMF_NIM_IC (ic);
93 
94   nimf_send_message (nic->connection->socket, nic->icid,
95                      NIMF_MESSAGE_PREEDIT_END, NULL, 0, NULL);
96   nimf_result_iteration_until (nic->connection->result, NULL, nic->icid,
97                                NIMF_MESSAGE_PREEDIT_END_REPLY);
98 }
99 
100 gboolean
nimf_nim_ic_emit_retrieve_surrounding(NimfServiceIC * ic)101 nimf_nim_ic_emit_retrieve_surrounding (NimfServiceIC *ic)
102 {
103   g_debug (G_STRLOC ": %s", G_STRFUNC);
104 
105   NimfNimIC *nic = NIMF_NIM_IC (ic);
106 
107   nimf_send_message (nic->connection->socket, nic->icid,
108                      NIMF_MESSAGE_RETRIEVE_SURROUNDING, NULL, 0, NULL);
109   nimf_result_iteration_until (nic->connection->result, NULL, nic->icid,
110                                NIMF_MESSAGE_RETRIEVE_SURROUNDING_REPLY);
111 
112   if (nic->connection->result->reply == NULL)
113     return FALSE;
114 
115   return *(gboolean *) (nic->connection->result->reply->data);
116 }
117 
118 gboolean
nimf_nim_ic_emit_delete_surrounding(NimfServiceIC * ic,gint offset,gint n_chars)119 nimf_nim_ic_emit_delete_surrounding (NimfServiceIC *ic,
120                                      gint           offset,
121                                      gint           n_chars)
122 {
123   g_debug (G_STRLOC ": %s", G_STRFUNC);
124 
125   NimfNimIC *nic = NIMF_NIM_IC (ic);
126 
127   gint *data = g_malloc (2 * sizeof (gint));
128   data[0] = offset;
129   data[1] = n_chars;
130 
131   nimf_send_message (nic->connection->socket, nic->icid,
132                      NIMF_MESSAGE_DELETE_SURROUNDING,
133                      data, 2 * sizeof (gint), g_free);
134   nimf_result_iteration_until (nic->connection->result, NULL, nic->icid,
135                                NIMF_MESSAGE_DELETE_SURROUNDING_REPLY);
136 
137   if (nic->connection->result->reply == NULL)
138     return FALSE;
139 
140   return *(gboolean *) (nic->connection->result->reply->data);
141 }
142 
nimf_nim_ic_emit_beep(NimfServiceIC * ic)143 void nimf_nim_ic_emit_beep (NimfServiceIC *ic)
144 {
145   g_debug (G_STRLOC ": %s", G_STRFUNC);
146 
147   NimfNimIC *nic = NIMF_NIM_IC (ic);
148 
149   nimf_send_message (nic->connection->socket, nic->icid,
150                      NIMF_MESSAGE_BEEP, NULL, 0, NULL);
151   nimf_result_iteration_until (nic->connection->result, NULL, nic->icid,
152                                NIMF_MESSAGE_BEEP_REPLY);
153 }
154 
155 const gchar *
nimf_nim_ic_get_service_id(NimfServiceIC * ic)156 nimf_nim_ic_get_service_id (NimfServiceIC *ic)
157 {
158   g_debug (G_STRLOC ": %s", G_STRFUNC);
159 
160   NimfService *service = NIMF_SERVICE (NIMF_NIM_IC (ic)->connection->nim);
161 
162   return nimf_service_get_id (service);
163 }
164 
165 NimfNimIC *
nimf_nim_ic_new(guint16 icid,NimfConnection * connection)166 nimf_nim_ic_new (guint16         icid,
167                  NimfConnection *connection)
168 {
169   g_debug (G_STRLOC ": %s", G_STRFUNC);
170 
171   NimfNimIC *nic = g_object_new (NIMF_TYPE_NIM_IC, NULL);
172 
173   nic->connection = connection;
174   nic->icid = icid;
175 
176   return nic;
177 }
178 
179 static void
nimf_nim_ic_init(NimfNimIC * nic)180 nimf_nim_ic_init (NimfNimIC *nic)
181 {
182   g_debug (G_STRLOC ": %s", G_STRFUNC);
183 }
184 
185 static void
nimf_nim_ic_finalize(GObject * object)186 nimf_nim_ic_finalize (GObject *object)
187 {
188   g_debug (G_STRLOC ": %s", G_STRFUNC);
189 
190   G_OBJECT_CLASS (nimf_nim_ic_parent_class)->finalize (object);
191 }
192 
193 static void
nimf_nim_ic_class_init(NimfNimICClass * class)194 nimf_nim_ic_class_init (NimfNimICClass *class)
195 {
196   g_debug (G_STRLOC ": %s", G_STRFUNC);
197 
198   GObjectClass       *object_class     = G_OBJECT_CLASS (class);
199   NimfServiceICClass *service_im_class = NIMF_SERVICE_IC_CLASS (class);
200 
201   object_class->finalize = nimf_nim_ic_finalize;
202 
203   service_im_class->emit_commit          = nimf_nim_ic_emit_commit;
204   service_im_class->emit_preedit_start   = nimf_nim_ic_emit_preedit_start;
205   service_im_class->emit_preedit_changed = nimf_nim_ic_emit_preedit_changed;
206   service_im_class->emit_preedit_end     = nimf_nim_ic_emit_preedit_end;
207   service_im_class->emit_retrieve_surrounding = nimf_nim_ic_emit_retrieve_surrounding;
208   service_im_class->emit_delete_surrounding = nimf_nim_ic_emit_delete_surrounding;
209   service_im_class->emit_beep            = nimf_nim_ic_emit_beep;
210   service_im_class->get_service_id       = nimf_nim_ic_get_service_id;
211 }
212