client-main.c 8.08 KB
Newer Older
Daiki Ueno's avatar
Daiki Ueno committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
/* 
 * Copyright (C) 2010-2011 Daiki Ueno <ueno@unixuser.org>
 * Copyright (C) 2010-2011 Red Hat, Inc.
 * 
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif  /* HAVE_CONFIG_H */

22
#include <stdlib.h>
23
24
#include <cspi/spi.h>
#include <gtk/gtk.h>
Daiki Ueno's avatar
Daiki Ueno committed
25
#include <glib/gi18n.h>
26
#include <gconf/gconf-client.h>
27
#include "eekboard/eekboard.h"
28
#include "client.h"
Daiki Ueno's avatar
Daiki Ueno committed
29

30
31
32
33
static gboolean opt_system = FALSE;
static gboolean opt_session = FALSE;
static gchar *opt_address = NULL;

34
35
36
37
38
#ifdef HAVE_CSPI
static gboolean opt_focus = FALSE;
static gboolean opt_keystroke = FALSE;
#endif  /* HAVE_CSPI */

Daiki Ueno's avatar
Daiki Ueno committed
39
40
static gchar *opt_keyboard = NULL;

41
42
43
44
45
static gchar *opt_model = NULL;
static gchar *opt_layouts = NULL;
static gchar *opt_options = NULL;

static gboolean opt_fullscreen = FALSE;
Daiki Ueno's avatar
Daiki Ueno committed
46
47

static const GOptionEntry options[] = {
48
49
50
51
52
53
    {"system", 'y', 0, G_OPTION_ARG_NONE, &opt_system,
     N_("Connect to the system bus")},
    {"session", 'e', 0, G_OPTION_ARG_NONE, &opt_session,
     N_("Connect to the session bus")},
    {"address", 'a', 0, G_OPTION_ARG_STRING, &opt_address,
     N_("Connect to the given D-Bus address")},
54
55
56
57
58
59
#ifdef HAVE_CSPI
    {"listen-focus", 'f', 0, G_OPTION_ARG_NONE, &opt_focus,
     N_("Listen focus change events with AT-SPI")},
    {"listen-keystroke", 's', 0, G_OPTION_ARG_NONE, &opt_keystroke,
     N_("Listen keystroke events with AT-SPI")},
#endif  /* HAVE_CSPI */
Daiki Ueno's avatar
Daiki Ueno committed
60
61
    {"keyboard", 'k', 0, G_OPTION_ARG_STRING, &opt_keyboard,
     N_("Specify keyboard file")},
62
63
64
65
66
67
68
69
    {"model", '\0', 0, G_OPTION_ARG_STRING, &opt_model,
     N_("Specify model")},
    {"layouts", '\0', 0, G_OPTION_ARG_STRING, &opt_layouts,
     N_("Specify layouts")},
    {"options", '\0', 0, G_OPTION_ARG_STRING, &opt_options,
     N_("Specify options")},
    {"fullscreen", 'F', 0, G_OPTION_ARG_NONE, &opt_fullscreen,
     N_("Create window in fullscreen mode")},
Daiki Ueno's avatar
Daiki Ueno committed
70
71
72
73
    {NULL}
};

static void
74
75
76
on_notify_keyboard_visible (GObject    *object,
                            GParamSpec *spec,
                            gpointer    user_data)
Daiki Ueno's avatar
Daiki Ueno committed
77
{
78
79
80
81
82
83
84
85
    GMainLoop *loop = user_data;
    gboolean visible;

    g_object_get (object, "keyboard-visible", &visible, NULL);

    /* user explicitly closed the window */
    if (!visible && eekboard_context_is_enabled (EEKBOARD_CONTEXT(object)))
        g_main_loop_quit (loop);
Daiki Ueno's avatar
Daiki Ueno committed
86
87
88
}

static void
89
90
on_context_destroyed (EekboardContext *context,
                      gpointer         user_data)
Daiki Ueno's avatar
Daiki Ueno committed
91
{
92
93
94
95
96
97
98
99
100
101
102
103
    GMainLoop *loop = user_data;

    g_main_loop_quit (loop);
}

static void
on_destroyed (EekboardEekboard *eekboard,
              gpointer          user_data)
{
    GMainLoop *loop = user_data;

    g_main_loop_quit (loop);
Daiki Ueno's avatar
Daiki Ueno committed
104
105
106
107
108
}

int
main (int argc, char **argv)
{
109
110
111
    EekboardClient *client;
    EekboardEekboard *eekboard;
    EekboardContext *context;
112
    GBusType bus_type;
113
    GDBusConnection *connection;
Daiki Ueno's avatar
Daiki Ueno committed
114
    GError *error;
115
    GConfClient *gconfc;
116
    GOptionContext *option_context;
117
    GMainLoop *loop;
Daiki Ueno's avatar
Daiki Ueno committed
118

119
120
121
122
    if (!gtk_init_check (&argc, &argv)) {
        g_printerr ("Can't init GTK\n");
        exit (1);
    }
Daiki Ueno's avatar
Daiki Ueno committed
123

124
    option_context = g_option_context_new ("eekboard-desktop-client");
125
126
127
    g_option_context_add_main_entries (option_context, options, NULL);
    g_option_context_parse (option_context, &argc, &argv, NULL);
    g_option_context_free (option_context);
Daiki Ueno's avatar
Daiki Ueno committed
128

129
130
131
132
133
134
135
136
137
138
139
140
141
    if (opt_system)
        bus_type = G_BUS_TYPE_SYSTEM;
    else if (opt_address)
        bus_type = G_BUS_TYPE_NONE;
    else
        bus_type = G_BUS_TYPE_SESSION;

    switch (bus_type) {
    case G_BUS_TYPE_SYSTEM:
    case G_BUS_TYPE_SESSION:
        error = NULL;
        connection = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &error);
        if (connection == NULL) {
Daiki Ueno's avatar
Daiki Ueno committed
142
            g_printerr ("Can't connect to the bus: %s\n", error->message);
143
144
145
146
147
148
149
150
151
152
153
            exit (1);
        }
        break;
    case G_BUS_TYPE_NONE:
        error = NULL;
        connection = g_dbus_connection_new_for_address_sync (opt_address,
                                                             0,
                                                             NULL,
                                                             NULL,
                                                             &error);
        if (connection == NULL) {
Daiki Ueno's avatar
Daiki Ueno committed
154
            g_printerr ("Can't connect to the bus at %s: %s\n",
155
156
157
158
159
160
161
162
                        opt_address,
                        error->message);
            exit (1);
        }
        break;
    default:
        g_assert_not_reached ();
        break;
Daiki Ueno's avatar
Daiki Ueno committed
163
164
    }

165
166
167
168
    client = eekboard_client_new (connection);
    if (client == NULL) {
        g_printerr ("Can't create a client\n");
        exit (1);
169
170
    }

171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
    gconfc = gconf_client_get_default ();

#ifdef HAVE_CSPI
    error = NULL;
    if (opt_focus || opt_keystroke) {
        if (gconf_client_get_bool (gconfc,
                                   "/desktop/gnome/interface/accessibility",
                                   &error) ||
            gconf_client_get_bool (gconfc,
                                   "/desktop/gnome/interface/accessibility2",
                                   &error)) {
            if (SPI_init () != 0) {
                g_printerr ("Can't init CSPI\n");
                exit (1);
            }

            if (opt_focus &&
                !eekboard_client_enable_cspi_focus (client)) {
                g_printerr ("Can't register focus change event listeners\n");
                exit (1);
            }

            if (opt_keystroke &&
                !eekboard_client_enable_cspi_keystroke (client)) {
                g_printerr ("Can't register keystroke event listeners\n");
                exit (1);
            }
        } else {
            g_printerr ("Desktop accessibility support is disabled\n");
            exit (1);
Daiki Ueno's avatar
Daiki Ueno committed
201
        }
202
    }
203
204
#endif  /* HAVE_CSPI */

Daiki Ueno's avatar
Daiki Ueno committed
205
206
207
208
209
210
211
212
213
214
215
    if (opt_keyboard && (opt_model || opt_layouts || opt_options)) {
        g_printerr ("Can't use --keyboard option with xklavier options\n");
        exit (1);
    }

    if (opt_keyboard) {
        if (!eekboard_client_load_keyboard_from_file (client, opt_keyboard)) {
            g_printerr ("Can't load keyboard\n");
            exit (1);
        }
    } else if (opt_model || opt_layouts || opt_options) {
216
        if (!eekboard_client_set_xkl_config (client,
Daiki Ueno's avatar
Daiki Ueno committed
217
218
219
                                             opt_model,
                                             opt_layouts,
                                             opt_options)) {
220
221
222
223
224
225
            g_printerr ("Can't set xklavier config\n");
            exit (1);
        }
    } else if (!eekboard_client_enable_xkl (client)) {
        g_printerr ("Can't register xklavier event listeners\n");
        exit (1);
Daiki Ueno's avatar
Daiki Ueno committed
226
227
    }

228
229
230
231
#ifdef HAVE_FAKEKEY
    if (!eekboard_client_enable_fakekey (client)) {
        g_printerr ("Can't init fakekey\n");
        exit (1);
Daiki Ueno's avatar
Daiki Ueno committed
232
    }
233
234
235
236
237
238
239
240
241
242
#endif  /* HAVE_FAKEKEY */

    loop = g_main_loop_new (NULL, FALSE);
    if (!opt_focus) {
        g_object_get (client, "context", &context, NULL);
        g_signal_connect (context, "notify::keyboard-visible",
                          G_CALLBACK(on_notify_keyboard_visible), loop);
        g_signal_connect (context, "destroyed",
                          G_CALLBACK(on_context_destroyed), loop);
        g_object_unref (context);
Daiki Ueno's avatar
Daiki Ueno committed
243
244
    }

245
246
247
248
    if (opt_fullscreen) {
        g_object_get (client, "context", &context, NULL);
        eekboard_context_set_fullscreen (context, TRUE, NULL);
        g_object_unref (context);
Daiki Ueno's avatar
Daiki Ueno committed
249
250
    }

251
252
253
    g_object_get (client, "eekboard", &eekboard, NULL);
    g_signal_connect (eekboard, "destroyed",
                      G_CALLBACK(on_destroyed), loop);
Daiki Ueno's avatar
Daiki Ueno committed
254

255
256
    g_main_loop_run (loop);
    g_main_loop_unref (loop);
Daiki Ueno's avatar
Daiki Ueno committed
257

258
    return 0;
Daiki Ueno's avatar
Daiki Ueno committed
259
}