linux/drivers/macintosh/mac_hid.c
<<
>>
Prefs
   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
  11#include <linux/init.h>
  12#include <linux/proc_fs.h>
  13#include <linux/sysctl.h>
  14#include <linux/input.h>
  15#include <linux/module.h>
  16#include <linux/kbd_kern.h>
  17
  18
  19static struct input_dev *emumousebtn;
  20static int emumousebtn_input_register(void);
  21static int mouse_emulate_buttons;
  22static int mouse_button2_keycode = KEY_RIGHTCTRL;       /* right control key */
  23static int mouse_button3_keycode = KEY_RIGHTALT;        /* right option key */
  24static int mouse_last_keycode;
  25
  26#if defined(CONFIG_SYSCTL)
  27/* file(s) in /proc/sys/dev/mac_hid */
  28static ctl_table mac_hid_files[] = {
  29        {
  30                .ctl_name       = DEV_MAC_HID_MOUSE_BUTTON_EMULATION,
  31                .procname       = "mouse_button_emulation",
  32                .data           = &mouse_emulate_buttons,
  33                .maxlen         = sizeof(int),
  34                .mode           = 0644,
  35                .proc_handler   = &proc_dointvec,
  36        },
  37        {
  38                .ctl_name       = DEV_MAC_HID_MOUSE_BUTTON2_KEYCODE,
  39                .procname       = "mouse_button2_keycode",
  40                .data           = &mouse_button2_keycode,
  41                .maxlen         = sizeof(int),
  42                .mode           = 0644,
  43                .proc_handler   = &proc_dointvec,
  44        },
  45        {
  46                .ctl_name       = DEV_MAC_HID_MOUSE_BUTTON3_KEYCODE,
  47                .procname       = "mouse_button3_keycode",
  48                .data           = &mouse_button3_keycode,
  49                .maxlen         = sizeof(int),
  50                .mode           = 0644,
  51                .proc_handler   = &proc_dointvec,
  52        },
  53        { .ctl_name = 0 }
  54};
  55
  56/* dir in /proc/sys/dev */
  57static ctl_table mac_hid_dir[] = {
  58        {
  59                .ctl_name       = DEV_MAC_HID,
  60                .procname       = "mac_hid",
  61                .maxlen         = 0,
  62                .mode           = 0555,
  63                .child          = mac_hid_files,
  64        },
  65        { .ctl_name = 0 }
  66};
  67
  68/* /proc/sys/dev itself, in case that is not there yet */
  69static ctl_table mac_hid_root_dir[] = {
  70        {
  71                .ctl_name       = CTL_DEV,
  72                .procname       = "dev",
  73                .maxlen         = 0,
  74                .mode           = 0555,
  75                .child          = mac_hid_dir,
  76        },
  77        { .ctl_name = 0 }
  78};
  79
  80static struct ctl_table_header *mac_hid_sysctl_header;
  81
  82#endif /* endif CONFIG_SYSCTL */
  83
  84int mac_hid_mouse_emulate_buttons(int caller, unsigned int keycode, int down)
  85{
  86        switch (caller) {
  87        case 1:
  88                /* Called from keyboard.c */
  89                if (mouse_emulate_buttons
  90                    && (keycode == mouse_button2_keycode
  91                        || keycode == mouse_button3_keycode)) {
  92                        if (mouse_emulate_buttons == 1) {
  93                                input_report_key(emumousebtn,
  94                                                 keycode == mouse_button2_keycode ? BTN_MIDDLE : BTN_RIGHT,
  95                                                 down);
  96                                input_sync(emumousebtn);
  97                                return 1;
  98                        }
  99                        mouse_last_keycode = down ? keycode : 0;
 100                }
 101                break;
 102        }
 103        return 0;
 104}
 105
 106static struct lock_class_key emumousebtn_event_class;
 107static struct lock_class_key emumousebtn_mutex_class;
 108
 109static int emumousebtn_input_register(void)
 110{
 111        int ret;
 112
 113        emumousebtn = input_allocate_device();
 114        if (!emumousebtn)
 115                return -ENOMEM;
 116
 117        lockdep_set_class(&emumousebtn->event_lock, &emumousebtn_event_class);
 118        lockdep_set_class(&emumousebtn->mutex, &emumousebtn_mutex_class);
 119
 120        emumousebtn->name = "Macintosh mouse button emulation";
 121        emumousebtn->id.bustype = BUS_ADB;
 122        emumousebtn->id.vendor = 0x0001;
 123        emumousebtn->id.product = 0x0001;
 124        emumousebtn->id.version = 0x0100;
 125
 126        emumousebtn->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL);
 127        emumousebtn->keybit[BIT_WORD(BTN_MOUSE)] = BIT_MASK(BTN_LEFT) |
 128                BIT_MASK(BTN_MIDDLE) | BIT_MASK(BTN_RIGHT);
 129        emumousebtn->relbit[0] = BIT_MASK(REL_X) | BIT_MASK(REL_Y);
 130
 131        ret = input_register_device(emumousebtn);
 132        if (ret)
 133                input_free_device(emumousebtn);
 134
 135        return ret;
 136}
 137
 138static int __init mac_hid_init(void)
 139{
 140        int err;
 141
 142        err = emumousebtn_input_register();
 143        if (err)
 144                return err;
 145
 146#if defined(CONFIG_SYSCTL)
 147        mac_hid_sysctl_header = register_sysctl_table(mac_hid_root_dir);
 148#endif /* CONFIG_SYSCTL */
 149
 150        return 0;
 151}
 152
 153device_initcall(mac_hid_init);
 154