1 /*
2  * Copyright 1999/2000 by Henning Zabel <henning@uni-paderborn.de>
3  *
4  * This program is free software; you can redistribute it and/or modify it
5  * under the terms of the GNU General Public License as published by the
6  * Free Software Foundation; either version 2 of the License, or (at your
7  * option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful, but
10  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
11  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12  * for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17  */
18 
19 /*
20  * gphoto driver for the Mustek MDC800 Digital Camera. The driver
21  * supports rs232 and USB.
22  */
23 
24 #include <stdlib.h>
25 #include <string.h>
26 
27 #include <gphoto2/gphoto2-library.h>
28 #include <gphoto2/gphoto2-result.h>
29 
30 #include "core.h"
31 #include "print.h"
32 
33 #ifdef ENABLE_NLS
34 #  include <libintl.h>
35 #  undef _
36 #  define _(String) dgettext (GETTEXT_PACKAGE, String)
37 #  ifdef gettext_noop
38 #    define N_(String) gettext_noop (String)
39 #  else
40 #    define _(String) (String)
41 #    define N_(String) (String)
42 #  endif
43 #else
44 #  define _(String) (String)
45 #  define N_(String) (String)
46 #endif
47 
48 /*----------------------  Funktion for Communication ------------------------ */
49 
50 /*
51  * Send the Initial Command. If the device is rs232 this
52  * function will probe for the baudrate.
53  */
54 static int
mdc800_sendInitialCommand(Camera * camera,unsigned char * answer)55 mdc800_sendInitialCommand (Camera *camera, unsigned char* answer)
56 {
57 	int	baud_rates[3]={19200,57600,115200};
58 	int	rate,ret;
59 	unsigned char	command [8]={COMMAND_BEGIN,COMMAND_INIT_CONNECT,0,0,0,COMMAND_END,0,0};
60 
61 	if (camera->port->type == GP_PORT_USB)
62 	    return mdc800_io_sendCommand_with_retry(camera->port,command,answer,8,1,1);
63 	for (rate=0;rate<3;rate++)
64 	{
65 	    GPPortSettings settings;
66 
67 	    ret = gp_port_get_settings(camera->port,&settings);
68 	    if (ret != GP_OK) return ret;
69 	    settings.serial.speed = baud_rates[rate];
70 	    ret = gp_port_set_settings(camera->port, settings);
71 	    if (ret != GP_OK) return ret;
72 	    if (GP_OK==mdc800_io_sendCommand_with_retry(camera->port,command,answer,8,1,1)) {
73 		printCoreNote("RS232 Baudrate probed at %d.\n",baud_rates[rate]);
74 		return GP_OK;
75 	    }
76 	    printCoreError("Probing RS232 Baudrate with %d fails.\n",baud_rates[rate]);
77 	}
78 	printCoreError ("Probing failed completely.\n");
79 	return GP_ERROR_IO;
80 }
81 
82 /*
83  * Opens the Camera:
84  *     (camera is already opened by gphoto2)
85  * (1) send Initial command
86  */
mdc800_openCamera(Camera * camera)87 int mdc800_openCamera (Camera *camera)
88 {
89 	unsigned char answer [8];
90 	int  i,ret;
91 
92 	if (camera->port->type == GP_PORT_USB) {
93 		printCoreNote ("Device Registered as USB.\n");
94 	} else {
95 		printCoreNote ("Device Registered as RS232. \n");
96 	}
97 
98 	camera->pl = malloc(sizeof(struct _CameraPrivateLibrary));
99 	if (!camera->pl)
100 	    return GP_ERROR_NO_MEMORY;
101 	camera->pl->system_flags_valid = 0;
102 	camera->pl->memory_source = -1;
103 
104 	/* Send initial command */
105 	ret = mdc800_sendInitialCommand(camera,answer);
106 	if (ret != GP_OK)
107 	{
108 		printCoreError ("(mdc800_openCamera) can't send initial command.\n");
109 		return ret;
110 	}
111 	printCoreNote ("Firmware info (last 5 Bytes) : ");
112 	for (i=0; i<8; i++)
113 		printCoreNote ("%i ", answer[i]);
114 	printCoreNote ("\n");
115 	camera->pl->system_flags_valid=0;
116 	camera->pl->memory_source=-1;
117 	ret = mdc800_setDefaultStorageSource(camera);
118 	if (ret != GP_OK) {
119 		printCoreError ("(mdc800_openCamera) can't set Storage Source.\n");
120 		return ret;
121 	}
122 	return GP_OK;
123 }
124 
mdc800_closeCamera(Camera * camera)125 int mdc800_closeCamera (Camera *camera)
126 {
127     if (camera->pl) {
128 	free(camera->pl);
129 	camera->pl = NULL;
130     }
131     return GP_OK;
132 }
133 
134 
135 /*
136  * Sets the camera speed to the defined value:
137  * 0: 19200, 1:57600, 2: 115200
138  */
mdc800_changespeed(Camera * camera,int new)139 int mdc800_changespeed (Camera *camera,int new)
140 {
141 	int baud_rate [3]={19200,57600,115200};
142 	GPPortSettings settings;
143 	int ret;
144 	unsigned int oldrate;
145 
146 	printFnkCall ("(mdc800_changespeed) called.\n");
147 	if (camera->port->type != GP_PORT_SERIAL) /* USB ... */
148 	    return GP_OK;
149 
150 	gp_port_get_settings(camera->port,&settings);
151 
152 	if (settings.serial.speed == baud_rate[new]) /* nothing to do */
153 	    return GP_OK;
154 
155 	for (oldrate=0;oldrate<sizeof(baud_rate)/sizeof(baud_rate[0]);oldrate++)
156 	    if (baud_rate[oldrate] == settings.serial.speed)
157 		break;
158 
159 	/* We did not find it? Can't happen? */
160 	if (oldrate == sizeof(baud_rate)/sizeof(baud_rate[0]))
161 	    return GP_ERROR_IO;
162 
163 	/* Setting comunication speed */
164 	ret = mdc800_io_sendCommand(camera->port,COMMAND_CHANGE_RS232_BAUD_RATE,new,oldrate,0,0,0);
165 	if (ret != GP_OK)
166 	{
167 		printCoreError ("(mdc800_changespeed) can't send first command.\n");
168 		return GP_ERROR_IO;
169 	}
170 	settings.serial.speed = baud_rate[new];
171 	ret = gp_port_set_settings(camera->port,settings);
172 	if (ret != GP_OK)
173 	{
174 		printCoreError ("(mdc800_changespeed) Changing Baudrate fails.\n");
175 		return ret;
176 	}
177 	/* Second Command */
178 	ret = mdc800_io_sendCommand(camera->port,COMMAND_CHANGE_RS232_BAUD_RATE,new,new,0,0,0);
179 	if (ret != GP_OK)
180 	{
181 		printCoreError ("(mdc800_changespeed) can't send second command.\n");
182 		return ret;
183 	}
184 	printCoreNote ("Set Baudrate to %d\n", baud_rate[new]);
185 	return GP_OK;
186 }
187 
188 /*
189  * Get the current Bautrate
190  */
mdc800_getSpeed(Camera * camera,int * speed)191 int mdc800_getSpeed (Camera *camera, int *speed)
192 {
193 	int rate, ret, baud_rate [3]={19200,57600,115200};
194 	GPPortSettings settings;
195 
196 	if (camera->port->type != GP_PORT_SERIAL)
197 	    return GP_ERROR_IO;
198 
199 	ret = gp_port_get_settings(camera->port,&settings);
200 	if (ret!=GP_OK) return ret;
201 
202 	for (rate=0;rate<3;rate++)
203 	    if (settings.serial.speed == baud_rate[rate])
204 		break;
205 	if (rate == 3)
206 	    return GP_ERROR_IO;
207 	*speed = rate;
208 	return GP_OK;
209 }
210 
211 
212 /*
213  * Sets Target
214  * 1: image, 2:thumbnail, 3:video, 4:not setting
215  */
mdc800_setTarget(Camera * camera,int value)216 int mdc800_setTarget (Camera *camera,int value)
217 {
218 	return mdc800_io_sendCommand(camera->port,COMMAND_SET_TARGET,value,0,0,0,0);
219 }
220 
221 
222 /*
223  * Loads a thumbnail from the cam .
224  */
mdc800_getThumbnail(Camera * camera,int index,void ** data,int * size)225 int mdc800_getThumbnail (Camera *camera,int index, void **data, int *size)
226 {
227 	int ret;
228 
229 	printFnkCall ("(mdc800_getThumbNail) called for %i . \n",index);
230 
231 	*size = 4096;
232 	*data = malloc(4096);
233 	if (!*data)
234 	    return GP_ERROR_NO_MEMORY;
235 	ret = mdc800_io_sendCommand(camera->port,COMMAND_GET_THUMBNAIL,index/100,(index%100)/10,index%10,*data,4096);
236 	if (ret != GP_OK)
237 	{
238 		printCoreError ("(mdc800_getThumbNail) can't get Thumbnail.\n");
239 		return ret;
240 	}
241 	mdc800_correctImageData(*data,1,0,camera->pl->memory_source == 1);
242 	return GP_OK;
243 }
244 
245 
246 
247 /*
248  * Load an Image from the cam ..
249  */
mdc800_getImage(Camera * camera,int nr,void ** data,int * size)250 int mdc800_getImage (Camera *camera, int nr, void **data, int *size)
251 {
252 	unsigned char buffer[3];
253 	int imagequality=-1;
254 	int imagesize=0;
255 	int ret;
256 
257 	printFnkCall ("(mdc800_getImage) called for %i . \n",nr);
258 
259 	ret = mdc800_setTarget (camera,1);
260 	if (GP_OK != ret) {
261 		printCoreError ("(mdc800_getImage) can't set Target. \n");
262 		return ret;
263 	}
264 	ret = mdc800_io_sendCommand(camera->port,COMMAND_GET_IMAGE_SIZE,nr/100,(nr%100)/10,nr%10,buffer,3);
265 	if (ret != GP_OK)
266 	{
267 		printCoreError ("(mdc800_getImage) request for Imagesize of %i fails.\n",nr);
268 		return ret;
269 	}
270 
271 	imagesize = buffer[0]*65536+buffer[1]*256+buffer[2];
272 	printCoreNote ("Imagesize of %i is %i ",nr,imagesize);
273 	switch (imagesize/1024)
274 	{
275 	case 48:
276 		imagequality=0;
277 		printCoreNote ("(Economic Quality 506x384)\n");
278 		break;
279 	case 128:
280 		imagequality=1;
281 		printCoreNote ("(Standard Quality 1012x768)\n");
282 		break;
283 	case 320:
284 		imagequality=2;
285 		printCoreNote ("(High Quality 1012x768)\n");
286 		break;
287 	case 4:
288 		printCoreNote ("(ThumbNail ? 112x96)\n");
289 		imagequality=-1;
290 		break;
291 	default:
292 		printCoreNote ("(not detected)\n");
293 		return 0;
294 	}
295 	*size = imagesize;
296 	*data = malloc(imagesize);
297 	ret = mdc800_io_sendCommand(camera->port,COMMAND_GET_IMAGE,nr/100,(nr%100)/10,nr%10,*data,imagesize);
298 	if (ret != GP_OK) {
299 		printCoreError ("(mdc800_getImage) request fails for Image %i.\n",nr);
300 		return 0;
301 	}
302 	mdc800_correctImageData(*data,imagequality == -1,imagequality,camera->pl->memory_source == 1);
303 	return GP_OK;
304 }
305 
306 
307 
308 /* ------	SystemStatus of the Camera ------------------------------------------/ */
309 
310 
311 /* Load the Status from the camera if necessary */
mdc800_getSystemStatus(Camera * camera)312 int mdc800_getSystemStatus (Camera *camera)
313 {
314 	int ret = GP_OK;
315 	int tries = 3;
316 	if (camera->pl->system_flags_valid)
317 		return GP_OK;
318 	fprintf(stderr,"mdc800_getSystemStatus entered...\n");
319 	while (tries--) {
320 	    ret = mdc800_io_sendCommand(camera->port,COMMAND_GET_SYSTEM_STATUS,0,0,0,camera->pl->system_flags,4);
321 	    if (ret == GP_OK)
322 		break;
323 	}
324 	if (ret!=GP_OK)
325 	{
326 		printCoreError ("(mdc800_getSystemStatus) request fails.\n");
327 		return ret;
328 	}
329 	fprintf(stderr,"mdc800_getSystemStatus leaving.\n");
330 	camera->pl->system_flags_valid=1;
331 	return GP_OK;
332 }
333 
334 
mdc800_isCFCardPresent(Camera * camera)335 int mdc800_isCFCardPresent(Camera *camera)
336 {
337 	mdc800_getSystemStatus(camera);
338 	if (camera->pl->system_flags_valid)
339 		return ((camera->pl->system_flags[0]&1) == 0);
340 	else
341 	{
342 		printCoreError ("(mdc800_isCFCardPresent) detection fails.\n");
343 		return 0;
344 	}
345 }
346 
347 
mdc800_isBatteryOk(Camera * camera)348 int mdc800_isBatteryOk(Camera *camera)
349 {
350 	mdc800_getSystemStatus(camera);
351 	return ((camera->pl->system_flags[0]&4) == 0)?1:0;
352 }
353 
354 
355 /*
356  * Gets CamMode.
357  * 0: Camera, 1: Playback, 2:VCam
358  */
mdc800_getMode(Camera * camera)359 int mdc800_getMode(Camera *camera)
360 {
361 	mdc800_getSystemStatus(camera);
362 	if ((camera->pl->system_flags[1]&16) == 0)
363 		return ((camera->pl->system_flags[1]&32) == 0)?1:0;
364 	else
365 		return 2;
366 }
367 
368 
369 /*
370  * Return status of Flashlight. The
371  * answer is one of MDC800_FLASHLIGHT_ Mask.
372  */
mdc800_getFlashLightStatus(Camera * camera)373 int mdc800_getFlashLightStatus(Camera *camera)
374 {
375 	mdc800_getSystemStatus(camera);
376 	return (camera->pl->system_flags[3]&7);
377 }
378 
379 
mdc800_isLCDEnabled(Camera * camera)380 int mdc800_isLCDEnabled(Camera *camera)
381 {
382 	mdc800_getSystemStatus(camera);
383 	return ((camera->pl->system_flags[1]&4) == 4);
384 }
385 
386 
mdc800_isMenuOn(Camera * camera)387 int mdc800_isMenuOn(Camera *camera)
388 {
389 	mdc800_getSystemStatus(camera);
390 	return ((camera->pl->system_flags[1]&1) == 1);
391 }
392 
mdc800_isAutoOffEnabled(Camera * camera)393 int mdc800_isAutoOffEnabled(Camera *camera)
394 {
395 	mdc800_getSystemStatus(camera);
396 	return ((camera->pl->system_flags[1]&8) == 8);
397 }
398 
399 /* ----- Other fine functions------------------------------------------------- */
400 
401 
402 /*
403  * Sets Source of Images :
404  * 0: FlashCard, 1: Internal Memory
405  */
mdc800_setStorageSource(Camera * camera,int flag)406 int mdc800_setStorageSource (Camera *camera,int flag)
407 {
408 	int ret;
409 	if (flag == camera->pl->memory_source)
410 		return GP_OK;
411 
412 	/* Check wether FlashCard is present */
413 	if ((flag == 0) && mdc800_isCFCardPresent (camera))
414 	{
415 		printCoreNote ("There's is no FlashCard in the Camera !\n");
416 		return GP_OK;
417 	}
418 	printFnkCall ("(mdc800_setStorageSource) called with flag=%i\n",flag);
419 	ret=mdc800_io_sendCommand(camera->port,COMMAND_SET_STORAGE_SOURCE,flag,0,0,0,0);
420 	if (ret != GP_OK)
421 	{
422 		if (flag)
423 		{
424 			printCoreError ("Can't set InternalMemory as Input!\n");
425 		}
426 		else
427 		{
428 			printCoreError ("Can't set FlashCard as Input!\n");
429 		}
430 		return ret;
431 	}
432 
433 	printCoreNote ("Storage Source set to ");
434 	if (flag) {
435 		printCoreNote ("Internal Memory.\n");
436 	} else {
437 		printCoreNote ("Compact Flash Card.\n");
438 	}
439 	camera->pl->system_flags_valid=0;
440 	camera->pl->memory_source=flag;
441 	return GP_OK;
442 }
443 
444 
445 /*
446  * Sets the default storage source.
447  * Default means, that if there's a FlashCard, the Flashcard
448  * is used, else the InternalMemory
449  *
450  * If camera->pl->memory_source is set ( after driver has been closed ),
451  * this value will be used.
452  */
mdc800_setDefaultStorageSource(Camera * camera)453 int mdc800_setDefaultStorageSource (Camera *camera)
454 {
455 	int ret,source;
456 
457 	if (camera->pl->memory_source != -1)
458 	{
459 		source=camera->pl->memory_source;
460 		camera->pl->memory_source=-1;
461 	}
462 	else
463 	{
464 		source=mdc800_isCFCardPresent (camera)?0:1;
465 	}
466 	ret=mdc800_setStorageSource (camera,source);
467 	if (ret!=GP_OK)
468 	{
469 		printCoreError ("(mdc800_setDefaultStorageSource) Setting Storage Source fails\n");
470 		return ret;
471 	}
472 	return GP_OK;
473 }
474 
475 
476 /*
477  *	Returns what StorageSource is selected by the driver
478  * 0: FlashCard, 1: Internal
479  */
mdc800_getStorageSource(Camera * camera)480 int mdc800_getStorageSource(Camera *camera)
481 {
482 	if (camera->pl->memory_source == -1)
483 		mdc800_setDefaultStorageSource(camera);
484 	return camera->pl->memory_source;
485 }
486 
487 
488 
489 /*
490  * Sets Camera to Camera- or PlaybackMode
491  * m: 0 Camera, 1 Playback, 2:VCam (USB)
492  */
mdc800_setMode(Camera * camera,int m)493 int mdc800_setMode (Camera *camera,int m)
494 {
495 	int last=mdc800_getMode (camera);
496 	int ret;
497 /*
498 	if (mdc800_getMode () == m)
499 		return 1;
500 */
501 	switch (m)
502 	{
503 		case 0:
504 			ret = mdc800_io_sendCommand(camera->port,COMMAND_SET_CAMERA_MODE,0,0,0,0,0);
505 			if (ret != GP_OK)
506 			{
507 				printCoreError ("(mdc800_setMode) setting Camera Mode fails\n");
508 				return ret;
509 			}
510 			if (last != m)
511 				printCoreNote ("Mode set to Camera Mode.\n");
512 			break;
513 
514 		case 1:
515 			ret = mdc800_io_sendCommand(camera->port,COMMAND_SET_PLAYBACK_MODE,0,0,0,0,0);
516 			if (ret != GP_OK)
517 			{
518 				printCoreError ("(mdc800_setMode) setting Playback Mode fails\n");
519 				return ret;
520 			}
521 			if (last != m)
522 				printCoreNote ("Mode set to Payback Mode.\n");
523 			break;
524 
525 	}
526 	camera->pl->system_flags_valid=0;
527 	return GP_OK;
528 }
529 
530 
531 /*
532  * Sets up Flashlight. The waitForCommit waits a long
533  * time, to give the camera enough time to load the
534  * flashlight.
535  */
mdc800_setFlashLight(Camera * camera,int value)536 int mdc800_setFlashLight (Camera* camera,int value)
537 {
538 	int command=0,redeye_flag=0,ret;
539 
540 	if (mdc800_getFlashLightStatus (camera) == value)
541 		return GP_OK;
542 
543 	redeye_flag=(value&MDC800_FLASHLIGHT_REDEYE) != 0;
544 
545 	if ((value&MDC800_FLASHLIGHT_ON) != 0)
546 		command=COMMAND_SET_FLASHMODE_ON;
547 	else if ((value&MDC800_FLASHLIGHT_OFF) != 0)
548 	{
549 		command=COMMAND_SET_FLASHMODE_OFF;
550 		redeye_flag=0;
551 	}
552 	else
553 		command=COMMAND_SET_FLASHMODE_AUTO;
554 
555 	camera->pl->system_flags_valid=0;
556 	ret = mdc800_io_sendCommand(camera->port,command,redeye_flag,0,0,0,0);
557 	if (ret != GP_OK)
558 	{
559 		printCoreError ("(mdc800_setFlashLight) sending command fails.\n");
560 		return ret;
561 	}
562 	printCoreNote ("%s", mdc800_getFlashLightString(value));
563 	printCoreNote ("\n");
564 	return GP_OK;
565 }
566 
567 /*
568  * Gets a String with the Text of the Flashlight-Status
569  * depending on value
570  */
mdc800_getFlashLightString(int value)571 char* mdc800_getFlashLightString (int value)
572 {
573 	switch (value)
574 	{
575 		case ( MDC800_FLASHLIGHT_REDEYE | MDC800_FLASHLIGHT_AUTO ) :
576 			return _("FlashLight : Auto (RedEye Reduction)");
577 		case MDC800_FLASHLIGHT_AUTO :
578 			return _("FlashLight : Auto");
579 		case ( MDC800_FLASHLIGHT_REDEYE | MDC800_FLASHLIGHT_ON ) :
580 			return _("FlashLight : On (RedEye Reduction)");
581 		case MDC800_FLASHLIGHT_ON :
582 			return _("FlashLight : On");
583 		case MDC800_FLASHLIGHT_OFF :
584 			return _("FlashLight : Off");
585 	}
586 	return _("FlashLight : undefined");
587 }
588 
589 
590 /*
591  * Enable/Disable the LCD
592  */
mdc800_enableLCD(Camera * camera,int enable)593 int mdc800_enableLCD (Camera*camera,int enable)
594 {
595 	int ret,command;
596 	if (enable == mdc800_isLCDEnabled (camera))
597 		return GP_OK;
598 
599 	if (enable)
600 		command=COMMAND_SET_LCD_ON;
601 	else
602 		command=COMMAND_SET_LCD_OFF;
603 
604 	camera->pl->system_flags_valid=0;
605 	ret = mdc800_io_sendCommand (camera->port,command,0,0,0,0,0);
606 	if (ret!=GP_OK)
607 	{
608 		printCoreError ("(mdc800_enableLCD) can't enable/disable LCD\n");
609 		return ret;
610 	}
611 	if (enable)
612 	{
613 		printCoreNote ("LCD is enabled\n");
614 	}
615 	else
616 	{
617 		printCoreNote ("LCD is disabled\n");
618 	}
619 	return GP_OK;
620 }
621 
622 
623 /*
624  * Shows the specified Image, the Camera has to
625  * be in Playback Mode !
626  */
mdc800_playbackImage(Camera * camera,int nr)627 int mdc800_playbackImage (Camera *camera,int nr )
628 {
629 	int ret;
630 	ret = mdc800_getMode (camera);
631 	if (ret != GP_OK)
632 	{
633 		printCoreError ("(mdc800_showImage) camera must be in Playback Mode !");
634 		return ret;
635 	}
636 
637 	ret = mdc800_io_sendCommand (camera->port,COMMAND_PLAYBACK_IMAGE,nr/100,(nr%100)/10,nr%10,0,0);
638 	if (ret!=GP_OK)
639 	{
640 		printCoreError ("(mdc800_showImage) can't playback Image %i \n",nr);
641 		return ret;
642 	}
643 	return GP_OK;
644 }
645 
646 /*
647  * With ths function you can get information about, how many
648  * pictures can be stored in the free memory of the camera.
649  *
650  * h: High Quality, s: Standard Quality, e: Economy Quality
651  * If one of these Pointers are 0 the will be ignored.
652  */
mdc800_getRemainFreeImageCount(Camera * camera,int * h,int * s,int * e)653 int mdc800_getRemainFreeImageCount (Camera *camera,int* h,int* s,int *e)
654 {
655 	unsigned char data [6];
656 	int ret;
657 
658 	ret = mdc800_io_sendCommand (camera->port,COMMAND_GET_REMAIN_FREE_IMAGE_COUNT,0,0,0,data,6);
659 	if (ret != GP_OK)
660 	{
661 		printCoreError ("(mdc800_getRemainFreeImageCount) Error sending Command.\n");
662 		return ret;
663 	}
664 
665 	if (h)
666 		*h=(int)((data[0]/16)*1000)+((data[0]%16)*100)+((data[1]/16)*10)+(data[1]%16);
667 	if (s)
668 		*s=(int)((data[2]/16)*1000)+((data[2]%16)*100)+((data[3]/16)*10)+(data[3]%16);
669 	if (e)
670 		*e=(int)((data[4]/16)*1000)+((data[4]%16)*100)+((data[5]/16)*10)+(data[5]%16);
671 	return GP_OK;
672 }
673 
674 
675 /*
676  * Get Image Quallity
677  * 0: Economic, 1:Standard, 2:High
678  */
mdc800_getImageQuality(Camera * camera,unsigned char * retval)679 int mdc800_getImageQuality (Camera *camera, unsigned char *retval)
680 {
681 	int ret;
682 	ret = mdc800_io_sendCommand (camera->port,COMMAND_GET_IMAGE_QUALITY,0,0,0,retval,1);
683 	if (ret!=GP_OK)
684 	{
685 		printCoreError ("(mdc800_getImageQuality) fails.\n");
686 		return ret;
687 	}
688 	return GP_OK;
689 }
690 
691 
692 /*
693  *	Set Image Quality, return GP_OK if ok.
694  */
mdc800_setImageQuality(Camera * camera,int v)695 int mdc800_setImageQuality (Camera *camera,int v)
696 {
697     return mdc800_io_sendCommand (camera->port,COMMAND_SET_IMAGE_QUALITY,v,0,0,0,0);
698 }
699 
700 
701 
702 /*
703  * Set the WhiteBalance value
704  * 1:auto ,2:indoor, 4:indoor with flashlight, 8:outdoor
705  */
mdc800_setWB(Camera * camera,int v)706 int mdc800_setWB (Camera *camera, int v)
707 {
708     return mdc800_io_sendCommand(camera->port,COMMAND_SET_WB,v,0,0,0,0);
709 }
710 
711 
712 /*
713  * Return the Exposure settings and W.B.
714  */
mdc800_getWBandExposure(Camera * camera,int * exp,int * wb)715 int mdc800_getWBandExposure (Camera *camera,int* exp, int* wb)
716 {
717 	unsigned char retval[2];
718 	int ret;
719 
720 	/* What's that here is a real diffenrence between USB and RS232 */
721 	int toggle= (camera->port->type == GP_PORT_USB);
722 
723 	ret = mdc800_io_sendCommand(camera->port,COMMAND_GET_WB_AND_EXPOSURE,0,0,0,retval,2);
724 	if (ret == GP_OK)
725 	{
726 		(*exp)= retval[toggle]-2;
727 		(*wb)= retval[1-toggle];
728 		return 1;
729 	}
730 	printCoreError ("(mdc800_getWBandExposure) fails.\n");
731 	return 0;
732 }
733 
734 
735 /*
736  * Sets the Exposure Value
737  */
mdc800_setExposure(Camera * camera,int v)738 int mdc800_setExposure (Camera *camera,int v)
739 {
740 	return mdc800_io_sendCommand(camera->port,COMMAND_SET_EXPOSURE,v+2,0,0,0,0);
741 }
742 
743 /*
744  * Sets the Exposure Mode
745  * 0: MTRX 1:CNTR
746  */
mdc800_setExposureMode(Camera * camera,int m)747 int mdc800_setExposureMode (Camera *camera,int m)
748 {
749 	return mdc800_io_sendCommand (camera->port,COMMAND_SET_EXPOSURE_MODE,m,0,0,0,0);
750 }
751 
752 
753 /*
754  * return the Exposure Mode or -1
755  */
mdc800_getExposureMode(Camera * camera,int * retval)756 int mdc800_getExposureMode (Camera *camera,int *retval)
757 {
758 	unsigned char cretval;
759 	int ret;
760 	ret = mdc800_io_sendCommand (camera->port,COMMAND_GET_EXPOSURE_MODE,0,0,0,&cretval,1);
761 	if (ret == GP_OK)
762 	    *retval = cretval;
763 	return ret;
764 }
765 
766 /*
767  * Enable, Disable the Menu
768  */
mdc800_enableMenu(Camera * camera,int enable)769 int mdc800_enableMenu (Camera *camera,int enable)
770 {
771 	char command=enable?COMMAND_SET_MENU_ON:COMMAND_SET_MENU_OFF;
772 
773 	if (enable == mdc800_isMenuOn (camera))
774 		return GP_OK;
775 	camera->pl->system_flags_valid=0;
776 	return mdc800_io_sendCommand (camera->port,command,0,0,0,0,0);
777 }
778 
mdc800_number_of_pictures(Camera * camera,int * nrofpics)779 int mdc800_number_of_pictures (Camera *camera, int *nrofpics)
780 {
781 	unsigned char answer [2];
782 	int ret;
783 
784 	printFnkCall ("(mdc800_number_of_pictures) called.\n");
785 
786 	ret= mdc800_setTarget (camera, 1);
787 	if (ret != GP_OK)
788 	{
789 		printAPIError ("(mdc800_number_of_pictures) can't set Target\n");
790 		return ret;
791 	}
792 
793 /*
794 	if (!mdc800_setMode (1))
795 	{
796 		printError ("(mdc800_number_of_pictures) can't set Mode\n");
797 		mdc800_close ();
798 		return 0;
799 	}
800 */
801 
802 	ret = mdc800_io_sendCommand(camera->port,COMMAND_GET_NUM_IMAGES,0,0,0,answer,2);
803 	if (ret != GP_OK)
804 	{
805 		printAPIError ("(mdc800_getNumberOfImages) request Number of Pictures fails.\n");
806 		return ret;
807 	}
808 	*nrofpics=answer[0]*256+answer [1];
809 	return GP_OK;
810 }
811