diff options
Diffstat (limited to 'kstars/kstars/indi/v4lphilips.cpp')
-rw-r--r-- | kstars/kstars/indi/v4lphilips.cpp | 610 |
1 files changed, 610 insertions, 0 deletions
diff --git a/kstars/kstars/indi/v4lphilips.cpp b/kstars/kstars/indi/v4lphilips.cpp new file mode 100644 index 00000000..cc15d43d --- /dev/null +++ b/kstars/kstars/indi/v4lphilips.cpp @@ -0,0 +1,610 @@ +/* + Phlips webcam INDI driver + Copyright (C) 2003-2005 by Jasem Mutlaq + + 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 Street, Fifth Floor, Boston, MA 02110-1301 USA + + 2005.04.29 JM: There is no need for this file for Video 4 Linux 2. It is kept for V4L 1 compatiblity. + +*/ + +#include "v4lphilips.h" +#include "webcam/pwc-ioctl.h" + +V4L_Philips::V4L_Philips() : V4L_Driver() +{ + +} + +V4L_Philips::~V4L_Philips() +{ + +} + +void V4L_Philips::initCamBase() +{ + #ifdef HAVE_LINUX_VIDEODEV2_H + v4l_base = new V4L2_Base(); + #else + v4l_pwc = new V4L1_PWC(); + v4l_base = (V4L1_Base *) v4l_pwc; + #endif +} + +void V4L_Philips::initProperties(const char *dev) +{ + + // Call parent + V4L_Driver::initProperties(dev); + + fillSwitch(&BackLightS[0], "ON", "", ISS_OFF); + fillSwitch(&BackLightS[1], "OFF", "", ISS_ON); + fillSwitchVector(&BackLightSP, BackLightS, NARRAY(BackLightS), dev, "Back Light", "", IMAGE_CONTROL, IP_RW, ISR_1OFMANY, 0 , IPS_IDLE); + + fillSwitch(&AntiFlickerS[0], "ON", "", ISS_OFF); + fillSwitch(&AntiFlickerS[1], "OFF", "", ISS_ON); + fillSwitchVector(&AntiFlickerSP, AntiFlickerS, NARRAY(AntiFlickerS), dev, "Anti Flicker", "", IMAGE_CONTROL, IP_RW, ISR_1OFMANY, 0 , IPS_IDLE); + + fillSwitch(&NoiseReductionS[0], "None", "", ISS_ON); + fillSwitch(&NoiseReductionS[1], "Low", "", ISS_OFF); + fillSwitch(&NoiseReductionS[2], "Medium", "", ISS_OFF); + fillSwitch(&NoiseReductionS[3], "High", "", ISS_OFF); + fillSwitchVector(&NoiseReductionSP, NoiseReductionS, NARRAY(NoiseReductionS), dev, "Noise Reduction", "", IMAGE_CONTROL, IP_RW, ISR_1OFMANY, 0, IPS_IDLE); + + fillSwitch(&CamSettingS[0], "Save", "", ISS_OFF); + fillSwitch(&CamSettingS[1], "Restore", "", ISS_OFF); + fillSwitch(&CamSettingS[2], "Factory", "", ISS_OFF); + fillSwitchVector(&CamSettingSP, CamSettingS, NARRAY(CamSettingS), dev, "Settings", "", IMAGE_CONTROL, IP_RW, ISR_1OFMANY, 0, IPS_IDLE); + + fillSwitch(&WhiteBalanceModeS[0], "Auto" , "", ISS_ON); + fillSwitch(&WhiteBalanceModeS[1], "Manual" , "", ISS_OFF); + fillSwitch(&WhiteBalanceModeS[2], "Indoor" , "", ISS_OFF); + fillSwitch(&WhiteBalanceModeS[3], "Outdoor" , "", ISS_OFF); + fillSwitch(&WhiteBalanceModeS[4], "Fluorescent" , "", ISS_OFF); + + fillSwitchVector(&WhiteBalanceModeSP, WhiteBalanceModeS, NARRAY(WhiteBalanceModeS), dev, "White Balance Mode", "", IMAGE_CONTROL, IP_RW, ISR_1OFMANY, 0, IPS_IDLE); + + fillNumber(&WhiteBalanceN[0], "Manual Red", "", "%0.f", 0., 256., 1., 0.); + fillNumber(&WhiteBalanceN[1], "Manual Blue", "", "%0.f", 0., 256., 1., 0.); + fillNumberVector(&WhiteBalanceNP, WhiteBalanceN, NARRAY(WhiteBalanceN), dev, "White Balance", "", IMAGE_CONTROL, IP_RW, 60, IPS_IDLE); + + fillNumber(&ShutterSpeedN[0], "Speed", "", "%0.f", 0., 65535., 100., 0.); + fillNumberVector(&ShutterSpeedNP, ShutterSpeedN, NARRAY(ShutterSpeedN), dev, "Shutter Speed", "", COMM_GROUP, IP_RW, 60, IPS_IDLE); + +} + +void V4L_Philips::ISGetProperties (const char *dev) +{ + + if (dev && strcmp (device_name, dev)) + return; + + #ifdef HAVE_LINUX_VIDEODEV2_H + V4L_Driver::ISGetProperties(dev); + return; + #endif + + /* COMM_GROUP */ + IDDefSwitch(&PowerSP, NULL); + IDDefText(&PortTP, NULL); + IDDefText(&camNameTP, NULL); + IDDefSwitch(&StreamSP, NULL); + IDDefNumber(&FrameRateNP, NULL); + IDDefNumber(&ExposeTimeNP, NULL); + IDDefNumber(&ShutterSpeedNP, NULL); + IDDefBLOB(&imageBP, NULL); + + /* Image Groups */ + IDDefSwitch(&CompressSP, NULL); + IDDefSwitch(&ImageTypeSP, NULL); + IDDefNumber(&FrameNP, NULL); + IDDefNumber(&ImageAdjustNP, NULL); + + /* Image Control */ + IDDefSwitch(&WhiteBalanceModeSP, NULL); + IDDefNumber(&WhiteBalanceNP, NULL); + IDDefSwitch(&BackLightSP, NULL); + IDDefSwitch(&AntiFlickerSP, NULL); + IDDefSwitch(&NoiseReductionSP, NULL); + IDDefSwitch(&CamSettingSP, NULL); + +} + +void V4L_Philips::ISNewSwitch (const char *dev, const char *name, ISState *states, char *names[], int n) +{ + char errmsg[ERRMSG_SIZE]; + int index=0; + + /* ignore if not ours */ + if (dev && strcmp (device_name, dev)) + return; + + #ifndef HAVE_LINUX_VIDEODEV2_H + /* Anti Flicker control */ + if (!strcmp (AntiFlickerSP.name, name)) + { + if (checkPowerS(&AntiFlickerSP)) + return; + + AntiFlickerSP.s = IPS_IDLE; + + IUResetSwitches(&AntiFlickerSP); + IUUpdateSwitches(&AntiFlickerSP, states, names, n); + + if (AntiFlickerS[0].s == ISS_ON) + { + if (v4l_pwc->setFlicker(true, errmsg) < 0) + { + AntiFlickerS[0].s = ISS_OFF; + AntiFlickerS[1].s = ISS_ON; + IDSetSwitch(&AntiFlickerSP, "%s", errmsg); + return; + } + + AntiFlickerSP.s = IPS_OK; + IDSetSwitch(&AntiFlickerSP, NULL); + } + else + { + if (v4l_pwc->setFlicker(false, errmsg) < 0) + { + AntiFlickerS[0].s = ISS_ON; + AntiFlickerS[1].s = ISS_OFF; + IDSetSwitch(&AntiFlickerSP, "%s", errmsg); + return; + } + + IDSetSwitch(&AntiFlickerSP, NULL); + } + + return; + } + + /* Back light compensation */ + if (!strcmp (BackLightSP.name, name)) + { + if (checkPowerS(&BackLightSP)) + return; + + BackLightSP.s = IPS_IDLE; + + IUResetSwitches(&BackLightSP); + IUUpdateSwitches(&BackLightSP, states, names, n); + + if (BackLightS[0].s == ISS_ON) + { + if (v4l_pwc->setBackLight(true, errmsg) < 0) + { + BackLightS[0].s = ISS_OFF; + BackLightS[1].s = ISS_ON; + IDSetSwitch(&BackLightSP, "%s", errmsg); + return; + } + + BackLightSP.s = IPS_OK; + IDSetSwitch(&BackLightSP, NULL); + } + else + { + if (v4l_pwc->setBackLight(false, errmsg) < 0) + { + BackLightS[0].s = ISS_ON; + BackLightS[1].s = ISS_OFF; + IDSetSwitch(&BackLightSP, "%s", errmsg); + return; + } + + IDSetSwitch(&BackLightSP, NULL); + } + + return; + } + + /* Noise reduction control */ + if (!strcmp (NoiseReductionSP.name, name)) + { + if (checkPowerS(&NoiseReductionSP)) + return; + + NoiseReductionSP.s = IPS_IDLE; + + IUResetSwitches(&NoiseReductionSP); + IUUpdateSwitches(&NoiseReductionSP, states, names, n); + + for (int i=0; i < 4; i++) + if (NoiseReductionS[i].s == ISS_ON) + { + index = i; + break; + } + + if (v4l_pwc->setNoiseRemoval(index, errmsg) < 0) + { + IUResetSwitches(&NoiseReductionSP); + NoiseReductionS[0].s = ISS_ON; + IDSetSwitch(&NoiseReductionSP, "%s", errmsg); + return; + } + + NoiseReductionSP.s = IPS_OK; + + IDSetSwitch(&NoiseReductionSP, NULL); + return; + } + + /* White balace mode */ + if (!strcmp (WhiteBalanceModeSP.name, name)) + { + if (checkPowerS(&WhiteBalanceModeSP)) + return; + + WhiteBalanceModeSP.s = IPS_IDLE; + + IUResetSwitches(&WhiteBalanceModeSP); + IUUpdateSwitches(&WhiteBalanceModeSP, states, names, n); + + for (int i=0; i < 5; i++) + if (WhiteBalanceModeS[i].s == ISS_ON) + { + index = i; + break; + } + + switch (index) + { + // Auto + case 0: + if (v4l_pwc->setWhiteBalanceMode(PWC_WB_AUTO, errmsg) < 0) + { + IUResetSwitches(&WhiteBalanceModeSP), + WhiteBalanceModeS[0].s = ISS_ON; + IDSetSwitch(&WhiteBalanceModeSP, "%s", errmsg); + return; + } + break; + + // Manual + case 1: + if (v4l_pwc->setWhiteBalanceMode(PWC_WB_MANUAL, errmsg) < 0) + { + IUResetSwitches(&WhiteBalanceModeSP), + WhiteBalanceModeS[0].s = ISS_ON; + IDSetSwitch(&WhiteBalanceModeSP, "%s", errmsg); + return; + } + break; + + // Indoor + case 2: + if (v4l_pwc->setWhiteBalanceMode(PWC_WB_INDOOR, errmsg) < 0) + { + IUResetSwitches(&WhiteBalanceModeSP), + WhiteBalanceModeS[0].s = ISS_ON; + IDSetSwitch(&WhiteBalanceModeSP, "%s", errmsg); + return; + } + break; + + // Outdoor + case 3: + if (v4l_pwc->setWhiteBalanceMode(PWC_WB_OUTDOOR, errmsg) < 0) + { + IUResetSwitches(&WhiteBalanceModeSP), + WhiteBalanceModeS[0].s = ISS_ON; + IDSetSwitch(&WhiteBalanceModeSP, "%s", errmsg); + return; + } + break; + + // Flurescent + case 4: + if (v4l_pwc->setWhiteBalanceMode(PWC_WB_FL, errmsg) < 0) + { + IUResetSwitches(&WhiteBalanceModeSP), + WhiteBalanceModeS[0].s = ISS_ON; + IDSetSwitch(&WhiteBalanceModeSP, "%s", errmsg); + return; + } + break; + + } + + WhiteBalanceModeSP.s = IPS_OK; + IDSetSwitch(&WhiteBalanceModeSP, NULL); + return; + + } + + /* Camera setttings */ + if (!strcmp (CamSettingSP.name, name)) + { + + if (checkPowerS(&CamSettingSP)) + return; + + CamSettingSP.s = IPS_IDLE; + + IUResetSwitches(&CamSettingSP); + IUUpdateSwitches(&CamSettingSP, states, names, n); + + if (CamSettingS[0].s == ISS_ON) + { + if (v4l_pwc->saveSettings(errmsg) < 0) + { + IUResetSwitches(&CamSettingSP); + IDSetSwitch(&CamSettingSP, "%s", errmsg); + return; + } + + CamSettingSP.s = IPS_OK; + IDSetSwitch(&CamSettingSP, "Settings saved."); + return; + } + + if (CamSettingS[1].s == ISS_ON) + { + v4l_pwc->restoreSettings(); + IUResetSwitches(&CamSettingSP); + CamSettingSP.s = IPS_OK; + IDSetSwitch(&CamSettingSP, "Settings restored."); + updateV4L1Controls(); + return; + } + + if (CamSettingS[2].s == ISS_ON) + { + v4l_pwc->restoreFactorySettings(); + IUResetSwitches(&CamSettingSP); + CamSettingSP.s = IPS_OK; + IDSetSwitch(&CamSettingSP, "Factory settings restored."); + updateV4L1Controls(); + return; + } + } + #endif + + // Call parent + V4L_Driver::ISNewSwitch(dev, name, states, names, n); + + + +} + +void V4L_Philips::ISNewText (const char *dev, const char *name, char *texts[], char *names[], int n) +{ + + V4L_Driver::ISNewText(dev, name, texts, names, n); + +} + +void V4L_Philips::ISNewNumber (const char *dev, const char *name, double values[], char *names[], int n) +{ + + // Nothing for V4L 2 to do here + #ifndef HAVE_LINUX_VIDEODEV2_H + char errmsg[ERRMSGSIZ]; + + /* Frame rate */ + if (!strcmp (FrameRateNP.name, name)) + { + if (checkPowerN(&FrameRateNP)) + return; + + FrameRateNP.s = IPS_IDLE; + + int oldFP = (int) FrameRateN[0].value; + + if (IUUpdateNumbers(&FrameRateNP, values, names, n) < 0) + return; + + if (v4l_pwc->setFrameRate( (int) FrameRateN[0].value, errmsg) < 0) + { + FrameRateN[0].value = oldFP; + IDSetNumber(&FrameRateNP, "%s", errmsg); + return; + } + + FrameRateNP.s = IPS_OK; + IDSetNumber(&FrameRateNP, NULL); + return; + } + + if (!strcmp (ShutterSpeedNP.name, name)) + { + if (checkPowerN(&ShutterSpeedNP)) + return; + + ShutterSpeedNP.s = IPS_IDLE; + + if (v4l_pwc->setExposure( (int) values[0], errmsg) < 0) + { + IDSetNumber(&ShutterSpeedNP, "%s", errmsg); + return; + } + + ShutterSpeedN[0].value = values[0]; + ShutterSpeedNP.s = IPS_OK; + IDSetNumber(&ShutterSpeedNP, NULL); + return; + } + + /* White balance */ + if (!strcmp (WhiteBalanceNP.name, name)) + { + if (checkPowerN(&WhiteBalanceNP)) + return; + + WhiteBalanceNP.s = IPS_IDLE; + + int oldBalance[2]; + oldBalance[0] = (int) WhiteBalanceN[0].value; + oldBalance[1] = (int) WhiteBalanceN[1].value; + + if (IUUpdateNumbers(&WhiteBalanceNP, values, names, n) < 0) + return; + + if (v4l_pwc->setWhiteBalanceRed( (int) WhiteBalanceN[0].value * 256, errmsg)) + { + WhiteBalanceN[0].value = oldBalance[0]; + WhiteBalanceN[1].value = oldBalance[1]; + IDSetNumber(&WhiteBalanceNP, "%s", errmsg); + return; + } + if (v4l_pwc->setWhiteBalanceBlue( (int) WhiteBalanceN[1].value * 256, errmsg)) + { + WhiteBalanceN[0].value = oldBalance[0]; + WhiteBalanceN[1].value = oldBalance[1]; + IDSetNumber(&WhiteBalanceNP, "%s", errmsg); + return; + } + + IUResetSwitches(&WhiteBalanceModeSP); + WhiteBalanceModeS[1].s = ISS_ON; + WhiteBalanceModeSP.s = IPS_OK; + WhiteBalanceNP.s = IPS_OK; + IDSetSwitch(&WhiteBalanceModeSP, NULL); + IDSetNumber(&WhiteBalanceNP, NULL); + return; + } + + #endif + + // Call parent + V4L_Driver::ISNewNumber(dev, name, values, names, n); + +} + +#ifndef HAVE_LINUX_VIDEODEV2_H +/* Retrieves basic data from the device upon connection.*/ +void V4L_Philips::getBasicData() +{ + + char errmsg[ERRMSGSIZ]; + bool result; + int xmax, ymax, xmin, ymin, index; + + v4l_pwc->getMaxMinSize(xmax, ymax, xmin, ymin); + + /* Width */ + FrameN[2].value = v4l_pwc->getWidth(); + FrameN[2].min = xmin; + FrameN[2].max = xmax; + + /* Height */ + FrameN[3].value = v4l_pwc->getHeight(); + FrameN[3].min = ymin; + FrameN[3].max = ymax; + + IDSetNumber(&FrameNP, NULL); + IUUpdateMinMax(&FrameNP); + + IUSaveText(&camNameT[0], v4l_pwc->getDeviceName()); + IDSetText(&camNameTP, NULL); + + IDLog("Raw values\n Contrast: %d \n Brightness %d \n Color %d \n Sharpness %d \n Gain %d \n Gamma %d \n", v4l_pwc->getContrast(), v4l_pwc->getBrightness(), v4l_pwc->getColor(), v4l_pwc->getSharpness(), v4l_pwc->getGain(), v4l_pwc->getGama()); + + updateV4L1Controls(); + + if (v4l_pwc->setFrameRate( (int) FrameRateN[0].value, errmsg) < 0) + { + FrameRateNP.s = IPS_ALERT; + IDSetNumber(&FrameRateNP, "%s", errmsg); + } + else + { + FrameRateNP.s = IPS_OK; + IDSetNumber(&FrameRateNP, NULL); + } + + result = v4l_pwc->getBackLight(); + if (result) + { + BackLightS[0].s = ISS_ON; + BackLightS[1].s = ISS_OFF; + } + else + { + BackLightS[0].s = ISS_OFF; + BackLightS[1].s = ISS_ON; + } + IDSetSwitch(&BackLightSP, NULL); + + result = v4l_pwc->getFlicker(); + if (result) + { + AntiFlickerS[0].s = ISS_ON; + AntiFlickerS[1].s = ISS_OFF; + } + else + { + AntiFlickerS[0].s = ISS_OFF; + AntiFlickerS[1].s = ISS_ON; + } + IDSetSwitch(&AntiFlickerSP, NULL); + + index = v4l_pwc->getNoiseRemoval(); + IUResetSwitches(&NoiseReductionSP); + NoiseReductionS[index].s = ISS_ON; + IDSetSwitch(&NoiseReductionSP, NULL); + + index = v4l_pwc->getWhiteBalance(); + IUResetSwitches(&WhiteBalanceModeSP); + switch (index) + { + case PWC_WB_AUTO: + WhiteBalanceModeS[0].s = ISS_ON; + break; + case PWC_WB_MANUAL: + WhiteBalanceModeS[1].s = ISS_ON; + break; + case PWC_WB_INDOOR: + WhiteBalanceModeS[2].s = ISS_ON; + break; + case PWC_WB_OUTDOOR: + WhiteBalanceModeS[3].s = ISS_ON; + break; + case PWC_WB_FL: + WhiteBalanceModeS[3].s = ISS_ON; + break; + } + IDSetSwitch(&WhiteBalanceModeSP, NULL); + +} +#endif + +#ifndef HAVE_LINUX_VIDEODEV2_H +void V4L_Philips::updateV4L1Controls() +{ + int index =0; + + ImageAdjustN[0].value = v4l_pwc->getContrast() / 256.; + ImageAdjustN[1].value = v4l_pwc->getBrightness() / 256.; + ImageAdjustN[2].value = v4l_pwc->getColor() / 256.; + index = v4l_pwc->getSharpness(); + if (index < 0) + ImageAdjustN[3].value = -1; + else + ImageAdjustN[3].value = v4l_pwc->getSharpness() / 256.; + + ImageAdjustN[4].value = v4l_pwc->getGain() / 256.; + ImageAdjustN[5].value = v4l_pwc->getGama() / 256.; + + ImageAdjustNP.s = IPS_OK; + IDSetNumber(&ImageAdjustNP, NULL); + + +} +#endif + |