0

基本上,我想从 shell 或 shell 脚本打开我笔记本的内置网络摄像头,而不必Fn+ESC每次我想打开它时都按一下。

我一直在尝试激活我的 lemote yeeloong 8089B 笔记本中的集成网络摄像头,方法是使用 /dev/uinput,在 debian 挤压下,内核 2.6.32-loongson-2f #1 PREEMPT 来自bjlx。我已经使用 uinput 激活了 WLAN,但是我无法使用 uinput 打开相机。通常,我会按下Fn+ESC打开相机,但使用 uinpuit 似乎不起作用。相机工作正常,可以通过以下方式进行测试:

mplayer tv:// -really-quiet -tv driver=v4l2:device=/dev/video0 </dev/null

我正在使用以下程序(基于 Gregory Thiemonge 和 Mehul Patel 的 HOWTO)尝试使用 uinput 激活我的网络摄像头(抱歉,如果代码有点难看,我有点匆忙写了它):

cam_wlan.c:

#include <errno.h>
#include <fcntl.h>
#include <linux/input.h>
#include <linux/uinput.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#define end(arg) do { \
    perror(arg); \
    exit(EXIT_FAILURE); \
} while (0)

static int fd = -1;
struct uinput_user_dev uidev;
struct input_event ev;

int setup_uinput_dev();
void cam();
void wifi();
int destroy_close();

int main(void) {
    setup_uinput_dev();
    cam();
    wifi();
    destroy_close();
    return 0;
}

int setup_uinput_dev() {
    fd = open("/dev/uinput", O_WRONLY | O_NDELAY);
    if(fd < 0)
        end("Unable to open /dev/uinput\n");
    memset(&uidev,0,sizeof(uidev));
    strncpy(uidev.name, "uinput-sample", UINPUT_MAX_NAME_SIZE);
    uidev.id.version = 1;
    uidev.id.bustype = BUS_USB;
    if(ioctl(fd, UI_SET_EVBIT, EV_KEY) < 0)
        end("Unable to setup UINPUT device.\n");
    if(ioctl(fd, UI_SET_KEYBIT, KEY_CAMERA) < 0)
        end("Unable to setup UINPUT device.\n");
    if(ioctl(fd, UI_SET_KEYBIT, KEY_WLAN) < 0)
        end("Unable to setup UINPUT device.\n");
    if(write(fd, &uidev, sizeof(uidev)) < 0)
        end("Unable to write to UINPUT device.\n");
    if(ioctl(fd, UI_DEV_CREATE) < 0)
        end("Unable to create UINPUT device.\n");
    return 0;
}

void cam() {
    memset(&ev, 0, sizeof(ev));
    ev.type = EV_KEY;
    ev.code = KEY_CAMERA;
    ev.value = 1;
    if(write(fd, &ev, sizeof(struct input_event)) < 0)
        end("Unable to write to UINPUT device.\n");
    ev.type = EV_SYN;
    ev.code = SYN_REPORT;
    ev.value = 0;
    if(write(fd, &ev, sizeof(struct input_event)) < 0)
        end("Unable to write to UINPUT device.\n");
    memset(&ev, 0, sizeof(ev));
    ev.type = EV_KEY;
    ev.code = KEY_CAMERA;
    ev.value = 0;
    if(write(fd, &ev, sizeof(struct input_event)) < 0)
        end("Unable to write to UINPUT device.\n");
    ev.type = EV_SYN;
    ev.code = SYN_REPORT;
    ev.value = 0;
    if(write(fd, &ev, sizeof(struct input_event)) < 0)
        end("Unable to write to UINPUT device.\n");
}

void wifi() {
    memset(&ev, 0, sizeof(ev));
    ev.type = EV_KEY;
    ev.code = KEY_WLAN;
    ev.value = 1;
    if(write(fd, &ev, sizeof(struct input_event)) < 0)
        end("Unable to write to UINPUT device.\n");
    ev.type = EV_SYN;
    ev.code = SYN_REPORT;
    ev.value = 0;
    if(write(fd, &ev, sizeof(struct input_event)) < 0)
        end("Unable to write to UINPUT device.\n");
    memset(&ev, 0, sizeof(ev));
    ev.type = EV_KEY;
    ev.code = KEY_WLAN;
    ev.value = 0;
    if(write(fd, &ev, sizeof(struct input_event)) < 0)
        end("Unable to write to UINPUT device.\n");
    ev.type = EV_SYN;
    ev.code = SYN_REPORT;
    ev.value = 0;
    if(write(fd, &ev, sizeof(struct input_event)) < 0)
        end("Unable to write to UINPUT device.\n");
}

int destroy_close() {
    if(ioctl(fd, UI_DEV_DESTROY) < 0)
        end("Unable to destroy UINPUT device.\n");
    close(fd);
    return 0;
}

我编译

gcc -o cam_wlan cam_wlan.c

在运行之前cam_wlan,必须以 root 身份:

modprobe uinput
lsmod | grep uinput
ls /dev/uinput

确认 uinput 设备已被激活。

我遇到的问题是,当我运行时cam_wlan,WLAN LED 会切换,但网络摄像头没有。通常,当我按下Fn+ESC切换内置网络摄像头时,dmesg会显示:

[45254.379000] usb 1-1: new high speed USB device using ehci_hcd and address 15
[45254.536000] usb 1-1: New USB device found, idVendor=064e, idProduct=a114
[45254.536000] usb 1-1: New USB device strings: Mfr=2, Product=1, SerialNumber=3
[45254.536000] usb 1-1: Product: USB 2.0 Camera
[45254.539000] usb 1-1: Manufacturer: SuYin
[45254.539000] usb 1-1: SerialNumber: CN0317-S30C-MC03-VS-B20081113
[45254.546000] usb 1-1: configuration #1 chosen from 1 choice
[45254.550000] uvcvideo: Found UVC 1.00 device USB 2.0 Camera (064e:a114)
[45254.567000] input: USB 2.0 Camera as /devices/pci0000:00/0000:00:09.1/usb1/1-1/1-1:1.0/input/input896

lsusb会显示:

Bus 001 Device 015: ID 064e:a114 Suyin Corp.

evtest /dev/input/event2以 root 身份运行将显示:

Input driver version is 1.0.0
Input device ID: bus 0x19 vendor 0x0 product 0x0 version 0x0
Input device name: "HotKeys"
Supported events:
  Event type 0 (Sync)
  Event type 1 (Key)
    Event code 113 (Mute)
    Event code 114 (VolumeDown)
    Event code 115 (VolumeUp)
    Event code 142 (Sleep)
    Event code 212 (Camera)
    Event code 224 (Brightness down)
    Event code 225 (Brightness up)
    Event code 227 (?)
    Event code 238 (?)
  Event type 5 (?)
    Event code 0 (?)
Testing ... (interrupt to exit)
Event: time 1364796475.137014, type 1 (Key), code 212 (Camera), value 1
Event: time 1364796475.138119, -------------- Report Sync ------------
Event: time 1364796475.138145, type 1 (Key), code 212 (Camera), value 0
Event: time 1364796475.138159, -------------- Report Sync ------------

但是,当我运行cam_wlan. 我应该提到,运行时 WLAN 切换不会发生任何事件报告cam_wlan,尽管 WLAN LED 确实会切换(并且 WLAN 会通过运行来激活和停用cam_wlan),而网络摄像头不会切换。

我还尝试在原始 cam_wlan.c 中替换这些行

...
    if(ioctl(fd, UI_SET_KEYBIT, KEY_WLAN) < 0)
...
    ev.code = KEY_WLAN;
...

...
    if(ioctl(fd, UI_SET_KEYBIT, KEY_FN_ESC) < 0)
...
    ev.code = KEY_FN_ESC;
...

但这也没有用。

所以,我愿意接受建议。为了从外壳激活我的集成网络摄像头,我还能尝试什么?(即,不必Fn+ESC在我的键盘上进行物理按下)

4

0 回答 0