+extern "C" {
+ static Component *
+ container_activate_component (Container *container, char *component_goad_id)
+ {
+ Component *component;
+ GnomeClientSite *client_site;
+ GnomeObjectClient *server;
+
+ /*
+ * The ClientSite is the container-side point of contact for
+ * the Embeddable. So there is a one-to-one correspondence
+ * between GnomeClientSites and GnomeEmbeddables. */
+ client_site = gnome_client_site_new (container->container);
+
+ /*
+ * A GnomeObjectClient is a simple wrapper for a remote
+ * GnomeObject (a server supporting GNOME::Unknown).
+ */
+ server = container_launch_component (client_site, container->container,
+ component_goad_id);
+ if (server == NULL) {
+ char *error_msg;
+
+ error_msg = g_strdup_printf (_("Could not launch Embeddable %s!"),
+ component_goad_id);
+ gnome_warning_dialog (error_msg);
+ g_free (error_msg);
+
+ return NULL;
+ }
+
+ /*
+ * Create the internal data structure which we will use to
+ * keep track of this component.
+ */
+ component = g_new0 (Component, 1);
+ component->container = container;
+ component->client_site = client_site;
+ component->server = server;
+
+ container_set_view (container, component);
+
+ return component;
+ }
+
+ static void
+ filenames_dropped (GtkWidget * widget,
+ GdkDragContext *context,
+ gint x,
+ gint y,
+ GtkSelectionData *selection_data,
+ guint info,
+ guint time,
+ Container *container)
+ {
+ GList *names, *tmp_list;
+
+ names = gnome_uri_list_extract_filenames ((char *)selection_data->data);
+ tmp_list = names;
+
+ while (tmp_list) {
+ const char *fname = (const char *)tmp_list->data;
+
+ if (fname) {
+ if (container->view_widget)
+ container = container_new (fname);
+ else
+ open_pdf (container, fname);
+ }
+
+ tmp_list = g_list_next (tmp_list);
+ }
+ }
+
+ /*
+ * GtkWidget key_press method override
+ *
+ * Scrolls the window on keypress
+ */
+ static gint
+ key_press_event_cb (GtkWidget *widget, GdkEventKey *event)
+ {
+ Container *container = (Container *) gtk_object_get_data (GTK_OBJECT (widget), "container_data");
+ Component *component;
+ GtkScrolledWindow *win;
+ float delta;
+
+ g_return_val_if_fail (container != NULL, FALSE);
+
+ win = container->scroll;
+ component = container->component;
+ if (component == NULL || win == NULL)
+ return FALSE;
+
+ /*
+ * Scrolling the view.
+ */
+ if (event->keyval == GDK_Up) {
+ GtkAdjustment *adj = gtk_scrolled_window_get_vadjustment (win);
+
+ if (event->state & GDK_CONTROL_MASK)
+ delta = adj->step_increment * 3;
+ else
+ delta = adj->step_increment;
+
+ adj->value = CLAMP (adj->value - delta,
+ adj->lower, adj->upper - adj->page_size);
+
+ gtk_adjustment_value_changed (adj);
+ return TRUE;
+ } else if (event->keyval == GDK_Down) {
+ GtkAdjustment *adj = gtk_scrolled_window_get_vadjustment (win);
+
+ if (event->state & GDK_CONTROL_MASK)
+ delta = adj->step_increment * 3;
+ else
+ delta = adj->step_increment;
+
+ adj->value = CLAMP (adj->value + delta,
+ adj->lower, adj->upper - adj->page_size);
+ gtk_adjustment_value_changed (adj);
+ return TRUE;
+ } else if (event->keyval == GDK_Left) {
+ GtkAdjustment *adj = gtk_scrolled_window_get_hadjustment (win);
+
+ if (event->state & GDK_CONTROL_MASK)
+ delta = adj->step_increment * 3;
+ else
+ delta = adj->step_increment;
+
+ adj->value = CLAMP (adj->value - delta,
+ adj->lower, adj->upper - adj->page_size);
+ gtk_adjustment_value_changed (adj);
+ return TRUE;
+ } else if (event->keyval == GDK_Right) {
+ GtkAdjustment *adj = gtk_scrolled_window_get_hadjustment (win);
+
+ if (event->state & GDK_CONTROL_MASK)
+ delta = adj->step_increment * 3;
+ else
+ delta = adj->step_increment;
+
+ adj->value = CLAMP (adj->value + delta,
+ adj->lower, adj->upper - adj->page_size);
+ gtk_adjustment_value_changed (adj);
+ return TRUE;
+
+ /*
+ * Various shortcuts mapped to verbs.
+ */
+
+ } else if (event->keyval == GDK_Home) {
+ gnome_view_frame_view_do_verb (component->view_frame, VERB_FIRST);
+ return TRUE;
+ } else if (event->keyval == GDK_End) {
+ gnome_view_frame_view_do_verb (component->view_frame, VERB_LAST);
+ return TRUE;
+ } else if (event->keyval == GDK_Page_Down ||
+ event->keyval == GDK_Next) {
+ gnome_view_frame_view_do_verb (component->view_frame, VERB_NEXT);
+ return TRUE;
+ } else if (event->keyval == GDK_Page_Up ||
+ event->keyval == GDK_Prior) {
+ gnome_view_frame_view_do_verb (component->view_frame, VERB_PREV);
+ return TRUE;
+ } else if (event->keyval == GDK_plus ||
+ event->keyval == GDK_equal) {
+ gnome_view_frame_view_do_verb (component->view_frame, VERB_Z_IN);
+ } else if (event->keyval == GDK_underscore ||
+ event->keyval == GDK_minus) {
+ gnome_view_frame_view_do_verb (component->view_frame, VERB_Z_OUT);
+ }
+ return FALSE;
+ }
+}