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
5 * See the README.txt file for copyright information and how to reach the author(s).
11 #include "AtmoMultiConnection.h"
13 #if !defined(_ATMO_VLC_PLUGIN_)
14 #include "AtmoMultiConfigDialog.h"
27 CAtmoMultiConnection::CAtmoMultiConnection(CAtmoConfig *cfg) : CAtmoConnection(cfg)
29 m_hComports[0] = INVALID_HANDLE_VALUE;
30 m_hComports[1] = INVALID_HANDLE_VALUE;
31 m_hComports[2] = INVALID_HANDLE_VALUE;
32 m_hComports[3] = INVALID_HANDLE_VALUE;
33 memset(&m_output, 0, sizeof(m_output));
36 CAtmoMultiConnection::~CAtmoMultiConnection(void)
40 HANDLE CAtmoMultiConnection::OpenDevice(char *devName)
44 #if !defined(_ATMO_VLC_PLUGIN_)
45 m_dwLastWin32Error = 0;
49 hComport = CreateFile(devName, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
50 if(hComport == INVALID_HANDLE_VALUE) {
51 #if !defined(_ATMO_VLC_PLUGIN_)
52 m_dwLastWin32Error = GetLastError();
54 return INVALID_HANDLE_VALUE;
56 /* change serial settings (Speed, stopbits etc.) */
57 DCB dcb; // für comport-parameter
58 dcb.DCBlength = sizeof(DCB);
59 GetCommState (hComport, &dcb); // ger current serialport settings
60 dcb.BaudRate = 38400; // set speed
61 dcb.ByteSize = 8; // set databits
62 dcb.Parity = NOPARITY; // set parity
63 dcb.StopBits = ONESTOPBIT; // set one stop bit
64 SetCommState (hComport, &dcb); // apply settings
69 hComport = open(devName,O_RDWR |O_NOCTTY);
71 return INVALID_HANDLE_VALUE;;
74 memset(&tio,0,sizeof(tio));
75 tio.c_cflag = (CS8 | CREAD | HUPCL | CLOCAL);
76 tio.c_iflag = (INPCK | BRKINT);
77 cfsetispeed(&tio, bconst);
78 cfsetospeed(&tio, bconst);
79 if(!tcsetattr(hComport, TCSANOW, &tio)) {
80 tcflush(hComport, TCIOFLUSH);
84 return INVALID_HANDLE_VALUE;
91 ATMO_BOOL CAtmoMultiConnection::OpenConnection()
94 #if defined(_ATMO_VLC_PLUGIN_)
96 for(int c = 0; c < 4; c++ ) {
97 char *devName = m_pAtmoConfig->getSerialDevice( c );
98 if( devName && strlen(devName) > 0 )
100 m_hComports[z] = OpenDevice( devName );
101 if(m_hComports[z] == INVALID_HANDLE_VALUE) {
105 CloseHandle( m_hComports[z] );
107 close( m_hComports[z] );
109 m_hComports[z] = INVALID_HANDLE_VALUE;
122 for(int c = 0; c < 4; c++ ) {
123 int comportnr = m_pAtmoConfig->getComport(c);
126 sprintf(devName,"com%d",comportnr);
127 m_hComports[z] = OpenDevice(devName);
128 if(m_hComports[z] == INVALID_HANDLE_VALUE) {
131 CloseHandle( m_hComports[z] );
132 m_hComports[z] = INVALID_HANDLE_VALUE;
143 void CAtmoMultiConnection::CloseConnection() {
144 for(int i = 0; i < 4; i++ ) {
145 if(m_hComports[i] != INVALID_HANDLE_VALUE) {
147 CloseHandle( m_hComports[i] );
149 close( m_hComports[i] );
151 m_hComports[i] = INVALID_HANDLE_VALUE;
156 ATMO_BOOL CAtmoMultiConnection::isOpen(void) {
158 for(int i = 0; i < 4; i++ )
159 if(m_hComports[i] != INVALID_HANDLE_VALUE) z++;
164 int CAtmoMultiConnection::getNumChannels()
167 #if defined(_ATMO_VLC_PLUGIN_)
169 for(int i=0;i<4;i++) {
170 psz_dev = m_pAtmoConfig->getSerialDevice( i );
171 if( psz_dev && strlen( psz_dev ) > 0 )
176 if(m_pAtmoConfig->getComport(i)>0)
182 ATMO_BOOL CAtmoMultiConnection::CreateDefaultMapping(CAtmoChannelAssignment *ca)
184 if(!ca) return ATMO_FALSE;
185 int z = getNumChannels();
187 // 1 : 1 mapping vorschlagen...
188 for(int i = 0; i < z ; i++ ) {
189 ca->setZoneIndex( i, i );
195 ATMO_BOOL CAtmoMultiConnection::internal_HardwareWhiteAdjust(HANDLE hComport,
204 ATMO_BOOL storeToEeprom) {
205 if(hComport == INVALID_HANDLE_VALUE)
215 [4] brightness 0..255 ?
217 [5] Contrast Red 11 .. 100
218 [6] Contrast Green 11 .. 100
219 [7] Contrast Blue 11 .. 100
221 [8] Gamma Red 11 .. 35
222 [9] Gamma Red 11 .. 35
223 [10] Gamma Red 11 .. 35
225 [11] Globale Contrast 11 .. 100
227 [12] Store Data: 199 (else 0)
230 unsigned char sendBuffer[16];
231 sendBuffer[0] = 0xFF;
232 sendBuffer[1] = 0x00;
233 sendBuffer[2] = 0x00;
236 sendBuffer[4] = (global_gamma & 255);
238 sendBuffer[5] = (contrast_red & 255);
239 sendBuffer[6] = (contrast_green & 255);
240 sendBuffer[7] = (contrast_blue & 255);
242 sendBuffer[8] = (gamma_red & 255);
243 sendBuffer[9] = (gamma_green & 255);
244 sendBuffer[10] = (gamma_blue & 255);
246 sendBuffer[11] = (global_contrast & 255);
248 if(storeToEeprom == ATMO_TRUE)
249 sendBuffer[12] = 199; // store to eeprom!
254 WriteFile(hComport, sendBuffer, 13, &iBytesWritten, NULL); // send to COM-Port
256 iBytesWritten = write(hComport, sendBuffer, 13);
260 return (iBytesWritten == 13) ? ATMO_TRUE : ATMO_FALSE;
264 ATMO_BOOL CAtmoMultiConnection::HardwareWhiteAdjust( int global_gamma,
272 ATMO_BOOL storeToEeprom)
274 for(int z = 0 ; z < 4; z++ ) {
275 if(m_hComports[z]!= INVALID_HANDLE_VALUE)
276 if(internal_HardwareWhiteAdjust(m_hComports[z], global_gamma, global_contrast,
277 contrast_red, contrast_green, contrast_blue,
278 gamma_red, gamma_green, gamma_blue,
279 storeToEeprom) == ATMO_FALSE)
285 ATMO_BOOL CAtmoMultiConnection::internal_SendData(HANDLE hComport, unsigned char *colorData)
287 if(m_hComports[0] == INVALID_HANDLE_VALUE)
290 unsigned char buffer[19];
293 buffer[0] = 0xFF; // Start Byte
294 buffer[1] = 0x00; // Start channel 0
295 buffer[2] = 0x00; // Start channel 0
297 buffer[4] = 0; // Summe Red
298 buffer[5] = 0; // Summe Green
299 buffer[6] = 0; // Summe Blue
300 memcpy(&buffer[7], colorData, 4 * 3);
303 WriteFile(hComport, buffer, 19, &iBytesWritten, NULL); // send to COM-Port
305 iBytesWritten = write(hComport, buffer, 19);
309 return (iBytesWritten == 19) ? ATMO_TRUE : ATMO_FALSE;
312 ATMO_BOOL CAtmoMultiConnection::SendData(pColorPacket data)
314 if(m_hComports[0] == INVALID_HANDLE_VALUE)
317 int numChannels = this->getNumChannels();
321 ATMO_BOOL result = ATMO_TRUE;
325 for(int i = 0; i < numChannels ; i++) {
326 if(m_ChannelAssignment && (i < m_NumAssignedChannels))
327 idx = m_ChannelAssignment[i];
330 if((idx>=0) && (idx<data->numColors)) {
331 m_output[iBuffer] = data->zone[idx].r;
332 m_output[iBuffer+1] = data->zone[idx].g;
333 m_output[iBuffer+2] = data->zone[idx].b;
337 for(int i = 0;i < 4; i++)
338 if(m_hComports[i] != INVALID_HANDLE_VALUE)
339 result = result & internal_SendData(m_hComports[i], &m_output[i*4*3]);
346 ATMO_BOOL CAtmoMultiConnection::setChannelColor(int channel, tRGBColor color)
348 if(m_hComports[0] == INVALID_HANDLE_VALUE)
350 if((channel < 0) || (channel >= getNumChannels()))
353 ATMO_BOOL result = ATMO_TRUE;
357 m_output[channel++] = color.r;
358 m_output[channel++] = color.g;
359 m_output[channel] = color.b;
360 for(int i = 0; i < 4; i++)
361 if(m_hComports[i] != INVALID_HANDLE_VALUE)
362 result = result & internal_SendData(m_hComports[i], &m_output[i*4*3]);
368 ATMO_BOOL CAtmoMultiConnection::setChannelValues(int numValues,unsigned char *channel_values)
370 if(m_hComports[0] == INVALID_HANDLE_VALUE)
373 if((numValues & 1) || !channel_values)
374 return ATMO_FALSE; // numValues must be even!
376 ATMO_BOOL result = ATMO_TRUE;
381 for (int i = 0; i < numValues; i+=2) {
382 Index = (int)channel_values[i];
383 if(Index < sizeof(m_output))
384 m_output[Index] = channel_values[i + 1];
386 for(int i = 0; i < 4; i++)
387 if(m_hComports[i] != INVALID_HANDLE_VALUE)
388 result = result & internal_SendData(m_hComports[i], &m_output[i*4*3]);
394 #if !defined(_ATMO_VLC_PLUGIN_)
396 char *CAtmoMultiConnection::getChannelName(int ch)
403 sprintf(buf,"Atmo[%d.%d] Links (%d)", devnum, kanal, ch);
407 sprintf(buf,"Atmo[%d.%d] Rechts (%d)", devnum, kanal, ch);
411 sprintf(buf,"Atmo[%d.%d] Oben (%d)", devnum, kanal, ch);
415 sprintf(buf,"Atmo[%d.%d] Unten (%d)", devnum, kanal, ch);
422 ATMO_BOOL CAtmoMultiConnection::ShowConfigDialog(HINSTANCE hInst, HWND parent, CAtmoConfig *cfg)
424 CAtmoMultiConfigDialog *dlg = new CAtmoMultiConfigDialog(hInst, parent, cfg);
426 INT_PTR result = dlg->ShowModal();