mirror of
https://github.com/csete/gpredict
synced 2026-08-13 17:39:46 -04:00
parent
1e203ca737
commit
677ebd8826
4 changed files with 440 additions and 230 deletions
|
|
@ -4,6 +4,7 @@
|
||||||
Copyright (C) 2001-2009 Alexandru Csete, OZ9AEC.
|
Copyright (C) 2001-2009 Alexandru Csete, OZ9AEC.
|
||||||
|
|
||||||
Authors: Alexandru Csete <oz9aec@gmail.com>
|
Authors: Alexandru Csete <oz9aec@gmail.com>
|
||||||
|
Patrick Dohmen <dl4pd@darc.de>
|
||||||
|
|
||||||
Comments, questions and bugreports should be submitted via
|
Comments, questions and bugreports should be submitted via
|
||||||
http://sourceforge.net/projects/gpredict/
|
http://sourceforge.net/projects/gpredict/
|
||||||
|
|
@ -24,6 +25,15 @@
|
||||||
You should have received a copy of the GNU General Public License
|
You should have received a copy of the GNU General Public License
|
||||||
along with this program; if not, visit http://www.fsf.org/
|
along with this program; if not, visit http://www.fsf.org/
|
||||||
*/
|
*/
|
||||||
|
/** \brief FREQ control.
|
||||||
|
*
|
||||||
|
* More info...
|
||||||
|
*
|
||||||
|
* 1 222.333 444 MHz
|
||||||
|
*
|
||||||
|
* \bug This should be a generic widget, not just frequency specific
|
||||||
|
*
|
||||||
|
*/
|
||||||
#include <gtk/gtk.h>
|
#include <gtk/gtk.h>
|
||||||
#include <glib/gi18n.h>
|
#include <glib/gi18n.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|
@ -35,15 +45,17 @@
|
||||||
|
|
||||||
static void gtk_freq_knob_class_init(GtkFreqKnobClass * class);
|
static void gtk_freq_knob_class_init(GtkFreqKnobClass * class);
|
||||||
static void gtk_freq_knob_init(GtkFreqKnob * list);
|
static void gtk_freq_knob_init(GtkFreqKnob * list);
|
||||||
static void gtk_freq_knob_destroy(GtkWidget * widget);
|
static void gtk_freq_knob_destroy(GtkObject * object);
|
||||||
static void gtk_freq_knob_update(GtkFreqKnob * knob);
|
static void *gtk_freq_knob_update(GtkFreqKnob * knob);
|
||||||
static void button_clicked_cb(GtkWidget * button, gpointer data);
|
static void button_clicked_cb(GtkWidget * button, gpointer data);
|
||||||
static gboolean on_button_press(GtkWidget * digit, GdkEventButton * event,
|
static gboolean on_button_press(GtkWidget * digit, GdkEventButton * event,
|
||||||
gpointer data);
|
gpointer data);
|
||||||
static gboolean on_button_scroll(GtkWidget * digit, GdkEventScroll * event,
|
static gboolean on_button_scroll(GtkWidget * digit, GdkEventScroll * event,
|
||||||
gpointer data);
|
gpointer data);
|
||||||
|
|
||||||
static GtkBoxClass *parent_class = NULL;
|
G_LOCK_DEFINE_STATIC(updatelock);
|
||||||
|
|
||||||
|
static GtkHBoxClass *parent_class = NULL;
|
||||||
|
|
||||||
#define FMTSTR "<span size='xx-large'>%c</span>"
|
#define FMTSTR "<span size='xx-large'>%c</span>"
|
||||||
|
|
||||||
|
|
@ -63,12 +75,14 @@ static const guint idx[] = {
|
||||||
|
|
||||||
static guint freq_changed_signal = 0;
|
static guint freq_changed_signal = 0;
|
||||||
|
|
||||||
|
|
||||||
GType gtk_freq_knob_get_type()
|
GType gtk_freq_knob_get_type()
|
||||||
{
|
{
|
||||||
static GType gtk_freq_knob_type = 0;
|
static GType gtk_freq_knob_type = 0;
|
||||||
|
|
||||||
if (!gtk_freq_knob_type)
|
if (!gtk_freq_knob_type)
|
||||||
{
|
{
|
||||||
|
|
||||||
static const GTypeInfo gtk_freq_knob_info = {
|
static const GTypeInfo gtk_freq_knob_info = {
|
||||||
sizeof(GtkFreqKnobClass),
|
sizeof(GtkFreqKnobClass),
|
||||||
NULL, /* base_init */
|
NULL, /* base_init */
|
||||||
|
|
@ -81,7 +95,8 @@ GType gtk_freq_knob_get_type()
|
||||||
(GInstanceInitFunc) gtk_freq_knob_init,
|
(GInstanceInitFunc) gtk_freq_knob_init,
|
||||||
NULL,
|
NULL,
|
||||||
};
|
};
|
||||||
gtk_freq_knob_type = g_type_register_static(GTK_TYPE_BOX,
|
|
||||||
|
gtk_freq_knob_type = g_type_register_static(GTK_TYPE_VBOX,
|
||||||
"GtkFreqKnob",
|
"GtkFreqKnob",
|
||||||
>k_freq_knob_info, 0);
|
>k_freq_knob_info, 0);
|
||||||
}
|
}
|
||||||
|
|
@ -91,16 +106,23 @@ GType gtk_freq_knob_get_type()
|
||||||
|
|
||||||
static void gtk_freq_knob_class_init(GtkFreqKnobClass * class)
|
static void gtk_freq_knob_class_init(GtkFreqKnobClass * class)
|
||||||
{
|
{
|
||||||
GtkWidgetClass *widget_class = (GtkWidgetClass *) class;
|
/*GObjectClass *gobject_class; */
|
||||||
widget_class->destroy = gtk_freq_knob_destroy;
|
GtkObjectClass *object_class;
|
||||||
|
|
||||||
|
/*GtkWidgetClass *widget_class; */
|
||||||
|
/*GtkContainerClass *container_class; */
|
||||||
|
|
||||||
|
/*gobject_class = G_OBJECT_CLASS (class); */
|
||||||
|
object_class = (GtkObjectClass *) class;
|
||||||
|
/*widget_class = (GtkWidgetClass*) class; */
|
||||||
|
/*container_class = (GtkContainerClass*) class; */
|
||||||
|
|
||||||
parent_class = g_type_class_peek_parent(class);
|
parent_class = g_type_class_peek_parent(class);
|
||||||
|
|
||||||
|
object_class->destroy = gtk_freq_knob_destroy;
|
||||||
|
|
||||||
/* create freq changed signal */
|
/* create freq changed signal */
|
||||||
freq_changed_signal = g_signal_new("freq-changed",
|
freq_changed_signal = g_signal_new("freq-changed", G_TYPE_FROM_CLASS(class), G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION, 0, //G_STRUCT_OFFSET (GtkFreqKnobClass, tictactoe),
|
||||||
G_TYPE_FROM_CLASS(class),
|
|
||||||
G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION,
|
|
||||||
0,
|
|
||||||
NULL,
|
NULL,
|
||||||
NULL,
|
NULL,
|
||||||
g_cclosure_marshal_VOID__VOID,
|
g_cclosure_marshal_VOID__VOID,
|
||||||
|
|
@ -114,17 +136,16 @@ static void gtk_freq_knob_init(GtkFreqKnob * knob)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void gtk_freq_knob_destroy(GtkWidget * widget)
|
static void gtk_freq_knob_destroy(GtkObject * object)
|
||||||
{
|
{
|
||||||
(*GTK_WIDGET_CLASS(parent_class)->destroy) (widget);
|
(*GTK_OBJECT_CLASS(parent_class)->destroy) (object);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new Frequency control widget.
|
* \brief Create a new Frequency control widget.
|
||||||
*
|
* \param[in] val The initial value of the control.
|
||||||
* @param val The initial value of the control.
|
* \param[in] buttons Flag indicating whether buttons should be shown
|
||||||
* @param buttons Flag indicating whether buttons should be shown
|
* \return A new frequency control widget.
|
||||||
* @return A new frequency control widget.
|
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
GtkWidget *gtk_freq_knob_new(gdouble val, gboolean buttons)
|
GtkWidget *gtk_freq_knob_new(gdouble val, gboolean buttons)
|
||||||
|
|
@ -135,6 +156,7 @@ GtkWidget *gtk_freq_knob_new(gdouble val, gboolean buttons)
|
||||||
guint i;
|
guint i;
|
||||||
gint delta;
|
gint delta;
|
||||||
|
|
||||||
|
|
||||||
widget = g_object_new(GTK_TYPE_FREQ_KNOB, NULL);
|
widget = g_object_new(GTK_TYPE_FREQ_KNOB, NULL);
|
||||||
|
|
||||||
GTK_FREQ_KNOB(widget)->value = val;
|
GTK_FREQ_KNOB(widget)->value = val;
|
||||||
|
|
@ -158,6 +180,7 @@ GtkWidget *gtk_freq_knob_new(gdouble val, gboolean buttons)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* active widget that allows changing the value */
|
/* active widget that allows changing the value */
|
||||||
|
|
||||||
gtk_widget_set_tooltip_text(GTK_FREQ_KNOB(widget)->digits[i],
|
gtk_widget_set_tooltip_text(GTK_FREQ_KNOB(widget)->digits[i],
|
||||||
_
|
_
|
||||||
("Use mouse buttons and wheel to change value"));
|
("Use mouse buttons and wheel to change value"));
|
||||||
|
|
@ -172,12 +195,14 @@ GtkWidget *gtk_freq_knob_new(gdouble val, gboolean buttons)
|
||||||
GTK_FREQ_KNOB(widget)->evtbox[i], idx[i],
|
GTK_FREQ_KNOB(widget)->evtbox[i], idx[i],
|
||||||
idx[i] + 1, 1, 2, GTK_SHRINK,
|
idx[i] + 1, 1, 2, GTK_SHRINK,
|
||||||
GTK_FILL | GTK_EXPAND, 0, 0);
|
GTK_FILL | GTK_EXPAND, 0, 0);
|
||||||
|
|
||||||
g_signal_connect(GTK_FREQ_KNOB(widget)->evtbox[i],
|
g_signal_connect(GTK_FREQ_KNOB(widget)->evtbox[i],
|
||||||
"button_press_event", (GCallback) on_button_press,
|
"button_press_event", (GCallback) on_button_press,
|
||||||
widget);
|
widget);
|
||||||
g_signal_connect(GTK_FREQ_KNOB(widget)->evtbox[i], "scroll_event",
|
g_signal_connect(GTK_FREQ_KNOB(widget)->evtbox[i], "scroll_event",
|
||||||
(GCallback) on_button_scroll, widget);
|
(GCallback) on_button_scroll, widget);
|
||||||
|
|
||||||
|
|
||||||
/* UP buttons */
|
/* UP buttons */
|
||||||
GTK_FREQ_KNOB(widget)->buttons[i] = gtk_button_new();
|
GTK_FREQ_KNOB(widget)->buttons[i] = gtk_button_new();
|
||||||
|
|
||||||
|
|
@ -230,7 +255,8 @@ GtkWidget *gtk_freq_knob_new(gdouble val, gboolean buttons)
|
||||||
gtk_table_attach(GTK_TABLE(table), label, 13, 14, 1, 2,
|
gtk_table_attach(GTK_TABLE(table), label, 13, 14, 1, 2,
|
||||||
GTK_SHRINK, GTK_SHRINK, 0, 0);
|
GTK_SHRINK, GTK_SHRINK, 0, 0);
|
||||||
|
|
||||||
gtk_freq_knob_update(GTK_FREQ_KNOB(widget));
|
|
||||||
|
g_idle_add((GSourceFunc) gtk_freq_knob_update, GTK_FREQ_KNOB(widget));
|
||||||
|
|
||||||
gtk_container_add(GTK_CONTAINER(widget), table);
|
gtk_container_add(GTK_CONTAINER(widget), table);
|
||||||
gtk_widget_show_all(widget);
|
gtk_widget_show_all(widget);
|
||||||
|
|
@ -239,10 +265,9 @@ GtkWidget *gtk_freq_knob_new(gdouble val, gboolean buttons)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the value of the frequency control widget.
|
* \brief Set the value of the frequency control widget.
|
||||||
*
|
* \param[in] knob The frequency control widget.
|
||||||
* @param knob The frequency control widget.
|
* \param[in] val The new value.
|
||||||
* @param val The new value.
|
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
void gtk_freq_knob_set_value(GtkFreqKnob * knob, gdouble val)
|
void gtk_freq_knob_set_value(GtkFreqKnob * knob, gdouble val)
|
||||||
|
|
@ -253,15 +278,14 @@ void gtk_freq_knob_set_value(GtkFreqKnob * knob, gdouble val)
|
||||||
knob->value = val;
|
knob->value = val;
|
||||||
|
|
||||||
/* update the display */
|
/* update the display */
|
||||||
gtk_freq_knob_update(knob);
|
g_idle_add((GSourceFunc) gtk_freq_knob_update, knob);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the current value of the frequency control widget.
|
* \brief Get the current value of the frequency control widget.
|
||||||
*
|
* \param[in] knob The frequency control widget.
|
||||||
* @param knob The frequency control widget.
|
* \return The current value.
|
||||||
* @return The current value.
|
|
||||||
*
|
*
|
||||||
* Hint: For reading the value you can also access knob->value.
|
* Hint: For reading the value you can also access knob->value.
|
||||||
*
|
*
|
||||||
|
|
@ -272,17 +296,19 @@ gdouble gtk_freq_knob_get_value(GtkFreqKnob * knob)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update frequency display widget.
|
* \brief Update frequency display widget.
|
||||||
*
|
* \param[in] knob The frequency control widget.
|
||||||
* @param knob The frequency control widget.
|
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
static void gtk_freq_knob_update(GtkFreqKnob * knob)
|
static void *gtk_freq_knob_update(GtkFreqKnob * knob)
|
||||||
{
|
{
|
||||||
gchar b[11];
|
gchar b[11];
|
||||||
gchar *buff;
|
gchar *buff;
|
||||||
guint i;
|
guint i;
|
||||||
|
|
||||||
|
/* Enter critical section! */
|
||||||
|
G_LOCK(updatelock);
|
||||||
|
|
||||||
g_ascii_formatd(b, 11, "%10.0f", fabs(knob->value));
|
g_ascii_formatd(b, 11, "%10.0f", fabs(knob->value));
|
||||||
|
|
||||||
/* set label markups */
|
/* set label markups */
|
||||||
|
|
@ -292,13 +318,16 @@ static void gtk_freq_knob_update(GtkFreqKnob * knob)
|
||||||
gtk_label_set_markup(GTK_LABEL(knob->digits[i]), buff);
|
gtk_label_set_markup(GTK_LABEL(knob->digits[i]), buff);
|
||||||
g_free(buff);
|
g_free(buff);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Leave critical section! */
|
||||||
|
G_UNLOCK(updatelock);
|
||||||
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Button clicked event.
|
* \brief Button clicked event.
|
||||||
*
|
* \param button The button that was clicked.
|
||||||
* @param button The button that was clicked.
|
* \param data Pointer to the GtkFreqKnob widget.
|
||||||
* @param data Pointer to the GtkFreqKnob widget.
|
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
static void button_clicked_cb(GtkWidget * button, gpointer data)
|
static void button_clicked_cb(GtkWidget * button, gpointer data)
|
||||||
|
|
@ -316,19 +345,18 @@ static void button_clicked_cb(GtkWidget * button, gpointer data)
|
||||||
knob->value += delta;
|
knob->value += delta;
|
||||||
}
|
}
|
||||||
|
|
||||||
gtk_freq_knob_update(knob);
|
g_idle_add((GSourceFunc) gtk_freq_knob_update, knob);
|
||||||
|
|
||||||
/* emit "freq_changed" signal */
|
/* emit "freq_changed" signal */
|
||||||
g_signal_emit(G_OBJECT(data), freq_changed_signal, 0);
|
g_signal_emit(G_OBJECT(data), freq_changed_signal, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Manage button press events
|
* \brief Manage button press events
|
||||||
*
|
* \param digit Pointer to the event box that received the event
|
||||||
* @param digit Pointer to the event box that received the event
|
* \param event Pointer to the GdkEventButton that contains details for te event
|
||||||
* @param event Pointer to the GdkEventButton that contains details for te event
|
* \param data Pointer to the GtkFreqKnob widget (we need it to update the value)
|
||||||
* @param data Pointer to the GtkFreqKnob widget (we need it to update the value)
|
* \return Always TRUE to prevent further propagation of the event
|
||||||
* @return Always TRUE to prevent further propagation of the event
|
|
||||||
*
|
*
|
||||||
* This function is called when a mouse button is pressed on a digit. This is used
|
* This function is called when a mouse button is pressed on a digit. This is used
|
||||||
* to increment or decrement the value:
|
* to increment or decrement the value:
|
||||||
|
|
@ -336,13 +364,16 @@ static void button_clicked_cb(GtkWidget * button, gpointer data)
|
||||||
* - Right button: down
|
* - Right button: down
|
||||||
* - Middle button: set digit to 0 (TBC)
|
* - Middle button: set digit to 0 (TBC)
|
||||||
*
|
*
|
||||||
* Wheel up/down are managed in a separate callback since these are treated as scroll events
|
* Wheel up/down are managed in a separate callback since these are treated as
|
||||||
* rather than button press events (they used to be button press events though)
|
* scroll events rather than button press events (they used to be button press
|
||||||
|
* events though)
|
||||||
*
|
*
|
||||||
* The digit labels are stored in an array. To get the amount of change corresponding to the
|
* The digit labels are stored in an array. To get the amount of change corresponding
|
||||||
* clicked label we can convert the index (attached to the evtbox): delta = 10^(9-index)
|
* to the clicked label we can convert the index (attached to the evtbox):
|
||||||
|
* delta = 10^(9-index)
|
||||||
*
|
*
|
||||||
* Whether the delta is positive or negative depends on which mouse button triggered the event.
|
* Whether the delta is positive or negative depends on which mouse button triggered
|
||||||
|
* the event.
|
||||||
*/
|
*/
|
||||||
static gboolean on_button_press(GtkWidget * evtbox,
|
static gboolean on_button_press(GtkWidget * evtbox,
|
||||||
GdkEventButton * event, gpointer data)
|
GdkEventButton * event, gpointer data)
|
||||||
|
|
@ -394,21 +425,21 @@ static gboolean on_button_press(GtkWidget * evtbox,
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Manage scroll wheel events
|
* \brief Manage scroll wheel events
|
||||||
|
* \param digit Pointer to the event box that received the event
|
||||||
|
* \param event Pointer to the GdkEventScroll that contains details for te event
|
||||||
|
* \param data Pointer to the GtkFreqKnob widget (we need it to update the value)
|
||||||
|
* \return Always TRUE to prevent further propagation of the event
|
||||||
*
|
*
|
||||||
* @param digit Pointer to the event box that received the event
|
* This function is called when the mouse wheel is moved up or down. This is used
|
||||||
* @param event Pointer to the GdkEventScroll that contains details for te event
|
* to increment or decrement the value.
|
||||||
* @param data Pointer to the GtkFreqKnob widget (we need it to update the value)
|
|
||||||
* @return Always TRUE to prevent further propagation of the event
|
|
||||||
*
|
*
|
||||||
* This function is called when the mouse wheel is moved up or down. This is used to increment
|
* Button presses are managed in a separate callback since these are treated as
|
||||||
* or decrement the value.
|
* different events.
|
||||||
*
|
*
|
||||||
* Button presses are managed in a separate callback since these are treated as different
|
* The digit labels are stored in an array. To get the amount of change corresponding
|
||||||
* events.
|
* to the clicked label we can convert the index (attached to the evtbox):
|
||||||
*
|
* delta = 10^(9-index)
|
||||||
* The digit labels are stored in an array. To get the amount of change corresponding to the
|
|
||||||
* clicked label we can convert the index (attached to the evtbox): delta = 10^(9-index)
|
|
||||||
*
|
*
|
||||||
* Whether the delta is positive or negative depends on the scroll direction.
|
* Whether the delta is positive or negative depends on the scroll direction.
|
||||||
*/
|
*/
|
||||||
|
|
@ -421,6 +452,7 @@ static gboolean on_button_scroll(GtkWidget * evtbox,
|
||||||
gdouble delta = pow(10, 9 - idx);
|
gdouble delta = pow(10, 9 - idx);
|
||||||
gdouble value;
|
gdouble value;
|
||||||
|
|
||||||
|
|
||||||
if (delta < 0.01)
|
if (delta < 0.01)
|
||||||
{
|
{
|
||||||
/* no change, user clicked on sign or decimal separator */
|
/* no change, user clicked on sign or decimal separator */
|
||||||
|
|
@ -435,6 +467,7 @@ static gboolean on_button_scroll(GtkWidget * evtbox,
|
||||||
|
|
||||||
switch (event->direction)
|
switch (event->direction)
|
||||||
{
|
{
|
||||||
|
|
||||||
/* decrease value by delta */
|
/* decrease value by delta */
|
||||||
case GDK_SCROLL_DOWN:
|
case GDK_SCROLL_DOWN:
|
||||||
case GDK_SCROLL_LEFT:
|
case GDK_SCROLL_LEFT:
|
||||||
|
|
|
||||||
|
|
@ -35,12 +35,13 @@
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif /* __cplusplus */
|
#endif /* __cplusplus */
|
||||||
/* *INDENT-ON* */
|
/* *INDENT-OO* */
|
||||||
|
|
||||||
|
|
||||||
#define GTK_TYPE_FREQ_KNOB (gtk_freq_knob_get_type ())
|
#define GTK_TYPE_FREQ_KNOB (gtk_freq_knob_get_type ())
|
||||||
#define GTK_FREQ_KNOB(obj) G_TYPE_CHECK_INSTANCE_CAST (obj,\
|
#define GTK_FREQ_KNOB(obj) G_TYPE_CHECK_INSTANCE_CAST (obj,\
|
||||||
gtk_freq_knob_get_type (),\
|
gtk_freq_knob_get_type (),\
|
||||||
GtkFreqKnob)
|
GtkFreqKnob)
|
||||||
|
|
||||||
#define GTK_FREQ_KNOB_CLASS(klass) G_TYPE_CHECK_CLASS_CAST (klass,\
|
#define GTK_FREQ_KNOB_CLASS(klass) G_TYPE_CHECK_CLASS_CAST (klass,\
|
||||||
gtk_freq_knob_get_type (),\
|
gtk_freq_knob_get_type (),\
|
||||||
|
|
@ -48,29 +49,32 @@ extern "C" {
|
||||||
|
|
||||||
#define IS_GTK_FREQ_KNOB(obj) G_TYPE_CHECK_INSTANCE_TYPE (obj, gtk_freq_knob_get_type ())
|
#define IS_GTK_FREQ_KNOB(obj) G_TYPE_CHECK_INSTANCE_TYPE (obj, gtk_freq_knob_get_type ())
|
||||||
|
|
||||||
typedef struct _gtk_freq_knob GtkFreqKnob;
|
|
||||||
typedef struct _GtkFreqKnobClass GtkFreqKnobClass;
|
|
||||||
|
|
||||||
struct _gtk_freq_knob {
|
typedef struct _gtk_freq_knob GtkFreqKnob;
|
||||||
GtkBox box;
|
typedef struct _GtkFreqKnobClass GtkFreqKnobClass;
|
||||||
|
|
||||||
GtkWidget *digits[10]; /*!< Labels for the digits */
|
struct _gtk_freq_knob
|
||||||
GtkWidget *evtbox[10]; /*!< Event boxes to catch mouse events over the digits */
|
{
|
||||||
GtkWidget *buttons[20]; /*!< Buttons; 0..9 up; 10..19 down */
|
GtkVBox vbox;
|
||||||
|
|
||||||
gdouble min;
|
GtkWidget *digits[10]; /*!< Labels for the digits */
|
||||||
gdouble max;
|
GtkWidget *evtbox[10]; /*!< Event boxes to catch mouse events over the digits */
|
||||||
gdouble value;
|
GtkWidget *buttons[20]; /*!< Buttons; 0..9 up; 10..19 down */
|
||||||
|
|
||||||
|
gdouble min;
|
||||||
|
gdouble max;
|
||||||
|
gdouble value;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _GtkFreqKnobClass {
|
struct _GtkFreqKnobClass
|
||||||
GtkBoxClass parent_class;
|
{
|
||||||
|
GtkVBoxClass parent_class;
|
||||||
};
|
};
|
||||||
|
|
||||||
GType gtk_freq_knob_get_type(void);
|
GType gtk_freq_knob_get_type (void);
|
||||||
GtkWidget *gtk_freq_knob_new(gdouble val, gboolean buttons);
|
GtkWidget* gtk_freq_knob_new (gdouble val, gboolean buttons);
|
||||||
void gtk_freq_knob_set_value(GtkFreqKnob * knob, gdouble val);
|
void gtk_freq_knob_set_value (GtkFreqKnob *knob, gdouble val);
|
||||||
gdouble gtk_freq_knob_get_value(GtkFreqKnob * knob);
|
gdouble gtk_freq_knob_get_value (GtkFreqKnob *knob);
|
||||||
|
|
||||||
|
|
||||||
/* *INDENT-OFF* */
|
/* *INDENT-OFF* */
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@
|
||||||
Copyright (C) 2001-2013 Alexandru Csete, OZ9AEC.
|
Copyright (C) 2001-2013 Alexandru Csete, OZ9AEC.
|
||||||
|
|
||||||
Authors: Alexandru Csete <oz9aec@gmail.com>
|
Authors: Alexandru Csete <oz9aec@gmail.com>
|
||||||
|
Patrick Dohmen <dl4pd@darc.de>
|
||||||
|
|
||||||
Comments, questions and bugreports should be submitted via
|
Comments, questions and bugreports should be submitted via
|
||||||
http://sourceforge.net/projects/gpredict/
|
http://sourceforge.net/projects/gpredict/
|
||||||
|
|
@ -76,7 +77,7 @@
|
||||||
|
|
||||||
static void gtk_rig_ctrl_class_init(GtkRigCtrlClass * class);
|
static void gtk_rig_ctrl_class_init(GtkRigCtrlClass * class);
|
||||||
static void gtk_rig_ctrl_init(GtkRigCtrl * list);
|
static void gtk_rig_ctrl_init(GtkRigCtrl * list);
|
||||||
static void gtk_rig_ctrl_destroy(GtkWidget * widget);
|
static void gtk_rig_ctrl_destroy(GtkObject * object);
|
||||||
|
|
||||||
static GtkWidget *create_downlink_widgets(GtkRigCtrl * ctrl);
|
static GtkWidget *create_downlink_widgets(GtkRigCtrl * ctrl);
|
||||||
static GtkWidget *create_uplink_widgets(GtkRigCtrl * ctrl);
|
static GtkWidget *create_uplink_widgets(GtkRigCtrl * ctrl);
|
||||||
|
|
@ -145,6 +146,13 @@ static inline gboolean check_get_response(gchar * buff, gboolean retcode,
|
||||||
static gint sat_name_compare(sat_t * a, sat_t * b);
|
static gint sat_name_compare(sat_t * a, sat_t * b);
|
||||||
static gint rig_name_compare(const gchar * a, const gchar * b);
|
static gint rig_name_compare(const gchar * a, const gchar * b);
|
||||||
|
|
||||||
|
/* add thread for hamlib communication */
|
||||||
|
gpointer rigctl_run(gpointer data);
|
||||||
|
static void rigctrl_open(GtkRigCtrl * data);
|
||||||
|
static void rigctrl_close(GtkRigCtrl * data);
|
||||||
|
static void setconfig(gpointer data);
|
||||||
|
static void remove_timer(GtkRigCtrl * data);
|
||||||
|
static void start_timer(GtkRigCtrl * data);
|
||||||
|
|
||||||
static GtkVBoxClass *parent_class = NULL;
|
static GtkVBoxClass *parent_class = NULL;
|
||||||
|
|
||||||
|
|
@ -179,11 +187,20 @@ GType gtk_rig_ctrl_get_type()
|
||||||
|
|
||||||
static void gtk_rig_ctrl_class_init(GtkRigCtrlClass * class)
|
static void gtk_rig_ctrl_class_init(GtkRigCtrlClass * class)
|
||||||
{
|
{
|
||||||
GtkWidgetClass *widget_class = (GtkWidgetClass *) class;
|
//GObjectClass *gobject_class;
|
||||||
|
GtkObjectClass *object_class;
|
||||||
|
|
||||||
widget_class->destroy = gtk_rig_ctrl_destroy;
|
//GtkWidgetClass *widget_class;
|
||||||
|
//GtkContainerClass *container_class;
|
||||||
|
|
||||||
|
//gobject_class = G_OBJECT_CLASS (class);
|
||||||
|
object_class = (GtkObjectClass *) class;
|
||||||
|
//widget_class = (GtkWidgetClass*) class;
|
||||||
|
//container_class = (GtkContainerClass*) class;
|
||||||
|
|
||||||
parent_class = g_type_class_peek_parent(class);
|
parent_class = g_type_class_peek_parent(class);
|
||||||
|
|
||||||
|
object_class->destroy = gtk_rig_ctrl_destroy;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void gtk_rig_ctrl_init(GtkRigCtrl * ctrl)
|
static void gtk_rig_ctrl_init(GtkRigCtrl * ctrl)
|
||||||
|
|
@ -211,13 +228,23 @@ static void gtk_rig_ctrl_init(GtkRigCtrl * ctrl)
|
||||||
ctrl->last_toggle_tx = -1;
|
ctrl->last_toggle_tx = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void gtk_rig_ctrl_destroy(GtkWidget * widget)
|
static void gtk_rig_ctrl_destroy(GtkObject * object)
|
||||||
{
|
{
|
||||||
GtkRigCtrl *ctrl = GTK_RIG_CTRL(widget);
|
GtkRigCtrl *ctrl = GTK_RIG_CTRL(object);
|
||||||
|
|
||||||
/* stop timer */
|
if (ctrl->rigctl_thread != NULL)
|
||||||
if (ctrl->timerid > 0)
|
{
|
||||||
g_source_remove(ctrl->timerid);
|
|
||||||
|
g_mutex_lock(&ctrl->widgetsync);
|
||||||
|
|
||||||
|
ctrl->engaged = 0;
|
||||||
|
setconfig(ctrl);
|
||||||
|
|
||||||
|
/* synchronization */
|
||||||
|
g_cond_wait(&ctrl->widgetready, &ctrl->widgetsync);
|
||||||
|
g_mutex_unlock(&ctrl->widgetsync);
|
||||||
|
ctrl->rigctl_thread = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
/* free configuration */
|
/* free configuration */
|
||||||
if (ctrl->conf != NULL)
|
if (ctrl->conf != NULL)
|
||||||
|
|
@ -242,12 +269,7 @@ static void gtk_rig_ctrl_destroy(GtkWidget * widget)
|
||||||
ctrl->trsplist = NULL;
|
ctrl->trsplist = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* close sockets if they are open */
|
(*GTK_OBJECT_CLASS(parent_class)->destroy) (object);
|
||||||
if (ctrl->sock)
|
|
||||||
close_rigctld_socket(&(ctrl->sock));
|
|
||||||
if (ctrl->sock2)
|
|
||||||
close_rigctld_socket(&(ctrl->sock2));
|
|
||||||
(*GTK_WIDGET_CLASS(parent_class)->destroy) (widget);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -310,10 +332,6 @@ GtkWidget *gtk_rig_ctrl_new(GtkSatModule * module)
|
||||||
|
|
||||||
gtk_container_add(GTK_CONTAINER(widget), table);
|
gtk_container_add(GTK_CONTAINER(widget), table);
|
||||||
|
|
||||||
GTK_RIG_CTRL(widget)->timerid = g_timeout_add(GTK_RIG_CTRL(widget)->delay,
|
|
||||||
rig_ctrl_timeout_cb,
|
|
||||||
GTK_RIG_CTRL(widget));
|
|
||||||
|
|
||||||
if (module->target > 0)
|
if (module->target > 0)
|
||||||
gtk_rig_ctrl_select_sat(GTK_RIG_CTRL(widget), module->target);
|
gtk_rig_ctrl_select_sat(GTK_RIG_CTRL(widget), module->target);
|
||||||
|
|
||||||
|
|
@ -333,6 +351,9 @@ void gtk_rig_ctrl_update(GtkRigCtrl * ctrl, gdouble t)
|
||||||
gdouble satfreq;
|
gdouble satfreq;
|
||||||
gchar *buff;
|
gchar *buff;
|
||||||
|
|
||||||
|
/* Enter critical section! */
|
||||||
|
g_mutex_lock(&ctrl->rig_ctrl_updatelock);
|
||||||
|
|
||||||
if (ctrl->target)
|
if (ctrl->target)
|
||||||
{
|
{
|
||||||
/* update Az/El */
|
/* update Az/El */
|
||||||
|
|
@ -401,6 +422,8 @@ void gtk_rig_ctrl_update(GtkRigCtrl * ctrl, gdouble t)
|
||||||
ctrl->pass = get_next_pass(ctrl->target, ctrl->qth, 3.0);
|
ctrl->pass = get_next_pass(ctrl->target, ctrl->qth, 3.0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/* Leave critical section! */
|
||||||
|
g_mutex_unlock(&ctrl->rig_ctrl_updatelock);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Select a satellite */
|
/** Select a satellite */
|
||||||
|
|
@ -941,7 +964,6 @@ static void sat_selected_cb(GtkComboBox * satsel, gpointer data)
|
||||||
free_pass(ctrl->pass);
|
free_pass(ctrl->pass);
|
||||||
ctrl->pass = NULL;
|
ctrl->pass = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1075,10 +1097,10 @@ static void delay_changed_cb(GtkSpinButton * spin, gpointer data)
|
||||||
|
|
||||||
ctrl->delay = (guint) gtk_spin_button_get_value(spin);
|
ctrl->delay = (guint) gtk_spin_button_get_value(spin);
|
||||||
|
|
||||||
if (ctrl->timerid > 0)
|
if (ctrl->engaged)
|
||||||
g_source_remove(ctrl->timerid);
|
{
|
||||||
|
start_timer(ctrl);
|
||||||
ctrl->timerid = g_timeout_add(ctrl->delay, rig_ctrl_timeout_cb, ctrl);
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -1283,74 +1305,21 @@ static void rig_engaged_cb(GtkToggleButton * button, gpointer data)
|
||||||
gtk_widget_set_sensitive(ctrl->DevSel, TRUE);
|
gtk_widget_set_sensitive(ctrl->DevSel, TRUE);
|
||||||
gtk_widget_set_sensitive(ctrl->DevSel2, TRUE);
|
gtk_widget_set_sensitive(ctrl->DevSel2, TRUE);
|
||||||
ctrl->engaged = FALSE;
|
ctrl->engaged = FALSE;
|
||||||
ctrl->lasttxf = 0.0;
|
|
||||||
ctrl->lastrxf = 0.0;
|
|
||||||
|
|
||||||
if ((ctrl->conf->type == RIG_TYPE_TOGGLE_AUTO) ||
|
/* stop worker thread... */
|
||||||
(ctrl->conf->type == RIG_TYPE_TOGGLE_MAN))
|
setconfig(ctrl);
|
||||||
{
|
ctrl->rigctl_thread = NULL;
|
||||||
unset_toggle(ctrl, ctrl->sock);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ctrl->conf2 != NULL)
|
|
||||||
{
|
|
||||||
close_rigctld_socket(&(ctrl->sock2));
|
|
||||||
}
|
|
||||||
close_rigctld_socket(&(ctrl->sock));
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
gtk_widget_set_sensitive(ctrl->DevSel, FALSE);
|
gtk_widget_set_sensitive(ctrl->DevSel, FALSE);
|
||||||
gtk_widget_set_sensitive(ctrl->DevSel2, FALSE);
|
gtk_widget_set_sensitive(ctrl->DevSel2, FALSE);
|
||||||
ctrl->engaged = TRUE;
|
ctrl->engaged = TRUE;
|
||||||
ctrl->wrops = 0;
|
|
||||||
|
|
||||||
open_rigctld_socket(ctrl->conf, &(ctrl->sock));
|
/* start worker thread... */
|
||||||
|
ctrl->rigctlq = g_async_queue_new();
|
||||||
/* set initial frequency */
|
ctrl->rigctl_thread = g_thread_new("rigctl_run", rigctl_run, ctrl);
|
||||||
if (ctrl->conf2 != NULL)
|
setconfig(ctrl);
|
||||||
{
|
|
||||||
open_rigctld_socket(ctrl->conf2, &(ctrl->sock2));
|
|
||||||
/* set initial dual mode */
|
|
||||||
exec_dual_rig_cycle(ctrl);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
switch (ctrl->conf->type)
|
|
||||||
{
|
|
||||||
|
|
||||||
case RIG_TYPE_RX:
|
|
||||||
exec_rx_cycle(ctrl);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case RIG_TYPE_TX:
|
|
||||||
exec_tx_cycle(ctrl);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case RIG_TYPE_TRX:
|
|
||||||
exec_trx_cycle(ctrl);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case RIG_TYPE_DUPLEX:
|
|
||||||
/* set rig into SAT mode (hamlib needs it even if rig already in SAT) */
|
|
||||||
setup_split(ctrl);
|
|
||||||
exec_duplex_cycle(ctrl);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case RIG_TYPE_TOGGLE_AUTO:
|
|
||||||
case RIG_TYPE_TOGGLE_MAN:
|
|
||||||
set_toggle(ctrl, ctrl->sock);
|
|
||||||
ctrl->last_toggle_tx = -1;
|
|
||||||
exec_toggle_cycle(ctrl);
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
/* this is an error! */
|
|
||||||
ctrl->conf->type = RIG_TYPE_RX;
|
|
||||||
exec_rx_cycle(ctrl);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1367,7 +1336,7 @@ static void rig_engaged_cb(GtkToggleButton * button, gpointer data)
|
||||||
static gboolean setup_split(GtkRigCtrl * ctrl)
|
static gboolean setup_split(GtkRigCtrl * ctrl)
|
||||||
{
|
{
|
||||||
gchar *buff;
|
gchar *buff;
|
||||||
gchar buffback[128];
|
gchar buffback[256 /*128 */ ]; /* issues with receiving rigctld answer (assertion failed) */
|
||||||
gboolean retcode;
|
gboolean retcode;
|
||||||
|
|
||||||
/* select TX VFO */
|
/* select TX VFO */
|
||||||
|
|
@ -1458,7 +1427,7 @@ static gboolean rig_ctrl_timeout_cb(gpointer data)
|
||||||
sat_log_log(SAT_LOG_LEVEL_ERROR,
|
sat_log_log(SAT_LOG_LEVEL_ERROR,
|
||||||
_("%s: Controller does not have a valid configuration"),
|
_("%s: Controller does not have a valid configuration"),
|
||||||
__func__);
|
__func__);
|
||||||
return (TRUE);
|
return FALSE;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1469,63 +1438,8 @@ static gboolean rig_ctrl_timeout_cb(gpointer data)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
check_aos_los(ctrl);
|
/* push event */
|
||||||
|
setconfig(ctrl);
|
||||||
if (ctrl->conf2 != NULL)
|
|
||||||
{
|
|
||||||
exec_dual_rig_cycle(ctrl);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Execute controller cycle depending on primary radio type */
|
|
||||||
switch (ctrl->conf->type)
|
|
||||||
{
|
|
||||||
|
|
||||||
case RIG_TYPE_RX:
|
|
||||||
exec_rx_cycle(ctrl);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case RIG_TYPE_TX:
|
|
||||||
exec_tx_cycle(ctrl);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case RIG_TYPE_TRX:
|
|
||||||
exec_trx_cycle(ctrl);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case RIG_TYPE_DUPLEX:
|
|
||||||
exec_duplex_cycle(ctrl);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case RIG_TYPE_TOGGLE_AUTO:
|
|
||||||
case RIG_TYPE_TOGGLE_MAN:
|
|
||||||
exec_toggle_cycle(ctrl);
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
/* invalid mode */
|
|
||||||
sat_log_log(SAT_LOG_LEVEL_ERROR,
|
|
||||||
_("%s: Invalid radio type %d. Setting type to "
|
|
||||||
"RIG_TYPE_RX"), __func__, ctrl->conf->type);
|
|
||||||
ctrl->conf->type = RIG_TYPE_RX;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* perform error count checking */
|
|
||||||
if (ctrl->errcnt >= MAX_ERROR_COUNT)
|
|
||||||
{
|
|
||||||
/* disengage device */
|
|
||||||
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(ctrl->LockBut), FALSE);
|
|
||||||
ctrl->engaged = FALSE;
|
|
||||||
ctrl->errcnt = 0;
|
|
||||||
sat_log_log(SAT_LOG_LEVEL_ERROR,
|
|
||||||
_("%s: MAX_ERROR_COUNT (%d) reached. Disengaging device!"),
|
|
||||||
__func__, MAX_ERROR_COUNT);
|
|
||||||
|
|
||||||
//g_print ("ERROR. WROPS = %d\n", ctrl->wrops);
|
|
||||||
}
|
|
||||||
|
|
||||||
//g_print (" WROPS = %d\n", ctrl->wrops);
|
|
||||||
|
|
||||||
g_mutex_unlock(&(ctrl->busy));
|
g_mutex_unlock(&(ctrl->busy));
|
||||||
|
|
||||||
|
|
@ -1890,7 +1804,6 @@ static void exec_toggle_tx_cycle(GtkRigCtrl * ctrl)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Execute TX cycle for full duplex radios.
|
* \brief Execute TX cycle for full duplex radios.
|
||||||
* \param ctrl Pointer to the GtkRigCtrl structure.
|
* \param ctrl Pointer to the GtkRigCtrl structure.
|
||||||
|
|
@ -2058,8 +1971,7 @@ static void exec_dual_rig_cycle(GtkRigCtrl * ctrl)
|
||||||
{
|
{
|
||||||
satfreqd = readfreq + ctrl->conf->lo;
|
satfreqd = readfreq + ctrl->conf->lo;
|
||||||
}
|
}
|
||||||
gtk_freq_knob_set_value(GTK_FREQ_KNOB(ctrl->SatFreqDown),
|
gtk_freq_knob_set_value(GTK_FREQ_KNOB(ctrl->SatFreqDown), satfreqd);
|
||||||
satfreqd);
|
|
||||||
|
|
||||||
/* Update uplink if locked to downlink */
|
/* Update uplink if locked to downlink */
|
||||||
if (ctrl->trsplock)
|
if (ctrl->trsplock)
|
||||||
|
|
@ -2301,6 +2213,7 @@ static gboolean get_ptt(GtkRigCtrl * ctrl, gint sock)
|
||||||
pttstat = g_ascii_strtoull(vbuff[0], NULL, 0); //FIXME base = 0 ok?
|
pttstat = g_ascii_strtoull(vbuff[0], NULL, 0); //FIXME base = 0 ok?
|
||||||
g_strfreev(vbuff);
|
g_strfreev(vbuff);
|
||||||
}
|
}
|
||||||
|
|
||||||
g_free(buff);
|
g_free(buff);
|
||||||
|
|
||||||
return (pttstat == 1) ? TRUE : FALSE;
|
return (pttstat == 1) ? TRUE : FALSE;
|
||||||
|
|
@ -2326,8 +2239,8 @@ static gboolean set_ptt(GtkRigCtrl * ctrl, gint sock, gboolean ptt)
|
||||||
buff = g_strdup_printf("T 0\x0aq\x0a");
|
buff = g_strdup_printf("T 0\x0aq\x0a");
|
||||||
|
|
||||||
retcode = send_rigctld_command(ctrl, sock, buff, buffback, 128);
|
retcode = send_rigctld_command(ctrl, sock, buff, buffback, 128);
|
||||||
|
|
||||||
g_free(buff);
|
g_free(buff);
|
||||||
|
|
||||||
return (check_set_response(buffback, retcode, __func__));
|
return (check_set_response(buffback, retcode, __func__));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -2511,6 +2424,7 @@ static gboolean get_freq_simplex(GtkRigCtrl * ctrl, gint sock, gdouble * freq)
|
||||||
retval = FALSE;
|
retval = FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//g_free(buff);
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2554,6 +2468,7 @@ static gboolean get_freq_toggle(GtkRigCtrl * ctrl, gint sock, gdouble * freq)
|
||||||
retval = FALSE;
|
retval = FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//g_free(buff);
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2886,6 +2801,9 @@ gboolean send_rigctld_command(GtkRigCtrl * ctrl, gint sock, gchar * buff,
|
||||||
gint written;
|
gint written;
|
||||||
gint size;
|
gint size;
|
||||||
|
|
||||||
|
/* Enter critical section! */
|
||||||
|
g_mutex_lock(&ctrl->writelock);
|
||||||
|
|
||||||
/* added by Marcel Cimander; win32 newline -> \10\13 */
|
/* added by Marcel Cimander; win32 newline -> \10\13 */
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
size = strlen(buff) - 1;
|
size = strlen(buff) - 1;
|
||||||
|
|
@ -2933,6 +2851,9 @@ gboolean send_rigctld_command(GtkRigCtrl * ctrl, gint sock, gchar * buff,
|
||||||
}
|
}
|
||||||
ctrl->wrops++;
|
ctrl->wrops++;
|
||||||
|
|
||||||
|
/* Leave critical section! */
|
||||||
|
g_mutex_unlock(&ctrl->writelock);
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2961,7 +2882,7 @@ static gboolean key_press_cb(GtkWidget * widget, GdkEventKey * pKey,
|
||||||
switch (pKey->keyval)
|
switch (pKey->keyval)
|
||||||
{
|
{
|
||||||
/* keyvals not in API docs. See <gdk/gdkkeysyms.h> for a complete list */
|
/* keyvals not in API docs. See <gdk/gdkkeysyms.h> for a complete list */
|
||||||
case GDK_KEY_space:
|
case GDK_space:
|
||||||
sat_log_log(SAT_LOG_LEVEL_INFO,
|
sat_log_log(SAT_LOG_LEVEL_INFO,
|
||||||
_("%s: Detected SPACEBAR pressed event"), __func__);
|
_("%s: Detected SPACEBAR pressed event"), __func__);
|
||||||
|
|
||||||
|
|
@ -3175,8 +3096,8 @@ static inline gboolean check_set_response(gchar * buffback, gboolean retcode,
|
||||||
if (strncmp(buffback, "RPRT 0", 6) != 0)
|
if (strncmp(buffback, "RPRT 0", 6) != 0)
|
||||||
{
|
{
|
||||||
sat_log_log(SAT_LOG_LEVEL_ERROR,
|
sat_log_log(SAT_LOG_LEVEL_ERROR,
|
||||||
_("%s: %s rigctld returned error (%s)"),
|
_("%s:%s: %s rigctld returned error (%s)"),
|
||||||
__FILE__, function, buffback);
|
__FILE__, __func__, function, buffback);
|
||||||
|
|
||||||
retcode = FALSE;
|
retcode = FALSE;
|
||||||
}
|
}
|
||||||
|
|
@ -3200,8 +3121,8 @@ static inline gboolean check_get_response(gchar * buffback, gboolean retcode,
|
||||||
if (strncmp(buffback, "RPRT", 4) == 0)
|
if (strncmp(buffback, "RPRT", 4) == 0)
|
||||||
{
|
{
|
||||||
sat_log_log(SAT_LOG_LEVEL_ERROR,
|
sat_log_log(SAT_LOG_LEVEL_ERROR,
|
||||||
_("%s: %s rigctld returned error (%s)"),
|
_("%s:%s: %s rigctld returned error (%s)"),
|
||||||
__FILE__, function, buffback);
|
__FILE__, __func__, function, buffback);
|
||||||
|
|
||||||
retcode = FALSE;
|
retcode = FALSE;
|
||||||
}
|
}
|
||||||
|
|
@ -3209,3 +3130,245 @@ static inline gboolean check_get_response(gchar * buffback, gboolean retcode,
|
||||||
|
|
||||||
return retcode;
|
return retcode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void rigctrl_close(GtkRigCtrl * data)
|
||||||
|
{
|
||||||
|
GtkRigCtrl *ctrl = GTK_RIG_CTRL(data);
|
||||||
|
|
||||||
|
ctrl->lasttxf = 0.0;
|
||||||
|
ctrl->lastrxf = 0.0;
|
||||||
|
|
||||||
|
remove_timer(ctrl);
|
||||||
|
|
||||||
|
if ((ctrl->conf->type == RIG_TYPE_TOGGLE_AUTO) ||
|
||||||
|
(ctrl->conf->type == RIG_TYPE_TOGGLE_MAN))
|
||||||
|
{
|
||||||
|
unset_toggle(ctrl, ctrl->sock);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ctrl->conf2 != NULL)
|
||||||
|
{
|
||||||
|
close_rigctld_socket(&(ctrl->sock2));
|
||||||
|
}
|
||||||
|
close_rigctld_socket(&(ctrl->sock));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void rigctrl_open(GtkRigCtrl * data)
|
||||||
|
{
|
||||||
|
GtkRigCtrl *ctrl = GTK_RIG_CTRL(data);
|
||||||
|
|
||||||
|
ctrl->wrops = 0;
|
||||||
|
|
||||||
|
start_timer(ctrl);
|
||||||
|
|
||||||
|
open_rigctld_socket(ctrl->conf, &(ctrl->sock));
|
||||||
|
|
||||||
|
/* set initial frequency */
|
||||||
|
if (ctrl->conf2 != NULL)
|
||||||
|
{
|
||||||
|
open_rigctld_socket(ctrl->conf2, &(ctrl->sock2));
|
||||||
|
/* set initial dual mode */
|
||||||
|
exec_dual_rig_cycle(ctrl);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
switch (ctrl->conf->type)
|
||||||
|
{
|
||||||
|
|
||||||
|
case RIG_TYPE_RX:
|
||||||
|
exec_rx_cycle(ctrl);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RIG_TYPE_TX:
|
||||||
|
exec_tx_cycle(ctrl);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RIG_TYPE_TRX:
|
||||||
|
exec_trx_cycle(ctrl);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RIG_TYPE_DUPLEX:
|
||||||
|
/* set rig into SAT mode (hamlib needs it even if rig already in SAT) */
|
||||||
|
setup_split(ctrl);
|
||||||
|
exec_duplex_cycle(ctrl);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RIG_TYPE_TOGGLE_AUTO:
|
||||||
|
case RIG_TYPE_TOGGLE_MAN:
|
||||||
|
set_toggle(ctrl, ctrl->sock);
|
||||||
|
ctrl->last_toggle_tx = -1;
|
||||||
|
exec_toggle_cycle(ctrl);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
/* this is an error! */
|
||||||
|
ctrl->conf->type = RIG_TYPE_RX;
|
||||||
|
exec_rx_cycle(ctrl);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Communication thread for hamlib rigctld
|
||||||
|
* \param data
|
||||||
|
* \return NULL
|
||||||
|
*/
|
||||||
|
gpointer rigctl_run(gpointer data)
|
||||||
|
{
|
||||||
|
GtkRigCtrl *ctrl = GTK_RIG_CTRL(data);
|
||||||
|
GtkRigCtrl *t_ctrl = GTK_RIG_CTRL(data);
|
||||||
|
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
t_ctrl = GTK_RIG_CTRL(g_async_queue_pop(ctrl->rigctlq));
|
||||||
|
ctrl = t_ctrl;
|
||||||
|
while (g_main_context_iteration(NULL, FALSE));
|
||||||
|
|
||||||
|
if (t_ctrl == NULL)
|
||||||
|
{
|
||||||
|
sat_log_log(SAT_LOG_LEVEL_ERROR,
|
||||||
|
_("%s:%s: ERROR: NO VALID ctrl-struct"), __FILE__,
|
||||||
|
__func__);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (t_ctrl->engaged)
|
||||||
|
{
|
||||||
|
if (!t_ctrl->sock)
|
||||||
|
{
|
||||||
|
rigctrl_open(t_ctrl);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!t_ctrl->timerid)
|
||||||
|
{
|
||||||
|
start_timer(t_ctrl);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
g_mutex_lock(&t_ctrl->widgetsync);
|
||||||
|
|
||||||
|
if (t_ctrl->sock > 0)
|
||||||
|
{
|
||||||
|
rigctrl_close(t_ctrl);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (t_ctrl->timerid)
|
||||||
|
{
|
||||||
|
remove_timer(t_ctrl);
|
||||||
|
}
|
||||||
|
|
||||||
|
g_cond_signal(&t_ctrl->widgetready);
|
||||||
|
g_mutex_unlock(&t_ctrl->widgetsync);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
check_aos_los(t_ctrl);
|
||||||
|
|
||||||
|
if (t_ctrl->conf2 != NULL)
|
||||||
|
{
|
||||||
|
exec_dual_rig_cycle(t_ctrl);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Execute controller cycle depending on primary radio type */
|
||||||
|
switch (t_ctrl->conf->type)
|
||||||
|
{
|
||||||
|
|
||||||
|
case RIG_TYPE_RX:
|
||||||
|
exec_rx_cycle(t_ctrl);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RIG_TYPE_TX:
|
||||||
|
exec_tx_cycle(t_ctrl);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RIG_TYPE_TRX:
|
||||||
|
exec_trx_cycle(t_ctrl);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RIG_TYPE_DUPLEX:
|
||||||
|
exec_duplex_cycle(t_ctrl);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RIG_TYPE_TOGGLE_AUTO:
|
||||||
|
case RIG_TYPE_TOGGLE_MAN:
|
||||||
|
exec_toggle_cycle(t_ctrl);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
/* invalid mode */
|
||||||
|
sat_log_log(SAT_LOG_LEVEL_ERROR,
|
||||||
|
_("%s:%s: Invalid radio type %d. Setting type to "
|
||||||
|
"RIG_TYPE_RX"), __FILE__, __func__,
|
||||||
|
t_ctrl->conf->type);
|
||||||
|
t_ctrl->conf->type = RIG_TYPE_RX;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* perform error count checking */
|
||||||
|
if (t_ctrl->errcnt >= MAX_ERROR_COUNT)
|
||||||
|
{
|
||||||
|
/* disengage device */
|
||||||
|
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(t_ctrl->LockBut),
|
||||||
|
FALSE);
|
||||||
|
t_ctrl->engaged = FALSE;
|
||||||
|
t_ctrl->errcnt = 0;
|
||||||
|
sat_log_log(SAT_LOG_LEVEL_ERROR,
|
||||||
|
_
|
||||||
|
("%s:%s: MAX_ERROR_COUNT (%d) reached. Disengaging device!"),
|
||||||
|
__FILE__, __func__, MAX_ERROR_COUNT);
|
||||||
|
|
||||||
|
//g_print ("ERROR. WROPS = %d\n", ctrl->wrops);
|
||||||
|
}
|
||||||
|
|
||||||
|
//g_print (" WROPS = %d\n", ctrl->wrops);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* let's have a clean exit: */
|
||||||
|
if (t_ctrl->sock > 0)
|
||||||
|
{
|
||||||
|
rigctrl_close(t_ctrl);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (t_ctrl->timerid)
|
||||||
|
{
|
||||||
|
remove_timer(t_ctrl);
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void start_timer(GtkRigCtrl * data)
|
||||||
|
{
|
||||||
|
GtkRigCtrl *ctrl = GTK_RIG_CTRL(data);
|
||||||
|
|
||||||
|
/* start timeout timer here ("Cycle")! */
|
||||||
|
if (ctrl->timerid > 0)
|
||||||
|
g_source_remove(ctrl->timerid);
|
||||||
|
|
||||||
|
ctrl->timerid =
|
||||||
|
gdk_threads_add_timeout(ctrl->delay, rig_ctrl_timeout_cb, ctrl);
|
||||||
|
}
|
||||||
|
|
||||||
|
void remove_timer(GtkRigCtrl * data)
|
||||||
|
{
|
||||||
|
GtkRigCtrl *ctrl = GTK_RIG_CTRL(data);
|
||||||
|
|
||||||
|
/* stop timer */
|
||||||
|
if (ctrl->timerid > 0)
|
||||||
|
g_source_remove(ctrl->timerid);
|
||||||
|
ctrl->timerid = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setconfig(gpointer data)
|
||||||
|
{
|
||||||
|
/* something has changed... */
|
||||||
|
GtkRigCtrl *ctrl = GTK_RIG_CTRL(data);
|
||||||
|
|
||||||
|
if (ctrl != NULL)
|
||||||
|
{
|
||||||
|
g_async_queue_push(ctrl->rigctlq, ctrl);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -108,6 +108,16 @@ struct _gtk_rig_ctrl {
|
||||||
/* debug related */
|
/* debug related */
|
||||||
guint wrops;
|
guint wrops;
|
||||||
guint rdops;
|
guint rdops;
|
||||||
|
|
||||||
|
/* DL4PD */
|
||||||
|
/* threads related stuff */
|
||||||
|
/* add mutexes etc, to make threads reentrant! */
|
||||||
|
GMutex writelock; /*!< Mutex for blocking write operation */
|
||||||
|
GMutex rig_ctrl_updatelock; /*!< Mutex wile updating widgets etc */
|
||||||
|
GMutex widgetsync; /*!< Mutex used while leaving (sync stuff) */
|
||||||
|
GCond widgetready; /*!< Condition when work is done (sync stuff) */
|
||||||
|
GAsyncQueue *rigctlq; /*!< Message queue to indicate something has changed */
|
||||||
|
GThread *rigctl_thread; /*!< Pointer to current rigctl-thread */
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _GtkRigCtrlClass {
|
struct _GtkRigCtrlClass {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue