/* Lock touchscreen until a gesture is drawn on the screen */

/* Copyright (c) 2009  Timo Juhani Lindfors <timo.lindfors@iki.fi> */

/* Permission is hereby granted, free of charge, to any person */
/* obtaining a copy of this software and associated documentation */
/* files (the "Software"), to deal in the Software without */
/* restriction, including without limitation the rights to use, */
/* copy, modify, merge, publish, distribute, sublicense, and/or sell */
/* copies of the Software, and to permit persons to whom the */
/* Software is furnished to do so, subject to the following */
/* conditions: */

/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the Software. */

/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES */
/* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND */
/* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT */
/* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, */
/* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING */
/* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR */
/* OTHER DEALINGS IN THE SOFTWARE. */

/*
 * Start with e.g. "lock-touscreen /dev/input/touschreen0"
 * Uses EVIOGRAB so that X does not see any events and thus does not
 * - turn on backligt
 * - consume cpu time
 * - send any spurious input to other applications.
 * The program exits and unlocks the screen if you move your finger
 * over the screen vertically from top to bottom. More advanced ideas
 * are welcome!
 */

#include <stdio.h>
#include <assert.h>
#include <time.h>
#include <stdint.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>

struct input_event {
    struct timeval time;
    uint16_t type;
    uint16_t code;
    int32_t value;
};

struct v3 {
    int x;
    int y;
    int z;
};

void vector_print(struct v3 a) {
    printf("%d %d %d", a.x, a.y, a.z);
}

#define HISTSIZE 15

int main(int argc, char *argv[]) {
    static struct v3 pos;
    struct input_event e;
    FILE *fp;
    int ret, prev_y_zone = 0, i;
    int zone_history[HISTSIZE], zone_history_ptr = 0;

    fp = fopen(argv[1], "r");
    assert(fp);

    ioctl(fileno(fp), 0x40044590, 1); // EVIOCGRAB

    for (i = 0; i < HISTSIZE; i++) {
        zone_history[i] = 0;
    }
    
    for (;;) {
        ret = fread(&e, sizeof(e), 1, fp);
        assert(ret == 1);

        if (e.type == 3 && e.code == 0)
            pos.y = e.value;
        if (e.type == 3 && e.code == 1)
            pos.x = e.value;
        if (e.type == 0 && e.code == 0) {
            int y_zone, match;
            
            y_zone = pos.y / 50;
            //printf("%d: ", y_zone);
            if (y_zone != prev_y_zone) {
                prev_y_zone = y_zone;
                zone_history[(zone_history_ptr++) % HISTSIZE] = y_zone;
            }

            match = 1;
            for (i = 0; i < HISTSIZE - 1; i++) {
                //printf(" %d", zone_history[(zone_history_ptr + i) % HISTSIZE]);
                if (zone_history[(zone_history_ptr + i) % HISTSIZE] !=
                    zone_history[(zone_history_ptr + i + 1) % HISTSIZE] + 1) {
                    match = 0;
                    break;
                }
            }
            //printf(" (%d)\n", match);
            if (match) {
                return 0;
            }
        }
    }
    return 0;
}
