diff -Nru v4l-utils-1.10.0+r3508/contrib/freebsd/include/linux/input-event-codes.h v4l-utils-1.10.0+r3520/contrib/freebsd/include/linux/input-event-codes.h --- v4l-utils-1.10.0+r3508/contrib/freebsd/include/linux/input-event-codes.h 2017-12-13 17:01:40.000000000 +0000 +++ v4l-utils-1.10.0+r3520/contrib/freebsd/include/linux/input-event-codes.h 2017-12-14 17:01:56.000000000 +0000 @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * Input event codes * @@ -406,6 +407,7 @@ #define BTN_TOOL_MOUSE 0x146 #define BTN_TOOL_LENS 0x147 #define BTN_TOOL_QUINTTAP 0x148 /* Five fingers on trackpad */ +#define BTN_STYLUS3 0x149 #define BTN_TOUCH 0x14a #define BTN_STYLUS 0x14b #define BTN_STYLUS2 0x14c diff -Nru v4l-utils-1.10.0+r3508/contrib/freebsd/include/linux/input.h v4l-utils-1.10.0+r3520/contrib/freebsd/include/linux/input.h --- v4l-utils-1.10.0+r3508/contrib/freebsd/include/linux/input.h 2017-12-13 17:01:40.000000000 +0000 +++ v4l-utils-1.10.0+r3520/contrib/freebsd/include/linux/input.h 2017-12-14 17:01:56.000000000 +0000 @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * Copyright (c) 1999-2002 Vojtech Pavlik * diff -Nru v4l-utils-1.10.0+r3508/contrib/freebsd/include/linux/ivtv.h v4l-utils-1.10.0+r3520/contrib/freebsd/include/linux/ivtv.h --- v4l-utils-1.10.0+r3508/contrib/freebsd/include/linux/ivtv.h 2017-12-13 17:01:40.000000000 +0000 +++ v4l-utils-1.10.0+r3520/contrib/freebsd/include/linux/ivtv.h 2017-12-14 17:01:56.000000000 +0000 @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */ /* Public ivtv API header Copyright (C) 2003-2004 Kevin Thayer diff -Nru v4l-utils-1.10.0+r3508/contrib/freebsd/include/linux/uinput.h v4l-utils-1.10.0+r3520/contrib/freebsd/include/linux/uinput.h --- v4l-utils-1.10.0+r3508/contrib/freebsd/include/linux/uinput.h 2017-12-13 17:01:40.000000000 +0000 +++ v4l-utils-1.10.0+r3520/contrib/freebsd/include/linux/uinput.h 2017-12-14 17:01:56.000000000 +0000 @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */ /* * User level driver support for input subsystem * diff -Nru v4l-utils-1.10.0+r3508/contrib/freebsd/include/linux/v4l2-common.h v4l-utils-1.10.0+r3520/contrib/freebsd/include/linux/v4l2-common.h --- v4l-utils-1.10.0+r3508/contrib/freebsd/include/linux/v4l2-common.h 2017-12-13 17:01:40.000000000 +0000 +++ v4l-utils-1.10.0+r3520/contrib/freebsd/include/linux/v4l2-common.h 2017-12-14 17:01:56.000000000 +0000 @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: ((GPL-2.0+ WITH Linux-syscall-note) OR BSD-3-Clause) */ /* * include/linux/v4l2-common.h * diff -Nru v4l-utils-1.10.0+r3508/contrib/freebsd/include/linux/v4l2-controls.h v4l-utils-1.10.0+r3520/contrib/freebsd/include/linux/v4l2-controls.h --- v4l-utils-1.10.0+r3508/contrib/freebsd/include/linux/v4l2-controls.h 2017-12-13 17:01:40.000000000 +0000 +++ v4l-utils-1.10.0+r3520/contrib/freebsd/include/linux/v4l2-controls.h 2017-12-14 17:01:56.000000000 +0000 @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: ((GPL-2.0+ WITH Linux-syscall-note) OR BSD-3-Clause) */ /* * Video for Linux Two controls header file * diff -Nru v4l-utils-1.10.0+r3508/contrib/freebsd/include/linux/videodev2.h v4l-utils-1.10.0+r3520/contrib/freebsd/include/linux/videodev2.h --- v4l-utils-1.10.0+r3508/contrib/freebsd/include/linux/videodev2.h 2017-12-13 17:01:40.000000000 +0000 +++ v4l-utils-1.10.0+r3520/contrib/freebsd/include/linux/videodev2.h 2017-12-14 17:01:56.000000000 +0000 @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: ((GPL-2.0+ WITH Linux-syscall-note) OR BSD-3-Clause) */ /* * Video for Linux Two header file * diff -Nru v4l-utils-1.10.0+r3508/contrib/xc3028-firmware/tuner-xc2028-types.h v4l-utils-1.10.0+r3520/contrib/xc3028-firmware/tuner-xc2028-types.h --- v4l-utils-1.10.0+r3508/contrib/xc3028-firmware/tuner-xc2028-types.h 2017-12-13 17:01:40.000000000 +0000 +++ v4l-utils-1.10.0+r3520/contrib/xc3028-firmware/tuner-xc2028-types.h 2017-12-14 17:01:56.000000000 +0000 @@ -1,10 +1,11 @@ -/* tuner-xc2028_types +/* + * SPDX-License-Identifier: GPL-2.0 + * tuner-xc2028_types * * This file includes internal tipes to be used inside tuner-xc2028. * Shouldn't be included outside tuner-xc2028 * * Copyright (c) 2007-2008 Mauro Carvalho Chehab (mchehab@infradead.org) - * This code is placed under the terms of the GNU General Public License v2 */ /* xc3028 firmware types */ diff -Nru v4l-utils-1.10.0+r3508/debian/bzr-builder.manifest v4l-utils-1.10.0+r3520/debian/bzr-builder.manifest --- v4l-utils-1.10.0+r3508/debian/bzr-builder.manifest 2017-12-13 17:01:41.000000000 +0000 +++ v4l-utils-1.10.0+r3520/debian/bzr-builder.manifest 2017-12-14 17:01:58.000000000 +0000 @@ -1,3 +1,3 @@ -# bzr-builder format 0.3 deb-version {debupstream}+r3508-71 -lp:libv4l revid:git-v1:06177db29466bebcceb43d6aaffd859bfd35e42a +# bzr-builder format 0.3 deb-version {debupstream}+r3520-71 +lp:libv4l revid:git-v1:3561d59c1adf5faf3e29e9fd103ca5d8d4e855d4 nest packaging lp:~libv4l/+junk/packaging debian revid:gjasny@googlemail.com-20160320110140-z8p5e9zmhomgtciv diff -Nru v4l-utils-1.10.0+r3508/debian/changelog v4l-utils-1.10.0+r3520/debian/changelog --- v4l-utils-1.10.0+r3508/debian/changelog 2017-12-13 17:01:41.000000000 +0000 +++ v4l-utils-1.10.0+r3520/debian/changelog 2017-12-14 17:01:58.000000000 +0000 @@ -1,8 +1,8 @@ -v4l-utils (1.10.0+r3508-71~ubuntu12.04.1) precise; urgency=low +v4l-utils (1.10.0+r3520-71~ubuntu12.04.1) precise; urgency=low * Auto build. - -- Launchpad Package Builder Wed, 13 Dec 2017 17:01:41 +0000 + -- Launchpad Package Builder Thu, 14 Dec 2017 17:01:58 +0000 v4l-utils (1.10.0-2) unstable; urgency=low diff -Nru v4l-utils-1.10.0+r3508/include/linux/cec-funcs.h v4l-utils-1.10.0+r3520/include/linux/cec-funcs.h --- v4l-utils-1.10.0+r3508/include/linux/cec-funcs.h 2017-12-13 17:01:40.000000000 +0000 +++ v4l-utils-1.10.0+r3520/include/linux/cec-funcs.h 2017-12-14 17:01:56.000000000 +0000 @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR BSD-3-Clause) */ /* * cec - HDMI Consumer Electronics Control message functions * diff -Nru v4l-utils-1.10.0+r3508/include/linux/cec.h v4l-utils-1.10.0+r3520/include/linux/cec.h --- v4l-utils-1.10.0+r3508/include/linux/cec.h 2017-12-13 17:01:40.000000000 +0000 +++ v4l-utils-1.10.0+r3520/include/linux/cec.h 2017-12-14 17:01:56.000000000 +0000 @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR BSD-3-Clause) */ /* * cec - HDMI Consumer Electronics Control public header * diff -Nru v4l-utils-1.10.0+r3508/include/linux/dvb/dmx.h v4l-utils-1.10.0+r3520/include/linux/dvb/dmx.h --- v4l-utils-1.10.0+r3508/include/linux/dvb/dmx.h 2017-12-13 17:01:40.000000000 +0000 +++ v4l-utils-1.10.0+r3520/include/linux/dvb/dmx.h 2017-12-14 17:01:56.000000000 +0000 @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: LGPL-2.1+ WITH Linux-syscall-note */ /* * dmx.h * diff -Nru v4l-utils-1.10.0+r3508/include/linux/dvb/frontend.h v4l-utils-1.10.0+r3520/include/linux/dvb/frontend.h --- v4l-utils-1.10.0+r3508/include/linux/dvb/frontend.h 2017-12-13 17:01:40.000000000 +0000 +++ v4l-utils-1.10.0+r3520/include/linux/dvb/frontend.h 2017-12-14 17:01:56.000000000 +0000 @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: LGPL-2.1+ WITH Linux-syscall-note */ /* * frontend.h * diff -Nru v4l-utils-1.10.0+r3508/include/linux/fb.h v4l-utils-1.10.0+r3520/include/linux/fb.h --- v4l-utils-1.10.0+r3508/include/linux/fb.h 2017-12-13 17:01:40.000000000 +0000 +++ v4l-utils-1.10.0+r3520/include/linux/fb.h 2017-12-14 17:01:56.000000000 +0000 @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _LINUX_FB_H #define _LINUX_FB_H diff -Nru v4l-utils-1.10.0+r3508/include/linux/ivtv.h v4l-utils-1.10.0+r3520/include/linux/ivtv.h --- v4l-utils-1.10.0+r3508/include/linux/ivtv.h 2017-12-13 17:01:40.000000000 +0000 +++ v4l-utils-1.10.0+r3520/include/linux/ivtv.h 2017-12-14 17:01:56.000000000 +0000 @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */ /* Public ivtv API header Copyright (C) 2003-2004 Kevin Thayer diff -Nru v4l-utils-1.10.0+r3508/include/linux/lirc.h v4l-utils-1.10.0+r3520/include/linux/lirc.h --- v4l-utils-1.10.0+r3508/include/linux/lirc.h 2017-12-13 17:01:40.000000000 +0000 +++ v4l-utils-1.10.0+r3520/include/linux/lirc.h 2017-12-14 17:01:56.000000000 +0000 @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * lirc.h - linux infrared remote control header file * last modified 2010/07/13 by Jarod Wilson @@ -46,12 +47,14 @@ #define LIRC_MODE_RAW 0x00000001 #define LIRC_MODE_PULSE 0x00000002 #define LIRC_MODE_MODE2 0x00000004 +#define LIRC_MODE_SCANCODE 0x00000008 #define LIRC_MODE_LIRCCODE 0x00000010 #define LIRC_CAN_SEND_RAW LIRC_MODE2SEND(LIRC_MODE_RAW) #define LIRC_CAN_SEND_PULSE LIRC_MODE2SEND(LIRC_MODE_PULSE) #define LIRC_CAN_SEND_MODE2 LIRC_MODE2SEND(LIRC_MODE_MODE2) +#define LIRC_CAN_SEND_SCANCODE LIRC_MODE2SEND(LIRC_MODE_SCANCODE) #define LIRC_CAN_SEND_LIRCCODE LIRC_MODE2SEND(LIRC_MODE_LIRCCODE) #define LIRC_CAN_SEND_MASK 0x0000003f @@ -63,6 +66,7 @@ #define LIRC_CAN_REC_RAW LIRC_MODE2REC(LIRC_MODE_RAW) #define LIRC_CAN_REC_PULSE LIRC_MODE2REC(LIRC_MODE_PULSE) #define LIRC_CAN_REC_MODE2 LIRC_MODE2REC(LIRC_MODE_MODE2) +#define LIRC_CAN_REC_SCANCODE LIRC_MODE2REC(LIRC_MODE_SCANCODE) #define LIRC_CAN_REC_LIRCCODE LIRC_MODE2REC(LIRC_MODE_LIRCCODE) #define LIRC_CAN_REC_MASK LIRC_MODE2REC(LIRC_CAN_SEND_MASK) @@ -130,4 +134,83 @@ #define LIRC_SET_WIDEBAND_RECEIVER _IOW('i', 0x00000023, __u32) +/* + * struct lirc_scancode - decoded scancode with protocol for use with + * LIRC_MODE_SCANCODE + * + * @timestamp: Timestamp in nanoseconds using CLOCK_MONOTONIC when IR + * was decoded. + * @flags: should be 0 for transmit. When receiving scancodes, + * LIRC_SCANCODE_FLAG_TOGGLE or LIRC_SCANCODE_FLAG_REPEAT can be set + * depending on the protocol + * @rc_proto: see enum rc_proto + * @keycode: the translated keycode. Set to 0 for transmit. + * @scancode: the scancode received or to be sent + */ +struct lirc_scancode { + __u64 timestamp; + __u16 flags; + __u16 rc_proto; + __u32 keycode; + __u64 scancode; +}; + +/* Set if the toggle bit of rc-5 or rc-6 is enabled */ +#define LIRC_SCANCODE_FLAG_TOGGLE 1 +/* Set if this is a nec or sanyo repeat */ +#define LIRC_SCANCODE_FLAG_REPEAT 2 + +/** + * enum rc_proto - the Remote Controller protocol + * + * @RC_PROTO_UNKNOWN: Protocol not known + * @RC_PROTO_OTHER: Protocol known but proprietary + * @RC_PROTO_RC5: Philips RC5 protocol + * @RC_PROTO_RC5X_20: Philips RC5x 20 bit protocol + * @RC_PROTO_RC5_SZ: StreamZap variant of RC5 + * @RC_PROTO_JVC: JVC protocol + * @RC_PROTO_SONY12: Sony 12 bit protocol + * @RC_PROTO_SONY15: Sony 15 bit protocol + * @RC_PROTO_SONY20: Sony 20 bit protocol + * @RC_PROTO_NEC: NEC protocol + * @RC_PROTO_NECX: Extended NEC protocol + * @RC_PROTO_NEC32: NEC 32 bit protocol + * @RC_PROTO_SANYO: Sanyo protocol + * @RC_PROTO_MCIR2_KBD: RC6-ish MCE keyboard + * @RC_PROTO_MCIR2_MSE: RC6-ish MCE mouse + * @RC_PROTO_RC6_0: Philips RC6-0-16 protocol + * @RC_PROTO_RC6_6A_20: Philips RC6-6A-20 protocol + * @RC_PROTO_RC6_6A_24: Philips RC6-6A-24 protocol + * @RC_PROTO_RC6_6A_32: Philips RC6-6A-32 protocol + * @RC_PROTO_RC6_MCE: MCE (Philips RC6-6A-32 subtype) protocol + * @RC_PROTO_SHARP: Sharp protocol + * @RC_PROTO_XMP: XMP protocol + * @RC_PROTO_CEC: CEC protocol + */ +enum rc_proto { + RC_PROTO_UNKNOWN = 0, + RC_PROTO_OTHER = 1, + RC_PROTO_RC5 = 2, + RC_PROTO_RC5X_20 = 3, + RC_PROTO_RC5_SZ = 4, + RC_PROTO_JVC = 5, + RC_PROTO_SONY12 = 6, + RC_PROTO_SONY15 = 7, + RC_PROTO_SONY20 = 8, + RC_PROTO_NEC = 9, + RC_PROTO_NECX = 10, + RC_PROTO_NEC32 = 11, + RC_PROTO_SANYO = 12, + RC_PROTO_MCIR2_KBD = 13, + RC_PROTO_MCIR2_MSE = 14, + RC_PROTO_RC6_0 = 15, + RC_PROTO_RC6_6A_20 = 16, + RC_PROTO_RC6_6A_24 = 17, + RC_PROTO_RC6_6A_32 = 18, + RC_PROTO_RC6_MCE = 19, + RC_PROTO_SHARP = 20, + RC_PROTO_XMP = 21, + RC_PROTO_CEC = 22, +}; + #endif diff -Nru v4l-utils-1.10.0+r3508/include/linux/media-bus-format.h v4l-utils-1.10.0+r3520/include/linux/media-bus-format.h --- v4l-utils-1.10.0+r3508/include/linux/media-bus-format.h 2017-12-13 17:01:40.000000000 +0000 +++ v4l-utils-1.10.0+r3520/include/linux/media-bus-format.h 2017-12-14 17:01:56.000000000 +0000 @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * Media Bus API header * diff -Nru v4l-utils-1.10.0+r3508/include/linux/media.h v4l-utils-1.10.0+r3520/include/linux/media.h --- v4l-utils-1.10.0+r3508/include/linux/media.h 2017-12-13 17:01:40.000000000 +0000 +++ v4l-utils-1.10.0+r3520/include/linux/media.h 2017-12-14 17:01:56.000000000 +0000 @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * Multimedia device API * diff -Nru v4l-utils-1.10.0+r3508/include/linux/v4l2-common.h v4l-utils-1.10.0+r3520/include/linux/v4l2-common.h --- v4l-utils-1.10.0+r3508/include/linux/v4l2-common.h 2017-12-13 17:01:40.000000000 +0000 +++ v4l-utils-1.10.0+r3520/include/linux/v4l2-common.h 2017-12-14 17:01:56.000000000 +0000 @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: ((GPL-2.0+ WITH Linux-syscall-note) OR BSD-3-Clause) */ /* * include/linux/v4l2-common.h * diff -Nru v4l-utils-1.10.0+r3508/include/linux/v4l2-controls.h v4l-utils-1.10.0+r3520/include/linux/v4l2-controls.h --- v4l-utils-1.10.0+r3508/include/linux/v4l2-controls.h 2017-12-13 17:01:40.000000000 +0000 +++ v4l-utils-1.10.0+r3520/include/linux/v4l2-controls.h 2017-12-14 17:01:56.000000000 +0000 @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: ((GPL-2.0+ WITH Linux-syscall-note) OR BSD-3-Clause) */ /* * Video for Linux Two controls header file * diff -Nru v4l-utils-1.10.0+r3508/include/linux/v4l2-mediabus.h v4l-utils-1.10.0+r3520/include/linux/v4l2-mediabus.h --- v4l-utils-1.10.0+r3508/include/linux/v4l2-mediabus.h 2017-12-13 17:01:40.000000000 +0000 +++ v4l-utils-1.10.0+r3520/include/linux/v4l2-mediabus.h 2017-12-14 17:01:56.000000000 +0000 @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * Media Bus API header * diff -Nru v4l-utils-1.10.0+r3508/include/linux/v4l2-subdev.h v4l-utils-1.10.0+r3520/include/linux/v4l2-subdev.h --- v4l-utils-1.10.0+r3508/include/linux/v4l2-subdev.h 2017-12-13 17:01:40.000000000 +0000 +++ v4l-utils-1.10.0+r3520/include/linux/v4l2-subdev.h 2017-12-14 17:01:56.000000000 +0000 @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * V4L2 subdev userspace API * diff -Nru v4l-utils-1.10.0+r3508/include/linux/videodev2.h v4l-utils-1.10.0+r3520/include/linux/videodev2.h --- v4l-utils-1.10.0+r3508/include/linux/videodev2.h 2017-12-13 17:01:40.000000000 +0000 +++ v4l-utils-1.10.0+r3520/include/linux/videodev2.h 2017-12-14 17:01:56.000000000 +0000 @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: ((GPL-2.0+ WITH Linux-syscall-note) OR BSD-3-Clause) */ /* * Video for Linux Two header file * diff -Nru v4l-utils-1.10.0+r3508/lib/libdvbv5/dvb-dev-local.c v4l-utils-1.10.0+r3520/lib/libdvbv5/dvb-dev-local.c --- v4l-utils-1.10.0+r3508/lib/libdvbv5/dvb-dev-local.c 2017-12-13 17:01:40.000000000 +0000 +++ v4l-utils-1.10.0+r3520/lib/libdvbv5/dvb-dev-local.c 2017-12-14 17:01:56.000000000 +0000 @@ -609,7 +609,7 @@ } } - ret = read(fd, buf, count); + ret = TEMP_FAILURE_RETRY(read(fd, buf, count)); if (ret == -1) { if (errno != EOVERFLOW && errno != EAGAIN) dvb_perror("read()"); @@ -724,8 +724,9 @@ } while (!patread){ - if (((count = read(fd, buf, sizeof(buft))) < 0) && errno == EOVERFLOW) - count = read(fd, buf, sizeof(buft)); + count = TEMP_FAILURE_RETRY(read(fd, buf, sizeof(buft))); + if (count < 0 && errno == EOVERFLOW) + count = TEMP_FAILURE_RETRY(read(fd, buf, sizeof(buft))); if (count < 0) { dvb_perror("read_sections: read error"); return -errno; diff -Nru v4l-utils-1.10.0+r3508/.pc/.quilt_patches v4l-utils-1.10.0+r3520/.pc/.quilt_patches --- v4l-utils-1.10.0+r3508/.pc/.quilt_patches 2017-12-13 17:01:46.000000000 +0000 +++ v4l-utils-1.10.0+r3520/.pc/.quilt_patches 2017-12-14 17:01:58.000000000 +0000 @@ -1 +1 @@ -/home/buildd/build-RECIPEBRANCHBUILD-1500371/chroot-autobuild/home/buildd/work/tree/v4l-utils-1.10.0+r3508/debian/patches +/home/buildd/build-RECIPEBRANCHBUILD-1500997/chroot-autobuild/home/buildd/work/tree/v4l-utils-1.10.0+r3520/debian/patches diff -Nru v4l-utils-1.10.0+r3508/.pc/.quilt_series v4l-utils-1.10.0+r3520/.pc/.quilt_series --- v4l-utils-1.10.0+r3508/.pc/.quilt_series 2017-12-13 17:01:46.000000000 +0000 +++ v4l-utils-1.10.0+r3520/.pc/.quilt_series 2017-12-14 17:01:58.000000000 +0000 @@ -1 +1 @@ -/home/buildd/build-RECIPEBRANCHBUILD-1500371/chroot-autobuild/home/buildd/work/tree/v4l-utils-1.10.0+r3508/debian/patches/series +/home/buildd/build-RECIPEBRANCHBUILD-1500997/chroot-autobuild/home/buildd/work/tree/v4l-utils-1.10.0+r3520/debian/patches/series diff -Nru v4l-utils-1.10.0+r3508/utils/cec-ctl/cec-ctl.cpp v4l-utils-1.10.0+r3520/utils/cec-ctl/cec-ctl.cpp --- v4l-utils-1.10.0+r3508/utils/cec-ctl/cec-ctl.cpp 2017-12-13 17:01:40.000000000 +0000 +++ v4l-utils-1.10.0+r3520/utils/cec-ctl/cec-ctl.cpp 2017-12-14 17:01:56.000000000 +0000 @@ -1011,7 +1011,8 @@ unsigned i; cec_ops_vendor_command_with_id(msg, &vendor_id, &size, &bytes); - printf("CEC_MSG_VENDOR_COMMAND_WITH_ID:\n"); + printf("CEC_MSG_VENDOR_COMMAND_WITH_ID (0x%02x):\n", + CEC_MSG_VENDOR_COMMAND_WITH_ID); log_arg(&arg_vendor_id, "vendor-id", vendor_id); printf("\tvendor-specific-data:"); for (i = 0; i < size; i++) @@ -1029,7 +1030,8 @@ switch (msg->msg[1]) { case CEC_MSG_VENDOR_COMMAND: - printf("CEC_MSG_VENDOR_COMMAND:\n"); + printf("CEC_MSG_VENDOR_COMMAND (0x%02x):\n", + CEC_MSG_VENDOR_COMMAND); cec_ops_vendor_command(msg, &size, &bytes); printf("\tvendor-specific-data:"); for (i = 0; i < size; i++) @@ -1043,7 +1045,8 @@ log_htng_msg(msg); break; default: - printf("CEC_MSG_VENDOR_COMMAND_WITH_ID:\n"); + printf("CEC_MSG_VENDOR_COMMAND_WITH_ID (0x%02x):\n", + CEC_MSG_VENDOR_COMMAND_WITH_ID); log_arg(&arg_vendor_id, "vendor-id", vendor_id); printf("\tvendor-specific-data:"); for (i = 0; i < size; i++) @@ -1053,7 +1056,8 @@ } break; case CEC_MSG_VENDOR_REMOTE_BUTTON_DOWN: - printf("CEC_MSG_VENDOR_REMOTE_BUTTON_DOWN:\n"); + printf("CEC_MSG_VENDOR_REMOTE_BUTTON_DOWN (0x%02x):\n", + CEC_MSG_VENDOR_REMOTE_BUTTON_DOWN); cec_ops_vendor_remote_button_down(msg, &size, &bytes); printf("\tvendor-specific-rc-code:"); for (i = 0; i < size; i++) @@ -1063,7 +1067,8 @@ case CEC_MSG_CDC_MESSAGE: phys_addr = (msg->msg[2] << 8) | msg->msg[3]; - printf("CEC_MSG_CDC 0x%02x:\n", msg->msg[4]); + printf("CEC_MSG_CDC_MESSAGE (0x%02x): 0x%02x:\n", + CEC_MSG_CDC_MESSAGE, msg->msg[4]); log_arg(&arg_u16, "phys-addr", phys_addr); printf("\tpayload:"); for (i = 5; i < msg->len; i++) diff -Nru v4l-utils-1.10.0+r3508/utils/cec-follower/cec-log.cpp v4l-utils-1.10.0+r3520/utils/cec-follower/cec-log.cpp --- v4l-utils-1.10.0+r3508/utils/cec-follower/cec-log.cpp 2017-12-13 17:01:40.000000000 +0000 +++ v4l-utils-1.10.0+r3520/utils/cec-follower/cec-log.cpp 2017-12-14 17:01:56.000000000 +0000 @@ -450,7 +450,8 @@ unsigned i; cec_ops_vendor_command_with_id(msg, &vendor_id, &size, &bytes); - printf("CEC_MSG_VENDOR_COMMAND_WITH_ID:\n"); + printf("CEC_MSG_VENDOR_COMMAND_WITH_ID (0x%02x):\n", + CEC_MSG_VENDOR_COMMAND_WITH_ID); log_arg(&arg_vendor_id, "vendor-id", vendor_id); printf("\tvendor-specific-data:"); for (i = 0; i < size; i++) @@ -468,7 +469,8 @@ switch (msg->msg[1]) { case CEC_MSG_VENDOR_COMMAND: - printf("CEC_MSG_VENDOR_COMMAND:\n"); + printf("CEC_MSG_VENDOR_COMMAND (0x%02x):\n", + CEC_MSG_VENDOR_COMMAND); cec_ops_vendor_command(msg, &size, &bytes); printf("\tvendor-specific-data:"); for (i = 0; i < size; i++) @@ -482,7 +484,8 @@ log_htng_msg(msg); break; default: - printf("CEC_MSG_VENDOR_COMMAND_WITH_ID:\n"); + printf("CEC_MSG_VENDOR_COMMAND_WITH_ID (0x%02x):\n", + CEC_MSG_VENDOR_COMMAND_WITH_ID); log_arg(&arg_vendor_id, "vendor-id", vendor_id); printf("\tvendor-specific-data:"); for (i = 0; i < size; i++) @@ -492,7 +495,8 @@ } break; case CEC_MSG_VENDOR_REMOTE_BUTTON_DOWN: - printf("CEC_MSG_VENDOR_REMOTE_BUTTON_DOWN:\n"); + printf("CEC_MSG_VENDOR_REMOTE_BUTTON_DOWN (0x%02x):\n", + CEC_MSG_VENDOR_REMOTE_BUTTON_DOWN); cec_ops_vendor_remote_button_down(msg, &size, &bytes); printf("\tvendor-specific-rc-code:"); for (i = 0; i < size; i++) @@ -502,7 +506,8 @@ case CEC_MSG_CDC_MESSAGE: phys_addr = (msg->msg[2] << 8) | msg->msg[3]; - printf("CEC_MSG_CDC 0x%02x:\n", msg->msg[4]); + printf("CEC_MSG_CDC_MESSAGE (0x%02x): 0x%02x:\n", + CEC_MSG_CDC_MESSAGE, msg->msg[4]); log_arg(&arg_u16, "phys-addr", phys_addr); printf("\tpayload:"); for (i = 5; i < msg->len; i++) diff -Nru v4l-utils-1.10.0+r3508/utils/common/cec-log.cpp v4l-utils-1.10.0+r3520/utils/common/cec-log.cpp --- v4l-utils-1.10.0+r3508/utils/common/cec-log.cpp 2017-12-13 17:01:40.000000000 +0000 +++ v4l-utils-1.10.0+r3520/utils/common/cec-log.cpp 2017-12-14 17:01:56.000000000 +0000 @@ -450,7 +450,8 @@ unsigned i; cec_ops_vendor_command_with_id(msg, &vendor_id, &size, &bytes); - printf("CEC_MSG_VENDOR_COMMAND_WITH_ID:\n"); + printf("CEC_MSG_VENDOR_COMMAND_WITH_ID (0x%02x):\n", + CEC_MSG_VENDOR_COMMAND_WITH_ID); log_arg(&arg_vendor_id, "vendor-id", vendor_id); printf("\tvendor-specific-data:"); for (i = 0; i < size; i++) @@ -468,7 +469,8 @@ switch (msg->msg[1]) { case CEC_MSG_VENDOR_COMMAND: - printf("CEC_MSG_VENDOR_COMMAND:\n"); + printf("CEC_MSG_VENDOR_COMMAND (0x%02x):\n", + CEC_MSG_VENDOR_COMMAND); cec_ops_vendor_command(msg, &size, &bytes); printf("\tvendor-specific-data:"); for (i = 0; i < size; i++) @@ -482,7 +484,8 @@ log_htng_msg(msg); break; default: - printf("CEC_MSG_VENDOR_COMMAND_WITH_ID:\n"); + printf("CEC_MSG_VENDOR_COMMAND_WITH_ID (0x%02x):\n", + CEC_MSG_VENDOR_COMMAND_WITH_ID); log_arg(&arg_vendor_id, "vendor-id", vendor_id); printf("\tvendor-specific-data:"); for (i = 0; i < size; i++) @@ -492,7 +495,8 @@ } break; case CEC_MSG_VENDOR_REMOTE_BUTTON_DOWN: - printf("CEC_MSG_VENDOR_REMOTE_BUTTON_DOWN:\n"); + printf("CEC_MSG_VENDOR_REMOTE_BUTTON_DOWN (0x%02x):\n", + CEC_MSG_VENDOR_REMOTE_BUTTON_DOWN); cec_ops_vendor_remote_button_down(msg, &size, &bytes); printf("\tvendor-specific-rc-code:"); for (i = 0; i < size; i++) @@ -502,7 +506,8 @@ case CEC_MSG_CDC_MESSAGE: phys_addr = (msg->msg[2] << 8) | msg->msg[3]; - printf("CEC_MSG_CDC 0x%02x:\n", msg->msg[4]); + printf("CEC_MSG_CDC_MESSAGE (0x%02x): 0x%02x:\n", + CEC_MSG_CDC_MESSAGE, msg->msg[4]); log_arg(&arg_u16, "phys-addr", phys_addr); printf("\tpayload:"); for (i = 5; i < msg->len; i++) diff -Nru v4l-utils-1.10.0+r3508/utils/common/ir-encode.c v4l-utils-1.10.0+r3520/utils/common/ir-encode.c --- v4l-utils-1.10.0+r3508/utils/common/ir-encode.c 1970-01-01 00:00:00.000000000 +0000 +++ v4l-utils-1.10.0+r3520/utils/common/ir-encode.c 2017-12-14 17:01:56.000000000 +0000 @@ -0,0 +1,465 @@ +/* + * ir-encode.c - encodes IR scancodes in different protocols + * + * Copyright (C) 2016 Sean Young + * + * 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, version 2 of the License. + + * 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. + */ + +/* + * TODO: XMP protocol and MCE keyboard + */ + +#include +#include +#include +#include + +#include + +#include "ir-encode.h" + +#define NS_TO_US(x) (((x)+500)/1000) + +static int nec_encode(enum rc_proto proto, unsigned scancode, unsigned *buf) +{ + const int nec_unit = 562500; + int n = 0; + + void add_byte(unsigned bits) + { + int i; + for (i=0; i<8; i++) { + buf[n++] = NS_TO_US(nec_unit); + if (bits & (1 << i)) + buf[n++] = NS_TO_US(nec_unit * 3); + else + buf[n++] = NS_TO_US(nec_unit); + } + } + + buf[n++] = NS_TO_US(nec_unit * 16); + buf[n++] = NS_TO_US(nec_unit * 8); + + switch (proto) { + default: + return 0; + case RC_PROTO_NEC: + add_byte(scancode >> 8); + add_byte(~(scancode >> 8)); + add_byte(scancode); + add_byte(~scancode); + break; + case RC_PROTO_NECX: + add_byte(scancode >> 16); + add_byte(scancode >> 8); + add_byte(scancode); + add_byte(~scancode); + break; + case RC_PROTO_NEC32: + /* + * At the time of writing kernel software nec decoder + * reverses the bit order so it will not match. Hardware + * decoders do not have this issue. + */ + add_byte(scancode >> 24); + add_byte(scancode >> 16); + add_byte(scancode >> 8); + add_byte(scancode); + break; + } + + buf[n++] = NS_TO_US(nec_unit); + + return n; +} + +static int jvc_encode(enum rc_proto proto, unsigned scancode, unsigned *buf) +{ + const int jvc_unit = 525000; + int i; + + /* swap bytes so address comes first */ + scancode = ((scancode << 8) & 0xff00) | ((scancode >> 8) & 0x00ff); + + *buf++ = NS_TO_US(jvc_unit * 16); + *buf++ = NS_TO_US(jvc_unit * 8); + + for (i=0; i<16; i++) { + *buf++ = NS_TO_US(jvc_unit); + + if (scancode & 1) + *buf++ = NS_TO_US(jvc_unit * 3); + else + *buf++ = NS_TO_US(jvc_unit); + + scancode >>= 1; + } + + *buf = NS_TO_US(jvc_unit); + + return 35; +} + +static int sanyo_encode(enum rc_proto proto, unsigned scancode, unsigned *buf) +{ + const int sanyo_unit = 562500; + + void add_bits(int bits, int count) + { + int i; + for (i=0; i> 8, 13); + add_bits(~(scancode >> 8), 13); + add_bits(scancode, 8); + add_bits(~scancode, 8); + + *buf = NS_TO_US(sanyo_unit); + + return 87; +} + +static int sharp_encode(enum rc_proto proto, unsigned scancode, unsigned *buf) +{ + const int sharp_unit = 40000; + + void add_bits(int bits, int count) + { + int i; + for (i=0; i> 8, 5); + add_bits(scancode, 8); + add_bits(1, 2); + + *buf++ = NS_TO_US(sharp_unit * 8); + *buf++ = NS_TO_US(sharp_unit * 1000); + + add_bits(scancode >> 8, 5); + add_bits(~scancode, 8); + add_bits(~1, 2); + *buf++ = NS_TO_US(sharp_unit * 8); + + return (13 + 2) * 4 + 3; +} + +static int sony_encode(enum rc_proto proto, unsigned scancode, unsigned *buf) +{ + const int sony_unit = 600000; + int n = 0; + + void add_bits(int bits, int count) + { + int i; + for (i=0; i> 16, 5); + break; + case RC_PROTO_SONY15: + add_bits(scancode, 7); + add_bits(scancode >> 16, 8); + break; + case RC_PROTO_SONY20: + add_bits(scancode, 7); + add_bits(scancode >> 16, 5); + add_bits(scancode >> 8, 8); + break; + default: + return 0; + } + + /* ignore last space */ + return n - 1; +} + +static int rc5_encode(enum rc_proto proto, unsigned scancode, unsigned *buf) +{ + const unsigned int rc5_unit = 888888; + unsigned n = 0; + + void advance_space(unsigned length) + { + if (n % 2) + buf[n] += length; + else + buf[++n] = length; + } + + void advance_pulse(unsigned length) + { + if (n % 2) + buf[++n] = length; + else + buf[n] += length; + } + + void add_bits(int bits, int count) + { + while (count--) { + if (bits & (1 << count)) { + advance_space(NS_TO_US(rc5_unit)); + advance_pulse(NS_TO_US(rc5_unit)); + } else { + advance_pulse(NS_TO_US(rc5_unit)); + advance_space(NS_TO_US(rc5_unit)); + } + } + } + + buf[n] = NS_TO_US(rc5_unit); + + switch (proto) { + default: + return 0; + case RC_PROTO_RC5: + add_bits(!(scancode & 0x40), 1); + add_bits(0, 1); + add_bits(scancode >> 8, 5); + add_bits(scancode, 6); + break; + case RC_PROTO_RC5_SZ: + add_bits(!!(scancode & 0x2000), 1); + add_bits(0, 1); + add_bits(scancode >> 6, 6); + add_bits(scancode, 6); + break; + case RC_PROTO_RC5X_20: + add_bits(!(scancode & 0x4000), 1); + add_bits(0, 1); + add_bits(scancode >> 16, 5); + advance_space(NS_TO_US(rc5_unit * 4)); + add_bits(scancode >> 8, 6); + add_bits(scancode, 6); + break; + } + + /* drop any trailing pulse */ + return (n % 2) ? n : n + 1; +} + +static int rc6_encode(enum rc_proto proto, unsigned scancode, unsigned *buf) +{ + const unsigned int rc6_unit = 444444; + unsigned n = 0; + + void advance_space(unsigned length) + { + if (n % 2) + buf[n] += length; + else + buf[++n] = length; + } + + void advance_pulse(unsigned length) + { + if (n % 2) + buf[++n] = length; + else + buf[n] += length; + } + + void add_bits(unsigned bits, unsigned count, unsigned length) + { + while (count--) { + if (bits & (1 << count)) { + advance_pulse(length); + advance_space(length); + } else { + advance_space(length); + advance_pulse(length); + } + } + } + + buf[n++] = NS_TO_US(rc6_unit * 6); + buf[n++] = NS_TO_US(rc6_unit * 2); + buf[n] = 0; + + switch (proto) { + default: + return 0; + case RC_PROTO_RC6_0: + add_bits(8, 4, NS_TO_US(rc6_unit)); + add_bits(0, 1, NS_TO_US(rc6_unit * 2)); + add_bits(scancode, 16, NS_TO_US(rc6_unit)); + break; + case RC_PROTO_RC6_6A_20: + add_bits(14, 4, NS_TO_US(rc6_unit)); + add_bits(0, 1, NS_TO_US(rc6_unit * 2)); + add_bits(scancode, 20, NS_TO_US(rc6_unit)); + break; + case RC_PROTO_RC6_6A_24: + add_bits(14, 4, NS_TO_US(rc6_unit)); + add_bits(0, 1, NS_TO_US(rc6_unit * 2)); + add_bits(scancode, 24, NS_TO_US(rc6_unit)); + break; + case RC_PROTO_RC6_6A_32: + case RC_PROTO_RC6_MCE: + add_bits(14, 4, NS_TO_US(rc6_unit)); + add_bits(0, 1, NS_TO_US(rc6_unit * 2)); + add_bits(scancode, 32, NS_TO_US(rc6_unit)); + break; + } + + /* drop any trailing pulse */ + return (n % 2) ? n : n + 1; +} + +static const struct { + char name[10]; + unsigned scancode_mask; + unsigned max_edges; + unsigned carrier; + int (*encode)(enum rc_proto proto, unsigned scancode, unsigned *buf); +} protocols[] = { + [RC_PROTO_RC5] = { "rc5", 0x1f7f, 24, 36000, rc5_encode }, + [RC_PROTO_RC5X_20] = { "rc5x_20", 0x1f7f3f, 40, 36000, rc5_encode }, + [RC_PROTO_RC5_SZ] = { "rc5_sz", 0x2fff, 26, 36000, rc5_encode }, + [RC_PROTO_SONY12] = { "sony12", 0x1f007f, 25, 40000, sony_encode }, + [RC_PROTO_SONY15] = { "sony15", 0xff007f, 31, 40000, sony_encode }, + [RC_PROTO_SONY20] = { "sony20", 0x1fff7f, 41, 40000, sony_encode }, + [RC_PROTO_JVC] = { "jvc", 0xffff, 35, 38000, jvc_encode }, + [RC_PROTO_NEC] = { "nec", 0xffff, 67, 38000, nec_encode }, + [RC_PROTO_NECX] = { "necx", 0xffffff, 67, 38000, nec_encode }, + [RC_PROTO_NEC32] = { "nec32", 0xffffffff, 67, 38000, nec_encode }, + [RC_PROTO_SANYO] = { "sanyo", 0x1fffff, 87, 38000, sanyo_encode }, + [RC_PROTO_RC6_0] = { "rc6_0", 0xffff, 24, 36000, rc6_encode }, + [RC_PROTO_RC6_6A_20] = { "rc6_6a_20", 0xfffff, 52, 36000, rc6_encode }, + [RC_PROTO_RC6_6A_24] = { "rc6_6a_24", 0xffffff, 60, 36000, rc6_encode }, + [RC_PROTO_RC6_6A_32] = { "rc6_6a_32", 0xffffffff, 76, 36000, rc6_encode }, + [RC_PROTO_RC6_MCE] = { "rc6_mce", 0xffff7fff, 76, 36000, rc6_encode }, + [RC_PROTO_SHARP] = { "sharp", 0x1fff, 63, 38000, sharp_encode }, + [RC_PROTO_MCIR2_KBD] = { "mcir2-kbd" }, + [RC_PROTO_MCIR2_MSE] = { "mcir2-mse" }, + [RC_PROTO_XMP] = { "xmp" }, + [RC_PROTO_CEC] = { "cec" }, +}; + +static bool str_like(const char *a, const char *b) +{ + while (*a && *b) { + while (*a == ' ' || *a == '-' || *a == '_') + a++; + while (*b == ' ' || *b == '-' || *b == '_') + b++; + + if (*a >= 0x7f || *b >= 0x7f) + return false; + + if (tolower(*a) != tolower(*b)) + return false; + + a++; b++; + } + + return !*a && !*b; +} + +bool protocol_match(const char *name, enum rc_proto *proto) +{ + enum rc_proto p; + + for (p=0; p> 16) ^ ~(s >> 8)) & 0xff) != 0; + } else if (p == RC_PROTO_NEC32) { + return (((s >> 24) ^ ~(s >> 16)) & 0xff) != 0; + } else if (p == RC_PROTO_RC6_MCE) { + return (s & 0xffff0000) == 0x800f0000; + } else if (p == RC_PROTO_RC6_6A_32) { + return (s & 0xffff0000) != 0x800f0000; + } + + return true; +} + +bool protocol_encoder_available(enum rc_proto proto) +{ + return protocols[proto].encode != NULL; +} + +unsigned protocol_encode(enum rc_proto proto, unsigned scancode, unsigned *buf) +{ + if (!protocols[proto].encode) + return 0; + + return protocols[proto].encode(proto, scancode, buf); +} + +const char* protocol_name(enum rc_proto proto) +{ + if (proto >= ARRAY_SIZE(protocols) || !protocols[proto].name[0]) + return NULL; + + return protocols[proto].name; +} diff -Nru v4l-utils-1.10.0+r3508/utils/common/ir-encode.h v4l-utils-1.10.0+r3520/utils/common/ir-encode.h --- v4l-utils-1.10.0+r3508/utils/common/ir-encode.h 1970-01-01 00:00:00.000000000 +0000 +++ v4l-utils-1.10.0+r3520/utils/common/ir-encode.h 2017-12-14 17:01:56.000000000 +0000 @@ -0,0 +1,16 @@ + +#ifndef __IR_ENCODE_H__ +#define __IR_ENCODE_H__ + +#define ARRAY_SIZE(x) (sizeof(x)/sizeof((x)[0])) + +bool protocol_match(const char *name, enum rc_proto *proto); +unsigned protocol_carrier(enum rc_proto proto); +unsigned protocol_max_size(enum rc_proto proto); +bool protocol_scancode_valid(enum rc_proto proto, unsigned scancode); +unsigned protocol_scancode_mask(enum rc_proto proto); +bool protocol_encoder_available(enum rc_proto proto); +unsigned protocol_encode(enum rc_proto proto, unsigned scancode, unsigned *buf); +const char *protocol_name(enum rc_proto proto); + +#endif diff -Nru v4l-utils-1.10.0+r3508/utils/ir-ctl/ir-ctl.1.in v4l-utils-1.10.0+r3520/utils/ir-ctl/ir-ctl.1.in --- v4l-utils-1.10.0+r3508/utils/ir-ctl/ir-ctl.1.in 2017-12-13 17:01:40.000000000 +0000 +++ v4l-utils-1.10.0+r3520/utils/ir-ctl/ir-ctl.1.in 2017-12-14 17:01:56.000000000 +0000 @@ -15,10 +15,10 @@ [\fIOPTION\fR]... \fI\-\-scancode\fR [\fIprotocol and scancode to send\fR] .br .B ir\-ctl -[\fIOPTION\fR]... \fI\-\-record\fR [\fIsave to file\fR] +[\fIOPTION\fR]... \fI\-\-receive\fR [\fIsave to file\fR] .SH DESCRIPTION ir\-ctl is a tool that allows one to list the features of a lirc device, -set its options, record raw IR, send raw IR or send complete IR scancodes. +set its options, receive raw IR, send raw IR or send complete IR scancodes. .PP Note: You need to have read or write permissions on the /dev/lirc device for options to work. @@ -30,21 +30,23 @@ \fB\-f\fR, \fB\-\-features\fR List the features of the lirc device. .TP -\fB\-r\fR, \fB\-\-record\fR=[\fIFILE\fR] -Record IR and print to standard output if no file is specified, else +\fB\-r\fR, \fB\-\-receive\fR=[\fIFILE\fR] +Receive IR and print to standard output if no file is specified, else save to the filename. .TP \fB\-s\fR, \fB\-\-send\fR=\fIFILE\fR Send IR in text file. It must be in the format described below. If this -option is specified multiple times, send all files in order with 125ms delay -between them. +option is specified multiple times, send all files in\-order with a 125ms gap +between them. The gap length can be modified with \fB\-\-gap\fR. .TP \fB-S\fR, \fB\-\-scancode\fR=\fIPROTOCOL:SCANCODE\fR -Send the IR scancode in the protocol specified. The protocol must one of -the protocols listed below, followed by a semicolon and the scancode number. +Send the IR scancode in the protocol specified. The protocol must one of the +protocols listed below, followed by a colon and the scancode number. If this +option is specified multiple times, send all scancodes in\-order with a 125ms +gap between them. The gap length can be modified with \fB\-\-gap\fR. .TP \fB\-1\fR, \fB\-\-oneshot\fR -When recording, stop recording after the first message, i.e. after a space or +When receiving, stop receiving after the first message, i.e. after a space or timeout of more than 19ms is received. .TP \fB\-w\fR, \fB\-\-wideband\fR @@ -62,24 +64,15 @@ .TP \fB\-m\fR, \fB\-\-measure\-carrier\fR If the hardware supports it, report what the carrier frequency is on -recording. You will get the keyword \fIcarrier\fR followed by the frequency. +receiving. You will get the keyword \fIcarrier\fR followed by the frequency. This might use the wideband receiver although this is hardware specific. .TP \fB\-M\fR, \fB\-\-no\-measure\-carrier\fR Disable reporting of the carrier frequency. This should make it possible to use the narrowband receiver. This is the default. .TP -\fB\-p\fR, \fB\-\-timeout\-reports\fR -When the IR receiver times out due to inactivity, a timeout message is -reported. When recording you will get the keyword \fItimeout\fR followed by -the length of time that no IR was detected for. -.TP -\fB\-P\fR, \fB\-\-no\-timeout\-reports\fR -When the IR receiver times out due to inactivity, do not report this. -This is the default. -.TP \fB\-t\fR, \fB\-\-timeout\fR=\fITIMEOUT\fR -Set the length of a space at which the recorder goes idle, specified in +Set the length of a space at which the receiver goes idle, specified in microseconds. .TP \fB\-c\fR, \fB\-\-carrier\fR=\fICARRIER\fR @@ -172,11 +165,15 @@ .PP scancode rc5:0x1e01 .PP -Do not specify scancodes with different protocols in one file, as the -carrier might differ and the transmitter cannot send this. Multiple -scancodes can be specified in one file but ensure that the rules for the -protocol are met by inserting an appropriate space between them. Also, -there are limits to what lirc devices can send in one go. +If multiple scancodes are specified in a file, a gap is inserted between +scancodes if there is no space between then (see \fB\-\-gap\fR). One file +can only have one carrier frequency, so this might cause problems +if different protocols are specified in one file if they use different +carrier frequencies. +.PP +Note that there are device-specific limits of how much IR can be sent +at a time. This can be both the length of the IR and the number of +different lengths of space and pulse. .PP .SS Supported Protocols A scancode with protocol can be specified on the command line or in the @@ -214,7 +211,7 @@ .br \fBir\-ctl \-r \-m \-w\fR .PP -Note that \fBir\-ctl \-rmw\fR would record to a file called \fBmw\fR. +Note that \fBir\-ctl \-rmw\fR would receive to a file called \fBmw\fR. .PP To restore the normal (longer distance) receiver: .br @@ -230,7 +227,7 @@ .PP To restore the IR receiver on /dev/lirc2 to the default state: .br - \fBir\-ctl \-PMn \-\-timeout 125000 \-\-device=/dev/lirc2\fR + \fBir\-ctl \-Mn \-\-timeout 125000 \-\-device=/dev/lirc2\fR .SH BUGS Report bugs to \fBLinux Media Mailing List \fR .SH COPYRIGHT diff -Nru v4l-utils-1.10.0+r3508/utils/ir-ctl/ir-ctl.c v4l-utils-1.10.0+r3520/utils/ir-ctl/ir-ctl.c --- v4l-utils-1.10.0+r3508/utils/ir-ctl/ir-ctl.c 2017-12-13 17:01:40.000000000 +0000 +++ v4l-utils-1.10.0+r3520/utils/ir-ctl/ir-ctl.c 2017-12-14 17:01:56.000000000 +0000 @@ -1,5 +1,5 @@ /* - * ir-ctl.c - Program to send and record IR using lirc interface + * ir-ctl.c - Program to send and receive IR using lirc interface * * Copyright (C) 2016 Sean Young * @@ -27,10 +27,10 @@ #include -#include "ir-encode.h" - #include +#include "ir-encode.h" + #ifdef ENABLE_NLS # define _(string) gettext(string) # include "gettext.h" @@ -66,15 +66,24 @@ struct file { struct file *next; const char *fname; - unsigned carrier; - unsigned len; - unsigned buf[LIRCBUF_SIZE]; + bool is_scancode; + union { + struct { + unsigned carrier; + unsigned len; + unsigned buf[LIRCBUF_SIZE]; + }; + struct { + unsigned scancode; + unsigned protocol; + }; + }; }; struct arguments { char *device; bool features; - bool record; + bool receive; bool verbose; struct file *send; bool oneshot; @@ -84,7 +93,6 @@ unsigned timeout; unsigned gap; int carrier_reports; - int timeout_reports; unsigned carrier; unsigned duty; unsigned emitters; @@ -94,20 +102,18 @@ static const struct argp_option options[] = { { "device", 'd', N_("DEV"), 0, N_("lirc device to use") }, { "features", 'f', 0, 0, N_("list lirc device features") }, - { "record", 'r', N_("FILE"), OPTION_ARG_OPTIONAL, N_("record IR to stdout or file") }, + { "receive", 'r', N_("FILE"), OPTION_ARG_OPTIONAL, N_("receive IR to stdout or file") }, { "send", 's', N_("FILE"), 0, N_("send IR pulse and space file") }, { "scancode", 'S', N_("SCANCODE"), 0, N_("send IR scancode in protocol specified") }, { "verbose", 'v', 0, 0, N_("verbose output") }, { .doc = N_("Recording options:") }, - { "one-shot", '1', 0, 0, N_("end recording after first message") }, + { "one-shot", '1', 0, 0, N_("end receiving after first message") }, { "wideband", 'w', 0, 0, N_("use wideband receiver aka learning mode") }, { "no-wideband",'n', 0, 0, N_("use normal narrowband receiver, disable learning mode") }, { "carrier-range", 'R', N_("RANGE"), 0, N_("set receiver carrier range") }, { "measure-carrier", 'm', 0, 0, N_("report carrier frequency") }, { "no-measure-carrier", 'M', 0, 0, N_("disable reporting carrier frequency") }, - { "timeout-reports", 'p', 0, 0, N_("report when a timeout occurs") }, - { "no-timeout-reports", 'P', 0, 0, N_("disable reporting when a timeout occurs") }, - { "timeout", 't', N_("TIMEOUT"), 0, N_("set recording timeout") }, + { "timeout", 't', N_("TIMEOUT"), 0, N_("set receiving timeout") }, { .doc = N_("Sending options:") }, { "carrier", 'c', N_("CARRIER"), 0, N_("set send carrier") }, { "duty-cycle", 'D', N_("DUTY"), 0, N_("set duty cycle") }, @@ -118,7 +124,7 @@ static const char args_doc[] = N_( "--features\n" - "--record [save to file]\n" + "--receive [save to file]\n" "--send [file to send]\n" "--scancode [scancode to send]\n" "[to set lirc option]"); @@ -134,7 +140,7 @@ " EMITTERS - comma separated list of emitters to use for sending, e.g. 1,2\n" " GAP - gap between pulse and files or scancodes in microseconds\n" " RANGE - set range of accepted carrier frequencies, e.g. 20000-40000\n" - " TIMEOUT - set length of space before recording stops in microseconds\n" + " TIMEOUT - set length of space before receiving stops in microseconds\n" " SCANCODE - protocol:scancode, e.g. nec:0xa814\n\n" "Note that most lirc setting have global state, i.e. the device will remain\n" "in this state until set otherwise."); @@ -209,6 +215,7 @@ fprintf(stderr, _("Failed to allocate memory\n")); return NULL; } + f->is_scancode = false; f->carrier = 0; f->fname = fname; @@ -255,6 +262,11 @@ return NULL; } + if (!protocol_encoder_available(proto)) { + fprintf(stderr, _("error: %s:%d: no encoder available for `%s'\n"), fname, lineno, protocol_name(proto)); + return NULL; + } + if (!protocol_scancode_valid(proto, scancode)) { fprintf(stderr, _("error: %s:%d: invalid scancode '%s' for protocol '%s'\n"), fname, lineno, scancodestr, protocol_name(proto)); return NULL; @@ -381,9 +393,9 @@ return NULL; } - f->carrier = protocol_carrier(proto); - f->fname = name; - f->len = protocol_encode(proto, scancode, f->buf); + f->is_scancode = true; + f->scancode = scancode; + f->protocol = proto; return f; } @@ -395,19 +407,19 @@ switch (k) { case 'f': - if (arguments->record || arguments->send) - argp_error(state, _("features can not be combined with record or send option")); + if (arguments->receive || arguments->send) + argp_error(state, _("features can not be combined with receive or send option")); arguments->features = true; break; - // recording + // receiving case 'r': if (arguments->features || arguments->send) - argp_error(state, _("record can not be combined with features or send option")); + argp_error(state, _("receive can not be combined with features or send option")); - arguments->record = true; + arguments->receive = true; if (arg) { if (arguments->savetofile) - argp_error(state, _("record filename already set")); + argp_error(state, _("receive filename already set")); arguments->savetofile = arg; } @@ -430,18 +442,6 @@ arguments->carrier_reports = 2; break; - case 'p': - if (arguments->timeout_reports == 2) - argp_error(state, _("cannot enable and disable timeout reports")); - - arguments->timeout_reports = 1; - break; - case 'P': - if (arguments->timeout_reports == 1) - argp_error(state, _("cannot enable and disable timeout reports")); - - arguments->timeout_reports = 2; - break; case 'n': if (arguments->wideband) argp_error(state, _("cannot use narrowband and wideband receiver at once")); @@ -500,8 +500,8 @@ argp_error(state, _("invalid duty cycle `%s'"), arg); break; case 's': - if (arguments->record || arguments->features) - argp_error(state, _("send can not be combined with record or features option")); + if (arguments->receive || arguments->features) + argp_error(state, _("send can not be combined with receive or features option")); s = read_file(arguments, arg); if (s == NULL) exit(EX_DATAERR); @@ -516,8 +516,8 @@ } break; case 'S': - if (arguments->record || arguments->features) - argp_error(state, _("send can not be combined with record or features option")); + if (arguments->receive || arguments->features) + argp_error(state, _("send can not be combined with receive or features option")); s = read_scancode(arg); if (s == NULL) exit(EX_DATAERR); @@ -609,7 +609,7 @@ if (features & LIRC_CAN_SET_REC_TIMEOUT) { rc = ioctl(fd, LIRC_SET_REC_TIMEOUT, &args->timeout); if (rc) - fprintf(stderr, _("%s: failed to set recording timeout\n"), dev); + fprintf(stderr, _("%s: failed to set receiving timeout\n"), dev); } else fprintf(stderr, _("%s: device does not support setting timeout\n"), dev); } @@ -634,11 +634,11 @@ fprintf(stderr, _("%s: device cannot measure carrier\n"), dev); } - if (args->timeout_reports) { - unsigned on = args->timeout_reports == 1; + if (features & LIRC_CAN_REC_MODE2) { + unsigned on = 1; rc = ioctl(fd, LIRC_SET_REC_TIMEOUT_REPORTS, &on); if (rc) - fprintf(stderr, _("%s: failed to set timeout reports %s: %m\n"), dev, on ? _("on") : _("off")); + fprintf(stderr, _("%s: failed to enable timeout reports: %m\n"), dev); } if (args->carrier_low) { @@ -694,7 +694,12 @@ fprintf(stderr, _("warning: %s: unexpected error while retrieving resolution: %m\n"), dev); } + bool can_receive = false; printf(_("Receive features %s:\n"), dev); + if (features & LIRC_CAN_REC_SCANCODE) { + printf(_(" - Device can receive scancodes\n")); + can_receive = true; + } if (features & LIRC_CAN_REC_MODE2) { printf(_(" - Device can receive raw IR\n")); if (resolution) @@ -709,28 +714,37 @@ unsigned min_timeout, max_timeout; int rc = ioctl(fd, LIRC_GET_MIN_TIMEOUT, &min_timeout); if (rc) { - fprintf(stderr, _("warning: %s: device supports setting recording timeout but LIRC_GET_MIN_TIMEOUT returns: %m\n"), dev); + fprintf(stderr, _("warning: %s: device supports setting receiving timeout but LIRC_GET_MIN_TIMEOUT returns: %m\n"), dev); min_timeout = 0; } else if (min_timeout == 0) - fprintf(stderr, _("warning: %s: device supports setting recording timeout but min timeout is 0\n"), dev); + fprintf(stderr, _("warning: %s: device supports setting receiving timeout but min timeout is 0\n"), dev); rc = ioctl(fd, LIRC_GET_MAX_TIMEOUT, &max_timeout); if (rc) { - fprintf(stderr, _("warning: %s: device supports setting recording timeout but LIRC_GET_MAX_TIMEOUT returns: %m\n"), dev); + fprintf(stderr, _("warning: %s: device supports setting receiving timeout but LIRC_GET_MAX_TIMEOUT returns: %m\n"), dev); max_timeout = 0; } else if (max_timeout == 0) { - fprintf(stderr, _("warning: %s: device supports setting recording timeout but max timeout is 0\n"), dev); + fprintf(stderr, _("warning: %s: device supports setting receiving timeout but max timeout is 0\n"), dev); } if (min_timeout || max_timeout) - printf(_(" - Can set recording timeout min:%u microseconds max:%u microseconds\n"), min_timeout, max_timeout); + printf(_(" - Can set receiving timeout min:%u microseconds max:%u microseconds\n"), min_timeout, max_timeout); } - } else if (features & LIRC_CAN_REC_LIRCCODE) { + can_receive = true; + } + if (features & LIRC_CAN_REC_LIRCCODE) { printf(_(" - Device can receive using device dependent LIRCCODE mode (not supported)\n")); - } else { - printf(_(" - Device cannot receive\n")); + can_receive = true; } + if (!can_receive) + printf(_(" - Device cannot receive\n")); + + bool can_send = false; printf(_("Send features %s:\n"), dev); + if (features & LIRC_CAN_SEND_SCANCODE) { + printf(_(" - Device can send scancodes\n")); + can_send = true; + } if (features & LIRC_CAN_SEND_PULSE) { printf(_(" - Device can send raw IR\n")); if (features & LIRC_CAN_SET_SEND_CARRIER) @@ -747,26 +761,60 @@ else printf(_(" - Set transmitter (%d available)\n"), rc); } - } else if (features & LIRC_CAN_SEND_LIRCCODE) { + can_send = true; + } + if (features & LIRC_CAN_SEND_LIRCCODE) { printf(_(" - Device can send using device dependent LIRCCODE mode (not supported)\n")); - } else { - printf(_(" - Device cannot send\n")); + can_send = true; } + + if (!can_send) + printf(_(" - Device cannot send\n")); } static int lirc_send(struct arguments *args, int fd, unsigned features, struct file *f) { const char *dev = args->device; - int mode = LIRC_MODE_PULSE; + int rc, mode; + ssize_t ret; + + if (f->is_scancode && (features & LIRC_CAN_SEND_SCANCODE)) { + mode = LIRC_MODE_SCANCODE; + rc = ioctl(fd, LIRC_SET_SEND_MODE, &mode); + if (rc == 0) { + struct lirc_scancode sc = { + .scancode = f->scancode, + .rc_proto = f->protocol, + .flags = 0 + }; + ret = TEMP_FAILURE_RETRY(write(fd, &sc, sizeof sc)); + if (ret > 0) + return 0; + } + } if (!(features & LIRC_CAN_SEND_PULSE)) { fprintf(stderr, _("%s: device cannot send raw ir\n"), dev); return EX_UNAVAILABLE; } - if (ioctl(fd, LIRC_SET_SEND_MODE, &mode)) { - fprintf(stderr, _("%s: failed to set send mode: %m\n"), dev); - return EX_IOERR; + mode = LIRC_MODE_PULSE; + rc = ioctl(fd, LIRC_SET_SEND_MODE, &mode); + if (rc) { + fprintf(stderr, _("%s: cannot set send mode\n"), dev); + return EX_UNAVAILABLE; + } + + if (f->is_scancode) { + // encode scancode + enum rc_proto proto = f->protocol; + if (!protocol_encoder_available(proto)) { + fprintf(stderr, _("%s: no encoder available for `%s'\n"), + dev, protocol_name(proto)); + return EX_UNAVAILABLE; + } + f->len = protocol_encode(f->protocol, f->scancode, f->buf); + f->carrier = protocol_carrier(proto); } if (args->carrier && f->carrier) @@ -781,7 +829,7 @@ for (i=0; ilen; i++) printf("%s %u\n", i & 1 ? "space" : "pulse", f->buf[i]); } - ssize_t ret = TEMP_FAILURE_RETRY(write(fd, f->buf, size)); + ret = TEMP_FAILURE_RETRY(write(fd, f->buf, size)); if (ret < 0) { fprintf(stderr, _("%s: failed to send: %m\n"), dev); return EX_IOERR; @@ -800,7 +848,7 @@ return 0; } -int lirc_record(struct arguments *args, int fd, unsigned features) +int lirc_receive(struct arguments *args, int fd, unsigned features) { char *dev = args->device; FILE *out = stdout; @@ -808,13 +856,13 @@ int mode = LIRC_MODE_MODE2; if (!(features & LIRC_CAN_REC_MODE2)) { - fprintf(stderr, _("%s: device cannot record raw ir\n"), dev); + fprintf(stderr, _("%s: device cannot receive raw ir\n"), dev); return EX_UNAVAILABLE; } // kernel v4.8 and v4.9 return ENOTTY if (ioctl(fd, LIRC_SET_REC_MODE, &mode) && errno != ENOTTY) { - fprintf(stderr, _("%s: failed to set record mode: %m\n"), dev); + fprintf(stderr, _("%s: failed to set receive mode: %m\n"), dev); return EX_IOERR; } @@ -932,8 +980,8 @@ s = next; } - if (args.record) { - rc = lirc_record(&args, fd, features); + if (args.receive) { + rc = lirc_receive(&args, fd, features); if (rc) { close(fd); exit(rc); diff -Nru v4l-utils-1.10.0+r3508/utils/ir-ctl/ir-encode.c v4l-utils-1.10.0+r3520/utils/ir-ctl/ir-encode.c --- v4l-utils-1.10.0+r3508/utils/ir-ctl/ir-encode.c 2017-12-13 17:01:40.000000000 +0000 +++ v4l-utils-1.10.0+r3520/utils/ir-ctl/ir-encode.c 2017-12-14 17:01:56.000000000 +0000 @@ -19,8 +19,11 @@ #include #include +#include #include +#include + #include "ir-encode.h" #define NS_TO_US(x) (((x)+500)/1000) @@ -349,7 +352,7 @@ unsigned max_edges; unsigned carrier; int (*encode)(enum rc_proto proto, unsigned scancode, unsigned *buf); -} encoders[RC_PROTO_COUNT] = { +} protocols[] = { [RC_PROTO_RC5] = { "rc5", 0x1f7f, 24, 36000, rc5_encode }, [RC_PROTO_RC5X_20] = { "rc5x_20", 0x1f7f3f, 40, 36000, rc5_encode }, [RC_PROTO_RC5_SZ] = { "rc5_sz", 0x2fff, 26, 36000, rc5_encode }, @@ -367,6 +370,10 @@ [RC_PROTO_RC6_6A_32] = { "rc6_6a_32", 0xffffffff, 76, 36000, rc6_encode }, [RC_PROTO_RC6_MCE] = { "rc6_mce", 0xffff7fff, 76, 36000, rc6_encode }, [RC_PROTO_SHARP] = { "sharp", 0x1fff, 63, 38000, sharp_encode }, + [RC_PROTO_MCIR2_KBD] = { "mcir2-kbd" }, + [RC_PROTO_MCIR2_MSE] = { "mcir2-mse" }, + [RC_PROTO_XMP] = { "xmp" }, + [RC_PROTO_CEC] = { "cec" }, }; static bool str_like(const char *a, const char *b) @@ -393,8 +400,8 @@ { enum rc_proto p; - for (p=0; p= ARRAY_SIZE(protocols) || !protocols[proto].name[0]) + return NULL; + + return protocols[proto].name; } diff -Nru v4l-utils-1.10.0+r3508/utils/ir-ctl/ir-encode.h v4l-utils-1.10.0+r3520/utils/ir-ctl/ir-encode.h --- v4l-utils-1.10.0+r3508/utils/ir-ctl/ir-encode.h 2017-12-13 17:01:40.000000000 +0000 +++ v4l-utils-1.10.0+r3520/utils/ir-ctl/ir-encode.h 2017-12-14 17:01:56.000000000 +0000 @@ -2,34 +2,14 @@ #ifndef __IR_ENCODE_H__ #define __IR_ENCODE_H__ -enum rc_proto { - RC_PROTO_RC5, - RC_PROTO_RC5X_20, - RC_PROTO_RC5_SZ, - RC_PROTO_JVC, - RC_PROTO_SONY12, - RC_PROTO_SONY15, - RC_PROTO_SONY20, - RC_PROTO_NEC, - RC_PROTO_NECX, - RC_PROTO_NEC32, - RC_PROTO_SANYO, - RC_PROTO_MCE_KBD, - RC_PROTO_RC6_0, - RC_PROTO_RC6_6A_20, - RC_PROTO_RC6_6A_24, - RC_PROTO_RC6_6A_32, - RC_PROTO_RC6_MCE, - RC_PROTO_SHARP, - RC_PROTO_XMP, - RC_PROTO_COUNT -}; +#define ARRAY_SIZE(x) (sizeof(x)/sizeof((x)[0])) bool protocol_match(const char *name, enum rc_proto *proto); unsigned protocol_carrier(enum rc_proto proto); unsigned protocol_max_size(enum rc_proto proto); bool protocol_scancode_valid(enum rc_proto proto, unsigned scancode); unsigned protocol_scancode_mask(enum rc_proto proto); +bool protocol_encoder_available(enum rc_proto proto); unsigned protocol_encode(enum rc_proto proto, unsigned scancode, unsigned *buf); const char *protocol_name(enum rc_proto proto); diff -Nru v4l-utils-1.10.0+r3508/utils/keytable/ir-encode.c v4l-utils-1.10.0+r3520/utils/keytable/ir-encode.c --- v4l-utils-1.10.0+r3508/utils/keytable/ir-encode.c 1970-01-01 00:00:00.000000000 +0000 +++ v4l-utils-1.10.0+r3520/utils/keytable/ir-encode.c 2017-12-14 17:01:56.000000000 +0000 @@ -0,0 +1,465 @@ +/* + * ir-encode.c - encodes IR scancodes in different protocols + * + * Copyright (C) 2016 Sean Young + * + * 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, version 2 of the License. + + * 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. + */ + +/* + * TODO: XMP protocol and MCE keyboard + */ + +#include +#include +#include +#include + +#include + +#include "ir-encode.h" + +#define NS_TO_US(x) (((x)+500)/1000) + +static int nec_encode(enum rc_proto proto, unsigned scancode, unsigned *buf) +{ + const int nec_unit = 562500; + int n = 0; + + void add_byte(unsigned bits) + { + int i; + for (i=0; i<8; i++) { + buf[n++] = NS_TO_US(nec_unit); + if (bits & (1 << i)) + buf[n++] = NS_TO_US(nec_unit * 3); + else + buf[n++] = NS_TO_US(nec_unit); + } + } + + buf[n++] = NS_TO_US(nec_unit * 16); + buf[n++] = NS_TO_US(nec_unit * 8); + + switch (proto) { + default: + return 0; + case RC_PROTO_NEC: + add_byte(scancode >> 8); + add_byte(~(scancode >> 8)); + add_byte(scancode); + add_byte(~scancode); + break; + case RC_PROTO_NECX: + add_byte(scancode >> 16); + add_byte(scancode >> 8); + add_byte(scancode); + add_byte(~scancode); + break; + case RC_PROTO_NEC32: + /* + * At the time of writing kernel software nec decoder + * reverses the bit order so it will not match. Hardware + * decoders do not have this issue. + */ + add_byte(scancode >> 24); + add_byte(scancode >> 16); + add_byte(scancode >> 8); + add_byte(scancode); + break; + } + + buf[n++] = NS_TO_US(nec_unit); + + return n; +} + +static int jvc_encode(enum rc_proto proto, unsigned scancode, unsigned *buf) +{ + const int jvc_unit = 525000; + int i; + + /* swap bytes so address comes first */ + scancode = ((scancode << 8) & 0xff00) | ((scancode >> 8) & 0x00ff); + + *buf++ = NS_TO_US(jvc_unit * 16); + *buf++ = NS_TO_US(jvc_unit * 8); + + for (i=0; i<16; i++) { + *buf++ = NS_TO_US(jvc_unit); + + if (scancode & 1) + *buf++ = NS_TO_US(jvc_unit * 3); + else + *buf++ = NS_TO_US(jvc_unit); + + scancode >>= 1; + } + + *buf = NS_TO_US(jvc_unit); + + return 35; +} + +static int sanyo_encode(enum rc_proto proto, unsigned scancode, unsigned *buf) +{ + const int sanyo_unit = 562500; + + void add_bits(int bits, int count) + { + int i; + for (i=0; i> 8, 13); + add_bits(~(scancode >> 8), 13); + add_bits(scancode, 8); + add_bits(~scancode, 8); + + *buf = NS_TO_US(sanyo_unit); + + return 87; +} + +static int sharp_encode(enum rc_proto proto, unsigned scancode, unsigned *buf) +{ + const int sharp_unit = 40000; + + void add_bits(int bits, int count) + { + int i; + for (i=0; i> 8, 5); + add_bits(scancode, 8); + add_bits(1, 2); + + *buf++ = NS_TO_US(sharp_unit * 8); + *buf++ = NS_TO_US(sharp_unit * 1000); + + add_bits(scancode >> 8, 5); + add_bits(~scancode, 8); + add_bits(~1, 2); + *buf++ = NS_TO_US(sharp_unit * 8); + + return (13 + 2) * 4 + 3; +} + +static int sony_encode(enum rc_proto proto, unsigned scancode, unsigned *buf) +{ + const int sony_unit = 600000; + int n = 0; + + void add_bits(int bits, int count) + { + int i; + for (i=0; i> 16, 5); + break; + case RC_PROTO_SONY15: + add_bits(scancode, 7); + add_bits(scancode >> 16, 8); + break; + case RC_PROTO_SONY20: + add_bits(scancode, 7); + add_bits(scancode >> 16, 5); + add_bits(scancode >> 8, 8); + break; + default: + return 0; + } + + /* ignore last space */ + return n - 1; +} + +static int rc5_encode(enum rc_proto proto, unsigned scancode, unsigned *buf) +{ + const unsigned int rc5_unit = 888888; + unsigned n = 0; + + void advance_space(unsigned length) + { + if (n % 2) + buf[n] += length; + else + buf[++n] = length; + } + + void advance_pulse(unsigned length) + { + if (n % 2) + buf[++n] = length; + else + buf[n] += length; + } + + void add_bits(int bits, int count) + { + while (count--) { + if (bits & (1 << count)) { + advance_space(NS_TO_US(rc5_unit)); + advance_pulse(NS_TO_US(rc5_unit)); + } else { + advance_pulse(NS_TO_US(rc5_unit)); + advance_space(NS_TO_US(rc5_unit)); + } + } + } + + buf[n] = NS_TO_US(rc5_unit); + + switch (proto) { + default: + return 0; + case RC_PROTO_RC5: + add_bits(!(scancode & 0x40), 1); + add_bits(0, 1); + add_bits(scancode >> 8, 5); + add_bits(scancode, 6); + break; + case RC_PROTO_RC5_SZ: + add_bits(!!(scancode & 0x2000), 1); + add_bits(0, 1); + add_bits(scancode >> 6, 6); + add_bits(scancode, 6); + break; + case RC_PROTO_RC5X_20: + add_bits(!(scancode & 0x4000), 1); + add_bits(0, 1); + add_bits(scancode >> 16, 5); + advance_space(NS_TO_US(rc5_unit * 4)); + add_bits(scancode >> 8, 6); + add_bits(scancode, 6); + break; + } + + /* drop any trailing pulse */ + return (n % 2) ? n : n + 1; +} + +static int rc6_encode(enum rc_proto proto, unsigned scancode, unsigned *buf) +{ + const unsigned int rc6_unit = 444444; + unsigned n = 0; + + void advance_space(unsigned length) + { + if (n % 2) + buf[n] += length; + else + buf[++n] = length; + } + + void advance_pulse(unsigned length) + { + if (n % 2) + buf[++n] = length; + else + buf[n] += length; + } + + void add_bits(unsigned bits, unsigned count, unsigned length) + { + while (count--) { + if (bits & (1 << count)) { + advance_pulse(length); + advance_space(length); + } else { + advance_space(length); + advance_pulse(length); + } + } + } + + buf[n++] = NS_TO_US(rc6_unit * 6); + buf[n++] = NS_TO_US(rc6_unit * 2); + buf[n] = 0; + + switch (proto) { + default: + return 0; + case RC_PROTO_RC6_0: + add_bits(8, 4, NS_TO_US(rc6_unit)); + add_bits(0, 1, NS_TO_US(rc6_unit * 2)); + add_bits(scancode, 16, NS_TO_US(rc6_unit)); + break; + case RC_PROTO_RC6_6A_20: + add_bits(14, 4, NS_TO_US(rc6_unit)); + add_bits(0, 1, NS_TO_US(rc6_unit * 2)); + add_bits(scancode, 20, NS_TO_US(rc6_unit)); + break; + case RC_PROTO_RC6_6A_24: + add_bits(14, 4, NS_TO_US(rc6_unit)); + add_bits(0, 1, NS_TO_US(rc6_unit * 2)); + add_bits(scancode, 24, NS_TO_US(rc6_unit)); + break; + case RC_PROTO_RC6_6A_32: + case RC_PROTO_RC6_MCE: + add_bits(14, 4, NS_TO_US(rc6_unit)); + add_bits(0, 1, NS_TO_US(rc6_unit * 2)); + add_bits(scancode, 32, NS_TO_US(rc6_unit)); + break; + } + + /* drop any trailing pulse */ + return (n % 2) ? n : n + 1; +} + +static const struct { + char name[10]; + unsigned scancode_mask; + unsigned max_edges; + unsigned carrier; + int (*encode)(enum rc_proto proto, unsigned scancode, unsigned *buf); +} protocols[] = { + [RC_PROTO_RC5] = { "rc5", 0x1f7f, 24, 36000, rc5_encode }, + [RC_PROTO_RC5X_20] = { "rc5x_20", 0x1f7f3f, 40, 36000, rc5_encode }, + [RC_PROTO_RC5_SZ] = { "rc5_sz", 0x2fff, 26, 36000, rc5_encode }, + [RC_PROTO_SONY12] = { "sony12", 0x1f007f, 25, 40000, sony_encode }, + [RC_PROTO_SONY15] = { "sony15", 0xff007f, 31, 40000, sony_encode }, + [RC_PROTO_SONY20] = { "sony20", 0x1fff7f, 41, 40000, sony_encode }, + [RC_PROTO_JVC] = { "jvc", 0xffff, 35, 38000, jvc_encode }, + [RC_PROTO_NEC] = { "nec", 0xffff, 67, 38000, nec_encode }, + [RC_PROTO_NECX] = { "necx", 0xffffff, 67, 38000, nec_encode }, + [RC_PROTO_NEC32] = { "nec32", 0xffffffff, 67, 38000, nec_encode }, + [RC_PROTO_SANYO] = { "sanyo", 0x1fffff, 87, 38000, sanyo_encode }, + [RC_PROTO_RC6_0] = { "rc6_0", 0xffff, 24, 36000, rc6_encode }, + [RC_PROTO_RC6_6A_20] = { "rc6_6a_20", 0xfffff, 52, 36000, rc6_encode }, + [RC_PROTO_RC6_6A_24] = { "rc6_6a_24", 0xffffff, 60, 36000, rc6_encode }, + [RC_PROTO_RC6_6A_32] = { "rc6_6a_32", 0xffffffff, 76, 36000, rc6_encode }, + [RC_PROTO_RC6_MCE] = { "rc6_mce", 0xffff7fff, 76, 36000, rc6_encode }, + [RC_PROTO_SHARP] = { "sharp", 0x1fff, 63, 38000, sharp_encode }, + [RC_PROTO_MCIR2_KBD] = { "mcir2-kbd" }, + [RC_PROTO_MCIR2_MSE] = { "mcir2-mse" }, + [RC_PROTO_XMP] = { "xmp" }, + [RC_PROTO_CEC] = { "cec" }, +}; + +static bool str_like(const char *a, const char *b) +{ + while (*a && *b) { + while (*a == ' ' || *a == '-' || *a == '_') + a++; + while (*b == ' ' || *b == '-' || *b == '_') + b++; + + if (*a >= 0x7f || *b >= 0x7f) + return false; + + if (tolower(*a) != tolower(*b)) + return false; + + a++; b++; + } + + return !*a && !*b; +} + +bool protocol_match(const char *name, enum rc_proto *proto) +{ + enum rc_proto p; + + for (p=0; p> 16) ^ ~(s >> 8)) & 0xff) != 0; + } else if (p == RC_PROTO_NEC32) { + return (((s >> 24) ^ ~(s >> 16)) & 0xff) != 0; + } else if (p == RC_PROTO_RC6_MCE) { + return (s & 0xffff0000) == 0x800f0000; + } else if (p == RC_PROTO_RC6_6A_32) { + return (s & 0xffff0000) != 0x800f0000; + } + + return true; +} + +bool protocol_encoder_available(enum rc_proto proto) +{ + return protocols[proto].encode != NULL; +} + +unsigned protocol_encode(enum rc_proto proto, unsigned scancode, unsigned *buf) +{ + if (!protocols[proto].encode) + return 0; + + return protocols[proto].encode(proto, scancode, buf); +} + +const char* protocol_name(enum rc_proto proto) +{ + if (proto >= ARRAY_SIZE(protocols) || !protocols[proto].name[0]) + return NULL; + + return protocols[proto].name; +} diff -Nru v4l-utils-1.10.0+r3508/utils/keytable/ir-encode.h v4l-utils-1.10.0+r3520/utils/keytable/ir-encode.h --- v4l-utils-1.10.0+r3508/utils/keytable/ir-encode.h 1970-01-01 00:00:00.000000000 +0000 +++ v4l-utils-1.10.0+r3520/utils/keytable/ir-encode.h 2017-12-14 17:01:56.000000000 +0000 @@ -0,0 +1,16 @@ + +#ifndef __IR_ENCODE_H__ +#define __IR_ENCODE_H__ + +#define ARRAY_SIZE(x) (sizeof(x)/sizeof((x)[0])) + +bool protocol_match(const char *name, enum rc_proto *proto); +unsigned protocol_carrier(enum rc_proto proto); +unsigned protocol_max_size(enum rc_proto proto); +bool protocol_scancode_valid(enum rc_proto proto, unsigned scancode); +unsigned protocol_scancode_mask(enum rc_proto proto); +bool protocol_encoder_available(enum rc_proto proto); +unsigned protocol_encode(enum rc_proto proto, unsigned scancode, unsigned *buf); +const char *protocol_name(enum rc_proto proto); + +#endif diff -Nru v4l-utils-1.10.0+r3508/utils/keytable/keytable.c v4l-utils-1.10.0+r3520/utils/keytable/keytable.c --- v4l-utils-1.10.0+r3508/utils/keytable/keytable.c 2017-12-13 17:01:40.000000000 +0000 +++ v4l-utils-1.10.0+r3520/utils/keytable/keytable.c 2017-12-14 17:01:56.000000000 +0000 @@ -18,16 +18,20 @@ #include #include #include +#include #include #include #include +#include #include #include #include #include #include +#include #include +#include "ir-encode.h" #include "parse.h" #ifdef ENABLE_NLS @@ -271,6 +275,7 @@ struct rc_device { char *sysfs_name; /* Device sysfs node name */ char *input_name; /* Input device file name */ + char *lirc_name; /* Lirc device file name */ char *drv_name; /* Kernel driver that implements it */ char *dev_name; /* Kernel device name */ char *keytable_name; /* Keycode table name */ @@ -666,8 +671,10 @@ closedir(dir); if (names == cur_name) { - fprintf(stderr, _("Couldn't find any node at %s%s*.\n"), - dname, node_name); + if (debug) + fprintf(stderr, _("Couldn't find any node at %s%s*.\n"), + dname, node_name); + free (names); names = NULL; } @@ -774,8 +781,10 @@ snprintf(dname, sizeof(dname), "/sys/class/rc/"); names = seek_sysfs_dir(dname, input); - if (!names) + if (!names) { + fprintf(stderr, _("No devices found\n")); return NULL; + } if (debug) { for (cur = names; cur->next; cur = cur->next) { @@ -1031,15 +1040,33 @@ static int get_attribs(struct rc_device *rc_dev, char *sysfs_name) { struct uevents *uevent; - char *input = "input", *event = "event"; + char *input = "input", *event = "event", *lirc = "lirc"; char *DEV = "/dev/"; - static struct sysfs_names *input_names, *event_names, *attribs, *cur; + static struct sysfs_names *input_names, *event_names, *attribs, *cur, *lirc_names; /* Clean the attributes */ memset(rc_dev, 0, sizeof(*rc_dev)); rc_dev->sysfs_name = sysfs_name; + lirc_names = seek_sysfs_dir(rc_dev->sysfs_name, lirc); + if (lirc_names) { + uevent = read_sysfs_uevents(lirc_names->name); + free_names(lirc_names); + if (uevent) { + while (uevent->next) { + if (!strcmp(uevent->key, "DEVNAME")) { + rc_dev->lirc_name = malloc(strlen(uevent->value) + strlen(DEV) + 1); + strcpy(rc_dev->lirc_name, DEV); + strcat(rc_dev->lirc_name, uevent->value); + break; + } + uevent = uevent->next; + } + free_uevent(uevent); + } + } + input_names = seek_sysfs_dir(rc_dev->sysfs_name, input); if (!input_names) return EINVAL; @@ -1051,9 +1078,13 @@ fprintf(stderr, _("Input sysfs node is %s\n"), input_names->name); event_names = seek_sysfs_dir(input_names->name, event); - free_names(input_names); - if (!event_names) + if (!event_names) { + fprintf(stderr, _("Couldn't find any node at %s%s*.\n"), + input_names->name, event); + free_names(input_names); return EINVAL; + } + free_names(input_names); if (event_names->next->next) { free_names(event_names); fprintf(stderr, _("Found more than one event interface. This is currently unsupported\n")); @@ -1281,16 +1312,100 @@ return ""; } -static void test_event(int fd) +static void print_scancodes(const struct lirc_scancode *scancodes, unsigned count) +{ + unsigned i; + + for (i=0; i< count; i++) { + const char *p = protocol_name(scancodes[i].rc_proto); + + printf(_("%llu.%06llu: "), + scancodes[i].timestamp / 1000000000ull, + (scancodes[i].timestamp % 1000000000ull) / 1000ull); + + if (p) + printf(_("lirc protocol(%s): scancode = 0x%llx"), + p, scancodes[i].scancode); + else + printf(_("lirc protocol(%d): scancode = 0x%llx"), + scancodes[i].rc_proto, scancodes[i].scancode); + + if (scancodes[i].flags & LIRC_SCANCODE_FLAG_REPEAT) + printf(_(" repeat")); + if (scancodes[i].flags & LIRC_SCANCODE_FLAG_TOGGLE) + printf(_(" toggle=1")); + + printf("\n"); + } +} + +static void test_event(struct rc_device *rc_dev, int fd) { struct input_event ev[64]; - int rd, i; + struct lirc_scancode sc[64]; + int rd, i, lircfd = -1; + unsigned mode; + + /* LIRC reports time in monotonic, set event to same */ + mode = CLOCK_MONOTONIC; + ioctl(fd, EVIOCSCLOCKID, &mode); + + if (rc_dev->lirc_name) { + lircfd = open(rc_dev->lirc_name, O_RDONLY | O_NONBLOCK); + if (lircfd == -1) { + perror(_("Can't open lirc device")); + return; + } + unsigned features; + if (ioctl(lircfd, LIRC_GET_FEATURES, &features)) { + perror(_("Can't get lirc features")); + return; + } + + if (!(features & LIRC_CAN_REC_SCANCODE)) { + close(lircfd); + lircfd = -1; + } + else { + unsigned mode = LIRC_MODE_SCANCODE; + if (ioctl(lircfd, LIRC_SET_REC_MODE, &mode)) { + perror(_("Can't set lirc scancode mode")); + return; + } + } + } printf (_("Testing events. Please, press CTRL-C to abort.\n")); while (1) { + struct pollfd pollstruct[2] = { + { .fd = fd, .events = POLLIN }, + { .fd = lircfd, .events = POLLIN }, + }; + + if (poll(pollstruct, 2, -1) < 0) { + if (errno == EINTR) + continue; + + perror(_("poll returned error")); + } + + if (lircfd != -1) { + rd = read(lircfd, sc, sizeof(sc)); + + if (rd != -1) { + print_scancodes(sc, rd / sizeof(struct lirc_scancode)); + } else if (errno != EAGAIN) { + perror(_("Error reading lirc scancode")); + return; + } + } + rd = read(fd, ev, sizeof(ev)); if (rd < (int) sizeof(struct input_event)) { + if (errno == EAGAIN) + continue; + perror(_("Error reading event")); return; } @@ -1482,6 +1597,9 @@ fprintf(stderr, _("\tDriver: %s, table: %s\n"), rc_dev->drv_name, rc_dev->keytable_name); + if (rc_dev->lirc_name) + fprintf(stderr, _("\tlirc device: %s\n"), + rc_dev->lirc_name); fprintf(stderr, _("\tSupported protocols: ")); write_sysfs_protocols(rc_dev->supported, stderr, "%s "); fprintf(stderr, "\n\t"); @@ -1615,7 +1733,7 @@ if (debug) fprintf(stderr, _("Opening %s\n"), devicename); - fd = open(devicename, O_RDONLY); + fd = open(devicename, O_RDONLY | O_NONBLOCK); if (fd < 0) { perror(devicename); return -1; @@ -1674,7 +1792,7 @@ } if (test) - test_event(fd); + test_event(&rc_dev, fd); return 0; } diff -Nru v4l-utils-1.10.0+r3508/utils/keytable/Makefile.am v4l-utils-1.10.0+r3520/utils/keytable/Makefile.am --- v4l-utils-1.10.0+r3508/utils/keytable/Makefile.am 2017-12-13 17:01:40.000000000 +0000 +++ v4l-utils-1.10.0+r3520/utils/keytable/Makefile.am 2017-12-14 17:01:56.000000000 +0000 @@ -4,7 +4,7 @@ keytablesystem_DATA = $(srcdir)/rc_keymaps/* udevrules_DATA = 70-infrared.rules -ir_keytable_SOURCES = keytable.c parse.h +ir_keytable_SOURCES = keytable.c parse.h ir-encode.c ir_keytable_LDADD = @LIBINTL@ ir_keytable_LDFLAGS = $(ARGP_LIBS) diff -Nru v4l-utils-1.10.0+r3508/utils/keytable/parse.h v4l-utils-1.10.0+r3520/utils/keytable/parse.h --- v4l-utils-1.10.0+r3508/utils/keytable/parse.h 2017-12-13 17:01:40.000000000 +0000 +++ v4l-utils-1.10.0+r3520/utils/keytable/parse.h 2017-12-14 17:01:56.000000000 +0000 @@ -332,6 +332,7 @@ {"BTN_TOOL_MOUSE", 0x146}, {"BTN_TOOL_LENS", 0x147}, {"BTN_TOOL_QUINTTAP", 0x148}, + {"BTN_STYLUS3", 0x149}, {"BTN_TOUCH", 0x14a}, {"BTN_STYLUS", 0x14b}, {"BTN_STYLUS2", 0x14c}, diff -Nru v4l-utils-1.10.0+r3508/utils/qv4l2/capture-win.cpp v4l-utils-1.10.0+r3520/utils/qv4l2/capture-win.cpp --- v4l-utils-1.10.0+r3508/utils/qv4l2/capture-win.cpp 2017-12-13 17:01:40.000000000 +0000 +++ v4l-utils-1.10.0+r3520/utils/qv4l2/capture-win.cpp 2017-12-14 17:01:56.000000000 +0000 @@ -353,8 +353,10 @@ } menu->addAction(m_appWin->m_resetScalingAct); - menu->addAction(m_appWin->m_useBlendingAct); - menu->addAction(m_appWin->m_useLinearAct); + if (m_appWin->m_useBlendingAct) + menu->addAction(m_appWin->m_useBlendingAct); + if (m_appWin->m_useLinearAct) + menu->addAction(m_appWin->m_useLinearAct); menu->addAction(m_appWin->m_snapshotAct); menu->addAction(m_appWin->m_showFramesAct); menu->addMenu(m_appWin->m_overrideColorspaceMenu); diff -Nru v4l-utils-1.10.0+r3508/utils/qv4l2/qv4l2.cpp v4l-utils-1.10.0+r3520/utils/qv4l2/qv4l2.cpp --- v4l-utils-1.10.0+r3508/utils/qv4l2/qv4l2.cpp 2017-12-13 17:01:40.000000000 +0000 +++ v4l-utils-1.10.0+r3520/utils/qv4l2/qv4l2.cpp 2017-12-14 17:01:56.000000000 +0000 @@ -274,6 +274,7 @@ } else { m_renderMethod = QV4L2_RENDER_QT; + m_useGLAct = m_useBlendingAct = m_useLinearAct = NULL; } m_capMenu->addAction(m_resetScalingAct);