Bug#790196: rasmol: Port to GTK+ 3 / VTE 2.91

Yavor Doganov yavor at gnu.org
Thu Sep 6 13:13:32 BST 2018


tags 790196 + patch
thanks

Attached is a patch which should fix this bug.

I used molecule files from src:avogadro to test.  (I think) I tried
all actions and couldn't spot any problems.  One known regression is
that the accelerators don't work when the menubar is hidden.  (I've
made only F9 to work so that the menubar can be brought back.)  There
might be other regressions as I'm not familiar with GTK+ API and I'm
not a proper programmer either.  One minor improvement is that the
tooltips work.

The second patch is only remotely related, it fixes the build system
so that LDFLAGS get inherited from the environment.  This is necessary
because traditionally GNOME/GTK+ libraries expose their dependencies
which results in overlinking causing unnecessary dependencies.

The third patch should fix the FTBFS on GNU/Hurd (untested).

I just subsribed to this package and will do my best to fix any issues
that arise as a result of my porting attempt.
-------------- next part --------------
>From 0545dcee54c57128d82872e2a016f8c43978530a Mon Sep 17 00:00:00 2001
From: Yavor Doganov <yavor at gnu.org>
Date: Thu, 6 Sep 2018 13:53:09 +0300
Subject: [PATCH 1/3] Port to GTK+ 3 / VTE 2.91

---
 debian/control                    |    3 +-
 debian/patches/14_gtk3-port.patch | 1979 +++++++++++++++++++++++++++++
 debian/patches/series             |    1 +
 3 files changed, 1981 insertions(+), 2 deletions(-)
 create mode 100644 debian/patches/14_gtk3-port.patch

diff --git a/debian/control b/debian/control
index 4bdd239..b7a9bd4 100644
--- a/debian/control
+++ b/debian/control
@@ -10,8 +10,7 @@ Build-Depends: debhelper (>= 11~),
                libxext-dev,
                libxi-dev,
                x11proto-core-dev,
-               libvte-dev,
-               libgtk2.0-dev,
+               libvte-2.91-dev,
                libcbf-dev,
                libcvector2-dev,
                libcqrlib2-dev,
diff --git a/debian/patches/14_gtk3-port.patch b/debian/patches/14_gtk3-port.patch
new file mode 100644
index 0000000..afd8bbe
--- /dev/null
+++ b/debian/patches/14_gtk3-port.patch
@@ -0,0 +1,1979 @@
+Description: Port to GTK+ 3 and VTE 2.91.
+ The real changes required are minimalistic; this patch is largish
+ because I wanted to avoid the deprecated API which will be removed in
+ GTK+ 4 (GtkUIManager, GtkAction and friends) and would require yet
+ another porting effort.  I deliberately chose to use the basic API
+ (rather than GtkBuilder, GtkApplication and GAction) because the GTK+
+ folks have a tendency to deprecate these high level APIs fairly
+ quickly.  Another reason for this choice is that I wanted to avoid
+ XML stuff; I find it extremely unpleasant to deal with.
+ .
+ However, this approach made the patch convoluted as I realized way
+ too late that there is a fully-fledged popup menu with nearly all
+ actions exposed.  These have to be kept in sync programmatically,
+ which is done in a clumsy/inefficient way.
+Debian-Bug: https://bugs.debian.org/790196
+Author: Yavor Doganov <yavor at gnu.org>
+Forwarded: no
+Last-Update: 2018-09-06
+---
+
+--- rasmol.orig/src/Imakefile
++++ rasmol/src/Imakefile
+@@ -131,9 +131,8 @@
+ #endif
+ 
+ #ifdef GTKWIN
+-#GTKLIBS = $(shell pkg-config --libs vte gtk+-2.0)
+-GTKLIBS = -lvte -lgtk-x11-2.0 -lgdk-x11-2.0 -lgdk_pixbuf-2.0 -lgobject-2.0 -lglib-2.0 -lcairo -lX11
+-GTKCFLAGS = $(shell pkg-config --cflags vte gtk+-2.0)
++GTKLIBS = $(shell pkg-config --libs vte-2.91)
++GTKCFLAGS = $(shell pkg-config --cflags vte-2.91)
+ GUISRC = gtkwin.c eggfileformatchooser.c 
+ GUIOBJ = gtkwin.o eggfileformatchooser.o
+ GUIDEF = -DGTKWIN
+@@ -437,13 +436,9 @@
+ 
+ gtkwin.c: gtkui.h
+ 
+-gtkui.h: sizechooser.glade printing-resolution.glade actionmenu.gtk
++gtkui.h: sizechooser.glade printing-resolution.glade
+ 	 echo "/* Automatically generated GTK ui definitions, do not edit! */" > gtkui.h
+ 	 echo >> gtkui.h
+-	 echo "const gchar *actionmenu_str = \"\\" >> gtkui.h
+-	 cat actionmenu.gtk | sed "s/$$/\\\/" | sed 's/"/\\\"/g' >> gtkui.h
+-	 echo "\";" >> gtkui.h
+-	 echo >> gtkui.h
+ 	 echo "const gchar *sizechooser_str = \"\\" >> gtkui.h
+ 	 gtk-builder-convert -w sizechooser.glade - | sed "s/$$/\\\/" | sed 's/"/\\\"/g' >> gtkui.h
+ 	 echo "\";" >> gtkui.h
+@@ -452,4 +447,3 @@
+ 	 gtk-builder-convert -w printing-resolution.glade - | sed "s/$$/\\\/" | sed 's/"/\\\"/g' >> gtkui.h
+ 	 echo "\";" >> gtkui.h
+ 	 echo >> gtkui.h
+-	 gdk-pixbuf-csource --name=rasmol_icon --struct rasmol_48x48.xpm  >> gtkui.h
+--- rasmol.orig/src/eggfileformatchooser.h
++++ rasmol/src/eggfileformatchooser.h
+@@ -19,7 +19,7 @@
+ #ifndef __EGG_FILE_FORMAT_CHOOSER_H__
+ #define __EGG_FILE_FORMAT_CHOOSER_H__
+ 
+-#include <gtk/gtkexpander.h>
++#include <gtk/gtk.h>
+ 
+ G_BEGIN_DECLS
+ 
+--- rasmol.orig/src/gtkwin.c
++++ rasmol/src/gtkwin.c
+@@ -106,6 +106,7 @@
+ #include "gtkwin.h"
+ #include "gtkui.h"
+ #include "eggfileformatchooser.h"
++#include "rasmol_48x48.xpm"
+ 
+ 
+ #define RASGTK_MINWIDTH  300
+@@ -127,6 +128,9 @@
+ GtkWidget *mainwin;
+ GtkWidget *mainvbox;
+ GtkWidget *menubar;
++GtkWidget *popup;
++GtkWidget *filemenu;
++GtkWidget *menus;
+ GtkWidget *mainvpane;
+ GtkWidget *ctable;
+ GtkWidget *canvasarea;
+@@ -155,7 +159,7 @@
+ 	RES_150,
+ 	RES_300
+ };
+-uintptr_t print_resolution = RES_CURRENT;
++int print_resolution = RES_CURRENT;
+ GtkPrintSettings *print_settings = NULL;
+ GtkPageSetup *print_pagesetup = NULL;
+ 
+@@ -169,8 +173,8 @@
+ guint merge_id;
+ gboolean dragging = FALSE;
+ 
+-#define ADDSIGNAL(A,B) g_signal_connect(gtk_ui_manager_get_action(ui_manager,\
+-(A)),"activate", G_CALLBACK(handlemenu_cb), (gpointer) &(B));
++#define ADDSIGNAL(A,B) g_signal_connect(A, "activate", \
++                         G_CALLBACK(handlemenu_cb), (gpointer) &(B));
+ 
+ /* Magic numbers for menus */
+ #define FILEMENU (0<<8)
+@@ -249,37 +253,260 @@
+ static const int m_h_register = (HELPMENU + 3);
+ static const int m_h_donate = (HELPMENU + 4);
+ 
+-
+-gboolean handlemenu_cb(GtkAction *action, gpointer user_data)
+-{
++/* Helper function to block signal emission when synchronizing the
++   state of the menu items in the callbacks.  */
++void sync_item(GtkCheckMenuItem *item, gpointer func,
++               gpointer data, gboolean state)
++{
++        g_signal_handlers_block_by_func(item, func, data);
++        gtk_check_menu_item_set_active(item, state);
++        g_signal_handlers_unblock_by_func(item, func, data);
++}
++
++gboolean handlemenu_cb(GtkMenuItem *item, gpointer user_data)
++{
++	GObject *mbar = G_OBJECT(menubar);
++	GtkCheckMenuItem *sibling = NULL;
++	gchar *kind;
++	gint active;
+ 	int menu;
+ 	
+ 	menu = *((int *)user_data);
+ 	HandleMenu(menu);
+-	/* Handle the strange tristate toggle on stereo mode */
+-	if(menu == m_o_stereo) {
+-		gtk_toggle_action_set_active((GtkToggleAction *)action, UseStereo);
++	kind = g_object_get_data(G_OBJECT(item), "kind");
++
++	/* Synchronize the state between items in the two menus.  */
++	if (kind && GTK_IS_CHECK_MENU_ITEM(item)) {
++	    active = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(item));
++	    switch (menu) {
++	        case m_o_slab:
++	            if (!g_ascii_strcasecmp(kind, "slab"))
++	                sibling = g_object_get_data(mbar, "slab_pop");
++	            else if (!g_ascii_strcasecmp(kind, "slab_pop"))
++	                sibling = g_object_get_data(mbar, "slab");
++
++	            sync_item(sibling, handlemenu_cb, user_data, active);
++	            break;
++
++	        case m_o_hydrogens:
++	            if (!g_ascii_strcasecmp(kind, "hydr"))
++	                sibling = g_object_get_data(mbar, "hydr_pop");
++	            else if (!g_ascii_strcasecmp(kind, "hydr_pop"))
++	                sibling = g_object_get_data(mbar, "hydr");
++
++	            sync_item(sibling, handlemenu_cb, user_data, active);
++	            break;
++
++	        case m_o_heteros:
++	            if (!g_ascii_strcasecmp(kind, "het"))
++	                sibling = g_object_get_data(mbar,"het_pop");
++	            else if (!g_ascii_strcasecmp(kind, "het_pop"))
++	                sibling = g_object_get_data(mbar, "het");
++
++	            sync_item(sibling, handlemenu_cb, user_data, active);
++	            break;
++
++	        case m_o_specular:
++	            if (!g_ascii_strcasecmp(kind, "spec"))
++	                sibling = g_object_get_data(mbar, "spec_pop");
++	            else if (!g_ascii_strcasecmp(kind, "spec_pop"))
++	                sibling = g_object_get_data(mbar, "spec");
++
++	            sync_item(sibling, handlemenu_cb, user_data, active);
++	            break;
++
++	        case m_o_shadows:
++	            if (!g_ascii_strcasecmp(kind, "shad"))
++	                sibling = g_object_get_data(mbar, "shad_pop");
++	            else if (!g_ascii_strcasecmp(kind, "shad_pop"))
++	                sibling = g_object_get_data(mbar, "shad");
++
++	            sync_item(sibling, handlemenu_cb, user_data, active);
++	            break;
++
++	        case m_o_stereo:
++	            if (!g_ascii_strcasecmp(kind, "ster"))
++	                sibling = g_object_get_data(mbar, "ster_pop");
++	            else if (!g_ascii_strcasecmp(kind, "ster_pop"))
++	                sibling = g_object_get_data(mbar, "ster");
++
++	            sync_item(sibling, handlemenu_cb, user_data, active);
++	            /* Handle the strange tristate toggle on stereo mode */
++	            if (active)
++	                UseStereo = True;
++	            else
++	                UseStereo = False;
++
++	            break;
++
++	        case m_o_labels:
++	            if (!g_ascii_strcasecmp(kind, "label"))
++	                sibling = g_object_get_data(mbar, "label_pop");
++	            else if (!g_ascii_strcasecmp(kind, "label_pop"))
++	                sibling = g_object_get_data(mbar, "label");
++
++	            sync_item(sibling, handlemenu_cb, user_data, active);
++	            break;
++
++	        default:
++	            break;
++	    }
+ 	}
++
+ 	if( ReDrawFlag ) {
+     	RefreshScreen();
++	gtk_widget_queue_draw(canvasarea);
+     	ReDrawFlag = NextReDrawFlag;
+ 	}
+ 	return FALSE;
+ }
+ 
+-void radio_cb (GtkRadioAction *action, GtkRadioAction *current, gpointer user_data)
++void radio_cb (GtkCheckMenuItem *item, gpointer data)
+ {
+-	gint value;
++	GObject *mbar = G_OBJECT(menubar);
++	GtkCheckMenuItem *sibling = NULL;
++	gint value, active, kind;
++
++	if (!gtk_check_menu_item_get_active(item))
++	    return;
++
++	value = GPOINTER_TO_INT(data);
++	kind = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(item), "kind"));
++	active = gtk_check_menu_item_get_active(item);
++
++	switch (value) {
++	    case m_s_poff:
++	        if (kind > 10)
++	        sibling = g_object_get_data(mbar, "pick_pop0");
++	        else
++	        sibling = g_object_get_data(mbar, "pick0");
++
++	        sync_item(sibling, radio_cb, data, active);
++	        break;
++
++	    case m_s_pident:
++	        if (kind > 10)
++	            sibling = g_object_get_data(mbar, "pick_pop1");
++	        else
++	            sibling = g_object_get_data(mbar, "pick1");
++
++	        /* Will be NULL when constructing the UI.  */
++	        if (sibling)
++	            sync_item(sibling, radio_cb, data, active);
++	        break;
++
++	    case m_s_pdist:
++	        if (kind > 10)
++	            sibling = g_object_get_data(mbar, "pick_pop2");
++	        else
++	            sibling = g_object_get_data(mbar, "pick2");
++
++	        sync_item(sibling, radio_cb, data, active);
++	        break;
++
++	    case m_s_pmon:
++	        if (kind > 10)
++	            sibling = g_object_get_data(mbar, "pick_pop3");
++	        else
++	            sibling = g_object_get_data(mbar, "pick3");
++
++	        sync_item(sibling, radio_cb, data, active);
++	        break;
++
++	    case m_s_pangle:
++	        if (kind > 10)
++	            sibling = g_object_get_data(mbar, "pick_pop4");
++	        else
++	            sibling = g_object_get_data(mbar, "pick4");
++
++	        sync_item(sibling, radio_cb, data, active);
++	        break;
++
++	    case m_s_ptorsion:
++	        if (kind > 10)
++	            sibling = g_object_get_data(mbar, "pick_pop5");
++	        else
++	            sibling = g_object_get_data(mbar, "pick5");
++
++	        sync_item(sibling, radio_cb, data, active);
++	        break;
++
++	    case m_s_plabel:
++	        if (kind > 10)
++	            sibling = g_object_get_data(mbar, "pick_pop6");
++	        else
++	            sibling = g_object_get_data(mbar, "pick6");
++
++	            sync_item(sibling, radio_cb, data, active);
++	        break;
++
++	    case m_s_pcentre:
++	        if (kind > 10)
++	            sibling = g_object_get_data(mbar, "pick_pop7");
++	        else
++	            sibling = g_object_get_data(mbar, "pick7");
++
++	        sync_item(sibling, radio_cb, data, active);
++	        break;
++
++	    case m_s_pcoord:
++	        if (kind > 10)
++	            sibling = g_object_get_data(mbar, "pick_pop8");
++	        else
++	            sibling = g_object_get_data(mbar, "pick8");
++
++	        sync_item(sibling, radio_cb, data, active);
++	        break;
++
++	    case m_s_pbond:
++	        if (kind > 10)
++	            sibling = g_object_get_data(mbar, "pick_pop9");
++	        else
++	            sibling = g_object_get_data(mbar, "pick9");
++
++	        sync_item(sibling, radio_cb, data, active);
++	        break;
++
++	    case m_s_rbond:
++	        if (kind > 10)
++	            sibling = g_object_get_data(mbar, "rotbond_pop");
++	        else
++	            sibling = g_object_get_data(mbar, "rotbond");
++
++	        sync_item(sibling, radio_cb, data, active);
++	        break;
++
++	    case m_s_rmol:
++	        if (kind > 10)
++	            sibling = g_object_get_data(mbar, "rotmol_pop");
++	        else
++	            sibling = g_object_get_data(mbar, "rotmol");
++
++	        sync_item(sibling, radio_cb, data, active);
++	        break;
++
++	    case m_s_rall:
++	        if (kind > 10)
++	            sibling = g_object_get_data(mbar, "rotall_pop");
++	        else
++	            sibling = g_object_get_data(mbar, "rotall");
++
++	        sync_item(sibling, radio_cb, data, active);
++	        break;
++
++	    default:
++	        break;
++	}
+ 
+-	value = gtk_radio_action_get_current_value (action);
+ 	HandleMenu(value);
+ 	if( ReDrawFlag ) {
+     	RefreshScreen();
++	gtk_widget_queue_draw(canvasarea);
+     	ReDrawFlag = NextReDrawFlag;
+ 	}
+ }
+ 
+-void open_cb(GtkAction *action, gpointer user_data)
++void open_cb(GtkMenuItem *item, gpointer user_data)
+ {
+     static char *prevname = NULL;
+     GtkWidget *opendialog = NULL;
+@@ -289,8 +516,8 @@
+     opendialog = gtk_file_chooser_dialog_new ("Open File",
+         GTK_WINDOW(mainwin),
+         GTK_FILE_CHOOSER_ACTION_OPEN,
+-        GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+-        GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
++        "_Cancel", GTK_RESPONSE_CANCEL,
++        "_Open", GTK_RESPONSE_ACCEPT,
+         NULL);
+ 
+     filter = gtk_file_filter_new();
+@@ -344,6 +571,7 @@
+             }
+             DefaultRepresentation();
+             RefreshScreen();
++            gtk_widget_queue_draw(canvasarea);
+         } else {
+             ;
+         }
+@@ -352,7 +580,7 @@
+     gtk_widget_destroy (opendialog);
+ }
+ 
+-void save_cb(GtkAction *action, gpointer user_data)
++void save_cb(GtkMenuItem *item, gpointer user_data)
+ {
+ 	static char *prevname = NULL;
+ 	GtkWidget *dialog;
+@@ -361,8 +589,8 @@
+ 	dialog = gtk_file_chooser_dialog_new ("Save to a PDB file",
+ 				      GTK_WINDOW(mainwin),
+ 				      GTK_FILE_CHOOSER_ACTION_SAVE,
+-				      GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+-				      GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT,
++				      "_Cancel", GTK_RESPONSE_CANCEL,
++				      "_Save", GTK_RESPONSE_ACCEPT,
+ 				      NULL);
+ 	gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_ACCEPT);
+ 	if(prevname) {
+@@ -521,8 +749,8 @@
+ 	exportdialog = gtk_file_chooser_dialog_new ("Export image to a file",
+ 					  GTK_WINDOW(mainwin),
+ 				      GTK_FILE_CHOOSER_ACTION_SAVE,
+-				      GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+-				      GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT,
++				      "_Cancel", GTK_RESPONSE_CANCEL,
++				      "_Save", GTK_RESPONSE_ACCEPT,
+ 				      NULL);
+    
+ 	format_chooser = egg_file_format_chooser_new ();   
+@@ -554,7 +782,7 @@
+ 	
+ 	size_chooser = GTK_WIDGET(gtk_builder_get_object(sizebuilder, "size_expander"));
+ 	
+-	extrabox = gtk_vbox_new(FALSE, 0);
++	extrabox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
+ 	g_assert(extrabox);
+ 	gtk_box_pack_start(GTK_BOX(extrabox), format_chooser, TRUE, TRUE, 0);
+ 	gtk_box_pack_start(GTK_BOX(extrabox), size_chooser, TRUE, TRUE, 10);
+@@ -568,7 +796,7 @@
+ }
+ 
+ 
+-void export_cb(GtkAction * action, gpointer user_data)
++void export_cb(GtkMenuItem * item, gpointer user_data)
+ {
+     static char *fname = NULL;
+ 
+@@ -680,7 +908,7 @@
+ }
+ 
+ 
+-void pagesetup_cb(GtkAction *action, gpointer user_data)
++void pagesetup_cb(GtkMenuItem *item, gpointer user_data)
+ {
+ 	if (print_pagesetup == NULL) {
+ 		print_pagesetup = gtk_page_setup_new();
+@@ -812,7 +1040,7 @@
+ 	return widget;
+ }
+ 
+-void print_cb(GtkAction *action, gpointer user_data)
++void print_cb(GtkMenuItem *item, gpointer user_data)
+ {
+ 	GtkPrintOperation *print;
+   	GtkPrintOperationResult res;
+@@ -868,12 +1096,22 @@
+ 		NULL);
+ }
+ 
++static void show_menubar_cb(GtkMenuItem *menu)
++{
++	gtk_menu_item_activate(menu);
++}
++
+ void build_window(void)
+ {
+ 	GList *vlist;
+-	GtkAction *a;
++	GtkCheckMenuItem *terminal, *scrollbars, *fullscreen;
++	GObject *mbar = G_OBJECT(menubar);
+ 	gint x, y;
+ 	
++	terminal = g_object_get_data(mbar, "terminal");
++	scrollbars = g_object_get_data(mbar, "scrollbars");
++	fullscreen = g_object_get_data(mbar, "fullscreen");
++
+ 	vlist = gtk_container_get_children(GTK_CONTAINER(mainvbox));
+ 	while(vlist) {
+ 		g_object_ref(vlist->data);
+@@ -881,8 +1119,7 @@
+ 		vlist = vlist->next;
+ 	}	
+ 	
+-	a = gtk_ui_manager_get_action(ui_manager, "/MainMenu/ViewMenu/Menus");
+-	if(gtk_toggle_action_get_active(GTK_TOGGLE_ACTION(a))) {
++	if (gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menus))) {
+ 		gtk_box_pack_start(GTK_BOX(mainvbox), menubar, FALSE, FALSE, 0);
+ 	}
+ 
+@@ -892,17 +1129,11 @@
+ 		gtk_container_remove(GTK_CONTAINER(ctable), GTK_WIDGET(vlist->data));
+ 		vlist = vlist->next;
+ 	}
+-	gtk_table_attach(GTK_TABLE(ctable), canvasarea, 0, 1, 0, 1,
+-		     GTK_EXPAND | GTK_FILL | GTK_SHRINK, 
+-			 GTK_EXPAND | GTK_FILL | GTK_SHRINK, 0, 0);
+-	a = gtk_ui_manager_get_action(ui_manager, "/MainMenu/ViewMenu/Scrolls");
+-	if(gtk_toggle_action_get_active(GTK_TOGGLE_ACTION(a))) {
+-		gtk_table_attach(GTK_TABLE(ctable), vscrollbar, 1, 2, 0, 1,
+-		     	GTK_EXPAND | GTK_FILL | GTK_SHRINK,
+-			 	GTK_EXPAND | GTK_FILL | GTK_SHRINK, 0, 0);
+-		gtk_table_attach(GTK_TABLE(ctable), hscrollbar, 0, 1, 1, 2,
+-		     	GTK_EXPAND | GTK_FILL | GTK_SHRINK, 
+-			 	GTK_EXPAND | GTK_FILL | GTK_SHRINK, 0, 0);
++	gtk_grid_attach(GTK_GRID(ctable), canvasarea, 0, 0, 1, 1);
++
++	if(gtk_check_menu_item_get_active(scrollbars)) {
++	        gtk_grid_attach(GTK_GRID(ctable), vscrollbar, 1, 0, 1, 1);
++	        gtk_grid_attach(GTK_GRID(ctable), hscrollbar, 0, 1, 1, 1);
+ 	}
+ 		
+ 	vlist = gtk_container_get_children(GTK_CONTAINER(mainvpane));
+@@ -912,8 +1143,7 @@
+ 		vlist = vlist->next;
+ 	}
+ 	
+-	a = gtk_ui_manager_get_action(ui_manager, "/MainMenu/ViewMenu/Command");
+-	if(gtk_toggle_action_get_active(GTK_TOGGLE_ACTION(a))) {
++	if(gtk_check_menu_item_get_active(terminal)) {
+ 		gtk_window_get_size(GTK_WINDOW(mainwin), &x, &y);
+ 		gtk_paned_set_position(GTK_PANED(mainvpane), y-200);
+ 		gtk_paned_pack1(GTK_PANED(mainvpane), ctable, TRUE, TRUE);
+@@ -922,11 +1152,10 @@
+ 	} else {
+ 		gtk_box_pack_start(GTK_BOX(mainvbox), ctable, TRUE, TRUE, 0);
+ 	}	  
+-	gtk_adjustment_value_changed(VTE_TERMINAL(vte)->adjustment);
+     gtk_widget_show_all (mainvbox);
+ 	
+-	a = gtk_ui_manager_get_action(ui_manager, "/MainMenu/ViewMenu/Fullscreen");
+-	if(gtk_toggle_action_get_active(GTK_TOGGLE_ACTION(a))) {
++
++	if(gtk_check_menu_item_get_active(fullscreen)) {
+ 		gtk_window_fullscreen(GTK_WINDOW(mainwin));
+ 	} else {
+ 		gtk_window_unfullscreen(GTK_WINDOW(mainwin));
+@@ -934,47 +1163,90 @@
+ }
+ 
+ 
+-void view_cb(GtkAction *action, gpointer user_data)
++void view_cb(GtkCheckMenuItem *item, gpointer user_data)
+ {
++    GObject *mbar = G_OBJECT(menubar);
++    GtkCheckMenuItem *sibling;
++    gchar *kind;
++    gint active;
++
++    active = gtk_check_menu_item_get_active(item);
++    kind = g_object_get_data(G_OBJECT(item), "kind");
++    if (kind)
++        {
++            if (!g_ascii_strcasecmp(kind, "terminal")) {
++                sibling = g_object_get_data(mbar, "term_pop");
++                sync_item(sibling, view_cb, user_data, active);
++            }
++            else if (!g_ascii_strcasecmp(kind, "term_pop")) {
++                sibling = g_object_get_data(mbar, "terminal");
++                sync_item(sibling, view_cb, user_data, active);
++            }
++            else if (!g_ascii_strcasecmp(kind, "scrollbars")) {
++                sibling = g_object_get_data(mbar, "scroll_pop");
++                sync_item(sibling, view_cb, user_data, active);
++            }
++            else if (!g_ascii_strcasecmp(kind, "scroll_pop")) {
++                sibling = g_object_get_data(mbar, "scrollbars");
++                sync_item(sibling, view_cb, user_data, active);
++            }
++            else if (!g_ascii_strcasecmp(kind, "menus")) {
++                sibling = g_object_get_data(mbar, "menus_pop");
++                sync_item(sibling, view_cb, user_data, active);
++            }
++            else if (!g_ascii_strcasecmp(kind, "menus_pop")) {
++                sibling = g_object_get_data(mbar, "menus");
++                sync_item(sibling, view_cb, user_data, active);
++            }
++            else if (!g_ascii_strcasecmp(kind, "fullscreen")) {
++                sibling = g_object_get_data(mbar, "fullscr_pop");
++                sync_item(sibling, view_cb, user_data, active);
++            }
++            else if (!g_ascii_strcasecmp(kind, "fullscr_pop")) {
++                sibling = g_object_get_data(mbar, "fullscreen");
++                sync_item(sibling, view_cb, user_data, active);
++            }
++        }
++
+ 	build_window();
+ }
+ 
+ 
+ void set_ui_elements(int mask)
+ {
+-    GtkAction* a;
++    GObject *mbar = G_OBJECT(menubar);
++    GtkCheckMenuItem* item;
+ 
+-    a = gtk_ui_manager_get_action(ui_manager, "/MainMenu/ViewMenu/Command");
+-    gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(a), mask & UI_COMMAND);
+-    a = gtk_ui_manager_get_action(ui_manager, "/MainMenu/ViewMenu/Scrolls");
+-    gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(a), mask & UI_SCROLLS);
+-    a = gtk_ui_manager_get_action(ui_manager, "/MainMenu/ViewMenu/Menus");
+-    gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(a), mask & UI_MENUS);
+-    a = gtk_ui_manager_get_action(ui_manager, "/MainMenu/ViewMenu/Fullscreen");
+-    gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(a), mask & UI_FULLSCREEN);
++    item = g_object_get_data(mbar, "terminal");
++    gtk_check_menu_item_set_active(item, mask & UI_COMMAND);
++    item = g_object_get_data(mbar, "scrollbars");
++    gtk_check_menu_item_set_active(item, mask & UI_SCROLLS);
++    gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menus), mask & UI_MENUS);
++    item = g_object_get_data(mbar, "fullscreen");
++    gtk_check_menu_item_set_active(item, mask & UI_FULLSCREEN);
+     build_window();
+ }
+ 
+ 
+-void setfont_cb(GtkAction *action, gpointer user_data)
++void setfont_cb(GtkMenuItem *item, gpointer user_data)
+ {
+-	static char *fontname = NULL;
+ 	GtkWidget *d;
++	PangoFontDescription *desc;
+ 	gint result;
+ 	
+-	d = gtk_font_selection_dialog_new("Command prompt font");
+-	if(fontname)
+-		gtk_font_selection_dialog_set_font_name(GTK_FONT_SELECTION_DIALOG(d), fontname);
+-	
++	d = gtk_font_chooser_dialog_new("Command prompt font",
++	                                GTK_WINDOW(mainwin));
++
+ 	result = gtk_dialog_run(GTK_DIALOG(d));
+ 	if(result == GTK_RESPONSE_OK) {
+-		fontname = gtk_font_selection_dialog_get_font_name(GTK_FONT_SELECTION_DIALOG(d));
+-		vte_terminal_set_font_from_string(VTE_TERMINAL(vte), fontname); 
++	        desc = gtk_font_chooser_get_font_desc(GTK_FONT_CHOOSER(d));
++		vte_terminal_set_font(VTE_TERMINAL(vte), desc);
++	        pango_font_description_free(desc);
+ 	}
+ 	gtk_widget_destroy (d);
+ }
+ 
+-void recent_cb(GtkAction *recent, gpointer user_data)
++void recent_cb(GtkRecentChooser *recent, gpointer user_data)
+ {
+     gchar *uri;
+ 
+@@ -984,140 +1256,98 @@
+         FetchFile(FormatPDB, False, uri+5);
+         DefaultRepresentation();
+         RefreshScreen();
++        gtk_widget_queue_draw(canvasarea);
+     }
+ }
+ 
+-static const GtkActionEntry menuentries[] = {
+-  { "FileMenu", NULL, "_File" },
+-  { "Open", GTK_STOCK_OPEN, "_Open...", "<control>O", "Open a file", G_CALLBACK(open_cb) },
+-  { "SaveAs", GTK_STOCK_SAVE_AS, "_Save As...", "<control>S", "Save a file", G_CALLBACK(save_cb) }, 
+-  { "Export", GTK_STOCK_CONVERT, "_Export...", "<control>X", "Export current image", G_CALLBACK(export_cb) },
+-  { "Close", GTK_STOCK_CLOSE, "_Close", "<control>W", "Close the selected molecule", NULL },
+-  { "PageSetup", NULL, "Page Set_up...", "", "Set the page parameters", G_CALLBACK(pagesetup_cb) },
+-  { "Print", GTK_STOCK_PRINT, "_Print...", "<control>P", "Print the current image", G_CALLBACK(print_cb) },
+-  { "Exit", GTK_STOCK_QUIT, "E_xit", "<control>Q", "Exit the program", RasMolExit },
+-  { "ViewMenu", NULL, "_View" },
+-  { "Setfont", NULL, "Set command font...", "", "", G_CALLBACK(setfont_cb) },
+-  { "DispMenu", NULL, "_Display" },
+-  { "Wireframe", NULL, "_Wireframe", "", "", NULL },
+-  { "Backbone", NULL, "_Backbone", "", "", NULL },
+-  { "Sticks", NULL, "S_ticks", "", "", NULL },
+-  { "Spheres", NULL, "_Spacefill", "", "", NULL},
+-  { "Ballstick", NULL, "B_all & stick", "", "", NULL },
+-  { "Ribbons", NULL, "_Ribbons", "", "", NULL },
+-  { "Strands", NULL, "Stran_ds", "", "", NULL },
+-  { "Cartoons", NULL, "_Cartoons", "", "", NULL },
+-  { "MolSurf", NULL, "_Molecular Surface", "", "", NULL },
+-  { "ColMenu", NULL, "_Colours" },
+-  { "Monochrome", NULL, "_Monochrome", "", "", NULL },
+-  { "CPK", NULL, "_CPK", "", "", NULL },
+-  { "Shapely", NULL, "_Shapely", "", "", NULL },
+-  { "Group", NULL, "_Group", "", "", NULL },
+-  { "Chain", NULL, "C_hain", "", "", NULL },
+-  { "Temperature", NULL, "_Temperature", "", "", NULL },
+-  { "Structure", NULL, "St_ructure", "", "", NULL },
+-  { "User", NULL, "_User", "", "", NULL },
+-  { "Model", NULL, "Mo_del", "", "", NULL },
+-  { "Alt", NULL, "_Alt", "", "", NULL },
+-  { "OptMenu", NULL, "_Options" },
+-  { "SetMenu", NULL, "_Settings" },
+-  { "HelpMenu", NULL, "_Help" },
+-  { "Manual", GTK_STOCK_HELP, "_User Manual", "F1", "", NULL },
+-  { "Register", NULL, "_Register", "", "", NULL },
+-  { "Donate", NULL, "_Donate", "", "", NULL },
+-  { "About", GTK_STOCK_ABOUT, "_About", "", "", G_CALLBACK(about_cb) },
++static const gchar *pick_labels[] = {
++  "Pick _Off" ,
++  "Pick _Ident",
++  "Pick _Distance",
++  "_Pick Monitor",
++  "Pick _Angle",
++  "Pick _Torsion",
++  "Pick _Label",
++  "Pick _Centre",
++  "Pick C_oord",
++  "Pick _Bond"
+ };
+ 
+-static const GtkToggleActionEntry view_toggles[] = {
+-  { "Command", NULL, "_Command prompt", "F7", "", NULL, FALSE },
+-  { "Scrolls", NULL, "_Scrollbars", "F8", "", NULL, FALSE },
+-  { "Menus",   NULL, "_Menubar", "F9", "", NULL, TRUE },
+-  { "Fullscreen",   NULL, "_Full Screen", "F11", "", NULL, FALSE },
++static int pick_data[] = {
++  m_s_poff,
++  m_s_pident,
++  m_s_pdist,
++  m_s_pmon,
++  m_s_pangle,
++  m_s_ptorsion,
++  m_s_plabel,
++  m_s_pcentre,
++  m_s_pcoord,
++  m_s_pbond
+ };
+ 
+-static const GtkToggleActionEntry opt_toggles[] = {
+-  { "Slab", NULL, "_Slab Mode", "", "", NULL, FALSE },
+-  { "Hydrogens", NULL, "Hy_drogens", "", "", NULL, FALSE },
+-  { "Heteros", NULL, "He_tero Atoms", "", "", NULL, FALSE },
+-  { "Specular", NULL, "Spe_cular", "", "", NULL, FALSE },
+-  { "Shadows", NULL, "S_hadows", "", "", NULL, FALSE },
+-  { "Stereo", NULL, "Stere_o", "", "", NULL, FALSE },
+-  { "Labels", NULL, "_Labels", "", "", NULL, FALSE }
++static const char *rot_labels[] = {
++    "_Rotate Bind",
++    "Rotate _Mol",
++    "Rotate _All"
+ };
+ 
+-static const GtkRadioActionEntry pick_radios[] = {
+-  { "POff", NULL, "Pick _Off", "", "", m_s_poff },  
+-  { "PIdent", NULL, "Pick _Ident", "", "", m_s_pident },  
+-  { "PDistance", NULL, "Pick _Distance", "", "", m_s_pdist },  
+-  { "PMonitor", NULL, "_Pick Monitor", "", "", m_s_pmon },  
+-  { "PAngle", NULL, "Pick _Angle", "", "", m_s_pangle },  
+-  { "PTorsion", NULL, "Pick _Torsion", "", "", m_s_ptorsion },  
+-  { "PLabel", NULL, "Pick _Label", "", "", m_s_plabel },  
+-  { "PCentre", NULL, "Pick _Centre", "", "", m_s_pcentre },  
+-  { "PCoord", NULL, "Pick C_oord", "", "", m_s_pcoord },  
+-  { "PBond", NULL, "Pick _Bond", "", "", m_s_pbond },   
+-};
+-	
+-static const GtkRadioActionEntry rot_radios[] = {
+-  { "RBond", NULL, "_Rotate Bond ", "", "", m_s_rbond },  
+-  { "RMol", NULL, "Rotate _Mol ", "", "", m_s_rmol },  
+-  { "RAll", NULL, "Rotate _All ", "", "", m_s_rall },  
++static int rot_data[] = {
++  m_s_rbond,
++  m_s_rmol,
++  m_s_rall
+ };
+ 
+-GtkActionGroup *ofiles_group;
++GSList *ofiles_group = NULL;
++GSList *pop_group = NULL;
+ 
+ void EnableRotBondMenu(int rot_enable) 
+ {
+-	GtkAction *a;
++	GtkCheckMenuItem *rotbond, *rotbond_pop, *rotmol, *rotmol_pop;
++	GObject *mbar = G_OBJECT(menubar);
+ 	
+-	a = gtk_ui_manager_get_action(ui_manager, "/MainMenu/SetMenu/RBond");
++	rotbond = g_object_get_data(mbar, "rotbond");
++	rotbond_pop = g_object_get_data(mbar, "rotbond_pop");
++	rotmol = g_object_get_data(mbar, "rotmol");
++	rotmol_pop = g_object_get_data(mbar, "rotmol_pop");
++
+ 	if(rot_enable) {
+-		gtk_action_set_sensitive(a, TRUE);
++	        gtk_widget_set_sensitive(GTK_WIDGET(rotbond), TRUE);
++	        gtk_widget_set_sensitive(GTK_WIDGET(rotbond_pop), TRUE);
+ 	} else {
+-		if(gtk_toggle_action_get_active((GtkToggleAction *) a))
+-			gtk_toggle_action_set_active((GtkToggleAction *) gtk_ui_manager_get_action(ui_manager, "/MainMenu/SetMenu/RMol"), TRUE);
+-		gtk_action_set_sensitive(a, FALSE);
++	        if (gtk_check_menu_item_get_active(rotbond))
++	                gtk_check_menu_item_set_active(rotmol, TRUE);
++	        if (gtk_check_menu_item_get_active(rotbond_pop))
++	                gtk_check_menu_item_set_active(rotmol_pop, TRUE);
++
++	        gtk_widget_set_sensitive(GTK_WIDGET(rotbond), FALSE);
++	        gtk_widget_set_sensitive(GTK_WIDGET(rotbond_pop), FALSE);
+ 	}
+ }
+ 
+-void set_gtk_open_file(int index)
++/* Just swaps arguments.  */
++void remove_molecules(gpointer item, gpointer menu)
+ {
+-    GList *alist;
+-    GtkRadioAction *radact;
+-
+-    alist = gtk_action_group_list_actions(ofiles_group);
+-    if(alist && alist->data) {
+-        radact = (GtkRadioAction *) alist->data;
+-        g_signal_handlers_block_by_func(radact, radio_cb, NULL);
+-        gtk_radio_action_set_current_value(radact, m_ofiles + index);
+-        g_signal_handlers_unblock_by_func(radact, radio_cb, NULL);
+-    }
+-    g_list_free(alist);
++    gtk_container_remove(GTK_CONTAINER(menu), item);
+ }
+ 
+-
+ void UpdateGtkMoleculeList(void) 
+ {
+     int i;
+     char itemname[4];
+     char itlabel[2*MAX_MOLNAME+1];
+-    GList *alist, *ahead;
+-    GSList *group = NULL;
+-    GtkRadioAction *rad;
++    GtkWidget *rad, *radpop;
+     GError *err = NULL;
+     GRegex *re = NULL;
+ 
+-    gtk_ui_manager_remove_ui(ui_manager, merge_id);
+-    merge_id = gtk_ui_manager_new_merge_id(ui_manager);
++    if (ofiles_group)
++        g_slist_foreach(ofiles_group, remove_molecules, filemenu);
+ 
+-    alist = gtk_action_group_list_actions (ofiles_group);
+-    ahead = alist;
+-    while(alist) {
+-        gtk_action_group_remove_action(ofiles_group,
+-                                       (GtkAction *) alist->data);
+-        alist = alist->next;
+-    }
+-    g_list_free(ahead);
++    if (pop_group)
++        g_slist_foreach(pop_group, remove_molecules, popup);
++
++    ofiles_group = NULL;
++    pop_group = NULL;
+ 
+     itlabel[2*MAX_MOLNAME] = '\0';
+     re = g_regex_new("[_]", 0, 0, &err);
+@@ -1129,50 +1359,270 @@
+         g_free(rep);
+         itlabel[0] = '_';
+         snprintf(itemname, 3, "%d", i);
+-        rad = gtk_radio_action_new(itemname, itlabel, NULL, NULL,
+-                                   (m_ofiles + i));
+-        gtk_radio_action_set_group (rad, group);
+-        group = gtk_radio_action_get_group(rad);
+-        if (i == MoleculeIndex)
+-            gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (rad), TRUE);
+-        gtk_action_group_add_action(ofiles_group, (GtkAction *) rad);
+-        g_object_unref(rad);
++        rad = gtk_radio_menu_item_new_with_mnemonic(ofiles_group, itlabel);
++        radpop = gtk_radio_menu_item_new_with_mnemonic(pop_group, itlabel);
++        gtk_widget_show (rad);
++        gtk_widget_show (radpop);
++        ofiles_group = gtk_radio_menu_item_get_group(GTK_RADIO_MENU_ITEM(rad));
++        pop_group = gtk_radio_menu_item_get_group(GTK_RADIO_MENU_ITEM(radpop));
++        if (i == MoleculeIndex) {
++            gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM(rad), TRUE);
++            gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM(radpop), TRUE);
++        }
++        g_signal_connect(rad, "toggled", G_CALLBACK (radio_cb),
++                         GINT_TO_POINTER(m_ofiles + i));
++        g_signal_connect(radpop, "toggled", G_CALLBACK (radio_cb),
++                         GINT_TO_POINTER(m_ofiles + i));
++        gtk_menu_shell_append(GTK_MENU_SHELL(filemenu), rad);
++        gtk_menu_shell_append(GTK_MENU_SHELL(popup), radpop);
+     }
+     g_regex_unref(re);
++}
+ 
+-    alist = gtk_action_group_list_actions(ofiles_group);
+-    if(alist) {
+-        g_signal_connect(alist->data, "changed", G_CALLBACK (radio_cb), NULL);
+-    }
+-    g_list_free(alist);
++GtkWidget *build_popup(void)
++{
++  GtkWidget *pmenu;
++  GtkWidget *menu;
++  GtkWidget *item;
++  GSList *group = NULL;
++  GObject *mbar = G_OBJECT(menubar);
++  gchar *str;
++  gint i;
++
++  pmenu = gtk_menu_new();
++  menu = gtk_menu_new();
++  item = gtk_menu_item_new_with_mnemonic("_View");
++  gtk_menu_item_set_submenu(GTK_MENU_ITEM(item), menu);
++  gtk_menu_shell_append(GTK_MENU_SHELL(pmenu), item);
++
++  item = gtk_check_menu_item_new_with_mnemonic("_Command prompt");
++  g_signal_connect(item, "activate", G_CALLBACK(view_cb), NULL);
++  g_object_set_data(mbar, "term_pop", item);
++  g_object_set_data(G_OBJECT(item), "kind", "term_pop");
++  gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
++
++  item = gtk_check_menu_item_new_with_mnemonic("_Scrollbars");
++  g_signal_connect(item, "activate", G_CALLBACK(view_cb), NULL);
++  g_object_set_data(mbar, "scroll_pop", item);
++  g_object_set_data(G_OBJECT(item), "kind", "scroll_pop");
++  gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
++
++  item = gtk_check_menu_item_new_with_mnemonic("_Menubar");
++  g_signal_connect(item, "activate", G_CALLBACK(view_cb), NULL);
++  g_object_set_data(mbar, "menus_pop", item);
++  g_object_set_data(G_OBJECT(item), "kind", "menus_pop");
++  gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
++
++  item = gtk_check_menu_item_new_with_mnemonic("_Full Screen");
++  g_signal_connect(item, "activate", G_CALLBACK(view_cb), NULL);
++  g_object_set_data(mbar, "fullscr_pop", item);
++  g_object_set_data(G_OBJECT(item), "kind", "fullscr_pop");
++  gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
++
++  item = gtk_separator_menu_item_new();
++  gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
++
++  item = gtk_menu_item_new_with_label("Set command font...");
++  g_signal_connect(item, "activate", G_CALLBACK(setfont_cb), NULL);
++  gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
++
++  menu = gtk_menu_new();
++  item = gtk_menu_item_new_with_mnemonic("_Display");
++  gtk_menu_item_set_submenu(GTK_MENU_ITEM(item), menu);
++  gtk_menu_shell_append(GTK_MENU_SHELL(pmenu), item);
++
++  item = gtk_menu_item_new_with_mnemonic("_Wireframe");
++  ADDSIGNAL(item, m_d_wireframe);
++  gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
++
++  item = gtk_menu_item_new_with_mnemonic("_Backbone");
++  ADDSIGNAL(item, m_d_backbone);
++  gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
++
++  item = gtk_menu_item_new_with_mnemonic("S_ticks");
++  ADDSIGNAL(item, m_d_sticks);
++  gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
++
++  item = gtk_menu_item_new_with_mnemonic("_Spacefill");
++  ADDSIGNAL(item, m_d_spheres);
++  gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
++
++  item = gtk_menu_item_new_with_mnemonic("B_all & stick");
++  ADDSIGNAL(item, m_d_ballstick);
++  gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
++
++  item = gtk_menu_item_new_with_mnemonic("_Ribbons");
++  ADDSIGNAL(item, m_d_ribbons);
++  gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
++
++  item = gtk_menu_item_new_with_mnemonic("Stran_ds");
++  ADDSIGNAL(item, m_d_strands);
++  gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
++
++  item = gtk_menu_item_new_with_mnemonic("_Cartoons");
++  ADDSIGNAL(item, m_d_cartoons);
++  gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
++
++  item = gtk_menu_item_new_with_mnemonic("_Molecular Surface");
++  ADDSIGNAL(item, m_d_molsurf);
++  gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
++
++  menu = gtk_menu_new();
++  item = gtk_menu_item_new_with_mnemonic("_Colours");
++  gtk_menu_item_set_submenu(GTK_MENU_ITEM(item), menu);
++  gtk_menu_shell_append(GTK_MENU_SHELL(pmenu), item);
++
++  item = gtk_menu_item_new_with_mnemonic("_Monochrome");
++  ADDSIGNAL(item, m_c_monochrome);
++  gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
++
++  item = gtk_menu_item_new_with_mnemonic("_CPK");
++  ADDSIGNAL(item, m_c_cpk);
++  gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
++
++  item = gtk_menu_item_new_with_mnemonic("_Shapely");
++  ADDSIGNAL(item, m_c_shapely);
++  gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
++
++  item = gtk_menu_item_new_with_mnemonic("_Group");
++  ADDSIGNAL(item, m_c_group);
++  gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
++
++  item = gtk_menu_item_new_with_mnemonic("C_hain");
++  ADDSIGNAL(item, m_c_chain);
++  gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
++
++  item = gtk_menu_item_new_with_mnemonic("_Temperature");
++  ADDSIGNAL(item, m_c_temperature);
++  gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
++
++  item = gtk_menu_item_new_with_mnemonic("St_ructure");
++  ADDSIGNAL(item, m_c_structure);
++  gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
++
++  item = gtk_menu_item_new_with_mnemonic("_User");
++  ADDSIGNAL(item, m_c_user);
++  gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
++
++  item = gtk_menu_item_new_with_mnemonic("Mo_del");
++  ADDSIGNAL(item, m_c_model);
++  gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
++
++  item = gtk_menu_item_new_with_mnemonic("_Alt");
++  ADDSIGNAL(item, m_c_alt);
++  gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
++
++  menu = gtk_menu_new();
++  item = gtk_menu_item_new_with_mnemonic("_Options");
++  gtk_menu_item_set_submenu(GTK_MENU_ITEM(item), menu);
++  gtk_menu_shell_append(GTK_MENU_SHELL(pmenu), item);
++
++  item = gtk_check_menu_item_new_with_mnemonic("_Slab Mode");
++  ADDSIGNAL(item, m_o_slab);
++  g_object_set_data(mbar, "slab_pop", item);
++  g_object_set_data(G_OBJECT(item), "kind", "slab_pop");
++  gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
++
++  item = gtk_check_menu_item_new_with_mnemonic("Hy_drogens");
++  ADDSIGNAL(item, m_o_hydrogens);
++  g_object_set_data(mbar, "hydr_pop", item);
++  g_object_set_data(G_OBJECT(item), "kind", "hydr_pop");
++  gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
++
++  item = gtk_check_menu_item_new_with_mnemonic("He_tero Atoms");
++  ADDSIGNAL(item, m_o_heteros);
++  g_object_set_data(mbar, "het_pop", item);
++  g_object_set_data(G_OBJECT(item), "kind", "het_pop");
++  gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
++
++  item = gtk_check_menu_item_new_with_mnemonic("Spe_cular");
++  ADDSIGNAL(item, m_o_specular);
++  g_object_set_data(mbar, "spec_pop", item);
++  g_object_set_data(G_OBJECT(item), "kind", "spec_pop");
++  gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
++
++  item = gtk_check_menu_item_new_with_mnemonic("S_hadows");
++  ADDSIGNAL(item, m_o_shadows);
++  g_object_set_data(mbar, "shad_pop", item);
++  g_object_set_data(G_OBJECT(item), "kind", "shad_pop");
++  gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
++
++  item = gtk_check_menu_item_new_with_mnemonic("Stere_o");
++  ADDSIGNAL(item, m_o_stereo);
++  g_object_set_data(mbar, "ster_pop", item);
++  g_object_set_data(G_OBJECT(item), "kind", "ster_pop");
++  gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
++
++  item = gtk_check_menu_item_new_with_mnemonic("_Labels");
++  ADDSIGNAL(item, m_o_labels);
++  g_object_set_data(mbar, "label_pop", item);
++  g_object_set_data(G_OBJECT(item), "kind", "label_pop");
++  gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
++
++  menu = gtk_menu_new();
++  item = gtk_menu_item_new_with_mnemonic("_Settings");
++  gtk_menu_item_set_submenu(GTK_MENU_ITEM(item), menu);
++  gtk_menu_shell_append(GTK_MENU_SHELL(pmenu), item);
++
++  for (i = 0; i < 10; i++) {
++      item = gtk_radio_menu_item_new_with_mnemonic(group, pick_labels[i]);
++      group = gtk_radio_menu_item_get_group(GTK_RADIO_MENU_ITEM(item));
++      g_signal_connect(item, "toggled", G_CALLBACK(radio_cb),
++                       GINT_TO_POINTER(pick_data[i]));
++      str = g_strdup_printf("pick_pop%d", i);
++      g_object_set_data(mbar, str, item);
++      g_object_set_data(G_OBJECT(item), "kind", GINT_TO_POINTER(i));
++      g_free(str);
++      if (i == 1)
++          gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(item), TRUE);
+ 
+-    for(i = 0; i < NumMolecules; i++) {
+-        snprintf(itemname, 3, "%d", i);
+-        gtk_ui_manager_add_ui(ui_manager, merge_id,
+-                              "/MainMenu/FileMenu/OFiles", itemname,
+-                              itemname, GTK_UI_MANAGER_MENUITEM, FALSE);
+-        gtk_ui_manager_add_ui(ui_manager, merge_id, "/popup/OFiles",
+-                              itemname, itemname,
+-                              GTK_UI_MANAGER_MENUITEM, FALSE);
+-    }
++      gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
++  }
++
++  item = gtk_separator_menu_item_new();
++  gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
+ 
+-    gtk_ui_manager_ensure_update (ui_manager);
++  group = NULL;
++  for (i = 0; i < 3; i++) {
++      item = gtk_radio_menu_item_new_with_mnemonic(group, rot_labels[i]);
++      group = gtk_radio_menu_item_get_group(GTK_RADIO_MENU_ITEM(item));
++      g_signal_connect(item, "toggled", G_CALLBACK(radio_cb),
++                       GINT_TO_POINTER(rot_data[i]));
++      if (i == 0)
++          g_object_set_data(mbar, "rotbond_pop", item);
++      else if (i == 1)
++          g_object_set_data(mbar, "rotmol_pop", item);
++      else
++          g_object_set_data(mbar, "rotall_pop", item);
++
++      g_object_set_data(G_OBJECT(item), "kind", GINT_TO_POINTER(i));
++
++      gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
++  }
++
++  item = gtk_separator_menu_item_new();
++  gtk_menu_shell_append(GTK_MENU_SHELL(pmenu), item);
++
++  gtk_widget_show_all(pmenu);
++
++  g_signal_connect (pmenu, "deactivate",
++                    G_CALLBACK (gtk_widget_hide), NULL);
++
++  return pmenu;
+ }
+ 
+ 
+ GtkWidget *build_gtkmenu(void)
+ {
+-    GError *error;
+-    GtkAction *recentaction = NULL;
++    GtkWidget *menu, *item;
++    GtkWidget *recentaction = NULL;
+     GtkRecentFilter *filter = NULL;
++    GSList *group = NULL;
++    GObject *mbar;
++    gchar *str;
+     int i;
+ 
+-    action_group = gtk_action_group_new("MenuActions");
+-    gtk_action_group_add_actions(action_group, menuentries,
+-                                  G_N_ELEMENTS(menuentries), NULL);
+-
+-    recentaction = gtk_recent_action_new("Recent", "Open _Recent",
+-                                         "Open a recently opened file", NULL);
++    recentaction = gtk_recent_chooser_menu_new();
+     filter = gtk_recent_filter_new();
+     gtk_recent_filter_add_application(filter, "RasMol");
+     gtk_recent_chooser_set_filter(GTK_RECENT_CHOOSER(recentaction), filter);
+@@ -1182,101 +1632,342 @@
+     gtk_recent_chooser_set_limit(GTK_RECENT_CHOOSER(recentaction), 30);
+     g_signal_connect(GTK_RECENT_CHOOSER(recentaction), "item-activated",
+                      G_CALLBACK(recent_cb), NULL);
+-    gtk_action_group_add_action(action_group, recentaction);
+-
+-    gtk_action_group_add_toggle_actions(action_group, view_toggles,
+-                                        G_N_ELEMENTS(view_toggles), NULL);
+-    gtk_action_group_add_toggle_actions(action_group, opt_toggles,
+-                                        G_N_ELEMENTS(opt_toggles), NULL);
+-    gtk_action_group_add_radio_actions(action_group, pick_radios,
+-                                       G_N_ELEMENTS(pick_radios), m_s_pident,
+-                                       G_CALLBACK(radio_cb), NULL);
+-    gtk_action_group_add_radio_actions(action_group, rot_radios,
+-                                       G_N_ELEMENTS(rot_radios), m_s_rmol,
+-                                       G_CALLBACK(radio_cb), NULL);
+ 
+-    ui_manager = gtk_ui_manager_new();
+-    gtk_ui_manager_insert_action_group(ui_manager, action_group, 0);
++    menubar = gtk_menu_bar_new();
++    mbar = G_OBJECT(menubar);
+ 
+-    accel_group = gtk_ui_manager_get_accel_group(ui_manager);
++    accel_group = gtk_accel_group_new();
+     gtk_window_add_accel_group(GTK_WINDOW(mainwin), accel_group);
+ 
+-    error = NULL;
+-    if(!gtk_ui_manager_add_ui_from_string(ui_manager, actionmenu_str,
+-                                          -1, &error)) {
+-        g_message("building menus failed: s", error->message);
+-        g_error_free(error);
+-        exit(EXIT_FAILURE);
+-    }
++    filemenu = gtk_menu_new();
++    gtk_menu_set_accel_group(GTK_MENU(filemenu), accel_group);
++    item = gtk_menu_item_new_with_mnemonic("_File");
++    gtk_menu_item_set_submenu(GTK_MENU_ITEM(item), filemenu);
++    gtk_menu_shell_append(GTK_MENU_SHELL(menubar), item);
++
++    item = gtk_menu_item_new_with_mnemonic("_Open");
++    gtk_widget_set_tooltip_text(item, "Open a file");
++    gtk_widget_add_accelerator(item, "activate", accel_group, GDK_KEY_O,
++                               GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE);
++    g_signal_connect(item, "activate", G_CALLBACK(open_cb), NULL);
++    gtk_menu_shell_append(GTK_MENU_SHELL(filemenu), item);
++
++    item = gtk_menu_item_new_with_mnemonic("Open _Recent");
++    gtk_widget_set_tooltip_text(item, "Open a recently opened file");
++    gtk_menu_item_set_submenu(GTK_MENU_ITEM(item), recentaction);
++    gtk_menu_shell_append(GTK_MENU_SHELL(filemenu), item);
++
++    item = gtk_menu_item_new_with_mnemonic("Save _As");
++    gtk_widget_set_tooltip_text(item, "Save a file");
++    gtk_widget_add_accelerator(item, "activate", accel_group, GDK_KEY_S,
++                               GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE);
++    g_signal_connect(item, "activate", G_CALLBACK(save_cb), NULL);
++    gtk_menu_shell_append(GTK_MENU_SHELL(filemenu), item);
++
++    item = gtk_menu_item_new_with_mnemonic("_Export...");
++    gtk_widget_set_tooltip_text(item, "Export current image");
++    gtk_widget_add_accelerator(item, "activate", accel_group, GDK_KEY_X,
++                               GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE);
++    g_signal_connect(item, "activate", G_CALLBACK(export_cb), NULL);
++    gtk_menu_shell_append(GTK_MENU_SHELL(filemenu), item);
++
++    item = gtk_menu_item_new_with_mnemonic("_Close");
++    gtk_widget_set_tooltip_text(item, "Close the selected molecule");
++    gtk_widget_add_accelerator(item, "activate", accel_group, GDK_KEY_W,
++                               GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE);
++    ADDSIGNAL(item, m_f_close);
++    gtk_menu_shell_append(GTK_MENU_SHELL(filemenu), item);
++
++    item = gtk_separator_menu_item_new();
++    gtk_menu_shell_append(GTK_MENU_SHELL(filemenu), item);
++
++    item = gtk_menu_item_new_with_mnemonic("Page Set_up...");
++    gtk_widget_set_tooltip_text(item, "Set the page parameters");
++    g_signal_connect(item, "activate", G_CALLBACK(pagesetup_cb), NULL);
++    gtk_menu_shell_append(GTK_MENU_SHELL(filemenu), item);
++
++    item = gtk_menu_item_new_with_mnemonic("_Print");
++    gtk_widget_set_tooltip_text(item, "Print the current image");
++    gtk_widget_add_accelerator(item, "activate", accel_group, GDK_KEY_P,
++                               GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE);
++    g_signal_connect(item, "activate", G_CALLBACK(print_cb), NULL);
++    gtk_menu_shell_append(GTK_MENU_SHELL(filemenu), item);
++
++    item = gtk_separator_menu_item_new();
++    gtk_menu_shell_append(GTK_MENU_SHELL(filemenu), item);
++
++    item = gtk_menu_item_new_with_mnemonic("_Quit");
++    gtk_widget_set_tooltip_text(item, "Exit the program");
++    gtk_widget_add_accelerator(item, "activate", accel_group, GDK_KEY_Q,
++                               GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE);
++    g_signal_connect(item, "activate", RasMolExit, NULL);
++    gtk_menu_shell_append(GTK_MENU_SHELL(filemenu), item);
++
++    item = gtk_separator_menu_item_new();
++    gtk_menu_shell_append(GTK_MENU_SHELL(filemenu), item);
++
++    menu = gtk_menu_new();
++    gtk_menu_set_accel_group(GTK_MENU(menu), accel_group);
++    item = gtk_menu_item_new_with_mnemonic("_View");
++    gtk_menu_item_set_submenu(GTK_MENU_ITEM(item), menu);
++    gtk_menu_shell_append(GTK_MENU_SHELL(menubar), item);
++
++    item = gtk_check_menu_item_new_with_mnemonic("_Command prompt");
++    gtk_widget_add_accelerator(item, "activate", accel_group, GDK_KEY_F7,
++                               0, GTK_ACCEL_VISIBLE);
++    g_signal_connect(item, "activate", G_CALLBACK(view_cb), NULL);
++    g_object_set_data(mbar, "terminal", item);
++    g_object_set_data(G_OBJECT(item), "kind", "terminal");
++    gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
++
++    item = gtk_check_menu_item_new_with_mnemonic("_Scrollbars");
++    gtk_widget_add_accelerator(item, "activate", accel_group, GDK_KEY_F8,
++                               0, GTK_ACCEL_VISIBLE);
++    g_signal_connect(item, "activate", G_CALLBACK(view_cb), NULL);
++    g_object_set_data(mbar, "scrollbars", item);
++    g_object_set_data(G_OBJECT(item), "kind", "scrollbars");
++    gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
++
++    menus = gtk_check_menu_item_new_with_mnemonic("_Menubar");
++    gtk_widget_add_accelerator(menus, "activate", accel_group, GDK_KEY_F9,
++                               0, GTK_ACCEL_VISIBLE);
++    /* This item is handled differently because accelerators don't
++       work when the menubar is hidden.  */
++    gtk_accel_group_connect(accel_group, GDK_KEY_F9, 0, 0,
++                            g_cclosure_new_swap(G_CALLBACK(show_menubar_cb),
++                                                menus, NULL));
++    g_signal_connect(menus, "activate", G_CALLBACK(view_cb), NULL);
++    g_object_set_data(mbar, "menus", menus);
++    g_object_set_data(G_OBJECT(menus), "kind", "menus");
++    gtk_menu_shell_append(GTK_MENU_SHELL(menu), menus);
++
++    item = gtk_check_menu_item_new_with_mnemonic("_Full Screen");
++    gtk_widget_add_accelerator(item, "activate", accel_group, GDK_KEY_F11,
++                               0, GTK_ACCEL_VISIBLE);
++    g_signal_connect(item, "activate", G_CALLBACK(view_cb), NULL);
++    g_object_set_data(mbar, "fullscreen", item);
++    g_object_set_data(G_OBJECT(item), "kind", "fullscreen");
++    gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
++
++    item = gtk_separator_menu_item_new();
++    gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
++
++    item = gtk_menu_item_new_with_label("Set command font...");
++    g_signal_connect(item, "activate", G_CALLBACK(setfont_cb), NULL);
++    gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
++
++    menu = gtk_menu_new();
++    item = gtk_menu_item_new_with_mnemonic("_Display");
++    gtk_menu_item_set_submenu(GTK_MENU_ITEM(item), menu);
++    gtk_menu_shell_append(GTK_MENU_SHELL(menubar), item);
++
++    item = gtk_menu_item_new_with_mnemonic("_Wireframe");
++    ADDSIGNAL(item, m_d_wireframe);
++    gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
++
++    item = gtk_menu_item_new_with_mnemonic("_Backbone");
++    ADDSIGNAL(item, m_d_backbone);
++    gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
++
++    item = gtk_menu_item_new_with_mnemonic("S_ticks");
++    ADDSIGNAL(item, m_d_sticks);
++    gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
++
++    item = gtk_menu_item_new_with_mnemonic("_Spacefill");
++    ADDSIGNAL(item, m_d_spheres);
++    gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
++
++    item = gtk_menu_item_new_with_mnemonic("B_all & stick");
++    ADDSIGNAL(item, m_d_ballstick);
++    gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
++
++    item = gtk_menu_item_new_with_mnemonic("_Ribbons");
++    ADDSIGNAL(item, m_d_ribbons);
++    gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
++
++    item = gtk_menu_item_new_with_mnemonic("Stran_ds");
++    ADDSIGNAL(item, m_d_strands);
++    gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
++
++    item = gtk_menu_item_new_with_mnemonic("_Cartoons");
++    ADDSIGNAL(item, m_d_cartoons);
++    gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
++
++    item = gtk_menu_item_new_with_mnemonic("_Molecular Surface");
++    ADDSIGNAL(item, m_d_molsurf);
++    gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
++
++    menu = gtk_menu_new();
++    item = gtk_menu_item_new_with_mnemonic("_Colours");
++    gtk_menu_item_set_submenu(GTK_MENU_ITEM(item), menu);
++    gtk_menu_shell_append(GTK_MENU_SHELL(menubar), item);
++
++    item = gtk_menu_item_new_with_mnemonic("_Monochrome");
++    ADDSIGNAL(item, m_c_monochrome);
++    gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
++
++    item = gtk_menu_item_new_with_mnemonic("_CPK");
++    ADDSIGNAL(item, m_c_cpk);
++    gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
++
++    item = gtk_menu_item_new_with_mnemonic("_Shapely");
++    ADDSIGNAL(item, m_c_shapely);
++    gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
++
++    item = gtk_menu_item_new_with_mnemonic("_Group");
++    ADDSIGNAL(item, m_c_group);
++    gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
++
++    item = gtk_menu_item_new_with_mnemonic("C_hain");
++    ADDSIGNAL(item, m_c_chain);
++    gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
++
++    item = gtk_menu_item_new_with_mnemonic("_Temperature");
++    ADDSIGNAL(item, m_c_temperature);
++    gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
++
++    item = gtk_menu_item_new_with_mnemonic("St_ructure");
++    ADDSIGNAL(item, m_c_structure);
++    gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
++
++    item = gtk_menu_item_new_with_mnemonic("_User");
++    ADDSIGNAL(item, m_c_user);
++    gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
++
++    item = gtk_menu_item_new_with_mnemonic("Mo_del");
++    ADDSIGNAL(item, m_c_model);
++    gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
++
++    item = gtk_menu_item_new_with_mnemonic("_Alt");
++    ADDSIGNAL(item, m_c_alt);
++    gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
++
++    menu = gtk_menu_new();
++    item = gtk_menu_item_new_with_mnemonic("_Options");
++    gtk_menu_item_set_submenu(GTK_MENU_ITEM(item), menu);
++    gtk_menu_shell_append(GTK_MENU_SHELL(menubar), item);
++
++    item = gtk_check_menu_item_new_with_mnemonic("_Slab Mode");
++    ADDSIGNAL(item, m_o_slab);
++    g_object_set_data(mbar, "slab", item);
++    g_object_set_data(G_OBJECT(item), "kind", "slab");
++    gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
++
++    item = gtk_check_menu_item_new_with_mnemonic("Hy_drogens");
++    ADDSIGNAL(item, m_o_hydrogens);
++    g_object_set_data(mbar, "hydr", item);
++    g_object_set_data(G_OBJECT(item), "kind", "hydr");
++    gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
++
++    item = gtk_check_menu_item_new_with_mnemonic("He_tero Atoms");
++    ADDSIGNAL(item, m_o_heteros);
++    g_object_set_data(mbar, "het", item);
++    g_object_set_data(G_OBJECT(item), "kind", "het");
++    gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
++
++    item = gtk_check_menu_item_new_with_mnemonic("Spe_cular");
++    ADDSIGNAL(item, m_o_specular);
++    g_object_set_data(mbar, "spec", item);
++    g_object_set_data(G_OBJECT(item), "kind", "spec");
++    gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
++
++    item = gtk_check_menu_item_new_with_mnemonic("S_hadows");
++    ADDSIGNAL(item, m_o_shadows);
++    g_object_set_data(mbar, "shad", item);
++    g_object_set_data(G_OBJECT(item), "kind", "shad");
++    gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
++
++    item = gtk_check_menu_item_new_with_mnemonic("Stere_o");
++    ADDSIGNAL(item, m_o_stereo);
++    g_object_set_data(mbar, "ster", item);
++    g_object_set_data(G_OBJECT(item), "kind", "ster");
++    gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
++
++    item = gtk_check_menu_item_new_with_mnemonic("_Labels");
++    ADDSIGNAL(item, m_o_labels);
++    g_object_set_data(mbar, "label", item);
++    g_object_set_data(G_OBJECT(item), "kind", "label");
++    gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
++
++    menu = gtk_menu_new();
++    item = gtk_menu_item_new_with_mnemonic("_Settings");
++    gtk_menu_item_set_submenu(GTK_MENU_ITEM(item), menu);
++    gtk_menu_shell_append(GTK_MENU_SHELL(menubar), item);
++
++    for (i = 0; i < 10; i++) {
++        item = gtk_radio_menu_item_new_with_mnemonic(group, pick_labels[i]);
++        group = gtk_radio_menu_item_get_group(GTK_RADIO_MENU_ITEM(item));
++        g_signal_connect(item, "toggled", G_CALLBACK(radio_cb),
++                         GINT_TO_POINTER(pick_data[i]));
++        str = g_strdup_printf("pick%d", i);
++        g_object_set_data(mbar, str, item);
++        g_object_set_data(G_OBJECT(item), "kind",
++                          GINT_TO_POINTER(pick_data[i]));
++        g_free(str);
++
++        if (i == 1)
++            gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(item), TRUE);
++
++        gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
++    }
++
++    item = gtk_separator_menu_item_new();
++    gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
++
++    group = NULL;
++    for (i = 0; i < 3; i++) {
++        item = gtk_radio_menu_item_new_with_mnemonic(group, rot_labels[i]);
++        group = gtk_radio_menu_item_get_group(GTK_RADIO_MENU_ITEM(item));
++        g_signal_connect(item, "toggled", G_CALLBACK(radio_cb),
++                         GINT_TO_POINTER(rot_data[i]));
++        if (i == 0)
++            g_object_set_data(mbar, "rotbond", item);
++        else if (i == 1)
++            g_object_set_data(mbar, "rotmol", item);
++        else
++            g_object_set_data(mbar, "rotall", item);
++
++        g_object_set_data(G_OBJECT(item), "kind",
++                          GINT_TO_POINTER(rot_data[i]));
++
++        gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
++    }
++
++    menu = gtk_menu_new();
++    gtk_menu_set_accel_group(GTK_MENU(menu), accel_group);
++    item = gtk_menu_item_new_with_mnemonic("_Help");
++    gtk_menu_item_set_submenu(GTK_MENU_ITEM(item), menu);
++    gtk_menu_shell_append(GTK_MENU_SHELL(menubar), item);
++
++    item = gtk_menu_item_new_with_mnemonic("_User Manual");
++    gtk_widget_add_accelerator(item, "activate", accel_group, GDK_KEY_F1,
++                               0, GTK_ACCEL_VISIBLE);
++    ADDSIGNAL(item, m_h_manual);
++    gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
++
++    item = gtk_menu_item_new_with_mnemonic("_Register");
++    ADDSIGNAL(item, m_h_register);
++    gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
++
++    item = gtk_menu_item_new_with_mnemonic("_Donate");
++    ADDSIGNAL(item, m_h_donate);
++    gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
++
++    item = gtk_menu_item_new_with_mnemonic("_About");
++    g_signal_connect(item, "activate", G_CALLBACK(about_cb), NULL);
++    gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
+ 
++    popup = build_popup();
+     EnableRotBondMenu(False);
+ 
+-    ADDSIGNAL("/MainMenu/FileMenu/Close", m_f_close);
+-    ADDSIGNAL("/MainMenu/DispMenu/Wireframe", m_d_wireframe);
+-    ADDSIGNAL("/MainMenu/DispMenu/Backbone", m_d_backbone);
+-    ADDSIGNAL("/MainMenu/DispMenu/Sticks", m_d_sticks);
+-    ADDSIGNAL("/MainMenu/DispMenu/Spheres", m_d_spheres);
+-    ADDSIGNAL("/MainMenu/DispMenu/Ballstick", m_d_ballstick);
+-    ADDSIGNAL("/MainMenu/DispMenu/Ribbons", m_d_ribbons);
+-    ADDSIGNAL("/MainMenu/DispMenu/Strands", m_d_strands);
+-    ADDSIGNAL("/MainMenu/DispMenu/Cartoons", m_d_cartoons);
+-    ADDSIGNAL("/MainMenu/DispMenu/MolSurf", m_d_molsurf);
+-    ADDSIGNAL("/MainMenu/ColMenu/Monochrome", m_c_monochrome);
+-    ADDSIGNAL("/MainMenu/ColMenu/CPK", m_c_cpk);
+-    ADDSIGNAL("/MainMenu/ColMenu/Shapely", m_c_shapely);
+-    ADDSIGNAL("/MainMenu/ColMenu/Group", m_c_group);
+-    ADDSIGNAL("/MainMenu/ColMenu/Chain", m_c_chain);
+-    ADDSIGNAL("/MainMenu/ColMenu/Temperature", m_c_temperature);
+-    ADDSIGNAL("/MainMenu/ColMenu/Structure", m_c_structure);
+-    ADDSIGNAL("/MainMenu/ColMenu/User", m_c_user);
+-    ADDSIGNAL("/MainMenu/ColMenu/Model", m_c_model);
+-    ADDSIGNAL("/MainMenu/ColMenu/Alt", m_c_alt);
+-    ADDSIGNAL("/MainMenu/OptMenu/Slab", m_o_slab);
+-    ADDSIGNAL("/MainMenu/OptMenu/Hydrogens", m_o_hydrogens);
+-    ADDSIGNAL("/MainMenu/OptMenu/Heteros", m_o_heteros);
+-    ADDSIGNAL("/MainMenu/OptMenu/Specular", m_o_specular);
+-    ADDSIGNAL("/MainMenu/OptMenu/Shadows", m_o_shadows);
+-    ADDSIGNAL("/MainMenu/OptMenu/Stereo", m_o_stereo);
+-    ADDSIGNAL("/MainMenu/OptMenu/Labels", m_o_labels);
+-    ADDSIGNAL("/MainMenu/HelpMenu/Manual", m_h_manual);
+-    ADDSIGNAL("/MainMenu/HelpMenu/Register", m_h_register);
+-    ADDSIGNAL("/MainMenu/HelpMenu/Donate", m_h_donate);
+-
+-    g_signal_connect(gtk_ui_manager_get_action(ui_manager,"/MainMenu/ViewMenu/Command"), "activate", G_CALLBACK(view_cb), NULL);
+-    g_signal_connect(gtk_ui_manager_get_action(ui_manager,"/MainMenu/ViewMenu/Scrolls"), "activate", G_CALLBACK(view_cb), NULL);
+-    g_signal_connect(gtk_ui_manager_get_action(ui_manager,"/MainMenu/ViewMenu/Menus"), "activate", G_CALLBACK(view_cb), NULL);
+-    g_signal_connect(gtk_ui_manager_get_action(ui_manager,"/MainMenu/ViewMenu/Fullscreen"), "activate", G_CALLBACK(view_cb), NULL);
+-
+-    /* merge id for filemenu additions */
+-    merge_id = gtk_ui_manager_new_merge_id(ui_manager);
+-    ofiles_group = gtk_action_group_new("OFileActions");
+-    gtk_ui_manager_insert_action_group(ui_manager, ofiles_group, 1);
+-
+-    menubar = gtk_ui_manager_get_widget(ui_manager, "/MainMenu");
+-
++    gtk_widget_show_all(menubar);
+     return menubar;
+ }
+ 
+ 
+ static void do_popup_menu (GtkWidget *widget, GdkEventButton *event)
+ {
+-  GtkWidget *menu;
+-  int button, event_time;
+-
+-  menu = gtk_ui_manager_get_widget(ui_manager, "/popup");
+-  g_signal_connect (menu, "deactivate", 
+-                    G_CALLBACK (gtk_widget_hide), NULL);
+-
+-  if (event) {
+-      button = event->button;
+-      event_time = event->time;
+-  } else {
+-      button = 0;
+-      event_time = gtk_get_current_event_time ();
+-  }
+-
+-  gtk_menu_popup (GTK_MENU (menu), NULL, NULL, NULL, NULL, 
+-                  0, event_time);
++  gtk_menu_popup_at_pointer (GTK_MENU(popup), (const GdkEvent*)event);
+ }
+ 	
+ 
+@@ -1317,6 +2008,9 @@
+ {
+     gdouble new, old;
+ 
++    if (!hscrollbar || !vscrollbar)
++        return;
++
+     if ( RotMode == RotAll ) {
+ 		new = WorldDialValue[YScrlDial]; 
+     } else {
+@@ -1368,12 +2062,7 @@
+ 
+ void TransferImage( void )
+ {
+-    gdk_draw_rgb_32_image (canvasarea->window,
+-			   canvasarea->style->fg_gc[GTK_STATE_NORMAL],
+-			   0, 0, XRange, YRange,
+-			   GDK_RGB_DITHER_NONE,
+-			   (guchar *) FBuffer,
+-			   XRange * 4);	
++    /* Dummy definition necessary for linking.  */
+ }
+ 
+ void SetMouseCaptureStatus( int bool )
+@@ -1396,9 +2085,25 @@
+ }
+ 
+ 
+-gboolean expose_cb(GtkWidget *widget, GdkEventExpose *event, gpointer user_data)
++gboolean draw_cb(GtkWidget *widget, cairo_t *cr, gpointer user_data)
+ {
+-    TransferImage();
++    GdkPixbuf *pixbuf = NULL;
++
++    /* This function needs to be called because when the first
++       molecule is loaded on startup, GTK+ 3 draws it on the default
++       greyish widget background.  Only on "button-press-event" the
++       background becomes black, which is unpleasant for the user.  */
++    RefreshScreen();
++
++    pixbuf = gdk_pixbuf_new_from_data((const guchar*)FBuffer,
++                                      GDK_COLORSPACE_RGB,
++                                      TRUE, 8, XRange, YRange,
++                                      XRange * 4, NULL, NULL);
++
++    gdk_cairo_set_source_pixbuf(cr, pixbuf, 0, 0);
++    cairo_paint(cr);
++    g_object_unref(pixbuf);
++
+     return FALSE;
+ }
+ 
+@@ -1418,10 +2123,9 @@
+     WRange = XRange>>1;
+     Range = MinFun(XRange,YRange);
+ 	
+-	gtk_widget_set_size_request(widget, XRange, YRange);
+-    
+     ReDrawFlag |= RFReSize;
+ 	RefreshScreen();
++	gtk_widget_queue_draw(canvasarea);
+ 	ReDrawFlag = NextReDrawFlag;
+ 	
+     return FALSE;
+@@ -1433,6 +2137,7 @@
+     WorldDialValue[YScrlDial] = gtk_range_get_value(range);
+     ReDrawFlag |= (1<<YScrlDial);
+     RefreshScreen();
++    gtk_widget_queue_draw(canvasarea);
+     ReDrawFlag = NextReDrawFlag;
+ }
+ 
+@@ -1449,6 +2154,7 @@
+     	ReDrawFlag |= (1<<XScrlDial);
+ 	}
+     RefreshScreen();
++    gtk_widget_queue_draw(canvasarea);
+     ReDrawFlag = NextReDrawFlag;
+ }
+ 
+@@ -1461,6 +2167,8 @@
+ gboolean motion_cb(GtkWidget *canvas, GdkEventMotion *event, gpointer user_data)
+ {
+     int stat, x, y, xorig, yorig;
++    GdkWindow *window;
++    GdkSeat *seat;
+     GdkModifierType mask;
+ 
+ 	dragging = TRUE;
+@@ -1468,11 +2176,15 @@
+     ProcessMouseMove(event->x,event->y,stat);
+     if(ReDrawFlag) {
+ 		RefreshScreen();
++		gtk_widget_queue_draw(canvasarea);
+         ReDrawFlag = NextReDrawFlag;
+     }
+     xorig = event->x;
+     yorig = event->y;
+-    gdk_window_get_pointer(canvas->window, &x, &y, &mask);
++    window = gtk_widget_get_window(canvas);
++    seat = gdk_display_get_default_seat(gdk_window_get_display(window));
++    gdk_window_get_device_position(window, gdk_seat_get_pointer(seat),
++                                   &x, &y, &mask);
+ 
+     return FALSE;
+ }
+@@ -1500,6 +2212,7 @@
+ 	}
+     if( ReDrawFlag ) {
+         RefreshScreen();
++        gtk_widget_queue_draw(canvasarea);
+     }
+ 	dragging = FALSE;
+ 	
+@@ -1515,6 +2228,7 @@
+         if(!CommandActive) {
+             ResetCommandLine(0);
+             RefreshScreen();
++            gtk_widget_queue_draw(canvasarea);
+             ReDrawFlag = NextReDrawFlag;
+         }
+     }	
+@@ -1600,7 +2314,7 @@
+ #endif
+     int i;
+     static char VersionStr[50];
+-    GError *gerr = NULL;
++    PangoFontDescription *desc;
+ 
+     sprintf (VersionStr,"RasMol Version %s", VERSION);
+ 
+@@ -1632,17 +2346,19 @@
+ 
+     menubar = build_gtkmenu();
+ 
+-    mainvbox = gtk_vbox_new(FALSE, 0);
++    mainvbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
+ 
+-    ctable = gtk_table_new(2, 2, FALSE);   
++    ctable = gtk_grid_new();
+ 
+     canvasarea = gtk_drawing_area_new();
++    gtk_widget_set_hexpand(canvasarea, TRUE);
++    gtk_widget_set_vexpand(canvasarea, TRUE);
+     gtk_widget_add_events(canvasarea, GDK_POINTER_MOTION_HINT_MASK);
+     gtk_widget_add_events(canvasarea, GDK_BUTTON_PRESS_MASK);
+     gtk_widget_add_events(canvasarea, GDK_BUTTON_RELEASE_MASK);    
+     gtk_widget_add_events(canvasarea, GDK_BUTTON_MOTION_MASK);        
+-    g_signal_connect (G_OBJECT (canvasarea), "expose-event",  
+-        G_CALLBACK (expose_cb), NULL);
++    g_signal_connect (G_OBJECT (canvasarea), "draw",
++        G_CALLBACK (draw_cb), NULL);
+     g_signal_connect (G_OBJECT (canvasarea), "configure-event",  
+         G_CALLBACK (configure_cb), NULL);
+     g_signal_connect (G_OBJECT (canvasarea), "motion-notify-event",  
+@@ -1654,17 +2370,13 @@
+     g_signal_connect (G_OBJECT (canvasarea), "popup-menu",  
+         G_CALLBACK (popup_cb), NULL);
+ 
+-    vscrollbar = gtk_vscrollbar_new(NULL);
+-    gtk_range_set_update_policy(GTK_RANGE(vscrollbar),
+-        GTK_UPDATE_CONTINUOUS);
++    vscrollbar = gtk_scrollbar_new(GTK_ORIENTATION_VERTICAL, NULL);
+     gtk_range_set_range(GTK_RANGE(vscrollbar), -1.0, 1.0);
+     gtk_range_set_increments(GTK_RANGE(vscrollbar), 0.01, 0.1);
+     vscr_handler = g_signal_connect(G_OBJECT(vscrollbar), "value-changed",
+         G_CALLBACK(vscroll_cb), NULL);
+ 
+-    hscrollbar = gtk_hscrollbar_new(NULL);
+-    gtk_range_set_update_policy(GTK_RANGE(hscrollbar),
+-        GTK_UPDATE_CONTINUOUS);
++    hscrollbar = gtk_scrollbar_new(GTK_ORIENTATION_HORIZONTAL, NULL);
+     gtk_range_set_range(GTK_RANGE(hscrollbar), -1.0, 1.0);
+     gtk_range_set_increments(GTK_RANGE(hscrollbar), 0.01, 0.1);
+     hscr_handler = g_signal_connect(G_OBJECT(hscrollbar), "value-changed",
+@@ -1673,20 +2385,24 @@
+     vte = vte_terminal_new();
+     g_assert(vte);
+     vte_terminal_set_size(VTE_TERMINAL(vte), 80, 10);
+-    vte_terminal_set_font_from_string(VTE_TERMINAL(vte), "Monospace 10");
++    desc = pango_font_description_from_string("Monospace 10");
++    vte_terminal_set_font(VTE_TERMINAL(vte), desc);
++    pango_font_description_free(desc);
+     vte_terminal_set_scroll_on_output(VTE_TERMINAL(vte), TRUE);
+     vte_terminal_set_backspace_binding(VTE_TERMINAL(vte), VTE_ERASE_ASCII_BACKSPACE);
+     vte_terminal_set_delete_binding(VTE_TERMINAL(vte), VTE_ERASE_DELETE_SEQUENCE);
+     g_signal_connect(G_OBJECT(vte), "commit", G_CALLBACK(termin_cb), NULL);
+ 
+-    termhbox = gtk_hbox_new(FALSE, 0);
++    termhbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
+     gtk_box_pack_start(GTK_BOX(termhbox), vte, TRUE, TRUE, 0);
+ 
+     GtkWidget *termscroll;
+-    termscroll = gtk_vscrollbar_new(VTE_TERMINAL(vte)->adjustment);
++    GtkAdjustment *adj;
++    adj = gtk_scrollable_get_vadjustment(GTK_SCROLLABLE(vte));
++    termscroll = gtk_scrollbar_new(GTK_ORIENTATION_VERTICAL, adj);
+     gtk_box_pack_start(GTK_BOX(termhbox), termscroll, FALSE, FALSE, 0);
+ 
+-    mainvpane = gtk_vpaned_new();
++    mainvpane = gtk_paned_new(GTK_ORIENTATION_VERTICAL);
+ 
+     build_window();
+ 
+@@ -1694,12 +2410,15 @@
+     geo.min_width = RASGTK_MINWIDTH;
+     geo.min_height = RASGTK_MINHEIGHT;
+     gtk_window_set_geometry_hints(GTK_WINDOW(mainwin), GTK_WIDGET(mainvbox),
+-        &geo, GDK_HINT_MIN_SIZE);
+-    gtk_window_set_default_icon(gdk_pixbuf_from_pixdata(&rasmol_icon,
+-                                                        TRUE, &gerr));
++                                  &geo, GDK_HINT_MIN_SIZE);
++
++    GdkPixbuf *pixbuf;
++    pixbuf = gdk_pixbuf_new_from_xpm_data(rasmol_xpm);
++    gtk_window_set_default_icon(pixbuf);
++    g_object_unref(pixbuf);
+ 
+     gtk_container_add (GTK_CONTAINER (mainwin), mainvbox);
+-    gtk_widget_set_size_request(mainwin, XRange, YRange);
++    gtk_window_set_default_size(GTK_WINDOW(mainwin), XRange, YRange);
+     gtk_widget_show_all (mainwin);
+ 
+     test.longword = (Long)0x000000ff;    
+--- rasmol.orig/src/rasmol_48x48.xpm
++++ rasmol/src/rasmol_48x48.xpm
+@@ -1,5 +1,5 @@
+ /* XPM */
+-static char * rasmol_xpm[] = {
++static const char * rasmol_xpm[] = {
+ "48 48 1168 2",
+ "  	c None",
+ ". 	c #D2D3E2",
+--- rasmol.orig/src/eggfileformatchooser.c
++++ rasmol/src/eggfileformatchooser.c
+@@ -365,7 +365,6 @@
+ 
+   view = gtk_tree_view_new_with_model (GTK_TREE_MODEL (self->priv->model));
+   self->priv->selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (view));
+-  gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (view), TRUE);
+ 
+ /* file format column */
+ 
+--- rasmol.orig/src/multiple.c
++++ rasmol/src/multiple.c
+@@ -553,9 +553,6 @@
+ 
+ void SelectMolecule(int index)
+ {
+-#ifdef GTKWIN
+-    set_gtk_open_file(index);
+-#endif
+     SwitchMolecule(index);
+     PickCount = 0;
+     if (Interactive) {
+--- rasmol.orig/src/actionmenu.gtk
++++ /dev/null
+@@ -1,140 +0,0 @@
+-<ui>
+-  <menubar name='MainMenu'>
+-    <menu action='FileMenu'>
+-      <menuitem action='Open' />
+-      <menuitem action='Recent' />
+-      <menuitem action='SaveAs' />
+-      <menuitem action='Export' />
+-      <menuitem action='Close' />
+-	  <separator/>
+-	  <menuitem action='PageSetup'/>
+-   	  <menuitem action='Print'/>
+-	  <separator/>
+-	  <menuitem action='Exit' />
+-  	  <separator/>
+-      <placeholder name='OFiles' />
+-    </menu>
+-	<menu action='ViewMenu'>
+-      <menuitem action='Command' />
+-	  <menuitem action='Scrolls' />
+-  	  <menuitem action='Menus' />
+-	  <menuitem action='Fullscreen' />
+-	  <separator/>
+-	  <menuitem action='Setfont' />
+-    </menu>
+-    <menu action='DispMenu'>
+-      <menuitem action='Wireframe' />
+-  	  <menuitem action='Backbone' />
+-	  <menuitem action='Sticks' />
+-	  <menuitem action='Spheres' />
+-	  <menuitem action='Ballstick' />
+-	  <menuitem action='Ribbons' />
+-	  <menuitem action='Strands' />
+-	  <menuitem action='Cartoons' />
+-	  <menuitem action='MolSurf' />
+-    </menu>
+-	<menu action='ColMenu'>
+-	  <menuitem action='Monochrome' />
+-      <menuitem action='CPK' />
+-	  <menuitem action='Shapely' />
+-	  <menuitem action='Group' />
+-	  <menuitem action='Chain' />
+-	  <menuitem action='Temperature' />
+-	  <menuitem action='Structure' />
+- 	  <menuitem action='User' />
+-	  <menuitem action='Model' />
+-	  <menuitem action='Alt' />
+-    </menu>
+-	<menu action='OptMenu'>
+-	  <menuitem action='Slab' />
+-	  <menuitem action='Hydrogens' />
+-	  <menuitem action='Heteros' />
+-	  <menuitem action='Specular' />
+-	  <menuitem action='Shadows' />
+-	  <menuitem action='Stereo' />
+-	  <menuitem action='Labels' />
+-    </menu>
+-	<menu action='SetMenu'>
+-      <menuitem action='POff' />
+-	  <menuitem action='PIdent' />
+-	  <menuitem action='PDistance' />
+-	  <menuitem action='PMonitor' />
+-	  <menuitem action='PAngle' />
+-	  <menuitem action='PTorsion' />
+-	  <menuitem action='PLabel' />
+-	  <menuitem action='PCentre' />
+-	  <menuitem action='PCoord' />
+-	  <menuitem action='PBond' />
+-	  <separator/>
+-	  <menuitem action='RBond' />
+-	  <menuitem action='RMol' />
+-	  <menuitem action='RAll' />
+-    </menu>
+-	<menu action='HelpMenu'>
+-	  	  <menuitem action='Manual' />
+-	  	  <menuitem action='Register' />
+-	  	  <menuitem action='Donate' />
+-		  <menuitem action='About' />
+-    </menu>
+-  </menubar>
+-  <popup>
+-  	<menu action='ViewMenu'>
+-      <menuitem action='Command' />
+-	  <menuitem action='Scrolls' />
+-  	  <menuitem action='Menus' />
+-	  <menuitem action='Fullscreen' />
+-	  <separator/>
+-	  <menuitem action='Setfont' />
+-    </menu>
+-    <menu action='DispMenu'>
+-      <menuitem action='Wireframe' />
+-  	  <menuitem action='Backbone' />
+-	  <menuitem action='Sticks' />
+-	  <menuitem action='Spheres' />
+-	  <menuitem action='Ballstick' />
+-	  <menuitem action='Ribbons' />
+-	  <menuitem action='Strands' />
+-	  <menuitem action='Cartoons' />
+-	  <menuitem action='MolSurf' />
+-    </menu>
+-	<menu action='ColMenu'>
+-	  <menuitem action='Monochrome' />
+-      <menuitem action='CPK' />
+-	  <menuitem action='Shapely' />
+-	  <menuitem action='Group' />
+-	  <menuitem action='Chain' />
+-	  <menuitem action='Temperature' />
+-	  <menuitem action='Structure' />
+- 	  <menuitem action='User' />
+-	  <menuitem action='Model' />
+-	  <menuitem action='Alt' />
+-    </menu>
+-	<menu action='OptMenu'>
+-	  <menuitem action='Slab' />
+-	  <menuitem action='Hydrogens' />
+-	  <menuitem action='Heteros' />
+-	  <menuitem action='Specular' />
+-	  <menuitem action='Shadows' />
+-	  <menuitem action='Stereo' />
+-	  <menuitem action='Labels' />
+-    </menu>
+-	<menu action='SetMenu'>
+-      <menuitem action='POff' />
+-	  <menuitem action='PIdent' />
+-	  <menuitem action='PDistance' />
+-	  <menuitem action='PMonitor' />
+-	  <menuitem action='PAngle' />
+-	  <menuitem action='PTorsion' />
+-	  <menuitem action='PLabel' />
+-	  <menuitem action='PCentre' />
+-	  <menuitem action='PCoord' />
+-	  <menuitem action='PBond' />
+-	  <separator/>
+-	  <menuitem action='RBond' />
+-	  <menuitem action='RMol' />
+-	  <menuitem action='RAll' />
+-    </menu>
+-	<separator/>
+-    <placeholder name='OFiles' />
+-  </popup>
+-</ui>
diff --git a/debian/patches/series b/debian/patches/series
index f921c55..69372f2 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -11,3 +11,4 @@
 11_RESOLUTION.patch
 12_privacy_breach.patch
 13_spelling.patch
+14_gtk3-port.patch
-- 
2.19.0.rc2

-------------- next part --------------
>From e657d99c34e91381039b52b9ebab08cba9c364ee Mon Sep 17 00:00:00 2001
From: Yavor Doganov <yavor at gnu.org>
Date: Thu, 6 Sep 2018 13:58:36 +0300
Subject: [PATCH 2/3] Respect LDFLAGS from the environment, append
 -Wl,--as-needed

---
 debian/patches/02_imakefile.patch | 18 ++++++++----------
 debian/rules                      |  2 ++
 2 files changed, 10 insertions(+), 10 deletions(-)

diff --git a/debian/patches/02_imakefile.patch b/debian/patches/02_imakefile.patch
index cf46f56..c07ec8d 100644
--- a/debian/patches/02_imakefile.patch
+++ b/debian/patches/02_imakefile.patch
@@ -5,10 +5,8 @@ X-git-branch: p/imakefile
  src/Imakefile |   35 +++++++++++++++++++----------------
  1 file changed, 19 insertions(+), 16 deletions(-)
 
-diff --git a/src/Imakefile b/src/Imakefile
-index b5a88dd..7937273 100755
---- a/src/Imakefile
-+++ b/src/Imakefile
+--- rasmol.orig/src/Imakefile
++++ rasmol/src/Imakefile
 @@ -1,8 +1,8 @@
 -#define CBFLIB_LOCAL
 -#define CQRLIB_LOCAL
@@ -23,7 +21,7 @@ index b5a88dd..7937273 100755
  ###########################################################################
  #                               RasMol 2.7.5                              #
  #                                                                         #
-@@ -124,14 +124,15 @@ DEPTHDEF = -DTHIRTYTWOBIT
+@@ -124,14 +124,15 @@
    LOCALEDEF =
  #endif
  
@@ -41,7 +39,7 @@ index b5a88dd..7937273 100755
  GTKCFLAGS = $(shell pkg-config --cflags vte gtk+-2.0)
  GUISRC = gtkwin.c eggfileformatchooser.c 
  GUIOBJ = gtkwin.o eggfileformatchooser.o
-@@ -197,7 +198,7 @@ CBFLIB_OBJDEP = $(CBFLIB_DIR)/lib/libcbf.a
+@@ -197,7 +198,7 @@
  ifeq ($(strip $(CBFLIB_DIR)),)
  CBFLIB_DIR = $(PKGDIR)
  endif
@@ -50,7 +48,7 @@ index b5a88dd..7937273 100755
  CBFLIB_LDLIB = -L$(CBFLIB_DIR)/lib -lcbf
  CBFLIB_OBJDEP =
  #define NO_CBFLIB_BUILD
-@@ -276,7 +277,7 @@ NEARTREE_OBJDEP =
+@@ -276,7 +277,7 @@
  
  # RasMol's on-line help direcory
  #   e.g. /usr/local/lib/rasmol/rasmol.hlp
@@ -59,7 +57,7 @@ index b5a88dd..7937273 100755
  
  
  #ifndef USE_XFORMSLIB
-@@ -317,7 +318,7 @@ OBJS = rasmol.o molecule.o abstree.o cmndline.o command.o transfor.o \
+@@ -317,7 +318,7 @@
  # Additional RS6000 AIX MITSHM Library
  # LDLIBS = -lm -lXi -lXextSam $(XLIB)
  
@@ -68,7 +66,7 @@ index b5a88dd..7937273 100755
  			$(CBFLIB_LDLIB) \
  			$(CQRLIB_LDLIB) \
  			$(CVECTOR_LDLIB) \
-@@ -332,26 +333,28 @@ LDLIBS = -lm -lXi $(XLIB) $(EXTRA_LIBRARIES) $(XFORMSLIB) $(GTKLIBS) \
+@@ -332,26 +333,28 @@
  #
  
  #ifdef HPArchitecture
@@ -99,7 +97,7 @@ index b5a88dd..7937273 100755
  #endif
  
 +CCOPTIONS = $(shell dpkg-buildflags --get CFLAGS)
-+LOCAL_LDFLAGS = $(shell dpkg-buildflags --get LDFLAGS)
++LOCAL_LDFLAGS = ${LDFLAGS}
  
  ComplexProgramTarget(rasmol)
  MakeDirectories(install,$(RASMOLDIR))
diff --git a/debian/rules b/debian/rules
index 50e69a5..992ffeb 100755
--- a/debian/rules
+++ b/debian/rules
@@ -1,6 +1,8 @@
 #!/usr/bin/make -f
 
 export DEB_BUILD_MAINT_OPTIONS = hardening=+all
+# Trim extra dependencies imposed by VTE.
+DEB_LDFLAGS_MAINT_APPEND = -Wl,--as-needed
 DPKG_EXPORT_BUILDFLAGS = 1
 include /usr/share/dpkg/buildflags.mk
 
-- 
2.19.0.rc2

-------------- next part --------------
>From 2432893f58932707cb01cc06ce2fba5d058a8f15 Mon Sep 17 00:00:00 2001
From: Yavor Doganov <yavor at gnu.org>
Date: Thu, 6 Sep 2018 14:18:18 +0300
Subject: [PATCH 3/3] Avoid PATH_MAX, should fix FTBFS on GNU/Hurd

---
 debian/patches/15_avoid-PATH_MAX.patch | 44 ++++++++++++++++++++++++++
 debian/patches/series                  |  1 +
 2 files changed, 45 insertions(+)
 create mode 100644 debian/patches/15_avoid-PATH_MAX.patch

diff --git a/debian/patches/15_avoid-PATH_MAX.patch b/debian/patches/15_avoid-PATH_MAX.patch
new file mode 100644
index 0000000..5c51f3b
--- /dev/null
+++ b/debian/patches/15_avoid-PATH_MAX.patch
@@ -0,0 +1,44 @@
+Description: Fix FTBFS on GNU/Hurd, avoid PATH_MAX usage.
+Author: Yavor Doganov <yavor at gnu.org>
+Forwarded: no
+Last-Update: 2018-09-06
+---
+
+--- rasmol.orig/src/gtkwin.c
++++ rasmol/src/gtkwin.c
+@@ -562,12 +562,13 @@
+             GTK_FILE_CHOOSER (opendialog));
+         strcpy(DataFileName, prevname);
+         if(FetchFile(FormatPDB, False, prevname)) {
+-            char tmp[PATH_MAX+10];
++            char *tmp = NULL;
+ 
+-            strcpy(tmp, "file://");
+-            if(realpath(prevname, tmp+7)) {
++            tmp = g_filename_to_uri(prevname, NULL, NULL);
++            if(tmp) {
+                 rman = gtk_recent_manager_get_default();
+                 gtk_recent_manager_add_item(rman, tmp);
++                g_free(tmp);
+             }
+             DefaultRepresentation();
+             RefreshScreen();
+--- rasmol.orig/src/rasmol.c
++++ rasmol/src/rasmol.c
+@@ -2537,12 +2537,13 @@
+         if( done )
+         {
+ #ifdef GTKWIN
+-            char tmp[PATH_MAX+10];
++            char *tmp = NULL;
+ 
+-            strcpy(tmp, "file://");
+-            if(realpath(FileNamePtrs[i], tmp+7)) {
++            tmp = g_filename_to_uri(FileNamePtrs[i], NULL, NULL);
++            if(tmp) {
+                 gtk_recent_manager_add_item(gtk_recent_manager_get_default(),
+                                             tmp);
++                g_free(tmp);
+             }
+ #endif // GTKWIN
+             DefaultRepresentation();
diff --git a/debian/patches/series b/debian/patches/series
index 69372f2..cbbf8cc 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -12,3 +12,4 @@
 12_privacy_breach.patch
 13_spelling.patch
 14_gtk3-port.patch
+15_avoid-PATH_MAX.patch
-- 
2.19.0.rc2



More information about the debian-science-maintainers mailing list