diff --git a/data/ui/BitwiseOperationsPlugin.ui b/data/ui/BitwiseOperationsPlugin.ui
index 5ce9c6e..ef2cc41 100644
--- a/data/ui/BitwiseOperationsPlugin.ui
+++ b/data/ui/BitwiseOperationsPlugin.ui
@@ -41,7 +41,8 @@
       </row>
     </data>
   </object>
-  <object class="GtkHBox" id="BitwiseOperationsHBox">
+  <object class="GtkBox" id="BitwiseOperationsHBox">
+    <property name="orientation">horizontal</property>
     <property name="visible">True</property>
     <property name="border_width">6</property>
     <property name="spacing">6</property>
@@ -119,8 +120,7 @@
     <child>
       <object class="GtkButton" id="DoOperationButton">
         <property name="visible">True</property>
-        <property name="label" translatable="no">gtk-execute</property>
-        <property name="use_stock">True</property>
+        <property name="icon-name">system-run</property>
         <signal handler="OnDoOperationClicked" name="clicked"/>
       </object>
       <packing>
diff --git a/data/ui/ConversionTablePlugin.ui b/data/ui/ConversionTablePlugin.ui
index 4b2359f..e5ee388 100644
--- a/data/ui/ConversionTablePlugin.ui
+++ b/data/ui/ConversionTablePlugin.ui
@@ -35,7 +35,6 @@
       <packing>
         <property name="left_attach">6</property>
         <property name="right_attach">7</property>
-        <property name="x_options">GTK_FILL</property>
         <property name="y_options"/>
       </packing>
     </child>
@@ -145,7 +144,6 @@
         <property name="right_attach">5</property>
         <property name="top_attach">4</property>
         <property name="bottom_attach">5</property>
-        <property name="x_options">GTK_FILL</property>
         <property name="y_options"/>
         <property name="x_padding">6</property>
       </packing>
@@ -169,7 +167,6 @@
         <property name="right_attach">4</property>
         <property name="top_attach">6</property>
         <property name="bottom_attach">7</property>
-        <property name="x_options">GTK_FILL</property>
         <property name="y_options"/>
       </packing>
     </child>
@@ -412,7 +409,6 @@
         <property name="right_attach">5</property>
         <property name="top_attach">3</property>
         <property name="bottom_attach">4</property>
-        <property name="x_options">GTK_FILL</property>
         <property name="y_options"/>
         <property name="x_padding">6</property>
       </packing>
@@ -428,7 +424,6 @@
         <property name="right_attach">5</property>
         <property name="top_attach">2</property>
         <property name="bottom_attach">3</property>
-        <property name="x_options">GTK_FILL</property>
         <property name="y_options"/>
         <property name="x_padding">6</property>
       </packing>
@@ -444,7 +439,6 @@
         <property name="right_attach">5</property>
         <property name="top_attach">1</property>
         <property name="bottom_attach">2</property>
-        <property name="x_options">GTK_FILL</property>
         <property name="y_options"/>
         <property name="x_padding">6</property>
       </packing>
@@ -458,7 +452,6 @@
       <packing>
         <property name="left_attach">4</property>
         <property name="right_attach">5</property>
-        <property name="x_options">GTK_FILL</property>
         <property name="y_options"/>
         <property name="x_padding">6</property>
       </packing>
@@ -474,7 +467,6 @@
         <property name="right_attach">3</property>
         <property name="top_attach">3</property>
         <property name="bottom_attach">4</property>
-        <property name="x_options">GTK_FILL</property>
         <property name="y_options"/>
         <property name="x_padding">6</property>
         <property name="y_padding">6</property>
@@ -491,7 +483,6 @@
         <property name="right_attach">3</property>
         <property name="top_attach">2</property>
         <property name="bottom_attach">3</property>
-        <property name="x_options">GTK_FILL</property>
         <property name="y_options"/>
         <property name="x_padding">6</property>
         <property name="y_padding">6</property>
@@ -508,7 +499,6 @@
         <property name="right_attach">3</property>
         <property name="top_attach">1</property>
         <property name="bottom_attach">2</property>
-        <property name="x_options">GTK_FILL</property>
         <property name="y_options"/>
         <property name="x_padding">6</property>
         <property name="y_padding">6</property>
@@ -523,7 +513,6 @@
       <packing>
         <property name="left_attach">2</property>
         <property name="right_attach">3</property>
-        <property name="x_options">GTK_FILL</property>
         <property name="y_options"/>
         <property name="x_padding">6</property>
         <property name="y_padding">6</property>
@@ -538,7 +527,6 @@
       <packing>
         <property name="top_attach">5</property>
         <property name="bottom_attach">6</property>
-        <property name="x_options">GTK_FILL</property>
         <property name="y_options"/>
         <property name="x_padding">6</property>
         <property name="y_padding">6</property>
@@ -553,7 +541,6 @@
       <packing>
         <property name="top_attach">4</property>
         <property name="bottom_attach">5</property>
-        <property name="x_options">GTK_FILL</property>
         <property name="y_options"/>
         <property name="x_padding">6</property>
         <property name="y_padding">6</property>
@@ -568,7 +555,6 @@
       <packing>
         <property name="top_attach">3</property>
         <property name="bottom_attach">4</property>
-        <property name="x_options">GTK_FILL</property>
         <property name="y_options"/>
         <property name="x_padding">6</property>
         <property name="y_padding">6</property>
@@ -583,7 +569,6 @@
       <packing>
         <property name="top_attach">2</property>
         <property name="bottom_attach">3</property>
-        <property name="x_options">GTK_FILL</property>
         <property name="y_options"/>
         <property name="x_padding">6</property>
         <property name="y_padding">6</property>
@@ -598,7 +583,6 @@
       <packing>
         <property name="top_attach">1</property>
         <property name="bottom_attach">2</property>
-        <property name="x_options">GTK_FILL</property>
         <property name="y_options"/>
         <property name="x_padding">6</property>
         <property name="y_padding">6</property>
@@ -611,7 +595,6 @@
         <property name="label" translatable="yes">Signed 8 bit:</property>
       </object>
       <packing>
-        <property name="x_options">GTK_FILL</property>
         <property name="y_options"/>
         <property name="x_padding">6</property>
         <property name="y_padding">6</property>
diff --git a/data/ui/ExportDialog.ui b/data/ui/ExportDialog.ui
index 14a259d..5184a87 100644
--- a/data/ui/ExportDialog.ui
+++ b/data/ui/ExportDialog.ui
@@ -1,6 +1,7 @@
 <?xml version="1.0"?>
 <interface>
-  <object class="GtkVBox" id="ExportDialogVBox">
+  <object class="GtkBox" id="ExportDialogVBox">
+    <property name="orientation">vertical</property>
     <property name="visible">True</property>
     <property name="spacing">6</property>
     <child>
@@ -11,17 +12,14 @@
         <property name="column_spacing">6</property>
         <property name="row_spacing">6</property>
         <child>
-          <object class="GtkHBox" id="hbox7">
+          <object class="GtkBox" id="hbox7">
+            <property name="orientation">horizontal</property>
             <property name="visible">True</property>
             <property name="spacing">6</property>
             <child>
-              <object class="GtkComboBoxEntry" id="ExportPatternComboEntry">
+              <object class="GtkComboBoxText" id="ExportPatternComboEntry">
+                <property name="has-entry">True</property>
                 <property name="visible">True</property>
-                <child internal-child="entry">
-                  <object class="GtkEntry" id="comboboxentry-entry1">
-                    <property name="visible">True</property>
-                  </object>
-                </child>
               </object>
             </child>
             <child>
@@ -96,11 +94,11 @@
           <packing>
             <property name="top_attach">2</property>
             <property name="bottom_attach">3</property>
-            <property name="x_options">GTK_FILL</property>
           </packing>
         </child>
         <child>
-          <object class="GtkHBox" id="hbox2">
+          <object class="GtkBox" id="hbox2">
+            <property name="orientation">horizontal</property>
             <property name="visible">True</property>
             <property name="spacing">6</property>
             <child>
@@ -140,7 +138,6 @@
           <packing>
             <property name="top_attach">1</property>
             <property name="bottom_attach">2</property>
-            <property name="x_options">GTK_FILL</property>
           </packing>
         </child>
         <child>
@@ -151,7 +148,6 @@
             <property name="use_underline">True</property>
           </object>
           <packing>
-            <property name="x_options">GTK_FILL</property>
           </packing>
         </child>
       </object>
@@ -172,7 +168,8 @@
       </packing>
     </child>
     <child>
-      <object class="GtkHBox" id="hbox3">
+      <object class="GtkBox" id="hbox3">
+        <property name="orientation">horizontal</property>
         <property name="visible">True</property>
         <child>
           <object class="GtkLabel" id="label9">
@@ -181,7 +178,8 @@
           </object>
         </child>
         <child>
-          <object class="GtkVBox" id="vbox2">
+          <object class="GtkBox" id="vbox2">
+            <property name="orientation">vertical</property>
             <property name="visible">True</property>
             <child>
               <object class="GtkRadioButton" id="WholeFileRadio">
@@ -210,7 +208,8 @@
               </packing>
             </child>
             <child>
-              <object class="GtkHBox" id="hbox6">
+              <object class="GtkBox" id="hbox6">
+                <property name="orientation">horizontal</property>
                 <property name="visible">True</property>
                 <property name="spacing">6</property>
                 <child>
@@ -270,7 +269,8 @@
       </packing>
     </child>
     <child>
-      <object class="GtkHBox" id="ProgressHBox">
+      <object class="GtkBox" id="ProgressHBox">
+        <property name="orientation">horizontal</property>
         <property name="visible">True</property>
         <property name="spacing">6</property>
         <child>
@@ -281,8 +281,7 @@
         <child>
           <object class="GtkButton" id="CancelButton">
             <property name="visible">True</property>
-            <property name="label" translatable="no">gtk-cancel</property>
-            <property name="use_stock">True</property>
+            <property name="icon-name">process-stop</property>
             <signal handler="OnExportCancelClicked" name="clicked"/>
           </object>
           <packing>
diff --git a/data/ui/FindReplacePlugin.ui b/data/ui/FindReplacePlugin.ui
index 65078f5..056f0b5 100644
--- a/data/ui/FindReplacePlugin.ui
+++ b/data/ui/FindReplacePlugin.ui
@@ -50,8 +50,6 @@
         <property name="right_attach">4</property>
         <property name="top_attach">1</property>
         <property name="bottom_attach">2</property>
-        <property name="x_options">GTK_FILL</property>
-        <property name="y_options">GTK_FILL</property>
       </packing>
     </child>
     <child>
@@ -70,8 +68,6 @@
       <packing>
         <property name="left_attach">3</property>
         <property name="right_attach">4</property>
-        <property name="x_options">GTK_FILL</property>
-        <property name="y_options">GTK_FILL</property>
       </packing>
     </child>
     <child>
@@ -88,7 +84,8 @@
             <property name="xscale">0</property>
             <property name="yscale">0</property>
             <child>
-              <object class="GtkHBox" id="hbox30">
+              <object class="GtkBox" id="hbox30">
+                <property name="orientation">horizontal</property>
                 <property name="visible">True</property>
                 <property name="spacing">2</property>
                 <child>
@@ -140,7 +137,8 @@
             <property name="xscale">0</property>
             <property name="yscale">0</property>
             <child>
-              <object class="GtkHBox" id="hbox32">
+              <object class="GtkBox" id="hbox32">
+                <property name="orientation">horizontal</property>
                 <property name="visible">True</property>
                 <property name="spacing">2</property>
                 <child>
@@ -175,7 +173,6 @@
         <property name="right_attach">5</property>
         <property name="top_attach">1</property>
         <property name="bottom_attach">2</property>
-        <property name="x_options">GTK_FILL</property>
         <property name="y_options"/>
         <property name="x_padding">6</property>
       </packing>
@@ -190,7 +187,6 @@
         <property name="right_attach">3</property>
         <property name="top_attach">1</property>
         <property name="bottom_attach">2</property>
-        <property name="x_options">GTK_FILL</property>
         <property name="y_options"/>
         <property name="x_padding">6</property>
       </packing>
@@ -203,7 +199,6 @@
       <packing>
         <property name="left_attach">2</property>
         <property name="right_attach">3</property>
-        <property name="x_options">GTK_FILL</property>
         <property name="y_options"/>
         <property name="x_padding">6</property>
       </packing>
@@ -224,7 +219,6 @@
         <property name="right_attach">6</property>
         <property name="top_attach">1</property>
         <property name="bottom_attach">2</property>
-        <property name="x_options">GTK_FILL</property>
         <property name="y_options"/>
       </packing>
     </child>
@@ -242,7 +236,8 @@
             <property name="xscale">0</property>
             <property name="yscale">0</property>
             <child>
-              <object class="GtkHBox" id="hbox31">
+              <object class="GtkBox" id="hbox31">
+                <property name="orientation">horizontal</property>
                 <property name="visible">True</property>
                 <property name="spacing">2</property>
                 <child>
@@ -276,7 +271,6 @@
       <packing>
         <property name="left_attach">5</property>
         <property name="right_attach">6</property>
-        <property name="x_options">GTK_FILL</property>
         <property name="y_options"/>
       </packing>
     </child>
@@ -318,7 +312,6 @@
       <packing>
         <property name="top_attach">1</property>
         <property name="bottom_attach">2</property>
-        <property name="x_options">GTK_FILL</property>
         <property name="y_options"/>
       </packing>
     </child>
@@ -330,7 +323,6 @@
         <property name="use_markup">True</property>
       </object>
       <packing>
-        <property name="x_options">GTK_FILL</property>
         <property name="y_options"/>
       </packing>
     </child>
@@ -350,8 +342,6 @@
       <packing>
         <property name="left_attach">6</property>
         <property name="right_attach">7</property>
-        <property name="x_options">GTK_FILL</property>
-        <property name="y_options">GTK_FILL</property>
       </packing>
     </child>
   </object>
diff --git a/data/ui/GotoOffsetPlugin.ui b/data/ui/GotoOffsetPlugin.ui
index afae5cc..49bdda8 100644
--- a/data/ui/GotoOffsetPlugin.ui
+++ b/data/ui/GotoOffsetPlugin.ui
@@ -1,6 +1,7 @@
 <?xml version="1.0"?>
 <interface>
-  <object class="GtkHBox" id="GotoOffsetHBox">
+  <object class="GtkBox" id="GotoOffsetHBox">
+    <property name="orientation">horizontal</property>
     <property name="visible">True</property>
     <property name="border_width">6</property>
     <property name="spacing">6</property>
@@ -40,7 +41,8 @@
             <property name="xscale">0</property>
             <property name="yscale">0</property>
             <child>
-              <object class="GtkHBox" id="hbox34">
+              <object class="GtkBox" id="hbox34">
+                <property name="orientation">horizontal</property>
                 <property name="visible">True</property>
                 <property name="spacing">2</property>
                 <child>
diff --git a/data/ui/LayoutSelectionDialog.ui b/data/ui/LayoutSelectionDialog.ui
index e7d552c..353e663 100644
--- a/data/ui/LayoutSelectionDialog.ui
+++ b/data/ui/LayoutSelectionDialog.ui
@@ -18,7 +18,6 @@
                 <property name="visible">True</property>
                 <property name="can_focus">True</property>
                 <property name="headers_visible">False</property>
-                <property name="rules_hint">True</property>
               </object>
             </child>
           </object>
diff --git a/data/ui/MainWindow.ui b/data/ui/MainWindow.ui
index c376e1f..9d4c0c2 100644
--- a/data/ui/MainWindow.ui
+++ b/data/ui/MainWindow.ui
@@ -7,7 +7,8 @@
     <property name="default_height">400</property>
     <signal handler="OnMainWindowDeleteEvent" name="delete_event"/>
     <child>
-      <object class="GtkVBox" id="MainVBox">
+      <object class="GtkBox" id="MainVBox">
+        <property name="orientation">vertical</property>
         <property name="visible">True</property>
         <child>
           <placeholder/>
@@ -16,7 +17,8 @@
           <placeholder/>
         </child>
         <child>
-          <object class="GtkHBox" id="DataViewBox">
+          <object class="GtkBox" id="DataViewBox">
+            <property name="orientation">horizontal</property>
             <property name="visible">True</property>
             <child>
               <placeholder/>
diff --git a/data/ui/PreferencesDialog.ui b/data/ui/PreferencesDialog.ui
index f81844c..e06b76f 100644
--- a/data/ui/PreferencesDialog.ui
+++ b/data/ui/PreferencesDialog.ui
@@ -61,12 +61,14 @@
       <placeholder/>
     </child>
   </object>
-  <object class="GtkVBox" id="GeneralPreferencesVBox">
+  <object class="GtkBox" id="GeneralPreferencesVBox">
+    <property name="orientation">vertical</property>
     <property name="visible">True</property>
     <property name="border_width">12</property>
     <property name="spacing">12</property>
     <child>
-      <object class="GtkVBox" id="vbox13">
+      <object class="GtkBox" id="vbox13">
+        <property name="orientation">vertical</property>
         <property name="visible">True</property>
         <property name="spacing">6</property>
         <child>
@@ -82,7 +84,8 @@
           </packing>
         </child>
         <child>
-          <object class="GtkHBox" id="hbox20">
+          <object class="GtkBox" id="hbox20">
+            <property name="orientation">horizontal</property>
             <property name="visible">True</property>
             <child>
               <object class="GtkLabel" id="label48">
@@ -95,11 +98,13 @@
               </packing>
             </child>
             <child>
-              <object class="GtkVBox" id="vbox14">
+              <object class="GtkBox" id="vbox14">
+                <property name="orientation">vertical</property>
                 <property name="visible">True</property>
                 <property name="spacing">6</property>
                 <child>
-                  <object class="GtkHBox" id="hbox21">
+                  <object class="GtkBox" id="hbox21">
+                    <property name="orientation">horizontal</property>
                     <property name="visible">True</property>
                     <property name="spacing">6</property>
                     <child>
@@ -133,7 +138,8 @@
                             <property name="xscale">0</property>
                             <property name="yscale">0</property>
                             <child>
-                              <object class="GtkHBox" id="hbox27">
+                              <object class="GtkBox" id="hbox27">
+                                <property name="orientation">horizontal</property>
                                 <property name="visible">True</property>
                                 <property name="spacing">2</property>
                                 <child>
@@ -210,7 +216,8 @@
       </packing>
     </child>
     <child>
-      <object class="GtkVBox" id="vbox17">
+      <object class="GtkBox" id="vbox17">
+        <property name="orientation">vertical</property>
         <property name="visible">True</property>
         <property name="spacing">6</property>
         <child>
@@ -226,7 +233,8 @@
           </packing>
         </child>
         <child>
-          <object class="GtkHBox" id="hbox25">
+          <object class="GtkBox" id="hbox25">
+            <property name="orientation">horizontal</property>
             <property name="visible">True</property>
             <child>
               <object class="GtkLabel" id="label55">
@@ -246,7 +254,8 @@
                 <property name="column_spacing">6</property>
                 <property name="row_spacing">6</property>
                 <child>
-                  <object class="GtkHBox" id="hbox4">
+                  <object class="GtkBox" id="hbox4">
+                    <property name="orientation">horizontal</property>
                     <property name="visible">True</property>
                     <child>
                       <object class="GtkEntry" id="TempDirEntry">
@@ -295,7 +304,6 @@
                     <property name="use_underline">True</property>
                   </object>
                   <packing>
-                    <property name="x_options">GTK_FILL</property>
                     <property name="y_options"/>
                   </packing>
                 </child>
@@ -313,8 +321,6 @@
                   <packing>
                     <property name="left_attach">1</property>
                     <property name="right_attach">2</property>
-                    <property name="x_options">GTK_FILL</property>
-                    <property name="y_options">GTK_FILL</property>
                   </packing>
                 </child>
               </object>
@@ -339,7 +345,8 @@
       </packing>
     </child>
   </object>
-  <object class="GtkVBox" id="SessionPreferencesVBox">
+  <object class="GtkBox" id="SessionPreferencesVBox">
+    <property name="orientation">vertical</property>
     <property name="visible">True</property>
     <property name="border_width">12</property>
     <property name="spacing">6</property>
@@ -358,7 +365,8 @@
       </packing>
     </child>
     <child>
-      <object class="GtkHBox" id="hbox19">
+      <object class="GtkBox" id="hbox19">
+        <property name="orientation">horizontal</property>
         <property name="visible">True</property>
         <child>
           <object class="GtkLabel" id="label46">
@@ -371,7 +379,8 @@
           </packing>
         </child>
         <child>
-          <object class="GtkVBox" id="vbox11">
+          <object class="GtkBox" id="vbox11">
+            <property name="orientation">vertical</property>
             <property name="visible">True</property>
             <property name="spacing">6</property>
             <child>
@@ -432,12 +441,14 @@
       </packing>
     </child>
   </object>
-  <object class="GtkVBox" id="UndoPreferencesVBox">
+  <object class="GtkBox" id="UndoPreferencesVBox">
+    <property name="orientation">vertical</property>
     <property name="visible">True</property>
     <property name="border_width">12</property>
     <property name="spacing">12</property>
     <child>
-      <object class="GtkVBox" id="vbox15">
+      <object class="GtkBox" id="vbox15">
+        <property name="orientation">vertical</property>
         <property name="visible">True</property>
         <property name="spacing">6</property>
         <child>
@@ -453,7 +464,8 @@
           </packing>
         </child>
         <child>
-          <object class="GtkHBox" id="hbox22">
+          <object class="GtkBox" id="hbox22">
+            <property name="orientation">horizontal</property>
             <property name="visible">True</property>
             <child>
               <object class="GtkLabel" id="label51">
@@ -466,11 +478,13 @@
               </packing>
             </child>
             <child>
-              <object class="GtkVBox" id="vbox16">
+              <object class="GtkBox" id="vbox16">
+                <property name="orientation">vertical</property>
                 <property name="visible">True</property>
                 <property name="spacing">6</property>
                 <child>
-                  <object class="GtkHBox" id="hbox23">
+                  <object class="GtkBox" id="hbox23">
+                    <property name="orientation">horizontal</property>
                     <property name="visible">True</property>
                     <property name="spacing">6</property>
                     <child>
@@ -553,7 +567,8 @@
       </packing>
     </child>
     <child>
-      <object class="GtkVBox" id="vbox3">
+      <object class="GtkBox" id="vbox3">
+        <property name="orientation">vertical</property>
         <property name="visible">True</property>
         <property name="spacing">6</property>
         <child>
@@ -569,7 +584,8 @@
           </packing>
         </child>
         <child>
-          <object class="GtkHBox" id="hbox5">
+          <object class="GtkBox" id="hbox5">
+            <property name="orientation">horizontal</property>
             <property name="visible">True</property>
             <child>
               <object class="GtkLabel" id="label13">
@@ -582,7 +598,8 @@
               </packing>
             </child>
             <child>
-              <object class="GtkVBox" id="vbox4">
+              <object class="GtkBox" id="vbox4">
+                <property name="orientation">vertical</property>
                 <property name="visible">True</property>
                 <property name="spacing">6</property>
                 <child>
diff --git a/data/ui/ProgressDialog.ui b/data/ui/ProgressDialog.ui
index 33c9c2e..26487d2 100644
--- a/data/ui/ProgressDialog.ui
+++ b/data/ui/ProgressDialog.ui
@@ -1,6 +1,7 @@
 <?xml version="1.0"?>
 <interface>
-  <object class="GtkVBox" id="ProgressVBox">
+  <object class="GtkBox" id="ProgressVBox">
+    <property name="orientation">vertical</property>
     <property name="visible">True</property>
     <property name="border_width">7</property>
     <property name="spacing">12</property>
@@ -38,7 +39,7 @@
       </packing>
     </child>
     <child>
-      <object class="GtkHButtonBox" id="hbuttonbox9">
+      <object class="GtkButtonBox" id="hbuttonbox9">
         <property name="visible">True</property>
         <property name="layout_style">GTK_BUTTONBOX_END</property>
         <child>
diff --git a/data/ui/ProgressDisplayPlugin.ui b/data/ui/ProgressDisplayPlugin.ui
index 49d6bf0..62cd15e 100644
--- a/data/ui/ProgressDisplayPlugin.ui
+++ b/data/ui/ProgressDisplayPlugin.ui
@@ -1,6 +1,7 @@
 <?xml version="1.0"?>
 <interface>
-  <object class="GtkHBox" id="ProgressBarHBox">
+  <object class="GtkBox" id="ProgressBarHBox">
+    <property name="orientation">horizontal</property>
     <property name="visible">True</property>
     <property name="border_width">6</property>
     <property name="spacing">6</property>
@@ -13,8 +14,7 @@
     <child>
       <object class="GtkButton" id="CancelButton">
         <property name="visible">True</property>
-        <property name="label" translatable="no">gtk-cancel</property>
-        <property name="use_stock">True</property>
+        <property name="icon-name">process-stop</property>
         <signal handler="OnCancelButtonClicked" name="clicked"/>
       </object>
       <packing>
diff --git a/data/ui/SelectRangePlugin.ui b/data/ui/SelectRangePlugin.ui
index 729cc10..5990e77 100644
--- a/data/ui/SelectRangePlugin.ui
+++ b/data/ui/SelectRangePlugin.ui
@@ -1,6 +1,7 @@
 <?xml version="1.0"?>
 <interface>
-  <object class="GtkHBox" id="SelectRangeHBox">
+  <object class="GtkBox" id="SelectRangeHBox">
+    <property name="orientation">horizontal</property>
     <property name="visible">True</property>
     <property name="border_width">6</property>
     <property name="spacing">6</property>
@@ -61,7 +62,8 @@
             <property name="xscale">0</property>
             <property name="yscale">0</property>
             <child>
-              <object class="GtkHBox" id="hbox36">
+              <object class="GtkBox" id="hbox36">
+                <property name="orientation">horizontal</property>
                 <property name="visible">True</property>
                 <property name="spacing">2</property>
                 <child>
diff --git a/meson.build b/meson.build
index c0c9929..22974b2 100644
--- a/meson.build
+++ b/meson.build
@@ -8,8 +8,8 @@ project(
 
 add_project_arguments('-d:ENABLE_UNIX_SPECIFIC', language: 'cs')
 
-gtk_sharp_2_dep = dependency('gtk-sharp-2.0')
-glib_sharp_2_dep = dependency('glib-sharp-2.0')
+gtk_sharp_2_dep = dependency('gtk-sharp-3.0')
+glib_sharp_2_dep = dependency('glib-sharp-3.0')
 
 subdir('src')
 subdir('data')
diff --git a/src/gui/DataBook.cs b/src/gui/DataBook.cs
index 4d84e34..94b3306 100644
--- a/src/gui/DataBook.cs
+++ b/src/gui/DataBook.cs
@@ -218,7 +218,7 @@ public class DataBook : Gtk.Notebook
 }
 
 ///<summary>A widget to display on each tab label</summary>
-class DataBookTabLabel : Gtk.HBox
+class DataBookTabLabel : Gtk.Box
 {
 	Gtk.Label label;
 	Gtk.Button closeButton;
@@ -235,6 +235,7 @@ class DataBookTabLabel : Gtk.HBox
 	}
 
 	public DataBookTabLabel(DataView dv, CloseViewDelegate deleg, string str)
+		: base(Gtk.Orientation.Horizontal, 2)
 	{
 		dataView = dv;
 		doCloseFile = deleg;
@@ -245,7 +246,7 @@ class DataBookTabLabel : Gtk.HBox
 		label.UseMarkup = true;
 		label.UseUnderline = false;
 
-		Gtk.Image img = new Gtk.Image(Gtk.Stock.Close, Gtk.IconSize.Menu);
+		Gtk.Image img = Gtk.Image.NewFromIconName("window-close", Gtk.IconSize.Menu);
 		img.SetSizeRequest(8, 8);
 
 		// This doesn't compile in 1.0.2 and older,
@@ -256,7 +257,6 @@ class DataBookTabLabel : Gtk.HBox
 		closeButton.Clicked += OnCloseClicked;
 		closeButton.CanFocus = false;
 
-		this.Spacing = 2;
 		this.PackStart(label, false, false, 0);
 		this.PackStart(closeButton, false, false, 0);
 
diff --git a/src/gui/DataViewControl.cs b/src/gui/DataViewControl.cs
index 590bcac..5434cd6 100644
--- a/src/gui/DataViewControl.cs
+++ b/src/gui/DataViewControl.cs
@@ -279,7 +279,7 @@ public class DataViewControl
 		Gdk.ModifierType state;
 
 		if (e.IsHint)
-			da.GdkWindow.GetPointer(out x, out y, out state);
+			da.Window.GetDevicePosition(da.Display.DeviceManager.ClientPointer, out x, out y, out state);
 		else {
 			x = (int)e.X;
 			y = (int)e.Y;
diff --git a/src/gui/DataViewDisplay.cs b/src/gui/DataViewDisplay.cs
index 39d17ae..8a43929 100644
--- a/src/gui/DataViewDisplay.cs
+++ b/src/gui/DataViewDisplay.cs
@@ -1,4 +1,3 @@
-// created on 1/11/2005 at 9:43 PM
 /*
  *   Copyright (c) 2005, Alexandros Frantzis (alf82 [at] freemail [dot] gr)
  *
@@ -29,13 +28,12 @@ using Bless.Util;
 namespace Bless.Gui {
 
 ///<summary>A widget that displays data from a buffer</summary>
-public class DataViewDisplay : Gtk.VBox {
+public class DataViewDisplay : Gtk.Box {
 	Layout layout;
-	Gtk.HBox hbox;
+	Gtk.Box hbox;
 	Gtk.DrawingArea drawingArea;
-	//static Gtk.DrawingArea drawingArea=new Gtk.DrawingArea();
 	Gtk.VScrollbar vscroll;
-	Gtk.HBox fileChangedBar;
+	FileChangedBar fileChangedBar;
 	bool widgetRealized;
 
 	DataViewControl dvControl;
@@ -43,18 +41,14 @@ public class DataViewDisplay : Gtk.VBox {
 
 	public enum ShowType { Closest, Start, End, Cursor }
 
-	public DataView View {
-		get { return dataView;}
-	}
+	public DataView View { get { return dataView; } }
 
 	public DataViewControl Control {
 		set {
 			DisconnectFromControl();
-			// connect new control
 			dvControl = value;
 			ConnectToControl();
 		}
-
 		get { return dvControl; }
 	}
 
@@ -62,18 +56,11 @@ public class DataViewDisplay : Gtk.VBox {
 		get { return layout; }
 
 		set {
-			// temporarily save previous layout
 			Layout prevLayout = layout;
-
-			// dispose Area pixmaps
 			layout.DisposePixmaps();
-
-			// set new layout
 			layout = value;
-
-			// set buffer
 			layout.AreaGroup.Buffer = dataView.Buffer;
-			
+
 			if (widgetRealized) {
 				layout.Realize(drawingArea);
 				Gdk.Rectangle alloc = drawingArea.Allocation;
@@ -81,25 +68,19 @@ public class DataViewDisplay : Gtk.VBox {
 
 				long prevOffset = 0;
 
-				// Setup new areas according to the old ones
 				if (prevLayout != null && prevLayout.AreaGroup.Areas.Count > 0) {
 					layout.AreaGroup.SetCursor(prevLayout.AreaGroup.CursorOffset, 0);
 					layout.AreaGroup.Selection = prevLayout.AreaGroup.Selection;
-				}
-				else {
+				} else {
 					layout.AreaGroup.SetCursor(0, 0);
 				}
 
-				// make sure cursor is visible
 				MakeOffsetVisible(prevOffset, ShowType.Closest);
 			}
 		}
-
 	}
 
-	internal Gtk.VScrollbar VScroll {
-		get { return vscroll; }
-	}
+	internal Gtk.VScrollbar VScroll { get { return vscroll; } }
 
 	public new bool HasFocus {
 		get { return drawingArea.HasFocus; }
@@ -107,28 +88,25 @@ public class DataViewDisplay : Gtk.VBox {
 	}
 
 	///<summary>Create a DataViewDisplay</summary>
-	public DataViewDisplay(DataView dv)
+	public DataViewDisplay(DataView dv) : base(Gtk.Orientation.Vertical, 0)
 	{
 		dataView = dv;
 
-		// load the default layout from the data directory
 		layout = new Layout(FileResourcePath.GetDataPath("bless-default.layout"));
 
-		// initialize scrollbar
-		Gtk.Adjustment
-		adj = new Gtk.Adjustment(0.0, 0.0, 1.0, 1.0, 10.0, 0.0);
+		Gtk.Adjustment adj = new Gtk.Adjustment(0.0, 0.0, 1.0, 1.0, 10.0, 0.0);
 		vscroll = new Gtk.VScrollbar(adj);
-
 		adj.ValueChanged += OnScrolled;
 
-		// initialize drawing area
 		drawingArea = new Gtk.DrawingArea();
-		drawingArea.Realized += OnRealized;
-		drawingArea.ExposeEvent += OnExposed;
+		drawingArea.Realized      += OnRealized;
+		drawingArea.Drawn         += OnDrawn;
 		drawingArea.ConfigureEvent += OnConfigured;
-		drawingArea.ModifyBg(StateType.Normal, new Gdk.Color(0xff, 0xff, 0xff));
 
-		// add events that we want to handle
+		// White background using GTK3 override (non-deprecated)
+		drawingArea.OverrideBackgroundColor(Gtk.StateFlags.Normal,
+			new Gdk.RGBA { Red = 1.0, Green = 1.0, Blue = 1.0, Alpha = 1.0 });
+
 		drawingArea.AddEvents((int)Gdk.EventMask.ButtonPressMask);
 		drawingArea.AddEvents((int)Gdk.EventMask.ButtonReleaseMask);
 		drawingArea.AddEvents((int)Gdk.EventMask.PointerMotionMask);
@@ -136,14 +114,13 @@ public class DataViewDisplay : Gtk.VBox {
 		drawingArea.AddEvents((int)Gdk.EventMask.KeyPressMask);
 		drawingArea.AddEvents((int)Gdk.EventMask.KeyReleaseMask);
 
-		drawingArea.CanFocus = true; // needed to catch key events
-
-		hbox = new Gtk.HBox();
+		drawingArea.CanFocus = true;
 
-		hbox.PackStart(drawingArea , true, true, 0);
-		hbox.PackStart(vscroll , false, false, 0);
+		hbox = new Gtk.Box(Gtk.Orientation.Horizontal, 0);
+		hbox.PackStart(drawingArea, true,  true,  0);
+		hbox.PackStart(vscroll,     false, false, 0);
 
-		this.PackStart(hbox);
+		this.PackStart(hbox, true, true, 0);
 	}
 
 	///<summary>Force a complete redraw of the view</summary>
@@ -158,64 +135,39 @@ public class DataViewDisplay : Gtk.VBox {
 		drawingArea.QueueDraw();
 	}
 
-	///<summary>
-	/// Find the number of bytes per row in order
-	/// to best utilize the available space and
-	/// keep all areas synchronized.
-	///</summary>
 	private int FindBestBpr(int width)
 	{
-		int n = 1; // current bpr
-		int bestBpr = -1; // best bpr so far
-		int swBest = 0; // width of best bpr so far
-
-		// try all values for n, from 0 upwards,
-		// until the width for a given n exceeds
-		// the available or the fixed bpr of an
-		// area is exceeded
+		int n       = 1;
+		int bestBpr = -1;
+		int swBest  = 0;
+
 		while (true) {
-			int sw = 0; // total width with current bpr
+			int sw             = 0;
 			bool breaksGrouping = false;
-			bool breaksFixed = false;
+			bool breaksFixed    = false;
 
-			foreach(Area a in layout.AreaGroup.Areas) {
+			foreach (Area a in layout.AreaGroup.Areas) {
 				int w = a.CalcWidth(n, false);
 
-				// if this number of bpr is not acceptable
 				if (w == -1) {
-					if (a.FixedBytesPerRow != -1 && n > a.FixedBytesPerRow )
+					if (a.FixedBytesPerRow != -1 && n > a.FixedBytesPerRow)
 						breaksFixed = true;
 					else
 						breaksGrouping = true;
 					break;
 				}
-
 				sw += w;
 			}
 
-			// If current bpr breaks a fixed size area
-			// stop searching and use the last bpr value
-			// that did't break it.
-			// If there isn't such an area, keep searching
 			if (breaksFixed && bestBpr != -1)
 				break;
 
-			// if current bpr breaks grouping, skip it
 			if (!breaksGrouping) {
-				bool shouldBreak = false;
-
-				// stop searching if available width is exceeded
-				// or last best width value equals current one
-				if (sw > width || sw == swBest)
-					shouldBreak = true;
-
-				// if we should break, but haven't found a suitable
-				// width yet, mark the current width as best so far
-				// even if it violates available width constraints.
-				if ((shouldBreak && bestBpr == -1) || (!shouldBreak)) {
-					// keep best bpr so far
+				bool shouldBreak = (sw > width || sw == swBest);
+
+				if ((shouldBreak && bestBpr == -1) || !shouldBreak) {
 					bestBpr = n;
-					swBest = sw;
+					swBest  = sw;
 				}
 
 				if (shouldBreak)
@@ -231,34 +183,28 @@ public class DataViewDisplay : Gtk.VBox {
 	///<summary>Benchmark the rendering</summary>
 	public void Benchmark()
 	{
-
 		System.DateTime t1;
 		System.DateTime t2;
-
 		int sum = 0;
 
-		Gdk.Window win = drawingArea.GdkWindow;
 		Gdk.Rectangle alloc = drawingArea.Allocation;
 		Gdk.Rectangle rect1 = new Gdk.Rectangle(0, 0, alloc.Width, alloc.Height);
 
 		for (int i = 0; i < 100; i++) {
 			t1 = System.DateTime.Now;
 
-			win.BeginPaintRect(rect1);
-
-			layout.AreaGroup.Render(true);
-
-			win.EndPaint();
+			drawingArea.Window.BeginPaintRect(rect1);
+			using (Cairo.Context cr = Gdk.CairoHelper.Create(drawingArea.Window)) {
+				layout.AreaGroup.Render(true, cr);
+			}
+			drawingArea.Window.EndPaint();
 
 			t2 = System.DateTime.Now;
-
 			sum += (t2 - t1).Milliseconds;
 		}
 
-
 		Gdk.Rectangle rect = drawingArea.Allocation;
 		Console.WriteLine("100 render screen ({0},{1}): {2} ms", rect.Width, rect.Height, sum / 100);
-
 	}
 
 	private void SetupScrollbarRange()
@@ -266,105 +212,78 @@ public class DataViewDisplay : Gtk.VBox {
 		if (layout.AreaGroup.Areas.Count <= 0)
 			return;
 
-		long bpr = ((Area)layout.AreaGroup.Areas[0]).BytesPerRow;
-		long nrows = ((dataView.Buffer.Size + 1) / bpr); // +1 because of append cursor position
+		long bpr  = ((Area)layout.AreaGroup.Areas[0]).BytesPerRow;
+		long nrows = ((dataView.Buffer.Size + 1) / bpr);
 
 		if (nrows < vscroll.Adjustment.PageSize) {
 			vscroll.Value = 0;
-			// set adjustment manually instead of using SetRange
-			// because gtk+ complains if low==high in SetRange()
 			vscroll.Adjustment.Lower = 0;
 			vscroll.Adjustment.Upper = nrows;
 			vscroll.Hide();
-		}
-		else if ((dataView.Buffer.Size + 1) % bpr == 0) {
+		} else if ((dataView.Buffer.Size + 1) % bpr == 0) {
 			vscroll.SetRange(0, nrows);
 			vscroll.Show();
-		}
-		else {
+		} else {
 			vscroll.SetRange(0, nrows + 1);
 			vscroll.Show();
 		}
-
 	}
 
-	///<summary>Handles window resizing</summary>
 	private void Resize(int winWidth, int winHeight)
 	{
-		// find bytes per row...
 		int bpr = FindBestBpr(winWidth);
 
-		// Ensure our offset is always aligned with bpr
 		if (bpr > 0)
 			layout.AreaGroup.Offset = (layout.AreaGroup.Offset / bpr) * bpr;
 
-		// configure areas
-		int s = 0;
+		int s          = 0;
 		int fontHeight = winHeight;
-		foreach(Area a in layout.AreaGroup.Areas) {
-			a.Height = winHeight;
-			a.Width = a.CalcWidth(bpr, true);
-			a.X = s;
+
+		foreach (Area a in layout.AreaGroup.Areas) {
+			a.Height      = winHeight;
+			a.Width       = a.CalcWidth(bpr, true);
+			a.X           = s;
 			a.BytesPerRow = bpr;
 			s += a.Width;
-			if (a.Drawer.Height < fontHeight) {
+			if (a.Drawer.Height < fontHeight)
 				fontHeight = a.Drawer.Height;
-			}
 		}
 
-		// configure scrollbar
 		vscroll.Adjustment.PageSize = (winHeight / fontHeight);
 		vscroll.SetIncrements(3, vscroll.Adjustment.PageSize - 1);
 
-		// decide whether the scrollbar is visible
-		// and its range
-		if (bpr == 0) {
-			// this can cause eternal loop!
-			// because hiding the scrollbar changes the
-			// area and causes a reconfigure which may
-			// show it again, and so on
-			//vscroll.Hide();
-		}
-		else
+		if (bpr != 0)
 			SetupScrollbarRange();
-			
+
 		layout.AreaGroup.Invalidate();
 	}
 
-	///<summary>Handle the Configure Event</summary>
-	void OnConfigured (object o, ConfigureEventArgs args)
+	void OnConfigured(object o, ConfigureEventArgs args)
 	{
 		if (widgetRealized == false)
 			return;
-		
-		Gdk.EventConfigure conf = args.Event;
 
+		Gdk.EventConfigure conf = args.Event;
 		Resize(conf.Width, conf.Height);
-
-		// make sure the current offset is visible
 		MakeOffsetVisible(dataView.Offset, ShowType.Start);
 	}
 
-	///<summary>Handle the Expose Event</summary>
-	void OnExposed (object o, ExposeEventArgs args)
+	///<summary>Handle the Drawn Event (GTK3 replacement for ExposeEvent)</summary>
+	void OnDrawn(object o, DrawnArgs args)
 	{
-		layout.AreaGroup.Render(true);
+		layout.AreaGroup.Render(true, args.Cr);
 	}
 
-	///<summary>Handle the Realized Event</summary>
-	void OnRealized (object o, EventArgs args)
+	void OnRealized(object o, EventArgs args)
 	{
-		// Create some default areas
 		layout.Realize(drawingArea);
 		widgetRealized = true;
 
-		// now we can configure properly
 		Gdk.Rectangle alloc = ((Widget)o).Allocation;
 		Resize(alloc.Width, alloc.Height);
 	}
 
-	///<summary>Handle scrolling</summary>
-	void OnScrolled (object o, EventArgs args)
+	void OnScrolled(object o, EventArgs args)
 	{
 		int bpr = 0;
 		if (layout.AreaGroup.Areas.Count > 0)
@@ -374,45 +293,31 @@ public class DataViewDisplay : Gtk.VBox {
 		layout.AreaGroup.Offset = offset;
 	}
 
-	///<summary>Scroll the view so that offset is visible</summary>
 	public void MakeOffsetVisible(long offset, ShowType type)
 	{
 		if (layout.AreaGroup.Areas.Count <= 0)
 			return;
 
-		int	bpr = ((Area)layout.AreaGroup.Areas[0]).BytesPerRow;
+		int bpr = ((Area)layout.AreaGroup.Areas[0]).BytesPerRow;
 		if (bpr == 0)
-			return ;
+			return;
 
-		long curOffset = layout.AreaGroup.Offset;
-		int h = ((Area)layout.AreaGroup.Areas[0]).Height;
-		Drawer font = ((Area)layout.AreaGroup.Areas[0]).Drawer;
-		int nrows = h / font.Height;
+		long curOffset    = layout.AreaGroup.Offset;
+		int h             = ((Area)layout.AreaGroup.Areas[0]).Height;
+		Drawer font       = ((Area)layout.AreaGroup.Areas[0]).Drawer;
+		int nrows         = h / font.Height;
 
-		long curOffsetRow = curOffset / bpr;
+		long curOffsetRow    = curOffset / bpr;
 		long curOffsetEndRow = curOffsetRow + nrows - 1;
-		long offsetRow = offset / bpr;
-
-		//System.Console.WriteLine("curOffRow: {0} curOffEndRow: {1} offRow: {2}",
-		//						curOffsetRow, curOffsetEndRow, offsetRow);
+		long offsetRow       = offset / bpr;
 
 		if (type == ShowType.Closest) {
-			// if already visible do nothing
-			//if (offsetRow >= curOffsetRow && offsetRow <= curOffsetEndRow)
-			//	;
 			if (curOffsetRow > offsetRow)
 				type = ShowType.Start;
 			else if (curOffsetEndRow < offsetRow)
 				type = ShowType.End;
 		}
 
-		// Make sure scrollbar range is updated.
-		// We need to call this here because
-		// a buffer change does not immediately
-		// update the range (eg callback goes through GLib.Idle)
-		// and a call to MakeOffsetVisible before
-		// the update will not behave correctly.
-		// eg see DataView.Paste()
 		SetupScrollbarRange();
 
 		if (type == ShowType.Cursor) {
@@ -421,7 +326,6 @@ public class DataViewDisplay : Gtk.VBox {
 
 			if (diff <= nrows && diff >= 0)
 				vscroll.Value = offsetRow - diff;
-			// else if diff is outside of a full screen range...
 			else if (diff > nrows)
 				type = ShowType.End;
 			else if (diff < 0)
@@ -430,8 +334,7 @@ public class DataViewDisplay : Gtk.VBox {
 
 		if (type == ShowType.Start) {
 			vscroll.Value = offsetRow;
-		}
-		else if (type == ShowType.End) {
+		} else if (type == ShowType.End) {
 			if (offsetRow - nrows >= 0)
 				vscroll.Value = offsetRow - nrows + 1;
 			else
@@ -439,10 +342,6 @@ public class DataViewDisplay : Gtk.VBox {
 		}
 	}
 
-	///<summary>
-	/// Show a warning that the file has been changed
-	/// outside of the respective DataView
-	///</summary>
 	public void ShowFileChangedBar()
 	{
 		if (fileChangedBar == null) {
@@ -457,8 +356,8 @@ public class DataViewDisplay : Gtk.VBox {
 	public void Cleanup()
 	{
 		layout.DisposePixmaps();
-		layout = null;
-		dataView = null;
+		layout    = null;
+		dataView  = null;
 		dvControl = null;
 	}
 
@@ -468,38 +367,36 @@ public class DataViewDisplay : Gtk.VBox {
 			drawingArea.GrabFocus();
 	}
 
-
-
 	private void ConnectToControl()
 	{
 		if (dvControl == null)
 			return;
 
-		drawingArea.ButtonPressEvent += dvControl.OnButtonPress;
+		drawingArea.ButtonPressEvent   += dvControl.OnButtonPress;
 		drawingArea.ButtonReleaseEvent += dvControl.OnButtonRelease;
-		drawingArea.MotionNotifyEvent += dvControl.OnMotionNotify;
-		drawingArea.KeyPressEvent += dvControl.OnKeyPress;
-		drawingArea.KeyReleaseEvent += dvControl.OnKeyRelease;
-		drawingArea.ScrollEvent += dvControl.OnMouseWheel;
-		drawingArea.FocusInEvent += dvControl.OnFocusInEvent;
-		drawingArea.FocusOutEvent += dvControl.OnFocusOutEvent;
+		drawingArea.MotionNotifyEvent  += dvControl.OnMotionNotify;
+		drawingArea.KeyPressEvent      += dvControl.OnKeyPress;
+		drawingArea.KeyReleaseEvent    += dvControl.OnKeyRelease;
+		drawingArea.ScrollEvent        += dvControl.OnMouseWheel;
+		drawingArea.FocusInEvent       += dvControl.OnFocusInEvent;
+		drawingArea.FocusOutEvent      += dvControl.OnFocusOutEvent;
 	}
 
 	private void DisconnectFromControl()
 	{
-		// disconnect previous control
 		if (dvControl == null)
 			return;
-		drawingArea.ButtonPressEvent -= dvControl.OnButtonPress;
+
+		drawingArea.ButtonPressEvent   -= dvControl.OnButtonPress;
 		drawingArea.ButtonReleaseEvent -= dvControl.OnButtonRelease;
-		drawingArea.MotionNotifyEvent -= dvControl.OnMotionNotify;
-		drawingArea.KeyPressEvent -= dvControl.OnKeyPress;
-		drawingArea.KeyReleaseEvent -= dvControl.OnKeyRelease;
-		drawingArea.ScrollEvent -= dvControl.OnMouseWheel;
-		drawingArea.FocusInEvent -= dvControl.OnFocusInEvent;
-		drawingArea.FocusOutEvent -= dvControl.OnFocusOutEvent;
+		drawingArea.MotionNotifyEvent  -= dvControl.OnMotionNotify;
+		drawingArea.KeyPressEvent      -= dvControl.OnKeyPress;
+		drawingArea.KeyReleaseEvent    -= dvControl.OnKeyRelease;
+		drawingArea.ScrollEvent        -= dvControl.OnMouseWheel;
+		drawingArea.FocusInEvent       -= dvControl.OnFocusInEvent;
+		drawingArea.FocusOutEvent      -= dvControl.OnFocusOutEvent;
 	}
 
-}// end DataView
+}// end DataViewDisplay
 
 }//namespace
diff --git a/src/gui/FileChangedBar.cs b/src/gui/FileChangedBar.cs
index 7da5d68..274df4e 100644
--- a/src/gui/FileChangedBar.cs
+++ b/src/gui/FileChangedBar.cs
@@ -31,17 +31,18 @@ namespace Bless.Gui
 /// A widget that notifies the user that the file has changed
 /// and prompts them to reload or ignore.
 ///</summary>
-public class FileChangedBar : Gtk.HBox
+public class FileChangedBar : Gtk.Box
 {
 	DataView dataView;
 
 	public FileChangedBar(DataView dv)
+		: base(Gtk.Orientation.Horizontal, 0)
 	{
 		dataView = dv;
 
 		this.BorderWidth = 3;
 
-		Gtk.Image img = new Gtk.Image(Gtk.Stock.DialogWarning, Gtk.IconSize.SmallToolbar);
+		Gtk.Image img = Gtk.Image.NewFromIconName("dialog-warning", Gtk.IconSize.SmallToolbar);
 
 		Gtk.Label label = new Gtk.Label(Catalog.GetString("This file has been changed on disk. You may choose to ignore the changes but reloading is the only safe option."));
 		label.LineWrap = true;
diff --git a/src/gui/MainWindow.cs b/src/gui/MainWindow.cs
index ae1c190..f01b5a0 100644
--- a/src/gui/MainWindow.cs
+++ b/src/gui/MainWindow.cs
@@ -159,7 +159,7 @@ public class BlessMain
 		dataBook.Removed += new RemovedHandler(OnDataViewRemoved);
 		dataBook.SwitchPage += new SwitchPageHandler(OnSwitchPage);
 
-		DataViewBox.PackStart(dataBook);
+		DataViewBox.PackStart(dataBook, true, true, 0);
 
 
 		// create the widget groups that hold utility widgets
diff --git a/src/gui/WidgetGroup.cs b/src/gui/WidgetGroup.cs
index 90a317b..917e4ba 100644
--- a/src/gui/WidgetGroup.cs
+++ b/src/gui/WidgetGroup.cs
@@ -23,10 +23,11 @@ using Gtk;
 namespace Bless.Gui
 {
 
-public class WidgetGroup : HBox
+public class WidgetGroup : Gtk.Box
 {
 
 	public WidgetGroup()
+		: base(Gtk.Orientation.Horizontal, 0)
 	{
 	}
 
diff --git a/src/gui/areas/Area.cs b/src/gui/areas/Area.cs
index 65f7758..6d820ff 100644
--- a/src/gui/areas/Area.cs
+++ b/src/gui/areas/Area.cs
@@ -1,4 +1,3 @@
-// created on 6/14/2004 at 10:39 PM
 /*
  *   Copyright (c) 2004, Alexandros Frantzis (alf82 [at] freemail [dot] gr)
  *
@@ -25,6 +24,7 @@ using Bless.Buffers;
 using Bless.Tools.Find;
 using System.Collections.Generic;
 using System.Xml;
+using Cairo;
 
 namespace Bless.Gui.Areas {
 
@@ -46,171 +46,51 @@ public abstract class Area
 	protected int bpr;
 	protected int dpb; // digits per byte
 	protected int fixedBpr;
-	protected Gdk.Drawable backPixmap;
-	protected bool manualDoubleBuffer;
+	// Cairo context used for all drawing (set before each render pass)
+	protected Cairo.Context backCr;
 	protected bool isAreaRealized;
 
-	// GC's
-	protected Gdk.GC cursorGC;
-	protected Gdk.GC activeCursorGC;
-	protected Gdk.GC inactiveCursorGC;
+	// Cursor colors (replaces Gdk.GC)
+	protected Gdk.Color activeCursorColor;
+	protected Gdk.Color inactiveCursorColor;
+	protected bool isActive;
 
-	
 	protected int cursorDigit;
 	protected bool cursorFocus;
 	protected bool canFocus;
-	
+
 	public enum RenderMergeFlags {None = 0, Left = 1, Right = 2}
+
 	// Abstract methods
-	
-	/// <summary>
-	/// Render (a part of) a row normally (without highlighting)
-	/// </summary>
-	/// <param name="i">
-	/// The row to render.
-	/// </param>
-	/// <param name="p">
-	/// The offset of the byte in the row to start rendering.
-	/// </param>
-	/// <param name="n">
-	/// The number of bytes to render.
-	/// </param>
-	/// <param name="blank">
-	/// Whether to blank the background before rendering.
-	/// </param>
 	abstract protected void RenderRowNormal(int i, int p, int n, bool blank);
-	
-	/// <summary>
-	/// Render (a part of) a row with highlighting.
-	/// </summary>
-	/// <param name="i">
-	/// The row to render.
-	/// </param>
-	/// <param name="p">
-	/// The offset of the byte in the row to start rendering.
-	/// </param>
-	/// <param name="n">
-	/// The number of bytes to render.
-	/// </param>
-	/// <param name="blank">
-	/// Whether to blank the background before rendering.
-	/// </param>
 	abstract protected void RenderRowHighlight(int i, int p, int n, bool blank, Drawer.HighlightType ht);
-
-	/// <summary>
-	/// Get info about where a specified buffer offset is currently displayed.
-	/// </summary>
-	/// <param name="off">
-	/// The offset to query.
-	/// </param>
-	/// <param name="orow">
-	/// The row the offset is displayed in.
-	/// </param>
-	/// <param name="obyte">
-	/// The byte in the row the offset is displayed on.
-	/// </param>
-	/// <param name="ox">
-	/// The X coordinate of the displayed position.
-	/// </param>
-	/// <param name="oy">
-	/// The Y coordinate of the displayed position.
-	/// </param>
 	abstract public void GetDisplayInfoByOffset(long off, out int orow, out int obyte, out int ox, out int oy);
 
-	/// <summary>
-	/// Flags containing extra info about positions in the view. 
-	/// </summary>
 	public enum GetOffsetFlags {
-		/// <summary>Position is beyond the end of file</summary>
-		Eof = 1,
-		/// <summary>Position is between bytes (in the so-called abyss)</summary>
+		Eof   = 1,
 		Abyss = 2
 	}
-	
-	/// <summary>
-	/// Gets the offset in the buffer that is displayed at specified location in the area
-	/// </summary>
-	/// <param name="x">
-	/// The X coordinate of the queried location.
-	/// </param>
-	/// <param name="y">
-	/// The Y coordinate of the queried location.
-	/// </param>
-	/// <param name="digit">
-	/// The digit of the byte at the specified location.
-	/// </param>
-	/// <param name="rflags">
-	/// Some flags with additional info about the location (<see cref="GetOffsetFlags"/>).
-	/// </param>
-	/// <returns>
-	/// The offset of the byte at the specified location.
-	/// </returns>
+
 	abstract public long GetOffsetByDisplayInfo(int x, int y, out int digit, out GetOffsetFlags rflags);
 
-	/// <summary>
-	/// Special key handler for the area. 
-	/// </summary>
-	/// <param name="key">
-	/// The key that was pressed.
-	/// </param>
-	/// <param name="overwrite">
-	/// Whether we are in overwrite mode.
-	/// </param>
-	/// <returns>
-	/// Whether the key was actually handled.
-	/// </returns>
 	virtual public bool HandleKey(Gdk.Key key, bool overwrite)
 	{
 		return false;
 	}
 
-	///<summary>
-	/// Calculates the width in pixels the
-	/// area will occupy with n bytes per row.
-	///</summary>
 	abstract public int CalcWidth(int n, bool force);
 
-	/// <summary>
-	/// A delegate that creates instances of area types.
-	/// </summary>
 	public delegate Area AreaCreatorFunc(AreaGroup ag);
-	
-	/// <summary>
-	/// A dictionary to hold area type names and creation functions
-	/// </summary>
+
 	static private Dictionary<string, AreaCreatorFunc> pluginTable;
-	
-	/// <summary>
-	/// Adds a new area type to the factory.
-	/// </summary>
-	/// <param name="name">
-	/// The name of the area type
-	/// </param>
-	/// <param name="createArea">
-	/// The delegate to call to create an instance of this area type.
-	/// </param>
-	/// <remarks>This is used by plugins to register new area types.</remarks>
+
 	static public void AddFactoryItem(string name, AreaCreatorFunc createArea)
 	{
-		if (pluginTable == null) {
+		if (pluginTable == null)
 			pluginTable = new Dictionary<string, AreaCreatorFunc>();
-		}
-		// System.Console.WriteLine("Adding plugin name {0}", name);
 		pluginTable.Add(name, createArea);
 	}
 
-	/// <summary>
-	/// Factory method to create instances of area types by name.
-	/// </summary>
-	/// <param name="name">
-	/// The name of the type of the area to create.
-	/// </param>
-	/// <param name="ag">
-	/// The <see cref="AreaGroup"/> this area will belong in.
-	/// </param>
-	/// <returns>
-	/// The created area.
-	/// </returns>
 	static public Area Factory(string name, AreaGroup ag)
 	{
 		try {
@@ -220,40 +100,23 @@ public abstract class Area
 		catch (KeyNotFoundException e) {
 			System.Console.WriteLine(e.Message);
 		}
-
 		return null;
 	}
 
-	
-	/// <summary>
-	/// Create an area.
-	/// </summary>
-	/// <param name="areaGroup">
-	/// The <see cref="AreaGroup"/> this area will belong in.
-	/// </param>
 	public Area(AreaGroup areaGroup)
 	{
 		this.areaGroup = areaGroup;
-		
 		drawerInformation = new Drawer.Information();
-
-		canFocus = false;
-		dpb = 0;
-		fixedBpr = -1;
+		canFocus  = false;
+		dpb       = 0;
+		fixedBpr  = -1;
 		isAreaRealized = false;
 	}
 
-	/// <summary>
-	/// Configure an area using an xml configuration.
-	/// </summary>
-	/// <param name="parentNode">
-	/// The <see cref="XmlNode"/> that holds the configuration for this area.
-	/// </param>
-	/// <remarks>This is overriden by inherited classes to accept extra options</remarks>
 	public virtual void Configure(XmlNode parentNode)
 	{
 		XmlNodeList childNodes = parentNode.ChildNodes;
-		foreach(XmlNode node in childNodes) {
+		foreach (XmlNode node in childNodes) {
 			if (node.Name == "bpr")
 				this.FixedBytesPerRow = System.Convert.ToInt32(node.InnerText);
 			if (node.Name == "display")
@@ -261,11 +124,10 @@ public abstract class Area
 		}
 	}
 
-	///<summary>Parse the <display> tag in layout files</summary>
 	void ParseDisplay(XmlNode parentNode, Drawer.Information info)
 	{
 		XmlNodeList childNodes = parentNode.ChildNodes;
-		foreach(XmlNode node in childNodes) {
+		foreach (XmlNode node in childNodes) {
 			if (node.Name == "evenrow")
 				ParseDisplayRow(node, info, Drawer.RowType.Even);
 			else if (node.Name == "oddrow")
@@ -279,7 +141,7 @@ public abstract class Area
 	{
 		Drawer.Color fg, bg;
 		XmlNodeList childNodes = parentNode.ChildNodes;
-		foreach(XmlNode node in childNodes) {
+		foreach (XmlNode node in childNodes) {
 			ParseDisplayType(node, out fg, out bg);
 			if (node.Name == "evencolumn") {
 				if (bg != null)
@@ -308,140 +170,83 @@ public abstract class Area
 		}
 	}
 
-	///<summary>Parse a font type</summary>
 	void ParseDisplayType(XmlNode parentNode, out Drawer.Color fg, out Drawer.Color bg)
 	{
 		fg = null;
 		bg = null;
 		XmlNodeList childNodes = parentNode.ChildNodes;
-		foreach(XmlNode node in childNodes) {
+		foreach (XmlNode node in childNodes) {
 			Gdk.Color col = new Gdk.Color();
 			if (node.Name == "foreground") {
 				Gdk.Color.Parse(node.InnerText, ref col);
-				Gdk.Colormap.System.AllocColor(ref col, false, true);
+				// Gdk.Colormap.System.AllocColor removed in GTK3; not needed
 				fg = new Drawer.Color(col);
 			}
 			if (node.Name == "background") {
 				Gdk.Color.Parse(node.InnerText, ref col);
-				Gdk.Colormap.System.AllocColor(ref col, false, true);
 				bg = new Drawer.Color(col);
 			}
 		}
 	}
 
-	///<summary>
-	/// Realize the area.
-	///</summary>
-	public virtual void Realize()
+	/// <summary>Set the Cairo context used for all drawing in this area.</summary>
+	internal void SetCairoContext(Cairo.Context cr)
 	{
-		Gtk.DrawingArea da = areaGroup.DrawingArea;
-
-		backPixmap = da.GdkWindow;
-
-		activeCursorGC = new Gdk.GC(da.GdkWindow);
-		inactiveCursorGC = new Gdk.GC(da.GdkWindow);
-
-		Gdk.Color col = new Gdk.Color();
-
-
-		Gdk.Color.Parse("red", ref col);
-		activeCursorGC.RgbFgColor = col;
-		Gdk.Color.Parse("gray", ref col);
-		inactiveCursorGC.RgbFgColor = col;
-		cursorGC = activeCursorGC;
-
-		isAreaRealized = true;
-	}
-
-	// Properties
-	//
-	public int X {
-		set { x = value; }
-		get	{ return x; }
-	}
-
-	public int Y {
-		set { y = value; }
-		get	{ return y; }
-	}
-
-	public int Width {
-		set { width = value; }
-		get	{ return width; }
-	}
-
-	public int Height {
-		set { height = value; }
-		get	{ return height; }
+		backCr = cr;
 	}
 
-	public int BytesPerRow {
-		set { bpr = value; }
-		get	{ return bpr; }
+	/// <summary>Realize the area (called once the DrawingArea is mapped).</summary>
+	public virtual void Realize()
+	{
+		Gdk.Color.Parse("red",  ref activeCursorColor);
+		Gdk.Color.Parse("gray", ref inactiveCursorColor);
+		isActive        = true;
+		isAreaRealized  = true;
 	}
 
-	public int FixedBytesPerRow {
-		set { fixedBpr = value; }
-		get { return fixedBpr; }
-	}
+	// Properties
+	public int X      { set { x = value; }     get { return x; } }
+	public int Y      { set { y = value; }     get { return y; } }
+	public int Width  { set { width = value; } get { return width; } }
+	public int Height { set { height = value; } get { return height; } }
 
-	public int DigitsPerByte {
-		get	{ return dpb; }
-	}
+	public int BytesPerRow   { set { bpr = value; }      get { return bpr; } }
+	public int FixedBytesPerRow { set { fixedBpr = value; } get { return fixedBpr; } }
+	public int DigitsPerByte { get { return dpb; } }
 
 	public int CursorDigit {
 		get { return cursorDigit; }
-		set { if (value >= dpb) cursorDigit = dpb - 1; else cursorDigit = value; }
+		set { cursorDigit = (value >= dpb) ? dpb - 1 : value; }
 	}
-	
+
 	public bool HasCursorFocus {
 		set { cursorFocus = value; }
-		get { return cursorFocus;}
+		get { return cursorFocus; }
 	}
 
-	public bool CanFocus {
-		get { return canFocus;}
-	}
+	public bool CanFocus { get { return canFocus; } }
 
-	public Drawer.Information DrawerInformation
-	{
+	public Drawer.Information DrawerInformation {
 		get { return drawerInformation; }
 		set { drawerInformation = value; }
 	}
 
-	public virtual Drawer Drawer {
-		get { return drawer; }
-	}
+	public virtual Drawer Drawer { get { return drawer; } }
 
-	public string Type {
-		get { return type; }
-	}
+	public string Type { get { return type; } }
 
 	public bool IsActive {
-		set {
-			if (value == true)
-				cursorGC = activeCursorGC;
-			else
-				cursorGC = inactiveCursorGC;
-
-			// doesn't actually change cursor position
-			// just redraws it with correct color
-			//MoveCursor(cursorOffset, cursorDigit);
-		}
-
-		get { return cursorGC == activeCursorGC; }
+		set { isActive = value; }
+		get { return isActive; }
 	}
 
 	/// <summary>
-	/// This method is only called to draw extra stuff when doing a complete
-	/// redraw of the area
+	/// Called to draw extra (data-independent) content during a full redraw.
 	/// </summary>
-	internal protected virtual void RenderExtra()
+	protected internal virtual void RenderExtra()
 	{
-	
 	}
-	
-	
+
 	void RenderRangeHelper(Drawer.HighlightType ht, int rstart, int bstart, int len)
 	{
 		if (ht != Drawer.HighlightType.Normal)
@@ -450,47 +255,37 @@ public abstract class Area
 			RenderRowNormal(rstart, bstart, len, false);
 	}
 
+	///<summary>Fill a rectangle with the given color using Cairo</summary>
+	protected void FillRect(Gdk.Color color, int rx, int ry, int rw, int rh)
+	{
+		Gdk.CairoHelper.SetSourceColor(backCr, color);
+		backCr.Rectangle(rx, ry, rw, rh);
+		backCr.Fill();
+	}
 
-	/// <summary>
-	/// Render the bytes in the highlight range.
-	/// </summary>
-	/// <param name="h">
-	/// A <see cref="Highlight"/>
-	/// </param>
-	/// <param name="merge">
-	/// Whether to visually merge the highlight with adjacent ones left and/or right.
-	/// </param>
-	/// <remarks>
-	/// This method doesn't check whether the merge flags are correct (eg there is indeed
-	/// a similar adjacent highlight). It just draws the highlight in such a way as 
-	/// to appear merged to any similar highlights if they exist.
-	///</remarks>
-	internal protected virtual void RenderHighlight(Highlight h, Drawer.HighlightType left, Drawer.HighlightType right)
+	protected internal virtual void RenderHighlight(Highlight h, Drawer.HighlightType left, Drawer.HighlightType right)
 	{
 		if (isAreaRealized == false)
 			return;
-		
+
 		int rstart, bstart, xstart, ystart;
 		int rend, bend, xend, yend;
 		bool odd;
-		Gdk.GC gc;
-		Gdk.GC oddGC;
-		Gdk.GC evenGC;
-		Gdk.GC leftGC;
-		Gdk.GC rightGC;
-		
-		oddGC = drawer.GetBackgroundGC(Drawer.RowType.Odd, h.Type);
-		evenGC = drawer.GetBackgroundGC(Drawer.RowType.Even, h.Type);
-		
+		Gdk.Color gc;
+		Gdk.Color oddColor;
+		Gdk.Color evenColor;
+		Gdk.Color leftColor;
+		Gdk.Color rightColor;
+
+		oddColor  = drawer.GetBackgroundColor(Drawer.RowType.Odd,  h.Type);
+		evenColor = drawer.GetBackgroundColor(Drawer.RowType.Even, h.Type);
 
 		GetDisplayInfoByOffset(h.Start, out rstart, out bstart, out xstart, out ystart);
-		GetDisplayInfoByOffset(h.End, out rend, out bend, out xend, out yend);
-		
-		//System.Console.WriteLine("Start {0:x} {1} {2} x:{3} y:{4}", h.Start, rstart, bstart, xstart, ystart);
-		//System.Console.WriteLine("End {0:x} {1} {2} x:{3} y:{4}", h.End, rend, bend, xend, yend);
+		GetDisplayInfoByOffset(h.End,   out rend,   out bend,   out xend,   out yend);
+
 		bool drawLeft = false;
 		int dxstart = xstart;
-		
+
 		if (bstart > 0) {
 			int digit;
 			GetOffsetFlags gof;
@@ -500,154 +295,110 @@ public abstract class Area
 				drawLeft = true;
 			}
 		}
-		
+
 		bool drawRight = false;
 		int dxend = xend;
-		
+
 		if (bend < bpr - 1) {
 			int digit;
 			GetOffsetFlags gof;
-			GetOffsetByDisplayInfo(xend + dpb*drawer.Width, yend, out digit, out gof);
+			GetOffsetByDisplayInfo(xend + dpb * drawer.Width, yend, out digit, out gof);
 			if ((gof & GetOffsetFlags.Abyss) != 0) {
 				dxend += drawer.Width;
 				drawRight = true;
 			}
 		}
-		
-		// if the whole range is on one row
+
+		// Single row
 		if (rstart == rend) {
-			if (areaGroup.ManualDoubleBuffer) {
-				BeginPaint(x + dxstart, y + ystart, dxend - dxstart + dpb*drawer.Width, drawer.Height);
-			}
-			// odd row?
 			odd = (((h.Start / bpr) % 2) == 1);
 			if (odd) {
-				gc = oddGC;
-				leftGC = drawer.GetBackgroundGC(Drawer.RowType.Odd, left);
-				rightGC = drawer.GetBackgroundGC(Drawer.RowType.Odd, right);
-			}
-			else {
-				gc = evenGC;
-				leftGC = drawer.GetBackgroundGC(Drawer.RowType.Even, left);
-				rightGC = drawer.GetBackgroundGC(Drawer.RowType.Even, right);
+				gc         = oddColor;
+				leftColor  = drawer.GetBackgroundColor(Drawer.RowType.Odd, left);
+				rightColor = drawer.GetBackgroundColor(Drawer.RowType.Odd, right);
+			} else {
+				gc         = evenColor;
+				leftColor  = drawer.GetBackgroundColor(Drawer.RowType.Even, left);
+				rightColor = drawer.GetBackgroundColor(Drawer.RowType.Even, right);
 			}
-			
-			//render
+
 			if (drawLeft)
-				backPixmap.DrawRectangle(leftGC, true, x + dxstart, y + ystart, drawer.Width, drawer.Height);
+				FillRect(leftColor, x + dxstart, y + ystart, drawer.Width, drawer.Height);
 			if (drawRight)
-				backPixmap.DrawRectangle(rightGC, true, x + xend + dpb*drawer.Width, y + yend, drawer.Width, drawer.Height);
-			
-			backPixmap.DrawRectangle(gc, true, x + xstart, y + ystart, xend - xstart + dpb*drawer.Width, drawer.Height);
+				FillRect(rightColor, x + xend + dpb * drawer.Width, y + yend, drawer.Width, drawer.Height);
 
+			FillRect(gc, x + xstart, y + ystart, xend - xstart + dpb * drawer.Width, drawer.Height);
 			RenderRangeHelper(h.Type, rstart, bstart, bend - bstart + 1);
 		}
-		else { // multi-row range
+		else {
+			// Multi-row range
 
-			if (areaGroup.ManualDoubleBuffer) {
-				// handle double-buffering
-				Gdk.Region paintRegion = new Gdk.Region();
-
-				Gdk.Rectangle rectStart = new Gdk.Rectangle(x + dxstart, y + ystart, width - dxstart, drawer.Height);
-
-				Gdk.Rectangle rectMiddle;
-				if (rend > rstart + 1)
-					rectMiddle = new Gdk.Rectangle(x, y + ystart + drawer.Height, width, yend - ystart - drawer.Height);
-				else
-					rectMiddle = Gdk.Rectangle.Zero;
-
-				Gdk.Rectangle rectEnd = new Gdk.Rectangle(x, y + yend, dxend + dpb*drawer.Width, drawer.Height);
-
-				paintRegion.UnionWithRect(rectStart);
-				paintRegion.UnionWithRect(rectMiddle);
-				paintRegion.UnionWithRect(rectEnd);
-
-				BeginPaintRegion(paintRegion);
-			}
-
-			// render first row
+			// Render first row
 			odd = (((h.Start / bpr) % 2) == 1);
 			if (odd) {
-				gc = oddGC;
-				leftGC = drawer.GetBackgroundGC(Drawer.RowType.Odd, left);
-				rightGC = drawer.GetBackgroundGC(Drawer.RowType.Odd, right);
-			}
-			else {
-				gc = evenGC;
-				leftGC = drawer.GetBackgroundGC(Drawer.RowType.Even, left);
-				rightGC = drawer.GetBackgroundGC(Drawer.RowType.Even, right);
+				gc         = oddColor;
+				leftColor  = drawer.GetBackgroundColor(Drawer.RowType.Odd, left);
+				rightColor = drawer.GetBackgroundColor(Drawer.RowType.Odd, right);
+			} else {
+				gc         = evenColor;
+				leftColor  = drawer.GetBackgroundColor(Drawer.RowType.Even, left);
+				rightColor = drawer.GetBackgroundColor(Drawer.RowType.Even, right);
 			}
-			
-			if (drawLeft)
-				backPixmap.DrawRectangle(leftGC, true, x + dxstart, y + ystart, drawer.Width, drawer.Height);
-			backPixmap.DrawRectangle(gc, true, x + xstart, y + ystart, width - xstart, drawer.Height);
 
+			if (drawLeft)
+				FillRect(leftColor, x + dxstart, y + ystart, drawer.Width, drawer.Height);
+			FillRect(gc, x + xstart, y + ystart, width - xstart, drawer.Height);
 			RenderRangeHelper(h.Type, rstart, bstart, bpr - bstart);
 
 			long curOffset = h.Start + bpr - bstart;
 
-			// render middle rows
-			for (int i = rstart + 1;i < rend;i++) {
+			// Middle rows
+			for (int i = rstart + 1; i < rend; i++) {
 				odd = (((curOffset / bpr) % 2) == 1);
-				if (odd)
-					gc = oddGC;
-				else
-					gc = evenGC;
-				backPixmap.DrawRectangle(gc, true, x, y + i*drawer.Height, width, drawer.Height);
+				gc  = odd ? oddColor : evenColor;
+				FillRect(gc, x, y + i * drawer.Height, width, drawer.Height);
 				RenderRangeHelper(h.Type, i, 0, bpr);
 				curOffset += bpr;
 			}
 
-			// render last row
+			// Last row
 			odd = (((h.End / bpr) % 2) == 1);
 			if (odd) {
-				gc = oddGC;
-				leftGC = drawer.GetBackgroundGC(Drawer.RowType.Odd, left);
-				rightGC = drawer.GetBackgroundGC(Drawer.RowType.Odd, right);
+				gc         = oddColor;
+				leftColor  = drawer.GetBackgroundColor(Drawer.RowType.Odd, left);
+				rightColor = drawer.GetBackgroundColor(Drawer.RowType.Odd, right);
+			} else {
+				gc         = evenColor;
+				leftColor  = drawer.GetBackgroundColor(Drawer.RowType.Even, left);
+				rightColor = drawer.GetBackgroundColor(Drawer.RowType.Even, right);
 			}
-			else {
-				gc = evenGC;
-				leftGC = drawer.GetBackgroundGC(Drawer.RowType.Even, left);
-				rightGC = drawer.GetBackgroundGC(Drawer.RowType.Even, right);
-			}
-			
+
 			if (drawRight)
-				backPixmap.DrawRectangle(rightGC, true, x + xend + dpb*drawer.Width, y + yend, drawer.Width, drawer.Height);
-			backPixmap.DrawRectangle(gc, true, x, y + yend, xend + dpb*drawer.Width, drawer.Height);
+				FillRect(rightColor, x + xend + dpb * drawer.Width, y + yend, drawer.Width, drawer.Height);
+			FillRect(gc, x, y + yend, xend + dpb * drawer.Width, drawer.Height);
 			RenderRangeHelper(h.Type, rend, 0, bend + 1);
 		}
-
-		if (areaGroup.ManualDoubleBuffer) {
-			EndPaint();
-		}
-
 	}
-	
-	/// <summary>
-	/// Blanks the selected offset
-	/// </summary>
-	/// <param name="offs">
-	/// A <see cref="System.Int64"/>
-	/// </param>
-	internal protected void BlankOffset(long offs)
+
+	/// <summary>Blank the background at the given offset position</summary>
+	protected internal void BlankOffset(long offs)
 	{
-		if (isAreaRealized == false) 
-			return; 
+		if (isAreaRealized == false)
+			return;
 
-		int nrows = height / drawer.Height; 
-		long bytesInView = nrows * bpr; 
+		int nrows = height / drawer.Height;
+		long bytesInView = nrows * bpr;
 
 		if (offs >= areaGroup.Offset && offs < areaGroup.Offset + bytesInView) {
-			int pcRow, pcByte, pcX, pcY; 
-			GetDisplayInfoByOffset(offs, out pcRow, out pcByte, out pcX, out pcY); 
-			Gdk.GC backEvenGC = drawer.GetBackgroundGC(Drawer.RowType.Even, Drawer.HighlightType.Normal); 
-			backPixmap.DrawRectangle(backEvenGC, true, x + pcX, y + pcY, drawer.Width*dpb, drawer.Height); 
-		} 
-	
+			int pcRow, pcByte, pcX, pcY;
+			GetDisplayInfoByOffset(offs, out pcRow, out pcByte, out pcX, out pcY);
+			Gdk.Color backEvenColor = drawer.GetBackgroundColor(Drawer.RowType.Even, Drawer.HighlightType.Normal);
+			FillRect(backEvenColor, x + pcX, y + pcY, drawer.Width * dpb, drawer.Height);
+		}
 	}
-	
-	///<summary>Render the cursor</summary>
-	internal protected void RenderCursor()
+
+	///<summary>Render the cursor indicator</summary>
+	protected internal void RenderCursor()
 	{
 		if (isAreaRealized == false)
 			return;
@@ -655,63 +406,39 @@ public abstract class Area
 		int cRow, cByte, cX, cY;
 		GetDisplayInfoByOffset(areaGroup.CursorOffset, out cRow, out cByte, out cX, out cY);
 
-		backPixmap.DrawRectangle(cursorGC, true, x + cX, y + cY + drawer.Height - 2, drawer.Width*dpb, 2);
+		Gdk.Color cursorColor = isActive ? activeCursorColor : inactiveCursorColor;
+
+		// Underline
+		FillRect(cursorColor, x + cX, y + cY + drawer.Height - 2, drawer.Width * dpb, 2);
+
 		if (cursorFocus) {
-			backPixmap.DrawRectangle(cursorGC, true, x + cX + cursorDigit*drawer.Width, y + cY, 1, drawer.Height - 2);
+			// Thin vertical line at current digit
+			FillRect(cursorColor, x + cX + cursorDigit * drawer.Width, y + cY, 1, drawer.Height - 2);
 		}
 	}
-	
-	/// <summary>
-	/// Dispose the (server side) pixmaps used by this area.
-	/// </summary>
+
+	/// <summary>Dispose cached Cairo surfaces used by the Drawer.</summary>
 	public void DisposePixmaps()
 	{
 		if (isAreaRealized == false)
 			return;
-
-		backPixmap.Dispose();
 		drawer.DisposePixmaps();
 	}
 
-	
-	void BeginPaintRegion(Gdk.Region r)
-	{
-		Gdk.Window win = areaGroup.DrawingArea.GdkWindow;
-
-		win.BeginPaintRegion(r);
-	}
-
-	void BeginPaint()
-	{
-		BeginPaint(this.x, this.y, this.width, this.height);
-	}
-
-	void BeginPaint(int x, int y, int w, int h)
-	{
-		Gdk.Window win = areaGroup.DrawingArea.GdkWindow;
-
-		win.BeginPaintRect(new Gdk.Rectangle(x, y, w, h));
-	}
-
-	void EndPaint()
-	{
-		areaGroup.DrawingArea.GdkWindow.EndPaint();
-	}
-
 	internal virtual void BlankBackground()
 	{
-		Gdk.GC backEvenGC = drawer.GetBackgroundGC(Drawer.RowType.Even, Drawer.HighlightType.Normal);
-		backPixmap.DrawRectangle(backEvenGC, true, x, y, width, height);
+		Gdk.Color backEvenColor = drawer.GetBackgroundColor(Drawer.RowType.Even, Drawer.HighlightType.Normal);
+		FillRect(backEvenColor, x, y, width, height);
 	}
-	
+
 	internal virtual void BlankEof()
 	{
 		int pcRow, pcByte, pcX, pcY;
 		GetDisplayInfoByOffset(areaGroup.Buffer.Size, out pcRow, out pcByte, out pcX, out pcY);
-		Gdk.GC backEvenGC = drawer.GetBackgroundGC(Drawer.RowType.Even, Drawer.HighlightType.Normal);
-		backPixmap.DrawRectangle(backEvenGC, true, x + pcX, y + pcY, drawer.Width*dpb, drawer.Height);
+		Gdk.Color backEvenColor = drawer.GetBackgroundColor(Drawer.RowType.Even, Drawer.HighlightType.Normal);
+		FillRect(backEvenColor, x + pcX, y + pcY, drawer.Width * dpb, drawer.Height);
 	}
-	
+
 	public virtual void ShowPopup(Gtk.UIManager uim)
 	{
 		Gtk.Widget popup = uim.GetWidget("/DefaultAreaPopup");
@@ -720,5 +447,4 @@ public abstract class Area
 
 }// Area
 
-
 } //namespace
diff --git a/src/gui/areas/AreaGroup.cs b/src/gui/areas/AreaGroup.cs
index 4a27190..196c671 100644
--- a/src/gui/areas/AreaGroup.cs
+++ b/src/gui/areas/AreaGroup.cs
@@ -1,4 +1,3 @@
-// Created on 12:43 AM 19/3/2008
 /*
  *   Copyright (c) 2008, Alexandros Frantzis (alf82 [at] freemail [dot] gr)
  *
@@ -24,96 +23,76 @@ using System.Collections.Generic;
 using Bless.Buffers;
 using Bless.Util;
 using Bless.Gui.Drawers;
+using Cairo;
 
 namespace Bless.Gui.Areas
 {
 
-/// <summary>
-/// An atomic highlight
-/// </summary>
+/// <summary>An atomic highlight</summary>
 class AtomicHighlight : Highlight
 {
 	IList<Highlight> containers;
-	
+
 	public IList<Highlight> Containers {
 		get { return containers; }
 	}
-	
-	/// <summary>
-	/// Adds a highlight as a container of this atomic highlight
-	/// </summary>
-	/// <remarks>The highlight is added only if it has lower or equal priority than this highlight</remarks>
+
 	public void AddContainer(Highlight h)
 	{
 		if (h.Type > type)
 			return;
-		
-		// insertion sort (higher priority first)
+
 		for (int i = 0; i < containers.Count; i++) {
 			if (h.Type >= containers[i].Type) {
 				containers.Insert(i, h);
 				return;
 			}
 		}
-		
 		containers.Add(h);
 	}
-	
-	/// <summary>
-	/// 
-	/// </summary>
+
 	public void GetAbyssHighlights(out Drawer.HighlightType left, out Drawer.HighlightType right)
-	{		
-		left = Drawer.HighlightType.Sentinel;
+	{
+		left  = Drawer.HighlightType.Sentinel;
 		right = Drawer.HighlightType.Sentinel;
 
-		foreach(Highlight h in containers) {
-			if (left == Drawer.HighlightType.Sentinel && h.Contains(start - 1))
-				left = h.Type;
-			
+		foreach (Highlight h in containers) {
+			if (left  == Drawer.HighlightType.Sentinel && h.Contains(start - 1))
+				left  = h.Type;
 			if (right == Drawer.HighlightType.Sentinel && h.Contains(end + 1))
 				right = h.Type;
 		}
-		
-		if (left == Drawer.HighlightType.Sentinel)
-			left = Drawer.HighlightType.Normal;
-		
-		if (right == Drawer.HighlightType.Sentinel)
-			right = Drawer.HighlightType.Normal;
-	}
-	
+
+		if (left  == Drawer.HighlightType.Sentinel) left  = Drawer.HighlightType.Normal;
+		if (right == Drawer.HighlightType.Sentinel) right = Drawer.HighlightType.Normal;
+	}
+
 	public AtomicHighlight(Highlight parent) : base(parent)
 	{
 		this.containers = new System.Collections.Generic.List<Highlight>(1);
-		this.containers.Add(parent);	
+		this.containers.Add(parent);
 	}
-	
+
 	public AtomicHighlight(AtomicHighlight h) : base(h)
 	{
 		this.containers = new System.Collections.Generic.List<Highlight>(h.containers);
 	}
-	
+
 	public override string ToString()
 	{
-		string str =  base.ToString() + " Containers: ";
-		
-		foreach(Highlight h in containers) {
+		string str = base.ToString() + " Containers: ";
+		foreach (Highlight h in containers)
 			str += h.ToString() + ", ";
-		}
-		
+
 		Drawer.HighlightType left, right;
-		
 		this.GetAbyssHighlights(out left, out right);
-		
 		str += string.Format("Left: {0} Right: {0}", left, right);
-		
 		return str;
 	}
 }
 
 /// <summary>
-/// A group of areas that display data from the same source
-/// and are synchronized.
+/// A group of areas that display data from the same source and are synchronized.
 /// </summary>
 public class AreaGroup
 {
@@ -121,597 +100,413 @@ public class AreaGroup
 	ByteBuffer byteBuffer;
 	Gtk.DrawingArea drawingArea;
 	Area focusedArea;
-	
+
 	IntervalTree<Highlight> highlights;
-	
-	enum Changes { Offset = 1, Cursor = 2, Highlights = 4}
-	
+
+	enum Changes { Offset = 1, Cursor = 2, Highlights = 4 }
+
 	Changes changes;
-	bool manualDoubleBuffer;
-	
-	// current offset of view in the buffer
-	long offset; 
-	
-	// current cursor
+
+	// Current offset of view in the buffer
+	long offset;
+
+	// Current cursor
 	long cursorOffset;
-	
-	// track changes
+
+	// Track changes
 	long prevCursorOffset;
-	
+
 	byte[] bufferCache;
-	
+
 	/// <value>
-	/// The previous atomic highlight ranges of the view.
-	/// These are non-overlapping ranges that describe the highlighting of the whole view
-	/// and can be used to render it quickly. They are also used to minimize
-	/// redrawing when possible (<see cref="AreaGroup.RenderHighlightDiffs"/>)
+	/// Previous atomic highlight ranges of the view (for efficient diff rendering).
 	/// </value>
 	IntervalTree<AtomicHighlight> prevAtomicHighlights;
-	
-	
+
 	Highlight selection;
-	
-	public IList<Area> Areas {
-		get { return areas; }
-	}
-	
+
+	public IList<Area> Areas { get { return areas; } }
+
 	public Area FocusedArea {
 		get { return focusedArea; }
 		set { UpdateFocusedArea(value); }
 	}
-	
+
 	public long Offset {
-		get { return offset;}
+		get { return offset; }
 		set {
 			if (offset == value)
 				return;
-			offset = value; 
+			offset = value;
 			SetChanged(Changes.Offset);
 		}
-		
 	}
 
-	public long CursorOffset {
-		get { return cursorOffset;}
-	}
-	
+	public long CursorOffset { get { return cursorOffset; } }
+
 	public int CursorDigit {
 		get {
-			if (focusedArea != null)
-				return focusedArea.CursorDigit;
-			else
-				return 0;
+			return (focusedArea != null) ? focusedArea.CursorDigit : 0;
 		}
 	}
-	
-	public long PrevCursorOffset {
-		get { return prevCursorOffset;}
-	}
-	
+
+	public long PrevCursorOffset { get { return prevCursorOffset; } }
+
 	public ByteBuffer Buffer {
 		get { return byteBuffer; }
-		set { byteBuffer = value; SetChanged(Changes.Offset);}
+		set { byteBuffer = value; SetChanged(Changes.Offset); }
 	}
-	
+
 	public Gtk.DrawingArea DrawingArea {
 		get { return drawingArea; }
 		set { drawingArea = value; }
 	}
-	
+
 	public Util.Range Selection {
 		get { return selection; }
-		set { 
+		set {
 			if (selection == value)
 				return;
 			highlights.Delete(selection);
 			selection.Start = value.Start; selection.End = value.End;
-			
-			// make sure the cursor is also updated (because it may 
-			// not have changed position so SetCursor() won't render it 
-			// but it may have to become visible again eg when a selection is cleared)
 			SetChanged(Changes.Highlights | Changes.Cursor);
 		}
 	}
-	
-	internal bool ManualDoubleBuffer {
-		get { return manualDoubleBuffer; }
-	}
-	
+
 	public void SetCursor(long coffset, int cdigit)
 	{
 		prevCursorOffset = cursorOffset;
-		
-		// if there is no change ignore...
+
 		if (cursorOffset == coffset && this.CursorDigit == cdigit)
 			return;
-		
+
 		cursorOffset = coffset;
-		foreach(Area a in areas)
+		foreach (Area a in areas)
 			a.CursorDigit = cdigit;
-		
+
 		SetChanged(Changes.Cursor);
 	}
-	
+
 	public byte GetCachedByte(long pos)
 	{
 		return bufferCache[pos - offset];
 	}
-	
+
 	public AreaGroup()
 	{
-		areas = new System.Collections.Generic.List<Area>();
-		highlights = new IntervalTree<Highlight>();
-		selection = new Highlight(Drawer.HighlightType.Selection);
+		areas                = new System.Collections.Generic.List<Area>();
+		highlights           = new IntervalTree<Highlight>();
+		selection            = new Highlight(Drawer.HighlightType.Selection);
 		prevAtomicHighlights = new IntervalTree<AtomicHighlight>();
-		bufferCache = new byte[0];
+		bufferCache          = new byte[0];
 	}
-	
-	
-	/// <summary>
-	/// Get the range of bytes and the number of rows that 
-	/// are displayed in the current view.
-	/// </summary>
+
+	/// <summary>Get the range of bytes and number of rows in the current view.</summary>
 	public Util.Range GetViewRange(out int nrows)
 	{
-		// find out number of rows, bytes in current view
-		
 		int minRows = int.MaxValue;
-		int minBpr = int.MaxValue;
+		int minBpr  = int.MaxValue;
 		foreach (Area a in areas) {
 			minRows = Math.Min(minRows, a.Height / a.Drawer.Height);
-			minBpr = Math.Min(minBpr, a.BytesPerRow);
+			minBpr  = Math.Min(minBpr,  a.BytesPerRow);
 		}
-		
+
 		nrows = minRows;
-		
 		long bleft = minRows * minBpr;
 
 		if (bleft + offset >= byteBuffer.Size)
 			bleft = byteBuffer.Size - offset;
-		
-		// make sure we get an empty clipping Range when bleft==0
-		if (bleft > 0)
-			return new Util.Range(offset, offset + bleft - 1);
-		else
-			return new Util.Range();
-	}
-	
-	/// <summary>
-	/// Whether a <see cref="Changes"/> has changed.
-	/// </summary>
-	private bool HasChanged(Changes c)
-	{
-		return ((changes & c) != 0);
-	}
-	
-	/// <summary>
-	/// Whether anything has changed.
-	/// </summary>
-	private bool HasAnythingChanged()
-	{
-		return changes != 0;
-	}
-	
-	/// <summary>
-	/// Clear all changes
-	/// </summary>
-	private void ClearChanges()
-	{
-		changes = 0;
+
+		return (bleft > 0)
+			? new Util.Range(offset, offset + bleft - 1)
+			: new Util.Range();
 	}
-	
-	/// <summary>
-	/// Set a  <see cref="Changes"/> as changed.
-	/// </summary>
-	/// <param name="c">
-	/// A <see cref="Changes"/>
-	/// </param>
-	///<remarks>This causes the group to be rendered again.</remarks>
+
+	private bool HasChanged(Changes c)      { return ((changes & c) != 0); }
+	private bool HasAnythingChanged()       { return changes != 0; }
+	private void ClearChanges()             { changes = 0; }
+
 	private void SetChanged(Changes c)
 	{
 		changes |= c;
-		
-			
+
 		Gtk.Application.Invoke(delegate {
-			if (drawingArea == null || drawingArea.GdkWindow == null)
+			if (drawingArea == null || drawingArea.Window == null)
 				return;
 
 			if (HasChanged(Changes.Offset)) {
 				Gdk.Rectangle view = drawingArea.Allocation;
-				view.X = 0;
-				view.Y = 0;
-				drawingArea.GdkWindow.BeginPaintRect(view);
-				Render(false);
-				drawingArea.GdkWindow.EndPaint();
+				view.X = 0; view.Y = 0;
+				drawingArea.Window.BeginPaintRect(view);
+				using (Cairo.Context cr = Gdk.CairoHelper.Create(drawingArea.Window)) {
+					Render(false, cr);
+				}
+				drawingArea.Window.EndPaint();
 			}
-			else 
+			else {
 				ExposeManually();
+			}
 		});
 	}
-	
-	/// <summary>
-	/// Render this group, manually handling the double buffering
-	/// </summary>
+
+	/// <summary>Manually trigger a render (cursor/highlight-only changes).</summary>
 	private void ExposeManually()
 	{
-		manualDoubleBuffer = true;
-		Render(false);
-		manualDoubleBuffer = false;
-	}
-	
-	/// <summary>
-	/// Invalidate this group (visually). This forces a complete redraw
-	/// on the next Render().
-	/// </summary>
-	public void Invalidate()
-	{
-		changes |= Changes.Offset;
-	}
-	
-	/// <summary>
-	/// Invalidate this group (visually). This forces a complete redraw
-	/// on the next Render().
-	/// </summary>
-	public void RedrawNow()
-	{
-		SetChanged(Changes.Offset);
+		if (drawingArea == null || drawingArea.Window == null)
+			return;
+		using (Cairo.Context cr = Gdk.CairoHelper.Create(drawingArea.Window)) {
+			Render(false, cr);
+		}
 	}
-	
+
+	public void Invalidate()   { changes |= Changes.Offset; }
+	public void RedrawNow()    { SetChanged(Changes.Offset); }
+
 	private void InitializeHighlights()
 	{
 		ClearHighlights();
 		if (!selection.IsEmpty())
 			highlights.Insert(selection);
 	}
-	
-	/// <summary>
-	/// Adds a highlight on a range of data.
-	/// </summary>
+
 	public void AddHighlight(long start, long end, Drawer.HighlightType ht)
 	{
 		highlights.Insert(new Highlight(start, end, ht));
 		changes |= Changes.Highlights;
 	}
-	
-	private void ClearHighlights()
-	{
-		highlights.Clear();
-	}
-	
+
+	private void ClearHighlights() { highlights.Clear(); }
+
 	private void SetupBufferCache()
 	{
 		int nrows;
 		Util.Range view = GetViewRange(out nrows);
 		if (view.Size != bufferCache.Length)
 			bufferCache = new byte[view.Size];
-		
-		for(int i = 0; i < view.Size; i++)
+
+		for (int i = 0; i < view.Size; i++)
 			bufferCache[i] = byteBuffer[view.Start + i];
 	}
-	
+
 	public void CycleFocus()
 	{
-		int faIndex; 
+		int faIndex;
 		for (faIndex = 0; faIndex < areas.Count; faIndex++)
 			if (focusedArea == areas[faIndex])
 				break;
-		
+
 		if (faIndex >= areas.Count)
 			faIndex = -1;
-		
+
 		int end = faIndex + areas.Count;
-		
-		// use < instead of != so this will work correctly
-		// even when faIndex = -1 in which case we should check
-		// all areas (instead of only the rest areas.Count - 1 
-		// areas when there is already a focused area)
+
 		for (faIndex++; faIndex < end; faIndex++) {
-			Area a = (areas[faIndex%areas.Count] as Area);
+			Area a = (areas[faIndex % areas.Count] as Area);
 			if (a.CanFocus == true) {
 				UpdateFocusedArea(a);
 				return;
 			}
 		}
-		
+
 		focusedArea = null;
 	}
-	
+
 	private void UpdateFocusedArea(Area fa)
 	{
 		focusedArea = fa;
-		
-		foreach(Area a in areas)
+
+		foreach (Area a in areas)
 			a.HasCursorFocus = false;
-		
+
 		focusedArea.HasCursorFocus = true;
-		
-		// set the previous cursor so that when
-		// the screen is rendered the byte under the
-		// cursor is properly cleared (before being drawn
-		// again)
 		prevCursorOffset = cursorOffset;
-		
 		SetChanged(Changes.Cursor);
 	}
-	
-	/// <summary>
-	/// Renders the extra (data independent) portions of the view 
-	/// </summary>
+
 	private void RenderExtra()
 	{
-		foreach(Area a in areas) {
+		foreach (Area a in areas)
 			a.RenderExtra();
-		}
 	}
-	/// <summary>
-	/// Renders a <see cref="Util.Range"/> of data using a specified <see cref="Drawer.HighlightType"/>
-	/// </summary>
+
 	private void RenderHighlight(AtomicHighlight h)
 	{
-		Drawer.HighlightType left;
-		Drawer.HighlightType right;
+		Drawer.HighlightType left, right;
 		h.GetAbyssHighlights(out left, out right);
-		
-		//System.Console.WriteLine("  Rendering {0}  ({1} {2})", h, left, right);
-		foreach(Area a in areas) {
+
+		foreach (Area a in areas)
 			a.RenderHighlight(h, left, right);
-		}
 	}
-	
-	/// <summary>
-	/// Blanks the view background
-	/// </summary>
+
 	private void BlankBackground()
 	{
-		foreach(Area a in areas) {
+		foreach (Area a in areas)
 			a.BlankBackground();
-		}
 	}
-	
+
 	private AtomicHighlight[] SplitAtomicPrioritized(AtomicHighlight q, Highlight r)
 	{
 		AtomicHighlight[] ha;
-		
+
 		if (q.Type > r.Type) {
-			ha = new AtomicHighlight[3]{new AtomicHighlight(r), new AtomicHighlight(q), new AtomicHighlight(r)};
+			ha = new AtomicHighlight[3] {
+				new AtomicHighlight(r), new AtomicHighlight(q), new AtomicHighlight(r)
+			};
 			Util.Range.SplitAtomic(ha, r, q);
 			ha[1].AddContainer(r);
-		}
-		else {
-			ha = new AtomicHighlight[3]{new AtomicHighlight(q), new AtomicHighlight(r), new AtomicHighlight(q)};
+		} else {
+			ha = new AtomicHighlight[3] {
+				new AtomicHighlight(q), new AtomicHighlight(r), new AtomicHighlight(q)
+			};
 			Util.Range.SplitAtomic(ha, q, r);
 			foreach (Highlight h in q.Containers)
 				ha[1].AddContainer(h);
 		}
-		
+
 		return ha;
 	}
-	
-	/// <summary>
-	/// Breaks down a base highlight and produces atomic highlights 
-	/// </summary>
+
 	private IntervalTree<AtomicHighlight> BreakDownHighlights(Highlight s, IList<Highlight> lst)
 	{
-		//System.Console.WriteLine("breaking down {0}", s);
 		IntervalTree<AtomicHighlight> it = new IntervalTree<AtomicHighlight>();
-		
+
 		if (!s.IsEmpty())
 			it.Insert(new AtomicHighlight(s));
-		
-		foreach(Highlight r in lst) {
-			//System.Console.WriteLine("  Processing {0}", r);
+
+		foreach (Highlight r in lst) {
 			IList<AtomicHighlight> overlaps = it.SearchOverlap(r);
-			foreach(AtomicHighlight q in overlaps) {
+			foreach (AtomicHighlight q in overlaps) {
 				it.Delete(q);
-				//System.Console.WriteLine("    Overlap {0}", q);
-				AtomicHighlight[] ha = SplitAtomicPrioritized(q, r);			
-				foreach(AtomicHighlight h in ha) {
-					// Keep only common parts to avoid duplications.
-					// This also has the useful side effect that everything
-					// is clipped inside s
+				AtomicHighlight[] ha = SplitAtomicPrioritized(q, r);
+				foreach (AtomicHighlight h in ha) {
 					h.Intersect(q);
-					//System.Console.WriteLine("      Atomic {0}", h);
-					if (!h.IsEmpty()) {
+					if (!h.IsEmpty())
 						it.Insert(h);
-					}
-				}	
+				}
 			}
 		}
-		
-		//foreach(AtomicHighlight ah in it.GetValues()) {
-		//	System.Console.WriteLine("  " + ah);
-		//}
-		
+
 		return it;
 	}
-		
-	
-	/// <summary>
-	/// Gets the atomic highlight ranges of the current view.
-	/// (Non-overlapping ranges that describe the highlighting of the whole view)
-	/// </summary>
+
 	private IntervalTree<AtomicHighlight> GetAtomicHighlights()
 	{
 		int nrows;
 		Util.Range clip = GetViewRange(out nrows);
-		Highlight view = new Highlight(clip, Drawer.HighlightType.Normal);
-		
-		// get all highlights in current view
+		Highlight view  = new Highlight(clip, Drawer.HighlightType.Normal);
+
 		IList<Highlight> viewableHighlights = highlights.SearchOverlap(view);
-		
 		return BreakDownHighlights(view, viewableHighlights);
 	}
-	
-	/// <summary>
-	/// Renders the area group based on the specified atomic highlights.
-	/// </summary>
+
 	private void RenderAtomicHighlights(IntervalTree<AtomicHighlight> atomicHighlights)
 	{
 		IList<AtomicHighlight> hl = atomicHighlights.GetValues();
-		
-		foreach(AtomicHighlight h in hl) {
+		foreach (AtomicHighlight h in hl)
 			RenderHighlight(h);
-		}
 	}
-	
-	/// <summary>
-	/// Render the whole view.
-	/// </summary>
-	/// <param name="atomicHighlights">
-	/// The current atomic highlight ranges
-	/// </param>
+
 	private void RenderAll(IntervalTree<AtomicHighlight> atomicHighlights)
 	{
 		SetupBufferCache();
-		
-		// blank the background
 		BlankBackground();
-		
 		RenderExtra();
-		
 		RenderAtomicHighlights(atomicHighlights);
-		
 		RenderCursor(atomicHighlights);
 	}
-	
-	/// <summary>
-	/// Render the new highlights taking into consideration the old highlights
-	/// (this means that only the differences are actually rendered)
-	/// </summary>
+
 	private void RenderHighlightDiffs(IntervalTree<AtomicHighlight> atomicHighlights)
 	{
-		//System.Console.WriteLine("Rendering highlight diffs");
 		IList<AtomicHighlight> hl = atomicHighlights.GetValues();
-		
-		foreach(AtomicHighlight h in hl) {
-			//System.Console.WriteLine("  Checking {0}", h);
+
+		foreach (AtomicHighlight h in hl) {
 			IList<AtomicHighlight> overlaps = prevAtomicHighlights.SearchOverlap(h);
-			foreach(AtomicHighlight overlap in overlaps) {
-				
+			foreach (AtomicHighlight overlap in overlaps) {
 				AtomicHighlight hTmp = new AtomicHighlight(h);
 				hTmp.Intersect(overlap);
 				AtomicHighlight oTmp = new AtomicHighlight(overlap);
 				oTmp.Intersect(h);
-				//System.Console.WriteLine("    Overlaps with {0}", oTmp);
-				
+
 				bool diffType = oTmp.Type != hTmp.Type;
-				
+
 				Drawer.HighlightType left, right, oleft, oright;
-								
-				hTmp.GetAbyssHighlights(out left, out right);
+				hTmp.GetAbyssHighlights(out left,  out right);
 				oTmp.GetAbyssHighlights(out oleft, out oright);
-				
+
 				bool diffAbyss = (left != oleft) || (right != oright);
-				
-				if (diffType || diffAbyss) {
-					//System.Console.Write(diffType?"      DiffType> ":"      DiffFlags> ");
-					//System.Console.WriteLine(hTmp);
+
+				if (diffType || diffAbyss)
 					RenderHighlight(hTmp);
-				}
 			}
 		}
 	}
-	
+
 	private void RenderCursor(IntervalTree<AtomicHighlight> atomicHighlights)
 	{
-		// find the kind of highlight the cursor was previously on
-		// if we don't find an overlap this means that either
-		// 1. the prev cursor position is not visible on the screen
-		// 2. the prev cursor position is at or beyond the end of the file
-		IList<AtomicHighlight> overlaps = atomicHighlights.SearchOverlap(new Util.Range(prevCursorOffset, prevCursorOffset));
-		
+		IList<AtomicHighlight> overlaps = atomicHighlights.SearchOverlap(
+			new Util.Range(prevCursorOffset, prevCursorOffset));
+
 		AtomicHighlight h = null;
-		
-		// if we find an overlap create a highlight
-		// to use to restore the prev position
+
 		if (overlaps.Count > 0) {
 			h = new AtomicHighlight(overlaps[0]);
 			h.Start = prevCursorOffset;
-			h.End = prevCursorOffset;
+			h.End   = prevCursorOffset;
 		}
-		
-		bool prevCursorBeyondEof =  prevCursorOffset >= byteBuffer.Size;
-		
-		if (h != null) {
+
+		bool prevCursorBeyondEof = (prevCursorOffset >= byteBuffer.Size);
+
+		if (h != null)
 			RenderHighlight(h);
-		}
-		else if (prevCursorBeyondEof) { // case 2
-			foreach(Area a in areas)
+		else if (prevCursorBeyondEof) {
+			foreach (Area a in areas)
 				a.BlankOffset(prevCursorOffset);
 		}
-		
+
 		if (selection.IsEmpty())
-			foreach(Area a in areas)
+			foreach (Area a in areas)
 				a.RenderCursor();
 	}
-	
+
 	/// <summary>
-	/// Render this area group.
+	/// Render this area group. Pass force=true to force a full redraw.
+	/// The Cairo context must be provided by the caller.
 	/// </summary>
-	/// <param name="force">
-	/// Whether to force a complete redraw of the group.
-	/// </param>
-	/// <remarks>
-	/// If force is false this method tries to redraw as little
-	/// as possible by drawing only the parts of the screen that
-	/// have changed (eg when changing the selection)
-	/// </remarks>
-	public void Render(bool force)
+	public void Render(bool force, Cairo.Context cr)
 	{
-		// sanity check
 		if (byteBuffer == null)
 			return;
-		
+
+		// Push Cairo context to all areas
+		foreach (Area a in areas)
+			a.SetCairoContext(cr);
+
 		InitializeHighlights();
-		
+
 		if (PreRenderEvent != null)
 			PreRenderEvent(this);
-		
-		/* This breaks the RenderExtra() optimizations in OffsetArea and SeparatorArea
-		
-		// if we are forced to redraw but nothing
-		// has changed, just redraw the previous atomic highlights
-		if (force && !HasAnythingChanged()) {
-			//System.Console.WriteLine("Not changed");
-			RenderAtomicHighlights(prevAtomicHighlights);
-			return;
-		}*/
-		
-		// get the current atomic highlights
+
 		IntervalTree<AtomicHighlight> atomicHighlights;
-		
-		// if atomic highlights have not changed, reuse them
+
 		if (!force && !HasChanged(Changes.Highlights) && !HasChanged(Changes.Offset))
-			atomicHighlights = prevAtomicHighlights; 
-		else {
-			//System.Console.WriteLine("Re-eval atomic highs");
+			atomicHighlights = prevAtomicHighlights;
+		else
 			atomicHighlights = GetAtomicHighlights();
-		}
-		
-		// if we are forced to redraw or the view has scrolled (the offset has changed)
-		// redraw everything
+
 		if (force || HasChanged(Changes.Offset)) {
-			//System.Console.WriteLine("Scroll");
 			RenderAll(atomicHighlights);
-		} // otherwise redraw only what is needed
-		else if (HasChanged(Changes.Highlights)) {
-			//System.Console.WriteLine("Diffs");
+		} else if (HasChanged(Changes.Highlights)) {
 			RenderHighlightDiffs(atomicHighlights);
 		}
-		
-		if (HasChanged(Changes.Cursor)) {
-			//System.Console.WriteLine("Cursor");
+
+		if (HasChanged(Changes.Cursor))
 			RenderCursor(atomicHighlights);
-		}
-		
-		// update prevAtomicHighlights
+
 		prevAtomicHighlights = atomicHighlights;
-		
 		ClearChanges();
 	}
-	
-	public delegate void PreRenderHandler(AreaGroup ag);
 
+	public delegate void PreRenderHandler(AreaGroup ag);
 	public event PreRenderHandler PreRenderEvent;
 }
 
diff --git a/src/gui/areas/AsciiArea.cs b/src/gui/areas/AsciiArea.cs
index bb4bd77..053d231 100644
--- a/src/gui/areas/AsciiArea.cs
+++ b/src/gui/areas/AsciiArea.cs
@@ -1,22 +1,6 @@
-// created on 6/15/2004 at 4:10 PM
 /*
  *   Copyright (c) 2004, Alexandros Frantzis (alf82 [at] freemail [dot] gr)
- *
- *   This file is part of Bless.
- *
- *   Bless is free software; you can redistribute it and/or modify
- *   it under the terms of the GNU General Public License as published by
- *   the Free Software Foundation; either version 2 of the License, or
- *   (at your option) any later version.
- *
- *   Bless is distributed in the hope that it will be useful,
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *   GNU General Public License for more details.
- *
- *   You should have received a copy of the GNU General Public License
- *   along with Bless; if not, write to the Free Software
- *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *   This file is part of Bless (GPL v2+).
  */
 using System;
 using Gtk;
@@ -30,7 +14,7 @@ public class AsciiAreaPlugin : AreaPlugin
 {
 	public AsciiAreaPlugin()
 	{
-		name = "ascii";
+		name   = "ascii";
 		author = "Alexandros Frantzis";
 	}
 
@@ -40,15 +24,14 @@ public class AsciiAreaPlugin : AreaPlugin
 	}
 }
 
-///<summary>An area that displays ascii</summary>
+///<summary>An area that displays ASCII</summary>
 public class AsciiArea : Area {
 
-
 	public AsciiArea(AreaGroup ag)
 			: base(ag)
 	{
-		type = "ascii";
-		dpb = 1;
+		type     = "ascii";
+		dpb      = 1;
 		canFocus = true;
 	}
 
@@ -58,39 +41,25 @@ public class AsciiArea : Area {
 		int ry = i * drawer.Height + y;
 		long roffset = areaGroup.Offset + i * bpr + p;
 		bool odd;
-		Gdk.GC backEvenGC = drawer.GetBackgroundGC(Drawer.RowType.Even, Drawer.HighlightType.Normal);
-		Gdk.GC backOddGC = drawer.GetBackgroundGC(Drawer.RowType.Odd, Drawer.HighlightType.Normal);
-
+		Gdk.Color backEvenColor = drawer.GetBackgroundColor(Drawer.RowType.Even, Drawer.HighlightType.Normal);
+		Gdk.Color backOddColor  = drawer.GetBackgroundColor(Drawer.RowType.Odd,  Drawer.HighlightType.Normal);
 
-		// odd row?
 		odd = (((roffset / bpr) % 2) == 1);
 
 		if (blank == true) {
-			if (odd)
-				backPixmap.DrawRectangle(backOddGC, true, rx, ry, width, drawer.Height);
-			else
-				backPixmap.DrawRectangle(backEvenGC, true, rx, ry, width, drawer.Height);
+			FillRect(odd ? backOddColor : backEvenColor, rx, ry, width, drawer.Height);
 		}
 
-		Drawer.RowType rowType;
-
-		if (odd)
-			rowType = Drawer.RowType.Odd;
-		else
-			rowType = Drawer.RowType.Even;
+		Drawer.RowType rowType = odd ? Drawer.RowType.Odd : Drawer.RowType.Even;
 
 		int pos = 0;
-
 		while (true) {
-
-			if (pos >= p) { //don't draw until we reach p
-				drawer.DrawNormal(backEvenGC, backPixmap, rx, ry, areaGroup.GetCachedByte(roffset++), rowType, Drawer.ColumnType.Even);
+			if (pos >= p) {
+				drawer.DrawNormal(backCr, rx, ry, areaGroup.GetCachedByte(roffset++), rowType, Drawer.ColumnType.Even);
 				if (--n <= 0)
 					break;
 			}
-
-			rx = rx + drawer.Width;
-
+			rx += drawer.Width;
 			pos++;
 		}
 	}
@@ -101,38 +70,25 @@ public class AsciiArea : Area {
 		int ry = i * drawer.Height + y;
 		long roffset = areaGroup.Offset + i * bpr + p;
 		bool odd;
-		Gdk.GC backEvenGC = drawer.GetBackgroundGC(Drawer.RowType.Even, Drawer.HighlightType.Normal);
-		Gdk.GC backOddGC = drawer.GetBackgroundGC(Drawer.RowType.Odd, Drawer.HighlightType.Normal);
+		Gdk.Color backEvenColor = drawer.GetBackgroundColor(Drawer.RowType.Even, Drawer.HighlightType.Normal);
+		Gdk.Color backOddColor  = drawer.GetBackgroundColor(Drawer.RowType.Odd,  Drawer.HighlightType.Normal);
 
-		// odd row?
 		odd = (((roffset / bpr) % 2) == 1);
 
 		if (blank == true) {
-			if (odd)
-				backPixmap.DrawRectangle(backOddGC, true, rx, ry, width, drawer.Height);
-			else
-				backPixmap.DrawRectangle(backEvenGC, true, rx, ry, width, drawer.Height);
+			FillRect(odd ? backOddColor : backEvenColor, rx, ry, width, drawer.Height);
 		}
 
-		Drawer.RowType rowType;
-
-		if (odd)
-			rowType = Drawer.RowType.Odd;
-		else
-			rowType = Drawer.RowType.Even;
+		Drawer.RowType rowType = odd ? Drawer.RowType.Odd : Drawer.RowType.Even;
 
 		int pos = 0;
-
 		while (true) {
-
-			if (pos >= p) { //don't draw until we reach p
-				drawer.DrawHighlight(backEvenGC, backPixmap, rx, ry, areaGroup.GetCachedByte(roffset++), rowType, ht);
+			if (pos >= p) {
+				drawer.DrawHighlight(backCr, rx, ry, areaGroup.GetCachedByte(roffset++), rowType, ht);
 				if (--n <= 0)
 					break;
 			}
-
-			rx = rx + drawer.Width;
-
+			rx += drawer.Width;
 			pos++;
 		}
 	}
@@ -141,18 +97,15 @@ public class AsciiArea : Area {
 	{
 		if (fixedBpr > 0 && n > fixedBpr && !force)
 			return -1;
-		else
-			return n*drawer.Width;
+		return n * drawer.Width;
 	}
 
 	public override void GetDisplayInfoByOffset(long off, out int orow, out int obyte, out int ox, out int oy)
 	{
-		orow = (int)((off - areaGroup.Offset) / bpr);
+		orow  = (int)((off - areaGroup.Offset) / bpr);
 		obyte = (int)((off - areaGroup.Offset) % bpr);
-
-		oy = orow * drawer.Height;
-
-		ox = obyte * drawer.Width;
+		oy    = orow * drawer.Height;
+		ox    = obyte * drawer.Width;
 	}
 
 	public override long GetOffsetByDisplayInfo(int x, int y, out int digit, out GetOffsetFlags flags)
@@ -166,32 +119,28 @@ public class AsciiArea : Area {
 			flags |= GetOffsetFlags.Eof;
 
 		digit = 0;
-
 		return off;
 	}
 
 	public override bool HandleKey(Gdk.Key key, bool overwrite)
 	{
-		//System.Console.WriteLine("Ascii: {0}", key);
 		byte[] ba = null;
 
 		if (key >= Gdk.Key.space && key <= Gdk.Key.asciitilde)
-			ba = new byte[]{(byte)key};
+			ba = new byte[] { (byte)key };
 		else if (key >= Gdk.Key.KP_0 && key <= Gdk.Key.KP_9)
-			ba = new byte[]{(byte)(key - Gdk.Key.KP_0 + Gdk.Key.Key_0)};
+			ba = new byte[] { (byte)(key - Gdk.Key.KP_0 + Gdk.Key.Key_0) };
 
 		if (ba != null) {
 			if (areaGroup.CursorOffset == areaGroup.Buffer.Size)
 				areaGroup.Buffer.Append(ba, 0, ba.LongLength);
 			else if (overwrite == true)
 				areaGroup.Buffer.Replace(areaGroup.CursorOffset, areaGroup.CursorOffset, ba);
-			else if (overwrite == false)
+			else
 				areaGroup.Buffer.Insert(areaGroup.CursorOffset, ba, 0, ba.LongLength);
-
 			return true;
 		}
-		else
-			return false;
+		return false;
 	}
 
 	public override void Realize()
@@ -203,5 +152,4 @@ public class AsciiArea : Area {
 
 }
 
-
 }//namespace
diff --git a/src/gui/areas/BinaryArea.cs b/src/gui/areas/BinaryArea.cs
index 8bcfe5a..4aadbcd 100644
--- a/src/gui/areas/BinaryArea.cs
+++ b/src/gui/areas/BinaryArea.cs
@@ -1,23 +1,8 @@
-// created on 6/24/2004 at 2:32 PM
 /*
  *   Copyright (c) 2004, Alexandros Frantzis (alf82 [at] freemail [dot] gr)
- *
- *   This file is part of Bless.
- *
- *   Bless is free software; you can redistribute it and/or modify
- *   it under the terms of the GNU General Public License as published by
- *   the Free Software Foundation; either version 2 of the License, or
- *   (at your option) any later version.
- *
- *   Bless is distributed in the hope that it will be useful,
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *   GNU General Public License for more details.
- *
- *   You should have received a copy of the GNU General Public License
- *   along with Bless; if not, write to the Free Software
- *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *   This file is part of Bless (GPL v2+).
  */
+using System.Xml;
 using Bless.Plugins;
 using Bless.Gui.Drawers;
 using Gtk;
@@ -28,7 +13,7 @@ public class BinaryAreaPlugin : AreaPlugin
 {
 	public BinaryAreaPlugin()
 	{
-		name = "binary";
+		name   = "binary";
 		author = "Alexandros Frantzis";
 	}
 
@@ -38,55 +23,17 @@ public class BinaryAreaPlugin : AreaPlugin
 	}
 }
 
-///<summary>An area that displays binary</summary>
+///<summary>An area that displays binary values</summary>
 public class BinaryArea : GroupedArea {
 
 	public BinaryArea(AreaGroup ag)
 			: base(ag)
 	{
 		type = "binary";
-		dpb = 8;
+		dpb  = 8;
 	}
 
-	public override bool HandleKey(Gdk.Key key, bool overwrite)
-	{
-		//System.Console.WriteLine("Binary: {0}", key);
-
-		if (key == Gdk.Key.Key_0 || key == Gdk.Key.Key_1 || key == Gdk.Key.KP_0 || key == Gdk.Key.KP_1) {
-			byte orig;
-
-			// if we are after the end of the buffer, assume
-			// a 0 byte
-			if (areaGroup.CursorOffset == areaGroup.Buffer.Size || (overwrite == false && areaGroup.CursorDigit == 0))
-				orig = 0;
-			else
-				orig = areaGroup.Buffer[areaGroup.CursorOffset];
-
-			byte repl;
-
-			if (key == Gdk.Key.Key_1 || key == Gdk.Key.KP_1 )
-				repl = (byte)((1 << (dpb - areaGroup.CursorDigit - 1)) | orig);
-			else
-				repl = (byte)((~(1 << (dpb - areaGroup.CursorDigit - 1))) & orig);
-
-			byte[] ba = new byte[]{repl};
-
-			if (areaGroup.CursorOffset == areaGroup.Buffer.Size)
-				areaGroup.Buffer.Append(ba, 0, ba.LongLength);
-			else if (overwrite == false && areaGroup.CursorDigit == 0)
-				areaGroup.Buffer.Insert(areaGroup.CursorOffset, ba, 0, ba.LongLength);
-			else /*(if (overwrite==true || cursorDigit > 0)*/
-				areaGroup.Buffer.Replace(areaGroup.CursorOffset, areaGroup.CursorOffset, ba);
-
-
-			return true;
-
-		}
-		else
-			return false;
-	}
-
-	public override void Realize ()
+	public override void Realize()
 	{
 		Gtk.DrawingArea da = areaGroup.DrawingArea;
 		drawer = new BinaryDrawer(da, drawerInformation);
diff --git a/src/gui/areas/DecimalArea.cs b/src/gui/areas/DecimalArea.cs
index 4f0e8b6..ebf501f 100644
--- a/src/gui/areas/DecimalArea.cs
+++ b/src/gui/areas/DecimalArea.cs
@@ -1,23 +1,8 @@
-// created on 7/1/2004 at 8:06 PM
 /*
  *   Copyright (c) 2004, Alexandros Frantzis (alf82 [at] freemail [dot] gr)
- *
- *   This file is part of Bless.
- *
- *   Bless is free software; you can redistribute it and/or modify
- *   it under the terms of the GNU General Public License as published by
- *   the Free Software Foundation; either version 2 of the License, or
- *   (at your option) any later version.
- *
- *   Bless is distributed in the hope that it will be useful,
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *   GNU General Public License for more details.
- *
- *   You should have received a copy of the GNU General Public License
- *   along with Bless; if not, write to the Free Software
- *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *   This file is part of Bless (GPL v2+).
  */
+using System.Xml;
 using Bless.Plugins;
 using Bless.Gui.Drawers;
 using Gtk;
@@ -28,7 +13,7 @@ public class DecimalAreaPlugin : AreaPlugin
 {
 	public DecimalAreaPlugin()
 	{
-		name = "decimal";
+		name   = "decimal";
 		author = "Alexandros Frantzis";
 	}
 
@@ -38,68 +23,17 @@ public class DecimalAreaPlugin : AreaPlugin
 	}
 }
 
-///<summary>An area that displays decimal</summary>
+///<summary>An area that displays decimal values</summary>
 public class DecimalArea : GroupedArea {
 
 	public DecimalArea(AreaGroup ag)
 			: base(ag)
 	{
 		type = "decimal";
-		dpb = 3;
+		dpb  = 3;
 	}
 
-	public override bool HandleKey(Gdk.Key key, bool overwrite)
-	{
-		//System.Console.WriteLine("Decimal: {0}", key);
-
-		if ((key >= Gdk.Key.Key_0 && key <= Gdk.Key.Key_9) || (key >= Gdk.Key.KP_0 && key <= Gdk.Key.KP_9)) {
-			byte b;
-			if (key >= Gdk.Key.Key_0 && key <= Gdk.Key.Key_9)
-				b = (byte)(key - Gdk.Key.Key_0);
-			else
-				b = (byte)(key - Gdk.Key.KP_0);
-
-			byte orig;
-
-			// if we are after the end of the buffer, assume
-			// a 0 byte
-			if (areaGroup.CursorOffset == areaGroup.Buffer.Size || (overwrite == false && areaGroup.CursorDigit == 0))
-				orig = 0;
-			else
-				orig = areaGroup.Buffer[areaGroup.CursorOffset];
-
-			byte orig1 = (byte)(orig % 10);
-			byte orig10 = (byte)((orig / 10) % 10);
-			byte orig100 = (byte)((orig / 100) % 10);
-
-			if (areaGroup.CursorDigit == 0)
-				orig100 = b;
-			else if (areaGroup.CursorDigit == 1)
-				orig10 = b;
-			else if (areaGroup.CursorDigit == 2)
-				orig1 = b;
-
-			int repl = orig100 * 100 + orig10 * 10 + orig1;
-			if (repl > 255)
-				return false;
-
-			byte[] ba = new byte[]{(byte)repl};
-
-			if (areaGroup.CursorOffset == areaGroup.Buffer.Size)
-				areaGroup.Buffer.Append(ba, 0, ba.LongLength);
-			else if (overwrite == false && areaGroup.CursorDigit == 0)
-				areaGroup.Buffer.Insert(areaGroup.CursorOffset, ba, 0, ba.LongLength);
-			else /*(if (overwrite==true || areaGroup.CursorDigit > 0)*/
-				areaGroup.Buffer.Replace(areaGroup.CursorOffset, areaGroup.CursorOffset, ba);
-
-
-			return true;
-
-		} else
-			return false;
-	}
-
-	public override void Realize ()
+	public override void Realize()
 	{
 		Gtk.DrawingArea da = areaGroup.DrawingArea;
 		drawer = new DecimalDrawer(da, drawerInformation);
diff --git a/src/gui/areas/GroupedArea.cs b/src/gui/areas/GroupedArea.cs
index f3933af..e843aa6 100644
--- a/src/gui/areas/GroupedArea.cs
+++ b/src/gui/areas/GroupedArea.cs
@@ -1,4 +1,3 @@
-// created on 7/16/2004 at 7:54 PM
 /*
  *   Copyright (c) 2004, Alexandros Frantzis (alf82 [at] freemail [dot] gr)
  *
@@ -38,11 +37,9 @@ abstract public class GroupedArea : Area {
 		canFocus = true;
 	}
 
-
 	public int Grouping {
-		set {  grouping = value; }
-		get {  return grouping; }
-
+		set { grouping = value; }
+		get { return grouping; }
 	}
 
 	protected override void RenderRowNormal(int i, int p, int n, bool blank)
@@ -51,48 +48,27 @@ abstract public class GroupedArea : Area {
 		int ry = i * drawer.Height + y;
 		long roffset = areaGroup.Offset + i * bpr + p;
 		bool odd;
-		Gdk.GC backEvenGC = drawer.GetBackgroundGC(Drawer.RowType.Even, Drawer.HighlightType.Normal);
-		Gdk.GC backOddGC = drawer.GetBackgroundGC(Drawer.RowType.Odd, Drawer.HighlightType.Normal);
+		Gdk.Color backEvenColor = drawer.GetBackgroundColor(Drawer.RowType.Even, Drawer.HighlightType.Normal);
+		Gdk.Color backOddColor  = drawer.GetBackgroundColor(Drawer.RowType.Odd,  Drawer.HighlightType.Normal);
 
-		// odd row?
 		odd = (((roffset / bpr) % 2) == 1);
 
 		if (blank == true) {
-			if (odd)
-				backPixmap.DrawRectangle(backOddGC, true, rx, ry, width, drawer.Height);
-			else
-				backPixmap.DrawRectangle(backEvenGC, true, rx, ry, width, drawer.Height);
+			FillRect(odd ? backOddColor : backEvenColor, rx, ry, width, drawer.Height);
 		}
 
 		Drawer.ColumnType colType;
-		Drawer.RowType rowType;
-
-		if (odd)
-			rowType = Drawer.RowType.Odd;
-		else
-			rowType = Drawer.RowType.Even;
+		Drawer.RowType rowType = odd ? Drawer.RowType.Odd : Drawer.RowType.Even;
 
 		int pos = 0;
-		// draw bytes
 		while (true) {
-
-			if (pos >= p) { //don't draw until we reach p
-				if ((pos / grouping) % 2 == 0)
-					colType = Drawer.ColumnType.Even;
-				else
-					colType = Drawer.ColumnType.Odd;
-
-				drawer.DrawNormal(backEvenGC, backPixmap, rx, ry, areaGroup.GetCachedByte(roffset++), rowType, colType);
+			if (pos >= p) {
+				colType = ((pos / grouping) % 2 == 0) ? Drawer.ColumnType.Even : Drawer.ColumnType.Odd;
+				drawer.DrawNormal(backCr, rx, ry, areaGroup.GetCachedByte(roffset++), rowType, colType);
 				if (--n <= 0)
 					break;
 			}
-
-			// space if necessary
-			if (pos % grouping == grouping - 1)
-				rx = rx + (dpb + 1) * drawer.Width;
-			else
-				rx = rx + dpb * drawer.Width;
-
+			rx += (pos % grouping == grouping - 1) ? (dpb + 1) * drawer.Width : dpb * drawer.Width;
 			pos++;
 		}
 	}
@@ -103,69 +79,47 @@ abstract public class GroupedArea : Area {
 		int ry = i * drawer.Height + y;
 		long roffset = areaGroup.Offset + i * bpr + p;
 		bool odd;
-		Gdk.GC backEvenGC = drawer.GetBackgroundGC(Drawer.RowType.Even, Drawer.HighlightType.Normal);
-		Gdk.GC backOddGC = drawer.GetBackgroundGC(Drawer.RowType.Odd, Drawer.HighlightType.Normal);
+		Gdk.Color backEvenColor = drawer.GetBackgroundColor(Drawer.RowType.Even, Drawer.HighlightType.Normal);
+		Gdk.Color backOddColor  = drawer.GetBackgroundColor(Drawer.RowType.Odd,  Drawer.HighlightType.Normal);
 
-		// odd row?
 		odd = (((roffset / bpr) % 2) == 1);
 
 		if (blank == true) {
-			if (odd)
-				backPixmap.DrawRectangle(backOddGC, true, rx, ry, width, drawer.Height);
-			else
-				backPixmap.DrawRectangle(backEvenGC, true, rx, ry, width, drawer.Height);
+			FillRect(odd ? backOddColor : backEvenColor, rx, ry, width, drawer.Height);
 		}
 
-		Drawer.RowType rowType;
-
-		if (odd)
-			rowType = Drawer.RowType.Odd;
-		else
-			rowType = Drawer.RowType.Even;
+		Drawer.RowType rowType = odd ? Drawer.RowType.Odd : Drawer.RowType.Even;
 
 		int pos = 0;
-		// draw bytes
 		while (true) {
-
-			if (pos >= p) { //don't draw until we reach p
-				drawer.DrawHighlight(backEvenGC, backPixmap, rx, ry, areaGroup.GetCachedByte(roffset++), rowType, ht);
+			if (pos >= p) {
+				drawer.DrawHighlight(backCr, rx, ry, areaGroup.GetCachedByte(roffset++), rowType, ht);
 				if (--n <= 0)
 					break;
 			}
-
-			// space if necessary
-			if (pos % grouping == grouping - 1)
-				rx = rx + (dpb + 1) * drawer.Width;
-			else
-				rx = rx + dpb * drawer.Width;
-
+			rx += (pos % grouping == grouping - 1) ? (dpb + 1) * drawer.Width : dpb * drawer.Width;
 			pos++;
 		}
 	}
 
 	public override int CalcWidth(int n, bool force)
 	{
-		if (n == 0)
-			return 0;
-		if (fixedBpr > 0 && n > fixedBpr && !force) // must adhere to fixed length
-			return -1;
-		if (n % grouping != 0 && !force) // can't break the grouping
-			return -1;
-
-		int ngroups = n / grouping;
-		int groupWidth = grouping * dpb * drawer.Width;
+		if (n == 0) return 0;
+		if (fixedBpr > 0 && n > fixedBpr && !force) return -1;
+		if (n % grouping != 0 && !force)              return -1;
 
-		return ngroups*groupWidth + (ngroups - 1)*drawer.Width;
+		int ngroups   = n / grouping;
+		int groupWidth = grouping * dpb * drawer.Width;
+		return ngroups * groupWidth + (ngroups - 1) * drawer.Width;
 	}
 
 	public override void GetDisplayInfoByOffset(long off, out int orow, out int obyte, out int ox, out int oy)
 	{
-		orow = (int)((off - areaGroup.Offset) / bpr);
+		orow  = (int)((off - areaGroup.Offset) / bpr);
 		obyte = (int)((off - areaGroup.Offset) % bpr);
+		oy    = orow * drawer.Height;
 
-		oy = orow * drawer.Height;
-
-		int group = obyte / grouping;
+		int group       = obyte / grouping;
 		int groupOffset = obyte % grouping;
 		ox = group * (grouping * dpb * drawer.Width + drawer.Width) + dpb * drawer.Width * groupOffset;
 	}
@@ -175,8 +129,8 @@ abstract public class GroupedArea : Area {
 		flags = 0;
 		int groupWidth = (grouping * dpb * drawer.Width + drawer.Width);
 
-		int row = y / drawer.Height;
-		int group = x / groupWidth;
+		int row       = y / drawer.Height;
+		int group     = x / groupWidth;
 		int groupByte = (x - group * groupWidth) / (dpb * drawer.Width);
 
 		digit = (x - group * groupWidth - groupByte * dpb * drawer.Width) / drawer.Width;
@@ -191,7 +145,6 @@ abstract public class GroupedArea : Area {
 			flags |= GetOffsetFlags.Eof;
 
 		return off;
-
 	}
 
 	public override void Configure(XmlNode parentNode)
@@ -199,7 +152,7 @@ abstract public class GroupedArea : Area {
 		base.Configure(parentNode);
 
 		XmlNodeList childNodes = parentNode.ChildNodes;
-		foreach(XmlNode node in childNodes) {
+		foreach (XmlNode node in childNodes) {
 			if (node.Name == "grouping")
 				this.Grouping = Convert.ToInt32(node.InnerText);
 		}
@@ -207,4 +160,4 @@ abstract public class GroupedArea : Area {
 
 }// end GroupedArea
 
-}//end namespace
\ No newline at end of file
+}//end namespace
diff --git a/src/gui/areas/HexArea.cs b/src/gui/areas/HexArea.cs
index 6d6c9d3..d64d456 100644
--- a/src/gui/areas/HexArea.cs
+++ b/src/gui/areas/HexArea.cs
@@ -1,22 +1,6 @@
-// created on 6/15/2004 at 4:10 PM
 /*
  *   Copyright (c) 2004, Alexandros Frantzis (alf82 [at] freemail [dot] gr)
- *
- *   This file is part of Bless.
- *
- *   Bless is free software; you can redistribute it and/or modify
- *   it under the terms of the GNU General Public License as published by
- *   the Free Software Foundation; either version 2 of the License, or
- *   (at your option) any later version.
- *
- *   Bless is distributed in the hope that it will be useful,
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *   GNU General Public License for more details.
- *
- *   You should have received a copy of the GNU General Public License
- *   along with Bless; if not, write to the Free Software
- *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *   This file is part of Bless (GPL v2+).
  */
 using System.Xml;
 using Bless.Plugins;
@@ -29,7 +13,7 @@ public class HexAreaPlugin : AreaPlugin
 {
 	public HexAreaPlugin()
 	{
-		name = "hexadecimal";
+		name   = "hexadecimal";
 		author = "Alexandros Frantzis";
 	}
 
@@ -38,29 +22,24 @@ public class HexAreaPlugin : AreaPlugin
 		return new HexArea(ag);
 	}
 }
+
 ///<summary>An area that displays hexadecimal</summary>
 public class HexArea : GroupedArea {
 
-
 	public HexArea(AreaGroup ag)
 			: base(ag)
 	{
 		type = "hexadecimal";
-		dpb = 2;
+		dpb  = 2;
 	}
 
 	private int KeyToHex(Gdk.Key key)
 	{
-		if (key >= Gdk.Key.Key_0 && key <= Gdk.Key.Key_9)
-			return key - Gdk.Key.Key_0;
-		else if (key >= Gdk.Key.A && key <= Gdk.Key.F)
-			return key - Gdk.Key.A + 10;
-		else if (key >= Gdk.Key.a && key <= Gdk.Key.f)
-			return key - Gdk.Key.a + 10;
-		else if (key >= Gdk.Key.KP_0 && key <= Gdk.Key.KP_9)
-			return key - Gdk.Key.KP_0;
-		else
-			return -1;
+		if (key >= Gdk.Key.Key_0 && key <= Gdk.Key.Key_9) return key - Gdk.Key.Key_0;
+		else if (key >= Gdk.Key.A && key <= Gdk.Key.F)    return key - Gdk.Key.A + 10;
+		else if (key >= Gdk.Key.a && key <= Gdk.Key.f)    return key - Gdk.Key.a + 10;
+		else if (key >= Gdk.Key.KP_0 && key <= Gdk.Key.KP_9) return key - Gdk.Key.KP_0;
+		else return -1;
 	}
 
 	public override bool HandleKey(Gdk.Key key, bool overwrite)
@@ -71,38 +50,32 @@ public class HexArea : GroupedArea {
 			byte b = (byte)hex;
 			byte orig;
 
-			// if we are after the end of the buffer, assume
-			// a 0 byte
 			if (areaGroup.CursorOffset == areaGroup.Buffer.Size || (overwrite == false && areaGroup.CursorDigit == 0))
 				orig = 0;
 			else
 				orig = areaGroup.Buffer[areaGroup.CursorOffset];
 
-			byte orig1 = (byte)(orig % 16);
+			byte orig1  = (byte)(orig % 16);
 			byte orig16 = (byte)((orig / 16) % 16);
 
-
 			if (areaGroup.CursorDigit == 0)
 				orig16 = b;
 			else if (areaGroup.CursorDigit == 1)
 				orig1 = b;
 
 			byte repl = (byte)(orig16 * 16 + orig1);
-
-			byte[] ba = new byte[]{repl};
+			byte[] ba = new byte[] { repl };
 
 			if (areaGroup.CursorOffset == areaGroup.Buffer.Size)
 				areaGroup.Buffer.Append(ba, 0, ba.LongLength);
 			else if (overwrite == false && areaGroup.CursorDigit == 0)
 				areaGroup.Buffer.Insert(areaGroup.CursorOffset, ba, 0, ba.LongLength);
-			else /*(if (overwrite==true || areaGroup.CursorDigit > 0)*/
+			else
 				areaGroup.Buffer.Replace(areaGroup.CursorOffset, areaGroup.CursorOffset, ba);
 
-
 			return true;
-
-		} else
-			return false;
+		}
+		return false;
 	}
 
 	public override void Configure(XmlNode parentNode)
@@ -110,13 +83,13 @@ public class HexArea : GroupedArea {
 		base.Configure(parentNode);
 
 		XmlNodeList childNodes = parentNode.ChildNodes;
-		foreach(XmlNode node in childNodes) {
+		foreach (XmlNode node in childNodes) {
 			if (node.Name == "case")
 				drawerInformation.Uppercase = (node.InnerText == "upper");
 		}
 	}
 
-	public override void Realize ()
+	public override void Realize()
 	{
 		Gtk.DrawingArea da = areaGroup.DrawingArea;
 		drawer = new HexDrawer(da, drawerInformation);
diff --git a/src/gui/areas/OctalArea.cs b/src/gui/areas/OctalArea.cs
index f6dd7d6..fb96fd6 100644
--- a/src/gui/areas/OctalArea.cs
+++ b/src/gui/areas/OctalArea.cs
@@ -1,23 +1,8 @@
-// created on 7/1/2004 at 8:39 PM
 /*
  *   Copyright (c) 2004, Alexandros Frantzis (alf82 [at] freemail [dot] gr)
- *
- *   This file is part of Bless.
- *
- *   Bless is free software; you can redistribute it and/or modify
- *   it under the terms of the GNU General Public License as published by
- *   the Free Software Foundation; either version 2 of the License, or
- *   (at your option) any later version.
- *
- *   Bless is distributed in the hope that it will be useful,
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *   GNU General Public License for more details.
- *
- *   You should have received a copy of the GNU General Public License
- *   along with Bless; if not, write to the Free Software
- *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *   This file is part of Bless (GPL v2+).
  */
+using System.Xml;
 using Bless.Plugins;
 using Bless.Gui.Drawers;
 using Gtk;
@@ -28,7 +13,7 @@ public class OctalAreaPlugin : AreaPlugin
 {
 	public OctalAreaPlugin()
 	{
-		name = "octal";
+		name   = "octal";
 		author = "Alexandros Frantzis";
 	}
 
@@ -38,69 +23,17 @@ public class OctalAreaPlugin : AreaPlugin
 	}
 }
 
-///<summary>An area that displays octal</summary>
+///<summary>An area that displays octal values</summary>
 public class OctalArea : GroupedArea {
 
 	public OctalArea(AreaGroup ag)
 			: base(ag)
 	{
 		type = "octal";
-		dpb = 3;
+		dpb  = 3;
 	}
 
-	public override bool HandleKey(Gdk.Key key, bool overwrite)
-	{
-		//System.Console.WriteLine("Octal: {0}", key);
-
-		if (key >= Gdk.Key.Key_0 && key <= Gdk.Key.Key_7 || (key >= Gdk.Key.KP_0 && key <= Gdk.Key.KP_7)) {
-			byte b;
-			if (key >= Gdk.Key.Key_0 && key <= Gdk.Key.Key_7)
-				b = (byte)(key - Gdk.Key.Key_0);
-			else
-				b = (byte)(key - Gdk.Key.KP_0);
-
-			byte orig;
-
-			// if we are after the end of the buffer, assume
-			// a 0 byte
-			if (areaGroup.CursorOffset == areaGroup.Buffer.Size || (overwrite == false && areaGroup.CursorDigit == 0))
-				orig = 0;
-			else
-				orig = areaGroup.Buffer[areaGroup.CursorOffset];
-
-			byte orig1 = (byte)(orig % 8);
-			byte orig8 = (byte)((orig / 8) % 8);
-			byte orig64 = (byte)((orig / 64) % 8);
-
-			if (areaGroup.CursorDigit == 0)
-				orig64 = b;
-			else if (areaGroup.CursorDigit == 1)
-				orig8 = b;
-			else if (areaGroup.CursorDigit == 2)
-				orig1 = b;
-
-			int repl = orig64 * 64 + orig8 * 8 + orig1;
-
-			if (repl > 255)
-				return false;
-
-			byte[] ba = new byte[]{(byte)repl};
-
-			if (areaGroup.CursorOffset == areaGroup.Buffer.Size)
-				areaGroup.Buffer.Append(ba, 0, ba.LongLength);
-			else if (overwrite == false && areaGroup.CursorDigit == 0)
-				areaGroup.Buffer.Insert(areaGroup.CursorOffset, ba, 0, ba.LongLength);
-			else /*(if (overwrite==true || areaGroup.CursorDigit > 0)*/
-				areaGroup.Buffer.Replace(areaGroup.CursorOffset, areaGroup.CursorOffset, ba);
-
-
-			return true;
-
-		} else
-			return false;
-	}
-
-	public override void Realize ()
+	public override void Realize()
 	{
 		Gtk.DrawingArea da = areaGroup.DrawingArea;
 		drawer = new OctalDrawer(da, drawerInformation);
diff --git a/src/gui/areas/OffsetArea.cs b/src/gui/areas/OffsetArea.cs
index c419d07..f002c34 100644
--- a/src/gui/areas/OffsetArea.cs
+++ b/src/gui/areas/OffsetArea.cs
@@ -1,24 +1,7 @@
-// created on 6/14/2004 at 11:05 PM
 /*
  *   Copyright (c) 2004, Alexandros Frantzis (alf82 [at] freemail [dot] gr)
- *
- *   This file is part of Bless.
- *
- *   Bless is free software; you can redistribute it and/or modify
- *   it under the terms of the GNU General Public License as published by
- *   the Free Software Foundation; either version 2 of the License, or
- *   (at your option) any later version.
- *
- *   Bless is distributed in the hope that it will be useful,
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *   GNU General Public License for more details.
- *
- *   You should have received a copy of the GNU General Public License
- *   along with Bless; if not, write to the Free Software
- *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *   This file is part of Bless (GPL v2+).
  */
-
 using System;
 using Gtk;
 using Gdk;
@@ -33,7 +16,7 @@ public class OffsetAreaPlugin : AreaPlugin
 {
 	public OffsetAreaPlugin()
 	{
-		name = "offset";
+		name   = "offset";
 		author = "Alexandros Frantzis";
 	}
 
@@ -43,7 +26,7 @@ public class OffsetAreaPlugin : AreaPlugin
 	}
 }
 
-///<summary>An area that display the offsets</summary>
+///<summary>An area that displays offsets</summary>
 public class OffsetArea : Area {
 
 	int bytes;
@@ -56,7 +39,7 @@ public class OffsetArea : Area {
 	public OffsetArea(AreaGroup ag)
 			: base(ag)
 	{
-		type = "offset";
+		type  = "offset";
 		bytes = 4;
 	}
 
@@ -67,16 +50,12 @@ public class OffsetArea : Area {
 
 		int nrows = height / drawer.Height;
 		long bleft = nrows * bpr;
-		int rfull = 0;
-		int blast = 0;
 
 		if (bleft + areaGroup.Offset > areaGroup.Buffer.Size)
-			bleft = areaGroup.Buffer.Size - areaGroup.Offset + 1; 
+			bleft = areaGroup.Buffer.Size - areaGroup.Offset + 1;
 
-		// calculate number of full rows
-		// and number of bytes in last (non-full)
-		rfull = (int)(bleft / bpr);
-		blast = (int)(bleft % bpr);
+		int rfull = (int)(bleft / bpr);
+		int blast = (int)(bleft % bpr);
 
 		if (blast > 0)
 			rfull++;
@@ -84,46 +63,36 @@ public class OffsetArea : Area {
 		for (int i = 0; i < rfull; i++)
 			RenderRowNormal(i, 0, bpr, true);
 	}
-	
+
 	protected override void RenderHighlight(Highlight h, Drawer.HighlightType left, Drawer.HighlightType right)
 	{
+		// Offset area doesn't show highlights
 	}
-	
+
 	protected override void RenderRowNormal(int i, int p, int n, bool blank)
 	{
 		int rx = (bytes - 1) * 2 * drawer.Width + x;
 		int ry = i * drawer.Height + y;
 		long roffset = areaGroup.Offset + i * bpr;
 		bool odd;
-		Gdk.GC backEvenGC = drawer.GetBackgroundGC(Drawer.RowType.Even, Drawer.HighlightType.Normal);
-		Gdk.GC backOddGC = drawer.GetBackgroundGC(Drawer.RowType.Odd, Drawer.HighlightType.Normal);
+		Gdk.Color backEvenColor = drawer.GetBackgroundColor(Drawer.RowType.Even, Drawer.HighlightType.Normal);
+		Gdk.Color backOddColor  = drawer.GetBackgroundColor(Drawer.RowType.Odd,  Drawer.HighlightType.Normal);
 
-		// odd row?
 		odd = (((roffset / bpr) % 2) == 1);
 
 		if (blank == true) {
-			if (odd)
-				backPixmap.DrawRectangle(backOddGC, true, x, ry, width, drawer.Height);
-			else
-				backPixmap.DrawRectangle(backEvenGC, true, x, ry, width, drawer.Height);
+			FillRect(odd ? backOddColor : backEvenColor, x, ry, width, drawer.Height);
 		}
 
-		Drawer.RowType rowType;
+		Drawer.RowType rowType = odd ? Drawer.RowType.Odd : Drawer.RowType.Even;
 
-		if (odd)
-			rowType = Drawer.RowType.Odd;
-		else
-			rowType = Drawer.RowType.Even;
-
-		// if nothing to draw return
 		if (n == 0)
 			return;
 
-		// draw offsets
 		for (int j = 0; j < bytes; j++) {
-			drawer.DrawNormal(backEvenGC, backPixmap, rx, ry, (byte)(roffset & 0xff), rowType, Drawer.ColumnType.Even);
+			drawer.DrawNormal(backCr, rx, ry, (byte)(roffset & 0xff), rowType, Drawer.ColumnType.Even);
 			roffset = roffset >> 8;
-			rx = rx - 2 * drawer.Width;
+			rx -= 2 * drawer.Width;
 		}
 	}
 
@@ -134,29 +103,25 @@ public class OffsetArea : Area {
 
 	public override int CalcWidth(int n, bool force)
 	{
-		return 2*bytes*drawer.Width;
+		return 2 * bytes * drawer.Width;
 	}
 
 	public override void GetDisplayInfoByOffset(long off, out int orow, out int obyte, out int ox, out int oy)
 	{
-		orow = (int)((off - areaGroup.Offset) / bpr);
+		orow  = (int)((off - areaGroup.Offset) / bpr);
 		obyte = (int)((off - areaGroup.Offset) % bpr);
-
-		oy = orow * drawer.Height;
-
-		ox = 0;
+		oy    = orow * drawer.Height;
+		ox    = 0;
 	}
 
 	public override long GetOffsetByDisplayInfo(int x, int y, out int digit, out GetOffsetFlags flags)
 	{
 		flags = 0;
-		int row = y / drawer.Height;
+		int row  = y / drawer.Height;
 		long off = row * bpr + areaGroup.Offset;
 		if (off >= areaGroup.Buffer.Size)
 			flags |= GetOffsetFlags.Eof;
-
 		digit = 0;
-
 		return off;
 	}
 
@@ -165,7 +130,7 @@ public class OffsetArea : Area {
 		base.Configure(parentNode);
 
 		XmlNodeList childNodes = parentNode.ChildNodes;
-		foreach(XmlNode node in childNodes) {
+		foreach (XmlNode node in childNodes) {
 			if (node.Name == "case")
 				drawerInformation.Uppercase = (node.InnerText == "upper");
 			if (node.Name == "bytes")
@@ -173,7 +138,7 @@ public class OffsetArea : Area {
 		}
 	}
 
-	public override void Realize ()
+	public override void Realize()
 	{
 		Gtk.DrawingArea da = areaGroup.DrawingArea;
 		drawer = new HexDrawer(da, drawerInformation);
@@ -181,5 +146,4 @@ public class OffsetArea : Area {
 	}
 }
 
-
 }//namespace
diff --git a/src/gui/areas/SeparatorArea.cs b/src/gui/areas/SeparatorArea.cs
index 3a2c5b5..25fbc81 100644
--- a/src/gui/areas/SeparatorArea.cs
+++ b/src/gui/areas/SeparatorArea.cs
@@ -1,22 +1,6 @@
-// created on 6/18/2004 at 7:46 PM
 /*
  *   Copyright (c) 2004, Alexandros Frantzis (alf82 [at] freemail [dot] gr)
- *
- *   This file is part of Bless.
- *
- *   Bless is free software; you can redistribute it and/or modify
- *   it under the terms of the GNU General Public License as published by
- *   the Free Software Foundation; either version 2 of the License, or
- *   (at your option) any later version.
- *
- *   Bless is distributed in the hope that it will be useful,
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *   GNU General Public License for more details.
- *
- *   You should have received a copy of the GNU General Public License
- *   along with Bless; if not, write to the Free Software
- *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *   This file is part of Bless (GPL v2+).
  */
 using System;
 using Gtk;
@@ -31,7 +15,7 @@ public class SeparatorAreaPlugin : AreaPlugin
 {
 	public SeparatorAreaPlugin()
 	{
-		name = "separator";
+		name   = "separator";
 		author = "Alexandros Frantzis";
 	}
 
@@ -41,10 +25,10 @@ public class SeparatorAreaPlugin : AreaPlugin
 	}
 }
 
-///<summary>An area that contains a vertical separator line</summary>
+///<summary>An area that shows a vertical separator line</summary>
 public class SeparatorArea : Area
 {
-	Gdk.GC lineGC;
+	Gdk.Color lineColor;
 
 	public SeparatorArea(AreaGroup ag)
 			: base(ag)
@@ -55,20 +39,16 @@ public class SeparatorArea : Area
 	public override void Realize()
 	{
 		Gtk.DrawingArea da = areaGroup.DrawingArea;
-		
-		drawer = new DummyDrawer(da, drawerInformation);
-
-		lineGC = new Gdk.GC(da.GdkWindow);
-
-		lineGC.RgbFgColor = drawer.Info.fgNormal[(int)Drawer.RowType.Even, (int)Drawer.ColumnType.Even].GdkColor;
-		
+		drawer    = new DummyDrawer(da, drawerInformation);
+		lineColor = drawer.Info.fgNormal[(int)Drawer.RowType.Even, (int)Drawer.ColumnType.Even].GdkColor;
 		base.Realize();
 	}
-	
+
 	protected override void RenderHighlight(Highlight h, Drawer.HighlightType left, Drawer.HighlightType right)
 	{
+		// Separator shows no highlights
 	}
-	
+
 	protected override void RenderRowNormal(int i, int p, int n, bool blank)
 	{
 	}
@@ -77,34 +57,35 @@ public class SeparatorArea : Area
 	{
 	}
 
-	protected override void RenderExtra() 
+	protected override void RenderExtra()
 	{
 		if (isAreaRealized == false)
-			return; 
+			return;
 
 		int nrows = height / drawer.Height;
 		long bleft = nrows * bpr;
-		int rfull = 0; 
-		int blast = 0; 
+		int rfull = 0;
+		int blast = 0;
 
 		if (bpr > 0) {
 			if (bleft + areaGroup.Offset > areaGroup.Buffer.Size)
-				bleft = areaGroup.Buffer.Size - areaGroup.Offset + 1; 
- 			
-			// calculate number of full rows
-			// and number of bytes in last (non-full) 
-			rfull = (int)(bleft / bpr); 
-			blast = (int)(bleft % bpr);
+				bleft = areaGroup.Buffer.Size - areaGroup.Offset + 1;
 
-			if (blast != 0) 
-				rfull++; 
+			rfull = (int)(bleft / bpr);
+			blast = (int)(bleft % bpr);
+			if (blast != 0)
+				rfull++;
 		}
 
-		if (rfull == 0) 
-			return; 
+		if (rfull == 0)
+			return;
 
-		// draw seperator 
-		backPixmap.DrawLine(lineGC, x + drawer.Width / 2, 0, x + drawer.Width / 2, drawer.Height*rfull);
+		// Draw the vertical separator line using Cairo
+		Gdk.CairoHelper.SetSourceColor(backCr, lineColor);
+		backCr.LineWidth = 1;
+		backCr.MoveTo(x + drawer.Width / 2, 0);
+		backCr.LineTo(x + drawer.Width / 2, drawer.Height * rfull);
+		backCr.Stroke();
 	}
 
 	public override int CalcWidth(int n, bool force)
@@ -114,27 +95,22 @@ public class SeparatorArea : Area
 
 	public override void GetDisplayInfoByOffset(long off, out int orow, out int obyte, out int ox, out int oy)
 	{
-		orow = (int)((off - areaGroup.Offset) / bpr);
+		orow  = (int)((off - areaGroup.Offset) / bpr);
 		obyte = (int)((off - areaGroup.Offset) % bpr);
-
-		oy = orow * drawer.Height;
-
-		ox = 0;
+		oy    = orow * drawer.Height;
+		ox    = 0;
 	}
 
-	public override long GetOffsetByDisplayInfo(int x, int y, out int digit, out  GetOffsetFlags flags)
+	public override long GetOffsetByDisplayInfo(int x, int y, out int digit, out GetOffsetFlags flags)
 	{
 		flags = 0;
-		int row = y / drawer.Height;
+		int row  = y / drawer.Height;
 		long off = row * bpr + areaGroup.Offset;
 		if (off >= areaGroup.Buffer.Size)
 			flags |= GetOffsetFlags.Eof;
-
 		digit = 0;
-
 		return off;
 	}
 }
 
-
 }//namespace
diff --git a/src/gui/dialogs/Alert.cs b/src/gui/dialogs/Alert.cs
index 80418b0..87cb2aa 100644
--- a/src/gui/dialogs/Alert.cs
+++ b/src/gui/dialogs/Alert.cs
@@ -27,8 +27,8 @@ namespace Bless.Gui.Dialogs {
 ///<summary>An alert dialog box as recommended in the Gnome HIG</summary>
 abstract public class Alert : Gtk.Dialog
 {
-	protected Gtk.HBox hbox;
-	protected Gtk.VBox labelBox;
+	protected Gtk.Box hbox;
+	protected Gtk.Box labelBox;
 	protected Gtk.Image image;
 	protected Gtk.Label labelPrimary;
 	protected Gtk.Label labelSecondary;
@@ -40,15 +40,14 @@ abstract public class Alert : Gtk.Dialog
 		this.Modal = true;
 		//this.TypeHint=Gdk.WindowTypeHint.Utility;
 		this.BorderWidth = 6;
-		this.HasSeparator = false;
 		this.Resizable = false;
 
-		this.VBox.Spacing = 12;
+		this.ContentArea.Spacing = 12;
 
-		hbox = new Gtk.HBox();
+		hbox = new Gtk.Box(Gtk.Orientation.Horizontal, 0);
 		hbox.Spacing = 12;
 		hbox.BorderWidth = 6;
-		this.VBox.Add(hbox);
+		this.ContentArea.Add(hbox);
 
 		// set-up image
 		image = new Gtk.Image();
@@ -71,7 +70,7 @@ abstract public class Alert : Gtk.Dialog
 		labelPrimary.Markup = "<span weight=\"bold\" size=\"larger\">" + primary + "</span>";
 		labelSecondary.Markup = "\n" + secondary;
 
-		labelBox = new VBox();
+		labelBox = new Gtk.Box(Gtk.Orientation.Vertical, 0);
 		labelBox.Add(labelPrimary);
 		labelBox.Add(labelSecondary);
 
diff --git a/src/gui/dialogs/ExportDialog.cs b/src/gui/dialogs/ExportDialog.cs
index 6b9c113..84bfa57 100644
--- a/src/gui/dialogs/ExportDialog.cs
+++ b/src/gui/dialogs/ExportDialog.cs
@@ -38,9 +38,9 @@ public class ExportDialog : Dialog
 	DataBook dataBook;
 	Gtk.Window mainWindow;
 
-	[Gtk.Builder.Object] Gtk.VBox ExportDialogVBox;
+	[Gtk.Builder.Object] Gtk.Box ExportDialogVBox;
 	[Gtk.Builder.Object] Gtk.ComboBox ExportAsCombo;
-	[Gtk.Builder.Object] Gtk.ComboBoxEntry ExportPatternComboEntry;
+	[Gtk.Builder.Object] Gtk.ComboBoxText ExportPatternComboEntry;
 	[Gtk.Builder.Object] Gtk.ProgressBar ExportProgressBar;
 	[Gtk.Builder.Object] Gtk.Entry ExportFileEntry;
 	[Gtk.Builder.Object] Gtk.RadioButton WholeFileRadio;
@@ -48,7 +48,7 @@ public class ExportDialog : Dialog
 	[Gtk.Builder.Object] Gtk.RadioButton RangeRadio;
 	[Gtk.Builder.Object] Gtk.Entry RangeFromEntry;
 	[Gtk.Builder.Object] Gtk.Entry RangeToEntry;
-	[Gtk.Builder.Object] Gtk.HBox ProgressHBox;
+	[Gtk.Builder.Object] Gtk.Box ProgressHBox;
 	Gtk.Button CloseButton;
 	Gtk.Button ExportButton;
 
@@ -79,7 +79,6 @@ public class ExportDialog : Dialog
 		SetupExportPlugins();
 
 		ExportPatternComboEntry.Model = new ListStore (typeof (string));
-		ExportPatternComboEntry.TextColumn = 0;
 		LoadFromPatternFile((ListStore)ExportPatternComboEntry.Model);
 
 		ProgressHBox.Visible = false;
@@ -87,11 +86,10 @@ public class ExportDialog : Dialog
 
 		this.Modal = false;
 		this.BorderWidth = 6;
-		this.HasSeparator = false;
 		CloseButton = (Gtk.Button)this.AddButton(Gtk.Stock.Close, ResponseType.Close);
 		ExportButton = (Gtk.Button)this.AddButton(Catalog.GetString("Export"), ResponseType.Ok);
 		this.Response += new ResponseHandler(OnDialogResponse);
-		this.VBox.Add(ExportDialogVBox);
+		this.ContentArea.Add(ExportDialogVBox);
 	}
 
 	private void SetupExportPlugins()
diff --git a/src/gui/dialogs/LayoutSelectionDialog.cs b/src/gui/dialogs/LayoutSelectionDialog.cs
index f1c91e4..4ca67bc 100644
--- a/src/gui/dialogs/LayoutSelectionDialog.cs
+++ b/src/gui/dialogs/LayoutSelectionDialog.cs
@@ -77,11 +77,10 @@ public class LayoutSelectionDialog : Dialog {
 		this.DefaultHeight = 300;
 		this.Modal = false;
 		this.BorderWidth = 6;
-		this.HasSeparator = false;
 		this.AddButton(Gtk.Stock.Close, ResponseType.Close);
 		this.AddButton(Gtk.Stock.Ok, ResponseType.Ok);
 		this.Response += new ResponseHandler(OnDialogResponse);
-		this.VBox.Add(LayoutSelectionPaned);
+		this.ContentArea.Add(LayoutSelectionPaned);
 	}
 
 	///<summary>Populate the layout list</summary>
@@ -122,7 +121,7 @@ public class LayoutSelectionDialog : Dialog {
 	public void OnLayoutListSelectionChanged (object o, EventArgs args)
 	{
 		TreeSelection sel = (TreeSelection)o;
-		TreeModel tm;
+		Gtk.ITreeModel tm;
 		TreeIter ti;
 
 		if (sel.GetSelected(out tm, out ti)) {
diff --git a/src/gui/dialogs/PreferencesDialog.cs b/src/gui/dialogs/PreferencesDialog.cs
index 5110fbe..37d8ecd 100644
--- a/src/gui/dialogs/PreferencesDialog.cs
+++ b/src/gui/dialogs/PreferencesDialog.cs
@@ -63,8 +63,8 @@ public class PreferencesDialog : Dialog
 		this.BorderWidth = 6;
 		this.AddButton(Gtk.Stock.Close, ResponseType.Close);
 		this.Response += new ResponseHandler(OnDialogResponse);
-		this.VBox.Add(PreferencesPaned);
-		this.VBox.ShowAll();
+		this.ContentArea.Add(PreferencesPaned);
+		this.ContentArea.ShowAll();
 	}
 	
 	void LoadPreferencesTreeView()
@@ -93,7 +93,7 @@ public class PreferencesDialog : Dialog
 	void OnPreferencesTreeViewSelectionChanged (object o, EventArgs args)
 	{
 		TreeSelection sel = (TreeSelection)o;
-		TreeModel tm;
+		Gtk.ITreeModel tm;
 		TreeIter ti;
 
 		if (sel.GetSelected(out tm, out ti)) {
@@ -130,7 +130,7 @@ public class PreferencesDialog : Dialog
 
 class GeneralPreferences : IPluginPreferences
 {
-	[Gtk.Builder.Object] Gtk.VBox GeneralPreferencesVBox;
+	[Gtk.Builder.Object] Gtk.Box GeneralPreferencesVBox;
 
 	[Gtk.Builder.Object] Entry LayoutFileEntry;
 	[Gtk.Builder.Object] CheckButton UseCurrentLayoutCheckButton;
@@ -290,7 +290,7 @@ class SessionPreferences : IPluginPreferences
 {
 	Preferences prefs;
 
-	[Gtk.Builder.Object] Gtk.VBox SessionPreferencesVBox;
+	[Gtk.Builder.Object] Gtk.Box SessionPreferencesVBox;
 	
 	[Gtk.Builder.Object] CheckButton LoadPreviousSessionCheckButton;
 	[Gtk.Builder.Object] CheckButton AskBeforeLoadingSessionCheckButton;
@@ -408,7 +408,7 @@ class UndoPreferences : IPluginPreferences
 {
 	Preferences prefs;
 
-	[Gtk.Builder.Object] Gtk.VBox UndoPreferencesVBox;
+	[Gtk.Builder.Object] Gtk.Box UndoPreferencesVBox;
 	
 	[Gtk.Builder.Object] RadioButton UndoLimitedRadioButton;
 	[Gtk.Builder.Object] RadioButton UndoUnlimitedRadioButton;
diff --git a/src/gui/dialogs/ProgressDialog.cs b/src/gui/dialogs/ProgressDialog.cs
index a8ef334..cb05241 100644
--- a/src/gui/dialogs/ProgressDialog.cs
+++ b/src/gui/dialogs/ProgressDialog.cs
@@ -30,7 +30,7 @@ namespace Bless.Gui.Dialogs {
 ///</summary>
 public class ProgressDialog : Gtk.Window {
 
-	[Gtk.Builder.Object] Gtk.VBox ProgressVBox;
+	[Gtk.Builder.Object] Gtk.Box ProgressVBox;
 	[Gtk.Builder.Object] Gtk.ProgressBar ProgressBar;
 	[Gtk.Builder.Object] Gtk.Label MessageLabel;
 	[Gtk.Builder.Object] Gtk.Label DetailsLabel;
diff --git a/src/gui/dialogs/SaveConfirmationMultiAlert.cs b/src/gui/dialogs/SaveConfirmationMultiAlert.cs
index 1b1f97b..a8b3023 100644
--- a/src/gui/dialogs/SaveConfirmationMultiAlert.cs
+++ b/src/gui/dialogs/SaveConfirmationMultiAlert.cs
@@ -53,12 +53,12 @@ public class SaveConfirmationMultiAlert : Alert
 		Label label = new Label(Catalog.GetString("\nSelect the files you want to save:\n"));
 		label.Xalign = 0.0f;
 
-		VBox vb = new VBox();
-		vb.PackStart(label);
+		Gtk.Box vb = new Gtk.Box(Gtk.Orientation.Vertical, 6);
+		vb.PackStart(label, false, false, 0);
 		treeView = CreateView(list);
-		vb.PackStart(treeView);
+		vb.PackStart(treeView, false, false, 0);
 
-		labelBox.PackStart(vb);
+		labelBox.PackStart(vb, false, false, 0);
 		labelBox.ReorderChild(vb, 1);
 
 		this.AddButton(Catalog.GetString("Close without Saving"), ResponseType.No);
diff --git a/src/gui/drawers/AsciiDrawer.cs b/src/gui/drawers/AsciiDrawer.cs
index 0cc2800..365dccd 100644
--- a/src/gui/drawers/AsciiDrawer.cs
+++ b/src/gui/drawers/AsciiDrawer.cs
@@ -1,67 +1,45 @@
-// created on 6/28/2004 at 4:46 PM
 /*
  *   Copyright (c) 2004, Alexandros Frantzis (alf82 [at] freemail [dot] gr)
- *
- *   This file is part of Bless.
- *
- *   Bless is free software; you can redistribute it and/or modify
- *   it under the terms of the GNU General Public License as published by
- *   the Free Software Foundation; either version 2 of the License, or
- *   (at your option) any later version.
- *
- *   Bless is distributed in the hope that it will be useful,
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *   GNU General Public License for more details.
- *
- *   You should have received a copy of the GNU General Public License
- *   along with Bless; if not, write to the Free Software
- *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *   This file is part of Bless (GPL v2+).
  */
+using Cairo;
 
 namespace Bless.Gui.Drawers {
 
-///<summary>Draws the ascii representation of a byte</summary>
+///<summary>Draws the ASCII representation of a byte</summary>
 public class AsciiDrawer : Drawer {
 
-	// Use the Zero Width Non-Joiner character \u200c to avoid ligatures
-	static readonly string AsciiTable = "................................ !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHI\u200cJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghi\u200cjklmnopqrs\u200ctuvwxyz{|}~.................................................................................................................................";
+	static readonly string AsciiTable =
+		"................................ !\"#$%&'()*+,-./0123456789:;<=>?" +
+		"@ABCDEFGHI\u200cJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghi\u200cjklmnopqrs\u200ctuvwxyz{|}~" +
+		".................................................................................................................................";
 
 	public AsciiDrawer(Gtk.Widget wid, Information inf)
-			: base(wid, inf)
+		: base(wid, inf)
 	{
 	}
 
-	protected override void Draw(Gdk.GC gc, Gdk.Drawable dest, int x, int y, byte b, Gdk.Pixmap pix)
+	protected override void Draw(Cairo.Context cr, int x, int y, byte b, Cairo.ImageSurface surf)
 	{
-		dest.DrawDrawable(gc, pix, b*width, 0, x, y, width, height);
+		BlitSurface(cr, surf, b * width, 0, x, y, width, height);
 	}
 
-	protected override Gdk.Pixmap Create(Gdk.Color fg, Gdk.Color bg)
+	protected override Cairo.ImageSurface Create(Gdk.Color fg, Gdk.Color bg)
 	{
-		Gdk.Window win = widget.GdkWindow;
-
-		Gdk.GC gc = new Gdk.GC(win);
-		Gdk.Pixmap pix = new Gdk.Pixmap(win, 256*width, height, -1);
-
-		// draw the background
-		gc.RgbFgColor = bg;
-		pix.DrawRectangle(gc, true, 0, 0, 256*width, height);
-
-		// render the bytes
-		string s = AsciiDrawer.AsciiTable;
-
-		//System.Console.WriteLine(s);
-
-		pangoLayout.SetText(s);
-
-
-		gc.RgbFgColor = fg;
-		pix.DrawLayout(gc, 0, 0, pangoLayout);
-
-		return pix;
+		Cairo.ImageSurface surf = new Cairo.ImageSurface(Cairo.Format.Argb32, 256 * width, height);
+		using (Cairo.Context cr = new Cairo.Context(surf)) {
+			Pango.CairoHelper.UpdateLayout(cr, pangoLayout);
+
+			Gdk.CairoHelper.SetSourceColor(cr, bg);
+			cr.Paint();
+
+			pangoLayout.SetText(AsciiTable);
+			Gdk.CairoHelper.SetSourceColor(cr, fg);
+			cr.MoveTo(0, 0);
+			Pango.CairoHelper.ShowLayout(cr, pangoLayout);
+		}
+		return surf;
 	}
-
 }
 
-} //namespace
+} // namespace
diff --git a/src/gui/drawers/BinaryDrawer.cs b/src/gui/drawers/BinaryDrawer.cs
index b9a2118..f6b5cd4 100644
--- a/src/gui/drawers/BinaryDrawer.cs
+++ b/src/gui/drawers/BinaryDrawer.cs
@@ -1,23 +1,8 @@
-// created on 6/28/2004 at 4:48 PM
 /*
  *   Copyright (c) 2004, Alexandros Frantzis (alf82 [at] freemail [dot] gr)
- *
- *   This file is part of Bless.
- *
- *   Bless is free software; you can redistribute it and/or modify
- *   it under the terms of the GNU General Public License as published by
- *   the Free Software Foundation; either version 2 of the License, or
- *   (at your option) any later version.
- *
- *   Bless is distributed in the hope that it will be useful,
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *   GNU General Public License for more details.
- *
- *   You should have received a copy of the GNU General Public License
- *   along with Bless; if not, write to the Free Software
- *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *   This file is part of Bless (GPL v2+).
  */
+using Cairo;
 
 namespace Bless.Gui.Drawers {
 
@@ -25,49 +10,39 @@ namespace Bless.Gui.Drawers {
 public class BinaryDrawer : Drawer {
 
 	public BinaryDrawer(Gtk.Widget wid, Information inf)
-			: base(wid, inf)
+		: base(wid, inf)
 	{
 	}
 
-
-	protected override void Draw(Gdk.GC gc, Gdk.Drawable dest, int x, int y, byte b, Gdk.Pixmap pix)
+	protected override void Draw(Cairo.Context cr, int x, int y, byte b, Cairo.ImageSurface surf)
 	{
-		// draw from the end backwards
-		x += 6 * width;
+		// Draw from MSB to LSB in 4 groups of 2 bits
+		int rx = x + 6 * width;
 		for (int i = 0; i < 4; i++) {
 			byte k = (byte)(b & 3);
-			dest.DrawDrawable(gc, pix, k*2*width, 0, x, y, 2*width, height);
-			x -= 2 * width;
+			BlitSurface(cr, surf, k * 2 * width, 0, rx, y, 2 * width, height);
+			rx -= 2 * width;
 			b = (byte)(b >> 2);
 		}
 	}
 
-	protected override Gdk.Pixmap Create(Gdk.Color fg, Gdk.Color bg)
+	protected override Cairo.ImageSurface Create(Gdk.Color fg, Gdk.Color bg)
 	{
-		Gdk.Window win = widget.GdkWindow;
-
-		Gdk.GC gc = new Gdk.GC(win);
-		Gdk.Pixmap pix = new Gdk.Pixmap(win, 4*2*width, height, -1);
-
-		// draw the background
-		gc.RgbFgColor = bg;
-		pix.DrawRectangle(gc, true, 0, 0, 4*2*width, height);
-
-		// render the bytes
-		string s = "00011011";
-
-
-		//Console.WriteLine(s);
-
-		pangoLayout.SetText(s);
-
-
-		gc.RgbFgColor = fg;
-		pix.DrawLayout(gc, 0, 0, pangoLayout);
-
-		return pix;
+		// Surface contains "00011011" (4 * 2-char entries for bit-pairs 00,01,10,11)
+		Cairo.ImageSurface surf = new Cairo.ImageSurface(Cairo.Format.Argb32, 4 * 2 * width, height);
+		using (Cairo.Context cr = new Cairo.Context(surf)) {
+			Pango.CairoHelper.UpdateLayout(cr, pangoLayout);
+
+			Gdk.CairoHelper.SetSourceColor(cr, bg);
+			cr.Paint();
+
+			pangoLayout.SetText("00011011");
+			Gdk.CairoHelper.SetSourceColor(cr, fg);
+			cr.MoveTo(0, 0);
+			Pango.CairoHelper.ShowLayout(cr, pangoLayout);
+		}
+		return surf;
 	}
-
 }
 
-} //namespace
\ No newline at end of file
+} // namespace
diff --git a/src/gui/drawers/DecimalDrawer.cs b/src/gui/drawers/DecimalDrawer.cs
index 1e07681..2c9e0b7 100644
--- a/src/gui/drawers/DecimalDrawer.cs
+++ b/src/gui/drawers/DecimalDrawer.cs
@@ -1,67 +1,51 @@
-// created on 7/1/2004 at 8:10 PM
 /*
  *   Copyright (c) 2004, Alexandros Frantzis (alf82 [at] freemail [dot] gr)
- *
- *   This file is part of Bless.
- *
- *   Bless is free software; you can redistribute it and/or modify
- *   it under the terms of the GNU General Public License as published by
- *   the Free Software Foundation; either version 2 of the License, or
- *   (at your option) any later version.
- *
- *   Bless is distributed in the hope that it will be useful,
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *   GNU General Public License for more details.
- *
- *   You should have received a copy of the GNU General Public License
- *   along with Bless; if not, write to the Free Software
- *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *   This file is part of Bless (GPL v2+).
  */
+using Cairo;
+
 namespace Bless.Gui.Drawers {
 
 ///<summary>Draws the decimal representation of a byte</summary>
 public class DecimalDrawer : Drawer {
 
-	static readonly string DecimalTable = "000001002003004005006007008009010011012013014015016017018019020021022023024025026027028029030031032033034035036037038039040041042043044045046047048049050051052053054055056057058059060061062063064065066067068069070071072073074075076077078079080081082083084085086087088089090091092093094095096097098099100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255";
+	static readonly string DecimalTable =
+		"000001002003004005006007008009010011012013014015016017018019020021022023024025026027028029" +
+		"030031032033034035036037038039040041042043044045046047048049050051052053054055056057058059" +
+		"060061062063064065066067068069070071072073074075076077078079080081082083084085086087088089" +
+		"090091092093094095096097098099100101102103104105106107108109110111112113114115116117118119" +
+		"120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149" +
+		"150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179" +
+		"180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209" +
+		"210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239" +
+		"240241242243244245246247248249250251252253254255";
 
 	public DecimalDrawer(Gtk.Widget wid, Information inf)
-			: base(wid, inf)
+		: base(wid, inf)
 	{
 	}
 
-	protected override void Draw(Gdk.GC gc, Gdk.Drawable dest, int x, int y, byte b, Gdk.Pixmap pix)
+	protected override void Draw(Cairo.Context cr, int x, int y, byte b, Cairo.ImageSurface surf)
 	{
-		dest.DrawDrawable(gc, pix, b*3*width, 0, x, y, 3*width, height);
+		BlitSurface(cr, surf, b * 3 * width, 0, x, y, 3 * width, height);
 	}
 
-	protected override Gdk.Pixmap Create(Gdk.Color fg, Gdk.Color bg)
+	protected override Cairo.ImageSurface Create(Gdk.Color fg, Gdk.Color bg)
 	{
-		Gdk.Window win = widget.GdkWindow;
-
-		Gdk.GC gc = new Gdk.GC(win);
-		Gdk.Pixmap pix = new Gdk.Pixmap(win, 256*3*width, height, -1);
-
-		// draw the background
-		gc.RgbFgColor = bg;
-		pix.DrawRectangle(gc, true, 0, 0, 256*3*width, height);
-
-		// render the bytes
-		string s = DecimalDrawer.DecimalTable;
-
-		//System.Console.WriteLine(s);
-
-		pangoLayout.SetText(s);
-
-
-		gc.RgbFgColor = fg;
-		pix.DrawLayout(gc, 0, 0, pangoLayout);
-
-		return pix;
+		Cairo.ImageSurface surf = new Cairo.ImageSurface(Cairo.Format.Argb32, 256 * 3 * width, height);
+		using (Cairo.Context cr = new Cairo.Context(surf)) {
+			Pango.CairoHelper.UpdateLayout(cr, pangoLayout);
+
+			Gdk.CairoHelper.SetSourceColor(cr, bg);
+			cr.Paint();
+
+			pangoLayout.SetText(DecimalTable);
+			Gdk.CairoHelper.SetSourceColor(cr, fg);
+			cr.MoveTo(0, 0);
+			Pango.CairoHelper.ShowLayout(cr, pangoLayout);
+		}
+		return surf;
 	}
-
-
-
 }
 
-} //namespace
\ No newline at end of file
+} // namespace
diff --git a/src/gui/drawers/Drawer.cs b/src/gui/drawers/Drawer.cs
index 21a1124..6881d6a 100644
--- a/src/gui/drawers/Drawer.cs
+++ b/src/gui/drawers/Drawer.cs
@@ -1,4 +1,3 @@
-// created on 6/14/2004 at 10:55 PM
 /*
  *   Copyright (c) 2004, Alexandros Frantzis (alf82 [at] freemail [dot] gr)
  *
@@ -24,6 +23,7 @@ using System.Collections.Specialized;
 using Gtk;
 using Gdk;
 using Pango;
+using Cairo;
 
 namespace Bless.Gui.Drawers {
 
@@ -58,7 +58,7 @@ public abstract class Drawer {
 
 			fgNormal = new Drawer.Color[2, 2];
 			bgNormal = new Drawer.Color[2, 2];
-			
+
 			fgHighlight = new Drawer.Color[2, (int)HighlightType.Sentinel];
 			bgHighlight = new Drawer.Color[2, (int)HighlightType.Sentinel];
 
@@ -82,13 +82,10 @@ public abstract class Drawer {
 			Gdk.Color.Parse("blue", ref fgNormal[(int)RowType.Odd, (int)ColumnType.Odd].GdkColor);
 			Gdk.Color.Parse("white", ref bgNormal[(int)RowType.Odd, (int)ColumnType.Odd].GdkColor);
 
-			// leave unspecified...
-			// if not specified by user they will
-			// be set up using theme defaults
+			// leave unspecified - will be set up using theme defaults
 			for (int i = 0; i < (int)HighlightType.Sentinel; i++) {
 				fgHighlight[(int)RowType.Even, i] = null;
 				bgHighlight[(int)RowType.Even, i] = null;
-
 				fgHighlight[(int)RowType.Odd, i] = null;
 				bgHighlight[(int)RowType.Odd, i] = null;
 			}
@@ -96,91 +93,97 @@ public abstract class Drawer {
 			Uppercase = false;
 		}
 
-		// setup unspecified hightlight colors using theme default colors
+		/// <summary>Convert Gdk.RGBA to Gdk.Color</summary>
+		static Gdk.Color RGBAToGdkColor(Gdk.RGBA rgba)
+		{
+			return new Gdk.Color(
+				(byte)(rgba.Red   * 255),
+				(byte)(rgba.Green * 255),
+				(byte)(rgba.Blue  * 255)
+			);
+		}
+
+		/// <summary>Make a color lighter while keeping its hue</summary>
+		Gdk.Color MakeColorLighter(Gdk.Color col, double factor)
+		{
+			Gdk.Color light = new Gdk.Color();
+			light.Red   = (ushort)(col.Red   + (ushort.MaxValue - col.Red)   * factor);
+			light.Blue  = (ushort)(col.Blue  + (ushort.MaxValue - col.Blue)  * factor);
+			light.Green = (ushort)(col.Green + (ushort.MaxValue - col.Green) * factor);
+			return light;
+		}
+
+		/// <summary>Make a color darker while keeping its hue</summary>
+		Gdk.Color MakeColorDarker(Gdk.Color col, double factor)
+		{
+			Gdk.Color dark = new Gdk.Color();
+			dark.Red   = (ushort)(col.Red   * factor);
+			dark.Blue  = (ushort)(col.Blue  * factor);
+			dark.Green = (ushort)(col.Green * factor);
+			return dark;
+		}
+
+		/// <summary>Setup unspecified highlight colors using theme default colors</summary>
 		public void SetupHighlight(Gtk.Widget widget)
 		{
-			Gdk.Color selFg;
-			Gdk.Color selBg;
-			Gdk.Color patMatchFg;
-			Gdk.Color patMatchBg;
+			Gdk.Color selFg, selBg, patMatchFg, patMatchBg;
+
+			// Use StyleContext (GTK3) to get theme selection colors
+			Gdk.RGBA selFgRgba = widget.StyleContext.GetColor(Gtk.StateFlags.Selected);
+			selFg = RGBAToGdkColor(selFgRgba);
+
+			// Try to get the selection background from theme; fall back to a blue if missing
+			Gdk.RGBA selBgRgba;
+			if (!widget.StyleContext.LookupColor("theme_selected_bg_color", out selBgRgba)) {
+				selBgRgba = new Gdk.RGBA();
+				selBgRgba.Red = 0.2; selBgRgba.Green = 0.4; selBgRgba.Blue = 0.8; selBgRgba.Alpha = 1.0;
+			}
+			selBg = RGBAToGdkColor(selBgRgba);
 
-			selFg = widget.Style.TextColors[(int)StateType.Selected];
-			selBg = widget.Style.BaseColors[(int)StateType.Selected];
 			patMatchBg = MakeColorLighter(selBg, 0.6);
 			patMatchFg = MakeColorDarker(selFg, 0.4);
 
 			// Selection
 			if (fgHighlight[(int)RowType.Even, (int)HighlightType.Selection] == null)
 				fgHighlight[(int)RowType.Even, (int)HighlightType.Selection] = new Drawer.Color(selFg);
-
 			if (bgHighlight[(int)RowType.Even, (int)HighlightType.Selection] == null)
 				bgHighlight[(int)RowType.Even, (int)HighlightType.Selection] = new Drawer.Color(selBg);
-
 			if (fgHighlight[(int)RowType.Odd, (int)HighlightType.Selection] == null)
 				fgHighlight[(int)RowType.Odd, (int)HighlightType.Selection] = new Drawer.Color(selFg);
-
 			if (bgHighlight[(int)RowType.Odd, (int)HighlightType.Selection] == null)
 				bgHighlight[(int)RowType.Odd, (int)HighlightType.Selection] = new Drawer.Color(selBg);
 
-			// Secondary selection
+			// Pattern match (secondary selection)
 			if (fgHighlight[(int)RowType.Even, (int)HighlightType.PatternMatch] == null)
 				fgHighlight[(int)RowType.Even, (int)HighlightType.PatternMatch] = new Drawer.Color(patMatchFg);
-
 			if (bgHighlight[(int)RowType.Even, (int)HighlightType.PatternMatch] == null)
 				bgHighlight[(int)RowType.Even, (int)HighlightType.PatternMatch] = new Drawer.Color(patMatchBg);
-
 			if (fgHighlight[(int)RowType.Odd, (int)HighlightType.PatternMatch] == null)
 				fgHighlight[(int)RowType.Odd, (int)HighlightType.PatternMatch] = new Drawer.Color(patMatchFg);
-
 			if (bgHighlight[(int)RowType.Odd, (int)HighlightType.PatternMatch] == null)
 				bgHighlight[(int)RowType.Odd, (int)HighlightType.PatternMatch] = new Drawer.Color(patMatchBg);
 		}
-
-		// Make a color lighter while keeping its hue
-		Gdk.Color MakeColorLighter(Gdk.Color col, double factor)
-		{
-			Gdk.Color light = new Gdk.Color();
-
-			light.Red = (ushort)(col.Red + (ushort.MaxValue - col.Red) * factor);
-			light.Blue = (ushort)(col.Blue + (ushort.MaxValue - col.Blue) * factor);
-			light.Green = (ushort)(col.Green + (ushort.MaxValue - col.Green) * factor);
-			return light;
-		}
-
-		// Make a color darker while keeping its hue
-		Gdk.Color MakeColorDarker(Gdk.Color col, double factor)
-		{
-			Gdk.Color dark = new Gdk.Color();
-
-			dark.Red = (ushort)(col.Red * factor);
-			dark.Blue = (ushort)(col.Blue * factor);
-			dark.Green = (ushort)(col.Green * factor);
-			return dark;
-		}
 	}
-	
-	// the order of this enumeration denotes the drawing priority of each highlight type
-	// For example if a Bookmark and PatternMatch highlight are to be drawn on the same offset
-	// the PatternMatch type will be drawn. In the same manner the Selection highlight
-	// is always drawn, whereas the Normal highlight is always drawn over.
+
+	// Highlight drawing priority: Normal < Bookmark < PatternMatch < Selection
 	public enum HighlightType { Normal, Bookmark, PatternMatch, Selection, Sentinel }
 	public enum RowType { Even, Odd }
 	public enum ColumnType { Even, Odd }
 
-	// the widget the font will finally
-	// be printed on (used for info only)
 	protected Gtk.Widget widget;
 	protected Pango.FontDescription fontDescription;
 	protected Information info;
 
-	protected Gdk.Pixmap[,] pixmapsNormal;
-	protected Gdk.Pixmap[,] pixmapsHighlight;
-	protected StringCollection pixmapIds;
+	// Cairo ImageSurface-based pre-rendered character caches (replaces Gdk.Pixmap)
+	protected Cairo.ImageSurface[,] surfacesNormal;
+	protected Cairo.ImageSurface[,] surfacesHighlight;
+	protected StringCollection surfaceIds;
 
-	// pango layout used for rendering text
 	protected Pango.Layout pangoLayout;
 
-	protected Gdk.GC[,] backGC;
+	// Background colors (replaces Gdk.GC)
+	protected Gdk.Color[,] backColor;
+
 	protected int width;
 	protected int height;
 
@@ -189,8 +192,9 @@ public abstract class Drawer {
 	{
 		widget = wid;
 		info = inf;
-		pixmapIds = new StringCollection();
-		// make sure highlight colors are set
+		surfaceIds = new StringCollection();
+
+		// Ensure highlight colors are set from the widget's theme
 		info.SetupHighlight(wid);
 
 		fontDescription = Pango.FontDescription.FromString(info.FontName);
@@ -200,184 +204,171 @@ public abstract class Drawer {
 		pangoCtx.FontDescription = fontDescription;
 		pangoCtx.Language = lang;
 
-		// set the font height and width
+		// Measure character size using a monospaced font
 		pangoLayout = new Pango.Layout(pangoCtx);
-		// we use a monospaced font, the actual character doesn't matter
 		pangoLayout.SetText("X");
 		pangoLayout.GetPixelSize(out width, out height);
 		pangoLayout.SetText("");
 
-		// create the font pixmaps
-		InitializePixmaps();
-
-		InitializeBackgroundGCs();
+		InitializeSurfaces();
+		InitializeBackgroundColors();
 	}
 
-	void InitializePixmaps()
+	void InitializeSurfaces()
 	{
-		pixmapsNormal = new Gdk.Pixmap[2,2];
-		pixmapsHighlight = new Gdk.Pixmap[2,(int)HighlightType.Sentinel];
+		surfacesNormal    = new Cairo.ImageSurface[2, 2];
+		surfacesHighlight = new Cairo.ImageSurface[2, (int)HighlightType.Sentinel];
 
-		Drawer.Color colorFg;
-		Drawer.Color colorBg;
+		Drawer.Color colorFg, colorBg;
 
-		//even rows
+		// Even rows
 		colorFg = info.fgNormal[(int)RowType.Even, (int)ColumnType.Even];
 		colorBg = info.bgNormal[(int)RowType.Even, (int)ColumnType.Even];
-		pixmapsNormal[(int)RowType.Even, (int)ColumnType.Even] = CreateWrapper(colorFg, colorBg);
+		surfacesNormal[(int)RowType.Even, (int)ColumnType.Even] = CreateWrapper(colorFg, colorBg);
 
 		colorFg = info.fgNormal[(int)RowType.Even, (int)ColumnType.Odd];
 		colorBg = info.bgNormal[(int)RowType.Even, (int)ColumnType.Odd];
-		pixmapsNormal[(int)RowType.Even, (int)ColumnType.Odd] = CreateWrapper(colorFg, colorBg);
+		surfacesNormal[(int)RowType.Even, (int)ColumnType.Odd] = CreateWrapper(colorFg, colorBg);
 
 		colorFg = info.fgHighlight[(int)RowType.Even, (int)HighlightType.Selection];
 		colorBg = info.bgHighlight[(int)RowType.Even, (int)HighlightType.Selection];
-		pixmapsHighlight[(int)RowType.Even, (int)HighlightType.Selection] = CreateWrapper(colorFg, colorBg);
+		surfacesHighlight[(int)RowType.Even, (int)HighlightType.Selection] = CreateWrapper(colorFg, colorBg);
 
 		colorFg = info.fgHighlight[(int)RowType.Even, (int)HighlightType.PatternMatch];
 		colorBg = info.bgHighlight[(int)RowType.Even, (int)HighlightType.PatternMatch];
-		pixmapsHighlight[(int)RowType.Even, (int)HighlightType.PatternMatch] = CreateWrapper(colorFg, colorBg);
-
+		surfacesHighlight[(int)RowType.Even, (int)HighlightType.PatternMatch] = CreateWrapper(colorFg, colorBg);
 
-		//odd rows
+		// Odd rows
 		colorFg = info.fgNormal[(int)RowType.Odd, (int)ColumnType.Even];
 		colorBg = info.bgNormal[(int)RowType.Odd, (int)ColumnType.Even];
-		pixmapsNormal[(int)RowType.Odd, (int)ColumnType.Even] = CreateWrapper(colorFg, colorBg);
+		surfacesNormal[(int)RowType.Odd, (int)ColumnType.Even] = CreateWrapper(colorFg, colorBg);
 
 		colorFg = info.fgNormal[(int)RowType.Odd, (int)ColumnType.Odd];
 		colorBg = info.bgNormal[(int)RowType.Odd, (int)ColumnType.Odd];
-		pixmapsNormal[(int)RowType.Odd, (int)ColumnType.Odd] = CreateWrapper(colorFg, colorBg);
+		surfacesNormal[(int)RowType.Odd, (int)ColumnType.Odd] = CreateWrapper(colorFg, colorBg);
 
 		colorFg = info.fgHighlight[(int)RowType.Odd, (int)HighlightType.Selection];
 		colorBg = info.bgHighlight[(int)RowType.Odd, (int)HighlightType.Selection];
-		pixmapsHighlight[(int)RowType.Odd, (int)HighlightType.Selection] = CreateWrapper(colorFg, colorBg);
+		surfacesHighlight[(int)RowType.Odd, (int)HighlightType.Selection] = CreateWrapper(colorFg, colorBg);
 
 		colorFg = info.fgHighlight[(int)RowType.Odd, (int)HighlightType.PatternMatch];
 		colorBg = info.bgHighlight[(int)RowType.Odd, (int)HighlightType.PatternMatch];
-		pixmapsHighlight[(int)RowType.Odd, (int)HighlightType.PatternMatch] = CreateWrapper(colorFg, colorBg);
+		surfacesHighlight[(int)RowType.Odd, (int)HighlightType.PatternMatch] = CreateWrapper(colorFg, colorBg);
 	}
 
-	void InitializeBackgroundGCs()
+	void InitializeBackgroundColors()
 	{
-		// initialize background GCs
-		backGC = new Gdk.GC[2, (int)Drawer.HighlightType.Sentinel];
-
-		for (int i = 0; i < 2; i++)
-			for (int j = 0; j < (int)Drawer.HighlightType.Sentinel; j++)
-				backGC[i,j] = new Gdk.GC(widget.GdkWindow);
+		backColor = new Gdk.Color[2, (int)Drawer.HighlightType.Sentinel];
 
 		Drawer.Color col;
 
-		// normal
+		// Normal even/odd
 		col = info.bgNormal[(int)RowType.Even, (int)ColumnType.Even];
-		backGC[(int)RowType.Even, (int)HighlightType.Normal].RgbFgColor = col.GdkColor;
+		backColor[(int)RowType.Even, (int)HighlightType.Normal] = col.GdkColor;
 
 		col = info.bgNormal[(int)RowType.Odd, (int)ColumnType.Even];
-		backGC[(int)RowType.Odd, (int)HighlightType.Normal].RgbFgColor = col.GdkColor;
+		backColor[(int)RowType.Odd, (int)HighlightType.Normal] = col.GdkColor;
 
-		// selection
+		// Selection
 		col = info.bgHighlight[(int)RowType.Even, (int)HighlightType.Selection];
-		backGC[(int)RowType.Even, (int)HighlightType.Selection].RgbFgColor = col.GdkColor;
+		backColor[(int)RowType.Even, (int)HighlightType.Selection] = col.GdkColor;
 
 		col = info.bgHighlight[(int)RowType.Odd, (int)HighlightType.Selection];
-		backGC[(int)RowType.Odd, (int)HighlightType.Selection].RgbFgColor = col.GdkColor;
+		backColor[(int)RowType.Odd, (int)HighlightType.Selection] = col.GdkColor;
 
-		// secondary selection
+		// PatternMatch
 		col = info.bgHighlight[(int)RowType.Even, (int)HighlightType.PatternMatch];
-		backGC[(int)RowType.Even, (int)HighlightType.PatternMatch].RgbFgColor = col.GdkColor;
+		backColor[(int)RowType.Even, (int)HighlightType.PatternMatch] = col.GdkColor;
 
 		col = info.bgHighlight[(int)RowType.Odd, (int)HighlightType.PatternMatch];
-		backGC[(int)RowType.Odd, (int)HighlightType.PatternMatch].RgbFgColor = col.GdkColor;
+		backColor[(int)RowType.Odd, (int)HighlightType.PatternMatch] = col.GdkColor;
 	}
 
-	///<summary>
-	/// Wrapper around create to avoid creating pixmaps we already have
-	///</summary>
-	private Gdk.Pixmap CreateWrapper(Drawer.Color fg, Drawer.Color bg)
+	///<summary>Wrapper that avoids creating duplicate surfaces for the same fg/bg combination</summary>
+	private Cairo.ImageSurface CreateWrapper(Drawer.Color fg, Drawer.Color bg)
 	{
 		string id = PixmapManager.Instance.GetPixmapId(this.GetType(), info, fg.GdkColor, bg.GdkColor);
 
-		Gdk.Pixmap pix = PixmapManager.Instance.GetPixmap(id);
-		if (pix == null) {
-			pix = Create(fg.GdkColor, bg.GdkColor); // can be null for DummyDrawer
-			if (pix != null) {
-				PixmapManager.Instance.AddPixmap(id, pix);
+		Cairo.ImageSurface surf = PixmapManager.Instance.GetPixmap(id);
+		if (surf == null) {
+			surf = Create(fg.GdkColor, bg.GdkColor); // may return null for DummyDrawer
+			if (surf != null) {
+				PixmapManager.Instance.AddPixmap(id, surf);
 				PixmapManager.Instance.ReferencePixmap(id);
-				pixmapIds.Add(id);
+				surfaceIds.Add(id);
 			}
 		}
 		else {
 			PixmapManager.Instance.ReferencePixmap(id);
-			pixmapIds.Add(id);
+			surfaceIds.Add(id);
 		}
 
-		return pix;
+		return surf;
 	}
 
-	///<summary>Creates a pixmap with the drawn data</summary>
-	abstract protected Gdk.Pixmap Create(Gdk.Color fg, Gdk.Color bg);
-
-	///<summary>Draws the a byte</summary>
+	///<summary>Creates a Cairo.ImageSurface with the pre-rendered character strip</summary>
+	abstract protected Cairo.ImageSurface Create(Gdk.Color fg, Gdk.Color bg);
 
-	abstract protected void Draw(Gdk.GC gc, Gdk.Drawable dest, int x, int y, byte b, Gdk.Pixmap pix);
+	///<summary>Draws a single byte at (x,y) using the provided surface strip and Cairo context</summary>
+	abstract protected void Draw(Cairo.Context cr, int x, int y, byte b, Cairo.ImageSurface surf);
 
-	public void DrawNormal(Gdk.GC gc, Gdk.Drawable dest, int x, int y, byte b, RowType rowType, ColumnType colType)
+	///<summary>Copy a horizontal strip of pixels from surf to cr at (destX, destY)</summary>
+	protected static void BlitSurface(Cairo.Context cr, Cairo.ImageSurface surf,
+	                                  int srcX, int srcY, int destX, int destY,
+	                                  int w, int h)
 	{
-		Draw(gc, dest, x, y, b, pixmapsNormal[(int)rowType, (int)colType]);
+		cr.Save();
+		cr.Rectangle(destX, destY, w, h);
+		cr.Clip();
+		cr.SetSourceSurface(surf, destX - srcX, destY - srcY);
+		cr.Paint();
+		cr.Restore();
 	}
 
-	public void DrawHighlight(Gdk.GC gc, Gdk.Drawable dest, int x, int y, byte b, RowType rowType, HighlightType ht)
+	public void DrawNormal(Cairo.Context cr, int x, int y, byte b, RowType rowType, ColumnType colType)
 	{
-		Draw(gc, dest, x, y, b, pixmapsHighlight[(int)rowType, (int)ht]);
+		Draw(cr, x, y, b, surfacesNormal[(int)rowType, (int)colType]);
 	}
 
-	public Gdk.GC GetBackgroundGC(RowType rowType, HighlightType ht)
+	public void DrawHighlight(Cairo.Context cr, int x, int y, byte b, RowType rowType, HighlightType ht)
 	{
-		return backGC[(int)rowType, (int)ht];
+		Draw(cr, x, y, b, surfacesHighlight[(int)rowType, (int)ht]);
 	}
 
-	public void DisposePixmaps()
+	public Gdk.Color GetBackgroundColor(RowType rowType, HighlightType ht)
 	{
-		foreach(string id in pixmapIds)
-		PixmapManager.Instance.DereferencePixmap(id);
-
-		pixmapIds.Clear();
-	}
-
-	public int Width{
-		get { return width; }
+		return backColor[(int)rowType, (int)ht];
 	}
 
-	public int Height{
-		get { return height; }
+	public void DisposePixmaps()
+	{
+		foreach (string id in surfaceIds)
+			PixmapManager.Instance.DereferencePixmap(id);
+		surfaceIds.Clear();
 	}
 
-	public Drawer.Information Info{
-		get { return info; }
-	}
+	public int Width  { get { return width;  } }
+	public int Height { get { return height; } }
 
+	public Drawer.Information Info { get { return info; } }
 }
 
-///<summary>dummy</summary>
+///<summary>Dummy drawer (no-op)</summary>
 public class DummyDrawer : Drawer {
 
 	public DummyDrawer(Gtk.Widget wid, Information inf)
-			: base(wid, inf)
+		: base(wid, inf)
 	{
 	}
 
-	protected override void Draw(Gdk.GC gc, Gdk.Drawable dest, int x, int y, byte b, Gdk.Pixmap pix)
+	protected override void Draw(Cairo.Context cr, int x, int y, byte b, Cairo.ImageSurface surf)
 	{
-
 	}
 
-	protected override Gdk.Pixmap Create(Gdk.Color fg, Gdk.Color bg)
+	protected override Cairo.ImageSurface Create(Gdk.Color fg, Gdk.Color bg)
 	{
 		return null;
 	}
-
-
-
 }
 
 } // end namespace
diff --git a/src/gui/drawers/HexDrawer.cs b/src/gui/drawers/HexDrawer.cs
index 7923384..281b711 100644
--- a/src/gui/drawers/HexDrawer.cs
+++ b/src/gui/drawers/HexDrawer.cs
@@ -1,82 +1,60 @@
-// created on 6/28/2004 at 4:18 PM
 /*
  *   Copyright (c) 2004, Alexandros Frantzis (alf82 [at] freemail [dot] gr)
- *
- *   This file is part of Bless.
- *
- *   Bless is free software; you can redistribute it and/or modify
- *   it under the terms of the GNU General Public License as published by
- *   the Free Software Foundation; either version 2 of the License, or
- *   (at your option) any later version.
- *
- *   Bless is distributed in the hope that it will be useful,
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *   GNU General Public License for more details.
- *
- *   You should have received a copy of the GNU General Public License
- *   along with Bless; if not, write to the Free Software
- *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *   This file is part of Bless (GPL v2+).
  */
+using Cairo;
+
 namespace Bless.Gui.Drawers {
 
 ///<summary>Draws the hex representation of a byte</summary>
 public class HexDrawer : Drawer {
 
-	// Use the Zero Width Non-Joiner character \u200c to avoid ligatures
-	static readonly string HexTableLower = "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeef\u200Cf0f1f2f3f4f5f6f7f8f9fafbfcfdfef\u200cf";
+	// Use Zero Width Non-Joiner \u200c to avoid ligatures
+	static readonly string HexTableLower = "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeef\u200Cf0f1f2f3f4f5f6f7f8f9fafbfcfdfef\u200cff";
 	static readonly string HexTableUpper = "000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F606162636465666768696A6B6C6D6E6F707172737475767778797A7B7C7D7E7F808182838485868788898A8B8C8D8E8F909192939495969798999A9B9C9D9E9FA0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6B7B8B9BABBBCBDBEBFC0C1C2C3C4C5C6C7C8C9CACBCCCDCECFD0D1D2D3D4D5D6D7D8D9DADBDCDDDEDFE0E1E2E3E4E5E6E7E8E9EAEBECEDEEEFF0F1F2F3F4F5F6F7F8F9FAFBFCFDFEFF";
 
 	public HexDrawer(Gtk.Widget wid, Information inf)
-			: base(wid, inf)
+		: base(wid, inf)
 	{
 	}
 
-	protected override void Draw(Gdk.GC gc, Gdk.Drawable dest, int x, int y, byte b, Gdk.Pixmap pix)
+	protected override void Draw(Cairo.Context cr, int x, int y, byte b, Cairo.ImageSurface surf)
 	{
-		dest.DrawDrawable(gc, pix, b*2*width, 0, x, y, 2*width, height);
+		BlitSurface(cr, surf, b * 2 * width, 0, x, y, 2 * width, height);
 	}
 
-	protected override Gdk.Pixmap Create(Gdk.Color fg, Gdk.Color bg)
+	protected override Cairo.ImageSurface Create(Gdk.Color fg, Gdk.Color bg)
 	{
-		Gdk.Window win = widget.GdkWindow;
-
-		Gdk.GC gc = new Gdk.GC(win);
-		Gdk.Pixmap pix = new Gdk.Pixmap(win, 256*2*width, height, -1);
+		string s = info.Uppercase ? HexTableUpper : HexTableLower;
 
-		// draw the background
-		gc.RgbFgColor = bg;
-		pix.DrawRectangle(gc, true, 0, 0, 256*2*width, height);
+		// Render in two halves to avoid driver bugs with very wide surfaces
+		// First half: chars 0x00-0x7f (256 chars total but string chars 0..255)
+		// Actually render the full table in two Pango calls each 256 printable chars
 
-		// render the bytes
-		string s;
+		Cairo.ImageSurface surf = new Cairo.ImageSurface(Cairo.Format.Argb32, 256 * 2 * width, height);
+		using (Cairo.Context cr = new Cairo.Context(surf)) {
+			Pango.CairoHelper.UpdateLayout(cr, pangoLayout);
 
-		if (info.Uppercase == false)
-			s = HexDrawer.HexTableLower;
-		else
-			s = HexDrawer.HexTableUpper;
+			// Fill background
+			Gdk.CairoHelper.SetSourceColor(cr, bg);
+			cr.Paint();
 
-		//System.Console.WriteLine(s);
+			// Render text
+			Gdk.CairoHelper.SetSourceColor(cr, fg);
 
-		gc.RgbFgColor = fg;
+			// First 256 printable chars (0x00–0x7f)
+			pangoLayout.SetText(s.Substring(0, 256));
+			cr.MoveTo(0, 0);
+			Pango.CairoHelper.ShowLayout(cr, pangoLayout);
 
-		// Render the text in two parts (256 printable characters each).  We do
-		// this to work around a bug in some drivers that fail to render text
-		// that ends up wider than 4096 pixels.
-		pangoLayout.SetText(s.Substring(0,256));
-		pix.DrawLayout(gc, 0, 0, pangoLayout);
-		
-		// The second part also contains the two Zero Width Non-Joiner
-		// characters, so it's actually 258 string characters, although still
-		// 256 printable characters.
-		pangoLayout.SetText(s.Substring(256));
-		pix.DrawLayout(gc, 128*2*width, 0, pangoLayout);
+			// Second 256 printable chars (0x80–0xff), includes the ZWNJs
+			pangoLayout.SetText(s.Substring(256));
+			cr.MoveTo(128 * 2 * width, 0);
+			Pango.CairoHelper.ShowLayout(cr, pangoLayout);
+		}
 
-		return pix;
+		return surf;
 	}
-
-
-
 }
 
-} //namespace
+} // namespace
diff --git a/src/gui/drawers/OctalDrawer.cs b/src/gui/drawers/OctalDrawer.cs
index f50bfed..4b9bc17 100644
--- a/src/gui/drawers/OctalDrawer.cs
+++ b/src/gui/drawers/OctalDrawer.cs
@@ -1,64 +1,50 @@
-// created on 7/1/2004 at 8:41 PM
 /*
  *   Copyright (c) 2004, Alexandros Frantzis (alf82 [at] freemail [dot] gr)
- *
- *   This file is part of Bless.
- *
- *   Bless is free software; you can redistribute it and/or modify
- *   it under the terms of the GNU General Public License as published by
- *   the Free Software Foundation; either version 2 of the License, or
- *   (at your option) any later version.
- *
- *   Bless is distributed in the hope that it will be useful,
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *   GNU General Public License for more details.
- *
- *   You should have received a copy of the GNU General Public License
- *   along with Bless; if not, write to the Free Software
- *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *   This file is part of Bless (GPL v2+).
  */
+using Cairo;
+
 namespace Bless.Gui.Drawers {
 
 ///<summary>Draws the octal representation of a byte</summary>
 public class OctalDrawer : Drawer {
 
-	static readonly string OctalTable = "000001002003004005006007010011012013014015016017020021022023024025026027030031032033034035036037040041042043044045046047050051052053054055056057060061062063064065066067070071072073074075076077100101102103104105106107110111112113114115116117120121122123124125126127130131132133134135136137140141142143144145146147150151152153154155156157160161162163164165166167170171172173174175176177200201202203204205206207210211212213214215216217220221222223224225226227230231232233234235236237240241242243244245246247250251252253254255256257260261262263264265266267270271272273274275276277300301302303304305306307310311312313314315316317320321322323324325326327330331332333334335336337340341342343344345346347350351352353354355356357360361362363364365366367370371372373374375376377";
+	static readonly string OctalTable =
+		"000001002003004005006007010011012013014015016017020021022023024025026027030031032033034035036037" +
+		"040041042043044045046047050051052053054055056057060061062063064065066067070071072073074075076077" +
+		"100101102103104105106107110111112113114115116117120121122123124125126127130131132133134135136137" +
+		"140141142143144145146147150151152153154155156157160161162163164165166167170171172173174175176177" +
+		"200201202203204205206207210211212213214215216217220221222223224225226227230231232233234235236237" +
+		"240241242243244245246247250251252253254255256257260261262263264265266267270271272273274275276277" +
+		"300301302303304305306307310311312313314315316317320321322323324325326327330331332333334335336337" +
+		"340341342343344345346347350351352353354355356357360361362363364365366367370371372373374375376377";
 
 	public OctalDrawer(Gtk.Widget wid, Information inf)
-			: base(wid, inf)
+		: base(wid, inf)
 	{
 	}
 
-	protected override void Draw(Gdk.GC gc, Gdk.Drawable dest, int x, int y, byte b, Gdk.Pixmap pix)
+	protected override void Draw(Cairo.Context cr, int x, int y, byte b, Cairo.ImageSurface surf)
 	{
-		dest.DrawDrawable(gc, pix, b*3*width, 0, x, y, 3*width, height);
+		BlitSurface(cr, surf, b * 3 * width, 0, x, y, 3 * width, height);
 	}
 
-	protected override Gdk.Pixmap Create(Gdk.Color fg, Gdk.Color bg)
+	protected override Cairo.ImageSurface Create(Gdk.Color fg, Gdk.Color bg)
 	{
-		Gdk.Window win = widget.GdkWindow;
-
-		Gdk.GC gc = new Gdk.GC(win);
-		Gdk.Pixmap pix = new Gdk.Pixmap(win, 256*3*width, height, -1);
-
-		// draw the background
-		gc.RgbFgColor = bg;
-		pix.DrawRectangle(gc, true, 0, 0, 256*3*width, height);
-
-		// render the bytes
-		string s = OctalDrawer.OctalTable;
-
-		//System.Console.WriteLine(s);
-
-		pangoLayout.SetText(s);
-
-
-		gc.RgbFgColor = fg;
-		pix.DrawLayout(gc, 0, 0, pangoLayout);
-
-		return pix;
+		Cairo.ImageSurface surf = new Cairo.ImageSurface(Cairo.Format.Argb32, 256 * 3 * width, height);
+		using (Cairo.Context cr = new Cairo.Context(surf)) {
+			Pango.CairoHelper.UpdateLayout(cr, pangoLayout);
+
+			Gdk.CairoHelper.SetSourceColor(cr, bg);
+			cr.Paint();
+
+			pangoLayout.SetText(OctalTable);
+			Gdk.CairoHelper.SetSourceColor(cr, fg);
+			cr.MoveTo(0, 0);
+			Pango.CairoHelper.ShowLayout(cr, pangoLayout);
+		}
+		return surf;
 	}
 }
 
-} //namespace
\ No newline at end of file
+} // namespace
diff --git a/src/gui/drawers/PixmapManager.cs b/src/gui/drawers/PixmapManager.cs
index 405e2fd..da87866 100644
--- a/src/gui/drawers/PixmapManager.cs
+++ b/src/gui/drawers/PixmapManager.cs
@@ -1,4 +1,3 @@
-// created on 12/23/2006 at 3:50 PM
 /*
  *   Copyright (c) 2005, Alexandros Frantzis (alf82 [at] freemail [dot] gr)
  *
@@ -8,25 +7,14 @@
  *   it under the terms of the GNU General Public License as published by
  *   the Free Software Foundation; either version 2 of the License, or
  *   (at your option) any later version.
- *
- *   Bless is distributed in the hope that it will be useful,
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *   GNU General Public License for more details.
- *
- *   You should have received a copy of the GNU General Public License
- *   along with Bless; if not, write to the Free Software
- *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
 using System.Collections.Generic;
-using Gdk;
+using Cairo;
 
 namespace Bless.Gui.Drawers {
 
-///<summary>
-/// Handles drawer pixmaps in an memory efficient manner
-///</summary>
+///<summary>Manages Cairo.ImageSurface instances efficiently (formerly Gdk.Pixmap manager)</summary>
 class PixmapManager
 {
 	static private PixmapManager manager;
@@ -35,74 +23,61 @@ class PixmapManager
 		get {
 			if (manager == null)
 				manager = new PixmapManager();
-
 			return manager;
 		}
 	}
 
-	Dictionary<string, Gdk.Pixmap> pixmaps;
+	Dictionary<string, Cairo.ImageSurface> pixmaps;
 	Dictionary<string, int> references;
 
 	private PixmapManager()
 	{
-		pixmaps = new Dictionary<string, Gdk.Pixmap>();
+		pixmaps    = new Dictionary<string, Cairo.ImageSurface>();
 		references = new Dictionary<string, int>();
 	}
 
-	///<summary>
-	/// Get the id of the pixmap with the specified properties
-	///</summary>
 	public string GetPixmapId(System.Type type, Drawer.Information info, Gdk.Color fg, Gdk.Color bg)
 	{
-		return string.Format("{0}{1}{2}{3}{4}{5}", type, info.FontName, info.FontLanguage, info.Uppercase, fg.ToString(), bg.ToString());
+		return string.Format("{0}{1}{2}{3}{4}{5}",
+		                     type, info.FontName, info.FontLanguage,
+		                     info.Uppercase, fg.ToString(), bg.ToString());
 	}
 
-	///<summary>
-	/// Get the pixmap with the specified id.
-	/// Returns null if the pixmap doesn't exist
-	///</summary>
-	public Gdk.Pixmap GetPixmap(string id)
+	public Cairo.ImageSurface GetPixmap(string id)
 	{
-		Gdk.Pixmap pix = null;
+		Cairo.ImageSurface surf = null;
 		if (pixmaps.ContainsKey(id))
-			pix = pixmaps[id];
-
-		return pix;
+			surf = pixmaps[id];
+		return surf;
 	}
 
-	///<summary>
-	/// Add the pixmap to the collection
-	///</summary>
-	public void AddPixmap(string id, Gdk.Pixmap pix)
+	public void AddPixmap(string id, Cairo.ImageSurface surf)
 	{
-		pixmaps[id] = pix;
+		pixmaps[id]    = surf;
 		references[id] = 0;
 	}
 
-	///<summary>
-	/// Mark that we are using the pixmap
-	///</summary>
 	public void ReferencePixmap(string id)
 	{
-		++references[id];
+		if (references.ContainsKey(id))
+			references[id]++;
 	}
 
-	///<summary>
-	/// Mark that we aren't using the pixmap anymore.
-	/// If nobody uses it, dispose of it
-	///</summary>
 	public void DereferencePixmap(string id)
 	{
-		--references[id];
+		if (!references.ContainsKey(id))
+			return;
+
+		references[id]--;
+
 		if (references[id] <= 0) {
-			pixmaps[id].Dispose();
-			pixmaps.Remove(id);
+			if (pixmaps.ContainsKey(id)) {
+				pixmaps[id].Dispose();
+				pixmaps.Remove(id);
+			}
 			references.Remove(id);
 		}
 	}
-
 }
 
-
-
-}
\ No newline at end of file
+} // end namespace
diff --git a/src/gui/plugins/BitwiseOperationsPlugin.cs b/src/gui/plugins/BitwiseOperationsPlugin.cs
index f18eabc..2d38ef7 100644
--- a/src/gui/plugins/BitwiseOperationsPlugin.cs
+++ b/src/gui/plugins/BitwiseOperationsPlugin.cs
@@ -191,7 +191,7 @@ public class BitwiseOperationsPlugin : GuiPlugin
 ///<summary>
 /// A widget for bitwise operations
 ///</summary>
-public class BitwiseOperationsWidget : Gtk.HBox
+public class BitwiseOperationsWidget : Gtk.Box
 {
 	[Gtk.Builder.Object] Gtk.HBox BitwiseOperationsHBox;
 	[Gtk.Builder.Object] Gtk.Label SourceLabel;
@@ -230,6 +230,7 @@ public class BitwiseOperationsWidget : Gtk.HBox
 	}
 
 	public BitwiseOperationsWidget(DataBook db, Gtk.Action action)
+		: base(Gtk.Orientation.Horizontal, 0)
 	{
 		dataBook = db;
 		performAction = action;
diff --git a/src/gui/plugins/ConversionTablePlugin.cs b/src/gui/plugins/ConversionTablePlugin.cs
index a37c04f..79a46ac 100644
--- a/src/gui/plugins/ConversionTablePlugin.cs
+++ b/src/gui/plugins/ConversionTablePlugin.cs
@@ -111,7 +111,7 @@ public class ConversionTablePlugin : GuiPlugin
 
 
 ///<summary> A widget to convert the data at the current offset to various types</summary>
-public class ConversionTable: Gtk.HBox
+public class ConversionTable: Gtk.Box
 {
 
 	[Gtk.Builder.Object] Gtk.Table ConversionTableWidget;
@@ -141,6 +141,7 @@ public class ConversionTable: Gtk.HBox
 	bool unsignedAsHex;
 
 	public ConversionTable(DataBook db)
+		: base(Gtk.Orientation.Horizontal, 0)
 	{
 		Gtk.Builder builder = new Gtk.Builder();
 		builder.AddFromFile(FileResourcePath.GetDataPath("ui", "ConversionTablePlugin.ui"));
diff --git a/src/gui/plugins/CopyOffsetPlugin.cs b/src/gui/plugins/CopyOffsetPlugin.cs
index 4e2da5e..adeba1e 100644
--- a/src/gui/plugins/CopyOffsetPlugin.cs
+++ b/src/gui/plugins/CopyOffsetPlugin.cs
@@ -190,9 +190,9 @@ class CopyOffsetPreferences : IPluginPreferences
 	}
 }
 
-class CopyOffsetPreferencesWidget : Gtk.VBox
+class CopyOffsetPreferencesWidget : Gtk.Box
 {
-	Gtk.ComboBox numberBaseCombo;
+	Gtk.ComboBoxText numberBaseCombo;
 
 	int BaseToActiveIndex(int number_base) {
 		switch (number_base) {
@@ -204,7 +204,7 @@ class CopyOffsetPreferencesWidget : Gtk.VBox
 		}
 	}
 
-	public Gtk.ComboBox NumberBaseCombo {
+	public Gtk.ComboBoxText NumberBaseCombo {
 		get { return numberBaseCombo; }
 	}
 
@@ -216,11 +216,12 @@ class CopyOffsetPreferencesWidget : Gtk.VBox
 	}
 
 	public CopyOffsetPreferencesWidget()
+		: base(Gtk.Orientation.Vertical, 0)
 	{
 		// Use a hbox inside an vbox to avoid expanding vertically.
-		Gtk.HBox hbox = new Gtk.HBox();
+		Gtk.Box hbox = new Gtk.Box(Gtk.Orientation.Horizontal, 0);
 		Gtk.Label label = new Gtk.Label(Catalog.GetString("Number base:"));
-		numberBaseCombo = Gtk.ComboBox.NewText();
+		numberBaseCombo = new Gtk.ComboBoxText();
 		numberBaseCombo.AppendText("2");
 		numberBaseCombo.AppendText("8");
 		numberBaseCombo.AppendText("10");
diff --git a/src/gui/plugins/FindReplacePlugin.cs b/src/gui/plugins/FindReplacePlugin.cs
index 77e3a29..5312c5d 100644
--- a/src/gui/plugins/FindReplacePlugin.cs
+++ b/src/gui/plugins/FindReplacePlugin.cs
@@ -266,7 +266,7 @@ public class FindReplacePlugin : GuiPlugin
 ///<summary>
 /// A widget for find and replace operations
 ///</summary>
-public class FindReplaceWidget : Gtk.HBox
+public class FindReplaceWidget : Gtk.Box
 {
 	DataBook dataBook;
 	IFinder finder;
@@ -331,6 +331,7 @@ public class FindReplaceWidget : Gtk.HBox
 	}
 
 	public FindReplaceWidget(DataBook db, IFinder iFinder)
+		: base(Gtk.Orientation.Horizontal, 0)
 	{
 		finder = iFinder;
 		dataBook = db;
diff --git a/src/gui/plugins/GotoOffsetPlugin.cs b/src/gui/plugins/GotoOffsetPlugin.cs
index 6fc1b18..cd78ac0 100644
--- a/src/gui/plugins/GotoOffsetPlugin.cs
+++ b/src/gui/plugins/GotoOffsetPlugin.cs
@@ -98,7 +98,7 @@ public class GotoOffsetPlugin : GuiPlugin
 ///<summary>
 /// A widget for go to offset operation
 ///</summary>
-public class GotoOffsetWidget : Gtk.HBox
+public class GotoOffsetWidget : Gtk.Box
 {
 	[Gtk.Builder.Object] Gtk.HBox GotoOffsetHBox;
 	[Gtk.Builder.Object] Gtk.Button GotoOffsetButton;
@@ -109,6 +109,7 @@ public class GotoOffsetWidget : Gtk.HBox
 
 
 	public GotoOffsetWidget(DataBook db)
+		: base(Gtk.Orientation.Horizontal, 0)
 	{
 		dataBook = db;
 
diff --git a/src/gui/plugins/InfobarPlugin.cs b/src/gui/plugins/InfobarPlugin.cs
index f5545ff..9563e54 100644
--- a/src/gui/plugins/InfobarPlugin.cs
+++ b/src/gui/plugins/InfobarPlugin.cs
@@ -73,7 +73,7 @@ public class InfobarPlugin : GuiPlugin
 
 		Services.UI.Info = widget;
 
-		((VBox)mainWindow.Child).PackEnd(widget, false, false, 0);
+		((Gtk.Box)mainWindow.Child).PackEnd(widget, false, false, 0);
 
 		AddMenuItems(uiManager);
 
@@ -250,7 +250,7 @@ public class InfobarPlugin : GuiPlugin
 ///<summary>
 /// An advanced statusbar for Bless
 ///</summary>
-public class Infobar : Gtk.HBox, IInfoDisplay
+public class Infobar : Gtk.Box, IInfoDisplay
 {
 	Label MessageLabel;
 	Label OffsetLabel;
@@ -303,6 +303,7 @@ public class Infobar : Gtk.HBox, IInfoDisplay
 	}
 
 	public Infobar(DataBook db)
+		: base(Gtk.Orientation.Horizontal, 0)
 	{
 		dataBook = db;
 
diff --git a/src/gui/plugins/PatternMatchHighlightPlugin.cs b/src/gui/plugins/PatternMatchHighlightPlugin.cs
index 98b34d3..cc647d5 100644
--- a/src/gui/plugins/PatternMatchHighlightPlugin.cs
+++ b/src/gui/plugins/PatternMatchHighlightPlugin.cs
@@ -194,7 +194,7 @@ class PatternMatchPreferences : IPluginPreferences
 	}
 }
 
-class PreferencesWidget : Gtk.HBox
+class PreferencesWidget : Gtk.Box
 {
 	Gtk.CheckButton enableHighlightCheckButton;
 	
@@ -203,6 +203,7 @@ class PreferencesWidget : Gtk.HBox
 	}
 
 	public PreferencesWidget()
+		: base(Gtk.Orientation.Horizontal, 0)
 	{
 		enableHighlightCheckButton = new Gtk.CheckButton("Highlight matches of selection pattern");
 		this.PackStart(enableHighlightCheckButton, false, false, 6);
diff --git a/src/gui/plugins/ProgressDisplayPlugin.cs b/src/gui/plugins/ProgressDisplayPlugin.cs
index f3936d2..5ca0b23 100644
--- a/src/gui/plugins/ProgressDisplayPlugin.cs
+++ b/src/gui/plugins/ProgressDisplayPlugin.cs
@@ -55,7 +55,7 @@ public class ProgressDisplayPlugin : GuiPlugin
 		// register the service
 		Services.UI.Progress = widget;
 
-		((VBox)mainWindow.Child).PackEnd(widget, false, false, 0);
+		((Gtk.Box)mainWindow.Child).PackEnd(widget, false, false, 0);
 
 		loaded = true;
 		return true;
@@ -66,12 +66,12 @@ public class ProgressDisplayPlugin : GuiPlugin
 ///<summary>
 /// Widget that displays a series of progress bars
 ///</summary>
-public class ProgressDisplayWidget : Gtk.VBox, IProgressDisplay
+public class ProgressDisplayWidget : Gtk.Box, IProgressDisplay
 {
 
 	public ProgressDisplayWidget()
+		: base(Gtk.Orientation.Vertical, 0)
 	{
-
 	}
 
 	///<summary>
@@ -81,7 +81,7 @@ public class ProgressDisplayWidget : Gtk.VBox, IProgressDisplay
 	{
 		ProgressDisplayBar pdb = new ProgressDisplayBar();
 
-		this.PackStart(pdb);
+		this.PackStart(pdb, false, false, 0);
 		pdb.DestroyEvent += OnProgressDisplayBarDestroyed;
 
 		return pdb.Update;
@@ -98,7 +98,7 @@ public class ProgressDisplayWidget : Gtk.VBox, IProgressDisplay
 
 }
 
-public class ProgressDisplayBar : Gtk.HBox {
+public class ProgressDisplayBar : Gtk.Box {
 
 	[Gtk.Builder.Object] Gtk.HBox ProgressBarHBox;
 	[Gtk.Builder.Object] Gtk.Button CancelButton;
@@ -107,6 +107,7 @@ public class ProgressDisplayBar : Gtk.HBox {
 	bool cancelClicked;
 
 	public ProgressDisplayBar()
+		: base(Gtk.Orientation.Horizontal, 0)
 	{
 		Gtk.Builder builder = new Gtk.Builder();
 		builder.AddFromFile(FileResourcePath.GetDataPath("ui", "ProgressDisplayPlugin.ui"));
diff --git a/src/gui/plugins/SelectRangePlugin.cs b/src/gui/plugins/SelectRangePlugin.cs
index a791bfe..f738cea 100644
--- a/src/gui/plugins/SelectRangePlugin.cs
+++ b/src/gui/plugins/SelectRangePlugin.cs
@@ -118,7 +118,7 @@ public class SelectRangePlugin : GuiPlugin
 ///<summary>
 /// A widget for the select range operation
 ///</summary>
-public class SelectRangeWidget : Gtk.HBox
+public class SelectRangeWidget : Gtk.Box
 {
 	[Gtk.Builder.Object] Gtk.HBox SelectRangeHBox;
 	[Gtk.Builder.Object] Gtk.Button SelectButton;
@@ -130,6 +130,7 @@ public class SelectRangeWidget : Gtk.HBox
 
 
 	public SelectRangeWidget(DataBook db)
+		: base(Gtk.Orientation.Horizontal, 0)
 	{
 		dataBook = db;
 
diff --git a/src/gui/plugins/StatisticsPlugin.cs b/src/gui/plugins/StatisticsPlugin.cs
index 65428c6..9bb091c 100644
--- a/src/gui/plugins/StatisticsPlugin.cs
+++ b/src/gui/plugins/StatisticsPlugin.cs
@@ -119,13 +119,14 @@ public class StatisticsInfo
 	}
 }
 
-public class StatisticsWidget : Gtk.HBox
+public class StatisticsWidget : Gtk.Box
 {
 	StatisticsDrawWidget  sdw;
 	DataBook dataBook;
 	Hashtable info;
 
 	public StatisticsWidget(DataBook db)
+		: base(Gtk.Orientation.Horizontal, 0)
 	{
 		info = new Hashtable();
 		dataBook = db;
@@ -285,12 +286,13 @@ public class StatisticsDrawWidget: Gtk.DrawingArea
 
 	void UpdateHighlight()
 	{
-		Gdk.Window win = this.GdkWindow;
+		Gdk.Window win = this.Window;
+		if (win == null) return;
 
 		Cairo.Context g = Gdk.CairoHelper.Create(win);
 
-		int x, y, w, h, d;
-		win.GetGeometry(out x, out y, out w, out h, out d);
+		int x, y, w, h;
+		win.GetGeometry(out x, out y, out w, out h);
 
 		g.Scale (w, h);
 		g.LineWidth = (1.0 / freqs.Length) * 0.6;
@@ -300,13 +302,13 @@ public class StatisticsDrawWidget: Gtk.DrawingArea
 			int end=previousHighlight+1;
 			if (start<0) start=0;
 			if (end>=barStart.Length) end=barStart.Length-1;*/
-			g.Color = new Color(0.0, 0.0, 0.0);
+			g.SetSourceRGB(0.0, 0.0, 0.0);
 			//for(int i=start; i<=end; i++)
 			DrawBar(g, previousHighlight);
 		}
 
 		if (currentHighlight != -1) {
-			g.Color = new Color(1.0, 0.0, 0.0);
+			g.SetSourceRGB(1.0, 0.0, 0.0);
 			DrawBar(g, currentHighlight);
 		}
 
@@ -315,19 +317,19 @@ public class StatisticsDrawWidget: Gtk.DrawingArea
 	void Draw (Cairo.Context gr, int width, int height)
 	{
 		gr.Scale (width, height);
-		gr.Color = new Color(1.0, 1.0, 1.0);
+		gr.SetSourceRGB(1.0, 1.0, 1.0);
 		gr.Rectangle(0.0, 0.0, 1.0, 1.0);
 		gr.Stroke();
-		gr.Color = new Color(0.0, 0.0, 0.0);
+		gr.SetSourceRGB(0.0, 0.0, 0.0);
 
 		gr.LineWidth = (1.0 / freqs.Length) * 0.6;
 
 		for (int i = 0; i < freqs.Length; i++) {
 			if (previousHighlight == i)
-				gr.Color = new Color(1.0, 0.0, 0.0);
+				gr.SetSourceRGB(1.0, 0.0, 0.0);
 			DrawBar(gr, i);
 			if (previousHighlight == i)
-				gr.Color = new Color(0.0, 0.0, 0.0);
+				gr.SetSourceRGB(0.0, 0.0, 0.0);
 		}
 
 	}
@@ -347,18 +349,13 @@ public class StatisticsDrawWidget: Gtk.DrawingArea
 		currentHighlight = -1;
 	}
 
-	protected override bool OnExposeEvent (Gdk.EventExpose args)
+	protected override bool OnDrawn(Cairo.Context g)
 	{
-		Gdk.Window win = args.Window;
-
-		Cairo.Context g = Gdk.CairoHelper.Create(win);
-
-		int x, y, w, h, d;
-		win.GetGeometry(out x, out y, out w, out h, out d);
+		Gdk.Rectangle alloc2 = this.Allocation;
+		int w = alloc2.Width;
+		int h = alloc2.Height;
 		this.HeightRequest = w / 5;
-
-		Draw (g, w, h);
-
+		Draw(g, w, h);
 		return true;
 	}
 
@@ -408,7 +405,7 @@ public class StatisticsDrawWidget: Gtk.DrawingArea
 		Gdk.ModifierType state;
 
 		if (e.IsHint)
-			this.GdkWindow.GetPointer(out x, out y, out state);
+			this.Window.GetDevicePosition(this.Display.DeviceManager.ClientPointer, out x, out y, out state);
 		else {
 			x = (int)e.X;
 			y = (int)e.Y;
diff --git a/src/plugins/GuiPlugin.cs b/src/plugins/GuiPlugin.cs
index 418ae4c..7b1777c 100644
--- a/src/plugins/GuiPlugin.cs
+++ b/src/plugins/GuiPlugin.cs
@@ -33,11 +33,11 @@ public class GuiPlugin : Plugin
 
 	protected Widget GetDataBook(Window win)
 	{
-		VBox vbox = (VBox)win.Child;
+		// MainVBox is a Gtk.Box (orientation=vertical) in GTK3
+		Gtk.Box vbox = (Gtk.Box)win.Child;
 		foreach (Widget child in vbox.Children) {
-			//System.Console.WriteLine("Child: {0}", child.GetType().ToString());
-			if (child.GetType() == typeof(HBox)) {
-				foreach (Widget child1 in ((HBox)child).Children) {
+			if (child is Gtk.Box && ((Gtk.Box)child).Orientation == Gtk.Orientation.Horizontal) {
+				foreach (Widget child1 in ((Gtk.Box)child).Children) {
 					if (child1.GetType().ToString() == "Bless.Gui.DataBook")
 						return child1;
 				}
@@ -49,9 +49,8 @@ public class GuiPlugin : Plugin
 
 	protected Widget GetMenuBar(Window win)
 	{
-		VBox vbox = (VBox)win.Child;
+		Gtk.Box vbox = (Gtk.Box)win.Child;
 		foreach (Widget child in vbox.Children) {
-			//System.Console.WriteLine("Child: {0}", child.GetType().ToString());
 			if (child.GetType() == typeof(MenuBar)) {
 				return child;
 			}
@@ -62,7 +61,7 @@ public class GuiPlugin : Plugin
 
 	protected Widget GetWidgetGroup(Window win, int n)
 	{
-		VBox vbox = (VBox)win.Child;
+		Gtk.Box vbox = (Gtk.Box)win.Child;
 		int i = 0;
 		foreach (Widget child in vbox.Children) {
 			//System.Console.WriteLine("Child: {0}", child.GetType().ToString());
@@ -79,14 +78,13 @@ public class GuiPlugin : Plugin
 
 	protected Widget GetSideWidgetGroup(Window win, int n)
 	{
-		VBox vbox = (VBox)win.Child;
+		Gtk.Box vbox = (Gtk.Box)win.Child;
 		int i = 0;
-		HBox hbox = null;
+		Gtk.Box hbox = null;
 
 		foreach (Widget child in vbox.Children) {
-			System.Console.WriteLine("Child: {0}", child.GetType().ToString());
-			if (child.GetType().ToString() == "Gtk.HBox") {
-				hbox = (HBox)child;
+			if (child is Gtk.Box && ((Gtk.Box)child).Orientation == Gtk.Orientation.Horizontal) {
+				hbox = (Gtk.Box)child;
 				break;
 			}
 		}
@@ -94,7 +92,6 @@ public class GuiPlugin : Plugin
 			return null;
 
 		foreach (Widget child in hbox.Children) {
-			System.Console.WriteLine("Child: {0}", child.GetType().ToString());
 			if (child.GetType().ToString() == "Bless.Gui.WidgetGroup") {
 				if (i == n)
 					return child;
