/*************************************************************************************** * * 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" extern GtkBuilder *_builder_; // work around for threads extern Filter filter; GtkWidget *temp_da = NULL; GdkPixbuf *temp_pixbuf = NULL; GtkWidget *image_da = NULL; GdkPixbuf *image_pixbuf = NULL; ////////////////////////////////////////////////////////////////////////////////////////////////// // // call back functions // gboolean cb_window_delete_event (GtkWidget *widget, GdkEvent *event, gpointer data) { gtk_main_quit(); return FALSE; }; 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")); printf ("%s:%d %s\n", __FILE__, __LINE__, __FUNCTION__); gtk_widget_set_sensitive(btnstart, true); gtk_widget_set_sensitive(btnstop, false); 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_filterimage (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_filtertemp (gpointer data) { VideoFrame *vf = (VideoFrame *) data; int pix_h, pix_w; if (temp_da == NULL) temp_da = GTK_WIDGET(gtk_builder_get_object (GTK_BUILDER(_builder_), "temp-da")); if (vf == NULL) { return false; } filter.LockTempMutex(); if (temp_pixbuf) { pix_h = gdk_pixbuf_get_height(temp_pixbuf); pix_w = gdk_pixbuf_get_width(temp_pixbuf); } else pix_h = 0; if (temp_pixbuf == NULL || pix_h != vf->h || pix_w != vf->w) { if (temp_pixbuf != NULL) g_object_unref (temp_pixbuf); printf ("%s:%d %s New Pixbuf: %d x %d\n", __FILE__, __LINE__, __FUNCTION__, vf->w, vf->h); temp_pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, false, 8, vf->w, vf->h); pix_w = vf->w; pix_h = vf->h; } videoframe_to_pixbuf(temp_pixbuf, vf); gdk_window_invalidate_rect(gtk_widget_get_window(temp_da), NULL, true); filter.UnLockTempMutex(); 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; GdkPixbuf *pixbuf = NULL; GdkPixbuf *src = NULL; if (area == temp_da) src = temp_pixbuf; else if (area == image_da) src = image_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); };