/* * Copyright 2000 Corel Corporation * Copyright 2006 Marcus Meissner * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ #include <stdarg.h> #include "gphoto2_i.h" #include "wine/debug.h" WINE_DEFAULT_DEBUG_CHANNEL(twain); static TW_UINT16 GPHOTO2_ICAPXferMech (pTW_CAPABILITY,TW_UINT16); static TW_UINT16 GPHOTO2_ICAPPixelType (pTW_CAPABILITY,TW_UINT16); static TW_UINT16 GPHOTO2_ICAPPixelFlavor (pTW_CAPABILITY,TW_UINT16); static TW_UINT16 GPHOTO2_ICAPBitDepth (pTW_CAPABILITY,TW_UINT16); static TW_UINT16 GPHOTO2_ICAPUnits (pTW_CAPABILITY,TW_UINT16); TW_UINT16 GPHOTO2_SaneCapability (pTW_CAPABILITY pCapability, TW_UINT16 action) { TW_UINT16 twCC = TWCC_SUCCESS; TRACE("capability=%d action=%d\n", pCapability->Cap, action); switch (pCapability->Cap) { case CAP_DEVICEEVENT: case CAP_ALARMS: case CAP_ALARMVOLUME: case ACAP_AUDIOFILEFORMAT: case ACAP_XFERMECH: case ICAP_AUTOMATICBORDERDETECTION: case ICAP_AUTOMATICDESKEW: case ICAP_AUTODISCARDBLANKPAGES: case ICAP_AUTOMATICROTATE: case ICAP_FLIPROTATION: case CAP_AUTOMATICCAPTURE: case CAP_TIMEBEFOREFIRSTCAPTURE: case CAP_TIMEBETWEENCAPTURES: case CAP_AUTOSCAN: case CAP_CLEARBUFFERS: case CAP_MAXBATCHBUFFERS: case ICAP_BARCODEDETECTIONENABLED: case ICAP_SUPPORTEDBARCODETYPES: case ICAP_BARCODEMAXSEARCHPRIORITIES: case ICAP_BARCODESEARCHPRIORITIES: case ICAP_BARCODESEARCHMODE: case ICAP_BARCODEMAXRETRIES: case ICAP_BARCODETIMEOUT: case CAP_EXTENDEDCAPS: case CAP_SUPPORTEDCAPS: case ICAP_FILTER: case ICAP_GAMMA: case ICAP_PLANARCHUNKY: case ICAP_BITORDERCODES: case ICAP_CCITTKFACTOR: case ICAP_JPEGPIXELTYPE: /*case ICAP_JPEGQUALITY:*/ case ICAP_PIXELFLAVORCODES: case ICAP_TIMEFILL: case CAP_DEVICEONLINE: case CAP_DEVICETIMEDATE: case CAP_SERIALNUMBER: case ICAP_EXPOSURETIME: case ICAP_FLASHUSED2: case ICAP_IMAGEFILTER: case ICAP_LAMPSTATE: case ICAP_LIGHTPATH: case ICAP_NOISEFILTER: case ICAP_OVERSCAN: case ICAP_PHYSICALHEIGHT: case ICAP_PHYSICALWIDTH: case ICAP_ZOOMFACTOR: case CAP_PRINTER: case CAP_PRINTERENABLED: case CAP_PRINTERINDEX: case CAP_PRINTERMODE: case CAP_PRINTERSTRING: case CAP_PRINTERSUFFIX: case CAP_AUTHOR: case CAP_CAPTION: case CAP_TIMEDATE: case ICAP_AUTOBRIGHT: case ICAP_BRIGHTNESS: case ICAP_CONTRAST: case ICAP_HIGHLIGHT: case ICAP_ORIENTATION: case ICAP_ROTATION: case ICAP_SHADOW: case ICAP_XSCALING: case ICAP_YSCALING: case ICAP_BITDEPTHREDUCTION: case ICAP_BITORDER: case ICAP_CUSTHALFTONE: case ICAP_HALFTONES: case ICAP_THRESHOLD: case CAP_LANGUAGE: case ICAP_FRAMES: case ICAP_MAXFRAMES: case ICAP_SUPPORTEDSIZES: case CAP_AUTOFEED: case CAP_CLEARPAGE: case CAP_FEEDERALIGNMENT: case CAP_FEEDERENABLED: case CAP_FEEDERLOADED: case CAP_FEEDERORDER: case CAP_FEEDPAGE: case CAP_PAPERBINDING: case CAP_PAPERDETECTABLE: case CAP_REACQUIREALLOWED: case CAP_REWINDPAGE: case ICAP_PATCHCODEDETECTIONENABLED: case ICAP_SUPPORTEDPATCHCODETYPES: case ICAP_PATCHCODEMAXSEARCHPRIORITIES: case ICAP_PATCHCODESEARCHPRIORITIES: case ICAP_PATCHCODESEARCHMODE: case ICAP_PATCHCODEMAXRETRIES: case ICAP_PATCHCODETIMEOUT: case CAP_BATTERYMINUTES: case CAP_BATTERYPERCENTAGE: case CAP_POWERDOWNTIME: case CAP_POWERSUPPLY: case ICAP_XNATIVERESOLUTION: case ICAP_XRESOLUTION: case ICAP_YNATIVERESOLUTION: case ICAP_YRESOLUTION: twCC = TWCC_CAPUNSUPPORTED; break; case CAP_XFERCOUNT: /* This is a required capability that every source need to support but we haven't implemented yet. */ twCC = TWCC_SUCCESS; break; /*case ICAP_COMPRESSION:*/ case ICAP_IMAGEFILEFORMAT: case ICAP_TILES: twCC = TWCC_CAPUNSUPPORTED; break; case ICAP_XFERMECH: twCC = GPHOTO2_ICAPXferMech (pCapability, action); break; case ICAP_PIXELTYPE: twCC = GPHOTO2_ICAPPixelType (pCapability, action); break; case ICAP_PIXELFLAVOR: twCC = GPHOTO2_ICAPPixelFlavor (pCapability, action); break; case ICAP_BITDEPTH: twCC = GPHOTO2_ICAPBitDepth (pCapability, action); break; case ICAP_UNITS: twCC = GPHOTO2_ICAPUnits (pCapability, action); break; case ICAP_UNDEFINEDIMAGESIZE: case CAP_CAMERAPREVIEWUI: case CAP_ENABLEDSUIONLY: case CAP_INDICATORS: case CAP_UICONTROLLABLE: twCC = TWCC_CAPUNSUPPORTED; break; case ICAP_COMPRESSION: twCC = TWCC_SUCCESS; break; default: twCC = TWRC_FAILURE; break; } return twCC; } static TW_BOOL GPHOTO2_OneValueSet32 (pTW_CAPABILITY pCapability, TW_UINT32 value) { pCapability->hContainer = GlobalAlloc (0, sizeof(TW_ONEVALUE)); TRACE("-> %ld\n", value); if (pCapability->hContainer) { pTW_ONEVALUE pVal = GlobalLock (pCapability->hContainer); pVal->ItemType = TWTY_UINT32; pVal->Item = value; GlobalUnlock (pCapability->hContainer); pCapability->ConType = TWON_ONEVALUE; return TRUE; } else return FALSE; } static TW_BOOL GPHOTO2_OneValueSet16 (pTW_CAPABILITY pCapability, TW_UINT16 value) { pCapability->hContainer = GlobalAlloc (0, sizeof(TW_ONEVALUE)); TRACE("-> %d\n", value); if (pCapability->hContainer) { pTW_ONEVALUE pVal = GlobalLock (pCapability->hContainer); pVal->ItemType = TWTY_UINT16; pVal->Item = value; GlobalUnlock (pCapability->hContainer); pCapability->ConType = TWON_ONEVALUE; return TRUE; } else return FALSE; } static TW_BOOL GPHOTO2_EnumSet16 (pTW_CAPABILITY pCapability, int nrofvalues, const TW_UINT16 *values, int current, int def) { pTW_ENUMERATION pVal; pCapability->hContainer = GlobalAlloc (0, sizeof(TW_ENUMERATION) + nrofvalues * sizeof(TW_UINT16)); if (!pCapability->hContainer) return FALSE; pVal = GlobalLock (pCapability->hContainer); pVal->ItemType = TWTY_UINT16; pVal->NumItems = nrofvalues; memcpy(pVal->ItemList, values, sizeof(TW_UINT16)*nrofvalues); pVal->CurrentIndex = current; pVal->DefaultIndex = def; pCapability->ConType = TWON_ENUMERATION; GlobalUnlock (pCapability->hContainer); return TRUE; } static TW_BOOL GPHOTO2_EnumGet16 (pTW_CAPABILITY pCapability, int *nrofvalues, TW_UINT16 **values) { pTW_ENUMERATION pVal = GlobalLock (pCapability->hContainer); if (!pVal) return FALSE; *nrofvalues = pVal->NumItems; *values = HeapAlloc( GetProcessHeap(), 0, sizeof(TW_UINT16)*pVal->NumItems); memcpy (*values, pVal->ItemList, sizeof(TW_UINT16)*(*nrofvalues)); FIXME("Current Index %ld, Default Index %ld\n", pVal->CurrentIndex, pVal->DefaultIndex); GlobalUnlock (pCapability->hContainer); return TRUE; } static TW_BOOL GPHOTO2_OneValueGet32 (pTW_CAPABILITY pCapability, TW_UINT32 *pValue) { pTW_ONEVALUE pVal = GlobalLock (pCapability->hContainer); if (pVal) { *pValue = pVal->Item; GlobalUnlock (pCapability->hContainer); return TRUE; } else return FALSE; } static TW_BOOL GPHOTO2_OneValueGet16 (pTW_CAPABILITY pCapability, TW_UINT16 *pValue) { pTW_ONEVALUE pVal = GlobalLock (pCapability->hContainer); if (pVal) { *pValue = pVal->Item; GlobalUnlock (pCapability->hContainer); return TRUE; } else return FALSE; } /* ICAP_XFERMECH */ static TW_UINT16 GPHOTO2_ICAPXferMech (pTW_CAPABILITY pCapability, TW_UINT16 action) { TRACE("ICAP_XFERMECH, action %d\n", action); switch (action) { case MSG_GET: if (!GPHOTO2_OneValueSet32 (pCapability, activeDS.capXferMech)) return TWCC_LOWMEMORY; return TWCC_SUCCESS; case MSG_SET: if (pCapability->ConType == TWON_ONEVALUE) { TW_UINT32 xfermechtemp = 0; if (!GPHOTO2_OneValueGet32 (pCapability, &xfermechtemp)) return TWCC_LOWMEMORY; activeDS.capXferMech = xfermechtemp; TRACE("xfermech is %ld\n", xfermechtemp); return TWCC_SUCCESS; } else if (pCapability->ConType == TWON_ENUMERATION) { } FIXME("GET FAILED\n"); break; case MSG_GETCURRENT: if (!GPHOTO2_OneValueSet32 (pCapability, activeDS.capXferMech)) return TWCC_LOWMEMORY; break; case MSG_GETDEFAULT: if (!GPHOTO2_OneValueSet32 (pCapability, TWSX_NATIVE)) return TWCC_LOWMEMORY; break; case MSG_RESET: activeDS.capXferMech = TWSX_NATIVE; break; } return TWCC_SUCCESS; } /* ICAP_PIXELTYPE */ static TW_UINT16 GPHOTO2_ICAPPixelType (pTW_CAPABILITY pCapability, TW_UINT16 action) { TRACE("Action %d\n", action); switch (action) { case MSG_GET: if ((pCapability->ConType == TWON_DONTCARE16) || (pCapability->ConType == TWON_ONEVALUE) ) { if (!GPHOTO2_OneValueSet16 (pCapability, activeDS.pixeltype)) return TWCC_LOWMEMORY; return TWCC_SUCCESS; } FIXME("Unknown container type %x in MSG_GET\n", pCapability->ConType); return TWCC_CAPBADOPERATION; case MSG_SET: if (pCapability->ConType == TWON_ONEVALUE) { TW_UINT16 pixeltype = 0; if (!GPHOTO2_OneValueGet16 (pCapability, &pixeltype)) return TWCC_LOWMEMORY; activeDS.pixeltype = pixeltype; FIXME("pixeltype changed to %d!\n", pixeltype); return TWCC_SUCCESS; } FIXME("set not done\n"); if (pCapability->ConType == TWON_ENUMERATION) { TW_UINT16 *values = NULL; int i, nrofvalues = 0; if (!GPHOTO2_EnumGet16 (pCapability, &nrofvalues, &values)) return TWCC_LOWMEMORY; for (i=0;i<nrofvalues;i++) FIXME("SET PixelType %d:%d\n", i, values[i]); HeapFree (GetProcessHeap(), 0, values); } break; case MSG_GETCURRENT: if (!GPHOTO2_OneValueSet16 (pCapability, activeDS.pixeltype)) { FIXME("Failed one value set in GETCURRENT, contype %d!\n", pCapability->ConType); return TWCC_LOWMEMORY; } break; case MSG_GETDEFAULT: if (!GPHOTO2_OneValueSet16 (pCapability, TWPT_RGB)) { FIXME("Failed onevalue set in GETDEFAULT!\n"); return TWCC_LOWMEMORY; } break; case MSG_RESET: activeDS.pixeltype = TWPT_RGB; break; } return TWCC_SUCCESS; } /* ICAP_PIXELFLAVOR */ static TW_UINT16 GPHOTO2_ICAPPixelFlavor (pTW_CAPABILITY pCapability, TW_UINT16 action) { TRACE("Action %d\n", action); switch (action) { case MSG_GET: if ((pCapability->ConType == TWON_DONTCARE16) || (pCapability->ConType == TWON_ONEVALUE) ) { if (!GPHOTO2_OneValueSet16 (pCapability, TWPF_CHOCOLATE)) return TWCC_LOWMEMORY; return TWCC_SUCCESS; } if (!pCapability->ConType) { TW_UINT16 arr[2]; arr[0] = TWPF_CHOCOLATE; arr[1] = TWPF_VANILLA; if (!GPHOTO2_EnumSet16 (pCapability, 2, arr, 1, 1)) return TWCC_LOWMEMORY; return TWCC_SUCCESS; } FIXME("MSG_GET container type %x unhandled\n", pCapability->ConType); return TWCC_BADVALUE; case MSG_SET: if (pCapability->ConType == TWON_ONEVALUE) { TW_UINT16 pixelflavor = 0; if (!GPHOTO2_OneValueGet16 (pCapability, &pixelflavor)) return TWCC_LOWMEMORY; activeDS.pixelflavor = pixelflavor; FIXME("pixelflavor is %d\n", pixelflavor); } break; case MSG_GETCURRENT: if (!GPHOTO2_OneValueSet16 (pCapability, activeDS.pixelflavor)) return TWCC_LOWMEMORY; break; case MSG_GETDEFAULT: if (!GPHOTO2_OneValueSet16 (pCapability, TWPF_CHOCOLATE)) return TWCC_LOWMEMORY; break; case MSG_RESET: break; } return TWCC_SUCCESS; } /* ICAP_BITDEPTH */ static TW_UINT16 GPHOTO2_ICAPBitDepth (pTW_CAPABILITY pCapability, TW_UINT16 action) { TRACE("Action %d\n", action); switch (action) { case MSG_GET: if ((pCapability->ConType == TWON_DONTCARE16) || (pCapability->ConType == TWON_ONEVALUE) ) { if (!GPHOTO2_OneValueSet16 (pCapability, 24)) return TWCC_LOWMEMORY; return TWCC_SUCCESS; } FIXME("MSG_GET container type %x unhandled\n", pCapability->ConType); return TWCC_SUCCESS; case MSG_SET: if (pCapability->ConType == TWON_ONEVALUE) { TW_UINT16 bitdepth = 0; if (!GPHOTO2_OneValueGet16 (pCapability, &bitdepth)) return TWCC_LOWMEMORY; if (bitdepth != 24) return TWCC_BADVALUE; return TWCC_SUCCESS; } if (pCapability->ConType == TWON_ENUMERATION) { int i, nrofvalues = 0; TW_UINT16 *values = NULL; if (!GPHOTO2_EnumGet16 (pCapability, &nrofvalues, &values)) return TWCC_LOWMEMORY; for (i=0;i<nrofvalues;i++) FIXME("SET: enum element %d = %d\n", i, values[i]); HeapFree (GetProcessHeap(), 0, values); return TWCC_SUCCESS; } FIXME("Unhandled container type %d in MSG_SET\n", pCapability->ConType); break; case MSG_GETCURRENT: if (!GPHOTO2_OneValueSet16 (pCapability, 24)) return TWCC_LOWMEMORY; break; case MSG_GETDEFAULT: if (!GPHOTO2_OneValueSet16 (pCapability, 24)) return TWCC_LOWMEMORY; break; case MSG_RESET: break; } return TWCC_SUCCESS; } /* ICAP_UNITS */ static TW_UINT16 GPHOTO2_ICAPUnits (pTW_CAPABILITY pCapability, TW_UINT16 action) { TRACE("Action %d\n", action); switch (action) { case MSG_GET: if ((pCapability->ConType == TWON_DONTCARE16) || (pCapability->ConType == TWON_ONEVALUE) ) { if (!GPHOTO2_OneValueSet16 (pCapability, TWUN_PIXELS)) return TWCC_LOWMEMORY; return TWCC_SUCCESS; } FIXME("MSG_GET container type %x unhandled\n", pCapability->ConType); return TWCC_SUCCESS; case MSG_SET: if (pCapability->ConType == TWON_ONEVALUE) { TW_UINT16 units = 0; if (!GPHOTO2_OneValueGet16 (pCapability, &units)) return TWCC_LOWMEMORY; FIXME("SET to type %d, stub.\n", units); return TWCC_SUCCESS; } if (pCapability->ConType == TWON_ENUMERATION) { int i, nrofvalues = 0; TW_UINT16 *values = NULL; if (!GPHOTO2_EnumGet16 (pCapability, &nrofvalues, &values)) return TWCC_LOWMEMORY; for (i=0;i<nrofvalues;i++) FIXME("SET: enum element %d = %d\n", i, values[i]); HeapFree (GetProcessHeap(), 0, values); return TWCC_SUCCESS; } FIXME("Unhandled container type %d in MSG_SET\n", pCapability->ConType); break; case MSG_GETCURRENT: if (!GPHOTO2_OneValueSet16 (pCapability, TWUN_INCHES)) return TWCC_LOWMEMORY; break; case MSG_GETDEFAULT: if (!GPHOTO2_OneValueSet16 (pCapability, TWUN_PIXELS)) return TWCC_LOWMEMORY; break; case MSG_RESET: break; } return TWCC_SUCCESS; }