Пример #1
0
static int executeJump(void)
{
	/*
	 * 0 = No jump pending, nothing done.
	 * 1 = Jump succeeded.
	 * 2 = Jump was pending, but target page invalid.
	 */
	int retval = 0;

	/* Jump? */
	if (target_page >= 0)
	{
		target_page--;

		/* Restrict to valid range. */
		if (target_page >= 0 && target_page < doc_n_pages)
		{
			doc_page = target_page;
			doc_page_beamer = target_page;
			setStatusText_strdup("Ready.");
			retval = 1;
		}
		else
		{
			setStatusText_strdup("Invalid page.");
			retval = 2;
		}

		/* Reset value to: "no jump pending". */
		target_page = -1;
	}

	return retval;
}
Пример #2
0
static int executeJump(void)
{
	/*
	 * 0 = No jump pending, nothing done.
	 * 1 = Jump succeeded.
	 * 2 = Jump was pending, but target page invalid.
	 */
	int retval = 0;

	/* Jump? */
	if (target_page >= 0)
	{
		
		int label = 0;
		int runs = 0;
		int page_number = target_page-1;
		while (runs < doc_n_pages && page_number >= 0 && page_number < doc_n_pages) {
		    PopplerPage *page = poppler_document_get_page(doc, page_number);
		    label = atoi(poppler_page_get_label(page));
		    if (label == target_page)
		        break;
		    if (label < target_page)
		        page_number++;
		    else if (label > target_page)
		        page_number--;
		    runs++;
		    g_object_unref(G_OBJECT(page));
		}
		
		target_page = page_number;

		/* Restrict to valid range. */
		if (target_page >= 0 && target_page < doc_n_pages)
		{
			doc_page = target_page;
			doc_page_beamer = target_page;
			setStatusText_strdup("Ready.");
			retval = 1;
		}
		else
		{
			setStatusText_strdup("Invalid page.");
			retval = 2;
		}

		/* Reset value to: "no jump pending". */
		target_page = -1;
	}

	return retval;
}
Пример #3
0
static void onSaveAsClicked(GtkWidget *widget, gpointer data)
{
	/* Unused parameters. */
	(void)widget;
	(void)data;

	gchar *msg = NULL;
	GtkWidget *fileChooser = NULL;

	fileChooser = gtk_file_chooser_dialog_new("Save File", NULL,
			GTK_FILE_CHOOSER_ACTION_SAVE, GTK_STOCK_CANCEL,
			GTK_RESPONSE_CANCEL, GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT,
			NULL);

	gtk_file_chooser_set_do_overwrite_confirmation(
			GTK_FILE_CHOOSER(fileChooser), TRUE);

	setLastFolderOn(fileChooser);

	if (gtk_dialog_run(GTK_DIALOG(fileChooser)) == GTK_RESPONSE_ACCEPT)
	{
		saveCurrentNote();

		if (savedAsFilename != NULL)
			g_free(savedAsFilename);

		savedAsFilename = gtk_file_chooser_get_filename(
				GTK_FILE_CHOOSER(fileChooser));

		if (saveNotes(savedAsFilename))
		{
			saveLastFolderFrom(fileChooser);

			isSaved = TRUE;
			gtk_widget_set_sensitive(GTK_WIDGET(saveButton), FALSE);

			msg = g_strdup_printf("Notes saved as '%s'.",
					savedAsFilename);
			setStatusText_strdup(msg);
			g_free(msg);
		}
	}
	gtk_widget_destroy(fileChooser);
}
Пример #4
0
static void showNotesFromFile(gchar *notefile)
{
	gchar *msg = NULL;

	if (savedAsFilename != NULL)
		g_free(savedAsFilename);

	savedAsFilename = notefile;

	if (readNotes(notefile))
	{
		msg = g_strdup_printf("Notes read from '%s'.", notefile);
		setStatusText_strdup(msg);
		g_free(msg);

		isSaved = TRUE;
		gtk_widget_set_sensitive(GTK_WIDGET(saveButton), FALSE);

		printNote(doc_page + 1);
	}
}
Пример #5
0
static void onSaveClicked(GtkWidget *widget, gpointer data)
{
	/* Unused parameters. */
	(void)widget;
	(void)data;

	gchar *msg = NULL;

	if (savedAsFilename == NULL)
		return;

	saveCurrentNote();
	if (!saveNotes(savedAsFilename))
		return;

	msg = g_strdup_printf("Notes saved: '%s'.", savedAsFilename);
	setStatusText_strdup(msg);
	g_free(msg);

	isSaved = TRUE;
	gtk_widget_set_sensitive(GTK_WIDGET(saveButton), FALSE);
}
Пример #6
0
static void initGUI(int numframes, gchar *notefile)
{
	int i = 0, transIndex = 0;
	GtkWidget *timeBox = NULL,
			  *notePadBox = NULL,
			  *notePadScroll = NULL,
			  *table = NULL;
	GtkWidget *image = NULL,
			  *frame = NULL,
			  *evbox = NULL,
			  *outerevbox = NULL,
			  *timeFrame = NULL;
	GtkWidget *mainVBox = NULL;
	GdkColor black;

	GtkWidget *toolbar = NULL, *timeToolbar = NULL;
	GtkToolItem *openButton = NULL,
				*saveAsButton = NULL,
				*fontSelectButton = NULL,
				*timeFontSelectButton = NULL;

	PangoFontDescription *font_desc = NULL;

	struct viewport *thisport = NULL;

	/* init colors */
	if (gdk_color_parse("#000000", &black) != TRUE)
		fprintf(stderr, "Could not resolve color \"black\".\n");
	if (gdk_color_parse("#BBFFBB", &col_current) != TRUE)
		fprintf(stderr, "Could not resolve color \"col_current\".\n");
	if (gdk_color_parse("#FFBBBB", &col_marked) != TRUE)
		fprintf(stderr, "Could not resolve color \"col_marked\".\n");
	if (gdk_color_parse("#BBBBBB", &col_dim) != TRUE)
		fprintf(stderr, "Could not resolve color \"col_dim\".\n");


	/* init our two windows */
	win_preview = gtk_window_new(GTK_WINDOW_TOPLEVEL);
	win_beamer  = gtk_window_new(GTK_WINDOW_TOPLEVEL);

	gtk_window_set_title(GTK_WINDOW(win_preview), "pdfpres - Preview");
	gtk_window_set_title(GTK_WINDOW(win_beamer),  "pdfpres - Beamer");

	g_signal_connect(G_OBJECT(win_preview), "delete_event",
			G_CALLBACK(onQuit), NULL);
	g_signal_connect(G_OBJECT(win_preview), "destroy",
			G_CALLBACK(onQuit), NULL);
	g_signal_connect(G_OBJECT(win_beamer), "delete_event",
			G_CALLBACK(onQuit), NULL);
	g_signal_connect(G_OBJECT(win_beamer), "destroy",
			G_CALLBACK(onQuit), NULL);

	g_signal_connect(G_OBJECT(win_preview), "key_press_event",
			G_CALLBACK(onKeyPressed), NULL);
	g_signal_connect(G_OBJECT(win_beamer), "key_press_event",
			G_CALLBACK(onKeyPressed), NULL);

	gtk_widget_add_events(win_beamer, GDK_BUTTON_RELEASE_MASK
					| GDK_SCROLL_MASK);
	g_signal_connect(G_OBJECT(win_beamer), "button_release_event",
			G_CALLBACK(onMouseReleased), NULL);
	g_signal_connect(G_OBJECT(win_beamer), "scroll_event",
			G_CALLBACK(onScroll), NULL);

	gtk_widget_add_events(win_preview, GDK_BUTTON_RELEASE_MASK
					 | GDK_SCROLL_MASK);
	g_signal_connect(G_OBJECT(win_preview), "button_release_event",
			G_CALLBACK(onMouseReleased), NULL);
	g_signal_connect(G_OBJECT(win_preview), "scroll_event",
			G_CALLBACK(onScroll), NULL);

	gtk_container_set_border_width(GTK_CONTAINER(win_preview), 0);
	gtk_container_set_border_width(GTK_CONTAINER(win_beamer), 0);

	gtk_widget_modify_bg(win_beamer, GTK_STATE_NORMAL, &black);

	/* create buttons */
	timeToolbar = gtk_toolbar_new();
	gtk_toolbar_set_style(GTK_TOOLBAR(timeToolbar), GTK_TOOLBAR_ICONS);
	gtk_container_set_border_width(GTK_CONTAINER(timeToolbar), 5);

	if (!prefs.timer_is_clock)
	{
		startButton = gtk_tool_button_new_from_stock(
				GTK_STOCK_MEDIA_PLAY);
		g_signal_connect(G_OBJECT(startButton), "clicked",
				G_CALLBACK(toggleTimer), NULL);
		gtk_toolbar_insert(GTK_TOOLBAR(timeToolbar), startButton, -1);

		resetButton = gtk_tool_button_new_from_stock(GTK_STOCK_MEDIA_REWIND);
		g_signal_connect(G_OBJECT(resetButton), "clicked",
				G_CALLBACK(resetTimer), NULL);
		gtk_toolbar_insert(GTK_TOOLBAR(timeToolbar), resetButton, -1);

		gtk_toolbar_insert(GTK_TOOLBAR(timeToolbar),
				gtk_separator_tool_item_new(), -1);
	}

	timeFontSelectButton =
		gtk_tool_button_new_from_stock(GTK_STOCK_SELECT_FONT);
	gtk_toolbar_insert(GTK_TOOLBAR(timeToolbar),
			timeFontSelectButton, -1);
	g_signal_connect(G_OBJECT(timeFontSelectButton), "clicked",
			G_CALLBACK(onTimerFontSelectClick), NULL);

	/* setting text size for time label */
	timeElapsedLabel = gtk_label_new(NULL);
	font_desc = pango_font_description_from_string(prefs.font_timer);
	gtk_widget_modify_font(GTK_WIDGET(timeElapsedLabel), font_desc);
	pango_font_description_free(font_desc);
	if (prefs.timer_is_clock)
	{
		printCurrentTime(timeElapsedLabel);
	}
	else
	{
		gtk_label_set_text(GTK_LABEL(timeElapsedLabel), "00:00");
	}

	/* Add timer label to another event box so we can set a nice border.
	 */
	evbox = gtk_event_box_new();
	gtk_container_add(GTK_CONTAINER(evbox), timeElapsedLabel);
	gtk_container_set_border_width(GTK_CONTAINER(evbox), 10);

	/* create timer */
	timeBox = gtk_vbox_new(FALSE, 5);
	gtk_box_pack_start(GTK_BOX(timeBox), evbox,
			TRUE, TRUE, 5);
	gtk_box_pack_start(GTK_BOX(timeBox), timeToolbar,
			FALSE, FALSE, 5);

	if (prefs.timer_is_clock)
	{
		timeFrame = gtk_frame_new("Clock");
	}
	else
	{
		timeFrame = gtk_frame_new("Timer");
	}
	gtk_container_add(GTK_CONTAINER(timeFrame), timeBox);

	/* create note pad inside a scrolled window */
	notePadBox = gtk_vbox_new(FALSE, 2);
	notePadScroll = gtk_scrolled_window_new(NULL, NULL);
	gtk_container_set_border_width(GTK_CONTAINER(notePadScroll), 5);
	notePadFrame = gtk_frame_new("Notes for current slide");
	notePad = gtk_text_view_new();
	gtk_text_view_set_editable(GTK_TEXT_VIEW(notePad), FALSE);
	gtk_text_view_set_cursor_visible(GTK_TEXT_VIEW(notePad), FALSE);
	g_signal_connect(G_OBJECT(notePad), "key_press_event",
			G_CALLBACK(onPadKeyPressed), NULL);

	/* Remarks:
	 *
	 * - The note pad uses word wrapping. If that's not enough, it also
	 *   uses wrapping on a per character basis.
	 * - The note pad is placed into a GtkScrolledWindow. This window
	 *   allows vertical scrolling but no horizontal scrolling.
	 */
	gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(notePad),
			GTK_WRAP_WORD_CHAR);
	gtk_container_add(GTK_CONTAINER(notePadScroll), notePad);
	gtk_scrolled_window_set_shadow_type(
			GTK_SCROLLED_WINDOW(notePadScroll), GTK_SHADOW_IN);
	gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(notePadScroll),
			GTK_POLICY_NEVER, GTK_POLICY_ALWAYS);
	gtk_box_pack_start(GTK_BOX(notePadBox), notePadScroll, TRUE,
			TRUE, 2);

	/* set note pad font and margin */
	font_desc = pango_font_description_from_string(prefs.font_notes);
	gtk_widget_modify_font(notePad, font_desc);
	pango_font_description_free(font_desc);

	gtk_text_view_set_left_margin(GTK_TEXT_VIEW(notePad), 5);
	gtk_text_view_set_right_margin(GTK_TEXT_VIEW(notePad), 5);

	noteBuffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(notePad));

	/* We detect changes of the notes by catching the "changed" signal.
	 * As this signal is also emitted when we change the buffer
	 * programmatically, we first have a look if there was a
	 * "begin_user_action" signal. If so, the user has changed the
	 * buffer.
	 */
	g_signal_connect(G_OBJECT(noteBuffer), "changed",
			G_CALLBACK(onEditing), NULL);
	g_signal_connect(G_OBJECT(noteBuffer), "begin_user_action",
			G_CALLBACK(onBeginUserAction), NULL);
	g_signal_connect(G_OBJECT(noteBuffer), "end_user_action",
			G_CALLBACK(onEndUserAction), NULL);

	/* create toolbar */
	toolbar = gtk_toolbar_new();
	gtk_toolbar_set_style(GTK_TOOLBAR(toolbar), GTK_TOOLBAR_ICONS);
	gtk_container_set_border_width(GTK_CONTAINER(toolbar), 5);

	openButton = gtk_tool_button_new_from_stock(GTK_STOCK_OPEN);
	gtk_toolbar_insert(GTK_TOOLBAR(toolbar), openButton, -1);
	g_signal_connect(G_OBJECT(openButton), "clicked",
			G_CALLBACK(onOpenClicked), NULL);

	/* TODO: Tooltips?! */
	saveButton = gtk_tool_button_new_from_stock(GTK_STOCK_SAVE);
	gtk_toolbar_insert(GTK_TOOLBAR(toolbar), saveButton, -1);
	gtk_widget_set_sensitive(GTK_WIDGET(saveButton), FALSE);
	g_signal_connect(G_OBJECT(saveButton), "clicked",
			G_CALLBACK(onSaveClicked), NULL);

	saveAsButton = gtk_tool_button_new_from_stock(GTK_STOCK_SAVE_AS);
	gtk_toolbar_insert(GTK_TOOLBAR(toolbar), saveAsButton, -1);
	g_signal_connect(G_OBJECT(saveAsButton), "clicked",
			G_CALLBACK(onSaveAsClicked), NULL);

	gtk_toolbar_insert(GTK_TOOLBAR(toolbar),
			gtk_separator_tool_item_new(), -1);

	editButton = gtk_toggle_tool_button_new_from_stock(GTK_STOCK_EDIT);
	gtk_toolbar_insert(GTK_TOOLBAR(toolbar), editButton, -1);
	g_signal_connect(G_OBJECT(editButton), "toggled",
			G_CALLBACK(onEditToggled), NULL);

	fontSelectButton =
		gtk_tool_button_new_from_stock(GTK_STOCK_SELECT_FONT);
	gtk_toolbar_insert(GTK_TOOLBAR(toolbar), fontSelectButton, -1);
	g_signal_connect(G_OBJECT(fontSelectButton), "clicked",
			G_CALLBACK(onFontSelectClick), NULL);

	gtk_box_pack_start(GTK_BOX(notePadBox), toolbar, FALSE, FALSE, 2);
	gtk_container_add(GTK_CONTAINER(notePadFrame), notePadBox);

	/* init containers for "preview" */
	table = gtk_table_new(numframes, numframes + 1, TRUE);
	gtk_table_set_col_spacings(GTK_TABLE(table), 5);
	gtk_container_set_border_width(GTK_CONTAINER(table), 10);

	/* dynamically create all the frames */
	for (i = 0; i < numframes; i++)
	{
		/* calc the offset for this frame */
		transIndex = i - (int)((double)numframes / 2.0);

		/* create the widget - note that it is important not to
		 * set the title to NULL. this would cause a lot more
		 * redraws on startup because the frame will get re-
		 * allocated when the title changes. */
		frame = gtk_frame_new("");

		/* create a new drawing area - the pdf will be rendered in
		 * there */
		image = gtk_image_new();

		/* add widgets to their parents. the image is placed in an
		 * eventbox, the box's size_allocate signal will be handled. so,
		 * we know the exact width/height we can render into. (placing
		 * the image into the frame would create the need of knowing the
		 * frame's border size...)
		 */
		evbox = gtk_event_box_new();
		gtk_container_add(GTK_CONTAINER(evbox), image);
		gtk_container_add(GTK_CONTAINER(frame), evbox);

		/* every frame will be placed in another eventbox so we can set a
		 * background color */
		outerevbox = gtk_event_box_new();
		gtk_container_add(GTK_CONTAINER(outerevbox), frame);

		if (i == 0)
		{
			gtk_table_attach_defaults(GTK_TABLE(table), notePadFrame,
					0, 1, 0, numframes - 1);
			gtk_table_attach_defaults(GTK_TABLE(table), outerevbox,
					0, 1, numframes - 1, numframes);
		}
		else
		{
			if (i == numframes - 1)
			{
				gtk_table_attach_defaults(GTK_TABLE(table), outerevbox,
						numframes, numframes + 1,
						0, 1);
				gtk_table_attach_defaults(GTK_TABLE(table), timeFrame,
						numframes, numframes + 1,
						numframes - 1, numframes);
			}
			else
			{
				if (i == (int)(numframes / 2))
				{
					gtk_table_attach_defaults(GTK_TABLE(table),
							outerevbox, i, i + 2, 0, numframes);
				}
				else
				{
					if (i < (int)(numframes / 2))
					{
						gtk_table_attach_defaults(GTK_TABLE(table),
								outerevbox, i, i + 1,
								numframes - i - 1, numframes - i);
					}
					else
					{
						gtk_table_attach_defaults(GTK_TABLE(table),
								outerevbox, i + 1, i + 2,
								numframes - i - 1, numframes - i);
					}
				}
			}
		}

		/* make the eventbox "transparent" */
		gtk_event_box_set_visible_window(GTK_EVENT_BOX(evbox), FALSE);

		/* save info of this rendering port */
		thisport = (struct viewport *)malloc(sizeof(struct viewport));
		g_assert(thisport);
		thisport->offset = transIndex;
		thisport->image = image;
		thisport->frame = frame;
		thisport->pixbuf = NULL;
		thisport->width = -1;
		thisport->height = -1;
		thisport->isBeamer = FALSE;
		ports = g_list_append(ports, thisport);

		/* resize callback */
		g_signal_connect(G_OBJECT(evbox), "size_allocate",
				G_CALLBACK(onResize), thisport);
		g_signal_connect(G_OBJECT(evbox), "expose_event",
				G_CALLBACK(onExpose), thisport);
	}

	/* Add main content and a status bar to preview window.
	 *
	 * Note: It's important to use gtk_box_pack_* to add the statusbar
	 * because gtk_container_add will pick unappropriate defaults. */
	mainVBox = gtk_vbox_new(FALSE, 5);
	gtk_container_add(GTK_CONTAINER(mainVBox), table);

	mainStatusbar = gtk_statusbar_new();
	gtk_box_pack_end(GTK_BOX(mainVBox), mainStatusbar,
			FALSE, FALSE, 0);

	setStatusText_strdup("Ready.");

	gtk_container_add(GTK_CONTAINER(win_preview), mainVBox);

	/* in order to set the initially highlighted frame */
	refreshFrames();

	/* add a rendering area to the beamer window */
	image = gtk_image_new();

	gtk_container_add(GTK_CONTAINER(win_beamer), image);

	/* save info of this rendering port */
	thisport = (struct viewport *)malloc(sizeof(struct viewport));
	g_assert(thisport);
	thisport->offset = 0;
	thisport->image = image;
	thisport->frame = NULL;
	thisport->pixbuf = NULL;
	thisport->width = -1;
	thisport->height = -1;
	thisport->isBeamer = TRUE;
	ports = g_list_append(ports, thisport);

	/* connect the on-resize-callback directly to the window */
	g_signal_connect(G_OBJECT(win_beamer), "size_allocate",
			G_CALLBACK(onResize), thisport);
	g_signal_connect(G_OBJECT(win_beamer), "expose_event",
			G_CALLBACK(onExpose), thisport);

	/* load notes if requested */
	if (notefile)
	{
		showNotesFromFile(notefile);
	}

	/* Set default sizes for both windows. (Note: If the widgets don't
	 * fit into that space, the windows will be larger. Also, they are
	 * allowed to get shrinked by the user.) */
	gtk_window_set_default_size(GTK_WINDOW(win_preview), 640, 480);
	gtk_window_set_default_size(GTK_WINDOW(win_beamer), 320, 240);

	/* show the windows */
	gtk_widget_show_all(win_preview);
	gtk_widget_show_all(win_beamer);

	/* now, as the real gdk window exists, hide mouse cursor in the
	 * beamer window */
	gdk_window_set_cursor(gtk_widget_get_window(GTK_WIDGET(win_beamer)),
			gdk_cursor_new(GDK_BLANK_CURSOR));

	/* Show a clock or a timer? */
	if (prefs.timer_is_clock)
	{
		g_timeout_add(500, (GSourceFunc)printCurrentTime,
				(gpointer)timeElapsedLabel);
	}
	else
	{
		g_timeout_add(500, (GSourceFunc)printTimeElapsed,
				(gpointer)timeElapsedLabel);
	}
}
Пример #7
0
static gboolean onKeyPressed(GtkWidget *widget, GdkEventKey *ev,
		gpointer data)
{
	/* Unused parameters. */
	(void)data;

	guint key = ev->keyval;
	gchar *msg = NULL;

	/* When inside the note pad, don't do anything here. */
	if (isInsideNotePad)
		return FALSE;

	/* Jump command?
	 *
	 * Note: This works as long as the values of GDK keysyms satisfy:
	 *   1)  GDK_0 < GDK_1 < GDK_2 < ... < GDK_9
	 *   2)  All of them must be >= 0.
	 */
	key -= GDK_0;
	if (key <= 9)
	{
		/* The initial value is -1, so we have to reset this on the
		 * first key stroke. */
		if (target_page < 0)
			target_page = 0;

		/* Do a "decimal left shift" and add the given value. */
		target_page *= 10;
		target_page += (int)key;

		/* Catch overflow and announce what would happen. */
		if (target_page < 0)
		{
			target_page = -1;
			setStatusText_strdup("Invalid page.");
		}
		else
		{
			msg = g_strdup_printf("Jump to page: %d", target_page);
			setStatusText_strdup(msg);
			g_free(msg);
		}

		return FALSE;
	}

	gboolean changed = TRUE;
	saveCurrentNote();

	switch (ev->keyval)
	{
		case GDK_Right:
		case GDK_Down:
		case GDK_Page_Down:
		case GDK_space:
			nextSlide();
			break;

		case GDK_Left:
		case GDK_Up:
		case GDK_Page_Up:
			prevSlide();
			break;

		case GDK_F5:
			/* Switch to fullscreen (if needed) and start the timer
			 * (unless it's already running). */
			if (!isFullScreen)
				toggleFullScreen();
			if (timerMode != 1)
				toggleTimer();
			break;

		case GDK_F6:
			/* this shall trigger a hard refresh, so empty the cache. */
			clearCache();
			break;

		case GDK_w:
			runpref.fit_mode = FIT_WIDTH;
			break;

		case GDK_h:
			runpref.fit_mode = FIT_HEIGHT;
			break;

		case GDK_p:
			runpref.fit_mode = FIT_PAGE;
			break;

		case GDK_l:
			current_fixate();
			break;

		case GDK_L:
			current_release(FALSE);
			break;

		case GDK_J:
			current_release(TRUE);
			break;

		case GDK_f:
			toggleFullScreen();
			break;

		case GDK_s:
			toggleTimer();
			changed = FALSE;
			break;

		case GDK_c:
			toggleCurserVisibility();
			break;

		case GDK_r:
			resetTimer();
			changed = FALSE;
			break;

		case GDK_Escape:
		case GDK_q:
			if (prefs.q_exits_fullscreen && isFullScreen)
			{
				toggleFullScreen();
				if (prefs.stop_timer_on_fs)
				{
					toggleTimer();
				}
			}
			else
			{
				changed = FALSE;
				onQuit(NULL, NULL, NULL);
			}
			break;

		case GDK_i:
			/* This must not work when we're on the beamer window. */
			if (widget != win_beamer)
				setEditingState(TRUE);

			changed = FALSE;
			break;

		case GDK_Return:
			if (executeJump() == 0)
				nextSlide();
			break;

		case GDK_G:
			executeJump();
			break;

		case GDK_period:
		case GDK_b:
			toggleBlankBeamer();
			changed = FALSE;
			break;

		default:
			changed = FALSE;
	}

	if (changed == TRUE)
	{
		refreshPorts();
	}

	return TRUE;
}