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