From fe63d0dea109fddb8cacbfd0c2bce6d3e7bcb9bc Mon Sep 17 00:00:00 2001
From: c vw <dl1ycf@darc.de>
Date: Mon, 3 Jun 2019 16:39:42 +0200
Subject: [PATCH] Avoid "overloading" of the GUI by high-frequency call to
 vfo_update().

---
 README.MIDI    | 21 +++++++++++++++------
 ext.c          | 12 +++++++++++-
 filter_menu.c  |  3 ++-
 freqent_menu.c |  5 +++--
 gpio.c         |  6 +++---
 gpio_mraa.c    |  2 +-
 noise_menu.c   |  3 ++-
 step_menu.c    |  3 ++-
 toolbar.c      | 18 +++++++++---------
 transmitter.c  |  4 ++--
 vfo.c          | 22 +++++++++++-----------
 vfo_menu.c     | 10 +++++-----
 vox_menu.c     |  3 ++-
 13 files changed, 68 insertions(+), 44 deletions(-)

diff --git a/README.MIDI b/README.MIDI
index 57a31f9..05d3e6a 100644
--- a/README.MIDI
+++ b/README.MIDI
@@ -23,9 +23,7 @@ provided as an example. The basic rules for the file are
 
   DEVICE=CMD PL
 
-  will accept the "CMD PL-1" MIDI controller. Note that events are processed
-  without looking at the channel number. This is so because for the Behringer
-  controller, one can accidentally change the channel number by hitting a key.
+  will accept the "CMD PL-1" MIDI controller.
 
 - The following lines all must contain one of the strings
   "KEY=", "CTRL=", or "PITCH=". The syntax is as follows:
@@ -35,10 +33,15 @@ provided as an example. The basic rules for the file are
 
   The syntay is 
 
-  KEY=<nr> ACTION=<action> <modifier>
+  KEY=<nr> CHAN=<chan> ACTION=<action> <modifier>
 
-  where <nr> is the Number of the Midi Note
-  and <action> is the key-word for a SDR "action" (see below)
+  where <nr> is the Number of the Midi Note, <chan> is the MIDI
+  channel where the event is expected.
+
+  The key words with the line can be given in any order. If
+  CHAN=  is omitted, MIDI events from any channel are accepted.
+
+   <action> is the key-word for a SDR "action" (see below)
   and <modifier> can be omitted, or can be the string "ONOFF".
   If the "ONOFF" modifier is there, an action is taken both upon
   Note-On and Note-Off events (usually: when pressing and releasing
@@ -108,6 +111,12 @@ provided as an example. The basic rules for the file are
   generated, since the controller values are always in the range
   0-127 and the threshold for fast and very-fast are never reached.
 
+  For wheels, there can be an additional directive DELAY=<delay>,
+  if this is given, it specifies a delay time (in msec) in which no
+  further WHEEL event is processed. If a wheel is used, for example,
+  to cycle through the filter settings, a delay takes care that this
+  does not go too fast.
+
   PITCH: MIDI PITCH sliders
   =========================
 
diff --git a/ext.c b/ext.c
index daacc6d..28f7ed7 100644
--- a/ext.c
+++ b/ext.c
@@ -54,11 +54,21 @@ int ext_set_frequency(void *data) {
   return 0;
 }
 
-int ext_vfo_update(void *data) {
+static guint vfo_timeout=0;
+
+static int vfo_timeout_cb(void * data) {
+  vfo_timeout=0;
   vfo_update();
   return 0;
 }
 
+int ext_vfo_update(void *data) {
+  if (vfo_timeout ==0) {
+    vfo_timeout=g_timeout_add(100, vfo_timeout_cb, NULL);
+  }
+  return 0;
+}
+
 int ext_vfo_filter_changed(void *data) {
   vfo_filter_changed((int)(uintptr_t)data);
   return 0;
diff --git a/filter_menu.c b/filter_menu.c
index 3bc8570..fad3098 100644
--- a/filter_menu.c
+++ b/filter_menu.c
@@ -31,6 +31,7 @@
 #include "receiver.h"
 #include "vfo.h"
 #include "button_text.h"
+#include "ext.h"
 
 static GtkWidget *parent_window=NULL;
 
@@ -87,7 +88,7 @@ static gboolean deviation_select_cb (GtkWidget *widget, gpointer data) {
   set_button_text_color(last_filter,"black");
   last_filter=widget;
   set_button_text_color(last_filter,"orange");
-  vfo_update();
+  g_idle_add(ext_vfo_update,NULL);
   return FALSE;
 }
 
diff --git a/freqent_menu.c b/freqent_menu.c
index 59d49e3..b118b1e 100644
--- a/freqent_menu.c
+++ b/freqent_menu.c
@@ -31,6 +31,7 @@
 #include "receiver.h"
 #include "vfo.h"
 #include "button_text.h"
+#include "ext.h"
 
 static GtkWidget *parent_window=NULL;
 static GtkWidget *dialog=NULL;
@@ -140,12 +141,12 @@ static gboolean freqent_select_cb (GtkWidget *widget, gpointer data) {
               }
             }
             setFrequency(f);
-            vfo_update();
+            g_idle_add(ext_vfo_update,NULL);
       
             set = 1;
         }
     }
-    vfo_update();
+    g_idle_add(ext_vfo_update,NULL);
     return FALSE;
 }
 
diff --git a/gpio.c b/gpio.c
index a34510d..dccc90f 100644
--- a/gpio.c
+++ b/gpio.c
@@ -1364,7 +1364,7 @@ static void encoder_changed(int action,int pos) {
       if(protocol==NEW_PROTOCOL) {
         schedule_high_priority();
       }
-      vfo_update();
+      g_idle_add(ext_vfo_update,NULL);
       break;
     case ENCODER_CW_SPEED:
       value=(double)cw_keyer_speed;
@@ -1375,7 +1375,7 @@ static void encoder_changed(int action,int pos) {
         value=60.0;
       }
       cw_keyer_speed=(int)value;
-      vfo_update();
+      g_idle_add(ext_vfo_update,NULL);
       break;
     case ENCODER_CW_FREQUENCY:
       value=(double)cw_keyer_sidetone_frequency;
@@ -1386,7 +1386,7 @@ static void encoder_changed(int action,int pos) {
         value=1000.0;
       }
       cw_keyer_sidetone_frequency=(int)value;
-      vfo_update();
+      g_idle_add(ext_vfo_update,NULL);
       break;
     case ENCODER_PANADAPTER_HIGH:
       value=(double)active_receiver->panadapter_high;
diff --git a/gpio_mraa.c b/gpio_mraa.c
index 9cc2bb2..e136172 100644
--- a/gpio_mraa.c
+++ b/gpio_mraa.c
@@ -774,7 +774,7 @@ static int vfo_encoder_changed(void *data) {
     //entry->frequency=entry->frequency+(pos*step);
     //setFrequency(entry->frequency);
     setFrequency(entry->frequency+ddsOffset+(pos*step));
-    vfo_update();
+    g_idle_add(ext_vfo_update,NULL);
   }
   free(data);
   return 0;
diff --git a/noise_menu.c b/noise_menu.c
index 2e61492..19a3100 100644
--- a/noise_menu.c
+++ b/noise_menu.c
@@ -34,6 +34,7 @@
 #include "radio.h"
 #include "vfo.h"
 #include "button_text.h"
+#include "ext.h"
 
 static GtkWidget *parent_window=NULL;
 
@@ -66,7 +67,7 @@ void update_noise() {
   SetRXAEMNRRun(active_receiver->id, active_receiver->nr2);
   SetRXAANFRun(active_receiver->id, active_receiver->anf);
   SetRXASNBARun(active_receiver->id, active_receiver->snb);
-  vfo_update();
+  g_idle_add(ext_vfo_update,NULL);
 }
 
 static void nb_none_cb(GtkWidget *widget, gpointer data) {
diff --git a/step_menu.c b/step_menu.c
index e656379..9782cb3 100644
--- a/step_menu.c
+++ b/step_menu.c
@@ -26,6 +26,7 @@
 #include "new_menu.h"
 #include "radio.h"
 #include "vfo.h"
+#include "ext.h"
 
 static GtkWidget *parent_window=NULL;
 
@@ -51,7 +52,7 @@ static gboolean delete_event(GtkWidget *widget, GdkEvent *event, gpointer user_d
 
 static gboolean step_select_cb (GtkWidget *widget, gpointer        data) {
   step=steps[(uintptr_t)data];
-  vfo_update();
+  g_idle_add(ext_vfo_update,NULL);
   return FALSE;
 }
 
diff --git a/toolbar.c b/toolbar.c
index 4a1ad9f..541e19a 100644
--- a/toolbar.c
+++ b/toolbar.c
@@ -88,7 +88,7 @@ static gboolean rit_timer_cb(gpointer data) {
   if(protocol==NEW_PROTOCOL) {
     schedule_high_priority();
   }
-  vfo_update();
+  g_idle_add(ext_vfo_update,NULL);
   return TRUE;
 }
 
@@ -195,7 +195,7 @@ void ctun_cb (GtkWidget *widget, gpointer data) {
   }
   vfo[id].ctun_frequency=vfo[id].frequency;
   set_offset(active_receiver,vfo[id].offset);
-  vfo_update();
+  g_idle_add(ext_vfo_update,NULL);
 }
 
 static void atob_cb (GtkWidget *widget, gpointer data) {
@@ -217,7 +217,7 @@ static void split_cb (GtkWidget *widget, gpointer data) {
   } else {
     tx_set_mode(transmitter,vfo[VFO_A].mode);
   }
-  vfo_update();
+  g_idle_add(ext_vfo_update,NULL);
 }
 
 static void rit_enable_cb(GtkWidget *widget, gpointer data) {
@@ -225,7 +225,7 @@ static void rit_enable_cb(GtkWidget *widget, gpointer data) {
   if(protocol==NEW_PROTOCOL) {
     schedule_high_priority();
   }
-  vfo_update();
+  g_idle_add(ext_vfo_update,NULL);
 }
 
 static void rit_cb(GtkWidget *widget, gpointer data) {
@@ -236,7 +236,7 @@ static void rit_cb(GtkWidget *widget, gpointer data) {
   if(protocol==NEW_PROTOCOL) {
     schedule_high_priority();
   }
-  vfo_update();
+  g_idle_add(ext_vfo_update,NULL);
   if(i<0) {
     rit_minus_timer=g_timeout_add(200,rit_timer_cb,(gpointer)(long)i);
   } else {
@@ -246,7 +246,7 @@ static void rit_cb(GtkWidget *widget, gpointer data) {
 
 static void rit_clear_cb(GtkWidget *widget, gpointer data) {
   vfo[active_receiver->id].rit=0;
-  vfo_update();
+  g_idle_add(ext_vfo_update,NULL);
 }
 
 static void freq_cb(GtkWidget *widget, gpointer data) {
@@ -259,7 +259,7 @@ static void mem_cb(GtkWidget *widget, gpointer data) {
 
 static void vox_cb(GtkWidget *widget, gpointer data) {
   vox_enabled=vox_enabled==1?0:1;
-  vfo_update();
+  g_idle_add(ext_vfo_update,NULL);
 }
 
 static void stop() {
@@ -332,7 +332,7 @@ static void exit_cb(GtkWidget *widget, gpointer data) {
 
 void lock_cb(GtkWidget *widget, gpointer data) {
   locked=locked==1?0:1;
-  vfo_update();
+  g_idle_add(ext_vfo_update,NULL);
 }
 
 void mox_cb(GtkWidget *widget, gpointer data) {
@@ -625,7 +625,7 @@ void sim_function_cb(GtkWidget *widget, gpointer data) {
     function=0;
   }
   update_toolbar_labels();
-  vfo_update();
+  g_idle_add(ext_vfo_update,NULL);
 }
 
 GtkWidget *toolbar_init(int my_width, int my_height, GtkWidget* parent) {
diff --git a/transmitter.c b/transmitter.c
index 18878b8..890be41 100644
--- a/transmitter.c
+++ b/transmitter.c
@@ -87,7 +87,7 @@ extern void cw_audio_write(double sample);
 static gint update_out_of_band(gpointer data) {
   TRANSMITTER *tx=(TRANSMITTER *)data;
   tx->out_of_band=0;
-  vfo_update();
+  g_idle_add(ext_vfo_update,NULL);
   return FALSE;
 }
 
@@ -1102,7 +1102,7 @@ void tx_set_ps(TRANSMITTER *tx,int state) {
     usleep(100000);
     tx->puresignal=0;
   }
-  vfo_update();
+  g_idle_add(ext_vfo_update,NULL);
 }
 
 void tx_set_twotone(TRANSMITTER *tx,int state) {
diff --git a/vfo.c b/vfo.c
index 997b4ec..dba5f8e 100644
--- a/vfo.c
+++ b/vfo.c
@@ -303,7 +303,7 @@ void vfo_band_changed(int b) {
     tx_set_mode(transmitter,vfo[VFO_A].mode);
   }
   calcDriveLevel();
-  vfo_update();
+  g_idle_add(ext_vfo_update,NULL);
 }
 
 void vfo_bandstack_changed(int b) {
@@ -342,7 +342,7 @@ void vfo_bandstack_changed(int b) {
     tx_set_mode(transmitter,vfo[VFO_A].mode);
   }
   calcDriveLevel();
-  vfo_update();
+  g_idle_add(ext_vfo_update,NULL);
 
 }
 
@@ -380,7 +380,7 @@ void vfo_mode_changed(int m) {
     tx_set_mode(transmitter,vfo[VFO_A].mode);
   }
 
-  vfo_update();
+  g_idle_add(ext_vfo_update,NULL);
 }
 
 void vfo_filter_changed(int f) {
@@ -401,7 +401,7 @@ void vfo_filter_changed(int f) {
       break;
   }
 
-  vfo_update();
+  g_idle_add(ext_vfo_update,NULL);
 }
 
 void vfo_a_to_b() {
@@ -421,7 +421,7 @@ void vfo_a_to_b() {
   if(split) {
     tx_set_mode(transmitter,vfo[VFO_B].mode);
   }
-  vfo_update();
+  g_idle_add(ext_vfo_update,NULL);
 }
 
 void vfo_b_to_a() {
@@ -438,7 +438,7 @@ void vfo_b_to_a() {
   if(!split) {
     tx_set_mode(transmitter,vfo[VFO_B].mode);
   }
-  vfo_update();
+  g_idle_add(ext_vfo_update,NULL);
 }
 
 void vfo_a_swap_b() {
@@ -491,7 +491,7 @@ void vfo_a_swap_b() {
   } else {
     tx_set_mode(transmitter,vfo[VFO_A].mode);
   }
-  vfo_update();
+  g_idle_add(ext_vfo_update,NULL);
 }
 
 void vfo_step(int steps) {
@@ -507,7 +507,7 @@ void vfo_step(int steps) {
     BANDSTACK_ENTRY* entry=bandstack_entry_get_current();
     setFrequency(active_receiver->frequency+(steps*step));
 #endif
-    vfo_update();
+    g_idle_add(ext_vfo_update,NULL);
   }
 }
 
@@ -529,7 +529,7 @@ void vfo_move(long long hz) {
         break;
     }
     receiver_frequency_changed(active_receiver);
-    vfo_update();
+    g_idle_add(ext_vfo_update,NULL);
   }
 }
 
@@ -586,7 +586,7 @@ void vfo_move_to(long long hz) {
     }
 #endif
 #endif
-    vfo_update();
+    g_idle_add(ext_vfo_update,NULL);
   }
 }
 
@@ -903,7 +903,7 @@ vfo_step_select_cb (GtkWidget *widget,
                gpointer        data)
 {
   step=steps[(int)data];
-  vfo_update();
+  g_idle_add(ext_vfo_update,NULL);
 }
 */
 
diff --git a/vfo_menu.c b/vfo_menu.c
index 1d77781..4118d72 100644
--- a/vfo_menu.c
+++ b/vfo_menu.c
@@ -155,12 +155,12 @@ static gboolean freqent_select_cb (GtkWidget *widget, gpointer data) {
         }
       }
       setFrequency(f);
-      vfo_update();
+      g_idle_add(ext_vfo_update,NULL);
     
       set = 1;
     }
   }
-  vfo_update();
+  g_idle_add(ext_vfo_update,NULL);
   return FALSE;
 }
 
@@ -176,12 +176,12 @@ static void rit_cb(GtkComboBox *widget,gpointer data) {
       rit_increment=100;
       break;
   }
-  vfo_update();
+  g_idle_add(ext_vfo_update,NULL);
 }
 
 static void vfo_cb(GtkComboBox *widget,gpointer data) {
   step=steps[gtk_combo_box_get_active(widget)];
-  vfo_update();
+  g_idle_add(ext_vfo_update,NULL);
 }
 
 #ifdef FREEDV
@@ -207,7 +207,7 @@ static void set_btn_state() {
 static void lock_cb(GtkWidget *widget, gpointer data) {
   locked=locked==1?0:1;
   set_btn_state();
-  vfo_update();
+  g_idle_add(ext_vfo_update,NULL);
 }
 
 static GtkWidget *last_mode;
diff --git a/vox_menu.c b/vox_menu.c
index ff418a5..40de5df 100644
--- a/vox_menu.c
+++ b/vox_menu.c
@@ -30,6 +30,7 @@
 #include "vfo.h"
 #include "vox_menu.h"
 #include "vox.h"
+#include "ext.h"
 
 static GtkWidget *parent_window=NULL;
 
@@ -115,7 +116,7 @@ static gboolean delete_event(GtkWidget *widget, GdkEvent *event, gpointer user_d
 static gboolean enable_cb (GtkWidget *widget, GdkEventButton *event, gpointer data) {
   vox_enabled=vox_enabled==1?0:1;
   gtk_button_set_label(GTK_BUTTON(widget),vox_enabled==0?"VOX Enable":"VOX Disable");
-  vfo_update();
+  g_idle_add(ext_vfo_update, (gpointer) 0);
   return TRUE;
 }
 
-- 
2.45.2