diff --git a/Xi/exevents.c b/Xi/exevents.c
index 9bd9d60..e41fa74 100644
--- a/Xi/exevents.c
+++ b/Xi/exevents.c
@@ -187,7 +187,16 @@ CopyKeyClass(DeviceIntPtr device, DeviceIntPtr master)
{
KeyClassPtr mk = master->key;
+#ifdef SUNSOFT
+ DeviceIntPtr mdev = dixLookupPrivate(&master->devPrivates,
+ HotkeyMapDevicePrivateKey);
+#endif
+
+#ifdef SUNSOFT
+ if ((device == master) || (device == mdev))
+#else
if (device == master)
+#endif
return;
mk->sourceid = device->id;
diff --git a/Xi/extinit.c b/Xi/extinit.c
index 7f09dfe..d81ca33 100644
--- a/Xi/extinit.c
+++ b/Xi/extinit.c
@@ -372,6 +372,10 @@ extern XExtensionVersion XIVersion;
Mask PropagateMask[MAXDEVICES];
+#ifdef SUNSOFT
+DevPrivateKeyRec HotkeyMapDevicePrivateKeyRec;
+#endif
+
/*****************************************************************
*
* Versioning support
@@ -1258,6 +1262,11 @@ XInputExtensionInit(void)
if (!dixRegisterPrivateKey(&XIClientPrivateKeyRec, PRIVATE_CLIENT, sizeof(XIClientRec)))
FatalError("Cannot request private for XI.\n");
+#ifdef SUNSOFT
+ if (!dixRegisterPrivateKey(&HotkeyMapDevicePrivateKeyRec, PRIVATE_DEVICE, 0))
+ FatalError("Cannot request private for hotkey.\n");
+#endif
+
if (!AddCallback(&ClientStateCallback, XIClientCallback, 0))
FatalError("Failed to add callback to XI.\n");
diff --git a/config/hal.c b/config/hal.c
index 297520a..44c1582 100644
--- a/config/hal.c
+++ b/config/hal.c
@@ -123,6 +123,63 @@ get_prop_string_array(LibHalContext *hal_ctx, const char *udi, const char *prop)
return ret;
}
+#ifdef SUNSOFT
+static void
+add_extra_device(char *driver)
+{
+ DeviceIntPtr dev;
+ char *config_info = NULL;
+ InputOption *options = NULL, *tmpo = NULL;
+ InputAttributes attrs = {0};
+
+ options = xcalloc(sizeof(*options), 1);
+ if (!options){
+ LogMessage(X_ERROR, "config/hal: couldn't allocate space for input options!\n");
+ goto unwind;
+ }
+
+ options->key = xstrdup("_source");
+ options->value = xstrdup("server/hal");
+ if (!options->key || !options->value) {
+ LogMessage(X_ERROR, "config/hal: couldn't allocate first key/value pair\n");
+ goto unwind;
+ }
+
+ add_option(&options, "driver", driver);
+ add_option(&options, "name", driver);
+
+ config_info = xalloc(strlen(driver) + 5); /* "hal:" and NULL */
+ if (!config_info) {
+ LogMessage(X_ERROR, "config/hal: couldn't allocate name\n");
+ goto unwind;
+ }
+ sprintf(config_info, "hal:%s", driver);
+
+ /* Check for duplicate devices */
+ if (device_is_duplicate(config_info))
+ goto unwind;
+
+ LogMessage(X_INFO, "config/hal: Adding input device %s\n", driver);
+ if (NewInputDeviceRequest(options, &attrs, &dev) != Success) {
+ LogMessage(X_ERROR, "config/hal: NewInputDeviceRequest failed\n");
+ dev = NULL;
+ goto unwind;
+ }
+
+ dev->config_info = xstrdup(config_info);
+
+unwind:
+ if (config_info)
+ xfree(config_info);
+ while (!dev && (tmpo = options)) {
+ options = tmpo->next;
+ xfree(tmpo->key);
+ xfree(tmpo->value);
+ xfree(tmpo);
+ }
+}
+#endif
+
static void
device_added(LibHalContext *hal_ctx, const char *udi)
{
@@ -134,6 +191,9 @@ device_added(LibHalContext *hal_ctx, const char *udi)
DBusError error;
struct xkb_options xkb_opts = {0};
int rc;
+#ifdef SUNSOFT
+ char *mdriver = NULL;
+#endif
LibHalPropertySet *set = NULL;
LibHalPropertySetIterator set_iter;
@@ -377,6 +437,16 @@ device_added(LibHalContext *hal_ctx, const char *udi)
add_option(&options, "xkb_options", xkb_opts.options);
add_option(&options, "config_info", config_info);
+#ifdef SUNSOFT
+ for (tmpo = options; tmpo; tmpo = tmpo->next) {
+ if (!strcmp(tmpo->key, "mdriver") && (tmpo->value))
+ mdriver = tmpo->value;
+ }
+
+ if (mdriver)
+ add_extra_device (mdriver);
+#endif
+
/* this isn't an error, but how else do you output something that the user can see? */
LogMessage(X_INFO, "config/hal: Adding input device %s\n", name);
if ((rc = NewInputDeviceRequest(options, &attrs, &dev)) != Success) {
diff --git a/config/x11-input.fdi b/config/x11-input.fdi
index b263f36..425aec2 100644
--- a/config/x11-input.fdi
+++ b/config/x11-input.fdi
@@ -71,6 +71,12 @@
<!-- If we're using Linux, we use evdev by default (falling back to
kbd otherwise). -->
<merge key="input.x11_driver" type="string">kbd</merge>
+ <match key="/org/freedesktop/Hal/devices/computer:system.formfactor" string="laptop">
+ <match key="/org/freedesktop/Hal/devices/computer:system.kernel.name"
+ string="SunOS">
+ <merge key="input.x11_options.mdriver" type="string">hotkey</merge>
+ </match>
+ </match>
<merge key="input.x11_options.XkbModel" type="string">pc105</merge>
<match key="/org/freedesktop/Hal/devices/computer:system.kernel.name"
string="Linux">
diff --git a/include/inputstr.h b/include/inputstr.h
index 2ee2fd8..1c3711c 100644
--- a/include/inputstr.h
+++ b/include/inputstr.h
@@ -57,6 +57,11 @@ SOFTWARE.
#include "geext.h"
#include "privates.h"
+#ifdef SUNSOFT
+extern _X_EXPORT DevPrivateKeyRec HotkeyMapDevicePrivateKeyRec;
+#define HotkeyMapDevicePrivateKey (&HotkeyMapDevicePrivateKeyRec)
+#endif
+
#define BitIsOn(ptr, bit) (!!(((BYTE *) (ptr))[(bit)>>3] & (1 << ((bit) & 7))))
#define SetBit(ptr, bit) (((BYTE *) (ptr))[(bit)>>3] |= (1 << ((bit) & 7)))
#define ClearBit(ptr, bit) (((BYTE *)(ptr))[(bit)>>3] &= ~(1 << ((bit) & 7)))