3 * Copyright © 2002 Patrick Mansfield <patman@aracnet.com>
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the
17 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 * Boston, MA 02111-1307, USA.
29 #include <gphoto2/gphoto2-library.h>
30 #include <gphoto2/gphoto2-port-log.h>
33 #include "sierra-desc.h"
39 # define _(String) dgettext (GETTEXT_PACKAGE, String)
41 # define N_(String) gettext_noop (String)
43 # define N_(String) (String)
46 # define textdomain(String) (String)
47 # define gettext(String) (String)
48 # define dgettext(Domain,Message) (Message)
49 # define dcgettext(Domain,Message,Type) (Message)
50 # define bindtextdomain(Domain,Directory) (Domain)
51 # define _(String) (String)
52 # define N_(String) (String)
55 #define GP_MODULE "sierra"
58 * For some reason, round() does not get a prototype from math.h.
60 extern double round(double x);
63 camera_cam_desc_get_value (ValueNameType *val_name_p, CameraWidgetType widge,
64 uint32_t reg_len, void *buff, int mask,
67 if ((widge == GP_WIDGET_RADIO) || (widge == GP_WIDGET_MENU)) {
68 gp_widget_add_choice (child, _(val_name_p->name));
69 GP_DEBUG ("get value %15s:\t%lld (0x%04llx)",
70 val_name_p->name, val_name_p->u.value,
72 /* XXX where is endian handled? */
73 if ((mask & *(int*) buff) == val_name_p->u.value) {
74 gp_widget_set_value (child, _(val_name_p->name));
76 } else if (widge == GP_WIDGET_DATE) {
77 GP_DEBUG ("get value date/time %s", ctime((time_t *) buff));
78 gp_widget_set_value (child, (int*) buff);
79 } else if (widge == GP_WIDGET_RANGE) {
80 float float_val, increment;
82 increment = val_name_p->u.range[2];
83 if (increment == 0.0) {
85 * Use a default value.
89 GP_DEBUG ("get value range:\t%08g:%08g increment %g (via %g)",
90 val_name_p->u.range[0], val_name_p->u.range[1],
91 increment, val_name_p->u.range[2]);
92 gp_widget_set_range (child, val_name_p->u.range[0],
93 val_name_p->u.range[1], increment);
95 * Kluge: store the value in buff as a 4 byte int, even
96 * though we might have read 8 bytes or more.
98 float_val = (*(int*) buff) * increment;
99 gp_widget_set_value (child, &float_val);
100 } else if (widge == GP_WIDGET_BUTTON) {
101 GP_DEBUG ("get button");
102 gp_widget_set_value (child, val_name_p->u.callback);
104 GP_DEBUG ("get value bad widget type %d", widge);
112 camera_cam_desc_get_widget (Camera *camera, CameraRegisterType *reg_p,
113 CameraWidget *section, GPContext *context)
115 int ind, vind, ret, value;
119 RegisterDescriptorType *reg_desc_p;
121 GP_DEBUG ("register %d", reg_p->reg_number);
122 if (reg_p->reg_len == 0) {
124 * This is 0 for GP_WIDGET_BUTTON (callbacks), since is no
125 * register for call backs. Frontends "get" the value, and
126 * call the function directly.
129 } else if (reg_p->reg_len == 4) {
131 ret = sierra_get_int_register (camera, reg_p->reg_number,
134 reg_p->reg_value = rval;
135 } else if (reg_p->reg_len == 8) {
137 * reg_value is 8 bytes maximum. If you need a bigger
138 * value, change the reg_value size, or allocate space on
139 * the fly and make a union with reg_value and a void*.
141 ret = sierra_get_string_register (camera, reg_p->reg_number,
142 -1, NULL, buff, &value, context);
143 if ((ret == GP_OK) && value != reg_p->reg_len) {
144 GP_DEBUG ("Bad length result %d", value);
147 memcpy (®_p->reg_value, buff, reg_p->reg_len);
149 GP_DEBUG ("Bad register length %d", reg_p->reg_number);
152 GP_DEBUG ("... '%s'.", gp_result_as_string (ret));
157 for (ind = 0; ind < reg_p->reg_desc_cnt; ind++) {
158 reg_desc_p = ®_p->reg_desc[ind];
159 mask = reg_desc_p->regs_mask;
160 GP_DEBUG ("window name is %s", reg_desc_p->regs_long_name);
161 gp_widget_new (reg_desc_p->reg_widget_type,
162 _(reg_desc_p->regs_long_name), &child);
163 gp_widget_set_name (child, reg_desc_p->regs_short_name);
165 * Setting the info for the preference settings does not
166 * make sense like it does for an icon button. This is
167 * used as the tool-tip field (mouse over hint that pops
168 * up after a second in gtkam). We don't want this used
169 * at all; setting it to space doesn't work well, so just
170 * set it to the same as regs_long_name.
172 gp_widget_set_info (child, _(reg_desc_p->regs_long_name));
173 GP_DEBUG ("reg_value 0x%016llx", reg_p->reg_value);
174 for (vind = 0; vind < reg_desc_p->reg_val_name_cnt; vind++) {
175 camera_cam_desc_get_value (®_desc_p->regs_value_names[vind],
176 reg_desc_p->reg_widget_type, reg_p->reg_len,
177 (char*) ®_p->reg_value, mask, child);
180 * For radio and menu values: if there has been no change, it
181 * means the value was not set, and so it is unknown.
183 if (((reg_desc_p->reg_widget_type == GP_WIDGET_RADIO) ||
184 (reg_desc_p->reg_widget_type == GP_WIDGET_MENU)) &&
185 !gp_widget_changed (child)) {
186 sprintf (buff, _("%lld (unknown)"), reg_p->reg_value);
187 gp_widget_add_choice (child, buff);
188 gp_widget_set_value (child, buff);
190 gp_widget_append (section, child);
196 camera_get_config_cam_desc (Camera *camera, CameraWidget **window,
199 CameraWidget *section;
201 const CameraDescType *cam_desc = NULL;
203 GP_DEBUG ("*** camera_get_config_cam_desc");
204 CHECK (camera_start (camera, context));
205 gp_widget_new (GP_WIDGET_WINDOW, _("Camera Configuration"), window);
207 cam_desc = camera->pl->cam_desc;
208 for (indw = 0; indw < 2 /* XXX sizeof () */; indw++) {
209 GP_DEBUG ("%s registers", cam_desc->regset[indw].window_name);
210 gp_widget_new (GP_WIDGET_SECTION,
211 _(cam_desc->regset[indw].window_name), §ion);
212 gp_widget_append (*window, section);
213 for (indr = 0; indr < cam_desc->regset[indw].reg_cnt; indr++) {
214 camera_cam_desc_get_widget (camera,
215 &cam_desc->regset[indw].regs[indr], section,
223 cam_desc_set_register (Camera *camera, CameraRegisterType *reg_p,
224 void *value, GPContext *context)
226 if (reg_p->reg_get_set.method == CAM_DESC_DEFAULT) {
227 if (reg_p->reg_len == 4) {
228 /* XXX endian problem or not? */
229 CHECK_STOP (camera, sierra_set_int_register
230 (camera, reg_p->reg_number,
231 *(int*)value, context));
232 } else if (reg_p->reg_len <= 8) {
233 CHECK_STOP (camera, sierra_set_string_register (camera,
234 reg_p->reg_number, (char*) value,
235 reg_p->reg_len, context));
238 * Note that sizeof u.value is 8, so if you have a
239 * larger value to store, somehow change u.value
240 * size, or add a union.
242 GP_DEBUG ("set value BAD LENGTH %d", reg_p->reg_len);
245 } else if (reg_p->reg_get_set.method == CAM_DESC_SUBACTION) {
247 * Right now, the only supported sub-action is for
248 * changing the LCD mode, the only other possible
249 * sub-actions are for testing, calibration, and
250 * protection mode. Just make sure the LCD mode setting
253 CHECK_STOP (camera, sierra_sub_action (camera,
254 reg_p->reg_get_set.action, *(int*) value,
257 GP_DEBUG ("Unsupported register setting action %d",
258 reg_p->reg_get_set.method);
265 camera_cam_desc_set_value (Camera *camera, CameraRegisterType *reg_p,
266 RegisterDescriptorType *reg_desc_p,
267 ValueNameType *val_name_p, void *data,
271 * Return GP_OK if match and OK, 1 if no match, or < 0 on error.
273 if ((reg_desc_p->reg_widget_type == GP_WIDGET_RADIO) ||
274 (reg_desc_p->reg_widget_type == GP_WIDGET_MENU)) {
277 GP_DEBUG ("set value comparing data '%s' with name '%s'", *(char**)data,
279 if (strcmp (*(char**)data, val_name_p->name) != 0) {
283 * For masking, we might actually set the same register
284 * twice - once for each change in the mask, so we have to
285 * reset reg_value to the new value.
287 * If we must to mask u.value, that is really a bug - the
288 * u.value should already be masked.
290 * For registers longer than 4 bytes, we are masking
291 * in whatever values were already in the upper 4 bytes -
292 * none of the current settings (new values) are longer
295 new_value = (reg_p->reg_value & ~reg_desc_p->regs_mask) |
296 (val_name_p->u.value & reg_desc_p->regs_mask);
297 reg_p->reg_value = new_value;
298 GP_DEBUG ("set new val 0x%x; reg val 0x%x; msk 0x%x; val 0x%x ",
299 new_value, (int)reg_p->reg_value,
300 reg_desc_p->regs_mask, (int)val_name_p->u.value);
301 CHECK_STOP (camera, cam_desc_set_register (camera, reg_p,
302 &new_value, context));
303 } else if (reg_desc_p->reg_widget_type == GP_WIDGET_DATE) {
304 GP_DEBUG ("set new date/time %s", ctime((time_t*)data));
305 CHECK_STOP (camera, cam_desc_set_register (camera, reg_p,
306 (int*)data, context));
307 } else if (reg_desc_p->reg_widget_type == GP_WIDGET_RANGE) {
311 if (reg_p->reg_get_set.method != CAM_DESC_DEFAULT) {
312 GP_DEBUG ("Setting range values using the non-default"
313 " register functions is not supported");
317 * The value in *data is a float, convert it to an int.
319 * Currently no need to support any subaction here.
321 * Similiar to the masking above, if we have a register
322 * larger than 4 bytes, put the four bytes in the int to
323 * into the low four bytes of the value we want to set;
324 * fill the rest with whatever was read from the camera.
326 increment = val_name_p->u.range[2];
327 if (increment == 0.0) {
328 increment = 1.0; /* default value */
330 GP_DEBUG ("set value range from %g inc %g", *(float*)data,
332 val[0] = round ((*(float*) data) / increment);
333 if (reg_p->reg_len == 4) {
335 * not used but set it anyway
338 } else if (reg_p->reg_len == 8) {
339 memcpy(&val[1], ((char*)®_p->reg_value)+sizeof(val[0]), sizeof(val[0]));
340 /* val[1] = ((int *) ®_p->reg_value)[1]; */
341 } else if (reg_p->reg_len != 4 ) {
342 GP_DEBUG ("Unsupported range with register length %d",
346 GP_DEBUG ("set value range to %d (0x%x and 0x%x)", val[0],
348 CHECK_STOP (camera, cam_desc_set_register (camera, reg_p,
351 GP_DEBUG ("bad reg_widget_type type %d",
352 reg_desc_p->reg_widget_type);
359 camera_cam_desc_set_widget (Camera *camera, CameraRegisterType *reg_p,
360 CameraWidget *window, GPContext *context)
370 RegisterDescriptorType *reg_desc_p;
372 GP_DEBUG ("register %d", reg_p->reg_number);
374 for (ind = 0; ind < reg_p->reg_desc_cnt; ind++) {
375 reg_desc_p = ®_p->reg_desc[ind];
376 mask = reg_desc_p->regs_mask;
377 GP_DEBUG ("window name is %s", reg_desc_p->regs_long_name);
379 if ((gp_widget_get_child_by_label (window,
380 _(reg_desc_p->regs_long_name), &child) >= 0) &&
381 gp_widget_changed (child)) {
382 gp_widget_get_value (child, &value_in);
383 for (vind = 0; vind < reg_desc_p->reg_val_name_cnt;
385 ret = camera_cam_desc_set_value (camera, reg_p,
387 ®_desc_p->regs_value_names[vind],
391 * Something got set, mark the
392 * widget as changed, so the user
393 * can repeat any actions - like
394 * going to the "next" picture by
395 * repeatedly hitting apply while
396 * in operation play mode.
398 * This has the side affect of
399 * changing whatever was just set
400 * twice when using the apply in
401 * gtkam - once when applied and
404 gp_widget_set_changed (child, 1);
409 * Value was set (GP_OK is 0), or
410 * some an error occurred (< 0),
411 * don't bother checking any other
423 camera_set_config_cam_desc (Camera *camera, CameraWidget *window,
427 const CameraDescType *cam_desc = NULL;
429 GP_DEBUG ("*** camera_set_config_cam_desc");
430 CHECK (camera_start (camera, context));
432 cam_desc = camera->pl->cam_desc;
433 for (wind = 0; wind < 2 /* XXX sizeof () */; wind++) {
434 GP_DEBUG ("%s registers", cam_desc->regset[wind].window_name);
435 for (rind = 0; rind < cam_desc->regset[wind].reg_cnt; rind++) {
436 camera_cam_desc_set_widget (camera,
437 &cam_desc->regset[wind].regs[rind], window,