mac_hid.c 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. /*
  2. * drivers/macintosh/mac_hid.c
  3. *
  4. * HID support stuff for Macintosh computers.
  5. *
  6. * Copyright (C) 2000 Franz Sirl.
  7. *
  8. * This file will soon be removed in favor of an uinput userspace tool.
  9. */
  10. #include <linux/init.h>
  11. #include <linux/proc_fs.h>
  12. #include <linux/sysctl.h>
  13. #include <linux/input.h>
  14. #include <linux/module.h>
  15. #include <linux/kbd_kern.h>
  16. static struct input_dev *emumousebtn;
  17. static int emumousebtn_input_register(void);
  18. static int mouse_emulate_buttons;
  19. static int mouse_button2_keycode = KEY_RIGHTCTRL; /* right control key */
  20. static int mouse_button3_keycode = KEY_RIGHTALT; /* right option key */
  21. static int mouse_last_keycode;
  22. #if defined(CONFIG_SYSCTL)
  23. /* file(s) in /proc/sys/dev/mac_hid */
  24. static ctl_table mac_hid_files[] = {
  25. {
  26. .procname = "mouse_button_emulation",
  27. .data = &mouse_emulate_buttons,
  28. .maxlen = sizeof(int),
  29. .mode = 0644,
  30. .proc_handler = proc_dointvec,
  31. },
  32. {
  33. .procname = "mouse_button2_keycode",
  34. .data = &mouse_button2_keycode,
  35. .maxlen = sizeof(int),
  36. .mode = 0644,
  37. .proc_handler = proc_dointvec,
  38. },
  39. {
  40. .procname = "mouse_button3_keycode",
  41. .data = &mouse_button3_keycode,
  42. .maxlen = sizeof(int),
  43. .mode = 0644,
  44. .proc_handler = proc_dointvec,
  45. },
  46. { }
  47. };
  48. /* dir in /proc/sys/dev */
  49. static ctl_table mac_hid_dir[] = {
  50. {
  51. .procname = "mac_hid",
  52. .maxlen = 0,
  53. .mode = 0555,
  54. .child = mac_hid_files,
  55. },
  56. { }
  57. };
  58. /* /proc/sys/dev itself, in case that is not there yet */
  59. static ctl_table mac_hid_root_dir[] = {
  60. {
  61. .procname = "dev",
  62. .maxlen = 0,
  63. .mode = 0555,
  64. .child = mac_hid_dir,
  65. },
  66. { }
  67. };
  68. static struct ctl_table_header *mac_hid_sysctl_header;
  69. #endif /* endif CONFIG_SYSCTL */
  70. int mac_hid_mouse_emulate_buttons(int caller, unsigned int keycode, int down)
  71. {
  72. switch (caller) {
  73. case 1:
  74. /* Called from keyboard.c */
  75. if (mouse_emulate_buttons
  76. && (keycode == mouse_button2_keycode
  77. || keycode == mouse_button3_keycode)) {
  78. if (mouse_emulate_buttons == 1) {
  79. input_report_key(emumousebtn,
  80. keycode == mouse_button2_keycode ? BTN_MIDDLE : BTN_RIGHT,
  81. down);
  82. input_sync(emumousebtn);
  83. return 1;
  84. }
  85. mouse_last_keycode = down ? keycode : 0;
  86. }
  87. break;
  88. }
  89. return 0;
  90. }
  91. static struct lock_class_key emumousebtn_event_class;
  92. static struct lock_class_key emumousebtn_mutex_class;
  93. static int emumousebtn_input_register(void)
  94. {
  95. int ret;
  96. emumousebtn = input_allocate_device();
  97. if (!emumousebtn)
  98. return -ENOMEM;
  99. lockdep_set_class(&emumousebtn->event_lock, &emumousebtn_event_class);
  100. lockdep_set_class(&emumousebtn->mutex, &emumousebtn_mutex_class);
  101. emumousebtn->name = "Macintosh mouse button emulation";
  102. emumousebtn->id.bustype = BUS_ADB;
  103. emumousebtn->id.vendor = 0x0001;
  104. emumousebtn->id.product = 0x0001;
  105. emumousebtn->id.version = 0x0100;
  106. emumousebtn->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL);
  107. emumousebtn->keybit[BIT_WORD(BTN_MOUSE)] = BIT_MASK(BTN_LEFT) |
  108. BIT_MASK(BTN_MIDDLE) | BIT_MASK(BTN_RIGHT);
  109. emumousebtn->relbit[0] = BIT_MASK(REL_X) | BIT_MASK(REL_Y);
  110. ret = input_register_device(emumousebtn);
  111. if (ret)
  112. input_free_device(emumousebtn);
  113. return ret;
  114. }
  115. static int __init mac_hid_init(void)
  116. {
  117. int err;
  118. err = emumousebtn_input_register();
  119. if (err)
  120. return err;
  121. #if defined(CONFIG_SYSCTL)
  122. mac_hid_sysctl_header = register_sysctl_table(mac_hid_root_dir);
  123. #endif /* CONFIG_SYSCTL */
  124. return 0;
  125. }
  126. device_initcall(mac_hid_init);