//------ scribble.c (for Archos 605) #include #include #include #include #include /* From Compaq's Touch Screen Specification version 0.2 (draft) */ struct ts_event { unsigned short pressure; unsigned short x; unsigned short y; unsigned short millisecs; }; struct fb_var_screeninfo vinfo; struct fb_fix_screeninfo finfo; long int screensize = 0; char *fbp = 0; void draw_rec(int x, int y, int side1,int side2, unsigned short colour); void draw_line(int x1, int y1, int x2, int y2, int thickness, unsigned short colour); void init_screen(); int main() { int fbfd = 0, tsfd = 0; struct ts_event tsev; // manually set touchscreen calibration for now (really needs proper calibration though) int min_x=146, max_x=3929, min_y=243, max_y=3840; // Open the framebuffer for reading and writing fbfd = open("/dev/fb0", O_RDWR); if (!fbfd) { printf("Error: cannot open framebuffer device.\n"); exit(1); } // Get fixed screen information ioctl(fbfd, FBIOGET_FSCREENINFO, &finfo); // Get variable screen information ioctl(fbfd, FBIOGET_VSCREENINFO, &vinfo); printf("%dx%d, %dbpp\n", vinfo.xres, vinfo.yres, vinfo.bits_per_pixel); // Figure out the size of the screen in bytes screensize = vinfo.xres * vinfo.yres * vinfo.bits_per_pixel / 8; // Map the device to memory fbp = (char *)mmap(0, screensize, PROT_READ | PROT_WRITE, MAP_SHARED, fbfd, 0); init_screen(); // Open the touchscreen for reading tsfd = open("/dev/input/tsraw0", O_RDONLY); if (!tsfd) { printf("Error: cannot open touchscreen raw device.\n"); exit(1); } int thickness = 4; unsigned short colour = 0; // black int xpos, ypos, oldx, oldy, oldms=0; // process touchscreen events do { read(tsfd, &tsev, 8); //printf("pressure=%u x=%u y=%u msec=%u\n", tsev.pressure, tsev.x, tsev.y, tsev.millisecs); if (tsev.pressure > 100) { xpos = (tsev.x-min_x) * vinfo.xres/(max_x-min_x); ypos = (tsev.y-min_y) * vinfo.yres/(max_y-min_y); if (xpos<0) xpos=0; if (xpos>vinfo.xres-thickness) xpos=vinfo.xres-thickness; if (ypos<0) ypos=0; if (ypos>vinfo.yres-thickness) ypos=vinfo.yres-thickness; //check for events in bottom left corner if (ypos>430 & xpos<300) { if (xpos < 50) break; // exit button if (xpos < 100) init_screen(); // clear screen else if (xpos < 150) colour = 31<<11; // red else if (xpos < 200) colour = 31<<6; // green else if (xpos < 250) colour = 31; // blue else if (xpos < 300) colour = 0; // black } else { // assume a slight gap in touchscreen events means start a new line. if (tsev.millisecs - oldms > 100) { draw_rec(xpos, ypos, thickness, thickness, colour); } else if (oldms < tsev.millisecs || (tsev.millisecs + 65536-oldms) < 100 ) draw_line(oldx, oldy, xpos, ypos, thickness, colour); else draw_rec(xpos, ypos, thickness, thickness, colour); oldx = xpos; oldy = ypos; oldms = tsev.millisecs; } } } while (1); munmap(fbp, screensize); close(fbfd); close(tsfd); // dump the screen? return 0; } void draw_rec(int x, int y, int side1, int side2, unsigned short colour) { long int pos; int i , j; int Bpp = vinfo.bits_per_pixel / 8; // Bytes per pixel pos = (x+vinfo.xoffset) * Bpp + (y+vinfo.yoffset) * finfo.line_length; for (j=0; j= 0 ? 1 : -1; sdy= dy >= 0 ? 1 : -1; x=dyabs>>1; y=dxabs>>1; px=x1; py=y1; if (dxabs>=dyabs) /* the line is more horizontal than vertical */ { for(i=0;i=dxabs) { y-=dxabs; py+=sdy; } px+=sdx; draw_rec(px,py,thickness,thickness,colour); } } else /* the line is more vertical than horizontal */ { for(i=0;i=dyabs) { x-=dyabs; px+=sdx; } py+=sdy; draw_rec(px,py,thickness,thickness,colour); } } } void init_screen() { //clear the screen draw_rec(0,0,800,480,0xffff); //Draw the exit and clear screen squares draw_rec(0,430,50,50,0); draw_rec(2,432,46,46,0xffff); draw_line(0,430,50,480,2,0); draw_line(0,480,50,430,2,0); draw_rec(50,430,50,50,0); draw_rec(52,432,46,46,0xffff); //Draw the palette squares draw_rec(100,430,50,50,31<<11); // red draw_rec(150,430,50,50,31<<6); // green draw_rec(200,430,50,50,31); // blue draw_rec(250,430,50,50,0); // black }