Index: NOTES
===================================================================
--- NOTES	(revision 2581)
+++ NOTES	(working copy)
@@ -67,3 +67,26 @@
  * We should avoid duplicate entries in history. If we'll activate entry
    that already exists (have the same title) we can just move it to the top.
 
+
+NOTES ON MULTIHEAD PRESENTATIONS:
+=================================
+ * About window placement: 
+   * If we have 2 monitors, we 
+     * leave the new window (dscwindow) on this screen, as we assume "this" 
+       screen is the default working screen, not the beamer/projector.
+     * throw the source window to "the other" screen.
+     * maximize the source window & bring it to (normal) presentation mode
+     * maximize the control window.
+   
+   * We do not possess supercow powers, so we only organize the windows 
+     if it's obvious what the user wants. Otherwise he/she does it him/herself.
+	
+   * On destroy, we move the window back. If we don't do that, it's going to 
+     toggle monitor on each start ... 
+
+   * The control window doesn't go fullscreen (but maximized), so the user might 
+     start applications like web browser (applets) to show during the 
+	 presentation. 
+
+   * If we do not have exactly 2 monitors, we do not go maximized to make it 
+     easier for the user to move the window where he/she wants it.
Index: shell/ev-utils.c
===================================================================
--- shell/ev-utils.c	(revision 2581)
+++ shell/ev-utils.c	(working copy)
@@ -369,3 +369,40 @@
 	ev_gui_sanitise_popup_position (menu, widget, x, y);
 }
 
+/**
+ * get_num_monitors
+ * w: optional GtkWindow to look at.
+ * @return Number of monitors, -1 if uncertain situation (like multiple screens)
+ */
+gint 
+get_num_monitors (GtkWindow * w)
+{
+	GdkDisplay * display = gdk_display_get_default();
+	gint num_screen = gdk_display_get_n_screens(display);
+	
+	if(num_screen==1){
+		GdkScreen * screen;
+		if(w){
+			screen = gtk_window_get_screen(w);
+		}else{
+			screen = gdk_display_get_screen(display, 0);
+		}
+		return gdk_screen_get_n_monitors(screen);
+	}else{
+		return -1;
+	}
+}
+
+gdouble
+get_screen_dpi (GtkWindow * window)
+{
+	GdkScreen *screen;
+	gdouble    xdpi, ydpi;
+
+	screen = gtk_window_get_screen (window);
+
+	xdpi = 25.4 * gdk_screen_get_width (screen) / gdk_screen_get_width_mm (screen);
+	ydpi = 25.4 * gdk_screen_get_height (screen) / gdk_screen_get_height_mm (screen);
+	
+	return (xdpi + ydpi) / 2.0;
+}
Index: shell/ev-utils.h
===================================================================
--- shell/ev-utils.h	(revision 2581)
+++ shell/ev-utils.h	(working copy)
@@ -47,6 +47,15 @@
 gboolean		using_pdf_printer (GnomePrintConfig *config);
 #endif
 
+/**
+ * get_num_monitors
+ * w: optional GtkWindow to look at.
+ * @return Number of monitors, -1 if uncertain situation (like multiple screens)
+ */
+gint get_num_monitors (GtkWindow * w);
+
+gdouble get_screen_dpi (GtkWindow * window);
+
 G_END_DECLS
 
 #endif /* __EV_VIEW_H__ */
Index: shell/ev-dualscreen.c
===================================================================
--- shell/ev-dualscreen.c	(revision 0)
+++ shell/ev-dualscreen.c	(revision 0)
@@ -0,0 +1,413 @@
+/* this file is part of evince, a gnome document viewer
+ *
+ *  Copyright (C) 2007 Johannes Buchner
+ * 
+ *  Author: 
+ *    Johannes Buchner <buchner.johannes@gmx.at>
+ *
+ * Evince is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * Evince is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include "ev-dualscreen.h"
+#include "ev-utils.h"
+
+#define EV_DSCWINDOW_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), \
+	EV_TYPE_DSCWINDOW, EvDSCWindowPrivate))
+
+typedef struct _EvDSCWindowPrivate {
+	GtkWidget *main_box;
+	GtkWidget *menubar;
+	GtkWidget *overview;
+	GtkWidget *notesview;
+	EvDocument * notesdocument;
+	
+	GtkWidget *overview_scrolled_window;
+	GtkWidget *notesview_scrolled_window;
+	
+	EvWindow *presentation_window; 
+	EvDocument * presentation_document;
+	gint moveback_monitor;
+} EvDSCWindowPrivate;
+
+static gpointer parent_class = NULL;
+G_DEFINE_TYPE (EvDSCWindow, ev_dscwindow, GTK_TYPE_WINDOW)
+
+static gboolean ev_dscwindow_handle_resized (GtkContainer *container, GParamSpec *pspec,
+	            	                         EvDSCWindow *ev_dscwindow);
+static gboolean ev_dscwindow_notes_interaction (GtkContainer *container, EvDSCWindow *self);
+static gboolean ev_dscwindow_notes_clicked (GtkWidget *widget, GdkEvent *event,
+	                                        EvDSCWindow *self);
+static gboolean ev_dscwindow_switch_monitors (GtkWidget *widget, EvDSCWindow *self);
+static gboolean ev_dscwindow_end (GtkWidget *widget, GdkEvent *event);
+gint            get_num_monitors (GtkWindow * w);
+static void     ev_dscwindow_window_placement (EvDSCWindow * self);
+static void     ev_dscwindow_init(EvDSCWindow * self);
+static void     ev_dscwindow_dispose (GObject *obj);
+static void     ev_dscwindow_class_init (EvDSCWindowClass * klass);
+GtkWidget *     ev_dscwindow_new (void);
+EvDSCWindow *   ev_dscwindow_get_control (void);
+void            ev_dscwindow_set_presentation (EvDSCWindow * self, 
+	                       EvWindow *presentation_window, EvDocument *document);
+
+/**
+ * ev_dscwindow_handle_resized
+ * Callback for window resize and gripper position change
+ * Rezooms the view so the available space is used.
+ **/
+static gboolean
+ev_dscwindow_handle_resized (GtkContainer *container, GParamSpec *pspec,
+	EvDSCWindow *ev_dscwindow)
+{
+	EvDSCWindowPrivate *priv = EV_DSCWINDOW_GET_PRIVATE (ev_dscwindow);
+
+	ev_view_update_view_size(EV_VIEW(priv->overview),  
+		GTK_SCROLLED_WINDOW(priv->overview_scrolled_window ));
+	ev_view_update_view_size(EV_VIEW(priv->notesview), 
+		GTK_SCROLLED_WINDOW(priv->notesview_scrolled_window));
+	return TRUE;
+}
+
+/**
+ * ev_dscwindow_notes_interaction
+ * User wants to load a different file as notes.
+ **/
+static gboolean
+ev_dscwindow_notes_interaction (GtkContainer *container, EvDSCWindow *self)
+{
+	EvDSCWindowPrivate *priv = EV_DSCWINDOW_GET_PRIVATE (self);
+	GtkWidget *dialog;
+	
+	dialog = gtk_file_chooser_dialog_new (
+		_("Open Notes Document"),
+		GTK_WINDOW (self),
+		GTK_FILE_CHOOSER_ACTION_OPEN,
+		GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT,
+		GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
+		NULL);
+	
+	ev_document_factory_add_filters (dialog, NULL);
+	gtk_file_chooser_set_select_multiple (GTK_FILE_CHOOSER (dialog), FALSE);
+	gtk_file_chooser_set_local_only (GTK_FILE_CHOOSER (dialog), TRUE);
+	
+	if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT)
+	{
+		char * uri = gtk_file_chooser_get_uri (GTK_FILE_CHOOSER(dialog));
+		GError * error = NULL;
+		ev_view_set_loading (EV_VIEW (priv->notesview), TRUE);
+
+		if (priv->notesdocument) {
+			ev_document_load (priv->notesdocument, uri, &error);
+		} else {
+			priv->notesdocument = ev_document_factory_get_document (uri, 
+				&error);
+		}
+		g_free (uri);
+		if (error == NULL){
+			ev_view_set_document(EV_VIEW (priv->notesview),  
+				priv->notesdocument);
+			/* TODO: go to the same page that is open at the moment, or 
+			 * move the presentation to the beginning. */
+		}
+	}
+	gtk_widget_destroy (dialog);
+	return TRUE;
+}
+
+/**
+ * ev_dscwindow_notes_clicked
+ * If the notesview was doubleclicked, the user wants to load the notes.
+ **/
+static gboolean
+ev_dscwindow_notes_clicked (GtkWidget *widget, GdkEvent *event,
+	EvDSCWindow *self)
+{
+	g_message("ev_dscwindow_notes_clicked");
+	g_return_val_if_fail (self != NULL, FALSE);
+	g_return_val_if_fail (EV_IS_DSCWINDOW (self), FALSE);
+	g_return_val_if_fail (event != NULL, FALSE);
+	if (event->type == GDK_2BUTTON_PRESS && ((GdkEventButton *)event)->button == 1)
+	{
+		ev_dscwindow_notes_interaction(NULL, self);
+	} else if (event->type == GDK_BUTTON_PRESS && ((GdkEventButton *)event)->button == 1) {
+		/* TODO: go forward in document */
+	} else if (event->type == GDK_BUTTON_PRESS && ((GdkEventButton *)event)->button == 3) {
+		/* TODO: go back in document */
+	}
+	return FALSE;	
+}
+
+
+static gboolean
+ev_dscwindow_switch_monitors (GtkWidget *widget, EvDSCWindow *self)
+{
+	g_assert(EV_IS_DSCWINDOW (self));
+	
+	EvDSCWindowPrivate *priv = EV_DSCWINDOW_GET_PRIVATE (self);
+	
+	gint num_monitors = get_num_monitors (GTK_WINDOW (self));
+	
+	if (num_monitors == 2) {
+		GtkWindow * presentation_window = GTK_WINDOW (priv->presentation_window);
+		GdkScreen * screen = gtk_window_get_screen (presentation_window);
+		
+		gint monitor_1 = gdk_screen_get_monitor_at_window (screen, 
+			GTK_WIDGET(presentation_window)->window);
+		
+		gint monitor_2 = (monitor_1 + 1) % 2; 
+		
+		GdkRectangle coords;
+		gdk_screen_get_monitor_geometry (screen, monitor_2, &coords);
+		ev_window_stop_presentation (priv->presentation_window);
+		gtk_window_move (presentation_window, coords.x, coords.y);
+		ev_window_run_presentation (priv->presentation_window);
+		priv->moveback_monitor = monitor_1;
+		
+		gdk_screen_get_monitor_geometry (screen, monitor_1, &coords);
+		gtk_window_unmaximize (GTK_WINDOW (self));
+		gtk_window_move (GTK_WINDOW (self), coords.x, coords.y);
+		gtk_window_maximize (GTK_WINDOW (self));
+	}
+	return TRUE;
+}
+
+
+static gboolean
+ev_dscwindow_end (GtkWidget *widget, GdkEvent *event)
+{
+	gtk_widget_destroy (GTK_WIDGET (ev_dscwindow_get_control()));
+	return TRUE;
+}
+
+/**
+ * ev_dscwindow_window_placement
+ **/
+static void 
+ev_dscwindow_window_placement (EvDSCWindow * self)
+{
+	EvDSCWindowPrivate *priv = EV_DSCWINDOW_GET_PRIVATE (self);
+	
+	gint num_monitors = get_num_monitors (GTK_WINDOW (self));
+	if (num_monitors == 2) {
+		GtkWindow * presentation_window = GTK_WINDOW (priv->presentation_window);
+		GdkScreen * screen = gtk_window_get_screen(presentation_window);
+		
+		gint work_monitor = gdk_screen_get_monitor_at_window (screen, 
+			GTK_WIDGET(presentation_window)->window);
+		
+		gint presentation_monitor = (work_monitor + 1) % 2; 
+		
+		GdkRectangle coords;
+		gdk_screen_get_monitor_geometry (screen, presentation_monitor, 
+			&coords);
+		
+		gtk_window_move (presentation_window, coords.x, coords.y);
+		ev_window_run_presentation (priv->presentation_window);
+		priv->moveback_monitor = work_monitor;
+		
+		gtk_window_maximize (GTK_WINDOW (self));
+	}
+}
+
+/**
+ * ev_dscwindow_init:
+ * Initializer for my window. Sets all kind of stuff. 
+ * ev_dscwindow_set_presentation has to be called afterwards for loading in a 
+ * document.
+ **/
+static void 
+ev_dscwindow_init(EvDSCWindow * self)
+{
+	EvDSCWindowPrivate *priv = EV_DSCWINDOW_GET_PRIVATE(self);
+	
+	priv->moveback_monitor = -1;
+	priv->notesdocument = NULL;
+	
+	gtk_window_set_title (GTK_WINDOW (self), _("Presentation Control"));
+	GtkWidget *h = gtk_hpaned_new ();
+	GtkWidget *v = gtk_vbox_new (FALSE, 0);
+	
+	{
+		priv->overview_scrolled_window = GTK_WIDGET (g_object_new (
+			GTK_TYPE_SCROLLED_WINDOW, "shadow-type", GTK_SHADOW_IN, NULL));
+		gtk_box_pack_start_defaults (GTK_BOX(v), priv->overview_scrolled_window);
+		
+		priv->overview = ev_view_new();
+		g_object_ref (priv->overview);
+		ev_view_set_screen_dpi (EV_VIEW (priv->overview),
+					get_screen_dpi (GTK_WINDOW(self)));
+		gtk_container_add (GTK_CONTAINER (priv->overview_scrolled_window),
+				   priv->overview);
+		
+		ev_view_set_continuous  (EV_VIEW (priv->overview), TRUE);
+		ev_view_set_dual_page   (EV_VIEW (priv->overview), FALSE); 
+		ev_view_set_sizing_mode (EV_VIEW (priv->overview), EV_SIZING_BEST_FIT);
+	}
+	
+	{
+		GtkWidget *e = gtk_expander_new (_("Expensive features"));
+		gtk_expander_set_expanded(GTK_EXPANDER (e), TRUE);
+		
+		GtkWidget *t = gtk_toolbar_new ();
+		
+		GtkToolItem* b_switch = gtk_tool_button_new (NULL, _("Switch monitors"));
+		gtk_tool_button_set_icon_name (GTK_TOOL_BUTTON (b_switch), "object-flip-horizontal");
+		gtk_toolbar_insert (GTK_TOOLBAR (t), b_switch, -1);  
+		g_signal_connect (b_switch, "clicked", 
+			G_CALLBACK (ev_dscwindow_switch_monitors), self);
+		
+		GtkToolItem* b_notes = gtk_tool_button_new (NULL, _("Load notes ..."));
+		gtk_tool_button_set_icon_name (GTK_TOOL_BUTTON (b_notes), "object-flip-horizontal");
+		gtk_toolbar_insert (GTK_TOOLBAR (t), b_notes, -1);  
+		g_signal_connect (b_notes, "clicked", 
+			G_CALLBACK (ev_dscwindow_notes_interaction), self);
+		
+		GtkToolItem* b_close = gtk_tool_button_new (NULL, _("End presentation"));
+		gtk_tool_button_set_icon_name (GTK_TOOL_BUTTON (b_close), "view-restore");
+		gtk_toolbar_insert (GTK_TOOLBAR (t), b_close, -1);  
+		g_signal_connect (b_close, "clicked", 
+			G_CALLBACK (ev_dscwindow_end), NULL);
+		
+		gtk_container_add (GTK_CONTAINER (e), t);
+		gtk_box_pack_end (GTK_BOX(v), e, FALSE, TRUE, 0);
+		gtk_paned_add1 (GTK_PANED(h), v);
+	}
+	
+	{
+		priv->notesview_scrolled_window = GTK_WIDGET (g_object_new (
+			GTK_TYPE_SCROLLED_WINDOW, "shadow-type", GTK_SHADOW_IN, NULL));
+		gtk_paned_add2 (GTK_PANED(h), priv->notesview_scrolled_window);
+		
+		priv->notesview = ev_view_new ();
+		g_object_ref (priv->notesview);
+		ev_view_set_screen_dpi (EV_VIEW (priv->notesview),
+					get_screen_dpi (GTK_WINDOW(self)));
+		gtk_container_add (GTK_CONTAINER (priv->notesview_scrolled_window),
+				   priv->notesview);
+		
+		ev_view_set_continuous(EV_VIEW (priv->notesview), FALSE);
+		ev_view_set_dual_page(EV_VIEW (priv->notesview), FALSE); 
+		ev_view_set_sizing_mode (EV_VIEW (priv->notesview), EV_SIZING_BEST_FIT);
+	}
+	
+	/* TODO: set width of left thing to: (height/[3 or 2?])*doc_width/doc_height */
+	gtk_paned_set_position (GTK_PANED(h), 400);
+	gtk_widget_show_all (h);
+	gtk_container_add (GTK_CONTAINER (self), h);
+	
+	/* fallback if we have >2 monitors (see window placement) */
+	gtk_window_set_default_size (GTK_WINDOW (self), 800, 600);
+	
+	g_signal_connect (h, "notify::position", 
+		G_CALLBACK (ev_dscwindow_handle_resized), self);
+	
+	g_signal_connect (self, "size-allocate", 
+		G_CALLBACK (ev_dscwindow_handle_resized), self);
+	
+	/* This would just open new windows. */
+	gtk_drag_dest_unset(GTK_WIDGET (priv->notesview));
+	gtk_drag_dest_unset(GTK_WIDGET (priv->overview));
+	
+	gint click = GDK_BUTTON1_MOTION_MASK | GDK_KEY_PRESS_MASK;
+	gtk_widget_add_events(GTK_WIDGET(priv->overview), click);
+	g_signal_connect(priv->notesview, "button-press-event", 
+		G_CALLBACK (ev_dscwindow_notes_clicked), self);
+	
+}
+
+static void 
+ev_dscwindow_dispose (GObject *obj)
+{
+	EvDSCWindow * self = EV_DSCWINDOW(obj);
+	EvDSCWindowPrivate *priv = EV_DSCWINDOW_GET_PRIVATE(self);
+	
+	if (EV_IS_VIEW (priv->overview)){
+		ev_view_set_document(EV_VIEW (priv->overview),  NULL);
+		g_object_unref(priv->overview);
+	}
+	if (EV_IS_VIEW (priv->notesview)){
+		ev_view_set_document(EV_VIEW (priv->notesview), NULL);
+		g_object_unref(priv->notesview);
+	}
+	
+	ev_window_stop_presentation(priv->presentation_window);
+	
+	if(priv->moveback_monitor >= 0){
+		GtkWindow * presentation_window = GTK_WINDOW(priv->presentation_window);
+		GdkRectangle coords;
+		
+		gdk_screen_get_monitor_geometry(
+			gtk_window_get_screen(presentation_window), 
+			priv->moveback_monitor, &coords);
+		
+		gtk_window_move(presentation_window, coords.x, coords.y);
+	}
+	
+	G_OBJECT_CLASS (parent_class)->dispose (obj);
+}
+
+static void 
+ev_dscwindow_class_init (EvDSCWindowClass * klass)
+{
+	GObjectClass *g_object_class = G_OBJECT_CLASS (klass);
+	parent_class = g_type_class_peek_parent (klass);
+	g_type_class_add_private (klass, sizeof (EvDSCWindowPrivate));
+	g_object_class->dispose  = ev_dscwindow_dispose;
+}
+
+GtkWidget *
+ev_dscwindow_new (void)
+{
+	return GTK_WIDGET (g_object_new (EV_TYPE_DSCWINDOW, 
+		"type", GTK_WINDOW_TOPLEVEL, NULL));
+}
+
+/**
+ * ev_dscwindow_get_control
+ * Get the control instance. If there is none, create one.
+ **/
+EvDSCWindow * 
+ev_dscwindow_get_control (void)
+{
+	static EvDSCWindow * control = NULL;
+	
+	if (!control || !EV_IS_DSCWINDOW (control)) {
+		control = EV_DSCWINDOW (g_object_new (EV_TYPE_DSCWINDOW, NULL));
+	}
+	
+	return control;
+}
+
+/**
+ * ev_dscwindow_set_presentation:
+ * @presentation_window: Main window we can 
+ * @document: Presentation document we will load in.
+ **/
+void
+ev_dscwindow_set_presentation (EvDSCWindow * self, 
+	EvWindow *presentation_window, EvDocument *document)
+{
+	if(EV_IS_WINDOW(presentation_window)){
+		EvDSCWindowPrivate *priv = EV_DSCWINDOW_GET_PRIVATE(self);
+		priv->presentation_window = presentation_window;
+		priv->presentation_document = document;
+		
+		ev_view_set_document(EV_VIEW (priv->overview),  
+			priv->presentation_document);
+		ev_view_set_document(EV_VIEW (priv->notesview), 
+			priv->presentation_document);
+		ev_dscwindow_window_placement(self);
+		ev_dscwindow_handle_resized(NULL, NULL, self);
+	}
+}
Index: shell/ev-dualscreen.h
===================================================================
--- shell/ev-dualscreen.h	(revision 0)
+++ shell/ev-dualscreen.h	(revision 0)
@@ -0,0 +1,74 @@
+/* this file is part of evince, a gnome document viewer
+ *
+ *  Copyright (C) 2007 Johannes Buchner
+ * 
+ *  Author: 
+ *    Johannes Buchner <buchner.johannes@gmx.at>
+ *
+ * Evince is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * Evince is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef EV_DUALSCREEN_H
+#define EV_DUALSCREEN_H
+
+#include <gtk/gtk.h>
+#include <glib.h>
+#include <glib/gi18n.h>
+#include "ev-window.h"
+#include "ev-view.h"
+#include "ev-document-factory.h"
+
+G_BEGIN_DECLS
+typedef struct _EvDSCWindow {
+	GtkWindow		base_instance;
+} EvDSCWindow;
+typedef struct _EvDSCWindowClass {
+	GtkWindowClass base_class;
+} EvDSCWindowClass;
+
+#define EV_TYPE_DSCWINDOW			(ev_dscwindow_get_type())
+#define EV_DSCWINDOW(object)		(G_TYPE_CHECK_INSTANCE_CAST((object), EV_TYPE_DSCWINDOW, EvDSCWindow))
+#define EV_DSCWINDOW_CLASS(klass)		(G_TYPE_CHECK_CLASS_CAST((klass), EV_TYPE_DSCWINDOW, EvDSCWindowClass))
+#define EV_IS_DSCWINDOW(object)		(G_TYPE_CHECK_INSTANCE_TYPE((object), EV_TYPE_DSCWINDOW))
+#define EV_IS_DSCWINDOW_CLASS(klass)	(G_TYPE_CHECK_CLASS_TYPE((klass), EV_TYPE_DSCWINDOW))
+#define EV_DSCWINDOW_GET_CLASS(object)	(G_TYPE_INSTANCE_GET_CLASS((object), EV_TYPE_DSCWINDOW, EvDSCWindowClass))
+
+GType		ev_dscwindow_get_type	  (void);
+
+/**
+ * Open a new presentation control window.
+ * You have to call ev_dscwindow_set_presentation afterwards to link it to the 
+ * document you want to see in it.
+ **/
+GtkWidget * ev_dscwindow_new (void);
+
+/**
+ * ev_dscwindow_set_presentation:
+ * Load in the presentation we want to see.
+ * @presentation_window: Main window we can 
+ * @document: Presentation document we will load in.
+ **/
+void ev_dscwindow_set_presentation (EvDSCWindow * self, 
+	EvWindow *presentation_window, EvDocument *document);
+
+/**
+ * ev_dscwindow_get_control
+ * Get the control instance. If there is none, create one.
+ **/
+EvDSCWindow * ev_dscwindow_get_control (void);
+
+G_END_DECLS
+
+#endif /* EV_DUALSCREEN_H */
Index: shell/ev-window.c
===================================================================
--- shell/ev-window.c	(revision 2581)
+++ shell/ev-window.c	(working copy)
@@ -36,6 +36,7 @@
 #include "ev-sidebar-links.h"
 #include "ev-sidebar-attachments.h"
 #include "ev-sidebar-thumbnails.h"
+#include "ev-utils.h"
 #include "ev-view.h"
 #include "ev-password.h"
 #include "ev-password-view.h"
@@ -47,6 +48,7 @@
 #include "ev-document-find.h"
 #include "ev-document-security.h"
 #include "ev-document-factory.h"
+#include "ev-dualscreen.h"
 #include "ev-job-queue.h"
 #include "ev-jobs.h"
 #include "ev-sidebar-page.h"
@@ -244,8 +246,6 @@
 static void     ev_window_stop_fullscreen               (EvWindow         *window);
 static void     ev_window_cmd_view_fullscreen           (GtkAction        *action,
 							 EvWindow         *window);
-static void     ev_window_run_presentation              (EvWindow         *window);
-static void     ev_window_stop_presentation             (EvWindow         *window);
 static void     ev_window_cmd_view_presentation         (GtkAction        *action,
 							 EvWindow         *window);
 static void     ev_window_run_preview                   (EvWindow         *window);
@@ -273,20 +273,6 @@
 
 G_DEFINE_TYPE (EvWindow, ev_window, GTK_TYPE_WINDOW)
 
-static gdouble
-ev_window_get_screen_dpi (EvWindow *ev_window)
-{
-	GdkScreen *screen;
-	gdouble    xdpi, ydpi;
-
-	screen = gtk_window_get_screen (GTK_WINDOW (ev_window));
-
-	xdpi = 25.4 * gdk_screen_get_width (screen) / gdk_screen_get_width_mm (screen);
-	ydpi = 25.4 * gdk_screen_get_height (screen) / gdk_screen_get_height_mm (screen);
-	
-	return (xdpi + ydpi) / 2.0;
-}
-
 static void
 ev_window_set_action_sensitive (EvWindow   *ev_window,
 		    	        const char *name,
@@ -457,7 +443,7 @@
 						      ZOOM_CONTROL_ACTION);
 
 		real_zoom = ev_view_get_zoom (EV_VIEW (ev_window->priv->view));
-		real_zoom *= 72.0 / ev_window_get_screen_dpi (ev_window);
+		real_zoom *= 72.0 / get_screen_dpi (GTK_WINDOW (ev_window));
 		zoom = ephy_zoom_get_nearest_zoom_level (real_zoom);
 
 		ephy_zoom_action_set_zoom_level (EPHY_ZOOM_ACTION (action), zoom);
@@ -987,7 +973,7 @@
 		gdouble zoom_value;
 
 		zoom_value = g_value_get_double (&zoom);
-		zoom_value *= ev_window_get_screen_dpi (window) / 72.0;
+		zoom_value *= get_screen_dpi (GTK_WINDOW (window)) / 72.0;
 		ev_view_set_zoom (view, zoom_value, FALSE);
 		g_value_unset (&zoom);
 	}
@@ -2967,7 +2953,7 @@
 		(action, G_CALLBACK (ev_window_cmd_view_presentation), window);
 }
 
-static void
+void
 ev_window_run_presentation (EvWindow *window)
 {
 	g_object_set (G_OBJECT (window->priv->scrolled_window),
@@ -2998,7 +2984,7 @@
 		ev_metadata_manager_set_boolean (window->priv->uri, "presentation", TRUE);
 }
 
-static void
+void
 ev_window_stop_presentation (EvWindow *window)
 {
 	if (!ev_view_get_presentation (EV_VIEW (window->priv->view)))
@@ -3032,14 +3018,30 @@
 {
 	gboolean presentation;
 
-        g_return_if_fail (EV_IS_WINDOW (window));
+	g_return_if_fail (EV_IS_WINDOW (window));
 	ev_window_stop_fullscreen (window);
 
 	presentation = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action));
-	if (presentation) {
-		ev_window_run_presentation (window);
+	
+	gint n = get_num_monitors(GTK_WINDOW(window));
+	
+	if (n > 1){
+		EvWindow *presentation_window = window;
+		EvDSCWindow * control = ev_dscwindow_get_control();
+		
+		if (presentation) {
+			ev_dscwindow_set_presentation (control, presentation_window, 
+				presentation_window->priv->document);
+			gtk_window_present (GTK_WINDOW (control));
+		} else {
+			gtk_widget_destroy (GTK_WIDGET (control));
+		}
 	} else {
-		ev_window_stop_presentation (window);
+		if (presentation) {
+			ev_window_run_presentation (window);
+		} else {
+			ev_window_stop_presentation (window);
+		}
 	}
 }
 
@@ -3106,7 +3108,7 @@
 #endif
 	
 	ev_view_set_screen_dpi (EV_VIEW (window->priv->view),
-				ev_window_get_screen_dpi (window));
+				get_screen_dpi (GTK_WINDOW (window)));
 	
 	if (GTK_WIDGET_CLASS (ev_window_parent_class)->screen_changed) {
 		GTK_WIDGET_CLASS (ev_window_parent_class)->screen_changed (widget, old_screen);
@@ -3504,38 +3506,6 @@
 }
 
 static void
-update_view_size (EvView *view, EvWindow *window)
-{
-	int width, height;
-	GtkRequisition vsb_requisition;
-	GtkRequisition hsb_requisition;
-	int scrollbar_spacing;
-
-	/* Calculate the width available for the */
-	width = window->priv->scrolled_window->allocation.width;
-	height = window->priv->scrolled_window->allocation.height;
-
-	if (gtk_scrolled_window_get_shadow_type (GTK_SCROLLED_WINDOW (window->priv->scrolled_window)) == GTK_SHADOW_IN) {
-		width -= 2 * window->priv->view->style->xthickness;
-		height -= 2 * window->priv->view->style->ythickness;
-	}
-
-	gtk_widget_size_request (GTK_SCROLLED_WINDOW (window->priv->scrolled_window)->vscrollbar,
-				 &vsb_requisition);
-	gtk_widget_size_request (GTK_SCROLLED_WINDOW (window->priv->scrolled_window)->hscrollbar,
-				 &hsb_requisition);
-	gtk_widget_style_get (window->priv->scrolled_window,
-			      "scrollbar_spacing", &scrollbar_spacing,
-			      NULL);
-
-	ev_view_set_zoom_for_size (EV_VIEW (window->priv->view),
-				   MAX (1, width),
-				   MAX (1, height),
-				   vsb_requisition.width + scrollbar_spacing,
-				   hsb_requisition.height + scrollbar_spacing);
-}
-
-static void
 save_sizing_mode (EvWindow *window)
 {
 	EvSizingMode mode;
@@ -3553,19 +3523,19 @@
 ev_window_sizing_mode_changed_cb (EvView *view, GParamSpec *pspec,
 		 		  EvWindow   *ev_window)
 {
-	GtkWidget *scrolled_window;
+	GtkScrolledWindow *scrolled_window;
 	EvSizingMode sizing_mode;
 
 	g_object_get (ev_window->priv->view,
 		      "sizing-mode", &sizing_mode,
 		      NULL);
 
-	scrolled_window = ev_window->priv->scrolled_window;
+	scrolled_window = GTK_SCROLLED_WINDOW (ev_window->priv->scrolled_window);
 
-	g_signal_handlers_disconnect_by_func (ev_window->priv->view, update_view_size, ev_window);
+	g_signal_handlers_disconnect_by_func (ev_window->priv->view, ev_view_update_view_size, scrolled_window);
 
 	if (sizing_mode != EV_SIZING_FREE)
-	    	update_view_size (NULL, ev_window);
+	    	ev_view_update_view_size (NULL, scrolled_window);
 
 	switch (sizing_mode) {
 	        case EV_SIZING_BEST_FIT:
@@ -3574,8 +3544,8 @@
 				      "vscrollbar-policy", GTK_POLICY_AUTOMATIC,
 				      NULL);
 			g_signal_connect (ev_window->priv->view, "zoom_invalid",
-					  G_CALLBACK (update_view_size),
-					  ev_window);
+					  G_CALLBACK (ev_view_update_view_size),
+					  scrolled_window);
 			break;
 	        case EV_SIZING_FIT_WIDTH:
 			g_object_set (G_OBJECT (scrolled_window),
@@ -3583,8 +3553,8 @@
 				      "vscrollbar-policy", GTK_POLICY_AUTOMATIC,
 				      NULL);
 			g_signal_connect (ev_window->priv->view, "zoom_invalid",
-					  G_CALLBACK (update_view_size),
-					  ev_window);
+					  G_CALLBACK (ev_view_update_view_size),
+					  scrolled_window);
 			break;
 	        case EV_SIZING_FREE:
 			g_object_set (G_OBJECT (scrolled_window),
@@ -3607,7 +3577,7 @@
 		gdouble zoom;
 
 		zoom = ev_view_get_zoom (view);
-		zoom *= 72.0 / ev_window_get_screen_dpi (ev_window);
+		zoom *= 72.0 / get_screen_dpi (GTK_WINDOW(ev_window));
 		ev_metadata_manager_set_double (ev_window->priv->uri, "zoom", zoom);
 	}
 }
@@ -3722,6 +3692,10 @@
 		"Bryan Clark <clarkbw@gnome.org>",
 		"Carlos Garcia Campos <carlosgc@gnome.org>",
 		"Wouter Bolsterlee <wbolster@gnome.org>",
+		"",
+		"Contributers:",
+		/* I guess a lot more here ... */
+		"Johannes Buchner <buchner.johannes@gmx.at> (Multihead Presentations)",
 		NULL
 	};
 
@@ -4075,7 +4049,7 @@
 	
 	if (mode == EV_SIZING_FREE) {
 		ev_view_set_zoom (EV_VIEW (ev_window->priv->view),
-				  zoom * ev_window_get_screen_dpi (ev_window) / 72.0,
+				  zoom * get_screen_dpi (GTK_WINDOW (ev_window)) / 72.0,
 				  FALSE);
 	}
 }
@@ -5305,7 +5279,7 @@
 
 	ev_window->priv->view = ev_view_new ();
 	ev_view_set_screen_dpi (EV_VIEW (ev_window->priv->view),
-				ev_window_get_screen_dpi (ev_window));
+				get_screen_dpi (GTK_WINDOW (ev_window)));
 	ev_window->priv->password_view = ev_password_view_new ();
 	g_signal_connect_swapped (ev_window->priv->password_view,
 				  "unlock",
Index: shell/ev-view.c
===================================================================
--- shell/ev-view.c	(revision 2581)
+++ shell/ev-view.c	(working copy)
@@ -4692,6 +4692,7 @@
 			   int     vsb_width,
 			   int     hsb_height)
 {
+	g_return_if_fail (EV_IS_VIEW(view));
 	g_return_if_fail (view->sizing_mode == EV_SIZING_FIT_WIDTH ||
 			  view->sizing_mode == EV_SIZING_BEST_FIT);
 	g_return_if_fail (width >= 0);
@@ -5564,3 +5565,36 @@
   }
   return etype;
 }
+
+void
+ev_view_update_view_size (EvView *view, GtkScrolledWindow * scrolled_window)
+{
+	int width, height;
+	GtkRequisition vsb_requisition;
+	GtkRequisition hsb_requisition;
+	int scrollbar_spacing;
+	
+	/* Calculate the width available for the content */ 
+	width  = GTK_WIDGET (scrolled_window)->allocation.width;
+	height = GTK_WIDGET (scrolled_window)->allocation.height;
+
+	if (gtk_scrolled_window_get_shadow_type (scrolled_window) == GTK_SHADOW_IN 
+		&& view
+	) {
+		width -=  2 * GTK_WIDGET(view)->style->xthickness;
+		height -= 2 * GTK_WIDGET(view)->style->ythickness;
+	}
+
+	gtk_widget_size_request (scrolled_window->vscrollbar, &vsb_requisition);
+	gtk_widget_size_request (scrolled_window->hscrollbar, &hsb_requisition);
+	gtk_widget_style_get (GTK_WIDGET (scrolled_window), "scrollbar_spacing", 
+		&scrollbar_spacing, NULL);
+	
+	if (EV_IS_VIEW(view)) {
+		ev_view_set_zoom_for_size (EV_VIEW (view),
+		   MAX (1, width),
+		   MAX (1, height),
+		   vsb_requisition.width + scrollbar_spacing,
+		   hsb_requisition.height + scrollbar_spacing);
+	}
+}
Index: shell/ev-window.h
===================================================================
--- shell/ev-window.h	(revision 2581)
+++ shell/ev-window.h	(working copy)
@@ -25,8 +25,10 @@
 
 #include <glib-object.h>
 #include <gtk/gtkwindow.h>
+#include <gtk/gtkscrolledwindow.h>
 
 #include "ev-link.h"
+#include "ev-view.h"
 #include "ev-page-cache.h"
 
 G_BEGIN_DECLS
@@ -80,6 +82,9 @@
 					   gboolean        unlink_temp_file,
 					   const gchar    *print_settings);
 gboolean	ev_window_is_empty	  (const EvWindow *ev_window);
+void ev_window_run_presentation (EvWindow *window);
+void ev_window_stop_presentation (EvWindow *window);
+
 #ifdef WITH_PRINT
 void		ev_window_print_range     (EvWindow       *ev_window,
 					   int             first_page,
@@ -88,4 +93,3 @@
 G_END_DECLS
 
 #endif /* !EV_WINDOW_H */
-
Index: shell/ev-view.h
===================================================================
--- shell/ev-view.h	(revision 2581)
+++ shell/ev-view.h	(working copy)
@@ -22,6 +22,7 @@
 
 #include <gtk/gtkwidget.h>
 #include <gtk/gtklayout.h>
+#include <gtk/gtkscrolledwindow.h>
 
 #include "ev-document.h"
 #include "ev-link.h"
@@ -146,6 +147,8 @@
 gboolean       ev_view_previous_page	  (EvView         *view);
 gchar*         ev_view_page_label_from_dest (EvView *view, EvLinkDest *dest);
 
+void           ev_view_update_view_size (EvView *view, GtkScrolledWindow * scrolled_window);
+
 G_END_DECLS
 
 #endif /* __EV_VIEW_H__ */
Index: shell/Makefile.am
===================================================================
--- shell/Makefile.am	(revision 2581)
+++ shell/Makefile.am	(working copy)
@@ -27,6 +27,8 @@
 	eggfindbar.h			\
 	ev-application.c		\
 	ev-application.h		\
+	ev-dualscreen.c			\
+	ev-dualscreen.h			\
 	ev-job-queue.h			\
 	ev-job-queue.c			\
 	ev-jobs.h			\
