1
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
3
#include <gobject/gvaluecollector.h>
4
#include "bonobo-app-client.h"
5
#include "bonobo-exception.h"
6
#include "bonobo-types.h"
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);
13
static gpointer parent_class;
16
bonobo_app_client_get_type (void)
18
static GType app_client_type = 0;
22
static const GTypeInfo app_client_info =
24
sizeof (BonoboAppClientClass),
26
NULL, /* base_finalize */
27
(GClassInitFunc) bonobo_app_client_class_init,
28
NULL, /* class_finalize */
29
NULL, /* class_data */
30
sizeof (BonoboAppClient),
32
(GInstanceInitFunc) bonobo_app_client_init,
35
app_client_type = g_type_register_static
36
(G_TYPE_OBJECT, "BonoboAppClient", &app_client_info, 0);
39
return app_client_type;
44
bonobo_app_client_finalize (GObject *object)
46
BonoboAppClient *self = BONOBO_APP_CLIENT (object);
49
bonobo_app_client_free_msgdescs (self);
51
if (self->app_server != CORBA_OBJECT_NIL) {
52
bonobo_object_release_unref (self->app_server, NULL);
53
self->app_server = CORBA_OBJECT_NIL;
56
if (G_OBJECT_CLASS(parent_class)->finalize)
57
G_OBJECT_CLASS(parent_class)->finalize (object);
62
bonobo_app_client_class_init (BonoboAppClientClass *class)
64
GObjectClass *object_class = G_OBJECT_CLASS (class);
66
parent_class = g_type_class_peek_parent (class);
67
object_class->finalize = bonobo_app_client_finalize;
72
bonobo_app_client_init (BonoboAppClient *app_client)
79
* bonobo_app_client_new:
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.)
85
* Create an application client object connected to the remote (or
86
* local) Bonobo::Application object.
88
* <warning>Applications should not use this function. See
89
* bonobo_application_register_unique().</warning>
91
* Return value: a #BonoboAppClient object.
94
bonobo_app_client_new (Bonobo_Application app_server)
96
BonoboAppClient *app_client;
98
app_client = g_object_new (BONOBO_TYPE_APP_CLIENT, NULL);
99
app_client->app_server = app_server;
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.
111
* Like bonobo_app_client_msg_send(), except that it receives a single
112
* argument vector instead of a variable number of arguments.
114
* Return value: the message return value
117
bonobo_app_client_msg_send_argv (BonoboAppClient *app_client,
119
const GValue *argv[],
120
CORBA_Environment *opt_env)
123
Bonobo_Application_ArgList *args;
125
CORBA_Environment ev1, *ev;
128
g_return_val_if_fail (app_client, NULL);
129
g_return_val_if_fail (BONOBO_IS_APP_CLIENT (app_client), NULL);
131
for (argv_len = -1; argv[++argv_len];);
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;
143
CORBA_sequence_set_release (args, CORBA_TRUE);
148
CORBA_exception_init (&ev1);
151
ret = Bonobo_Application_message (app_client->app_server, message, args, ev);
153
if (ev->_major != CORBA_NO_EXCEPTION) {
155
g_warning ("error while sending message to application server: %s",
156
bonobo_exception_get_text (ev));
157
CORBA_exception_free (&ev1);
162
CORBA_exception_free (&ev1);
164
if (ret->_type != TC_void) {
165
rv = g_new0 (GValue, 1);
166
bonobo_arg_to_gvalue_alloc (ret, rv);
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
182
* See bonobo_app_client_msg_send().
184
* Return value: return value
187
bonobo_app_client_msg_send_valist (BonoboAppClient *app_client,
189
CORBA_Environment *opt_env,
190
GType first_arg_type,
198
gboolean first_arg = TRUE;
200
g_return_val_if_fail (app_client, NULL);
201
g_return_val_if_fail (BONOBO_IS_APP_CLIENT (app_client), NULL);
203
argv = g_ptr_array_new ();
204
while ((type = (first_arg? first_arg_type :
205
va_arg (var_args, GType))) != G_TYPE_NONE)
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);
214
g_ptr_array_add (argv, NULL);
216
rv = bonobo_app_client_msg_send_argv (app_client, message,
217
(const GValue **) argv->pdata,
220
for (i = 0; i < argv->len - 1; ++i) {
221
value = g_ptr_array_index (argv, i);
222
g_value_unset (value);
225
g_ptr_array_free (argv, TRUE);
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
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>
242
* retval = bonobo_app_client_msg_send (app_client, "openURL",
243
* G_TYPE_STRING, "http://www.gnome.org",
244
* G_TYPE_BOOLEAN, TRUE,
246
* </programlisting></informalexample>
248
* Return value: a GValue containing the value returned from the
252
bonobo_app_client_msg_send (BonoboAppClient *app_client,
254
CORBA_Environment *opt_env,
255
GType first_arg_type,
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);
269
static __inline__ GType
270
_typecode_to_gtype (CORBA_TypeCode tc)
272
static GHashTable *hash = NULL;
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));
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);
287
mapping (BONOBO_TYPE_CORBA_ANY, TC_CORBA_any);
290
return GPOINTER_TO_UINT (g_hash_table_lookup (hash, tc));
294
bonobo_app_client_free_msgdescs (BonoboAppClient *self)
298
for (i = 0; self->msgdescs[i].name; ++i) {
299
g_free (self->msgdescs[i].name);
300
g_free (self->msgdescs[i].types);
302
g_free (self->msgdescs);
303
self->msgdescs = NULL;
307
bonobo_app_client_get_msgdescs (BonoboAppClient *self)
309
Bonobo_Application_MessageList *msglist;
310
CORBA_Environment ev;
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);
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);
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);
344
* bonobo_app_client_msg_list:
346
* Obtain a list of messages supported by the application server.
348
* Return value: a NULL terminated vector of strings; use g_strfreev()
351
BonoboAppClientMsgDesc const *
352
bonobo_app_client_msg_list (BonoboAppClient *app_client)
355
g_return_val_if_fail (BONOBO_IS_APP_CLIENT (app_client), NULL);
357
if (!app_client->msgdescs)
358
bonobo_app_client_get_msgdescs (app_client);
359
return app_client->msgdescs;
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.
370
* Ask the application server to emit a "new-instance" signal
371
* containing the specified string vector.
373
* Return value: the message return value
376
bonobo_app_client_new_instance (BonoboAppClient *app_client,
379
CORBA_Environment *opt_env)
381
CORBA_sequence_CORBA_string *corba_argv;
384
CORBA_Environment *ev, ev1;
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]);
396
CORBA_exception_init (&ev1);
399
rv = Bonobo_Application_newInstance (app_client->app_server, corba_argv, ev);
400
CORBA_free (corba_argv);
402
if (ev->_major != CORBA_NO_EXCEPTION)
403
g_warning ("newInstance failed: %s", bonobo_exception_get_text (ev));
404
CORBA_exception_free (&ev1);