Remove g_type_init() calls.
[platform/upstream/ibus.git] / src / ibusshare.c
1 /* -*- mode: C; c-basic-offset: 4; indent-tabs-mode: nil; -*- */
2 /* vim:set et sts=4: */
3 /* ibus - The Input Bus
4  * Copyright (C) 2008-2010 Peng Huang <shawn.p.huang@gmail.com>
5  * Copyright (C) 2008-2010 Red Hat, Inc.
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, write to the
19  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20  * Boston, MA 02111-1307, USA.
21  */
22
23 #include "ibusshare.h"
24 #include <glib.h>
25 #include <glib/gstdio.h>
26 #include <glib-object.h>
27 #include <sys/time.h>
28 #include <sys/types.h>
29 #include <unistd.h>
30 #include <stdlib.h>
31 #include <stdio.h>
32 #include <string.h>
33 #include <ibus.h>
34
35 static gchar *_display = NULL;
36
37 const gchar *
38 ibus_get_local_machine_id (void)
39 {
40     static gchar *machine_id = NULL;
41
42     if (machine_id == NULL) {
43         GError *error = NULL;
44         if (!g_file_get_contents ("/var/lib/dbus/machine-id",
45                                   &machine_id,
46                                   NULL,
47                                   &error) &&
48             !g_file_get_contents ("/etc/machine-id",
49                                   &machine_id,
50                                   NULL,
51                                   NULL)) {
52             g_warning ("Unable to load /var/lib/dbus/machine-id: %s", error->message);
53             g_error_free (error);
54             machine_id = "machine-id";
55         }
56         else {
57             g_strstrip (machine_id);
58         }
59     }
60
61     return machine_id;
62 }
63
64 void
65 ibus_set_display (const gchar *display)
66 {
67     if (_display != NULL)
68         g_free (_display);
69     _display = g_strdup (display);
70 }
71
72 const gchar *
73 ibus_get_user_name (void)
74 {
75     return g_get_user_name ();
76 }
77
78 glong
79 ibus_get_daemon_uid (void)
80 {
81     return getuid ();
82 }
83
84 const gchar *
85 ibus_get_session_id (void)
86 {
87     return g_getenv("IBUS_SESSION_ID");
88 }
89
90 const gchar *
91 ibus_get_socket_path (void)
92 {
93     static gchar *path = NULL;
94
95     if (path == NULL) {
96         gchar *hostname = "unix";
97         gchar *display;
98         gchar *displaynumber = "0";
99         /* gchar *screennumber = "0"; */
100         gchar *p;
101
102         path = g_strdup (g_getenv ("IBUS_ADDRESS_FILE"));
103         if (path != NULL) {
104             return path;
105         }
106
107         if (_display == NULL) {
108             display = g_strdup (g_getenv ("DISPLAY"));
109         }
110         else {
111             display = g_strdup (_display);
112         }
113
114         if (display == NULL) {
115             g_warning ("DISPLAY is empty! We use default DISPLAY (:0.0)");
116         }
117         else {
118             p = display;
119             hostname = display;
120             for (; *p != ':' && *p != '\0'; p++);
121
122             if (*p == ':') {
123                 *p = '\0';
124                 p++;
125                 displaynumber = p;
126             }
127
128             for (; *p != '.' && *p != '\0'; p++);
129
130             if (*p == '.') {
131                 *p = '\0';
132                 p++;
133                 /* Do not use screennumber
134                  screennumber = p; */
135             }
136         }
137
138         if (hostname[0] == '\0')
139             hostname = "unix";
140
141         p = g_strdup_printf ("%s-%s-%s",
142                              ibus_get_local_machine_id (),
143                              hostname,
144                              displaynumber);
145         path = g_build_filename (g_get_user_config_dir (),
146                                  "ibus",
147                                  "bus",
148                                  p,
149                                  NULL);
150         g_free (p);
151         g_free (display);
152     }
153     return path;
154 }
155
156 gint
157 ibus_get_timeout (void)
158 {
159     /* 6000 ms is the default timeout on the ibus-daemon side (5 sec) plus 1. */
160     static const gint default_timeout = 6000;
161
162     static gint64 timeout = -2;
163     if (timeout == -2) {
164         const gchar *timeout_str = g_getenv ("IBUS_TIMEOUT");
165         if (timeout_str == NULL) {
166             timeout = default_timeout;
167         } else {
168             timeout = g_ascii_strtoll(timeout_str, NULL, 10);
169             if (timeout < -1 || timeout == 0 || timeout > G_MAXINT) {
170                 timeout = default_timeout;
171             }
172         }
173     }
174     return timeout;
175 }
176
177 const gchar *
178 ibus_get_address (void)
179 {
180     static gchar *address = NULL;
181     pid_t pid = -1;
182     static gchar buffer[1024];
183     FILE *pf;
184
185     /* free address */
186     if (address != NULL) {
187         g_free (address);
188         address = NULL;
189     }
190
191     /* get address from env variable */
192     address = g_strdup (g_getenv ("IBUS_ADDRESS"));
193     if (address) {
194         return address;
195     }
196
197     /* read address from ~/.config/ibus/bus/soketfile */
198     pf = fopen (ibus_get_socket_path (), "r");
199     if (pf == NULL) {
200         return NULL;
201     }
202
203     while (!feof (pf)) {
204         gchar *p = buffer;
205         if (fgets (buffer, sizeof (buffer), pf) == NULL)
206             break;
207
208         /* skip comment line */
209         if (p[0] == '#')
210             continue;
211         /* parse IBUS_ADDRESS */
212         if (strncmp (p, "IBUS_ADDRESS=", sizeof ("IBUS_ADDRESS=") - 1) == 0) {
213             address = p + sizeof ("IBUS_ADDRESS=") - 1;
214             for (p = (gchar *)address; *p != '\n' && *p != '\0'; p++);
215             if (*p == '\n')
216                 *p = '\0';
217             address = g_strdup (address);
218             continue;
219         }
220
221         /* parse IBUS_DAEMON_PID */
222         if (strncmp (p, "IBUS_DAEMON_PID=", sizeof ("IBUS_DAEMON_PID=") - 1) == 0) {
223             pid = atoi(p + sizeof ("IBUS_DAEMON_PID=") - 1);
224             continue;
225         }
226
227     }
228     fclose (pf);
229
230     if (pid == -1 || kill (pid, 0) != 0) {
231         return NULL;
232     }
233
234     return address;
235 }
236
237 void
238 ibus_write_address (const gchar *address)
239 {
240     FILE *pf;
241     gchar *path;
242     g_return_if_fail (address != NULL);
243
244     path = g_path_get_dirname (ibus_get_socket_path ());
245     g_mkdir_with_parents (path, 0700);
246     g_free (path);
247
248     g_unlink (ibus_get_socket_path ());
249     pf = fopen (ibus_get_socket_path (), "w");
250     g_return_if_fail (pf != NULL);
251
252     fprintf (pf,
253         "# This file is created by ibus-daemon, please do not modify it\n"
254         "IBUS_ADDRESS=%s\n"
255         "IBUS_DAEMON_PID=%ld\n",
256         address, (glong) getpid ());
257     fclose (pf);
258 }
259
260 void
261 ibus_free_strv (gchar **strv)
262 {
263     gchar **p;
264
265     if (strv == NULL)
266         return;
267
268     for (p = strv; *p != NULL; p++) {
269         g_free (*p);
270     }
271
272     g_free (strv);
273 }
274
275 void
276 ibus_init (void)
277 {
278 #if !GLIB_CHECK_VERSION(2,35,0)
279     g_type_init ();
280 #endif
281     IBUS_ERROR;
282     IBUS_TYPE_TEXT;
283     IBUS_TYPE_ATTRIBUTE;
284     IBUS_TYPE_ATTR_LIST;
285     IBUS_TYPE_LOOKUP_TABLE;
286     IBUS_TYPE_COMPONENT;
287     IBUS_TYPE_ENGINE_DESC;
288 }
289
290 static GMainLoop *main_loop = NULL;
291
292 void
293 ibus_main (void)
294 {
295     main_loop = g_main_loop_new (NULL, FALSE);
296
297     g_main_loop_run (main_loop);
298
299     g_main_loop_unref (main_loop);
300     main_loop = NULL;
301 }
302
303 void
304 ibus_quit (void)
305 {
306     if (main_loop) {
307         g_main_loop_quit (main_loop);
308     }
309 }
310
311 static gboolean ibus_log_handler_is_verbose = FALSE;
312 static guint ibus_log_handler_id = 0;
313
314 static void
315 ibus_log_handler (const gchar    *log_domain,
316                   GLogLevelFlags  log_level,
317                   const gchar    *message,
318                   gpointer        user_data)
319 {
320     // In the quiet mode (i.e. not verbose), we'll ignore DEBUG and
321     // WARNING messages.
322     if (!ibus_log_handler_is_verbose &&
323         ((log_level & G_LOG_LEVEL_DEBUG) ||
324          (log_level & G_LOG_LEVEL_WARNING))) {
325         return;
326     }
327     // Add timing info like "17:34:57.680038" (hour, min, sec, microsecond).
328     struct timeval time_val;
329     gettimeofday (&time_val, NULL);
330     struct tm local_time;
331     localtime_r (&time_val.tv_sec, &local_time);
332     char* new_message =
333         g_strdup_printf ("%02d:%02d:%02d.%6d: %s",
334                          local_time.tm_hour,
335                          local_time.tm_min,
336                          local_time.tm_sec,
337                          (int)time_val.tv_usec,
338                          message);
339     g_log_default_handler (log_domain, log_level, new_message, user_data);
340     g_free (new_message);
341 }
342
343 void
344 ibus_set_log_handler (gboolean verbose)
345 {
346     if (ibus_log_handler_id != 0) {
347         g_log_remove_handler (G_LOG_DOMAIN, ibus_log_handler_id);
348     }
349
350     ibus_log_handler_is_verbose = verbose;
351     ibus_log_handler_id = g_log_set_handler (G_LOG_DOMAIN,
352                                              G_LOG_LEVEL_MASK,
353                                              ibus_log_handler,
354                                              NULL);
355 }
356
357 void
358 ibus_unset_log_handler (void)
359 {
360     if (ibus_log_handler_id != 0) {
361         g_log_remove_handler (G_LOG_DOMAIN, ibus_log_handler_id);
362         ibus_log_handler_id = 0;
363     }
364 }