1124N/Adiff --git a/Xi/exevents.c b/Xi/exevents.c
1340N/Aindex 106da3a..dd7e3a2 100644
1124N/A--- a/Xi/exevents.c
1124N/A+++ b/Xi/exevents.c
1276N/A@@ -225,7 +225,16 @@ CopyKeyClass(DeviceIntPtr device, DeviceIntPtr master)
1088N/A {
851N/A KeyClassPtr mk = master->key;
1088N/A
764N/A+#ifdef SUNSOFT
764N/A+ DeviceIntPtr mdev = dixLookupPrivate(&master->devPrivates,
764N/A+ HotkeyMapDevicePrivateKey);
764N/A+#endif
1088N/A+
764N/A+#ifdef SUNSOFT
851N/A+ if ((device == master) || (device == mdev))
764N/A+#else
851N/A if (device == master)
764N/A+#endif
851N/A return;
764N/A
851N/A mk->sourceid = device->id;
1124N/Adiff --git a/Xi/extinit.c b/Xi/extinit.c
1340N/Aindex 7e30755..5c008e4 100644
1124N/A--- a/Xi/extinit.c
1124N/A+++ b/Xi/extinit.c
1340N/A@@ -371,6 +371,10 @@ Mask PropagateMask[EMASKSIZE];
1088N/A
1340N/A DevPrivateKeyRec XIClientPrivateKeyRec;
1088N/A
1088N/A+#ifdef SUNSOFT
1088N/A+DevPrivateKeyRec HotkeyMapDevicePrivateKeyRec;
1088N/A+#endif
1088N/A+
1088N/A /*****************************************************************
1088N/A *
1340N/A * Declarations of local routines.
1276N/A@@ -1260,6 +1264,11 @@ XInputExtensionInit(void)
1276N/A (&XIClientPrivateKeyRec, PRIVATE_CLIENT, sizeof(XIClientRec)))
1088N/A FatalError("Cannot request private for XI.\n");
1088N/A
1088N/A+#ifdef SUNSOFT
1088N/A+ if (!dixRegisterPrivateKey(&HotkeyMapDevicePrivateKeyRec, PRIVATE_DEVICE, 0))
1088N/A+ FatalError("Cannot request private for hotkey.\n");
1088N/A+#endif
1088N/A+
1088N/A if (!AddCallback(&ClientStateCallback, XIClientCallback, 0))
1088N/A FatalError("Failed to add callback to XI.\n");
1088N/A
1124N/Adiff --git a/config/hal.c b/config/hal.c
1340N/Aindex 2ead556..9de9dfc 100644
1124N/A--- a/config/hal.c
1124N/A+++ b/config/hal.c
1276N/A@@ -123,6 +123,49 @@ get_prop_string_array(LibHalContext * hal_ctx, const char *udi,
1088N/A return ret;
764N/A }
764N/A
764N/A+#ifdef SUNSOFT
851N/A+static void
764N/A+add_extra_device(char *driver)
764N/A+{
764N/A+ DeviceIntPtr dev;
764N/A+ char *config_info = NULL;
1265N/A+ InputOption *input_options = NULL;
1088N/A+ InputAttributes attrs = {0};
764N/A+
1265N/A+ input_options = input_option_new(NULL, "_source", "server/hal");
1265N/A+ if (!input_options){
764N/A+ LogMessage(X_ERROR, "config/hal: couldn't allocate first key/value pair\n");
764N/A+ goto unwind;
764N/A+ }
764N/A+
1265N/A+ input_options = input_option_new(input_options, "driver", driver);
1265N/A+ input_options = input_option_new(input_options, "name", driver);
764N/A+
1265N/A+ if (!asprintf(&config_info, "hal:%s", driver) == -1) {
1265N/A+ config_info = NULL;
764N/A+ LogMessage(X_ERROR, "config/hal: couldn't allocate name\n");
764N/A+ goto unwind;
764N/A+ }
764N/A+
764N/A+ /* Check for duplicate devices */
764N/A+ if (device_is_duplicate(config_info))
764N/A+ goto unwind;
764N/A+
764N/A+ LogMessage(X_INFO, "config/hal: Adding input device %s\n", driver);
1265N/A+ if (NewInputDeviceRequest(input_options, &attrs, &dev) != Success) {
764N/A+ LogMessage(X_ERROR, "config/hal: NewInputDeviceRequest failed\n");
764N/A+ dev = NULL;
764N/A+ goto unwind;
764N/A+ }
764N/A+
764N/A+ dev->config_info = xstrdup(config_info);
764N/A+
764N/A+unwind:
1549N/A+ free(config_info);
1265N/A+ input_option_free_list(&input_options);
764N/A+}
764N/A+#endif
764N/A+
851N/A static void
1276N/A device_added(LibHalContext * hal_ctx, const char *udi)
764N/A {
1276N/A@@ -382,6 +425,14 @@ device_added(LibHalContext * hal_ctx, const char *udi)
1276N/A input_option_new(input_options, "xkb_options", xkb_opts.options);
1265N/A input_options = input_option_new(input_options, "config_info", config_info);
764N/A
764N/A+#ifdef SUNSOFT
1265N/A+ InputOption *md = input_option_find(input_options, "mdriver");
1265N/A+ if (md) {
1312N/A+ char *mdriver = input_option_get_value(md);
1265N/A+ add_extra_device (mdriver);
764N/A+ }
764N/A+#endif
764N/A+
764N/A /* this isn't an error, but how else do you output something that the user can see? */
764N/A LogMessage(X_INFO, "config/hal: Adding input device %s\n", name);
1265N/A if ((rc = NewInputDeviceRequest(input_options, &attrs, &dev)) != Success) {
1124N/Adiff --git a/config/x11-input.fdi b/config/x11-input.fdi
1124N/Aindex b263f36..425aec2 100644
1124N/A--- a/config/x11-input.fdi
1124N/A+++ b/config/x11-input.fdi
1124N/A@@ -71,6 +71,12 @@
764N/A <!-- If we're using Linux, we use evdev by default (falling back to
764N/A kbd otherwise). -->
764N/A <merge key="input.x11_driver" type="string">kbd</merge>
764N/A+ <match key="/org/freedesktop/Hal/devices/computer:system.formfactor" string="laptop">
764N/A+ <match key="/org/freedesktop/Hal/devices/computer:system.kernel.name"
764N/A+ string="SunOS">
764N/A+ <merge key="input.x11_options.mdriver" type="string">hotkey</merge>
764N/A+ </match>
764N/A+ </match>
764N/A <merge key="input.x11_options.XkbModel" type="string">pc105</merge>
764N/A <match key="/org/freedesktop/Hal/devices/computer:system.kernel.name"
764N/A string="Linux">
1124N/Adiff --git a/include/inputstr.h b/include/inputstr.h
1340N/Aindex 5a38924..263b1b1 100644
1124N/A--- a/include/inputstr.h
1124N/A+++ b/include/inputstr.h
1276N/A@@ -57,6 +57,11 @@ SOFTWARE.
851N/A #include "geext.h"
851N/A #include "privates.h"
764N/A
764N/A+#ifdef SUNSOFT
1088N/A+extern _X_EXPORT DevPrivateKeyRec HotkeyMapDevicePrivateKeyRec;
1088N/A+#define HotkeyMapDevicePrivateKey (&HotkeyMapDevicePrivateKeyRec)
764N/A+#endif
851N/A+
1265N/A #define BitIsOn(ptr, bit) (!!(((const BYTE *) (ptr))[(bit)>>3] & (1 << ((bit) & 7))))
851N/A #define SetBit(ptr, bit) (((BYTE *) (ptr))[(bit)>>3] |= (1 << ((bit) & 7)))
851N/A #define ClearBit(ptr, bit) (((BYTE *)(ptr))[(bit)>>3] &= ~(1 << ((bit) & 7)))