source: trunk/third/gnome-core/panel/applet-widget.c @ 17152

Revision 17152, 55.4 KB checked in by ghudson, 23 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r17151, which included commits to RCS files with non-trunk default branches.
Line 
1#include <config.h>
2#include <string.h>
3#include <X11/X.h>
4#include <X11/Xlib.h>
5#include <gtk/gtk.h>
6#include <gdk/gdkx.h>
7#include <gnome.h>
8
9#include <applet-widget.h>
10#include <libgnorba/gnorba.h>
11#include <libgnorba/gnome-factory.h>
12
13#include "gnome-panel.h"
14
15struct _AppletWidgetPrivate
16{
17        /* CORBA stuff */
18        gpointer                corbadat;
19
20        /* something was added */
21        gboolean                added_child;
22       
23        /*change freezing*/
24        int                     frozen_level;
25
26        gboolean                frozen_got_orient;
27        PanelOrientType         frozen_orient;                 
28
29        gboolean                frozen_got_size;
30        int                     frozen_size;                   
31       
32        gboolean                frozen_got_back;
33        PanelBackType           frozen_back_type;                       
34        char                    *frozen_back_pixmap;                   
35        GdkColor                frozen_back_color;                     
36       
37        gboolean                frozen_got_position;
38        int                     frozen_position_x;
39        int                     frozen_position_y;
40
41        /* for local case */
42        GtkWidget               *ebox;
43};
44
45/*****************************************************************************
46  CORBA STUFF
47 *****************************************************************************/
48
49typedef struct _CallbackInfo CallbackInfo;
50struct _CallbackInfo {
51        char                    *name;
52        AppletCallbackFunc      func;
53        gpointer                data;
54};
55
56static GNOME_Panel panel_client = CORBA_OBJECT_NIL;
57
58#define pg_return_if_fail(evp,x) {if(!(x)) { g_warning("file %s: line %d: Corba Exception: type = %d exid = %s\n", __FILE__, __LINE__, (evp)->_major, (evp)->_repo_id); return; }}
59#define pg_return_val_if_fail(evp,x,y) {if(!(x)) { g_warning("file %s: line %d: Corba Exception: type = %d exid = %s\n", __FILE__, __LINE__, (evp)->_major, (evp)->_repo_id); return y;}}
60
61typedef struct {
62        POA_GNOME_Applet                servant;
63        PortableServer_ObjectId         *objid;
64        PortableServer_POA              poa;
65
66        AppletWidget                    *appwidget;
67        GSList                          *callbacks;
68        GNOME_PanelSpot                 pspot;
69        GNOME_Applet                    obj;
70        guint32                         winid;
71
72        char                            *goad_id;
73} CustomAppletServant;
74
75static PortableServer_ServantBase__epv base_epv = {
76        NULL, NULL, NULL
77};
78
79static void
80server_applet_change_orient(PortableServer_Servant _servant,
81                            const GNOME_Panel_OrientType orient,
82                            CORBA_Environment *ev);
83
84static void
85server_applet_change_size(PortableServer_Servant _servant,
86                          const CORBA_short size,
87                          CORBA_Environment *ev);
88
89static void
90server_applet_do_callback(PortableServer_Servant _servant,
91                          const CORBA_char * callback_name,
92                          CORBA_Environment *ev);
93
94static void
95server_applet_save_session(PortableServer_Servant _servant,
96                           const CORBA_char * cfgpath,
97                           const CORBA_char * globcfgpath,
98                           const CORBA_unsigned_long cookie,
99                           CORBA_Environment *ev);
100
101static CORBA_boolean
102server_applet_session_save(PortableServer_Servant _servant,
103                           const CORBA_char * cfgpath,
104                           const CORBA_char * globcfgpath,
105                           CORBA_Environment *ev);
106
107static void
108server_applet_back_change(PortableServer_Servant _servant,
109                          const GNOME_Panel_BackInfoType *backing,
110                          CORBA_Environment *ev);
111
112static void
113server_applet_draw(PortableServer_Servant _servant,
114                   CORBA_Environment *ev);
115
116static void
117server_applet_set_tooltips_state(PortableServer_Servant _servant,
118                                 const CORBA_boolean enabled,
119                                 CORBA_Environment *ev);
120
121static void
122server_applet_change_position(PortableServer_Servant _servant,
123                              const CORBA_short x,
124                              const CORBA_short y,
125                              CORBA_Environment *ev);
126
127static CORBA_char *
128server_applet__get_goad_id(PortableServer_Servant _servant,
129                           CORBA_Environment *ev);
130
131static void
132server_applet_freeze_changes(PortableServer_Servant _servant,
133                             CORBA_Environment *ev);
134
135static void
136server_applet_thaw_changes(PortableServer_Servant _servant,
137                           CORBA_Environment *ev);
138
139static POA_GNOME_Applet__epv applet_epv = {
140  NULL,
141  server_applet_change_orient,
142  server_applet_do_callback,
143  server_applet_session_save,
144  server_applet_back_change,
145  server_applet_set_tooltips_state,
146  server_applet__get_goad_id,
147  server_applet_draw,
148  server_applet_save_session,
149  server_applet_change_size,
150  server_applet_change_position,
151  server_applet_freeze_changes,
152  server_applet_thaw_changes
153};
154
155static POA_GNOME_Applet__vepv vepv = { &base_epv, &applet_epv };
156
157/*****************************************************************************
158  WIDGET STUFF
159 *****************************************************************************/
160static void applet_widget_class_init    (AppletWidgetClass *klass);
161static void wapplet_widget_init         (AppletWidget      *applet_widget);
162
163
164typedef int (*SaveSignal) (GtkObject * object,
165                           char *cfgpath,
166                           char *globcfgpath,
167                           gpointer data);
168
169typedef void (*BackSignal) (GtkObject * object,
170                            GNOME_Panel_BackType type,
171                            char *pixmap,
172                            GdkColor *color,
173                            gpointer data);
174
175typedef void (*PositionSignal) (GtkObject * object,
176                                int x,
177                                int y,
178                                gpointer data);
179
180static int applet_count = 0;
181
182static gboolean die_on_last = FALSE;
183static GtkPlugClass *parent_class;
184static GtkTooltips *applet_tooltips = NULL;
185
186#define CD(applet) ((CustomAppletServant *)APPLET_WIDGET(applet)->_priv->corbadat)
187
188guint
189applet_widget_get_type (void)
190{
191        static guint applet_widget_type = 0;
192
193        if (!applet_widget_type) {
194                static const GtkTypeInfo applet_widget_info = {
195                        "AppletWidget",
196                        sizeof (AppletWidget),
197                        sizeof (AppletWidgetClass),
198                        (GtkClassInitFunc) applet_widget_class_init,
199                        (GtkObjectInitFunc) wapplet_widget_init,
200                        NULL,
201                        NULL,
202                        NULL
203                };
204
205                applet_widget_type = gtk_type_unique (gtk_plug_get_type (), &applet_widget_info);
206        }
207
208        return applet_widget_type;
209}
210
211enum {
212        CHANGE_ORIENT_SIGNAL,
213        CHANGE_PIXEL_SIZE_SIGNAL,
214        SAVE_SESSION_SIGNAL,
215        BACK_CHANGE_SIGNAL,
216        DO_DRAW_SIGNAL,
217        TOOLTIP_STATE_SIGNAL,
218        CHANGE_POSITION_SIGNAL,
219        LAST_SIGNAL
220};
221
222static guint applet_widget_signals[LAST_SIGNAL] = {0};
223
224static void
225marshal_signal_save (GtkObject * object,
226                     GtkSignalFunc func,
227                     gpointer func_data,
228                     GtkArg * args)
229{
230        SaveSignal rfunc;
231        int *retval;
232
233        rfunc = (SaveSignal) func;
234
235        retval = GTK_RETLOC_BOOL(args[2]);
236
237        *retval = (*rfunc) (object, GTK_VALUE_STRING (args[0]),
238                            GTK_VALUE_STRING (args[1]),
239                            func_data);
240       
241        /*make applets that forget to do this not fsckup*/
242        gnome_config_sync();
243        gnome_config_drop_all();
244}
245
246static void
247marshal_signal_back (GtkObject * object,
248                     GtkSignalFunc func,
249                     gpointer func_data,
250                     GtkArg * args)
251{
252        BackSignal rfunc;
253
254        rfunc = (BackSignal) func;
255
256        (*rfunc) (object, GTK_VALUE_ENUM (args[0]),
257                  GTK_VALUE_POINTER (args[1]),
258                  GTK_VALUE_POINTER (args[2]),
259                  func_data);
260}
261
262static void
263marshal_signal_position (GtkObject * object,
264                         GtkSignalFunc func,
265                         gpointer func_data,
266                         GtkArg * args)
267{
268        PositionSignal rfunc;
269
270        rfunc = (PositionSignal) func;
271
272        (*rfunc) (object,
273                  GTK_VALUE_INT (args[0]),
274                  GTK_VALUE_INT (args[1]),
275                  func_data);
276}
277
278static void
279applet_widget_class_init (AppletWidgetClass *class)
280{
281        GtkObjectClass *object_class;
282
283        object_class = (GtkObjectClass*) class;
284
285        parent_class = gtk_type_class (gtk_plug_get_type ());
286
287        applet_widget_signals[CHANGE_ORIENT_SIGNAL] =
288                gtk_signal_new("change_orient",
289                               GTK_RUN_FIRST,
290                               object_class->type,
291                               GTK_SIGNAL_OFFSET(AppletWidgetClass,
292                                                 change_orient),
293                               gtk_marshal_NONE__ENUM,
294                               GTK_TYPE_NONE,
295                               1,
296                               GTK_TYPE_ENUM);
297        applet_widget_signals[CHANGE_PIXEL_SIZE_SIGNAL] =
298                gtk_signal_new("change_pixel_size",
299                               GTK_RUN_FIRST,
300                               object_class->type,
301                               GTK_SIGNAL_OFFSET(AppletWidgetClass,
302                                                 change_pixel_size),
303                               gtk_marshal_NONE__INT,
304                               GTK_TYPE_NONE,
305                               1,
306                               GTK_TYPE_INT);
307        applet_widget_signals[SAVE_SESSION_SIGNAL] =
308                gtk_signal_new("save_session",
309                               GTK_RUN_LAST,
310                               object_class->type,
311                               GTK_SIGNAL_OFFSET(AppletWidgetClass,
312                                                 save_session),
313                               marshal_signal_save,
314                               GTK_TYPE_BOOL,
315                               2,
316                               GTK_TYPE_STRING,
317                               GTK_TYPE_STRING);
318        applet_widget_signals[BACK_CHANGE_SIGNAL] =
319                gtk_signal_new("back_change",
320                               GTK_RUN_LAST,
321                               object_class->type,
322                               GTK_SIGNAL_OFFSET(AppletWidgetClass,
323                                                 back_change),
324                               marshal_signal_back,
325                               GTK_TYPE_NONE,
326                               3,
327                               GTK_TYPE_ENUM,
328                               GTK_TYPE_POINTER,
329                               GTK_TYPE_POINTER);
330        applet_widget_signals[DO_DRAW_SIGNAL] =
331                gtk_signal_new("do_draw",
332                               GTK_RUN_LAST,
333                               object_class->type,
334                               GTK_SIGNAL_OFFSET(AppletWidgetClass,
335                                                 do_draw),
336                               gtk_signal_default_marshaller,
337                               GTK_TYPE_NONE,
338                               0);
339        applet_widget_signals[TOOLTIP_STATE_SIGNAL] =
340                gtk_signal_new("tooltip_state",
341                               GTK_RUN_LAST,
342                               object_class->type,
343                               GTK_SIGNAL_OFFSET(AppletWidgetClass,
344                                                 tooltip_state),
345                               gtk_marshal_NONE__INT,
346                               GTK_TYPE_NONE,
347                               1,
348                               GTK_TYPE_INT);
349        applet_widget_signals[CHANGE_POSITION_SIGNAL] =
350                gtk_signal_new("change_position",
351                               GTK_RUN_LAST,
352                               object_class->type,
353                               GTK_SIGNAL_OFFSET(AppletWidgetClass,
354                                                 change_position),
355                               marshal_signal_position,
356                               GTK_TYPE_NONE,
357                               2,
358                               GTK_TYPE_INT,
359                               GTK_TYPE_INT);
360
361        gtk_object_class_add_signals(object_class,applet_widget_signals,
362                                     LAST_SIGNAL);
363
364        class->change_orient = NULL;
365        class->save_session = NULL;
366        class->back_change = NULL;
367        class->do_draw = NULL;
368        class->tooltip_state = NULL;
369        class->change_position = NULL;
370}
371
372static void
373wapplet_widget_init (AppletWidget *applet)
374{
375        g_return_if_fail(applet != NULL);
376        g_return_if_fail(IS_APPLET_WIDGET(applet));
377       
378        applet->orient = ORIENT_UP;
379        applet->size = PIXEL_SIZE_STANDARD;
380        applet->_priv = g_new0(AppletWidgetPrivate, 1);
381        applet->_priv->corbadat = NULL;
382        applet->_priv->added_child = FALSE;
383        applet->_priv->frozen_level = 0;
384        applet->_priv->frozen_got_orient = FALSE;
385        applet->_priv->frozen_got_size = FALSE;
386        applet->_priv->frozen_got_back = FALSE;
387        applet->_priv->frozen_got_position = FALSE;
388}
389
390static void
391applet_servant_destroy(CustomAppletServant *servant)
392{
393        GSList *list;
394        PortableServer_POA poa;
395        CORBA_Environment ev;
396
397        for(list = servant->callbacks; list; list = g_slist_next(list)) {
398                CallbackInfo *info = (CallbackInfo *)list->data;
399                g_free(info->name);
400                info->name = NULL;
401                g_free(info);
402
403                list->data = NULL;
404        }
405        g_slist_free(servant->callbacks);
406        servant->callbacks = NULL;
407
408        CORBA_exception_init(&ev);
409        poa = servant->poa;
410        servant->poa = NULL;
411        PortableServer_POA_deactivate_object(poa, servant->objid, &ev);
412        CORBA_free(servant->objid);
413        servant->objid = NULL;
414
415        goad_server_unregister(CORBA_OBJECT_NIL, servant->goad_id,
416                               "server", &ev);
417        g_free(servant->goad_id);
418        servant->goad_id = NULL;
419
420        CORBA_Object_release(servant->pspot, &ev);
421        servant->pspot = NULL;
422        CORBA_Object_release(servant->obj, &ev);
423        servant->obj = NULL;
424        POA_GNOME_Applet__fini((PortableServer_Servant) servant, &ev);
425        g_free(servant);
426        CORBA_Object_release((CORBA_Object)poa, &ev);
427        CORBA_exception_free(&ev);
428}
429
430static void
431applet_widget_destroy(GtkWidget *w, gpointer data)
432{
433        AppletWidget *applet;
434        GtkPlug *plug;
435        CORBA_Environment ev;
436
437        g_return_if_fail(w != NULL);
438        g_return_if_fail(IS_APPLET_WIDGET(w));
439
440        applet = APPLET_WIDGET(w);
441        plug = GTK_PLUG(w);
442
443        /* XXX: hackaround to broken gtkplug/gtksocket, we kill the references
444           to ourselves on the socket and our references to the socket and
445           destroy the socket */
446        if(plug->same_app && plug->socket_window) {
447                GtkSocket *socket;
448                gdk_window_get_user_data (plug->socket_window,
449                                          (gpointer *)&socket);
450                if(socket) {
451                        GtkWidget *toplevel = gtk_widget_get_toplevel (GTK_WIDGET(socket));
452                        if (toplevel && GTK_IS_WINDOW (toplevel))
453                                gtk_window_remove_embedded_xid (GTK_WINDOW (toplevel),
454                                                                GDK_WINDOW_XWINDOW (socket->plug_window));
455                        socket->plug_window = NULL;
456                        socket->same_app = FALSE;
457                        plug->socket_window = NULL;
458                        plug->same_app = FALSE;
459                        gtk_widget_destroy(GTK_WIDGET(socket));
460                }
461        }
462
463        if(applet->_priv->ebox && GTK_BIN(applet->_priv->ebox)->child) {
464                GtkWidget *child = GTK_BIN(applet->_priv->ebox)->child;
465                /* disconnect the destroy handler */
466                gtk_signal_disconnect_by_data(GTK_OBJECT(child), applet);
467                gtk_widget_destroy(child);
468        }
469
470
471        if(applet->privcfgpath) {
472                g_free(applet->privcfgpath);
473                g_free(applet->globcfgpath);
474
475                applet->privcfgpath = NULL;
476                applet->globcfgpath = NULL;
477
478                CORBA_exception_init(&ev);
479                /* if nothing has been added as our child, this means we have
480                   not yet fully completed load, so notify the panel that we
481                   are going to die */
482                if( ! applet->_priv->added_child)
483                        GNOME_PanelSpot_abort_load(CD(applet)->pspot, &ev);
484                CORBA_exception_free(&ev);
485        }
486
487        applet_servant_destroy(applet->_priv->corbadat);
488        applet->_priv->corbadat = NULL;
489
490        applet_count--;
491
492        if(die_on_last && applet_count == 0)
493                applet_widget_gtk_main_quit();
494
495        g_free(applet->_priv);
496        applet->_priv = NULL;
497}
498
499/**
500 * applet_widget_abort_load:
501 * @applet: #AppletWidget to work on.
502 *
503 * Description:  Abort the applet loading, once applet has been created, this is
504 * a way to tell the panel to forget about us if we decide we want to quit
505 * before we add the actual applet to the applet-widget.  This is only useful
506 * to abort after #applet_widget_new was called but before #applet_widget_add
507 * is called.
508 **/
509void
510applet_widget_abort_load(AppletWidget *applet)
511{
512        CORBA_Environment ev;
513        CORBA_exception_init(&ev);
514        GNOME_PanelSpot_abort_load(CD(applet)->pspot, &ev);
515        CORBA_exception_free(&ev);
516}
517
518/**
519 * applet_widget_remove:
520 * @applet: #AppletWidget to work on.
521 *
522 * Description:  Remove the plug from the panel, this will destroy the applet.
523 * You can only call this once for each applet.
524 **/
525void
526applet_widget_remove(AppletWidget *applet)
527{
528        CORBA_Environment ev;
529        CustomAppletServant *servant;
530        g_return_if_fail(applet != NULL);
531        g_return_if_fail(IS_APPLET_WIDGET(applet));
532
533        CORBA_exception_init(&ev);
534        servant = applet->_priv->corbadat;
535        goad_server_unregister(CORBA_OBJECT_NIL, servant->goad_id,
536                               "server", &ev);
537
538        GNOME_PanelSpot_unregister_us(CD(applet)->pspot, &ev);
539        CORBA_exception_free(&ev);
540}
541
542/**
543 * applet_widget_sync_config:
544 * @applet: #AppletWidget to work on.
545 *
546 * Description:  Tell the panel to save our session here (just saves, no
547 * shutdown).  This should be done when you change some of your config and want
548 * the panel to save it's config, you should NOT call this in the session_save
549 * handler as it will result in a locked panel, as it will actually trigger
550 * another session_save signal for you.  However it also asks for a complete
551 * panel save, so you should not do this too often, and only when the user
552 * has changed some preferences and you want to sync them to disk.
553 * Theoretically you don't even need to do that if you don't mind loosing
554 * settings on a panel crash or when the user kills the session without
555 * logging out properly, since the panel will always save your session when
556 * it exists.
557 **/
558void
559applet_widget_sync_config(AppletWidget *applet)
560{
561        CORBA_Environment ev;
562        g_return_if_fail(applet != NULL);
563        g_return_if_fail(IS_APPLET_WIDGET(applet));
564
565        CORBA_exception_init(&ev);
566        GNOME_PanelSpot_sync_config(CD(applet)->pspot, &ev);
567        CORBA_exception_free(&ev);
568}
569
570static const char*
571make_sane_name(const char *name)
572{
573        if(!name)
574                return NULL;
575        while(*name=='/')
576                name++;
577        if(*name)
578                return name;
579        return NULL;
580}
581
582static CallbackInfo *
583get_callback_info(GtkWidget *applet, const char *name)
584{
585        GSList *list;
586        CallbackInfo *info;
587
588        for(list=CD(applet)->callbacks;
589            list!=NULL;
590            list=g_slist_next(list)) {
591                info = (CallbackInfo *)list->data;
592                if(strcmp(name,info->name)==0)
593                        return info;
594        }
595
596        return NULL;
597}
598
599
600/*adds a callback to the callback hash*/
601static void
602gnome_panel_applet_register_callback(GtkWidget *applet,
603                                     const char *name,
604                                     const char *stock_item,
605                                     const char *menutext,
606                                     AppletCallbackFunc func,
607                                     gpointer data)
608{
609        CallbackInfo *info;
610        CORBA_Environment ev;
611
612        /*skip over leading '/'s*/
613        name = make_sane_name(name);
614
615        g_return_if_fail(name!=NULL);
616       
617        info = get_callback_info(applet,name);
618        if(!info) {
619                info = g_new0(CallbackInfo,1);
620                CD(applet)->callbacks = g_slist_prepend(CD(applet)->callbacks,
621                                                        info);
622        } else
623                g_free(info->name);
624
625        info->name = g_strdup(name);
626        info->func = func;
627        info->data = data;
628
629        CORBA_exception_init(&ev);
630        /*register the callback with the panel*/
631        GNOME_PanelSpot_add_callback(CD(applet)->pspot,
632                                     name, stock_item,
633                                     menutext, &ev);
634        CORBA_exception_free(&ev);
635}
636
637/**
638 * applet_widget_register_callback:
639 * @applet: #AppletWidget to work on.
640 * @name: path to the menu item.
641 * @menutext: text for the menu item.
642 * @func: #AppletCallbacFunc to call when the menu item is activated.
643 * @data: data passed to @func.
644 *
645 * Description:  Adds a menu item to the applet's context menu.  The name
646 * should be a path that is separated by '/' and ends in the name of this
647 * item.  You need to add any submenus with
648 * #applet_widget_register_callback_dir.
649 **/
650void
651applet_widget_register_callback(AppletWidget *applet,
652                                const char *name,
653                                const char *menutext,
654                                AppletCallbackFunc func,
655                                gpointer data)
656{
657        g_return_if_fail(applet != NULL);
658        g_return_if_fail(IS_APPLET_WIDGET(applet));
659        g_return_if_fail(name != NULL);
660        g_return_if_fail(menutext != NULL);
661        g_return_if_fail(func != NULL);
662
663        gnome_panel_applet_register_callback (GTK_WIDGET(applet),name,
664                                              "",menutext,func,data);
665}
666
667/**
668 * applet_widget_register_stock_callback:
669 * @applet: #AppletWidget to work on.
670 * @name: path to the menu item.
671 * @stock_type: GNOME_STOCK string to use for the pixmap
672 * @menutext: text for the menu item.
673 * @func: #AppletCallbacFunc to call when the menu item is activated.
674 * @data: data passed to @func.
675 *
676 * Description:  Adds a menu item to the applet's context menu with a stock
677 * GNOME pixmap.  This works almost exactly the same as
678 * #applet_widget_register_callback.
679 **/
680void
681applet_widget_register_stock_callback(AppletWidget *applet,
682                                      const char *name,
683                                      const char *stock_type,
684                                      const char *menutext,
685                                      AppletCallbackFunc func,
686                                      gpointer data)
687{
688        g_return_if_fail(applet != NULL);
689        g_return_if_fail(IS_APPLET_WIDGET(applet));
690        g_return_if_fail(name != NULL);
691        g_return_if_fail(stock_type != NULL);
692        g_return_if_fail(menutext != NULL);
693        g_return_if_fail(func != NULL);
694
695        gnome_panel_applet_register_callback (GTK_WIDGET(applet),name,
696                                              stock_type,menutext,func,data);
697}
698
699
700/**
701 * applet_widget_unregister_callback:
702 * @applet: #AppletWidget to work on.
703 * @name: path to the menu item.
704 *
705 * Description:  Remove a menu item from the applet's context menu.  The
706 * @name should be the full path to the menu item.  This will not remove
707 * any submenus.
708 **/
709void
710applet_widget_unregister_callback(AppletWidget *applet,
711                                  const char *name)
712{
713        GSList *li;
714        CallbackInfo *cbi = NULL;
715        CORBA_Environment ev;
716
717        g_return_if_fail(applet != NULL);
718        g_return_if_fail(IS_APPLET_WIDGET(applet));
719
720        /*skip over leading '/'s*/
721        name = make_sane_name(name);
722
723        g_return_if_fail(name!=NULL);
724
725        for(li = CD(applet)->callbacks; li; li = g_slist_next(li)) {
726                if(!strcmp(((CallbackInfo*)li->data)->name, name)) {
727                        cbi = li->data;
728                        break;
729                }
730        }
731
732        if(!cbi) return;
733        CD(applet)->callbacks = g_slist_remove(CD(applet)->callbacks, cbi);
734
735        CORBA_exception_init(&ev);
736        GNOME_PanelSpot_remove_callback(CD(applet)->pspot, name, &ev);
737        CORBA_exception_free(&ev);
738}
739
740static void
741gnome_panel_applet_register_callback_dir(GtkWidget *applet,
742                                         const char *name,
743                                         const char *stock_item,
744                                         const char *menutext)
745{
746        char *n;
747        CORBA_Environment ev;
748
749        /*skip over leading '/'s*/
750        name = make_sane_name(name);
751        g_return_if_fail(name!=NULL);
752
753        if(name[strlen(name)-1]!='/')
754                n = g_strconcat(name,"/",NULL);
755        else
756                n = g_strdup(name);
757        CORBA_exception_init(&ev);
758        /*unregister the dir with the panel*/
759        GNOME_PanelSpot_add_callback(CD(applet)->pspot,
760                                     n,stock_item,menutext, &ev);
761        CORBA_exception_free(&ev);
762        g_free(n);
763}
764
765
766/**
767 * applet_widget_register_callback_dir:
768 * @applet: #AppletWidget to work on.
769 * @name: path to the menu item.
770 * @menutext: text for the menu item.
771 *
772 * Description:  Adds a submenu to the applet's context menu.  The @name
773 * should be the full path of the new submenu with the name of the new
774 * submenu as the last part of the path.  The @name can, but doesn't
775 * have to be terminated with a '/'.
776 **/
777void
778applet_widget_register_callback_dir(AppletWidget *applet,
779                                    const char *name,
780                                    const char *menutext)
781{
782        g_return_if_fail(applet != NULL);
783        g_return_if_fail(IS_APPLET_WIDGET(applet));
784        g_return_if_fail(name != NULL);
785        g_return_if_fail(menutext != NULL);
786
787        gnome_panel_applet_register_callback_dir (GTK_WIDGET(applet),name,
788                                                  "",menutext);
789}
790
791
792/**
793 * applet_widget_register_stock_callback_dir:
794 * @applet: #AppletWidget to work on.
795 * @name: path to the menu item.
796 * @stock_type: GNOME_STOCK string to use for the pixmap
797 * @menutext: text for the menu item.
798 *
799 * Description:  Adds a submenu to the applet's context menu with a stock
800 * GNOME pixmap.  This is similiar to #applet_widget_register_callback_dir.
801 **/
802void
803applet_widget_register_stock_callback_dir(AppletWidget *applet,
804                                          const char *name,
805                                          const char *stock_type,
806                                          const char *menutext)
807{
808        g_return_if_fail(applet != NULL);
809        g_return_if_fail(IS_APPLET_WIDGET(applet));
810        g_return_if_fail(name != NULL);
811        g_return_if_fail(stock_type != NULL);
812        g_return_if_fail(menutext != NULL);
813
814        gnome_panel_applet_register_callback_dir (GTK_WIDGET(applet),name,
815                                                  stock_type,menutext);
816}
817
818/**
819 * applet_widget_unregister_callback_dir:
820 * @applet: #AppletWidget to work on.
821 * @name: path to the menu item.
822 *
823 * Description:  Removes a submenu from the applet's context menu.  Use
824 * this instead of #applet_widget_unregister_callback to remove submenus.
825 * The @name can be, but doesn't have to be terminated with a '/'.  If you
826 * have not removed the subitems of this menu, it will still be shown but
827 * without it's title or icon.  So make sure to first remove any items and
828 * submenus before calling this function.
829 **/
830void
831applet_widget_unregister_callback_dir(AppletWidget *applet, const char *name)
832{
833        CORBA_Environment ev;
834        char *n;
835        g_return_if_fail(applet != NULL);
836        g_return_if_fail(IS_APPLET_WIDGET(applet));
837
838        /*skip over leading '/'s*/
839        name = make_sane_name(name);
840        if(name[strlen(name)-1]!='/')
841                n = g_strconcat(name,"/",NULL);
842        else
843                n = g_strdup(name);
844
845        g_return_if_fail(name!=NULL);
846
847        /*unregister the callback with the panel*/
848        CORBA_exception_init(&ev);
849        GNOME_PanelSpot_remove_callback(CD(applet)->pspot, n, &ev);
850        CORBA_exception_free(&ev);
851        g_free(n);
852}
853
854/**
855 * applet_widget_callback_set_sensitive:
856 * @applet: #AppletWidget to work on.
857 * @name: path to the menu item.
858 * @sensitive: whether menu item should be sensitive.
859 *
860 * Description:  Sets the sensitivity of a menu item in the applet's
861 * context menu.
862 **/
863void
864applet_widget_callback_set_sensitive(AppletWidget *applet,
865                                     const char *name,
866                                     gboolean sensitive)
867{
868        CORBA_Environment ev;
869
870        g_return_if_fail(applet != NULL);
871        g_return_if_fail(IS_APPLET_WIDGET(applet));
872
873        /*skip over leading '/'s*/
874        name = make_sane_name(name);
875
876        g_return_if_fail(name!=NULL);
877
878        CORBA_exception_init(&ev);
879        GNOME_PanelSpot_callback_set_sensitive(CD(applet)->pspot, name,
880                                               sensitive, &ev);
881        CORBA_exception_free(&ev);
882}
883
884static CustomAppletServant *
885gnome_panel_applet_corba_init(AppletWidget *applet, const char *goad_id)
886{
887        PortableServer_POA poa;
888        CustomAppletServant *applet_servant;
889        CORBA_Environment ev;
890        GNOME_Applet applet_obj;
891        CORBA_ORB orb;
892        CORBA_char *privcfg;
893        CORBA_char *globcfg;
894
895        CORBA_exception_init(&ev);
896
897        orb = gnome_CORBA_ORB();
898
899        applet_servant = g_new0(CustomAppletServant, 1);
900        applet_servant->servant.vepv = &vepv;
901
902        POA_GNOME_Applet__init((POA_GNOME_Applet *)applet_servant, &ev);
903        pg_return_val_if_fail(&ev, ev._major == CORBA_NO_EXCEPTION, NULL);
904
905        applet_servant->poa = poa = (PortableServer_POA)
906                CORBA_ORB_resolve_initial_references(orb, "RootPOA", &ev);
907        pg_return_val_if_fail(&ev, ev._major == CORBA_NO_EXCEPTION, NULL);
908
909        PortableServer_POAManager_activate(PortableServer_POA__get_the_POAManager(poa, &ev), &ev);
910        pg_return_val_if_fail(&ev, ev._major == CORBA_NO_EXCEPTION, NULL);
911
912        applet_servant->objid =
913                PortableServer_POA_activate_object(poa, applet_servant,
914                                                   &ev);
915        pg_return_val_if_fail(&ev, ev._major == CORBA_NO_EXCEPTION, NULL);
916
917        applet_servant->obj = applet_obj =
918                PortableServer_POA_servant_to_reference(poa, applet_servant,
919                                                        &ev);
920        pg_return_val_if_fail(&ev, ev._major == CORBA_NO_EXCEPTION, NULL);
921
922        goad_server_register(CORBA_OBJECT_NIL, applet_obj, goad_id,
923                             "server", &ev);
924        pg_return_val_if_fail(&ev, ev._major == CORBA_NO_EXCEPTION, NULL);
925
926        if (panel_client == CORBA_OBJECT_NIL) {
927                panel_client =
928                        goad_server_activate_with_repo_id(NULL,
929                                                          "IDL:GNOME/Panel:1.0",
930                                                          0, NULL);
931
932                if(panel_client == CORBA_OBJECT_NIL) {
933                        g_warning(_("Cannot activate a panel object"));
934                        g_free (applet_servant);
935                        return NULL;
936                }
937        }
938
939        /*{  static volatile int stop_here = 0;
940                while(stop_here);}*/
941
942        /* we need to do this as 1.0 panel will crap out otherwise, it NEEDS
943           to know the applet as it's doing orient change signals during
944           this */
945        applet_servant->appwidget = applet;
946        /* this is just for consistency with the above */
947        applet_servant->goad_id = g_strdup(goad_id);
948
949        applet_servant->pspot = GNOME_Panel_add_applet(panel_client,
950                                                       applet_obj,
951                                                       (char *)goad_id,
952                                                       &privcfg,&globcfg,
953                                                       &applet_servant->winid,
954                                                       &ev);
955        pg_return_val_if_fail(&ev, ev._major == CORBA_NO_EXCEPTION, NULL);
956
957        if(privcfg && *privcfg)
958                applet->privcfgpath = g_strdup(privcfg);
959        else
960                applet->privcfgpath = NULL;
961        CORBA_free(privcfg);
962        if(globcfg && *globcfg)
963                applet->globcfgpath = g_strdup(globcfg);
964        else
965                applet->globcfgpath = NULL;
966        CORBA_free(globcfg);
967
968        /* initialize orient and size correctly */
969        applet->orient =
970                GNOME_PanelSpot__get_parent_orient(applet_servant->pspot,&ev);
971        if(ev._major) {
972                g_warning("CORBA Exception, can't get orient");
973                /* just recycle the exception */
974                CORBA_exception_free(&ev);
975                CORBA_exception_init(&ev);
976                applet->size = ORIENT_UP;
977        }
978        applet->size =
979                GNOME_PanelSpot__get_parent_size(applet_servant->pspot,&ev);
980        if(ev._major) {
981                g_warning("CORBA Exception, can't get size");
982                applet->size = PIXEL_SIZE_STANDARD;
983                /* no need to recycle the exception here, as we will free it
984                   next */
985        }
986
987        CORBA_exception_free(&ev);
988
989        return applet_servant;
990}
991
992
993/**
994 * applet_widget_new:
995 * @goad_id: The goad_id of the applet we are starting
996 *
997 * Description: Make a new applet and register us with the panel, if you
998 * decide to cancel the load before calling #applet_widget_add, you should
999 * call #applet_widget_abort_load.  This widget is a simple container but you
1000 * should always use only #applet_widget_add to add a child and you should
1001 * only use it once.
1002 *
1003 * Returns: A pointer to a new widget of type #AppletWidget, or %NULL if
1004 * something went wrong.
1005 **/
1006GtkWidget *
1007applet_widget_new(const char *goad_id)
1008{
1009        AppletWidget *applet;
1010
1011        applet = APPLET_WIDGET (gtk_type_new (applet_widget_get_type()));
1012        applet_widget_construct(applet, goad_id);
1013
1014        return GTK_WIDGET(applet);
1015}
1016
1017/**
1018 * applet_widget_construct:
1019 * @applet: #AppletWidget to work on
1020 * @goad_id: goad_id of the applet to construct
1021 *
1022 * Description: For bindings and subclassing only
1023 **/
1024void
1025applet_widget_construct(AppletWidget* applet, const char *goad_id)
1026{
1027        CustomAppletServant *corbadat;
1028        GdkWindow *win;
1029       
1030        g_return_if_fail(goad_id != NULL);
1031
1032        applet->_priv->corbadat = corbadat = gnome_panel_applet_corba_init(applet,goad_id);
1033
1034        if(!corbadat) {
1035                g_warning(_("Cannot start CORBA"));
1036                return;
1037        }
1038
1039        win = gdk_window_lookup(corbadat->winid);
1040
1041        gtk_plug_construct(GTK_PLUG(applet), corbadat->winid);
1042
1043        /* after doing all that we just take the socket and put it in limbo */
1044        if(win) {
1045                GtkWidget *socket;
1046                gdk_window_get_user_data (win, (gpointer *)&socket);
1047                if(socket) {
1048                        GtkWidget *temp_window =
1049                                gtk_window_new(GTK_WINDOW_TOPLEVEL);
1050                        applet->_priv->ebox = socket->parent;
1051                        gtk_widget_set_uposition(GTK_WIDGET(temp_window),
1052                                                 gdk_screen_width()+1,
1053                                                 gdk_screen_height()+1);
1054                        gtk_widget_realize(temp_window);
1055                        gtk_widget_reparent(GTK_WIDGET(socket),
1056                                            temp_window);
1057                        gtk_signal_connect_object(GTK_OBJECT(applet->_priv->ebox),
1058                                                  "destroy",
1059                                                  GTK_SIGNAL_FUNC(gtk_widget_destroy),
1060                                                  GTK_OBJECT(temp_window));
1061                }
1062        }
1063       
1064        gtk_signal_connect(GTK_OBJECT(applet),"destroy",
1065                           GTK_SIGNAL_FUNC(applet_widget_destroy),
1066                           NULL);
1067
1068        applet_count++;
1069}
1070
1071/**
1072 * applet_widget_get_applet_count:
1073 *
1074 * Description:  Gets the number of applets loaded in this this process.  If
1075 * this is a shared lib applet it will return the total number of shared lib
1076 * applets loaded.
1077 *
1078 * Returns:  The number of applets loaded.
1079 **/
1080int
1081applet_widget_get_applet_count(void)
1082{
1083        return applet_count;
1084}
1085
1086static gboolean
1087applet_event(GtkWidget *w, GdkEvent *event, AppletWidget *aw)
1088{
1089        GdkEventButton *bevent = (GdkEventButton *)event;
1090        if(event->type == GDK_BUTTON_PRESS &&
1091           (bevent->button == 3 || bevent->button == 2)) {
1092                XButtonEvent ev;
1093                GtkWidget *wi;
1094                GtkPlug *plug = GTK_PLUG(aw);
1095
1096                /* on local case */
1097                if(aw->_priv->ebox)
1098                        return gtk_widget_event(aw->_priv->ebox, event);
1099
1100                if((wi = gtk_grab_get_current()))
1101                        gtk_grab_remove(wi);
1102                gdk_pointer_ungrab(GDK_CURRENT_TIME);
1103                gdk_keyboard_ungrab(GDK_CURRENT_TIME);
1104                gdk_flush();
1105                gtk_signal_emit_stop_by_name(GTK_OBJECT(w),
1106                                             "event");
1107                ev.type = ButtonPress;
1108                ev.send_event = True;
1109                ev.display = GDK_DISPLAY();
1110                ev.window = GDK_WINDOW_XWINDOW(plug->socket_window);
1111                ev.subwindow = None;
1112                ev.time = bevent->time;
1113                ev.x = bevent->x;
1114                ev.y = bevent->y;
1115                ev.x_root = bevent->x_root;
1116                ev.y_root = bevent->y_root;
1117                ev.state = bevent->state;
1118                ev.button = bevent->button;
1119                ev.same_screen = True;
1120                /* in the local case send it to our ebox */
1121                if(aw->_priv->ebox && aw->_priv->ebox->window) {
1122                        XSendEvent(GDK_DISPLAY(),
1123                                   GDK_WINDOW_XWINDOW(aw->_priv->ebox->window),
1124                                   True,NoEventMask,(XEvent *)&ev);
1125                } else if(plug->socket_window)
1126                        XSendEvent(GDK_DISPLAY(),
1127                                   GDK_WINDOW_XWINDOW(plug->socket_window),
1128                                   True,NoEventMask,(XEvent *)&ev);
1129               
1130                return TRUE;
1131        }
1132        return FALSE;
1133}
1134
1135static void
1136bind_applet_events(GtkWidget *widget, gpointer data)
1137{
1138        if (!GTK_WIDGET_NO_WINDOW(widget)) {
1139                gtk_signal_connect(GTK_OBJECT(widget), "event",
1140                                   (GtkSignalFunc) applet_event,
1141                                   data);
1142        }
1143       
1144        if (GTK_IS_CONTAINER(widget))
1145                gtk_container_foreach (GTK_CONTAINER (widget),
1146                                       bind_applet_events, data);
1147}
1148
1149static void
1150destroy_the_applet(GtkWidget *w, AppletWidget *applet)
1151{
1152        applet->_priv->ebox = NULL;
1153        gtk_widget_destroy(GTK_WIDGET(applet));
1154}
1155
1156/**
1157 * applet_widget_add_full:
1158 * @applet: the #AppletWidget to work with
1159 * @widget: the child to add
1160 * @bind_events: bind 2nd and 3rd button events over the applet if %TRUE
1161 *
1162 * Description:  Add a child (@widget) to the @applet.  This finishes the
1163 * handshaking with the panel started in @applet_widget_new.  You should never
1164 * call this function twice for the same @applet and you should always use
1165 * this function rather then #gtk_container_add.  If you have already created
1166 * an applet widget with #applet_widget_new, but need to cancel the loading
1167 * of the applet, use #applet_widget_abort_load.  This function is only for
1168 * special applets and you should use #applet_widget_bind_events on some
1169 * internal widget if @bind_events was %FALSE.  Normally you'll just want to
1170 * use #applet_widget_add.
1171 **/
1172void
1173applet_widget_add_full(AppletWidget *applet, GtkWidget *widget,
1174                       gboolean bind_events)
1175{
1176        CORBA_Environment ev;
1177
1178        g_return_if_fail(applet != NULL);
1179        g_return_if_fail(IS_APPLET_WIDGET(applet));
1180        g_return_if_fail(widget != NULL);
1181        g_return_if_fail(GTK_IS_WIDGET(widget));
1182
1183        if(applet->_priv->ebox) {
1184                gtk_container_add(GTK_CONTAINER(applet->_priv->ebox), widget);
1185                gtk_signal_connect(GTK_OBJECT(widget), "destroy",
1186                                   GTK_SIGNAL_FUNC(destroy_the_applet),
1187                                   applet);
1188        } else
1189                gtk_container_add(GTK_CONTAINER(applet), widget);
1190
1191
1192        CORBA_exception_init(&ev);
1193 
1194        GNOME_PanelSpot_register_us(CD(applet)->pspot, &ev);
1195
1196        if(ev._major) {
1197                g_warning(_("CORBA Exception"));
1198                CORBA_exception_free(&ev);
1199                gtk_widget_destroy(widget);
1200                return;
1201        }
1202
1203        CORBA_exception_free(&ev);
1204
1205        if(bind_events) {
1206                if(applet->_priv->ebox)
1207                        bind_applet_events(widget, applet);
1208                else
1209                        bind_applet_events(GTK_WIDGET(applet), applet);
1210        }
1211
1212        applet->_priv->added_child = TRUE;
1213}
1214
1215/**
1216 * applet_widget_add:
1217 * @applet: the #AppletWidget to work with
1218 * @widget: the child to add
1219 *
1220 * Description:  Add a child (@widget) to the @applet.  This finishes the
1221 * handshaking with the panel started in @applet_widget_new.  You should never
1222 * call this function twice for the same @applet and you should always use
1223 * this function rather then #gtk_container_add.  If you have already created
1224 * an applet widget with #applet_widget_new, but need to cancel the loading
1225 * of the applet, use #applet_widget_abort_load.
1226 **/
1227void
1228applet_widget_add(AppletWidget *applet, GtkWidget *widget)
1229{
1230        applet_widget_add_full(applet, widget, TRUE);
1231}
1232
1233/**
1234 * applet_widget_bind_events:
1235 * @applet: the #AppletWidget to work with
1236 * @widget: the widget over which to bind events
1237 *
1238 * Description:  Binds the 2nd and 3rd button clicks over this widget.
1239 * Normally this is done during #applet_widget_add, but if you need to
1240 * bind events over a widget which you added later, use this function.
1241 **/
1242void
1243applet_widget_bind_events(AppletWidget *applet, GtkWidget *widget)
1244{
1245        g_return_if_fail(applet != NULL);
1246        g_return_if_fail(IS_APPLET_WIDGET(applet));
1247        g_return_if_fail(widget != NULL);
1248        g_return_if_fail(IS_APPLET_WIDGET(widget));
1249       
1250        if(applet->_priv->ebox && GTK_WIDGET(applet) == widget) {
1251                GtkWidget *child = GTK_BIN(applet->_priv->ebox)->child;
1252                if(child) bind_applet_events(child, applet);
1253        } else
1254                bind_applet_events(GTK_WIDGET(widget), applet);
1255}
1256
1257/**
1258 * applet_widget_set_widget_tooltip:
1259 * @applet: the #AppletWidget to work with
1260 * @widget: the widget to set tooltip on
1261 * @text: the tooltip text
1262 *
1263 * Description:  Set a tooltip on the @widget that will follow the tooltip
1264 * setting from the panel configuration.
1265 **/
1266void
1267applet_widget_set_widget_tooltip(AppletWidget *applet,
1268                                 GtkWidget *widget,
1269                                 const char *text)
1270{
1271        g_return_if_fail(applet != NULL);
1272        g_return_if_fail(IS_APPLET_WIDGET(applet));
1273        g_return_if_fail(widget != NULL);
1274        g_return_if_fail(GTK_IS_WIDGET(widget));
1275
1276        if(!applet_tooltips)
1277                applet_tooltips = gtk_tooltips_new();
1278
1279        gtk_tooltips_set_tip (applet_tooltips,  widget, text, NULL);
1280}
1281
1282/**
1283 * applet_widget_set_tooltip:
1284 * @applet: the #AppletWidget to work with
1285 * @text: the tooltip text
1286 *
1287 * Description:  Set a tooltip on the entire applet that will follow the
1288 * tooltip setting from the panel configuration.
1289 **/
1290void
1291applet_widget_set_tooltip(AppletWidget *applet, const char *text)
1292{
1293        CORBA_Environment ev;
1294        g_return_if_fail(applet != NULL);
1295        g_return_if_fail(IS_APPLET_WIDGET(applet));
1296
1297        CORBA_exception_init(&ev);
1298        GNOME_PanelSpot__set_tooltip(CD(applet)->pspot, text?text:"", &ev);
1299        if(ev._major) {
1300                g_warning(_("CORBA Exception"));
1301                CORBA_exception_free(&ev);
1302                return;
1303        }
1304        CORBA_exception_free(&ev);
1305}
1306
1307/**
1308 * applet_widget_get_panel_orient:
1309 * @applet: the #AppletWidget to work with
1310 *
1311 * Description:  Gets the orientation of the panel this widget is on.
1312 * it can be one of ORIENT_UP, ORIENT_DOWN, ORIENT_LEFT and ORIENT_RIGHT.
1313 * This is not the position of the panel, but rather the direction that the
1314 * applet should be "reaching out".  So any arrows should for example point
1315 * in this direction.  It will be ORIENT_UP or ORIENT_DOWN for horizontal
1316 * panels and ORIENT_LEFT or ORIENT_RIGHT for vertical panels
1317 *
1318 * Returns:  PanelOrientType enum of the orientation
1319 **/
1320PanelOrientType
1321applet_widget_get_panel_orient(AppletWidget *applet)
1322{
1323        g_return_val_if_fail(applet != NULL,ORIENT_UP);
1324        g_return_val_if_fail(IS_APPLET_WIDGET(applet), ORIENT_UP);
1325
1326        return applet->orient;
1327}
1328
1329/**
1330 * applet_widget_get_panel_pixel_size:
1331 * @applet: the #AppletWidget to work with
1332 *
1333 * Description:  Gets the width of the panel in pixels.  This is not the
1334 * actual size, but the recomended one.  The panel may be streched if the
1335 * applets use larger sizes then this.
1336 *
1337 * Returns:  Size of panel in pixels
1338 **/
1339int
1340applet_widget_get_panel_pixel_size(AppletWidget *applet)
1341{
1342        g_return_val_if_fail(applet != NULL, PIXEL_SIZE_STANDARD);
1343        g_return_val_if_fail(IS_APPLET_WIDGET(applet), PIXEL_SIZE_STANDARD);
1344
1345        return applet->size;
1346}
1347
1348/**
1349 * applet_widget_get_free_space:
1350 * @applet: the #AppletWidget to work with
1351 *
1352 * Description:  Gets the free space left that you can use for your applet.
1353 * This is the number of pixels around your applet to both sides.  If you
1354 * strech by this amount you will not disturb any other applets.  If you
1355 * are on a packed panel 0 will be returned.
1356 *
1357 * Returns:  Free space left for your applet.
1358 **/
1359int
1360applet_widget_get_free_space(AppletWidget *applet)
1361{
1362        CORBA_Environment ev;
1363        int r;
1364        g_return_val_if_fail(applet != NULL, 0);
1365        g_return_val_if_fail(IS_APPLET_WIDGET(applet), 0);
1366       
1367        CORBA_exception_init(&ev);
1368        r = GNOME_PanelSpot__get_free_space(CD(applet)->pspot, &ev);
1369        if(ev._major) {
1370                g_warning(_("CORBA Exception"));
1371                CORBA_exception_free(&ev);
1372                return 0;
1373        }
1374        CORBA_exception_free(&ev);
1375        return r;
1376}
1377
1378/**
1379 * applet_widget_send_position:
1380 * @applet: the #AppletWidget to work with
1381 * @enable: whether to enable or disable change_position signal
1382 *
1383 * Description:  If you need to get a signal everytime this applet changes
1384 * position relative to the screen, you need to run this function with %TRUE
1385 * for @enable and bind the change_position signal on the applet.  This signal
1386 * can be quite CPU/bandwidth consuming so only applets which need it should
1387 * use it.  By default change_position is not sent.
1388 **/
1389void
1390applet_widget_send_position(AppletWidget *applet, gboolean enable)
1391{
1392        CORBA_Environment ev;
1393        g_return_if_fail(applet != NULL);
1394        g_return_if_fail(IS_APPLET_WIDGET(applet));
1395       
1396        CORBA_exception_init(&ev);
1397        GNOME_PanelSpot__set_send_position(CD(applet)->pspot, enable, &ev);
1398        if(ev._major) {
1399                g_warning(_("CORBA Exception"));
1400                CORBA_exception_free(&ev);
1401                return;
1402        }
1403        CORBA_exception_free(&ev);
1404}
1405
1406/**
1407 * applet_widget_send_draw:
1408 * @applet: the #AppletWidget to work with
1409 * @enable: whether to enable or disable do_draw signal
1410 *
1411 * Description:  If you are using rgb background drawing, call this function
1412 * with %TRUE for @enable, and then bind the do_draw signal.  Inside that
1413 * signal you can get an RGB buffer to draw on with #applet_widget_get_rgb_bg.
1414 * The do_draw signal will only be sent when the RGB truly changed.
1415 **/
1416void
1417applet_widget_send_draw(AppletWidget *applet, gboolean enable)
1418{
1419        CORBA_Environment ev;
1420        g_return_if_fail(applet != NULL);
1421        g_return_if_fail(IS_APPLET_WIDGET(applet));
1422       
1423        CORBA_exception_init(&ev);
1424        GNOME_PanelSpot__set_send_draw(CD(applet)->pspot, enable, &ev);
1425        if(ev._major) {
1426                g_warning(_("CORBA Exception"));
1427                CORBA_exception_free(&ev);
1428                return;
1429        }
1430        CORBA_exception_free(&ev);
1431}
1432
1433/**
1434 * applet_widget_get_rgb_bg:
1435 * @applet: the #AppletWidget to work with
1436 * @rgb: pointer to a pointer to which the rgb buffer will be returned
1437 * @w: pointer to an integer in which the width will be stored
1438 * @h: pointer to an integer in which the height will be stored
1439 * @rowstride: pointer to an integer in which the rowstride will be stored
1440 *
1441 * Description:  Gets an rgb buffer that you can draw your applet on.  Useful
1442 * in conjunction with the do_draw signal and the #applet_widget_send_draw
1443 * method.  The rgb should be freed after use with g_free.
1444 **/
1445void
1446applet_widget_get_rgb_bg(AppletWidget *applet, guchar **rgb,
1447                         int *w, int *h, int *rowstride)
1448{
1449        CORBA_Environment ev;
1450        GNOME_Panel_RgbImage *image;
1451
1452        g_return_if_fail(applet!=NULL);
1453        g_return_if_fail(IS_APPLET_WIDGET(applet));
1454        g_return_if_fail(rgb!=NULL);
1455        g_return_if_fail(w!=NULL);
1456        g_return_if_fail(h!=NULL);
1457        g_return_if_fail(rowstride!=NULL);
1458       
1459        CORBA_exception_init(&ev);
1460        image = GNOME_PanelSpot__get_rgb_background(CD(applet)->pspot, &ev);
1461        if(ev._major) {
1462                g_warning(_("CORBA Exception"));
1463                CORBA_exception_free(&ev);
1464                return;
1465        }
1466        CORBA_exception_free(&ev);
1467
1468        *w = image->width;
1469        *h = image->height;
1470        if(!image->color_only)
1471                *rowstride = image->rowstride;
1472        else
1473                *rowstride = (*w)*3;
1474
1475        if(image->data._buffer) {
1476                *rgb = g_new(guchar, (*h)*(*rowstride));
1477                if(!image->color_only) {
1478                        int size = (*h)*(*rowstride);
1479                        if(image->data._length<size)
1480                                size = image->data._length;
1481                        memcpy(*rgb,image->data._buffer,
1482                               sizeof(guchar)*size);
1483                } else {
1484                        int i;
1485                        int r;
1486                        int g;
1487                        int b;
1488                        guchar *p;
1489
1490                        r = *(image->data._buffer);
1491                        g = *(image->data._buffer+1);
1492                        b = *(image->data._buffer+2);
1493
1494                        p = *rgb;
1495                        for(i=0;i<(*w)*(*h);i++) {
1496                                *(p++) = r;
1497                                *(p++) = g;
1498                                *(p++) = b;
1499                        }
1500                }
1501        } else {
1502                /* this will make a black background */
1503                *rgb = g_new0(guchar, (*h)*(*rowstride));
1504        }
1505       
1506        CORBA_free(image);
1507}
1508
1509/**
1510 * applet_widget_init:
1511 * @app_id: applet id
1512 * @app_version: applet version
1513 * @argc: the argc passed to main
1514 * @argv: the argv passed to main
1515 * @options: extra popt options to use
1516 * @flags: extra popt flags
1517 * @return_ctx: return popt context
1518 *
1519 * Description: Initialize the applet library, gnome and corba.
1520 * Don't call this if your app has an applet, but your process is not
1521 * simply an applet process.  This will 1) disconnect the session
1522 * manager and 2) setup stuff to call gtk_main_quit when the last applet
1523 * you create exists.  And that's all really.
1524 *
1525 * Returns: A boolean, %TRUE if we succeed, %FALSE if an error occured
1526 **/
1527gboolean
1528applet_widget_init(const char *app_id,
1529                   const char *app_version,
1530                   int argc,
1531                   char **argv,
1532                   struct poptOption *options,
1533                   unsigned int flags,
1534                   poptContext *return_ctx)
1535{
1536        CORBA_Environment ev;
1537        CORBA_ORB orb;
1538
1539        /*this is not called for shlib applets so we set it to true here*/
1540        die_on_last = TRUE;
1541
1542        gnome_client_disable_master_connection ();
1543        CORBA_exception_init(&ev);
1544        orb = gnome_CORBA_init_with_popt_table(app_id, app_version,
1545                                               &argc, argv,
1546                                               options, flags, return_ctx,
1547                                               GNORBA_INIT_SERVER_FUNC, &ev);
1548        if(ev._major != CORBA_NO_EXCEPTION) {
1549                CORBA_exception_free(&ev);
1550                return FALSE;
1551        }
1552
1553        CORBA_exception_free(&ev);
1554
1555        return TRUE;
1556}
1557
1558/*****************************************************************************
1559  CORBA STUFF
1560 *****************************************************************************/
1561
1562/**
1563 * applet_widget_gtk_main:
1564 *
1565 * Description: Run the main loop, just like #gtk_main
1566 **/
1567void
1568applet_widget_gtk_main(void)
1569{
1570        gtk_main();
1571}
1572
1573/**
1574 * applet_widget_gtk_main_quit:
1575 *
1576 * Description: Quit the main loop, just like #gtk_main_quit
1577 **/
1578void
1579applet_widget_gtk_main_quit (void)
1580{
1581        gtk_main_quit();
1582}
1583
1584/**
1585 * applet_widget_panel_quit:
1586 *
1587 * Description: Trigger 'Log out' on the panel.  This shouldn't be
1588 * used in normal applets, as it is not normal for applets to trigger
1589 * a logout.
1590 **/
1591void
1592applet_widget_panel_quit (void)
1593{
1594        CORBA_Environment ev;
1595
1596        CORBA_exception_init(&ev);
1597        GNOME_Panel_quit(panel_client, &ev);
1598        if(ev._major) {
1599                g_warning(_("CORBA Exception"));
1600                CORBA_exception_free(&ev);
1601                return;
1602        }
1603        CORBA_exception_free(&ev);
1604}
1605
1606/**
1607 * applet_widget_queue_resize:
1608 * @applet: #AppletWidget to work on
1609 *
1610 * Description:  For shared library applets this calls #gtk_widget_queue_resize
1611 * on the internal panel eventbox, for external applets this just calls this on
1612 * the #AppletWidget itself, but in both cases it forces a resize of the socket
1613 * on the panel
1614 **/
1615void
1616applet_widget_queue_resize(AppletWidget *applet)
1617{
1618        GtkPlug *plug;
1619
1620        g_return_if_fail(applet != NULL);
1621        g_return_if_fail(IS_APPLET_WIDGET(applet));
1622
1623        plug = GTK_PLUG(applet);
1624
1625        if(applet->_priv->ebox)
1626                gtk_widget_queue_resize(applet->_priv->ebox);
1627        else
1628                gtk_widget_queue_resize(GTK_WIDGET(applet));
1629}
1630
1631static void
1632server_applet_change_orient(PortableServer_Servant _servant,
1633                            const GNOME_Panel_OrientType orient,
1634                            CORBA_Environment *ev)
1635{
1636        CustomAppletServant *servant = (CustomAppletServant *)_servant;
1637        servant->appwidget->orient = orient;
1638        if (servant->appwidget->_priv->frozen_level > 0) {
1639                servant->appwidget->_priv->frozen_got_orient = TRUE;
1640                servant->appwidget->_priv->frozen_orient = (GNOME_Panel_OrientType)orient;
1641        } else {
1642                gtk_signal_emit(GTK_OBJECT(servant->appwidget),
1643                                applet_widget_signals[CHANGE_ORIENT_SIGNAL],
1644                                (GNOME_Panel_OrientType)orient);
1645        }
1646}
1647
1648static void
1649server_applet_change_size (PortableServer_Servant _servant,
1650                           const CORBA_short size,
1651                           CORBA_Environment *ev)
1652{
1653        CustomAppletServant *servant = (CustomAppletServant *)_servant;
1654        servant->appwidget->size = size;
1655        if (servant->appwidget->_priv->frozen_level > 0) {
1656                servant->appwidget->_priv->frozen_got_size = TRUE;
1657                servant->appwidget->_priv->frozen_size = size;
1658        } else {
1659                gtk_signal_emit(GTK_OBJECT(servant->appwidget),
1660                                applet_widget_signals[CHANGE_PIXEL_SIZE_SIGNAL],
1661                                size);
1662        }
1663}
1664
1665static void
1666server_applet_do_callback(PortableServer_Servant _servant,
1667                          const CORBA_char * callback_name,
1668                          CORBA_Environment *ev)
1669{
1670        CustomAppletServant *servant = (CustomAppletServant *)_servant;
1671        GSList *list;
1672        CallbackInfo *info;
1673
1674        for(list = servant->callbacks;
1675            list!=NULL;list = g_slist_next (list)) {
1676                info = (CallbackInfo *)list->data;
1677                if(strcmp(info->name,(char *)callback_name)==0) {
1678                        (*(info->func)) (servant->appwidget,
1679                                         info->data);
1680                        return;
1681                }
1682        }
1683}
1684
1685/* this is the new session saving call and the one which should be used */
1686static void
1687server_applet_save_session(PortableServer_Servant _servant,
1688                           const CORBA_char * cfgpath,
1689                           const CORBA_char * globcfgpath,
1690                           const CORBA_unsigned_long cookie,
1691                           CORBA_Environment *ev)
1692{
1693        CustomAppletServant *servant = (CustomAppletServant *)_servant;
1694        AppletWidget *applet;
1695        char *cfg = g_strdup(cfgpath);
1696        char *globcfg = g_strdup(globcfgpath);
1697
1698        int return_val = FALSE;
1699
1700        applet = servant->appwidget;
1701        gtk_signal_emit(GTK_OBJECT(applet),
1702                        applet_widget_signals[SAVE_SESSION_SIGNAL],
1703                        cfg, globcfg, &return_val);
1704        g_free(cfg);
1705        g_free(globcfg);
1706       
1707        /*return_val of true would mean that the applet handeled the
1708          session saving itself, therefore we pass the reverse to the
1709          corba function */
1710        GNOME_PanelSpot_done_session_save(CD(applet)->pspot,
1711                                          !return_val, cookie, ev);
1712}
1713
1714/* this is here just that if an applet uses the new lib with the old
1715   panel it will still work */
1716static CORBA_boolean
1717server_applet_session_save(PortableServer_Servant _servant,
1718                           const CORBA_char * cfgpath,
1719                           const CORBA_char * globcfgpath,
1720                           CORBA_Environment *ev)
1721{
1722        CustomAppletServant *servant = (CustomAppletServant *)_servant;
1723        AppletWidget *applet;
1724        char *cfg = g_strdup(cfgpath);
1725        char *globcfg = g_strdup(globcfgpath);
1726
1727        int return_val = FALSE;
1728
1729        applet = servant->appwidget;
1730        gtk_signal_emit(GTK_OBJECT(applet),
1731                        applet_widget_signals[SAVE_SESSION_SIGNAL],
1732                        cfg, globcfg, &return_val);
1733        g_free(cfg);
1734        g_free(globcfg);
1735
1736        return !return_val;
1737}
1738
1739static void
1740server_applet_back_change(PortableServer_Servant _servant,
1741                          const GNOME_Panel_BackInfoType *backing,
1742                          CORBA_Environment *ev)
1743{
1744        CustomAppletServant *servant = (CustomAppletServant *)_servant;
1745        GdkColor color={0,0,0,0}, *cptr = NULL;
1746        char *pptr = NULL;
1747
1748        switch(backing->_d) {
1749        case GNOME_Panel_BACK_COLOR:
1750                color.red = backing->_u.c.red;
1751                color.green = backing->_u.c.green;
1752                color.blue = backing->_u.c.blue;
1753                cptr = &color;
1754                break;
1755        case GNOME_Panel_BACK_PIXMAP:
1756        case GNOME_Panel_BACK_TRANSLUCENT:
1757                pptr = backing->_u.pmap;
1758                break;
1759        default:
1760                break;
1761        }
1762
1763        if(servant->appwidget->_priv->frozen_level>0) {
1764                servant->appwidget->_priv->frozen_got_back = TRUE;
1765                servant->appwidget->_priv->frozen_back_type = (GNOME_Panel_BackType)backing->_d;
1766                g_free(servant->appwidget->_priv->frozen_back_pixmap);
1767                if(servant->appwidget->_priv->frozen_back_pixmap)
1768                        servant->appwidget->_priv->frozen_back_pixmap = g_strdup(pptr);
1769                else
1770                        servant->appwidget->_priv->frozen_back_pixmap = NULL;
1771                servant->appwidget->_priv->frozen_back_color = color;
1772        } else {
1773                gtk_signal_emit(GTK_OBJECT(servant->appwidget),
1774                                applet_widget_signals[BACK_CHANGE_SIGNAL],
1775                                (GNOME_Panel_BackType)backing->_d,
1776                                pptr,
1777                                cptr);
1778        }
1779}
1780
1781static void
1782server_applet_draw(PortableServer_Servant _servant,
1783                   CORBA_Environment *ev)
1784{
1785        CustomAppletServant *servant = (CustomAppletServant *)_servant;
1786        gtk_signal_emit(GTK_OBJECT(servant->appwidget),
1787                        applet_widget_signals[DO_DRAW_SIGNAL]);
1788}
1789
1790static void
1791server_applet_set_tooltips_state(PortableServer_Servant _servant,
1792                                 const CORBA_boolean enabled,
1793                                 CORBA_Environment *ev)
1794{
1795        CustomAppletServant *servant = (CustomAppletServant *)_servant;
1796        if(!applet_tooltips)
1797                applet_tooltips = gtk_tooltips_new();
1798
1799        if(enabled)
1800                gtk_tooltips_enable(applet_tooltips);
1801        else
1802                gtk_tooltips_disable(applet_tooltips);
1803
1804        gtk_signal_emit(GTK_OBJECT(servant->appwidget),
1805                        applet_widget_signals[TOOLTIP_STATE_SIGNAL],
1806                        enabled);
1807}
1808
1809static void
1810server_applet_change_position(PortableServer_Servant _servant,
1811                              const CORBA_short x,
1812                              const CORBA_short y,
1813                              CORBA_Environment *ev)
1814{
1815        CustomAppletServant *servant = (CustomAppletServant *)_servant;
1816        if(servant->appwidget->_priv->frozen_level>0) {
1817                servant->appwidget->_priv->frozen_got_position = TRUE;
1818                servant->appwidget->_priv->frozen_position_x = x;
1819                servant->appwidget->_priv->frozen_position_y = y;
1820        } else {
1821                gtk_signal_emit(GTK_OBJECT(servant->appwidget),
1822                                applet_widget_signals[CHANGE_POSITION_SIGNAL],
1823                                (int)x,
1824                                (int)y);
1825        }
1826}
1827
1828static CORBA_char *
1829server_applet__get_goad_id(PortableServer_Servant _servant,
1830                           CORBA_Environment *ev)
1831{
1832        CustomAppletServant *servant = (CustomAppletServant *)_servant;
1833        return CORBA_string_dup(servant->goad_id);
1834}
1835
1836static void
1837server_applet_freeze_changes(PortableServer_Servant _servant,
1838                             CORBA_Environment *ev)
1839{
1840        CustomAppletServant *servant = (CustomAppletServant *)_servant;
1841        servant->appwidget->_priv->frozen_level++;
1842}
1843
1844static void
1845server_applet_thaw_changes(PortableServer_Servant _servant,
1846                           CORBA_Environment *ev)
1847{
1848        CustomAppletServant *servant = (CustomAppletServant *)_servant;
1849        if(servant->appwidget->_priv->frozen_level>0)
1850                servant->appwidget->_priv->frozen_level--;
1851       
1852        if(servant->appwidget->_priv->frozen_level>0)
1853                return;
1854
1855        if(servant->appwidget->_priv->frozen_got_orient) {
1856                servant->appwidget->_priv->frozen_got_orient = FALSE;
1857                gtk_signal_emit(GTK_OBJECT(servant->appwidget),
1858                                applet_widget_signals[CHANGE_ORIENT_SIGNAL],
1859                                servant->appwidget->_priv->frozen_orient);
1860        }
1861        if(servant->appwidget->_priv->frozen_got_size) {
1862                servant->appwidget->_priv->frozen_got_size = FALSE;
1863                gtk_signal_emit(GTK_OBJECT(servant->appwidget),
1864                                applet_widget_signals[CHANGE_PIXEL_SIZE_SIGNAL],
1865                                servant->appwidget->_priv->frozen_size);
1866        }
1867        if(servant->appwidget->_priv->frozen_got_back) {
1868                servant->appwidget->_priv->frozen_got_back = FALSE;
1869                gtk_signal_emit(GTK_OBJECT(servant->appwidget),
1870                                applet_widget_signals[BACK_CHANGE_SIGNAL],
1871                                servant->appwidget->_priv->frozen_back_type,
1872                                servant->appwidget->_priv->frozen_back_pixmap,
1873                                &servant->appwidget->_priv->frozen_back_color);
1874                g_free(servant->appwidget->_priv->frozen_back_pixmap);
1875        }
1876        if(servant->appwidget->_priv->frozen_got_position) {
1877                servant->appwidget->_priv->frozen_got_position = FALSE;
1878                gtk_signal_emit(GTK_OBJECT(servant->appwidget),
1879                                applet_widget_signals[CHANGE_POSITION_SIGNAL],
1880                                servant->appwidget->_priv->frozen_position_x,
1881                                servant->appwidget->_priv->frozen_position_y);
1882        }
1883}
1884
1885/*XXX: this is not used!
1886static void
1887applet_handle_connection(GIOPConnection *cnx, gint source,
1888                         GdkInputCondition cond)
1889{
1890        switch(cond) {
1891        case GDK_INPUT_EXCEPTION:
1892                giop_main_handle_connection_exception(cnx);
1893                break;
1894        default:
1895                giop_main_handle_connection(cnx);
1896        }
1897}
1898*/
1899
1900/*XXX: this is not used!
1901static void
1902orb_add_connection(GIOPConnection *cnx)
1903{
1904        cnx->user_data =
1905                GINT_TO_POINTER(gtk_input_add_full(GIOP_CONNECTION_GET_FD(cnx),
1906                                                   GDK_INPUT_READ|
1907                                                     GDK_INPUT_EXCEPTION,
1908                                                   (GdkInputFunction)
1909                                                     applet_handle_connection,
1910                                                   NULL, cnx, NULL));
1911}
1912*/
1913
1914/*XXX: this is not used!
1915static void
1916orb_remove_connection(GIOPConnection *cnx)
1917{
1918        gtk_input_remove(GPOINTER_TO_INT(cnx->user_data));
1919}
1920*/
1921
1922/* Used by shlib applets */
1923/**
1924 * applet_widget_corba_activate:
1925 * @applet: widget to embed.
1926 * @poa: the POA to use.
1927 * @goad_id: the GOAD ID string for the applet.
1928 * @params: params passed when the applet is activated.
1929 * @impl_ptr:
1930 * @ev: CORBA environment to use for errors.
1931 *
1932 * Description: Duplicates the applet's CORBA object.  This should
1933 * be called when a shared library applet is activated.
1934 *
1935 * Returns: the duplication CORBA object to use.
1936 **/
1937CORBA_Object
1938applet_widget_corba_activate(GtkWidget *applet,
1939                             PortableServer_POA poa,
1940                             const char *goad_id,
1941                             const char **params,
1942                             gpointer *impl_ptr,
1943                             CORBA_Environment *ev)
1944{
1945        return CORBA_Object_duplicate(CD(applet)->obj, ev);
1946}
1947
1948/**
1949 * applet_widget_corba_deactivate:
1950 * @poa: the POA to use.
1951 * @goad_id: the GOAD ID of the applet.
1952 * @impl_ptr:
1953 * @ev: CORBA environment to use for errors.
1954 *
1955 * Description:
1956 **/
1957void
1958applet_widget_corba_deactivate(PortableServer_POA poa,
1959                               const char *goad_id,
1960                               gpointer impl_ptr,
1961                               CORBA_Environment *ev)
1962{
1963        /*FIXME: fill this in*/
1964}
1965
1966typedef struct {
1967        POA_GNOME_GenericFactory        servant;
1968        AppletFactoryActivator          afunc;
1969        AppletFactoryQuerier            qfunc;
1970        CORBA_Object                    fobj;
1971        PortableServer_ObjectId         *objid;
1972} AppletFactory;
1973
1974static CORBA_boolean
1975server_applet_factory_supports(PortableServer_Servant _servant,
1976                               const CORBA_char * obj_goad_id,
1977                               CORBA_Environment * ev)
1978{
1979        AppletFactory *servant = (AppletFactory *)_servant;
1980        if(servant->qfunc)
1981                return servant->qfunc(obj_goad_id);
1982
1983        g_message("No AppletFactoryQuerier to check on %s in panel applet",
1984                  obj_goad_id);
1985
1986        return CORBA_FALSE;
1987}
1988
1989static CORBA_Object
1990server_applet_factory_create_object(PortableServer_Servant _servant,
1991                                    const CORBA_char * goad_id,
1992                                    const GNOME_stringlist * params,
1993                                    CORBA_Environment * ev)
1994{
1995        AppletFactory *servant = (AppletFactory *)_servant;
1996        GtkWidget *applet;
1997
1998        applet = servant->afunc(goad_id, (const char **)params->_buffer,
1999                                params->_length);
2000
2001        if(!applet) {
2002                g_warning(_("Cannot create object"));
2003                return CORBA_OBJECT_NIL;
2004        }
2005
2006        if(!IS_APPLET_WIDGET(applet)) {
2007                g_warning(_("Object created is not AppletWidget"));
2008                gtk_widget_destroy(applet);
2009                return CORBA_OBJECT_NIL;
2010        }
2011
2012        return CORBA_Object_duplicate(CD(applet)->obj, ev);
2013}
2014
2015static POA_GNOME_GenericFactory__epv applet_factory_epv = {
2016        NULL,
2017        server_applet_factory_supports,
2018        server_applet_factory_create_object
2019};
2020
2021static POA_GNOME_GenericFactory__vepv applet_factory_vepv = {
2022        &base_epv,
2023        &applet_factory_epv
2024};
2025
2026/**
2027 * applet_factory_new:
2028 * @goad_id: GOAD ID of the factory to be registered.
2029 * @qfunc: #AppletFactoryQuerier to determine whether an applet with
2030 * a specified GOAD ID can be created.
2031 * @afunc: #AppletFactoryActivator to activate a specified GOAD ID.
2032 *
2033 * Description: create a new applet factory.  It is used for applets
2034 * that can run many applets from one process.
2035 **/
2036void applet_factory_new(const char *goad_id, AppletFactoryQuerier qfunc,
2037                        AppletFactoryActivator afunc)
2038{
2039        AppletFactory *f;
2040        CORBA_Environment ev;
2041        PortableServer_POA poa;
2042
2043        g_return_if_fail(afunc);
2044
2045        CORBA_exception_init(&ev);
2046
2047        f = g_new0(AppletFactory, 1);
2048        f->servant.vepv = &applet_factory_vepv;
2049        f->afunc = afunc;
2050        f->qfunc = qfunc;
2051        POA_GNOME_GenericFactory__init((PortableServer_Servant)f, &ev);
2052
2053        CORBA_exception_free(&ev);
2054
2055        poa = (PortableServer_POA)
2056                CORBA_ORB_resolve_initial_references(gnome_CORBA_ORB(),
2057                                                     "RootPOA", &ev);
2058
2059        PortableServer_POAManager_activate
2060                (PortableServer_POA__get_the_POAManager(poa, &ev), &ev);
2061
2062        pg_return_if_fail(&ev, ev._major == CORBA_NO_EXCEPTION);
2063
2064        f->objid = PortableServer_POA_activate_object(poa, f, &ev);
2065        pg_return_if_fail(&ev, ev._major == CORBA_NO_EXCEPTION);
2066
2067        f->fobj = PortableServer_POA_servant_to_reference(poa, f, &ev);
2068
2069        goad_server_register(CORBA_OBJECT_NIL, f->fobj, goad_id, "server", &ev);
2070}
Note: See TracBrowser for help on using the repository browser.