~ubuntu-branches/ubuntu/quantal/libbonobo/quantal-201207170711

« back to all changes in this revision

Viewing changes to bonobo/bonobo-app-client.c

  • Committer: Bazaar Package Importer
  • Author(s): Sebastien Bacher
  • Date: 2005-02-18 14:40:51 UTC
  • mto: (3.1.1 etch) (1.1.25 upstream)
  • mto: This revision was merged to the branch mainline in revision 3.
  • Revision ID: james.westby@ubuntu.com-20050218144051-fo4h9qh2gim8x3wt
Tags: upstream-2.8.1
ImportĀ upstreamĀ versionĀ 2.8.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
  /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
 
2
#include <string.h>
 
3
#include <gobject/gvaluecollector.h>
 
4
#include "bonobo-app-client.h"
 
5
#include "bonobo-exception.h"
 
6
#include "bonobo-types.h"
 
7
 
 
8
 
 
9
static void bonobo_app_client_class_init    (BonoboAppClientClass *klass);
 
10
static void bonobo_app_client_init          (BonoboAppClient      *app_client);
 
11
static void bonobo_app_client_free_msgdescs (BonoboAppClient      *self);
 
12
 
 
13
static gpointer parent_class;
 
14
 
 
15
GType
 
16
bonobo_app_client_get_type (void)
 
17
{
 
18
        static GType app_client_type = 0;
 
19
 
 
20
        if (!app_client_type)
 
21
        {
 
22
                static const GTypeInfo app_client_info =
 
23
                        {
 
24
                                sizeof (BonoboAppClientClass),
 
25
                                NULL,           /* base_init */
 
26
                                NULL,           /* base_finalize */
 
27
                                (GClassInitFunc) bonobo_app_client_class_init,
 
28
                                NULL,           /* class_finalize */
 
29
                                NULL,           /* class_data */
 
30
                                sizeof (BonoboAppClient),
 
31
                                0,              /* n_preallocs */
 
32
                                (GInstanceInitFunc) bonobo_app_client_init,
 
33
                        };
 
34
                
 
35
                app_client_type = g_type_register_static
 
36
                        (G_TYPE_OBJECT, "BonoboAppClient", &app_client_info, 0);
 
37
        }
 
38
 
 
39
        return app_client_type;
 
40
}
 
41
 
 
42
 
 
43
static void
 
44
bonobo_app_client_finalize (GObject *object)
 
45
{
 
46
        BonoboAppClient *self = BONOBO_APP_CLIENT (object);
 
47
 
 
48
        if (self->msgdescs)
 
49
                bonobo_app_client_free_msgdescs (self);
 
50
 
 
51
        if (self->app_server != CORBA_OBJECT_NIL) {
 
52
                bonobo_object_release_unref (self->app_server, NULL);
 
53
                self->app_server = CORBA_OBJECT_NIL;
 
54
        }
 
55
 
 
56
        if (G_OBJECT_CLASS(parent_class)->finalize)
 
57
                G_OBJECT_CLASS(parent_class)->finalize (object);
 
58
}
 
59
 
 
60
 
 
61
static void
 
62
bonobo_app_client_class_init (BonoboAppClientClass *class)
 
63
{
 
64
        GObjectClass *object_class = G_OBJECT_CLASS (class);
 
65
 
 
66
        parent_class = g_type_class_peek_parent (class);
 
67
        object_class->finalize = bonobo_app_client_finalize;
 
68
}
 
69
 
 
70
 
 
71
static void
 
72
bonobo_app_client_init (BonoboAppClient *app_client)
 
73
{
 
74
 
 
75
}
 
76
 
 
77
 
 
78
/**
 
79
 * bonobo_app_client_new:
 
80
 
 
81
 * @app_server: object reference to a Bonobo::Application; this
 
82
 * function takes ownership of this reference (use
 
83
 * bonobo_object_dup_ref() if you want to keep your own reference.)
 
84
 * 
 
85
 * Create an application client object connected to the remote (or
 
86
 * local) Bonobo::Application object.
 
87
 *
 
88
 * <warning>Applications should not use this function. See
 
89
 * bonobo_application_register_unique().</warning>
 
90
 * 
 
91
 * Return value: a #BonoboAppClient object.
 
92
 **/
 
93
BonoboAppClient *
 
94
bonobo_app_client_new (Bonobo_Application app_server)
 
95
{
 
96
        BonoboAppClient *app_client;
 
97
 
 
98
        app_client = g_object_new (BONOBO_TYPE_APP_CLIENT, NULL);
 
99
        app_client->app_server = app_server;
 
100
        return app_client;
 
101
}
 
102
 
 
103
 
 
104
/**
 
105
 * bonobo_app_client_msg_send_argv:
 
106
 * @app_client: client
 
107
 * @message: message name
 
108
 * @argv: %NULL-terminated vector of pointers to GValue, the arguments
 
109
 * to pass with the message.
 
110
 * 
 
111
 * Like bonobo_app_client_msg_send(), except that it receives a single
 
112
 * argument vector instead of a variable number of arguments.
 
113
 * 
 
114
 * Return value: the message return value
 
115
 **/
 
116
GValue *
 
117
bonobo_app_client_msg_send_argv (BonoboAppClient   *app_client,
 
118
                                 const char        *message,
 
119
                                 const GValue      *argv[],
 
120
                                 CORBA_Environment *opt_env)
 
121
{
 
122
        CORBA_any                  *ret;
 
123
        Bonobo_Application_ArgList *args;
 
124
        GValue                     *rv;
 
125
        CORBA_Environment           ev1, *ev;
 
126
        int                         i, argv_len;
 
127
 
 
128
        g_return_val_if_fail (app_client, NULL);
 
129
        g_return_val_if_fail (BONOBO_IS_APP_CLIENT (app_client), NULL);
 
130
 
 
131
        for (argv_len = -1; argv[++argv_len];);
 
132
 
 
133
        args = Bonobo_Application_ArgList__alloc ();
 
134
        args->_length = argv_len;
 
135
        args->_buffer = Bonobo_Application_ArgList_allocbuf (argv_len);
 
136
        for (i = 0; i < argv_len; ++i) {
 
137
                if (!bonobo_arg_from_gvalue_alloc (&args->_buffer[i], argv[i])) {
 
138
                        g_warning ("Failed to convert type '%s' to CORBA::any",
 
139
                                   g_type_name (G_VALUE_TYPE (argv[i])));
 
140
                        args->_buffer[i]._type = TC_void;
 
141
                }
 
142
        }
 
143
        CORBA_sequence_set_release (args, CORBA_TRUE);
 
144
 
 
145
        if (opt_env)
 
146
                ev = opt_env;
 
147
        else {
 
148
                CORBA_exception_init (&ev1);
 
149
                ev = &ev1;
 
150
        }
 
151
        ret = Bonobo_Application_message (app_client->app_server, message, args, ev);
 
152
        CORBA_free (args);
 
153
        if (ev->_major != CORBA_NO_EXCEPTION) {
 
154
                if (!opt_env) {
 
155
                        g_warning ("error while sending message to application server: %s",
 
156
                                   bonobo_exception_get_text (ev));
 
157
                        CORBA_exception_free (&ev1);
 
158
                }
 
159
                return NULL;
 
160
        }
 
161
        if (!opt_env)
 
162
                CORBA_exception_free (&ev1);
 
163
        
 
164
        if (ret->_type != TC_void) {
 
165
                rv = g_new0 (GValue, 1);
 
166
                bonobo_arg_to_gvalue_alloc (ret, rv);
 
167
        } else
 
168
                rv = NULL;
 
169
        CORBA_free (ret);
 
170
        return rv;
 
171
}
 
172
 
 
173
 
 
174
/**
 
175
 * bonobo_app_client_msg_send_valist:
 
176
 * @app_client: client
 
177
 * @message: message name
 
178
 * @opt_env: optional corba environment
 
179
 * @first_arg_type: first message parameter
 
180
 * @var_args: remaining parameters
 
181
 * 
 
182
 * See bonobo_app_client_msg_send().
 
183
 * 
 
184
 * Return value: return value
 
185
 **/
 
186
GValue *
 
187
bonobo_app_client_msg_send_valist (BonoboAppClient   *app_client,
 
188
                                   const char        *message,
 
189
                                   CORBA_Environment *opt_env,
 
190
                                   GType              first_arg_type,
 
191
                                   va_list            var_args)
 
192
{
 
193
        GValue                     *value, *rv;
 
194
        GPtrArray                  *argv;
 
195
        GType                       type;
 
196
        gchar                      *err;
 
197
        int                         i;
 
198
        gboolean                    first_arg = TRUE;
 
199
 
 
200
        g_return_val_if_fail (app_client, NULL);
 
201
        g_return_val_if_fail (BONOBO_IS_APP_CLIENT (app_client), NULL);
 
202
 
 
203
        argv = g_ptr_array_new ();
 
204
        while ((type = (first_arg? first_arg_type :
 
205
                        va_arg (var_args, GType))) != G_TYPE_NONE)
 
206
        {
 
207
                first_arg = FALSE;
 
208
                value = g_new0 (GValue, 1);
 
209
                g_value_init (value, type);
 
210
                G_VALUE_COLLECT(value, var_args, 0, &err);
 
211
                if (err) g_error("error collecting value: %s", err);
 
212
                g_ptr_array_add (argv, value);
 
213
        }
 
214
        g_ptr_array_add (argv, NULL);
 
215
 
 
216
        rv = bonobo_app_client_msg_send_argv (app_client, message,
 
217
                                              (const GValue **) argv->pdata,
 
218
                                              opt_env);
 
219
 
 
220
        for (i = 0; i < argv->len - 1; ++i) {
 
221
                value = g_ptr_array_index (argv, i);
 
222
                g_value_unset (value);
 
223
                g_free (value);
 
224
        }
 
225
        g_ptr_array_free (argv, TRUE);
 
226
 
 
227
        return rv;
 
228
}
 
229
 
 
230
/**
 
231
 * bonobo_app_client_msg_send:
 
232
 * @app_client: the client interface associated with the application
 
233
 * to which we wish to send a message
 
234
 * @message: message name
 
235
 * @...: arguments
 
236
 * 
 
237
 * Send a message to the application server. Takes a variable length
 
238
 * argument list of GType, value pairs, terminated with
 
239
 * %G_TYPE_NONE. Values are direct C values, not GValues! Example:
 
240
 * <informalexample><programlisting>
 
241
 * GValue *retval;
 
242
 * retval = bonobo_app_client_msg_send (app_client, "openURL",
 
243
 *                                      G_TYPE_STRING, "http://www.gnome.org",
 
244
 *                                      G_TYPE_BOOLEAN, TRUE,
 
245
 *                                      G_TYPE_NONE);
 
246
 * </programlisting></informalexample>
 
247
 * 
 
248
 * Return value: a GValue containing the value returned from the
 
249
 * aplication server.
 
250
 **/
 
251
GValue *
 
252
bonobo_app_client_msg_send (BonoboAppClient   *app_client,
 
253
                            const char        *message,
 
254
                            CORBA_Environment *opt_env,
 
255
                            GType              first_arg_type,
 
256
                            ...)
 
257
{
 
258
        GValue  *rv;
 
259
        va_list  var_args;
 
260
        
 
261
        va_start (var_args, first_arg_type);
 
262
        rv = bonobo_app_client_msg_send_valist (app_client, message, opt_env,
 
263
                                                first_arg_type, var_args);
 
264
        va_end (var_args);
 
265
        return rv;
 
266
}
 
267
 
 
268
 
 
269
static __inline__ GType
 
270
_typecode_to_gtype (CORBA_TypeCode tc)
 
271
{
 
272
        static GHashTable *hash = NULL;
 
273
 
 
274
        if (!hash) {
 
275
                hash = g_hash_table_new (g_direct_hash, g_direct_equal);
 
276
#define mapping(gtype, corba_type)\
 
277
                g_hash_table_insert (hash, corba_type, GUINT_TO_POINTER (gtype));
 
278
                
 
279
                mapping (G_TYPE_NONE,    TC_void);
 
280
                mapping (G_TYPE_BOOLEAN, TC_CORBA_boolean);
 
281
                mapping (G_TYPE_LONG,    TC_CORBA_long);
 
282
                mapping (G_TYPE_ULONG,   TC_CORBA_unsigned_long);
 
283
                mapping (G_TYPE_FLOAT,   TC_CORBA_float);
 
284
                mapping (G_TYPE_DOUBLE,  TC_CORBA_double);
 
285
                mapping (G_TYPE_STRING,  TC_CORBA_string);
 
286
 
 
287
                mapping (BONOBO_TYPE_CORBA_ANY,  TC_CORBA_any);
 
288
#undef mapping
 
289
        }
 
290
        return GPOINTER_TO_UINT (g_hash_table_lookup (hash, tc));
 
291
}
 
292
 
 
293
static void
 
294
bonobo_app_client_free_msgdescs (BonoboAppClient *self)
 
295
{
 
296
        int i;
 
297
        
 
298
        for (i = 0; self->msgdescs[i].name; ++i) {
 
299
                g_free (self->msgdescs[i].name);
 
300
                g_free (self->msgdescs[i].types);
 
301
        }
 
302
        g_free (self->msgdescs);
 
303
        self->msgdescs = NULL;
 
304
}
 
305
 
 
306
static void
 
307
bonobo_app_client_get_msgdescs (BonoboAppClient *self)
 
308
{
 
309
        Bonobo_Application_MessageList  *msglist;
 
310
        CORBA_Environment                ev;
 
311
        int                              i, j;
 
312
 
 
313
        g_return_if_fail (!self->msgdescs);
 
314
        CORBA_exception_init (&ev);
 
315
        msglist = Bonobo_Application_listMessages (self->app_server, &ev);
 
316
        if (ev._major != CORBA_NO_EXCEPTION) {
 
317
                g_warning ("Bonobo::Application::listMessages: %s",
 
318
                           bonobo_exception_get_text (&ev));
 
319
                CORBA_exception_free (&ev);
 
320
                return;
 
321
        }
 
322
        CORBA_exception_free (&ev);
 
323
        g_return_if_fail (msglist);
 
324
        self->msgdescs = g_new (BonoboAppClientMsgDesc, msglist->_length + 1);
 
325
        for (i = 0; i < msglist->_length; ++i) {
 
326
                self->msgdescs[i].name = g_strdup (msglist->_buffer[i].name);
 
327
                self->msgdescs[i].return_type =
 
328
                        _typecode_to_gtype (msglist->_buffer[i].return_type);
 
329
                self->msgdescs[i].types = g_new (GType, msglist->_buffer[i].types._length + 1);
 
330
                for (j = 0; j < msglist->_buffer[i].types._length; ++j)
 
331
                        self->msgdescs[i].types[j] =
 
332
                                _typecode_to_gtype (msglist->_buffer[i].types._buffer[j]);
 
333
                self->msgdescs[i].types[j] = G_TYPE_NONE;
 
334
                self->msgdescs[i].description = g_strdup (msglist->_buffer[i].description);
 
335
        }
 
336
        self->msgdescs[i].name = NULL;
 
337
        self->msgdescs[i].return_type = G_TYPE_NONE;
 
338
        self->msgdescs[i].types = NULL;
 
339
        CORBA_free (msglist);
 
340
}
 
341
 
 
342
 
 
343
/**
 
344
 * bonobo_app_client_msg_list:
 
345
 * 
 
346
 * Obtain a list of messages supported by the application server.
 
347
 * 
 
348
 * Return value: a NULL terminated vector of strings; use g_strfreev()
 
349
 * to free it.
 
350
 **/
 
351
BonoboAppClientMsgDesc const *
 
352
bonobo_app_client_msg_list (BonoboAppClient *app_client)
 
353
{
 
354
 
 
355
        g_return_val_if_fail (BONOBO_IS_APP_CLIENT (app_client), NULL);
 
356
 
 
357
        if (!app_client->msgdescs)
 
358
                bonobo_app_client_get_msgdescs (app_client);
 
359
        return app_client->msgdescs;
 
360
}
 
361
 
 
362
 
 
363
/**
 
364
 * bonobo_app_client_new_instance:
 
365
 * @app_client: a #BonoboAppClient
 
366
 * @argc: length of @argv
 
367
 * @argv: array of command-line arguments
 
368
 * @opt_env: a #CORBA_Environment, or %NULL.
 
369
 * 
 
370
 * Ask the application server to emit a "new-instance" signal
 
371
 * containing the specified string vector.
 
372
 * 
 
373
 * Return value: the message return value
 
374
 **/
 
375
gint
 
376
bonobo_app_client_new_instance (BonoboAppClient   *app_client,
 
377
                                int                argc,
 
378
                                char              *argv[],
 
379
                                CORBA_Environment *opt_env)
 
380
{
 
381
        CORBA_sequence_CORBA_string *corba_argv;
 
382
        int                          i;
 
383
        gint                         rv;
 
384
        CORBA_Environment            *ev, ev1;
 
385
 
 
386
        corba_argv = CORBA_sequence_CORBA_string__alloc();
 
387
        corba_argv->_buffer  = CORBA_sequence_CORBA_string_allocbuf (argc);
 
388
        corba_argv->_length  = argc;
 
389
        corba_argv->_maximum = argc;
 
390
        for (i = 0; i < argc; ++i)
 
391
                corba_argv->_buffer[i] = CORBA_string_dup (argv[i]);
 
392
 
 
393
        if (opt_env)
 
394
                ev = opt_env;
 
395
        else {
 
396
                CORBA_exception_init (&ev1);
 
397
                ev = &ev1;
 
398
        }
 
399
        rv = Bonobo_Application_newInstance (app_client->app_server, corba_argv, ev);
 
400
        CORBA_free (corba_argv);
 
401
        if (!opt_env) {
 
402
                if (ev->_major != CORBA_NO_EXCEPTION)
 
403
                        g_warning ("newInstance failed: %s", bonobo_exception_get_text (ev));
 
404
                CORBA_exception_free (&ev1);
 
405
        }
 
406
        return rv;
 
407
}
 
408