REKLAMA

winlirc-0.6.5.zip

Jak odblokować USB w LG 37LH3000 do oglądania zdjęć i filmów?

Witam kolegów. Zakupiłem ten telewizor znając ten temat i w co można ten telewizor przerobić :) Chciałem też uniknąć zmiany firmware'u więc postanowiłem zrobić sobie samemu pilot serwisowy (bo nie mam palmtopa oraz smartfona aby emulować pilota). Ściągnąłem sobie program WinLIRC 0.6.5 (jest w załączniku) oraz chciałem skonstruować układ do nadawania IR. Znalazłem układ: http://obrazki.elektroda.net/48_1261251444.jpg Widok złącza RS-232 jest to widok złącza żeńskiego w laptopie (jakbyśmy na niego patrzyli). Ale wziąłem stary pilot od jakiegoś telewizora Sanyo gdzie układ diody, rezystora w kolektorze i diody IR jest tam identyczny (pewnie w każdym pilocie TV tak jest) więc tylko podpiąłem się do bazy i emitera owego tranzystora (oczywiście w obwód bazy wrzuciłem diodę i rezystor 3,3k - bo nie miałem 4,7k jak w schemacie). http://obrazki.elektroda.net/9_1261251637.jpg A więc wychodziły z pilota 2 kabelki które podłączyłem do portu RS w laptopie (sygnały GND oraz DTR). Na zdjęciu kabelki wchodzą w dziwne miejsca w złącze RS-232 ale tylko dlatego bo tam był jakiś przeplot, więc sugerujcie się schematem a nie moim zdjęciem. Po podłączeniu do komputera powinniście mieć napięcie między DTR-GND ok -5,2V (ujemne). Dalej włożyłem baterie do pilota (2 paluszki) i do roboty. Uruchomiłem program WinLirc i skonfigurowałem go następująco: http://obrazki.elektroda.net/39_1261251863.jpg http://obrazki.elektroda.net/35_1261251880.jpg Jak widzicie na 1 zdjęciu jest wybrany plik LG.cf (dałem go w załączniku) - jest to plik definiujący nasz pilot serwisowy. Sama emisja sygnału okazała się nieco dziwna. Jednokrotne naciśnięcie przycisku "Send" nie uruchamia menu serwisowego. Okazuje się, że trzeba 2 albo 3 razy szybko pod rząd go nacisnąć (zmiana opcji repeat nic nie daje). A dalej to już tak jak w opisach panów którzy się wypowiadali, np. TU. Jeśli chcecie zobaczyć czy sam pilot nadaje to taka sztuczka: uruchomcie tryb robienia zdjęcia w swoim telefonie komórkowym i gdy będziecie się patrzeć na pilot to przy jego naciskaniu będzie widać jak dioda miga.


Pobierz plik - link do postu
  • winlirc-0.6.5.zip
    • trayicon.cpp
    • l_ok.ico
    • l_recv.ico
    • irconfig.h
    • learndlg.cpp
    • drvdlg.h
    • sample.cf
    • confdlg.cpp
    • winlirc.dsp
    • transmit.cpp
    • changes.txt
    • COPYING
    • dumpcfg.cpp
    • server.h
    • remote.h
    • README
    • globals.cpp
    • winlirc.h
    • irconfig.cpp
    • config.h
    • trayicon.h
    • l_error.ico
    • winlirc.cpp
    • globals.h
    • version.h
    • stdafx.h
    • confdlg.h
    • learndlg.h
    • l_send.ico
    • winlirc.dsw
    • server.cpp
    • remote.cpp
    • config.cpp
    • l_init.ico
    • resource.h
    • lirc.ico
    • dumpcfg.h
    • drvdlg.cpp
    • winlirc.exe
    • winlirc.rc
    • irdriver.h
    • irdriver.cpp


winlirc-0.6.5.zip > stdafx.h

/*
* This file is part of the WinLIRC package, which was derived from
* LIRC (Linux Infrared Remote Control) 0.5.4pre9.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published
* by the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* Copyright (C) 1999 Jim Paris & lt; jim@jtan.com & gt;
*/

#if !defined(AFX_STDAFX_H__4011A5C9_ABBE_11D2_8C7F_004005637418__INCLUDED_)
#define AFX_STDAFX_H__4011A5C9_ABBE_11D2_8C7F_004005637418__INCLUDED_

#if _MSC_VER & gt; = 1000
#pragma once
#endif // _MSC_VER & gt; = 1000

#define VC_EXTRALEAN // Exclude rarely-used stuff from Windows headers

#include & lt; afxwin.h & gt; // MFC core and standard components
#include & lt; afxext.h & gt; // MFC extensions
#include & lt; afxmt.h & gt; // Multithreading
#ifndef _AFX_NO_AFXCMN_SUPPORT
#include & lt; afxcmn.h & gt; // MFC support for Windows Common Controls
#endif // _AFX_NO_AFXCMN_SUPPORT

#include & lt; winsock2.h & gt; // winsock 2
#include & lt; afxsock.h & gt; // MFC socket extensions

//{{AFX_INSERT_LOCATION}}
// Microsoft Developer Studio will insert additional declarations immediately before the previous line.

#endif // !defined(AFX_STDAFX_H__4011A5C9_ABBE_11D2_8C7F_004005637418__INCLUDED_)


winlirc-0.6.5.zip > trayicon.cpp

/*
* This file is part of the WinLIRC package, which was derived from
* LIRC (Linux Infrared Remote Control) 0.5.4pre9.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published
* by the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* Derived from published code by Paul DiLascia.
* Copyright (C) 1999 Jim Paris & lt; jim@jtan.com & gt;
* RX device, some other stuff Copyright (C) 2002 Alexander Nesterovsky & lt; Nsky@users.sourceforge.net & gt;
*/

#include " stdafx.h "
#include & lt; afxpriv.h & gt;
#include " trayicon.h "
#include " winlirc.h "

IMPLEMENT_DYNAMIC(CTrayIcon, CCmdTarget)

CTrayIcon::CTrayIcon(unsigned int uID)
{
memset( & icondata,0,sizeof(icondata));
icondata.cbSize=sizeof(icondata);
icondata.uID=uID;
AfxLoadString(uID,icondata.szTip,sizeof(icondata.szTip));
}

CTrayIcon::~CTrayIcon()
{
SetIcon(0);
}

void CTrayIcon::SetNotificationWnd(CWnd *notifywnd, unsigned int message)
{
if(notifywnd!=NULL & & !::IsWindow(notifywnd- & gt; GetSafeHwnd()))
{
DEBUG( " Invalid window\n " );
return;
}

icondata.hWnd=notifywnd- & gt; GetSafeHwnd();

if(message!=0 & & message & lt; WM_USER)
{
DEBUG( " Invalid message\n " );
message=0;
}
icondata.uCallbackMessage=message;
}

bool CTrayIcon::SetIcon(unsigned int uID)
{
HICON icon=NULL;
if(uID)
{
AfxLoadString(uID,icondata.szTip,sizeof(icondata.szTip));
icon=AfxGetApp()- & gt; LoadIcon(uID);
}
return SetIcon(icon,NULL);
}

bool CTrayIcon::SetIcon(HICON icon, const char *tip)
{
unsigned int msg;
icondata.uFlags=0;

if(icon)
{
if (notrayicon) return true;
if(icondata.hIcon) msg=NIM_MODIFY;
else msg=NIM_ADD;
icondata.hIcon=icon;
icondata.uFlags|=NIF_ICON;
}
else
{
if(icondata.hIcon==NULL)
return true;
msg=NIM_DELETE;
}

if(tip)
strncpy(icondata.szTip,tip,sizeof(icondata.szTip));
if(*icondata.szTip)
icondata.uFlags|=NIF_TIP;

if(icondata.uCallbackMessage & & icondata.hWnd)
icondata.uFlags|=NIF_MESSAGE;

int ret=Shell_NotifyIcon(msg, & icondata);
if(msg==NIM_DELETE || !ret)
icondata.hIcon=NULL;
return (ret==TRUE);
}

LRESULT CTrayIcon::OnTrayNotification(WPARAM id, LPARAM event)
{
if(id!=icondata.uID || (event!=WM_RBUTTONUP & & event!=WM_LBUTTONDBLCLK))
return 0;

// resource menu with same ID as icon will be used as popup menu
CMenu menu;
if(!menu.LoadMenu(icondata.uID)) return 0;
CMenu *submenu=menu.GetSubMenu(0);
if(!submenu)
return 0;

if(event==WM_RBUTTONUP)
{
::SetMenuDefaultItem(submenu- & gt; m_hMenu,0,true);
CPoint mouse;
GetCursorPos( & mouse);
::SetForegroundWindow(icondata.hWnd);
::TrackPopupMenu(submenu- & gt; m_hMenu,0,mouse.x,mouse.y,0,icondata.hWnd,NULL);
}
else
{
::SendMessage(icondata.hWnd,WM_COMMAND,submenu- & gt; GetMenuItemID(0),0);
}

return 1;
}

bool CTrayIcon::SetStandardIcon(const char *iconname, const char *tip)
{
return SetIcon(::LoadIcon(NULL,iconname),tip);
}

bool CTrayIcon::SetIcon(const char *resname, const char *tip)
{
return SetIcon(resname?AfxGetApp()- & gt; LoadIcon(resname):NULL,tip);
}


winlirc-0.6.5.zip > irconfig.h

/*
* This file is part of the WinLIRC package, which was derived from
* LIRC (Linux Infrared Remote Control) 0.5.4pre9.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published
* by the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* Copyright (C) 1999 Jim Paris & lt; jim@jtan.com & gt;
* RX device, some other stuff Copyright (C) 2002 Alexander Nesterovsky & lt; Nsky@users.sourceforge.net & gt;
*/

#ifndef IRCONFIG_H
#define IRCONFIG_H

#include " globals.h "

#include " stdafx.h "
#include " irdriver.h "

class CIRConfig {
public:
CString port;
int sense;
BOOL animax;
CString conf;

unsigned transmittertype;
unsigned long speed;
unsigned long devicetype;
unsigned long notrayicon;
unsigned long virtpulse;

CIRConfig();
~CIRConfig();

bool ReadConfig(CIRDriver *driver);
bool WriteConfig(void);
};

#endif


winlirc-0.6.5.zip > learndlg.cpp

/*
* This file is part of the WinLIRC package, which was derived from
* LIRC (Linux Infrared Remote Control) 0.5.4pre9.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published
* by the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* Copyright (C) 1998,99 Christoph Bartelmus & lt; columbus@hit.handshake.de & gt;
* Copyright (C) 1999 Jim Paris & lt; jim@jtan.com & gt;
*/

#include " stdafx.h "
#include " winlirc.h "
#include " learndlg.h "
#include & lt; sys/types.h & gt;
#include & lt; string.h & gt;
#include " dumpcfg.h "
#include " config.h "
#include " remote.h "

#ifndef min
#define min(a,b) (a & gt; b ? b:a)
#endif
#ifndef max
#define max(a,b) (a & gt; b ? a:b)
#endif

unsigned int LearnThread(void *dlg) {((Clearndlg *)dlg)- & gt; LearnThreadProc();return 0;}
unsigned int AnalyzeThread(void *dlg) {((Clearndlg *)dlg)- & gt; AnalyzeThreadProc();return 0;}
unsigned int RawThread(void *dlg) {((Clearndlg *)dlg)- & gt; RawThreadProc();return 0;}


/////////////////////////////////////////////////////////////////////////////
// Clearndlg dialog


Clearndlg::Clearndlg(CIRDriver *ndrv, const char *nfilename,
lm nlearn_mode, CWnd* pParent /*=NULL*/)
: CDialog(Clearndlg::IDD, pParent)
{
//{{AFX_DATA_INIT(Clearndlg)
// NOTE: the ClassWizard will add member initialization here
//}}AFX_DATA_INIT

drv=ndrv;
filename=nfilename;
learn_mode=nlearn_mode;
fout=NULL;

::learn_dialog=this;
}

Clearndlg::~Clearndlg()
{
KillThread( & LearnThreadHandle, & LearnThreadEvent);
if(fout!=NULL) { fclose(fout); fout=NULL; }
if(GotInput) { CloseHandle(GotInput); GotInput=NULL; }
}

void Clearndlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(Clearndlg)
// NOTE: the ClassWizard will add DDX and DDV calls here
//}}AFX_DATA_MAP
}


BEGIN_MESSAGE_MAP(Clearndlg, CDialog)
//{{AFX_MSG_MAP(Clearndlg)
ON_BN_CLICKED(IDC_BUTTON1, OnEnter)
ON_WM_CLOSE()
ON_BN_CLICKED(IDC_ENTER, OnEnter)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// Clearndlg message handlers

BOOL Clearndlg::OnInitDialog()
{
CDialog::OnInitDialog();

((CEdit *)GetDlgItem(IDC_OUT))- & gt; SetLimitText(0xFFFF);

char *mode=(learn_mode==lm_learn)? " w " : " r " ;

if((fout=fopen(filename,mode))==NULL)
{
MessageBox( " Could not open configuration file. " );
EndDialog2(IDCANCEL);
}

if((GotInput=CreateEvent(NULL,FALSE,FALSE,NULL))==NULL)
{
MessageBox( " Could not create event. " );
EndDialog2(IDCANCEL);
}

/* THREAD_PRIORITY_IDLE combined with the REALTIME_PRIORITY_CLASS */
/* of this program still results in a really high priority. (16 out of 31) */

AFX_THREADPROC tp;
switch(learn_mode)
{
case lm_learn: tp=LearnThread; break;
case lm_analyze: tp=AnalyzeThread; break;
case lm_raw: tp=RawThread; break;
}
if((LearnThreadHandle=AfxBeginThread(tp,
(void *)this,THREAD_PRIORITY_IDLE))==NULL)
{
CloseHandle(GotInput); GotInput=NULL;
MessageBox( " Could not initialize thread. " );
EndDialog2(IDCANCEL);
}

return TRUE; // return TRUE unless you set the focus to a control
// EXCEPTION: OCX Property Pages should return FALSE
}

void Clearndlg::output(const char *s, bool replacelast)
{
CEdit *out=(CEdit *)GetDlgItem(IDC_OUT);
if (out==NULL) return;
if(s==NULL)
{
/* clear output */
out- & gt; SetSel(0,-1);
out- & gt; ReplaceSel( " " );
return;
}

/* limit it to 120 characters, then add \r\n (if not replacing current line) */
/* we don't add \r\n if replacing current line because that causes the box to */
/* scroll up and down real quick when the last line is deleted and removed. */
char t[256];
_snprintf(t,120, " %s " ,s);
t[120]=0;

if(replacelast & & out- & gt; GetLineCount() & gt; 1)
{
out- & gt; SetSel(out- & gt; LineIndex(out- & gt; GetLineCount()-2),out- & gt; GetWindowTextLength()-2);
}
else
{
strcat(t, " \r\n " );
out- & gt; SetSel(out- & gt; GetWindowTextLength(),out- & gt; GetWindowTextLength());
}
out- & gt; ReplaceSel(t);

if(out- & gt; GetLineCount() & gt; 500)
{
/* start clearing out lines to avoid hitting the 64k limit */
/* (122 * 500 = 61000) */
out- & gt; SetSel(0,out- & gt; LineIndex(100),TRUE);
out- & gt; ReplaceSel( " " );
}
out- & gt; SetSel(out- & gt; GetWindowTextLength(),out- & gt; GetWindowTextLength());
}

void Clearndlg::input(const char *prompt, char *s, int maxlen, bool allowempty)
{
CEdit *in=(CEdit *)GetDlgItem(IDC_IN);
CButton *ent=(CButton *)GetDlgItem(IDC_ENTER);

ent- & gt; EnableWindow(true);
in- & gt; SetSel(0,-1);
in- & gt; ReplaceSel( " " );
in- & gt; SetLimitText(maxlen);
this- & gt; GotoDlgCtrl(in);

int len;
HANDLE events[2]={GotInput,LearnThreadEvent};
do {
output(prompt);
ResetEvent(GotInput);
int res=WaitForMultipleObjects(2,events,FALSE,INFINITE);
if(res==(WAIT_OBJECT_0+1))
{
DEBUG( " LearnThread terminating\n " );
AfxEndThread(0);
return;
}
len=in- & gt; GetWindowTextLength();
} while((!allowempty & & len==0));
s[len]=0;

ent- & gt; EnableWindow(false);
in- & gt; GetWindowText(s,maxlen);
in- & gt; SetSel(0,-1);
in- & gt; ReplaceSel( " " );
in- & gt; SetLimitText(maxlen);
}

void Clearndlg::OnClose()
{
DEBUG( " Killing LearnThread\n " );
KillThread( & LearnThreadHandle, & LearnThreadEvent);
DEBUG( " Closing GotInput event\n " );
if(GotInput) { CloseHandle(GotInput); GotInput=NULL; }
DEBUG( " Closing fout\n " );
if(fout!=NULL) fclose(fout); fout=NULL;
DEBUG( " Calling CDialog::OnClose()\n " );
CDialog::OnClose();
}

void Clearndlg::OnEnter()
{
SetEvent(GotInput);
}

bool Clearndlg::GetGap(unsigned long & gap,
unsigned long & count,
unsigned long & repeat_gap,
unsigned long *repeat)
{
unsigned long data, average, signalcount;
int mode;

signalcount=average=mode=0;
while(drv- & gt; readdata(250*1000,LearnThreadEvent)!=0)
; /* wait for signals to stop coming for at least 0.25 sec */

for(;;)
{
data=drv- & gt; readdata(30*1000*1000,LearnThreadEvent);

if(data==0) return false;
if(signalcount & gt; MAX_SIGNALS) return false;

if(is_space(data) & & mode==0)
{
if(average==0)
{
if(data & gt; 100000) continue;
average=data;
}
else
{
if(data & gt; 10*average ||
(signalcount & gt; 10 & & data & gt; 5*average))
{
count=signalcount;
signalcount=0;
gap=data;
mode=1;
continue;
}
average = (average*signalcount + data)/(signalcount+1);
}
}
/* found gap, getting repeat code */
if(mode==1)
{
if(signalcount & lt; 3) repeat[signalcount]=data & (PULSE_BIT-1);
else
{
if(data & lt; (gap - gap*remote.eps/100))
{
/* if value is less than current gap,
then it's probably not a repeat gap */
DEBUG( " repeat not detected, data=%d gap=%d\n " ,data,gap);
repeat[0]=repeat[1]=repeat[2]=0;
}
else
{
/* otherwise, we'll assume it is */
DEBUG( " repeat detected, repeat_gap=%d\n " ,data);
repeat_gap=data;
}
break;
}
}
signalcount++;
}
return true;
}

void Clearndlg::DoGetGap(void)
{
output( " Step One: Determine signal gap, signal length, and repeat codes. " );
output( " ---------------------------------------------------------------- "
" ---------------------------------------------------------------- " );
output( " " );
output( " You will be asked to press an arbitrary button a number of times. " );
output( " Please hold it in for at least one second each time, and wait at " );
output( " least one second between keypresses. " );
output( " " );
output( " If you want to manually enter a signal gap and signal length, you " );
output( " may do so now (ie, \ " 31000 52\ " ). Otherwise, just hit ENTER. " );

/* First, read it until we get two results in a row that are pretty close. */
int fault=0;
unsigned long last_gap=0;
unsigned long last_count=0;
unsigned long last_repeat_gap=0;
unsigned long last_repeat[3]={0,0,0};
unsigned long gap, count, repeat_gap, repeat[3];
int i;
bool manualdata=false;
char s[1024];


input( " Gap and length? " ,s,1024,true);
if(strlen(s)!=0 & & sscanf(s, " %ld %ld " , & gap, & count)==2) manualdata=true;

if(manualdata)
{
DEBUG( " manual data entered, gap=%ld count=%ld\n " ,gap,count);
code.length=count;
remote.gap=gap;
remote.repeat_gap=0;
remote.prepeat=0;
remote.srepeat=0;
remote.ptrail=0;

fprint_comment(fout, & remote);
fprint_remote_head(fout, & remote);
fprint_remote_signal_head(fout, & remote);
return;
}

output( " Press a button. " );
bool match=false;
while(!match)
{
if(GetGap(gap,count,repeat_gap,repeat)==false)
{
DEBUG( " GetGap failed\n " );
output( " Error reading signal; please try again. " );
continue;
}

if(last_count==0)
{
for(i=0;i & lt; 3;i++) last_repeat[i]=repeat[i];
last_count=count;
last_gap=gap;
last_repeat_gap=repeat_gap;
output( " Please wait a second and press it again. " );
continue;
}

match=true;
/* match repeats */
if(repeat[0]==0 & & last_repeat[0]!=0)
{
DEBUG( " repeat[0] was zero but last_repeat[0] was %d\n " ,last_repeat[0]);
match=false;
}
else if(last_repeat[0]==0 & & repeat[0]!=0)
{
DEBUG( " last_repeat[0] was zero but repeat[0] was %d\n " ,repeat[0]);
match=false;
}
else {
for(i=0;i & lt; 3;i++)
if(!expect( & remote,last_repeat[i],repeat[i]))
{
DEBUG( " repeat[%d]=%d doesn't match last_repeat[%d]=%d\n " ,
i,repeat[i],i,last_repeat[i]);
match=false;
}
}

/* match counts */
if(count!=last_count)
{
DEBUG( " Mismatched count: count=%d, last_count=%d\n " ,count,last_count);
match=false;
}

/* match gaps */
if(!expect( & remote,last_gap,gap))
{
DEBUG( " gaps don't match: last_gap=%d, gap=%d\n " ,last_gap,gap);
match=false;
}

/* match repeat gaps */
if(!expect( & remote,last_repeat_gap,repeat_gap))
{
DEBUG( " repeat gaps don't match: last_repeat_gap=%d, repeat_gap=%d\n " ,
last_repeat_gap,repeat_gap);
match=false;
}


if(!match)
{
for(i=0;i & lt; 3;i++) last_repeat[i]=repeat[i];
last_count=count;
last_gap=gap;
last_repeat_gap=repeat_gap;
fault++;
if(fault & gt; 5)
{
MessageBox( " Too many faults. Possible reasons:\n "
" 1) This remote can't be automatically learned (sorry)\n "
" 2) The system is too slow or bogged down to accurately record\n "
" times (try closing all other programs) " , " Error " );
EndDialog2(IDCANCEL);
DEBUG( " LearnThread terminating\n " );
AfxEndThread(0);
return;
}
DEBUG( " Did not get consistent signal\n " );
output( " Did not get a consistent signal; please try again. " );
}
}

/* Now, refine the information for gap and repeat */
unsigned long avg_gap;
unsigned long avg_repeat_gap;
unsigned long avg_count;
unsigned long avg_repeat[3];
avg_count=count;
avg_gap=(gap+last_gap)/2;
avg_repeat_gap=(repeat_gap+last_repeat_gap)/2;
for(i=0;i & lt; 3;i++) avg_repeat[i]=(repeat[i]+last_repeat[i])/2;
int j=0;
output( " Baseline initialized. " );
while(j & lt; 10)
{
sprintf(s, " Please wait a second and press a button again (%d left) " ,10-j);
output(s);
if(GetGap(gap,count,repeat_gap,repeat)==false)
{
DEBUG( " GetGap error\n " );
output( " Error reading signal; please try again. " );
continue;
}
match=true;
/* match repeats */
if(repeat[0]==0 & & avg_repeat[0]!=0)
{
DEBUG( " repeat[0] was zero but avg_repeat[0] was %d\n " ,avg_repeat[0]);
match=false;
}
else if(avg_repeat[0]==0 & & repeat[0]!=0)
{
DEBUG( " avg_repeat[0] was zero but repeat[0] was %d\n " ,repeat[0]);
match=false;
}
else if(avg_repeat[0]!=0) {
for(i=0;i & lt; 3;i++)
if(!expect( & remote,avg_repeat[i],repeat[i]))
{
DEBUG( " repeat[%d]=%d doesn't match avg_repeat[%d]=%d\n " ,
i,repeat[i],i,avg_repeat[i]);
match=false;
}
}

/* match counts */
if(count!=avg_count)
{
DEBUG( " counts didn't match\n " );
match=false;
}

/* match gaps */
if(!expect( & remote,avg_gap,gap))
{
DEBUG( " gap was too far from old gap\n " );
match=false;
}

/* match repeat gaps */
if(!expect( & remote,last_repeat_gap,repeat_gap))
{
DEBUG( " repeat gaps was too far from old repeat gap\n " );
match=false;
}


if(!match)
{
fault++;
if(fault & gt; 10)
{
MessageBox( " Too many faults. Possible reasons:\n "
" 1) This remote can't be automatically learned (sorry)\n "
" 2) The system is too slow or bogged down to accurately record\n "
" times (try closing all other programs)\n "
" 3) The detection got off to a bad start (try again) " , " Error " );
EndDialog2(IDCANCEL);
DEBUG( " LearnThread terminating\n " );
AfxEndThread(0);
return;
}
output( " Did not get a consistent signal. " );
continue;
}
else
{
avg_gap=((avg_gap*(j+2)) + gap)/(j+3);
avg_repeat_gap=((avg_repeat_gap*(j+2)) + repeat_gap)/(j+3);
for(i=0;i & lt; 3;i++) avg_repeat[i]=((avg_repeat[i]*(j+2)) + repeat[i])/(j+3);
j++;
}
}

/* Save it so far */
code.length=avg_count;
remote.gap=avg_gap;
remote.repeat_gap=avg_repeat_gap;
remote.prepeat=avg_repeat[0];
remote.srepeat=avg_repeat[1];
remote.ptrail=avg_repeat[2];

fprint_comment(fout, & remote);
fprint_remote_head(fout, & remote);
fprint_remote_signal_head(fout, & remote);
}

bool Clearndlg::GetRawButton(unsigned long *signals, int & count, bool waitgap)
{
count=0;
unsigned long data;

while(count & lt; MAX_SIGNALS)
{
data=drv- & gt; readdata(waitgap?(30*1000*1000):(5*remote.gap),LearnThreadEvent);
if(data==0) return false;

if(waitgap)
{
if(!is_space(data) || data & lt; remote.gap-remote.gap*remote.eps/100)
return false;
waitgap=false;
}
else
{
/* we've hit the end */
if(is_space(data) & & data & gt; remote.gap-remote.gap*remote.eps/100)
return true;

signals[count]=data & (PULSE_BIT-1);
count++;
}
}
return false;
}

bool Clearndlg::GetButton(unsigned long *signals, bool repeating)
{
/* read 64 samples if repeating */
/* read 8 samples if non-repeating */

int count, i, j;
unsigned long sig[MAX_SIGNALS+1];
unsigned long last_sig[MAX_SIGNALS+1];

while(drv- & gt; readdata(250*1000,LearnThreadEvent)!=0)
; /* wait for signals to stop coming for at least 0.25 sec */

int fault=0, expectfault=0;
bool match=false;
bool first=true;
char s[256];

if(repeating)
{
sprintf(s, " Please press and hold down the '%s' button until told to stop. " ,code.name);
output(s);
}
else
{
sprintf(s, " Please repeatedly press and release the '%s' button until " ,code.name);
output(s),
output( " told to stop. You must wait at least half of a second " );
output( " between keypresses or they will not be recognized. " );
}

while(!match)
{
/* read two in a row that match */
match=true;
if(!repeating)
while(drv- & gt; readdata(250*1000,LearnThreadEvent)!=0)
; /* wait for signals to stop coming for at least 0.25 sec */
if(!GetRawButton(sig,count,repeating?first:true))
{
DEBUG( " GetRawButton failed\n " );
match=false;
}
if(count!=code.length)
{
DEBUG( " Bad count: count=%d, code.length=%d\n " ,count,code.length);
match=false;
}
for(i=0;i & lt; code.length & & match;i++)
if(!expect( & remote,last_sig[i],sig[i]))
{
expectfault++;
DEBUG( " signal too far from old signal\n " );
match=false;
}
if(!match)
{
fault++;
if(fault & gt; (repeating?10:5))
{
DEBUG( " failed to get consistent signal\n " );
output( " Stop. Failed to get a consistent initial signal. "
" Please try again. " );
if(expectfault & gt; (repeating?8:4))
{
output( " You will probably get better results if you " );
output( " increase the margin of error for this remote. " );
}
return false;
}
if(!repeating)
output( " No match yet; please continue " );
}
first=false;
for(i=0;i & lt; code.length;i++)
last_sig[i]=sig[i];
}


if(repeating)
output( " Baseline initialized. " );
else
output( " Baseline initialized. Please continue to press the button. " );
fault=0;
for(i=0;i & lt; code.length;i++) signals[i]=(sig[i]+last_sig[i])/2;
j=2;
output( " " ); // need this to prevent last line from being overwritten
while(j & lt; (repeating?64:8))
{
sprintf(s, " matches=%d, faults=%d " ,j,fault);
output(s,true);

match=true;
if(!repeating)
while(drv- & gt; readdata(250*1000,LearnThreadEvent)!=0)
; /* wait for signals to stop coming for at least 0.25 sec */
if(!GetRawButton(sig,count,repeating?false:true))
{
DEBUG( " GetRawButton failed\n " );
match=false;
}
if(count!=code.length)
{
DEBUG( " Bad count: count=%d, code.length=%d\n " ,count,code.length);
match=false;
}
for(i=0;i & lt; code.length & & match;i++)
if(!expect( & remote,signals[i],sig[i]))
{
DEBUG( " signal too far from old signal\n " );
match=false;
}
if(!match)
{
fault++;
if(fault & gt; (repeating?64:12))
{
DEBUG( " failed to get consistent signal\n " );
output( " Stop. Failed to get a consistent signal. Please try again. " );
return false;
}
}
else
{
for(i=0;i & lt; code.length;i++)
signals[i]=(signals[i]*j + sig[i])/(j+1);
j++;
}
}
sprintf(s, " matches=%d, faults=%d " ,j,fault);
output(s,true);
output( " Stop. " );
return true;
}

void Clearndlg::DoGetButtons(void)
{
output( " Step Two: Input buttons. " );
output( " ---------------------------------------------------------------- "
" ---------------------------------------------------------------- " );
output( " " );
if(remote.prepeat==0)
{
DEBUG( " this remote is a signal repeating remote\n " );
output( " This is a signal-repeating remote with no special repeat code. " );
output( " Holding down the button can quickly yield many copies of that "
" button's code. " );
output( " Therefore, 64 samples of each button will be taken. " );
}
else
{
DEBUG( " this remote has a special repeat code\n " );
output( " This remote has a special repeat code. " );
output( " The button needs to be pressed and released for each new copy of that " );
output( " button's code. 8 samples of each button will be taken. " );
}

output( " " );
output( " You will be prompted to enter each button's name in turn. " );
output( " To finish recording buttons, enter a blank button name. " );
output( " " );

char buffer[BUTTON];
unsigned long signals[MAX_SIGNALS+1];
code.signals=signals;
char s[1024];
int button=1;

for(;;)
{
if(button & gt; 1)
sprintf(s, " Button %d name? (blank to stop) " ,button);
else
sprintf(s, " Button %d name? " ,button);
input(s,buffer,BUTTON,true);

if(strchr(buffer,' ') || strchr(buffer,'\t'))
{
output( " A button name may not contain any whitespace. " );
continue;
}
if(strlen(buffer)==0) break;
code.name=buffer;
bool res=false;
res=GetButton(signals,(remote.prepeat==0)?true:false);
if(!res)
{
DEBUG( " GetButton failed\n " );
continue;
}
output( " " );output( " " );
sprintf(s, " Button '%s' recorded. Do you wish to keep this recording? " ,buffer);
if(MessageBox(s, " Keep it? " ,MB_YESNO)==IDNO) continue;
fprint_remote_signal(fout, & remote, & code);
button++;
}
fprint_remote_signal_foot(fout, & remote);
fprint_remote_foot(fout, & remote);
}

void Clearndlg::LearnThreadProc(void)
{
char s[256];
char brand[64];
unsigned long data;

output( " This will record the signals from your remote control " );
output( " and create a config file for WinLIRC. " );
output( " " );
remote.flags=RAW_CODES;
remote.aeps=AEPS;
do {
input( " Please enter a name for this remote. " ,brand,63);
if(strchr(brand,' ') || strchr(brand,'\t'))
{
output( " The remote name may not contain any whitespace. " );
brand[0]=0;
}
} while(brand[0]==0);

remote.name=brand;
output(brand);
output( " " );
output( " When learning and analyzing signals, a margin of error is used in order to " );
output( " handle the normal variations in the received signal. The margin of error " );
sprintf(s, " ranges from 1%% to 99%%. The default is %d%%, but larger values might " ,EPS);
output(s);
output( " be necessary depending on your hardware and software. If you are having " );
output( " trouble using your remote, try increasing this value. You may enter the " );
output( " allowable margin of error now, or press ENTER to use the default. " );
output( " " );
int user_eps=0;
do {
sprintf(s, " Desired margin of error for this remote? (1-99, enter=%d) " ,EPS);
input(s,s,63,true);
if(strlen(s)==0) user_eps=EPS;
else user_eps=atoi(s);
} while(user_eps & lt; 1 || user_eps & gt; 99);

remote.eps=user_eps;

/* Clear out the buffer */
while(drv- & gt; GetData( & data)==true)
;

output(NULL);
DoGetGap();

output(NULL);
DoGetButtons();

MessageBox( " Configuration successfully written. " , " Success " );
EndDialog2(IDOK);
DEBUG( " LearnThread terminating\n " );
AfxEndThread(0);
return;
}

void Clearndlg::RawThreadProc(void)
{
output( " Outputting raw mode2 data. " );
DEBUG( " Raw mode2 data:\n " );
output( " " );

unsigned long int x;
char s[256];
for(;;)
{
x=drv- & gt; readdata(0,LearnThreadEvent);
if(x & PULSE_BIT)
sprintf(s, " pulse %ld " ,x & ~PULSE_BIT);
else
sprintf(s, " space %ld " ,x & ~PULSE_BIT);
output(s);
strcat(s, " \n " );
DEBUG(s);
}
}

void Clearndlg::AnalyzeThreadProc(void)
{
output( " Analyzing data, please wait... " );

/* Read it in */
struct ir_remote *myremotes, *sr;
myremotes=read_config(fout);

/* See if it's OK */
bool ok=true;
if(myremotes==(struct ir_remote *)-1 || myremotes==NULL)
ok=false;
for(sr=myremotes;sr!=NULL & & ok;sr=sr- & gt; next)
{
if(sr- & gt; codes==NULL)
{
free_config(myremotes);
myremotes=NULL;
ok=false;
}
}
if(!ok)
{
MessageBox( " Error parsing configuration file.\n " , " Error " );
EndDialog2(IDCANCEL);
DEBUG( " AnalyzeThread terminating\n " );
AfxEndThread(0);
return;
}

fclose(fout); fout=NULL;

/* Now analyze it */
if(analyze(myremotes)==-1)
{
free_config(myremotes);
myremotes=NULL;
MessageBox( " Analysis failed. This remote is probably only\n "
" supported in raw mode. Configuration file is unchanged. " , " Error " );
EndDialog2(IDCANCEL);
DEBUG( " AnalyzeThread terminating\n " );
AfxEndThread(0);
return;
}

/* Yay, success */

if((fout=fopen(filename, " w " ))==NULL)
{
free_config(myremotes);
myremotes=NULL;
MessageBox( " Analysis succeeded, but re-open of file failed. "
" Configuration file is unchanged. " , " Error " );
EndDialog2(IDCANCEL);
DEBUG( " AnalyzeThread terminating\n " );
AfxEndThread(0);
return;
}

fprint_remotes(fout,myremotes);
free_config(myremotes);
myremotes=NULL;

MessageBox( " Analysis successful.\n " , " Success " );

EndDialog2(IDOK);
DEBUG( " AnalyzeThread terminating\n " );
AfxEndThread(0);
return;
}

/* Analysis stuff from here down */

int Clearndlg::analyze(struct ir_remote *remotes)
{
int scheme;

while(remotes!=NULL)
{
if(remotes- & gt; flags & RAW_CODES)
{
scheme=get_scheme(remotes);
switch(scheme)
{
case 0:
output( " Config file does not contain any buttons. " );
return(-1);
break;
case SPACE_ENC:
if(-1==check_lengths(remotes))
{
output( " check_lengths failed " );
return(-1);
}
if(-1==get_lengths(remotes))
{
output( " get_lengths failed " );
return(-1);
}
remotes- & gt; flags & =~RAW_CODES;
remotes- & gt; flags|=SPACE_ENC;
if(-1==get_codes(remotes))
{
remotes- & gt; flags & =~SPACE_ENC;
remotes- & gt; flags|=RAW_CODES;
output( " get_codes failed " );
return(-1);
}
get_pre_data(remotes);
get_post_data(remotes);
break;
case SHIFT_ENC:
output( " Shift encoded remotes are not supported yet. " );
return(-1);
break;
}
}
remotes=remotes- & gt; next;
}
return(0);
}

int Clearndlg::get_sum(struct ir_remote *remote)
{
int sum,i;
struct ir_ncode *codes;

sum=0;
codes=remote- & gt; codes;
for(i=0;codes[i].name!=NULL;i++)
{
sum++;
}
return(sum);
}

int Clearndlg::get_scheme(struct ir_remote *remote)
{
struct ir_ncode *codes;
int match,sum,i,j;

sum=get_sum(remote);
if(sum==0)
{
return(0);
}
codes=remote- & gt; codes;
for(i=0;i & lt; sum;i++)
{
match=0;
for(j=i+1;j & lt; sum;j++)
{
if(codes[i].length==codes[j].length)
{
match++;
/* I want less than 20% mismatches */
if(match & gt; =80*sum/100)
{
/* this is not yet the
number of bits */
remote- & gt; bits=codes[i].length;
return(SPACE_ENC);
}
}
}
}
return(SHIFT_ENC);
}

int Clearndlg::check_lengths(struct ir_remote *remote)
{
int i,flag;
struct ir_ncode *codes;

flag=0;
codes=remote- & gt; codes;
for(i=0;codes[i].name!=NULL;i++)
{
if(codes[i].length!=remote- & gt; bits)
{
char s[128];
_snprintf(s,127, " Button \ " %s\ " has wrong signal length.\r\n "
" Try to record it again. " ,codes[i].name);
output(s);
flag=-1;
}
}
return(flag);
}

struct lengths *Clearndlg::new_length(unsigned long length)
{
struct lengths *l;

l=(struct lengths *)malloc(sizeof(struct lengths));
if(l==NULL) return(NULL);
l- & gt; count=1;
l- & gt; sum=length;
l- & gt; lower_bound=length/100*100;
l- & gt; upper_bound=length/100*100+99;
l- & gt; min=l- & gt; max=length;
l- & gt; next=NULL;
return(l);
}

int Clearndlg::add_length(struct lengths **first,unsigned long length)
{
struct lengths *l,*last;

if(*first==NULL)
{
*first=new_length(length);
if(*first==NULL) return(-1);
return(0);
}
l=*first;
while(l!=NULL)
{
if(l- & gt; lower_bound & lt; =length & & length & lt; =l- & gt; upper_bound)
{
l- & gt; count++;
l- & gt; sum+=length;
l- & gt; min=min(l- & gt; min,length);
l- & gt; max=max(l- & gt; max,length);
return(0);
}
last=l;
l=l- & gt; next;
}
last- & gt; next=new_length(length);
if(last- & gt; next==NULL) return(-1);
return(0);
}

void Clearndlg::free_lengths(struct lengths *first)
{
struct lengths *next;

if(first==NULL) return;
while(first!=NULL)
{
next=first- & gt; next;
free(first);
first=next;
}
}

void Clearndlg::merge_lengths(struct lengths *first)
{
struct lengths *l,*inner,*last;
unsigned long new_sum;
int new_count;

l=first;
while(l!=NULL)
{
last=l;
inner=l- & gt; next;
while(inner!=NULL)
{
new_sum=l- & gt; sum+inner- & gt; sum;
new_count=l- & gt; count+inner- & gt; count;

if((l- & gt; max & lt; =new_sum/new_count+AEPS & &
l- & gt; min & gt; =new_sum/new_count-AEPS & &
inner- & gt; max & lt; =new_sum/new_count+AEPS & &
inner- & gt; min & gt; =new_sum/new_count-AEPS)
||
(l- & gt; max & lt; =new_sum/new_count*(100+EPS) & &
l- & gt; min & gt; =new_sum/new_count*(100-EPS) & &
inner- & gt; max & lt; =new_sum/new_count*(100+EPS) & &
inner- & gt; min & gt; =new_sum/new_count*(100-EPS)))
{
l- & gt; sum=new_sum;
l- & gt; count=new_count;
l- & gt; upper_bound=max(l- & gt; upper_bound,
inner- & gt; upper_bound);
l- & gt; lower_bound=min(l- & gt; lower_bound,
inner- & gt; lower_bound);
l- & gt; min=min(l- & gt; min,inner- & gt; min);
l- & gt; max=max(l- & gt; max,inner- & gt; max);

last- & gt; next=inner- & gt; next;
free(inner);
inner=last;
}
last=inner;
inner=inner- & gt; next;
}
l=l- & gt; next;
}
}

void Clearndlg::get_header_length(struct ir_remote *remote,struct lengths **first_pulse,
struct lengths **first_space)
{
unsigned int sum,match,i;
struct lengths *p,*s,*plast,*slast;
struct ir_ncode *codes;

sum=get_sum(remote);
p=*first_pulse;
plast=NULL;
while(p!=NULL)
{
if(p- & gt; count & gt; =90*sum/100)
{
s=*first_space;
slast=NULL;
while(s!=NULL)
{
if(s- & gt; count & gt; =90*sum/100 & &
(p- & gt; count & lt; =sum || s- & gt; count & lt; =sum))
{

codes=remote- & gt; codes;
match=0;
for(i=0;codes[i].name!=NULL;i++)
{
if(expect(remote,
remote- & gt; codes[i].signals[0],
(int) (p- & gt; sum/p- & gt; count))
& &
expect(remote,
remote- & gt; codes[i].signals[1],
(int) (s- & gt; sum/s- & gt; count)))
{
match++;
}
}
if(match & gt; =sum*90/100)
{
remote- & gt; phead=p- & gt; sum/p- & gt; count;
remote- & gt; shead=s- & gt; sum/s- & gt; count;
p- & gt; sum-=sum*p- & gt; sum/p- & gt; count;
s- & gt; sum-=sum*s- & gt; sum/s- & gt; count;
p- & gt; count-=sum;
s- & gt; count-=sum;
if(p- & gt; count & lt; =0)
{
if(plast==NULL)
{
plast=*first_pulse;
*first_pulse=plast- & gt; next;
free(plast);
}
else
{
plast- & gt; next=p- & gt; next;
free(p);
}
}
if(s- & gt; count & lt; =0)
{
if(slast==NULL)
{
slast=*first_space;
*first_space=slast- & gt; next;
free(slast);
}
else
{
slast- & gt; next=s- & gt; next;
free(s);
}
}
return;
}
}
slast=s;
s=s- & gt; next;
}
}
plast=p;
p=p- & gt; next;
}
}

unsigned long Clearndlg::get_length(struct ir_remote *remote,struct lengths *first,
unsigned long l)
{
while(first!=NULL)
{
if(expect(remote,l,first- & gt; sum/first- & gt; count))
{
return(first- & gt; sum/first- & gt; count);
}
first=first- & gt; next;
}
return(0);
}

int Clearndlg::is_bit(struct ir_remote *remote,unsigned long pulse, unsigned long space)
{
int i,j,match,sum;
struct ir_ncode *codes;

sum=get_sum(remote);
match=0;
codes=remote- & gt; codes;
for(i=0;codes[i].name!=NULL;i++)
{
for(j=has_header(remote) ? 2:0;j+2 & lt; codes[i].length;j+=2)
{
if(expect(remote,codes[i].signals[j],pulse) & &
expect(remote,codes[i].signals[j+1],space))
{
match++;
}
}
}
sum*=(remote- & gt; bits-1-(has_header(remote) ? 2:0));
sum/=2;
if(match & gt; =20*sum/100)
{
return(1);
}
return(0);
}

int Clearndlg::get_one_length(struct ir_remote *remote,struct lengths **first_pulse,
struct lengths **first_space)
{
int i,j;
struct ir_ncode *codes;
unsigned long pulse,space;

codes=remote- & gt; codes;
for(i=0;codes[i].name!=NULL;i++)
{
j=has_header(remote) ? 2:0;
pulse=get_length(remote,*first_pulse,codes[i].signals[j]);
space=get_length(remote,*first_space,codes[i].signals[j+1]);

if(pulse!=0 & & space!=0)
{
if(is_bit(remote,pulse,space))
{
remote- & gt; pone=pulse;
remote- & gt; sone=space;
return(0);
}
}
}
return(-1);
}

int Clearndlg::get_zero_length(struct ir_remote *remote,struct lengths **first_pulse,
struct lengths **first_space)
{
int i,j;
struct ir_ncode *codes;
unsigned long pulse,space;

codes=remote- & gt; codes;
for(i=0;codes[i].name!=NULL;i++)
{
for(j=has_header(remote) ? 2:0;j+2 & lt; codes[i].length;j+=2)
{

if(expect(remote,codes[i].signals[j],
remote- & gt; pone)==0
|| expect(remote,codes[i].signals[j+1],
remote- & gt; sone)==0)
{
pulse=get_length(remote,*first_pulse,
codes[i].signals[j]);
space=get_length(remote,*first_space,
codes[i].signals[j+1]);
if(is_bit(remote,pulse,space))
{
remote- & gt; pzero=pulse;
remote- & gt; szero=space;
return(0);
}
}
}
}
return(-1);
}

int Clearndlg::get_trail_length(struct ir_remote *remote,struct lengths **first_pulse)
{
unsigned int sum,match,i;
struct lengths *p,*plast;
struct ir_ncode *codes;

sum=get_sum(remote);
p=*first_pulse;
plast=NULL;
while(p!=NULL)
{
if(p- & gt; count & gt; =sum)
{
codes=remote- & gt; codes;
match=0;
for(i=0;codes[i].name!=NULL;i++)
{
if(expect(remote,
remote- & gt; codes[i].signals[remote- & gt; codes[i].length-1],
(int) (p- & gt; sum/p- & gt; count)))
{
match++;
}
}
if(match & gt; =sum*90/100)
{
remote- & gt; ptrail=p- & gt; sum/p- & gt; count;
p- & gt; sum-=sum*p- & gt; sum/p- & gt; count;
p- & gt; count-=sum;
if(p- & gt; count==0)
{
if(plast==NULL)
{
plast=*first_pulse;
*first_pulse=plast- & gt; next;
free(plast);
}
else
{
plast- & gt; next=p- & gt; next;
free(p);
}
}
return(0);
}
}
plast=p;
p=p- & gt; next;
}
return(-1);
}

int Clearndlg::get_lengths(struct ir_remote *remote)
{
struct lengths *first_space=NULL,*first_pulse=NULL;
int i,j;
struct ir_ncode *codes;

/* get all spaces */

codes=remote- & gt; codes;
for(i=0;codes[i].name!=NULL;i++)
{
for(j=1;codes[i].signals[j]!=0;j+=2)
{
if(-1==add_length( & first_space,codes[i].signals[j]))
{
free_lengths(first_space);
output( " add_length failed " );
return(-1);
}
}
}
merge_lengths(first_space);

/* and now all pulses */

codes=remote- & gt; codes;
for(i=0;codes[i].name!=NULL;i++)
{
for(j=0;j & lt; codes[i].length;j+=2)
{
if(-1==add_length( & first_pulse,codes[i].signals[j]))
{
free_lengths(first_space);
free_lengths(first_pulse);
output( " add_length failed " );
return(-1);
}
}
}
merge_lengths(first_pulse);

get_header_length(remote, & first_pulse, & first_space);
if(-1==get_trail_length(remote, & first_pulse))
{
free_lengths(first_space);
free_lengths(first_pulse);
output( " get_trail_length failed " );
return(-1);
}
if(-1==get_one_length(remote, & first_pulse, & first_space))
{
free_lengths(first_space);
free_lengths(first_pulse);
output( " get_one_length failed " );
return(-1);
}
if(-1==get_zero_length(remote, & first_pulse, & first_space))
{
free_lengths(first_space);
free_lengths(first_pulse);
output( " get_zero_length failed " );
return(-1);
}

remote- & gt; bits--;
if(has_header(remote)) remote- & gt; bits-=2;
remote- & gt; bits/=2;
if(remote- & gt; bits & gt; 64) /* can't handle more than 64 bits in normal mode */
{
free_lengths(first_space);
free_lengths(first_pulse);
output( " bits & gt; 64 " );
return(-1);
}
#ifndef LONG_IR_CODE
if(remote- & gt; bits & gt; 32)
{
output( " this remote control sends more than 32 bits " );
output( " recompile the package using LONG_IR_CODE " );
return(-1);
}
#endif

free_lengths(first_space);
free_lengths(first_pulse);
return(0);
}

int Clearndlg::get_codes(struct ir_remote *remote)
{
struct ir_ncode *codes;

codes=remote- & gt; codes;
while(codes- & gt; name!=NULL)
{
rec_buffer.rptr=rec_buffer.wptr=0;
clear_rec_buffer(remote- & gt; gap);

current=codes;
use_ir_hardware=false;
if(decode(remote))
{
codes- & gt; code=remote- & gt; post_data;
remote- & gt; post_data=0;
}
else
{
return(-1);
}
codes++;
}
return(0);
}

unsigned long Clearndlg::readdata(unsigned long maxusec)
{
static int i=0;
static struct ir_ncode *codes=NULL;
unsigned long data;

if(codes!=current)
{
i=0;
codes=current;
}

if(i & lt; current- & gt; length)
{
data=current- & gt; signals[i];
i++;
return(i%2 ? data|PULSE_BIT:data);
}
return(0);
}

void Clearndlg::get_pre_data(struct ir_remote *remote)
{
struct ir_ncode *codes;
ir_code mask,last;
int count,i;

if(remote- & gt; bits==0) return;
mask=(-1);
codes=remote- & gt; codes;
if(codes- & gt; name==NULL) return; /* at least 2 codes needed */
last=codes- & gt; code;
codes++;
if(codes- & gt; name==NULL) return; /* at least 2 codes needed */
while(codes- & gt; name!=NULL)
{
mask & =~(last^codes- & gt; code);
last=codes- & gt; code;
codes++;
}
count=0;
#ifdef LONG_IR_CODE
while(mask & 0x8000000000000000)
#else
while(mask & 0x80000000)
#endif
{
count++;
mask=mask & lt; & lt; 1;
}
count-=sizeof(ir_code)*CHAR_BIT-remote- & gt; bits;

/* only " even " numbers should go to pre/post data */
if(count%8 & & (remote- & gt; bits-count)%8)
{
count-=count%8;
}
if(count & gt; 0)
{
mask=0;
for(i=0;i & lt; count;i++)
{
mask=mask & lt; & lt; 1;
mask|=1;
}
remote- & gt; bits-=count;
mask=mask & lt; & lt; (remote- & gt; bits);
remote- & gt; pre_data_bits=count;
remote- & gt; pre_data=(last & mask) & gt; & gt; (remote- & gt; bits);

codes=remote- & gt; codes;
while(codes- & gt; name!=NULL)
{
codes- & gt; code & =~mask;
codes++;
}
}
}

void Clearndlg::get_post_data(struct ir_remote *remote)
{
struct ir_ncode *codes;
ir_code mask,last;
int count,i;

if(remote- & gt; bits==0) return;

mask=(-1);
codes=remote- & gt; codes;
if(codes- & gt; name==NULL) return; /* at least 2 codes needed */
last=codes- & gt; code;
codes++;
if(codes- & gt; name==NULL) return; /* at least 2 codes needed */
while(codes- & gt; name!=NULL)
{
mask & =~(last^codes- & gt; code);
last=codes- & gt; code;
codes++;
}
count=0;
while(mask & 0x1)
{
count++;
mask=mask & gt; & gt; 1;
}
/* only " even " numbers should go to pre/post data */
if(count%8 & & (remote- & gt; bits-count)%8)
{
count-=count%8;
}
if(count & gt; 0)
{
mask=0;
for(i=0;i & lt; count;i++)
{
mask=mask & lt; & lt; 1;
mask|=1;
}
remote- & gt; bits-=count;
remote- & gt; post_data_bits=count;
remote- & gt; post_data=last & mask;

codes=remote- & gt; codes;
while(codes- & gt; name!=NULL)
{
codes- & gt; code=codes- & gt; code & gt; & gt; count;
codes++;
}
}
}

void Clearndlg::EndDialog2( int nResult )
{
if(fout!=NULL) { fclose(fout); fout=NULL; }
if (nResult==IDOK)
PostMessage(WM_COMMAND,IDOK,0);
else
PostMessage(WM_SYSCOMMAND,SC_CLOSE,0);
}


winlirc-0.6.5.zip > drvdlg.h

/*
* This file is part of the WinLIRC package, which was derived from
* LIRC (Linux Infrared Remote Control) 0.5.4pre9.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published
* by the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* Copyright (C) 1999 Jim Paris & lt; jim@jtan.com & gt;
* Modifications Copyright (C) 2000 Scott Baily & lt; baily@uiuc.edu & gt;
*/

#if !defined(AFX_DRVDLG_H__C20B80E0_C848_11D2_8C7F_004005637418__INCLUDED_)
#define AFX_DRVDLG_H__C20B80E0_C848_11D2_8C7F_004005637418__INCLUDED_

#if _MSC_VER & gt; 1000
#pragma once
#endif // _MSC_VER & gt; 1000
// drvdlg.h : header file
//

#include " globals.h "

#include " winlirc.h "
#include " trayicon.h "
#include " irdriver.h "
#include " irconfig.h "

class CIRDriver;
class CIRConfig;

/////////////////////////////////////////////////////////////////////////////
// Cdrvdlg dialog

class Cdrvdlg : public CDialog
{
// Construction
public:
Cdrvdlg(CWnd* pParent = NULL); // standard constructor

// Pointer to the class that listens on the serial port
CIRDriver driver;
CIRConfig config;

bool initialized;
bool AllowTrayNotification;
bool DoInitializeDaemon();
bool InitializeDaemon();
void GoGreen();
void GoBlue(); //turns the tray icon blue to indicate a transmission

// Dialog Data
//{{AFX_DATA(Cdrvdlg)
enum { IDD = IDD_DIALOG };
CComboBox m_IrCodeEditCombo;
CComboBox m_remote_DropDown;
CString m_ircode_edit;
CString m_remote_edit;
int m_reps_edit;
//}}AFX_DATA

CTrayIcon ti;

// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(Cdrvdlg)
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
//}}AFX_VIRTUAL

// Implementation
protected:

// Generated message map functions
//{{AFX_MSG(Cdrvdlg)
virtual void OnOK();
virtual void OnCancel();
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
afx_msg void OnToggleWindow();
afx_msg void OnConfig();
afx_msg void OnHideme();
afx_msg void OnExitLirc();
afx_msg void OnTimer(UINT nIDEvent);
virtual BOOL OnInitDialog();
afx_msg void OnSendcode();
afx_msg LRESULT OnCopyData(CWnd* pWnd, COPYDATASTRUCT* pCopyDataStruct);
afx_msg void OnDropdownIrcodeEdit();
//}}AFX_MSG
afx_msg LRESULT OnPowerBroadcast(WPARAM uPowerEvent, LPARAM lP);
void UpdateRemoteComboLists();
void UpdateIrCodeComboLists();
LRESULT OnTrayNotification(WPARAM uID, LPARAM lEvent);
DECLARE_MESSAGE_MAP()
};

//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.

#endif // !defined(AFX_DRVDLG_H__C20B80E0_C848_11D2_8C7F_004005637418__INCLUDED_)


winlirc-0.6.5.zip > confdlg.cpp

/*
* This file is part of the WinLIRC package, which was derived from
* LIRC (Linux Infrared Remote Control) 0.5.4pre9.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published
* by the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* Copyright (C) 1999 Jim Paris & lt; jim@jtan.com & gt;
* RX device, some other stuff Copyright (C) 2002 Alexander Nesterovsky & lt; Nsky@users.sourceforge.net & gt;
*/

#include " winlirc.h "
#include " confdlg.h "
#include " drvdlg.h "
#include " irdriver.h "
#include " learndlg.h "
#include " config.h "
#include " remote.h "
#include " globals.h "


/////////////////////////////////////////////////////////////////////////////
// Cconfdlg dialog


Cconfdlg::Cconfdlg(Cdrvdlg *nparent, CWnd* pParent /*=NULL*/)
: CDialog(Cconfdlg::IDD, pParent)
{
//{{AFX_DATA_INIT(Cconfdlg)
m_port = _T( " " );
m_filename = _T( " " );
m_animax = FALSE;
m_notrayicon = FALSE;
m_devicetype = -1;
m_speed = _T( " " );
m_virtpulse = 0;
m_transmitterpin = -1;
m_hardcarrier = FALSE;
m_inverted = FALSE;
//}}AFX_DATA_INIT
parent=nparent;
}


void Cconfdlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(Cconfdlg)
DDX_CBString(pDX, IDC_PORT, m_port);
DDV_MaxChars(pDX, m_port, 64);
DDX_Text(pDX, IDC_FILE, m_filename);
DDV_MaxChars(pDX, m_filename, 250);
DDX_Check(pDX, IDC_CHECKANIMAX, m_animax);
DDX_Check(pDX, IDC_CHECKTRAY, m_notrayicon);
DDX_Radio(pDX, IDC_RADIORX, m_devicetype);
DDX_CBString(pDX, IDC_SPEED, m_speed);
DDV_MaxChars(pDX, m_speed, 16);
DDX_Text(pDX, IDC_VIRTPULSE, m_virtpulse);
DDV_MinMaxInt(pDX, m_virtpulse, 0, 16777215);
DDX_Radio(pDX, IDC_RADIODTR, m_transmitterpin);
DDX_Check(pDX, IDC_CHECKHARDCARRIER, m_hardcarrier);
DDX_Check(pDX, IDC_INVERTED, m_inverted);
//}}AFX_DATA_MAP
}


BEGIN_MESSAGE_MAP(Cconfdlg, CDialog)
//{{AFX_MSG_MAP(Cconfdlg)
ON_BN_CLICKED(IDC_BUTTON1, OnBrowse)
ON_BN_CLICKED(IDC_LEARN, OnLearn)
ON_BN_CLICKED(IDC_ANALYZE, OnAnalyze)
ON_BN_CLICKED(IDC_RAW, OnRaw)
ON_BN_CLICKED(IDC_BROWSE, OnBrowse)
ON_BN_CLICKED(IDC_RADIORX, OnRadiorx)
ON_BN_CLICKED(IDC_RADIODCD, OnRadiodcd)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// Cconfdlg message handlers

void Cconfdlg::OnOK()
{
UpdateData();

FILE *tmp;
if(m_filename== " " || (tmp=fopen(m_filename, " r " ))==NULL)
{
MessageBox( " The configuration filename is invalid.\n "
" Please try again. " , " Configuration Error " );
return;
}
fclose(tmp);

WriteSettingsToParent();

if(parent- & gt; config.WriteConfig())
CDialog::OnOK();
else
CDialog::OnCancel();
}

BOOL Cconfdlg::OnInitDialog()
{
CDialog::OnInitDialog();

CComboBox *p=(CComboBox *)GetDlgItem(IDC_PORT);
int x;
if((x=p- & gt; FindStringExact(0,parent- & gt; config.port))!=CB_ERR)
{
p- & gt; SetCurSel(x);
UpdateData();
}
else
{
m_port=parent- & gt; config.port;
}

m_animax=parent- & gt; config.animax;
m_hardcarrier=parent- & gt; config.transmittertype & HARDCARRIER;
m_transmitterpin=(parent- & gt; config.transmittertype & TXTRANSMITTER) & gt; & gt; 1;
m_inverted=(parent- & gt; config.transmittertype & INVERTED) & gt; & gt; 2;
m_filename=parent- & gt; config.conf;
m_speed.Format( " %d " ,parent- & gt; config.speed);
m_devicetype = parent- & gt; config.devicetype;
m_notrayicon = parent- & gt; config.notrayicon;
m_virtpulse = parent- & gt; config.virtpulse;
UpdateData(false);

OnRadiorx();

((CComboBox *)GetDlgItem(IDC_SENSE))- & gt; SetCurSel(parent- & gt; config.sense+1);

return TRUE; // return TRUE unless you set the focus to a control
// EXCEPTION: OCX Property Pages should return FALSE
}

void Cconfdlg::OnBrowse()
{
CFileDialog dlg(TRUE,NULL,NULL,
OFN_HIDEREADONLY|OFN_PATHMUSTEXIST|OFN_NOTESTFILECREATE,
" Configuration Files (*.cfg;*.conf;*.cf;*.rc)|*.cfg;*.conf;*.cf;*.rc|All Files (*.*)|*.*|| " );

if(dlg.DoModal()!=IDOK) return;

UpdateData();
m_filename=dlg.GetPathName();
UpdateData(false);
}

void Cconfdlg::OnLearn()
{
UpdateData();

CWaitCursor foo;

if(m_filename== " " )
{
MessageBox( " The configuration filename is invalid.\n "
" Please enter the name of a non-existent\n "
" file and try again. " , " Error " );
return;
}
FILE *tmp;
if((tmp=fopen(m_filename, " r " ))!=NULL)
{
fclose(tmp);
if(MessageBox( " The configuration file already exists.\n "
" Do you wish to overwrite it? " , " WinLIRC " ,MB_YESNO)==IDNO)
return;
}

if((tmp=fopen(m_filename, " w " ))==NULL)
{
MessageBox( " Cannot create the configuration file.\n "
" Please try again. " , " Error " );
return;
}
fclose(tmp);

WriteSettingsToParent();

parent- & gt; ti.SetIcon(AfxGetApp()- & gt; LoadIcon(IDI_LIRC_INIT), " WinLIRC / Initializing " );

if(parent- & gt; driver.InitPort( & parent- & gt; config,false)==false)
{
parent- & gt; ti.SetIcon(
AfxGetApp()- & gt; LoadIcon(IDI_LIRC_ERROR),
" WinLIRC / Initialization Error " );
MessageBox( " There was an error initializing WinLIRC.\n "
" Please check the port settings and try again.\n " , " Error " );
fclose(tmp);
return;
}

parent- & gt; ti.SetIcon(AfxGetApp()- & gt; LoadIcon(IDI_LIRC_OK), " WinLIRC / Ready " );

Clearndlg dlg( & parent- & gt; driver,m_filename,lm_learn);
int result=dlg.DoModal();
parent- & gt; ti.SetIcon(
AfxGetApp()- & gt; LoadIcon(IDI_LIRC_ERROR),
" WinLIRC / Disabled During Configuration " );
parent- & gt; driver.ResetPort();
if(result==IDOK)
MessageBox( " Don't forget to 'analyze' this data for better performance. " ,
" Remote successfully configured " );
}


void Cconfdlg::OnAnalyze()
{
UpdateData();

CWaitCursor foo;

if(m_filename== " " )
{
MessageBox( " The configuration filename is invalid.\n "
" Please enter the name of an existing\n "
" file and try again. " , " Error " );
return;
}
FILE *tmp;
if((tmp=fopen(m_filename, " r " ))==NULL)
{
MessageBox( " Error opening configuration file. " );
return;
}
fclose(tmp);

Clearndlg dlg( & parent- & gt; driver,m_filename,lm_analyze);
DEBUG( " Analyze DoModal() call\n " );
dlg.DoModal();
DEBUG( " Analyze DoModal() returned\n " );
}

void Cconfdlg::OnRaw()
{
UpdateData();

CWaitCursor foo;

if(m_filename== " " )
{
MessageBox( " The configuration filename is invalid.\n "
" Please enter the name of an existing\n "
" file and try again. " , " Error " );
return;
}

FILE *tmp;
if((tmp=fopen(m_filename, " r " ))==NULL)
{
MessageBox( " Error opening configuration file. " );
return;
}
fclose(tmp);

WriteSettingsToParent();

parent- & gt; ti.SetIcon(AfxGetApp()- & gt; LoadIcon(IDI_LIRC_INIT), " WinLIRC / Initializing " );

if(parent- & gt; driver.InitPort( & parent- & gt; config,false)==false)
{
parent- & gt; ti.SetIcon(
AfxGetApp()- & gt; LoadIcon(IDI_LIRC_ERROR),
" WinLIRC / Initialization Error " );
MessageBox( " There was an error initializing WinLIRC.\n "
" Please check the port settings and try again.\n " , " Error " );
return;
}

parent- & gt; ti.SetIcon(AfxGetApp()- & gt; LoadIcon(IDI_LIRC_OK), " WinLIRC / Ready " );

Clearndlg dlg( & parent- & gt; driver,m_filename,lm_raw);
int result=dlg.DoModal();
parent- & gt; ti.SetIcon(
AfxGetApp()- & gt; LoadIcon(IDI_LIRC_ERROR),
" WinLIRC / Disabled During Configuration " );
parent- & gt; driver.ResetPort();
}

void Cconfdlg::OnRadiorx()
{
UpdateData(TRUE);
GetDlgItem(IDC_SENSE)- & gt; EnableWindow(m_devicetype);
GetDlgItem(IDC_VIRTPULSE)- & gt; EnableWindow(!m_devicetype);
GetDlgItem(IDC_CHECKANIMAX)- & gt; EnableWindow(m_devicetype);
}

void Cconfdlg::OnRadiodcd()
{
OnRadiorx();
}

void Cconfdlg::WriteSettingsToParent()
{
parent- & gt; config.port=m_port;
parent- & gt; config.animax=m_animax;
parent- & gt; config.transmittertype=(m_inverted & lt; & lt; 2)|(m_transmitterpin & lt; & lt; 1)|m_hardcarrier;
parent- & gt; config.conf=m_filename;
int sense=((CComboBox *)GetDlgItem(IDC_SENSE))- & gt; GetCurSel();
if(sense & gt; =1 & & sense & lt; =2) sense--;
else sense=-1;
parent- & gt; config.sense=sense;

parent- & gt; config.speed = atoi(m_speed);
parent- & gt; config.devicetype = m_devicetype;
parent- & gt; config.notrayicon = m_notrayicon;
parent- & gt; config.virtpulse = m_virtpulse;
}


winlirc-0.6.5.zip > transmit.cpp

int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
LRESULT copyDataResult;
HWND pOtherWnd = FindWindow(NULL, " WinLirc " );
if (pOtherWnd)
{
COPYDATASTRUCT cpd;
cpd.dwData = 0;
cpd.cbData = strlen(lpCmdLine);
cpd.lpData = (void*)lpCmdLine;
copyDataResult = SendMessage(pOtherWnd,WM_COPYDATA,(WPARAM)hInstance,(LPARAM) & cpd);
// copyDataResult has value returned by other app
}
else
{
return 1;
}
return 0;
}


winlirc-0.6.5.zip > confdlg.h

/*
* This file is part of the WinLIRC package, which was derived from
* LIRC (Linux Infrared Remote Control) 0.5.4pre9.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published
* by the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* Copyright (C) 1999 Jim Paris & lt; jim@jtan.com & gt;
* RX device, some other stuff Copyright (C) 2002 Alexander Nesterovsky & lt; Nsky@users.sourceforge.net & gt;
*/

#if !defined(AFX_CONFDLG_H__768417C3_C8E5_11D2_8C7F_004005637418__INCLUDED_)
#define AFX_CONFDLG_H__768417C3_C8E5_11D2_8C7F_004005637418__INCLUDED_

#if _MSC_VER & gt; 1000
#pragma once
#endif // _MSC_VER & gt; 1000
// confdlg.h : header file
//

#include " globals.h "

#include " irconfig.h "
#include " drvdlg.h "

/////////////////////////////////////////////////////////////////////////////
// Cconfdlg dialog

class Cconfdlg : public CDialog
{
// Construction
public:
Cconfdlg(Cdrvdlg *nparent, CWnd* pParent = NULL);
void WriteSettingsToParent();

Cdrvdlg *parent;

// Dialog Data
//{{AFX_DATA(Cconfdlg)
enum { IDD = IDD_CONFIG };
CString m_port;
CString m_filename;
BOOL m_animax;
BOOL m_notrayicon;
int m_devicetype;
CString m_speed;
int m_virtpulse;
int m_transmitterpin;
BOOL m_hardcarrier;
BOOL m_inverted;
//}}AFX_DATA


// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(Cconfdlg)
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
//}}AFX_VIRTUAL

// Implementation
protected:

// Generated message map functions
//{{AFX_MSG(Cconfdlg)
virtual void OnOK();
virtual BOOL OnInitDialog();
afx_msg void OnBrowse();
afx_msg void OnLearn();
afx_msg void OnAnalyze();
afx_msg void OnRaw();
afx_msg void OnRadiorx();
afx_msg void OnRadiodcd();
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};

//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.

#endif // !defined(AFX_CONFDLG_H__768417C3_C8E5_11D2_8C7F_004005637418__INCLUDED_)


winlirc-0.6.5.zip > changes.txt

new in version 0.6.5
--------------------
Added support for all documented aspects of the LIRC TCP/IP protocol,
except that SEND_START and SEND_STOP are not supported. For full
compatibility, set the transmit password to " SEND_ONCE " . The password
is no longer case sensitive. Clients are now notified about
reconfiguration, etc.

Bugfixes:
Fixed LONG_IR_CODE
Fixed gap length for transmitting remotes with CONST_LENGTH
Transmitter type is now set correctly for the last remote in the config file

new in version 0.6.4
--------------------
advanced power management support

The TCP port for the server is now configurable via a registry key.
-use regedit to add a new DWORD value to software\LIRC
- name it " tcp_port " set the value to whatever port you want.
- winlirc will use this new value the next time it is restarted.

added an inverted option for the transmitters (not used for TX softcarrier)
-this swaps the definition of on and off states.
-this makes it possible to support pioneer SR control by wire
(and possibly sony S-Link)

the number of pre and post data bits now break evenly into hexidecimal
(so the config files will be easier to read).

buttons can now be named " begin " or " end "
(this will be allowed in future versions of lirc as well)

config files support a " transmitter " field for the remote
if the SPECIAL_TRANSMITTER flag is specified, then the transmitter type
will override the default settings (but only for that remote).
-LIRC does not support these settings, and winlirc will not write this data to
the config files it creates
-this means you can have a different type of transmitter for each remote.
-to use add |SPECIAL_TRANSMITTER to the flags section then add the line
transmitter & lt; type & gt;
where & lt; type & gt; is the same value used in software\LIRC\transmittertype when
configured for the transmitter you want.
e.g., transmitter 0x05 uses INVERTED HARDWARE_CARRIER DTR

bugfixes:
fixed all known crashing bugs in windows NT/2000/XP.
possible lockup when exiting raw codes mode is eliminated.
restored the yellow light on initialization.
closes some file handles that were previously left open.
the tx transmitter supports longer pulses
toggle_bits are now transmitted correctly
scrolling output windows now remove about 100 lines at a time when filling up

new in version 0.6.3
--------------------
RX device support
No tray icon option
tx transmitter support
hard carrier transmitter support
RC-6 support
RC-MM support (receive only)
bugfixes:
detects RC-5 codes that start with 1
lets codes from raw remotes be sent from other applications

new in version 0.6.2
--------------------
fixed bug where server expects the LIRC key to exist and fails to start.

new in version 0.6.1pre3
-------------------------------
The " animax " serial port receiver is now supported. This receiver uses DTR and RTS pin for power. If you have an animax receiver, check the animax box at the configuration screen. Note that animax receivers are incompatible with the current winlirc transmitter.

You can now tell WinLIRC to transmit codes from the TCP/IP port
The format is:
password remotename codename reps
(just like transmit.exe, but with a password in front). To enable this, you need to use regedit to add a key software\LIRC\password it should be a string that contains no spaces or tabs. If the password key is not set, or the password is wrong WinLIRC won't accept commands from the TCP interface

WinLIRC can now transmit codes from raw (unanalyzed) remotes.

Hopefully, the win2k/xp crashes are gone.

Some user interface improvements.


winlirc-0.6.5.zip > dumpcfg.cpp

/*
* This file is part of the WinLIRC package, which was derived from
* LIRC (Linux Infrared Remote Control) 0.5.4pre9.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published
* by the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* Copyright (C) 1998 Pablo d'Angelo & lt; pablo@ag-trek.allgaeu.org & gt;
* Copyright (C) 1999 Jim Paris & lt; jim@jtan.com & gt;
* RX device, some other stuff Copyright (C) 2002 Alexander Nesterovsky & lt; Nsky@users.sourceforge.net & gt;
*/

#include " dumpcfg.h "
#include " config.h "
#include " remote.h "
#include " globals.h "

void fprint_comment(FILE *f,struct ir_remote *rem)
{
time_t timet;
struct tm *tmp;

timet=time(NULL);
tmp=localtime( & timet);
fprintf(f,
" #\n "
" # this config file was automatically generated\n "
" # using %s on %s "
" #\n "
" # contributed by \n "
" #\n "
" # brand: %s\n "
" # model: \n "
" # supported devices: \n "
" #\n\n " ,LIRC_VERSION,asctime(tmp),
rem- & gt; name);
}

void fprint_flags(FILE *f, int flags)
{
int i;
int begin=0;

for(i=0;i & lt; NR_FLAGS;i++)
{
if(flags & all_flags[i].flag)
{
if(begin==0) fprintf(f, " flags " );
else if(begin==1) fprintf(f, " | " );
fprintf(f, " %s " ,all_flags[i].name);
begin=1;
}
}
if(begin==1) fprintf(f, " \n " );
}

void fprint_remotes(FILE *f, struct ir_remote *all){

while(all)
{
fprint_remote(f, all);
fprintf(f, " \n\n " );
all=all- & gt; next;
}
}

void fprint_remote_head(FILE *f, struct ir_remote *rem)
{
fprintf(f, " begin remote\n\n " );
if(!is_raw(rem)){
fprintf(f, " name %s\n " ,rem- & gt; name);
fprintf(f, " bits %5d\n " ,rem- & gt; bits);
fprint_flags(f,rem- & gt; flags);
fprintf(f, " eps %5d\n " ,rem- & gt; eps);
fprintf(f, " aeps %5d\n\n " ,rem- & gt; aeps);
if(has_header(rem))
{
fprintf(f, " header %5d %5d\n " ,
rem- & gt; phead, rem- & gt; shead);
}
fprintf(f, " one %5d %5d\n " ,rem- & gt; pone, rem- & gt; sone);
fprintf(f, " zero %5d %5d\n " ,rem- & gt; pzero, rem- & gt; szero);
if(rem- & gt; ptrail!=0)
{
fprintf(f, " ptrail %5d\n " ,rem- & gt; ptrail);
}
if(rem- & gt; plead!=0)
{
fprintf(f, " plead %5d\n " ,rem- & gt; plead);
}
if(has_foot(rem))
{
fprintf(f, " foot %5d %5d\n " ,
rem- & gt; pfoot, rem- & gt; sfoot);
}
if(has_repeat(rem))
{
fprintf(f, " repeat %5d %5d\n " ,
rem- & gt; prepeat, rem- & gt; srepeat);
}
if(rem- & gt; pre_data_bits & gt; 0)
{
fprintf(f, " pre_data_bits %d\n " ,rem- & gt; pre_data_bits);
# ifdef LONG_IR_CODE
fprintf(f, " pre_data 0x%I64X\n " ,rem- & gt; pre_data);
# else
fprintf(f, " pre_data 0x%lX\n " ,rem- & gt; pre_data);
# endif
}
if(rem- & gt; post_data_bits & gt; 0)
{
fprintf(f, " post_data_bits %d\n " ,rem- & gt; post_data_bits);
# ifdef LONG_IR_CODE
fprintf(f, " post_data 0x%I64X\n " ,rem- & gt; post_data);
# else
fprintf(f, " post_data 0x%lX\n " ,rem- & gt; post_data);
# endif
}
if(rem- & gt; pre_p!=0 & & rem- & gt; pre_s!=0)
{
fprintf(f, " pre %5d %5d\n " ,
rem- & gt; pre_p, rem- & gt; pre_s);
}
if(rem- & gt; post_p!=0 & & rem- & gt; post_s!=0)
{
fprintf(f, " post %5d %5d\n " ,
rem- & gt; post_p, rem- & gt; post_s);
}
fprintf(f, " gap %lu\n " ,rem- & gt; gap);
if(has_repeat_gap(rem))
{
fprintf(f, " repeat_gap %lu\n " ,rem- & gt; repeat_gap);
}
if(rem- & gt; min_repeat & gt; 0)
{
fprintf(f, " min_repeat %d\n " ,rem- & gt; min_repeat);
}
fprintf(f, " toggle_bit %d\n\n " ,rem- & gt; toggle_bit);
}
else
{
fprintf(f, " name %s\n " ,rem- & gt; name);
fprint_flags(f,rem- & gt; flags);
fprintf(f, " eps %5d\n " ,rem- & gt; eps);
fprintf(f, " aeps %5d\n\n " ,rem- & gt; aeps);
fprintf(f, " ptrail %5d\n " ,rem- & gt; ptrail);
fprintf(f, " repeat %5d %5d\n " ,rem- & gt; prepeat, rem- & gt; srepeat);
fprintf(f, " gap %lu\n\n " ,rem- & gt; gap);
}
if(rem- & gt; freq!=0)
{
fprintf(f, " frequency %u\n " ,rem- & gt; freq);
}
if(rem- & gt; duty_cycle!=0)
{
fprintf(f, " duty_cycle %u\n " ,rem- & gt; duty_cycle);
}
fprintf(f, " \n " );
}

void fprint_remote_foot(FILE *f, struct ir_remote *rem)
{
fprintf(f, " end remote\n " );
}

void fprint_remote_signal_head(FILE *f, struct ir_remote *rem)
{
if(!is_raw(rem))
fprintf(f, " begin codes\n " );
else
fprintf(f, " begin raw_codes\n\n " );
}

void fprint_remote_signal_foot(FILE *f, struct ir_remote *rem)
{
if(!is_raw(rem))
fprintf(f, " end codes\n\n " );
else
fprintf(f, " end raw_codes\n\n " );
}

void fprint_remote_signal(FILE *f,struct ir_remote *rem, struct ir_ncode *codes)
{
int i,j;

if(!is_raw(rem))
{
# ifdef LONG_IR_CODE
fprintf(f, " %-24s 0x%016I64X\n " ,codes- & gt; name, codes- & gt; code);
# else
fprintf(f, " %-24s 0x%016lX\n " ,codes- & gt; name, codes- & gt; code);
# endif
}
else
{
fprintf(f, " name %s\n " ,codes- & gt; name);
j=0;
for(i=0;i & lt; codes- & gt; length;i++){
if (j==0){
fprintf(f, " %7lu " ,codes- & gt; signals[i]);
}else if (j & lt; 5){
fprintf(f, " %7lu " ,codes- & gt; signals[i]);
}else{
fprintf(f, " %7lu\n " ,codes- & gt; signals[i]);
j=-1;
}
j++;
}
codes++;
if (j==0)
{
fprintf(f, " \n " );
}else
{
fprintf(f, " \n\n " );
j=0;
}
}
}

void fprint_remote_signals(FILE *f, struct ir_remote *rem)
{
struct ir_ncode *codes;

fprint_remote_signal_head(f,rem);
codes=rem- & gt; codes;
while(codes- & gt; name!=NULL)
{
fprint_remote_signal(f,rem,codes);
codes++;
}
fprint_remote_signal_foot(f,rem);
}


void fprint_remote(FILE *f, struct ir_remote *rem)
{
fprint_comment(f,rem);
fprint_remote_head(f,rem);
fprint_remote_signals(f,rem);
fprint_remote_foot(f,rem);
}

void fprint_copyright(FILE *fout)
{
/* As this program is distributed under GPL you could just
remove this copyright notice and the config files generated
with the modified program would automatically be covered by
the GPL. Although I am aware of this I will not prevent it.

I hope that nobody will do so because the license I put on
the config files is not really a restriction. Instead it
emphasizes the spirit of the GPL to make things available
to everybody. */

fprintf(fout,
" \n "
" # Copyright (C) 1999 Christoph Bartelmus\n "
" #\n "
" # You may only use this file if you make it available to others,\n "
" # i.e. if you send it to & lt; lirc@bartelmus.de & gt; \n " );
}


winlirc-0.6.5.zip > server.h

/*
* This file is part of the WinLIRC package, which was derived from
* LIRC (Linux Infrared Remote Control) 0.5.4pre9.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published
* by the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* Copyright (C) 1999 Jim Paris & lt; jim@jtan.com & gt;
*/

#ifndef SERVER__H
#define SERVER__H

#include " globals.h "

#include " stdafx.h "
#include " winlirc.h "
#include " drvdlg.h "
#include " irdriver.h "
#include & lt; atlbase.h & gt; //password stuff


class Cserver {
public:

Cserver();
~Cserver();

bool startserver(void);
void stopserver(void);

bool init(void);
void send(const char *s);

void ThreadProc(void);

private:
void reply(const char *command,int client,bool success,const char *data);
SOCKET server;
SOCKET clients[MAX_CLIENTS];
CString password; //password for transmission
int tcp_port; //tcp port for server
};

#endif