devices.c
/*
This file is part of darktable,
copyright (c) 2010 henrik andersson.
darktable is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
darktable is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with darktable. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdio.h>
#include <stdlib.h>
#include "gui/gtk.h"
#include "gui/devices.h"
#include "gui/camera_import_dialog.h"
#include "develop/develop.h"
#include "dtgtk/label.h"
#include "dtgtk/button.h"
#include "control/conf.h"
#include "control/control.h"
#include "control/jobs.h"
#include "common/film.h"
#include "common/variables.h"
#include "common/camera_control.h"
static dt_camctl_listener_t _gui_camctl_listener;
static void _camctl_camera_disconnected_callback (const dt_camera_t *camera,void *data)
{
dt_camctl_detect_cameras(darktable.camctl);
gdk_threads_enter();
dt_gui_devices_update();
gdk_threads_leave();
}
static void _camctl_camera_control_status_callback(dt_camctl_status_t status,void *data)
{
int needlock = !pthread_equal(pthread_self(),darktable.control->gui_thread);
if(needlock) gdk_threads_enter();
switch(status)
{
case CAMERA_CONTROL_BUSY:
{
//dt_control_log(_("camera control is busy."));
GtkWidget *widget = darktable.gui->widgets.devices_expander_body;
GList *child = gtk_container_get_children(GTK_CONTAINER(widget));
if(child)
do
{
if( !(GTK_IS_TOGGLE_BUTTON(child->data) && gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(child->data))==TRUE) )
gtk_widget_set_sensitive(GTK_WIDGET(child->data),FALSE);
}
while( (child=g_list_next(child)) );
}
break;
case CAMERA_CONTROL_AVAILABLE:
{
//dt_control_log(_("camera control is available."));
GtkWidget *widget = darktable.gui->widgets.devices_expander_body;
GList *child = gtk_container_get_children(GTK_CONTAINER(widget));
if(child)
do
{
gtk_widget_set_sensitive(GTK_WIDGET(child->data),TRUE);
}
while( (child=g_list_next(child)) );
}
break;
}
if(needlock) gdk_threads_leave();
}
static void scan_callback(GtkButton *button,gpointer data)
{
dt_camctl_detect_cameras(darktable.camctl);
dt_gui_devices_update();
}
static void import_callback(GtkButton *button,gpointer data)
{
dt_camera_import_dialog_param_t *params=(dt_camera_import_dialog_param_t *)g_malloc(sizeof(dt_camera_import_dialog_param_t));
memset( params, 0, sizeof(dt_camera_import_dialog_param_t));
params->camera = (dt_camera_t*)data;
dt_camera_import_dialog_new(params);
if( params->result )
{
// Let's initialize a import job and put it on queue....
gchar *path = g_build_path(G_DIR_SEPARATOR_S,params->basedirectory,params->subdirectory,(char *)NULL);
dt_job_t j;
dt_camera_import_job_init(&j,params->jobcode,path,params->filenamepattern,params->result,params->camera);
dt_control_add_job(darktable.control, &j);
g_free(path);
}
g_free(params);
}
static void tethered_callback(GtkToggleButton *button,gpointer data)
{
/* select camera to work with before switching mode */
dt_camctl_select_camera(darktable.camctl, (dt_camera_t *)data);
dt_conf_set_int( "plugins/capture/mode", DT_CAPTURE_MODE_TETHERED);
dt_conf_set_int("plugins/capture/current_filmroll",-1);
dt_ctl_switch_mode_to(DT_CAPTURE);
}
void dt_gui_devices_init()
{
memset(&_gui_camctl_listener,0,sizeof(dt_camctl_listener_t));
_gui_camctl_listener.control_status = _camctl_camera_control_status_callback;
_gui_camctl_listener.camera_disconnected = _camctl_camera_disconnected_callback;
dt_camctl_register_listener( darktable.camctl, &_gui_camctl_listener );
dt_gui_devices_update();
}
void dt_gui_devices_update()
{
GtkWidget *widget = darktable.gui->widgets.devices_expander_body;
GList *citem;
// Lets clear all items in container...
GList *item;
if((item=gtk_container_get_children(GTK_CONTAINER(widget)))!=NULL)
do
{
gtk_container_remove(GTK_CONTAINER(widget),GTK_WIDGET(item->data));
}
while((item=g_list_next(item))!=NULL);
// Add the rescan button
GtkButton *scan=GTK_BUTTON(gtk_button_new_with_label(_("scan for devices")));
gtk_button_set_alignment(scan, 0.05, 0.5);
g_object_set(G_OBJECT(scan), "tooltip-text", _("scan for newly attached devices"), (char *)NULL);
g_signal_connect (G_OBJECT(scan), "clicked",G_CALLBACK (scan_callback), NULL);
gtk_box_pack_start(GTK_BOX(widget),GTK_WIDGET(scan),TRUE,TRUE,0);
gtk_box_pack_start(GTK_BOX(widget),GTK_WIDGET(gtk_label_new("")),TRUE,TRUE,0);
uint32_t count=0;
if( (citem = g_list_first (darktable.camctl->cameras))!=NULL)
{
// Add detected supported devices
char buffer[512]= {0};
do
{
dt_camera_t *camera=(dt_camera_t *)citem->data;
count++;
// Add camera label
GtkWidget *label = GTK_WIDGET (dtgtk_label_new (camera->model,DARKTABLE_LABEL_TAB|DARKTABLE_LABEL_ALIGN_LEFT));
gtk_box_pack_start (GTK_BOX (widget),label,TRUE,TRUE,0);
// Set summary if exists for tooltip
if( camera->summary.text !=NULL && strlen(camera->summary.text) >0 )
{
g_object_set(G_OBJECT(label), "tooltip-text", camera->summary.text, (char *)NULL);
}
else
{
sprintf(buffer,_("device \"%s\" connected on port \"%s\"."),camera->model,camera->port);
g_object_set(G_OBJECT(label), "tooltip-text", buffer, (char *)NULL);
}
// Add camera action buttons
GtkWidget *ib=NULL,*tb=NULL;
GtkWidget *vbx=gtk_vbox_new(FALSE,5);
if( camera->can_import==TRUE )
gtk_box_pack_start (GTK_BOX (vbx),(ib=gtk_button_new_with_label (_("import from camera"))),FALSE,FALSE,0);
if( camera->can_tether==TRUE )
gtk_box_pack_start (GTK_BOX (vbx),(tb=gtk_button_new_with_label (_("tethered shoot"))),FALSE,FALSE,0);
if( ib )
{
g_signal_connect (G_OBJECT (ib), "clicked",G_CALLBACK (import_callback), camera);
gtk_button_set_alignment(GTK_BUTTON(ib), 0.05, 0.5);
}
if( tb )
{
g_signal_connect (G_OBJECT (tb), "clicked",G_CALLBACK (tethered_callback), camera);
gtk_button_set_alignment(GTK_BUTTON(tb), 0.05, 0.5);
}
gtk_box_pack_start (GTK_BOX (widget),vbx,FALSE,FALSE,0);
}
while ((citem=g_list_next (citem))!=NULL);
}
if( count == 0 )
{
// No supported devices is detected lets notice user..
gtk_box_pack_start(GTK_BOX(widget),gtk_label_new(_("no supported devices found")),TRUE,TRUE,0);
}
gtk_widget_show_all(widget);
}