0

Fn+ESC基本的に、ノートブックの内蔵 Web カメラをシェルまたはシェル スクリプトからオンにしたいのですが、オンにするたびに物理的に押す必要はありません。

/dev/uinput を使用して、lemote yeeloong 8089B ノートブックの統合 Web カメラを、debian スクイーズで、 bjlx のカーネル 2.6.32-loongson-2f #1 PREEMPT でアクティブにしようとしています。uinput を使用して WLAN をアクティブ化することは既に達成していますが、uinput でカメラをオンにすることはできません。通常は を押しFn+ESCてカメラをオンにしますが、uinput では機能しないようです。カメラは動作し、次の方法でテストできます。

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

次のプログラム (Gregory Thiemonge と Mehul Patel による HOWTO に基づく) を使用して、uinput を使用して Web カメラをアクティブにしようとしています (コードが少し醜い場合は申し訳ありませんが、急いで書きました)。

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 がトグルするのに Web カメラがトグルしないことです。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ルートとして実行すると、次のように表示されます。

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)、Web カメラはトグルしません。

また、元の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;
...

しかし、それもうまくいきませんでした。

だから、私は提案を受け入れています。シェルから統合 Web カメラをアクティブ化するには、他に何を試すことができますか? Fn+ESC(つまり、そうするために物理的にキーボードを押す必要がない)

4

0 に答える 0