photobooth/focus.c
2016-04-27 18:07:13 +02:00

228 lines
5.6 KiB
C

#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <gphoto2/gphoto2-camera.h>
/*
* This function looks up a label or key entry of
* a configuration widget.
* The functions descend recursively, so you can just
* specify the last component.
*/
static int
_lookup_widget(CameraWidget*widget, const char *key, CameraWidget **child) {
int ret;
ret = gp_widget_get_child_by_name (widget, key, child);
if (ret < GP_OK)
ret = gp_widget_get_child_by_label (widget, key, child);
return ret;
}
/* calls the Nikon DSLR or Canon DSLR autofocus method. */
int
camera_eosviewfinder(Camera *camera, GPContext *context, int onoff) {
CameraWidget *widget = NULL, *child = NULL;
CameraWidgetType type;
int ret,val;
ret = gp_camera_get_config (camera, &widget, context);
if (ret < GP_OK) {
fprintf (stderr, "camera_get_config failed: %d\n", ret);
return ret;
}
ret = _lookup_widget (widget, "eosviewfinder", &child);
if (ret < GP_OK) {
fprintf (stderr, "lookup 'eosviewfinder' failed: %d\n", ret);
goto out;
}
/* check that this is a toggle */
ret = gp_widget_get_type (child, &type);
if (ret < GP_OK) {
fprintf (stderr, "widget get type failed: %d\n", ret);
goto out;
}
switch (type) {
case GP_WIDGET_TOGGLE:
break;
default:
fprintf (stderr, "widget has bad type %d\n", type);
ret = GP_ERROR_BAD_PARAMETERS;
goto out;
}
ret = gp_widget_get_value (child, &val);
if (ret < GP_OK) {
fprintf (stderr, "could not get widget value: %d\n", ret);
goto out;
}
val = onoff;
ret = gp_widget_set_value (child, &val);
if (ret < GP_OK) {
fprintf (stderr, "could not set widget value to 1: %d\n", ret);
goto out;
}
ret = gp_camera_set_config (camera, widget, context);
if (ret < GP_OK) {
fprintf (stderr, "could not set config tree to eosviewfinder: %d\n", ret);
goto out;
}
out:
gp_widget_free (widget);
return ret;
}
int
camera_auto_focus(Camera *camera, GPContext *context, int onoff) {
CameraWidget *widget = NULL, *child = NULL;
CameraWidgetType type;
int ret,val;
ret = gp_camera_get_config (camera, &widget, context);
if (ret < GP_OK) {
fprintf (stderr, "camera_get_config failed: %d\n", ret);
return ret;
}
ret = _lookup_widget (widget, "autofocusdrive", &child);
if (ret < GP_OK) {
fprintf (stderr, "lookup 'autofocusdrive' failed: %d\n", ret);
goto out;
}
/* check that this is a toggle */
ret = gp_widget_get_type (child, &type);
if (ret < GP_OK) {
fprintf (stderr, "widget get type failed: %d\n", ret);
goto out;
}
switch (type) {
case GP_WIDGET_TOGGLE:
break;
default:
fprintf (stderr, "widget has bad type %d\n", type);
ret = GP_ERROR_BAD_PARAMETERS;
goto out;
}
ret = gp_widget_get_value (child, &val);
if (ret < GP_OK) {
fprintf (stderr, "could not get widget value: %d\n", ret);
goto out;
}
val = onoff;
ret = gp_widget_set_value (child, &val);
if (ret < GP_OK) {
fprintf (stderr, "could not set widget value to 1: %d\n", ret);
goto out;
}
ret = gp_camera_set_config (camera, widget, context);
if (ret < GP_OK) {
fprintf (stderr, "could not set config tree to autofocus: %d\n", ret);
goto out;
}
out:
gp_widget_free (widget);
return ret;
}
/* Manual focusing a camera...
* xx is -3 / -2 / -1 / 0 / 1 / 2 / 3
*/
int
camera_manual_focus (Camera *camera, int xx, GPContext *context) {
CameraWidget *widget = NULL, *child = NULL;
CameraWidgetType type;
int ret;
float rval;
char *mval;
ret = gp_camera_get_config (camera, &widget, context);
if (ret < GP_OK) {
fprintf (stderr, "camera_get_config failed: %d\n", ret);
return ret;
}
ret = _lookup_widget (widget, "manualfocusdrive", &child);
if (ret < GP_OK) {
fprintf (stderr, "lookup 'manualfocusdrive' failed: %d\n", ret);
goto out;
}
/* check that this is a toggle */
ret = gp_widget_get_type (child, &type);
if (ret < GP_OK) {
fprintf (stderr, "widget get type failed: %d\n", ret);
goto out;
}
switch (type) {
case GP_WIDGET_RADIO: {
int choices = gp_widget_count_choices (child);
ret = gp_widget_get_value (child, &mval);
if (ret < GP_OK) {
fprintf (stderr, "could not get widget value: %d\n", ret);
goto out;
}
if (choices == 7) { /* see what Canon has in EOS_MFDrive */
ret = gp_widget_get_choice (child, xx+4, (const char**)&mval);
if (ret < GP_OK) {
fprintf (stderr, "could not get widget choice %d: %d\n", xx+2, ret);
goto out;
}
fprintf(stderr,"manual focus %d -> %s\n", xx, mval);
}
ret = gp_widget_set_value (child, mval);
if (ret < GP_OK) {
fprintf (stderr, "could not set widget value to 1: %d\n", ret);
goto out;
}
break;
}
case GP_WIDGET_RANGE:
ret = gp_widget_get_value (child, &rval);
if (ret < GP_OK) {
fprintf (stderr, "could not get widget value: %d\n", ret);
goto out;
}
switch (xx) { /* Range is on Nikon from -32768 <-> 32768 */
case -3: rval = -1024;break;
case -2: rval = -512;break;
case -1: rval = -128;break;
case 0: rval = 0;break;
case 1: rval = 128;break;
case 2: rval = 512;break;
case 3: rval = 1024;break;
default: rval = xx; break; /* hack */
}
fprintf(stderr,"manual focus %d -> %f\n", xx, rval);
ret = gp_widget_set_value (child, &rval);
if (ret < GP_OK) {
fprintf (stderr, "could not set widget value to 1: %d\n", ret);
goto out;
}
break;
default:
fprintf (stderr, "widget has bad type %d\n", type);
ret = GP_ERROR_BAD_PARAMETERS;
goto out;
}
ret = gp_camera_set_config (camera, widget, context);
if (ret < GP_OK) {
fprintf (stderr, "could not set config tree to autofocus: %d\n", ret);
goto out;
}
out:
gp_widget_free (widget);
return ret;
}