]> git.sesse.net Git - vlc/blob - modules/video_filter/atmo/AtmoMultiConnection.cpp
Use _WIN32 rather than WIN32 (same for WIN64)
[vlc] / modules / video_filter / atmo / AtmoMultiConnection.cpp
1 /*
2  * AtmoMultiConnection.cpp: Class for communication with up to 4 - 4 channel classic atmolight controllers
3  * so you can built a cheap solution for having up to 16 channels
4  *
5  * See the README.txt file for copyright information and how to reach the author(s).
6  *
7  * $Id$
8  */
9
10 #ifdef HAVE_CONFIG_H
11 # include "config.h"
12 #endif
13
14 #include "AtmoDefs.h"
15 #include "AtmoMultiConnection.h"
16
17 #if !defined(_ATMO_VLC_PLUGIN_)
18 #include "AtmoMultiConfigDialog.h"
19 #endif
20
21 #include <stdio.h>
22 #include <fcntl.h>
23
24 #if !defined(_WIN32)
25 #include <termios.h>
26 #include <unistd.h>
27 #endif
28
29
30
31 CAtmoMultiConnection::CAtmoMultiConnection(CAtmoConfig *cfg) : CAtmoConnection(cfg)
32 {
33    m_hComports[0] = INVALID_HANDLE_VALUE;
34    m_hComports[1] = INVALID_HANDLE_VALUE;
35    m_hComports[2] = INVALID_HANDLE_VALUE;
36    m_hComports[3] = INVALID_HANDLE_VALUE;
37    memset(&m_output, 0, sizeof(m_output));
38 }
39
40 CAtmoMultiConnection::~CAtmoMultiConnection(void)
41 {
42 }
43
44 HANDLE CAtmoMultiConnection::OpenDevice(char *devName)
45 {
46      HANDLE hComport;
47
48 #if !defined(_ATMO_VLC_PLUGIN_)
49      m_dwLastWin32Error = 0;
50 #endif
51
52 #if defined(_WIN32)
53      hComport = CreateFileA(devName, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
54      if(hComport == INVALID_HANDLE_VALUE) {
55 #if !defined(_ATMO_VLC_PLUGIN_)
56             m_dwLastWin32Error = GetLastError();
57 #endif
58             return INVALID_HANDLE_VALUE;
59      }
60      /* change serial settings (Speed, stopbits etc.) */
61      DCB dcb; // für comport-parameter
62      dcb.DCBlength = sizeof(DCB);
63      GetCommState (hComport, &dcb); // ger current serialport settings
64      dcb.BaudRate  = 38400;        // set speed
65      dcb.ByteSize  = 8;            // set databits
66      dcb.Parity    = NOPARITY;     // set parity
67      dcb.StopBits  = ONESTOPBIT;   // set one stop bit
68      SetCommState (hComport, &dcb);    // apply settings
69
70 #else
71
72      int bconst = B38400;
73      hComport = open(devName,O_RDWR |O_NOCTTY);
74      if(hComport < 0) {
75             return INVALID_HANDLE_VALUE;;
76      }
77      struct termios tio;
78      memset(&tio,0,sizeof(tio));
79      tio.c_cflag = (CS8 | CREAD | HUPCL | CLOCAL);
80      tio.c_iflag = (INPCK | BRKINT);
81      cfsetispeed(&tio, bconst);
82      cfsetospeed(&tio, bconst);
83      if(!tcsetattr(hComport, TCSANOW, &tio)) {
84          tcflush(hComport, TCIOFLUSH);
85      } else {
86          // can't change parms
87         close(hComport);
88         return INVALID_HANDLE_VALUE;
89      }
90 #endif
91
92      return hComport;
93 }
94
95 ATMO_BOOL CAtmoMultiConnection::OpenConnection()
96 {
97     int z = 0;
98 #if defined(_ATMO_VLC_PLUGIN_)
99
100     for(int c = 0; c < 4; c++ ) {
101         char *devName = m_pAtmoConfig->getSerialDevice( c );
102         if( !EMPTY_STR( devName ) )
103         {
104             m_hComports[z] = OpenDevice( devName );
105             if(m_hComports[z] == INVALID_HANDLE_VALUE) {
106                 while(z) {
107                       z--;
108 #if defined(_WIN32)
109                       CloseHandle( m_hComports[z] );
110 #else
111                       close( m_hComports[z] );
112 #endif
113                       m_hComports[z] = INVALID_HANDLE_VALUE;
114                 }
115                 return ATMO_FALSE;
116             }
117             z++;
118         }
119     }
120
121
122 #else
123
124     char devName[16];
125
126     for(int c = 0; c < 4; c++ ) {
127         int comportnr = m_pAtmoConfig->getComport(c);
128         if(comportnr > 0)
129         {
130             sprintf(devName,"com%d",comportnr);
131             m_hComports[z] = OpenDevice(devName);
132             if(m_hComports[z] == INVALID_HANDLE_VALUE) {
133                 while(z) {
134                       z--;
135                       CloseHandle( m_hComports[z] );
136                       m_hComports[z] = INVALID_HANDLE_VALUE;
137                 }
138                 return ATMO_FALSE;
139             }
140             z++;
141         }
142     }
143 #endif
144     return ATMO_TRUE;
145 }
146
147 void CAtmoMultiConnection::CloseConnection() {
148     for(int i = 0; i < 4; i++ ) {
149         if(m_hComports[i] != INVALID_HANDLE_VALUE) {
150 #if defined(_WIN32)
151            CloseHandle( m_hComports[i] );
152 #else
153            close( m_hComports[i] );
154 #endif
155                m_hComports[i] = INVALID_HANDLE_VALUE;
156         }
157     }
158 }
159
160 ATMO_BOOL CAtmoMultiConnection::isOpen(void) {
161      int z = 0;
162      for(int i = 0; i < 4; i++ )
163          if(m_hComports[i] != INVALID_HANDLE_VALUE) z++;
164
165          return (z > 0);
166 }
167
168 int CAtmoMultiConnection::getNumChannels()
169 {
170     int z = 0;
171 #if defined(_ATMO_VLC_PLUGIN_)
172     char *psz_dev;
173     for(int i=0;i<4;i++) {
174         psz_dev = m_pAtmoConfig->getSerialDevice( i );
175         if( !EMPTY_STR( psz_dev ) )
176             z+=4;
177     }
178 #else
179     for(int i=0;i<4;i++)
180         if(m_pAtmoConfig->getComport(i)>0)
181            z+=4;
182 #endif
183     return z;
184 }
185
186 ATMO_BOOL CAtmoMultiConnection::CreateDefaultMapping(CAtmoChannelAssignment *ca)
187 {
188   if(!ca) return ATMO_FALSE;
189   int z = getNumChannels();
190   ca->setSize( z );
191   // 1 : 1 mapping vorschlagen...
192   for(int i = 0; i < z ; i++ ) {
193       ca->setZoneIndex( i, i );
194   }
195   return ATMO_TRUE;
196 }
197
198
199 ATMO_BOOL CAtmoMultiConnection::internal_HardwareWhiteAdjust(HANDLE hComport,
200                                                      int global_gamma,
201                                                      int global_contrast,
202                                                      int contrast_red,
203                                                      int contrast_green,
204                                                      int contrast_blue,
205                                                      int gamma_red,
206                                                      int gamma_green,
207                                                      int gamma_blue,
208                                                      ATMO_BOOL storeToEeprom) {
209   if(hComport == INVALID_HANDLE_VALUE)
210      return ATMO_FALSE;
211
212      DWORD iBytesWritten;
213 /*
214 [0] = 255
215 [1] = 00
216 [2] = 00
217 [3] = 101
218
219 [4]  brightness  0..255 ?
220
221 [5]  Contrast Red     11 .. 100
222 [6]  Contrast  Green  11 .. 100
223 [7]  Contrast  Blue   11 .. 100
224
225 [8]   Gamma Red    11 .. 35
226 [9]   Gamma Red    11 .. 35
227 [10]  Gamma Red    11 .. 35
228
229 [11]  Globale Contrast  11 .. 100
230
231 [12]  Store Data: 199 (else 0)
232
233 */
234      unsigned char sendBuffer[16];
235      sendBuffer[0] = 0xFF;
236      sendBuffer[1] = 0x00;
237      sendBuffer[2] = 0x00;
238      sendBuffer[3] = 101;
239
240      sendBuffer[4] = (global_gamma & 255);
241
242      sendBuffer[5] = (contrast_red & 255);
243      sendBuffer[6] = (contrast_green & 255);
244      sendBuffer[7] = (contrast_blue & 255);
245
246      sendBuffer[8]  = (gamma_red & 255);
247      sendBuffer[9]  = (gamma_green & 255);
248      sendBuffer[10] = (gamma_blue & 255);
249
250      sendBuffer[11] = (global_contrast & 255);
251
252      if(storeToEeprom == ATMO_TRUE)
253         sendBuffer[12] = 199; // store to eeprom!
254      else
255         sendBuffer[12] = 0;
256
257 #if defined(_WIN32)
258      WriteFile(hComport, sendBuffer, 13, &iBytesWritten, NULL); // send to COM-Port
259 #else
260      iBytesWritten = write(hComport, sendBuffer, 13);
261      tcdrain(hComport);
262 #endif
263
264      return (iBytesWritten == 13) ? ATMO_TRUE : ATMO_FALSE;
265 }
266
267
268 ATMO_BOOL CAtmoMultiConnection::HardwareWhiteAdjust( int global_gamma,
269                                                      int global_contrast,
270                                                      int contrast_red,
271                                                      int contrast_green,
272                                                      int contrast_blue,
273                                                      int gamma_red,
274                                                      int gamma_green,
275                                                      int gamma_blue,
276                                                      ATMO_BOOL storeToEeprom)
277 {
278     for(int z = 0 ; z < 4; z++ ) {
279         if(m_hComports[z]!= INVALID_HANDLE_VALUE)
280            if(internal_HardwareWhiteAdjust(m_hComports[z], global_gamma, global_contrast,
281                                            contrast_red, contrast_green, contrast_blue,
282                                            gamma_red, gamma_green, gamma_blue,
283                                            storeToEeprom) == ATMO_FALSE)
284                                                 return ATMO_FALSE;
285     }
286     return ATMO_TRUE;
287 }
288
289 ATMO_BOOL CAtmoMultiConnection::internal_SendData(HANDLE hComport, unsigned char *colorData)
290 {
291  if(m_hComports[0] == INVALID_HANDLE_VALUE)
292     return ATMO_FALSE;
293
294   unsigned char buffer[19];
295   DWORD iBytesWritten;
296
297   buffer[0] = 0xFF;  // Start Byte
298   buffer[1] = 0x00;  // Start channel 0
299   buffer[2] = 0x00;  // Start channel 0
300   buffer[3] = 15; //
301   buffer[4] = 0; // Summe Red
302   buffer[5] = 0; // Summe Green
303   buffer[6] = 0; // Summe Blue
304   memcpy(&buffer[7], colorData, 4 * 3);
305
306 #if defined(_WIN32)
307    WriteFile(hComport, buffer, 19, &iBytesWritten, NULL); // send to COM-Port
308 #else
309    iBytesWritten = write(hComport, buffer, 19);
310    tcdrain(hComport);
311 #endif
312
313  return (iBytesWritten == 19) ? ATMO_TRUE : ATMO_FALSE;
314 }
315
316 ATMO_BOOL CAtmoMultiConnection::SendData(pColorPacket data)
317 {
318    if(m_hComports[0] == INVALID_HANDLE_VALUE)
319           return ATMO_FALSE;
320
321    int numChannels = this->getNumChannels();
322
323    int idx;
324    int iBuffer = 0;
325    ATMO_BOOL result = ATMO_TRUE;
326
327    Lock();
328
329    for(int i = 0; i < numChannels ; i++) {
330        if(m_ChannelAssignment && (i < m_NumAssignedChannels))
331           idx = m_ChannelAssignment[i];
332        else
333           idx = -1;
334        if((idx>=0) && (idx<data->numColors)) {
335           m_output[iBuffer] = data->zone[idx].r;
336           m_output[iBuffer+1] = data->zone[idx].g;
337           m_output[iBuffer+2] = data->zone[idx].b;
338        }
339        iBuffer+=3;
340    }
341    for(int i = 0;i < 4; i++)
342        if(m_hComports[i] != INVALID_HANDLE_VALUE)
343           result = result & internal_SendData(m_hComports[i], &m_output[i*4*3]);
344
345    Unlock();
346
347    return result;
348 }
349
350 ATMO_BOOL CAtmoMultiConnection::setChannelColor(int channel, tRGBColor color)
351 {
352    if(m_hComports[0] == INVALID_HANDLE_VALUE)
353           return ATMO_FALSE;
354    if((channel < 0) || (channel >= getNumChannels()))
355       return ATMO_FALSE;
356
357    ATMO_BOOL result = ATMO_TRUE;
358
359    Lock();
360    channel*=3;
361    m_output[channel++] = color.r;
362    m_output[channel++] = color.g;
363    m_output[channel]   = color.b;
364    for(int i = 0; i < 4; i++)
365        if(m_hComports[i] != INVALID_HANDLE_VALUE)
366           result = result & internal_SendData(m_hComports[i], &m_output[i*4*3]);
367    Unlock();
368
369    return result;
370 }
371
372 ATMO_BOOL CAtmoMultiConnection::setChannelValues(int numValues,unsigned char *channel_values)
373 {
374   if(m_hComports[0] == INVALID_HANDLE_VALUE)
375      return ATMO_FALSE;
376
377   if((numValues & 1) || !channel_values)
378      return ATMO_FALSE; // numValues must be even!
379
380   ATMO_BOOL result = ATMO_TRUE;
381
382
383   Lock();
384   size_t Index = 0;
385   for (int i = 0; i < numValues; i+=2) {
386        Index = (size_t)channel_values[i];
387        if(Index < sizeof(m_output))
388           m_output[Index] = channel_values[i + 1];
389   }
390   for(int i = 0; i < 4; i++)
391       if(m_hComports[i] != INVALID_HANDLE_VALUE)
392          result = result & internal_SendData(m_hComports[i], &m_output[i*4*3]);
393
394   Unlock();
395   return result;
396 }
397
398 #if !defined(_ATMO_VLC_PLUGIN_)
399
400 char *CAtmoMultiConnection::getChannelName(int ch)
401 {
402   int devnum = ch / 4;
403   int kanal  = ch % 4;
404   char buf[60];
405   switch(kanal) {
406          case 0: {
407                    sprintf(buf,"Atmo[%d.%d] Links (%d)", devnum, kanal, ch);
408                    break;
409                  }
410          case 1: {
411                    sprintf(buf,"Atmo[%d.%d] Rechts (%d)", devnum, kanal, ch);
412                    break;
413                  }
414          case 2: {
415                    sprintf(buf,"Atmo[%d.%d] Oben (%d)", devnum, kanal, ch);
416                    break;
417                  }
418          case 3: {
419                    sprintf(buf,"Atmo[%d.%d] Unten (%d)", devnum, kanal, ch);
420                    break;
421                  }
422   }
423   return strdup(buf);
424 }
425
426 ATMO_BOOL CAtmoMultiConnection::ShowConfigDialog(HINSTANCE hInst, HWND parent, CAtmoConfig *cfg)
427 {
428     CAtmoMultiConfigDialog *dlg = new CAtmoMultiConfigDialog(hInst, parent, cfg);
429
430     INT_PTR result = dlg->ShowModal();
431
432     delete dlg;
433
434     if(result == IDOK)
435       return ATMO_TRUE;
436     else
437       return ATMO_FALSE;
438 }
439
440 #endif
441