I have already detailed how this code was written from automatically generated code from ORBit. So, here is the raw code.
The first thing to do is to implement the GNOME::EmbeddableFactory. This is what the following code does. The factory is created, and it is registered against the GOAD. Typically, this code will be called by the goad_activate_factory function which itself is called by goad_activate_with_id (list, "Component", ...).
int main (int argc, char **argv) { CORBA_Environment ev; CORBA_ORB orb; CORBA_Object root_poa; PortableServer_POAManager root_poa_manager; CosNaming_NamingContext name_server; CORBA_Object obj; CORBA_exception_init (&ev); orb = gnome_CORBA_init ("a \"simple\" container", "1.0", &argc, argv, GNORBA_INIT_SERVER_FUNC, &ev); root_poa = CORBA_ORB_resolve_initial_references (orb, "RootPOA", &ev); root_poa_manager = PortableServer_POA__get_the_POAManager ( (PortableServer_POA) root_poa, &ev); PortableServer_POAManager_activate (root_poa_manager, &ev); /* this function will create all the other * needed interfaces */ obj = impl_GNOME_EmbeddableFactory__create ((PortableServer_POA) root_poa, &ev); /* register against the name service */ name_server = gnome_name_service_get (); goad_server_register (name_server, obj, goad_server_activation_id(), "server", &ev); /* finished !! */ CORBA_exception_free (&ev); gtk_main (); return 0; } |
Once the EmbeddableFactory is created and registered, the GOAD is likely to call the GNOME::EmbeddableFactory::create_object function to create our Embeddable object.
static CORBA_Object impl_GNOME_EmbeddableFactory_create_object(impl_POA_GNOME_EmbeddableFactory * servant, CORBA_char * goad_id, GNOME_stringlist * params, CORBA_Environment * ev) { CORBA_Object retval = CORBA_OBJECT_NIL; retval = impl_GNOME_Embeddable__create (servant->poa, ev); goad_server_register (CORBA_OBJECT_NIL, retval, goad_id, "server", ev); return retval; } |
The GNOME::Embeddable creation function, impl_GNOME_Embeddable__create is rather simple. It will simply do standard stuff and initialize the Embeddable with the "Ok ?!" data. (ie: the data which will be displayed on the button).
static GNOME_Embeddable impl_GNOME_Embeddable__create(PortableServer_POA poa, CORBA_Environment * ev) { GNOME_Embeddable retval; impl_POA_GNOME_Embeddable *newservant; PortableServer_ObjectId *objid; newservant = g_new0(impl_POA_GNOME_Embeddable, 1); newservant->servant.vepv = &impl_GNOME_Embeddable_vepv; newservant->poa = poa; strcpy (newservant->data, "Ok ?!");; POA_GNOME_Embeddable__init((PortableServer_Servant) newservant, ev); objid = PortableServer_POA_activate_object(poa, newservant, ev); CORBA_free(objid); retval = PortableServer_POA_servant_to_reference(poa, newservant, ev); return retval; } |
The next call which will be done to the Embeddable is to the Embeddable::set_client_site function. This function will call the ClientSite::show_window function to make sure the ClientSite knows that we will be doing some non-in-place activation.
static void impl_GNOME_Embeddable_set_client_site(impl_POA_GNOME_Embeddable * servant, GNOME_ClientSite client_site, CORBA_Environment * ev) { servant->client_site = CORBA_Object_duplicate (client_site, ev); /* tell the container that the embeddable will be activated in an external window */ GNOME_ClientSite_show_window (client_site, 1, ev); } |
The next step in this process is creating a new view which will be done with GNOME::Embeddable::new_view. We'll just create the view itself and store a pointer to this view in the embeddable servant. The view is also given a pointer to the corresponding ViewFrame and Embeddable.
static GNOME_View impl_GNOME_Embeddable_new_view(impl_POA_GNOME_Embeddable * servant, GNOME_ViewFrame frame, CORBA_Environment * ev) { GNOME_View view; impl_POA_GNOME_View *view_servant; view_servant = impl_GNOME_View__create (servant->poa, frame, servant, ev); servant->view_servant_list = g_slist_append (servant->view_servant_list, view_servant); view = PortableServer_POA_servant_to_reference(servant->poa, view_servant, ev); return view; } |
The impl_GNOME_View__create function just initializes some stuff.
static impl_POA_GNOME_View * impl_GNOME_View__create(PortableServer_POA poa, GNOME_ViewFrame frame, impl_POA_GNOME_Embeddable *embeddable_servant, CORBA_Environment * ev) { impl_POA_GNOME_View *newservant; PortableServer_ObjectId *objid; newservant = g_new0(impl_POA_GNOME_View, 1); newservant->servant.vepv = &impl_GNOME_View_vepv; newservant->poa = poa; newservant->frame = CORBA_Object_duplicate (frame, ev); newservant->embeddable_servant = embeddable_servant; /* this is what will be displayed in the component view ! */ newservant->widget = gtk_button_new_with_label (embeddable_servant->data); POA_GNOME_View__init((PortableServer_Servant) newservant, ev); objid = PortableServer_POA_activate_object(poa, newservant, ev); CORBA_free(objid); return newservant; } |
Once the view is created, it will wait to be given an X window. This will be done by the Container which will call GNOME::View::set_window
static void impl_GNOME_View_set_window(impl_POA_GNOME_View * servant, GNOME_View_windowid id, CORBA_Environment * ev) { servant->plug = gtk_plug_new (id); gtk_container_add (GTK_CONTAINER(servant->plug), servant->widget); gtk_widget_show_all (servant->plug); } |
Views are activated through the GNOME::View::activate function which must be called by the container. First, it will check if the View is to be activated or deactivated and build the editing GUI or not. Last, it will call GNOME::ViewFrame::view_activated to tell the container to set on or off the cover over the View.
static void impl_GNOME_View_activate(impl_POA_GNOME_View * servant, CORBA_boolean activated, CORBA_Environment * ev) { static GtkWidget *window = NULL; GtkWidget *vbox; GtkWidget *hbox; GtkWidget *button; GtkWidget *entry; if (activated == 1) { /* activate view */ /* sample code to create the external editing window of the view */ /* ...... here, code for the editing GUI ...... */ } else if (activated == 0 && window != NULL) { /* deactivate view */ gtk_widget_destroy (window); } /* tell the container the view was activated or not*/ GNOME_ViewFrame_view_activated (servant->frame, activated, ev); } |
If the view is to be activated, the GUI will be build:
window = gtk_window_new (GTK_WINDOW_TOPLEVEL); gtk_object_set_data (GTK_OBJECT (window), "view_servant", servant); gtk_signal_connect (GTK_OBJECT (window), "destroy", GTK_SIGNAL_FUNC (cancel_cb), window); gtk_signal_connect (GTK_OBJECT (window), "delete_event", GTK_SIGNAL_FUNC (cancel_cb), window); vbox = gtk_vbox_new (TRUE, TRUE); hbox = gtk_hbox_new (TRUE, TRUE); entry = gtk_entry_new_with_max_length (10); gtk_entry_set_text (GTK_ENTRY (entry), servant->embeddable_servant->data); gtk_box_pack_start (GTK_BOX (vbox), entry, TRUE, 0, 0); gtk_box_pack_start (GTK_BOX (vbox), gtk_hseparator_new(), TRUE, 0, 0); gtk_box_pack_end (GTK_BOX(vbox), hbox, TRUE, 0, 0); button = gtk_button_new_with_label ("Cancel"); gtk_box_pack_end (GTK_BOX(hbox), button, TRUE, 0, 0); gtk_signal_connect (GTK_OBJECT(button), "clicked", GTK_SIGNAL_FUNC(cancel_cb), window); button = gtk_button_new_with_label ("Apply"); gtk_object_set_data (GTK_OBJECT (button), "window", window); gtk_box_pack_end (GTK_BOX(hbox), button, TRUE, 0, 0); gtk_signal_connect (GTK_OBJECT(button), "clicked", GTK_SIGNAL_FUNC(apply_cb), entry); button = gtk_button_new_with_label ("Ok"); gtk_object_set_data (GTK_OBJECT (button), "window", window); gtk_box_pack_end (GTK_BOX(hbox), button, TRUE, 0, 0); gtk_signal_connect (GTK_OBJECT(button), "clicked", GTK_SIGNAL_FUNC(ok_cb), entry); gtk_container_add (GTK_CONTAINER(window), vbox); gtk_widget_show_all (GTK_WIDGET(window)); |
The important idea is that the buttons of the GUI are given enough parameters to either close the GUI or apply the changes to all the views of the activated Embeddable. Here is for example the apply_cb function which loops through all the embeddable views to change their buttons' labels.
void apply_cb (GtkWidget *button, gpointer data) { GSList *list; impl_POA_GNOME_View * servant; GtkWidget *label; GtkWidget *entry = (GtkWidget *) data; GtkWidget *window = gtk_object_get_data (GTK_OBJECT(button), "window"); impl_POA_GNOME_View *view_servant = (impl_POA_GNOME_View *) gtk_object_get_data (GTK_OBJECT (window), "view_servant"); strcpy (view_servant->embeddable_servant->data, gtk_entry_get_text (GTK_ENTRY (entry))); list = view_servant->embeddable_servant->view_servant_list; while (list != g_slist_last (view_servant->embeddable_servant->view_servant_list)) { servant = (impl_POA_GNOME_View *)list->data; label = GTK_BIN(servant->widget)->child; gtk_label_set_text (GTK_LABEL(label), view_servant->embeddable_servant->data); list = list->next; } servant = (impl_POA_GNOME_View *)list->data; label = GTK_BIN(servant->widget)->child; gtk_label_set_text (GTK_LABEL(label), view_servant->embeddable_servant->data); } |