📄 remote.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) 1996,97 Ralph Metzler (rjkm@thp.uni-koeln.de)
* Copyright (C) 1998 Christoph Bartelmus (columbus@hit.handshake.de)
* Copyright (C) 1999 Jim Paris <jim@jtan.com>
* Copyright (C) 2002 Scott Baily <baily@uiuc.edu>
*/
#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
#include <sys/timeb.h>
#include "remote.h"
#include "irdriver.h"
#include "learndlg.h"
#include "globals.h"
int gettimeofday(struct mytimeval *a, void *)
/* only accurate to milliseconds, instead of microseconds */
{
struct _timeb tstruct;
_ftime(&tstruct);
a->tv_sec=tstruct.time;
a->tv_usec=tstruct.millitm*1000;
return 1;
}
struct ir_remote *get_ir_remote(char *name)
{
CSingleLock lock(&CS_global_remotes,TRUE);
struct ir_remote *all;
/* use remotes carefully, it may be changed on SIGHUP */
all=global_remotes;
while(all)
{
if(strcasecmp(all->name,name)==0)
{
return(all);
}
all=all->next;
}
return(NULL);
}
struct ir_ncode *get_ir_code(struct ir_remote *remote,char *name)
{
struct ir_ncode *all;
all=remote->codes;
while(all->name!=NULL)
{
if(strcasecmp(all->name,name)==0)
{
return(all);
}
all++;
}
return(0);
}
inline ir_code reverse(ir_code data,int bits)
{
int i;
ir_code c;
c=0;
for(i=0;i<bits;i++)
{
c|=(ir_code) (((data & (((ir_code) 1)<<i)) ? 1:0))
<< (bits-1-i);
}
return(c);
}
inline void set_bit(ir_code *code,int bit,int data)
{
(*code)&=~((((ir_code) 1)<<bit));
(*code)|=((ir_code) (data ? 1:0)<<bit);
}
/*
sending stuff
inline unsigned long time_left(struct mytimeval *current,struct mytimeval *last,
unsigned long gap)
{
unsigned long secs,usecs,diff;
secs=current->tv_sec-last->tv_sec;
usecs=current->tv_usec-last->tv_usec;
diff=1000000*secs+usecs;
return(diff<gap ? gap-diff:0);
}
inline void clear_send_buffer(void)
{
send_buffer.wptr=0;
send_buffer.too_long=0;
send_buffer.is_biphase=0;
send_buffer.pendingp=0;
send_buffer.pendings=0;
send_buffer.sum=0;
}
inline void add_send_buffer(unsigned long data)
{
if(send_buffer.wptr<WBUF_SIZE)
{
send_buffer.sum+=data;
send_buffer.data[send_buffer.wptr]=data;
send_buffer.wptr++;
}
else
{
send_buffer.too_long=1;
}
}
inline void send_pulse(unsigned long data)
{
if(send_buffer.pendingp>0)
{
send_buffer.pendingp+=data;
}
else
{
if(send_buffer.pendings>0)
{
add_send_buffer(send_buffer.pendings);
send_buffer.pendings=0;
}
send_buffer.pendingp=data;
}
}
inline void send_space(unsigned long data)
{
if(send_buffer.wptr==0 && send_buffer.pendingp==0)
{
#ifdef __DEBUG
logprintf("first signal is a space!\n");
#endif
return;
}
if(send_buffer.pendings>0)
{
send_buffer.pendings+=data;
}
else
{
if(send_buffer.pendingp>0)
{
add_send_buffer(send_buffer.pendingp);
send_buffer.pendingp=0;
}
send_buffer.pendings=data;
}
}
inline int bad_send_buffer(void)
{
if(send_buffer.too_long!=0) return(1);
if(send_buffer.is_shift==1)
{
if(send_buffer.wptr==WBUF_SIZE && send_buffer.pendingp>0)
{
return(1);
}
}
return(0);
}
int write_send_buffer(int length,unsigned long *signals)
{
#if defined(SIM_SEND) && !defined(DAEMONIZE)
int i;
if(send_buffer.wptr==0 && length>0 && signals!=NULL)
{
for(i=0;;)
{
printf("pulse %ld\n",signals[i++]);
if(i>=length) break;
printf("space %ld\n",signals[i++]);
}
return(length*sizeof(unsigned long));
}
if(send_buffer.pendingp>0)
{
add_send_buffer(send_buffer.pendingp);
send_buffer.pendingp=0;
}
if(send_buffer.wptr==0)
{
# ifdef __DEBUG
logprintf("nothing to send\n");
# endif __DEBUG
return(0);
}
if(send_buffer.wptr%2==0) send_buffer.wptr--;
for(i=0;;)
{
printf("pulse %ld\n",send_buffer.data[i++]);
if(i>=send_buffer.wptr) break;
printf("space %ld\n",send_buffer.data[i++]);
}
return(send_buffer.wptr*sizeof(unsigned long));
#else
if(send_buffer.wptr==0 && length>0 && signals!=NULL)
{
return(write(lirc,signals,length*sizeof(unsigned long)));
}
if(send_buffer.pendingp>0)
{
add_send_buffer(send_buffer.pendingp);
send_buffer.pendingp=0;
}
if(send_buffer.wptr==0)
{
# ifdef __DEBUG
logprintf("nothing to send\n");
# endif __DEBUG
return(0);
}
if(send_buffer.wptr%2==0) send_buffer.wptr--;
return(write(lirc,send_buffer.data,
send_buffer.wptr*sizeof(unsigned long)));
#endif
}
*/
void on_dtr(void)
{
EscapeCommFunction(tPort,SETDTR);
}
void off_dtr(void)
{
EscapeCommFunction(tPort,CLRDTR);
}
void on_tx(void)
{
SetCommBreak(tPort);
}
void off_tx_hard(void)
{
ClearCommBreak(tPort);
}
void off_tx_soft(void){;};
int init_timer()
{
if (!QueryPerformanceFrequency((LARGE_INTEGER*)&freq))
return (-1); // error hardware doesn't support performance counter
QueryPerformanceCounter((LARGE_INTEGER*)&lasttime);
return(0);
}
int send_pulse_dtr_soft (unsigned long usecs)
{
__int64 end;
end= lasttime + usecs * freq / 1000000;
do
{
on();
uwait(pulse_width);
off();
uwait(space_width);
} while (lasttime < end);
return(1);
}
int send_space_hard_or_dtr(unsigned long length)
{
if(length==0) return(1);
off();
uwait(length);
return(1);
}
int send_pulse_hard (unsigned long length)
{
if(length==0) return(1);
on();
uwait(length);
return(1);
}
int send_pulse_tx_soft (unsigned long usecs)
{
lasttime+=usecs * freq / 1000000;
OVERLAPPED osWrite = {0};
DWORD dwWritten;
BOOL fRes;
DWORD dwToWrite=usecs/pulse_byte_length;
// Create this writes OVERLAPPED structure hEvent.
osWrite.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
if (osWrite.hEvent == NULL)
// Error creating overlapped event handle.
return FALSE;
// Issue write.
if (!WriteFile(tPort, pulsedata, dwToWrite, &dwWritten, &osWrite)) {
if (GetLastError() != ERROR_IO_PENDING) {
// WriteFile failed, but it isn't delayed. Report error and abort.
fRes = FALSE;
}
else {
// Write is pending.
if (!GetOverlappedResult(tPort, &osWrite, &dwWritten, TRUE))
fRes = FALSE;
else
// Write operation completed successfully.
fRes = TRUE;
}
}
else
// WriteFile completed immediately.
fRes = TRUE;
CloseHandle(osWrite.hEvent);
return(fRes);
}
int send_space_tx_soft(unsigned long length)
{
if(length==0) return(1);
uwait(length);
return(1);
}
inline void send_header(struct ir_remote *remote)
{
if(has_header(remote))
{
send_pulse(remote->phead);
send_space(remote->shead);
}
}
inline void send_foot(struct ir_remote *remote)
{
if(has_foot(remote))
{
send_space(remote->sfoot);
send_pulse(remote->pfoot);
}
}
inline void send_lead(struct ir_remote *remote)
{
if(remote->plead!=0)
{
send_pulse(remote->plead);
}
}
inline void send_trail(struct ir_remote *remote)
{
if(remote->ptrail!=0)
{
send_pulse(remote->ptrail);
}
}
inline void send_data(struct ir_remote *remote,ir_code data,int bits)
{
int i;
if(!(remote->flags&REVERSE)) data=reverse(data,bits);
for(i=0;i<bits;i++)
{
if(data&1)
{
if(is_biphase(remote))
{
if(is_rc6(remote) && i+1==remote->toggle_bit)
{
send_space(2*remote->sone);
send_pulse(2*remote->pone);
}
else
{
send_space(remote->sone);
send_pulse(remote->pone);
}
}
else
{
send_pulse(remote->pone);
send_space(remote->sone);
}
}
else
{
if(is_rc6(remote) && i+1==remote->toggle_bit)
{
send_pulse(2*remote->pzero);
send_space(2*remote->szero);
}
else
{
send_pulse(remote->pzero);
send_space(remote->szero);
}
}
data=data>>1;
}
}
inline void send_pre(struct ir_remote *remote)
{
if(has_pre(remote))
{
ir_code pre;
pre=remote->pre_data;
if(remote->toggle_bit>0)
{
if(remote->toggle_bit<=remote->pre_data_bits)
{
set_bit(&pre,
remote->pre_data_bits
-remote->toggle_bit,
remote->repeat_state);
}
}
send_data(remote,pre,remote->pre_data_bits);
if(remote->pre_p>0 && remote->pre_s>0)
{
send_pulse(remote->pre_p);
send_space(remote->pre_s);
}
}
}
inline void send_post(struct ir_remote *remote)
{
if(has_post(remote))
{
ir_code post;
post=remote->post_data;
if(remote->toggle_bit>0)
{
if(remote->toggle_bit>remote->pre_data_bits
+remote->bits
&&
remote->toggle_bit<=remote->pre_data_bits
+remote->bits
+remote->post_data_bits)
{
set_bit(&post,
remote->pre_data_bits
+remote->bits
+remote->post_data_bits
-remote->toggle_bit,
remote->repeat_state);
}
}
if(remote->post_p>0 && remote->post_s>0)
{
send_pulse(remote->post_p);
send_space(remote->post_s);
}
send_data(remote,post,remote->post_data_bits);
}
}
inline void send_repeat(struct ir_remote *remote)
{
send_lead(remote);
send_pulse(remote->prepeat);
send_space(remote->srepeat);
send_trail(remote);
}
inline void send_code(struct ir_remote *remote,ir_code code)
{
if(remote->toggle_bit>0)
{
if(remote->toggle_bit>remote->pre_data_bits
&&
remote->toggle_bit<=remote->pre_data_bits
+remote->bits)
{
set_bit(&code,
remote->pre_data_bits
+remote->bits
-remote->toggle_bit,
remote->repeat_state);
}
else if(remote->toggle_bit>remote->pre_data_bits
+remote->bits
+remote->post_data_bits)
{
//logprintf("bad toggle_bit\n");
}
}
if(repeat_remote==NULL || !(remote->flags&NO_HEAD_REP))
send_header(remote);
send_lead(remote);
send_pre(remote);
send_data(remote,code,remote->bits);
send_post(remote);
send_trail(remote);
if(repeat_remote==NULL || !(remote->flags&NO_FOOT_REP))
send_foot(remote);
}
int init_send(struct ir_remote *remote,struct ir_ncode *code)
{
__int64 start;
start=lasttime;
if(is_rcmm(remote))
{
# ifdef __DEBUG
logprintf(LOG_ERR,"sorry, can't send this protocol yet");
# endif
return(0);
}
if(repeat_remote!=NULL && has_repeat(remote))
{
if(remote->flags&REPEAT_HEADER && has_header(remote))
{
send_header(remote);
}
send_repeat(remote);
}
else
{
if(!is_raw(remote))
{
send_code(remote,code->code);
}
else
{
send(code->signals,code->length);
}
}
if(is_const(remote))
{
remote->remaining_gap=remote->gap - (lasttime - start) * 1000000 / freq;
}
else
{
if(has_repeat_gap(remote) &&
repeat_remote!=NULL &&
has_repeat(remote))
{
remote->remaining_gap=remote->repeat_gap;
}
else
{
remote->remaining_gap=remote->gap;
}
}
return(1);
}
void SetTransmitPort(HANDLE hCom,unsigned type) // sets the serial port to transmit on
{
tPort=hCom;
void (*tmp) (void);
switch (type%4)
{
case HARDCARRIER|TXTRANSMITTER: //tx hard carrier
on=on_tx;
off=off_tx_hard;
send_pulse=send_pulse_hard;
send_space=send_space_hard_or_dtr;
break;
case HARDCARRIER: //dtr hard carrier
on=on_dtr;
off=off_dtr;
send_pulse=send_pulse_hard;
send_space=send_space_hard_or_dtr;
break;
case TXTRANSMITTER: //tx soft carrier
on=off_tx_soft;
off=off_tx_soft;
send_pulse=send_pulse_tx_soft;
send_space=send_space_tx_soft;
break;
default: //dtr soft carrier
on=on_dtr;
off=off_dtr;
send_pulse=send_pulse_dtr_soft;
send_space=send_space_hard_or_dtr;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -