| /* |
| * 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 "config.h" |
| |
| #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("-> %d\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 %d, Default Index %d\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 %d\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; |
| } |