]> git.sesse.net Git - vlc/blob - modules/video_filter/atmo/AtmoDmxSerialConnection.cpp
enhanced & corrected AtmoLight filter module
[vlc] / modules / video_filter / atmo / AtmoDmxSerialConnection.cpp
1 /*
2  * AtmoDmxSerialConnection.cpp: Class for communication with a Simple DMX Dongle/Controller
3  * for hardware see also:
4  * http://www.dzionsko.de/elektronic/index.htm
5  * http://www.ulrichradig.de/ (search for dmx on his page)
6  *
7  * See the README.txt file for copyright information and how to reach the author(s).
8  *
9  * $Id$
10  */
11 #include "AtmoDefs.h"
12 #include "AtmoDmxSerialConnection.h"
13 #include "DmxTools.h"
14
15 #if !defined(_ATMO_VLC_PLUGIN_)
16 #include "DmxConfigDialog.h"
17 #endif
18
19 #include <stdio.h>
20 #include <fcntl.h>
21
22 #if !defined(WIN32)
23 #include <termios.h>
24 #include <unistd.h>
25 #endif
26
27
28 CAtmoDmxSerialConnection::CAtmoDmxSerialConnection(CAtmoConfig *cfg) : CAtmoConnection(cfg) {
29     m_hComport = INVALID_HANDLE_VALUE;
30
31     memset(&DMXout, 0, sizeof(DMXout));
32     DMXout[0] = 0x5A;     // DMX Command Start Byte
33     DMXout[1] = 0xA1;     // DMX Controlcommand for 256 channels
34     DMXout[258] = 0xA5;   // end of block
35
36     m_dmx_channels_base = ConvertDmxStartChannelsToInt( cfg->getDMX_RGB_Channels(), cfg->getDMX_BaseChannels());
37 }
38
39
40 CAtmoDmxSerialConnection::~CAtmoDmxSerialConnection() {
41     delete m_dmx_channels_base;
42 }
43
44 ATMO_BOOL CAtmoDmxSerialConnection::OpenConnection() {
45 #if defined(_ATMO_VLC_PLUGIN_)
46      char *serdevice = m_pAtmoConfig->getSerialDevice();
47      if(!serdevice)
48         return ATMO_FALSE;
49 #else
50      int portNummer = m_pAtmoConfig->getComport();
51      m_dwLastWin32Error = 0;
52          if(portNummer < 1) return ATMO_FALSE; // make no real sense;-)
53 #endif
54
55      if(!m_dmx_channels_base)
56         return ATMO_FALSE;
57
58          CloseConnection();
59
60 #if !defined(_ATMO_VLC_PLUGIN_)
61      char serdevice[16];  // com4294967295
62      sprintf(serdevice,"com%d",portNummer);
63 #endif
64
65 #if defined(WIN32)
66
67      m_hComport = CreateFile(serdevice, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
68      if(m_hComport == INVALID_HANDLE_VALUE) {
69 //      we have a problem here can't open com port... somebody else may use it?
70 //          m_dwLastWin32Error = GetLastError();
71             return ATMO_FALSE;
72      }
73      /* change serial settings (Speed, stopbits etc.) */
74      DCB dcb; // für comport-parameter
75      dcb.DCBlength = sizeof(DCB);
76      GetCommState (m_hComport, &dcb); // ger current serialport settings
77      dcb.BaudRate  = 115200;        // set speed
78      dcb.ByteSize  = 8;            // set databits
79      dcb.Parity    = NOPARITY;     // set parity
80      dcb.StopBits  = ONESTOPBIT;   // set one stop bit
81      SetCommState (m_hComport, &dcb);    // apply settings
82
83 #else
84
85      int bconst = B115200;
86      m_hComport = open(serdevice, O_RDWR |O_NOCTTY);
87      if(m_hComport < 0) {
88             return ATMO_FALSE;
89      }
90
91      struct termios tio;
92      memset(&tio,0,sizeof(tio));
93      tio.c_cflag = (CS8 | CREAD | HUPCL | CLOCAL);
94      tio.c_iflag = (INPCK | BRKINT);
95      cfsetispeed(&tio, bconst);
96      cfsetospeed(&tio, bconst);
97      if(!tcsetattr(m_hComport, TCSANOW, &tio)) {
98          tcflush(m_hComport, TCIOFLUSH);
99      } else {
100          // can't change parms
101         close(m_hComport);
102         m_hComport = -1;
103         return false;
104      }
105
106 #endif
107
108      return true;
109 }
110
111 void CAtmoDmxSerialConnection::CloseConnection() {
112   if(m_hComport!=INVALID_HANDLE_VALUE) {
113 #if defined(WIN32)
114      CloseHandle(m_hComport);
115 #else
116      close(m_hComport);
117 #endif
118          m_hComport = INVALID_HANDLE_VALUE;
119   }
120 }
121
122 ATMO_BOOL CAtmoDmxSerialConnection::isOpen(void) {
123          return (m_hComport != INVALID_HANDLE_VALUE);
124 }
125
126 ATMO_BOOL CAtmoDmxSerialConnection::HardwareWhiteAdjust(int global_gamma,
127                                                      int global_contrast,
128                                                      int contrast_red,
129                                                      int contrast_green,
130                                                      int contrast_blue,
131                                                      int gamma_red,
132                                                      int gamma_green,
133                                                      int gamma_blue,
134                                                      ATMO_BOOL storeToEeprom) {
135             return ATMO_FALSE;
136 }
137
138
139 ATMO_BOOL CAtmoDmxSerialConnection::SendData(pColorPacket data) {
140    if(m_hComport == INVALID_HANDLE_VALUE)
141           return ATMO_FALSE;
142
143    int iBuffer = 2;
144    DWORD iBytesWritten;
145
146    Lock();
147
148    int idx, z = 0;
149
150    for(int i=0;i<getNumChannels();i++) {
151        if(m_ChannelAssignment && (i < m_NumAssignedChannels))
152          idx = m_ChannelAssignment[i];
153        else
154          idx = -1;
155
156        if((idx>=0) && (idx<data->numColors)) {
157           if( m_dmx_channels_base[z] >= 0 )
158               iBuffer = m_dmx_channels_base[z] + 2;
159           else
160               iBuffer += 3;
161
162           DMXout[iBuffer]   = data->zone[ idx ].r;
163           DMXout[iBuffer+1] = data->zone[ idx ].g;
164           DMXout[iBuffer+2] = data->zone[ idx ].b;
165        }
166
167        if( m_dmx_channels_base[z] >= 0 )
168           z++;
169    }
170
171 #if defined(WIN32)
172    WriteFile(m_hComport, DMXout, 259, &iBytesWritten, NULL); // send to COM-Port
173 #else
174    iBytesWritten = write(m_hComport, DMXout, 259);
175    tcdrain(m_hComport);
176 #endif
177    Unlock();
178
179    return (iBytesWritten == 259) ? ATMO_TRUE : ATMO_FALSE;
180 }
181
182
183 ATMO_BOOL CAtmoDmxSerialConnection::setChannelValues(int numValues,unsigned char *channel_values)
184 {
185         DWORD iBytesWritten;
186     if((numValues & 1) || !channel_values)
187        return ATMO_FALSE; // numValues must be even!
188
189     /*
190        the array shall contain
191     */
192
193         Lock();
194     int dmxIndex = 0;
195
196     for (int i = 0; i < numValues; i+=2) {
197          dmxIndex = ((int)channel_values[i]) + 2;
198          DMXout[dmxIndex] = channel_values[i+1];
199     }
200 #if defined(WIN32)
201         WriteFile(m_hComport, DMXout, 259, &iBytesWritten, NULL);
202 #else
203     iBytesWritten = write(m_hComport, DMXout, 259);
204     tcdrain(m_hComport);
205 #endif
206
207     Unlock();
208
209         return (iBytesWritten == 259) ? ATMO_TRUE : ATMO_FALSE;
210 }
211
212
213 ATMO_BOOL CAtmoDmxSerialConnection::setChannelColor(int channel, tRGBColor color)
214 {
215         DWORD iBytesWritten;
216         
217     Lock();
218
219     DMXout[channel+0+2]=color.r;
220         DMXout[channel+1+2]=color.g;
221         DMXout[channel+2+2]=color.b;
222
223 #if defined(WIN32)
224         WriteFile(m_hComport, DMXout, 259, &iBytesWritten, NULL);
225 #else
226     iBytesWritten = write(m_hComport, DMXout, 259);
227     tcdrain(m_hComport);
228 #endif
229
230
231     Unlock();
232
233         return (iBytesWritten == 259) ? ATMO_TRUE : ATMO_FALSE;
234 }
235
236 ATMO_BOOL CAtmoDmxSerialConnection::CreateDefaultMapping(CAtmoChannelAssignment *ca)
237 {
238     if(!ca) return ATMO_FALSE;
239     ca->setSize( getNumChannels() );
240     for(int i = 0; i < getNumChannels(); i++)
241         ca->setZoneIndex(i , i);
242     return ATMO_TRUE;
243 }
244
245 #if !defined(_ATMO_VLC_PLUGIN_)
246
247 char *CAtmoDmxSerialConnection::getChannelName(int ch)
248 {
249   if(ch < 0) return NULL;
250   char buf[30];
251
252   switch(ch) {
253       case 0:
254           sprintf(buf,"Summenkanal [%d]",ch);
255           break;
256       case 1:
257           sprintf(buf,"Linker Kanal [%d]",ch);
258           break;
259       case 2:
260           sprintf(buf,"Rechter Kanal [%d]",ch);
261           break;
262       case 3:
263           sprintf(buf,"Oberer Kanal [%d]",ch);
264           break;
265       case 4:
266           sprintf(buf,"Unterer Kanal [%d]",ch);
267           break;
268       default:
269           sprintf(buf,"Kanal [%d]",ch);
270           break;
271   }
272
273   return strdup(buf);
274 }
275
276 ATMO_BOOL CAtmoDmxSerialConnection::ShowConfigDialog(HINSTANCE hInst, HWND parent, CAtmoConfig *cfg)
277 {
278     CDmxConfigDialog *dlg = new CDmxConfigDialog(hInst, parent, cfg);
279
280     INT_PTR result = dlg->ShowModal();
281
282     delete dlg;
283
284     if(result == IDOK)
285       return ATMO_TRUE;
286     else
287       return ATMO_FALSE;
288 }
289
290 #endif
291
292
293 int CAtmoDmxSerialConnection::getNumChannels()
294 {
295     return m_pAtmoConfig->getDMX_RGB_Channels();
296 }
297