   // read touch position, add DOWN event to event queue
   ts_read(&last_x, &last_y);
   event_push(event_Down, last_x, last_y);
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// Code to handle the PixelVFO menus
+//////////////////////////////////////////////////////////////////////////////
+
+// handler for selection of an item
+typedef void (*ItemAction)(struct Menu *, int);
+
+// structure defining a menu item
+struct MenuItem
+{
+  const char *title;          // menu item display text
+  struct Menu *menu;          // if not NULL, submenu to pass to show_menu()
+  ItemAction action;          // if not NULL, address of action function
+};
+
+// A structure defining a menu
+struct Menu
+{
+  const char *title;          // title displayed on menu page
+  int num_items;              // number of items in the array below
+  struct MenuItem **items;    // array of pointers to MenuItem data
+};
+
+//----------------------------------------
+// dump a MenuItem to the console
+// only called from dump_menu()
+//----------------------------------------
+
+void dump_menuitem(struct MenuItem *menuitem)
+{
+  Serial.printf(F("  menuitem address=%08x\n"), menuitem);
+  Serial.printf(F("  title=%s\n"), menuitem->title);
+  Serial.printf(F("  menu=%08x\n"), menuitem->menu);
+  Serial.printf(F("  action=%08x\n"), menuitem->action);
+}
+
+//----------------------------------------
+// dump a Menu and contained MenuItems to the console
+//----------------------------------------
+
+void dump_menu(const char *msg, struct Menu *menu)
+{
+  Serial.printf(F("----------------- Menu --------------------\n"));
+  Serial.printf(F("%s\n"), msg);
+  Serial.printf(F("menu address=%08x\n"), menu);
+  Serial.printf(F("  title=%s\n"), menu->title);
+  Serial.printf(F("  num_items=%d\n"), menu->num_items);
+  Serial.printf(F("  items address=%08x\n"), menu->items);
+  
+  for (int i = 0; i < menu->num_items; ++i)
+    dump_menuitem(menu->items[i]);
+    
+  Serial.printf(F("^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n"));
+}
+
+//----------------------------------------
+// Handle the menu 'BACK' hotspot.
+//     pointer to the hotspot we are actioning
+//     arg     the integer arg from the menu handler
+//----------------------------------------
+
+bool hs_menuback_handler(HotSpot *hs, int arg)
+{
+  
+}
+
+//----------------------------------------
+// Handle the menu 'select menuitem' hotspot
+//     pointer to the hotspot we are actioning
+//     row     index number of the menuitem row selected
+//----------------------------------------
+
+bool hs_menuitem_handler(HotSpot *hs, int row)
+{
+  
+}
+
+//----------------------------------------
+// Draw a menu on the screen.
+//     menu  pointer to a Menu structure
+// Only draws the top row.
+//----------------------------------------
+
+void menu_draw(struct Menu *menu)
+{
+  // clear screen and write menu title on upper row
+#if 0
+  tft.clear();
+  tft.setCursor(0, 0);
+  tft.print(menu->title);
+#endif
+}
+
+//----------------------------------------
+// Draw a standard menuitem on the screen.
+//     menu      pointer to a Menu structure
+//     item_num  the item number to show
+//     row       menu row to draw menuitem on
+// Custome menuitems are drawn by their handler.
+//----------------------------------------
+
+void menuitem_draw(struct Menu *menu, int item_num, int row)
+{
+  // figure out max length of item strings
+  int max_len = 0;
+  int row_offset = MENUITEM_HEIGHT*row;
+
+  for (int i = 0; i < menu->num_items; ++ i)
+  {
+    int16_t x1;
+    int16_t y1;
+    uint16_t w;
+    uint16_t h;
+    
+    tft.getTextBounds((char *) menu->items[i]->title, 30, 30, &x1, &y1, &w, &h);
+
+    if (w > max_len)
+        max_len = w;
+  }
+
+  // write indexed item on lower row, right-justified
+  tft.fillRect(0, 2, ts_width, DEPTH_FREQ_DISPLAY+row_offset, SCREEN_BG);
+  
+  tft.setCursor(max_len, DEPTH_FREQ_DISPLAY+row_offset);
+  tft.print(menu->items[item_num]->title);
+}
+
+// menu HotSpot definitions
+HotSpot hs_menu[] =
+{
+  {0, 0, ts_width, DEPTH_FREQ_DISPLAY, hs_menuback_handler, 0},
+  {0, DEPTH_FREQ_DISPLAY+MENUITEM_HEIGHT*0, ts_width, MENUITEM_HEIGHT, hs_menuitem_handler, 0},
+  {0, DEPTH_FREQ_DISPLAY+MENUITEM_HEIGHT*1, ts_width, MENUITEM_HEIGHT, hs_menuitem_handler, 1},
+  {0, DEPTH_FREQ_DISPLAY+MENUITEM_HEIGHT*2, ts_width, MENUITEM_HEIGHT, hs_menuitem_handler, 2},
+  {0, DEPTH_FREQ_DISPLAY+MENUITEM_HEIGHT*3, ts_width, MENUITEM_HEIGHT, hs_menuitem_handler, 3},
+  {0, DEPTH_FREQ_DISPLAY+MENUITEM_HEIGHT*4, ts_width, MENUITEM_HEIGHT, hs_menuitem_handler, 4},
+};  
+//----------------------------------------
+// Handle a menu.
+//     menu      pointer to a defining Menu structure
+//
+// Handle events in the loop here.
+// This code doesn't see events handled in any *_action() routine.
+//----------------------------------------
+
+void menu_show(struct Menu *menu)
+{
+  int item_num = 0;     // index of the menuitem to show
+
+  // draw the menu page
+  menu_draw(menu);
+  for (int row = 0; row < min(MAXMENUITEMROWS, menu->num_items); ++row)
+  {
+      menuitem_draw(menu, item_num, row);
+  }
+
+  // get rid of any stray events to this point
+  event_flush();
+
+  while (true)
+  {
+    // handle any pending event
+    if (event_pending() > 0)
+    {
+      // get next event and handle it
+      VFOEvent *event = event_pop();
+      Serial.printf(F("menu_show loop: event=%s\n"), event2display(event));
+
+      switch (event->event)
+      {
+        case event_Down:
+          Serial.printf(F("Event %s\n"), event2display(event));
+          if (hs_handletouch(event->x, event->y, hs_menu, MenuHSLen))
+          {
+            Serial.printf(F("hs_handletouch() returned 'true', refreshing display\n"));
+            draw_screen();
+            freq_show();
+            //event_flush();
+          }
+          break;
+        case event_None:
+          return;
+        default:
+          abort("Unrecognized event!?");
+      }
+    }
+  }
+}
+
+//----------------------------------------
+// Show that *something* happened.
+// Flash the screen in a possibly eye-catching way.
+//----------------------------------------
+
+void display_flash(void)
+{
+  Serial.printf("display_flash: called\n");
 }
 
 //////////////////////////////////////////////////////////////////////////////

}

//-----------------------------------------------
// Setup the whole shebang.
//-----------------------------------------------
void setup(void)
{
  Serial.begin(115200);

#define MENU_BG2            ILI9341_BLACK
#define MENU_FG             ILI9341_BLACK

// constants for the menu system
#define MENUITEM_HEIGHT     35
#define MAXMENUITEMROWS     5

// macro to get number of elements in an array
#define ALEN(a)    (sizeof(a)/sizeof((a)[0]))

// the VFO states
enum VFOState
{
