summaryrefslogtreecommitdiff
path: root/maintain_focus.c
blob: a1121a66cb8fc00ec5c3b58fc8031a03dd4ebf0d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <gphoto2/gphoto2.h>
#include <time.h>
#include <ncurses.h>

#define FOCUS_WIDGET_NAME         "manualfocusdrive"
#define VIEWFINDER_WIDGET_NAME    "viewfinder"

/**
 gp_widget_set_value(CameraWidget*, const void) <-sets value
 gp_widget_get_child_by_label(CameraWidget* widget, const char* label, CameraWidget ** child) <- child is widget
 gp_camera_get_config(Camera* camera, CameraWidget **window, GpContext* context) <- window is parent

 camera_init(Camera* camera, GPContext *context)


 Create context: 
 	context = gp_context_new();
      gp_context_set_error_func (context, ctx_error_func, NULL);
      gp_context_set_status_func (context, ctx_status_func, NULL);
 Create camera:
  gp_camera_new(&camera); <- point to return value

**/
void user_conf() {
  printw("\nPress enter to continue.\n");
  refresh();
  getchar();
}

int set_widget_value(CameraWidget *widget, void *widget_value, const char *widget_name, Camera *camera, GPContext *context) {
  int err;
  if ((err = gp_widget_set_value(widget, widget_value)) != 0) {
    printw("Error setting local widget value: %s\nThis is not the hardware\'s fault. Fix your code!\n", gp_result_as_string(err));
    return(1);
  }
  if((err = gp_camera_set_single_config(camera, widget_name, widget, context)) != 0) {
    printw("Error modifying camera widget: %s\n", gp_result_as_string(err));
    return(2);
  }
  
}

int main() {
  char focus_state[8] = "None";
  int user_focusing = 1;
  int toggle = 1; //wish there was a better way to do this...
  int key;
  int err;
  unsigned int focal_distance[3] = {0, 0, 0};

  Camera *cam;
  CameraWidget *widget_root;
  CameraWidget *focus_widget;
  CameraWidget *liveview_widget;

  initscr();
  cbreak();
  noecho();

  char *key_help_msg = "Press [q] [w] [e] to focus closer, [q] moving the fastest.\nPress [a] [s] [d] to focus further, [a] being the fastest.\nPress [Q] when done.\n";
  
  GPContext *context = gp_context_new(); 
  gp_camera_new(&cam);

  //start up and connect to camera  
  printw("Initilizing camera...\n");
  refresh();
  if ((err = gp_camera_init(cam, context)) != 0) {
    printw("Couldn't connect to camera: %s\n", gp_result_as_string(err));
    refresh();
    return(1);
  }

  //get configuration tree
  gp_camera_get_config(cam, &widget_root, context); 
  //get child widgets
  gp_widget_get_child_by_name(widget_root, FOCUS_WIDGET_NAME, &focus_widget);
  gp_widget_get_child_by_name(widget_root, VIEWFINDER_WIDGET_NAME, &liveview_widget);

  //set to liveview so we can ajust focus
  set_widget_value(liveview_widget, &toggle, VIEWFINDER_WIDGET_NAME, cam, context); 

  printw("\nCamera now connected.\nOn the camera, manually focus all the way to the left. Turn on autofocus when done.\n");
  user_conf();
  

  /**
   * Left:      far
   * Right:     near
   * Powerful:  3
   * There's a lot of limitations, such as not knowing when we've hit the limit. We'll just have to depend on the user (me!) for that.
   * We also don't know how much "Near/Far 3" is compared to "Near/Far 1".
   */
  while(user_focusing) {
    clear();
    printw("%s", key_help_msg);
    printw("Level 3:\t\t%i\nLevel 2:\t\t%i\nLevel 1:\t\t%i\n", focal_distance[2], focal_distance[1], focal_distance[0]);
    refresh();
    flushinp();
    switch(getch()) {
      case 'q':
        focal_distance[2]++;
        set_widget_value(focus_widget, "Near 3", FOCUS_WIDGET_NAME, cam, context); 
        usleep(500000);
        break;
      case 'w':
        focal_distance[1]++;
        set_widget_value(focus_widget, "Near 2", FOCUS_WIDGET_NAME, cam, context); 
        usleep(250000);
        break;
      case 'e':
        focal_distance[0]++;
        set_widget_value(focus_widget, "Near 1", FOCUS_WIDGET_NAME, cam, context); 
        usleep(125000);
        break;
      case 'a':
        if(focal_distance[2] > 0) {
          focal_distance[2]--;
          set_widget_value(focus_widget, "Far 3", FOCUS_WIDGET_NAME, cam, context); 
          usleep(500000);
        }
        break;
      case 's':
        if(focal_distance[1] > 0) { 
          focal_distance[1]--;
          set_widget_value(focus_widget, "Far 2", FOCUS_WIDGET_NAME, cam, context); 
          usleep(250000);
        }
        break;
      case 'd':
        if(focal_distance[0] > 0) { 
          focal_distance[0]--;
          set_widget_value(focus_widget, "Far 1", FOCUS_WIDGET_NAME, cam, context); 
          usleep(125000);
        }
        break;
      case 'Q':
        user_focusing = 0;
        break;
      default:
        break;
    }
  }
  clear();
  printw("Focal length saved, put on the filter now. You can turn off autofocus.\n");
  user_conf();

  clear();
  printw("Manually focus all the way to left, then turn on autofocus.\n");
  user_conf();

  clear();
  printw("Restoring focus...\n");
  for(; focal_distance[2] >= 1; focal_distance[2]--) {
    set_widget_value(focus_widget, "Near 3", FOCUS_WIDGET_NAME, cam, context);
    usleep(500000);
  }

  for(; focal_distance[1] >= 1; focal_distance[1]--) {
    set_widget_value(focus_widget, "Near 2", FOCUS_WIDGET_NAME, cam, context);
    usleep(250000);
  }

  for(; focal_distance[0] >= 1; focal_distance[0]--) {
    set_widget_value(focus_widget, "Near 1", FOCUS_WIDGET_NAME, cam, context);
    usleep(125000);
  }

  printw("Done!\n");
  user_conf();

  endwin(); 
  gp_camera_exit(cam, context); 
 
  
  return(0);

}