2

Multi-Touch プロトコルを使用するドライバー ファイルを編集しています。私の目標は、(x1,y1) から (x2,y2) へのスワイプ ジェスチャを線に沿ってバインドすることです。

これを行うには、キー圧力検出関数内でこの関数を実行します。

static void do_swipe(struct kp *kp, long xstart, long ystart, long xend, long yend,
        int id) {
    printk("SWIPE! X1 %d Y1 %d X2 %d Y2 %d ID %d \n",xstart,ystart,xend,yend,id);
    int sx, sy;
    int dx = abs(xend - xstart);
    int dy = abs(yend - ystart);
    if (xstart < xend)
        sx = 1;
    else
        sx = -1;
    if (ystart < yend)
        sy = 1;
    else
        sy = -1;
    int err = dx - dy;
    long tempx = xstart;
    long tempy = ystart;
    while (1) {
        key_report(kp, tempx, tempy, id);
        //Touch is now detected with input_sync
        input_sync(kp->input);
        if(tempx == xend && tempy == yend) break;
        int e2 = 2 * err;
        if (e2 > (-1)*dy) {
            err = err - dy;
            tempx = tempx + sx;
        } else if (e2 < dx) {
            err = err + dx;
            tempy = tempy + sy;
        }
    }
    printk("END! X %d Y %d \n",tempx, tempy);

}

この関数は編集された Bresenham の線アルゴリズムであり、線を描画する代わりに key_report を呼び出して、指定された座標でのタッチをシミュレートします。

static void key_report(struct kp *kp, long x, long y, int id) {
    if (x == 0 && y == 0) {
        //printk("---------- zero point --------------\n");
        ;
    } else {
        input_report_key(kp->input, BTN_TOUCH, 1);
        input_report_abs(kp->input, ABS_MT_TRACKING_ID, id);
        input_report_abs(kp->input, ABS_MT_TOUCH_MAJOR, 20);
        input_report_abs(kp->input, ABS_MT_WIDTH_MAJOR, 20);
        input_report_abs(kp->input, ABS_MT_POSITION_X, x);
        input_report_abs(kp->input, ABS_MT_POSITION_Y, y);
        input_mt_sync(kp->input);
    }
    release = 1;
}

kp-> input はそのように定義されています

struct input_dev *input;

編集:コードを更新し、キー圧力の汎用コードも添付しています。これは、スワイプのループを避けるために、ドライバーがキー圧力ごとに1回だけスワイプを実行するようにするためです。

static void kp_work(struct kp *kp) {
int i, code, value;
kp_search_key(kp);
if (key_param[0] == 3) {
    if (kp->key_valid[4] == 1) {
        value = kp->key_value[4];
        kp->flagchan4 = 0;
        if (value >= 0 && value <= (9 + 40)) {
            if (key_param[99] == 1 ) {
                do_swipe(kp, key_param[25], key_param[26], key_param[97],
                        key_param[98], 12);
            } else
                key_report(kp, key_param[25], key_param[26], 12);
        } else if (value >= 392 - 40 && value <= (392 + 40)) {
            if (key_param[102] == 1) {
                do_swipe(kp, key_param[23], key_param[24], key_param[100],
                        key_param[101], 12);
            } else
                key_report(kp, key_param[23], key_param[24], 12);
        } 
        kp->flagchan4 = 0;
    } else {
        kp->flagchan4 = 1;
    }
}
input_sync(kp->input);
}

たぶん、kp->flagchan4にチェックを設定できます... 編集: flagchan4にチェックを設定するとうまくいきました。

4

0 に答える 0