1 | /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */ |
---|
2 | /* |
---|
3 | * bonobo-activation: A library for accessing bonobo-activation-server. |
---|
4 | * |
---|
5 | * Copyright (C) 1999, 2000 Red Hat, Inc. |
---|
6 | * Copyright (C) 2000 Eazel, Inc. |
---|
7 | * |
---|
8 | * This library is free software; you can redistribute it and/or |
---|
9 | * modify it under the terms of the GNU Library General Public |
---|
10 | * License as published by the Free Software Foundation; either |
---|
11 | * version 2 of the License, or (at your option) any later version. |
---|
12 | * |
---|
13 | * This library is distributed in the hope that it will be useful, |
---|
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
---|
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
---|
16 | * Library General Public License for more details. |
---|
17 | * |
---|
18 | * You should have received a copy of the GNU Library General Public |
---|
19 | * License along with this library; if not, write to the Free |
---|
20 | * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
---|
21 | * |
---|
22 | * Author: Elliot Lee <sopwith@redhat.com> |
---|
23 | */ |
---|
24 | #include <config.h> |
---|
25 | #include <string.h> |
---|
26 | #include <stdlib.h> |
---|
27 | #include <locale.h> |
---|
28 | |
---|
29 | #include <bonobo-activation/bonobo-activation-activate.h> |
---|
30 | |
---|
31 | #include <bonobo-activation/bonobo-activation-id.h> |
---|
32 | #include <bonobo-activation/bonobo-activation-init.h> |
---|
33 | #include <bonobo-activation/bonobo-activation-server-info.h> |
---|
34 | #include <bonobo-activation/bonobo-activation-private.h> |
---|
35 | #include <bonobo-activation/bonobo-activation-shlib.h> |
---|
36 | #include <bonobo-activation/bonobo-activation-client.h> |
---|
37 | #include <bonobo-activation/bonobo-activation-async.h> |
---|
38 | #include <bonobo-activation/bonobo-activation-i18n.h> |
---|
39 | #include <bonobo-activation/Bonobo_ActivationContext.h> |
---|
40 | |
---|
41 | static Bonobo_ActivationEnvironment activation_environment; |
---|
42 | |
---|
43 | /* FIXME: deprecated internal functions. Should we just remove? |
---|
44 | */ |
---|
45 | void |
---|
46 | bonobo_activation_set_test_components_enabled (gboolean val) |
---|
47 | { |
---|
48 | } |
---|
49 | |
---|
50 | gboolean |
---|
51 | bonobo_activation_get_test_components_enabled (void) |
---|
52 | { |
---|
53 | return FALSE; |
---|
54 | } |
---|
55 | |
---|
56 | static void |
---|
57 | copy_strv_to_sequence (char *const *selection_order, |
---|
58 | Bonobo_StringList *str_seq) |
---|
59 | { |
---|
60 | int len; |
---|
61 | |
---|
62 | if (!selection_order) { |
---|
63 | memset (str_seq, 0, sizeof (Bonobo_StringList)); |
---|
64 | return; |
---|
65 | } |
---|
66 | |
---|
67 | for (len = 0; selection_order [len]; len++); |
---|
68 | |
---|
69 | str_seq->_length = str_seq->_maximum = len; |
---|
70 | str_seq->_buffer = (char **) selection_order; |
---|
71 | str_seq->_release = FALSE; |
---|
72 | } |
---|
73 | |
---|
74 | /* Limit of the number of cached queries */ |
---|
75 | #define QUERY_CACHE_MAX 32 |
---|
76 | #undef QUERY_CACHE_DEBUG |
---|
77 | |
---|
78 | static GHashTable *query_cache = NULL; |
---|
79 | |
---|
80 | typedef struct { |
---|
81 | char *query; |
---|
82 | char **sort_criteria; |
---|
83 | |
---|
84 | Bonobo_ServerInfoList *list; |
---|
85 | } QueryCacheEntry; |
---|
86 | |
---|
87 | static void |
---|
88 | query_cache_entry_free (gpointer data) |
---|
89 | { |
---|
90 | QueryCacheEntry *entry = data; |
---|
91 | |
---|
92 | #ifdef QUERY_CACHE_DEBUG |
---|
93 | g_warning ("Blowing item %p", entry); |
---|
94 | #endif /* QUERY_CACHE_DEBUG */ |
---|
95 | |
---|
96 | g_free (entry->query); |
---|
97 | g_strfreev (entry->sort_criteria); |
---|
98 | CORBA_free (entry->list); |
---|
99 | g_free (entry); |
---|
100 | } |
---|
101 | |
---|
102 | static gboolean |
---|
103 | cache_clean_half (gpointer key, |
---|
104 | gpointer value, |
---|
105 | gpointer user_data) |
---|
106 | { |
---|
107 | int *a = user_data; |
---|
108 | /* Blow half the elements */ |
---|
109 | return (*a)++ % 2; |
---|
110 | } |
---|
111 | |
---|
112 | static gboolean |
---|
113 | query_cache_equal (gconstpointer a, gconstpointer b) |
---|
114 | { |
---|
115 | int i; |
---|
116 | char **strsa, **strsb; |
---|
117 | const QueryCacheEntry *entrya = a; |
---|
118 | const QueryCacheEntry *entryb = b; |
---|
119 | |
---|
120 | if (strcmp (entrya->query, entryb->query)) |
---|
121 | return FALSE; |
---|
122 | |
---|
123 | strsa = entrya->sort_criteria; |
---|
124 | strsb = entryb->sort_criteria; |
---|
125 | |
---|
126 | if (!strsa && !strsb) |
---|
127 | return TRUE; |
---|
128 | |
---|
129 | if (!strsa || !strsb) |
---|
130 | return FALSE; |
---|
131 | |
---|
132 | for (i = 0; strsa [i] && strsb [i]; i++) |
---|
133 | if (strcmp (strsa [i], strsb [i])) |
---|
134 | return FALSE; |
---|
135 | |
---|
136 | if (strsa [i] || strsb [i]) |
---|
137 | return FALSE; |
---|
138 | |
---|
139 | return TRUE; |
---|
140 | } |
---|
141 | |
---|
142 | static guint |
---|
143 | query_cache_hash (gconstpointer a) |
---|
144 | { |
---|
145 | guint hash, i; |
---|
146 | char **strs; |
---|
147 | const QueryCacheEntry *entry = a; |
---|
148 | |
---|
149 | hash = g_str_hash (entry->query); |
---|
150 | strs = entry->sort_criteria; |
---|
151 | |
---|
152 | for (i = 0; strs && strs [i]; i++) |
---|
153 | hash ^= g_str_hash (strs [i]); |
---|
154 | |
---|
155 | return hash; |
---|
156 | } |
---|
157 | |
---|
158 | static void |
---|
159 | query_cache_reset (void) |
---|
160 | { |
---|
161 | if (query_cache) { |
---|
162 | g_hash_table_destroy (query_cache); |
---|
163 | query_cache = NULL; |
---|
164 | } |
---|
165 | } |
---|
166 | |
---|
167 | static void |
---|
168 | create_query_cache (void) |
---|
169 | { |
---|
170 | query_cache = g_hash_table_new_full ( |
---|
171 | query_cache_hash, |
---|
172 | query_cache_equal, |
---|
173 | query_cache_entry_free, |
---|
174 | NULL); |
---|
175 | bonobo_activation_add_reset_notify (query_cache_reset); |
---|
176 | } |
---|
177 | |
---|
178 | static Bonobo_ServerInfoList * |
---|
179 | query_cache_lookup (const char *query, |
---|
180 | char * const *sort_criteria) |
---|
181 | { |
---|
182 | QueryCacheEntry fake; |
---|
183 | QueryCacheEntry *entry; |
---|
184 | |
---|
185 | if (!query_cache) { |
---|
186 | create_query_cache (); |
---|
187 | return NULL; |
---|
188 | } |
---|
189 | |
---|
190 | fake.query = (char *) query; |
---|
191 | fake.sort_criteria = (char **) sort_criteria; |
---|
192 | if ((entry = g_hash_table_lookup (query_cache, &fake))) { |
---|
193 | #ifdef QUERY_CACHE_DEBUG |
---|
194 | g_warning ("\n\n --- Hit (%p) ---\n\n\n", entry->list); |
---|
195 | #endif /* QUERY_CACHE_DEBUG */ |
---|
196 | return Bonobo_ServerInfoList_duplicate (entry->list); |
---|
197 | } else { |
---|
198 | #ifdef QUERY_CACHE_DEBUG |
---|
199 | g_warning ("Miss"); |
---|
200 | #endif /* QUERY_CACHE_DEBUG */ |
---|
201 | return NULL; |
---|
202 | } |
---|
203 | } |
---|
204 | |
---|
205 | static void |
---|
206 | query_cache_insert (const char *query, |
---|
207 | char * const *sort_criteria, |
---|
208 | Bonobo_ServerInfoList *list) |
---|
209 | { |
---|
210 | int idx = 0; |
---|
211 | QueryCacheEntry *entry = g_new (QueryCacheEntry, 1); |
---|
212 | |
---|
213 | if (!query_cache) { |
---|
214 | create_query_cache (); |
---|
215 | |
---|
216 | } else if (g_hash_table_size (query_cache) > QUERY_CACHE_MAX) { |
---|
217 | g_hash_table_foreach_remove ( |
---|
218 | query_cache, cache_clean_half, &idx); |
---|
219 | } |
---|
220 | |
---|
221 | entry->query = g_strdup (query); |
---|
222 | entry->sort_criteria = g_strdupv ((char **) sort_criteria); |
---|
223 | entry->list = Bonobo_ServerInfoList_duplicate (list); |
---|
224 | |
---|
225 | g_hash_table_replace (query_cache, entry, entry); |
---|
226 | |
---|
227 | #ifdef QUERY_CACHE_DEBUG |
---|
228 | g_warning ("Query cache size now %d", |
---|
229 | g_hash_table_size (query_cache)); |
---|
230 | #endif /* QUERY_CACHE_DEBUG */ |
---|
231 | } |
---|
232 | |
---|
233 | /** |
---|
234 | * bonobo_activation_query: |
---|
235 | * @requirements: query string. |
---|
236 | * @selection_order: sort criterion for returned list. |
---|
237 | * @ev: a %CORBA_Environment structure which will contain |
---|
238 | * the CORBA exception status of the operation, or NULL |
---|
239 | * |
---|
240 | * Executes the @requirements query on the bonobo-activation-server. |
---|
241 | * The result is sorted according to @selection_order. |
---|
242 | * @selection_order can safely be NULL as well as @ev. |
---|
243 | * The returned list has to be freed with CORBA_free. |
---|
244 | * |
---|
245 | * Return value: the list of servers matching the requirements. |
---|
246 | */ |
---|
247 | Bonobo_ServerInfoList * |
---|
248 | bonobo_activation_query (const char *requirements, |
---|
249 | char * const *selection_order, |
---|
250 | CORBA_Environment *opt_ev) |
---|
251 | { |
---|
252 | Bonobo_StringList selorder; |
---|
253 | Bonobo_ServerInfoList *retval; |
---|
254 | Bonobo_ActivationContext ac; |
---|
255 | CORBA_Environment tempenv, *ev; |
---|
256 | |
---|
257 | g_return_val_if_fail (requirements != NULL, CORBA_OBJECT_NIL); |
---|
258 | |
---|
259 | ac = bonobo_activation_activation_context_get (); |
---|
260 | g_return_val_if_fail (ac != NULL, CORBA_OBJECT_NIL); |
---|
261 | |
---|
262 | retval = query_cache_lookup (requirements, selection_order); |
---|
263 | if (retval) |
---|
264 | return retval; |
---|
265 | |
---|
266 | if (!opt_ev) { |
---|
267 | CORBA_exception_init (&tempenv); |
---|
268 | ev = &tempenv; |
---|
269 | } else |
---|
270 | ev = opt_ev; |
---|
271 | |
---|
272 | copy_strv_to_sequence (selection_order, &selorder); |
---|
273 | |
---|
274 | retval = Bonobo_ActivationContext_query ( |
---|
275 | ac, requirements, &selorder, |
---|
276 | bonobo_activation_context_get (), ev); |
---|
277 | |
---|
278 | if (ev->_major == CORBA_NO_EXCEPTION) |
---|
279 | query_cache_insert (requirements, selection_order, retval); |
---|
280 | else |
---|
281 | retval = NULL; |
---|
282 | |
---|
283 | if (!opt_ev) |
---|
284 | CORBA_exception_free (&tempenv); |
---|
285 | |
---|
286 | return retval; |
---|
287 | } |
---|
288 | |
---|
289 | static CORBA_Object |
---|
290 | handle_activation_result (Bonobo_ActivationResult *result, |
---|
291 | Bonobo_ActivationID *ret_aid, |
---|
292 | CORBA_Environment *ev) |
---|
293 | { |
---|
294 | CORBA_Object retval = CORBA_OBJECT_NIL; |
---|
295 | |
---|
296 | switch (result->res._d) { |
---|
297 | case Bonobo_ACTIVATION_RESULT_SHLIB: |
---|
298 | retval = bonobo_activation_activate_shlib_server (result, ev); |
---|
299 | break; |
---|
300 | case Bonobo_ACTIVATION_RESULT_OBJECT: |
---|
301 | retval = CORBA_Object_duplicate (result->res._u.res_object, ev); |
---|
302 | break; |
---|
303 | case Bonobo_ACTIVATION_RESULT_NONE: |
---|
304 | default: |
---|
305 | break; |
---|
306 | } |
---|
307 | |
---|
308 | if (ret_aid) { |
---|
309 | if (result->aid && result->aid [0]) |
---|
310 | *ret_aid = g_strdup (result->aid); |
---|
311 | else |
---|
312 | *ret_aid = NULL; |
---|
313 | } |
---|
314 | |
---|
315 | CORBA_free (result); |
---|
316 | |
---|
317 | return retval; |
---|
318 | } |
---|
319 | |
---|
320 | /** |
---|
321 | * bonobo_activation_activate: |
---|
322 | * @requirements: query string. |
---|
323 | * @selection_order: sort criterion for returned list. |
---|
324 | * @flags: how to activate the object. |
---|
325 | * @ret_aid: AID of the activated object. |
---|
326 | * @ev: %CORBA_Environment structure which will contain |
---|
327 | * the CORBA exception status of the operation. |
---|
328 | * |
---|
329 | * Activates a given object. @ret_aid can be safely NULLed as well |
---|
330 | * as @ev and @selection_order. @flags can be set to zero if you do |
---|
331 | * not what to use. |
---|
332 | * |
---|
333 | * Return value: the CORBA object reference of the activated object. |
---|
334 | * This value can be CORBA_OBJECT_NIL: you are supposed |
---|
335 | * to check @ev for success. |
---|
336 | */ |
---|
337 | CORBA_Object |
---|
338 | bonobo_activation_activate (const char *requirements, |
---|
339 | char *const *selection_order, |
---|
340 | Bonobo_ActivationFlags flags, |
---|
341 | Bonobo_ActivationID *ret_aid, |
---|
342 | CORBA_Environment *opt_ev) |
---|
343 | { |
---|
344 | Bonobo_ActivationContext ac; |
---|
345 | Bonobo_ActivationResult *result; |
---|
346 | CORBA_Environment tempenv, *ev; |
---|
347 | Bonobo_StringList selorder; |
---|
348 | CORBA_Object retval = CORBA_OBJECT_NIL; |
---|
349 | |
---|
350 | g_return_val_if_fail (requirements != NULL, CORBA_OBJECT_NIL); |
---|
351 | |
---|
352 | ac = bonobo_activation_activation_context_get (); |
---|
353 | g_return_val_if_fail (ac != NULL, CORBA_OBJECT_NIL); |
---|
354 | |
---|
355 | if (!opt_ev) { |
---|
356 | CORBA_exception_init (&tempenv); |
---|
357 | ev = &tempenv; |
---|
358 | } else |
---|
359 | ev = opt_ev; |
---|
360 | |
---|
361 | copy_strv_to_sequence (selection_order, &selorder); |
---|
362 | |
---|
363 | result = Bonobo_ActivationContext_activateMatching ( |
---|
364 | ac, requirements, &selorder, &activation_environment, |
---|
365 | flags, bonobo_activation_context_get (), ev); |
---|
366 | |
---|
367 | if (ev->_major == CORBA_NO_EXCEPTION) |
---|
368 | retval = handle_activation_result (result, ret_aid, ev); |
---|
369 | |
---|
370 | if (!opt_ev) |
---|
371 | CORBA_exception_free (&tempenv); |
---|
372 | |
---|
373 | return retval; |
---|
374 | } |
---|
375 | |
---|
376 | /** |
---|
377 | * bonobo_activation_activate_from_id |
---|
378 | * @aid: AID or IID of the object to activate. |
---|
379 | * @flags: activation flag. |
---|
380 | * @ret_aid: AID of the activated server. |
---|
381 | * @ev: %CORBA_Environment structure which will contain |
---|
382 | * the CORBA exception status of the operation. |
---|
383 | * |
---|
384 | * Activates the server corresponding to @aid. @ret_aid can be safely |
---|
385 | * NULLed as well as @ev. @flags can be zero if you do not know what |
---|
386 | * to do. |
---|
387 | * |
---|
388 | * Return value: a CORBA object reference to the newly activated |
---|
389 | * server. Do not forget to check @ev for failure!! |
---|
390 | */ |
---|
391 | CORBA_Object |
---|
392 | bonobo_activation_activate_from_id (const Bonobo_ActivationID aid, |
---|
393 | Bonobo_ActivationFlags flags, |
---|
394 | Bonobo_ActivationID *ret_aid, |
---|
395 | CORBA_Environment *opt_ev) |
---|
396 | { |
---|
397 | Bonobo_ActivationContext ac; |
---|
398 | Bonobo_ActivationResult *result; |
---|
399 | CORBA_Environment *ev, tempenv; |
---|
400 | CORBA_Object retval = CORBA_OBJECT_NIL; |
---|
401 | |
---|
402 | g_return_val_if_fail (aid != NULL, CORBA_OBJECT_NIL); |
---|
403 | |
---|
404 | if (!strncmp ("OAFIID:", aid, 7)) { |
---|
405 | char *requirements; |
---|
406 | |
---|
407 | requirements = g_alloca (strlen (aid) + sizeof ("iid == ''")); |
---|
408 | sprintf (requirements, "iid == '%s'", aid); |
---|
409 | |
---|
410 | return bonobo_activation_activate ( |
---|
411 | requirements, NULL, flags, ret_aid, opt_ev); |
---|
412 | } |
---|
413 | |
---|
414 | if (!opt_ev) { |
---|
415 | CORBA_exception_init (&tempenv); |
---|
416 | ev = &tempenv; |
---|
417 | } else |
---|
418 | ev = opt_ev; |
---|
419 | |
---|
420 | ac = bonobo_activation_internal_activation_context_get_extended ( |
---|
421 | (flags & Bonobo_ACTIVATION_FLAG_EXISTING_ONLY), ev); |
---|
422 | if (!ac) { |
---|
423 | if (!opt_ev) |
---|
424 | CORBA_exception_free (&tempenv); |
---|
425 | |
---|
426 | return CORBA_OBJECT_NIL; |
---|
427 | } |
---|
428 | |
---|
429 | result = Bonobo_ActivationContext_activateFromAid ( |
---|
430 | ac, aid, flags, bonobo_activation_context_get (), ev); |
---|
431 | |
---|
432 | if (ev->_major == CORBA_NO_EXCEPTION) |
---|
433 | retval = handle_activation_result (result, ret_aid, ev); |
---|
434 | |
---|
435 | if (!opt_ev) |
---|
436 | CORBA_exception_free (&tempenv); |
---|
437 | |
---|
438 | return retval; |
---|
439 | } |
---|
440 | |
---|
441 | /* Async activation |
---|
442 | */ |
---|
443 | |
---|
444 | #define ASYNC_ERROR_NO_AID (_("No ActivationID supplied")) |
---|
445 | #define ASYNC_ERROR_NO_REQUIREMENTS (_("No requirements supplied")) |
---|
446 | #define ASYNC_ERROR_NO_CONTEXT (_("Failed to initialise the AcitvationContext")) |
---|
447 | #define ASYNC_ERROR_INV_FAILED (_("Failed to invoke method on the AcitvationContext")) |
---|
448 | #define ASYNC_ERROR_GENERAL_EXCEPTION (_("System exception: %s : %s")) |
---|
449 | #define ASYNC_ERROR_EXCEPTION (_("System exception: %s")) |
---|
450 | |
---|
451 | static ORBit_IMethod *activate_matching_method = NULL; |
---|
452 | static ORBit_IMethod *activate_from_aid_method = NULL; |
---|
453 | |
---|
454 | typedef struct { |
---|
455 | BonoboActivationCallback user_cb; |
---|
456 | gpointer user_data; |
---|
457 | } AsyncActivationData; |
---|
458 | |
---|
459 | static void |
---|
460 | setup_methods (void) |
---|
461 | { |
---|
462 | activate_matching_method = &Bonobo_ActivationContext__iinterface.methods._buffer [6]; |
---|
463 | activate_from_aid_method = &Bonobo_ActivationContext__iinterface.methods._buffer [7]; |
---|
464 | |
---|
465 | /* If these blow the IDL changed order, and the above |
---|
466 | indexes need updating */ |
---|
467 | g_assert (!strcmp (activate_matching_method->name, "activateMatching")); |
---|
468 | g_assert (!strcmp (activate_from_aid_method->name, "activateFromAid")); |
---|
469 | } |
---|
470 | |
---|
471 | static void |
---|
472 | activation_async_callback (CORBA_Object object, |
---|
473 | ORBit_IMethod *m_data, |
---|
474 | ORBitAsyncQueueEntry *aqe, |
---|
475 | gpointer user_data, |
---|
476 | CORBA_Environment *ev) |
---|
477 | { |
---|
478 | Bonobo_ActivationResult *result = NULL; |
---|
479 | AsyncActivationData *async_data = user_data; |
---|
480 | Bonobo_GeneralError *err; |
---|
481 | CORBA_Object retval; |
---|
482 | char *reason = NULL; |
---|
483 | |
---|
484 | g_return_if_fail (async_data != NULL); |
---|
485 | g_return_if_fail (async_data->user_cb != NULL); |
---|
486 | |
---|
487 | if (ev->_major != CORBA_NO_EXCEPTION) |
---|
488 | goto return_exception; |
---|
489 | |
---|
490 | ORBit_small_demarshal_async (aqe, &result, NULL, ev); |
---|
491 | |
---|
492 | if (ev->_major != CORBA_NO_EXCEPTION) |
---|
493 | goto return_exception; |
---|
494 | |
---|
495 | retval = handle_activation_result (result, NULL, ev); |
---|
496 | |
---|
497 | if (ev->_major != CORBA_NO_EXCEPTION) |
---|
498 | goto return_exception; |
---|
499 | |
---|
500 | async_data->user_cb (retval, NULL, async_data->user_data); |
---|
501 | |
---|
502 | clean_out: |
---|
503 | g_free (async_data); |
---|
504 | return; |
---|
505 | |
---|
506 | return_exception: |
---|
507 | if (!strcmp (ev->_id, "IDL:Bonobo/GeneralError:1.0")) { |
---|
508 | err = ev->_any._value; |
---|
509 | |
---|
510 | if (!err || !err->description) |
---|
511 | reason = g_strdup_printf (ASYNC_ERROR_GENERAL_EXCEPTION, |
---|
512 | ev->_id, "(no description)"); |
---|
513 | else |
---|
514 | reason = g_strdup_printf (ASYNC_ERROR_GENERAL_EXCEPTION, |
---|
515 | ev->_id, err->description); |
---|
516 | } else |
---|
517 | reason = g_strdup_printf (ASYNC_ERROR_EXCEPTION, ev->_id); |
---|
518 | |
---|
519 | async_data->user_cb (CORBA_OBJECT_NIL, reason, async_data->user_data); |
---|
520 | g_free (reason); |
---|
521 | |
---|
522 | goto clean_out; |
---|
523 | } |
---|
524 | |
---|
525 | /** |
---|
526 | * bonobo_activation_activate_async: |
---|
527 | * @requirements: the bonobo-activation query string. |
---|
528 | * @selection_order: preference array. |
---|
529 | * @flags: activation flags. |
---|
530 | * @callback: callback function. |
---|
531 | * @user_data: data to be poassed to the callback function. |
---|
532 | * @ev: exception structure. |
---|
533 | * |
---|
534 | * This function will asynchronously try to activate a component |
---|
535 | * given the @requirements query string. When the component is |
---|
536 | * activated or when the activation fails, it will call @callback |
---|
537 | * with the given @user_data data as parameter. |
---|
538 | * callback will be called with a CORBA_OBJECT_NIL object if the |
---|
539 | * activation fails. If the activation fails, the callback will be |
---|
540 | * given a human-readable string containing a description of the |
---|
541 | * error. In case of sucess, the error string value is undefined. |
---|
542 | * |
---|
543 | * @selection_order can be safely NULLed as well as @ev and |
---|
544 | * @user_data. @flags can be set to 0 if you do not know what to |
---|
545 | * use. |
---|
546 | */ |
---|
547 | void |
---|
548 | bonobo_activation_activate_async (const char *requirements, |
---|
549 | char *const *selection_order, |
---|
550 | Bonobo_ActivationFlags flags, |
---|
551 | BonoboActivationCallback async_cb, |
---|
552 | gpointer user_data, |
---|
553 | CORBA_Environment *opt_ev) |
---|
554 | { |
---|
555 | Bonobo_ActivationContext ac; |
---|
556 | AsyncActivationData *async_data; |
---|
557 | CORBA_Environment *ev, tempenv; |
---|
558 | Bonobo_StringList selorder; |
---|
559 | gpointer args [4]; |
---|
560 | |
---|
561 | if (!requirements) { |
---|
562 | async_cb (CORBA_OBJECT_NIL, ASYNC_ERROR_NO_REQUIREMENTS, user_data); |
---|
563 | return; |
---|
564 | } |
---|
565 | |
---|
566 | ac = bonobo_activation_activation_context_get (); |
---|
567 | if (!ac) { |
---|
568 | async_cb (CORBA_OBJECT_NIL, ASYNC_ERROR_NO_CONTEXT, user_data); |
---|
569 | return; |
---|
570 | } |
---|
571 | |
---|
572 | if (!opt_ev) { |
---|
573 | CORBA_exception_init (&tempenv); |
---|
574 | ev = &tempenv; |
---|
575 | } else |
---|
576 | ev = opt_ev; |
---|
577 | |
---|
578 | async_data = g_new (AsyncActivationData, 1); |
---|
579 | async_data->user_cb = async_cb; |
---|
580 | async_data->user_data = user_data; |
---|
581 | |
---|
582 | copy_strv_to_sequence (selection_order, &selorder); |
---|
583 | |
---|
584 | args [0] = &requirements; |
---|
585 | args [1] = &selorder; |
---|
586 | args [2] = &activation_environment; |
---|
587 | args [3] = &flags; |
---|
588 | |
---|
589 | if (!activate_matching_method) |
---|
590 | setup_methods (); |
---|
591 | |
---|
592 | ORBit_small_invoke_async (ac, activate_matching_method, |
---|
593 | activation_async_callback, async_data, |
---|
594 | args, bonobo_activation_context_get (), ev); |
---|
595 | |
---|
596 | if (ev->_major != CORBA_NO_EXCEPTION) { |
---|
597 | async_cb (CORBA_OBJECT_NIL, ASYNC_ERROR_INV_FAILED, user_data); |
---|
598 | g_free (async_data); |
---|
599 | } |
---|
600 | |
---|
601 | if (!opt_ev) |
---|
602 | CORBA_exception_free (&tempenv); |
---|
603 | |
---|
604 | return; |
---|
605 | } |
---|
606 | |
---|
607 | /** |
---|
608 | * bonobo_activation_activate_from_id_async: |
---|
609 | * @aid: the AID or IID of the component to activate. |
---|
610 | * @flags: activation flags. |
---|
611 | * @callback: callback function. |
---|
612 | * @user_data: data to be poassed to the callback function. |
---|
613 | * @ev: exception structure. |
---|
614 | * |
---|
615 | * This function will asynchronously try to activate a component |
---|
616 | * with the given @aid. When the component is |
---|
617 | * activated or when the activation fails, it will call @callback |
---|
618 | * with the given @user_data data as parameter. |
---|
619 | * callback will be called with a CORBA_OBJECT_NIL object if the |
---|
620 | * activation fails. If the activation fails, the callback will be |
---|
621 | * given a human-readable string containing a description of the |
---|
622 | * error. In case of sucess, the error string value is undefined. |
---|
623 | * |
---|
624 | * @flags can be 0 if you do not know what to set it to and |
---|
625 | * @ev can be safely set to NULL. |
---|
626 | */ |
---|
627 | void |
---|
628 | bonobo_activation_activate_from_id_async (const Bonobo_ActivationID aid, |
---|
629 | Bonobo_ActivationFlags flags, |
---|
630 | BonoboActivationCallback async_cb, |
---|
631 | gpointer user_data, |
---|
632 | CORBA_Environment *opt_ev) |
---|
633 | { |
---|
634 | Bonobo_ActivationContext ac; |
---|
635 | AsyncActivationData *async_data; |
---|
636 | CORBA_Environment *ev, tempenv; |
---|
637 | gpointer args [2]; |
---|
638 | |
---|
639 | if (!aid) { |
---|
640 | async_cb (CORBA_OBJECT_NIL, ASYNC_ERROR_NO_AID, user_data); |
---|
641 | return; |
---|
642 | } |
---|
643 | |
---|
644 | if (!strncmp ("OAFIID:", aid, 7)) { |
---|
645 | char *requirements; |
---|
646 | |
---|
647 | requirements = g_alloca (strlen (aid) + sizeof ("iid == ''")); |
---|
648 | sprintf (requirements, "iid == '%s'", aid); |
---|
649 | |
---|
650 | bonobo_activation_activate_async ( |
---|
651 | requirements, NULL, flags, async_cb, user_data, opt_ev); |
---|
652 | return; |
---|
653 | } |
---|
654 | |
---|
655 | if (!opt_ev) { |
---|
656 | CORBA_exception_init (&tempenv); |
---|
657 | ev = &tempenv; |
---|
658 | } else |
---|
659 | ev = opt_ev; |
---|
660 | |
---|
661 | ac = bonobo_activation_internal_activation_context_get_extended ( |
---|
662 | (flags & Bonobo_ACTIVATION_FLAG_EXISTING_ONLY), ev); |
---|
663 | if (!ac) { |
---|
664 | if (!opt_ev) |
---|
665 | CORBA_exception_free (&tempenv); |
---|
666 | |
---|
667 | async_cb (CORBA_OBJECT_NIL, ASYNC_ERROR_NO_CONTEXT, user_data); |
---|
668 | return; |
---|
669 | } |
---|
670 | |
---|
671 | async_data = g_new (AsyncActivationData, 1); |
---|
672 | async_data->user_cb = async_cb; |
---|
673 | async_data->user_data = user_data; |
---|
674 | |
---|
675 | if (!activate_from_aid_method) |
---|
676 | setup_methods (); |
---|
677 | |
---|
678 | args [0] = (gpointer) &aid; |
---|
679 | args [1] = &flags; |
---|
680 | |
---|
681 | ORBit_small_invoke_async (ac, activate_from_aid_method, |
---|
682 | activation_async_callback, async_data, |
---|
683 | args, bonobo_activation_context_get (), ev); |
---|
684 | |
---|
685 | if (ev->_major != CORBA_NO_EXCEPTION) { |
---|
686 | async_cb (CORBA_OBJECT_NIL, ASYNC_ERROR_INV_FAILED, user_data); |
---|
687 | g_free (async_data); |
---|
688 | } |
---|
689 | |
---|
690 | if (!opt_ev) |
---|
691 | CORBA_exception_free (&tempenv); |
---|
692 | |
---|
693 | return; |
---|
694 | |
---|
695 | } |
---|
696 | |
---|
697 | void |
---|
698 | bonobo_activation_init_activation_env (void) |
---|
699 | { |
---|
700 | int i, j, num_items = 0; |
---|
701 | |
---|
702 | struct { |
---|
703 | const char *name; |
---|
704 | const char *value; |
---|
705 | } getenv_values[] = { |
---|
706 | { "DISPLAY", NULL }, /* X display */ |
---|
707 | { "SESSION_MANAGER", NULL }, /* XSMP session manager */ |
---|
708 | { "AUDIODEV", NULL }, /* Audio device on Sun systems */ |
---|
709 | { "LANG", NULL }, /* Fallback locale name */ |
---|
710 | { NULL, NULL } |
---|
711 | }; |
---|
712 | |
---|
713 | struct { |
---|
714 | int category; |
---|
715 | const char *name; |
---|
716 | const char *value; |
---|
717 | } setlocale_values[] = { /* locale information: see setlocale(3) */ |
---|
718 | { LC_ALL, "LC_ALL", NULL }, |
---|
719 | { LC_COLLATE, "LC_COLLATE", NULL }, |
---|
720 | { LC_MESSAGES, "LC_MESSAGES", NULL }, |
---|
721 | { LC_MONETARY, "LC_MONETARY", NULL }, |
---|
722 | { LC_NUMERIC, "LC_NUMERIC", NULL }, |
---|
723 | { LC_TIME, "LC_TIME", NULL }, |
---|
724 | { 0, NULL, NULL } |
---|
725 | }; |
---|
726 | |
---|
727 | for (i = 0; getenv_values [i].name; i++) { |
---|
728 | getenv_values [i].value = getenv (getenv_values [i].name); |
---|
729 | |
---|
730 | if (getenv_values [i].value) |
---|
731 | num_items++; |
---|
732 | } |
---|
733 | |
---|
734 | for (i = 0; setlocale_values [i].name; i++) { |
---|
735 | setlocale_values [i].value = setlocale (setlocale_values [i].category, NULL); |
---|
736 | |
---|
737 | if (!setlocale_values [i].value) |
---|
738 | setlocale_values [i].value = getenv (setlocale_values [i].name); |
---|
739 | |
---|
740 | if (setlocale_values [i].value) { |
---|
741 | num_items++; |
---|
742 | if (setlocale_values [i].category == LC_ALL) |
---|
743 | break; /* LC_ALL overrides all others */ |
---|
744 | } |
---|
745 | } |
---|
746 | |
---|
747 | if (!num_items) |
---|
748 | return; |
---|
749 | |
---|
750 | activation_environment._length = activation_environment._maximum = num_items; |
---|
751 | activation_environment._buffer = Bonobo_ActivationEnvironment_allocbuf (num_items); |
---|
752 | activation_environment._release = TRUE; |
---|
753 | |
---|
754 | j = 0; |
---|
755 | |
---|
756 | for (i = 0; getenv_values [i].name; i++) { |
---|
757 | if (!getenv_values [i].value) |
---|
758 | continue; |
---|
759 | |
---|
760 | Bonobo_ActivationEnvValue_set ( |
---|
761 | &activation_environment._buffer [j++], |
---|
762 | getenv_values [i].name, |
---|
763 | getenv_values [i].value); |
---|
764 | } |
---|
765 | |
---|
766 | |
---|
767 | for (i = 0; setlocale_values [i].name; i++) { |
---|
768 | if (!setlocale_values [i].value) |
---|
769 | continue; |
---|
770 | |
---|
771 | Bonobo_ActivationEnvValue_set ( |
---|
772 | &activation_environment._buffer [j++], |
---|
773 | setlocale_values [i].name, |
---|
774 | setlocale_values [i].value); |
---|
775 | } |
---|
776 | |
---|
777 | g_assert (j == num_items); |
---|
778 | } |
---|
779 | |
---|
780 | void |
---|
781 | bonobo_activation_set_activation_env_value (const char *name, |
---|
782 | const char *value) |
---|
783 | { |
---|
784 | Bonobo_ActivationEnvValue *old_buffer; |
---|
785 | int i; |
---|
786 | |
---|
787 | g_return_if_fail (name != NULL); |
---|
788 | |
---|
789 | for (i = 0; i < activation_environment._length; i++) |
---|
790 | if (!strcmp (activation_environment._buffer [i].name, name)) { |
---|
791 | Bonobo_ActivationEnvValue_set ( |
---|
792 | &activation_environment._buffer [i], name, value); |
---|
793 | break; |
---|
794 | } |
---|
795 | |
---|
796 | if (i > 0 && i != activation_environment._length) |
---|
797 | return; /* We've overwritten a value */ |
---|
798 | |
---|
799 | old_buffer = activation_environment._buffer; |
---|
800 | |
---|
801 | activation_environment._length++; |
---|
802 | activation_environment._maximum++; |
---|
803 | activation_environment._buffer = Bonobo_ActivationEnvironment_allocbuf ( |
---|
804 | activation_environment._length); |
---|
805 | activation_environment._release = TRUE; |
---|
806 | |
---|
807 | for (i = 0; i < activation_environment._length - 1; i++) |
---|
808 | Bonobo_ActivationEnvValue_copy ( |
---|
809 | &activation_environment._buffer [i], &old_buffer [i]); |
---|
810 | |
---|
811 | Bonobo_ActivationEnvValue_set (&activation_environment._buffer [i], name, value); |
---|
812 | |
---|
813 | if (old_buffer) |
---|
814 | CORBA_free (old_buffer); |
---|
815 | } |
---|
816 | |
---|
817 | /** |
---|
818 | * bonobo_activation_name_service_get: |
---|
819 | * @ev: %CORBA_Environment structure which will contain |
---|
820 | * the CORBA exception status of the operation. |
---|
821 | * |
---|
822 | * Returns the name server of bonobo-activation. @ev can be NULL. |
---|
823 | * |
---|
824 | * Return value: the name server of bonobo-activation. |
---|
825 | */ |
---|
826 | CORBA_Object |
---|
827 | bonobo_activation_name_service_get (CORBA_Environment * ev) |
---|
828 | { |
---|
829 | return bonobo_activation_activate_from_id ( |
---|
830 | "OAFIID:Bonobo_CosNaming_NamingContext", 0, NULL, ev); |
---|
831 | } |
---|