/*************************************************************************************** * * main.cc is part of SimpleSkyCam. * *****************************************************************************************/ #if defined(_WIN32) || defined(_WIN64) || defined(__CYGWIN__) #else #include /* close() */ #endif #include #include #include "gui.h" #include "config.h" #include "video.h" #include "filter.h" #include "detect.h" extern GtkBuilder *_builder_; // work around for threads extern Filter filter; extern Detect detect; GtkWidget *detect_da = NULL; GdkPixbuf *detect_pixbuf = NULL; GtkWidget *image_da = NULL; GdkPixbuf *image_pixbuf = NULL; std::string filename = ""; ////////////////////////////////////////////////////////////////////////////////////////////////// // // call back functions // gboolean cb_window_delete_event (GtkWidget *widget, GdkEvent *event, gpointer data) { gtk_main_quit(); return FALSE; }; // // setup default values // void cb_window_show (GtkWidget *widget, gpointer data) { GtkWidget *btnstart = GTK_WIDGET(gtk_builder_get_object (GTK_BUILDER(_builder_), "btn-video-rec")); GtkWidget *btnstop = GTK_WIDGET(gtk_builder_get_object (GTK_BUILDER(_builder_), "btn-video-stop")); GtkWidget *w = GTK_WIDGET(gtk_builder_get_object (GTK_BUILDER(_builder_), "detect-entry-w")); GtkWidget *h = GTK_WIDGET(gtk_builder_get_object (GTK_BUILDER(_builder_), "detect-entry-h")); printf ("%s:%d %s\n", __FILE__, __LINE__, __FUNCTION__); gtk_widget_set_sensitive(btnstart, true); gtk_widget_set_sensitive(btnstop, false); gtk_entry_set_text(GTK_ENTRY(w),"300"); gtk_entry_set_text(GTK_ENTRY(h),"300"); detect.SetObjectSize(300, 300); g_timeout_add(2000, videoctrl_update, NULL); }; void displayerror (std::string error) { GtkWidget *dialog; GtkWidget *window = GTK_WIDGET (gtk_builder_get_object (_builder_, "main-window")); dialog = gtk_message_dialog_new(GTK_WINDOW(window), GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, error.c_str()); gtk_window_set_title(GTK_WINDOW(dialog), "Error"); gtk_dialog_run(GTK_DIALOG(dialog)); gtk_widget_destroy(dialog); }; // // callback from filter thread. Data will point to the output VideoFrame. // Access to this data must be Locked before use. gboolean cb_thread_filter (gpointer data) { VideoFrame *vf = (VideoFrame *) data; int pix_h, pix_w; if (image_da == NULL) image_da = GTK_WIDGET(gtk_builder_get_object (GTK_BUILDER(_builder_), "image-da")); if (vf == NULL) { return false; } filter.LockImageMutex(); if (image_pixbuf) { pix_h = gdk_pixbuf_get_height(image_pixbuf); pix_w = gdk_pixbuf_get_width(image_pixbuf); } else pix_h = 0; if (image_pixbuf == NULL || pix_h != vf->h || pix_w != vf->w) { if (image_pixbuf != NULL) g_object_unref (image_pixbuf); printf ("%s:%d %s New Pixbuf: %d x %d\n", __FILE__, __LINE__, __FUNCTION__, vf->w, vf->h); image_pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, false, 8, vf->w, vf->h); pix_w = vf->w; pix_h = vf->h; } videoframe_to_pixbuf(image_pixbuf, vf); gdk_window_invalidate_rect(gtk_widget_get_window(image_da), NULL, true); filter.UnLockImageMutex(); return false; }; // // callback from filter thread. Data will point to the temp VideoFrame. // this is propabely the object detection // Access to this data must be Locked before use and pointers must be looked to gboolean cb_thread_detect (gpointer data) { GtkWidget *e_x = GTK_WIDGET(gtk_builder_get_object (GTK_BUILDER(_builder_), "detect-entry-posx")); GtkWidget *e_y = GTK_WIDGET(gtk_builder_get_object (GTK_BUILDER(_builder_), "detect-entry-posy")); DetectOutput *dout = (DetectOutput *) data; int pix_h, pix_w; if (detect_da == NULL) detect_da = GTK_WIDGET(gtk_builder_get_object (GTK_BUILDER(_builder_), "temp-da")); if (dout == NULL) return false; if (dout->image == NULL) return false; gtk_entry_set_text(GTK_ENTRY(e_x), std::to_string(dout->posx).c_str()); gtk_entry_set_text(GTK_ENTRY(e_y), std::to_string(dout->posy).c_str()); detect.LockImageMutex(); if (detect_pixbuf) { pix_h = gdk_pixbuf_get_height(detect_pixbuf); pix_w = gdk_pixbuf_get_width(detect_pixbuf); } else pix_h = 0; if (detect_pixbuf == NULL || pix_h != dout->image->h || pix_w != dout->image->w) { if (detect_pixbuf != NULL) g_object_unref (detect_pixbuf); printf ("%s:%d %s New Pixbuf: %d x %d\n", __FILE__, __LINE__, __FUNCTION__, dout->image->w, dout->image->h); detect_pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, false, 8, dout->image->w, dout->image->h); pix_w = dout->image->w; pix_h = dout->image->h; } videoframe_to_pixbuf(detect_pixbuf, dout->image); gdk_window_invalidate_rect(gtk_widget_get_window(detect_da), NULL, true); filter.NewFrame(dout->image, dout->posx, dout->posy); detect.UnLockImageMutex(); return false; }; void cb_imagetempda_draw(GtkWidget *area, cairo_t *cr, int w, int h, gpointer data) { int clientw, clienth, pixbufw, pixbufh; float clientar, pixbufar; GdkRGBA color; GdkPixbuf *pixbuf = NULL; GdkPixbuf *src = NULL; if (area == image_da) src = image_pixbuf; else if (area == detect_da) src = detect_pixbuf; else return; clienth = gtk_widget_get_allocated_height(area); clientw = gtk_widget_get_allocated_width(area); clientar = (float)clientw/(float)clienth; pixbufh = gdk_pixbuf_get_height(src); pixbufw = gdk_pixbuf_get_width(src); pixbufar = (float)pixbufw/(float)pixbufh; if (pixbufar < clientar) { clientw = (pixbufar * (float) clienth); } else { clienth = ((float) clientw / pixbufar); } pixbuf = gdk_pixbuf_scale_simple (src, clientw, clienth, GDK_INTERP_NEAREST); gdk_cairo_set_source_pixbuf(cr, pixbuf, 0, 0); cairo_paint(cr); cairo_fill (cr); g_object_unref (pixbuf); }; void cb_detect_btnsetsize (GtkWidget *widget, gpointer data) { GtkWidget *txtw = GTK_WIDGET(gtk_builder_get_object (GTK_BUILDER(_builder_), "detect-entry-w")); GtkWidget *txth = GTK_WIDGET(gtk_builder_get_object (GTK_BUILDER(_builder_), "detect-entry-h")); detect.SetObjectSize( atoi(gtk_entry_get_text(GTK_ENTRY(txtw))), atoi(gtk_entry_get_text(GTK_ENTRY(txth)))); }; void cb_image_btnnew (GtkWidget *widget, gpointer data) { filter.NewImage(); }; void cb_image_btnsave (GtkWidget *widget, gpointer data) { GtkBuilder *builder = (GtkBuilder *) data; GtkWindow *window = GTK_WINDOW (gtk_builder_get_object (builder, "window-main")); GtkWidget *dialog; GtkFileChooser *chooser; GtkFileChooserAction action = GTK_FILE_CHOOSER_ACTION_SAVE; GtkFileFilter *filter; gint res; if (image_pixbuf == NULL) return; dialog = gtk_file_chooser_dialog_new ("Save File", window, action, "_Cancel", GTK_RESPONSE_CANCEL, "_Save", GTK_RESPONSE_ACCEPT, NULL); chooser = GTK_FILE_CHOOSER (dialog); filter = gtk_file_filter_new(); gtk_file_filter_add_pattern(filter, "*.modbus"); gtk_file_filter_set_name(filter, "Test Modbus Config"); gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(dialog), filter); filter = gtk_file_filter_new(); gtk_file_filter_add_pattern(filter, "*.*"); gtk_file_filter_set_name(filter, "All Files"); gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(dialog), filter); gtk_file_chooser_set_do_overwrite_confirmation (chooser, TRUE); if (filename.length () == 0) gtk_file_chooser_set_current_name (chooser, "capture-001.png"); else gtk_file_chooser_set_filename (chooser, filename.c_str()); res = gtk_dialog_run (GTK_DIALOG (dialog)); if (res == GTK_RESPONSE_ACCEPT) { char *filename; filename = gtk_file_chooser_get_filename (chooser); gdk_pixbuf_save(image_pixbuf, filename, "png", NULL, "quality", "100", NULL); g_free (filename); } gtk_widget_destroy (dialog); }; void cb_detect_bright (GtkRange *range, gpointer data) { GtkWidget *scale = GTK_WIDGET(gtk_builder_get_object (GTK_BUILDER(_builder_), "detect-adj-bright")); double value; value = gtk_range_get_value(range); detect.SetMinBrightness(value); }; void cb_detect_inputtype (GtkWidget *widget, gpointer data) { if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(widget)) == 1) { if (widget == GTK_WIDGET(gtk_builder_get_object (GTK_BUILDER(_builder_), "detect-type-indet1"))) detect.SetInputType(0); if (widget == GTK_WIDGET(gtk_builder_get_object (GTK_BUILDER(_builder_), "detect-type-indet2"))) detect.SetInputType(1); if (widget == GTK_WIDGET(gtk_builder_get_object (GTK_BUILDER(_builder_), "detect-type-indet3"))) detect.SetInputType(2); } };