|
Packit |
3ff832 |
/* -*- mode: C; c-basic-offset: 4; indent-tabs-mode: nil; -*- */
|
|
Packit |
3ff832 |
/* vim:set et sts=4: */
|
|
Packit |
3ff832 |
/* ibus - The Input Bus
|
|
Packit |
3ff832 |
* Copyright (C) 2008-2010 Peng Huang <shawn.p.huang@gmail.com>
|
|
Packit |
3ff832 |
* Copyright (C) 2015-2018 Takao Fujiwara <takao.fujiwara1@gmail.com>
|
|
Packit |
3ff832 |
* Copyright (C) 2008-2018 Red Hat, Inc.
|
|
Packit |
3ff832 |
*
|
|
Packit |
3ff832 |
* This library is free software; you can redistribute it and/or
|
|
Packit |
3ff832 |
* modify it under the terms of the GNU Lesser General Public
|
|
Packit |
3ff832 |
* License as published by the Free Software Foundation; either
|
|
Packit |
3ff832 |
* version 2.1 of the License, or (at your option) any later version.
|
|
Packit |
3ff832 |
*
|
|
Packit |
3ff832 |
* This library is distributed in the hope that it will be useful,
|
|
Packit |
3ff832 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit |
3ff832 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
Packit |
3ff832 |
* Lesser General Public License for more details.
|
|
Packit |
3ff832 |
*
|
|
Packit |
3ff832 |
* You should have received a copy of the GNU Lesser General Public
|
|
Packit |
3ff832 |
* License along with this library; if not, write to the Free Software
|
|
Packit |
3ff832 |
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
|
|
Packit |
3ff832 |
* USA
|
|
Packit |
3ff832 |
*/
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
#include "ibusshare.h"
|
|
Packit |
3ff832 |
#include <glib.h>
|
|
Packit |
3ff832 |
#include <glib/gstdio.h>
|
|
Packit |
3ff832 |
#include <glib-object.h>
|
|
Packit |
3ff832 |
#include <sys/time.h>
|
|
Packit |
3ff832 |
#include <sys/types.h>
|
|
Packit |
3ff832 |
#include <unistd.h>
|
|
Packit |
3ff832 |
#include <stdlib.h>
|
|
Packit |
3ff832 |
#include <stdio.h>
|
|
Packit |
3ff832 |
#include <string.h>
|
|
Packit |
3ff832 |
#include <ibus.h>
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
static gchar *_display = NULL;
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
const gchar *
|
|
Packit |
3ff832 |
ibus_get_local_machine_id (void)
|
|
Packit |
3ff832 |
{
|
|
Packit |
3ff832 |
static gchar *machine_id = NULL;
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
if (machine_id == NULL) {
|
|
Packit |
3ff832 |
GError *error = NULL;
|
|
Packit |
3ff832 |
if (!g_file_get_contents ("/var/lib/dbus/machine-id",
|
|
Packit |
3ff832 |
&machine_id,
|
|
Packit |
3ff832 |
NULL,
|
|
Packit |
3ff832 |
&error) &&
|
|
Packit |
3ff832 |
!g_file_get_contents ("/etc/machine-id",
|
|
Packit |
3ff832 |
&machine_id,
|
|
Packit |
3ff832 |
NULL,
|
|
Packit |
3ff832 |
NULL)) {
|
|
Packit |
3ff832 |
g_warning ("Unable to load /var/lib/dbus/machine-id: %s", error->message);
|
|
Packit |
3ff832 |
machine_id = "machine-id";
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
else {
|
|
Packit |
3ff832 |
g_strstrip (machine_id);
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
if (error != NULL) {
|
|
Packit |
3ff832 |
g_error_free (error);
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
return machine_id;
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
void
|
|
Packit |
3ff832 |
ibus_set_display (const gchar *display)
|
|
Packit |
3ff832 |
{
|
|
Packit |
3ff832 |
if (_display != NULL)
|
|
Packit |
3ff832 |
g_free (_display);
|
|
Packit |
3ff832 |
_display = g_strdup (display);
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
const gchar *
|
|
Packit |
3ff832 |
ibus_get_user_name (void)
|
|
Packit |
3ff832 |
{
|
|
Packit |
3ff832 |
return g_get_user_name ();
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
glong
|
|
Packit |
3ff832 |
ibus_get_daemon_uid (void)
|
|
Packit |
3ff832 |
{
|
|
Packit |
3ff832 |
return getuid ();
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
const gchar *
|
|
Packit |
3ff832 |
ibus_get_session_id (void)
|
|
Packit |
3ff832 |
{
|
|
Packit |
3ff832 |
return g_getenv("IBUS_SESSION_ID");
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
const gchar *
|
|
Packit |
3ff832 |
ibus_get_socket_path (void)
|
|
Packit |
3ff832 |
{
|
|
Packit |
3ff832 |
static gchar *path = NULL;
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
if (path == NULL) {
|
|
Packit |
3ff832 |
gchar *hostname = "unix";
|
|
Packit |
3ff832 |
gchar *display;
|
|
Packit |
3ff832 |
gchar *displaynumber = "0";
|
|
Packit |
3ff832 |
/* gchar *screennumber = "0"; */
|
|
Packit |
3ff832 |
gchar *p;
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
path = g_strdup (g_getenv ("IBUS_ADDRESS_FILE"));
|
|
Packit |
3ff832 |
if (path != NULL) {
|
|
Packit |
3ff832 |
return path;
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
if (_display == NULL) {
|
|
Packit |
3ff832 |
display = g_strdup (g_getenv ("DISPLAY"));
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
else {
|
|
Packit |
3ff832 |
display = g_strdup (_display);
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
if (display) {
|
|
Packit |
3ff832 |
p = display;
|
|
Packit |
3ff832 |
hostname = display;
|
|
Packit |
3ff832 |
for (; *p != ':' && *p != '\0'; p++);
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
if (*p == ':') {
|
|
Packit |
3ff832 |
*p = '\0';
|
|
Packit |
3ff832 |
p++;
|
|
Packit |
3ff832 |
displaynumber = p;
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
for (; *p != '.' && *p != '\0'; p++);
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
if (*p == '.') {
|
|
Packit |
3ff832 |
*p = '\0';
|
|
Packit |
3ff832 |
p++;
|
|
Packit |
3ff832 |
/* Do not use screennumber
|
|
Packit |
3ff832 |
screennumber = p; */
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
if (hostname[0] == '\0')
|
|
Packit |
3ff832 |
hostname = "unix";
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
p = g_strdup_printf ("%s-%s-%s",
|
|
Packit |
3ff832 |
ibus_get_local_machine_id (),
|
|
Packit |
3ff832 |
hostname,
|
|
Packit |
3ff832 |
displaynumber);
|
|
Packit |
3ff832 |
path = g_build_filename (g_get_user_config_dir (),
|
|
Packit |
3ff832 |
"ibus",
|
|
Packit |
3ff832 |
"bus",
|
|
Packit |
3ff832 |
p,
|
|
Packit |
3ff832 |
NULL);
|
|
Packit |
3ff832 |
g_free (p);
|
|
Packit |
3ff832 |
g_free (display);
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
return path;
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
gint
|
|
Packit |
3ff832 |
ibus_get_timeout (void)
|
|
Packit |
3ff832 |
{
|
|
Packit |
3ff832 |
/* 16000 ms is the default timeout on the ibus-daemon side
|
|
Packit |
3ff832 |
* (15 sec) plus 1. */
|
|
Packit |
3ff832 |
static const gint default_timeout = 16000;
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
static gint64 timeout = -2;
|
|
Packit |
3ff832 |
if (timeout == -2) {
|
|
Packit |
3ff832 |
const gchar *timeout_str = g_getenv ("IBUS_TIMEOUT");
|
|
Packit |
3ff832 |
if (timeout_str == NULL) {
|
|
Packit |
3ff832 |
timeout = default_timeout;
|
|
Packit |
3ff832 |
} else {
|
|
Packit |
3ff832 |
timeout = g_ascii_strtoll(timeout_str, NULL, 10);
|
|
Packit |
3ff832 |
if (timeout < -1 || timeout == 0 || timeout > G_MAXINT) {
|
|
Packit |
3ff832 |
timeout = default_timeout;
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
return timeout;
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
const gchar *
|
|
Packit |
3ff832 |
ibus_get_address (void)
|
|
Packit |
3ff832 |
{
|
|
Packit |
3ff832 |
static gchar *address = NULL;
|
|
Packit |
3ff832 |
pid_t pid = -1;
|
|
Packit |
3ff832 |
static gchar buffer[1024];
|
|
Packit |
3ff832 |
FILE *pf;
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
/* free address */
|
|
Packit |
3ff832 |
if (address != NULL) {
|
|
Packit |
3ff832 |
g_free (address);
|
|
Packit |
3ff832 |
address = NULL;
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
/* get address from env variable */
|
|
Packit |
3ff832 |
address = g_strdup (g_getenv ("IBUS_ADDRESS"));
|
|
Packit |
3ff832 |
if (address) {
|
|
Packit |
3ff832 |
return address;
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
/* read address from ~/.config/ibus/bus/soketfile */
|
|
Packit |
3ff832 |
pf = fopen (ibus_get_socket_path (), "r");
|
|
Packit |
3ff832 |
if (pf == NULL) {
|
|
Packit |
3ff832 |
return NULL;
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
while (!feof (pf)) {
|
|
Packit |
3ff832 |
gchar *p = buffer;
|
|
Packit |
3ff832 |
if (fgets (buffer, sizeof (buffer), pf) == NULL)
|
|
Packit |
3ff832 |
break;
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
/* skip comment line */
|
|
Packit |
3ff832 |
if (p[0] == '#')
|
|
Packit |
3ff832 |
continue;
|
|
Packit |
3ff832 |
/* parse IBUS_ADDRESS */
|
|
Packit |
3ff832 |
if (strncmp (p, "IBUS_ADDRESS=", sizeof ("IBUS_ADDRESS=") - 1) == 0) {
|
|
Packit |
3ff832 |
address = p + sizeof ("IBUS_ADDRESS=") - 1;
|
|
Packit |
3ff832 |
for (p = (gchar *)address; *p != '\n' && *p != '\0'; p++);
|
|
Packit |
3ff832 |
if (*p == '\n')
|
|
Packit |
3ff832 |
*p = '\0';
|
|
Packit |
3ff832 |
address = g_strdup (address);
|
|
Packit |
3ff832 |
continue;
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
/* parse IBUS_DAEMON_PID */
|
|
Packit |
3ff832 |
if (strncmp (p, "IBUS_DAEMON_PID=", sizeof ("IBUS_DAEMON_PID=") - 1) == 0) {
|
|
Packit |
3ff832 |
pid = atoi(p + sizeof ("IBUS_DAEMON_PID=") - 1);
|
|
Packit |
3ff832 |
continue;
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
fclose (pf);
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
if (pid == -1 || kill (pid, 0) != 0) {
|
|
Packit |
3ff832 |
return NULL;
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
return address;
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
void
|
|
Packit |
3ff832 |
ibus_write_address (const gchar *address)
|
|
Packit |
3ff832 |
{
|
|
Packit |
3ff832 |
FILE *pf;
|
|
Packit |
3ff832 |
gchar *path;
|
|
Packit |
3ff832 |
g_return_if_fail (address != NULL);
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
path = g_path_get_dirname (ibus_get_socket_path ());
|
|
Packit |
3ff832 |
g_mkdir_with_parents (path, 0700);
|
|
Packit |
3ff832 |
g_free (path);
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
g_unlink (ibus_get_socket_path ());
|
|
Packit |
3ff832 |
pf = fopen (ibus_get_socket_path (), "w");
|
|
Packit |
3ff832 |
g_return_if_fail (pf != NULL);
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
fprintf (pf,
|
|
Packit |
3ff832 |
"# This file is created by ibus-daemon, please do not modify it\n"
|
|
Packit |
3ff832 |
"IBUS_ADDRESS=%s\n"
|
|
Packit |
3ff832 |
"IBUS_DAEMON_PID=%ld\n",
|
|
Packit |
3ff832 |
address, (glong) getpid ());
|
|
Packit |
3ff832 |
fclose (pf);
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
void
|
|
Packit |
3ff832 |
ibus_free_strv (gchar **strv)
|
|
Packit |
3ff832 |
{
|
|
Packit |
3ff832 |
gchar **p;
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
if (strv == NULL)
|
|
Packit |
3ff832 |
return;
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
for (p = strv; *p != NULL; p++) {
|
|
Packit |
3ff832 |
g_free (*p);
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
g_free (strv);
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
void
|
|
Packit |
3ff832 |
ibus_init (void)
|
|
Packit |
3ff832 |
{
|
|
Packit |
3ff832 |
#if !GLIB_CHECK_VERSION(2,35,0)
|
|
Packit |
3ff832 |
g_type_init ();
|
|
Packit |
3ff832 |
#endif
|
|
Packit |
3ff832 |
IBUS_ERROR;
|
|
Packit |
3ff832 |
IBUS_TYPE_TEXT;
|
|
Packit |
3ff832 |
IBUS_TYPE_ATTRIBUTE;
|
|
Packit |
3ff832 |
IBUS_TYPE_ATTR_LIST;
|
|
Packit |
3ff832 |
IBUS_TYPE_LOOKUP_TABLE;
|
|
Packit |
3ff832 |
IBUS_TYPE_COMPONENT;
|
|
Packit |
3ff832 |
IBUS_TYPE_ENGINE_DESC;
|
|
Packit |
3ff832 |
IBUS_TYPE_OBSERVED_PATH;
|
|
Packit |
3ff832 |
IBUS_TYPE_REGISTRY;
|
|
Packit |
3ff832 |
IBUS_TYPE_X_EVENT;
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
static GMainLoop *main_loop = NULL;
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
void
|
|
Packit |
3ff832 |
ibus_main (void)
|
|
Packit |
3ff832 |
{
|
|
Packit |
3ff832 |
main_loop = g_main_loop_new (NULL, FALSE);
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
g_main_loop_run (main_loop);
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
g_main_loop_unref (main_loop);
|
|
Packit |
3ff832 |
main_loop = NULL;
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
void
|
|
Packit |
3ff832 |
ibus_quit (void)
|
|
Packit |
3ff832 |
{
|
|
Packit |
3ff832 |
if (main_loop) {
|
|
Packit |
3ff832 |
g_main_loop_quit (main_loop);
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
static gboolean ibus_log_handler_is_verbose = FALSE;
|
|
Packit |
3ff832 |
static guint ibus_log_handler_id = 0;
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
static void
|
|
Packit |
3ff832 |
ibus_log_handler (const gchar *log_domain,
|
|
Packit |
3ff832 |
GLogLevelFlags log_level,
|
|
Packit |
3ff832 |
const gchar *message,
|
|
Packit |
3ff832 |
gpointer user_data)
|
|
Packit |
3ff832 |
{
|
|
Packit |
3ff832 |
// In the quiet mode (i.e. not verbose), we'll ignore DEBUG and
|
|
Packit |
3ff832 |
// WARNING messages.
|
|
Packit |
3ff832 |
if (!ibus_log_handler_is_verbose &&
|
|
Packit |
3ff832 |
((log_level & G_LOG_LEVEL_DEBUG) ||
|
|
Packit |
3ff832 |
(log_level & G_LOG_LEVEL_WARNING))) {
|
|
Packit |
3ff832 |
return;
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
// Add timing info like "17:34:57.680038" (hour, min, sec, microsecond).
|
|
Packit |
3ff832 |
struct timeval time_val;
|
|
Packit |
3ff832 |
gettimeofday (&time_val, NULL);
|
|
Packit |
3ff832 |
struct tm local_time;
|
|
Packit |
3ff832 |
localtime_r (&time_val.tv_sec, &local_time);
|
|
Packit |
3ff832 |
char* new_message =
|
|
Packit |
3ff832 |
g_strdup_printf ("%02d:%02d:%02d.%6d: %s",
|
|
Packit |
3ff832 |
local_time.tm_hour,
|
|
Packit |
3ff832 |
local_time.tm_min,
|
|
Packit |
3ff832 |
local_time.tm_sec,
|
|
Packit |
3ff832 |
(int)time_val.tv_usec,
|
|
Packit |
3ff832 |
message);
|
|
Packit |
3ff832 |
g_log_default_handler (log_domain, log_level, new_message, user_data);
|
|
Packit |
3ff832 |
g_free (new_message);
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
void
|
|
Packit |
3ff832 |
ibus_set_log_handler (gboolean verbose)
|
|
Packit |
3ff832 |
{
|
|
Packit |
3ff832 |
if (ibus_log_handler_id != 0) {
|
|
Packit |
3ff832 |
g_log_remove_handler (G_LOG_DOMAIN, ibus_log_handler_id);
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
ibus_log_handler_is_verbose = verbose;
|
|
Packit |
3ff832 |
ibus_log_handler_id = g_log_set_handler (G_LOG_DOMAIN,
|
|
Packit |
3ff832 |
G_LOG_LEVEL_MASK,
|
|
Packit |
3ff832 |
ibus_log_handler,
|
|
Packit |
3ff832 |
NULL);
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
|
|
Packit |
3ff832 |
void
|
|
Packit |
3ff832 |
ibus_unset_log_handler (void)
|
|
Packit |
3ff832 |
{
|
|
Packit |
3ff832 |
if (ibus_log_handler_id != 0) {
|
|
Packit |
3ff832 |
g_log_remove_handler (G_LOG_DOMAIN, ibus_log_handler_id);
|
|
Packit |
3ff832 |
ibus_log_handler_id = 0;
|
|
Packit |
3ff832 |
}
|
|
Packit |
3ff832 |
}
|