#include "configuration.h" #include "video.h" #include "gui.h" #include "detect.h" #include #include // 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::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 je; list::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 *parameters) { if (btn < 0 || btn >= BTN_PRESET_MAX) return; presetbtn[btn] = *parameters; }; list Configuration::GetPresetButton (int btn) { list 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; };