]> git.rkrishnan.org Git - pihpsdr.git/commitdiff
Manual update
authorc vw <dl1ycf@darc.de>
Mon, 19 Jul 2021 15:26:56 +0000 (17:26 +0200)
committerc vw <dl1ycf@darc.de>
Mon, 19 Jul 2021 15:26:56 +0000 (17:26 +0200)
34 files changed:
Makefile
action_dialog.c [new file with mode: 0644]
action_dialog.h [new file with mode: 0644]
actions.c
actions.h
alsa_midi.c
configure.c
css.c
css.h [new file with mode: 0644]
encoder_menu.c
ext.h
gpio.c
gpio.h
i2c.c
mac_midi.c
main.c
midi.h
midi2.c
midi3.c
midi_menu.c
new_menu.c
new_menu.h
radio.c
radio_menu.c
rx_menu.c
rx_panadapter.c
sliders.c
sliders.h
soapy_discovery.c
switch_menu.c
toolbar.c
toolbar_menu.c [new file with mode: 0644]
toolbar_menu.h [new file with mode: 0644]
zoompan.c

index 04e21d867d7f501b9f0d9c0325041e88a2aa0f9f..579baa5d5bfc931621da2d328706470598b794c0 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -29,7 +29,7 @@ MIDI_INCLUDE=MIDI
 #LOCALCW_INCLUDE=LOCALCW
 
 # uncomment the line below for SoapySDR
-#SOAPYSDR_INCLUDE=SOAPYSDR
+SOAPYSDR_INCLUDE=SOAPYSDR
 
 # uncomment the line to below include support for sx1509 i2c expander
 #SX1509_INCLUDE=sx1509
@@ -297,6 +297,7 @@ receiver.c \
 rigctl.c \
 rigctl_menu.c \
 toolbar.c \
+toolbar_menu.c \
 transmitter.c \
 zoompan.c \
 sliders.c \
@@ -316,6 +317,7 @@ cwramp.c \
 protocols.c \
 css.c \
 actions.c \
+action_dialog.c \
 switch_menu.c \
 gpio.c
 
@@ -371,6 +373,7 @@ receiver.h \
 rigctl.h \
 rigctl_menu.h \
 toolbar.h \
+toolbar_menu.h \
 transmitter.h \
 zoompan.h \
 sliders.h \
@@ -388,6 +391,7 @@ ext.h \
 error_handler.h \
 protocols.h \
 actions.h \
+action_dialog.h \
 switch_menu.h \
 gpio.h
 
@@ -442,6 +446,7 @@ receiver.o \
 rigctl.o \
 rigctl_menu.o \
 toolbar.o \
+toolbar_menu.o \
 transmitter.o \
 zoompan.o \
 sliders.o \
@@ -459,6 +464,7 @@ error_handler.o \
 cwramp.o \
 protocols.o \
 css.o \
+action_dialog.o \
 actions.o \
 switch_menu.o \
 gpio.o
diff --git a/action_dialog.c b/action_dialog.c
new file mode 100644 (file)
index 0000000..a60fd71
--- /dev/null
@@ -0,0 +1,73 @@
+#include <gtk/gtk.h>
+#include "actions.h"
+
+#define GRID_WIDTH 6
+
+typedef struct _choice {
+  int action;
+  GtkWidget *button;
+  gulong signal_id;
+} CHOICE;
+
+static GtkWidget *dialog;
+static GtkWidget *previous_button;
+static gulong previous_signal_id;
+static int action;
+
+static void action_select_cb(GtkWidget *widget,gpointer data) {
+  CHOICE *choice=(CHOICE *)data;
+  g_signal_handler_block(G_OBJECT(previous_button),previous_signal_id);
+  gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(previous_button),FALSE);
+  g_signal_handler_unblock(G_OBJECT(previous_button),previous_signal_id);
+  previous_button=widget;
+  previous_signal_id=choice->signal_id;
+  action=choice->action;
+}
+
+int action_dialog(GtkWidget *parent,int filter,int currentAction) {
+  int i,j;
+
+  action=currentAction;
+  previous_button=NULL;
+  dialog=gtk_dialog_new_with_buttons("Action",GTK_WINDOW(parent),GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,("_OK"),GTK_RESPONSE_ACCEPT,("_Cancel"),GTK_RESPONSE_REJECT,NULL);
+  GtkWidget *content=gtk_dialog_get_content_area(GTK_DIALOG(dialog));
+  GtkWidget *scrolled_window=gtk_scrolled_window_new(NULL,NULL);
+  gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled_window),GTK_POLICY_AUTOMATIC,GTK_POLICY_ALWAYS);
+  gtk_widget_set_size_request(scrolled_window,790,380);
+
+  GtkWidget *grid=gtk_grid_new();
+  gtk_grid_set_column_spacing(GTK_GRID(grid),2);
+  gtk_grid_set_row_spacing(GTK_GRID(grid),2);
+  gtk_grid_set_column_homogeneous(GTK_GRID(grid),TRUE);
+  gtk_grid_set_row_homogeneous(GTK_GRID(grid),TRUE);
+  j=0;
+  for(i=0;i<ACTIONS;i++) {
+    if((ActionTable[i].type&filter) || (ActionTable[i].type==TYPE_NONE)) {
+      GtkWidget *button=gtk_toggle_button_new_with_label(ActionTable[i].str);
+      gtk_widget_set_name(button,"small_button");
+      gtk_grid_attach(GTK_GRID(grid),button,j%GRID_WIDTH,j/GRID_WIDTH,1,1);
+      if(ActionTable[i].action==currentAction) {
+        gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button),TRUE);
+      }
+      CHOICE *choice=g_new0(CHOICE,1);
+      choice->action=i;
+      choice->button=button;
+      choice->signal_id=g_signal_connect(button,"toggled",G_CALLBACK(action_select_cb),choice);
+      if(ActionTable[i].action==currentAction) {
+        previous_button=button;
+        previous_signal_id=choice->signal_id;
+      }
+      j++;
+    }
+  }
+  gtk_container_add(GTK_CONTAINER(scrolled_window),grid);
+  gtk_container_add(GTK_CONTAINER(content),scrolled_window);
+  gtk_widget_show_all(content);
+  int result = gtk_dialog_run (GTK_DIALOG (dialog));
+  gtk_widget_destroy(dialog);
+  if(result!=GTK_RESPONSE_ACCEPT) {
+    action=currentAction;
+  }
+  return action;
+}
+
diff --git a/action_dialog.h b/action_dialog.h
new file mode 100644 (file)
index 0000000..c134e2e
--- /dev/null
@@ -0,0 +1 @@
+int action_dialog(GtkWidget *parent,int filter,int current);
index 4614b72debd6dad7fcc6d0af353e4f71c78c41a1..ce436247daa37eff78a32aacde1973b7c2b37d78 100644 (file)
--- a/actions.c
+++ b/actions.c
 #include "actions.h"
 #include "gpio.h"
 #include "toolbar.h"
+#ifdef LOCALCW
+#include "iambic.h"
+#endif
 
-char *encoder_string[ENCODER_ACTIONS] = {
-  "NO ACTION",
-  "AF GAIN",
-  "AF GAIN RX1",
-  "AF GAIN RX2",
-  "AGC GAIN",
-  "AGC GAIN RX1",
-  "AGC GAIN RX2",
-  "ATTENUATION",
-  "COMP",
-  "CW FREQUENCY",
-  "CW SPEED",
-  "DIVERSITY GAIN",
-  "DIVERSITY GAIN (coarse)",
-  "DIVERSITY GAIN (fine)",
-  "DIVERSITY PHASE",
-  "DIVERSITY PHASE (coarse)",
-  "DIVERSITY PHASE (fine)",
-  "DRIVE",
-  "IF SHIFT",
-  "IF SHIFT RX1",
-  "IF SHIFT RX2",
-  "IF WIDTH",
-  "IF WIDTH RX1",
-  "IF WIDTH RX2",
-  "MIC GAIN",
-  "PAN",
-  "PANADAPTER HIGH",
-  "PANADAPTER LOW",
-  "PANADAPTER STEP",
-  "RF GAIN",
-  "RF GAIN RX1",
-  "RF GAIN RX2",
-  "RIT",
-  "RIT RX1",
-  "RIT RX2",
-  "SQUELCH",
-  "SQUELCH RX1",
-  "SQUELCH RX2",
-  "TUNE DRIVE",
-  "VFO",
-  "WATERFALL HIGH",
-  "WATERFALL LOW",
-  "XIT",
-  "ZOOM"
-};
-
-char *sw_string[SWITCH_ACTIONS] = {
-  "",
-  "A TO B",
-  "A SWAP B",
-  "AGC +",
-  "ANF",
-  "B TO A",
-  "BAND -",
-  "BAND +",
-  "BSTACK -",
-  "BSTACK +",
-  "CTUN",
-  "DIV",
-  "DUPLEX",
-  "FILTER -",
-  "FILTER +",
-  "FUNCT",
-  "LOCK",
-  "AGC",
-  "BAND",
-  "BSTACK",
-  "DIV",
-  "FILTER",
-  "FREQUENCY",
-  "MEMORY",
-  "MODE",
-  "NOISE",
-  "PS",
-  "MODE -",
-  "MODE +",
-  "MOX",
-  "MUTE",
-  "NB",
-  "NR",
-  "PAN -",
-  "PAN +",
-  "PS",
-  "RIT",
-  "RIT CL",
-  "RIT -",
-  "RIT +",
-  "RSAT",
-  "SAT",
-  "SNB",
-  "SPLIT",
-  "TUN",
-  "TUNE FULL",
-  "TUNE MEM",
-  "TWO TONE",
-  "VFOSTEP +",
-  "VFOSTEP -",
-  "XIT",
-  "XIT CL",
-  "XIT -",
-  "XIT +",
-  "ZOOM -",
-  "ZOOM +"
-};
-
-char *sw_cap_string[SWITCH_ACTIONS] = {
-  "",
-  "A>B",
-  "A<>B",
-  "AGC",
-  "ANF",
-  "B>A",
-  "BAND -",
-  "BAND +",
-  "BST-",
-  "BST+",
-  "CTUN",
-  "DIV",
-  "DUP",
-  "FILT -",
-  "FILT +",
-  "FUNC",
-  "LOCK",
-  "AGC",
-  "BAND",
-  "BSTACK",
-  "DIV",
-  "FILTER",
-  "FREQ",
-  "MEM",
-  "MODE",
-  "NOISE",
-  "PS",
-  "MODE -",
-  "MODE +",
-  "MOX",
-  "MUTE",
-  "NB",
-  "NR",
-  "PAN-",
-  "PAN+",
-  "PS",
-  "RIT",
-  "RIT CL",
-  "RIT -",
-  "RIT +",
-  "RSAT",
-  "SAT",
-  "SNB",
-  "SPLIT",
-  "TUNE",
-  "TUN-F",
-  "TUN-M",
-  "2TONE",
-  "STEP+",
-  "STEP-",
-  "XIT",
-  "XIT CL",
-  "XIT -",
-  "XIT +",
-  "ZOOM-",
-  "ZOOM+",
+ACTION_TABLE ActionTable[] = {
+  {NO_ACTION,          "NONE",                 NULL,           TYPE_NONE},
+  {A_SWAP_B,           "A<>B",                 "A<>B",         MIDI_KEY | CONTROLLER_SWITCH},
+  {A_TO_B,             "A>B",                  "A>B",          MIDI_KEY | CONTROLLER_SWITCH},
+  {AF_GAIN,            "AF GAIN",              NULL,           MIDI_KNOB | MIDI_WHEEL | CONTROLLER_ENCODER},
+  {AF_GAIN_RX1,                "AF GAIN\nRX1",         NULL,           MIDI_KNOB | MIDI_WHEEL | CONTROLLER_ENCODER},
+  {AF_GAIN_RX2,                "AF GAIN\nRX2",         NULL,           MIDI_KNOB | MIDI_WHEEL | CONTROLLER_ENCODER},
+  {AGC,                        "AGC",                  "AGC",          MIDI_KEY | CONTROLLER_SWITCH},
+  {AGC_GAIN,           "AGC GAIN",             NULL,           MIDI_KNOB | MIDI_WHEEL | CONTROLLER_ENCODER},
+  {AGC_GAIN_RX1,       "AGC GAIN\nRX1",        NULL,           MIDI_KNOB | MIDI_WHEEL | CONTROLLER_ENCODER},
+  {AGC_GAIN_RX2,       "AGC GAIN\nRX2",        NULL,           MIDI_KNOB | MIDI_WHEEL | CONTROLLER_ENCODER},
+  {ANF,                        "ANF",                  "ANF",          MIDI_KEY | CONTROLLER_SWITCH},
+  {ATTENUATION,                "ATTEN",                NULL,           MIDI_KNOB | MIDI_WHEEL | CONTROLLER_ENCODER},
+  {B_TO_A,             "A<B",                  "A<B",          MIDI_KEY | CONTROLLER_SWITCH},
+  {BAND_10,            "BAND 10",              "10",           MIDI_KEY},
+  {BAND_12,            "BAND 12",              "12",           MIDI_KEY},
+  {BAND_1240,          "BAND 1240",            "1240",         MIDI_KEY},
+  {BAND_144,           "BAND 144",             "144",          MIDI_KEY},
+  {BAND_15,            "BAND 15",              "15",           MIDI_KEY},
+  {BAND_160,           "BAND 160",             "160",          MIDI_KEY},
+  {BAND_17,            "BAND 17",              "17",           MIDI_KEY},
+  {BAND_20,            "BAND 20",              "20",           MIDI_KEY},
+  {BAND_220,           "BAND 220",             "220",          MIDI_KEY},
+  {BAND_2300,          "BAND 2300",            "2300",         MIDI_KEY},
+  {BAND_30,            "BAND 30",              "30",           MIDI_KEY},
+  {BAND_3400,          "BAND 3400",            "3400",         MIDI_KEY},
+  {BAND_40,            "BAND 40",              "40",           MIDI_KEY},
+  {BAND_430,           "BAND 430",             "430",          MIDI_KEY},
+  {BAND_6,             "BAND 6",               "6",            MIDI_KEY},
+  {BAND_60,            "BAND 60",              "60",           MIDI_KEY},
+  {BAND_70,            "BAND 70",              "70",           MIDI_KEY},
+  {BAND_80,            "BAND 80",              "80",           MIDI_KEY},
+  {BAND_902,           "BAND 902",             "902",          MIDI_KEY},
+  {BAND_AIR,           "BAND AIR",             "AIR",          MIDI_KEY},
+  {BAND_GEN,           "BAND GEN",             "GEN",          MIDI_KEY},
+  {BAND_MINUS,         "BAND -",               "BND+",         MIDI_KEY | CONTROLLER_SWITCH},
+  {BAND_PLUS,          "BAND +",               "BND-",         MIDI_KEY | CONTROLLER_SWITCH},
+  {BAND_WWV,           "BAND WWV",             "WWV",          MIDI_KEY},
+  {BANDSTACK_MINUS,    "BANDSTACK -",          "BSTK-",        MIDI_KEY | CONTROLLER_SWITCH},
+  {BANDSTACK_PLUS,     "BANDSTACK +",          "BSTK+",        MIDI_KEY | CONTROLLER_SWITCH},
+  {COMP_ENABLE,                "COMP ON/OFF",          "COMP",         MIDI_KEY | CONTROLLER_SWITCH},
+  {COMPRESSION,                "COMPRESSION",          NULL,           MIDI_KNOB | MIDI_WHEEL | CONTROLLER_ENCODER},
+  {CTUN,               "CTUN",                 "CTUN",         MIDI_KEY | CONTROLLER_SWITCH},
+  {CW_FREQUENCY,       "CW FREQUENCY",         NULL,           MIDI_KNOB | MIDI_WHEEL | CONTROLLER_ENCODER},
+  {CW_KEYER,            "CW(keyer)",            NULL,           MIDI_KEY},
+  {CW_LEFT,            "CW LEFT",              "CWL",          MIDI_KEY | CONTROLLER_SWITCH},
+  {CW_RIGHT,           "CW RIGHT",             "CWR",          MIDI_KEY | CONTROLLER_SWITCH},
+  {CW_SPEED,           "CW SPEED",             NULL,           MIDI_KNOB | MIDI_WHEEL | CONTROLLER_ENCODER},
+  {DIV,                        "DIV ON/OFF",           "DIV",          MIDI_KEY | CONTROLLER_SWITCH},
+  {DIV_GAIN,           "DIV GAIN",             NULL,           MIDI_KNOB | MIDI_WHEEL | CONTROLLER_ENCODER},
+  {DIV_GAIN_COARSE,    "DIV GAIN\nCOARSE",     NULL,           MIDI_KNOB | MIDI_WHEEL | CONTROLLER_ENCODER},
+  {DIV_GAIN_FINE,      "DIV GAIN\nFINE",       NULL,           MIDI_KNOB | MIDI_WHEEL | CONTROLLER_ENCODER},
+  {DIV_PHASE,          "DIV PHASE",            NULL,           MIDI_KNOB | MIDI_WHEEL | CONTROLLER_ENCODER},
+  {DIV_PHASE_COARSE,   "DIV PHASE\nCOARSE",    NULL,           MIDI_KNOB | MIDI_WHEEL | CONTROLLER_ENCODER},
+  {DIV_PHASE_FINE,     "DIV PHASE\nFINE",      NULL,           MIDI_KNOB | MIDI_WHEEL | CONTROLLER_ENCODER},
+  {DRIVE,              "TX DRIVE",             NULL,           MIDI_KNOB | MIDI_WHEEL | CONTROLLER_ENCODER},
+  {DUPLEX,             "DUPLEX",               "DUP",          MIDI_KEY | CONTROLLER_SWITCH},
+  {FILTER_MINUS,       "FILTER +",             "FL+",          MIDI_KEY | CONTROLLER_SWITCH},
+  {FILTER_PLUS,                "FILTER -",             "FL-",          MIDI_KEY | CONTROLLER_SWITCH},
+  {FUNCTION,           "FUNC",                 "FUNC",         CONTROLLER_SWITCH},
+  {IF_SHIFT,           "IF SHIFT",             NULL,           MIDI_KNOB | MIDI_WHEEL | CONTROLLER_ENCODER},
+  {IF_SHIFT_RX1,       "IF SHIFT\nRX1",        NULL,           MIDI_KNOB | MIDI_WHEEL | CONTROLLER_ENCODER},
+  {IF_SHIFT_RX2,       "IF SHIFT\nRX2",        NULL,           MIDI_KNOB | MIDI_WHEEL | CONTROLLER_ENCODER},
+  {IF_WIDTH,           "IF WIDTH",             NULL,           MIDI_KNOB | MIDI_WHEEL | CONTROLLER_ENCODER},
+  {IF_WIDTH_RX1,       "IF WIDTH\nRX1",        NULL,           MIDI_KNOB | MIDI_WHEEL | CONTROLLER_ENCODER},
+  {IF_WIDTH_RX2,       "IF WIDTH\nRX2",        NULL,           MIDI_KNOB | MIDI_WHEEL | CONTROLLER_ENCODER},
+  {LINEIN_GAIN,                "LINEIN\nGAIN",         NULL,           MIDI_KNOB | MIDI_WHEEL | CONTROLLER_ENCODER},
+  {LOCK,               "LOCK",                 "LOCK",         MIDI_KEY | CONTROLLER_SWITCH},
+  {MENU_AGC,           "AGC\nMENU",            "AGC",          MIDI_KEY | CONTROLLER_SWITCH},
+  {MENU_BAND,          "BAND\nMENU",           "BAND",         MIDI_KEY | CONTROLLER_SWITCH},
+  {MENU_BANDSTACK,     "BSTK\nMENU",           "BSTK",         MIDI_KEY | CONTROLLER_SWITCH},
+  {MENU_DIVERSITY,     "DIV\nMENU",            "DIV",          MIDI_KEY | CONTROLLER_SWITCH},
+  {MENU_FILTER,                "FILT\nMENU",           "FILT",         MIDI_KEY | CONTROLLER_SWITCH},
+  {MENU_FREQUENCY,     "FREQ\nMENU",           "FREQ",         MIDI_KEY | CONTROLLER_SWITCH},
+  {MENU_MEMORY,                "MEM\nMENU",            "MEM",          MIDI_KEY | CONTROLLER_SWITCH},
+  {MENU_MODE,          "MODE\nMENU",           "MODE",         MIDI_KEY | CONTROLLER_SWITCH},
+  {MENU_NOISE,         "NOISE\nMENU",          "NOISE",        MIDI_KEY | CONTROLLER_SWITCH},
+  {MENU_PS,            "PS MENU",              "PS",           MIDI_KEY | CONTROLLER_SWITCH},
+  {MIC_GAIN,           "MIC GAIN",             NULL,           MIDI_KNOB | MIDI_WHEEL | CONTROLLER_ENCODER},
+  {MODE_MINUS,         "MODE -",               "MD-",          MIDI_KEY | CONTROLLER_SWITCH},
+  {MODE_PLUS,          "MODE +",               "MD+",          MIDI_KEY | CONTROLLER_SWITCH},
+  {MOX,                        "MOX",                  "MOX",          MIDI_KEY | CONTROLLER_SWITCH},
+  {MUTE,               "MUTE",                 "MUTE",         MIDI_KEY | CONTROLLER_SWITCH},
+  {NB,                 "NB",                   "NB",           MIDI_KEY | CONTROLLER_SWITCH},
+  {NR,                 "NR",                   "NR",           MIDI_KEY | CONTROLLER_SWITCH},
+  {NUMPAD_0,           "NUMPAD 0",             "0",            MIDI_KEY},
+  {NUMPAD_1,           "NUMPAD 1",             "1",            MIDI_KEY},
+  {NUMPAD_2,           "NUMPAD 2",             "2",            MIDI_KEY},
+  {NUMPAD_3,           "NUMPAD 3",             "3",            MIDI_KEY},
+  {NUMPAD_4,           "NUMPAD 4",             "4",            MIDI_KEY},
+  {NUMPAD_5,           "NUMPAD 5",             "5",            MIDI_KEY},
+  {NUMPAD_6,           "NUMPAD 6",             "6",            MIDI_KEY},
+  {NUMPAD_7,           "NUMPAD 7",             "7",            MIDI_KEY},
+  {NUMPAD_8,           "NUMPAD 8",             "8",            MIDI_KEY},
+  {NUMPAD_9,           "NUMPAD 9",             "9",            MIDI_KEY},
+  {NUMPAD_CL,          "NUMPAD\nCL",           "CL",           MIDI_KEY},
+  {NUMPAD_ENTER,       "NUMPAD\nENTER",        "EN",           MIDI_KEY},
+  {PAN,                        "PAN",                  NULL,           MIDI_KNOB | MIDI_WHEEL | CONTROLLER_ENCODER},
+  {PAN_MINUS,          "PAN -",                "PAN-",         MIDI_KEY | CONTROLLER_SWITCH},
+  {PAN_PLUS,           "PAN +",                "PAN+",         MIDI_KEY | CONTROLLER_SWITCH},
+  {PANADAPTER_HIGH,    "PAN HIGH",             NULL,           MIDI_KNOB | MIDI_WHEEL | CONTROLLER_ENCODER},
+  {PANADAPTER_LOW,     "PAN LOW",              NULL,           MIDI_KNOB | MIDI_WHEEL | CONTROLLER_ENCODER},
+  {PANADAPTER_STEP,    "PAN STEP",             NULL,           MIDI_KNOB | MIDI_WHEEL | CONTROLLER_ENCODER},
+  {PREAMP,             "PREAMP\nON/OFF",       "PRE",          MIDI_KEY | CONTROLLER_SWITCH},
+  {PS,                 "PS ON/OFF",            "PS",           MIDI_KEY | CONTROLLER_SWITCH},
+  {PTT,                        "PTT",                  "PTT",          MIDI_KEY | CONTROLLER_SWITCH},
+  {PTT_KEYER,          "PTT(keyer)",           NULL,           MIDI_KEY},
+  {RF_GAIN,            "RF GAIN",              NULL,           MIDI_KNOB | MIDI_WHEEL | CONTROLLER_ENCODER},
+  {RF_GAIN_RX1,                "RF GAIN\nRX1",         NULL,           MIDI_KNOB | MIDI_WHEEL | CONTROLLER_ENCODER},
+  {RF_GAIN_RX2,                "RF GAIN\nRX2",         NULL,           MIDI_KNOB | MIDI_WHEEL | CONTROLLER_ENCODER},
+  {RIT,                        "RIT",                  NULL,           MIDI_KNOB | MIDI_WHEEL | CONTROLLER_ENCODER},
+  {RIT_CLEAR,          "RIT\nCLEAR",           "RITCL",        MIDI_KEY | CONTROLLER_SWITCH},
+  {RIT_ENABLE,         "RIT\nON/OFF",          "RIT",          MIDI_KEY | CONTROLLER_SWITCH},
+  {RIT_MINUS,          "RIT +",                "RIT-",         MIDI_KEY | CONTROLLER_SWITCH},
+  {RIT_PLUS,           "RIT -",                "RIT+",         MIDI_KEY | CONTROLLER_SWITCH},
+  {RIT_RX1,            "RIT\nRX1",             NULL,           MIDI_KNOB | MIDI_WHEEL | CONTROLLER_ENCODER},
+  {RIT_RX2,            "RIT\nRX2",             NULL,           MIDI_KNOB | MIDI_WHEEL | CONTROLLER_ENCODER},
+  {RIT_STEP,           "RIT\nSTEP",            "RITST",        MIDI_KEY | CONTROLLER_SWITCH},
+  {RSAT,               "RSAT",                 "RSAT",         MIDI_KEY | CONTROLLER_SWITCH},
+  {SAT,                        "SAT",                  "SAT",          MIDI_KEY | CONTROLLER_SWITCH},
+  {SNB,                        "SNB",                  "SNB",          MIDI_KEY | CONTROLLER_SWITCH},
+  {SPLIT,              "SPLIT",                "SPLIT",        MIDI_KEY | CONTROLLER_SWITCH},
+  {SQUELCH,            "SQUELCH",              NULL,           MIDI_KNOB | MIDI_WHEEL | CONTROLLER_ENCODER},
+  {SQUELCH_RX1,                "SQUELCH\nRX1",         NULL,           MIDI_KNOB | MIDI_WHEEL | CONTROLLER_ENCODER},
+  {SQUELCH_RX2,                "SQUELCH\nRX1",         NULL,           MIDI_KNOB | MIDI_WHEEL | CONTROLLER_ENCODER},
+  {SWAP_RX,            "SWAP RX",              "SWAPRX",       MIDI_KEY | CONTROLLER_SWITCH},
+  {TUNE,               "TUNE",                 "TUNE",         MIDI_KEY | CONTROLLER_SWITCH},
+  {TUNE_DRIVE,         "TUNE\nDRV",            NULL,           MIDI_KNOB | MIDI_WHEEL | CONTROLLER_ENCODER},
+  {TUNE_FULL,          "TUNE\nFUL",            "TUNF",         MIDI_KEY | CONTROLLER_SWITCH},
+  {TUNE_MEMORY,                "TUNE\nMEM",            "TUNM",         MIDI_KEY | CONTROLLER_SWITCH},
+  {TWO_TONE,           "TWO TONE",             "2TONE",        MIDI_KEY | CONTROLLER_SWITCH},
+  {VFO,                        "VFO",                  NULL,           MIDI_WHEEL | CONTROLLER_ENCODER},
+  {VFO_STEP_MINUS,     "VFO STEP -",           "STEP-",        MIDI_KEY | CONTROLLER_SWITCH},
+  {VFO_STEP_PLUS,      "VFO STEP +",           "STEP+",        MIDI_KEY | CONTROLLER_SWITCH},
+  {VFOA,               "VFO A",                NULL,           MIDI_WHEEL | CONTROLLER_ENCODER},
+  {VFOB,               "VFO B",                NULL,           MIDI_WHEEL | CONTROLLER_ENCODER},
+  {VOX,                        "VOX\nON/OFF",          "VOX",          MIDI_KEY | CONTROLLER_SWITCH},
+  {VOXLEVEL,           "VOX\nLEVEL",           NULL,           MIDI_WHEEL | CONTROLLER_ENCODER},
+  {WATERFALL_HIGH,     "WFALL\nHIGH",          NULL,           MIDI_WHEEL | CONTROLLER_ENCODER},
+  {WATERFALL_LOW,      "WFALL\nLOW",           NULL,           MIDI_WHEEL | CONTROLLER_ENCODER},
+  {XIT ,               "XIT",                  NULL,           MIDI_WHEEL | CONTROLLER_ENCODER},
+  {XIT_CLEAR,          "XIT\nCLEAR",           "XITCL",        MIDI_KEY | CONTROLLER_SWITCH},
+  {XIT_ENABLE,         "XIT\nON/OFF",          "XIT",          MIDI_KEY | CONTROLLER_SWITCH},
+  {XIT_MINUS,          "XIT -",                "XIT-",         MIDI_KEY | CONTROLLER_SWITCH},
+  {XIT_PLUS,           "XIT +",                "XIT+",         MIDI_KEY | CONTROLLER_SWITCH},
+  {ZOOM,               "ZOOM",                 NULL,           MIDI_WHEEL | CONTROLLER_ENCODER},
+  {ZOOM_MINUS,         "ZOOM -",               "ZOOM-",        MIDI_KEY | CONTROLLER_SWITCH},
+  {ZOOM_PLUS,          "ZOOM +",               "ZOOM+",        MIDI_KEY | CONTROLLER_SWITCH},
+  {ACTIONS,            "",                     NULL,           TYPE_NONE}
 };
 
 
-int encoder_action(void *data) {
-  ENCODER_ACTION *a=(ENCODER_ACTION *)data;
+int process_action(void *data) {
+  PROCESS_ACTION *a=(PROCESS_ACTION *)data;
   double value;
   int mode;
   int id;
@@ -205,14 +194,31 @@ int encoder_action(void *data) {
   FILTER *band_filter;
   FILTER *filter;
   int new_val;
+  int i;
 
+  g_print("%s: action=%d mode=%d value=%d\n",__FUNCTION__,a->action,a->mode,a->val);
   switch(a->action) {
-    case ENCODER_VFO:
-      vfo_step(a->val);
+
+    case A_SWAP_B:
+      if(a->mode==PRESSED) {
+        vfo_a_swap_b();
+      }
+      break;
+    case A_TO_B:
+      if(a->mode==PRESSED) {
+        vfo_a_to_b();
+      }
       break;
-    case ENCODER_AF_GAIN:
+    case AF_GAIN:
       value=active_receiver->volume;
-      value+=a->val/100.0;
+      switch(a->mode) {
+       case RELATIVE:
+          value+=a->val/100.0;
+         break;
+       case ABSOLUTE:
+         value=a->val/100.0;
+         break;
+      }
       if(value<0.0) {
         value=0.0;
       } else if(value>1.0) {
@@ -220,7 +226,7 @@ int encoder_action(void *data) {
       }
       set_af_gain(active_receiver->id,value);
       break;
-    case ENCODER_AF_GAIN_RX1:
+    case AF_GAIN_RX1:
       value=receiver[0]->volume;
       value+=a->val/100.0;
       if(value<0.0) {
@@ -230,7 +236,7 @@ int encoder_action(void *data) {
       }
       set_af_gain(0,value);
       break;
-    case ENCODER_AF_GAIN_RX2:
+    case AF_GAIN_RX2:
       value=receiver[1]->volume;
       value+=a->val/100.0;
       if(value<0.0) {
@@ -240,40 +246,17 @@ int encoder_action(void *data) {
       }
       set_af_gain(1,value);
       break;
-    case ENCODER_RF_GAIN:
-      //value=active_receiver->gain;
-      value=adc[active_receiver->id].gain;
-      value+=a->val;
-      if(value<0.0) {
-        value=0.0;
-      } else if(value>100.0) {
-        value=100.0;
-      }
-      set_rf_gain(active_receiver->id,value);
-      break;
-    case ENCODER_RF_GAIN_RX1:
-      //value=receiver[0]->rf_gain;
-      value=adc[receiver[0]->id].gain;
-      value+=a->val;
-      if(value<0.0) {
-        value=0.0;
-      } else if(value>100.0) {
-        value=100.0;
-      }
-      set_rf_gain(0,value);
-      break;
-    case ENCODER_RF_GAIN_RX2:
-      //value=receiver[1]->rf_gain;
-      value=adc[receiver[1]->id].gain;
-      value+=a->val;
-      if(value<0.0) {
-        value=0.0;
-      } else if(value>71.0) {
-        value=71.0;
+    case AGC:
+      if(a->mode==PRESSED) {
+        active_receiver->agc++;
+        if(active_receiver->agc>+AGC_LAST) {
+          active_receiver->agc=0;
+        }
+        set_agc(active_receiver, active_receiver->agc);
+        g_idle_add(ext_vfo_update, NULL);
       }
-      set_rf_gain(1,value);
       break;
-    case ENCODER_AGC_GAIN:
+    case AGC_GAIN:
       value=active_receiver->agc_gain;
       value+=a->val;
       if(value<-20.0) {
@@ -283,7 +266,7 @@ int encoder_action(void *data) {
       }
       set_agc_gain(active_receiver->id,value);
       break;
-    case ENCODER_AGC_GAIN_RX1:
+    case AGC_GAIN_RX1:
       value=receiver[0]->agc_gain;
       value+=a->val;
       if(value<-20.0) {
@@ -293,7 +276,7 @@ int encoder_action(void *data) {
       }
       set_agc_gain(0,value);
       break;
-    case ENCODER_AGC_GAIN_RX2:
+    case AGC_GAIN_RX2:
       value=receiver[1]->agc_gain;
       value+=a->val;
       if(value<-20.0) {
@@ -303,25 +286,20 @@ int encoder_action(void *data) {
       }
       set_agc_gain(1,value);
       break;
-    case ENCODER_IF_WIDTH:
-      filter_width_changed(active_receiver->id,a->val);
-      break;
-    case ENCODER_IF_WIDTH_RX1:
-      filter_width_changed(0,a->val);
-      break;
-    case ENCODER_IF_WIDTH_RX2:
-      filter_width_changed(1,a->val);
-      break;
-    case ENCODER_IF_SHIFT:
-      filter_shift_changed(active_receiver->id,a->val);
-      break;
-    case ENCODER_IF_SHIFT_RX1:
-      filter_shift_changed(0,a->val);
-      break;
-    case ENCODER_IF_SHIFT_RX2:
-      filter_shift_changed(1,a->val);
+    case ANF:
+      if(a->mode==PRESSED) {
+        if(active_receiver->anf==0) {
+          active_receiver->anf=1;
+          mode_settings[vfo[active_receiver->id].mode].anf=1;
+        } else {
+          active_receiver->anf=0;
+          mode_settings[vfo[active_receiver->id].mode].anf=0;
+        }
+        SetRXAANFRun(active_receiver->id, active_receiver->anf);
+        g_idle_add(ext_vfo_update, NULL);
+      }
       break;
-    case ENCODER_ATTENUATION:
+    case ATTENUATION:
       value=(double)adc[active_receiver->adc].attenuation;
       value+=(double)a->val;
       if(have_rx_gain) {
@@ -339,213 +317,455 @@ int encoder_action(void *data) {
       }
       set_attenuation_value(value);
       break;
-    case ENCODER_MIC_GAIN:
-      value=mic_gain;
-      value+=(double)a->val;
-      if(value<-12.0) {
-        value=-12.0;
-      } else if(value>50.0) {
-        value=50.0;
+    case B_TO_A:
+      if(a->mode==PRESSED) {
+        vfo_b_to_a();
       }
-      set_mic_gain(value);
       break;
-    case ENCODER_DRIVE:
-      value=getDrive();
-      value+=(double)a->val;
-      if(value<0.0) {
-        value=0.0;
-      } else if(value>drive_max) {
-        value=drive_max;
+    case BAND_10:
+      if(a->mode==PRESSED) {
+        vfo_band_changed(active_receiver->id,band160);
       }
-      set_drive(value);
       break;
-    case ENCODER_RIT:
-      vfo_rit(active_receiver->id,a->val);
+    case BAND_12:
+      if(a->mode==PRESSED) {
+        vfo_band_changed(active_receiver->id,band12);
+      }
       break;
-    case ENCODER_RIT_RX1:
-      vfo_rit(receiver[0]->id,a->val);
+#ifdef SOAPYSDR
+    case BAND_1240:
+      if(a->mode==PRESSED) {
+        vfo_band_changed(active_receiver->id,band1240);
+      }
       break;
-    case ENCODER_RIT_RX2:
-      vfo_rit(receiver[1]->id,a->val);
+    case BAND_144:
+      if(a->mode==PRESSED) {
+        vfo_band_changed(active_receiver->id,band144);
+      }
       break;
-    case ENCODER_XIT:
-      value=(double)transmitter->xit;
-      value+=(double)(a->val*rit_increment);
-      if(value<-10000.0) {
-        value=-10000.0;
-      } else if(value>10000.0) {
-        value=10000.0;
+#endif
+    case BAND_15:
+      if(a->mode==PRESSED) {
+        vfo_band_changed(active_receiver->id,band15);
       }
-      transmitter->xit=(int)value;
-      if(protocol==NEW_PROTOCOL) {
-        schedule_high_priority();
+      break;
+    case BAND_160:
+      if(a->mode==PRESSED) {
+        vfo_band_changed(active_receiver->id,band160);
       }
-      g_idle_add(ext_vfo_update,NULL);
       break;
-    case ENCODER_CW_SPEED:
-      value=(double)cw_keyer_speed;
-      value+=(double)a->val;
-      if(value<1.0) {
-        value=1.0;
-      } else if(value>60.0) {
-        value=60.0;
+    case BAND_17:
+      if(a->mode==PRESSED) {
+        vfo_band_changed(active_receiver->id,band17);
       }
-      cw_keyer_speed=(int)value;
-      g_idle_add(ext_vfo_update,NULL);
       break;
-    case ENCODER_CW_FREQUENCY:
-      value=(double)cw_keyer_sidetone_frequency;
-      value+=(double)a->val;
-      if(value<0.0) {
-        value=0.0;
-      } else if(value>1000.0) {
-        value=1000.0;
+    case BAND_20:
+      if(a->mode==PRESSED) {
+        vfo_band_changed(active_receiver->id,band20);
       }
-      cw_keyer_sidetone_frequency=(int)value;
-      g_idle_add(ext_vfo_update,NULL);
       break;
-    case ENCODER_PANADAPTER_HIGH:
-      value=(double)active_receiver->panadapter_high;
-      value+=(double)a->val;
-      active_receiver->panadapter_high=(int)value;
+#ifdef SOAPYSDR
+    case BAND_220:
+      if(a->mode==PRESSED) {
+        vfo_band_changed(active_receiver->id,band220);
+      }
       break;
-    case ENCODER_PANADAPTER_LOW:
-      value=(double)active_receiver->panadapter_low;
-      value+=(double)a->val;
-      active_receiver->panadapter_low=(int)value;
+    case BAND_2300:
+      if(a->mode==PRESSED) {
+        vfo_band_changed(active_receiver->id,band2300);
+      }
       break;
-    case ENCODER_PANADAPTER_STEP:
-      value=(double)active_receiver->panadapter_step;
-      value+=(double)a->val;
-      active_receiver->panadapter_step=(int)value;
+#endif
+    case BAND_30:
+      if(a->mode==PRESSED) {
+        vfo_band_changed(active_receiver->id,band30);
+      }
       break;
-    case ENCODER_WATERFALL_HIGH:
-      value=(double)active_receiver->waterfall_high;
-      value+=(double)a->val;
-      active_receiver->waterfall_high=(int)value;
+#ifdef SOAPYSDR
+    case BAND_3400:
+      if(a->mode==PRESSED) {
+        vfo_band_changed(active_receiver->id,band3400);
+      }
       break;
-    case ENCODER_WATERFALL_LOW:
-      value=(double)active_receiver->waterfall_low;
-      value+=(double)a->val;
-      active_receiver->waterfall_low=(int)value;
+#endif
+    case BAND_40:
+      if(a->mode==PRESSED) {
+        vfo_band_changed(active_receiver->id,band40);
+      }
       break;
-    case ENCODER_SQUELCH:
-      value=active_receiver->squelch;
-      value+=(double)a->val;
-      if(value<0.0) {
-        value=0.0;
-      } else if(value>100.0) {
-        value=100.0;
+#ifdef SOAPYSDR
+    case BAND_430:
+      if(a->mode==PRESSED) {
+        vfo_band_changed(active_receiver->id,band430);
       }
-      active_receiver->squelch=value;
-      set_squelch(active_receiver);
       break;
-    case ENCODER_SQUELCH_RX1:
-      value=receiver[0]->squelch;
-      value+=(double)a->val;
-      if(value<0.0) {
-        value=0.0;
-      } else if(value>100.0) {
-        value=100.0;
+#endif
+    case BAND_6:
+      if(a->mode==PRESSED) {
+        vfo_band_changed(active_receiver->id,band6);
       }
-      receiver[0]->squelch=value;
-      set_squelch(receiver[0]);
       break;
-    case ENCODER_SQUELCH_RX2:
-      value=receiver[1]->squelch;
-      value+=(double)a->val;
-      if(value<0.0) {
-        value=0.0;
-      } else if(value>100.0) {
-        value=100.0;
+    case BAND_60:
+      if(a->mode==PRESSED) {
+        vfo_band_changed(active_receiver->id,band60);
       }
-      receiver[1]->squelch=value;
-      set_squelch(receiver[1]);
       break;
-    case ENCODER_COMP:
-      value=(double)transmitter->compressor_level;
-      value+=(double)a->val;
-      if(value<0.0) {
-        value=0.0;
-      } else if(value>20.0) {
-        value=20.0;
+#ifdef SOAPYSDR
+    case BAND_70:
+      if(a->mode==PRESSED) {
+        vfo_band_changed(active_receiver->id,band70);
       }
-      transmitter->compressor_level=(int)value;
-      set_compression(transmitter);
       break;
-    case ENCODER_DIVERSITY_GAIN:
-      update_diversity_gain((double)a->val * 0.5);
+#endif
+    case BAND_80:
+      if(a->mode==PRESSED) {
+        vfo_band_changed(active_receiver->id,band80);
+      }
       break;
-    case ENCODER_DIVERSITY_GAIN_COARSE:
-      update_diversity_gain((double)a->val * 2.5);
+#ifdef SOAPYSDR
+    case BAND_902:
+      if(a->mode==PRESSED) {
+        vfo_band_changed(active_receiver->id,band902);
+      }
       break;
-    case ENCODER_DIVERSITY_GAIN_FINE:
-      update_diversity_gain((double)a->val * 0.1);
+    case BAND_AIR:
+      if(a->mode==PRESSED) {
+        vfo_band_changed(active_receiver->id,bandAIR);
+      }
       break;
-    case ENCODER_DIVERSITY_PHASE:
-      update_diversity_phase((double)a->val* 0.5);
+#endif
+    case BAND_GEN:
+      if(a->mode==PRESSED) {
+        vfo_band_changed(active_receiver->id,bandGen);
+      }
       break;
-    case ENCODER_DIVERSITY_PHASE_COARSE:
-      update_diversity_phase((double)a->val*2.5);
+    case BAND_MINUS:
+      if(a->mode==PRESSED) {
+        long long frequency_min=radio->frequency_min;
+        long long frequency_max=radio->frequency_max;
+        int b=vfo[active_receiver->id].band;
+        BAND *band;
+        int found=0;
+        while(!found) {
+          b--;
+          if(b<0) b=BANDS+XVTRS-1;
+          band=(BAND*)band_get_band(b);
+          if(strlen(band->title)>0) {
+            if(b<BANDS) {
+              if(band->frequencyMin<frequency_min || band->frequencyMax>frequency_max) {
+                continue;
+              }
+            }
+            vfo_band_changed(active_receiver->id,b);
+            found=1;
+          }
+        }
+      }
       break;
-    case ENCODER_DIVERSITY_PHASE_FINE:
-      update_diversity_phase((double)a->val*0.1);
+    case BAND_PLUS:
+      if(a->mode==PRESSED) {
+        long long frequency_min=radio->frequency_min;
+        long long frequency_max=radio->frequency_max;
+        int b=vfo[active_receiver->id].band;
+        BAND *band;
+        int found=0;
+        while(!found) {
+          b++;
+          if(b>=BANDS+XVTRS) b=0;
+          band=(BAND*)band_get_band(b);
+          if(strlen(band->title)>0) {
+            if(b<BANDS) {
+              if(!(band->frequencyMin==0.0 && band->frequencyMax==0.0)) {
+                if(band->frequencyMin<frequency_min || band->frequencyMax>frequency_max) {
+                  continue;
+                }
+              }
+            }
+            vfo_band_changed(active_receiver->id,b);
+            found=1;
+          }
+        }
+      }
       break;
-    case ENCODER_ZOOM:
-      update_zoom((double)a->val);
+    case BAND_WWV:
+      if(a->mode==PRESSED) {
+        vfo_band_changed(active_receiver->id,bandWWV);
+      }
       break;
-    case ENCODER_PAN:
-      update_pan((double)a->val*100);
+    case BANDSTACK_MINUS:
+      if(a->mode==PRESSED) {
+        BAND *band=band_get_band(vfo[active_receiver->id].band);
+        BANDSTACK *bandstack=band->bandstack;
+        int b=vfo[active_receiver->id].bandstack-1;
+        if(b<0) b=bandstack->entries-1;;
+        vfo_bandstack_changed(b);
+      }
       break;
-  }
-  g_free(data);
-  return 0;
-}
-
-int switch_action(void *data) {
-  int i;
-  SWITCH_ACTION *a=(SWITCH_ACTION *)data;
-  if(a->state==PRESSED) {
-    switch(a->action) {
-      case FUNCTION:
-       switch(controller) {
-          case NO_CONTROLLER:
-          case CONTROLLER1:
-            function++;
-            if(function>=MAX_FUNCTIONS) {
-              function=0;
-            }
-            toolbar_switches=switches_controller1[function];
-            switches=switches_controller1[function];
-            update_toolbar_labels();
-           break;
-         case CONTROLLER2_V1:
-         case CONTROLLER2_V2:
-            function++;
-            if(function>=MAX_FUNCTIONS) {
-              function=0;
-            }
-            toolbar_switches=switches_controller1[function];
-            update_toolbar_labels();
-           break;
+    case BANDSTACK_PLUS:
+      if(a->mode==PRESSED) {
+        BAND *band=band_get_band(vfo[active_receiver->id].band);
+        BANDSTACK *bandstack=band->bandstack;
+        int b=vfo[active_receiver->id].bandstack+1;
+        if(b>=bandstack->entries) b=0;
+        vfo_bandstack_changed(b);
+      }
+      break;
+    case COMP_ENABLE:
+      if(can_transmit) {
+        transmitter_set_compressor(transmitter,transmitter->compressor?FALSE:TRUE);
+      }
+      break;
+    case COMPRESSION:
+      if(can_transmit) {
+        value=transmitter->compressor_level;
+        value+=a->val;
+        if(value<0.0) {
+          value=0.0;
+        } else if(value>20.0) {
+          value=20.0;
         }
-        break;
-      case TUNE:
-       if(getMox()==1) {
-          setMox(0);
+       transmitter_set_compressor_level(transmitter,value);
+      }
+      break;
+    case CTUN:
+      if(a->mode==PRESSED) {
+        vfo[active_receiver->id].ctun=!vfo[active_receiver->id].ctun;
+        if(!vfo[active_receiver->id].ctun) {
+          vfo[active_receiver->id].offset=0;
         }
-        if(getTune()==0) {
-          if(canTransmit() || tx_out_of_band) {
-            setTune(1);
-          } else {
-            transmitter_set_out_of_band(transmitter);
-          }
-        } else {
-          setTune(0);
+        vfo[active_receiver->id].ctun_frequency=vfo[active_receiver->id].frequency;
+        set_offset(receiver[active_receiver->id],vfo[active_receiver->id].offset);
+        g_idle_add(ext_vfo_update, NULL);
+      }
+      break;
+    case CW_FREQUENCY:
+#ifdef LOCALCW
+      value=(double)cw_keyer_sidetone_frequency;
+      value+=(double)a->val;
+      if(value<0.0) {
+        value=0.0;
+      } else if(value>1000.0) {
+        value=1000.0;
+      }
+      cw_keyer_sidetone_frequency=(int)value;
+      g_idle_add(ext_vfo_update,NULL);
+#endif
+      break;
+    case CW_LEFT:
+    case CW_RIGHT:
+      if(a->mode==PRESSED || a->mode==RELEASED) {
+#ifdef LOCALCW
+        keyer_event(a->action==CW_LEFT,a->mode==PRESSED);
+#endif
+      }
+      break;
+    case CW_SPEED:
+#ifdef LOCALCW
+      value=(double)cw_keyer_speed;
+      value+=(double)a->val;
+      if(value<1.0) {
+        value=1.0;
+      } else if(value>60.0) {
+        value=60.0;
+      }
+      cw_keyer_speed=(int)value;
+      g_idle_add(ext_vfo_update,NULL);
+#endif
+      break;
+    case DIV:
+      if(a->mode==PRESSED) {
+        diversity_enabled=diversity_enabled==1?0:1;
+        if (protocol == NEW_PROTOCOL) {
+          schedule_high_priority();
+          schedule_receive_specific();
         }
-        g_idle_add(ext_vfo_update,NULL);
-        break;
-      case MOX:
+        g_idle_add(ext_vfo_update, NULL);
+      }
+      break;
+    case DIV_GAIN:
+      update_diversity_gain((double)a->val * 0.5);
+      break;
+    case DIV_GAIN_COARSE:
+      update_diversity_gain((double)a->val * 2.5);
+      break;
+    case DIV_GAIN_FINE:
+      update_diversity_gain((double)a->val * 0.1);
+      break;
+    case DIV_PHASE:
+      update_diversity_phase((double)a->val* 0.5);
+      break;
+    case DIV_PHASE_COARSE:
+      update_diversity_phase((double)a->val*2.5);
+      break;
+    case DIV_PHASE_FINE:
+      update_diversity_phase((double)a->val*0.1);
+      break;
+    case DRIVE:
+      value=getDrive();
+      value+=(double)a->val;
+      if(value<0.0) {
+        value=0.0;
+      } else if(value>drive_max) {
+        value=drive_max;
+      }
+      set_drive(value);
+      break;
+    case DUPLEX:
+      if(can_transmit && !isTransmitting()) {
+        duplex=duplex==1?0:1;
+        g_idle_add(ext_set_duplex, NULL);
+      }
+      break;
+    case FILTER_MINUS:
+      if(a->mode==PRESSED) {
+        int f=vfo[active_receiver->id].filter+1;
+        if(f>=FILTERS) f=0;
+        vfo_filter_changed(f);
+      }
+      break;
+    case FILTER_PLUS:
+      if(a->mode==PRESSED) {
+        int f=vfo[active_receiver->id].filter-1;
+        if(f<0) f=FILTERS-1;
+        vfo_filter_changed(f);
+      }
+      break;
+    case FUNCTION:
+      switch(controller) {
+        case NO_CONTROLLER:
+        case CONTROLLER1:
+          function++;
+          if(function>=MAX_FUNCTIONS) {
+            function=0;
+          }
+          toolbar_switches=switches_controller1[function];
+          switches=switches_controller1[function];
+          update_toolbar_labels();
+         break;
+       case CONTROLLER2_V1:
+       case CONTROLLER2_V2:
+          function++;
+          if(function>=MAX_FUNCTIONS) {
+            function=0;
+          }
+          toolbar_switches=switches_controller1[function];
+          update_toolbar_labels();
+         break;
+      }
+      break;
+    case IF_SHIFT:
+      filter_shift_changed(active_receiver->id,a->val);
+      break;
+    case IF_SHIFT_RX1:
+      filter_shift_changed(0,a->val);
+      break;
+    case IF_SHIFT_RX2:
+      filter_shift_changed(1,a->val);
+      break;
+    case IF_WIDTH:
+      filter_width_changed(active_receiver->id,a->val);
+      break;
+    case IF_WIDTH_RX1:
+      filter_width_changed(0,a->val);
+      break;
+    case IF_WIDTH_RX2:
+      filter_width_changed(1,a->val);
+      break;
+    //case LINEIN_GAIN:
+    case LOCK:
+      if(a->mode==PRESSED) {
+#ifdef CLIENT_SERVER
+        if(radio_is_remote) {
+          send_lock(client_socket,locked==1?0:1);
+        } else {
+#endif
+          locked=locked==1?0:1;
+          g_idle_add(ext_vfo_update, NULL);
+#ifdef CLIENT_SERVER
+        }
+#endif
+      }
+      break;
+    case MENU_AGC:
+      if(a->mode==PRESSED) {
+        start_agc();
+      }
+      break;
+    case MENU_BAND:
+      if(a->mode==PRESSED) {
+        start_band();
+      }
+      break;
+    case MENU_BANDSTACK:
+      if(a->mode==PRESSED) {
+        start_bandstack();
+      }
+      break;
+    case MENU_DIVERSITY:
+      if(a->mode==PRESSED) {
+        start_diversity();
+      }
+      break;
+    case MENU_FILTER:
+      if(a->mode==PRESSED) {
+        start_filter();
+      }
+      break;
+    case MENU_FREQUENCY:
+      if(a->mode==PRESSED) {
+        start_vfo(active_receiver->id);
+      }
+      break;
+    case MENU_MEMORY:
+      if(a->mode==PRESSED) {
+        start_store();
+      }
+      break;
+    case MENU_MODE:
+      if(a->mode==PRESSED) {
+        start_mode();
+      }
+      break;
+    case MENU_NOISE:
+      if(a->mode==PRESSED) {
+        start_noise();
+      }
+      break;
+#ifdef PURESIGNAL
+    case MENU_PS:
+      if(a->mode==PRESSED) {
+        start_ps();
+      }
+      break;
+#endif
+    case MIC_GAIN:
+      value=mic_gain;
+      value+=(double)a->val;
+      if(value<-12.0) {
+        value=-12.0;
+      } else if(value>50.0) {
+        value=50.0;
+      }
+      set_mic_gain(value);
+      break;
+    case MODE_MINUS:
+      if(a->mode==PRESSED) {
+        int mode=vfo[active_receiver->id].mode;
+        mode--;
+        if(mode<0) mode=MODES-1;
+        vfo_mode_changed(mode);
+      }
+      break;
+    case MODE_PLUS:
+      if(a->mode==PRESSED) {
+        int mode=vfo[active_receiver->id].mode;
+        mode++;
+        if(mode>=MODES) mode=0;
+        vfo_mode_changed(mode);
+      }
+      break;
+    case MOX:
+      if(a->mode==PRESSED) {
         if(getTune()==1) {
           setTune(0);
         }
@@ -559,105 +779,436 @@ int switch_action(void *data) {
           setMox(0);
         }
         g_idle_add(ext_vfo_update,NULL);
-        break;
-      case PS:
+      }
+      break;
+    case MUTE:
+      if(a->mode==PRESSED) {
+        active_receiver->mute_radio=!active_receiver->mute_radio;
+      }
+      break;
+    case NB:
+      if(a->mode==PRESSED) {
+        if(active_receiver->nb==0 && active_receiver->nb2==0) {
+          active_receiver->nb=1;
+          active_receiver->nb2=0;
+          mode_settings[vfo[active_receiver->id].mode].nb=1;
+          mode_settings[vfo[active_receiver->id].mode].nb2=0;
+        } else if(active_receiver->nb==1 && active_receiver->nb2==0) {
+          active_receiver->nb=0;
+          active_receiver->nb2=1;
+          mode_settings[vfo[active_receiver->id].mode].nb=0;
+          mode_settings[vfo[active_receiver->id].mode].nb2=1;
+        } else if(active_receiver->nb==0 && active_receiver->nb2==1) {
+          active_receiver->nb=0;
+          active_receiver->nb2=0;
+          mode_settings[vfo[active_receiver->id].mode].nb=0;
+          mode_settings[vfo[active_receiver->id].mode].nb2=0;
+        }
+        update_noise();
+      }
+      break;
+    case NR:
+      if(a->mode==PRESSED) {
+        if(active_receiver->nr==0 && active_receiver->nr2==0) {
+          active_receiver->nr=1;
+          active_receiver->nr2=0;
+          mode_settings[vfo[active_receiver->id].mode].nr=1;
+          mode_settings[vfo[active_receiver->id].mode].nr2=0;
+        } else if(active_receiver->nr==1 && active_receiver->nr2==0) {
+          active_receiver->nr=0;
+          active_receiver->nr2=1;
+          mode_settings[vfo[active_receiver->id].mode].nr=0;
+          mode_settings[vfo[active_receiver->id].mode].nr2=1;
+        } else if(active_receiver->nr==0 && active_receiver->nr2==1) {
+          active_receiver->nr=0;
+          active_receiver->nr2=0;
+          mode_settings[vfo[active_receiver->id].mode].nr=0;
+          mode_settings[vfo[active_receiver->id].mode].nr2=0;
+        }
+        update_noise();
+      }
+      break;
+    case NUMPAD_0:
+      g_idle_add(ext_num_pad,GINT_TO_POINTER(0));
+      break;
+    case NUMPAD_1:
+      g_idle_add(ext_num_pad,GINT_TO_POINTER(1));
+      break;
+    case NUMPAD_2:
+      g_idle_add(ext_num_pad,GINT_TO_POINTER(2));
+      break;
+    case NUMPAD_3:
+      g_idle_add(ext_num_pad,GINT_TO_POINTER(3));
+      break;
+    case NUMPAD_4:
+      g_idle_add(ext_num_pad,GINT_TO_POINTER(4));
+      break;
+    case NUMPAD_5:
+      g_idle_add(ext_num_pad,GINT_TO_POINTER(5));
+      break;
+    case NUMPAD_6:
+      g_idle_add(ext_num_pad,GINT_TO_POINTER(6));
+      break;
+    case NUMPAD_7:
+      g_idle_add(ext_num_pad,GINT_TO_POINTER(7));
+      break;
+    case NUMPAD_8:
+      g_idle_add(ext_num_pad,GINT_TO_POINTER(8));
+      break;
+    case NUMPAD_9:
+      g_idle_add(ext_num_pad,GINT_TO_POINTER(9));
+      break;
+    case NUMPAD_CL:
+      g_idle_add(ext_num_pad,GINT_TO_POINTER(-1));
+      break;
+    case NUMPAD_ENTER:
+      g_idle_add(ext_num_pad,GINT_TO_POINTER(-2));
+      break;
+    case PAN:
+      update_pan((double)a->val*100);
+      break;
+    case PAN_MINUS:
+      if(a->mode==PRESSED) {
+        update_pan(-100.0);
+      }
+      break;
+    case PAN_PLUS:
+       if(a->mode==PRESSED) {
+         update_pan(+100.0);
+       }
+       break;
+    case PANADAPTER_HIGH:
+      value=(double)active_receiver->panadapter_high;
+      value+=(double)a->val;
+      active_receiver->panadapter_high=(int)value;
+      break;
+    case PANADAPTER_LOW:
+      value=(double)active_receiver->panadapter_low;
+      value+=(double)a->val;
+      active_receiver->panadapter_low=(int)value;
+      break;
+    case PANADAPTER_STEP:
+      value=(double)active_receiver->panadapter_step;
+      value+=(double)a->val;
+      active_receiver->panadapter_step=(int)value;
+      break;
+    case PREAMP:
+    case PS:
 #ifdef PURESIGNAL
+      if(a->mode==PRESSED) {
         if(can_transmit) {
           if(transmitter->puresignal==0) {
             tx_set_ps(transmitter,1);
           } else {
-            tx_set_ps(transmitter,0);
+            tx_set_ps(transmitter,0);
+          }
+        }
+      }
+#endif
+      break;
+    case PTT:
+      if(a->mode==PRESSED || a->mode==RELEASED) {
+       mox_update(a->mode==PRESSED);
+      }
+      break;
+    case RF_GAIN:
+      value=adc[active_receiver->id].gain;
+      value+=a->val;
+      if(value<0.0) {
+        value=0.0;
+      } else if(value>100.0) {
+        value=100.0;
+      }
+      set_rf_gain(active_receiver->id,value);
+      break;
+    case RF_GAIN_RX1:
+      value=adc[receiver[0]->id].gain;
+      value+=a->val;
+      if(value<0.0) {
+        value=0.0;
+      } else if(value>100.0) {
+        value=100.0;
+      }
+      set_rf_gain(0,value);
+      break;
+    case RF_GAIN_RX2:
+      value=adc[receiver[1]->id].gain;
+      value+=a->val;
+      if(value<0.0) {
+        value=0.0;
+      } else if(value>71.0) {
+        value=71.0;
+      }
+      set_rf_gain(1,value);
+      break;
+    case RIT:
+      vfo_rit(active_receiver->id,a->val);
+      break;
+    case RIT_CLEAR:
+      if(a->mode==PRESSED) {
+        vfo_rit_clear(active_receiver->id);
+      }
+      break;
+    case RIT_ENABLE:
+      if(a->mode==PRESSED) {
+        vfo_rit_update(active_receiver->id);
+      }
+      break;
+    case RIT_MINUS:
+      if(a->mode==PRESSED) {
+        vfo_rit(active_receiver->id,-1);
+      }
+      break;
+    case RIT_PLUS:
+      if(a->mode==PRESSED) {
+        vfo_rit(active_receiver->id,1);
+      }
+      break;
+    case RIT_RX1:
+      vfo_rit(receiver[0]->id,a->val);
+      break;
+    case RIT_RX2:
+      vfo_rit(receiver[1]->id,a->val);
+      break;
+    case RIT_STEP:
+      switch(a->mode) {
+        case PRESSED:
+         a->val=1;
+         // fall through
+       case RELATIVE:
+         if(a->val>0) {
+            rit_increment=10*rit_increment;
+         } else {
+            rit_increment=rit_increment/10;
+         }
+         if(rit_increment<1) rit_increment=100;
+         if(rit_increment>100) rit_increment=1;
+         break;
+      }
+      g_idle_add(ext_vfo_update,NULL);
+      break;
+    case RSAT:
+      if(a->mode==PRESSED) {
+        sat_mode=RSAT_MODE;
+        g_idle_add(ext_vfo_update, NULL);
+      }
+      break;
+    case SAT:
+      if(a->mode==PRESSED) {
+        sat_mode=SAT_MODE;
+        g_idle_add(ext_vfo_update, NULL);
+      }
+      break;
+    case SNB:
+      if(a->mode==PRESSED) {
+        if(active_receiver->snb==0) {
+          active_receiver->snb=1;
+          mode_settings[vfo[active_receiver->id].mode].snb=1;
+        } else {
+          active_receiver->snb=0;
+        mode_settings[vfo[active_receiver->id].mode].snb=0;
+        }
+        update_noise();
+      }
+      break;
+    case SPLIT:
+      if(a->mode==PRESSED) {
+        if(can_transmit) {
+          split=split==1?0:1;
+          tx_set_mode(transmitter,get_tx_mode());
+          g_idle_add(ext_vfo_update, NULL);
+        }
+      }
+      break;
+    case SQUELCH:
+      value=active_receiver->squelch;
+      value+=(double)a->val;
+      if(value<0.0) {
+        value=0.0;
+      } else if(value>100.0) {
+        value=100.0;
+      }
+      active_receiver->squelch=value;
+      set_squelch(active_receiver);
+      break;
+    case SQUELCH_RX1:
+      value=receiver[0]->squelch;
+      value+=(double)a->val;
+      if(value<0.0) {
+        value=0.0;
+      } else if(value>100.0) {
+        value=100.0;
+      }
+      receiver[0]->squelch=value;
+      set_squelch(receiver[0]);
+      break;
+    case SQUELCH_RX2:
+      value=receiver[1]->squelch;
+      value+=(double)a->val;
+      if(value<0.0) {
+        value=0.0;
+      } else if(value>100.0) {
+        value=100.0;
+      }
+      receiver[1]->squelch=value;
+      set_squelch(receiver[1]);
+      break;
+    case SWAP_RX:
+      if(a->mode==PRESSED) {
+        if(receivers==2) {
+          active_receiver=receiver[active_receiver->id==1?0:1];
+          g_idle_add(menu_active_receiver_changed,NULL);
+          g_idle_add(ext_vfo_update,NULL);
+          g_idle_add(sliders_active_receiver_changed,NULL);
+        }
+      }
+      break;
+    case TUNE:
+      if(a->mode==PRESSED) {
+        if(getMox()==1) {
+          setMox(0);
+        }
+        if(getTune()==0) {
+          if(canTransmit() || tx_out_of_band) {
+            setTune(1);
+          } else {
+            transmitter_set_out_of_band(transmitter);
           }
+        } else {
+          setTune(0);
         }
-#endif
-        break;
-      case TWO_TONE:
+        g_idle_add(ext_vfo_update,NULL);
+      }
+      break;
+    case TUNE_DRIVE:
+      if(can_transmit) {
+        switch(a->mode) {
+          case RELATIVE:
+            if(a->val>0) {
+              transmitter->tune_percent=transmitter->tune_percent+1;
+           }
+            if(a->val<0) {
+              transmitter->tune_percent=transmitter->tune_percent-1;
+           }
+           if(transmitter->tune_percent<0) transmitter->tune_percent=0;
+           if(transmitter->tune_percent>100) transmitter->tune_percent=100;
+            break;
+          case ABSOLUTE:
+           transmitter->tune_percent=(int)a->val;
+           if(transmitter->tune_percent<0) transmitter->tune_percent=0;
+           if(transmitter->tune_percent>100) transmitter->tune_percent=100;
+            break;
+        }
+      }
+      break;
+    case TUNE_FULL:
+      if(a->mode==PRESSED) {
+        if(can_transmit) {
+         full_tune=full_tune?FALSE:TRUE;
+         memory_tune=FALSE;
+       }
+      }
+      break;
+    case TUNE_MEMORY:
+      if(a->mode==PRESSED) {
+        if(can_transmit) {
+         memory_tune=memory_tune?FALSE:TRUE;
+         full_tune=FALSE;
+       }
+      }
+      break;
+    case TWO_TONE:
+      if(a->mode==PRESSED) {
         if(can_transmit) {
           int state=transmitter->twotone?0:1;
           tx_set_twotone(transmitter,state);
         }
-        break;
-      case VFOSTEP_PLUS:
+      }
+      break;
+    case VFO:
+      vfo_step(a->val);
+      break;
+    case VFO_STEP_MINUS:
+      if(a->mode==PRESSED) {
         for(i=0;i<STEPS;i++) {
           if(steps[i]==step) break;
         }
         if(i>=STEPS) i=0;
-       i++;
-       if(i>=STEPS) i=0;
+        i--;
+        if(i<0) i=STEPS-1;
         step=steps[i];
         g_idle_add(ext_vfo_update, NULL);
-       break;
-      case VFOSTEP_MINUS:
+      }
+      break;
+    case VFO_STEP_PLUS:
+      if(a->mode==PRESSED) {
         for(i=0;i<STEPS;i++) {
           if(steps[i]==step) break;
         }
         if(i>=STEPS) i=0;
-       i--;
-       if(i<0) i=STEPS-1;
+        i++;
+        if(i>=STEPS) i=0;
         step=steps[i];
         g_idle_add(ext_vfo_update, NULL);
-       break;
-      case NR:
-        if(active_receiver->nr==0 && active_receiver->nr2==0) {
-          active_receiver->nr=1;
-          active_receiver->nr2=0;
-          mode_settings[vfo[active_receiver->id].mode].nr=1;
-          mode_settings[vfo[active_receiver->id].mode].nr2=0;
-        } else if(active_receiver->nr==1 && active_receiver->nr2==0) {
-          active_receiver->nr=0;
-          active_receiver->nr2=1;
-          mode_settings[vfo[active_receiver->id].mode].nr=0;
-          mode_settings[vfo[active_receiver->id].mode].nr2=1;
-        } else if(active_receiver->nr==0 && active_receiver->nr2==1) {
-          active_receiver->nr=0;
-          active_receiver->nr2=0;
-          mode_settings[vfo[active_receiver->id].mode].nr=0;
-          mode_settings[vfo[active_receiver->id].mode].nr2=0;
-        }
-        update_noise();
-        break;
-      case NB:
-        if(active_receiver->nb==0 && active_receiver->nb2==0) {
-          active_receiver->nb=1;
-          active_receiver->nb2=0;
-          mode_settings[vfo[active_receiver->id].mode].nb=1;
-          mode_settings[vfo[active_receiver->id].mode].nb2=0;
-        } else if(active_receiver->nb==1 && active_receiver->nb2==0) {
-          active_receiver->nb=0;
-          active_receiver->nb2=1;
-          mode_settings[vfo[active_receiver->id].mode].nb=0;
-          mode_settings[vfo[active_receiver->id].mode].nb2=1;
-        } else if(active_receiver->nb==0 && active_receiver->nb2==1) {
-          active_receiver->nb=0;
-          active_receiver->nb2=0;
-          mode_settings[vfo[active_receiver->id].mode].nb=0;
-          mode_settings[vfo[active_receiver->id].mode].nb2=0;
-        }
-        update_noise();
-        break;
-      case SNB:
-        if(active_receiver->snb==0) {
-          active_receiver->snb=1;
-          mode_settings[vfo[active_receiver->id].mode].snb=1;
-        } else {
-          active_receiver->snb=0;
-          mode_settings[vfo[active_receiver->id].mode].snb=0;
+      }
+      break;
+    case VFOA:
+      if(a->mode==RELATIVE && !locked) {
+       vfo_id_step(0,(int)a->val);
+      }
+      break;
+    case VFOB:
+      if(a->mode==RELATIVE && !locked) {
+       vfo_id_step(1,(int)a->val);
+      }
+      break;
+    case VOX:
+      vox_enabled = !vox_enabled;
+      g_idle_add(ext_vfo_update, NULL);
+      break;
+    case VOXLEVEL:
+      if(a->mode==ABSOLUTE) {
+       vox_threshold = 0.01 * a->val;
+      } else if(a->mode==RELATIVE) {
+        vox_threshold += a->val * 0.01;
+        if (vox_threshold > 1.0) vox_threshold=1.0;
+        if (vox_threshold < 0.0) vox_threshold=0.0;
+      }
+      break;
+    case WATERFALL_HIGH:
+      value=(double)active_receiver->waterfall_high;
+      value+=(double)a->val;
+      active_receiver->waterfall_high=(int)value;
+      break;
+    case WATERFALL_LOW:
+      value=(double)active_receiver->waterfall_low;
+      value+=(double)a->val;
+      active_receiver->waterfall_low=(int)value;
+      break;
+    case XIT:
+      value=(double)transmitter->xit;
+      value+=(double)(a->val*rit_increment);
+      if(value<-10000.0) {
+        value=-10000.0;
+      } else if(value>10000.0) {
+        value=10000.0;
+      }
+      transmitter->xit=(int)value;
+      if(protocol==NEW_PROTOCOL) {
+        schedule_high_priority();
+      }
+      g_idle_add(ext_vfo_update,NULL);
+      break;
+    case XIT_CLEAR:
+      if(a->mode==PRESSED) {
+        if(can_transmit) {
+          transmitter->xit=0;
+          g_idle_add(ext_vfo_update, NULL);
         }
-        update_noise();
-        break;
-      case RIT:
-        vfo_rit_update(active_receiver->id);
-        break;
-      case RIT_CLEAR:
-        vfo_rit_clear(active_receiver->id);
-        break;
-      case RIT_MINUS:
-       vfo_rit(active_receiver->id,-1);
-        break;
-      case RIT_PLUS:
-       vfo_rit(active_receiver->id,1);
-        break;
-      case XIT:
+      }
+      break;
+    case XIT_ENABLE:
+      if(a->mode==PRESSED) {
         if(can_transmit) {
           transmitter->xit_enabled=transmitter->xit_enabled==1?0:1;
           if(protocol==NEW_PROTOCOL) {
@@ -665,14 +1216,10 @@ int switch_action(void *data) {
           }
         }
         g_idle_add(ext_vfo_update, NULL);
-        break;
-      case XIT_CLEAR:
-        if(can_transmit) {
-          transmitter->xit=0;
-          g_idle_add(ext_vfo_update, NULL);
-        }
-        break;
-      case XIT_MINUS:
+      }
+      break;
+    case XIT_MINUS:
+      if(a->mode==PRESSED) {
         if(can_transmit) {
           double value=(double)transmitter->xit;
           value-=(double)rit_increment;
@@ -686,9 +1233,11 @@ int switch_action(void *data) {
             schedule_high_priority();
           }
           g_idle_add(ext_vfo_update,NULL);
-       }
-       break;
-      case XIT_PLUS:
+        }
+      }
+      break;
+    case XIT_PLUS:
+      if(a->mode==PRESSED) {
         if(can_transmit) {
           double value=(double)transmitter->xit;
           value+=(double)rit_increment;
@@ -703,227 +1252,29 @@ int switch_action(void *data) {
           }
           g_idle_add(ext_vfo_update,NULL);
         }
-        break;
-      case BAND_PLUS:
-        {
-        long long frequency_min=radio->frequency_min;
-        long long frequency_max=radio->frequency_max;
-        int b=vfo[active_receiver->id].band;
-        BAND *band;
-        int found=0;
-        while(!found) {
-          b++;
-          if(b>=BANDS+XVTRS) b=0;
-          band=(BAND*)band_get_band(b);
-          if(strlen(band->title)>0) {
-            if(b<BANDS) {
-              if(!(band->frequencyMin==0.0 && band->frequencyMax==0.0)) {
-                if(band->frequencyMin<frequency_min || band->frequencyMax>frequency_max) {
-                  continue;
-                }
-              }
-            }
-            vfo_band_changed(active_receiver->id,b);
-            found=1;
-          }
-        }
-        }
-        break;
-      case BAND_MINUS:
-        {
-        long long frequency_min=radio->frequency_min;
-        long long frequency_max=radio->frequency_max;
-        int b=vfo[active_receiver->id].band;
-        BAND *band;
-        int found=0;
-        while(!found) {
-          b--;
-          if(b<0) b=BANDS+XVTRS-1;
-          band=(BAND*)band_get_band(b);
-          if(strlen(band->title)>0) {
-            if(b<BANDS) {
-              if(band->frequencyMin<frequency_min || band->frequencyMax>frequency_max) {
-                continue;
-              }
-            }
-            vfo_band_changed(active_receiver->id,b);
-            found=1;
-          }
-        }
-        }
-        break;
-      case BANDSTACK_PLUS:
-        {
-        BAND *band=band_get_band(vfo[active_receiver->id].band);
-        BANDSTACK *bandstack=band->bandstack;
-        int b=vfo[active_receiver->id].bandstack+1;
-        if(b>=bandstack->entries) b=0;
-        vfo_bandstack_changed(b);
-        }
-        break;
-      case BANDSTACK_MINUS:
-        {
-        BAND *band=band_get_band(vfo[active_receiver->id].band);
-        BANDSTACK *bandstack=band->bandstack;
-        int b=vfo[active_receiver->id].bandstack-1;
-        if(b<0) b=bandstack->entries-1;;
-        vfo_bandstack_changed(b);
-        }
-        break;
-      case MODE_PLUS:
-        {
-        int mode=vfo[active_receiver->id].mode;
-        mode++;
-        if(mode>=MODES) mode=0;
-        vfo_mode_changed(mode);
-        }
-        break;
-      case MODE_MINUS:
-        {
-        int mode=vfo[active_receiver->id].mode;
-        mode--;
-        if(mode<0) mode=MODES-1;
-        vfo_mode_changed(mode);
-        }
-        break;
-      case FILTER_PLUS:
-        {
-        int f=vfo[active_receiver->id].filter-1;
-        if(f<0) f=FILTERS-1;
-        vfo_filter_changed(f);
-        }
-        break;
-      case FILTER_MINUS:
-        {
-        int f=vfo[active_receiver->id].filter+1;
-        if(f>=FILTERS) f=0;
-        vfo_filter_changed(f);
-        }
-        break;
-      case A_TO_B:
-        vfo_a_to_b();
-        break;
-      case B_TO_A:
-        vfo_b_to_a();
-        break;
-      case A_SWAP_B:
-        vfo_a_swap_b();
-        break;
-      case LOCK:
-#ifdef CLIENT_SERVER
-        if(radio_is_remote) {
-          send_lock(client_socket,locked==1?0:1);
-        } else {
-#endif
-          locked=locked==1?0:1;
-          g_idle_add(ext_vfo_update, NULL);
-#ifdef CLIENT_SERVER
-        }
-#endif
-        break;
-      case CTUN:
-        vfo[active_receiver->id].ctun=!vfo[active_receiver->id].ctun;
-        if(!vfo[active_receiver->id].ctun) {
-          vfo[active_receiver->id].offset=0;
-        }
-        vfo[active_receiver->id].ctun_frequency=vfo[active_receiver->id].frequency;
-        set_offset(receiver[active_receiver->id],vfo[active_receiver->id].offset);
-        g_idle_add(ext_vfo_update, NULL);
-        break;
-      case AGC:
-        active_receiver->agc++;
-        if(active_receiver->agc>+AGC_LAST) {
-          active_receiver->agc=0;
-        }
-        set_agc(active_receiver, active_receiver->agc);
-        g_idle_add(ext_vfo_update, NULL);
-        break;
-      case SPLIT:
-        if(can_transmit) {
-          split=split==1?0:1;
-          tx_set_mode(transmitter,get_tx_mode());
-          g_idle_add(ext_vfo_update, NULL);
-        }
-        break;
-      case DIVERSITY:
-        diversity_enabled=diversity_enabled==1?0:1;
-        if (protocol == NEW_PROTOCOL) {
-          schedule_high_priority();
-          schedule_receive_specific();
-        }
-        g_idle_add(ext_vfo_update, NULL);
-        break;
-      case SAT:
-        switch(sat_mode) {
-          case SAT_NONE:
-            sat_mode=SAT_MODE;
-            break;
-          case SAT_MODE:
-            sat_mode=RSAT_MODE;
-            break;
-          case RSAT_MODE:
-            sat_mode=SAT_NONE;
-            break;
-        }
-        g_idle_add(ext_vfo_update, NULL);
-        break;
-      case MENU_AGC:
-        start_agc();
-        break;
-      case MENU_BAND:
-        start_band();
-        break;
-      case MENU_BANDSTACK:
-        start_bandstack();
-        break;
-      case MENU_MODE:
-        start_mode();
-        break;
-      case MENU_NOISE:
-        start_noise();
-        break;
-      case MENU_FILTER:
-        start_filter();
-        break;
-      case MENU_FREQUENCY:
-        start_vfo(active_receiver->id);
-        break;
-      case MENU_MEMORY:
-        start_store();
-        break;
-      case MENU_DIVERSITY:
-        start_diversity();
-        break;
-#ifdef PURESIGNAL
-      case MENU_PS:
-        start_ps();
-        break;
-#endif
-      case MUTE:
-        active_receiver->mute_radio=!active_receiver->mute_radio;
-        break;
-      case PAN_MINUS:
-        update_pan(-100.0);
-        break;
-      case PAN_PLUS:
-        update_pan(+100.0);
-        break;
-      case ZOOM_MINUS:
+      }
+      break;
+    case ZOOM:
+      update_zoom((double)a->val);
+      break;
+    case ZOOM_MINUS:
+      if(a->mode==PRESSED) {
         update_zoom(-1);
-        break;
-      case ZOOM_PLUS:
+      }
+      break;
+    case ZOOM_PLUS:
+      if(a->mode==PRESSED) {
         update_zoom(+1);
-        break;
-      default:
-        g_print("%s: UNKNOWN PRESSED SWITCH ACTION %d\n",__FUNCTION__,a->action);
-        break;
-    }
-  } else if(a->state==RELEASED) {
-    // only switch functions that increment/decrement while pressed
-    switch(a->action) {
-      default:
-        break;
-    }
+      }
+      break;
+
+    default:
+      if(a->action>=0 && a->action<ACTIONS) {
+        g_print("%s: UNKNOWN PRESSED SWITCH ACTION %d (%s)\n",__FUNCTION__,a->action,ActionTable[a->action].str);
+      } else {
+        g_print("%s: INVALID PRESSED SWITCH ACTION %d\n",__FUNCTION__,a->action);
+      }
+      break;
   }
   g_free(data);
   return 0;
index b48c5b396aee745cb2d89b41a1b67cd5d109c764..52bdd97609e9d701e9c68bac2ae6c4f88d5155a9 100644 (file)
--- a/actions.h
+++ b/actions.h
@@ -1,69 +1,71 @@
 
-enum {
-  ENCODER_NO_ACTION=0,
-  ENCODER_AF_GAIN,
-  ENCODER_AF_GAIN_RX1,
-  ENCODER_AF_GAIN_RX2,
-  ENCODER_AGC_GAIN,
-  ENCODER_AGC_GAIN_RX1,
-  ENCODER_AGC_GAIN_RX2,
-  ENCODER_ATTENUATION,
-  ENCODER_COMP,
-  ENCODER_CW_FREQUENCY,
-  ENCODER_CW_SPEED,
-  ENCODER_DIVERSITY_GAIN,
-  ENCODER_DIVERSITY_GAIN_COARSE,
-  ENCODER_DIVERSITY_GAIN_FINE,
-  ENCODER_DIVERSITY_PHASE,
-  ENCODER_DIVERSITY_PHASE_COARSE,
-  ENCODER_DIVERSITY_PHASE_FINE,
-  ENCODER_DRIVE,
-  ENCODER_IF_SHIFT,
-  ENCODER_IF_SHIFT_RX1,
-  ENCODER_IF_SHIFT_RX2,
-  ENCODER_IF_WIDTH,
-  ENCODER_IF_WIDTH_RX1,
-  ENCODER_IF_WIDTH_RX2,
-  ENCODER_MIC_GAIN,
-  ENCODER_PAN,
-  ENCODER_PANADAPTER_HIGH,
-  ENCODER_PANADAPTER_LOW,
-  ENCODER_PANADAPTER_STEP,
-  ENCODER_RF_GAIN,
-  ENCODER_RF_GAIN_RX1,
-  ENCODER_RF_GAIN_RX2,
-  ENCODER_RIT,
-  ENCODER_RIT_RX1,
-  ENCODER_RIT_RX2,
-  ENCODER_SQUELCH,
-  ENCODER_SQUELCH_RX1,
-  ENCODER_SQUELCH_RX2,
-  ENCODER_TUNE_DRIVE,
-  ENCODER_VFO,
-  ENCODER_WATERFALL_HIGH,
-  ENCODER_WATERFALL_LOW,
-  ENCODER_XIT,
-  ENCODER_ZOOM,
-  ENCODER_ACTIONS
-};
-
-enum {
+enum ACTION {
   NO_ACTION=0,
-  A_TO_B,
   A_SWAP_B,
+  A_TO_B,
+  AF_GAIN,
+  AF_GAIN_RX1,
+  AF_GAIN_RX2,
   AGC,
+  AGC_GAIN,
+  AGC_GAIN_RX1,
+  AGC_GAIN_RX2,
   ANF,
+  ATTENUATION,
   B_TO_A,
+  BAND_10,
+  BAND_12,
+  BAND_1240,
+  BAND_144,
+  BAND_15,
+  BAND_160,
+  BAND_17,
+  BAND_20,
+  BAND_220,
+  BAND_2300,
+  BAND_30,
+  BAND_3400,
+  BAND_40,
+  BAND_430,
+  BAND_6,
+  BAND_60,
+  BAND_70,
+  BAND_80,
+  BAND_902,
+  BAND_AIR,
+  BAND_GEN,
   BAND_MINUS,
   BAND_PLUS,
+  BAND_WWV,
   BANDSTACK_MINUS,
   BANDSTACK_PLUS,
+  COMP_ENABLE,
+  COMPRESSION,
   CTUN,
-  DIVERSITY,
+  CW_FREQUENCY,
+  CW_KEYER,
+  CW_LEFT,
+  CW_RIGHT,
+  CW_SPEED,
+  DIV,
+  DIV_GAIN,
+  DIV_GAIN_COARSE,
+  DIV_GAIN_FINE,
+  DIV_PHASE,
+  DIV_PHASE_COARSE,
+  DIV_PHASE_FINE,
+  DRIVE,
   DUPLEX,
   FILTER_MINUS,
   FILTER_PLUS,
   FUNCTION,
+  IF_SHIFT,
+  IF_SHIFT_RX1,
+  IF_SHIFT_RX2,
+  IF_WIDTH,
+  IF_WIDTH_RX1,
+  IF_WIDTH_RX2,
+  LINEIN_GAIN,
   LOCK,
   MENU_AGC,
   MENU_BAND,
@@ -75,63 +77,109 @@ enum {
   MENU_MODE,
   MENU_NOISE,
   MENU_PS,
+  MIC_GAIN,
   MODE_MINUS,
   MODE_PLUS,
   MOX,
   MUTE,
   NB,
   NR,
+  NUMPAD_0,
+  NUMPAD_1,
+  NUMPAD_2,
+  NUMPAD_3,
+  NUMPAD_4,
+  NUMPAD_5,
+  NUMPAD_6,
+  NUMPAD_7,
+  NUMPAD_8,
+  NUMPAD_9,
+  NUMPAD_CL,
+  NUMPAD_ENTER,
+  PAN,
   PAN_MINUS,
   PAN_PLUS,
+  PANADAPTER_HIGH,
+  PANADAPTER_LOW,
+  PANADAPTER_STEP,
+  PREAMP,
   PS,
+  PTT,
+  PTT_KEYER,
+  RF_GAIN,
+  RF_GAIN_RX1,
+  RF_GAIN_RX2,
   RIT,
   RIT_CLEAR,
+  RIT_ENABLE,
   RIT_MINUS,
   RIT_PLUS,
+  RIT_RX1,
+  RIT_RX2,
+  RIT_STEP,
   RSAT,
   SAT,
   SNB,
   SPLIT,
+  SQUELCH,
+  SQUELCH_RX1,
+  SQUELCH_RX2,
+  SWAP_RX,
   TUNE,
+  TUNE_DRIVE,
   TUNE_FULL,
   TUNE_MEMORY,
   TWO_TONE,
-  VFOSTEP_PLUS,
-  VFOSTEP_MINUS,
+  VFO,
+  VFO_STEP_MINUS,
+  VFO_STEP_PLUS,
+  VFOA,
+  VFOB,
+  VOX,
+  VOXLEVEL,
+  WATERFALL_HIGH,
+  WATERFALL_LOW,
   XIT,
   XIT_CLEAR,
+  XIT_ENABLE,
   XIT_MINUS,
   XIT_PLUS,
+  ZOOM,
   ZOOM_MINUS,
   ZOOM_PLUS,
-  SWITCH_ACTIONS,
+  ACTIONS
 };
 
-enum {
-  PRESSED,
-  RELEASED
+enum ACTIONtype {
+  TYPE_NONE=0,
+  MIDI_KEY=1,           // MIDI Button (press event)
+  MIDI_KNOB=2,          // MIDI Knob   (value between 0 and 100)
+  MIDI_WHEEL=4,         // MIDI Wheel  (direction and speed)
+  CONTROLLER_SWITCH=8,  // Controller Button
+  CONTROLLER_ENCODER=16 // Controller Encoder
 };
 
-typedef struct _switch_action {
-  gint action;
-  gboolean state;
-} SWITCH_ACTION;
+typedef struct _action_table {
+  enum ACTION action;
+  const char *str;             // desciptive text
+  const char *button_str;      // short button text
+  enum ACTIONtype type;
+} ACTION_TABLE;
 
-enum {
+enum ACTION_MODE {
   RELATIVE,
-  ABSOLUTE
+  ABSOLUTE,
+  PRESSED,
+  RELEASED
 };
 
-typedef struct _encoder_action {
-  gint action;
-  gboolean mode;
+typedef struct process_action {
+  enum ACTION action;
+  enum ACTION_MODE mode;
   gint val;
-} ENCODER_ACTION;
+} PROCESS_ACTION;
 
-extern char *encoder_string[ENCODER_ACTIONS];
-extern char *sw_string[SWITCH_ACTIONS];
-extern char *sw_cap_string[SWITCH_ACTIONS];
+extern ACTION_TABLE ActionTable[ACTIONS+1];
 
-extern int encoder_action(void *data);
-extern int switch_action(void *data);
+extern int process_action(void *data);
 
index 369b24f121866ec583fd1753ac415f5fb5d7fdbf..2072f9861d95bc2f4dc927152e4a1abb91447d55 100644 (file)
@@ -20,6 +20,7 @@
 
 #include <gtk/gtk.h>
 
+#include "actions.h"
 #include "midi.h"
 #include "midi_menu.h"
 #include "alsa_midi.h"
index a949414480143b34ba79169980bd7571ed0b1b8c..8f7cfc29186a7fd2c5ac5d05527c8e63725e5f87 100644 (file)
@@ -87,50 +87,62 @@ void configure_gpio(GtkWidget *parent) {
   }
 
   if (max_encoders > 0) {
+  // No indent for this block to facilitate "diff"
 
-    grid=gtk_grid_new();
-    gtk_grid_set_column_homogeneous(GTK_GRID(grid),FALSE);
-    gtk_grid_set_row_homogeneous(GTK_GRID(grid),TRUE);
-    gtk_grid_set_column_spacing (GTK_GRID(grid),2);
-    gtk_grid_set_row_spacing (GTK_GRID(grid),2);
+  grid=gtk_grid_new();
+  gtk_grid_set_column_homogeneous(GTK_GRID(grid),FALSE);
+  gtk_grid_set_row_homogeneous(GTK_GRID(grid),TRUE);
+  gtk_grid_set_column_spacing (GTK_GRID(grid),2);
+  gtk_grid_set_row_spacing (GTK_GRID(grid),2);
 
 
 /*
-    widget=gtk_label_new(NULL);
-    gtk_label_set_markup (GTK_LABEL(widget), "<span foreground=\"#ff0000\"><b>Note: Pin number now use Broadcom GPIO</b></span>");
-    gtk_grid_attach(GTK_GRID(grid),widget,col,row,6,1);
+  widget=gtk_label_new(NULL);
+  gtk_label_set_markup (GTK_LABEL(widget), "<span foreground=\"#ff0000\"><b>Note: Pin number now use Broadcom GPIO</b></span>");
+  gtk_grid_attach(GTK_GRID(grid),widget,col,row,6,1);
 
-    row++;
-    col=0;
+  row++;
+  col=0;
 */
-    widget=gtk_label_new("");
-    gtk_grid_attach(GTK_GRID(grid),widget,col,row,1,1);
-    col++;
+  widget=gtk_label_new("");
+  gtk_grid_attach(GTK_GRID(grid),widget,col,row,1,1);
+  col++;
+
+  widget=gtk_label_new(NULL);
+  gtk_label_set_markup (GTK_LABEL(widget), controller==CONTROLLER2_V2?"<b>Bottom Encoder</b>":"<b>Encoder</b>");
+  gtk_grid_attach(GTK_GRID(grid),widget,col,row,2,1);
+  col+=2;
 
+  if(controller==CONTROLLER2_V2) {
     widget=gtk_label_new(NULL);
-    gtk_label_set_markup (GTK_LABEL(widget), controller==CONTROLLER2_V2?"<b>Bottom Encoder</b>":"<b>Encoder</b>");
+    gtk_label_set_markup (GTK_LABEL(widget), "<b>Top Encoder</b>");
     gtk_grid_attach(GTK_GRID(grid),widget,col,row,2,1);
     col+=2;
+  }
 
-    if(controller==CONTROLLER2_V2) {
-      widget=gtk_label_new(NULL);
-      gtk_label_set_markup (GTK_LABEL(widget), "<b>Top Encoder</b>");
-      gtk_grid_attach(GTK_GRID(grid),widget,col,row,2,1);
-      col+=2;
-    }
+  widget=gtk_label_new(NULL);
+  gtk_label_set_markup (GTK_LABEL(widget), "<b>Switch</b>");
+  gtk_grid_attach(GTK_GRID(grid),widget,col,row,1,1);
 
-    widget=gtk_label_new(NULL);
-    gtk_label_set_markup (GTK_LABEL(widget), "<b>Switch</b>");
-    gtk_grid_attach(GTK_GRID(grid),widget,col,row,1,1);
+  row++;
+  col=0;
 
-    row++;
-    col=0;
+  widget=gtk_label_new(NULL);
+  gtk_label_set_markup (GTK_LABEL(widget), "<b>ID</b>");
+  gtk_grid_attach(GTK_GRID(grid),widget,col,row,1,1);
+  col++;
 
-    widget=gtk_label_new(NULL);
-    gtk_label_set_markup (GTK_LABEL(widget), "<b>ID</b>");
-    gtk_grid_attach(GTK_GRID(grid),widget,col,row,1,1);
-    col++;
+  widget=gtk_label_new(NULL);
+  gtk_label_set_markup (GTK_LABEL(widget), "<b>Gpio A</b>");
+  gtk_grid_attach(GTK_GRID(grid),widget,col,row,1,1);
+  col++;
+
+  widget=gtk_label_new(NULL);
+  gtk_label_set_markup (GTK_LABEL(widget), "<b>Gpio B</b>");
+  gtk_grid_attach(GTK_GRID(grid),widget,col,row,1,1);
+  col++;
 
+  if(controller==CONTROLLER2_V2) {
     widget=gtk_label_new(NULL);
     gtk_label_set_markup (GTK_LABEL(widget), "<b>Gpio A</b>");
     gtk_grid_attach(GTK_GRID(grid),widget,col,row,1,1);
@@ -140,87 +152,76 @@ void configure_gpio(GtkWidget *parent) {
     gtk_label_set_markup (GTK_LABEL(widget), "<b>Gpio B</b>");
     gtk_grid_attach(GTK_GRID(grid),widget,col,row,1,1);
     col++;
+  }
 
-    if(controller==CONTROLLER2_V2) {
-      widget=gtk_label_new(NULL);
-      gtk_label_set_markup (GTK_LABEL(widget), "<b>Gpio A</b>");
-      gtk_grid_attach(GTK_GRID(grid),widget,col,row,1,1);
-      col++;
+  widget=gtk_label_new(NULL);
+  gtk_label_set_markup (GTK_LABEL(widget), "<b>Gpio</b>");
+  gtk_grid_attach(GTK_GRID(grid),widget,col,row,1,1);
+  col++;
 
-      widget=gtk_label_new(NULL);
-      gtk_label_set_markup (GTK_LABEL(widget), "<b>Gpio B</b>");
-      gtk_grid_attach(GTK_GRID(grid),widget,col,row,1,1);
-      col++;
-    }
+  row++;
+  col=0;
 
+  for(i=0;i<max_encoders;i++) {
     widget=gtk_label_new(NULL);
-    gtk_label_set_markup (GTK_LABEL(widget), "<b>Gpio</b>");
+    gchar id[16];
+    g_sprintf(id,"<b>%d</b>",i);
+    gtk_label_set_markup (GTK_LABEL(widget), id);
     gtk_grid_attach(GTK_GRID(grid),widget,col,row,1,1);
     col++;
 
-    row++;
-    col=0;
+    widget=gtk_spin_button_new_with_range (0.0,28.0,1.0);
+    gtk_spin_button_set_value (GTK_SPIN_BUTTON(widget),encoders[i].bottom_encoder_address_a);
+    gtk_grid_attach(GTK_GRID(grid),widget,col,row,1,1);
+    col++;
 
-    for(i=0;i<max_encoders;i++) {
-      widget=gtk_label_new(NULL);
-      gchar id[16];
-      g_sprintf(id,"<b>%d</b>",i);
-      gtk_label_set_markup (GTK_LABEL(widget), id);
-      gtk_grid_attach(GTK_GRID(grid),widget,col,row,1,1);
-      col++;
+    widget=gtk_spin_button_new_with_range (0.0,28.0,1.0);
+    gtk_spin_button_set_value (GTK_SPIN_BUTTON(widget),encoders[i].bottom_encoder_address_b);
+    gtk_grid_attach(GTK_GRID(grid),widget,col,row,1,1);
+    col++;
 
+    if(controller==CONTROLLER2_V2 && i<(max_encoders-1)) {
       widget=gtk_spin_button_new_with_range (0.0,28.0,1.0);
-      gtk_spin_button_set_value (GTK_SPIN_BUTTON(widget),encoders[i].bottom_encoder_address_a);
+      gtk_spin_button_set_value (GTK_SPIN_BUTTON(widget),encoders[i].top_encoder_address_a);
       gtk_grid_attach(GTK_GRID(grid),widget,col,row,1,1);
       col++;
-    
       widget=gtk_spin_button_new_with_range (0.0,28.0,1.0);
-      gtk_spin_button_set_value (GTK_SPIN_BUTTON(widget),encoders[i].bottom_encoder_address_b);
+      gtk_spin_button_set_value (GTK_SPIN_BUTTON(widget),encoders[i].top_encoder_address_b);
       gtk_grid_attach(GTK_GRID(grid),widget,col,row,1,1);
       col++;
-    
-      if(controller==CONTROLLER2_V2 && i<(max_encoders-1)) {
-        widget=gtk_spin_button_new_with_range (0.0,28.0,1.0);
-        gtk_spin_button_set_value (GTK_SPIN_BUTTON(widget),encoders[i].top_encoder_address_a);
-        gtk_grid_attach(GTK_GRID(grid),widget,col,row,1,1);
-        col++;
-   
-        widget=gtk_spin_button_new_with_range (0.0,28.0,1.0);
-        gtk_spin_button_set_value (GTK_SPIN_BUTTON(widget),encoders[i].top_encoder_address_b);
-        gtk_grid_attach(GTK_GRID(grid),widget,col,row,1,1);
-        col++;
-      }
-
-      if(i<(max_encoders-1)) {
-        widget=gtk_spin_button_new_with_range (0.0,28.0,1.0);
-        gtk_spin_button_set_value (GTK_SPIN_BUTTON(widget),encoders[i].switch_address);
-        gtk_grid_attach(GTK_GRID(grid),widget,col,row,1,1);
-        col++;
-      }
+    }
 
-      row++;
-      col=0;
+    if(i<(max_encoders-1)) {
+      widget=gtk_spin_button_new_with_range (0.0,28.0,1.0);
+      gtk_spin_button_set_value (GTK_SPIN_BUTTON(widget),encoders[i].switch_address);
+      gtk_grid_attach(GTK_GRID(grid),widget,col,row,1,1);
+      col++;
     }
-    gtk_notebook_append_page(GTK_NOTEBOOK(notebook),grid,gtk_label_new("Encoders"));
+
+    row++;
+    col=0;
+  }
+  gtk_notebook_append_page(GTK_NOTEBOOK(notebook),grid,gtk_label_new("Encoders"));
   }
 
 
   // switches
-  gint max_switches=MAX_SWITCHES;
-  switch(controller) {
-    case NO_CONTROLLER:
-      max_switches=0;
-      break;
-    case CONTROLLER1:
-      max_switches=8;
-      break;
-    case CONTROLLER2_V1:
-      max_switches=0;
-      break;
-    case CONTROLLER2_V2:
-      max_switches=0;
-      break;
-  }
+    gint max_switches=MAX_SWITCHES;
+    switch(controller) {
+      case NO_CONTROLLER:
+        max_switches=0;
+        break;
+      case CONTROLLER1:
+        max_switches=8;
+        break;
+      case CONTROLLER2_V1:
+        max_switches=0;
+        break;
+      case CONTROLLER2_V2:
+        max_switches=0;
+        break;
+    }
   
   if (max_switches > 0) {
     grid=gtk_grid_new();
diff --git a/css.c b/css.c
index c8b9ae3060d0bfcedf8113b6f274c290ce3fcf47..810492ca70e5d6ef9254584e0ed4093b627b60f5 100644 (file)
--- a/css.c
+++ b/css.c
@@ -1,10 +1,11 @@
 #include <gtk/gtk.h>
+#include "css.h"
 
 char *css=
-"  #small {\n"
+"  #small_button {\n"
 "    padding: 0;\n"
 "    font-family: Sans;\n"
-"    font-size: 12px;\n"
+"    font-size: 15px;\n"
 "    }\n"
 ;
 
diff --git a/css.h b/css.h
new file mode 100644 (file)
index 0000000..35a4487
--- /dev/null
+++ b/css.h
@@ -0,0 +1 @@
+void load_css();
index 44876eb3db0ff8e608062950bf5a96afe9cbaa12..2c1220f8059659759fdb2dc76a55ba65fedad0e9 100644 (file)
 #include "vfo.h"
 #include "button_text.h"
 #include "actions.h"
+#include "action_dialog.h"
 #include "gpio.h"
 #include "i2c.h"
 
 typedef struct _choice {
   int id;
   int action;
+  GtkWidget *initial_button;
   GtkWidget *button;
+  gulong signal_id;
 } CHOICE;
 
 static GtkWidget *parent_window=NULL;
@@ -65,110 +68,54 @@ static gboolean delete_event(GtkWidget *widget, GdkEvent *event, gpointer user_d
   return FALSE;
 }
 
-static void encoder_bottom_select_cb(GtkWidget *widget,gpointer data) {
-  CHOICE *choice=(CHOICE *)data;
-  encoders[choice->id].bottom_encoder_function=choice->action;
-  gtk_button_set_label(GTK_BUTTON(choice->button),encoder_string[choice->action]);
-}
-
-static void encoder_top_select_cb(GtkWidget *widget,gpointer data) {
-  CHOICE *choice=(CHOICE *)data;
-  encoders[choice->id].top_encoder_function=choice->action;
-  gtk_button_set_label(GTK_BUTTON(choice->button),encoder_string[choice->action]);
-}
-
-static void encoder_switch_select_cb(GtkWidget *widget,gpointer data) {
-  CHOICE *choice=(CHOICE *)data;
-  encoders[choice->id].switch_function=choice->action;
-  gtk_button_set_label(GTK_BUTTON(choice->button),sw_string[choice->action]);
-}
-
 static gboolean encoder_bottom_cb(GtkWidget *widget, GdkEvent *event, gpointer data) {
-  int encoder=GPOINTER_TO_INT(data);
-  int i;
-
-  GtkWidget *menu=gtk_menu_new();
-  for(i=0;i<ENCODER_ACTIONS;i++) {
-    GtkWidget *menu_item=gtk_menu_item_new_with_label(encoder_string[i]);
-    CHOICE *choice=g_new0(CHOICE,1);
-    choice->id=encoder;
-    choice->action=i;
-    choice->button=widget;
-    g_signal_connect(menu_item,"activate",G_CALLBACK(encoder_bottom_select_cb),choice);
-    gtk_menu_shell_append(GTK_MENU_SHELL(menu),menu_item);
-  }
-  gtk_widget_show_all(menu);
-#if GTK_CHECK_VERSION(3,22,0)
-  gtk_menu_popup_at_pointer(GTK_MENU(menu),(GdkEvent *)event);
-// the following line of code is to work around the problem of the popup menu not having scroll bars.
-  gtk_menu_reposition(GTK_MENU(menu));
-#else
-  gtk_menu_popup(GTK_MENU(menu),NULL,NULL,NULL,NULL,0,gtk_get_current_event_time());
-#endif
+  int en=GPOINTER_TO_INT(data);
+  int action=action_dialog(top_window,CONTROLLER_ENCODER,encoders[en].bottom_encoder_function);
+  gtk_button_set_label(GTK_BUTTON(widget),ActionTable[action].str);
+  encoders[en].bottom_encoder_function=action;
   return TRUE;
 }
 
 static gboolean encoder_top_cb(GtkWidget *widget, GdkEvent *event, gpointer data) {
-  int encoder=GPOINTER_TO_INT(data);
-  int i;
-
-  GtkWidget *menu=gtk_menu_new();
-  for(i=0;i<ENCODER_ACTIONS;i++) {
-    GtkWidget *menu_item=gtk_menu_item_new_with_label(encoder_string[i]);
-    CHOICE *choice=g_new0(CHOICE,1);
-    choice->id=encoder;
-    choice->action=i;
-    choice->button=widget;
-    g_signal_connect(menu_item,"activate",G_CALLBACK(encoder_top_select_cb),choice);
-    gtk_menu_shell_append(GTK_MENU_SHELL(menu),menu_item);
-  }
-  gtk_widget_show_all(menu);
-#if GTK_CHECK_VERSION(3,22,0)
-  gtk_menu_popup_at_pointer(GTK_MENU(menu),(GdkEvent *)event);
-// the following line of code is to work around the problem of the popup menu not having scroll bars.
-  gtk_menu_reposition(GTK_MENU(menu));
-#else
-  gtk_menu_popup(GTK_MENU(menu),NULL,NULL,NULL,NULL,0,gtk_get_current_event_time());
-#endif
+  int en=GPOINTER_TO_INT(data);
+  int action=action_dialog(dialog,CONTROLLER_ENCODER,encoders[en].top_encoder_function);
+  gtk_button_set_label(GTK_BUTTON(widget),ActionTable[action].str);
+  encoders[en].top_encoder_function=action;
   return TRUE;
 }
 
 static gboolean encoder_switch_cb(GtkWidget *widget, GdkEvent *event, gpointer data) {
-  int encoder=GPOINTER_TO_INT(data);
-  int i;
-
-  GtkWidget *menu=gtk_menu_new();
-  for(i=0;i<SWITCH_ACTIONS;i++) {
-    GtkWidget *menu_item=gtk_menu_item_new_with_label(sw_string[i]);
-    CHOICE *choice=g_new0(CHOICE,1);
-    choice->id=encoder;
-    choice->action=i;
-    choice->button=widget;
-    g_signal_connect(menu_item,"activate",G_CALLBACK(encoder_switch_select_cb),choice);
-    gtk_menu_shell_append(GTK_MENU_SHELL(menu),menu_item);
-  }
-  gtk_widget_show_all(menu);
-#if GTK_CHECK_VERSION(3,22,0)
-  gtk_menu_popup_at_pointer(GTK_MENU(menu),(GdkEvent *)event);
-// the following line of code is to work around the problem of the popup menu not having scroll bars.
-  gtk_menu_reposition(GTK_MENU(menu));
-#else
-  gtk_menu_popup(GTK_MENU(menu),NULL,NULL,NULL,NULL,0,gtk_get_current_event_time());
-#endif
+  int en=GPOINTER_TO_INT(data);
+  int action=action_dialog(dialog,CONTROLLER_SWITCH,encoders[en].switch_function);
+  gtk_button_set_label(GTK_BUTTON(widget),ActionTable[action].str);
+  encoders[en].switch_function=action;
   return TRUE;
 }
 
-
 void encoder_menu(GtkWidget *parent) {
   gint row=0;
   gint col=0;
   char label[32];
+  GtkWidget *widget;
 
   dialog=gtk_dialog_new();
   gtk_window_set_transient_for(GTK_WINDOW(dialog),GTK_WINDOW(parent));
   //gtk_window_set_decorated(GTK_WINDOW(dialog),FALSE);
-  char title[32];
-  sprintf(title,"piHPSDR - Encoder Actions");
+  char title[64];
+  switch(controller) {
+    case NO_CONTROLLER:
+      sprintf(title,"piHPSDR - No Encoders");
+      break;
+    case CONTROLLER1:
+      sprintf(title,"piHPSDR - Controller 1 Encoder Actions");
+      break;
+    case CONTROLLER2_V1:
+      sprintf(title,"piHPSDR - Controller 2 V1 Encoder Actions");
+      break;
+    case CONTROLLER2_V2:
+      sprintf(title,"piHPSDR - Controller 2 V2 Encoder Actions");
+      break;
+  }
   gtk_window_set_title(GTK_WINDOW(dialog),title);
   g_signal_connect (dialog, "delete_event", G_CALLBACK (delete_event), NULL);
 
@@ -185,26 +132,238 @@ void encoder_menu(GtkWidget *parent) {
   row++;
   col=0;
 
-  gint max_encoders=MAX_ENCODERS;
   switch(controller) {
     case NO_CONTROLLER:
-      max_encoders=0;
+      // should never happen
       break;
     case CONTROLLER1:
-      max_encoders=4;
+      // 3 vertical single encoders with switches plus VFO
+      col=4;
+      for(int i=0;i<3;i++) {
+        widget=gtk_label_new(NULL);
+        gtk_widget_set_name(widget,"small_button");
+        gtk_label_set_markup (GTK_LABEL(widget), "<b>Switch</b>");
+        gtk_grid_attach(GTK_GRID(grid),widget,col,row,1,1);
+        col++;
+        widget=gtk_button_new_with_label(ActionTable[encoders[i].switch_function].str);
+        gtk_widget_set_name(widget,"small_button");
+        g_signal_connect(widget,"button-press-event",G_CALLBACK(encoder_switch_cb),GINT_TO_POINTER(i));
+        gtk_grid_attach(GTK_GRID(grid),widget,col,row,1,1);
+        row++;
+        col=4;
+        
+        widget=gtk_label_new(NULL);
+        gtk_widget_set_name(widget,"small_button");
+        gtk_label_set_markup (GTK_LABEL(widget),"<b>Encoder</b>");
+        gtk_grid_attach(GTK_GRID(grid),widget,col,row,1,1);
+        col++;
+        widget=gtk_button_new_with_label(ActionTable[encoders[i].bottom_encoder_function].str);
+        gtk_widget_set_name(widget,"small_button");
+        g_signal_connect(widget,"button-press-event",G_CALLBACK(encoder_bottom_cb),GINT_TO_POINTER(i));
+        gtk_grid_attach(GTK_GRID(grid),widget,col,row,1,1);
+        row++;
+        col=4;
+      }
+
+      widget=gtk_label_new(NULL);
+      gtk_widget_set_name(widget,"small_button");
+      gtk_label_set_markup (GTK_LABEL(widget),"<b>Encoder</b>");
+      gtk_grid_attach(GTK_GRID(grid),widget,col,row,1,1);
+      col++;
+      widget=gtk_label_new(NULL);
+      gtk_widget_set_name(widget,"small_button");
+      g_sprintf(label,"<b>%s</b>",ActionTable[encoders[3].bottom_encoder_function].str);
+      gtk_label_set_markup (GTK_LABEL(widget), label);
+      gtk_grid_attach(GTK_GRID(grid),widget,col,row,1,1);
+      row++;
+      col=0;
       break;
     case CONTROLLER2_V1:
-      max_encoders=5;
+      // 3 horizontal single encoders with switches
+      row=4;
+      col=0;
+      for(int i=0;i<3;i++) {
+        widget=gtk_label_new(NULL);
+        gtk_widget_set_name(widget,"small_button");
+        gtk_label_set_markup (GTK_LABEL(widget), "<b>Switch</b>");
+        gtk_grid_attach(GTK_GRID(grid),widget,col,row,1,1);
+        col++;
+        widget=gtk_button_new_with_label(ActionTable[encoders[i].switch_function].str);
+        gtk_widget_set_name(widget,"small_button");
+        g_signal_connect(widget,"button-press-event",G_CALLBACK(encoder_switch_cb),GINT_TO_POINTER(i));
+        gtk_grid_attach(GTK_GRID(grid),widget,col,row,1,1);
+        col++;
+      }
+      row++;
+      col=0;
+      for(int i=0;i<3;i++) {
+        widget=gtk_label_new(NULL);
+        gtk_widget_set_name(widget,"small_button");
+        gtk_label_set_markup (GTK_LABEL(widget),"<b>Encoder</b>");
+        gtk_grid_attach(GTK_GRID(grid),widget,col,row,1,1);
+        col++;
+        widget=gtk_button_new_with_label(ActionTable[encoders[i].bottom_encoder_function].str);
+        gtk_widget_set_name(widget,"small_button");
+        g_signal_connect(widget,"button-press-event",G_CALLBACK(encoder_bottom_cb),GINT_TO_POINTER(i));
+        gtk_grid_attach(GTK_GRID(grid),widget,col,row,1,1);
+        col++;
+      }
+
+      // padding
+      row=1;
+      col=6;
+      widget=gtk_label_new("");
+      gtk_widget_set_name(widget,"small_button");
+      gtk_grid_attach(GTK_GRID(grid),widget,col,row,1,1);
+
+      // 1 vertical single encoder with switch plus VFO encoder
+      row=1;
+      col=7;
+      widget=gtk_label_new(NULL);
+      gtk_widget_set_name(widget,"small_button");
+      gtk_label_set_markup (GTK_LABEL(widget), "<b>Switch</b>");
+      gtk_grid_attach(GTK_GRID(grid),widget,col,row,1,1);
+      col++;
+      widget=gtk_button_new_with_label(ActionTable[encoders[3].switch_function].str);
+      gtk_widget_set_name(widget,"small_button");
+      g_signal_connect(widget,"button-press-event",G_CALLBACK(encoder_switch_cb),GINT_TO_POINTER(3));
+      gtk_grid_attach(GTK_GRID(grid),widget,col,row,1,1);
+      row++;
+      col=7;
+      widget=gtk_label_new(NULL);
+      gtk_widget_set_name(widget,"small_button");
+      gtk_label_set_markup (GTK_LABEL(widget),"<b>Encoder</b>");
+      gtk_grid_attach(GTK_GRID(grid),widget,col,row,1,1);
+      col++;
+      widget=gtk_button_new_with_label(ActionTable[encoders[3].bottom_encoder_function].str);
+      gtk_widget_set_name(widget,"small_button");
+      g_signal_connect(widget,"button-press-event",G_CALLBACK(encoder_bottom_cb),GINT_TO_POINTER(3));
+      gtk_grid_attach(GTK_GRID(grid),widget,col,row,1,1);
+
+      row=5;
+      col=7;
+      widget=gtk_label_new(NULL);
+      gtk_widget_set_name(widget,"small_button");
+      gtk_label_set_markup (GTK_LABEL(widget),"<b>Encoder</b>");
+      gtk_grid_attach(GTK_GRID(grid),widget,col,row,1,1);
+      col++;
+      widget=gtk_button_new_with_label(ActionTable[encoders[4].bottom_encoder_function].str);
+      gtk_widget_set_name(widget,"small_button");
+      gtk_grid_attach(GTK_GRID(grid),widget,col,row,1,1);
+
       break;
     case CONTROLLER2_V2:
-      max_encoders=5;
+      // 3 horizontal double encoders with switches
+      row=5;
+      col=0;
+      for(int i=0;i<3;i++) {
+        widget=gtk_label_new(NULL);
+        gtk_widget_set_name(widget,"small_button");
+        gtk_label_set_markup (GTK_LABEL(widget), "<b>Switch</b>");
+        gtk_grid_attach(GTK_GRID(grid),widget,col,row,1,1);
+        col++;
+        widget=gtk_button_new_with_label(ActionTable[encoders[i].switch_function].str);
+        gtk_widget_set_name(widget,"small_button");
+        g_signal_connect(widget,"button-press-event",G_CALLBACK(encoder_switch_cb),GINT_TO_POINTER(i));
+        gtk_grid_attach(GTK_GRID(grid),widget,col,row,1,1);
+        col++;
+      }
+      row++;
+      col=0;
+      for(int i=0;i<3;i++) {
+        widget=gtk_label_new(NULL);
+        gtk_widget_set_name(widget,"small_button");
+        gtk_label_set_markup (GTK_LABEL(widget),"<b>Top</b>");
+        gtk_grid_attach(GTK_GRID(grid),widget,col,row,1,1);
+        col++;
+        widget=gtk_button_new_with_label(ActionTable[encoders[i].top_encoder_function].str);
+        gtk_widget_set_name(widget,"small_button");
+        g_signal_connect(widget,"button-press-event",G_CALLBACK(encoder_top_cb),GINT_TO_POINTER(i));
+        gtk_grid_attach(GTK_GRID(grid),widget,col,row,1,1);
+        col++;
+      }
+      row++;
+      col=0;
+      for(int i=0;i<3;i++) {
+        widget=gtk_label_new(NULL);
+        gtk_widget_set_name(widget,"small_button");
+        gtk_label_set_markup (GTK_LABEL(widget),"<b>Bottom</b>");
+        gtk_grid_attach(GTK_GRID(grid),widget,col,row,1,1);
+        col++;
+        widget=gtk_button_new_with_label(ActionTable[encoders[i].bottom_encoder_function].str);
+        gtk_widget_set_name(widget,"small_button");
+        g_signal_connect(widget,"button-press-event",G_CALLBACK(encoder_bottom_cb),GINT_TO_POINTER(i));
+        gtk_grid_attach(GTK_GRID(grid),widget,col,row,1,1);
+        col++;
+      }
+
+      // padding
+      row=1;
+      col=6;
+      widget=gtk_label_new("");
+      gtk_widget_set_name(widget,"small_button");
+      gtk_grid_attach(GTK_GRID(grid),widget,col,row,1,1);
+
+      // 1 vertical single double with switch plus VFO encoder
+      row=1;
+      col=7;
+      widget=gtk_label_new(NULL);
+      gtk_widget_set_name(widget,"small_button");
+      gtk_label_set_markup (GTK_LABEL(widget), "<b>Switch</b>");
+      gtk_grid_attach(GTK_GRID(grid),widget,col,row,1,1);
+      col++;
+      widget=gtk_button_new_with_label(ActionTable[encoders[3].switch_function].str);
+      gtk_widget_set_name(widget,"small_button");
+      g_signal_connect(widget,"button-press-event",G_CALLBACK(encoder_switch_cb),GINT_TO_POINTER(3));
+      gtk_grid_attach(GTK_GRID(grid),widget,col,row,1,1);
+      row++;
+      col=7;
+      widget=gtk_label_new(NULL);
+      gtk_widget_set_name(widget,"small_button");
+      gtk_label_set_markup (GTK_LABEL(widget),"<b>Top</b>");
+      gtk_grid_attach(GTK_GRID(grid),widget,col,row,1,1);
+      col++;
+      widget=gtk_button_new_with_label(ActionTable[encoders[3].top_encoder_function].str);
+      gtk_widget_set_name(widget,"small_button");
+      g_signal_connect(widget,"button-press-event",G_CALLBACK(encoder_top_cb),GINT_TO_POINTER(3));
+      gtk_grid_attach(GTK_GRID(grid),widget,col,row,1,1);
+      row++;
+      col=7;
+      widget=gtk_label_new(NULL);
+      gtk_widget_set_name(widget,"small_button");
+      gtk_label_set_markup (GTK_LABEL(widget),"<b>Bottom</b>");
+      gtk_grid_attach(GTK_GRID(grid),widget,col,row,1,1);
+      col++;
+      widget=gtk_button_new_with_label(ActionTable[encoders[3].bottom_encoder_function].str);
+      gtk_widget_set_name(widget,"small_button");
+      g_signal_connect(widget,"button-press-event",G_CALLBACK(encoder_bottom_cb),GINT_TO_POINTER(3));
+      gtk_grid_attach(GTK_GRID(grid),widget,col,row,1,1);
+
+      row=7;
+      col=7;
+      widget=gtk_label_new(NULL);
+      gtk_widget_set_name(widget,"small_button");
+      gtk_label_set_markup (GTK_LABEL(widget),"<b>Encoder</b>");
+      gtk_grid_attach(GTK_GRID(grid),widget,col,row,1,1);
+      col++;
+      widget=gtk_button_new_with_label(ActionTable[encoders[4].bottom_encoder_function].str);
+      gtk_widget_set_name(widget,"small_button");
+      gtk_grid_attach(GTK_GRID(grid),widget,col,row,1,1);
+
       break;
   }
 
+/*
+  widget=gtk_label_new(NULL);
+  gtk_label_set_markup (GTK_LABEL(widget), controller==CONTROLLER2_V2?"<b>Bottom Encoder</b>":"<b>Encoder</b>");
+  gtk_grid_attach(GTK_GRID(grid),widget,col,row,1,1);
+  col++;
+
   GtkWidget *widget=gtk_label_new("");
   gtk_grid_attach(GTK_GRID(grid),widget,col,row,1,1);
   col++;
 
+
   widget=gtk_label_new(NULL);
   gtk_label_set_markup (GTK_LABEL(widget), controller==CONTROLLER2_V2?"<b>Bottom Encoder</b>":"<b>Encoder</b>");
   gtk_grid_attach(GTK_GRID(grid),widget,col,row,1,1);
@@ -233,25 +392,25 @@ void encoder_menu(GtkWidget *parent) {
 
     if(i==(max_encoders-1)) {
       widget=gtk_label_new(NULL);
-      g_sprintf(label,"<b>%s</b>",encoder_string[encoders[i].bottom_encoder_function]);
+      g_sprintf(label,"<b>%s</b>",ActionTable[encoders[i].bottom_encoder_function].str);
       gtk_label_set_markup (GTK_LABEL(widget), label);
     } else {
-      widget=gtk_button_new_with_label(encoder_string[encoders[i].bottom_encoder_function]);
-      g_signal_connect(widget,"button_press_event",G_CALLBACK(encoder_bottom_cb),GINT_TO_POINTER(i));
+      widget=gtk_button_new_with_label(ActionTable[encoders[i].bottom_encoder_function].str);
+      g_signal_connect(widget,"button-press-event",G_CALLBACK(encoder_bottom_cb),GINT_TO_POINTER(i));
     }
     gtk_grid_attach(GTK_GRID(grid),widget,col,row,1,1);
     col++;
 
     if(controller==CONTROLLER2_V2) {
-      widget=gtk_button_new_with_label(encoder_string[encoders[i].top_encoder_function]);
-      g_signal_connect(widget,"button_press_event",G_CALLBACK(encoder_top_cb),GINT_TO_POINTER(i));
+      widget=gtk_button_new_with_label(ActionTable[encoders[i].top_encoder_function].str);
+      g_signal_connect(widget,"button-press-event",G_CALLBACK(encoder_top_cb),GINT_TO_POINTER(i));
       gtk_grid_attach(GTK_GRID(grid),widget,col,row,1,1);
       col++;
     }
 
     if(i!=(max_encoders-1)) {
-      widget=gtk_button_new_with_label(sw_string[encoders[i].switch_function]);
-      g_signal_connect(widget,"button_press_event",G_CALLBACK(encoder_switch_cb),GINT_TO_POINTER(i));
+      widget=gtk_button_new_with_label(ActionTable[encoders[i].switch_function].str);
+      g_signal_connect(widget,"button-press-event",G_CALLBACK(encoder_switch_cb),GINT_TO_POINTER(i));
       gtk_grid_attach(GTK_GRID(grid),widget,col,row,1,1);
       col++;
     }
@@ -259,7 +418,7 @@ void encoder_menu(GtkWidget *parent) {
     row++;
     col=0;
   }
-
+*/
   gtk_container_add(GTK_CONTAINER(content),grid);
 
   sub_menu=dialog;
diff --git a/ext.h b/ext.h
index 66c74f97970a78b5880d893ae49661788a18a75f..380918228c714da6d15d0a2e4d51f05de5c07aed 100644 (file)
--- a/ext.h
+++ b/ext.h
@@ -31,6 +31,9 @@ extern int ext_remote_command(void *data);
 extern int ext_receiver_remote_update_display(void *data);
 #endif
 
+extern int ext_menu_filter(void *data);
+extern int ext_menu_mode(void *data);
+extern int ext_num_pad(void *data);
 extern int ext_discovery(void *data);
 extern int ext_vfo_update(void *data);
 extern int ext_set_frequency(void *data);
@@ -54,6 +57,8 @@ extern int ext_nr_update(void *data);
 extern int ext_nb_update(void *data);
 extern int ext_snb_update(void *data);
 extern int ext_anf_update(void *data);
+extern int ext_band_select(void *data);
+
 extern int ext_band_plus(void *data);
 extern int ext_band_minus(void *data);
 extern int ext_bandstack_plus(void *data);
diff --git a/gpio.c b/gpio.c
index 544181a29f6f5728f0b1d80132975785c1f1070c..9c3c3aea3dda7685fa4e319bbc86b1a3bb63cd5a 100644 (file)
--- a/gpio.c
+++ b/gpio.c
@@ -157,40 +157,31 @@ ENCODER encoders_no_controller[MAX_ENCODERS]={
   };
 
 ENCODER encoders_controller1[MAX_ENCODERS]={
-  {TRUE,TRUE,20,1,26,1,0,ENCODER_AF_GAIN,R_START,FALSE,TRUE,0,0,0,0,0,0,R_START,TRUE,TRUE,25,MENU_BAND,0L},
-  {TRUE,TRUE,16,1,19,1,0,ENCODER_AGC_GAIN,R_START,FALSE,TRUE,0,0,0,0,0,0,R_START,TRUE,TRUE,8,MENU_BANDSTACK,0L},
-  {TRUE,TRUE,4,1,21,1,0,ENCODER_DRIVE,R_START,FALSE,TRUE,0,0,0,0,0,0,R_START,TRUE,TRUE,7,MENU_MODE,0L},
-  {TRUE,TRUE,18,1,17,1,0,ENCODER_VFO,R_START,FALSE,TRUE,0,0,0,0,0,0,R_START,FALSE,TRUE,0,0,0L},
+  {TRUE,TRUE,20,1,26,1,0,AF_GAIN,R_START,FALSE,TRUE,0,0,0,0,0,0,R_START,TRUE,TRUE,25,MENU_BAND,0L},
+  {TRUE,TRUE,16,1,19,1,0,AGC_GAIN,R_START,FALSE,TRUE,0,0,0,0,0,0,R_START,TRUE,TRUE,8,MENU_BANDSTACK,0L},
+  {TRUE,TRUE,4,1,21,1,0,DRIVE,R_START,FALSE,TRUE,0,0,0,0,0,0,R_START,TRUE,TRUE,7,MENU_MODE,0L},
+  {TRUE,TRUE,18,1,17,1,0,VFO,R_START,FALSE,TRUE,0,0,0,0,0,0,R_START,FALSE,TRUE,0,0,0L},
   {FALSE,TRUE,0,1,0,0,1,0,R_START,FALSE,TRUE,0,0,0,0,0,0,R_START,FALSE,TRUE,0,0,0L},
   };
 
 ENCODER encoders_controller2_v1[MAX_ENCODERS]={
-  {TRUE,TRUE,20,1,26,1,0,ENCODER_AF_GAIN,R_START,FALSE,TRUE,0,0,0,0,0,0,R_START,TRUE,TRUE,22,MENU_BAND,0L},
-  {TRUE,TRUE,4,1,21,1,0,ENCODER_AGC_GAIN,R_START,FALSE,TRUE,0,0,0,0,0,0,R_START,TRUE,TRUE,27,MENU_BANDSTACK,0L},
-  {TRUE,TRUE,16,1,19,1,0,ENCODER_IF_WIDTH,R_START,FALSE,TRUE,0,0,0,0,0,0,R_START,TRUE,TRUE,23,MENU_MODE,0L},
-  {TRUE,TRUE,25,1,8,1,0,ENCODER_RIT,R_START,FALSE,TRUE,0,0,0,0,0,0,R_START,TRUE,TRUE,24,MENU_FREQUENCY,0L},
-  {TRUE,TRUE,18,1,17,1,0,ENCODER_VFO,R_START,FALSE,TRUE,0,0,0,0,0,0,R_START,FALSE,TRUE,0,0,0L},
+  {TRUE,TRUE,20,1,26,1,0,AF_GAIN,R_START,FALSE,TRUE,0,0,0,0,0,0,R_START,TRUE,TRUE,22,MENU_BAND,0L},
+  {TRUE,TRUE,4,1,21,1,0,AGC_GAIN,R_START,FALSE,TRUE,0,0,0,0,0,0,R_START,TRUE,TRUE,27,MENU_BANDSTACK,0L},
+  {TRUE,TRUE,16,1,19,1,0,IF_WIDTH,R_START,FALSE,TRUE,0,0,0,0,0,0,R_START,TRUE,TRUE,23,MENU_MODE,0L},
+  {TRUE,TRUE,25,1,8,1,0,RIT,R_START,FALSE,TRUE,0,0,0,0,0,0,R_START,TRUE,TRUE,24,MENU_FREQUENCY,0L},
+  {TRUE,TRUE,18,1,17,1,0,VFO,R_START,FALSE,TRUE,0,0,0,0,0,0,R_START,FALSE,TRUE,0,0,0L},
   };
 
 ENCODER encoders_controller2_v2[MAX_ENCODERS]={
-  {TRUE,TRUE,5,1,6,1,0,ENCODER_RF_GAIN,R_START,TRUE,TRUE,26,1,20,1,0,ENCODER_AF_GAIN,R_START,TRUE,TRUE,22,MENU_BAND,0L},
-  {TRUE,TRUE,9,1,7,1,0,ENCODER_ATTENUATION,R_START,TRUE,TRUE,21,1,4,1,0,ENCODER_AGC_GAIN,R_START,TRUE,TRUE,27,MENU_MODE,0L},
-  {TRUE,TRUE,11,1,10,1,0,ENCODER_IF_WIDTH,R_START,TRUE,TRUE,19,1,16,1,0,ENCODER_IF_SHIFT,R_START,TRUE,TRUE,23,MENU_FILTER,0L},
-  {TRUE,TRUE,13,1,12,1,0,ENCODER_XIT,R_START,TRUE,TRUE,8,1,25,1,0,ENCODER_RIT,R_START,TRUE,TRUE,24,MENU_FREQUENCY,0L},
-  {TRUE,TRUE,18,1,17,1,0,ENCODER_VFO,R_START,FALSE,TRUE,0,0,0,0,0,0,R_START,FALSE,TRUE,0,0,0L},
+  {TRUE,TRUE,5,1,6,1,0,RF_GAIN,R_START,TRUE,TRUE,26,1,20,1,0,AF_GAIN,R_START,TRUE,TRUE,22,MENU_BAND,0L},
+  {TRUE,TRUE,9,1,7,1,0,ATTENUATION,R_START,TRUE,TRUE,21,1,4,1,0,AGC_GAIN,R_START,TRUE,TRUE,27,MENU_MODE,0L},
+  {TRUE,TRUE,11,1,10,1,0,IF_WIDTH,R_START,TRUE,TRUE,19,1,16,1,0,IF_SHIFT,R_START,TRUE,TRUE,23,MENU_FILTER,0L},
+  {TRUE,TRUE,13,1,12,1,0,XIT,R_START,TRUE,TRUE,8,1,25,1,0,RIT,R_START,TRUE,TRUE,24,MENU_FREQUENCY,0L},
+  {TRUE,TRUE,18,1,17,1,0,VFO,R_START,FALSE,TRUE,0,0,0,0,0,0,R_START,FALSE,TRUE,0,0,0L},
   };
 
 ENCODER *encoders=encoders_no_controller;
 
-//
-// in switches_cw,only the switch address will be used
-//
-SWITCH switches_cw[3]={
-  {FALSE,FALSE, 9,NO_ACTION,0L},
-  {FALSE,FALSE,11,NO_ACTION,0L},
-  {FALSE,FALSE,10,NO_ACTION,0L}
-};
-
 SWITCH switches_no_controller[MAX_SWITCHES]={
   {FALSE,FALSE,0,NO_ACTION,0L},
   {FALSE,FALSE,0,NO_ACTION,0L},
@@ -216,8 +207,8 @@ SWITCH switches_controller1[MAX_FUNCTIONS][MAX_SWITCHES]={
    {TRUE,TRUE,12,MENU_BANDSTACK,0L},
    {TRUE,TRUE,6,MENU_MODE,0L},
    {TRUE,TRUE,5,MENU_FILTER,0L},
-   {TRUE,TRUE,24,NR,0L},
-   {TRUE,TRUE,23,AGC,0L},
+   {TRUE,TRUE,24,MENU_NOISE,0L},
+   {TRUE,TRUE,23,MENU_AGC,0L},
    {TRUE,TRUE,22,FUNCTION,0L},
    {FALSE,FALSE,0,NO_ACTION,0L},
    {FALSE,FALSE,0,NO_ACTION,0L},
@@ -246,7 +237,7 @@ SWITCH switches_controller1[MAX_FUNCTIONS][MAX_SWITCHES]={
   {{TRUE,TRUE,27,MOX,0L},
    {TRUE,TRUE,13,MENU_FREQUENCY,0L},
    {TRUE,TRUE,12,MENU_MEMORY,0L},
-   {TRUE,TRUE,6,RIT,0L},
+   {TRUE,TRUE,6,RIT_ENABLE,0L},
    {TRUE,TRUE,5,RIT_PLUS,0L},
    {TRUE,TRUE,24,RIT_MINUS,0L},
    {TRUE,TRUE,23,RIT_CLEAR,0L},
@@ -262,7 +253,7 @@ SWITCH switches_controller1[MAX_FUNCTIONS][MAX_SWITCHES]={
   {{TRUE,TRUE,27,MOX,0L},
    {TRUE,TRUE,13,MENU_FREQUENCY,0L},
    {TRUE,TRUE,12,MENU_MEMORY,0L},
-   {TRUE,TRUE,6,XIT,0L},
+   {TRUE,TRUE,6,XIT_ENABLE,0L},
    {TRUE,TRUE,5,XIT_PLUS,0L},
    {TRUE,TRUE,24,XIT_MINUS,0L},
    {TRUE,TRUE,23,XIT_CLEAR,0L},
@@ -372,7 +363,7 @@ static unsigned int millis () {
 }
 
 static gpointer rotary_encoder_thread(gpointer data) {
-  ENCODER_ACTION *a;
+  PROCESS_ACTION *a;
   int i;
 
   usleep(250000);
@@ -382,20 +373,20 @@ static gpointer rotary_encoder_thread(gpointer data) {
     for(i=0;i<MAX_ENCODERS;i++) {
       if(encoders[i].bottom_encoder_enabled && encoders[i].bottom_encoder_pos!=0) {
         //g_print("%s: BOTTOM encoder %d pos=%d\n",__FUNCTION__,i,encoders[i].bottom_encoder_pos);
-        a=g_new(ENCODER_ACTION,1);
+        a=g_new(PROCESS_ACTION,1);
         a->action=encoders[i].bottom_encoder_function;
         a->mode=RELATIVE;
         a->val=encoders[i].bottom_encoder_pos;
-        g_idle_add(encoder_action,a);
+        g_idle_add(process_action,a);
         encoders[i].bottom_encoder_pos=0;
       }
       if(encoders[i].top_encoder_enabled && encoders[i].top_encoder_pos!=0) {
         //g_print("%s: TOP encoder %d pos=%d\n",__FUNCTION__,i,encoders[i].top_encoder_pos);
-        a=g_new(ENCODER_ACTION,1);
+        a=g_new(PROCESS_ACTION,1);
         a->action=encoders[i].top_encoder_function;
         a->mode=RELATIVE;
         a->val=encoders[i].top_encoder_pos;
-        g_idle_add(encoder_action,a);
+        g_idle_add(process_action,a);
         encoders[i].top_encoder_pos=0;
       }
     }
@@ -419,7 +410,7 @@ static unsigned long switch_debounce;
 
 static void process_encoder(int e,int l,int addr,int val) {
   guchar pinstate;
-  //g_print("%s: encoder=%d level=%d addr=0x%02X val=%d\n",__FUNCTION__,e,l,addr,val);
+  g_print("%s: encoder=%d level=%d addr=0x%02X val=%d\n",__FUNCTION__,e,l,addr,val);
   g_mutex_lock(&encoder_mutex);
   switch(l) {
     case BOTTOM_ENCODER:
@@ -428,7 +419,7 @@ static void process_encoder(int e,int l,int addr,int val) {
           encoders[e].bottom_encoder_a_value=val;
           pinstate=(encoders[e].bottom_encoder_b_value<<1) | encoders[e].bottom_encoder_a_value;
           encoders[e].bottom_encoder_state=encoder_state_table[encoders[e].bottom_encoder_state&0xf][pinstate];
-          //g_print("%s: state=%02X\n",__FUNCTION__,encoders[e].bottom_encoder_state);
+          g_print("%s: state=%02X\n",__FUNCTION__,encoders[e].bottom_encoder_state);
           switch(encoders[e].bottom_encoder_state&0x30) {
             case DIR_NONE:
               break;
@@ -442,13 +433,13 @@ static void process_encoder(int e,int l,int addr,int val) {
               break;
           }
 
-          //g_print("%s: %s BOTTOM pos=%d\n",__FUNCTION__,encoder_string[encoders[e].bottom_encoder_function],encoders[e].bottom_encoder_pos);
+          g_print("%s: %d BOTTOM pos=%d\n",__FUNCTION__,e,encoders[e].bottom_encoder_pos);
           break;
         case B:
           encoders[e].bottom_encoder_b_value=val;
           pinstate=(encoders[e].bottom_encoder_b_value<<1) | encoders[e].bottom_encoder_a_value;
           encoders[e].bottom_encoder_state=encoder_state_table[encoders[e].bottom_encoder_state&0xf][pinstate];
-          //g_print("%s: state=%02X\n",__FUNCTION__,encoders[e].bottom_encoder_state);
+          g_print("%s: state=%02X\n",__FUNCTION__,encoders[e].bottom_encoder_state);
           switch(encoders[e].bottom_encoder_state&0x30) {
             case DIR_NONE:
               break;
@@ -462,7 +453,7 @@ static void process_encoder(int e,int l,int addr,int val) {
               break;
           }
 
-          //g_print("%s: %s BOTTOM pos=%d\n",__FUNCTION__,encoder_string[encoders[e].bottom_encoder_function],encoders[e].bottom_encoder_pos);
+          g_print("%s: %d BOTTOM pos=%d\n",__FUNCTION__,e,encoders[e].bottom_encoder_pos);
 
           break;
       }
@@ -473,7 +464,7 @@ static void process_encoder(int e,int l,int addr,int val) {
           encoders[e].top_encoder_a_value=val;
           pinstate=(encoders[e].top_encoder_b_value<<1) | encoders[e].top_encoder_a_value;
           encoders[e].top_encoder_state=encoder_state_table[encoders[e].top_encoder_state&0xf][pinstate];
-          //g_print("%s: state=%02X\n",__FUNCTION__,encoders[e].top_encoder_state);
+          g_print("%s: state=%02X\n",__FUNCTION__,encoders[e].top_encoder_state);
           switch(encoders[e].top_encoder_state&0x30) {
             case DIR_NONE:
               break;
@@ -486,13 +477,13 @@ static void process_encoder(int e,int l,int addr,int val) {
             default:
               break;
           }
-          //g_print("%s: %s TOP pos=%d\n",__FUNCTION__,encoder_string[encoders[e].top_encoder_function],encoders[e].top_encoder_pos);
+          g_print("%s: %d TOP pos=%d\n",__FUNCTION__,e,encoders[e].top_encoder_pos);
           break;
         case B:
           encoders[e].top_encoder_b_value=val;
           pinstate=(encoders[e].top_encoder_b_value<<1) | encoders[e].top_encoder_a_value;
           encoders[e].top_encoder_state=encoder_state_table[encoders[e].top_encoder_state&0xf][pinstate];
-          //g_print("%s: state=%02X\n",__FUNCTION__,encoders[e].top_encoder_state);
+          g_print("%s: state=%02X\n",__FUNCTION__,encoders[e].top_encoder_state);
           switch(encoders[e].top_encoder_state&0x30) {
             case DIR_NONE:
               break;
@@ -505,7 +496,7 @@ static void process_encoder(int e,int l,int addr,int val) {
             default:
               break;
           }
-          //g_print("%s: %s TOP pos=%d\n",__FUNCTION__,encoder_string[encoders[e].top_encoder_function],encoders[e].top_encoder_pos);
+          g_print("%s: %d TOP pos=%d\n",__FUNCTION__,e,encoders[e].top_encoder_pos);
 
           break;
       }
@@ -527,7 +518,7 @@ static void process_edge(int offset,int value) {
       keyer_event(1, CW_ACTIVE_LOW ? (value==PRESSED) : value);
       found=TRUE;
     } else if(offset==CWR_BUTTON) {
-      keyer_event(2, CW_ACTIVE_LOW ? (value==PRESSED) : value);
+      keyer_event(1, CW_ACTIVE_LOW ? (value==PRESSED) : value);
       found=TRUE;
     }
   }
@@ -537,30 +528,30 @@ static void process_edge(int offset,int value) {
   for(i=0;i<MAX_ENCODERS;i++) {
     if(encoders[i].bottom_encoder_enabled && encoders[i].bottom_encoder_address_a==offset) {
       //g_print("%s: found %d encoder %d bottom A\n",__FUNCTION__,offset,i);
-      process_encoder(i,BOTTOM_ENCODER,A,value);
+      process_encoder(i,BOTTOM_ENCODER,A,value==PRESSED?1:0);
       found=TRUE;
       break;
     } else if(encoders[i].bottom_encoder_enabled && encoders[i].bottom_encoder_address_b==offset) {
       //g_print("%s: found %d encoder %d bottom B\n",__FUNCTION__,offset,i);
-      process_encoder(i,BOTTOM_ENCODER,B,value);
+      process_encoder(i,BOTTOM_ENCODER,B,value==PRESSED?1:0);
       found=TRUE;
       break;
     } else if(encoders[i].top_encoder_enabled && encoders[i].top_encoder_address_a==offset) {
       //g_print("%s: found %d encoder %d top A\n",__FUNCTION__,offset,i);
-      process_encoder(i,TOP_ENCODER,A,value);
+      process_encoder(i,TOP_ENCODER,A,value==PRESSED?1:0);
       found=TRUE;
       break;
     } else if(encoders[i].top_encoder_enabled && encoders[i].top_encoder_address_b==offset) {
       //g_print("%s: found %d encoder %d top B\n",__FUNCTION__,offset,i);
-      process_encoder(i,TOP_ENCODER,B,value);
+      process_encoder(i,TOP_ENCODER,B,value==PRESSED?1:0);
       found=TRUE;
       break;
     } else if(encoders[i].switch_enabled && encoders[i].switch_address==offset) {
       //g_print("%s: found %d encoder %d switch\n",__FUNCTION__,offset,i);
-      SWITCH_ACTION *a=g_new(SWITCH_ACTION,1);
+      PROCESS_ACTION *a=g_new(PROCESS_ACTION,1);
       a->action=encoders[i].switch_function;
-      a->state=value;
-      g_idle_add(switch_action,a);
+      a->mode=value?PRESSED:RELEASED;
+      g_idle_add(process_action,a);
       found=TRUE;
       break;
     }
@@ -584,12 +575,12 @@ static void process_edge(int offset,int value) {
         if(t<switches[i].switch_debounce) {
           return;
         }
-g_print("%s: switches=%p function=%d (%s)\n",__FUNCTION__,switches,switches[i].switch_function,sw_string[switches[i].switch_function]);
+//g_print("%s: switches=%p function=%d (%s)\n",__FUNCTION__,switches,switches[i].switch_function,sw_string[switches[i].switch_function]);
         switches[i].switch_debounce=t+settle_time;
-        SWITCH_ACTION *a=g_new(SWITCH_ACTION,1);
+        PROCESS_ACTION *a=g_new(PROCESS_ACTION,1);
         a->action=switches[i].switch_function;
-        a->state=value;
-        g_idle_add(switch_action,a);
+        a->mode=value?PRESSED:RELEASED;
+        g_idle_add(process_action,a);
         break;
       }
     }
@@ -650,7 +641,6 @@ void gpio_restore_state() {
 
   loadProperties("gpio.props");
  
-  controller=NO_CONTROLLER;
   value=getProperty("controller");
   if(value) controller=atoi(value);
   gpio_set_defaults(controller);
@@ -720,7 +710,6 @@ void gpio_restore_state() {
       if(value) switches[i].switch_address=atoi(value);
     }
   }
-
 }
 
 void gpio_save_state() {
@@ -807,6 +796,13 @@ void gpio_save_state() {
 void gpio_restore_actions() {
   char name[80];
   char *value;
+  int previous_controller=NO_CONTROLLER;
+  
+  value=getProperty("controller");
+  if(value) previous_controller=atoi(value);
+  gpio_set_defaults(controller);
+
+  if(controller==previous_controller) {
   if(controller!=NO_CONTROLLER) {
     for(int i=0;i<MAX_ENCODERS;i++) {
       sprintf(name,"encoders[%d].bottom_encoder_function",i);
@@ -835,11 +831,16 @@ void gpio_restore_actions() {
       if(value) switches[i].switch_function=atoi(value);
     }
   }
+  }
 }
 
 void gpio_save_actions() {
   char value[80];
   char name[80];
+
+  sprintf(value,"%d",controller);
+  setProperty("controller",value);
+
   if(controller!=NO_CONTROLLER) {
     for(int i=0;i<MAX_ENCODERS;i++) {
       sprintf(name,"encoders[%d].bottom_encoder_function",i);
@@ -1091,13 +1092,13 @@ void gpio_close() {
 #ifdef LOCALCW
 void gpio_cw_sidetone_set(int level) {
   int rc;
-#ifdef GPIO
   if (ENABLE_GPIO_SIDETONE) {
-    if((rc=gpiod_ctxless_set_value(gpio_device,SIDETONE_GPIO,level,FALSE,consumer,NULL,NULL))<0) {
+#ifdef GPIO
+    if((rc=gpiod_ctxless_set_value_ext(gpio_device,SIDETONE_GPIO,level,FALSE,consumer,NULL,NULL,0))<0) {
       g_print("%s: err=%d\n",__FUNCTION__,rc);
     }
-  }
 #endif
+  }
 }
 
 int  gpio_cw_sidetone_enabled() {
diff --git a/gpio.h b/gpio.h
index 9c82314a2d623c76c21853a222bc6ff7c24b9846..bfdce8a4dd5aee54e9895eb28314105534531a30 100644 (file)
--- a/gpio.h
+++ b/gpio.h
@@ -60,7 +60,9 @@ typedef struct _switch {
   gulong switch_debounce;
 } SWITCH;
 
+#ifdef LOCALCW
 extern SWITCH switches_cw[3];
+#endif
 extern SWITCH switches_no_controller[MAX_SWITCHES];
 extern SWITCH switches_controller1[MAX_FUNCTIONS][MAX_SWITCHES];
 extern SWITCH switches_controller2_v1[MAX_SWITCHES];
@@ -89,8 +91,6 @@ extern int ENABLE_GPIO_SIDETONE;
 extern int ENABLE_CW_BUTTONS;
 extern int CW_ACTIVE_LOW;
 extern void gpio_cw_sidetone_set(int level);
-extern int  gpio_left_cw_key();
-extern int  gpio_right_cw_key();
 extern int  gpio_cw_sidetone_enabled();
 #endif
 
diff --git a/i2c.c b/i2c.c
index 78fc43b9e9db29b6945bfc0cc66de563693dced2..711cd87ab5d757c866fff79bb4f30a68bef71363 100644 (file)
--- a/i2c.c
+++ b/i2c.c
@@ -93,10 +93,10 @@ g_print("%s: flags=%04X ints=%04X\n",__FUNCTION__,flags,ints);
         }
         if(i<16) {
 g_print("%s: switches=%p sw=%d action=%d\n",__FUNCTION__,switches,i,switches[i].switch_function);
-          SWITCH_ACTION *a=g_new(SWITCH_ACTION,1);
+          PROCESS_ACTION *a=g_new(PROCESS_ACTION,1);
           a->action=switches[i].switch_function;
-          a->state=PRESSED;
-          g_idle_add(switch_action,a);
+          a->mode=PRESSED;
+          g_idle_add(process_action,a);
         }
       }
     }
index 459e2a1cdd714e0d90adb480e90394ed210eda72..696cd0bbf9a88e7ca2cb932816d6016b354b5318 100644 (file)
@@ -35,6 +35,7 @@
 #include "adc.h"
 #include "dac.h"
 #include "radio.h"
+#include "actions.h"
 #include "midi.h"
 #include "midi_menu.h"
 #include "alsa_midi.h"
@@ -136,37 +137,37 @@ static void ReadMIDIdevice(const MIDIPacketList *pktlist, void *refCon, void *co
                            // a push-button.
                            if (arg2 == 0) {
                              if(configure) {
-                               NewMidiConfigureEvent(MIDI_EVENT_NOTE, chan, arg1, 0);
+                               NewMidiConfigureEvent(MIDI_NOTE, chan, arg1, 0);
                              } else {
-                               NewMidiEvent(MIDI_EVENT_NOTE, chan, arg1, 0);
+                               NewMidiEvent(MIDI_NOTE, chan, arg1, 0);
                              }
                            } else {
                              if(configure) {
-                               NewMidiConfigureEvent(MIDI_EVENT_NOTE, chan, arg1, 1);
+                               NewMidiConfigureEvent(MIDI_NOTE, chan, arg1, 1);
                              } else {
-                               NewMidiEvent(MIDI_EVENT_NOTE, chan, arg1, 1);
+                               NewMidiEvent(MIDI_NOTE, chan, arg1, 1);
                              }
                            }
                            break;
                         case CMD_NOTEOFF:
                            if(configure) {
-                             NewMidiConfigureEvent(MIDI_EVENT_NOTE, chan, arg1, 0);
+                             NewMidiConfigureEvent(MIDI_NOTE, chan, arg1, 0);
                            } else {
-                             NewMidiEvent(MIDI_EVENT_NOTE, chan, arg1, 0);
+                             NewMidiEvent(MIDI_NOTE, chan, arg1, 0);
                            }
                            break;
                         case CMD_CTRL:
                            if(configure) {
-                             NewMidiConfigureEvent(MIDI_EVENT_CTRL, chan, arg1, arg2);
+                             NewMidiConfigureEvent(MIDI_CTRL, chan, arg1, arg2);
                            } else {
-                             NewMidiEvent(MIDI_EVENT_CTRL, chan, arg1, arg2);
+                             NewMidiEvent(MIDI_CTRL, chan, arg1, arg2);
                            }
                            break;
                         case CMD_PITCH:
                            if(configure) {
-                             NewMidiConfigureEvent(MIDI_EVENT_PITCH, chan, 0, arg1+128*arg2);
+                             NewMidiConfigureEvent(MIDI_PITCH, chan, 0, arg1+128*arg2);
                            } else {
-                             NewMidiEvent(MIDI_EVENT_PITCH, chan, 0, arg1+128*arg2);
+                             NewMidiEvent(MIDI_PITCH, chan, 0, arg1+128*arg2);
                            }
                            break;
                     }
diff --git a/main.c b/main.c
index d93fe9b1057b03f2d1ed88e619b4fbe15272c68e..d964e7f3e0eaf2befdf0de5e5de7639e3d3c90a3 100644 (file)
--- a/main.c
+++ b/main.c
@@ -62,6 +62,7 @@
 #endif
 #include "ext.h"
 #include "vfo.h"
+#include "css.h"
 
 struct utsname unameData;
 
@@ -229,6 +230,8 @@ static void activate_pihpsdr(GtkApplication *app, gpointer data) {
   fprintf(stderr,"version: %s\n",unameData.version);
   fprintf(stderr,"machine: %s\n",unameData.machine);
 
+  load_css();
+
   GdkScreen *screen=gdk_screen_get_default();
   if(screen==NULL) {
     fprintf(stderr,"no default screen!\n");
diff --git a/midi.h b/midi.h
index 2a290139c851ae03130e9be5df3fdbd476920be5..bfce7bef4068909bc09fa06e1dddb180e6d2798a 100644 (file)
--- a/midi.h
+++ b/midi.h
  * must generate MIDI events on different channels
  */
 
-//
-// MIDIaction encodes the "action" to be taken in Layer3
-// (sorted alphabetically by the keyword).
-// All MIDIaction entries should begin with "MIDI_ACTION"
-//
-enum MIDIaction {
-  MIDI_ACTION_NONE=0,          // NONE:                No-Op (unassigned key)
-  MIDI_ACTION_VFO_A2B,         // A2B:                 VFO A -> B
-  MIDI_ACTION_AF_GAIN,         // AFGAIN:              AF gain
-  MIDI_ACTION_AGCATTACK,       // AGCATTACK:           AGC ATTACK (cycle fast/med/slow etc.)
-  MIDI_ACTION_AGC,             // AGCVAL:              AGC level
-  MIDI_ACTION_ANF,             // ANF:                 toggel ANF on/off
-  MIDI_ACTION_ATT,             // ATT:                 Step attenuator or Programmable attenuator
-  MIDI_ACTION_VFO_B2A,         // B2A:                 VFO B -> A
-  MIDI_ACTION_BAND_10,          // BAND10
-  MIDI_ACTION_BAND_12,          // BAND12
-  MIDI_ACTION_BAND_1240,        // BAND1240
-  MIDI_ACTION_BAND_144,         // BAND144
-  MIDI_ACTION_BAND_15,          // BAND15
-  MIDI_ACTION_BAND_160,         // BAND160
-  MIDI_ACTION_BAND_17,          // BAND17
-  MIDI_ACTION_BAND_20,          // BAND20
-  MIDI_ACTION_BAND_220,         // BAND220
-  MIDI_ACTION_BAND_2300,        // BAND2300
-  MIDI_ACTION_BAND_30,          // BAND30
-  MIDI_ACTION_BAND_3400,        // BAND3400
-  MIDI_ACTION_BAND_40,          // BAND40
-  MIDI_ACTION_BAND_430,         // BAND430
-  MIDI_ACTION_BAND_6,           // BAND6
-  MIDI_ACTION_BAND_60,          // BAND60
-  MIDI_ACTION_BAND_70,          // BAND70
-  MIDI_ACTION_BAND_80,          // BAND80
-  MIDI_ACTION_BAND_902,         // BAND902
-  MIDI_ACTION_BAND_AIR,         // BANDAIR
-  MIDI_ACTION_BAND_DOWN,       // BANDDOWN:            cycle through bands downwards
-  MIDI_ACTION_BAND_GEN,                // BANDGEN
-  MIDI_ACTION_BAND_UP,         // BANDUP:              cycle through bands upwards
-  MIDI_ACTION_BAND_WWV,                // BANDWWVUP:           cycle through bands upwards
-  MIDI_ACTION_COMPRESS,                // COMPRESS:            TX compressor value
-  MIDI_ACTION_CTUN,            // CTUN:                toggle CTUN on/off
-  MIDI_ACTION_VFO,             // CURRVFO:             change VFO frequency
-  MIDI_ACTION_CWKEYER,         // CW(Keyer):           Unconditional CW key-down/up (outside keyer)
-  MIDI_ACTION_CWLEFT,          // CWLEFT:              Left paddle pressed (use with ONOFF)
-  MIDI_ACTION_CWRIGHT,         // CWRIGHT:             Right paddle pressed (use with ONOFF)
-  MIDI_ACTION_CWSPEED,         // CWSPEED:             Set speed of (iambic) CW keyer
-  MIDI_ACTION_DIV_COARSEGAIN,  // DIVCOARSEGAIN:       change DIVERSITY gain in large increments
-  MIDI_ACTION_DIV_COARSEPHASE, // DIVCOARSEPHASE:      change DIVERSITY phase in large increments
-  MIDI_ACTION_DIV_FINEGAIN,    // DIVFINEGAIN:         change DIVERSITY gain in small increments
-  MIDI_ACTION_DIV_FINEPHASE,   // DIVFINEPHASE:        change DIVERSITY phase in small increments
-  MIDI_ACTION_DIV_GAIN,                // DIVGAIN:             change DIVERSITY gain in medium increments
-  MIDI_ACTION_DIV_PHASE,       // DIVPHASE:            change DIVERSITY phase in medium increments
-  MIDI_ACTION_DIV_TOGGLE,      // DIVTOGGLE:           DIVERSITY on/off
-  MIDI_ACTION_DUP,             // DUP:                 toggle duplex on/off
-  MIDI_ACTION_FILTER_DOWN,     // FILTERDOWN:          cycle through filters downwards
-  MIDI_ACTION_FILTER_UP,       // FILTERUP:            cycle through filters upwards
-  MIDI_ACTION_LOCK,            // LOCK:                lock VFOs, disable frequency changes
-  MIDI_ACTION_MEM_RECALL_M0,    // RECALLM0:           load current freq/mode/filter from memory slot #0
-  MIDI_ACTION_MEM_RECALL_M1,    // RECALLM1:           load current freq/mode/filter from memory slot #1
-  MIDI_ACTION_MEM_RECALL_M2,    // RECALLM2:           load current freq/mode/filter from memory slot #2
-  MIDI_ACTION_MEM_RECALL_M3,    // RECALLM3:           load current freq/mode/filter from memory slot #3
-  MIDI_ACTION_MEM_RECALL_M4,    // RECALLM4:           load current freq/mode/filter from memory slot #4
-  MIDI_ACTION_MENU_FILTER,      // MENU_FILTER
-  MIDI_ACTION_MENU_MODE,        // MENU_MODE
-  MIDI_ACTION_MIC_VOLUME,      // MICGAIN:             MIC gain
-  MIDI_ACTION_MODE_DOWN,       // MODEDOWN:            cycle through modes downwards
-  MIDI_ACTION_MODE_UP,         // MODEUP:              cycle through modes upwards
-  MIDI_ACTION_MOX,             // MOX:                 toggle "mox" state
-  MIDI_ACTION_MUTE,            // MUTE:                toggle mute on/off
-  MIDI_ACTION_NB,              // NOISEBLANKER:        cycle through NoiseBlanker states (none, NB, NB2)
-  MIDI_ACTION_NR,              // NOISEREDUCTION:      cycle through NoiseReduction states (none, NR, NR2)
-  MIDI_ACTION_NUMPAD_0,         // NUMPAD0
-  MIDI_ACTION_NUMPAD_1,         // NUMPAD1
-  MIDI_ACTION_NUMPAD_2,         // NUMPAD2
-  MIDI_ACTION_NUMPAD_3,         // NUMPAD3
-  MIDI_ACTION_NUMPAD_4,         // NUMPAD4
-  MIDI_ACTION_NUMPAD_5,         // NUMPAD5
-  MIDI_ACTION_NUMPAD_6,         // NUMPAD6
-  MIDI_ACTION_NUMPAD_7,         // NUMPAD7
-  MIDI_ACTION_NUMPAD_8,         // NUMPAD8
-  MIDI_ACTION_NUMPAD_9,         // NUMPAD9
-  MIDI_ACTION_NUMPAD_CL,        // NUMPADCL
-  MIDI_ACTION_NUMPAD_ENTER,     // NUMPADENTER
-  MIDI_ACTION_PAN,             // PAN:                 change panning of panadater/waterfall when zoomed
-  MIDI_ACTION_PAN_HIGH,                // PANHIGH:             "high" value of current panadapter
-  MIDI_ACTION_PAN_LOW,         // PANLOW:              "low" value of current panadapter
-  MIDI_ACTION_PRE,             // PREAMP:              preamp on/off
-  MIDI_ACTION_PTTKEYER,                // PTT(Keyer):                  set PTT state to "on" or "off"
-  MIDI_ACTION_PS,              // PURESIGNAL:          toggle PURESIGNAL on/off
-  MIDI_ACTION_RF_GAIN,         // RFGAIN:              receiver RF gain
-  MIDI_ACTION_TX_DRIVE,                // RFPOWER:             adjust TX RF output power
-  MIDI_ACTION_RIT_CLEAR,       // RITCLEAR:            clear RIT and XIT value
-  MIDI_ACTION_RIT_STEP,                // RITSTEP:             cycle through RIT/XIT step size values
-  MIDI_ACTION_RIT_TOGGLE,      // RITTOGGLE:           toggle RIT on/off
-  MIDI_ACTION_RIT_VAL,         // RITVAL:              change RIT value
-  MIDI_ACTION_SAT,             // SAT:                 cycle through SAT modes off/SAT/RSAT
-  MIDI_ACTION_SNB,             // SNB:                 toggle SNB on/off
-  MIDI_ACTION_SPLIT,           // SPLIT:               Split on/off
-  MIDI_ACTION_MEM_STORE_M0,     // STOREM0:            store current freq/mode/filter in memory slot #0
-  MIDI_ACTION_MEM_STORE_M1,     // STOREM1:            store current freq/mode/filter in memory slot #1
-  MIDI_ACTION_MEM_STORE_M2,     // STOREM2:            store current freq/mode/filter in memory slot #2
-  MIDI_ACTION_MEM_STORE_M3,     // STOREM3:            store current freq/mode/filter in memory slot #3
-  MIDI_ACTION_MEM_STORE_M4,     // STOREM4:            store current freq/mode/filter in memory slot #4
-  MIDI_ACTION_SWAP_RX,                 // SWAPRX:              swap active receiver (if there are two receivers)
-  MIDI_ACTION_SWAP_VFO,                // SWAPVFO:             swap VFO A/B frequency
-  MIDI_ACTION_TUNE,            // TUNE:                toggle "tune" state
-  MIDI_ACTION_VFOA,            // VFOA:                change VFO-A frequency
-  MIDI_ACTION_VFOB,            // VFOB:                change VFO-B frequency
-  MIDI_ACTION_VFO_STEP_UP,     // VFOSTEPUP:           cycle through vfo steps upwards;
-  MIDI_ACTION_VFO_STEP_DOWN,   // VFOSTEPDOWN:         cycle through vfo steps downwards;
-  MIDI_ACTION_VOX,             // VOX:                 toggle VOX on/off
-  MIDI_ACTION_VOXLEVEL,        // VOXLEVEL:            adjust VOX threshold
-  MIDI_ACTION_XIT_CLEAR,       // XITCLEAR:            clear XIT value
-  MIDI_ACTION_XIT_VAL,         // XITVAL:              change XIT value
-  MIDI_ACTION_ZOOM,            // ZOOM:                change zoom factor
-  MIDI_ACTION_ZOOM_UP,         // ZOOMUP:              change zoom factor
-  MIDI_ACTION_ZOOM_DOWN,       // ZOOMDOWN:            change zoom factor
-  MIDI_ACTION_LAST,             // flag for end of list
-};
-
-//
-// MIDItype encodes the type of MIDI control. This info
-// is passed from Layer-2 to Layer-3
-//
-// MIDI_TYPE_KEY has no parameters and indicates that some
-// button has been pressed.
-//
-// MIDI_TYPE_KNOB has a "value" parameter (between 0 and 100)
-// and indicates that some knob has been set to a specific
-// position.
-//
-// MIDI_TYPE_WHEEL has a "direction" parameter and indicates that
-// some knob has been turned left/down or right/ip. The  value
-// can be
-//
-// -100 very fast going down
-//  -10 fast going down
-//   -1 going down
-//    1 going up
-//   10 fast going up
-//  100 very fast going up
-//
-
-enum MIDItype {
- MIDI_TYPE_NONE =0,
- MIDI_TYPE_KEY  =1,      // Button (press event)
- MIDI_TYPE_KNOB =2,      // Knob   (value between 0 and 100)
- MIDI_TYPE_WHEEL=4       // Wheel  (direction and speed)
-};
+#ifndef _MIDI_H
+#define _MIDI_H
 
 extern gchar *midi_types[];
 extern gchar *midi_events[];
@@ -201,24 +55,22 @@ extern gchar *midi_events[];
 // MIDI_KNOB or MIDI_WHEEL, depending on the device description.
 //
 enum MIDIevent {
MIDI_EVENT_NONE=0,
- MIDI_EVENT_NOTE,
- MIDI_EVENT_CTRL,
- MIDI_EVENT_PITCH
+ EVENT_NONE=0,
+ MIDI_NOTE,
+ MIDI_CTRL,
+ MIDI_PITCH
 };
 
-typedef struct _action_table {
-  enum MIDIaction action;
-  const char *str;
-  enum MIDItype type;
-  int onoff;
-} ACTION_TABLE;
-
-extern ACTION_TABLE ActionTable[];
-
 //
 // Data structure for Layer-2
 //
+typedef struct _old_action_table {
+  enum ACTION action;
+  const char *str;
+  enum ACTIONtype type;
+} OLD_ACTION_TABLE;
+
+extern OLD_ACTION_TABLE OLD_ActionTable[];
 
 //
 // There is linked list of all specified MIDI events for a given "Note" value,
@@ -249,7 +101,7 @@ struct desc {
    int               channel;     // -1 for ANY channel
    enum MIDIevent    event;      // type of event (NOTE on/off, Controller change, Pitch value)
    int               onoff;       // 1: generate upstream event both for Note-on and Note-off
-   enum MIDItype     type;        // Key, Knob, or Wheel
+   enum ACTIONtype   type;        // Key, Knob, or Wheel
    int               vfl1,vfl2;   // Wheel only: range of controller values for "very fast left"
    int               fl1,fl2;     // Wheel only: range of controller values for "fast left"
    int               lft1,lft2;   // Wheel only: range of controller values for "slow left"
@@ -257,7 +109,7 @@ struct desc {
    int               fr1,fr2;     // Wheel only: range of controller values for "fast right"
    int               rgt1,rgt2;   // Wheel only: range of controller values for "slow right"
    int              delay;       // Wheel only: delay (msec) before next message is given upstream
-   enum MIDIaction   action;     // SDR "action" to generate
+   int               action;     // SDR "action" to generate
    struct desc       *next;       // Next defined action for a controller/key with that note value (NULL for end of list)
 };
 
@@ -296,4 +148,5 @@ void MidiReleaseCommands();
 // tons of invocations of g_idle_add with routines from ext.c
 //
 
-void DoTheMidi(enum MIDIaction code, enum MIDItype type, int val);
+void DoTheMidi(int code, enum ACTIONtype type, int val);
+#endif
diff --git a/midi2.c b/midi2.c
index ebc6f6393d9eb9ac00140004b62bcf85f5af4a38..d1941a69518368cf7a46f3af5303748fe75215ec 100644 (file)
--- a/midi2.c
+++ b/midi2.c
@@ -24,6 +24,7 @@
 #include "transmitter.h"
 #include "radio.h"
 #include "main.h"
+#include "actions.h"
 #include "midi.h"
 #include "alsa_midi.h"
 
@@ -33,7 +34,7 @@ void NewMidiEvent(enum MIDIevent event, int channel, int note, int val) {
 
     struct desc *desc;
     int new;
-    static enum MIDIaction last_wheel_action=MIDI_ACTION_NONE ;
+    static int last_wheel_action=NO_ACTION ;
     static struct timespec tp, last_wheel_tp={0,0};
     long delta;
     struct timespec ts;  // used in debug code
@@ -44,28 +45,28 @@ void NewMidiEvent(enum MIDIevent event, int channel, int note, int val) {
 //now=ts.tv_sec + 1E-9*ts.tv_nsec;
 //g_print("%s:%12.3f:EVENT=%d CHAN=%d NOTE=%d VAL=%d\n",__FUNCTION__,now,event,channel,note,val);
 
-    if (event == MIDI_EVENT_PITCH) {
+    if (event == MIDI_PITCH) {
        desc=MidiCommandsTable[128];
     } else {
        desc=MidiCommandsTable[note];
     }
-//g_print("MIDI:init DESC=%p\n",desc);
+//g_print("%s: init DESC=%p\n",__FUNCTION__,desc);
     while (desc) {
-//g_print("DESC=%p next=%p CHAN=%d EVENT=%d\n", desc,desc->next,desc->channel,desc->event);
+//g_print("%s: DESC=%p next=%p CHAN=%d EVENT=%d\n",__FUNCTION__,desc,desc->next,desc->channel,desc->event);
        if ((desc->channel == channel || desc->channel == -1) && (desc->event == event)) {
            // Found matching entry
            switch (desc->event) {
-               case MIDI_EVENT_NOTE:
-                   if ((val == 1 || (desc->onoff == 1)) && desc->type == MIDI_TYPE_KEY) {
+               case MIDI_NOTE:
+                   if ((val == 1 || (desc->onoff == 1)) && desc->type == MIDI_KEY) {
                        DoTheMidi(desc->action, desc->type, val);
                    }
                    break;
-               case MIDI_EVENT_CTRL:
-                   if (desc->type == MIDI_TYPE_KNOB) {
+               case MIDI_CTRL:
+                   if (desc->type == MIDI_KNOB) {
                        // normalize value to range 0 - 100
                        new = (val*100)/127;
                        DoTheMidi(desc->action, desc->type, new);
-                   } else if (desc->type == MIDI_TYPE_WHEEL) {
+                   } else if (desc->type == MIDI_WHEEL) {
                        if (desc->delay > 0 && last_wheel_action == desc->action) {
                          clock_gettime(CLOCK_MONOTONIC, &tp);
                          delta=1000*(tp.tv_sec - last_wheel_tp.tv_sec);
@@ -81,21 +82,22 @@ void NewMidiEvent(enum MIDIevent event, int channel, int note, int val) {
                        if ((val >= desc->rgt1) && (val <= desc->rgt2)) new= 1;
                        if ((val >= desc-> fr1) && (val <= desc-> fr2)) new= 4;
                        if ((val >= desc->vfr1) && (val <= desc->vfr2)) new= 16;
-//                     g_print("WHEEL: val=%d new=%d thrs=%d/%d, %d/%d, %d/%d, %d/%d, %d/%d, %d/%d\n",
+//                     g_print("%s: WHEEL PARAMS: val=%d new=%d thrs=%d/%d, %d/%d, %d/%d, %d/%d, %d/%d, %d/%d\n",
+//                               __FUNCTION__,
 //                               val, new, desc->vfl1, desc->vfl2, desc->fl1, desc->fl2, desc->lft1, desc->lft2,
 //                              desc->rgt1, desc->rgt2, desc->fr1, desc->fr2, desc->vfr1, desc->vfr2);
                        if (new != 0) DoTheMidi(desc->action, desc->type, new);
                        last_wheel_action=desc->action;
                    }
                    break;
-               case MIDI_EVENT_PITCH:
-                   if (desc->type == MIDI_TYPE_KNOB) {
+               case MIDI_PITCH:
+                   if (desc->type == MIDI_KNOB) {
                        // normalize value to 0 - 100
                        new = (val*100)/16383;
                        DoTheMidi(desc->action, desc->type, new);
                    }
                    break;
-               case MIDI_EVENT_NONE:
+               case EVENT_NONE:
                    break;
            }
            break;
@@ -105,158 +107,15 @@ void NewMidiEvent(enum MIDIevent event, int channel, int note, int val) {
     }
     if (!desc) {
       // Nothing found. This is nothing to worry about, but log the key to stderr
-      if (event == MIDI_EVENT_PITCH) g_print("Unassigned PitchBend Value=%d\n", val);
-      if (event == MIDI_EVENT_NOTE ) g_print("Unassigned Key Note=%d Val=%d\n", note, val);
-      if (event == MIDI_EVENT_CTRL ) g_print("Unassigned Controller Ctl=%d Val=%d\n", note, val);
+        if (event == MIDI_PITCH) g_print("Unassigned PitchBend Value=%d\n", val);
+        if (event == MIDI_NOTE ) g_print("Unassigned Key Note=%d Val=%d\n", note, val);
+        if (event == MIDI_CTRL ) g_print("Unassigned Controller Ctl=%d Val=%d\n", note, val);
     }
 }
 
 gchar *midi_types[] = {"NONE","KEY","KNOB/SLIDER","*INVALID*","WHEEL"};
 gchar *midi_events[] = {"NONE","NOTE","CTRL","PITCH"};
 
-/*
- * This data structre connects names as used in the midi.props file with
- * our MIDIaction enum values.
- *
- * At some places in the code, it is assumes that ActionTable[i].action == i
- * so keep the entries strictly in the order the enum is defined, and
- * add one entry with ACTION_NONE at the end.
- */
-
-ACTION_TABLE ActionTable[] = {
-        { MIDI_ACTION_NONE,            "NONE",                 MIDI_TYPE_KEY|MIDI_TYPE_KNOB|MIDI_TYPE_WHEEL,   0},
-        { MIDI_ACTION_VFO_A2B,                 "A2B",                  MIDI_TYPE_KEY,                                  0},
-        { MIDI_ACTION_AF_GAIN,                 "AFGAIN",               MIDI_TYPE_KNOB|MIDI_TYPE_WHEEL,                 0},
-        { MIDI_ACTION_AGCATTACK,               "AGCATTACK",            MIDI_TYPE_KEY,                                  0},
-        { MIDI_ACTION_AGC,                     "AGCVAL",               MIDI_TYPE_KNOB|MIDI_TYPE_WHEEL,                 0},
-       { MIDI_ACTION_ANF,              "ANF",                  MIDI_TYPE_KEY,                                  0},
-        { MIDI_ACTION_ATT,                     "ATT",                  MIDI_TYPE_KEY|MIDI_TYPE_KNOB|MIDI_TYPE_WHEEL,   0},
-        { MIDI_ACTION_VFO_B2A,         "B2A",                  MIDI_TYPE_KEY,                                  0},
-        { MIDI_ACTION_BAND_10,                 "BAND10",               MIDI_TYPE_KEY,                                  0},
-        { MIDI_ACTION_BAND_12,                 "BAND12",               MIDI_TYPE_KEY,                                  0},
-        { MIDI_ACTION_BAND_1240,               "BAND1240",             MIDI_TYPE_KEY,                                  0},
-        { MIDI_ACTION_BAND_144,                "BAND144",              MIDI_TYPE_KEY,                                  0},
-        { MIDI_ACTION_BAND_15,                 "BAND15",               MIDI_TYPE_KEY,                                  0},
-        { MIDI_ACTION_BAND_160,                "BAND160",              MIDI_TYPE_KEY,                                  0},
-        { MIDI_ACTION_BAND_17,                 "BAND17",               MIDI_TYPE_KEY,                                  0},
-        { MIDI_ACTION_BAND_20,                 "BAND20",               MIDI_TYPE_KEY,                                  0},
-        { MIDI_ACTION_BAND_220,                "BAND220",              MIDI_TYPE_KEY,                                  0},
-        { MIDI_ACTION_BAND_2300,               "BAND2300",             MIDI_TYPE_KEY,                                  0},
-        { MIDI_ACTION_BAND_30,                 "BAND30",               MIDI_TYPE_KEY,                                  0},
-        { MIDI_ACTION_BAND_3400,               "BAND3400",             MIDI_TYPE_KEY,                                  0},
-        { MIDI_ACTION_BAND_40,                 "BAND40",               MIDI_TYPE_KEY,                                  0},
-        { MIDI_ACTION_BAND_430,                "BAND430",              MIDI_TYPE_KEY,                                  0},
-        { MIDI_ACTION_BAND_6,                  "BAND6",                MIDI_TYPE_KEY,                                  0},
-        { MIDI_ACTION_BAND_60,                 "BAND60",               MIDI_TYPE_KEY,                                  0},
-        { MIDI_ACTION_BAND_70,                 "BAND70",               MIDI_TYPE_KEY,                                  0},
-        { MIDI_ACTION_BAND_80,                 "BAND80",               MIDI_TYPE_KEY,                                  0},
-        { MIDI_ACTION_BAND_902,                "BAND902",              MIDI_TYPE_KEY,                                  0},
-        { MIDI_ACTION_BAND_AIR,                "BANDAIR",              MIDI_TYPE_KEY,                                  0},
-        { MIDI_ACTION_BAND_DOWN,       "BANDDOWN",             MIDI_TYPE_KEY|MIDI_TYPE_KNOB|MIDI_TYPE_WHEEL,   0},
-        { MIDI_ACTION_BAND_GEN,        "BANDGEN",              MIDI_TYPE_KEY,                                  0},
-        { MIDI_ACTION_BAND_UP,                 "BANDUP",               MIDI_TYPE_KEY|MIDI_TYPE_KNOB|MIDI_TYPE_WHEEL,   0},
-        { MIDI_ACTION_BAND_WWV,                "BANDWWV",              MIDI_TYPE_KEY,                                  0},
-        { MIDI_ACTION_COMPRESS,                "COMPRESS",             MIDI_TYPE_KNOB|MIDI_TYPE_WHEEL,                 0},
-        { MIDI_ACTION_CTUN,                    "CTUN",                 MIDI_TYPE_KEY,                                  0},
-        { MIDI_ACTION_VFO,                     "CURRVFO",              MIDI_TYPE_WHEEL,                                0},
-        { MIDI_ACTION_CWKEYER,                 "CW(Keyer)",            MIDI_TYPE_KEY,                                  1},
-        { MIDI_ACTION_CWLEFT,          "CWLEFT",               MIDI_TYPE_KEY,                                  1},
-        { MIDI_ACTION_CWRIGHT,                 "CWRIGHT",              MIDI_TYPE_KEY,                                  1},
-        { MIDI_ACTION_CWSPEED,                 "CWSPEED",              MIDI_TYPE_KNOB|MIDI_TYPE_WHEEL,                 0},
-        { MIDI_ACTION_DIV_COARSEGAIN,          "DIVCOARSEGAIN",        MIDI_TYPE_KNOB|MIDI_TYPE_WHEEL,                 0},
-        { MIDI_ACTION_DIV_COARSEPHASE,  "DIVCOARSEPHASE",       MIDI_TYPE_KNOB|MIDI_TYPE_WHEEL,                        0},
-        { MIDI_ACTION_DIV_FINEGAIN,     "DIVFINEGAIN",         MIDI_TYPE_KNOB|MIDI_TYPE_WHEEL,                 0},
-        { MIDI_ACTION_DIV_FINEPHASE,    "DIVFINEPHASE",        MIDI_TYPE_KNOB|MIDI_TYPE_WHEEL,                 0},
-        { MIDI_ACTION_DIV_GAIN,         "DIVGAIN",             MIDI_TYPE_KNOB|MIDI_TYPE_WHEEL,                 0},
-        { MIDI_ACTION_DIV_PHASE,        "DIVPHASE",            MIDI_TYPE_KNOB|MIDI_TYPE_WHEEL,                 0},
-        { MIDI_ACTION_DIV_TOGGLE,       "DIVTOGGLE",           MIDI_TYPE_KEY,                                  0},
-        { MIDI_ACTION_DUP,                     "DUP",                  MIDI_TYPE_KEY,                                  0},
-        { MIDI_ACTION_FILTER_DOWN,      "FILTERDOWN",          MIDI_TYPE_KEY|MIDI_TYPE_KNOB|MIDI_TYPE_WHEEL,   0},
-        { MIDI_ACTION_FILTER_UP,        "FILTERUP",            MIDI_TYPE_KEY|MIDI_TYPE_KNOB|MIDI_TYPE_WHEEL,   0},
-        { MIDI_ACTION_LOCK,                    "LOCK",                 MIDI_TYPE_KEY,                                  0},
-        { MIDI_ACTION_MEM_RECALL_M0,    "RECALLM0",            MIDI_TYPE_KEY,                                  0},
-        { MIDI_ACTION_MEM_RECALL_M1,    "RECALLM1",            MIDI_TYPE_KEY,                                  0},
-        { MIDI_ACTION_MEM_RECALL_M2,    "RECALLM2",            MIDI_TYPE_KEY,                                  0},
-        { MIDI_ACTION_MEM_RECALL_M3,    "RECALLM3",            MIDI_TYPE_KEY,                                  0},
-        { MIDI_ACTION_MEM_RECALL_M4,    "RECALLM4",            MIDI_TYPE_KEY,                                  0},
-        { MIDI_ACTION_MENU_FILTER,      "MENU_FILTER",         MIDI_TYPE_KEY,                                  0},
-        { MIDI_ACTION_MENU_MODE,        "MENU_MODE",           MIDI_TYPE_KEY,                                  0},
-        { MIDI_ACTION_MIC_VOLUME,       "MICGAIN",             MIDI_TYPE_KNOB|MIDI_TYPE_WHEEL,                 0},
-        { MIDI_ACTION_MODE_DOWN,        "MODEDOWN",            MIDI_TYPE_KEY|MIDI_TYPE_KNOB|MIDI_TYPE_WHEEL,   0},
-        { MIDI_ACTION_MODE_UP,          "MODEUP",              MIDI_TYPE_KEY|MIDI_TYPE_KNOB|MIDI_TYPE_WHEEL,   0},
-        { MIDI_ACTION_MOX,                     "MOX",                  MIDI_TYPE_KEY,                                  0},
-        { MIDI_ACTION_MUTE,                    "MUTE",                 MIDI_TYPE_KEY,                                  0},
-        { MIDI_ACTION_NB,              "NOISEBLANKER",         MIDI_TYPE_KEY,                                  0},
-        { MIDI_ACTION_NR,                      "NOISEREDUCTION",       MIDI_TYPE_KEY,                                  0},
-        { MIDI_ACTION_NUMPAD_0,                "NUMPAD0",              MIDI_TYPE_KEY,                                  0},
-        { MIDI_ACTION_NUMPAD_1,                "NUMPAD1",              MIDI_TYPE_KEY,                                  0},
-        { MIDI_ACTION_NUMPAD_2,                "NUMPAD2",              MIDI_TYPE_KEY,                                  0},
-        { MIDI_ACTION_NUMPAD_3,                "NUMPAD3",              MIDI_TYPE_KEY,                                  0},
-        { MIDI_ACTION_NUMPAD_4,                "NUMPAD4",              MIDI_TYPE_KEY,                                  0},
-        { MIDI_ACTION_NUMPAD_5,                "NUMPAD5",              MIDI_TYPE_KEY,                                  0},
-        { MIDI_ACTION_NUMPAD_6,                "NUMPAD6",              MIDI_TYPE_KEY,                                  0},
-        { MIDI_ACTION_NUMPAD_7,                "NUMPAD7",              MIDI_TYPE_KEY,                                  0},
-        { MIDI_ACTION_NUMPAD_8,                "NUMPAD8",              MIDI_TYPE_KEY,                                  0},
-        { MIDI_ACTION_NUMPAD_9,                "NUMPAD9",              MIDI_TYPE_KEY,                                  0},
-        { MIDI_ACTION_NUMPAD_CL,               "NUMPADCL",             MIDI_TYPE_KEY,                                  0},
-        { MIDI_ACTION_NUMPAD_ENTER,            "NUMPADENTER",          MIDI_TYPE_KEY,                                  0},
-        { MIDI_ACTION_PAN,                     "PAN",                  MIDI_TYPE_KNOB|MIDI_TYPE_WHEEL,                 0},
-        { MIDI_ACTION_PAN_HIGH,                "PANHIGH",              MIDI_TYPE_KNOB|MIDI_TYPE_WHEEL,                 0},
-        { MIDI_ACTION_PAN_LOW,                 "PANLOW",               MIDI_TYPE_KNOB|MIDI_TYPE_WHEEL,                 0},
-        { MIDI_ACTION_PRE,                     "PREAMP",               MIDI_TYPE_KEY,                                  0},
-        { MIDI_ACTION_PTTKEYER,                "PTT(Keyer)",           MIDI_TYPE_KEY,                                  1},
-        { MIDI_ACTION_PS,               "PURESIGNAL",          MIDI_TYPE_KEY,                                  0},
-        { MIDI_ACTION_RF_GAIN,                 "RFGAIN",               MIDI_TYPE_KNOB|MIDI_TYPE_WHEEL,                 0},
-        { MIDI_ACTION_TX_DRIVE,         "RFPOWER",             MIDI_TYPE_KNOB|MIDI_TYPE_WHEEL,                 0},
-        { MIDI_ACTION_RIT_CLEAR,               "RITCLEAR",             MIDI_TYPE_KEY,                                  0},
-        { MIDI_ACTION_RIT_STEP,         "RITSTEP",             MIDI_TYPE_KEY|MIDI_TYPE_WHEEL,                  0},
-        { MIDI_ACTION_RIT_TOGGLE,       "RITTOGGLE",           MIDI_TYPE_KEY,                                  0},
-        { MIDI_ACTION_RIT_VAL,          "RITVAL",              MIDI_TYPE_KNOB|MIDI_TYPE_WHEEL,                 0},
-        { MIDI_ACTION_SAT,                     "SAT",                  MIDI_TYPE_KEY,                                  0},
-        { MIDI_ACTION_SNB,              "SNB",                 MIDI_TYPE_KEY,                                  0},
-        { MIDI_ACTION_SPLIT,                   "SPLIT",                MIDI_TYPE_KEY,                                  0},
-        { MIDI_ACTION_MEM_STORE_M0,     "STOREM0",                     MIDI_TYPE_KEY,                                  0},
-        { MIDI_ACTION_MEM_STORE_M1,     "STOREM1",                     MIDI_TYPE_KEY,                                  0},
-        { MIDI_ACTION_MEM_STORE_M2,     "STOREM2",                     MIDI_TYPE_KEY,                                  0},
-        { MIDI_ACTION_MEM_STORE_M3,     "STOREM3",              MIDI_TYPE_KEY,                                 0},
-        { MIDI_ACTION_MEM_STORE_M4,     "STOREM4",              MIDI_TYPE_KEY,                                 0},
-        { MIDI_ACTION_SWAP_RX,          "SWAPRX",              MIDI_TYPE_KEY,                                  0},
-        { MIDI_ACTION_SWAP_VFO,         "SWAPVFO",             MIDI_TYPE_KEY,                                  0},
-        { MIDI_ACTION_TUNE,                    "TUNE",                 MIDI_TYPE_KEY,                                  0},
-        { MIDI_ACTION_VFOA,             "VFOA",                MIDI_TYPE_WHEEL,                                0},
-        { MIDI_ACTION_VFOB,             "VFOB",                MIDI_TYPE_WHEEL,                                0},
-        { MIDI_ACTION_VFO_STEP_UP,      "VFOSTEPUP",           MIDI_TYPE_KEY|MIDI_TYPE_WHEEL,                  0},
-        { MIDI_ACTION_VFO_STEP_DOWN,    "VFOSTEPDOWN",         MIDI_TYPE_KEY|MIDI_TYPE_WHEEL,                  0},
-        { MIDI_ACTION_VOX,              "VOX",                 MIDI_TYPE_KEY,                                  0},
-        { MIDI_ACTION_VOXLEVEL,         "VOXLEVEL",            MIDI_TYPE_KNOB|MIDI_TYPE_WHEEL,                 0},
-        { MIDI_ACTION_XIT_CLEAR,               "XITCLEAR",             MIDI_TYPE_KEY,                                  0},
-        { MIDI_ACTION_XIT_VAL,          "XITVAL",              MIDI_TYPE_KNOB|MIDI_TYPE_WHEEL,                 0},
-        { MIDI_ACTION_ZOOM,                    "ZOOM",                 MIDI_TYPE_KNOB|MIDI_TYPE_WHEEL,                 0},
-        { MIDI_ACTION_ZOOM_UP,          "ZOOMUP",              MIDI_TYPE_KEY|MIDI_TYPE_WHEEL,                  0},
-        { MIDI_ACTION_ZOOM_DOWN,        "ZOOMDOWN",            MIDI_TYPE_KEY|MIDI_TYPE_WHEEL,                  0},
-        { MIDI_ACTION_LAST,            "NONE",                 MIDI_TYPE_NONE,                                 0},
-};
-
-
-/*
- * Translation from keyword in midi.props file to MIDIaction
- */
-
-static void keyword2action(char *s, enum MIDIaction *action, int *onoff) {
-    int i=0;
-
-    for (i=0; i< (sizeof(ActionTable) / sizeof(ActionTable[0])); i++) {
-       if (!strcmp(s, ActionTable[i].str)) {
-          *action = ActionTable[i].action;
-          *onoff  = ActionTable[i].onoff;
-          return;
-        }
-    }
-    g_print("%s: action keyword %s NOT FOUND.\n", __FUNCTION__, s);
-    *action = MIDI_ACTION_NONE;
-    *onoff  = 0;
-}
-
 int MIDIstop() {
   for (int i=0; i<n_midi_devices; i++) {
     if (midi_devices[i].active) {
@@ -313,22 +172,136 @@ void MidiAddCommand(int note, struct desc *desc) {
   }
 }
 
+//
+// maintained so old midi configurations can be loaded
+//
+OLD_ACTION_TABLE OLD_ActionTable[] = {
+       { NO_ACTION,            "NONE",         TYPE_NONE},
+       { A_TO_B,               "A2B",          MIDI_KEY},
+        { AF_GAIN,             "AFGAIN",       MIDI_KNOB|MIDI_WHEEL},
+       { AGC,                  "AGCATTACK",    MIDI_KEY},
+        { AGC_GAIN,            "AGCVAL",       MIDI_KNOB|MIDI_WHEEL},
+        { ANF,                 "ANF",          MIDI_KEY},
+        { ATTENUATION,                 "ATT",          MIDI_KNOB|MIDI_WHEEL},
+       { B_TO_A,                       "B2A",          MIDI_KEY},
+       { BAND_10,         "BAND10",    MIDI_KEY},
+        { BAND_12,         "BAND12",   MIDI_KEY},
+        { BAND_1240,       "BAND1240", MIDI_KEY},
+        { BAND_144,        "BAND144",  MIDI_KEY},
+        { BAND_15,         "BAND15",   MIDI_KEY},
+        { BAND_160,        "BAND160",  MIDI_KEY},
+        { BAND_17,         "BAND17",   MIDI_KEY},
+        { BAND_20,         "BAND20",   MIDI_KEY},
+        { BAND_220,        "BAND220",  MIDI_KEY},
+        { BAND_2300,       "BAND2300", MIDI_KEY},
+        { BAND_30,         "BAND30",   MIDI_KEY},
+        { BAND_3400,       "BAND3400", MIDI_KEY},
+        { BAND_40,         "BAND40",   MIDI_KEY},
+        { BAND_430,        "BAND430",  MIDI_KEY},
+        { BAND_6,          "BAND6",    MIDI_KEY},
+        { BAND_60,         "BAND60",   MIDI_KEY},
+        { BAND_70,         "BAND70",   MIDI_KEY},
+        { BAND_80,         "BAND80",   MIDI_KEY},
+        { BAND_902,        "BAND902",  MIDI_KEY},
+        { BAND_AIR,        "BANDAIR",  MIDI_KEY},
+        { BAND_MINUS,      "BANDDOWN", MIDI_KEY},
+        { BAND_GEN,        "BANDGEN",  MIDI_KEY},
+        { BAND_PLUS,       "BANDUP",   MIDI_KEY},
+        { BAND_WWV,        "BANDWWV",  MIDI_KEY},
+        { COMPRESSION,         "COMPRESS",     MIDI_KEY},
+       { CTUN,                 "CTUN",         MIDI_KEY},
+       { VFO,                  "CURRVFO",      MIDI_WHEEL},
+       { CW_LEFT,              "CWL",          MIDI_KEY},
+       { CW_RIGHT,             "CWR",          MIDI_KEY},
+       { CW_SPEED,             "CWSPEED",      MIDI_KNOB|MIDI_WHEEL},
+       { DIV_GAIN_COARSE,      "DIVCOARSEGAIN",        MIDI_KNOB|MIDI_WHEEL},
+       { DIV_PHASE_COARSE,     "DIVCOARSEPHASE",       MIDI_KNOB|MIDI_WHEEL},
+       { DIV_GAIN_FINE,        "DIVFINEGAIN",  MIDI_KNOB|MIDI_WHEEL},
+       { DIV_PHASE_FINE,       "DIVFINEPHASE", MIDI_KNOB|MIDI_WHEEL},
+       { DIV_GAIN,             "DIVGAIN",      MIDI_KNOB|MIDI_WHEEL},
+       { DIV_PHASE,            "DIVPHASE",     MIDI_KNOB|MIDI_WHEEL},
+       { DIV,                  "DIVTOGGLE",    MIDI_KEY},
+       { DUPLEX,               "DUP",          MIDI_KEY},
+        { FILTER_MINUS,        "FILTERDOWN",   MIDI_KEY},
+        { FILTER_PLUS,         "FILTERUP",     MIDI_KEY},
+       { MENU_FILTER,          "MENU_FILTER",  MIDI_KEY},
+       { MENU_MODE,            "MENU_MODE",    MIDI_KEY},
+       { LOCK,                 "LOCK",         MIDI_KEY},
+        { MIC_GAIN,            "MICGAIN",      MIDI_KNOB|MIDI_WHEEL},
+       { MODE_MINUS,           "MODEDOWN",     MIDI_KEY|MIDI_KNOB|MIDI_WHEEL},
+       { MODE_PLUS,            "MODEUP",       MIDI_KEY|MIDI_KNOB|MIDI_WHEEL},
+        { MOX,                         "MOX",  MIDI_KEY},
+       { MUTE,                 "MUTE", MIDI_KEY},
+       { NB,                   "NOISEBLANKER", MIDI_KEY},
+       { NR,                   "NOISEREDUCTION",       MIDI_KEY},
+       { NUMPAD_0,             "NUMPAD0",      MIDI_KEY},
+       { NUMPAD_1,             "NUMPAD1",      MIDI_KEY},
+       { NUMPAD_2,             "NUMPAD2",      MIDI_KEY},
+       { NUMPAD_3,             "NUMPAD3",      MIDI_KEY},
+       { NUMPAD_4,             "NUMPAD4",      MIDI_KEY},
+       { NUMPAD_5,             "NUMPAD5",      MIDI_KEY},
+       { NUMPAD_6,             "NUMPAD6",      MIDI_KEY},
+       { NUMPAD_7,             "NUMPAD7",      MIDI_KEY},
+       { NUMPAD_8,             "NUMPAD8",      MIDI_KEY},
+       { NUMPAD_9,             "NUMPAD9",      MIDI_KEY},
+       { NUMPAD_CL,            "NUMPADCL",     MIDI_KEY},
+       { NUMPAD_ENTER,         "NUMPADENTER",  MIDI_KEY},
+        { PAN,                 "PAN",  MIDI_KNOB|MIDI_WHEEL},
+        { PANADAPTER_HIGH,             "PANHIGH",      MIDI_KNOB|MIDI_WHEEL},
+        { PANADAPTER_LOW,              "PANLOW",       MIDI_KNOB|MIDI_WHEEL},
+        { PREAMP,              "PREAMP",       MIDI_KEY},
+       { PS,                   "PURESIGNAL",   MIDI_KEY},
+       { RF_GAIN,              "RFGAIN",       MIDI_KNOB|MIDI_WHEEL},
+        { DRIVE,               "RFPOWER",      MIDI_KNOB|MIDI_WHEEL},
+       { RIT_CLEAR,            "RITCLEAR",     MIDI_KEY},
+       { RIT_STEP,             "RITSTEP",      MIDI_KNOB|MIDI_WHEEL},
+        { RIT_ENABLE,          "RITTOGGLE",    MIDI_KEY},
+        { RIT,                 "RITVAL",       MIDI_KNOB|MIDI_WHEEL},
+        { SAT,                 "SAT",  MIDI_KEY},
+        { SNB,                         "SNB",  MIDI_KEY},
+       { SPLIT,                "SPLIT",        MIDI_KEY},
+       { SWAP_RX,              "SWAPRX",       MIDI_KEY},
+       { A_SWAP_B,             "SWAPVFO",      MIDI_KEY},
+        { TUNE,                "TUNE", MIDI_KEY},
+        { VFOA,                "VFOA", MIDI_WHEEL},
+        { VFOB,                "VFOB", MIDI_WHEEL},
+       { VFO_STEP_MINUS,       "VFOSTEPDOWN",  MIDI_KEY},
+       { VFO_STEP_PLUS,        "VFOSTEPUP",    MIDI_KEY},
+       { VOX,                  "VOX",  MIDI_KEY},
+       { VOXLEVEL,             "VOXLEVEL",     MIDI_KNOB|MIDI_WHEEL},
+       { XIT_CLEAR,            "XITCLEAR",     MIDI_KEY},
+       { XIT,                  "XITVAL",       MIDI_KNOB|MIDI_WHEEL},
+       { ZOOM,                 "ZOOM", MIDI_KNOB|MIDI_WHEEL},
+       { ZOOM_MINUS,           "ZOOMDOWN",     MIDI_KEY},
+       { ZOOM_PLUS,            "ZOOMUP",       MIDI_KEY},
+        { NO_ACTION,   "NONE", TYPE_NONE}
+};
+
 /*
- * Here we read in a MIDI description file and fill the MidiCommandsTable
- * data structure
+ * Translation from keyword in midi.props file to MIDIaction
  */
 
+static int keyword2action(char *s) {
+    int i=0;
+
+    for (i=0; i< (sizeof(OLD_ActionTable) / sizeof(OLD_ActionTable[0])); i++) {
+       if (!strcmp(s, OLD_ActionTable[i].str)) return OLD_ActionTable[i].action;
+    }
+    fprintf(stderr,"MIDI: action keyword %s NOT FOUND.\n", s);
+    return NO_ACTION;
+}
+
 int MIDIstartup(char *filename) {
     FILE *fpin;
     char zeile[255];
     char *cp,*cq;
     int key;
-    enum MIDIaction action;
+    int action;
     int chan;
     int t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12;
     int onoff, delay;
     struct desc *desc;
-    enum MIDItype type;
+    enum ACTIONtype type;
     enum MIDIevent event;
     char c;
 
@@ -374,8 +347,8 @@ int MIDIstartup(char *filename) {
       t7=65; t8=127;
       t9 = t10 = t11 = t12 = -1;
       onoff=0;                  // this will be set automatically
-      event=MIDI_EVENT_NONE;
-      type=MIDI_TYPE_NONE;
+      event=EVENT_NONE;
+      type=TYPE_NONE;
       key=0;
       delay=0;
 
@@ -386,25 +359,25 @@ int MIDIstartup(char *filename) {
       //
       if ((cp = strstr(zeile, "KEY="))) {
         sscanf(cp+4, "%d", &key);
-        event=MIDI_EVENT_NOTE;
-       type=MIDI_TYPE_KEY;
+        event=MIDI_NOTE;
+       type=MIDI_KEY;
 //g_print("%s: MIDI:KEY:%d\n",__FUNCTION__, key);
       }
       if ((cp = strstr(zeile, "CTRL="))) {
         sscanf(cp+5, "%d", &key);
-       event=MIDI_EVENT_CTRL;
-       type=MIDI_TYPE_KNOB;
+       event=MIDI_CTRL;
+       type=MIDI_KNOB;
 //g_print("%s: MIDI:CTL:%d\n",__FUNCTION__, key);
       }
       if ((cp = strstr(zeile, "PITCH "))) {
-        event=MIDI_EVENT_PITCH;
-       type=MIDI_TYPE_KNOB;
+        event=MIDI_PITCH;
+       type=MIDI_KNOB;
 //g_print("%s: MIDI:PITCH\n",__FUNCTION__);
       }
       //
       // If event is still undefined, skip line
       //
-      if (event == MIDI_EVENT_NONE) {
+      if (event == EVENT_NONE) {
 //g_print("%s: no event found: %s\n", __FUNCTION__, zeile);
        continue;
       }
@@ -421,9 +394,9 @@ int MIDIstartup(char *filename) {
         if (chan<0 || chan>15) chan=-1;
 //g_print("%s:CHAN:%d\n",__FUNCTION__,chan);
       }
-      if ((cp = strstr(zeile, "WHEEL")) && (type == MIDI_TYPE_KNOB)) {
-       // change type from MIDI_TYPE_KNOB to MIDI_TYPE_WHEEL
-        type=MIDI_TYPE_WHEEL;
+      if ((cp = strstr(zeile, "WHEEL")) && (type == MIDI_KNOB)) {
+       // change type from MIDI_KNOB to MIDI_WHEEL
+        type=MIDI_WHEEL;
 //g_print("%s:WHEEL\n",__FUNCTION__);
       }
       if ((cp = strstr(zeile, "DELAY="))) {
@@ -440,7 +413,21 @@ int MIDIstartup(char *filename) {
         cq=cp+7;
         while (*cq != 0 && *cq != '\n' && *cq != ' ' && *cq != '\t') cq++;
        *cq=0;
-        keyword2action(cp+7, &action, &onoff);
+        action=keyword2action(cp+7);
+        //
+        // set ONOFF flag automatically
+        //
+        switch (action) {
+          case CW_LEFT:
+          case CW_RIGHT:
+          case CW_KEYER:
+          case PTT_KEYER:
+           onoff=1;
+            break;
+         default:
+           onoff=0;
+           break;
+        }
 //g_print("MIDI:ACTION:%s (%d), onoff=%d\n",cp+7, action, onoff);
       }
       //
@@ -470,11 +457,11 @@ int MIDIstartup(char *filename) {
       // insert descriptor into linked list.
       // We have a linked list for each key value to speed up searches
       //
-      if (event == MIDI_EVENT_PITCH) {
+      if (event == MIDI_PITCH) {
 //g_print("%s: Insert desc=%p in CMDS[128] table\n",__FUNCTION__,desc);
         MidiAddCommand(128, desc);
       }
-      if (event == MIDI_EVENT_NOTE || event == MIDI_EVENT_CTRL) {
+      if (event == MIDI_NOTE || event == MIDI_CTRL) {
 //g_print("%s: Insert desc=%p in CMDS[%d] table\n",__FUNCTION__,desc,key);
         MidiAddCommand(key, desc);
       }
diff --git a/midi3.c b/midi3.c
index 0b5b7eea7d5497294d6de994880c8fac43be54db..55b3c4d8eaea056b4ceea4dfcef302776555749f 100644 (file)
--- a/midi3.c
+++ b/midi3.c
@@ -6,9 +6,9 @@
  *
  * In most cases, a certain action only makes sense for a specific
  * type. For example, changing the VFO frequency will only be implemeted
- * for MIDI_TYPE_WHEEL, and TUNE off/on only with MIDI_TYPE_KNOB.
+ * for MIDI_WHEEL, and TUNE off/on only with MIDI_KNOB.
  *
- * However, changing the volume makes sense both with MIDI_TYPE_KNOB and MIDI_TYPE_WHEEL.
+ * However, changing the volume makes sense both with MIDI_KNOB and MIDI_WHEEL.
  */
 #include <gtk/gtk.h>
 
 #include "sliders.h"
 #include "ext.h"
 #include "agc.h"
+#include "actions.h"
 #include "midi.h"
-#include "store.h"
 #ifdef LOCALCW
 #include "iambic.h"
 #endif
-#include "wdsp.h"
-#include "diversity_menu.h"
-#include "radio_menu.h"
-#include "toolbar.h"
-#include "noise_menu.h"
-#include "zoompan.h"
 
-//
-// Virtually all MIDI actions at the end lead to functions that have
-// to be invoked by GTK. Instead of having dozens of g_idle_add() in the
-// code below, one can queue the "big switch statement" into the GTK
-// idle queue and exectue all GUI functions directly.
-//
-// However, this is not wanted for CWKEYER, CWLEFT and CWRIGHT since
-// these have to be processed with minimal delay (and do not call GUI functions).
-//
-// Therefore, these three cases are already handled in the MIDI callback
-// function and everything else is put into the GTK queue
-//
+void DoTheMidi(int action, enum ACTIONtype type, int val) {
 
-//
-// This is the data struct generated by processing the MIDI event
-// it is passed to the function DoTheMidi
-//
-struct _MIDIcmd {
-   enum MIDIaction action;
-   enum MIDItype type;
-   int val;
-};
-
-typedef struct _MIDIcmd MIDIcmd;
+    int new;
+    double dnew;
+    double *dp;
+    int    *ip;
+    PROCESS_ACTION *a;
 
-static int DoTheRestOfTheMIDI(void *data);
+    g_print("%s: action=%d type=%d val=%d\n",__FUNCTION__,action,type,val);
 
-void DoTheMidi(enum MIDIaction action, enum MIDItype type, int val) {
-    if (action == MIDI_ACTION_CWKEYER) {
+    //
+    // CW actions are time-critical, so they are handled HERE
+    // instead of invoking the GTK idle queue
+    //
+    if (action == CW_KEYER) {
           //
           // This is a CW key-up/down which uses functions from the keyer
           // that by-pass the interrupt-driven standard action.
@@ -85,1023 +65,36 @@ void DoTheMidi(enum MIDIaction action, enum MIDItype type, int val) {
           }
           return;
     }
-#ifdef LOCALCW
-    if (action == MIDI_ACTION_CWLEFT) {
-         keyer_event(1, val);
-         return;
+#ifdef LOCALCW  
+    if (action == CW_LEFT) {
+       keyer_event(1, val);
+       return;
     }
-    if (action == MIDI_ACTION_CWRIGHT) {
-         keyer_event(0, val);
-         return;
+    if (action == CW_RIGHT) {
+       keyer_event(0, val);
+       return;
     }
 #endif
-    //
-    // For all other MIDI actions, the parser is put into the idle queu
-    //
-    MIDIcmd *cmd=malloc(sizeof(MIDIcmd));
-    cmd->action = action;
-    cmd->type   = type;
-    cmd->val    = val;
-    g_idle_add(DoTheRestOfTheMIDI, cmd);
-    return;
-}
-
-int DoTheRestOfTheMIDI(void *data) {
-    MIDIcmd *cmd = (MIDIcmd *)data;
-   
-    int new;
-    int id, c25;
-    double dnew;
-
-    enum MIDIaction action = cmd->action;
-    enum MIDItype   type   = cmd->type;
-    int             val    = cmd->val;
-
-    free(data);
-
-    //
-    // Handle cases in alphabetical order of the key words in midi.props
-    //
-    switch (action) {
-       /////////////////////////////////////////////////////////// "A2B"
-       case MIDI_ACTION_VFO_A2B: // only key supported
-            vfo_a_to_b();
-           break;
-       /////////////////////////////////////////////////////////// "AFGAIN"
-       case MIDI_ACTION_AF_GAIN: // knob or wheel supported
-            switch (type) {
-             case MIDI_TYPE_KNOB:
-               active_receiver->volume = 0.01*val;
-               break;
-             case MIDI_TYPE_WHEEL:     
-               dnew=active_receiver->volume += 0.01*val;
-               if (dnew < 0.0) dnew=0.0; if (dnew > 1.0) dnew=1.0;
-               active_receiver->volume = dnew;
-               break;
-             default:
-               // do not change volume
-               // we should not come here anyway
-               break;
-           }
-            update_af_gain();
-           break;
-       /////////////////////////////////////////////////////////// "AGCATTACK"
-       case MIDI_ACTION_AGCATTACK: // only key supported
-           // cycle through fast/med/slow AGC attack
-           new=active_receiver->agc + 1;
-           if (new > AGC_FAST) new=0;
-           active_receiver->agc=new;
-            vfo_update();
-           break;
-       /////////////////////////////////////////////////////////// "AGCVAL"
-       case MIDI_ACTION_AGC: // knob or wheel supported
-           switch (type) {
-             case MIDI_TYPE_KNOB:
-               dnew = -20.0 + 1.4*val;
-               break;
-             case MIDI_TYPE_WHEEL:
-               dnew=active_receiver->agc_gain + val;
-               if (dnew < -20.0) dnew = -20.0;
-                if (dnew > 120.0) dnew = 120.0;
-               break;
-             default:
-               // do not change value
-               // we should not come here anyway
-               dnew=active_receiver->agc_gain;
-               break;
-           }
-            set_agc_gain(active_receiver->id, dnew);
-           break;
-       /////////////////////////////////////////////////////////// "ANF"
-       case MIDI_ACTION_ANF:   // only key supported
-            if (active_receiver->anf==0) {
-              active_receiver->anf=1;
-              mode_settings[vfo[active_receiver->id].mode].anf=1;
-            } else {
-              active_receiver->snb=0;
-              mode_settings[vfo[active_receiver->id].mode].anf=0;
-            }
-            SetRXAANFRun(active_receiver->id, active_receiver->anf);
-            vfo_update();
-           break;
-       /////////////////////////////////////////////////////////// "ATT"
-       case MIDI_ACTION_ATT:   // Key for ALEX attenuator, wheel or knob for slider
-           switch(type) {
-             case MIDI_TYPE_KEY:
-               if (filter_board == ALEX && active_receiver->adc == 0) {
-                 new=active_receiver->alex_attenuation + 1;
-                 if (new > 3) new=0;
-                  set_alex_attenuation(new);
-                  update_att_preamp();
-               }
-               break;
-             case MIDI_TYPE_WHEEL:
-               dnew=adc[active_receiver->adc].attenuation + val;
-                if(have_rx_gain) {
-                  if(dnew < -12.0) {
-                    dnew = -12.0;
-                  } else if(dnew > 48.0) {
-                    dnew=48.0;
-                  }
-                } else {
-                  if (dnew < 0.0) {
-                    dnew = 0.0;
-                  } else if (dnew > 31.0) {
-                    dnew = 31.0;
-                  }
-                }
-                set_attenuation_value(dnew);
-               break;
-             case MIDI_TYPE_KNOB:
-                if (have_rx_gain) {
-                 dnew = -12.0 + 0.6*val;
-                } else {
-                  dnew  = 0.31*val;
-                }
-                set_attenuation_value(dnew);
-               break;
-             default:
-               // do nothing
-               // we should not come here anyway
-               break;
-           }
-           break;
-       /////////////////////////////////////////////////////////// "B2A"
-       case MIDI_ACTION_VFO_B2A: // only key supported
-            vfo_b_to_a();
-           break;
-        /////////////////////////////////////////////////////////// "BANDxxx"
-        case MIDI_ACTION_BAND_10:
-            vfo_band_changed(active_receiver->id, band10);
-            break;
-        case MIDI_ACTION_BAND_12:
-            vfo_band_changed(active_receiver->id, band12);
-            break;
-#ifdef SOAPYSDR
-        case MIDI_ACTION_BAND_1240:
-            vfo_band_changed(active_receiver->id, band1240);
-            break;
-        case MIDI_ACTION_BAND_144:
-            vfo_band_changed(active_receiver->id, band144);
-            break;
-#endif
-        case MIDI_ACTION_BAND_15:
-            vfo_band_changed(active_receiver->id, band15);
-            break;
-        case MIDI_ACTION_BAND_160:
-            vfo_band_changed(active_receiver->id, band160);
-            break;
-        case MIDI_ACTION_BAND_17:
-            vfo_band_changed(active_receiver->id, band17);
-            break;
-        case MIDI_ACTION_BAND_20:
-            vfo_band_changed(active_receiver->id, band20);
-            break;
-#ifdef SOAPYSDR
-        case MIDI_ACTION_BAND_220:
-            vfo_band_changed(active_receiver->id, band220);
-            break;
-        case MIDI_ACTION_BAND_2300:
-            vfo_band_changed(active_receiver->id, band2300);
-            break;
-#endif
-        case MIDI_ACTION_BAND_30:
-            vfo_band_changed(active_receiver->id, band30);
-            break;
-#ifdef SOAPYSDR
-        case MIDI_ACTION_BAND_3400:
-            vfo_band_changed(active_receiver->id, band3400);
-            break;
-#endif
-        case MIDI_ACTION_BAND_40:
-            vfo_band_changed(active_receiver->id, band40);
-            break;
-#ifdef SOAPYSDR
-        case MIDI_ACTION_BAND_430:
-            vfo_band_changed(active_receiver->id, band430);
-            break;
-#endif
-        case MIDI_ACTION_BAND_6:
-            vfo_band_changed(active_receiver->id, band6);
-            break;
-        case MIDI_ACTION_BAND_60:
-            vfo_band_changed(active_receiver->id, band60);
-            break;
-#ifdef SOAPYSDR
-        case MIDI_ACTION_BAND_70:
-            vfo_band_changed(active_receiver->id, band70);
-            break;
-#endif
-        case MIDI_ACTION_BAND_80:
-            vfo_band_changed(active_receiver->id, band80);
-            break;
-#ifdef SOAPYSDR
-        case MIDI_ACTION_BAND_902:
-            vfo_band_changed(active_receiver->id, band902);
-            break;
-        case MIDI_ACTION_BAND_AIR:
-            vfo_band_changed(active_receiver->id, bandAIR);
-            break;
-#endif
-        case MIDI_ACTION_BAND_GEN:
-            vfo_band_changed(active_receiver->id, bandGen);
-            break;
-        case MIDI_ACTION_BAND_WWV:
-            vfo_band_changed(active_receiver->id, bandWWV);
-            break;
-       /////////////////////////////////////////////////////////// "BANDDOWN"
-       /////////////////////////////////////////////////////////// "BANDUP"
-       case MIDI_ACTION_BAND_DOWN:
-       case MIDI_ACTION_BAND_UP:
-           switch (type) {
-             case MIDI_TYPE_KEY:
-               new=(action == MIDI_ACTION_BAND_UP) ? 1 : -1;
-               break;
-             case MIDI_TYPE_WHEEL:
-               new=val > 0 ? 1 : -1;
-               break;
-             case MIDI_TYPE_KNOB:
-               // cycle through the bands
-               new = ((BANDS-1) * val) / 100 - vfo[active_receiver->id].band;
-               break;
-             default:
-               // do not change
-               // we should not come here anyway
-               new=0;
-               break;
-           }
-           //
-           // If the band has not changed, do nothing. Otherwise
-           // vfo.c will loop through the band stacks
-           //
-           if (new != 0) {
-             new+=vfo[active_receiver->id].band;
-             if (new >= BANDS) new=0;
-             if (new < 0) new=BANDS-1;
-              vfo_band_changed(active_receiver->id, new);
-           }
-           break;
-       /////////////////////////////////////////////////////////// "COMPRESS"
-       case MIDI_ACTION_COMPRESS: // wheel or knob
-           switch (type) {
-             case MIDI_TYPE_WHEEL:
-               dnew=transmitter->compressor_level + val;
-               if (dnew > 20.0) dnew=20.0;
-               if (dnew < 0 ) dnew=0;
-               break;
-             case MIDI_TYPE_KNOB:
-               dnew=(20.0*val)/100.0;
-               break;
-             default:
-               // do not change
-               // we should not come here anyway
-               dnew=transmitter->compressor_level;
-               break;
-           }
-            if (can_transmit) {
-             transmitter->compressor_level=dnew;
-             // automatically engange compressor if level > 0.5
-             if (dnew < 0.5) transmitter->compressor=0;
-             if (dnew > 0.5) transmitter->compressor=1;
-              set_compression(transmitter);
-            }
-           break;
-       /////////////////////////////////////////////////////////// "CTUN"
-       case MIDI_ACTION_CTUN: // only key supported
-           // toggle CTUN
-            id=active_receiver->id;
-            vfo[id].ctun=vfo[id].ctun==1?0:1;
-            if(!vfo[id].ctun) {
-              vfo[id].offset=0;
-            }
-            vfo[id].ctun_frequency=vfo[id].frequency;
-            set_offset(receiver[id],vfo[id].offset);
-           break;
-       /////////////////////////////////////////////////////////// "CURRVFO"
-       case MIDI_ACTION_VFO: // only wheel supported
-            vfo_step(val);
-           break;
-       /////////////////////////////////////////////////////////// "CWSPEED"
-       case MIDI_ACTION_CWSPEED: // knob or wheel
-            switch (type) {
-              case MIDI_TYPE_KNOB:
-               // speed between 5 and 35 wpm
-                new= (int) (5.0 + (double) val * 0.3);
-                break;
-              case MIDI_TYPE_WHEEL:
-               // here we allow from 1 to 60 wpm
-                new = cw_keyer_speed + val;
-               if (new <  1) new=1;
-               if (new > 60) new=60;
-                break;
-              default:
-                // do not change
-                // we should not come here anyway
-                new = cw_keyer_speed;
-                break;
-            }
-           cw_keyer_speed=new;
-#ifdef LOCALCW
-           keyer_update();
-#endif
-            vfo_update();
-           break;
-       /////////////////////////////////////////////////////////// "DIVCOARSEGAIN"
-       case MIDI_ACTION_DIV_COARSEGAIN:  // knob or wheel supported
-       case MIDI_ACTION_DIV_FINEGAIN:    // knob or wheel supported
-       case MIDI_ACTION_DIV_GAIN:        // knob or wheel supported
-            switch (type) {
-              case MIDI_TYPE_KNOB:
-                if (action == MIDI_ACTION_DIV_COARSEGAIN || action == MIDI_ACTION_DIV_GAIN) {
-                 // -25 to +25 dB in steps of 0.5 dB
-                 dnew = 10.0*(-25.0 + 0.5*val - div_gain);
-               } else {
-                 // round gain to a multiple of 0.5 dB and apply a +/- 0.5 dB update
-                  new = (int) (2*div_gain + 1.0) / 2;
-                 dnew = 10.0*((double) new + 0.01*val - 0.5 - div_gain);
-               }
-                break;
-              case MIDI_TYPE_WHEEL:
-                // coarse: increaments in steps of 0.25 dB, medium: steps of 0.1 dB fine: in steps of 0.01 dB
-                if (action == MIDI_ACTION_DIV_GAIN) {
-                 dnew = val*0.5;
-               } else if (action == MIDI_ACTION_DIV_COARSEGAIN) {
-                 dnew = val*2.5;
-               } else {
-                 dnew = val * 0.1;
-               }
-                break;
-              default:
-                // do not change
-                // we should not come here anyway
-               dnew = 0.0;
-                break;
-            }
-           // dnew is the delta times 10
-            update_diversity_gain(dnew);
-            break;
-        /////////////////////////////////////////////////////////// "DIVPHASE"
-        case MIDI_ACTION_DIV_COARSEPHASE:   // knob or wheel supported
-        case MIDI_ACTION_DIV_FINEPHASE:     // knob or wheel supported
-       case MIDI_ACTION_DIV_PHASE:             // knob or wheel supported
-            dnew=0.0;
-            switch (type) {
-              case MIDI_TYPE_KNOB:
-               // coarse: change phase from -180 to 180
-                // fine: change from -5 to 5
-                if (action == MIDI_ACTION_DIV_COARSEPHASE || action == MIDI_ACTION_DIV_PHASE) {
-                 // coarse: change phase from -180 to 180 in steps of 3.6 deg
-                  dnew = (-180.0 + 3.6*val - div_phase);
-                } else {
-                 // fine: round to multiple of 5 deg and apply a +/- 5 deg update
-                  new = 5 * ((int) (div_phase+0.5) / 5);
-                  dnew =  (double) new + 0.1*val -5.0 -div_phase;
-                }
-                break;
-              case MIDI_TYPE_WHEEL:
-               if (action == MIDI_ACTION_DIV_PHASE) {
-                 dnew = val*0.5; 
-               } else if (action == MIDI_ACTION_DIV_COARSEPHASE) {
-                 dnew = val*2.5;
-               } else if (action == MIDI_ACTION_DIV_FINEPHASE) {
-                 dnew = 0.1*val;
-               }
-                break;
-              default:
-                // do nothing
-                break;
-            }
-            // dnew is the delta
-            update_diversity_phase(dnew);
-            break;
-        /////////////////////////////////////////////////////////// "DIVTOGGLE"
-        case MIDI_ACTION_DIV_TOGGLE:   // only key supported
-            // enable/disable DIVERSITY
-            diversity_enabled = diversity_enabled ? 0 : 1;
-            vfo_update();
-            break;
-       /////////////////////////////////////////////////////////// "DUP"
-        case MIDI_ACTION_DUP:
-           if (can_transmit && !isTransmitting()) {
-             duplex=duplex==1?0:1;
-              setDuplex();
-           }
-            break;
-       /////////////////////////////////////////////////////////// "FILTERDOWN"
-       /////////////////////////////////////////////////////////// "FILTERUP"
-       case MIDI_ACTION_FILTER_DOWN:
-       case MIDI_ACTION_FILTER_UP:
-           //
-           // In filter.c, the filters are sorted such that the widest one comes first
-           // Therefore let MIDI_ACTION_FILTER_UP move down.
-           //
-           switch (type) {
-             case MIDI_TYPE_KEY:
-               new=(action == MIDI_ACTION_FILTER_UP) ? -1 : 1;
-               break;
-             case MIDI_TYPE_WHEEL:
-               new=val > 0 ? -1 : 1;
-               break;
-             case MIDI_TYPE_KNOB:
-               // cycle through all the filters: val=100 maps to filter #0
-               new = ((FILTERS-1) * (val-100)) / 100 - vfo[active_receiver->id].filter;
-               break;
-             default:
-               // do not change filter setting
-               // we should not come here anyway
-               new=0;
-               break;
-           }
-           if (new != 0) {
-             new+=vfo[active_receiver->id].filter;
-             if (new >= FILTERS) new=0;
-             if (new <0) new=FILTERS-1;
-              vfo_filter_changed(new);
-           }
-           break;
-        /////////////////////////////////////////////////////////// "MENU_FILTER"
-        case MIDI_ACTION_MENU_FILTER:
-            start_filter();
-            break;
-        /////////////////////////////////////////////////////////// "MENU_MODE"
-        case MIDI_ACTION_MENU_MODE:
-            start_mode();
-            break;
-       /////////////////////////////////////////////////////////// "LOCK"
-       case MIDI_ACTION_LOCK: // only key supported
-           locked=!locked;
-            vfo_update();
-           break;
-       /////////////////////////////////////////////////////////// "MICGAIN"
-       case MIDI_ACTION_MIC_VOLUME: // knob or wheel supported
-           // TODO: possibly adjust linein value if that is effective
-           switch (type) {
-             case MIDI_TYPE_KNOB:
-               dnew = -10.0 + 0.6*val;
-               break;
-             case MIDI_TYPE_WHEEL:
-               dnew = mic_gain + val;
-               if (dnew < -10.0) dnew = -10.0;
-                if (dnew >  50.0) dnew =  50.0;
-               break;
-             default:
-               // do not change mic gain
-               // we should not come here anyway
-               dnew = mic_gain;
-               break;
-           }
-            set_mic_gain(dnew);
-           break;
-       /////////////////////////////////////////////////////////// "MODEDOWN"
-       /////////////////////////////////////////////////////////// "MODEUP"
-       case MIDI_ACTION_MODE_DOWN:
-       case MIDI_ACTION_MODE_UP:
-           switch (type) {
-             case MIDI_TYPE_KEY:
-               new=(action == MIDI_ACTION_MODE_UP) ? 1 : -1;
-               break;
-             case MIDI_TYPE_WHEEL:
-               new=val > 0 ? 1 : -1;
-               break;
-             case MIDI_TYPE_KNOB:
-               // cycle through all the modes
-               new = ((MODES-1) * val) / 100 - vfo[active_receiver->id].mode;
-               break;
-             default:
-               // do not change
-               // we should not come here anyway
-               new=0;
-               break;
-           }
-           if (new != 0) {
-             new+=vfo[active_receiver->id].mode;
-             if (new >= MODES) new=0;
-             if (new <0) new=MODES-1;
-              vfo_mode_changed(new);
-           }
-           break;
-       /////////////////////////////////////////////////////////// "MOX"
-       case MIDI_ACTION_MOX: // only key supported
-           // Note this toggles the PTT state without knowing the
-            // actual state. See MIDI_ACTION_PTTKEYER for actually
-            // *setting* PTT
-           if (can_transmit) {
-               new = !mox;
-                mox_update(new);
-           }
-           break;    
-        /////////////////////////////////////////////////////////// "MUTE"
-        case MIDI_ACTION_MUTE:
-            active_receiver->mute_radio=!active_receiver->mute_radio;
-            break;
-       /////////////////////////////////////////////////////////// "NOISEBLANKER"
-       case MIDI_ACTION_NB: // only key supported
-           // cycle through NoiseBlanker settings: OFF, NB, NB2
-           if (active_receiver->nb) {
-             active_receiver->nb = 0;
-             active_receiver->nb2= 1;
-           } else if (active_receiver->nb2) {
-             active_receiver->nb = 0;
-             active_receiver->nb2= 0;
-           } else {
-             active_receiver->nb = 1;
-             active_receiver->nb2= 0;
-           }
-           update_noise();
-            vfo_update();
-           break;
-       /////////////////////////////////////////////////////////// "NOISEREDUCTION"
-       case MIDI_ACTION_NR: // only key supported
-           // cycle through NoiseReduction settings: OFF, NR1, NR2
-           if (active_receiver->nr) {
-             active_receiver->nr = 0;
-             active_receiver->nr2= 1;
-           } else if (active_receiver->nr2) {
-             active_receiver->nr = 0;
-             active_receiver->nr2= 0;
-           } else {
-             active_receiver->nr = 1;
-             active_receiver->nr2= 0;
-           }
-            update_noise();
-            vfo_update();
-           break;
-        /////////////////////////////////////////////////////////// "NUMPADxx"
-        case MIDI_ACTION_NUMPAD_0:
-            num_pad(0);
-            break;
-        case MIDI_ACTION_NUMPAD_1:
-            num_pad(1);
-            break;
-        case MIDI_ACTION_NUMPAD_2:
-            num_pad(2);
-            break;
-        case MIDI_ACTION_NUMPAD_3:
-            num_pad(3);
-            break;
-        case MIDI_ACTION_NUMPAD_4:
-            num_pad(4);
-            break;
-        case MIDI_ACTION_NUMPAD_5:
-            num_pad(5);
-            break;
-        case MIDI_ACTION_NUMPAD_6:
-            num_pad(6);
-            break;
-        case MIDI_ACTION_NUMPAD_7:
-            num_pad(7);
-            break;
-        case MIDI_ACTION_NUMPAD_8:
-            num_pad(9);
-            break;
-        case MIDI_ACTION_NUMPAD_9:
-            num_pad(9);
-            break;
-        case MIDI_ACTION_NUMPAD_CL:
-            num_pad(-1);
-            break;
-        case MIDI_ACTION_NUMPAD_ENTER:
-            num_pad(-2);
-            break;
-       /////////////////////////////////////////////////////////// "PAN"
-        case MIDI_ACTION_PAN:  // wheel and knob
-           switch (type) {
-              case MIDI_TYPE_WHEEL:
-                update_pan(val*10.0);
-                break;
-             case MIDI_TYPE_KNOB:
-                if(active_receiver->zoom>1) {
-                  int pos=GPOINTER_TO_INT(data);
-                  double pan=(double)((active_receiver->zoom-1)*active_receiver->width)*((double)pos/100.0);
-                  set_pan(active_receiver->id,(double)pan);
-                }
-                break;
-             default:
-               // no action for keys (we should not come here anyway)
-               break;
-            }
-            break;
-       /////////////////////////////////////////////////////////// "PANHIGH"
-       case MIDI_ACTION_PAN_HIGH:  // wheel or knob
-           switch (type) {
-             case MIDI_TYPE_WHEEL:
-               if (mox) {
-                   // TX panadapter affected
-                   transmitter->panadapter_high += val;
-               } else {
-                   active_receiver->panadapter_high += val;
-               }
-               break;
-           case MIDI_TYPE_KNOB:
-               // Adjust "high water" in the range -50 ... 0 dBm
-               new = -50 + val/2;
-               if (mox) {
-                   transmitter->panadapter_high = new;
-               } else {
-                   active_receiver->panadapter_high = new;
-               }
-               break;
-             default:
-               // do nothing
-               // we should not come here anyway
-               break;
-           }
-            vfo_update();
-           break;
-       /////////////////////////////////////////////////////////// "PANLOW"
-       case MIDI_ACTION_PAN_LOW:  // wheel and knob
-           switch (type) {
-             case MIDI_TYPE_WHEEL:
-               if (isTransmitting()) {
-                   // TX panadapter affected
-                   transmitter->panadapter_low += val;
-               } else {
-                   active_receiver->panadapter_low += val;
-               }
-               break;
-             case MIDI_TYPE_KNOB:
-               if (isTransmitting()) {
-                   // TX panadapter: use values -100 through -50
-                   new = -100 + val/2;
-                   transmitter->panadapter_low =new;
-               } else {
-                   // RX panadapter: use values -140 through -90
-                   new = -140 + val/2;
-                   active_receiver->panadapter_low = new;
-               }
-               break;
-             default:
-               // do nothing
-               // we should not come here anyway
-               break;
-           }
-            vfo_update();
-           break;
-       /////////////////////////////////////////////////////////// "PREAMP"
-       case MIDI_ACTION_PRE:   // only key supported
-           //
-           // Normally on/off, but for CHARLY25, cycle through three
-           // possible states. Current HPSDR hardware does no have
-           // switch'able preamps.
-           //
-           c25= (filter_board == CHARLY25);
-           new = active_receiver->preamp + active_receiver->dither;
-           new++;
-           if (c25) {
-             if (new >2) new=0;
-           } else {
-             if (new >1) new=0;
-           }
-           switch (new) {
-             case 0:
-               active_receiver->preamp=0;
-               if (c25) active_receiver->dither=0;
-               break;
-             case 1:
-               active_receiver->preamp=1;
-               if (c25) active_receiver->dither=0;
-               break;
-             case 2:
-               active_receiver->preamp=1;
-               if (c25) active_receiver->dither=1;
-               break;
-           }
-            update_att_preamp();
-           break;
-       /////////////////////////////////////////////////////////// "PTT(Keyer)"
-        case MIDI_ACTION_PTTKEYER:  // key only
-            // always use with "ONOFF"
-           if (can_transmit) {
-                mox_update(val);
-           }
-           break;    
-       /////////////////////////////////////////////////////////// "PURESIGNAL"
-       case MIDI_ACTION_PS: // only key supported
-#ifdef PURESIGNAL
-           // toggle PURESIGNAL
-            if (can_transmit) {
-             new=!(transmitter->puresignal);
-              tx_set_ps(transmitter, new);
-            }
-#endif
-           break;
-       /////////////////////////////////////////////////////////// "RECALLMx"
-       case MIDI_ACTION_MEM_RECALL_M0:
-            recall_memory_slot(0);
-            break;
-       case MIDI_ACTION_MEM_RECALL_M1:
-            recall_memory_slot(1);
-            break;
-       case MIDI_ACTION_MEM_RECALL_M2:
-            recall_memory_slot(2);
-            break;
-       case MIDI_ACTION_MEM_RECALL_M3:
-            recall_memory_slot(3);
-            break;
-       case MIDI_ACTION_MEM_RECALL_M4:
-            recall_memory_slot(4);
-            break;
-       /////////////////////////////////////////////////////////// "RFGAIN"
-        case MIDI_ACTION_RF_GAIN: // knob or wheel supported
-            switch (type) {
-              case MIDI_TYPE_KNOB:
-                dnew=val;
-                break;
-              case MIDI_TYPE_WHEEL:
-                dnew=adc[active_receiver->id].gain+val;
-                break;
-              default:
-                // Arriving here means there is an error somewhere else
-                dnew=0.0;
-                break;
-            }
-            if (dnew <   0.0) dnew =   0.0;
-            if (dnew > 100.0) dnew = 100.0;
-            set_rf_gain(active_receiver->id, dnew);
-           break;
-       /////////////////////////////////////////////////////////// "RFPOWER"
-       case MIDI_ACTION_TX_DRIVE: // knob or wheel supported
-           switch (type) {
-             case MIDI_TYPE_KNOB:
-               dnew = val;
-               break;
-             case MIDI_TYPE_WHEEL:
-               dnew=transmitter->drive + val;
-               if (dnew < 0.0) dnew=0.0; if (dnew > 100.0) dnew=100.0;
-               break;
-             default:
-               // do not change value
-               // we should not come here anyway
-               dnew=transmitter->drive;
-               break;
-           }
-            set_drive(dnew);
-           break;
-       /////////////////////////////////////////////////////////// "RITCLEAR"
-       case MIDI_ACTION_RIT_CLEAR:       // only key supported
-           // clear RIT value
-           vfo[active_receiver->id].rit = 0;
-           vfo[active_receiver->id].rit_enabled = 0;
-            vfo_update();
-           break;
-       /////////////////////////////////////////////////////////// "RITSTEP"
-        case MIDI_ACTION_RIT_STEP: // key or wheel supported
-            // This cycles between RIT increments 1, 10, 100, 1, 10, 100, ...
-            switch (type) {
-              case MIDI_TYPE_KEY:
-                // key cycles through in upward direction
-                val=1;
-                /* FALLTHROUGH */
-              case MIDI_TYPE_WHEEL:
-                // wheel cycles upward or downward
-                if (val > 0) {
-                  rit_increment=10*rit_increment;
-                } else {
-                  rit_increment=rit_increment/10;
-                }
-                if (rit_increment < 1) rit_increment=100;
-                if (rit_increment > 100) rit_increment=1;
-                break;
-              default:
-                // do nothing
-                break;
-            }
-            vfo_update();
-            break;
-       /////////////////////////////////////////////////////////// "RITTOGGLE"
-       case MIDI_ACTION_RIT_TOGGLE:  // only key supported
-           // enable/disable RIT
-           new=vfo[active_receiver->id].rit_enabled;
-           vfo[active_receiver->id].rit_enabled = new ? 0 : 1;
-            vfo_update();
-           break;
-       /////////////////////////////////////////////////////////// "RITVAL"
-       case MIDI_ACTION_RIT_VAL:       // wheel or knob
-           switch (type) {
-             case MIDI_TYPE_WHEEL:
-               // This changes the RIT value incrementally,
-               // but we restrict the change to +/ 9.999 kHz
-               new = vfo[active_receiver->id].rit + val*rit_increment;
-               if (new >  9999) new=  9999;
-               if (new < -9999) new= -9999;
-               vfo[active_receiver->id].rit = new;
-               break;
-             case MIDI_TYPE_KNOB:
-               // knob: adjust in the range +/ 50*rit_increment
-               new = (val-50) * rit_increment;
-               vfo[active_receiver->id].rit = new;
-               break;
-             default:
-               // do nothing
-               // we should not come here anyway
-               break;
-           }
-           // enable/disable RIT according to RIT value
-           vfo[active_receiver->id].rit_enabled = (vfo[active_receiver->id].rit == 0) ? 0 : 1;
-            vfo_update();
-           break;
-       /////////////////////////////////////////////////////////// "SAT"
-        case MIDI_ACTION_SAT:
-           switch (sat_mode) {
-               case SAT_NONE:
-                 sat_mode=SAT_MODE;
-                 break;
-               case SAT_MODE:
-                 sat_mode=RSAT_MODE;
-                 break;
-               case RSAT_MODE:
-               default:
-                 sat_mode=SAT_NONE;
-                 break;
-           }
-            vfo_update();
-            break;
-       /////////////////////////////////////////////////////////// "SNB"
-       case MIDI_ACTION_SNB:   // only key supported
-            if(active_receiver->snb==0) {
-              active_receiver->snb=1;
-              mode_settings[vfo[active_receiver->id].mode].snb=1;
-            } else {
-              active_receiver->snb=0;
-              mode_settings[vfo[active_receiver->id].mode].snb=0;
-            }
-            update_noise();
-           break;
-       /////////////////////////////////////////////////////////// "SPLIT"
-       case MIDI_ACTION_SPLIT: // only key supported
-           // toggle split mode
-            new= split ? 0:1;
-            set_split(new);
-           break;
-       /////////////////////////////////////////////////////////// "STOREMx"
-       case MIDI_ACTION_MEM_STORE_M0:
-            store_memory_slot(0);
-           break;
-       case MIDI_ACTION_MEM_STORE_M1:
-            store_memory_slot(1);
-           break;
-       case MIDI_ACTION_MEM_STORE_M2:
-            store_memory_slot(2);
-           break;
-       case MIDI_ACTION_MEM_STORE_M3:
-            store_memory_slot(3);
-           break;
-       case MIDI_ACTION_MEM_STORE_M4:
-            store_memory_slot(4);
-           break;
-       /////////////////////////////////////////////////////////// "SWAPRX"
-       case MIDI_ACTION_SWAP_RX:       // only key supported
-           if (receivers == 2) {
-               new=active_receiver->id;        // 0 or 1
-               new= (new == 1) ? 0 : 1;        // id of currently inactive receiver
-               active_receiver=receiver[new];
-               g_idle_add(menu_active_receiver_changed,NULL);
-               g_idle_add(sliders_active_receiver_changed,NULL);
-                vfo_update();
-           }
-           break;    
-       /////////////////////////////////////////////////////////// "SWAPVFO"
-       case MIDI_ACTION_SWAP_VFO:      // only key supported
-            vfo_a_swap_b();
-           break;    
-       /////////////////////////////////////////////////////////// "TUNE"
-       case MIDI_ACTION_TUNE: // only key supported
-           if (can_transmit) {
-               new = !tune;
-                tune_update(new);
-           }
-           break;    
-       /////////////////////////////////////////////////////////// "VFOA"
-       /////////////////////////////////////////////////////////// "VFOB"
-       case MIDI_ACTION_VFOA: // only wheel supported
-       case MIDI_ACTION_VFOB: // only wheel supported
-           if (!locked) {
-               new = (action == MIDI_ACTION_VFOA) ? 0 : 1;
-                vfo_id_step(new, val);
-           }
-           break;
-       /////////////////////////////////////////////////////////// "VFOSTEPDOWN"
-       /////////////////////////////////////////////////////////// "VFOSTEPUP"
-        case MIDI_ACTION_VFO_STEP_DOWN: // key or wheel supported
-        case MIDI_ACTION_VFO_STEP_UP:
-           switch (type) {
-             case MIDI_TYPE_KEY:
-               new =  (action == MIDI_ACTION_VFO_STEP_UP) ? 1 : -1;
-                update_vfo_step(new);
-               break;
-             case MIDI_TYPE_WHEEL:
-               new = (val > 0) ? 1 : -1;
-                update_vfo_step(new);
-               break;
-             default:
-               // do nothing
-               // we should not come here anyway
-                break;
-           }
-            break;
-       /////////////////////////////////////////////////////////// "VOX"
-       case MIDI_ACTION_VOX: // only key supported
-           // toggle VOX
-            if (can_transmit) {
-             vox_enabled = !vox_enabled;
-              vfo_update();
-            }
-           break;
-       /////////////////////////////////////////////////////////// "VOXLEVEL"
-       case MIDI_ACTION_VOXLEVEL: // knob or wheel supported
-            switch (type) {
-              case MIDI_TYPE_WHEEL:
-                // This changes the value incrementally,
-                // but stay within limits (0.0 through 1.0)
-                vox_threshold += (double) val * 0.01;
-               if (vox_threshold > 1.0) vox_threshold=1.0;
-               if (vox_threshold < 0.0) vox_threshold=0.0;
-                break;
-              case MIDI_TYPE_KNOB:
-                vox_threshold = 0.01 * (double) val;
-                break;
-              default:
-                // do nothing
-                // we should not come here anyway
-                break;
-            }
-           // VOX level not shown on screen, hence no VFO update
-           break;
-       /////////////////////////////////////////////////////////// "XITCLEAR"
-        case MIDI_ACTION_XIT_CLEAR:  // only key supported
-            // this clears the XIT value and disables XIT
-            if(can_transmit) {
-              transmitter->xit = 0;
-              transmitter->xit_enabled = 0;
-              vfo_update();
-            }
-            break;
-       /////////////////////////////////////////////////////////// "XITVAL"
-        case MIDI_ACTION_XIT_VAL:   // wheel and knob supported.
-           if (can_transmit) {
-              switch (type) {
-                case MIDI_TYPE_WHEEL:
-                  // This changes the XIT value incrementally,
-                  // but we restrict the change to +/ 9.999 kHz
-                  new = transmitter->xit + val*rit_increment;
-                  if (new >  9999) new =  9999;
-                  if (new < -9999) new = -9999;
-                  transmitter->xit = new;
-                  break;
-                case MIDI_TYPE_KNOB:
-                  // knob: adjust in the range +/ 50*rit_increment
-                  new = (val-50) * rit_increment;
-                  transmitter->xit = new;
-                  break;
-                default:
-                  // do nothing
-                  // we should not come here anyway
-                  break;
-              }
-              // enable/disable XIT according to XIT value
-              transmitter->xit_enabled = (transmitter->xit == 0) ? 0 : 1;
-              vfo_update();
-           }
-            break;
-       /////////////////////////////////////////////////////////// "ZOOM"
-       /////////////////////////////////////////////////////////// "ZOOMDOWN"
-       /////////////////////////////////////////////////////////// "ZOOMUP"
-        //
-        // The ZOOM key word is redundant but we leave it to maintain
-        // backwards compatibility
-        //
-        case MIDI_ACTION_ZOOM:       // wheel, knob
-        case MIDI_ACTION_ZOOM_UP:    // key, wheel, knob
-        case MIDI_ACTION_ZOOM_DOWN:  // key, wheel, knob
-           switch (type) {
-             case MIDI_TYPE_KEY:
-                if (action == MIDI_ACTION_ZOOM) break;
-               dnew =  (action == MIDI_ACTION_ZOOM_UP) ? 1.0 :-1.0;
-                update_zoom(dnew);
-               break;
-             case MIDI_TYPE_WHEEL:
-               dnew = (val > 0) ? 1.0 : -1.0;
-                update_zoom(dnew);
-               break;
-              case MIDI_TYPE_KNOB:
-                dnew= 1.0+ 0.07*val;  // from 1.0 to 8.0
-                if((int)dnew != active_receiver->zoom) {
-                  set_zoom(active_receiver->id, dnew);
-                }
-                break;
-             default:
-               // do nothing
-               // we should not come here anyway
-               break;
-           }
-            break;
-
-       case MIDI_ACTION_NONE:
-           // No error message, this is the "official" action for un-used controller buttons.
-           break;;
-       default:
-           // This means we have forgotten to implement an action, so we inform on stderr.
-           fprintf(stderr,"Unimplemented MIDI action: A=%d\n", (int) action);
+    switch(type) {
+      case MIDI_KEY:
+        a=g_new(PROCESS_ACTION,1);
+        a->action=action;
+        a->mode=val?PRESSED:RELEASED;
+        g_idle_add(process_action,a);
+       break;
+      case MIDI_KNOB:
+        a=g_new(PROCESS_ACTION,1);
+        a->action=action;
+        a->mode=ABSOLUTE;
+        a->val=val;
+        g_idle_add(process_action,a);
+        break;
+      case MIDI_WHEEL:
+        a=g_new(PROCESS_ACTION,1);
+        a->action=action;
+        a->mode=RELATIVE;
+        a->val=val;
+        g_idle_add(process_action,a);
+        break;
     }
-    return 0;
 }
index 3c5ff648118f083810d9ee3a9c08ee5cdafb8ebd..e4417ed9bb510b9eebb1710f4df1991bf5c338c3 100644 (file)
@@ -34,6 +34,7 @@
 #include "adc.h"
 #include "dac.h"
 #include "radio.h"
+#include "actions.h"
 #include "midi.h"
 #include "alsa_midi.h"
 #include "new_menu.h"
@@ -78,7 +79,7 @@ static GtkWidget *update_b;
 static GtkWidget *delete_b;
 static GtkWidget *device_b[MAX_MIDI_DEVICES];
 
-static enum MIDIevent thisEvent=MIDI_EVENT_NONE;
+static enum MIDIevent thisEvent=EVENT_NONE;
 static int thisChannel;
 static int thisNote;
 static int thisVal;
@@ -101,8 +102,8 @@ static GtkWidget *set_rgt1, *set_rgt2;
 static GtkWidget *set_fr1,  *set_fr2;
 static GtkWidget *set_vfr1, *set_vfr2;
 
-static enum MIDItype thisType;
-static enum MIDIaction thisAction;
+static enum ACTIONtype thisType;
+static int thisAction;
 
 static gboolean accept_any=FALSE;
 
@@ -178,7 +179,7 @@ static void update_wheelparams(gpointer user_data) {
   //       thre current type is a wheel. If it is a wheel,
   //       set spin buttons to current values.
   //
-  if (thisType==MIDI_TYPE_WHEEL) {
+  if (thisType==MIDI_WHEEL) {
     gtk_spin_button_set_value(GTK_SPIN_BUTTON(set_delay),(double) thisDelay);
     gtk_spin_button_set_value(GTK_SPIN_BUTTON(set_vfl1 ),(double) thisVfl1 );
     gtk_spin_button_set_value(GTK_SPIN_BUTTON(set_vfl2 ),(double) thisVfl2 );
@@ -218,17 +219,17 @@ static void type_changed_cb(GtkWidget *widget, gpointer data) {
   gtk_widget_hide(newAction_knob);
   gtk_widget_hide(newAction_wheel);
   if (strcmp(type,"NONE")==0) {
-    thisType=MIDI_TYPE_NONE;
+    thisType=TYPE_NONE;
   } else if(strcmp(type,"KEY")==0) {
-    thisType=MIDI_TYPE_KEY;
+    thisType=MIDI_KEY;
     gtk_widget_show(newAction_key);
     gtk_combo_box_set_active(GTK_COMBO_BOX(newAction_key),key_list[thisAction]);
   } else if(strcmp(type,"KNOB/SLIDER")==0) {
-    thisType=MIDI_TYPE_KNOB;
+    thisType=MIDI_KNOB;
     gtk_widget_show(newAction_knob);
     gtk_combo_box_set_active(GTK_COMBO_BOX(newAction_knob),knob_list[thisAction]);
   } else if(strcmp(type,"WHEEL")==0) {
-    thisType=MIDI_TYPE_WHEEL;
+    thisType=MIDI_WHEEL;
     gtk_widget_show(newAction_wheel);
     gtk_combo_box_set_active(GTK_COMBO_BOX(newAction_wheel),wheel_list[thisAction]);
   }
@@ -262,13 +263,13 @@ static void tree_selection_changed_cb (GtkTreeSelection *selection, gpointer dat
       if(str_event!=NULL && str_channel!=NULL && str_note!=NULL && str_type!=NULL && str_action!=NULL) {
 
         if(strcmp(str_event,"CTRL")==0) {
-          thisEvent=MIDI_EVENT_CTRL;
+          thisEvent=MIDI_CTRL;
         } else if(strcmp(str_event,"PITCH")==0) {
-          thisEvent=MIDI_EVENT_PITCH;
+          thisEvent=MIDI_PITCH;
         } else if(strcmp(str_event,"NOTE")==0) {
-          thisEvent=MIDI_EVENT_NOTE;
+          thisEvent=MIDI_NOTE;
         } else {
-          thisEvent=MIDI_EVENT_NONE;
+          thisEvent=EVENT_NONE;
         }
         if (!strncmp(str_channel,"Any", 3)) {
           thisChannel=-1;
@@ -280,17 +281,17 @@ static void tree_selection_changed_cb (GtkTreeSelection *selection, gpointer dat
         thisMin=0;
         thisMax=0;
         if(strcmp(str_type,"KEY")==0) {
-          thisType=MIDI_TYPE_KEY;
+          thisType=MIDI_KEY;
         } else if(strcmp(str_type,"KNOB/SLIDER")==0) {
-          thisType=MIDI_TYPE_KNOB;
+          thisType=MIDI_KNOB;
         } else if(strcmp(str_type,"WHEEL")==0) {
-          thisType=MIDI_TYPE_WHEEL;
+          thisType=MIDI_WHEEL;
         } else {
-          thisType=MIDI_TYPE_NONE;
+          thisType=TYPE_NONE;
         }
-        thisAction=MIDI_ACTION_NONE;
+        thisAction=NO_ACTION;
         int i=0;
-        while(ActionTable[i].action!=MIDI_ACTION_LAST) {
+        while(ActionTable[i].action!=ACTIONS) {
           if(strcmp(ActionTable[i].str,str_action)==0) {
             thisAction=ActionTable[i].action;
             break;
@@ -322,7 +323,7 @@ static void wheelparam_cb(GtkWidget *widget, gpointer user_data) {
   int val=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(widget));
   int newval=val;
 
-  if (thisType != MIDI_TYPE_WHEEL) {
+  if (thisType != MIDI_WHEEL) {
     // we should never arrive here
     return;
   }
@@ -489,16 +490,16 @@ static void add_store(int key,struct desc *cmd) {
 
   //g_print("%s: key=%d desc=%p\n",__FUNCTION__,key,cmd);
   switch(cmd->event) {
-    case MIDI_EVENT_NONE:
+    case EVENT_NONE:
       strcpy(str_event,"NONE");
       break;
-    case MIDI_EVENT_NOTE:
+    case MIDI_NOTE:
       strcpy(str_event,"NOTE");
       break;
-    case MIDI_EVENT_CTRL:
+    case MIDI_CTRL:
       strcpy(str_event,"CTRL");
       break;
-    case MIDI_EVENT_PITCH:
+    case MIDI_PITCH:
       strcpy(str_event,"PITCH");
       break;
   }
@@ -509,18 +510,22 @@ static void add_store(int key,struct desc *cmd) {
   }
   sprintf(str_note,"%d",key);
   switch(cmd->type) {
-    case MIDI_TYPE_NONE:
+    case TYPE_NONE:
       strcpy(str_type,"NONE");
       break;
-    case MIDI_TYPE_KEY:
+    case MIDI_KEY:
       strcpy(str_type,"KEY");
       break;
-    case MIDI_TYPE_KNOB:
+    case MIDI_KNOB:
       strcpy(str_type,"KNOB/SLIDER");
       break;
-    case MIDI_TYPE_WHEEL:
+    case MIDI_WHEEL:
       strcpy(str_type,"WHEEL");
       break;
+    default:
+      // Controlle types cannot arise here
+      strcpy(str_type,"ERROR");
+      break;
   }
   // ATTENTION: this assumes ActionTable is sorted by action enum
   strcpy(str_action,ActionTable[cmd->action].str);
@@ -571,26 +576,25 @@ static void add_cb(GtkButton *widget,gpointer user_data) {
   }
 
   if(strcmp(str_type,"KEY")==0) {
-    type=MIDI_TYPE_KEY;
+    type=MIDI_KEY;
     str_action=gtk_combo_box_text_get_active_text(GTK_COMBO_BOX_TEXT(newAction_key));
   } else if(strcmp(str_type,"KNOB/SLIDER")==0) {
-    type=MIDI_TYPE_KNOB;
+    type=MIDI_KNOB;
     str_action=gtk_combo_box_text_get_active_text(GTK_COMBO_BOX_TEXT(newAction_knob));
   } else if(strcmp(str_type,"WHEEL")==0) {
-    type=MIDI_TYPE_WHEEL;
+    type=MIDI_WHEEL;
     str_action=gtk_combo_box_text_get_active_text(GTK_COMBO_BOX_TEXT(newAction_wheel));
   } else {
-    type=MIDI_TYPE_NONE;
+    type=TYPE_NONE;
     str_action="NONE";
   }
 
-  action=MIDI_ACTION_NONE;
+  action=NO_ACTION;
   onoff=0;
   i=0;
-  while(ActionTable[i].action!=MIDI_ACTION_LAST) {
+  while(ActionTable[i].action!=ACTIONS) {
     if(strcmp(ActionTable[i].str,str_action)==0) {
       action=ActionTable[i].action;
-      onoff=ActionTable[i].onoff;
       break;
     }
     i++;
@@ -651,27 +655,26 @@ static void update_cb(GtkButton *widget,gpointer user_data) {
   gchar *str_action;
 
   if(strcmp(str_type,"KEY")==0) {
-    thisType=MIDI_TYPE_KEY;
+    thisType=MIDI_KEY;
     str_action=gtk_combo_box_text_get_active_text(GTK_COMBO_BOX_TEXT(newAction_key));
   } else if(strcmp(str_type,"KNOB/SLIDER")==0) {
-    thisType=MIDI_TYPE_KNOB;
+    thisType=MIDI_KNOB;
     str_action=gtk_combo_box_text_get_active_text(GTK_COMBO_BOX_TEXT(newAction_knob));
   } else if(strcmp(str_type,"WHEEL")==0) {
-    thisType=MIDI_TYPE_WHEEL;
+    thisType=MIDI_WHEEL;
     str_action=gtk_combo_box_text_get_active_text(GTK_COMBO_BOX_TEXT(newAction_wheel));
   } else {
-    thisType=MIDI_TYPE_NONE;
+    thisType=TYPE_NONE;
     str_action="NONE";
   }
   //g_print("%s: type=%s action=%s\n",__FUNCTION__,str_type,str_action);
 
-  thisAction=MIDI_ACTION_NONE;
+  thisAction=NO_ACTION;
   onoff=0;
   i=0;
-  while(ActionTable[i].action!=MIDI_ACTION_LAST) {
+  while(ActionTable[i].action!=ACTIONS) {
     if(strcmp(ActionTable[i].str,str_action)==0) {
       thisAction=ActionTable[i].action;
-      onoff=ActionTable[i].onoff;
       break;
     }
     i++;
@@ -697,16 +700,16 @@ static void update_cb(GtkButton *widget,gpointer user_data) {
   current_cmd->vfr2  =thisVfr2;
 
   switch(current_cmd->event) {
-    case MIDI_EVENT_NONE:
+    case EVENT_NONE:
       strcpy(str_event,"NONE");
       break;
-    case MIDI_EVENT_NOTE:
+    case MIDI_NOTE:
       strcpy(str_event,"NOTE");
       break;
-    case MIDI_EVENT_CTRL:
+    case MIDI_CTRL:
       strcpy(str_event,"CTRL");
       break;
-    case MIDI_EVENT_PITCH:
+    case MIDI_PITCH:
       strcpy(str_event,"PITCH");
       break;
   }
@@ -942,7 +945,7 @@ void midi_menu(GtkWidget *parent) {
 
   // Determint number of actions
   i=0;
-  while(ActionTable[i].action!=MIDI_ACTION_LAST) {
+  while(ActionTable[i].action!=ACTIONS) {
     i++;
   }
   key_list   = (int *) g_new(int, i);
@@ -958,19 +961,19 @@ void midi_menu(GtkWidget *parent) {
   // the lists note the position of the action #i in the newAction_<type> combo-box
   // an action can appear in more than one combo-box.
   //
-  while(ActionTable[i].action!=MIDI_ACTION_LAST) {
+  while(ActionTable[i].action!=ACTIONS) {
     key_list[i]=0;
     knob_list[i]=0;
     wheel_list[i]=0;
-    if(ActionTable[i].type&MIDI_TYPE_KEY) {
+    if(ActionTable[i].type&MIDI_KEY) {
       gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(newAction_key),NULL,ActionTable[i].str);
       key_list[i]=jkey++;
     }
-    if(ActionTable[i].type&MIDI_TYPE_KNOB) {
+    if(ActionTable[i].type&MIDI_KNOB) {
       gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(newAction_knob),NULL,ActionTable[i].str);
       knob_list[i]=jknob++;
     }
-    if(ActionTable[i].type&MIDI_TYPE_WHEEL) {
+    if(ActionTable[i].type&MIDI_WHEEL) {
       gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(newAction_wheel),NULL,ActionTable[i].str);
       wheel_list[i]=jwheel++;
     }
@@ -1217,16 +1220,16 @@ static int update(void *data) {
     case UPDATE_NEW:
       g_print("%s: UPDATE_NEW\n",__FUNCTION__);
       switch(thisEvent) {
-        case MIDI_EVENT_NONE:
+        case EVENT_NONE:
           gtk_label_set_text(GTK_LABEL(newEvent),"NONE");
           break;
-        case MIDI_EVENT_NOTE:
+        case MIDI_NOTE:
           gtk_label_set_text(GTK_LABEL(newEvent),"NOTE");
           break;
-        case MIDI_EVENT_CTRL:
+        case MIDI_CTRL:
           gtk_label_set_text(GTK_LABEL(newEvent),"CTRL");
           break;
-        case MIDI_EVENT_PITCH:
+        case MIDI_PITCH:
           gtk_label_set_text(GTK_LABEL(newEvent),"PITCH");
           break;
       }
@@ -1241,15 +1244,15 @@ static int update(void *data) {
       gtk_combo_box_text_remove_all(GTK_COMBO_BOX_TEXT(newType));
       gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(newType),NULL,"NONE");
       switch(thisEvent) {
-        case MIDI_EVENT_NONE:
+        case EVENT_NONE:
           gtk_combo_box_set_active (GTK_COMBO_BOX(newType),0);
           break;
-        case MIDI_EVENT_NOTE:
-        case MIDI_EVENT_PITCH:
+        case MIDI_NOTE:
+        case MIDI_PITCH:
           gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(newType),NULL,"KEY");
           gtk_combo_box_set_active (GTK_COMBO_BOX(newType),1);
           break;
-        case MIDI_EVENT_CTRL:
+        case MIDI_CTRL:
           gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(newType),NULL,"KNOB/SLIDER");
           gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(newType),NULL,"WHEEL");
           gtk_combo_box_set_active (GTK_COMBO_BOX(newType),0);
@@ -1281,16 +1284,16 @@ static int update(void *data) {
     case UPDATE_EXISTING:
       g_print("%s: UPDATE_EXISTING Type=%d Action=%d\n",__FUNCTION__,thisType,thisAction);
       switch(thisEvent) {
-        case MIDI_EVENT_NONE:
+        case EVENT_NONE:
           gtk_label_set_text(GTK_LABEL(newEvent),"NONE");
           break;
-        case MIDI_EVENT_NOTE:
+        case MIDI_NOTE:
           gtk_label_set_text(GTK_LABEL(newEvent),"NOTE");
           break;
-        case MIDI_EVENT_CTRL:
+        case MIDI_CTRL:
           gtk_label_set_text(GTK_LABEL(newEvent),"CTRL");
           break;
-        case MIDI_EVENT_PITCH:
+        case MIDI_PITCH:
           gtk_label_set_text(GTK_LABEL(newEvent),"PITCH");
           break;
       }
@@ -1305,26 +1308,26 @@ static int update(void *data) {
       gtk_combo_box_text_remove_all(GTK_COMBO_BOX_TEXT(newType));
       gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(newType),NULL,"NONE");
       switch(thisEvent) {
-        case MIDI_EVENT_NONE:
+        case EVENT_NONE:
          gtk_combo_box_set_active (GTK_COMBO_BOX(newType),0);
           break;
-        case MIDI_EVENT_NOTE:
-        case MIDI_EVENT_PITCH:
+        case MIDI_NOTE:
+        case MIDI_PITCH:
           gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(newType),NULL,"KEY");
-         if(thisType==MIDI_TYPE_NONE) {
+         if(thisType==TYPE_NONE) {
            gtk_combo_box_set_active (GTK_COMBO_BOX(newType),0);
-         } else if(thisType==MIDI_TYPE_KEY) {
+         } else if(thisType==MIDI_KEY) {
            gtk_combo_box_set_active (GTK_COMBO_BOX(newType),1);
          }
           break;
-        case MIDI_EVENT_CTRL:
+        case MIDI_CTRL:
           gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(newType),NULL,"KNOB/SLIDER");
           gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(newType),NULL,"WHEEL");
-         if(thisType==MIDI_TYPE_NONE) {
+         if(thisType==TYPE_NONE) {
            gtk_combo_box_set_active (GTK_COMBO_BOX(newType),0);
-         } else if(thisType==MIDI_TYPE_KNOB) {
+         } else if(thisType==MIDI_KNOB) {
            gtk_combo_box_set_active (GTK_COMBO_BOX(newType),1);
-         } else if(thisType==MIDI_TYPE_WHEEL) {
+         } else if(thisType==MIDI_WHEEL) {
             gtk_combo_box_set_active (GTK_COMBO_BOX(newType),2);
           }
           break;
@@ -1396,8 +1399,8 @@ void NewMidiConfigureEvent(enum MIDIevent event, int channel, int note, int val)
     thisVal=val;
     thisMin=val;
     thisMax=val;
-    thisType=MIDI_TYPE_NONE;
-    thisAction=MIDI_ACTION_NONE;
+    thisType=TYPE_NONE;
+    thisAction=NO_ACTION;
     //
     // set default values for wheel parameters
     //
@@ -1428,13 +1431,13 @@ void NewMidiConfigureEvent(enum MIDIevent event, int channel, int note, int val)
 
       if(str_event!=NULL && str_channel!=NULL && str_note!=NULL && str_type!=NULL && str_action!=NULL) {
         if(strcmp(str_event,"CTRL")==0) {
-          tree_event=MIDI_EVENT_CTRL;
+          tree_event=MIDI_CTRL;
         } else if(strcmp(str_event,"PITCH")==0) {
-          tree_event=MIDI_EVENT_PITCH;
+          tree_event=MIDI_PITCH;
         } else if(strcmp(str_event,"NOTE")==0) {
-          tree_event=MIDI_EVENT_NOTE;
+          tree_event=MIDI_NOTE;
         } else {
-          tree_event=MIDI_EVENT_NONE;
+          tree_event=EVENT_NONE;
         }
         if (!strncmp(str_channel,"Any", 3)) {
          tree_channel=-1;
@@ -1448,17 +1451,17 @@ void NewMidiConfigureEvent(enum MIDIevent event, int channel, int note, int val)
           thisMin=0;
           thisMax=0;
           if(strcmp(str_type,"KEY")==0) {
-            thisType=MIDI_TYPE_KEY;
+            thisType=MIDI_KEY;
           } else if(strcmp(str_type,"KNOB/SLIDER")==0) {
-            thisType=MIDI_TYPE_KNOB;
+            thisType=MIDI_KNOB;
           } else if(strcmp(str_type,"WHEEL")==0) {
-            thisType=MIDI_TYPE_WHEEL;
+            thisType=MIDI_WHEEL;
           } else {
-            thisType=MIDI_TYPE_NONE;
+            thisType=TYPE_NONE;
           }
-          thisAction=MIDI_ACTION_NONE;
+          thisAction=NO_ACTION;
           int i=1;
-          while(ActionTable[i].action!=MIDI_ACTION_LAST) {
+          while(ActionTable[i].action!=ACTIONS) {
             if(strcmp(ActionTable[i].str,str_action)==0) {
               thisAction=ActionTable[i].action;
               break;
@@ -1531,7 +1534,7 @@ void midi_save_state() {
         // For wheels, also store the additional parameters,
         // but do so only if they deviate from the default values.
         //
-        if (cmd->type == MIDI_TYPE_WHEEL) {
+        if (cmd->type == MIDI_WHEEL) {
           if (cmd->delay > 0) {
             sprintf(name,"midi[%d].index[%d].delay",i,index);
             sprintf(value,"%d",cmd->delay);
@@ -1628,7 +1631,6 @@ void midi_restore_state() {
   // set the "active" flag, and the devices will be opened in
   // radio.c when it is appropriate
   //
-    
   for(int i=0; i<MAX_MIDI_DEVICES; i++) {
     sprintf(name,"mididevice[%d].name",i);
     value=getProperty(name);
@@ -1651,7 +1653,7 @@ void midi_restore_state() {
       for(int index=0; index<indices; index++) {
         sprintf(name,"midi[%d].index[%d].event",i,index);
         value=getProperty(name);
-       event=MIDI_EVENT_NONE;
+       event=EVENT_NONE;
         if(value) {
           for(int j=0;j<4;j++) {
            if(strcmp(value,midi_events[j])==0) {
@@ -1662,7 +1664,7 @@ void midi_restore_state() {
        }
         sprintf(name,"midi[%d].index[%d].type",i,index);
         value=getProperty(name);
-       type=MIDI_TYPE_NONE;
+       type=TYPE_NONE;
         if(value) {
           for(int j=0;j<5;j++) {
             if(strcmp(value,midi_types[j])==0) {
@@ -1673,10 +1675,10 @@ void midi_restore_state() {
        }
         sprintf(name,"midi[%d].index[%d].action",i,index);
         value=getProperty(name);
-       action=MIDI_ACTION_NONE;
+       action=NO_ACTION;
         if(value) {
          int j=0;
-         while(ActionTable[j].type!=MIDI_ACTION_LAST) {
+         while(ActionTable[j].action!=ACTIONS) {
             if(strcmp(value,ActionTable[j].str)==0) {
               action=ActionTable[j].action;
              break;
@@ -1751,8 +1753,8 @@ void midi_restore_state() {
         vfr2=-1;
         if (value) vfr2=atoi(value);
 
-       // ATTENTION: this assumes ActionTable is sorted by Action enums
-        onoff=ActionTable[action].onoff;
+        onoff=0;
+        if (action == CW_LEFT || action == CW_RIGHT || action == CW_KEYER || action == PTT_KEYER) onoff=1;
 
        struct desc *desc = (struct desc *) malloc(sizeof(struct desc));
 
index 695edd45f8c8a86f92d0c4935bca6ca86783f927..ae12557a6d78a7927219efb4970f8d0d72492208 100644 (file)
@@ -54,6 +54,7 @@
 #include "ps_menu.h"
 #include "encoder_menu.h"
 #include "switch_menu.h"
+#include "toolbar_menu.h"
 #include "vfo_menu.h"
 #include "fft_menu.h"
 #include "main.h"
@@ -65,7 +66,6 @@
 #include "server_menu.h"
 #endif
 #ifdef MIDI
-#include "midi.h"
 #include "midi_menu.h"
 #endif
 
@@ -108,6 +108,7 @@ static gboolean close_cb (GtkWidget *widget, GdkEventButton *event, gpointer dat
   return TRUE;
 }
 
+#ifdef RESTART_BUTTON
 //
 // The "Restart" button restarts the protocol
 // This may help to recover from certain error conditions
@@ -132,6 +133,7 @@ static gboolean restart_cb (GtkWidget *widget, GdkEventButton *event, gpointer d
   }
   return TRUE;
 }
+#endif
 
 static gboolean about_b_cb (GtkWidget *widget, GdkEventButton *event, gpointer data) {
   cleanup();
@@ -193,13 +195,19 @@ static gboolean encoder_cb (GtkWidget *widget, GdkEventButton *event, gpointer d
   encoder_menu(top_window);
   return TRUE;
 }
-#endif
 
 static gboolean switch_cb (GtkWidget *widget, GdkEventButton *event, gpointer data) {
   cleanup();
   switch_menu(top_window);
   return TRUE;
 }
+#endif
+
+static gboolean toolbar_cb (GtkWidget *widget, GdkEventButton *event, gpointer data) {
+  cleanup();
+  toolbar_menu(top_window);
+  return TRUE;
+}
 
 static gboolean cw_cb (GtkWidget *widget, GdkEventButton *event, gpointer data) {
   cleanup();
@@ -379,8 +387,12 @@ static gboolean vfo_cb (GtkWidget *widget, GdkEventButton *event, gpointer data)
 }
 
 void start_store() {
+  int old_menu=active_menu;
   cleanup();
-  store_menu(top_window);
+  if (old_menu != STORE_MENU) {
+    store_menu(top_window);
+    active_menu=STORE_MENU;
+  }
 }
 
 static gboolean store_cb (GtkWidget *widget, GdkEventButton *event, gpointer data) {
@@ -480,6 +492,7 @@ void new_menu()
     g_signal_connect (close_b, "button-press-event", G_CALLBACK(close_cb), NULL);
     gtk_grid_attach(GTK_GRID(grid),close_b,0,0,2,1);
 
+#ifdef RESTART_BUTTON
     //
     // The "Restart" restarts the protocol
     // This may help to recover from certain error conditions
@@ -487,6 +500,7 @@ void new_menu()
     GtkWidget *restart_b=gtk_button_new_with_label("Restart");
     g_signal_connect (restart_b, "button-press-event", G_CALLBACK(restart_cb), NULL);
     gtk_grid_attach(GTK_GRID(grid),restart_b,2,0,2,1);
+#endif
 
     GtkWidget *exit_b=gtk_button_new_with_label("Exit piHPSDR");
     g_signal_connect (exit_b, "button-press-event", G_CALLBACK(exit_cb), NULL);
@@ -591,14 +605,28 @@ void new_menu()
 
     switch(controller) {
       case NO_CONTROLLER:
-       {
+        {
+        GtkWidget *toolbar_b=gtk_button_new_with_label("Toolbar");
+        g_signal_connect (toolbar_b, "button-press-event", G_CALLBACK(toolbar_cb), NULL);
+        gtk_grid_attach(GTK_GRID(grid),toolbar_b,(i%5),i/5,1,1);
+        i++;
+        }
+        break;
+      case CONTROLLER1:
+#ifdef GPIO
+        {
+        GtkWidget *encoders_b=gtk_button_new_with_label("Encoders");
+        g_signal_connect (encoders_b, "button-press-event", G_CALLBACK(encoder_cb), NULL);
+        gtk_grid_attach(GTK_GRID(grid),encoders_b,(i%5),i/5,1,1);
+        i++;
+
         GtkWidget *switches_b=gtk_button_new_with_label("Switches");
         g_signal_connect (switches_b, "button-press-event", G_CALLBACK(switch_cb), NULL);
         gtk_grid_attach(GTK_GRID(grid),switches_b,(i%5),i/5,1,1);
         i++;
         }
+#endif
         break;
-      case CONTROLLER1:
       case CONTROLLER2_V1:
       case CONTROLLER2_V2:
         {
@@ -607,11 +635,16 @@ void new_menu()
         g_signal_connect (encoders_b, "button-press-event", G_CALLBACK(encoder_cb), NULL);
         gtk_grid_attach(GTK_GRID(grid),encoders_b,(i%5),i/5,1,1);
         i++;
-#endif
+
         GtkWidget *switches_b=gtk_button_new_with_label("Switches");
         g_signal_connect (switches_b, "button-press-event", G_CALLBACK(switch_cb), NULL);
         gtk_grid_attach(GTK_GRID(grid),switches_b,(i%5),i/5,1,1);
         i++;
+#endif
+        GtkWidget *toolbar_b=gtk_button_new_with_label("Toolbar");
+        g_signal_connect (toolbar_b, "button-press-event", G_CALLBACK(toolbar_cb), NULL);
+        gtk_grid_attach(GTK_GRID(grid),toolbar_b,(i%5),i/5,1,1);
+        i++;
         }
         break;
     }
index 977c564e34596dfa96b6689ab0e3adfb0fab509b..398200b2c7040e413ae3d67acab28cd7325e5d58 100644 (file)
@@ -42,7 +42,8 @@ enum {
   FILTER_MENU,
   NOISE_MENU,
   AGC_MENU,
-  VFO_MENU
+  VFO_MENU,
+  STORE_MENU
 };
 
 extern int active_menu;
diff --git a/radio.c b/radio.c
index 783ac4e6e154ec01e522c610c8393777d6f0e07f..d33f99a4d53a81f5cdb8699155b06067e7f7ce51 100644 (file)
--- a/radio.c
+++ b/radio.c
@@ -2150,9 +2150,6 @@ g_print("radioRestoreState: %s\n",property_path);
     memRestoreState();
     vfo_restore_state();
     modesettings_restore_state();
-//#ifdef GPIO
-//    gpio_restore_actions();
-//#endif
     gpio_restore_actions();
     value=getProperty("rigctl_enable");
     if(value) rigctl_enable=atoi(value);
@@ -2211,7 +2208,6 @@ g_print("radioRestoreState: %s\n",property_path);
     if(device==SOAPYSDR_USB_DEVICE) {
       value=getProperty("radio.adc[0].agc");
       if (value) adc[0].agc=atoi(value);
-      //if(value) soapy_protocol_set_automatic_gain(atoi(value));
     }
 #endif
 
@@ -2251,7 +2247,6 @@ g_print("radioRestoreState: %s\n",property_path);
       if(device==SOAPYSDR_USB_DEVICE) {
         value=getProperty("radio.adc[1].agc");
         if (value) adc[1].agc=atoi(value);
-        //if(value) soapy_protocol_set_automatic_gain(atoi(value));
       }
 #endif
 
@@ -2295,11 +2290,6 @@ g_print("radioSaveState: %s\n",property_path);
   
   g_mutex_lock(&property_mutex);
   clearProperties();
-//#ifdef GPIO
-//  if(controller!=NO_CONTROLLER) {
-//    gpio_save_actions();
-//  }
-//#endif
   gpio_save_actions();
   sprintf(value,"%d",receivers);
   setProperty("receivers",value);
index 0cec40a06b0a5dc64444a0ddea06b73926ec9b52..90d1e019fe3e3d6d0e3eac0f6b39f497f10650f3 100644 (file)
@@ -39,8 +39,8 @@
 #ifdef SOAPYSDR
 #include "soapy_protocol.h"
 #endif
-#ifdef GPIO
 #include "actions.h"
+#ifdef GPIO
 #include "gpio.h"
 #endif
 #include "vfo.h"
@@ -678,19 +678,19 @@ void radio_menu(GtkWidget *parent) {
   gtk_grid_attach(GTK_GRID(grid),rit_label,col,row,1,1);
   row++;
 
-  GtkWidget *rit_1=gtk_radio_button_new_with_label(NULL,"1/10");
+  GtkWidget *rit_1=gtk_radio_button_new_with_label(NULL,"1");
   gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (rit_1), rit_increment==1);
   gtk_grid_attach(GTK_GRID(grid),rit_1,col,row,1,1);
   g_signal_connect(rit_1,"pressed",G_CALLBACK(rit_cb),(gpointer *)1);
   row++;
 
-  GtkWidget *rit_10=gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(rit_1),"10/100");
+  GtkWidget *rit_10=gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(rit_1),"10");
   gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (rit_10), rit_increment==10);
   gtk_grid_attach(GTK_GRID(grid),rit_10,col,row,1,1);
   g_signal_connect(rit_10,"pressed",G_CALLBACK(rit_cb),(gpointer *)10);
   row++;
 
-  GtkWidget *rit_100=gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(rit_10),"100/1000");
+  GtkWidget *rit_100=gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(rit_10),"100");
   gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (rit_100), rit_increment==100);
   gtk_grid_attach(GTK_GRID(grid),rit_100,col,row,1,1);
   g_signal_connect(rit_100,"pressed",G_CALLBACK(rit_cb),(gpointer *)100);
index 4c45d82b1500a85e40b5cbb08ffe034b0fd8c3c8..105b1fd0e47eda03005a6a517c4b6495cc3aa266 100644 (file)
--- a/rx_menu.c
+++ b/rx_menu.c
@@ -197,9 +197,6 @@ void rx_menu(GtkWidget *parent) {
 
   GtkWidget *grid=gtk_grid_new();
   gtk_grid_set_column_spacing (GTK_GRID(grid),10);
-  //gtk_grid_set_row_spacing (GTK_GRID(grid),10);
-  //gtk_grid_set_row_homogeneous(GTK_GRID(grid),TRUE);
-  //gtk_grid_set_column_homogeneous(GTK_GRID(grid),TRUE);
 
   GtkWidget *close_b=gtk_button_new_with_label("Close");
   g_signal_connect (close_b, "button_press_event", G_CALLBACK(close_cb), NULL);
index ed2478790cfc17a9eee77bc2a794e7a6beef5f4e..f1a873385328cf09cb5dff169ddb61ee17797c63 100644 (file)
@@ -38,6 +38,7 @@
 #include "rx_panadapter.h"
 #include "vfo.h"
 #include "mode.h"
+#include "actions.h"
 #ifdef GPIO
 #include "gpio.h"
 #endif
index c8a4c9500d8d1482536bf43731d9040983f45f68..b1e85db97df3fdb2640040c993f8b0ed9125612a 100644 (file)
--- a/sliders.c
+++ b/sliders.c
@@ -59,6 +59,7 @@
 #ifdef CLIENT_SERVER
 #include "client_server.h"
 #endif
+#include "actions.h"
 
 static int width;
 static int height;
@@ -348,7 +349,6 @@ void update_af_gain() {
 }
 
 void set_af_gain(int rx,double value) {
-  g_print("%s\n",__FUNCTION__);
   receiver[rx]->volume=value;
   SetRXAPanelGain1 (receiver[rx]->id, receiver[rx]->volume);
   if(display_sliders) {
@@ -448,7 +448,7 @@ void set_rf_gain(int rx,double value) {
 
 void set_filter_width(int rx,int width) {
   g_print("%s\n",__FUNCTION__);
-    if(scale_status!=FILTER_WIDTH || scale_rx!=rx) {
+    if(scale_status!=IF_WIDTH || scale_rx!=rx) {
       if(scale_status!=NO_FUNCTION) {
         g_source_remove(scale_timer);
         gtk_widget_destroy(scale_dialog);
@@ -456,7 +456,7 @@ void set_filter_width(int rx,int width) {
       }
     }
     if(scale_status==NO_FUNCTION) {
-      scale_status=FILTER_WIDTH;
+      scale_status=IF_WIDTH;
       scale_rx=rx;
       char title[64];
       sprintf(title,"Filter Width RX %d (Hz)",rx);
@@ -479,7 +479,7 @@ void set_filter_width(int rx,int width) {
 
 void set_filter_shift(int rx,int shift) {
   g_print("%s\n",__FUNCTION__);
-    if(scale_status!=FILTER_SHIFT || scale_rx!=rx) {
+    if(scale_status!=IF_SHIFT || scale_rx!=rx) {
       if(scale_status!=NO_FUNCTION) {
         g_source_remove(scale_timer);
         gtk_widget_destroy(scale_dialog);
@@ -487,7 +487,7 @@ void set_filter_shift(int rx,int shift) {
       }
     }
     if(scale_status==NO_FUNCTION) {
-      scale_status=FILTER_SHIFT;
+      scale_status=IF_SHIFT;
       scale_rx=rx;
       char title[64];
       sprintf(title,"Filter SHIFT RX %d (Hz)",rx);
@@ -723,7 +723,7 @@ void set_compression(TRANSMITTER* tx) {
     gtk_range_set_value (GTK_RANGE(comp_scale),tx->compressor_level);
   } else {
 #endif
-    if(scale_status!=COMP) {
+    if(scale_status!=COMPRESSION) {
       if(scale_status!=NO_FUNCTION) {
         g_source_remove(scale_timer);
         gtk_widget_destroy(scale_dialog);
@@ -731,7 +731,7 @@ void set_compression(TRANSMITTER* tx) {
       }
     }
     if(scale_status==NO_FUNCTION) {
-      scale_status=COMP;
+      scale_status=COMPRESSION;
       scale_dialog=gtk_dialog_new_with_buttons("COMP",GTK_WINDOW(top_window),GTK_DIALOG_DESTROY_WITH_PARENT,NULL,NULL);
       GtkWidget *content=gtk_dialog_get_content_area(GTK_DIALOG(scale_dialog));
       comp_scale=gtk_scale_new_with_range(GTK_ORIENTATION_HORIZONTAL,0.0, 20.0, 1.00);
@@ -754,7 +754,7 @@ void set_compression(TRANSMITTER* tx) {
 
 void show_diversity_gain() {
   g_print("%s\n",__FUNCTION__);
-    if(scale_status!=DIVERSITY_GAIN) {
+    if(scale_status!=DIV_GAIN) {
       if(scale_status!=NO_FUNCTION) {
         g_source_remove(scale_timer);
         gtk_widget_destroy(scale_dialog);
@@ -762,7 +762,7 @@ void show_diversity_gain() {
       }
     }
     if(scale_status==NO_FUNCTION) {
-      scale_status=DIVERSITY_GAIN;
+      scale_status=DIV_GAIN;
       scale_dialog=gtk_dialog_new_with_buttons("Diversity Gain",GTK_WINDOW(top_window),GTK_DIALOG_DESTROY_WITH_PARENT,NULL,NULL);
       GtkWidget *content=gtk_dialog_get_content_area(GTK_DIALOG(scale_dialog));
       diversity_gain_scale=gtk_scale_new_with_range(GTK_ORIENTATION_HORIZONTAL,-27.0, 27.0, 0.01);
@@ -782,7 +782,7 @@ void show_diversity_gain() {
 
 void show_diversity_phase() {
   g_print("%s\n",__FUNCTION__);
-    if(scale_status!=DIVERSITY_PHASE) {
+    if(scale_status!=DIV_PHASE) {
       if(scale_status!=NO_FUNCTION) {
         g_source_remove(scale_timer);
         gtk_widget_destroy(scale_dialog);
@@ -790,7 +790,7 @@ void show_diversity_phase() {
       }
     }
     if(scale_status==NO_FUNCTION) {
-      scale_status=DIVERSITY_PHASE;
+      scale_status=DIV_PHASE;
       scale_dialog=gtk_dialog_new_with_buttons("Diversity Phase",GTK_WINDOW(top_window),GTK_DIALOG_DESTROY_WITH_PARENT,NULL,NULL);
       GtkWidget *content=gtk_dialog_get_content_area(GTK_DIALOG(scale_dialog));
       diversity_phase_scale=gtk_scale_new_with_range(GTK_ORIENTATION_HORIZONTAL, -180.0, 180.0, 0.1);
index 7c981c7c4ffba31476f71358429b802267735fac..c532bdb96834e63b5bb728e69de12b26326b6dd0 100644 (file)
--- a/sliders.h
+++ b/sliders.h
 
 enum {
   NO_FUNCTION=0,
-  AF_GAIN,
-  RF_GAIN,
-  MIC_GAIN,
-  LINEIN_GAIN,
-  AGC_GAIN,
-  DRIVE,
-  ATTENUATION,
-  SQUELCH,
-  COMP,
-  FILTER_WIDTH,
-  FILTER_SHIFT,
-  DIVERSITY_GAIN,
-  DIVERSITY_PHASE,
-  ZOOM,
-  PAN
+  SLIDER_AF_GAIN,
+  SLIDER_RF_GAIN,
+  SLIDER_MIC_GAIN,
+  SLIDER_LINEIN_GAIN,
+  SLIDER_AGC_GAIN,
+  SLIDER_DRIVE,
+  SLIDER_ATTENUATION,
+  SLIDER_SQUELCH,
+  SLIDER_COMP,
+  SLIDER_FILTER_WIDTH,
+  SLIDER_FILTER_SHIFT,
+  SLIDER_DIVERSITY_GAIN,
+  SLIDER_DIVERSITY_PHASE,
+  SLIDER_ZOOM,
+  SLIDER_PAN
 };
 
 extern gint scale_timer;
index 4d0918cc6f6cc6ee9a55c057fdee04455eb91764..c459ac0fedb85130274a99959bdd8dc9afa3786d 100644 (file)
@@ -118,44 +118,18 @@ static void get_info(char *driver) {
   }
 
 
-  int sample_rate=0;
+  int sample_rate=768000;
   SoapySDRRange *rx_rates=SoapySDRDevice_getSampleRateRange(sdr, SOAPY_SDR_RX, 0, &rx_rates_length);
   fprintf(stderr,"Rx sample rates: ");
   for (size_t i = 0; i < rx_rates_length; i++) {
     fprintf(stderr,"%f -> %f (%f),", rx_rates[i].minimum, rx_rates[i].maximum, rx_rates[i].minimum/48000.0);
-    if(sample_rate==0) {
-      if(rx_rates[i].minimum==rx_rates[i].maximum) {
-        if(((int)rx_rates[i].minimum%48000)==0) {
-          sample_rate=(int)rx_rates[i].minimum;
-        }
-      } else {
-        if((384000.0>=rx_rates[i].minimum) && (384000<=(int)rx_rates[i].maximum)) {
-          sample_rate=384000;
-        }
-        if((768000.0>=rx_rates[i].minimum) && (768000<=(int)rx_rates[i].maximum)) {
-          sample_rate=768000;
-        }
-      }
-    }
   }
-  fprintf(stderr,"\n");
-  free(rx_rates);
-
-  if(strcmp(driver,"lime")==0) {
-    sample_rate=768000;
-  } else if(strcmp(driver,"plutosdr")==0) {
-    sample_rate=768000;
-  } else if(strcmp(driver,"rtlsdr")==0) {
+  if(strcmp(driver,"rtlsdr")==0) {
     sample_rate=1536000;
-  } else if(strcmp(driver,"sdrplay")==0) {
-    //sample_rate=96000;
-    sample_rate=768000;
-  } else if(strcmp(driver,"radioberry")==0) {
-    sample_rate=48000;
-  } else {
-    sample_rate=1048576;
   }
-
+  
+  fprintf(stderr,"\n");
+  free(rx_rates);
   fprintf(stderr,"sample_rate selected %d\n",sample_rate);
 
   if(tx_channels>0) {
@@ -270,8 +244,6 @@ static void get_info(char *driver) {
     }
     if(strcmp(driver,"lime")==0) {
       sprintf(discovered[devices].info.soapy.version,"fw=%s gw=%s hw=%s p=%s", fw_version, gw_version, hw_version, p_version);
-    } else if (strcmp(driver,"radioberry")==0) {
-      sprintf(discovered[devices].info.soapy.version,"fw=%s gw=%s", fw_version, gw_version);
     } else {
       strcpy(discovered[devices].info.soapy.version,"");
     }
index dadb6ce5f37d9208b5062d10c1e4ee29ff3a4ed8..16d479e39808cc834e9465f61db7381d7e6fd6b1 100644 (file)
 #include "button_text.h"
 #include "toolbar.h"
 #include "actions.h"
+#include "action_dialog.h"
 #include "gpio.h"
 #include "i2c.h"
 
 typedef struct _choice {
   int sw;
   int action;
+  GtkWidget *initial_button;
   GtkWidget *button;
+  gulong signal_id;
 } CHOICE;
 
 static GtkWidget *parent_window=NULL;
@@ -70,51 +73,19 @@ static gboolean delete_event(GtkWidget *widget, GdkEvent *event, gpointer user_d
 }
 
 void switch_page_cb(GtkNotebook *notebook,GtkWidget *page,guint page_num,gpointer user_data) {
-  g_print("%s: page %d\n",__FUNCTION__,page_num);
   temp_switches=switches_controller1[page_num];
 }
 
-static void switch_select_cb(GtkWidget *widget, gpointer data) {
-  char text[128];
-  CHOICE *choice=(CHOICE *)data;
-g_print("%s: temp_switches=%p\n",__FUNCTION__,temp_switches);
-  temp_switches[choice->sw].switch_function=choice->action;
-  GtkWidget *label=gtk_bin_get_child(GTK_BIN(choice->button));
-  sprintf(text,"<span size=\"smaller\">%s</span>",sw_string[choice->action]);
-  gtk_label_set_markup (GTK_LABEL(label), text);
-  update_toolbar_labels();
-}
-
 static gboolean switch_cb(GtkWidget *widget, GdkEvent *event, gpointer data) {
   int sw=GPOINTER_TO_INT(data);
-  int i;
-
-  GtkWidget *menu=gtk_menu_new();
-  for(i=0;i<SWITCH_ACTIONS;i++) {
-    GtkWidget *menu_item=gtk_menu_item_new_with_label(sw_string[i]);
-    CHOICE *choice=g_new0(CHOICE,1);
-    choice->sw=sw;
-    choice->action=i;
-    choice->button=widget;
-    g_signal_connect(menu_item,"activate",G_CALLBACK(switch_select_cb),choice);
-    gtk_menu_shell_append(GTK_MENU_SHELL(menu),menu_item);
-  }
-  gtk_widget_show_all(menu);
-#if GTK_CHECK_VERSION(3,22,0)
-  gtk_menu_popup_at_pointer(GTK_MENU(menu),(GdkEvent *)event);
-// the following line of code is to work around the problem of the popup menu not having scroll bars.
-  gtk_menu_reposition(GTK_MENU(menu));
-#else
-  gtk_menu_popup(GTK_MENU(menu),NULL,NULL,NULL,NULL,0,gtk_get_current_event_time());
-#endif
+  int action=action_dialog(top_window,CONTROLLER_SWITCH,temp_switches[sw].switch_function);
+  gtk_button_set_label(GTK_BUTTON(widget),ActionTable[action].str);
+  temp_switches[sw].switch_function=action;
+  update_toolbar_labels();
   return TRUE;
 }
 
 static void response_event(GtkWidget *dialog,gint id,gpointer user_data) {
-  g_print("%s: id=%d\n",__FUNCTION__,id);
-  if(id==GTK_RESPONSE_ACCEPT) {
-    g_print("%s: ACCEPT\n",__FUNCTION__);
-  }
   gtk_widget_destroy(dialog);
   dialog=NULL;
   active_menu=NO_MENU;
@@ -130,9 +101,8 @@ void switch_menu(GtkWidget *parent) {
   GtkWidget *widget;
   gint function=0;
 
-g_print("%s: switches_no_controller=%p switches_controller1=%p switches_controller2_v1=%p switches_controller2_v2=%p\n",__FUNCTION__,&switches_no_controller,&switches_controller1,&switches_controller2_v1,&switches_controller2_v2);
 
-  dialog=gtk_dialog_new_with_buttons("piHPSDR - Switch Actions",GTK_WINDOW(parent),GTK_DIALOG_DESTROY_WITH_PARENT,("OK"),GTK_RESPONSE_ACCEPT,NULL);
+  dialog=gtk_dialog_new_with_buttons("piHPSDR - Switch Actions",GTK_WINDOW(parent),GTK_DIALOG_DESTROY_WITH_PARENT,"_OK",GTK_RESPONSE_ACCEPT,NULL);
   g_signal_connect (dialog, "response", G_CALLBACK (response_event), NULL);
 
   GtkWidget *content=gtk_dialog_get_content_area(GTK_DIALOG(dialog));
@@ -146,10 +116,10 @@ g_print("%s: switches_no_controller=%p switches_controller1=%p switches_controll
 next_function_set:
 
   grid=gtk_grid_new();
-  gtk_grid_set_column_homogeneous(GTK_GRID(grid),FALSE);
+  gtk_grid_set_column_homogeneous(GTK_GRID(grid),TRUE);
   gtk_grid_set_row_homogeneous(GTK_GRID(grid),FALSE);
-  gtk_grid_set_column_spacing (GTK_GRID(grid),2);
-  gtk_grid_set_row_spacing (GTK_GRID(grid),2);
+  gtk_grid_set_column_spacing (GTK_GRID(grid),0);
+  gtk_grid_set_row_spacing (GTK_GRID(grid),0);
 
 
   row=0;
@@ -175,82 +145,97 @@ next_function_set:
       break;
   }
 
-  g_print("%s: temp_switches=%p\n",__FUNCTION__,temp_switches);
 
   int original_row=row;
 
   if(controller==CONTROLLER2_V1 || controller==CONTROLLER2_V2) {
     row=row+5;
     col=0;
-    widget=gtk_button_new_with_label(sw_string[temp_switches[0].switch_function]);
-    g_signal_connect(widget,"button_press_event",G_CALLBACK(switch_cb),GINT_TO_POINTER(0));
+    widget=gtk_button_new_with_label(ActionTable[temp_switches[0].switch_function].str);
+    gtk_widget_set_name(widget,"small_button");
+    g_signal_connect(widget,"button-press-event",G_CALLBACK(switch_cb),GINT_TO_POINTER(0));
     gtk_grid_attach(GTK_GRID(grid),widget,col,row,1,1);
     col++;
-    widget=gtk_button_new_with_label(sw_string[temp_switches[1].switch_function]);
-    g_signal_connect(widget,"button_press_event",G_CALLBACK(switch_cb),GINT_TO_POINTER(1));
+    widget=gtk_button_new_with_label(ActionTable[temp_switches[1].switch_function].str);
+    gtk_widget_set_name(widget,"small_button");
+    g_signal_connect(widget,"button-press-event",G_CALLBACK(switch_cb),GINT_TO_POINTER(1));
     gtk_grid_attach(GTK_GRID(grid),widget,col,row,1,1);
     col++;
-    widget=gtk_button_new_with_label(sw_string[temp_switches[2].switch_function]);
-    g_signal_connect(widget,"button_press_event",G_CALLBACK(switch_cb),GINT_TO_POINTER(2));
+    widget=gtk_button_new_with_label(ActionTable[temp_switches[2].switch_function].str);
+    gtk_widget_set_name(widget,"small_button");
+    g_signal_connect(widget,"button-press-event",G_CALLBACK(switch_cb),GINT_TO_POINTER(2));
     gtk_grid_attach(GTK_GRID(grid),widget,col,row,1,1);
     col++;
-    widget=gtk_button_new_with_label(sw_string[temp_switches[3].switch_function]);
-    g_signal_connect(widget,"button_press_event",G_CALLBACK(switch_cb),GINT_TO_POINTER(3));
+    widget=gtk_button_new_with_label(ActionTable[temp_switches[3].switch_function].str);
+    gtk_widget_set_name(widget,"small_button");
+    g_signal_connect(widget,"button-press-event",G_CALLBACK(switch_cb),GINT_TO_POINTER(3));
     gtk_grid_attach(GTK_GRID(grid),widget,col,row,1,1);
     col++;
-    widget=gtk_button_new_with_label(sw_string[temp_switches[4].switch_function]);
-    g_signal_connect(widget,"button_press_event",G_CALLBACK(switch_cb),GINT_TO_POINTER(4));
+    widget=gtk_button_new_with_label(ActionTable[temp_switches[4].switch_function].str);
+    gtk_widget_set_name(widget,"small_button");
+    g_signal_connect(widget,"button-press-event",G_CALLBACK(switch_cb),GINT_TO_POINTER(4));
     gtk_grid_attach(GTK_GRID(grid),widget,col,row,1,1);
     col++;
-    widget=gtk_button_new_with_label(sw_string[temp_switches[5].switch_function]);
-    g_signal_connect(widget,"button_press_event",G_CALLBACK(switch_cb),GINT_TO_POINTER(5));
+    widget=gtk_button_new_with_label(ActionTable[temp_switches[5].switch_function].str);
+    gtk_widget_set_name(widget,"small_button");
+    g_signal_connect(widget,"button-press-event",G_CALLBACK(switch_cb),GINT_TO_POINTER(5));
     gtk_grid_attach(GTK_GRID(grid),widget,col,row,1,1);
     col++;
-    widget=gtk_button_new_with_label(sw_string[temp_switches[6].switch_function]);
-    g_signal_connect(widget,"button_press_event",G_CALLBACK(switch_cb),GINT_TO_POINTER(6));
+    widget=gtk_button_new_with_label(ActionTable[temp_switches[6].switch_function].str);
+    gtk_widget_set_name(widget,"small_button");
+    g_signal_connect(widget,"button-press-event",G_CALLBACK(switch_cb),GINT_TO_POINTER(6));
     gtk_grid_attach(GTK_GRID(grid),widget,col,row,1,1);
     col++;
 
     row=original_row;
     col=8;
-    widget=gtk_button_new_with_label(sw_string[temp_switches[7].switch_function]);
-    g_signal_connect(widget,"button_press_event",G_CALLBACK(switch_cb),GINT_TO_POINTER(7));
+    widget=gtk_button_new_with_label(ActionTable[temp_switches[7].switch_function].str);
+    gtk_widget_set_name(widget,"small_button");
+    g_signal_connect(widget,"button-press-event",G_CALLBACK(switch_cb),GINT_TO_POINTER(7));
     gtk_grid_attach(GTK_GRID(grid),widget,col,row,1,1);
     row++;
     col=7;
-    widget=gtk_button_new_with_label(sw_string[temp_switches[8].switch_function]);
-    g_signal_connect(widget,"button_press_event",G_CALLBACK(switch_cb),GINT_TO_POINTER(8));
+    widget=gtk_button_new_with_label(ActionTable[temp_switches[8].switch_function].str);
+    gtk_widget_set_name(widget,"small_button");
+    g_signal_connect(widget,"button-press-event",G_CALLBACK(switch_cb),GINT_TO_POINTER(8));
     gtk_grid_attach(GTK_GRID(grid),widget,col,row,1,1);
     col++;
-    widget=gtk_button_new_with_label(sw_string[temp_switches[9].switch_function]);
-    g_signal_connect(widget,"button_press_event",G_CALLBACK(switch_cb),GINT_TO_POINTER(9));
+    widget=gtk_button_new_with_label(ActionTable[temp_switches[9].switch_function].str);
+    gtk_widget_set_name(widget,"small_button");
+    g_signal_connect(widget,"button-press-event",G_CALLBACK(switch_cb),GINT_TO_POINTER(9));
     gtk_grid_attach(GTK_GRID(grid),widget,col,row,1,1);
     row++;
     col=7;
-    widget=gtk_button_new_with_label(sw_string[temp_switches[10].switch_function]);
-    g_signal_connect(widget,"button_press_event",G_CALLBACK(switch_cb),GINT_TO_POINTER(10));
+    widget=gtk_button_new_with_label(ActionTable[temp_switches[10].switch_function].str);
+    gtk_widget_set_name(widget,"small_button");
+    g_signal_connect(widget,"button-press-event",G_CALLBACK(switch_cb),GINT_TO_POINTER(10));
     gtk_grid_attach(GTK_GRID(grid),widget,col,row,1,1);
     col++;
-    widget=gtk_button_new_with_label(sw_string[temp_switches[11].switch_function]);
-    g_signal_connect(widget,"button_press_event",G_CALLBACK(switch_cb),GINT_TO_POINTER(11));
+    widget=gtk_button_new_with_label(ActionTable[temp_switches[11].switch_function].str);
+    gtk_widget_set_name(widget,"small_button");
+    g_signal_connect(widget,"button-press-event",G_CALLBACK(switch_cb),GINT_TO_POINTER(11));
     gtk_grid_attach(GTK_GRID(grid),widget,col,row,1,1);
     row++;
     col=7;
-    widget=gtk_button_new_with_label(sw_string[temp_switches[12].switch_function]);
-    g_signal_connect(widget,"button_press_event",G_CALLBACK(switch_cb),GINT_TO_POINTER(12));
+    widget=gtk_button_new_with_label(ActionTable[temp_switches[12].switch_function].str);
+    gtk_widget_set_name(widget,"small_button");
+    g_signal_connect(widget,"button-press-event",G_CALLBACK(switch_cb),GINT_TO_POINTER(12));
     gtk_grid_attach(GTK_GRID(grid),widget,col,row,1,1);
     col++;
-    widget=gtk_button_new_with_label(sw_string[temp_switches[13].switch_function]);
-    g_signal_connect(widget,"button_press_event",G_CALLBACK(switch_cb),GINT_TO_POINTER(13));
+    widget=gtk_button_new_with_label(ActionTable[temp_switches[13].switch_function].str);
+    gtk_widget_set_name(widget,"small_button");
+    g_signal_connect(widget,"button-press-event",G_CALLBACK(switch_cb),GINT_TO_POINTER(13));
     gtk_grid_attach(GTK_GRID(grid),widget,col,row,1,1);
     row++;
     col=7;
-    widget=gtk_button_new_with_label(sw_string[temp_switches[14].switch_function]);
-    g_signal_connect(widget,"button_press_event",G_CALLBACK(switch_cb),GINT_TO_POINTER(14));
+    widget=gtk_button_new_with_label(ActionTable[temp_switches[14].switch_function].str);
+    gtk_widget_set_name(widget,"small_button");
+    g_signal_connect(widget,"button-press-event",G_CALLBACK(switch_cb),GINT_TO_POINTER(14));
     gtk_grid_attach(GTK_GRID(grid),widget,col,row,1,1);
     col++;
-    widget=gtk_button_new_with_label(sw_string[temp_switches[15].switch_function]);
-    g_signal_connect(widget,"button_press_event",G_CALLBACK(switch_cb),GINT_TO_POINTER(15));
+    widget=gtk_button_new_with_label(ActionTable[temp_switches[15].switch_function].str);
+    gtk_widget_set_name(widget,"small_button");
+    g_signal_connect(widget,"button-press-event",G_CALLBACK(switch_cb),GINT_TO_POINTER(15));
     gtk_grid_attach(GTK_GRID(grid),widget,col,row,1,1);
 
     gtk_container_add(GTK_CONTAINER(content),grid);
@@ -258,12 +243,12 @@ next_function_set:
     int start_row=row;
     for(int i=0;i<max_switches;i++) {
       if((controller==NO_CONTROLLER || controller==CONTROLLER1) && (temp_switches[i].switch_function==FUNCTION)) {
-        widget=gtk_label_new(NULL);
-        g_sprintf(label,"<b>%s</b>",sw_string[temp_switches[i].switch_function]);
-        gtk_label_set_markup (GTK_LABEL(widget), label);
+        widget=gtk_button_new_with_label(ActionTable[temp_switches[i].switch_function].str);
+        // no signal for Function button
       } else {
-        widget=gtk_button_new_with_label(sw_string[temp_switches[i].switch_function]);
-        g_signal_connect(widget,"button_press_event",G_CALLBACK(switch_cb),GINT_TO_POINTER(i));
+        widget=gtk_button_new_with_label(ActionTable[temp_switches[i].switch_function].str);
+        g_signal_connect(widget,"button-press-event",G_CALLBACK(switch_cb),GINT_TO_POINTER(i));
+g_print("%s: %d\n",__FUNCTION__,i);
       }
       gtk_grid_attach(GTK_GRID(grid),widget,col,row,1,1);
       col++;
index 7e619a87b3e52080b60bf86ba53bd43ace3da57a..1c7c7879e5f0e3e205686d55cbd244fab0eef03d 100644 (file)
--- a/toolbar.c
+++ b/toolbar.c
@@ -24,9 +24,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include "actions.h"
-#ifdef GPIO
 #include "gpio.h"
-#endif
 #include "toolbar.h"
 #include "mode.h"
 #include "filter.h"
@@ -94,11 +92,7 @@ static gboolean rit_timer_cb(gpointer data) {
 
 static gboolean xit_timer_cb(gpointer data) {
   int i=GPOINTER_TO_INT(data);
-  //
-  // In most operations, one want to move XIT faster than RIT
-  // therefore take 10 times the RIT value for XIT
-  //
-  transmitter->xit+=(10*i*rit_increment);
+  transmitter->xit+=(i*rit_increment);
   if(transmitter->xit>10000) transmitter->xit=10000;
   if(transmitter->xit<-10000) transmitter->xit=-10000;
   if(protocol==NEW_PROTOCOL) {
@@ -109,14 +103,14 @@ static gboolean xit_timer_cb(gpointer data) {
 }
 
 void update_toolbar_labels() {
-  gtk_button_set_label(GTK_BUTTON(sim_mox),sw_cap_string[toolbar_switches[0].switch_function]);
-  gtk_button_set_label(GTK_BUTTON(sim_s1),sw_cap_string[toolbar_switches[1].switch_function]);
-  gtk_button_set_label(GTK_BUTTON(sim_s2),sw_cap_string[toolbar_switches[2].switch_function]);
-  gtk_button_set_label(GTK_BUTTON(sim_s3),sw_cap_string[toolbar_switches[3].switch_function]);
-  gtk_button_set_label(GTK_BUTTON(sim_s4),sw_cap_string[toolbar_switches[4].switch_function]);
-  gtk_button_set_label(GTK_BUTTON(sim_s5),sw_cap_string[toolbar_switches[5].switch_function]);
-  gtk_button_set_label(GTK_BUTTON(sim_s6),sw_cap_string[toolbar_switches[6].switch_function]);
-  gtk_button_set_label(GTK_BUTTON(sim_function),sw_cap_string[toolbar_switches[7].switch_function]);
+  gtk_button_set_label(GTK_BUTTON(sim_mox),ActionTable[toolbar_switches[0].switch_function].button_str);
+  gtk_button_set_label(GTK_BUTTON(sim_s1),ActionTable[toolbar_switches[1].switch_function].button_str);
+  gtk_button_set_label(GTK_BUTTON(sim_s2),ActionTable[toolbar_switches[2].switch_function].button_str);
+  gtk_button_set_label(GTK_BUTTON(sim_s3),ActionTable[toolbar_switches[3].switch_function].button_str);
+  gtk_button_set_label(GTK_BUTTON(sim_s4),ActionTable[toolbar_switches[4].switch_function].button_str);
+  gtk_button_set_label(GTK_BUTTON(sim_s5),ActionTable[toolbar_switches[5].switch_function].button_str);
+  gtk_button_set_label(GTK_BUTTON(sim_s6),ActionTable[toolbar_switches[6].switch_function].button_str);
+  gtk_button_set_label(GTK_BUTTON(sim_function),ActionTable[toolbar_switches[7].switch_function].button_str);
 }
 
 static void close_cb(GtkWidget *widget, gpointer data) {
@@ -327,12 +321,7 @@ static void xit_enable_cb(GtkWidget *widget, gpointer data) {
 static void xit_cb(GtkWidget *widget, gpointer data) {
   if(can_transmit) {
     int i=GPOINTER_TO_INT(data);
-    //
-    // in practical operation, you mostly want to change rit by small amounts
-    // (if listening to a group of non-transceive members) but XIT is mostly used
-    // for "split" operation and needs 10 times larger increments
-    //
-    transmitter->xit+=i*rit_increment*10;
+    transmitter->xit+=i*rit_increment;
     if(transmitter->xit>10000) transmitter->xit=10000;
     if(transmitter->xit<-10000) transmitter->xit=-10000;
     if(protocol==NEW_PROTOCOL) {
@@ -513,18 +502,18 @@ void tune_update(int state) {
 
 void switch_pressed_cb(GtkWidget *widget, gpointer data) {
   gint i=GPOINTER_TO_INT(data);
-  SWITCH_ACTION *a=g_new(SWITCH_ACTION,1);
+  PROCESS_ACTION *a=g_new(PROCESS_ACTION,1);
   a->action=toolbar_switches[i].switch_function;
-  a->state=PRESSED;
-  g_idle_add(switch_action,a);
+  a->mode=PRESSED;
+  g_idle_add(process_action,a);
 }
 
 void switch_released_cb(GtkWidget *widget, gpointer data) {
   gint i=GPOINTER_TO_INT(data);
-  SWITCH_ACTION *a=g_new(SWITCH_ACTION,1);
+  PROCESS_ACTION *a=g_new(PROCESS_ACTION,1);
   a->action=toolbar_switches[i].switch_function;
-  a->state=RELEASED;
-  g_idle_add(switch_action,a);
+  a->mode=RELEASED;
+  g_idle_add(process_action,a);
 }
 
 GtkWidget *toolbar_init(int my_width, int my_height, GtkWidget* parent) {
@@ -550,44 +539,43 @@ GtkWidget *toolbar_init(int my_width, int my_height, GtkWidget* parent) {
     gtk_widget_set_size_request (toolbar, width, height);
     gtk_grid_set_column_homogeneous(GTK_GRID(toolbar),TRUE);
 
-    sim_mox=gtk_button_new_with_label(sw_cap_string[toolbar_switches[0].switch_function]);
+    sim_mox=gtk_button_new_with_label(ActionTable[toolbar_switches[0].switch_function].button_str);
     g_signal_connect(G_OBJECT(sim_mox),"pressed",G_CALLBACK(switch_pressed_cb),GINT_TO_POINTER(0));
     gtk_grid_attach(GTK_GRID(toolbar),sim_mox,0,0,4,1);
 
-
-    sim_s1=gtk_button_new_with_label(sw_cap_string[toolbar_switches[1].switch_function]);
+    sim_s1=gtk_button_new_with_label(ActionTable[toolbar_switches[1].switch_function].button_str);
     gtk_widget_set_size_request (sim_s1, button_width, 0);
     g_signal_connect(G_OBJECT(sim_s1),"pressed",G_CALLBACK(switch_pressed_cb),GINT_TO_POINTER(1));
     g_signal_connect(G_OBJECT(sim_s1),"released",G_CALLBACK(switch_released_cb),GINT_TO_POINTER(1));
     gtk_grid_attach(GTK_GRID(toolbar),sim_s1,4,0,4,1);
 
-    sim_s2=gtk_button_new_with_label(sw_cap_string[toolbar_switches[2].switch_function]);
-    gtk_widget_set_size_request (sim_s2, button_width, 0); 
+    sim_s2=gtk_button_new_with_label(ActionTable[toolbar_switches[2].switch_function].button_str);
+    gtk_widget_set_size_request (sim_s2, button_width, 0);
     g_signal_connect(G_OBJECT(sim_s2),"pressed",G_CALLBACK(switch_pressed_cb),GINT_TO_POINTER(2));
     g_signal_connect(G_OBJECT(sim_s2),"released",G_CALLBACK(switch_released_cb),GINT_TO_POINTER(2));
     gtk_grid_attach(GTK_GRID(toolbar),sim_s2,8,0,4,1);
 
-    sim_s3=gtk_button_new_with_label(sw_cap_string[toolbar_switches[3].switch_function]);
+    sim_s3=gtk_button_new_with_label(ActionTable[toolbar_switches[3].switch_function].button_str);
     g_signal_connect(G_OBJECT(sim_s3),"pressed",G_CALLBACK(switch_pressed_cb),GINT_TO_POINTER(3));
     g_signal_connect(G_OBJECT(sim_s3),"released",G_CALLBACK(switch_released_cb),GINT_TO_POINTER(3));
     gtk_grid_attach(GTK_GRID(toolbar),sim_s3,12,0,4,1);
 
-    sim_s4=gtk_button_new_with_label(sw_cap_string[toolbar_switches[4].switch_function]);
+    sim_s4=gtk_button_new_with_label(ActionTable[toolbar_switches[4].switch_function].button_str);
     g_signal_connect(G_OBJECT(sim_s4),"pressed",G_CALLBACK(switch_pressed_cb),GINT_TO_POINTER(4));
     g_signal_connect(G_OBJECT(sim_s4),"released",G_CALLBACK(switch_released_cb),GINT_TO_POINTER(4));
     gtk_grid_attach(GTK_GRID(toolbar),sim_s4,16,0,4,1);
 
-    sim_s5=gtk_button_new_with_label(sw_cap_string[toolbar_switches[5].switch_function]);
+    sim_s5=gtk_button_new_with_label(ActionTable[toolbar_switches[5].switch_function].button_str);
     g_signal_connect(G_OBJECT(sim_s5),"pressed",G_CALLBACK(switch_pressed_cb),GINT_TO_POINTER(5));
     g_signal_connect(G_OBJECT(sim_s5),"released",G_CALLBACK(switch_released_cb),GINT_TO_POINTER(5));
     gtk_grid_attach(GTK_GRID(toolbar),sim_s5,20,0,4,1);
 
-    sim_s6=gtk_button_new_with_label(sw_cap_string[toolbar_switches[6].switch_function]);
+    sim_s6=gtk_button_new_with_label(ActionTable[toolbar_switches[6].switch_function].button_str);
     g_signal_connect(G_OBJECT(sim_s6),"pressed",G_CALLBACK(switch_pressed_cb),GINT_TO_POINTER(6));
     g_signal_connect(G_OBJECT(sim_s6),"released",G_CALLBACK(switch_released_cb),GINT_TO_POINTER(6));
     gtk_grid_attach(GTK_GRID(toolbar),sim_s6,24,0,4,1);
 
-    sim_function=gtk_button_new_with_label(sw_cap_string[toolbar_switches[7].switch_function]);
+    sim_function=gtk_button_new_with_label(ActionTable[toolbar_switches[7].switch_function].button_str);
     g_signal_connect(G_OBJECT(sim_function),"pressed",G_CALLBACK(switch_pressed_cb),GINT_TO_POINTER(7));
     gtk_grid_attach(GTK_GRID(toolbar),sim_function,28,0,4,1);
 
diff --git a/toolbar_menu.c b/toolbar_menu.c
new file mode 100644 (file)
index 0000000..0297e36
--- /dev/null
@@ -0,0 +1,156 @@
+
+/* Copyright (C)
+* 2016 - John Melton, G0ORX/N6LYT
+*
+* This program 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.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+*
+*/
+
+#include <gtk/gtk.h>
+#include <glib/gprintf.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "main.h"
+#include "new_menu.h"
+#include "agc_menu.h"
+#include "agc.h"
+#include "band.h"
+#include "channel.h"
+#include "radio.h"
+#include "receiver.h"
+#include "vfo.h"
+#include "button_text.h"
+#include "toolbar.h"
+#include "actions.h"
+#include "action_dialog.h"
+#include "gpio.h"
+#include "i2c.h"
+
+typedef struct _choice {
+  int sw;
+  int action;
+  GtkWidget *initial_button;
+  GtkWidget *button;
+  gulong signal_id;
+} CHOICE;
+
+static GtkWidget *parent_window=NULL;
+
+static GtkWidget *dialog=NULL;
+
+static SWITCH *temp_switches;
+
+
+static void cleanup() {
+  if(dialog!=NULL) {
+    gtk_widget_destroy(dialog);
+    dialog=NULL;
+    active_menu=NO_MENU;
+    sub_menu=NULL;
+  }
+}
+
+static gboolean close_cb (GtkWidget *widget, GdkEventButton *event, gpointer data) {
+  cleanup();
+  return TRUE;
+}
+
+static gboolean delete_event(GtkWidget *widget, GdkEvent *event, gpointer user_data) {
+  cleanup();
+  return FALSE;
+}
+
+static void switch_page_cb(GtkNotebook *notebook,GtkWidget *page,guint page_num,gpointer user_data) {
+  temp_switches=switches_controller1[page_num];
+}
+
+static gboolean switch_cb(GtkWidget *widget, GdkEvent *event, gpointer data) {
+  int sw=GPOINTER_TO_INT(data);
+  int action=action_dialog(top_window,CONTROLLER_SWITCH,temp_switches[sw].switch_function);
+  gtk_button_set_label(GTK_BUTTON(widget),ActionTable[action].str);
+  temp_switches[sw].switch_function=action;
+  update_toolbar_labels();
+  return TRUE;
+}
+
+static void response_event(GtkWidget *dialog,gint id,gpointer user_data) {
+  gtk_widget_destroy(dialog);
+  dialog=NULL;
+  active_menu=NO_MENU;
+  sub_menu=NULL;
+}
+
+void toolbar_menu(GtkWidget *parent) {
+  gint row;
+  gint col;
+  gchar label[64];
+  GtkWidget *notebook;
+  GtkWidget *grid;
+  GtkWidget *widget;
+  gint function=0;
+
+
+  dialog=gtk_dialog_new_with_buttons("piHPSDR - Toolbar Actions",GTK_WINDOW(parent),GTK_DIALOG_DESTROY_WITH_PARENT,"_OK",GTK_RESPONSE_ACCEPT,NULL);
+  g_signal_connect (dialog, "response", G_CALLBACK (response_event), NULL);
+
+  GtkWidget *content=gtk_dialog_get_content_area(GTK_DIALOG(dialog));
+
+  function=0;
+
+  notebook=gtk_notebook_new();
+next_function_set:
+
+  grid=gtk_grid_new();
+  gtk_grid_set_column_homogeneous(GTK_GRID(grid),TRUE);
+  gtk_grid_set_row_homogeneous(GTK_GRID(grid),FALSE);
+  gtk_grid_set_column_spacing (GTK_GRID(grid),0);
+  gtk_grid_set_row_spacing (GTK_GRID(grid),0);
+
+
+  row=0;
+  col=0;
+
+  gint max_switches=MAX_SWITCHES;
+  max_switches=8;
+  temp_switches=switches_controller1[function];
+
+  for(int i=0;i<max_switches;i++) {
+    if(temp_switches[i].switch_function==FUNCTION) {
+      widget=gtk_button_new_with_label(ActionTable[temp_switches[i].switch_function].str);
+      // no signal for Function button
+    } else {
+      widget=gtk_button_new_with_label(ActionTable[temp_switches[i].switch_function].str);
+      g_signal_connect(widget,"button-press-event",G_CALLBACK(switch_cb),GINT_TO_POINTER(i));
+g_print("%s: %d\n",__FUNCTION__,i);
+    }
+    gtk_grid_attach(GTK_GRID(grid),widget,col,row,1,1);
+    col++;
+  }
+
+  g_sprintf(label,"Function %d",function);
+  gtk_notebook_append_page(GTK_NOTEBOOK(notebook),grid,gtk_label_new(label));
+  function++;
+  if(function<MAX_FUNCTIONS) {
+    goto next_function_set;
+  }
+  gtk_container_add(GTK_CONTAINER(content),notebook);
+  g_signal_connect (notebook, "switch-page",G_CALLBACK(switch_page_cb),NULL);
+
+  sub_menu=dialog;
+
+  gtk_widget_show_all(dialog);
+}
diff --git a/toolbar_menu.h b/toolbar_menu.h
new file mode 100644 (file)
index 0000000..a1d52df
--- /dev/null
@@ -0,0 +1 @@
+void toolbar_menu(GtkWidget *parent);
index 2052e4887515e44e8f2e78af1d43a73e347cd3c9..b9bfe0f915969b7c3a9d22ddee21373f1a922fc8 100644 (file)
--- a/zoompan.c
+++ b/zoompan.c
@@ -32,6 +32,7 @@
 #ifdef CLIENT_SERVER
 #include "client_server.h"
 #endif
+#include "actions.h"
 
 static int width;
 static int height;