该驱动可用于没有触摸屏的设备上,加上虚拟FrameBuffer驱动(vfb)就可以模拟触摸屏。比如在Android系统的移植中,系统要正常启动,就必须要有FrameBuffer驱动和声卡驱动,此二者可使用drivers/video/vfb.c和sound/drivers/dummy.c两个虚拟驱动代替,系统正常起来后,可使用加上虚拟触摸屏驱动,就可以使用android-vnc-server(http://code.google.com/p/android-vnc-server/)以启动VNC服务,然后使用VNC客户端将Android系统桌面显示到远端。配合虚拟触摸屏驱动,在远端就可以使用鼠标进行操作。
   由于触摸屏的大小参数必须和FrameBuffer的参数一致,所以驱动实现了使用启动参数传递大小参数,以此可作为如何通过启动参数给驱动程序传递参数的示例,代码如下:
  1. /*
  2.  * Virtual TouchScreen driver
  3.  *
  4.  * Copyright (C) 2011 Niu Tao <niutao0602@gmail.com>
  5.  *
  6.  * This file is subject to the terms and conditions of the GNU General Public
  7.  * License. See the file COPYING in the main directory of this archive for
  8.  * more details.
  9.  *
  10.  */

  11. #include <linux/module.h>
  12. #include <linux/kernel.h>
  13. #include <linux/init.h>
  14. #include <linux/errno.h>
  15. #include <linux/delay.h>
  16. #include <linux/ioport.h>
  17. #include <linux/interrupt.h>
  18. #include <linux/input.h>

  19. #define DRIVER_DESC "Virtual TouchScreen"

  20. static struct input_dev *vts_dev;

  21. #define VTS_MIN_XC 0
  22. #define VTS_MAX_XC 320
  23. #define VTS_MIN_YC 0
  24. #define VTS_MAX_YC 480

  25. static int __initdata vts_max_xc = VTS_MAX_XC;
  26. static int __initdata vts_max_yc = VTS_MAX_YC;

  27. #ifndef MODULE
  28. static int __initdata vts_use = 0;
  29. /**
  30.  * parse options,format must be vts=widthxheigth
  31.  */
  32. static int __init vts_setup(char *str)
  33. {
  34.     char buf[64];
  35.     char *p;
  36.     int xc, yc;

  37.     vts_use = 1;

  38.     strncpy(buf, str, sizeof(buf));
  39.     p = strchr(buf, 'x');
  40.     if (!p)
  41.         goto out;
  42.     *p = '\0';
  43.     xc = simple_strtoul(buf, NULL, 0);
  44.     yc = simple_strtoul(p + 1, NULL, 0);
  45.     
  46.     if (!xc || !yc)
  47.         goto out;

  48.     vts_max_xc = xc;
  49.     vts_max_yc = yc;
  50.     return 1;
  51. out:
  52.     printk(KERN_WARNING "vts: option format must be like 'vts=widthxheigth'. "
  53.             "use default config vts=%dx%d\n", vts_max_xc, vts_max_yc);
  54.     return 0;
  55. }
  56. __setup("vts=", vts_setup);
  57. #endif

  58. static int __init vts_init(void)
  59. {
  60.     int err;

  61. #ifndef MODULE
  62.     if (!vts_use)
  63.         return -ENODEV;
  64. #endif
  65.     vts_dev = input_allocate_device();
  66.     if (!vts_dev) {
  67.         printk(KERN_ERR "vts: not enough memory\n");
  68.         err = -ENOMEM;
  69.         goto fail1;
  70.     }

  71.     vts_dev->name = DRIVER_DESC;
  72.     vts_dev->phys = "vts/input0";
  73.     vts_dev->id.bustype = BUS_VIRTUAL;
  74.     vts_dev->id.vendor = 0x0000;
  75.     vts_dev->id.product = 0x0000;
  76.     vts_dev->id.version = 0x0100;

  77.     vts_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
  78.     vts_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
  79.     input_set_abs_params(vts_dev, ABS_X, VTS_MIN_XC, vts_max_xc, 0, 0);
  80.     input_set_abs_params(vts_dev, ABS_Y, VTS_MIN_YC, vts_max_yc, 0, 0);

  81.     err = input_register_device(vts_dev);
  82.     if (err)
  83.         goto fail2;

  84.     return 0;

  85. fail2:
  86.     input_free_device(vts_dev);
  87. fail1:
  88.     return err;
  89. }
  90. module_init(vts_init);
  91. #ifdef MODULE
  92. static void __exit vts_exit(void)
  93. {
  94.     input_unregister_device(vts_dev);
  95.     input_free_device(vts_dev);
  96. }
  97. module_exit(vts_exit);
  98. #endif
  99. MODULE_AUTHOR("Niu Tao ");
  100. MODULE_DESCRIPTION(DRIVER_DESC);
  101. MODULE_LICENSE("GPL");
01-01 13:03