2 * Copyright (C) 2012 The Android Open Source Project
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
18 #include <sys/types.h>
21 #include <sys/ioctl.h>
23 #include <linux/input.h>
27 #include <cutils/memory.h>
28 #include <asm-generic/mman.h>
30 #include <utils/threads.h>
34 using namespace android;
36 #ifndef FBIO_WAITFORVSYNC
37 #define FBIO_WAITFORVSYNC _IOW('F', 0x20, __u32)
50 void clearBuffer(Buffer* buf, uint32_t pixel) {
51 android_memset32(buf->pixels, pixel, buf->s * buf->h * 4);
54 void drawTwoPixels(Buffer* buf, uint32_t pixel, ssize_t x, ssize_t y, size_t w) {
55 if (y>0 && y<ssize_t(buf->h)) {
56 uint32_t* bits = buf->pixels + y * buf->s;
57 if (x>=0 && x<ssize_t(buf->w)) {
61 if ((x+W)>=0 && (x+W)<ssize_t(buf->w)) {
67 void drawHLine(Buffer* buf, uint32_t pixel, ssize_t x, ssize_t y, size_t w) {
68 if (y>0 && y<ssize_t(buf->h)) {
78 uint32_t* bits = buf->pixels + y * buf->s + x;
79 android_memset32(bits, pixel, W*4);
84 void drawRect(Buffer* buf, uint32_t pixel, ssize_t x, ssize_t y, size_t w, size_t h) {
94 if (x+w > buf->w) W = buf->w - x;
95 if (y+h > buf->h) H = buf->h - y;
97 uint32_t* bits = buf->pixels + y * buf->s + x;
98 for (ssize_t i=0 ; i<H ; i++) {
99 android_memset32(bits, pixel, W*4);
105 void drawCircle(Buffer* buf, uint32_t pixel,
106 size_t x0, size_t y0, size_t radius, bool filled = false) {
107 ssize_t f = 1 - radius;
109 ssize_t ddF_y = -2 * radius;
113 drawHLine(buf, pixel, x0-radius, y0, 2*radius);
115 drawTwoPixels(buf, pixel, x0-radius, y0, 2*radius);
127 drawHLine(buf, pixel, x0-x, y0+y, 2*x);
128 drawHLine(buf, pixel, x0-x, y0-y, 2*x);
129 drawHLine(buf, pixel, x0-y, y0+x, 2*y);
130 drawHLine(buf, pixel, x0-y, y0-x, 2*y);
132 drawTwoPixels(buf, pixel, x0-x, y0+y, 2*x);
133 drawTwoPixels(buf, pixel, x0-x, y0-y, 2*x);
134 drawTwoPixels(buf, pixel, x0-y, y0+x, 2*y);
135 drawTwoPixels(buf, pixel, x0-y, y0-x, 2*y);
141 class EventThread : public Thread {
144 virtual bool threadLoop() {
148 read(fd, &event, sizeof(event));
149 if (event.type == EV_ABS) {
150 if (event.code == ABS_MT_TRACKING_ID) {
151 down = event.value == -1 ? 0 : 1;
154 if (event.code == ABS_MT_POSITION_X) {
157 if (event.code == ABS_MT_POSITION_Y) {
161 } while (event.type == EV_SYN);
167 EventThread() : Thread(false),
170 fd = open("/dev/input/event1", O_RDONLY);
173 sp<EventThread> thread;
177 thread = new EventThread();
178 thread->run("EventThread", PRIORITY_URGENT_DISPLAY);
181 int getMostRecentPosition(int* x, int* y) {
195 Queue() : index(0) { }
196 void push(int x, int y) {
202 void get(int lag, int* x, int* y) {
203 const int i = (index - lag) & 0xF;
215 void usage(const char* name) {
216 printf("\nusage: %s [-h] [-l lag]\n", name);
219 int main(int argc, char** argv) {
220 fb_var_screeninfo vi;
221 fb_fix_screeninfo fi;
224 int fd = open("/dev/graphics/fb0", O_RDWR);
225 ioctl(fd, FBIOGET_VSCREENINFO, &vi);
226 ioctl(fd, FBIOGET_FSCREENINFO, &fi);
227 void* bits = mmap(0, fi.smem_len, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
229 framebuffer.w = vi.xres;
230 framebuffer.h = vi.yres;
231 framebuffer.s = fi.line_length / (vi.bits_per_pixel >> 3);
232 framebuffer.addr = bits;
235 while ((ch = getopt(argc, argv, "hl:")) != -1) {
255 int lag_x=0, lag_y=0;
257 clearBuffer(&framebuffer, 0);
260 ioctl(fd, FBIO_WAITFORVSYNC, &crt);
263 drawRect(&framebuffer, 0x400000, framebuffer.w-2, 0, 2, framebuffer.h);
266 drawCircle(&framebuffer, 0, lag_x, lag_y, 100);
267 drawHLine(&framebuffer, 0, 0, lag_y, 32);
269 drawCircle(&framebuffer, 0, x, y, 100, true);
270 drawHLine(&framebuffer, 0, 0, y, 32);
272 // draw a line at y=1000
273 drawHLine(&framebuffer, 0x808080, 0, 1000, framebuffer.w);
276 touch.getMostRecentPosition(&x, &y);
278 queue.get(lag, &lag_x, &lag_y);
281 drawCircle(&framebuffer, 0x00FF00, lag_x, lag_y, 100);
282 drawHLine(&framebuffer, 0x00FF00, 0, lag_y, 32);
285 drawCircle(&framebuffer, 0xFFFFFF, x, y, 100, true);
286 drawHLine(&framebuffer, 0xFFFFFF, 0, y, 32);
288 // draw end of frame beam marker
289 drawRect(&framebuffer, 0x004000, framebuffer.w-2, 0, 2, framebuffer.h);