137f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian/* 237f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian * Copyright (C) 2012 The Android Open Source Project 337f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian * 437f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian * Licensed under the Apache License, Version 2.0 (the "License"); 537f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian * you may not use this file except in compliance with the License. 637f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian * You may obtain a copy of the License at 737f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian * 837f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian * http://www.apache.org/licenses/LICENSE-2.0 937f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian * 1037f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian * Unless required by applicable law or agreed to in writing, software 1137f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian * distributed under the License is distributed on an "AS IS" BASIS, 1237f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1337f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian * See the License for the specific language governing permissions and 1437f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian * limitations under the License. 1537f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian */ 1637f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian 1737f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian#include <stdint.h> 1837f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian#include <sys/types.h> 1937f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian 2037f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian#include <fcntl.h> 2137f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian#include <sys/ioctl.h> 2237f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian#include <linux/fb.h> 2337f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian#include <linux/input.h> 2437f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian#include <errno.h> 2537f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian#include <string.h> 2637f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian#include <stdio.h> 2737f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian#include <cutils/memory.h> 2837f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian#include <asm-generic/mman.h> 2937f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian#include <sys/mman.h> 3037f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian#include <utils/threads.h> 3137f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian#include <unistd.h> 3237f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian#include <math.h> 3337f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian 3437f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopianusing namespace android; 3537f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian 3637f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian#ifndef FBIO_WAITFORVSYNC 3737f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian#define FBIO_WAITFORVSYNC _IOW('F', 0x20, __u32) 3837f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian#endif 3937f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian 4037f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopianstruct Buffer { 4137f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian size_t w; 4237f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian size_t h; 4337f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian size_t s; 4437f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian union { 4537f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian void* addr; 4637f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian uint32_t* pixels; 4737f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian }; 4837f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian}; 4937f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian 5037f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopianvoid clearBuffer(Buffer* buf, uint32_t pixel) { 5137f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian android_memset32(buf->pixels, pixel, buf->s * buf->h * 4); 5237f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian} 5337f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian 5437f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopianvoid drawTwoPixels(Buffer* buf, uint32_t pixel, ssize_t x, ssize_t y, size_t w) { 5537f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian if (y>0 && y<ssize_t(buf->h)) { 5637f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian uint32_t* bits = buf->pixels + y * buf->s; 571c8cbb54407b9c1d56626de80a796a395012a92cAurimas Liutikas if (x>=0 && x<ssize_t(buf->w)) { 5837f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian bits[x] = pixel; 5937f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian } 6037f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian ssize_t W(w); 611c8cbb54407b9c1d56626de80a796a395012a92cAurimas Liutikas if ((x+W)>=0 && (x+W)<ssize_t(buf->w)) { 6237f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian bits[x+W] = pixel; 6337f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian } 6437f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian } 6537f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian} 6637f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian 6737f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopianvoid drawHLine(Buffer* buf, uint32_t pixel, ssize_t x, ssize_t y, size_t w) { 6837f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian if (y>0 && y<ssize_t(buf->h)) { 6937f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian ssize_t W(w); 7037f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian if (x<0) { 7137f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian W += x; 7237f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian x = 0; 7337f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian } 7437f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian if (x+w > buf->w) { 7537f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian W = buf->w - x; 7637f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian } 7737f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian if (W>0) { 7837f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian uint32_t* bits = buf->pixels + y * buf->s + x; 7937f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian android_memset32(bits, pixel, W*4); 8037f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian } 8137f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian } 8237f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian} 8337f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian 8437f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopianvoid drawRect(Buffer* buf, uint32_t pixel, ssize_t x, ssize_t y, size_t w, size_t h) { 8537f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian ssize_t W(w), H(h); 8637f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian if (x<0) { 8737f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian w += x; 8837f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian x = 0; 8937f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian } 9037f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian if (y<0) { 9137f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian h += y; 9237f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian y = 0; 9337f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian } 9437f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian if (x+w > buf->w) W = buf->w - x; 9537f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian if (y+h > buf->h) H = buf->h - y; 9637f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian if (W>0 && H>0) { 9737f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian uint32_t* bits = buf->pixels + y * buf->s + x; 9837f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian for (ssize_t i=0 ; i<H ; i++) { 9937f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian android_memset32(bits, pixel, W*4); 10037f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian bits += buf->s; 10137f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian } 10237f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian } 10337f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian} 10437f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian 10537f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopianvoid drawCircle(Buffer* buf, uint32_t pixel, 10637f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian size_t x0, size_t y0, size_t radius, bool filled = false) { 10737f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian ssize_t f = 1 - radius; 10837f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian ssize_t ddF_x = 1; 10937f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian ssize_t ddF_y = -2 * radius; 11037f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian ssize_t x = 0; 11137f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian ssize_t y = radius; 11237f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian if (filled) { 11337f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian drawHLine(buf, pixel, x0-radius, y0, 2*radius); 11437f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian } else { 11537f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian drawTwoPixels(buf, pixel, x0-radius, y0, 2*radius); 11637f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian } 11737f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian while (x < y) { 11837f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian if (f >= 0) { 11937f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian y--; 12037f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian ddF_y += 2; 12137f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian f += ddF_y; 12237f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian } 12337f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian x++; 12437f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian ddF_x += 2; 12537f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian f += ddF_x; 12637f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian if (filled) { 12737f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian drawHLine(buf, pixel, x0-x, y0+y, 2*x); 12837f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian drawHLine(buf, pixel, x0-x, y0-y, 2*x); 12937f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian drawHLine(buf, pixel, x0-y, y0+x, 2*y); 13037f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian drawHLine(buf, pixel, x0-y, y0-x, 2*y); 13137f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian } else { 13237f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian drawTwoPixels(buf, pixel, x0-x, y0+y, 2*x); 13337f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian drawTwoPixels(buf, pixel, x0-x, y0-y, 2*x); 13437f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian drawTwoPixels(buf, pixel, x0-y, y0+x, 2*y); 13537f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian drawTwoPixels(buf, pixel, x0-y, y0-x, 2*y); 13637f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian } 13737f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian } 13837f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian} 13937f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian 14037f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopianclass TouchEvents { 14137f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian class EventThread : public Thread { 14237f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian int fd; 14337f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian 14437f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian virtual bool threadLoop() { 14537f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian input_event event; 14637f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian int first_down = 0; 14737f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian do { 14837f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian read(fd, &event, sizeof(event)); 14937f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian if (event.type == EV_ABS) { 15037f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian if (event.code == ABS_MT_TRACKING_ID) { 15137f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian down = event.value == -1 ? 0 : 1; 15237f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian first_down = down; 15337f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian } 15437f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian if (event.code == ABS_MT_POSITION_X) { 15537f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian x = event.value; 15637f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian } 15737f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian if (event.code == ABS_MT_POSITION_Y) { 15837f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian y = event.value; 15937f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian } 16037f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian } 16137f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian } while (event.type == EV_SYN); 16237f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian return true; 16337f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian } 16437f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian 16537f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian public: 16637f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian int x, y, down; 16737f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian EventThread() : Thread(false), 16837f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian x(0), y(0), down(0) 16937f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian { 17037f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian fd = open("/dev/input/event1", O_RDONLY); 17137f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian } 17237f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian}; 17337f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian sp<EventThread> thread; 17437f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian 17537f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopianpublic: 17637f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian TouchEvents() { 17737f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian thread = new EventThread(); 17837f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian thread->run("EventThread", PRIORITY_URGENT_DISPLAY); 17937f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian } 18037f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian 18137f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian int getMostRecentPosition(int* x, int* y) { 18237f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian *x = thread->x; 18337f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian *y = thread->y; 18437f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian return thread->down; 18537f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian } 18637f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian}; 18737f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian 18837f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian 18937f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopianstruct Queue { 19037f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian struct position { 19137f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian int x, y; 19237f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian }; 19337f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian int index; 19437f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian position q[16]; 19537f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian Queue() : index(0) { } 19637f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian void push(int x, int y) { 19737f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian index++; 19837f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian index &= 0xF; 19937f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian q[index].x = x; 20037f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian q[index].y = y; 20137f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian } 20237f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian void get(int lag, int* x, int* y) { 20337f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian const int i = (index - lag) & 0xF; 20437f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian *x = q[i].x; 20537f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian *y = q[i].y; 20637f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian } 20737f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian}; 20837f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian 20937f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopianextern char *optarg; 21037f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopianextern int optind; 21137f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopianextern int optopt; 21237f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopianextern int opterr; 21337f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopianextern int optreset; 21437f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian 21537f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopianvoid usage(const char* name) { 21637f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian printf("\nusage: %s [-h] [-l lag]\n", name); 21737f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian} 21837f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian 21937f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopianint main(int argc, char** argv) { 22037f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian fb_var_screeninfo vi; 22137f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian fb_fix_screeninfo fi; 22237f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian 22337f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian int lag = 0; 22437f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian int fd = open("/dev/graphics/fb0", O_RDWR); 22537f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian ioctl(fd, FBIOGET_VSCREENINFO, &vi); 22637f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian ioctl(fd, FBIOGET_FSCREENINFO, &fi); 22737f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian void* bits = mmap(0, fi.smem_len, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); 22837f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian Buffer framebuffer; 22937f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian framebuffer.w = vi.xres; 23037f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian framebuffer.h = vi.yres; 23137f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian framebuffer.s = fi.line_length / (vi.bits_per_pixel >> 3); 23237f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian framebuffer.addr = bits; 23337f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian 23437f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian int ch; 23537f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian while ((ch = getopt(argc, argv, "hl:")) != -1) { 23637f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian switch (ch) { 23737f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian case 'l': 23837f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian lag = atoi(optarg); 23937f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian break; 24037f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian case 'h': 24137f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian default: 24237f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian usage(argv[0]); 24337f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian exit(0); 24437f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian } 24537f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian } 24637f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian argc -= optind; 24737f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian argv += optind; 24837f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian 24937f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian 25037f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian TouchEvents touch; 25137f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian Queue queue; 25237f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian 25337f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian 2541c8cbb54407b9c1d56626de80a796a395012a92cAurimas Liutikas int x=0, y=0; 25537f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian int lag_x=0, lag_y=0; 25637f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian 25737f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian clearBuffer(&framebuffer, 0); 25837f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian while (true) { 25937f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian uint32_t crt = 0; 2601c8cbb54407b9c1d56626de80a796a395012a92cAurimas Liutikas ioctl(fd, FBIO_WAITFORVSYNC, &crt); 26137f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian 26237f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian // draw beam marker 26337f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian drawRect(&framebuffer, 0x400000, framebuffer.w-2, 0, 2, framebuffer.h); 26437f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian // erase screen 26537f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian if (lag) { 26637f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian drawCircle(&framebuffer, 0, lag_x, lag_y, 100); 26737f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian drawHLine(&framebuffer, 0, 0, lag_y, 32); 26837f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian } 26937f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian drawCircle(&framebuffer, 0, x, y, 100, true); 27037f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian drawHLine(&framebuffer, 0, 0, y, 32); 27137f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian 27237f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian // draw a line at y=1000 27337f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian drawHLine(&framebuffer, 0x808080, 0, 1000, framebuffer.w); 27437f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian 27537f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian // get touch events 27637f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian touch.getMostRecentPosition(&x, &y); 27737f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian queue.push(x, y); 27837f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian queue.get(lag, &lag_x, &lag_y); 27937f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian 28037f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian if (lag) { 28137f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian drawCircle(&framebuffer, 0x00FF00, lag_x, lag_y, 100); 28237f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian drawHLine(&framebuffer, 0x00FF00, 0, lag_y, 32); 28337f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian } 28437f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian 28537f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian drawCircle(&framebuffer, 0xFFFFFF, x, y, 100, true); 28637f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian drawHLine(&framebuffer, 0xFFFFFF, 0, y, 32); 28737f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian 28837f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian // draw end of frame beam marker 28937f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian drawRect(&framebuffer, 0x004000, framebuffer.w-2, 0, 2, framebuffer.h); 29037f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian } 29137f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian 29237f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian close(fd); 29337f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian return 0; 29437f6934e863de13926975ff5c4e60b9ee9fa79ccMathias Agopian} 295