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).
15 #include "AtmoMultiConnection.h"
17 #if !defined(_ATMO_VLC_PLUGIN_)
18 #include "AtmoMultiConfigDialog.h"
31 CAtmoMultiConnection::CAtmoMultiConnection(CAtmoConfig *cfg) : CAtmoConnection(cfg)
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));
40 CAtmoMultiConnection::~CAtmoMultiConnection(void)
44 HANDLE CAtmoMultiConnection::OpenDevice(char *devName)
48 #if !defined(_ATMO_VLC_PLUGIN_)
49 m_dwLastWin32Error = 0;
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();
58 return INVALID_HANDLE_VALUE;
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
73 hComport = open(devName,O_RDWR |O_NOCTTY);
75 return INVALID_HANDLE_VALUE;;
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);
88 return INVALID_HANDLE_VALUE;
95 ATMO_BOOL CAtmoMultiConnection::OpenConnection()
98 #if defined(_ATMO_VLC_PLUGIN_)
100 for(int c = 0; c < 4; c++ ) {
101 char *devName = m_pAtmoConfig->getSerialDevice( c );
102 if( !EMPTY_STR( devName ) )
104 m_hComports[z] = OpenDevice( devName );
105 if(m_hComports[z] == INVALID_HANDLE_VALUE) {
109 CloseHandle( m_hComports[z] );
111 close( m_hComports[z] );
113 m_hComports[z] = INVALID_HANDLE_VALUE;
126 for(int c = 0; c < 4; c++ ) {
127 int comportnr = m_pAtmoConfig->getComport(c);
130 sprintf(devName,"com%d",comportnr);
131 m_hComports[z] = OpenDevice(devName);
132 if(m_hComports[z] == INVALID_HANDLE_VALUE) {
135 CloseHandle( m_hComports[z] );
136 m_hComports[z] = INVALID_HANDLE_VALUE;
147 void CAtmoMultiConnection::CloseConnection() {
148 for(int i = 0; i < 4; i++ ) {
149 if(m_hComports[i] != INVALID_HANDLE_VALUE) {
151 CloseHandle( m_hComports[i] );
153 close( m_hComports[i] );
155 m_hComports[i] = INVALID_HANDLE_VALUE;
160 ATMO_BOOL CAtmoMultiConnection::isOpen(void) {
162 for(int i = 0; i < 4; i++ )
163 if(m_hComports[i] != INVALID_HANDLE_VALUE) z++;
168 int CAtmoMultiConnection::getNumChannels()
171 #if defined(_ATMO_VLC_PLUGIN_)
173 for(int i=0;i<4;i++) {
174 psz_dev = m_pAtmoConfig->getSerialDevice( i );
175 if( !EMPTY_STR( psz_dev ) )
180 if(m_pAtmoConfig->getComport(i)>0)
186 ATMO_BOOL CAtmoMultiConnection::CreateDefaultMapping(CAtmoChannelAssignment *ca)
188 if(!ca) return ATMO_FALSE;
189 int z = getNumChannels();
191 // 1 : 1 mapping vorschlagen...
192 for(int i = 0; i < z ; i++ ) {
193 ca->setZoneIndex( i, i );
199 ATMO_BOOL CAtmoMultiConnection::internal_HardwareWhiteAdjust(HANDLE hComport,
208 ATMO_BOOL storeToEeprom) {
209 if(hComport == INVALID_HANDLE_VALUE)
219 [4] brightness 0..255 ?
221 [5] Contrast Red 11 .. 100
222 [6] Contrast Green 11 .. 100
223 [7] Contrast Blue 11 .. 100
225 [8] Gamma Red 11 .. 35
226 [9] Gamma Red 11 .. 35
227 [10] Gamma Red 11 .. 35
229 [11] Globale Contrast 11 .. 100
231 [12] Store Data: 199 (else 0)
234 unsigned char sendBuffer[16];
235 sendBuffer[0] = 0xFF;
236 sendBuffer[1] = 0x00;
237 sendBuffer[2] = 0x00;
240 sendBuffer[4] = (global_gamma & 255);
242 sendBuffer[5] = (contrast_red & 255);
243 sendBuffer[6] = (contrast_green & 255);
244 sendBuffer[7] = (contrast_blue & 255);
246 sendBuffer[8] = (gamma_red & 255);
247 sendBuffer[9] = (gamma_green & 255);
248 sendBuffer[10] = (gamma_blue & 255);
250 sendBuffer[11] = (global_contrast & 255);
252 if(storeToEeprom == ATMO_TRUE)
253 sendBuffer[12] = 199; // store to eeprom!
258 WriteFile(hComport, sendBuffer, 13, &iBytesWritten, NULL); // send to COM-Port
260 iBytesWritten = write(hComport, sendBuffer, 13);
264 return (iBytesWritten == 13) ? ATMO_TRUE : ATMO_FALSE;
268 ATMO_BOOL CAtmoMultiConnection::HardwareWhiteAdjust( int global_gamma,
276 ATMO_BOOL storeToEeprom)
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)
289 ATMO_BOOL CAtmoMultiConnection::internal_SendData(HANDLE hComport, unsigned char *colorData)
291 if(m_hComports[0] == INVALID_HANDLE_VALUE)
294 unsigned char buffer[19];
297 buffer[0] = 0xFF; // Start Byte
298 buffer[1] = 0x00; // Start channel 0
299 buffer[2] = 0x00; // Start channel 0
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);
307 WriteFile(hComport, buffer, 19, &iBytesWritten, NULL); // send to COM-Port
309 iBytesWritten = write(hComport, buffer, 19);
313 return (iBytesWritten == 19) ? ATMO_TRUE : ATMO_FALSE;
316 ATMO_BOOL CAtmoMultiConnection::SendData(pColorPacket data)
318 if(m_hComports[0] == INVALID_HANDLE_VALUE)
321 int numChannels = this->getNumChannels();
325 ATMO_BOOL result = ATMO_TRUE;
329 for(int i = 0; i < numChannels ; i++) {
330 if(m_ChannelAssignment && (i < m_NumAssignedChannels))
331 idx = m_ChannelAssignment[i];
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;
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]);
350 ATMO_BOOL CAtmoMultiConnection::setChannelColor(int channel, tRGBColor color)
352 if(m_hComports[0] == INVALID_HANDLE_VALUE)
354 if((channel < 0) || (channel >= getNumChannels()))
357 ATMO_BOOL result = ATMO_TRUE;
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]);
372 ATMO_BOOL CAtmoMultiConnection::setChannelValues(int numValues,unsigned char *channel_values)
374 if(m_hComports[0] == INVALID_HANDLE_VALUE)
377 if((numValues & 1) || !channel_values)
378 return ATMO_FALSE; // numValues must be even!
380 ATMO_BOOL result = ATMO_TRUE;
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];
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]);
398 #if !defined(_ATMO_VLC_PLUGIN_)
400 char *CAtmoMultiConnection::getChannelName(int ch)
407 sprintf(buf,"Atmo[%d.%d] Links (%d)", devnum, kanal, ch);
411 sprintf(buf,"Atmo[%d.%d] Rechts (%d)", devnum, kanal, ch);
415 sprintf(buf,"Atmo[%d.%d] Oben (%d)", devnum, kanal, ch);
419 sprintf(buf,"Atmo[%d.%d] Unten (%d)", devnum, kanal, ch);
426 ATMO_BOOL CAtmoMultiConnection::ShowConfigDialog(HINSTANCE hInst, HWND parent, CAtmoConfig *cfg)
428 CAtmoMultiConfigDialog *dlg = new CAtmoMultiConfigDialog(hInst, parent, cfg);
430 INT_PTR result = dlg->ShowModal();