]> git.rkrishnan.org Git - pihpsdr.git/commitdiff
merge conflicts
authorPA3GSB <admin@pa3gsb.nl>
Wed, 15 Feb 2017 19:35:20 +0000 (20:35 +0100)
committerPA3GSB <admin@pa3gsb.nl>
Wed, 15 Feb 2017 19:35:20 +0000 (20:35 +0100)
15 files changed:
1  2 
Makefile
Makefile.orig
audio.c
discovered.h
general_menu.c
general_menu.c.orig
main.c
main.c.orig
radio.c
radio.c.orig
toolbar.c
toolbar.c.orig
vfo.c
vfo.c.orig
wdsp_init.c

diff --cc Makefile
index 7110791261340f21aa9aa846c228da1396df303d,de84be5e3aa8d4a77c6510ba96ba1a45821fd5df..68b6a6ffb566239a68e67affb730de90579aeb80
+++ b/Makefile
@@@ -105,37 -108,25 +125,25 @@@ beep.o 
  iambic.o
  endif
  
- #required for MRAA GPIO
- #MRAA_INCLUDE=MRAA
- ifeq ($(MRAA_INCLUDE),MRAA)
-   GPIO_OPTIONS=-D GPIO
-   GPIO_LIBS=-lmraa
-   GPIO_SOURCES= \
-   gpio_mraa.c
-   GPIO_HEADERS= \
-   gpio.h
-   GPIO_OBJS= \
-   gpio_mraa.o
- else
-   ifeq ($(UNAME_N),raspberrypi)
+ ifeq ($(GPIO_INCLUDE),GPIO)
    GPIO_OPTIONS=-D GPIO
 -  GPIO_LIBS=-lwiringPi -lpigpio
 +  GPIO_LIBS=-lwiringPi -lpigpio 
-   endif
-   ifeq ($(UNAME_N),odroid)
-   GPIO_LIBS=-lwiringPi
-   endif
-   ifeq ($(SX1509_INCLUDE),sx1509)
-   GPIO_OPTIONS=-D GPIO
-   GPIO_OPTIONS+=-D sx1509
-   GPIO_LIBS+=-lsx1509
-   endif
    GPIO_SOURCES= \
-   gpio.c
+   gpio.c \
+   encoder_menu.c
    GPIO_HEADERS= \
-   gpio.h
+   gpio.h \
+   encoder_menu.h
    GPIO_OBJS= \
-   gpio.o
+   gpio.o \
+   encoder_menu.o
+ endif
+ ifeq ($(I2C_INCLUDE),I2C)
+   I2C_OPTIONS=-D I2C
+   I2C_SOURCES=i2c.c
+   I2C_HEADERS=i2c.h
+   I2C_OBJS=i2c.o
  endif
  
  #uncomment if build for SHORT FRAMES (MIC and Audio)
diff --cc Makefile.orig
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..ff0926db2ed98afcd3e5bff4566af7168dfd9e33
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,402 @@@
++# Get git commit version and date
++#GIT_VERSION := $(shell git --no-pager describe --tags --always --dirty)
++GIT_DATE := $(firstword $(shell git --no-pager show --date=short --format="%ai" --name-only))
++GIT_VERSION := $(shell git describe --abbrev=0 --tags)
++
++# uncomment the line below to include GPIO
++GPIO_INCLUDE=GPIO
++
++# uncomment the line below to include USB Ozy support
++USBOZY_INCLUDE=USBOZY
++
++# uncomment the line below to include support for psk31
++#PSK_INCLUDE=PSK
++
++# uncomment the line to below include support for FreeDV codec2
++#FREEDV_INCLUDE=FREEDV
++
++# uncomment the line to below include support for sx1509 i2c expander
++#SX1509_INCLUDE=sx1509
++
++# uncomment the line to below include support local CW keyer
++#LOCALCW_INCLUDE=LOCALCW
++
++# uncomment the line below to include MCP23017 I2C
++#I2C_INCLUDE=I2C
++
++#uncomment the line below for the platform being compiled on
++UNAME_N=raspberrypi
++#UNAME_N=odroid
++#UNAME_N=up
++#UNAME_N=pine64
++#UNAME_N=x86
++
++CC=gcc
++LINK=gcc
++
++# uncomment the line below for various debug facilities
++#DEBUG_OPTION=-D DEBUG
++
++ifeq ($(USBOZY_INCLUDE),USBOZY)
++USBOZY_OPTIONS=-D USBOZY
++USBOZY_LIBS=-lusb-1.0
++USBOZY_SOURCES= \
++ozyio.c
++USBOZY_HEADERS= \
++ozyio.h
++USBOZY_OBJS= \
++ozyio.o
++endif
++
++# uncomment the line below for LimeSDR (uncomment line below)
++#LIMESDR_INCLUDE=LIMESDR
++
++# uncomment the line below when Radioberry radio cape is plugged in
++RADIOBERRY_INCLUDE=RADIOBERRY
++
++ifeq ($(RADIOBERRY_INCLUDE),RADIOBERRY)
++RADIOBERRY_OPTIONS=-D RADIOBERRY
++RADIOBERRY_SOURCES= \
++radioberry_discovery.c \
++radioberry.c
++RADIOBERRY_HEADERS= \
++radioberry_discovery.h \
++radioberry.h
++RADIOBERRY_OBJS= \
++radioberry_discovery.o \
++radioberry.o
++endif
++
++
++ifeq ($(LIMESDR_INCLUDE),LIMESDR)
++LIMESDR_OPTIONS=-D LIMESDR
++SOAPYSDRLIBS=-lSoapySDR
++LIMESDR_SOURCES= \
++lime_discovery.c \
++lime_protocol.c
++LIMESDR_HEADERS= \
++lime_discovery.h \
++lime_protocol.h
++LIMESDR_OBJS= \
++lime_discovery.o \
++lime_protocol.o
++endif
++
++
++ifeq ($(PSK_INCLUDE),PSK)
++PSK_OPTIONS=-D PSK
++PSKLIBS=-lpsk
++PSK_SOURCES= \
++psk.c \
++psk_waterfall.c
++PSK_HEADERS= \
++psk.h \
++psk_waterfall.h
++PSK_OBJS= \
++psk.o \
++psk_waterfall.o
++endif
++
++
++ifeq ($(FREEDV_INCLUDE),FREEDV)
++FREEDV_OPTIONS=-D FREEDV
++FREEDVLIBS=-lcodec2
++FREEDV_SOURCES= \
++freedv.c \
++freedv_menu.c
++FREEDV_HEADERS= \
++freedv.h \
++freedv_menu.h
++FREEDV_OBJS= \
++freedv.o \
++freedv_menu.o
++endif
++
++ifeq ($(LOCALCW_INCLUDE),LOCALCW)
++LOCALCW_OPTIONS=-D LOCALCW
++LOCALCW_SOURCES= \
++beep.c \
++iambic.c
++LOCALCW_HEADERS= \
++beep.h \
++iambic.h
++LOCALCW_OBJS= \
++beep.o \
++iambic.o
++endif
++
++ifeq ($(GPIO_INCLUDE),GPIO)
++  GPIO_OPTIONS=-D GPIO
++<<<<<<< HEAD
++  GPIO_LIBS=-lwiringPi -lpigpio 
++  endif
++  ifeq ($(UNAME_N),odroid)
++  GPIO_LIBS=-lwiringPi
++  endif
++  ifeq ($(SX1509_INCLUDE),sx1509)
++  GPIO_OPTIONS=-D GPIO
++  GPIO_OPTIONS+=-D sx1509
++  GPIO_LIBS+=-lsx1509
++  endif
++=======
++  GPIO_LIBS=-lwiringPi -lpigpio
++>>>>>>> upstream/master
++  GPIO_SOURCES= \
++  gpio.c \
++  encoder_menu.c
++  GPIO_HEADERS= \
++  gpio.h \
++  encoder_menu.h
++  GPIO_OBJS= \
++  gpio.o \
++  encoder_menu.o
++endif
++
++ifeq ($(I2C_INCLUDE),I2C)
++  I2C_OPTIONS=-D I2C
++  I2C_SOURCES=i2c.c
++  I2C_HEADERS=i2c.h
++  I2C_OBJS=i2c.o
++endif
++
++#uncomment if build for SHORT FRAMES (MIC and Audio)
++SHORT_FRAMES=-D SHORT_FRAMES
++
++GTKINCLUDES=`pkg-config --cflags gtk+-3.0`
++GTKLIBS=`pkg-config --libs gtk+-3.0`
++
++AUDIO_LIBS=-lasound
++#AUDIO_LIBS=-lsoundio
++
++<<<<<<< HEAD
++OPTIONS=-g -D $(UNAME_N) $(GPIO_OPTIONS) $(LIMESDR_OPTIONS) $(RADIOBERRY_OPTIONS) $(FREEDV_OPTIONS) $(LOCALCW_OPTIONS) $(PSK_OPTIONS) $(SHORT_FRAMES) -D GIT_DATE='"$(GIT_DATE)"' -D GIT_VERSION='"$(GIT_VERSION)"' $(DEBUG_OPTION) -O3
++=======
++OPTIONS=-g -Wno-deprecated-declarations -D $(UNAME_N) $(USBOZY_OPTIONS) $(I2C_OPTIONS) $(GPIO_OPTIONS) $(LIMESDR_OPTIONS) $(FREEDV_OPTIONS) $(LOCALCW_OPTIONS) $(PSK_OPTIONS) $(SHORT_FRAMES) -D GIT_DATE='"$(GIT_DATE)"' -D GIT_VERSION='"$(GIT_VERSION)"' $(DEBUG_OPTION) -O3
++>>>>>>> upstream/master
++
++LIBS=-lrt -lm -lwdsp -lpthread $(AUDIO_LIBS) $(USBOZY_LIBS) $(PSKLIBS) $(GTKLIBS) $(GPIO_LIBS) $(SOAPYSDRLIBS) $(FREEDVLIBS)
++INCLUDES=$(GTKINCLUDES)
++
++COMPILE=$(CC) $(OPTIONS) $(INCLUDES)
++
++PROGRAM=pihpsdr
++
++SOURCES= \
++audio.c \
++band.c \
++configure.c \
++frequency.c \
++discovered.c \
++discovery.c \
++filter.c \
++main.c \
++new_menu.c \
++exit_menu.c \
++radio_menu.c \
++rx_menu.c \
++ant_menu.c \
++display_menu.c \
++dsp_menu.c \
++pa_menu.c \
++cw_menu.c \
++oc_menu.c \
++xvtr_menu.c \
++equalizer_menu.c \
++step_menu.c \
++meter_menu.c \
++band_menu.c \
++bandstack_menu.c \
++mode_menu.c \
++filter_menu.c \
++noise_menu.c \
++agc_menu.c \
++vox_menu.c \
++diversity_menu.c \
++freqent_menu.c \
++tx_menu.c \
++vfo_menu.c \
++test_menu.c \
++meter.c \
++mode.c \
++old_discovery.c \
++new_discovery.c \
++old_protocol.c \
++new_protocol.c \
++new_protocol_programmer.c \
++rx_panadapter.c \
++tx_panadapter.c \
++property.c \
++radio.c \
++receiver.c \
++rigctl.c \
++toolbar.c \
++transmitter.c \
++sliders.c \
++version.c \
++vfo.c \
++waterfall.c \
++button_text.c \
++vox.c \
++update.c \
++store.c \
++store_menu.c \
++memory.c
++
++
++HEADERS= \
++audio.h \
++agc.h \
++alex.h \
++band.h \
++configure.h \
++frequency.h \
++bandstack.h \
++channel.h \
++discovered.h \
++discovery.h \
++filter.h \
++new_menu.h \
++rx_menu.h \
++exit_menu.h \
++radio_menu.h \
++ant_menu.h \
++display_menu.h \
++dsp_menu.h \
++pa_menu.h \
++cw_menu.h \
++oc_menu.h \
++xvtr_menu.h \
++equalizer_menu.h \
++step_menu.h \
++meter_menu.h \
++band_menu.h \
++bandstack_menu.h \
++mode_menu.h \
++filter_menu.h \
++noise_menu.h \
++agc_menu.h \
++vox_menu.h \
++diversity_menu.h \
++freqent_menu.h \
++tx_menu.h \
++vfo_menu.h \
++test_menu.h \
++meter.h \
++mode.h \
++old_discovery.h \
++new_discovery.h \
++old_protocol.h \
++new_protocol.h \
++rx_panadapter.h \
++tx_panadapter.h \
++property.h \
++radio.h \
++receiver.h \
++rigctl.h \
++toolbar.h \
++transmitter.h \
++sliders.h \
++version.h \
++vfo.h \
++waterfall.h \
++button_text.h \
++vox.h \
++update.h \
++store.h \
++store_menu.h \
++memory.h
++
++
++OBJS= \
++audio.o \
++band.o \
++configure.o \
++frequency.o \
++discovered.o \
++discovery.o \
++filter.o \
++version.o \
++main.o \
++new_menu.o \
++rx_menu.o \
++exit_menu.o \
++radio_menu.o \
++ant_menu.o \
++display_menu.o \
++dsp_menu.o \
++pa_menu.o \
++cw_menu.o \
++oc_menu.o \
++xvtr_menu.o \
++equalizer_menu.o \
++step_menu.o \
++meter_menu.o \
++band_menu.o \
++bandstack_menu.o \
++mode_menu.o \
++filter_menu.o \
++noise_menu.o \
++agc_menu.o \
++vox_menu.o \
++diversity_menu.o \
++freqent_menu.o \
++tx_menu.o \
++vfo_menu.o \
++test_menu.o \
++meter.o \
++mode.o \
++old_discovery.o \
++new_discovery.o \
++old_protocol.o \
++new_protocol.o \
++new_protocol_programmer.o \
++rx_panadapter.o \
++tx_panadapter.o \
++property.o \
++radio.o \
++receiver.o \
++rigctl.o \
++toolbar.o \
++transmitter.o \
++sliders.o \
++vfo.o \
++waterfall.o \
++button_text.o \
++vox.o \
++update.o \
++store.o \
++store_menu.o \
++memory.o
++
++<<<<<<< HEAD
++all: prebuild $(PROGRAM) $(HEADERS) $(LIMESDR_HEADERS) $(RADIOBERRY_HEADERS) $(FREEDV_HEADERS) $(LOCALCW_HEADERS) $(GPIO_HEADERS) $(PSK_HEADERS) $(SOURCES) $(LIMESDR_SOURCES) $(RADIOBERRY_SOURCES) $(FREEDV_SOURCES) $(GPIO_SOURCES) $(PSK_SOURCES)
++=======
++all: prebuild $(PROGRAM) $(HEADERS) $(USBOZY_HEADERS) $(LIMESDR_HEADERS) $(FREEDV_HEADERS) $(LOCALCW_HEADERS) $(I2C_HEADERS) $(GPIO_HEADERS) $(PSK_HEADERS) $(SOURCES) $(USBOZY_SOURCES) $(LIMESDR_SOURCES) $(FREEDV_SOURCES) $(I2C_SOURCES) $(GPIO_SOURCES) $(PSK_SOURCES)
++>>>>>>> upstream/master
++
++prebuild:
++      rm -f version.o
++
++<<<<<<< HEAD
++$(PROGRAM): $(OBJS) $(LIMESDR_OBJS) $(RADIOBERRY_OBJS) $(FREEDV_OBJS) $(LOCALCW_OBJS) $(GPIO_OBJS) $(PSK_OBJS)
++      $(LINK) -o $(PROGRAM) $(OBJS) $(GPIO_OBJS) $(LIMESDR_OBJS) $(RADIOBERRY_OBJS) $(FREEDV_OBJS) $(LOCALCW_OBJS) $(PSK_OBJS) $(LIBS)
++=======
++$(PROGRAM): $(OBJS) $(USBOZY_OBJS) $(LIMESDR_OBJS) $(FREEDV_OBJS) $(LOCALCW_OBJS) $(I2C_OBJS) $(GPIO_OBJS) $(PSK_OBJS)
++      $(LINK) -o $(PROGRAM) $(OBJS) $(USBOZY_OBJS) $(I2C_OBJS) $(GPIO_OBJS) $(LIMESDR_OBJS) $(FREEDV_OBJS) $(LOCALCW_OBJS) $(PSK_OBJS) $(LIBS)
++>>>>>>> upstream/master
++
++.c.o:
++      $(COMPILE) -c -o $@ $<
++
++
++clean:
++      -rm -f *.o
++      -rm -f $(PROGRAM)
++
++install:
++      cp pihpsdr ../pihpsdr
++      cp pihpsdr ./release/pihpsdr
++      cd release; echo $(GIT_VERSION) > pihpsdr/latest
++      cd release; tar cvf pihpsdr_$(GIT_VERSION).tar pihpsdr
++      cd release; tar cvf pihpsdr.tar pihpsdr
++
diff --cc audio.c
index 0f2c5769bcfb7635ee76ab0d3f3402f7966e249b,39f135947169e4597943528b45216b7f327843e2..43ffc81ec8b965605ba5f676a3ce418ce6f2ceac
+++ b/audio.c
  
  #include <alsa/asoundlib.h>
  
- #include "audio.h"
  #include "new_protocol.h"
  #include "old_protocol.h"
 +#ifdef RADIOBERRY
 +#include "radioberry.h"
 +#endif
  #include "radio.h"
+ #include "receiver.h"
+ #include "audio.h"
  
  int audio = 0;
  int audio_buffer_size = 256; // samples (both left and right)
diff --cc discovered.h
Simple merge
diff --cc general_menu.c
index 5b55a174040b66fb62621210e77b79e3d473b813,da5bb154f7e28e61c14bd3d1c0be69e4ea7f1eac..185bc896467ee054a8654fb7fb5e64c0f415bde7
@@@ -212,23 -175,7 +175,12 @@@ void general_menu(GtkWidget *parent) 
    gtk_grid_attach(GTK_GRID(grid),vfo_divisor,4,2,1,1);
    g_signal_connect(vfo_divisor,"value_changed",G_CALLBACK(vfo_divisor_value_changed_cb),NULL);
  
 -  if(protocol==ORIGINAL_PROTOCOL || protocol==NEW_PROTOCOL) {
 +  if(protocol==ORIGINAL_PROTOCOL || protocol==NEW_PROTOCOL
 +#ifdef RADIOBERRY
 +  || protocol==RADIOBERRY_PROTOCOL) {
 +#else
 +      ){
 +#endif  
-     GtkWidget *rx_dither_b=gtk_check_button_new_with_label("Dither");
-     //gtk_widget_override_font(rx_dither_b, pango_font_description_from_string("Arial 18"));
-     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (rx_dither_b), rx_dither);
-     gtk_grid_attach(GTK_GRID(grid),rx_dither_b,1,4,1,1);
-     g_signal_connect(rx_dither_b,"toggled",G_CALLBACK(rx_dither_cb),NULL);
-     GtkWidget *rx_random_b=gtk_check_button_new_with_label("Random");
-     //gtk_widget_override_font(rx_random_b, pango_font_description_from_string("Arial 18"));
-     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (rx_random_b), rx_random);
-     gtk_grid_attach(GTK_GRID(grid),rx_random_b,1,5,1,1);
-     g_signal_connect(rx_random_b,"toggled",G_CALLBACK(rx_random_cb),NULL);
  
      if((protocol==NEW_PROTOCOL && device==NEW_DEVICE_ORION) ||
         (protocol==NEW_PROTOCOL && device==NEW_DEVICE_ORION2) ||
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..6bbc78e2c7287d72bd172c9431c139e7564c8a98
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,350 @@@
++/* Copyright (C)
++* 2015 - 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 <semaphore.h>
++#include <stdio.h>
++#include <string.h>
++
++#include "new_menu.h"
++#include "general_menu.h"
++#include "band.h"
++#include "filter.h"
++#include "radio.h"
++#include "receiver.h"
++
++static GtkWidget *parent_window=NULL;
++
++static GtkWidget *menu_b=NULL;
++
++static GtkWidget *dialog=NULL;
++
++static gboolean close_cb (GtkWidget *widget, GdkEventButton *event, gpointer data) {
++  if(dialog!=NULL) {
++    gtk_widget_destroy(dialog);
++    dialog=NULL;
++    sub_menu=NULL;
++  }
++  return TRUE;
++}
++
++static void vfo_divisor_value_changed_cb(GtkWidget *widget, gpointer data) {
++  vfo_encoder_divisor=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(widget));
++}
++
++/*
++static void toolbar_dialog_buttons_cb(GtkWidget *widget, gpointer data) {
++  toolbar_dialog_buttons=toolbar_dialog_buttons==1?0:1;
++  update_toolbar_labels();
++}
++*/
++
++static void ptt_cb(GtkWidget *widget, gpointer data) {
++  mic_ptt_enabled=mic_ptt_enabled==1?0:1;
++}
++
++static void ptt_ring_cb(GtkWidget *widget, gpointer data) {
++  mic_ptt_tip_bias_ring=0;
++}
++
++static void ptt_tip_cb(GtkWidget *widget, gpointer data) {
++  mic_ptt_tip_bias_ring=1;
++}
++
++static void bias_cb(GtkWidget *widget, gpointer data) {
++  mic_bias_enabled=mic_bias_enabled==1?0:1;
++}
++
++static void apollo_cb(GtkWidget *widget, gpointer data);
++
++static void alex_cb(GtkWidget *widget, gpointer data) {
++  if(filter_board==ALEX) {
++    filter_board=NONE;
++  } else if(filter_board==NONE) {
++    filter_board=ALEX;
++  } else if(filter_board==APOLLO) {
++    GtkWidget *w=(GtkWidget *)data;
++    gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (w), FALSE);
++    filter_board=ALEX;
++  }
++
++  if(protocol==NEW_PROTOCOL) {
++    filter_board_changed();
++  }
++
++  if(filter_board==ALEX) {
++    BAND *band=band_get_current_band();
++    BANDSTACK_ENTRY* entry=bandstack_entry_get_current();
++    setFrequency(entry->frequency);
++    //setMode(entry->mode);
++    set_mode(active_receiver,entry->mode);
++    FILTER* band_filters=filters[entry->mode];
++    FILTER* band_filter=&band_filters[entry->filter];
++    //setFilter(band_filter->low,band_filter->high);
++    set_filter(active_receiver,band_filter->low,band_filter->high);
++    if(active_receiver->id==0) {
++      set_alex_rx_antenna(band->alexRxAntenna);
++      set_alex_tx_antenna(band->alexTxAntenna);
++      set_alex_attenuation(band->alexAttenuation);
++    }
++  }
++}
++
++static void apollo_cb(GtkWidget *widget, gpointer data) {
++  if(filter_board==APOLLO) {
++    filter_board=NONE;
++  } else if(filter_board==NONE) {
++    filter_board=APOLLO;
++  } else if(filter_board==ALEX) {
++    GtkWidget *w=(GtkWidget *)data;
++    gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (w), FALSE);
++    filter_board=APOLLO;
++  }
++  if(protocol==NEW_PROTOCOL) {
++    filter_board_changed();
++  }
++
++  if(filter_board==APOLLO) {
++    BAND *band=band_get_current_band();
++    BANDSTACK_ENTRY* entry=bandstack_entry_get_current();
++    setFrequency(entry->frequency);
++    //setMode(entry->mode);
++    set_mode(active_receiver,entry->mode);
++    FILTER* band_filters=filters[entry->mode];
++    FILTER* band_filter=&band_filters[entry->filter];
++    //setFilter(band_filter->low,band_filter->high);
++    set_filter(active_receiver,band_filter->low,band_filter->high);
++  }
++}
++
++static void sample_rate_cb(GtkWidget *widget, gpointer data) {
++<<<<<<< HEAD
++ switch(protocol) {
++    case ORIGINAL_PROTOCOL:
++      old_protocol_new_sample_rate((int)data);
++      break;
++    case NEW_PROTOCOL:
++      new_protocol_new_sample_rate((int)data);
++      break;
++#ifdef RADIOBERRY
++      case RADIOBERRY_PROTOCOL:
++              radioberry_new_sample_rate((int)data);
++              break;
++#endif
++  }  
++  
++=======
++  radio_change_sample_rate((int)data);
++>>>>>>> upstream/master
++}
++
++static void rit_cb(GtkWidget *widget,gpointer data) {
++  rit_increment=(int)data;
++}
++
++void general_menu(GtkWidget *parent) {
++  parent_window=parent;
++
++  dialog=gtk_dialog_new();
++  gtk_window_set_transient_for(GTK_WINDOW(dialog),GTK_WINDOW(parent_window));
++  gtk_window_set_decorated(GTK_WINDOW(dialog),FALSE);
++
++  GdkRGBA color;
++  color.red = 1.0;
++  color.green = 1.0;
++  color.blue = 1.0;
++  color.alpha = 1.0;
++  gtk_widget_override_background_color(dialog,GTK_STATE_FLAG_NORMAL,&color);
++
++  GtkWidget *content=gtk_dialog_get_content_area(GTK_DIALOG(dialog));
++
++  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 General");
++  g_signal_connect (close_b, "button_press_event", G_CALLBACK(close_cb), NULL);
++  gtk_grid_attach(GTK_GRID(grid),close_b,0,0,1,1);
++
++  GtkWidget *vfo_divisor_label=gtk_label_new("VFO Encoder Divisor: ");
++  gtk_grid_attach(GTK_GRID(grid),vfo_divisor_label,4,1,1,1);
++
++  GtkWidget *vfo_divisor=gtk_spin_button_new_with_range(1.0,60.0,1.0);
++  gtk_spin_button_set_value(GTK_SPIN_BUTTON(vfo_divisor),(double)vfo_encoder_divisor);
++  gtk_grid_attach(GTK_GRID(grid),vfo_divisor,4,2,1,1);
++  g_signal_connect(vfo_divisor,"value_changed",G_CALLBACK(vfo_divisor_value_changed_cb),NULL);
++
++<<<<<<< HEAD
++  if(protocol==ORIGINAL_PROTOCOL || protocol==NEW_PROTOCOL
++#ifdef RADIOBERRY
++  || protocol==RADIOBERRY_PROTOCOL) {
++#else
++      ){
++#endif  
++    GtkWidget *rx_dither_b=gtk_check_button_new_with_label("Dither");
++    //gtk_widget_override_font(rx_dither_b, pango_font_description_from_string("Arial 18"));
++    gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (rx_dither_b), rx_dither);
++    gtk_grid_attach(GTK_GRID(grid),rx_dither_b,1,4,1,1);
++    g_signal_connect(rx_dither_b,"toggled",G_CALLBACK(rx_dither_cb),NULL);
++
++    GtkWidget *rx_random_b=gtk_check_button_new_with_label("Random");
++    //gtk_widget_override_font(rx_random_b, pango_font_description_from_string("Arial 18"));
++    gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (rx_random_b), rx_random);
++    gtk_grid_attach(GTK_GRID(grid),rx_random_b,1,5,1,1);
++    g_signal_connect(rx_random_b,"toggled",G_CALLBACK(rx_random_cb),NULL);
++=======
++  if(protocol==ORIGINAL_PROTOCOL || protocol==NEW_PROTOCOL) {
++>>>>>>> upstream/master
++
++    if((protocol==NEW_PROTOCOL && device==NEW_DEVICE_ORION) ||
++       (protocol==NEW_PROTOCOL && device==NEW_DEVICE_ORION2) ||
++       (protocol==ORIGINAL_PROTOCOL && device==DEVICE_ORION) ||
++       (protocol==ORIGINAL_PROTOCOL && device==DEVICE_ORION2)) {
++
++      GtkWidget *ptt_ring_b=gtk_radio_button_new_with_label(NULL,"PTT On Ring, Mic and Bias on Tip");
++      gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (ptt_ring_b), mic_ptt_tip_bias_ring==0);
++      gtk_grid_attach(GTK_GRID(grid),ptt_ring_b,3,1,1,1);
++      g_signal_connect(ptt_ring_b,"pressed",G_CALLBACK(ptt_ring_cb),NULL);
++
++      GtkWidget *ptt_tip_b=gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(ptt_ring_b),"PTT On Tip, Mic and Bias on Ring");
++      gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (ptt_tip_b), mic_ptt_tip_bias_ring==1);
++      gtk_grid_attach(GTK_GRID(grid),ptt_tip_b,3,2,1,1);
++      g_signal_connect(ptt_tip_b,"pressed",G_CALLBACK(ptt_tip_cb),NULL);
++
++      GtkWidget *ptt_b=gtk_check_button_new_with_label("PTT Enabled");
++      gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (ptt_b), mic_ptt_enabled);
++      gtk_grid_attach(GTK_GRID(grid),ptt_b,3,3,1,1);
++      g_signal_connect(ptt_b,"toggled",G_CALLBACK(ptt_cb),NULL);
++
++      GtkWidget *bias_b=gtk_check_button_new_with_label("BIAS Enabled");
++      gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (bias_b), mic_bias_enabled);
++      gtk_grid_attach(GTK_GRID(grid),bias_b,3,4,1,1);
++      g_signal_connect(bias_b,"toggled",G_CALLBACK(bias_cb),NULL);
++    }
++
++#ifdef RADIOBERRY
++  if (protocol==ORIGINAL_PROTOCOL || protocol==NEW_PROTOCOL) {
++#endif  
++    GtkWidget *alex_b=gtk_check_button_new_with_label("ALEX");
++    gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (alex_b), filter_board==ALEX);
++    gtk_grid_attach(GTK_GRID(grid),alex_b,1,1,1,1);
++
++    GtkWidget *apollo_b=gtk_check_button_new_with_label("APOLLO");
++    gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (apollo_b), filter_board==APOLLO);
++    gtk_grid_attach(GTK_GRID(grid),apollo_b,1,2,1,1);
++
++    g_signal_connect(alex_b,"toggled",G_CALLBACK(alex_cb),apollo_b);
++    g_signal_connect(apollo_b,"toggled",G_CALLBACK(apollo_cb),alex_b);
++#ifdef RADIOBERRY
++      }
++#endif 
++  }
++
++  GtkWidget *sample_rate_label=gtk_label_new("Sample Rate:");
++  gtk_grid_attach(GTK_GRID(grid),sample_rate_label,0,1,1,1);
++
++  if(protocol==ORIGINAL_PROTOCOL || protocol==NEW_PROTOCOL
++ #ifdef RADIOBERRY
++  || protocol==RADIOBERRY_PROTOCOL) {
++#else
++      ){
++#endif  
++    GtkWidget *sample_rate_48=gtk_radio_button_new_with_label(NULL,"48000");
++    gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (sample_rate_48), sample_rate==48000);
++    gtk_grid_attach(GTK_GRID(grid),sample_rate_48,0,2,1,1);
++    g_signal_connect(sample_rate_48,"pressed",G_CALLBACK(sample_rate_cb),(gpointer *)48000);
++
++    GtkWidget *sample_rate_96=gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(sample_rate_48),"96000");
++    gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (sample_rate_96), sample_rate==96000);
++    gtk_grid_attach(GTK_GRID(grid),sample_rate_96,0,3,1,1);
++    g_signal_connect(sample_rate_96,"pressed",G_CALLBACK(sample_rate_cb),(gpointer *)96000);
++
++    GtkWidget *sample_rate_192=gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(sample_rate_96),"192000");
++    gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (sample_rate_192), sample_rate==192000);
++    gtk_grid_attach(GTK_GRID(grid),sample_rate_192,0,4,1,1);
++    g_signal_connect(sample_rate_192,"pressed",G_CALLBACK(sample_rate_cb),(gpointer *)192000);
++
++    GtkWidget *sample_rate_384=gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(sample_rate_192),"384000");
++    gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (sample_rate_384), sample_rate==384000);
++    gtk_grid_attach(GTK_GRID(grid),sample_rate_384,0,5,1,1);
++    g_signal_connect(sample_rate_384,"pressed",G_CALLBACK(sample_rate_cb),(gpointer *)384000);
++
++    if(protocol==NEW_PROTOCOL) {
++      GtkWidget *sample_rate_768=gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(sample_rate_384),"768000");
++      gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (sample_rate_768), sample_rate==768000);
++      gtk_grid_attach(GTK_GRID(grid),sample_rate_768,0,6,1,1);
++      g_signal_connect(sample_rate_768,"pressed",G_CALLBACK(sample_rate_cb),(gpointer *)768000);
++
++      GtkWidget *sample_rate_1536=gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(sample_rate_768),"1536000");
++      gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (sample_rate_1536), sample_rate==1536000);
++        gtk_grid_attach(GTK_GRID(grid),sample_rate_1536,0,7,1,1);
++      g_signal_connect(sample_rate_1536,"pressed",G_CALLBACK(sample_rate_cb),(gpointer *)1536000);
++
++#ifdef GPIO
++      gtk_widget_set_sensitive(sample_rate_768,FALSE);
++      gtk_widget_set_sensitive(sample_rate_1536,FALSE);
++#endif
++    }
++
++  }
++
++#ifdef LIMESDR
++  if(protocol==LIMESDR_PROTOCOL) {
++    GtkWidget *sample_rate_1M=gtk_radio_button_new_with_label(NULL,"1000000");
++    gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (sample_rate_1M), sample_rate==1000000);
++    gtk_grid_attach(GTK_GRID(grid),sample_rate_1M,0,2,1,1);
++    g_signal_connect(sample_rate_1M,"pressed",G_CALLBACK(sample_rate_cb),(gpointer *)1000000);
++
++    GtkWidget *sample_rate_2M=gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(sample_rate_1M),"2000000");
++    gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (sample_rate_2M), sample_rate==2000000);
++    gtk_grid_attach(GTK_GRID(grid),sample_rate_2M,0,3,1,1);
++    g_signal_connect(sample_rate_2M,"pressed",G_CALLBACK(sample_rate_cb),(gpointer *)2000000);
++
++  }
++#endif
++
++
++  GtkWidget *rit_label=gtk_label_new("RIT step: ");
++  gtk_grid_attach(GTK_GRID(grid),rit_label,5,1,1,1);
++
++  GtkWidget *rit_1=gtk_radio_button_new_with_label(NULL,"1 Hz");
++  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (rit_1), rit_increment==1);
++  gtk_grid_attach(GTK_GRID(grid),rit_1,5,2,1,1);
++  g_signal_connect(rit_1,"pressed",G_CALLBACK(rit_cb),(gpointer *)1);
++
++  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,5,3,1,1);
++  g_signal_connect(rit_10,"pressed",G_CALLBACK(rit_cb),(gpointer *)10);
++
++  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,5,4,1,1);
++  g_signal_connect(rit_100,"pressed",G_CALLBACK(rit_cb),(gpointer *)100);
++
++  gtk_container_add(GTK_CONTAINER(content),grid);
++
++  sub_menu=dialog;
++
++  gtk_widget_show_all(dialog);
++
++}
++
diff --cc main.c
index a33536d1b40ced18329bf1b666cc23784b650734,d340d05ec76bf9f66ea0a43060707c0b95629530..8398ffa4261e8e430c4d3bd94197be8e725e4c25
--- 1/main.c
--- 2/main.c
+++ b/main.c
  #include "discovered.h"
  #include "configure.h"
  #include "gpio.h"
- #include "old_discovery.h"
- #include "new_discovery.h"
- #ifdef LIMESDR
- #include "lime_discovery.h"
- #endif
- #ifdef RADIOBERRY
- #include "radioberry_discovery.h"
- #endif
- #include "old_protocol.h"
- #include "new_protocol.h"
- #ifdef LIMESDR
- #include "lime_protocol.h"
- #endif
 +#ifdef RADIOBERRY
 +#include "radioberry.h"
 +#endif
  #include "wdsp.h"
- #include "vfo.h"
- //#include "menu.h"
  #include "new_menu.h"
- #include "rit.h"
- #include "meter.h"
- #include "panadapter.h"
- #include "splash.h"
- #include "waterfall.h"
- #include "toolbar.h"
- #include "sliders.h"
  #include "radio.h"
- #include "rigctl.h"
- #include "wdsp_init.h"
  #include "version.h"
- #include "mode.h"
- #ifdef PSK
- #include "psk.h"
- #include "psk_waterfall.h"
- #endif
- #define DISPLAY_INCREMENT (display_height/32)
- #define VFO_HEIGHT (DISPLAY_INCREMENT*4)
- //#define VFO_HEIGHT (DISPLAY_INCREMENT*8)
- #define VFO_WIDTH ((display_width/32)*21)
- #define MENU_HEIGHT VFO_HEIGHT
- //#define MENU_HEIGHT (DISPLAY_INCREMENT*4)
- #define MENU_WIDTH ((display_width/32)*3)
- //#define RIT_WIDTH ((MENU_WIDTH/3)*2)
- #define METER_HEIGHT VFO_HEIGHT
- //#define METER_HEIGHT (DISPLAY_INCREMENT*4)
- #define METER_WIDTH ((display_width/32)*8)
- #define PANADAPTER_HEIGHT (DISPLAY_INCREMENT*8)
- #define SLIDERS_HEIGHT (DISPLAY_INCREMENT*6)
- #define TOOLBAR_HEIGHT (DISPLAY_INCREMENT*2)
- #define WATERFALL_HEIGHT (display_height-(VFO_HEIGHT+PANADAPTER_HEIGHT+SLIDERS_HEIGHT+TOOLBAR_HEIGHT))
- #ifdef PSK
- #define PSK_WATERFALL_HEIGHT (DISPLAY_INCREMENT*6)
- #define PSK_HEIGHT (display_height-(VFO_HEIGHT+PSK_WATERFALL_HEIGHT+SLIDERS_HEIGHT+TOOLBAR_HEIGHT))
+ #include "button_text.h"
+ #ifdef I2C
+ #include "i2c.h"
  #endif
+ #include "discovery.h"
  
  struct utsname unameData;
  
diff --cc main.c.orig
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..9d6c98878233df4fce510eea01f2e59b166beb01
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,885 @@@
++/* Copyright (C)
++* 2015 - 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 <gdk/gdk.h>
++#include <math.h>
++#include <unistd.h>
++#include <stdlib.h>
++#include <string.h>
++#include <semaphore.h>
++#include <sys/socket.h>
++#include <netinet/in.h>
++#include <arpa/inet.h>
++
++#include "audio.h"
++#include "band.h"
++#include "bandstack.h"
++#include "main.h"
++#include "channel.h"
++#include "discovered.h"
++#include "configure.h"
++#include "gpio.h"
++<<<<<<< HEAD
++#include "old_discovery.h"
++#include "new_discovery.h"
++#ifdef LIMESDR
++#include "lime_discovery.h"
++#endif
++#ifdef RADIOBERRY
++#include "radioberry_discovery.h"
++#endif
++#include "old_protocol.h"
++#include "new_protocol.h"
++#ifdef LIMESDR
++#include "lime_protocol.h"
++#endif
++#ifdef RADIOBERRY
++#include "radioberry.h"
++#endif
++=======
++>>>>>>> upstream/master
++#include "wdsp.h"
++#include "new_menu.h"
++#include "radio.h"
++#include "version.h"
++#include "button_text.h"
++#ifdef I2C
++#include "i2c.h"
++#endif
++#include "discovery.h"
++
++struct utsname unameData;
++
++gint display_width;
++gint display_height;
++gint full_screen=1;
++
++static GtkWidget *discovery_dialog;
++
++static sem_t wisdom_sem;
++
++static GdkCursor *cursor_arrow;
++static GdkCursor *cursor_watch;
++
++static GtkWidget *splash;
++
++GtkWidget *top_window;
++GtkWidget *grid;
++
++static DISCOVERED* d;
++
++static GtkWidget *status;
++
++void status_text(char *text) {
++  //fprintf(stderr,"splash_status: %s\n",text);
++  gtk_label_set_text(GTK_LABEL(status),text);
++  usleep(10000);
++  while (gtk_events_pending ())
++    gtk_main_iteration ();
++}
++
++static gint save_cb(gpointer data) {
++    radioSaveState();
++    return TRUE;
++}
++
++static pthread_t wisdom_thread_id;
++
++static void* wisdom_thread(void *arg) {
++  status_text("Creating FFTW Wisdom file ...");
++  WDSPwisdom ((char *)arg);
++  sem_post(&wisdom_sem);
++}
++
++gboolean main_delete (GtkWidget *widget) {
++#ifdef GPIO
++  gpio_close();
++#endif
++  switch(protocol) {
++    case ORIGINAL_PROTOCOL:
++      old_protocol_stop();
++      break;
++    case NEW_PROTOCOL:
++      new_protocol_stop();
++      break;
++#ifdef LIMESDR
++    case LIMESDR_PROTOCOL:
++      lime_protocol_stop();
++      break;
++#endif
++#ifdef RADIOBERRY
++      case RADIOBERRY_PROTOCOL:
++              radioberry_protocol_stop();
++              break;
++#endif
++  }
++  radioSaveState();
++  _exit(0);
++}
++
++<<<<<<< HEAD
++static gboolean start_cb (GtkWidget *widget, GdkEventButton *event, gpointer data) {
++fprintf(stderr,"start_cb: %p\n",data);
++  radio=(DISCOVERED *)data;
++  gtk_widget_destroy(discovery_dialog);
++  start_radio();
++  return TRUE;
++}
++
++#ifdef GPIO
++static gboolean gpio_cb (GtkWidget *widget, GdkEventButton *event, gpointer data) {
++  configure_gpio(discovery_dialog);
++  return TRUE;
++}
++#endif
++
++static gboolean discover_cb (GtkWidget *widget, GdkEventButton *event, gpointer data) {
++  gtk_widget_destroy(discovery_dialog);
++  discover_devices();
++  return TRUE;
++}
++
++static gboolean exit_cb (GtkWidget *widget, GdkEventButton *event, gpointer data) {
++  gtk_widget_destroy(discovery_dialog);
++  _exit(0);
++  return TRUE;
++}
++
++static void discover_devices() {
++
++      gdk_window_set_cursor(splash_window,cursor_watch);
++      selected_device=0;
++      devices=0;
++      splash_status("Old Protocol ... Discovering Devices");
++      old_discovery();
++      splash_status("New Protocol ... Discovering Devices");
++      new_discovery();
++#ifdef LIMESDR
++      splash_status("LimeSDR ... Discovering Devices");
++      lime_discovery();
++#endif
++#ifdef RADIOBERRY
++      splash_status("Radioberry SDR ... Discovering Device");
++      radioberry_discovery();
++#endif
++      splash_status("Discovery");
++      if(devices==0) {
++          gdk_window_set_cursor(splash_window,cursor_arrow);
++          fprintf(stderr,"No devices found!\n");
++          GtkDialogFlags flags = GTK_DIALOG_DESTROY_WITH_PARENT;
++/*
++          discovery_dialog = gtk_message_dialog_new (GTK_WINDOW(splash_screen),
++                                 flags,
++                                 GTK_MESSAGE_ERROR,
++                                 GTK_BUTTONS_OK_CANCEL,
++                                 "No devices found! Retry Discovery?");
++*/
++          discovery_dialog = gtk_dialog_new();
++          gtk_window_set_transient_for(GTK_WINDOW(discovery_dialog),GTK_WINDOW(splash_screen));
++          gtk_window_set_decorated(GTK_WINDOW(discovery_dialog),FALSE);
++
++          gtk_widget_override_font(discovery_dialog, pango_font_description_from_string("FreeMono 16"));
++
++          GdkRGBA color;
++          color.red = 1.0;
++          color.green = 1.0;
++          color.blue = 1.0;
++          color.alpha = 1.0;
++          gtk_widget_override_background_color(discovery_dialog,GTK_STATE_FLAG_NORMAL,&color);
++
++          GtkWidget *content;
++
++          content=gtk_dialog_get_content_area(GTK_DIALOG(discovery_dialog));
++
++          GtkWidget *grid=gtk_grid_new();
++          gtk_grid_set_row_homogeneous(GTK_GRID(grid),TRUE);
++          gtk_grid_set_column_homogeneous(GTK_GRID(grid),TRUE);
++          gtk_grid_set_row_spacing (GTK_GRID(grid),10);
++
++          GtkWidget *label=gtk_label_new("No devices found!");
++          gtk_grid_attach(GTK_GRID(grid),label,0,0,2,1);
++
++          GtkWidget *exit_b=gtk_button_new_with_label("Exit");
++          g_signal_connect (exit_b, "button-press-event", G_CALLBACK(exit_cb), NULL);
++          gtk_grid_attach(GTK_GRID(grid),exit_b,0,1,1,1);
++
++          GtkWidget *discover_b=gtk_button_new_with_label("Retry Discovery");
++          g_signal_connect (discover_b, "button-press-event", G_CALLBACK(discover_cb), NULL);
++          gtk_grid_attach(GTK_GRID(grid),discover_b,1,1,1,1);
++
++          gtk_container_add (GTK_CONTAINER (content), grid);
++          gtk_widget_show_all(discovery_dialog);
++      } else {
++          //fprintf(stderr,"%s: found %d devices.\n", (char *)arg, devices);
++          gdk_window_set_cursor(splash_window,cursor_arrow);
++/*
++          GtkDialogFlags flags=GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT;
++          discovery_dialog = gtk_dialog_new_with_buttons ("Discovered",
++                                      GTK_WINDOW(splash_window),
++                                      flags,
++#ifdef GPIO
++                                      "Configure GPIO",
++                                      GTK_RESPONSE_YES,
++#endif
++                                      "Discover",
++                                      GTK_RESPONSE_REJECT,
++                                      "Exit",
++                                      GTK_RESPONSE_CLOSE,
++                                      NULL);
++*/
++
++          discovery_dialog = gtk_dialog_new();
++          gtk_window_set_transient_for(GTK_WINDOW(discovery_dialog),GTK_WINDOW(splash_screen));
++          gtk_window_set_decorated(GTK_WINDOW(discovery_dialog),FALSE);
++
++          gtk_widget_override_font(discovery_dialog, pango_font_description_from_string("FreeMono 16"));
++
++          GdkRGBA color;
++          color.red = 1.0;
++          color.green = 1.0;
++          color.blue = 1.0;
++          color.alpha = 1.0;
++          gtk_widget_override_background_color(discovery_dialog,GTK_STATE_FLAG_NORMAL,&color);
++
++          GtkWidget *content;
++
++          content=gtk_dialog_get_content_area(GTK_DIALOG(discovery_dialog));
++
++          GtkWidget *grid=gtk_grid_new();
++          gtk_grid_set_row_homogeneous(GTK_GRID(grid),TRUE);
++          gtk_grid_set_column_homogeneous(GTK_GRID(grid),TRUE);
++          gtk_grid_set_row_spacing (GTK_GRID(grid),10);
++
++          int i;
++          char version[16];
++          char text[128];
++          for(i=0;i<devices;i++) {
++              d=&discovered[i];
++fprintf(stderr,"%p protocol=%d name=%s\n",d,d->protocol,d->name);
++              if(d->protocol==ORIGINAL_PROTOCOL) {
++                  sprintf(version,"%d.%d",
++                        d->software_version/10,
++                        d->software_version%10);
++              } else {
++                  sprintf(version,"%d.%d.%d",
++                        d->software_version/100,
++                        (d->software_version%100)/10,
++                        d->software_version%10);
++              }
++              switch(d->protocol) {
++                case ORIGINAL_PROTOCOL:
++                case NEW_PROTOCOL:
++                  sprintf(text,"%s (%s %s) %s (%02X:%02X:%02X:%02X:%02X:%02X) on %s\n",
++                        d->name,
++                        d->protocol==ORIGINAL_PROTOCOL?"old":"new",
++                        version,
++                        inet_ntoa(d->info.network.address.sin_addr),
++                        d->info.network.mac_address[0],
++                        d->info.network.mac_address[1],
++                        d->info.network.mac_address[2],
++                        d->info.network.mac_address[3],
++                        d->info.network.mac_address[4],
++                        d->info.network.mac_address[5],
++                        d->info.network.interface_name);
++                  break;
++#ifdef LIMESDR
++                case LIMESDR_PROTOCOL:
++/*
++                  sprintf(text,"%s (%s %s)\n",
++                        d->name,
++                        "lime",
++                        version);
++*/
++                  sprintf(text,"%s\n",
++                        d->name);
++                  break;
++#endif
++#ifdef RADIOBERRY
++                              case RADIOBERRY_PROTOCOL:
++                                      sprintf(text,"%s\n",d->name);
++                              break;
++#endif
++              }
++
++              GtkWidget *label=gtk_label_new(text);
++              gtk_widget_override_font(label, pango_font_description_from_string("FreeMono 12"));
++              gtk_widget_show(label);
++              gtk_grid_attach(GTK_GRID(grid),label,0,i,3,1);
++
++              GtkWidget *start_button=gtk_button_new_with_label("Start");
++              gtk_widget_override_font(start_button, pango_font_description_from_string("FreeMono 18"));
++              gtk_widget_show(start_button);
++              gtk_grid_attach(GTK_GRID(grid),start_button,3,i,1,1);
++              g_signal_connect(start_button,"button_press_event",G_CALLBACK(start_cb),(gpointer)d);
++
++              // if not available then cannot start it
++              if(d->status!=STATE_AVAILABLE) {
++                gtk_button_set_label(GTK_BUTTON(start_button),"In Use");
++                gtk_widget_set_sensitive(start_button, FALSE);
++              }
++
++              // if not on the same subnet then cannot start it
++              if((d->info.network.interface_address.sin_addr.s_addr&d->info.network.interface_netmask.sin_addr.s_addr) != (d->info.network.address.sin_addr.s_addr&d->info.network.interface_netmask.sin_addr.s_addr)) {
++                gtk_button_set_label(GTK_BUTTON(start_button),"Subnet!");
++                gtk_widget_set_sensitive(start_button, FALSE);
++              }
++
++          }
++
++#ifdef GPIO
++          GtkWidget *gpio_b=gtk_button_new_with_label("Config GPIO");
++          g_signal_connect (gpio_b, "button-press-event", G_CALLBACK(gpio_cb), NULL);
++          gtk_grid_attach(GTK_GRID(grid),gpio_b,0,i,1,1);
++#endif
++          GtkWidget *discover_b=gtk_button_new_with_label("Discover");
++          g_signal_connect (discover_b, "button-press-event", G_CALLBACK(discover_cb), NULL);
++          gtk_grid_attach(GTK_GRID(grid),discover_b,1,i,1,1);
++
++          GtkWidget *exit_b=gtk_button_new_with_label("Exit");
++          g_signal_connect (exit_b, "button-press-event", G_CALLBACK(exit_cb), NULL);
++          gtk_grid_attach(GTK_GRID(grid),exit_b,2,i,1,1);
++
++
++          gtk_container_add (GTK_CONTAINER (content), grid);
++          gtk_widget_show_all(discovery_dialog);
++      }
++}
++
++static gboolean minimize_cb (GtkWidget *widget, GdkEventButton *event, gpointer data) {
++  gtk_window_iconify(GTK_WINDOW(window));
++  return TRUE;
++}
++
++static void start_radio() {
++  int y;
++fprintf(stderr,"start: selected radio=%p device=%d\n",radio,radio->device);
++  gdk_window_set_cursor(splash_window,cursor_watch);
++
++  splash_status("Initializing wdsp ...");
++  protocol=radio->protocol;
++  device=radio->device;
++
++  switch(radio->protocol) {
++    case ORIGINAL_PROTOCOL:
++    case NEW_PROTOCOL:
++      sprintf(property_path,"%02X-%02X-%02X-%02X-%02X-%02X.props",
++                        radio->info.network.mac_address[0],
++                        radio->info.network.mac_address[1],
++                        radio->info.network.mac_address[2],
++                        radio->info.network.mac_address[3],
++                        radio->info.network.mac_address[4],
++                        radio->info.network.mac_address[5]);
++      break;
++#ifdef LIMESDR
++    case LIMESDR_PROTOCOL:
++      sprintf(property_path,"limesdr.props");
++      break;
++#endif
++#ifdef RADIOBERRY
++      case RADIOBERRY_PROTOCOL:
++              sprintf(property_path,"radioberry.props");
++              break;
++#endif
++ }
++
++#ifdef GPIO
++  fprintf(stderr,"gpio_init\n");
++  splash_status("Initializing GPIO ...");
++  if(gpio_init()<0) {
++  }
++#ifdef LOCALCW
++  // init local keyer if enabled
++  else if (cw_keyer_internal == 0)
++    keyer_update();
++#endif
++#endif
++ 
++ 
++  radioRestoreState();
++
++  fprintf(stderr,"malloc samples\n");
++  if(radio->protocol==NEW_PROTOCOL) {
++    samples=malloc(display_width*sizeof(float)*2*4); // 192 -> 48
++  } else {
++    samples=malloc(display_width*sizeof(float)*2);
++  }
++
++  //splash_status("Initializing wdsp ...");
++  fprintf(stderr,"wdsp_init\n");
++  wdsp_init(0,display_width,radio->protocol);
++
++  switch(radio->protocol) {
++    case ORIGINAL_PROTOCOL:
++      splash_status("Initializing old protocol ...");
++  fprintf(stderr,"old_protocol_init\n");
++      old_protocol_init(0,display_width);
++      break;
++    case NEW_PROTOCOL:
++      splash_status("Initializing new protocol ...");
++  fprintf(stderr,"new_protocol_init\n");
++      new_protocol_init(display_width);
++      break;
++#ifdef LIMESDR
++    case LIMESDR_PROTOCOL:
++      splash_status("Initializing lime protocol ...");
++      lime_protocol_init(0,display_width);
++      break;
++#endif
++#ifdef RADIOBERRY
++      case RADIOBERRY_PROTOCOL:
++              splash_status("Initializing radioberry protocol ...");
++              radioberry_protocol_init(0,display_width);
++              break;
++#endif
++  }
++
++
++
++  window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
++  gtk_window_set_title (GTK_WINDOW (window), "pihpsdr");
++  gtk_window_set_position(GTK_WINDOW(window),GTK_WIN_POS_CENTER_ALWAYS);
++  gtk_window_set_resizable(GTK_WINDOW(window), FALSE);
++  g_signal_connect (window, "delete-event", G_CALLBACK (main_delete), NULL);
++
++  fixed=gtk_fixed_new();
++  gtk_container_add(GTK_CONTAINER(window), fixed);
++  y=0;
++
++  vfo = vfo_init(VFO_WIDTH,VFO_HEIGHT,window);
++  gtk_fixed_put(GTK_FIXED(fixed),vfo,0,0);
++
++
++
++  //rit_control = rit_init(RIT_WIDTH,MENU_HEIGHT,window);
++  //gtk_fixed_put(GTK_FIXED(fixed),rit_control,VFO_WIDTH,y);
++
++  GtkWidget *minimize_b=gtk_button_new_with_label("Hide");
++  gtk_widget_override_font(minimize_b, pango_font_description_from_string("FreeMono Bold 10"));
++  gtk_widget_set_size_request (minimize_b, MENU_WIDTH, MENU_HEIGHT/2);
++  g_signal_connect (minimize_b, "button-press-event", G_CALLBACK(minimize_cb), NULL);
++  gtk_widget_show(minimize_b);
++  gtk_fixed_put(GTK_FIXED(fixed),minimize_b,VFO_WIDTH,y);
++
++  //menu = menu_init(MENU_WIDTH,MENU_HEIGHT,window);
++  menu = new_menu_init(MENU_WIDTH,MENU_HEIGHT/2,window);
++  gtk_fixed_put(GTK_FIXED(fixed),menu,VFO_WIDTH,y+(MENU_HEIGHT/2));
++
++  meter = meter_init(METER_WIDTH,METER_HEIGHT,window);
++  gtk_fixed_put(GTK_FIXED(fixed),meter,VFO_WIDTH+MENU_WIDTH,y);
++  y+=VFO_HEIGHT;
++
++  if(display_panadapter) {
++    int height=PANADAPTER_HEIGHT;
++    if(!display_waterfall) {
++      height+=WATERFALL_HEIGHT;
++      if(!display_sliders) {
++        height+=SLIDERS_HEIGHT;
++      }
++      if(!display_toolbar) {
++        height+=TOOLBAR_HEIGHT;
++      }
++    } else {
++      if(!display_sliders) {
++        height+=SLIDERS_HEIGHT/2;
++      }
++    }
++    panadapter = panadapter_init(display_width,height);
++    gtk_fixed_put(GTK_FIXED(fixed),panadapter,0,VFO_HEIGHT);
++    y+=height;
++  }
++
++  if(display_waterfall) {
++    int height=WATERFALL_HEIGHT;
++    if(!display_panadapter) {
++      height+=PANADAPTER_HEIGHT;
++    }
++    if(!display_sliders) {
++      if(display_panadapter) {
++        height+=SLIDERS_HEIGHT/2;
++      } else {
++        height+=SLIDERS_HEIGHT;
++      }
++    }
++    if(!display_toolbar) {
++      height+=TOOLBAR_HEIGHT;
++    }
++    waterfall = waterfall_init(display_width,height);
++    gtk_fixed_put(GTK_FIXED(fixed),waterfall,0,y);
++    y+=height;
++
++  }
++
++#ifdef PSK
++    int psk_height=PSK_WATERFALL_HEIGHT;
++    if(!display_sliders) {
++      psk_height+=SLIDERS_HEIGHT/2;
++    }
++    if(!display_toolbar) {
++      psk_height+=TOOLBAR_HEIGHT/2;
++    }
++    psk_waterfall = psk_waterfall_init(display_width,psk_height);
++    gtk_fixed_put(GTK_FIXED(fixed),psk_waterfall,0,VFO_HEIGHT);
++    psk = init_psk();
++    gtk_fixed_put(GTK_FIXED(fixed),psk,0,VFO_HEIGHT+psk_height);
++#endif
++
++  if(display_sliders) {
++    sliders = sliders_init(display_width,SLIDERS_HEIGHT,window);
++    gtk_fixed_put(GTK_FIXED(fixed),sliders,0,y);
++    y+=SLIDERS_HEIGHT;
++  }
++
++  if(display_toolbar) {
++    toolbar = toolbar_init(display_width,TOOLBAR_HEIGHT,window);
++    gtk_fixed_put(GTK_FIXED(fixed),toolbar,0,y);
++    y+=TOOLBAR_HEIGHT;
++  }
++
++  splash_close();
++
++  gtk_widget_show_all (window);
++
++  linein_changed();
++
++  if(full_screen) {
++    gtk_window_fullscreen(GTK_WINDOW(window));
++  }
++
++  GdkWindow *gdk_window = gtk_widget_get_window(window);
++  gdk_window_set_cursor(gdk_window,cursor_arrow);
++
++  // start the receiver
++  SetChannelState(CHANNEL_RX0,1,1);
++
++  //update_timer_id=gdk_threads_add_timeout(1000/updates_per_second, update, NULL);
++  update_timer_id=gdk_threads_add_timeout_full(G_PRIORITY_HIGH_IDLE,1000/updates_per_second, update, NULL, NULL);
++
++  // save every 30 seconds
++  save_timer_id=gdk_threads_add_timeout(30000, save_cb, NULL);
++
++
++  if(protocol!=NEW_PROTOCOL) {
++    setFrequency(getFrequency());
++  }
++
++#ifdef PSK
++  if(mode==modePSK) {
++    show_psk();
++  } else {
++    show_waterfall();
++  }
++#endif
++
++  launch_rigctl();
++
++  g_idle_add(vfo_update,(gpointer)NULL);
++
++}
++
++#ifdef PSK
++void show_psk() {
++  if(display_waterfall) {
++    gtk_widget_hide(waterfall);
++  }
++  if(display_panadapter) {
++    gtk_widget_hide(panadapter);
++  }
++  gtk_widget_show(psk);
++  gtk_widget_show(psk_waterfall);
++}
++
++void show_waterfall() {
++  gtk_widget_hide(psk_waterfall);
++  gtk_widget_hide(psk);
++  if(display_panadapter) {
++    gtk_widget_show(panadapter);
++  }
++  if(display_waterfall) {
++    gtk_widget_show(waterfall);
++  }
++}
++#endif
++
++void reconfigure_display() {
++  int y=VFO_HEIGHT;
++
++  // configure panadapter
++  if(display_panadapter) {
++    int height=PANADAPTER_HEIGHT;
++    if(!display_waterfall) {
++      height+=WATERFALL_HEIGHT;
++      if(!display_sliders) {
++        height+=SLIDERS_HEIGHT;
++      }
++      if(!display_toolbar) {
++        height+=TOOLBAR_HEIGHT;
++      }
++    } else {
++      if(!display_sliders) {
++        height+=SLIDERS_HEIGHT/2;
++      }
++      if(!display_toolbar) {
++        height+=TOOLBAR_HEIGHT/2;
++      }
++    }
++fprintf(stderr,"panadapter_height=%d\n",height);
++    if(panadapter==NULL) {
++fprintf(stderr,"reconfigure_display: panadapter_init: width:%d height:%d\n",display_width,height);
++      panadapter = panadapter_init(display_width,height);
++      gtk_fixed_put(GTK_FIXED(fixed),panadapter,0,y);
++    } else {
++      // set the size
++fprintf(stderr,"reconfigure_display: panadapter set_size_request: width:%d height:%d\n",display_width,height);
++      gtk_widget_set_size_request(panadapter, display_width, height);
++      // move the current one
++      gtk_fixed_move(GTK_FIXED(fixed),panadapter,0,y);
++    }
++    gtk_widget_show_all(panadapter);
++    y+=height;
++  } else {
++    gtk_widget_hide(panadapter);
++  }
++
++  // configure waterfall
++  if(display_waterfall) {
++    int height=WATERFALL_HEIGHT;
++
++    if(!display_panadapter) {
++      height+=PANADAPTER_HEIGHT;
++      if(!display_sliders) {
++        height+=SLIDERS_HEIGHT;
++      }
++      if(!display_toolbar) {
++        height+=TOOLBAR_HEIGHT;
++      }
++    } else {
++      if(!display_sliders) {
++        height+=SLIDERS_HEIGHT/2;
++      }
++      if(!display_toolbar) {
++        height+=TOOLBAR_HEIGHT/2;
++      }
++    }
++fprintf(stderr,"waterfall_height=%d\n",height);
++    if(waterfall==NULL) {
++fprintf(stderr,"reconfigure_display: waterfall_init: width:%d height:%d\n",display_width,height);
++      waterfall = waterfall_init(display_width,height);
++      gtk_fixed_put(GTK_FIXED(fixed),waterfall,0,y);
++    } else {
++      // set the size
++fprintf(stderr,"reconfigure_display: waterfall set_size_request: width:%d height:%d\n",display_width,height);
++      gtk_widget_set_size_request (waterfall, display_width, height);
++      // move the current one
++      gtk_fixed_move(GTK_FIXED(fixed),waterfall,0,y);
++    }
++    gtk_widget_show_all(waterfall);
++    y+=height;
++  } else {
++    gtk_widget_hide(waterfall);
++  }
++
++  if(display_sliders) {
++fprintf(stderr,"sliders_height=%d\n",SLIDERS_HEIGHT);
++    if(sliders==NULL) {
++fprintf(stderr,"reconfigure_display: sliders_init: width:%d height:%d\n",display_width,SLIDERS_HEIGHT);
++      sliders = sliders_init(display_width,SLIDERS_HEIGHT,window);
++      gtk_fixed_put(GTK_FIXED(fixed),sliders,0,y);
++    } else {
++      gtk_fixed_move(GTK_FIXED(fixed),sliders,0,y);
++      gtk_widget_show(sliders);
++    }
++    gtk_widget_show_all(sliders);
++    linein_changed();
++    y+=SLIDERS_HEIGHT;
++  } else {
++    gtk_widget_hide(sliders);
++  }
++
++  if(display_toolbar) {
++fprintf(stderr,"toolbar_height=%d\n",TOOLBAR_HEIGHT);
++    if(toolbar==NULL) {
++fprintf(stderr,"reconfigure_display: toolbar_init: width:%d height:%d\n",display_width,TOOLBAR_HEIGHT);
++      toolbar = toolbar_init(display_width,TOOLBAR_HEIGHT,window);
++      gtk_fixed_put(GTK_FIXED(fixed),toolbar,0,y);
++    } else {
++      gtk_fixed_move(GTK_FIXED(fixed),toolbar,0,y);
++      gtk_widget_show(toolbar);
++    }
++    gtk_widget_show_all(toolbar);
++    y+=TOOLBAR_HEIGHT;
++  } else {
++    gtk_widget_hide(toolbar);
++  }
++
++}
++
++gint init(void* arg) {
++=======
++static int init(void *data) {
++>>>>>>> upstream/master
++  char *res;
++  char wisdom_directory[1024];
++  char wisdom_file[1024];
++
++  fprintf(stderr,"init\n");
++
++  audio_get_cards();
++
++  cursor_arrow=gdk_cursor_new(GDK_ARROW);
++  cursor_watch=gdk_cursor_new(GDK_WATCH);
++
++  gdk_window_set_cursor(gtk_widget_get_window(top_window),cursor_watch);
++
++  // check if wisdom file exists
++  res=getcwd(wisdom_directory, sizeof(wisdom_directory));
++  strcpy(&wisdom_directory[strlen(wisdom_directory)],"/");
++  strcpy(wisdom_file,wisdom_directory);
++  strcpy(&wisdom_file[strlen(wisdom_file)],"wdspWisdom");
++  status_text("Checking FFTW Wisdom file ...");
++  if(access(wisdom_file,F_OK)<0) {
++      int rc=sem_init(&wisdom_sem, 0, 0);
++      rc=pthread_create(&wisdom_thread_id, NULL, wisdom_thread, (void *)wisdom_directory);
++      while(sem_trywait(&wisdom_sem)<0) {
++        status_text(wisdom_get_status());
++        while (gtk_events_pending ())
++          gtk_main_iteration ();
++        usleep(100000); // 100ms
++      }
++  }
++
++  g_idle_add(discovery,NULL);
++  return 0;
++}
++
++static void activate_pihpsdr(GtkApplication *app, gpointer data) {
++
++
++  //gtk_init (&argc, &argv);
++
++  fprintf(stderr,"Build: %s %s\n",build_date,version);
++
++  uname(&unameData);
++  fprintf(stderr,"sysname: %s\n",unameData.sysname);
++  fprintf(stderr,"nodename: %s\n",unameData.nodename);
++  fprintf(stderr,"release: %s\n",unameData.release);
++  fprintf(stderr,"version: %s\n",unameData.version);
++  fprintf(stderr,"machine: %s\n",unameData.machine);
++
++  GdkScreen *screen=gdk_screen_get_default();
++  if(screen==NULL) {
++    fprintf(stderr,"no default screen!\n");
++    _exit(0);
++  }
++
++
++  display_width=gdk_screen_get_width(screen);
++  display_height=gdk_screen_get_height(screen);
++
++fprintf(stderr,"width=%d height=%d\n", display_width, display_height);
++  if(display_width>800 || display_height>480) {
++    display_width=800;
++    display_height=480;
++    full_screen=0;
++  }
++
++fprintf(stderr,"display_width=%d display_height=%d\n", display_width, display_height);
++
++  fprintf(stderr,"create top level window\n");
++  top_window = gtk_application_window_new (app);
++  if(full_screen) {
++fprintf(stderr,"full screen\n");
++    gtk_window_fullscreen(GTK_WINDOW(top_window));
++  }
++  gtk_widget_set_size_request(top_window, display_width, display_height);
++  gtk_window_set_title (GTK_WINDOW (top_window), "pihpsdr");
++  gtk_window_set_position(GTK_WINDOW(top_window),GTK_WIN_POS_CENTER_ALWAYS);
++  gtk_window_set_resizable(GTK_WINDOW(top_window), FALSE);
++  g_signal_connect (top_window, "delete-event", G_CALLBACK (main_delete), NULL);
++  //g_signal_connect (top_window,"draw", G_CALLBACK (main_draw_cb), NULL);
++
++//fprintf(stderr,"create fixed container\n");
++  //fixed=gtk_fixed_new();
++  //gtk_container_add(GTK_CONTAINER(top_window), fixed);
++
++fprintf(stderr,"create grid\n");
++  grid = gtk_grid_new();
++  gtk_widget_set_size_request(grid, display_width, display_height);
++  gtk_grid_set_row_homogeneous(GTK_GRID(grid),FALSE);
++  gtk_grid_set_column_homogeneous(GTK_GRID(grid),FALSE);
++fprintf(stderr,"add grid\n");
++  gtk_container_add (GTK_CONTAINER (top_window), grid);
++
++fprintf(stderr,"create image\n");
++  GtkWidget  *image=gtk_image_new_from_file("hpsdr.png");
++fprintf(stderr,"add image to grid\n");
++  gtk_grid_attach(GTK_GRID(grid), image, 0, 0, 1, 4);
++
++fprintf(stderr,"create pi label\n");
++  char build[64];
++  sprintf(build,"build: %s %s",build_date, version);
++  GtkWidget *pi_label=gtk_label_new("pihpsdr by John Melton g0orx/n6lyt");
++  gtk_label_set_justify(GTK_LABEL(pi_label),GTK_JUSTIFY_LEFT);
++  gtk_widget_show(pi_label);
++fprintf(stderr,"add pi label to grid\n");
++  gtk_grid_attach(GTK_GRID(grid),pi_label,1,0,1,1);
++
++fprintf(stderr,"create build label\n");
++  GtkWidget *build_date_label=gtk_label_new(build);
++  gtk_label_set_justify(GTK_LABEL(build_date_label),GTK_JUSTIFY_LEFT);
++  gtk_widget_show(build_date_label);
++fprintf(stderr,"add build label to grid\n");
++  gtk_grid_attach(GTK_GRID(grid),build_date_label,1,1,1,1);
++
++fprintf(stderr,"create status\n");
++  status=gtk_label_new("");
++  gtk_label_set_justify(GTK_LABEL(status),GTK_JUSTIFY_LEFT);
++  gtk_widget_override_font(status, pango_font_description_from_string("FreeMono 18"));
++  gtk_widget_show(status);
++fprintf(stderr,"add status to grid\n");
++  gtk_grid_attach(GTK_GRID(grid), status, 1, 3, 1, 1);
++
++/*
++fprintf(stderr,"create exit button\n");
++  GtkWidget *button = gtk_button_new_with_label ("Exit");
++  //g_signal_connect (button, "clicked", G_CALLBACK (print_hello), NULL);
++  g_signal_connect_swapped (button, "clicked", G_CALLBACK (gtk_widget_destroy), top_window);
++fprintf(stderr,"add exit button to grid\n");
++  gtk_grid_attach(GTK_GRID(grid), button, 1, 4, 1, 1);
++*/
++
++  gtk_widget_show_all(top_window);
++
++  g_idle_add(init,NULL);
++  //g_idle_add(discovery,NULL);
++
++
++}
++
++int main(int argc,char **argv) {
++  GtkApplication *pihpsdr;
++  int status;
++
++  pihpsdr=gtk_application_new("org.g0orx.pihpsdr", G_APPLICATION_FLAGS_NONE);
++  g_signal_connect(pihpsdr, "activate", G_CALLBACK(activate_pihpsdr), NULL);
++  status=g_application_run(G_APPLICATION(pihpsdr), argc, argv);
++fprintf(stderr,"exiting ...\n");
++  g_object_unref(pihpsdr);
++  return status;
++}
diff --cc radio.c
index e25779e93f67ce991cb6a9441b9e76e2ccd43161,e4a55d560e14e16749ed89ad4cdeb2dcb29797b0..0ecb73141aef28edfd84a00bcf0f3a305ebe2ecf
+++ b/radio.c
@@@ -357,19 -735,17 +735,20 @@@ void setFrequency(long long f) 
    switch(protocol) {
      case NEW_PROTOCOL:
      case ORIGINAL_PROTOCOL:
 -      if(vfo[v].ctun) {
 -        long long minf=vfo[v].frequency-(long long)(active_receiver->sample_rate/2);
 -        long long maxf=vfo[v].frequency+(long long)(active_receiver->sample_rate/2);
 +#ifdef RADIOBERRY
 +      case RADIOBERRY_PROTOCOL:
 +#endif
 +      if(ctun) {
 +        long long minf=entry->frequencyA-(long long)(sample_rate/2);
 +        long long maxf=entry->frequencyA+(long long)(sample_rate/2);
          if(f<minf) f=minf;
          if(f>maxf) f=maxf;
-         ddsOffset=f-entry->frequencyA;
-         wdsp_set_offset(ddsOffset);
+         vfo[v].offset=f-vfo[v].frequency;
+         set_offset(active_receiver,vfo[v].offset);
          return;
        } else {
-         entry->frequencyA=f;
+         //entry->frequency=f;
+         vfo[v].frequency=f;
        }
        break;
  #ifdef LIMESDR
  #endif
    }
  
-   displayFrequency=f;
-   ddsFrequency=f;
-   if(band->frequencyLO!=0LL) {
-     ddsFrequency=f-band->frequencyLO;
-   }
    switch(protocol) {
      case NEW_PROTOCOL:
-       schedule_high_priority(5);
+       schedule_high_priority();
        break;
      case ORIGINAL_PROTOCOL:
 +#ifdef RADIOBERRY
 +      case RADIOBERRY_PROTOCOL:
 +#endif
        schedule_frequency_changed();
        break;
  #ifdef LIMESDR
diff --cc radio.c.orig
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..f9127079a099de997232c9e31487f194b74d192f
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,1309 @@@
++/* Copyright (C)
++* 2015 - 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 <stdlib.h>
++#include <stdio.h>
++#include <string.h>
++#include <semaphore.h>
++#include <math.h>
++
++#include <wdsp.h>
++
++#include "audio.h"
++#include "discovered.h"
++//#include "discovery.h"
++#include "filter.h"
++#include "main.h"
++#include "mode.h"
++#include "radio.h"
++#include "receiver.h"
++#include "transmitter.h"
++#include "channel.h"
++#include "agc.h"
++#include "band.h"
++#include "property.h"
++#include "new_protocol.h"
++#include "old_protocol.h"
++#include "store.h"
++#ifdef LIMESDR
++#include "lime_protocol.h"
++#endif
++#ifdef FREEDV
++#include "freedv.h"
++#endif
++#ifdef GPIO
++#include "gpio.h"
++#endif
++#include "vfo.h"
++#include "meter.h"
++#include "rx_panadapter.h"
++#include "tx_panadapter.h"
++#include "waterfall.h"
++#include "sliders.h"
++#include "toolbar.h"
++
++#define min(x,y) (x<y?x:y)
++#define max(x,y) (x<y?y:x)
++
++#define DISPLAY_INCREMENT (display_height/32)
++#define MENU_HEIGHT (DISPLAY_INCREMENT*2)
++#define MENU_WIDTH ((display_width/32)*3)
++#define VFO_HEIGHT (DISPLAY_INCREMENT*4)
++#define VFO_WIDTH (display_width-METER_WIDTH-MENU_WIDTH)
++#define METER_HEIGHT (DISPLAY_INCREMENT*4)
++#define METER_WIDTH ((display_width/32)*8)
++#define PANADAPTER_HEIGHT (DISPLAY_INCREMENT*8)
++#define SLIDERS_HEIGHT (DISPLAY_INCREMENT*6)
++#define TOOLBAR_HEIGHT (DISPLAY_INCREMENT*2)
++#define WATERFALL_HEIGHT (display_height-(VFO_HEIGHT+PANADAPTER_HEIGHT+SLIDERS_HEIGHT+TOOLBAR_HEIGHT))
++#ifdef PSK
++#define PSK_WATERFALL_HEIGHT (DISPLAY_INCREMENT*6)
++#define PSK_HEIGHT (display_height-(VFO_HEIGHT+PSK_WATERFALL_HEIGHT+SLIDERS_HEIGHT+TOOLBAR_HEIGHT))
++#endif
++
++static GtkWidget *fixed;
++static GtkWidget *vfo_panel;
++static GtkWidget *meter;
++static GtkWidget *menu;
++static GtkWidget *sliders;
++static GtkWidget *toolbar;
++static GtkWidget *panadapter;
++static GtkWidget *waterfall;
++#ifdef PSK
++static GtkWidget *psk;
++static GtkWidget *psk_waterfall;
++#endif
++
++#ifdef GPIO
++static GtkWidget *encoders;
++static cairo_surface_t *encoders_surface = NULL;
++#endif
++
++int echo=0;
++
++static gint save_timer_id;
++
++DISCOVERED *radio;
++
++char property_path[128];
++sem_t property_sem;
++
++RECEIVER *receiver[MAX_RECEIVERS];
++RECEIVER *active_receiver;
++TRANSMITTER *transmitter;
++
++int buffer_size=1024; // 64, 128, 256, 512, 1024
++int fft_size=4096; // 1024, 2048, 4096, 8192, 16384
++
++int atlas_penelope=0;
++int atlas_clock_source_10mhz=0;
++int atlas_clock_source_128mhz=0;
++int atlas_config=0;
++int atlas_mic_source=0;
++
++int classE=0;
++
++int tx_out_of_band=0;
++
++int tx_cfir=0;
++int tx_alc=1;
++int tx_leveler=0;
++
++double tone_level=0.0;
++
++int filter_board=ALEX;
++//int pa=PA_ENABLED;
++//int apollo_tuner=0;
++
++int updates_per_second=10;
++
++int panadapter_high=-40;
++int panadapter_low=-140;
++
++int display_filled=1;
++int display_detector_mode=DETECTOR_MODE_AVERAGE;
++int display_average_mode=AVERAGE_MODE_LOG_RECURSIVE;
++double display_average_time=120.0;
++
++
++int waterfall_high=-100;
++int waterfall_low=-150;
++int waterfall_automatic=1;
++
++int display_sliders=1;
++
++//double volume=0.2;
++double mic_gain=0.0;
++int binaural=0;
++
++int mic_linein=0;
++int linein_gain=16; // 0..31
++int mic_boost=0;
++int mic_bias_enabled=0;
++int mic_ptt_enabled=0;
++int mic_ptt_tip_bias_ring=0;
++
++double tune_drive=10;
++double drive=50;
++
++int drive_level=0;
++int tune_drive_level=0;
++
++int receivers=RECEIVERS;
++
++int locked=0;
++
++long long step=100;
++
++//int rit=0;
++int rit_increment=10;
++
++int lt2208Dither = 0;
++int lt2208Random = 0;
++int attenuation = 0; // 0dB
++//unsigned long alex_rx_antenna=0;
++//unsigned long alex_tx_antenna=0;
++//unsigned long alex_attenuation=0;
++
++int cw_keys_reversed=0; // 0=disabled 1=enabled
++int cw_keyer_speed=12; // 1-60 WPM
++int cw_keyer_mode=KEYER_STRAIGHT;
++int cw_keyer_weight=30; // 0-100
++int cw_keyer_spacing=0; // 0=on 1=off
++int cw_keyer_internal=1; // 0=external 1=internal
++int cw_keyer_sidetone_volume=127; // 0-127
++int cw_keyer_ptt_delay=20; // 0-255ms
++int cw_keyer_hang_time=300; // ms
++int cw_keyer_sidetone_frequency=400; // Hz
++int cw_breakin=1; // 0=disabled 1=enabled
++int cw_active_level=1; // 0=active_low 1=active_high
++
++int vfo_encoder_divisor=15;
++
++int protocol;
++int device;
++int ozy_software_version;
++int mercury_software_version;
++int penelope_software_version;
++int ptt;
++int dot;
++int dash;
++int adc_overload;
++int pll_locked;
++unsigned int exciter_power;
++unsigned int alex_forward_power;
++unsigned int alex_reverse_power;
++unsigned int AIN3;
++unsigned int AIN4;
++unsigned int AIN6;
++unsigned int IO1;
++unsigned int IO2;
++unsigned int IO3;
++int supply_volts;
++int mox;
++int tune;
++int memory_tune=0;
++int full_tune=0;
++
++//long long displayFrequency=14250000;
++//long long ddsFrequency=14250000;
++//long long ddsOffset=0;
++
++long long frequencyB=14250000;
++int modeB=modeUSB;
++int filterB=5;
++
++int split=0;
++
++unsigned char OCtune=0;
++int OCfull_tune_time=2800; // ms
++int OCmemory_tune_time=550; // ms
++long long tune_timeout;
++
++int smeter=RXA_S_AV;
++int alc=TXA_ALC_PK;
++
++int local_audio=0;
++int local_microphone=0;
++
++int eer_pwm_min=100;
++int eer_pwm_max=800;
++
++int tx_filter_low=150;
++int tx_filter_high=2850;
++
++#ifdef FREEDV
++char freedv_tx_text_data[64];
++#endif
++
++static int pre_tune_filter_low;
++static int pre_tune_filter_high;
++
++int enable_tx_equalizer=0;
++int tx_equalizer[4]={0,0,0,0};
++
++int enable_rx_equalizer=0;
++int rx_equalizer[4]={0,0,0,0};
++
++int deviation=2500;
++int pre_emphasize=0;
++
++int vox_setting=0;
++int vox_enabled=0;
++double vox_threshold=0.001;
++double vox_gain=10.0;
++double vox_hang=250.0;
++int vox=0;
++
++int diversity_enabled=0;
++double i_rotate[2]={1.0,1.0};
++double q_rotate[2]={0.0,0.0};
++
++void reconfigure_radio() {
++  int i;
++  int y;
++  int rx_height=display_height-VFO_HEIGHT-TOOLBAR_HEIGHT;
++  if(display_sliders) {
++    rx_height-=SLIDERS_HEIGHT;
++  }
++ 
++  y=VFO_HEIGHT;
++  for(i=0;i<receivers;i++) {
++    reconfigure_receiver(receiver[i],rx_height/receivers);
++    gtk_fixed_move(GTK_FIXED(fixed),receiver[i]->panel,0,y);
++    y+=rx_height/receivers;
++  }
++
++  if(display_sliders) {
++    if(sliders==NULL) {
++      sliders = sliders_init(display_width,SLIDERS_HEIGHT);
++      gtk_fixed_put(GTK_FIXED(fixed),sliders,0,y);
++    } else {
++      gtk_fixed_move(GTK_FIXED(fixed),sliders,0,y);
++    }
++    gtk_widget_show_all(sliders);
++    // force change of sliders for mic or linein
++    g_idle_add(linein_changed,NULL);
++  } else {
++    if(sliders!=NULL) {
++      gtk_container_remove(GTK_CONTAINER(fixed),sliders); 
++      sliders=NULL;
++    }
++  }
++
++  reconfigure_transmitter(transmitter,rx_height);
++
++}
++
++static gboolean save_cb(gpointer data) {
++    radioSaveState();
++    return TRUE;
++}
++
++static gboolean minimize_cb (GtkWidget *widget, GdkEventButton *event, gpointer data) {
++  gtk_window_iconify(GTK_WINDOW(top_window));
++  return TRUE;
++}
++
++static gboolean menu_cb (GtkWidget *widget, GdkEventButton *event, gpointer data) {
++  new_menu(top_window);
++  return TRUE;
++}
++
++void start_radio() {
++  int i;
++  int x;
++  int y;
++fprintf(stderr,"start_radio: selected radio=%p device=%d\n",radio,radio->device);
++  gdk_window_set_cursor(gtk_widget_get_window(top_window),gdk_cursor_new(GDK_WATCH));
++
++  int rc;
++  rc=sem_init(&property_sem, 0, 0);
++  if(rc!=0) {
++    fprintf(stderr,"start_radio: sem_init failed for property_sem: %d\n", rc);
++    exit(-1);
++  }
++  sem_post(&property_sem);
++
++  status_text("starting radio ...");
++  protocol=radio->protocol;
++  device=radio->device;
++
++  switch(radio->protocol) {
++    case ORIGINAL_PROTOCOL:
++    case NEW_PROTOCOL:
++      switch(radio->device) {
++#ifdef USBOZY
++        case DEVICE_OZY:
++          sprintf(property_path,"ozy.props");
++          break;
++#endif
++        default:
++          sprintf(property_path,"%02X-%02X-%02X-%02X-%02X-%02X.props",
++                        radio->info.network.mac_address[0],
++                        radio->info.network.mac_address[1],
++                        radio->info.network.mac_address[2],
++                        radio->info.network.mac_address[3],
++                        radio->info.network.mac_address[4],
++                        radio->info.network.mac_address[5]);
++          break;
++      }
++      break;
++#ifdef LIMESDR
++    case LIMESDR_PROTOCOL:
++      sprintf(property_path,"limesdr.props");
++      break;
++#endif
++  }
++
++  radioRestoreState();
++
++  y=0;
++
++  fixed=gtk_fixed_new();
++  gtk_container_remove(GTK_CONTAINER(top_window),grid);
++  gtk_container_add(GTK_CONTAINER(top_window), fixed);
++
++fprintf(stderr,"radio: vfo_init\n");
++  vfo_panel = vfo_init(VFO_WIDTH,VFO_HEIGHT,top_window);
++  gtk_fixed_put(GTK_FIXED(fixed),vfo_panel,0,y);
++
++fprintf(stderr,"radio: meter_init\n");
++  meter = meter_init(METER_WIDTH,METER_HEIGHT,top_window);
++  gtk_fixed_put(GTK_FIXED(fixed),meter,VFO_WIDTH,y);
++
++
++  GtkWidget *minimize_b=gtk_button_new_with_label("Hide");
++  gtk_widget_override_font(minimize_b, pango_font_description_from_string("FreeMono Bold 10"));
++  gtk_widget_set_size_request (minimize_b, MENU_WIDTH, MENU_HEIGHT);
++  g_signal_connect (minimize_b, "button-press-event", G_CALLBACK(minimize_cb), NULL) ;
++  gtk_fixed_put(GTK_FIXED(fixed),minimize_b,VFO_WIDTH+METER_WIDTH,y);
++  y+=MENU_HEIGHT;
++
++  GtkWidget *menu_b=gtk_button_new_with_label("Menu");
++  gtk_widget_override_font(menu_b, pango_font_description_from_string("FreeMono Bold 10"));
++  gtk_widget_set_size_request (menu_b, MENU_WIDTH, MENU_HEIGHT);
++  g_signal_connect (menu_b, "button-press-event", G_CALLBACK(menu_cb), NULL) ;
++  gtk_fixed_put(GTK_FIXED(fixed),menu_b,VFO_WIDTH+METER_WIDTH,y);
++  y+=MENU_HEIGHT;
++
++
++  int rx_height=display_height-VFO_HEIGHT-TOOLBAR_HEIGHT;
++  if(display_sliders) {
++    rx_height-=SLIDERS_HEIGHT;
++  }
++  int tx_height=rx_height;
++  rx_height=rx_height/receivers;
++
++
++fprintf(stderr,"Create %d receivers: height=%d\n",receivers,rx_height);
++  for(i=0;i<MAX_RECEIVERS;i++) {
++    receiver[i]=create_receiver(i, buffer_size, fft_size, display_width, updates_per_second, display_width, rx_height);
++    g_object_ref((gpointer)receiver[i]->panel);
++    if(i<receivers) {
++      gtk_fixed_put(GTK_FIXED(fixed),receiver[i]->panel,0,y);
++fprintf(stderr,"receiver %d: height=%d y=%d\n",receiver[i]->id,rx_height,y);
++      set_displaying(receiver[i],1);
++      y+=rx_height;
++    } else {
++      set_displaying(receiver[i],0);
++    }
++  }
++  active_receiver=receiver[0];
++
++  fprintf(stderr,"Create transmitter\n");
++  transmitter=create_transmitter(CHANNEL_TX, buffer_size, fft_size, updates_per_second, display_width, tx_height);
++  g_object_ref((gpointer)transmitter->panel);
++
++  switch(radio->protocol) {
++    case ORIGINAL_PROTOCOL:
++      old_protocol_init(0,display_width,receiver[0]->sample_rate);
++      break;
++    case NEW_PROTOCOL:
++      new_protocol_init(display_width);
++      break;
++#ifdef LIMESDR
++    case LIMESDR_PROTOCOL:
++      lime_protocol_init(0,display_width);
++      break;
++#endif
++  }
++
++#ifdef GPIO
++  if(gpio_init()<0) {
++    fprintf(stderr,"GPIO failed to initialize\n");
++  }
++#ifdef LOCALCW
++  // init local keyer if enabled
++  else if (cw_keyer_internal == 0)
++    keyer_update();
++#endif
++#endif
++
++#ifdef I2C
++  i2c_init();
++#endif
++
++  if(display_sliders) {
++fprintf(stderr,"create sliders\n");
++    sliders = sliders_init(display_width,SLIDERS_HEIGHT);
++    gtk_fixed_put(GTK_FIXED(fixed),sliders,0,y);
++    y+=SLIDERS_HEIGHT;
++  }
++
++  toolbar = toolbar_init(display_width,TOOLBAR_HEIGHT,top_window);
++  gtk_fixed_put(GTK_FIXED(fixed),toolbar,0,y);
++  y+=TOOLBAR_HEIGHT;
++
++  gtk_widget_show_all (fixed);
++
++  // force change of sliders for mic or linein
++  g_idle_add(linein_changed,NULL);
++
++  // save every 30 seconds
++fprintf(stderr,"start save timer\n");
++  save_timer_id=gdk_threads_add_timeout(30000, save_cb, NULL);
++
++#ifdef PSK
++  if(active_receiver->mode==modePSK) {
++    show_psk();
++  } else {
++    show_waterfall();
++  }
++#endif
++
++  launch_rigctl();
++
++  calcDriveLevel();
++  calcTuneDriveLevel();
++
++  if(protocol==NEW_PROTOCOL) {
++    schedule_high_priority();
++  }
++
++  g_idle_add(vfo_update,(gpointer)NULL);
++
++fprintf(stderr,"set cursor\n");
++  gdk_window_set_cursor(gtk_widget_get_window(top_window),gdk_cursor_new(GDK_ARROW));
++
++for(i=0;i<MAX_VFOS;i++) {
++  fprintf(stderr,"start_radio: vfo %d band=%d bandstack=%d frequency=%lld mode=%d filter=%d rit=%lld lo=%%ld offset=%lld\n",
++    i,
++    vfo[i].band,
++    vfo[i].bandstack,
++    vfo[i].frequency,
++    vfo[i].mode,
++    vfo[i].filter,
++    vfo[i].rit,
++    vfo[i].lo,
++    vfo[i].offset);
++}
++}
++
++
++void radio_change_receivers(int r) {
++  switch(r) {
++    case 1:
++      if(receivers==2) {
++        set_displaying(receiver[1],0);
++        gtk_container_remove(GTK_CONTAINER(fixed),receiver[1]->panel);
++      }
++      receivers=1;
++      break;
++    case 2:
++      gtk_fixed_put(GTK_FIXED(fixed),receiver[1]->panel,0,0);
++      set_displaying(receiver[1],1);
++      receivers=2;
++      break;
++  }
++  reconfigure_radio();
++  active_receiver=receiver[0];
++}
++
++void radio_change_sample_rate(int rate) {
++  int i;
++  switch(protocol) {
++    case ORIGINAL_PROTOCOL:
++      old_protocol_stop();
++      for(i=0;i<receivers;i++) {
++        receiver_change_sample_rate(receiver[i],rate);
++      }
++      old_protocol_set_mic_sample_rate(rate);
++      old_protocol_run();
++      break;
++#ifdef LIMESDR
++    case LIMESDR_PROTOCOL:
++      break;
++#endif
++  }
++}
++
++static void rxtx(int state) {
++  int i;
++  int y=VFO_HEIGHT;
++
++  if(state) {
++    // switch to tx
++    for(i=0;i<receivers;i++) {
++      SetChannelState(receiver[i]->id,0,i==(receivers-1));
++      set_displaying(receiver[i],0);
++      if(protocol==NEW_PROTOCOL) {
++        schedule_high_priority();
++      }
++      gtk_container_remove(GTK_CONTAINER(fixed),receiver[i]->panel);
++    }
++    gtk_fixed_put(GTK_FIXED(fixed),transmitter->panel,0,y);
++    SetChannelState(transmitter->id,1,0);
++    tx_set_displaying(transmitter,1);
++#ifdef FREEDV
++    if(active_receiver->mode==modeFREEDV) {
++      freedv_reset_tx_text_index();
++    }
++#endif
++  } else {
++    SetChannelState(transmitter->id,0,1);
++    if(protocol==NEW_PROTOCOL) {
++      schedule_high_priority();
++    }
++    tx_set_displaying(transmitter,0);
++    gtk_container_remove(GTK_CONTAINER(fixed),transmitter->panel);
++    int rx_height=display_height-VFO_HEIGHT-TOOLBAR_HEIGHT;
++    if(display_sliders) {
++      rx_height-=SLIDERS_HEIGHT;
++    }
++    for(i=0;i<receivers;i++) {
++      SetChannelState(receiver[i]->id,1,0);
++      set_displaying(receiver[i],1);
++      gtk_fixed_put(GTK_FIXED(fixed),receiver[i]->panel,0,y);
++      y+=(rx_height/receivers);
++    }
++  }
++
++  gtk_widget_show_all(fixed);
++  g_idle_add(linein_changed,NULL);
++}
++
++void setMox(int state) {
++  if(mox!=state) {
++    mox=state;
++    if(vox_enabled && vox) {
++      vox_cancel();
++    } else {
++      rxtx(state);
++    }
++  }
++}
++
++int getMox() {
++    return mox;
++}
++
++void setVox(int state) {
++  if(vox!=state && !tune) {
++    vox=state;
++    rxtx(state);
++  }
++}
++
++void setTune(int state) {
++  int i;
++
++  if(tune!=state) {
++    tune=state;
++    if(vox_enabled && vox) {
++      vox_cancel();
++    }
++    if(tune) {
++      if(full_tune) {
++        if(OCfull_tune_time!=0) {
++          struct timeval te;
++          gettimeofday(&te,NULL);
++          tune_timeout=(te.tv_sec*1000LL+te.tv_usec/1000)+(long long)OCfull_tune_time;
++        }
++      }
++      if(memory_tune) {
++        if(OCmemory_tune_time!=0) {
++          struct timeval te;
++          gettimeofday(&te,NULL);
++          tune_timeout=(te.tv_sec*1000LL+te.tv_usec/1000)+(long long)OCmemory_tune_time;
++        }
++      }
++    }
++    if(protocol==NEW_PROTOCOL) {
++      schedule_high_priority();
++      //schedule_general();
++    }
++    if(tune) {
++      for(i=0;i<receivers;i++) {
++        SetChannelState(receiver[i]->id,0,i==(receivers-1));
++        set_displaying(receiver[i],0);
++        if(protocol==NEW_PROTOCOL) {
++          schedule_high_priority();
++        }
++      }
++
++      int mode=vfo[VFO_A].mode;;
++      if(split) {
++        mode=vfo[VFO_B].mode;
++      }
++      double freq=(double)cw_keyer_sidetone_frequency;
++      
++      pre_tune_filter_low=transmitter->filter_low;
++      pre_tune_filter_high=transmitter->filter_high;
++
++      switch(mode) {
++        case modeUSB:
++        case modeCWU:
++        case modeDIGU:
++          SetTXAPostGenToneFreq(transmitter->id,(double)cw_keyer_sidetone_frequency);
++          transmitter->filter_low=cw_keyer_sidetone_frequency-100;
++          transmitter->filter_high=cw_keyer_sidetone_frequency+100;
++          freq=(double)(cw_keyer_sidetone_frequency+100);
++          break;
++        case modeLSB:
++        case modeCWL:
++        case modeDIGL:
++          SetTXAPostGenToneFreq(transmitter->id,-(double)cw_keyer_sidetone_frequency);
++          transmitter->filter_low=-cw_keyer_sidetone_frequency-100;
++          transmitter->filter_high=-cw_keyer_sidetone_frequency+100;
++          freq=(double)(-cw_keyer_sidetone_frequency-100);
++          break;
++        case modeDSB:
++          SetTXAPostGenToneFreq(transmitter->id,(double)cw_keyer_sidetone_frequency);
++          transmitter->filter_low=cw_keyer_sidetone_frequency-100;
++          transmitter->filter_high=cw_keyer_sidetone_frequency+100;
++          freq=(double)(cw_keyer_sidetone_frequency+100);
++          break;
++        case modeAM:
++        case modeSAM:
++        case modeFMN:
++          SetTXAPostGenToneFreq(transmitter->id,(double)cw_keyer_sidetone_frequency);
++          transmitter->filter_low=cw_keyer_sidetone_frequency-100;
++          transmitter->filter_high=cw_keyer_sidetone_frequency+100;
++          freq=(double)(cw_keyer_sidetone_frequency+100);
++          break;
++      }
++
++      SetTXABandpassFreqs(transmitter->id,transmitter->filter_low,transmitter->filter_high);
++
++      
++      SetTXAMode(transmitter->id,modeDIGU);
++      SetTXAPostGenMode(transmitter->id,0);
++      SetTXAPostGenToneMag(transmitter->id,0.99999);
++      SetTXAPostGenRun(transmitter->id,1);
++    } else {
++      SetTXAPostGenRun(transmitter->id,0);
++      SetTXAMode(transmitter->id,transmitter->mode);
++      transmitter->filter_low=pre_tune_filter_low;
++      transmitter->filter_high=pre_tune_filter_high;
++      SetTXABandpassFreqs(transmitter->id,transmitter->filter_low,transmitter->filter_high);
++    }
++    rxtx(tune);
++  }
++}
++
++int getTune() {
++  return tune;
++}
++
++int isTransmitting() {
++  return ptt || mox || vox || tune;
++}
++
++void setFrequency(long long f) {
++  BAND *band=band_get_current_band();
++  BANDSTACK_ENTRY* entry=bandstack_entry_get_current();
++  int v=active_receiver->id;
++
++  switch(protocol) {
++    case NEW_PROTOCOL:
++    case ORIGINAL_PROTOCOL:
++<<<<<<< HEAD
++#ifdef RADIOBERRY
++      case RADIOBERRY_PROTOCOL:
++#endif
++      if(ctun) {
++        long long minf=entry->frequencyA-(long long)(sample_rate/2);
++        long long maxf=entry->frequencyA+(long long)(sample_rate/2);
++=======
++      if(vfo[v].ctun) {
++        long long minf=vfo[v].frequency-(long long)(active_receiver->sample_rate/2);
++        long long maxf=vfo[v].frequency+(long long)(active_receiver->sample_rate/2);
++>>>>>>> upstream/master
++        if(f<minf) f=minf;
++        if(f>maxf) f=maxf;
++        vfo[v].offset=f-vfo[v].frequency;
++        set_offset(active_receiver,vfo[v].offset);
++        return;
++      } else {
++        //entry->frequency=f;
++        vfo[v].frequency=f;
++      }
++      break;
++#ifdef LIMESDR
++    case LIMESDR_PROTOCOL:
++      {
++      long long minf=entry->frequency-(long long)(active_receiver->sample_rate/2);
++      long long maxf=entry->frequency+(long long)(active_receiver->sample_rate/2);
++      if(f<minf) f=minf;
++      if(f>maxf) f=maxf;
++      ddsOffset=f-entry->frequency;
++      wdsp_set_offset(ddsOffset);
++      return;
++      }
++      break;
++#endif
++  }
++
++  switch(protocol) {
++    case NEW_PROTOCOL:
++      schedule_high_priority();
++      break;
++    case ORIGINAL_PROTOCOL:
++#ifdef RADIOBERRY
++      case RADIOBERRY_PROTOCOL:
++#endif
++      schedule_frequency_changed();
++      break;
++#ifdef LIMESDR
++    case LIMESDR_PROTOCOL:
++      lime_protocol_set_frequency(f);
++      ddsOffset=0;
++      wdsp_set_offset(ddsOffset);
++      break;
++#endif
++  }
++}
++
++long long getFrequency() {
++    return vfo[active_receiver->id].frequency;
++}
++
++double getDrive() {
++    return drive;
++}
++
++static int calcLevel(double d) {
++  int level=0;
++  int v=VFO_A;
++  if(split) v=VFO_B;
++
++  BAND *band=band_get_band(vfo[v].band);
++  double target_dbm = 10.0 * log10(d * 1000.0);
++  double gbb=band->pa_calibration;
++  target_dbm-=gbb;
++  double target_volts = sqrt(pow(10, target_dbm * 0.1) * 0.05);
++  double volts=min((target_volts / 0.8), 1.0);
++  double actual_volts=volts*(1.0/0.98);
++
++  if(actual_volts<0.0) {
++    actual_volts=0.0;
++  } else if(actual_volts>1.0) {
++    actual_volts=1.0;
++  }
++
++  level=(int)(actual_volts*255.0);
++  return level;
++}
++
++void calcDriveLevel() {
++    drive_level=calcLevel(drive);
++    if(mox && protocol==NEW_PROTOCOL) {
++      schedule_high_priority();
++    }
++}
++
++void setDrive(double value) {
++    drive=value;
++    calcDriveLevel();
++}
++
++double getTuneDrive() {
++    return tune_drive;
++}
++
++void calcTuneDriveLevel() {
++    tune_drive_level=calcLevel(tune_drive);
++    if(tune  && protocol==NEW_PROTOCOL) {
++      schedule_high_priority();
++    }
++}
++
++void setTuneDrive(double value) {
++    tune_drive=value;
++    calcTuneDriveLevel();
++}
++
++void set_attenuation(int value) {
++    switch(protocol) {
++      case NEW_PROTOCOL:
++        schedule_high_priority();
++        break;
++#ifdef LIMESDR
++      case LIMESDR_PROTOCOL:
++        lime_protocol_set_attenuation(value);
++        break;
++#endif
++    }
++}
++
++int get_attenuation() {
++    return active_receiver->attenuation;
++}
++
++void set_alex_rx_antenna(int v) {
++    if(active_receiver->id==0) {
++      active_receiver->alex_antenna=v;
++      if(protocol==NEW_PROTOCOL) {
++          schedule_high_priority();
++      }
++    }
++#ifdef LIMESDR
++    if(protocol==LIMESDR_PROTOCOL) {
++        lime_protocol_set_antenna(v);;
++    }
++#endif
++}
++
++void set_alex_tx_antenna(int v) {
++    transmitter->alex_antenna=v;
++    if(protocol==NEW_PROTOCOL) {
++        schedule_high_priority();
++    }
++}
++
++void set_alex_attenuation(int v) {
++    if(active_receiver->id==0) {
++      active_receiver->alex_attenuation=v;
++      if(protocol==NEW_PROTOCOL) {
++          schedule_high_priority();
++      }
++    }
++}
++
++void radioRestoreState() {
++    char *value;
++
++fprintf(stderr,"radioRestoreState: %s\n",property_path);
++    sem_wait(&property_sem);
++    loadProperties(property_path);
++
++    value=getProperty("buffer_size");
++    if(value) buffer_size=atoi(value);
++    value=getProperty("fft_size");
++    if(value) fft_size=atoi(value);
++    value=getProperty("atlas_penelope");
++    if(value) atlas_penelope=atoi(value);
++    value=getProperty("tx_out_of_band");
++    if(value) tx_out_of_band=atoi(value);
++    value=getProperty("filter_board");
++    if(value) filter_board=atoi(value);
++/*
++    value=getProperty("apollo_tuner");
++    if(value) apollo_tuner=atoi(value);
++    value=getProperty("pa");
++    if(value) pa=atoi(value);
++*/
++    value=getProperty("updates_per_second");
++    if(value) updates_per_second=atoi(value);
++    value=getProperty("display_filled");
++    if(value) display_filled=atoi(value);
++    value=getProperty("display_detector_mode");
++    if(value) display_detector_mode=atoi(value);
++    value=getProperty("display_average_mode");
++    if(value) display_average_mode=atoi(value);
++    value=getProperty("display_average_time");
++    if(value) display_average_time=atof(value);
++    value=getProperty("panadapter_high");
++    if(value) panadapter_high=atoi(value);
++    value=getProperty("panadapter_low");
++    if(value) panadapter_low=atoi(value);
++    value=getProperty("display_sliders");
++    if(value) display_sliders=atoi(value);
++/*
++    value=getProperty("display_toolbar");
++    if(value) display_toolbar=atoi(value);
++*/
++    value=getProperty("waterfall_high");
++    if(value) waterfall_high=atoi(value);
++    value=getProperty("waterfall_low");
++    if(value) waterfall_low=atoi(value);
++    value=getProperty("waterfall_automatic");
++    if(value) waterfall_automatic=atoi(value);
++//    value=getProperty("volume");
++//    if(value) volume=atof(value);
++    value=getProperty("drive");
++    if(value) drive=atof(value);
++    value=getProperty("tune_drive");
++    if(value) tune_drive=atof(value);
++    value=getProperty("mic_gain");
++    if(value) mic_gain=atof(value);
++    value=getProperty("mic_boost");
++    if(value) mic_boost=atof(value);
++    value=getProperty("mic_linein");
++    if(value) mic_linein=atoi(value);
++    value=getProperty("linein_gain");
++    if(value) linein_gain=atoi(value);
++    value=getProperty("mic_ptt_enabled");
++    if(value) mic_ptt_enabled=atof(value);
++    value=getProperty("mic_bias_enabled");
++    if(value) mic_bias_enabled=atof(value);
++    value=getProperty("mic_ptt_tip_bias_ring");
++    if(value) mic_ptt_tip_bias_ring=atof(value);
++
++    value=getProperty("tx_filter_low");
++    if(value) tx_filter_low=atoi(value);
++    value=getProperty("tx_filter_high");
++    if(value) tx_filter_high=atoi(value);
++
++    value=getProperty("step");
++    if(value) step=atoll(value);
++    value=getProperty("cw_keys_reversed");
++    if(value) cw_keys_reversed=atoi(value);
++    value=getProperty("cw_keyer_speed");
++    if(value) cw_keyer_speed=atoi(value);
++    value=getProperty("cw_keyer_mode");
++    if(value) cw_keyer_mode=atoi(value);
++    value=getProperty("cw_keyer_weight");
++    if(value) cw_keyer_weight=atoi(value);
++    value=getProperty("cw_keyer_spacing");
++    if(value) cw_keyer_spacing=atoi(value);
++#ifdef LOCALCW
++    value=getProperty("cw_keyer_internal");
++    if(value) cw_keyer_internal=atoi(value);
++#endif
++    value=getProperty("cw_active_level");
++    if(value) cw_active_level=atoi(value);
++    value=getProperty("cw_keyer_sidetone_volume");
++    if(value) cw_keyer_sidetone_volume=atoi(value);
++    value=getProperty("cw_keyer_ptt_delay");
++    if(value) cw_keyer_ptt_delay=atoi(value);
++    value=getProperty("cw_keyer_hang_time");
++    if(value) cw_keyer_hang_time=atoi(value);
++    value=getProperty("cw_keyer_sidetone_frequency");
++    if(value) cw_keyer_sidetone_frequency=atoi(value);
++    value=getProperty("cw_breakin");
++    if(value) cw_breakin=atoi(value);
++    value=getProperty("vfo_encoder_divisor");
++    if(value) vfo_encoder_divisor=atoi(value);
++    value=getProperty("OCtune");
++    if(value) OCtune=atoi(value);
++    value=getProperty("OCfull_tune_time");
++    if(value) OCfull_tune_time=atoi(value);
++    value=getProperty("OCmemory_tune_time");
++    if(value) OCmemory_tune_time=atoi(value);
++#ifdef FREEDV
++    strcpy(freedv_tx_text_data,"NO TEXT DATA");
++    value=getProperty("freedv_tx_text_data");
++    if(value) strcpy(freedv_tx_text_data,value);
++#endif
++    value=getProperty("smeter");
++    if(value) smeter=atoi(value);
++    value=getProperty("alc");
++    if(value) alc=atoi(value);
++#ifdef OLD_AUDIO
++    value=getProperty("local_audio");
++    if(value) local_audio=atoi(value);
++    value=getProperty("n_selected_output_device");
++    if(value) n_selected_output_device=atoi(value);
++#endif
++    value=getProperty("local_microphone");
++    if(value) local_microphone=atoi(value);
++//    value=getProperty("n_selected_input_device");
++//    if(value) n_selected_input_device=atoi(value);
++    value=getProperty("enable_tx_equalizer");
++    if(value) enable_tx_equalizer=atoi(value);
++    value=getProperty("tx_equalizer.0");
++    if(value) tx_equalizer[0]=atoi(value);
++    value=getProperty("tx_equalizer.1");
++    if(value) tx_equalizer[1]=atoi(value);
++    value=getProperty("tx_equalizer.2");
++    if(value) tx_equalizer[2]=atoi(value);
++    value=getProperty("tx_equalizer.3");
++    if(value) tx_equalizer[3]=atoi(value);
++    value=getProperty("enable_rx_equalizer");
++    if(value) enable_rx_equalizer=atoi(value);
++    value=getProperty("rx_equalizer.0");
++    if(value) rx_equalizer[0]=atoi(value);
++    value=getProperty("rx_equalizer.1");
++    if(value) rx_equalizer[1]=atoi(value);
++    value=getProperty("rx_equalizer.2");
++    if(value) rx_equalizer[2]=atoi(value);
++    value=getProperty("rx_equalizer.3");
++    if(value) rx_equalizer[3]=atoi(value);
++    value=getProperty("rit_increment");
++    if(value) rit_increment=atoi(value);
++    value=getProperty("deviation");
++    if(value) deviation=atoi(value);
++    value=getProperty("pre_emphasize");
++    if(value) pre_emphasize=atoi(value);
++
++    value=getProperty("vox_enabled");
++    if(value) vox_enabled=atoi(value);
++    value=getProperty("vox_threshold");
++    if(value) vox_threshold=atof(value);
++/*
++    value=getProperty("vox_gain");
++    if(value) vox_gain=atof(value);
++*/
++    value=getProperty("vox_hang");
++    if(value) vox_hang=atof(value);
++
++    value=getProperty("binaural");
++    if(value) binaural=atoi(value);
++
++    value=getProperty("frequencyB");
++    if(value) frequencyB=atol(value);
++
++    value=getProperty("modeB");
++    if(value) modeB=atoi(value);
++
++    value=getProperty("filterB");
++    if(value) filterB=atoi(value);
++
++#ifdef GPIO
++    value=getProperty("e1_encoder_action");
++    if(value) e1_encoder_action=atoi(value);
++    value=getProperty("e2_encoder_action");
++    if(value) e2_encoder_action=atoi(value);
++    value=getProperty("e3_encoder_action");
++    if(value) e3_encoder_action=atoi(value);
++#endif
++
++    value=getProperty("receivers");
++    if(value) receivers=atoi(value);
++
++    filterRestoreState();
++    bandRestoreState();
++    memRestoreState();
++    vfo_restore_state();
++
++    sem_post(&property_sem);
++}
++
++void radioSaveState() {
++    int i;
++    char value[80];
++
++    sem_wait(&property_sem);
++    sprintf(value,"%d",buffer_size);
++    setProperty("buffer_size",value);
++    sprintf(value,"%d",fft_size);
++    setProperty("fft_size",value);
++    sprintf(value,"%d",atlas_penelope);
++    setProperty("atlas_penelope",value);
++    sprintf(value,"%d",filter_board);
++    setProperty("filter_board",value);
++    sprintf(value,"%d",tx_out_of_band);
++    setProperty("tx_out_of_band",value);
++/*
++    sprintf(value,"%d",apollo_tuner);
++    setProperty("apollo_tuner",value);
++    sprintf(value,"%d",pa);
++    setProperty("pa",value);
++*/
++    sprintf(value,"%d",updates_per_second);
++    setProperty("updates_per_second",value);
++    sprintf(value,"%d",display_filled);
++    setProperty("display_filled",value);
++    sprintf(value,"%d",display_detector_mode);
++    setProperty("display_detector_mode",value);
++    sprintf(value,"%d",display_average_mode);
++    setProperty("display_average_mode",value);
++    sprintf(value,"%f",display_average_time);
++    setProperty("display_average_time",value);
++    sprintf(value,"%d",panadapter_high);
++    setProperty("panadapter_high",value);
++    sprintf(value,"%d",panadapter_low);
++    setProperty("panadapter_low",value);
++    sprintf(value,"%d",display_sliders);
++    setProperty("display_sliders",value);
++/*
++    sprintf(value,"%d",display_toolbar);
++    setProperty("display_toolbar",value);
++*/
++    sprintf(value,"%d",waterfall_high);
++    setProperty("waterfall_high",value);
++    sprintf(value,"%d",waterfall_low);
++    setProperty("waterfall_low",value);
++    sprintf(value,"%d",waterfall_automatic);
++    setProperty("waterfall_automatic",value);
++//    sprintf(value,"%f",volume);
++//    setProperty("volume",value);
++    sprintf(value,"%f",mic_gain);
++    setProperty("mic_gain",value);
++    sprintf(value,"%f",drive);
++    setProperty("drive",value);
++    sprintf(value,"%f",tune_drive);
++    setProperty("tune_drive",value);
++    sprintf(value,"%d",mic_boost);
++    setProperty("mic_boost",value);
++    sprintf(value,"%d",mic_linein);
++    setProperty("mic_linein",value);
++    sprintf(value,"%d",linein_gain);
++    setProperty("linein_gain",value);
++    sprintf(value,"%d",mic_ptt_enabled);
++    setProperty("mic_ptt_enabled",value);
++    sprintf(value,"%d",mic_bias_enabled);
++    setProperty("mic_bias_enabled",value);
++    sprintf(value,"%d",mic_ptt_tip_bias_ring);
++    setProperty("mic_ptt_tip_bias_ring",value);
++    sprintf(value,"%d",tx_filter_low);
++    setProperty("tx_filter_low",value);
++    sprintf(value,"%d",tx_filter_high);
++    setProperty("tx_filter_high",value);
++
++    sprintf(value,"%lld",step);
++    setProperty("step",value);
++    sprintf(value,"%d",cw_keys_reversed);
++    setProperty("cw_keys_reversed",value);
++    sprintf(value,"%d",cw_keyer_speed);
++    setProperty("cw_keyer_speed",value);
++    sprintf(value,"%d",cw_keyer_mode);
++    setProperty("cw_keyer_mode",value);
++    sprintf(value,"%d",cw_keyer_weight);
++    setProperty("cw_keyer_weight",value);
++    sprintf(value,"%d",cw_keyer_spacing);
++    setProperty("cw_keyer_spacing",value);
++    sprintf(value,"%d",cw_keyer_internal);
++    setProperty("cw_keyer_internal",value);
++    sprintf(value,"%d",cw_active_level);
++    setProperty("cw_active_level",value);
++    sprintf(value,"%d",cw_keyer_sidetone_volume);
++    setProperty("cw_keyer_sidetone_volume",value);
++    sprintf(value,"%d",cw_keyer_ptt_delay);
++    setProperty("cw_keyer_ptt_delay",value);
++    sprintf(value,"%d",cw_keyer_hang_time);
++    setProperty("cw_keyer_hang_time",value);
++    sprintf(value,"%d",cw_keyer_sidetone_frequency);
++    setProperty("cw_keyer_sidetone_frequency",value);
++    sprintf(value,"%d",cw_breakin);
++    setProperty("cw_breakin",value);
++    sprintf(value,"%d",vfo_encoder_divisor);
++    setProperty("vfo_encoder_divisor",value);
++    sprintf(value,"%d",OCtune);
++    setProperty("OCtune",value);
++    sprintf(value,"%d",OCfull_tune_time);
++    setProperty("OCfull_tune_time",value);
++    sprintf(value,"%d",OCmemory_tune_time);
++    setProperty("OCmemory_tune_time",value);
++#ifdef FREEDV
++    if(strlen(freedv_tx_text_data)>0) {
++      setProperty("freedv_tx_text_data",freedv_tx_text_data);
++    }
++#endif
++    sprintf(value,"%d",smeter);
++    setProperty("smeter",value);
++    sprintf(value,"%d",alc);
++    setProperty("alc",value);
++#ifdef OLD_AUDIO
++    sprintf(value,"%d",local_audio);
++    setProperty("local_audio",value);
++    sprintf(value,"%d",n_selected_output_device);
++    setProperty("n_selected_output_device",value);
++#endif
++    sprintf(value,"%d",local_microphone);
++    setProperty("local_microphone",value);
++//    sprintf(value,"%d",n_selected_input_device);
++//    setProperty("n_selected_input_device",value);
++
++    sprintf(value,"%d",enable_tx_equalizer);
++    setProperty("enable_tx_equalizer",value);
++    sprintf(value,"%d",tx_equalizer[0]);
++    setProperty("tx_equalizer.0",value);
++    sprintf(value,"%d",tx_equalizer[1]);
++    setProperty("tx_equalizer.1",value);
++    sprintf(value,"%d",tx_equalizer[2]);
++    setProperty("tx_equalizer.2",value);
++    sprintf(value,"%d",tx_equalizer[3]);
++    setProperty("tx_equalizer.3",value);
++    sprintf(value,"%d",enable_rx_equalizer);
++    setProperty("enable_rx_equalizer",value);
++    sprintf(value,"%d",rx_equalizer[0]);
++    setProperty("rx_equalizer.0",value);
++    sprintf(value,"%d",rx_equalizer[1]);
++    setProperty("rx_equalizer.1",value);
++    sprintf(value,"%d",rx_equalizer[2]);
++    setProperty("rx_equalizer.2",value);
++    sprintf(value,"%d",rx_equalizer[3]);
++    setProperty("rx_equalizer.3",value);
++    sprintf(value,"%d",rit_increment);
++    setProperty("rit_increment",value);
++    sprintf(value,"%d",deviation);
++    setProperty("deviation",value);
++    sprintf(value,"%d",pre_emphasize);
++    setProperty("pre_emphasize",value);
++
++    sprintf(value,"%d",vox_enabled);
++    setProperty("vox_enabled",value);
++    sprintf(value,"%f",vox_threshold);
++    setProperty("vox_threshold",value);
++/*
++    sprintf(value,"%f",vox_gain);
++    setProperty("vox_gain",value);
++*/
++    sprintf(value,"%f",vox_hang);
++    setProperty("vox_hang",value);
++
++    sprintf(value,"%d",binaural);
++    setProperty("binaural",value);
++
++    sprintf(value,"%lld",frequencyB);
++    setProperty("frequencyB",value);
++    sprintf(value,"%d",modeB);
++    setProperty("modeB",value);
++    sprintf(value,"%d",filterB);
++    setProperty("filterB",value);
++
++#ifdef GPIO
++    sprintf(value,"%d",e1_encoder_action);
++    setProperty("e1_encoder_action",value);
++    sprintf(value,"%d",e2_encoder_action);
++    setProperty("e2_encoder_action",value);
++    sprintf(value,"%d",e3_encoder_action);
++    setProperty("e3_encoder_action",value);
++#endif
++
++
++    vfo_save_state();
++    sprintf(value,"%d",receivers);
++    setProperty("receivers",value);
++    for(i=0;i<receivers;i++) {
++      receiver_save_state(receiver[i]);
++    }
++    transmitter_save_state(transmitter);
++
++    filterSaveState();
++    bandSaveState();
++    memSaveState();
++    saveProperties(property_path);
++    sem_post(&property_sem);
++}
++
++void calculate_display_average(RECEIVER *rx) {
++  double display_avb;
++  int display_average;
++
++  double t=0.001*display_average_time;
++  display_avb = exp(-1.0 / ((double)rx->fps * t));
++  display_average = max(2, (int)min(60, (double)rx->fps * t));
++  SetDisplayAvBackmult(rx->id, 0, display_avb);
++  SetDisplayNumAverage(rx->id, 0, display_average);
++}
diff --cc toolbar.c
index 9e2284bc21682ae8137dc57d699293cac93ea0f5,27019901b36f4b59cd9e922ccbc62596794a36c7..e0cc785d4bc110c68f6343b25c4f57565b69efc9
+++ b/toolbar.c
  #include "channel.h"
  #include "wdsp.h"
  #include "radio.h"
+ #include "receiver.h"
  #include "property.h"
  #include "new_menu.h"
+ #include "button_text.h"
 +#ifdef RADIOBERRY
 +#include "radioberry.h"       
 +#endif
  
+ #define MAX_FUNCTION 3
  int function=0;
  
  static int width;
diff --cc toolbar.c.orig
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..93434081fecc1fc254de23335faf9fb2508df15a
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,883 @@@
++/* Copyright (C)
++* 2015 - 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 <semaphore.h>
++#include <stdio.h>
++#include <string.h>
++#ifdef GPIO
++#include "gpio.h"
++#endif
++#include "toolbar.h"
++#include "mode.h"
++#include "filter.h"
++#include "frequency.h"
++#include "bandstack.h"
++#include "band.h"
++#include "discovered.h"
++#include "new_protocol.h"
++#include "vfo.h"
++#include "alex.h"
++#include "agc.h"
++#include "channel.h"
++#include "wdsp.h"
++#include "radio.h"
++#include "receiver.h"
++#include "property.h"
++#include "new_menu.h"
++<<<<<<< HEAD
++#ifdef RADIOBERRY
++#include "radioberry.h"       
++#endif
++=======
++#include "button_text.h"
++>>>>>>> upstream/master
++
++#define MAX_FUNCTION 3
++int function=0;
++
++static int width;
++static int height;
++
++static GtkWidget *parent_window;
++static GtkWidget *toolbar;
++
++static GtkWidget *last_dialog;
++
++static GtkWidget *sim_mox;
++static GtkWidget *sim_s1;
++static GtkWidget *sim_s2;
++static GtkWidget *sim_s3;
++static GtkWidget *sim_s4;
++static GtkWidget *sim_s5;
++static GtkWidget *sim_s6;
++static GtkWidget *sim_function;
++
++
++static GtkWidget *last_band;
++static GtkWidget *last_bandstack;
++static GtkWidget *last_mode;
++static GtkWidget *last_filter;
++
++static GdkRGBA white;
++static GdkRGBA gray;
++
++static gint rit_timer;
++
++static gboolean rit_timer_cb(gpointer data) {
++  int i=(int)data;
++  vfo[active_receiver->id].rit+=(i*rit_increment);
++  if(vfo[active_receiver->id].rit>1000) vfo[active_receiver->id].rit=1000;
++  if(vfo[active_receiver->id].rit<-1000) vfo[active_receiver->id].rit=-1000;
++  vfo_update(NULL);
++  return TRUE;
++}
++
++void update_toolbar_labels() {
++  switch(function) {
++    case 0:
++      gtk_button_set_label(GTK_BUTTON(sim_mox),"Mox");
++      gtk_button_set_label(GTK_BUTTON(sim_s1),"Band");
++      gtk_button_set_label(GTK_BUTTON(sim_s2),"BStack");
++      gtk_button_set_label(GTK_BUTTON(sim_s3),"Mode");
++      gtk_button_set_label(GTK_BUTTON(sim_s4),"Filter");
++      gtk_button_set_label(GTK_BUTTON(sim_s5),"Noise");
++      gtk_button_set_label(GTK_BUTTON(sim_s6),"AGC");
++      set_button_text_color(sim_s1,"black");
++      set_button_text_color(sim_s2,"black");
++      break;
++
++    case 1:
++      gtk_button_set_label(GTK_BUTTON(sim_mox),"Mox");
++      gtk_button_set_label(GTK_BUTTON(sim_s1),"Lock");
++      gtk_button_set_label(GTK_BUTTON(sim_s2),"CTUN");
++      gtk_button_set_label(GTK_BUTTON(sim_s3),"A>B");
++      gtk_button_set_label(GTK_BUTTON(sim_s4),"A<B");
++      gtk_button_set_label(GTK_BUTTON(sim_s5),"A<>B");
++      gtk_button_set_label(GTK_BUTTON(sim_s6),"Split");
++      break;
++    case 2:
++      gtk_button_set_label(GTK_BUTTON(sim_mox),"Mox");
++      gtk_button_set_label(GTK_BUTTON(sim_s1),"Freq");
++      gtk_button_set_label(GTK_BUTTON(sim_s2),"Mem");
++      gtk_button_set_label(GTK_BUTTON(sim_s3),"Vox");
++      gtk_button_set_label(GTK_BUTTON(sim_s4),"RIT+");
++      gtk_button_set_label(GTK_BUTTON(sim_s5),"RIT-");
++      gtk_button_set_label(GTK_BUTTON(sim_s6),"");
++      if(full_tune) {
++        set_button_text_color(sim_s1,"red");
++      }
++      if(memory_tune) {
++        set_button_text_color(sim_s2,"red");
++      }
++      break;
++    case 3:
++      gtk_button_set_label(GTK_BUTTON(sim_mox),"Tune");
++      if(OCtune!=0 && OCfull_tune_time!=0) {
++        gtk_button_set_label(GTK_BUTTON(sim_s1),"Full");
++      } else {
++        gtk_button_set_label(GTK_BUTTON(sim_s1),"");
++      }
++      if(OCtune!=0 && OCmemory_tune_time!=0) {
++        gtk_button_set_label(GTK_BUTTON(sim_s2),"Memory");
++      } else {
++        gtk_button_set_label(GTK_BUTTON(sim_s2),"");
++      }
++      gtk_button_set_label(GTK_BUTTON(sim_s3),"");
++      gtk_button_set_label(GTK_BUTTON(sim_s4),"");
++      gtk_button_set_label(GTK_BUTTON(sim_s5),"");
++      gtk_button_set_label(GTK_BUTTON(sim_s6),"");
++      if(full_tune) {
++        set_button_text_color(sim_s1,"red");
++      }
++      if(memory_tune) {
++        set_button_text_color(sim_s2,"red");
++      }
++      break;
++  }
++}
++
++static void close_cb(GtkWidget *widget, gpointer data) {
++  gtk_widget_destroy(last_dialog);
++  last_dialog=NULL;
++}
++
++void band_cb(GtkWidget *widget, gpointer data) {
++  start_band();
++}
++
++void bandstack_cb(GtkWidget *widget, gpointer data) {
++  start_bandstack();
++}
++
++void mode_cb(GtkWidget *widget, gpointer data) {
++  start_mode();
++}
++
++void filter_cb(GtkWidget *widget, gpointer data) {
++  start_filter();
++}
++
++void agc_cb(GtkWidget *widget, gpointer data) {
++  start_agc();
++}
++
++void noise_cb(GtkWidget *widget, gpointer data) {
++  start_noise();
++}
++
++void ctun_cb (GtkWidget *widget, gpointer data) {
++  int 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(active_receiver,vfo[id].offset);
++  vfo_update(NULL);
++}
++
++static void atob_cb (GtkWidget *widget, gpointer data) {
++  vfo_a_to_b();
++}
++
++static void btoa_cb (GtkWidget *widget, gpointer data) {
++  vfo_b_to_a();
++}
++
++static void aswapb_cb (GtkWidget *widget, gpointer data) {
++  vfo_a_swap_b();
++}
++
++static void split_cb (GtkWidget *widget, gpointer data) {
++  split=split==1?0:1;
++  if(split) {
++    tx_set_mode(transmitter,vfo[VFO_B].mode);
++  } else {
++    tx_set_mode(transmitter,vfo[VFO_A].mode);
++  }
++  vfo_update(NULL);
++}
++
++static void rit_cb(GtkWidget *widget, gpointer data) {
++  int i=(int)data;
++  vfo[active_receiver->id].rit+=i*rit_increment;
++  if(vfo[active_receiver->id].rit>1000) vfo[active_receiver->id].rit=1000;
++  if(vfo[active_receiver->id].rit<-1000) vfo[active_receiver->id].rit=-1000;
++  vfo_update(NULL);
++  rit_timer=g_timeout_add(200,rit_timer_cb,(void *)i);
++}
++
++static void freq_cb(GtkWidget *widget, gpointer data) {
++  start_vfo();
++}
++
++static void mem_cb(GtkWidget *widget, gpointer data) {
++  start_store();
++}
++
++static void vox_cb(GtkWidget *widget, gpointer data) {
++  vox=vox==1?0:1;
++  vfo_update(NULL);
++}
++
++static void stop() {
++#ifdef RADIOBERRY
++      if(protocol==RADIOBERRY_PROTOCOL) {
++              radioberry_protocol_stop();
++      }
++#endif
++  if(protocol==ORIGINAL_PROTOCOL) {
++    old_protocol_stop();
++  } else {
++    new_protocol_stop();
++  }
++#ifdef GPIO
++  gpio_close();
++#endif
++}
++
++static void yes_cb(GtkWidget *widget, gpointer data) {
++  stop();
++  _exit(0);
++}
++
++static void halt_cb(GtkWidget *widget, gpointer data) {
++  stop();
++  system("shutdown -h -P now");
++  _exit(0);
++}
++
++static void exit_cb(GtkWidget *widget, gpointer data) {
++
++  radioSaveState();
++
++  GtkWidget *dialog=gtk_dialog_new_with_buttons("Exit",GTK_WINDOW(parent_window),GTK_DIALOG_DESTROY_WITH_PARENT,NULL,NULL);
++
++  GtkWidget *content=gtk_dialog_get_content_area(GTK_DIALOG(dialog));
++  GtkWidget *grid=gtk_grid_new();
++
++  gtk_grid_set_column_homogeneous(GTK_GRID(grid),TRUE);
++  gtk_grid_set_row_homogeneous(GTK_GRID(grid),TRUE);
++
++  GtkWidget *label=gtk_label_new("Exit?");
++  //gtk_widget_override_font(label, pango_font_description_from_string("Arial 18"));
++  gtk_widget_show(label);
++  gtk_grid_attach(GTK_GRID(grid),label,1,0,1,1);
++
++  GtkWidget *b_yes=gtk_button_new_with_label("Yes");
++  //gtk_widget_override_font(b_yes, pango_font_description_from_string("Arial 18"));
++  gtk_widget_show(b_yes);
++  gtk_grid_attach(GTK_GRID(grid),b_yes,0,1,1,1);
++  g_signal_connect(b_yes,"pressed",G_CALLBACK(yes_cb),NULL);
++
++  GtkWidget *b_halt=gtk_button_new_with_label("Halt System");
++  //gtk_widget_override_font(b_halt, pango_font_description_from_string("Arial 18"));
++  gtk_widget_show(b_halt);
++  gtk_grid_attach(GTK_GRID(grid),b_halt,2,1,1,1);
++  g_signal_connect(b_halt,"pressed",G_CALLBACK(halt_cb),NULL);
++
++  gtk_container_add(GTK_CONTAINER(content),grid);
++  GtkWidget *close_button=gtk_dialog_add_button(GTK_DIALOG(dialog),"Cancel",GTK_RESPONSE_OK);
++  //gtk_widget_override_font(close_button, pango_font_description_from_string("Arial 18"));
++  gtk_widget_show_all(dialog);
++
++  g_signal_connect_swapped (dialog,
++                           "response",
++                           G_CALLBACK (gtk_widget_destroy),
++                           dialog);
++
++  int result=gtk_dialog_run(GTK_DIALOG(dialog));
++
++}
++
++static void cw_keyer_internal_cb(GtkWidget *widget, gpointer data) {
++  cw_keyer_internal=cw_keyer_internal==1?0:1;
++  cw_changed();
++}
++
++static void cw_keyer_speed_value_changed_cb(GtkWidget *widget, gpointer data) {
++  cw_keyer_speed=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(widget));
++  cw_changed();
++}
++
++static void cw_breakin_cb(GtkWidget *widget, gpointer data) {
++  cw_breakin=cw_breakin==1?0:1;
++  cw_changed();
++}
++
++static void cw_keyer_hang_time_value_changed_cb(GtkWidget *widget, gpointer data) {
++  cw_keyer_hang_time=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(widget));
++  cw_changed();
++}
++
++static void cw_keys_reversed_cb(GtkWidget *widget, gpointer data) {
++  cw_keys_reversed=cw_keys_reversed==1?0:1;
++  cw_changed();
++}
++
++static void cw_keyer_mode_cb(GtkWidget *widget, gpointer data) {
++  cw_keyer_mode=(int)data;
++  cw_changed();
++}
++
++static void vfo_divisor_value_changed_cb(GtkWidget *widget, gpointer data) {
++  vfo_encoder_divisor=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(widget));
++}
++
++static void panadapter_high_value_changed_cb(GtkWidget *widget, gpointer data) {
++  panadapter_high=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(widget));
++}
++
++static void panadapter_low_value_changed_cb(GtkWidget *widget, gpointer data) {
++  panadapter_low=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(widget));
++}
++
++static void waterfall_high_value_changed_cb(GtkWidget *widget, gpointer data) {
++  waterfall_high=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(widget));
++}
++
++static void waterfall_low_value_changed_cb(GtkWidget *widget, gpointer data) {
++  waterfall_low=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(widget));
++}
++
++static void waterfall_automatic_cb(GtkWidget *widget, gpointer data) {
++  waterfall_automatic=waterfall_automatic==1?0:1;
++}
++
++static void config_cb(GtkWidget *widget, gpointer data) {
++  GtkWidget *dialog=gtk_dialog_new_with_buttons("Audio",GTK_WINDOW(parent_window),GTK_DIALOG_DESTROY_WITH_PARENT,NULL,NULL);
++  GtkWidget *content=gtk_dialog_get_content_area(GTK_DIALOG(dialog));
++  GtkWidget *grid=gtk_grid_new();
++  gtk_grid_set_column_homogeneous(GTK_GRID(grid),TRUE);
++  gtk_grid_set_row_homogeneous(GTK_GRID(grid),TRUE);
++
++  GtkWidget *display_label=gtk_label_new("Display: ");
++  //gtk_widget_override_font(display_label, pango_font_description_from_string("Arial 18"));
++  gtk_widget_show(display_label);
++  gtk_grid_attach(GTK_GRID(grid),display_label,0,0,1,1);
++
++  GtkWidget *panadapter_high_label=gtk_label_new("Panadapter High: ");
++  //gtk_widget_override_font(panadapter_high_label, pango_font_description_from_string("Arial 18"));
++  gtk_widget_show(panadapter_high_label);
++  gtk_grid_attach(GTK_GRID(grid),panadapter_high_label,0,1,1,1);
++
++  GtkWidget *panadapter_high_r=gtk_spin_button_new_with_range(-220.0,100.0,1.0);
++  //gtk_widget_override_font(panadapter_high_r, pango_font_description_from_string("Arial 18"));
++  gtk_spin_button_set_value(GTK_SPIN_BUTTON(panadapter_high_r),(double)panadapter_high);
++  gtk_widget_show(panadapter_high_r);
++  gtk_grid_attach(GTK_GRID(grid),panadapter_high_r,1,1,1,1);
++  g_signal_connect(panadapter_high_r,"value_changed",G_CALLBACK(panadapter_high_value_changed_cb),NULL);
++
++  GtkWidget *panadapter_low_label=gtk_label_new("Panadapter Low: ");
++  //gtk_widget_override_font(panadapter_low_label, pango_font_description_from_string("Arial 18"));
++  gtk_widget_show(panadapter_low_label);
++  gtk_grid_attach(GTK_GRID(grid),panadapter_low_label,0,2,1,1);
++
++  GtkWidget *panadapter_low_r=gtk_spin_button_new_with_range(-220.0,100.0,1.0);
++  //gtk_widget_override_font(panadapter_low_r, pango_font_description_from_string("Arial 18"));
++  gtk_spin_button_set_value(GTK_SPIN_BUTTON(panadapter_low_r),(double)panadapter_low);
++  gtk_widget_show(panadapter_low_r);
++  gtk_grid_attach(GTK_GRID(grid),panadapter_low_r,1,2,1,1);
++  g_signal_connect(panadapter_low_r,"value_changed",G_CALLBACK(panadapter_low_value_changed_cb),NULL);
++
++  GtkWidget *waterfall_automatic_label=gtk_label_new("Waterfall Automatic: ");
++  //gtk_widget_override_font(waterfall_automatic_label, pango_font_description_from_string("Arial 18"));
++  gtk_widget_show(waterfall_automatic_label);
++  gtk_grid_attach(GTK_GRID(grid),waterfall_automatic_label,0,3,1,1);
++
++  GtkWidget *waterfall_automatic_b=gtk_check_button_new();
++  ////gtk_widget_override_font(waterfall_automatic_b, pango_font_description_from_string("Arial 18"));
++  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (waterfall_automatic_b), waterfall_automatic);
++  gtk_widget_show(waterfall_automatic_b);
++  gtk_grid_attach(GTK_GRID(grid),waterfall_automatic_b,1,3,1,1);
++  g_signal_connect(waterfall_automatic_b,"toggled",G_CALLBACK(waterfall_automatic_cb),NULL);
++
++  GtkWidget *waterfall_high_label=gtk_label_new("Waterfall High: ");
++  //gtk_widget_override_font(waterfall_high_label, pango_font_description_from_string("Arial 18"));
++  gtk_widget_show(waterfall_high_label);
++  gtk_grid_attach(GTK_GRID(grid),waterfall_high_label,0,4,1,1);
++
++  GtkWidget *waterfall_high_r=gtk_spin_button_new_with_range(-220.0,100.0,1.0);
++  //gtk_widget_override_font(waterfall_high_r, pango_font_description_from_string("Arial 18"));
++  gtk_spin_button_set_value(GTK_SPIN_BUTTON(waterfall_high_r),(double)waterfall_high);
++  gtk_widget_show(waterfall_high_r);
++  gtk_grid_attach(GTK_GRID(grid),waterfall_high_r,1,4,1,1);
++  g_signal_connect(waterfall_high_r,"value_changed",G_CALLBACK(waterfall_high_value_changed_cb),NULL);
++
++  GtkWidget *waterfall_low_label=gtk_label_new("Waterfall Low: ");
++  //gtk_widget_override_font(waterfall_low_label, pango_font_description_from_string("Arial 18"));
++  gtk_widget_show(waterfall_low_label);
++  gtk_grid_attach(GTK_GRID(grid),waterfall_low_label,0,5,1,1);
++
++  GtkWidget *waterfall_low_r=gtk_spin_button_new_with_range(-220.0,100.0,1.0);
++  //gtk_widget_override_font(waterfall_low_r, pango_font_description_from_string("Arial 18"));
++  gtk_spin_button_set_value(GTK_SPIN_BUTTON(waterfall_low_r),(double)waterfall_low);
++  gtk_widget_show(waterfall_low_r);
++  gtk_grid_attach(GTK_GRID(grid),waterfall_low_r,1,5,1,1);
++  g_signal_connect(waterfall_low_r,"value_changed",G_CALLBACK(waterfall_low_value_changed_cb),NULL);
++
++
++  GtkWidget *vfo_encoder_label=gtk_label_new("VFO Encoder: ");
++  //gtk_widget_override_font(vfo_encoder_label, pango_font_description_from_string("Arial 18"));
++  gtk_widget_show(vfo_encoder_label);
++  gtk_grid_attach(GTK_GRID(grid),vfo_encoder_label,0,6,1,1);
++
++  GtkWidget *vfo_divisor_label=gtk_label_new("Divisor: ");
++  //gtk_widget_override_font(vfo_divisor_label, pango_font_description_from_string("Arial 18"));
++  gtk_widget_show(vfo_divisor_label);
++  gtk_grid_attach(GTK_GRID(grid),vfo_divisor_label,0,7,1,1);
++
++  GtkWidget *vfo_divisor=gtk_spin_button_new_with_range(1.0,60.0,1.0);
++  //gtk_widget_override_font(vfo_divisor, pango_font_description_from_string("Arial 18"));
++  gtk_spin_button_set_value(GTK_SPIN_BUTTON(vfo_divisor),(double)vfo_encoder_divisor);
++  gtk_widget_show(vfo_divisor);
++  gtk_grid_attach(GTK_GRID(grid),vfo_divisor,1,7,1,1);
++  g_signal_connect(vfo_divisor,"value_changed",G_CALLBACK(vfo_divisor_value_changed_cb),NULL);
++
++  gtk_container_add(GTK_CONTAINER(content),grid);
++  GtkWidget *close_button=gtk_dialog_add_button(GTK_DIALOG(dialog),"Close",GTK_RESPONSE_OK);
++  //gtk_widget_override_font(close_button, pango_font_description_from_string("Arial 18"));
++  gtk_widget_show_all(dialog);
++
++  g_signal_connect_swapped (dialog,
++                           "response",
++                           G_CALLBACK (gtk_widget_destroy),
++                           dialog);
++
++  int result=gtk_dialog_run(GTK_DIALOG(dialog));
++}
++
++static void cw_cb(GtkWidget *widget, gpointer data) {
++  GtkWidget *dialog=gtk_dialog_new_with_buttons("CW",GTK_WINDOW(parent_window),GTK_DIALOG_DESTROY_WITH_PARENT,NULL,NULL);
++  GtkWidget *content=gtk_dialog_get_content_area(GTK_DIALOG(dialog));
++  GtkWidget *grid=gtk_grid_new();
++  //gtk_grid_set_column_homogeneous(GTK_GRID(grid),TRUE);
++  gtk_grid_set_row_homogeneous(GTK_GRID(grid),TRUE);
++
++
++  GtkWidget *cw_keyer_internal_b=gtk_check_button_new_with_label("CW Internal - Speed (WPM)");
++  //gtk_widget_override_font(cw_keyer_internal_b, pango_font_description_from_string("Arial 18"));
++  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (cw_keyer_internal_b), cw_keyer_internal);
++  gtk_widget_show(cw_keyer_internal_b);
++  gtk_grid_attach(GTK_GRID(grid),cw_keyer_internal_b,0,0,1,1);
++  g_signal_connect(cw_keyer_internal_b,"toggled",G_CALLBACK(cw_keyer_internal_cb),NULL);
++
++  GtkWidget *cw_keyer_speed_b=gtk_spin_button_new_with_range(1.0,60.0,1.0);
++  //gtk_widget_override_font(cw_keyer_speed_b, pango_font_description_from_string("Arial 18"));
++  gtk_spin_button_set_value(GTK_SPIN_BUTTON(cw_keyer_speed_b),(double)cw_keyer_speed);
++  gtk_widget_show(cw_keyer_speed_b);
++  gtk_grid_attach(GTK_GRID(grid),cw_keyer_speed_b,1,0,1,1);
++  g_signal_connect(cw_keyer_speed_b,"value_changed",G_CALLBACK(cw_keyer_speed_value_changed_cb),NULL);
++
++  GtkWidget *cw_breakin_b=gtk_check_button_new_with_label("CW Break In - Delay (ms)");
++  //gtk_widget_override_font(cw_breakin_b, pango_font_description_from_string("Arial 18"));
++  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (cw_breakin_b), cw_breakin);
++  gtk_widget_show(cw_breakin_b);
++  gtk_grid_attach(GTK_GRID(grid),cw_breakin_b,0,1,1,1);
++  g_signal_connect(cw_breakin_b,"toggled",G_CALLBACK(cw_breakin_cb),NULL);
++
++  GtkWidget *cw_keyer_hang_time_b=gtk_spin_button_new_with_range(0.0,1000.0,1.0);
++  //gtk_widget_override_font(cw_keyer_hang_time_b, pango_font_description_from_string("Arial 18"));
++  gtk_spin_button_set_value(GTK_SPIN_BUTTON(cw_keyer_hang_time_b),(double)cw_keyer_hang_time);
++  gtk_widget_show(cw_keyer_hang_time_b);
++  gtk_grid_attach(GTK_GRID(grid),cw_keyer_hang_time_b,1,1,1,1);
++  g_signal_connect(cw_keyer_hang_time_b,"value_changed",G_CALLBACK(cw_keyer_hang_time_value_changed_cb),NULL);
++  
++  GtkWidget *cw_keyer_straight=gtk_radio_button_new_with_label(NULL,"CW KEYER STRAIGHT");
++  //gtk_widget_override_font(cw_keyer_straight, pango_font_description_from_string("Arial 18"));
++  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (cw_keyer_straight), cw_keyer_mode==KEYER_STRAIGHT);
++  gtk_widget_show(cw_keyer_straight);
++  gtk_grid_attach(GTK_GRID(grid),cw_keyer_straight,0,2,1,1);
++  g_signal_connect(cw_keyer_straight,"pressed",G_CALLBACK(cw_keyer_mode_cb),(gpointer *)KEYER_STRAIGHT);
++
++  GtkWidget *cw_keyer_mode_a=gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(cw_keyer_straight),"CW KEYER MODE A");
++  //gtk_widget_override_font(cw_keyer_mode_a, pango_font_description_from_string("Arial 18"));
++  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (cw_keyer_mode_a), cw_keyer_mode==KEYER_MODE_A);
++  gtk_widget_show(cw_keyer_mode_a);
++  gtk_grid_attach(GTK_GRID(grid),cw_keyer_mode_a,0,3,1,1);
++  g_signal_connect(cw_keyer_mode_a,"pressed",G_CALLBACK(cw_keyer_mode_cb),(gpointer *)KEYER_MODE_A);
++
++  GtkWidget *cw_keyer_mode_b=gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(cw_keyer_mode_a),"CW KEYER MODE B");
++  //gtk_widget_override_font(cw_keyer_mode_b, pango_font_description_from_string("Arial 18"));
++  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (cw_keyer_mode_b), cw_keyer_mode==KEYER_MODE_B);
++  gtk_widget_show(cw_keyer_mode_b);
++  gtk_grid_attach(GTK_GRID(grid),cw_keyer_mode_b,0,4,1,1);
++  g_signal_connect(cw_keyer_mode_b,"pressed",G_CALLBACK(cw_keyer_mode_cb),(gpointer *)KEYER_MODE_B);
++
++  gtk_container_add(GTK_CONTAINER(content),grid);
++  GtkWidget *close_button=gtk_dialog_add_button(GTK_DIALOG(dialog),"Close",GTK_RESPONSE_OK);
++  //gtk_widget_override_font(close_button, pango_font_description_from_string("Arial 18"));
++  gtk_widget_show_all(dialog);
++
++  g_signal_connect_swapped (dialog,
++                           "response",
++                           G_CALLBACK (gtk_widget_destroy),
++                           dialog);
++
++  int result=gtk_dialog_run(GTK_DIALOG(dialog));
++}
++
++void lock_cb(GtkWidget *widget, gpointer data) {
++  locked=locked==1?0:1;
++  vfo_update(NULL);
++}
++
++void mox_cb(GtkWidget *widget, gpointer data) {
++  if(getTune()==1) {
++    setTune(0);
++  }
++  if(getMox()==1) {
++    setMox(0);
++    if(ptt) {
++      ptt=0;
++    }
++  } else if(canTransmit() || tx_out_of_band) {
++    setMox(1);
++  }
++  g_idle_add(vfo_update,NULL);
++}
++
++int mox_update(void *data) {
++  if(getTune()==1) {
++    setTune(0);
++  }
++  setMox((int)data);
++  return 0;
++}
++
++int ptt_update(void *data) {
++  int mode;
++  if(split) {
++    mode=vfo[1].mode;
++  } else {
++    mode=vfo[0].mode;
++  }
++  if(protocol==NEW_PROTOCOL || (mode!=modeCWU && mode!=modeCWL)) {
++    mox_cb(NULL,NULL);
++  }
++  return 0;
++}
++
++void tune_cb(GtkWidget *widget, gpointer data) {
++  if(getMox()==1) {
++    setMox(0);
++  }
++  if(getTune()==1) {
++    setTune(0);
++  } else if(canTransmit() || tx_out_of_band) {
++    setTune(1);
++  }
++  vfo_update(NULL);
++}
++
++void sim_s1_pressed_cb(GtkWidget *widget, gpointer data) {
++  switch(function) {
++    case 0:
++      band_cb(widget,data);
++      break;
++    case 1:
++      lock_cb(widget,data);
++      break;
++    case 2:
++      freq_cb(widget,data);
++      break;
++    case 3:
++      full_tune=full_tune==1?0:1;
++      if(full_tune) {
++        set_button_text_color(sim_s2,"black");
++        set_button_text_color(sim_s1,"red");
++      } else {
++        set_button_text_color(sim_s1,"black");
++      }
++      break;
++  }
++}
++
++void sim_s1_released_cb(GtkWidget *widget, gpointer data) {
++  switch(function) {
++    case 0:
++      break;
++    case 1:
++      break;
++    case 2:
++      break;
++    case 3:
++      break;
++  }
++}
++
++void sim_s2_pressed_cb(GtkWidget *widget, gpointer data) {
++  switch(function) {
++    case 0:
++      bandstack_cb(widget,data);
++      break;
++    case 1:
++      ctun_cb(widget,data);
++      break;
++    case 2:
++      mem_cb(widget,data);
++      break;
++    case 3:
++      memory_tune=memory_tune==1?0:1;
++      if(memory_tune) {
++        set_button_text_color(sim_s1,"black");
++        set_button_text_color(sim_s2,"red");
++      } else {
++        set_button_text_color(sim_s2,"black");
++      }
++      break;
++  }
++}
++
++void sim_s2_released_cb(GtkWidget *widget, gpointer data) {
++  switch(function) {
++    case 0:
++      break;
++    case 1:
++      break;
++    case 2:
++      break;
++    case 3:
++      break;
++  }
++}
++
++
++void sim_s3_pressed_cb(GtkWidget *widget, gpointer data) {
++  switch(function) {
++    case 0:
++      mode_cb(widget,data);
++      break;
++    case 1:
++      // A>B
++      atob_cb(widget,data);
++      break;
++    case 2:
++      vox_cb(widget,data);
++      break;
++    case 3:
++      break;
++  }
++}
++
++void sim_s3_released_cb(GtkWidget *widget, gpointer data) {
++  switch(function) {
++    case 0:
++      break;
++    case 1:
++      break;
++    case 2:
++      break;
++    case 3:
++      break;
++  }
++}
++
++void sim_s4_pressed_cb(GtkWidget *widget, gpointer data) {
++  switch(function) {
++    case 0:
++      filter_cb(widget,data);
++      break;
++    case 1:
++      // A<B
++      btoa_cb(widget,data);
++      break;
++    case 2:
++      rit_cb(widget,(void *)1);
++      break;
++    case 3:
++      break;
++  }
++}
++
++void sim_s4_released_cb(GtkWidget *widget, gpointer data) {
++  switch(function) {
++    case 0:
++      break;
++    case 1:
++      break;
++    case 2:
++      g_source_remove(rit_timer);
++      break;
++    case 3:
++      break;
++  }
++}
++
++void sim_s5_pressed_cb(GtkWidget *widget, gpointer data) {
++  switch(function) {
++    case 0:
++      noise_cb(widget,data);
++      break;
++    case 1:
++      // A<>B
++      aswapb_cb(widget,data);
++      break;
++    case 2:
++      rit_cb(widget,(void *)-1);
++      break;
++    case 3:
++      break;
++  }
++}
++
++void sim_s5_released_cb(GtkWidget *widget, gpointer data) {
++  switch(function) {
++    case 0:
++      break;
++    case 1:
++      break;
++    case 2:
++      g_source_remove(rit_timer);
++      break;
++    case 3:
++      break;
++  }
++}
++
++void sim_s6_pressed_cb(GtkWidget *widget, gpointer data) {
++  switch(function) {
++    case 0:
++      agc_cb(widget,data);
++      break;
++    case 1:
++      split_cb(widget,data);
++      break;
++    case 2:
++      break;
++    case 3:
++      break;
++  }
++}
++
++void sim_s6_released_cb(GtkWidget *widget, gpointer data) {
++  switch(function) {
++    case 0:
++      break;
++    case 1:
++      break;
++    case 2:
++      break;
++    case 3:
++      break;
++  }
++}
++
++void sim_mox_cb(GtkWidget *widget, gpointer data) {
++  switch(function) {
++    case 0:
++    case 1:
++    case 2:
++      mox_cb((GtkWidget *)NULL, (gpointer)NULL);
++      break;
++    case 3:
++      tune_cb((GtkWidget *)NULL, (gpointer)NULL);
++      break;
++  }
++}
++
++void sim_function_cb(GtkWidget *widget, gpointer data) {
++  function++;
++  if(function>MAX_FUNCTION) {
++    function=0;
++  }
++  update_toolbar_labels();
++  vfo_update(NULL);
++}
++
++GtkWidget *toolbar_init(int my_width, int my_height, GtkWidget* parent) {
++    width=my_width;
++    height=my_height;
++    parent_window=parent;
++
++    int button_width=width/8;
++
++    fprintf(stderr,"toolbar_init: width=%d height=%d button_width=%d\n", width,height,button_width);
++
++    white.red=1.0;
++    white.green=1.0;
++    white.blue=1.0;
++    white.alpha=0.0;
++
++    gray.red=0.25;
++    gray.green=0.25;
++    gray.blue=0.25;
++    gray.alpha=0.0;
++
++    toolbar=gtk_grid_new();
++    gtk_widget_set_size_request (toolbar, width, height);
++    gtk_grid_set_column_homogeneous(GTK_GRID(toolbar),TRUE);
++
++    sim_mox=gtk_button_new_with_label("Mox");
++    //gtk_widget_override_font(sim_mox, pango_font_description_from_string("Arial 16"));
++    g_signal_connect(G_OBJECT(sim_mox),"clicked",G_CALLBACK(sim_mox_cb),NULL);
++    gtk_grid_attach(GTK_GRID(toolbar),sim_mox,0,0,4,1);
++
++    sim_s1=gtk_button_new_with_label("Band");
++    gtk_widget_set_size_request (sim_s1, button_width, 0);
++    //gtk_widget_override_font(sim_s1, pango_font_description_from_string("Arial 16"));
++    g_signal_connect(G_OBJECT(sim_s1),"pressed",G_CALLBACK(sim_s1_pressed_cb),NULL);
++    g_signal_connect(G_OBJECT(sim_s1),"released",G_CALLBACK(sim_s1_released_cb),NULL);
++    gtk_grid_attach(GTK_GRID(toolbar),sim_s1,4,0,4,1);
++
++    sim_s2=gtk_button_new_with_label("BStack");
++    gtk_widget_set_size_request (sim_s2, button_width, 0);
++    //gtk_widget_override_font(sim_s2, pango_font_description_from_string("Arial 16"));
++    g_signal_connect(G_OBJECT(sim_s2),"pressed",G_CALLBACK(sim_s2_pressed_cb),NULL);
++    g_signal_connect(G_OBJECT(sim_s2),"released",G_CALLBACK(sim_s2_released_cb),NULL);
++    gtk_grid_attach(GTK_GRID(toolbar),sim_s2,8,0,4,1);
++
++    sim_s3=gtk_button_new_with_label("Mode");
++    //gtk_widget_override_font(sim_s3, pango_font_description_from_string("Arial 16"));
++    g_signal_connect(G_OBJECT(sim_s3),"pressed",G_CALLBACK(sim_s3_pressed_cb),NULL);
++    g_signal_connect(G_OBJECT(sim_s3),"released",G_CALLBACK(sim_s3_released_cb),NULL);
++    gtk_grid_attach(GTK_GRID(toolbar),sim_s3,12,0,4,1);
++
++    sim_s4=gtk_button_new_with_label("Filter");
++    //gtk_widget_override_font(sim_s4, pango_font_description_from_string("Arial 16"));
++    g_signal_connect(G_OBJECT(sim_s4),"pressed",G_CALLBACK(sim_s4_pressed_cb),NULL);
++    g_signal_connect(G_OBJECT(sim_s4),"released",G_CALLBACK(sim_s4_released_cb),NULL);
++    gtk_grid_attach(GTK_GRID(toolbar),sim_s4,16,0,4,1);
++
++    sim_s5=gtk_button_new_with_label("Noise");
++    //gtk_widget_override_font(sim_s5, pango_font_description_from_string("Arial 16"));
++    g_signal_connect(G_OBJECT(sim_s5),"pressed",G_CALLBACK(sim_s5_pressed_cb),NULL);
++    g_signal_connect(G_OBJECT(sim_s5),"released",G_CALLBACK(sim_s5_released_cb),NULL);
++    gtk_grid_attach(GTK_GRID(toolbar),sim_s5,20,0,4,1);
++
++    sim_s6=gtk_button_new_with_label("AGC");
++    //gtk_widget_override_font(sim_s6, pango_font_description_from_string("Arial 16"));
++    g_signal_connect(G_OBJECT(sim_s6),"pressed",G_CALLBACK(sim_s6_pressed_cb),NULL);
++    g_signal_connect(G_OBJECT(sim_s6),"released",G_CALLBACK(sim_s6_released_cb),NULL);
++    gtk_grid_attach(GTK_GRID(toolbar),sim_s6,24,0,4,1);
++
++    sim_function=gtk_button_new_with_label("Function");
++    //gtk_widget_override_font(sim_function, pango_font_description_from_string("Arial 16"));
++    g_signal_connect(G_OBJECT(sim_function),"clicked",G_CALLBACK(sim_function_cb),NULL);
++    gtk_grid_attach(GTK_GRID(toolbar),sim_function,28,0,4,1);
++
++    //update_toolbar_labels();
++
++    last_dialog=NULL;
++
++    gtk_widget_show_all(toolbar);
++
++  return toolbar;
++}
diff --cc vfo.c
index f11897f0d1c0f2aa2c2da193e746cef457fc2d8c,512c30807afc1a99fcd498da83714cb97b1d3bba..551df1b31716370ea8def466abd2ac8e1b960e07
--- 1/vfo.c
--- 2/vfo.c
+++ b/vfo.c
@@@ -203,29 -539,41 +539,60 @@@ int vfo_update(void *data) 
  
          char version[16];
          char text[128];
 -        }
 -
+         if(radio->protocol==ORIGINAL_PROTOCOL) {
+           switch(radio->device) {
+ #ifdef USBOZY
+             case DEVICE_OZY:
+               strcpy(version,"");
+               break;
+ #endif
+             default:
+               sprintf(version,"%d.%d",
+                   radio->software_version/10,
+                   radio->software_version%10);
+               break;
+           }
+         } else {
+             sprintf(version,"%d.%d",
+                 radio->software_version/10,
+                 radio->software_version%10);
 +              
 +              switch(radio->protocol) {
 +                      case ORIGINAL_PROTOCOL:
 +#ifdef RADIOBERRY
 +                      case RADIOBERRY_PROTOCOL:
 +#endif
 +                      sprintf(version,"%d.%d",
 +                                      radio->software_version/10,
 +                                      radio->software_version%10);
 +                        break;
 +                      case NEW_PROTOCOL:
 +#ifdef LIMESDR
 +                      case LIMESDR_PROTOCOL:
 +#endif
 +                      sprintf(version,"%d.%d.%d",
 +                radio->software_version/100,
 +                (radio->software_version%100)/10,
 +                radio->software_version%10);
 +                      break;
 +              }               
 +      
          switch(radio->protocol) {
              case ORIGINAL_PROTOCOL:
+               switch(radio->device) {
+ #ifdef USBOZY
+                 case DEVICE_OZY:
+                   sprintf(text,"%s", radio->name);
+                   break;
+ #endif
+                 default:
+                   sprintf(text,"%s %s %s",
+                     radio->name,
+                     version,
+                     inet_ntoa(radio->info.network.address.sin_addr));
+                   break;
+               }
+               break;
              case NEW_PROTOCOL:
                sprintf(text,"%s %s %s",
                      radio->name,
                break;
  #ifdef LIMESDR
              case LIMESDR_PROTOCOL:
-               sprintf(text,"%s\n",
-                     radio->name);
+               sprintf(text,"%s", radio->name);
                break;
 +#endif
 +#ifdef RADIOBERRY
 +                      case RADIOBERRY_PROTOCOL:
 +                              sprintf(text,"%s\n", radio->name);
 +                      break;
  #endif
          }
-         cairo_set_source_rgb(cr, 0.5, 0.5, 0.5);
-         cairo_set_font_size(cr, 10);
+         cairo_set_source_rgb(cr, 0.7, 0.7, 0.7);
+         cairo_set_font_size(cr, 12);
          cairo_move_to(cr, 5, 15);  
          cairo_show_text(cr, text);
  
diff --cc vfo.c.orig
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..152fb1f6423c374fbe8edca46a30520c050e195c
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,854 @@@
++/* Copyright (C)
++* 2015 - 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 <gdk/gdk.h>
++#include <math.h>
++#include <pthread.h>
++#include <semaphore.h>
++#include <string.h>
++#include <stdlib.h>
++#include <unistd.h>
++#include <netinet/in.h>
++#include <arpa/inet.h>
++#include <netdb.h>
++#include <net/if_arp.h>
++#include <net/if.h>
++#include <ifaddrs.h>
++
++#include "discovered.h"
++#include "main.h"
++#include "agc.h"
++#include "mode.h"
++#include "filter.h"
++#include "bandstack.h"
++#include "band.h"
++#include "frequency.h"
++#include "new_protocol.h"
++#include "property.h"
++#include "radio.h"
++#include "receiver.h"
++#include "vfo.h"
++#include "channel.h"
++#include "toolbar.h"
++#include "wdsp.h"
++#include "new_menu.h"
++#include "rigctl.h"
++
++static GtkWidget *parent_window;
++static int my_width;
++static int my_height;
++
++static GtkWidget *vfo_panel;
++static cairo_surface_t *vfo_surface = NULL;
++
++int steps[]={1,10,25,50,100,250,500,1000,2500,5000,6250,9000,10000,12500,15000,20000,25000,30000,50000,100000,0};
++char *step_labels[]={"1Hz","10Hz","25Hz","50Hz","100Hz","250Hz","500Hz","1kHz","2.5kHz","5kHz","6.25kHz","9kHz","10kHz","12.5kHz","15kHz","20kHz","25kHz","30kHz","50kHz","100kHz",0};
++
++static GtkWidget* menu=NULL;
++static GtkWidget* band_menu=NULL;
++
++
++static void vfo_save_bandstack() {
++  BANDSTACK *bandstack=bandstack_get_bandstack(vfo[0].band);
++  BANDSTACK_ENTRY *entry=&bandstack->entry[vfo[0].bandstack];
++  entry->frequency=vfo[0].frequency;
++  entry->mode=vfo[0].mode;
++  entry->filter=vfo[0].filter;
++}
++
++void vfo_save_state() {
++  int i;
++  char name[80];
++  char value[80];
++
++  vfo_save_bandstack();
++
++  for(i=0;i<MAX_VFOS;i++) {
++    sprintf(name,"vfo.%d.band",i);
++    sprintf(value,"%d",vfo[i].band);
++    setProperty(name,value);
++    sprintf(name,"vfo.%d.frequency",i);
++    sprintf(value,"%lld",vfo[i].frequency);
++    setProperty(name,value);
++    sprintf(name,"vfo.%d.ctun",i);
++    sprintf(value,"%d",vfo[i].ctun);
++    setProperty(name,value);
++    sprintf(name,"vfo.%d.rit",i);
++    sprintf(value,"%lld",vfo[i].rit);
++    setProperty(name,value);
++    sprintf(name,"vfo.%d.lo",i);
++    sprintf(value,"%lld",vfo[i].lo);
++    setProperty(name,value);
++    sprintf(name,"vfo.%d.ctun_frequency",i);
++    sprintf(value,"%lld",vfo[i].ctun_frequency);
++    setProperty(name,value);
++    sprintf(name,"vfo.%d.offset",i);
++    sprintf(value,"%lld",vfo[i].offset);
++    setProperty(name,value);
++    sprintf(name,"vfo.%d.mode",i);
++    sprintf(value,"%d",vfo[i].mode);
++    setProperty(name,value);
++    sprintf(name,"vfo.%d.filter",i);
++    sprintf(value,"%d",vfo[i].filter);
++    setProperty(name,value);
++  }
++}
++
++void vfo_restore_state() {
++  int i;
++  char name[80];
++  char *value;
++
++  for(i=0;i<MAX_VFOS;i++) {
++
++    vfo[i].band=band20;
++    vfo[i].bandstack=0;
++    vfo[i].frequency=14010000;
++    vfo[i].mode=modeCWU;
++    vfo[i].filter=6;
++    vfo[i].lo=0;
++    vfo[i].offset=0;
++    vfo[i].rit=0;
++    vfo[i].ctun=0;
++
++    sprintf(name,"vfo.%d.band",i);
++    value=getProperty(name);
++    if(value) vfo[i].band=atoi(value);
++    sprintf(name,"vfo.%d.frequency",i);
++    value=getProperty(name);
++    if(value) vfo[i].frequency=atoll(value);
++    sprintf(name,"vfo.%d.ctun",i);
++    value=getProperty(name);
++    if(value) vfo[i].ctun=atoi(value);
++    sprintf(name,"vfo.%d.ctun_frequency",i);
++    value=getProperty(name);
++    if(value) vfo[i].ctun_frequency=atoll(value);
++    sprintf(name,"vfo.%d.rit",i);
++    value=getProperty(name);
++    if(value) vfo[i].rit=atoll(value);
++    sprintf(name,"vfo.%d.lo",i);
++    value=getProperty(name);
++    if(value) vfo[i].lo=atoll(value);
++    sprintf(name,"vfo.%d.offset",i);
++    value=getProperty(name);
++    if(value) vfo[i].offset=atoll(value);
++    sprintf(name,"vfo.%d.mode",i);
++    value=getProperty(name);
++    if(value) vfo[i].mode=atoi(value);
++    sprintf(name,"vfo.%d.filter",i);
++    value=getProperty(name);
++    if(value) vfo[i].filter=atoi(value);
++
++  }
++}
++
++void vfo_band_changed(int b) {
++  BANDSTACK *bandstack;
++
++  int id=active_receiver->id;
++
++  if(id==0) {
++    vfo_save_bandstack();
++  }
++  if(b==vfo[id].band) {
++    // same band selected - step to the next band stack
++    bandstack=bandstack_get_bandstack(b);
++    vfo[id].bandstack++;
++    if(vfo[id].bandstack>=bandstack->entries) {
++      vfo[id].bandstack=0;
++    }
++  } else {
++    // new band - get band stack entry
++    bandstack=bandstack_get_bandstack(b);
++    vfo[id].bandstack=bandstack->current_entry;
++  }
++
++  BAND *band=band_get_band(b);
++  BANDSTACK_ENTRY *entry=&bandstack->entry[vfo[id].bandstack];
++  vfo[id].band=b;
++  vfo[id].frequency=entry->frequency;
++  vfo[id].mode=entry->mode;
++  vfo[id].filter=entry->filter;
++  vfo[id].lo=band->frequencyLO;
++
++  switch(id) {
++    case 0:
++      bandstack->current_entry=vfo[id].bandstack;
++      receiver_vfo_changed(receiver[id]);
++      BAND *band=band_get_band(vfo[id].band);
++      set_alex_rx_antenna(band->alexRxAntenna);
++      set_alex_tx_antenna(band->alexTxAntenna);
++      set_alex_attenuation(band->alexAttenuation);
++      receiver_vfo_changed(receiver[0]);
++      break;
++   case 1:
++      if(receivers==2) {
++        receiver_vfo_changed(receiver[1]);
++      }
++      break;
++  }
++
++  if(split) {
++    tx_set_mode(transmitter,vfo[VFO_B].mode);
++  } else {
++    tx_set_mode(transmitter,vfo[VFO_A].mode);
++  }
++  calcDriveLevel();
++  calcTuneDriveLevel();
++  vfo_update(NULL);
++}
++
++void vfo_bandstack_changed(int b) {
++  int id=active_receiver->id;
++  if(id==0) {
++    vfo_save_bandstack();
++  }
++  vfo[id].bandstack=b;
++
++  BANDSTACK *bandstack=bandstack_get_bandstack(vfo[id].band);
++  BANDSTACK_ENTRY *entry=&bandstack->entry[vfo[id].bandstack];
++  vfo[id].frequency=entry->frequency;
++  vfo[id].mode=entry->mode;
++  vfo[id].filter=entry->filter;
++
++  switch(id) {
++    case 0:
++      bandstack->current_entry=vfo[id].bandstack;
++      receiver_vfo_changed(receiver[id]);
++      BAND *band=band_get_band(vfo[id].band);
++      set_alex_rx_antenna(band->alexRxAntenna);
++      set_alex_tx_antenna(band->alexTxAntenna);
++      set_alex_attenuation(band->alexAttenuation);
++      receiver_vfo_changed(receiver[0]);
++      break;
++   case 1:
++      if(receivers==2) {
++        receiver_vfo_changed(receiver[1]);
++      }
++      break;
++  }
++
++  if(split) {
++    tx_set_mode(transmitter,vfo[VFO_B].mode);
++  } else {
++    tx_set_mode(transmitter,vfo[VFO_A].mode);
++  }
++  calcDriveLevel();
++  calcTuneDriveLevel();
++  vfo_update(NULL);
++
++}
++
++void vfo_mode_changed(int m) {
++  int id=active_receiver->id;
++  vfo[id].mode=m;
++  switch(id) {
++    case 0:
++      receiver_mode_changed(receiver[0]);
++      receiver_filter_changed(receiver[0]);
++      break;
++    case 1:
++      if(receivers==2) {
++        receiver_mode_changed(receiver[1]);
++        receiver_filter_changed(receiver[1]);
++      }
++      break;
++  }
++  if(split) {
++    tx_set_mode(transmitter,vfo[VFO_B].mode);
++  } else {
++    tx_set_mode(transmitter,vfo[VFO_A].mode);
++  }
++
++  vfo_update(NULL);
++}
++
++void vfo_filter_changed(int f) {
++  int id=active_receiver->id;
++  vfo[id].filter=f;
++  switch(id) {
++    case 0:
++      receiver_filter_changed(receiver[0]);
++      break;
++    case 1:
++      if(receivers==2) {
++        receiver_filter_changed(receiver[1]);
++      }
++      break;
++  }
++
++  vfo_update(NULL);
++}
++
++void vfo_a_to_b() {
++  vfo[VFO_B].band=vfo[VFO_A].band;
++  vfo[VFO_B].bandstack=vfo[VFO_A].bandstack;
++  vfo[VFO_B].frequency=vfo[VFO_A].frequency;
++  vfo[VFO_B].mode=vfo[VFO_A].mode;
++  vfo[VFO_B].filter=vfo[VFO_A].filter;
++  vfo[VFO_B].filter=vfo[VFO_A].filter;
++  vfo[VFO_B].lo=vfo[VFO_A].lo;
++  vfo[VFO_B].offset=vfo[VFO_A].offset;
++  vfo[VFO_B].rit=vfo[VFO_A].rit;
++
++  if(receivers==2) {
++    receiver_vfo_changed(receiver[1]);
++  }
++  if(split) {
++    tx_set_mode(transmitter,vfo[VFO_B].mode);
++  }
++  vfo_update(NULL);
++}
++
++void vfo_b_to_a() {
++  vfo[VFO_A].band=vfo[VFO_B].band;
++  vfo[VFO_A].bandstack=vfo[VFO_B].bandstack;
++  vfo[VFO_A].frequency=vfo[VFO_B].frequency;
++  vfo[VFO_A].mode=vfo[VFO_B].mode;
++  vfo[VFO_A].filter=vfo[VFO_B].filter;
++  vfo[VFO_A].lo=vfo[VFO_B].lo;
++  vfo[VFO_A].offset=vfo[VFO_B].offset;
++  vfo[VFO_A].rit=vfo[VFO_B].rit;
++  receiver_vfo_changed(receiver[0]);
++  if(!split) {
++    tx_set_mode(transmitter,vfo[VFO_B].mode);
++  }
++  vfo_update(NULL);
++}
++
++void vfo_a_swap_b() {
++  int temp_band;
++  int temp_bandstack;
++  long long temp_frequency;
++  int temp_mode;
++  int temp_filter;
++  int temp_lo;
++  int temp_offset;
++  int temp_rit;
++
++  temp_band=vfo[VFO_A].band;
++  temp_bandstack=vfo[VFO_A].bandstack;
++  temp_frequency=vfo[VFO_A].frequency;
++  temp_mode=vfo[VFO_A].mode;
++  temp_filter=vfo[VFO_A].filter;
++  temp_lo=vfo[VFO_A].lo;
++  temp_offset=vfo[VFO_A].offset;
++  temp_rit=vfo[VFO_A].rit;
++
++  vfo[VFO_A].band=vfo[VFO_B].band;
++  vfo[VFO_A].bandstack=vfo[VFO_B].bandstack;
++  vfo[VFO_A].frequency=vfo[VFO_B].frequency;
++  vfo[VFO_A].mode=vfo[VFO_B].mode;
++  vfo[VFO_A].filter=vfo[VFO_B].filter;
++  vfo[VFO_A].lo=vfo[VFO_B].lo;
++  vfo[VFO_A].offset=vfo[VFO_B].offset;
++  vfo[VFO_A].rit=vfo[VFO_B].rit;
++
++  vfo[VFO_B].band=temp_band;
++  vfo[VFO_B].bandstack=temp_bandstack;
++  vfo[VFO_B].frequency=temp_frequency;
++  vfo[VFO_B].mode=temp_mode;
++  vfo[VFO_B].filter=temp_filter;
++  vfo[VFO_B].lo=temp_lo;
++  vfo[VFO_B].offset=temp_offset;
++  vfo[VFO_B].rit=temp_rit;
++
++  receiver_vfo_changed(receiver[0]);
++  if(receivers==2) {
++    receiver_vfo_changed(receiver[1]);
++  }
++  if(split) {
++    tx_set_mode(transmitter,vfo[VFO_B].mode);
++  } else {
++    tx_set_mode(transmitter,vfo[VFO_A].mode);
++  }
++  vfo_update(NULL);
++}
++
++void vfo_step(int steps) {
++  int id=active_receiver->id;
++  if(!locked) {
++    if(vfo[id].ctun) {
++      vfo[id].ctun_frequency=vfo[id].ctun_frequency+(steps*step);
++    } else {
++      vfo[id].frequency=vfo[id].frequency+(steps*step);
++    }
++    receiver_frequency_changed(active_receiver);
++#ifdef INCLUDED
++    BANDSTACK_ENTRY* entry=bandstack_entry_get_current();
++    setFrequency(active_receiver->frequency+(steps*step));
++#endif
++    vfo_update(NULL);
++  }
++}
++
++void vfo_move(long long hz) {
++  int id=active_receiver->id;
++  if(!locked) {
++    switch(protocol) {
++#ifdef LIMESDR
++      case LIMESDR_PROTOCOL:
++        break;
++#endif
++      default:
++        if(vfo[id].ctun) {
++          vfo[id].ctun_frequency=((vfo[id].ctun_frequency-hz)/step)*step;
++        } else {
++          vfo[id].frequency=((vfo[id].frequency+hz)/step)*step;
++        }
++        break;
++    }
++    receiver_frequency_changed(active_receiver);
++    vfo_update(NULL);
++  }
++}
++
++void vfo_move_to(long long hz) {
++  int id=active_receiver->id;
++  if(!locked) {
++    switch(protocol) {
++#ifdef LIMESDR
++      case LIMESDR_PROTOCOL:
++        break;
++#endif
++      default:
++        if(vfo[id].ctun) {
++          vfo[id].ctun_frequency=(vfo[id].frequency+hz)/step*step;
++          if(vfo[id].mode==modeCWL) {
++            vfo[id].ctun_frequency+=cw_keyer_sidetone_frequency;
++          } else if(vfo[id].mode==modeCWU) {
++            vfo[id].ctun_frequency-=cw_keyer_sidetone_frequency;
++          }
++        } else {
++          vfo[id].frequency=(vfo[id].frequency+hz)/step*step;
++          if(vfo[id].mode==modeCWL) {
++            vfo[id].frequency+=cw_keyer_sidetone_frequency;
++          } else if(vfo[id].mode==modeCWU) {
++            vfo[id].frequency-=cw_keyer_sidetone_frequency;
++          }
++        }
++        break;
++    }
++    receiver_vfo_changed(active_receiver);
++
++#ifdef INCLUDED
++
++    BANDSTACK_ENTRY* entry=bandstack_entry_get_current();
++
++#ifdef LIMESDR
++    if(protocol==LIMESDR_PROTOCOL) {
++      setFrequency((entry->frequency+active_receiver->dds_offset-hz)/step*step);
++    } else {
++#endif
++      if(vfo[id].ctun) {
++        setFrequency((active_receiver->frequency+hz)/step*step);
++      } else {
++        long long f=(active_receiver->frequency+active_receiver->dds_offset+hz)/step*step;
++        if(vfo[active_receiver->id].mode==modeCWL) {
++          f+=cw_keyer_sidetone_frequency;
++        } else if(vfo[active_receiver->id].mode==modeCWU) {
++          f-=cw_keyer_sidetone_frequency;
++        }
++        setFrequency(f);
++      }
++#ifdef LIMESDR
++    }
++#endif
++#endif
++    vfo_update(NULL);
++  }
++}
++
++static gboolean
++vfo_scroll_event_cb (GtkWidget      *widget,
++               GdkEventScroll *event,
++               gpointer        data)
++{
++  int i;
++  if(event->direction==GDK_SCROLL_UP) {
++    vfo_move(step);
++  } else {
++    vfo_move(-step);
++  }
++}
++
++
++static gboolean vfo_configure_event_cb (GtkWidget         *widget,
++            GdkEventConfigure *event,
++            gpointer           data)
++{
++  if (vfo_surface)
++    cairo_surface_destroy (vfo_surface);
++
++  vfo_surface = gdk_window_create_similar_surface (gtk_widget_get_window (widget),
++                                       CAIRO_CONTENT_COLOR,
++                                       gtk_widget_get_allocated_width (widget),
++                                       gtk_widget_get_allocated_height (widget));
++
++  /* Initialize the surface to black */
++  cairo_t *cr;
++  cr = cairo_create (vfo_surface);
++  cairo_set_source_rgb (cr, 0, 0, 0);
++  cairo_paint (cr);
++  cairo_destroy(cr);
++  g_idle_add(vfo_update,NULL);
++  return TRUE;
++}
++
++static gboolean vfo_draw_cb (GtkWidget *widget,
++ cairo_t   *cr,
++ gpointer   data)
++{
++  cairo_set_source_surface (cr, vfo_surface, 0, 0);
++  cairo_paint (cr);
++  return TRUE;
++}
++
++int vfo_update(void *data) {
++    
++    int id=active_receiver->id;
++    FILTER* band_filters=filters[vfo[id].mode];
++    FILTER* band_filter=&band_filters[vfo[id].filter];
++    if(vfo_surface) {
++        char temp_text[32];
++        cairo_t *cr;
++        cr = cairo_create (vfo_surface);
++        cairo_set_source_rgb (cr, 0, 0, 0);
++        cairo_paint (cr);
++
++        cairo_select_font_face(cr, "FreeMono",
++            CAIRO_FONT_SLANT_NORMAL,
++            CAIRO_FONT_WEIGHT_BOLD);
++
++        char version[16];
++        char text[128];
++<<<<<<< HEAD
++              
++              switch(radio->protocol) {
++                      case ORIGINAL_PROTOCOL:
++#ifdef RADIOBERRY
++                      case RADIOBERRY_PROTOCOL:
++#endif
++                      sprintf(version,"%d.%d",
++                                      radio->software_version/10,
++                                      radio->software_version%10);
++                        break;
++                      case NEW_PROTOCOL:
++#ifdef LIMESDR
++                      case LIMESDR_PROTOCOL:
++#endif
++                      sprintf(version,"%d.%d.%d",
++                radio->software_version/100,
++                (radio->software_version%100)/10,
++                radio->software_version%10);
++                      break;
++              }               
++      
++=======
++        if(radio->protocol==ORIGINAL_PROTOCOL) {
++          switch(radio->device) {
++#ifdef USBOZY
++            case DEVICE_OZY:
++              strcpy(version,"");
++              break;
++#endif
++            default:
++              sprintf(version,"%d.%d",
++                  radio->software_version/10,
++                  radio->software_version%10);
++              break;
++          }
++        } else {
++            sprintf(version,"%d.%d",
++                radio->software_version/10,
++                radio->software_version%10);
++        }
++
++>>>>>>> upstream/master
++        switch(radio->protocol) {
++            case ORIGINAL_PROTOCOL:
++              switch(radio->device) {
++#ifdef USBOZY
++                case DEVICE_OZY:
++                  sprintf(text,"%s", radio->name);
++                  break;
++#endif
++                default:
++                  sprintf(text,"%s %s %s",
++                    radio->name,
++                    version,
++                    inet_ntoa(radio->info.network.address.sin_addr));
++                  break;
++              }
++              break;
++            case NEW_PROTOCOL:
++              sprintf(text,"%s %s %s",
++                    radio->name,
++                    version,
++                    inet_ntoa(radio->info.network.address.sin_addr));
++              break;
++#ifdef LIMESDR
++            case LIMESDR_PROTOCOL:
++              sprintf(text,"%s", radio->name);
++              break;
++#endif
++#ifdef RADIOBERRY
++                      case RADIOBERRY_PROTOCOL:
++                              sprintf(text,"%s\n", radio->name);
++                      break;
++#endif
++        }
++        cairo_set_source_rgb(cr, 0.7, 0.7, 0.7);
++        cairo_set_font_size(cr, 12);
++        cairo_move_to(cr, 5, 15);  
++        cairo_show_text(cr, text);
++
++        //long long af=active_receiver->frequency+active_receiver->dds_offset;
++        long long af=vfo[0].frequency+vfo[0].offset;
++        sprintf(temp_text,"VFO A: %0lld.%06lld",af/(long long)1000000,af%(long long)1000000);
++        if(isTransmitting() && !split) {
++            cairo_set_source_rgb(cr, 1, 0, 0);
++        } else {
++            if(active_receiver->id==0) {
++              cairo_set_source_rgb(cr, 0, 1, 0);
++            } else {
++              cairo_set_source_rgb(cr, 0, 0.65, 0);
++            }
++        }
++        cairo_move_to(cr, 5, 38);  
++        cairo_set_font_size(cr, 22); 
++        cairo_show_text(cr, temp_text);
++
++        //long long bf=frequencyB;
++        long long bf=vfo[1].frequency+vfo[1].offset;
++        sprintf(temp_text,"VFO B: %0lld.%06lld",bf/(long long)1000000,bf%(long long)1000000);
++        if(isTransmitting() && split) {
++            cairo_set_source_rgb(cr, 1, 0, 0);
++        } else {
++            if(active_receiver->id==1) {
++              cairo_set_source_rgb(cr, 0, 1, 0);
++            } else {
++              cairo_set_source_rgb(cr, 0, 0.65, 0);
++            }
++        }
++        cairo_move_to(cr, 260, 38);  
++        cairo_show_text(cr, temp_text);
++
++        cairo_set_font_size(cr, 12);
++
++        if(vfo[id].rit==0) {
++            cairo_set_source_rgb(cr, 0.7, 0.7, 0.7);
++        } else {
++            cairo_set_source_rgb(cr, 1, 1, 0);
++        }
++        sprintf(temp_text,"RIT: %d Hz",vfo[id].rit);
++        cairo_move_to(cr, 5, 50);  
++        cairo_set_font_size(cr, 12);
++        cairo_show_text(cr, temp_text);
++
++        cairo_move_to(cr, 210, 15);  
++        if(locked) {
++          cairo_set_source_rgb(cr, 1, 0, 0);
++        } else {
++          cairo_set_source_rgb(cr, 0.7, 0.7, 0.7);
++        }
++        cairo_show_text(cr, "Locked");
++        
++        cairo_set_source_rgb(cr, 1, 1, 0);
++        cairo_move_to(cr, 100, 50);  
++        if(vfo[id].mode==modeFMN) {
++          if(deviation==2500) {
++            sprintf(temp_text,"%s 8k",mode_string[vfo[id].mode]); 
++          } else {
++            sprintf(temp_text,"%s 16k",mode_string[vfo[id].mode]); 
++          }
++        } else {
++          sprintf(temp_text,"%s %s",mode_string[vfo[id].mode],band_filter->title); 
++        }
++        cairo_show_text(cr, temp_text);
++
++        cairo_move_to(cr, 170, 50);  
++        if(active_receiver->nr) {
++          cairo_set_source_rgb(cr, 1.0, 1.0, 0.0);
++        } else {
++          cairo_set_source_rgb(cr, 0.7, 0.7, 0.7);
++        }
++        cairo_show_text(cr, "NR");
++
++        cairo_move_to(cr, 200, 50);  
++        if(active_receiver->nr2) {
++          cairo_set_source_rgb(cr, 1.0, 1.0, 0.0);
++        } else {
++          cairo_set_source_rgb(cr, 0.7, 0.7, 0.7);
++        }
++        cairo_show_text(cr, "NR2");
++
++        cairo_move_to(cr, 230, 50);  
++        if(active_receiver->anf) {
++          cairo_set_source_rgb(cr, 1.0, 1.0, 0.0);
++        } else {
++          cairo_set_source_rgb(cr, 0.7, 0.7, 0.7);
++        }
++        cairo_show_text(cr, "ANF");
++
++        cairo_move_to(cr, 260, 50);  
++        if(active_receiver->snb) {
++          cairo_set_source_rgb(cr, 1.0, 1.0, 0.0);
++        } else {
++          cairo_set_source_rgb(cr, 0.7, 0.7, 0.7);
++        }
++        cairo_show_text(cr, "SNB");
++
++        cairo_move_to(cr, 290, 50);  
++        switch(active_receiver->agc) {
++          case AGC_OFF:
++            cairo_set_source_rgb(cr, 0.7, 0.7, 0.7);
++            cairo_show_text(cr, "AGC OFF");
++            break;
++          case AGC_LONG:
++            cairo_set_source_rgb(cr, 1, 1, 0);
++            cairo_show_text(cr, "AGC LONG");
++            break;
++          case AGC_SLOW:
++            cairo_set_source_rgb(cr, 1, 1, 0);
++            cairo_show_text(cr, "AGC SLOW");
++            break;
++          case AGC_MEDIUM:
++            cairo_set_source_rgb(cr, 1, 1, 0);
++            cairo_show_text(cr, "AGC MEDIUM");
++            break;
++          case AGC_FAST:
++            cairo_set_source_rgb(cr, 1, 1, 0);
++            cairo_show_text(cr, "AGC FAST");
++            break;
++        }
++
++        int s=0;
++        while(steps[s]!=step && steps[s]!=0) {
++          s++;
++        }
++        sprintf(temp_text,"Step %s",step_labels[s]);
++        cairo_move_to(cr, 375, 50);
++        cairo_set_source_rgb(cr, 1, 1, 0);
++        cairo_show_text(cr, temp_text);
++
++        char *info=getFrequencyInfo(af);
++/*
++        cairo_move_to(cr, (my_width/4)*3, 50);
++        cairo_show_text(cr, getFrequencyInfo(af));
++*/
++         
++        cairo_move_to(cr, 460, 50);  
++        if(vfo[id].ctun) {
++          cairo_set_source_rgb(cr, 1, 1, 0);
++        } else {
++          cairo_set_source_rgb(cr, 0.7, 0.7, 0.7);
++        }
++        cairo_show_text(cr, "CTUN");
++
++        cairo_move_to(cr, 500, 50);  
++        if(cat_control>0) {
++          cairo_set_source_rgb(cr, 1, 1, 0);
++        } else {
++          cairo_set_source_rgb(cr, 0.7, 0.7, 0.7);
++        }
++        cairo_show_text(cr, "CAT");
++
++        cairo_move_to(cr, 270, 15);
++        if(split) {
++          cairo_set_source_rgb(cr, 1, 0, 0);
++        } else {
++          cairo_set_source_rgb(cr, 0.7, 0.7, 0.7);
++        }
++        cairo_show_text(cr, "Split");
++       
++        cairo_move_to(cr, 310, 15);
++        if(vfo[id].mode==modeCWL || vfo[id].mode==modeCWU) {
++          cairo_set_source_rgb(cr, 1, 1, 0);
++        } else {
++          cairo_set_source_rgb(cr, 0.7, 0.7, 0.7);
++        }
++        sprintf(temp_text,"CW %d wpm, sidetone %d Hz",cw_keyer_speed,cw_keyer_sidetone_frequency);
++        cairo_show_text(cr, temp_text);
++
++        cairo_destroy (cr);
++        gtk_widget_queue_draw (vfo_panel);
++    } else {
++fprintf(stderr,"vfo_update: no surface!\n");
++    }
++    return 0;
++}
++
++/*
++static gboolean
++vfo_step_select_cb (GtkWidget *widget,
++               gpointer        data)
++{
++  step=steps[(int)data];
++  vfo_update(NULL);
++}
++*/
++
++static gboolean
++vfo_press_event_cb (GtkWidget *widget,
++               GdkEventButton *event,
++               gpointer        data)
++{
++/*
++  if((int)event->x < (my_width/4)) {
++    //lock_cb(NULL,NULL);
++  } else if((int)event->x < (my_width/2) && (int)event->x > (my_width/4)) {
++    start_freqent();
++  } else {
++    start_step();
++  }
++*/
++  start_vfo();
++  return TRUE;
++}
++
++GtkWidget* vfo_init(int width,int height,GtkWidget *parent) {
++  int i;
++
++fprintf(stderr,"vfo_init: width=%d height=%d\n", width, height);
++
++  parent_window=parent;
++  my_width=width;
++  my_height=height;
++
++  vfo_panel = gtk_drawing_area_new ();
++  gtk_widget_set_size_request (vfo_panel, width, height);
++
++  g_signal_connect (vfo_panel,"configure-event",
++            G_CALLBACK (vfo_configure_event_cb), NULL);
++  g_signal_connect (vfo_panel, "draw",
++            G_CALLBACK (vfo_draw_cb), NULL);
++
++  /* Event signals */
++  g_signal_connect (vfo_panel, "button-press-event",
++            G_CALLBACK (vfo_press_event_cb), NULL);
++  g_signal_connect(vfo_panel,"scroll_event",
++            G_CALLBACK(vfo_scroll_event_cb),NULL);
++  gtk_widget_set_events (vfo_panel, gtk_widget_get_events (vfo_panel)
++                     | GDK_BUTTON_PRESS_MASK
++                     | GDK_SCROLL_MASK);
++
++  return vfo_panel;
++}
diff --cc wdsp_init.c
index 8b9d575c5b5fa28cd437ae19a9f6876f5497b181,cdeec089dbba3c32e26d269daff762c65f071be4..9cd1487097f8f3c91929b57c6a58aa33629671e4
@@@ -81,19 -81,19 +81,19 @@@ static int SPECTRUM_UPDATES_PER_SECOND=
  static void initAnalyzer(int channel,int buffer_size);
  
  static void calc_tx_buffer_size() {
 -  if(protocol==ORIGINAL_PROTOCOL) {
 +  if(protocol==ORIGINAL_PROTOCOL | protocol==RADIOBERRY_PROTOCOL) {
      switch(sample_rate) {
        case 48000:
-         tx_buffer_size=BUFFER_SIZE;
+         tx_buffer_size=buffer_size;
          break;
        case 96000:
-         tx_buffer_size=BUFFER_SIZE/2;
+         tx_buffer_size=buffer_size/2;
          break;
        case 192000:
-         tx_buffer_size=BUFFER_SIZE/4;
+         tx_buffer_size=buffer_size/4;
          break;
        case 384000:
-         tx_buffer_size=BUFFER_SIZE/8;
+         tx_buffer_size=buffer_size/8;
          break;
      }
    } else {