You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
405 lines
11 KiB
405 lines
11 KiB
|
|
#include "configuration.h"
|
|
#include "video.h"
|
|
#include "gui.h"
|
|
#include "detect.h"
|
|
|
|
#include <stdlib.h>
|
|
#include <string>
|
|
|
|
// extern VideoDev *videodev;
|
|
extern GtkBuilder *_builder_; // work around for threads
|
|
extern PosCtl posctl;
|
|
|
|
|
|
Configuration::Configuration() {
|
|
debugpath = NULL;
|
|
readdumppath = NULL;
|
|
destpath = "./";
|
|
show_debugwin = 0;
|
|
};
|
|
|
|
|
|
Configuration::~Configuration() {
|
|
};
|
|
|
|
|
|
std::string Configuration::GetDefaultFileName() {
|
|
std::string fn = "";
|
|
char *hd = getenv ((char*)"HOME");
|
|
|
|
if (hd != NULL) {
|
|
fn = hd;
|
|
fn = fn + "/" + CONFIGURATION_DEFAULTFILE;
|
|
}
|
|
|
|
return fn;
|
|
};
|
|
|
|
|
|
void Configuration::SaveDefault() {
|
|
std::string fn = GetDefaultFileName();
|
|
if (fn.length() < 1) {
|
|
printf ("%s:%d %s could not read HOME environment variable\n", __FILE__, __LINE__, __FUNCTION__);
|
|
return;
|
|
}
|
|
SaveConfig (fn);
|
|
};
|
|
|
|
|
|
void Configuration::LoadDefault() {
|
|
std::string fn = GetDefaultFileName();
|
|
if (fn.length() < 1) {
|
|
printf ("%s:%d %s could not read HOME environment variable\n", __FILE__, __LINE__, __FUNCTION__);
|
|
return;
|
|
}
|
|
LoadConfig (fn);
|
|
};
|
|
|
|
|
|
/*
|
|
* collect all the settings, and push them into the JSONparse object
|
|
* save the json string.
|
|
*/
|
|
void Configuration::SaveConfig(std::string filename) {
|
|
JSONParse jp;
|
|
string vstr;
|
|
int i;
|
|
GtkWidget *cb;
|
|
GtkWidget *cbe;
|
|
|
|
std::string s = setlocale(LC_ALL, NULL);
|
|
setlocale (LC_ALL, "C");
|
|
|
|
//
|
|
// Add resolution, format and video device to config json element
|
|
cb = GTK_WIDGET(gtk_builder_get_object (GTK_BUILDER(_builder_), "cb-videores"));
|
|
cbe = gtk_bin_get_child(GTK_BIN(cb));
|
|
jp.AddObject("video_resolution", (string) gtk_entry_get_text(GTK_ENTRY(cbe)));
|
|
cb = GTK_WIDGET(gtk_builder_get_object (GTK_BUILDER(_builder_), "cb-videofmt"));
|
|
cbe = gtk_bin_get_child(GTK_BIN(cb));
|
|
jp.AddObject("video_format", (string) gtk_entry_get_text(GTK_ENTRY(cbe)));
|
|
cb = GTK_WIDGET(gtk_builder_get_object (GTK_BUILDER(_builder_), "cb-videodev"));
|
|
cbe = gtk_bin_get_child(GTK_BIN(cb));
|
|
jp.AddObject("device", (string) gtk_entry_get_text(GTK_ENTRY(cbe)));
|
|
|
|
//
|
|
// save posctl settings
|
|
double amin, amax, akp, aki, akd;
|
|
JSONParse jaxis;
|
|
|
|
posctl.LockMutex();
|
|
for (i = 0; i < 2; i++) {
|
|
posctl.GetAxisParam(i, &amin, &amax, &akp, &aki, &akd);
|
|
jaxis.Clear();
|
|
jaxis.AddObject("min", amin);
|
|
jaxis.AddObject("max", amax);
|
|
jaxis.AddObject("kp", akp);
|
|
jaxis.AddObject("ki", aki);
|
|
jaxis.AddObject("kd", akd);
|
|
printf ("%s:%d save config axis %d Out Range: %f - %f kP:%g kI:%g kD:%g\n",
|
|
__FILE__, __LINE__, i, amin, amax, akp, aki, akd);
|
|
jp.AddObject("posctl_axis" + to_string(i), jaxis);
|
|
}
|
|
jp.AddObject("posctl_filter", posctl.GetFilter());
|
|
jp.AddObject("posctl_device", posctl.GetDevice());
|
|
posctl.UnLockMutex();
|
|
|
|
//
|
|
// histogram settings and debayer mode
|
|
jp.AddObject("histogram_log", histogram_log);
|
|
jp.AddObject("debayer_mode", debayer_mode);
|
|
|
|
//
|
|
// save destination path
|
|
jp.AddObject("destination_path", destpath);
|
|
|
|
//
|
|
// save button config
|
|
for (i = 0; i < BTN_PRESET_MAX; i++) {
|
|
JSONElement je;
|
|
je.type = JSON_T_ARRAY;
|
|
je.name = "presetbtn"+ std::to_string(i);
|
|
list<VideoDevCtrl>::iterator vciter;
|
|
JSONParse jpbtn;
|
|
jpbtn.Clear();
|
|
|
|
// convert VideoDevCtrl to JSON
|
|
for (vciter = presetbtn[i].begin(); vciter != presetbtn[i].end(); vciter++) {
|
|
jpbtn.Clear();
|
|
jpbtn.AddObject("name", vciter->name);
|
|
jpbtn.AddObject("id", (signed int) vciter->id);
|
|
jpbtn.AddObject("max", vciter->max);
|
|
jpbtn.AddObject("min", vciter->min);
|
|
jpbtn.AddObject("value", vciter->value);
|
|
|
|
if (je.value.length()>0) je.value += "," + jpbtn.ToString();
|
|
else je.value = jpbtn.ToString();
|
|
}
|
|
jp.AddObject(je);
|
|
}
|
|
|
|
//
|
|
// save windows position
|
|
printf ("%s:%d Xwayland is not able to retrieve the current position.\n", __FILE__, __LINE__);
|
|
for (i = 0; i < 6; i++) {
|
|
int x, y, w, h, show;
|
|
string name;
|
|
|
|
switch (i) {
|
|
case 0:
|
|
name = "window-main";
|
|
break;
|
|
case 1:
|
|
name = "window-input";
|
|
break;
|
|
case 2:
|
|
name = "window-output";
|
|
break;
|
|
case 3:
|
|
name = "window-detect";
|
|
break;
|
|
case 4:
|
|
name = "window-histogram";
|
|
break;
|
|
case 5:
|
|
name = "window-posctl";
|
|
break;
|
|
}
|
|
|
|
GtkWidget *wnd = GTK_WIDGET(gtk_builder_get_object (GTK_BUILDER(_builder_), name.c_str()));
|
|
if (wnd) {
|
|
g_object_get (wnd, "visible", &show, NULL);
|
|
gtk_widget_show (wnd);
|
|
gtk_window_get_position (GTK_WINDOW(wnd), &x, &y);
|
|
gtk_window_get_size (GTK_WINDOW(wnd), &w, &h);
|
|
|
|
jp.AddObject(name+"_x", x);
|
|
jp.AddObject(name+"_y", y);
|
|
jp.AddObject(name+"_w", w);
|
|
jp.AddObject(name+"_h", h);
|
|
jp.AddObject(name+"_show", show);
|
|
}
|
|
}
|
|
|
|
//
|
|
// save config
|
|
if (jp.SaveToFile(filename)) {
|
|
printf ("%s:%d %s could not save to file [%s] Error: %s\n", __FILE__, __LINE__, __FUNCTION__,
|
|
filename.c_str(), strerror(errno));
|
|
}
|
|
|
|
setlocale (LC_ALL, s.c_str());
|
|
};
|
|
|
|
|
|
void Configuration::LoadConfig(std::string filename) {
|
|
JSONParse jp;
|
|
string vstr;
|
|
int i;
|
|
JSONElement je;
|
|
|
|
std::string s = setlocale(LC_ALL, NULL);
|
|
setlocale (LC_ALL, "C");
|
|
|
|
if (jp.LoadFromFile(filename)) {
|
|
printf ("%s:%d %s could not load from file [%s] Error: %s\n", __FILE__, __LINE__, __FUNCTION__,
|
|
filename.c_str(), strerror(errno));
|
|
}
|
|
else {
|
|
printf ("%s:%d %s\n", __FILE__, __LINE__, __FUNCTION__);
|
|
|
|
//
|
|
// set resolution and video stream mode
|
|
//
|
|
if (jp.GetValue("video_resolution", &vstr)) {
|
|
GtkWidget *cbox = GTK_WIDGET(gtk_builder_get_object (GTK_BUILDER(_builder_), "cb-videores"));
|
|
GtkWidget *cbdevice = gtk_bin_get_child(GTK_BIN(cbox));
|
|
gtk_entry_set_text(GTK_ENTRY(cbdevice), vstr.c_str());
|
|
}
|
|
if (jp.GetValue("video_format", &vstr)) {
|
|
GtkWidget *cbox = GTK_WIDGET(gtk_builder_get_object (GTK_BUILDER(_builder_), "cb-videofmt"));
|
|
GtkWidget *cbdevice = gtk_bin_get_child(GTK_BIN(cbox));
|
|
gtk_entry_set_text(GTK_ENTRY(cbdevice), vstr.c_str());
|
|
}
|
|
|
|
//
|
|
// load posctl
|
|
double amin, amax, akp, aki, akd, f;
|
|
JSONParse jaxis;
|
|
|
|
posctl.LockMutex();
|
|
for (i = 0; i < 2; i++) {
|
|
if (jp.GetObjectJson("posctl_axis"+to_string(i), &jaxis)) {
|
|
jaxis.GetValueDouble("min", &amin);
|
|
jaxis.GetValueDouble("max", &amax);
|
|
jaxis.GetValueDouble("kp", &akp);
|
|
jaxis.GetValueDouble("ki", &aki);
|
|
jaxis.GetValueDouble("kd", &akd);
|
|
}
|
|
printf ("%s:%d load config axis %d Out Range: %f - %f kP:%f kI:%f kD:%f\n",
|
|
__FILE__, __LINE__, i, amin, amax, akp, aki, akd);
|
|
posctl.SetAxisParam(i, amin, amax, akp, aki, akd);
|
|
}
|
|
if (jp.GetValue("posctl_device", &vstr))
|
|
posctl.SetDevice(vstr);
|
|
if (jp.GetValueDouble("posctl_filter", &f))
|
|
posctl.SetFilter(f);
|
|
jp.AddObject("posctl_filter", posctl.GetFilter());
|
|
|
|
posctl.UnLockMutex();
|
|
|
|
jp.GetValueInt("histogram_log", &i);
|
|
SetHistogramLog(i);
|
|
|
|
jp.GetValueInt("debayer_mode", &i);
|
|
SetDebayerMode(i);
|
|
|
|
if (jp.GetValue("destination_path", &destpath)) {
|
|
GtkWidget *entry = GTK_WIDGET(gtk_builder_get_object (GTK_BUILDER(_builder_), "input_entry_destpath"));
|
|
gtk_entry_set_text(GTK_ENTRY(entry), destpath.c_str());
|
|
}
|
|
|
|
//
|
|
// start streaming if a device was selected.
|
|
//
|
|
if (jp.GetValue("device", &vstr)) {
|
|
GtkWidget *cbox = GTK_WIDGET(gtk_builder_get_object (GTK_BUILDER(_builder_), "cb-videodev"));
|
|
GtkWidget *cbdevice = gtk_bin_get_child(GTK_BIN(cbox));
|
|
gtk_entry_set_text(GTK_ENTRY(cbdevice), vstr.c_str());
|
|
}
|
|
|
|
//
|
|
// load the button config
|
|
//
|
|
for (i = 0; i < BTN_PRESET_MAX; i++) {
|
|
VideoDevCtrl ctrl;
|
|
JSONParse jpbtn, jpctrl;
|
|
list<JSONElement> je;
|
|
list<JSONElement>::iterator iter;
|
|
int ctrli;
|
|
int64_t id;
|
|
|
|
//
|
|
// load all controls from JSONParse object
|
|
presetbtn[i].clear();
|
|
ctrli = 0;
|
|
while (jp.GetObjectIdx("presetbtn"+ std::to_string(i), ctrli, &jpctrl)) {
|
|
jpctrl.GetValue("name", &ctrl.name);
|
|
jpctrl.GetValueInt64("id", &id);
|
|
ctrl.id = id;
|
|
jpctrl.GetValueInt("min", &ctrl.min);
|
|
jpctrl.GetValueInt("max", &ctrl.max);
|
|
jpctrl.GetValueInt("value", &ctrl.value);
|
|
presetbtn[i].push_back(ctrl);
|
|
ctrli++;
|
|
}
|
|
}
|
|
|
|
|
|
//
|
|
// check is the windows are inside the screen
|
|
// not really needed since gnome seem to take care about the windows positions
|
|
// and placement quite well.
|
|
GdkDisplay *dsp = gdk_display_get_default();
|
|
int n_monitor = -1;
|
|
if (dsp) {
|
|
n_monitor = gdk_display_get_n_monitors (dsp);
|
|
}
|
|
|
|
if (dsp && n_monitor > 0) {
|
|
GdkMonitor *g_monitor;
|
|
GdkRectangle geometry;
|
|
for (i = 0; i < n_monitor; i++) {
|
|
g_monitor = gdk_display_get_monitor(dsp, i);
|
|
if (g_monitor) {
|
|
gdk_monitor_get_geometry(g_monitor, &geometry);
|
|
printf ("%s:%d Monitor %d Pos:%d,%d Size:%d x %d\n", __FILE__, __LINE__, i,
|
|
geometry.x, geometry.y, geometry.width, geometry.height);
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// load windows position
|
|
for (i = 0; i < 6; i++) {
|
|
int x, y, w, h, show;
|
|
string name;
|
|
|
|
switch (i) {
|
|
case 0:
|
|
name = "window-main";
|
|
break;
|
|
case 1:
|
|
name = "window-input";
|
|
break;
|
|
case 2:
|
|
name = "window-output";
|
|
break;
|
|
case 3:
|
|
name = "window-detect";
|
|
break;
|
|
case 4:
|
|
name = "window-histogram";
|
|
break;
|
|
case 5:
|
|
name = "window-posctl";
|
|
break;
|
|
}
|
|
|
|
if (jp.GetValueInt(name+"_x", &x) && jp.GetValueInt(name+"_y", &y) &&
|
|
jp.GetValueInt(name+"_w", &w) && jp.GetValueInt(name+"_h", &h) &&
|
|
jp.GetValueInt(name+"_show", &show)) {
|
|
|
|
GtkWidget *wnd = GTK_WIDGET(gtk_builder_get_object (GTK_BUILDER(_builder_), name.c_str()));
|
|
if (wnd) {
|
|
printf ("%s:%d window '%s' set geometry %d,%d : %d x %d\n", __FILE__, __LINE__, name.c_str(), x, y, w, h);
|
|
gtk_window_move (GTK_WINDOW(wnd), x, y);
|
|
gtk_window_resize (GTK_WINDOW(wnd), w, h);
|
|
gtk_widget_show(wnd);
|
|
// g_object_set (wnd, "visible", &show, NULL);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
setlocale (LC_ALL, s.c_str());
|
|
|
|
// we need to update the gui so floating numbers will displayed with the correct
|
|
// language setting.
|
|
gdk_threads_add_idle(cb_thread_posctl, NULL);
|
|
};
|
|
|
|
|
|
/*
|
|
* presetbtn[btn]
|
|
*/
|
|
void Configuration::SetPresetButton (int btn, list<VideoDevCtrl> *parameters) {
|
|
if (btn < 0 || btn >= BTN_PRESET_MAX) return;
|
|
presetbtn[btn] = *parameters;
|
|
};
|
|
|
|
|
|
list<VideoDevCtrl> Configuration::GetPresetButton (int btn) {
|
|
list<VideoDevCtrl> emptylist;
|
|
if (btn >= 0 && btn < BTN_PRESET_MAX) return presetbtn[btn];
|
|
return emptylist;
|
|
};
|
|
|
|
|
|
void Configuration::SetHistogramLog(int trueorfalse) {
|
|
GtkWidget *cfg_logh = GTK_WIDGET(gtk_builder_get_object (GTK_BUILDER(_builder_), "menu-settings-loghistogram"));
|
|
gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM(cfg_logh), (trueorfalse == 1));
|
|
histogram_log = trueorfalse;
|
|
};
|
|
|
|
|
|
|
|
void Configuration::SetDebayerMode(int trueorfalse) {
|
|
GtkWidget *cfg_debayer = GTK_WIDGET(gtk_builder_get_object (GTK_BUILDER(_builder_), "menu-settings-bilinearrgb"));
|
|
gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM(cfg_debayer), (trueorfalse == 1));
|
|
debayer_mode = trueorfalse;
|
|
};
|
|
|
|
|