6824603 ACPI hotkey X support
authorHenry Zhao <Henry.Zhao@Sun.COM>
Fri, 07 Aug 2009 22:52:55 -0700
changeset 764 ab397169f258
parent 763 16e275b50576
child 765 a3c7a0790719
6824603 ACPI hotkey X support 6827540 dispswitch: need to support display switch function key
open-src/driver/Makefile
open-src/driver/xf86-input-hotkey/Makefile
open-src/driver/xf86-input-hotkey/sun-src/Makefile
open-src/driver/xf86-input-hotkey/sun-src/config.h
open-src/driver/xf86-input-hotkey/sun-src/hotkey.c
open-src/xserver/xorg/hotkey.patch
open-src/xserver/xorg/patch-list
packages/SUNWxorg-server/prototype_i386
--- a/open-src/driver/Makefile	Wed Aug 05 16:10:40 2009 -0700
+++ b/open-src/driver/Makefile	Fri Aug 07 22:52:55 2009 -0700
@@ -28,7 +28,7 @@
 # or other dealings in this Software without prior written authorization
 # of the copyright holder.
 #
-# @(#)Makefile	1.13	09/05/15
+# @(#)Makefile	1.14	09/07/17
 #
 ###############################################################################
 
@@ -51,6 +51,7 @@
 	xf86-input-mutouch		\
 	xf86-input-penmount		\
 	xf86-input-vmmouse		\
+	xf86-input-hotkey		\
 	xf86-video-apm			\
 	xf86-video-ark			\
 	xf86-video-ati			\
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/open-src/driver/xf86-input-hotkey/Makefile	Fri Aug 07 22:52:55 2009 -0700
@@ -0,0 +1,58 @@
+###############################################################################
+#
+# xf86-input-keyboard 1.x Makefile
+#
+# Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+# Use subject to license terms.
+#
+# Permission is hereby granted, free of charge, to any person obtaining a
+# copy of this software and associated documentation files (the
+# "Software"), to deal in the Software without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, and/or sell copies of the Software, and to permit persons
+# to whom the Software is furnished to do so, provided that the above
+# copyright notice(s) and this permission notice appear in all copies of
+# the Software and that both the above copyright notice(s) and this
+# permission notice appear in supporting documentation.
+# 
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
+# OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+# HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL
+# INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING
+# FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+# NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+# WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+# 
+# Except as contained in this notice, the name of a copyright holder
+# shall not be used in advertising or otherwise to promote the sale, use
+# or other dealings in this Software without prior written authorization
+# of the copyright holder.
+#
+#pragma  ident  "@(#)Makefile 1.1     09/04/09 SMI"
+
+# Package name used in tarballs
+MODULE_NAME=hotkey
+
+# Version number (used in path names)
+MODULE_VERSION=src
+SOURCE_TARBALL_NAME=NONE
+SOURCE_TARBALL_NAME_SET=yes
+ADDITIONAL_SOURCE_DIR=sun-src
+
+# No configure script to run
+CONFIGURE_TARGETS=
+CONFIGURE_TARGETS_SET=yes
+
+SUN_PACKAGE=SUNWxorg-server
+MODULE_STABILITY=Volatile
+
+# Since we don't have a configure script, pass configure flags to make
+MODULE_BUILD_MAKEFLAGS=$(CONFIG_ENV) PREFIX=$(MODULE_PREFIX)
+MODULE_INSTALL_MAKEFLAGS=$(CONFIG_ENV) PREFIX=$(MODULE_PREFIX)
+
+include ../Makefile.inc
+
+source_gen:: $(LNDIR)
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/open-src/driver/xf86-input-hotkey/sun-src/Makefile	Fri Aug 07 22:52:55 2009 -0700
@@ -0,0 +1,46 @@
+# Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+# Use subject to license terms.
+#
+# Permission is hereby granted, free of charge, to any person obtaining a
+# copy of this software and associated documentation files (the
+# "Software"), to deal in the Software without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, and/or sell copies of the Software, and to permit persons
+# to whom the Software is furnished to do so, provided that the above
+# copyright notice(s) and this permission notice appear in all copies of
+# the Software and that both the above copyright notice(s) and this
+# permission notice appear in supporting documentation.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
+# OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+# HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL
+# INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING
+# FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+# NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+# WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+#
+# Except as contained in this notice, the name of a copyright holder
+# shall not be used in advertising or otherwise to promote the sale, use
+# or other dealings in this Software without prior written authorization
+# of the copyright holder.
+#
+# "@(#)Makefile 1.1     09/04/07 SMI"
+
+SRCS = hotkey.c
+OBJS = $(SRCS:.c=.o)
+REQLIBS = -lsysevent
+MODULEDIR = /lib/modules
+DRVDIR = /input
+
+hotkey_drv.so: $(OBJS)
+	$(CC) -o $@ $(LDFLAGS) -shared $(OBJS) $(REQLIBS)
+
+.c.o:
+	$(CC) -fpic -DPIC $(CFLAGS) $(CPPFLAGS) -c $<
+
+install: hotkey_drv.so 
+	mkdir -p $(DESTDIR)$(PREFIX)$(MODULEDIR)$(ARCHLIBSUBDIR)$(DRVDIR)
+	$(INSTALL) hotkey_drv.so $(DESTDIR)$(PREFIX)$(MODULEDIR)$(ARCHLIBSUBDIR)$(DRVDIR)
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/open-src/driver/xf86-input-hotkey/sun-src/config.h	Fri Aug 07 22:52:55 2009 -0700
@@ -0,0 +1,70 @@
+/* config.h.  Generated from config.h.in by configure.  */
+/* config.h.in.  Generated from configure.ac by autoheader.  */
+
+#include "xorg-server.h"
+
+/* Define to 1 if you have the <dlfcn.h> header file. */
+#define HAVE_DLFCN_H 1
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#define HAVE_INTTYPES_H 1
+
+/* Define to 1 if you have the <memory.h> header file. */
+#define HAVE_MEMORY_H 1
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#define HAVE_STDINT_H 1
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#define HAVE_STDLIB_H 1
+
+/* Define to 1 if you have the <strings.h> header file. */
+#define HAVE_STRINGS_H 1
+
+/* Define to 1 if you have the <string.h> header file. */
+#define HAVE_STRING_H 1
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#define HAVE_SYS_STAT_H 1
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#define HAVE_SYS_TYPES_H 1
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#define HAVE_UNISTD_H 1
+
+/* Name of package */
+#define PACKAGE "xf86-input-hotkey"
+
+/* Define to the address where bug reports for this package should be sent. */
+#define PACKAGE_BUGREPORT "https://bugs.freedesktop.org/enter_bug.cgi?product=xorg"
+
+/* Define to the full name of this package. */
+#define PACKAGE_NAME "xf86-input-hotkey"
+
+/* Define to the full name and version of this package. */
+#define PACKAGE_STRING "xf86-input-hotkey 1.0.0"
+
+/* Define to the one symbol short name of this package. */
+#define PACKAGE_TARNAME "xf86-input-hotkey"
+
+/* Define to the version of this package. */
+#define PACKAGE_VERSION "1.0.0"
+
+/* Major version of this package */
+#define PACKAGE_VERSION_MAJOR 1
+
+/* Minor version of this package */
+#define PACKAGE_VERSION_MINOR 0
+
+/* Patch version of this package */
+#define PACKAGE_VERSION_PATCHLEVEL 0
+
+/* Define to 1 if you have the ANSI C header files. */
+#define STDC_HEADERS 1
+
+/* Version number of package */
+#define VERSION "1.0.0"
+
+/* Flag */
+#define SUNSOFT 1
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/open-src/driver/xf86-input-hotkey/sun-src/hotkey.c	Fri Aug 07 22:52:55 2009 -0700
@@ -0,0 +1,351 @@
+/* Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, and/or sell copies of the Software, and to permit persons
+ * to whom the Software is furnished to do so, provided that the above
+ * copyright notice(s) and this permission notice appear in all copies of
+ * the Software and that both the above copyright notice(s) and this
+ * permission notice appear in supporting documentation.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
+ * OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL
+ * INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING
+ * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Except as contained in this notice, the name of a copyright holder
+ * shall not be used in advertising or otherwise to promote the sale, use
+ * or other dealings in this Software without prior written authorization
+ * of the copyright holder.
+ */
+
+#pragma  ident  "@(#)hotkey.c 1.2     09/04/14 SMI"
+
+#include "config.h"
+#include "xf86.h"
+#include "xf86Priv.h"
+#include "xf86Xinput.h"
+#include "xf86_OSproc.h"
+#include <X11/XF86keysym.h>
+#include <unistd.h>
+#include <sys/stat.h>
+#include <signal.h>
+#include <errno.h>
+#include <libsysevent.h>
+#ifdef XKB
+#include <xkbsrv.h>
+#endif
+
+static InputInfoPtr HkeyPreInit(InputDriverPtr drv, IDevPtr dev, int flags);
+static void HkeyUnInit(InputDriverPtr drv, InputInfoPtr pInfo, int flags);
+
+_X_EXPORT InputDriverRec HKEY = {
+        1,
+        "hotkey",
+        NULL,
+        HkeyPreInit,
+        HkeyUnInit,
+        NULL,
+        0
+};
+
+static struct {
+    const char	*sub_class;
+    KeySym	keysym;
+} sub_to_keysym_table [] = {
+    { "ESC_acpiev_display_switch", 	XF86XK_Display },
+    { "ESC_acpiev_sleep",	 	XF86XK_Sleep },	
+    { "ESC_acpiev_screen_lock",		XF86XK_ScreenSaver },
+    { NULL,				NoSymbol }
+};
+
+
+#define	EC_ACPIEV			"EC_acpiev"
+#define HOTKEY_KEYSYM_ROOT		(XF86XK_Display & 0xFFFFFF00)
+
+static sysevent_handle_t	*hotkey_event_entry;
+static int 			hotkey_event_fd[2] = {-1, -1};
+
+static void 
+hotkey_event_handler(sysevent_t *ev)
+{
+    int		i;
+    char	buf;
+    char	*subclass;
+    KeySym	keysym = 0;
+
+    subclass = sysevent_get_subclass_name(ev);
+    for (i = 0; sub_to_keysym_table[i].sub_class != NULL; i++)
+	if (!strcmp (sub_to_keysym_table[i].sub_class, subclass)) {
+	    keysym = sub_to_keysym_table[i].keysym;
+	    break;
+	}
+
+    if (sub_to_keysym_table[i].sub_class == NULL)
+	return;
+
+    buf = keysym - HOTKEY_KEYSYM_ROOT;
+
+    write(hotkey_event_fd[1], &buf, 1);
+}
+
+
+static  Bool 
+map_init(DeviceIntPtr device) 
+{
+
+#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 5
+    XkbRMLVOSet rmlvo;
+
+    XkbGetRulesDflts(&rmlvo);
+    if (!InitKeyboardDeviceStruct(device, &rmlvo, NULL, NULL)) {
+	xf86Msg(X_WARNING, "hotkey map_init failed\n");
+	return FALSE;
+    }
+#else
+    KeySymsRec  keySyms;
+    CARD8	*modMap;
+
+    keySyms.minKeyCode = inputInfo.keyboard->key->curKeySyms.minKeyCode;
+    keySyms.maxKeyCode = inputInfo.keyboard->key->curKeySyms.maxKeyCode;
+    keySyms.mapWidth = inputInfo.keyboard->key->curKeySyms.mapWidth;
+
+    keySyms.map = (KeySym *)xcalloc(sizeof(KeySym),
+	(keySyms.maxKeyCode - keySyms.minKeyCode + 1) * keySyms.mapWidth);
+    if (!keySyms.map) {
+	xf86Msg (X_WARNING, "Couldn't allocate hotkey core keymap\n");
+	return FALSE;
+    }
+
+    modMap = (CARD8 *)xcalloc(1, MAP_LENGTH);
+    if (!modMap) {
+	xf86Msg (X_WARNING, "Couldn't allocate hotkey modifier keymap\n");
+	return FALSE;
+    }
+
+#ifdef XKB
+    if (!noXkbExtension) {
+	XkbComponentNamesRec names;
+
+	bzero(&names, sizeof(names));
+	XkbInitKeyboardDeviceStruct(device, &names, &keySyms, modMap, NULL, NULL);
+    } else
+#endif
+	/* FIXME Our keymap here isn't exactly useful. */
+    InitKeyboardDeviceStruct((DevicePtr)device, &keySyms, modMap, NULL, NULL);
+
+    xfree(keySyms.map);
+    xfree(modMap);
+#endif
+
+    return TRUE;
+}
+
+static void
+hotkey_events_fini(void)
+{
+    sysevent_unsubscribe_event (hotkey_event_entry, EC_ACPIEV);
+    sysevent_unbind_handle (hotkey_event_entry);
+    hotkey_event_entry = NULL;
+    xf86Msg(X_CONFIG, "hotkey_events_fini: succeeded\n");
+}
+
+static	Bool
+hotkey_events_init(DeviceIntPtr device) {
+    const char	*subclass_list[] = {EC_SUB_ALL};
+
+    hotkey_event_entry = sysevent_bind_handle (hotkey_event_handler);
+    if (hotkey_event_entry == NULL) {
+	xf86Msg(X_WARNING, 
+	    "hotkey_events_init: sysevent_bind_handle failed: with errno = %d\n" , errno);
+	return FALSE;
+    }
+    else {
+	if (sysevent_subscribe_event(hotkey_event_entry, EC_ACPIEV, subclass_list, 1)
+	    != 0) {
+	    sysevent_unbind_handle(hotkey_event_entry);
+	    hotkey_event_entry = NULL;
+	    xf86Msg(X_CONFIG, "hotkey_events_init: sysevent_subscribe_event failed\n");
+	    return FALSE;
+	}
+    }
+
+    return  TRUE;
+}
+
+static void
+hotkey_read_input(InputInfoPtr pInfo)
+{
+    unsigned char	buf;
+    KeySym	keysym = NoSymbol;
+    KeyCode	keycode = 0;
+    KeySymsPtr	curKeySyms;
+    DeviceIntPtr	dev = pInfo->dev;
+    int         i;
+
+    if (read (pInfo->fd, &buf, 1 ) == 1)
+	keysym = buf + HOTKEY_KEYSYM_ROOT;
+
+    if (dev->u.master)
+	curKeySyms = &dev->u.master->key->curKeySyms;
+    else
+	curKeySyms = &inputInfo.keyboard->key->curKeySyms;
+
+    for (i = curKeySyms->minKeyCode; i <= curKeySyms->maxKeyCode; i++) {
+	if (curKeySyms->map[(i - curKeySyms->minKeyCode) * curKeySyms->mapWidth] 
+	    == keysym) {
+	    keycode = i;
+	    break;
+	}
+    }
+
+    if (!keycode)
+	xf86MsgVerb(X_WARNING, 0, "Hotkey keysym %x not mapped\n", (int) keysym);
+    else {
+	xf86MsgVerb(X_INFO, 3, "Posting keycode %d for keysym %x on device %s\n", 
+		keycode, (int) keysym, pInfo->dev->name);
+	xf86PostKeyboardEvent(pInfo->dev, keycode, TRUE);
+	xf86PostKeyboardEvent(pInfo->dev, keycode, FALSE);
+    }
+}
+
+static int
+HkeyProc(DeviceIntPtr device, int what)
+{
+    InputInfoPtr pInfo = device->public.devicePrivate;
+    char	 *s;
+    DeviceIntPtr mdev;
+
+    switch (what) {
+     	case DEVICE_INIT:
+	    if (!map_init(device)) {
+		xf86Msg(X_WARNING, "HkeyProc: map_init failed\n");
+		return (!Success);
+	    }
+
+	    if (hotkey_events_init(device)) {
+		if (pipe (hotkey_event_fd) == -1) {
+		    xf86Msg(X_WARNING,
+		    "hotkey_events_init: pipe open failed with errno %d\n", errno);
+		    hotkey_events_fini();
+		    return (!Success);
+		} else {
+		    pInfo->fd = hotkey_event_fd[0];
+		    xf86Msg(X_CONFIG, "hotkey_events_init and pipe open succeeded\n");
+                }
+            } else {
+		xf86Msg(X_WARNING, "hotkey_events_init failed\n");
+		return (!Success);
+	    }
+
+    	    device->public.on = FALSE;
+	    break;
+	case DEVICE_ON:
+    	    if (device->public.on)
+	    	break;
+	    xf86FlushInput(pInfo->fd);
+	    AddEnabledDevice(pInfo->fd);
+
+	    if (device->u.master)
+		dixSetPrivate(&device->u.master->devPrivates, 
+		    HotkeyMapDevicePrivateKey, device);
+
+	    device->public.on = TRUE;
+	    break;
+	case DEVICE_CLOSE:
+	    if (pInfo->fd != -1)
+		RemoveEnabledDevice(pInfo->fd);
+	    close(hotkey_event_fd[0]);
+	    close(hotkey_event_fd[1]);
+	    hotkey_events_fini();
+	    break;
+	case DEVICE_OFF:
+	    if (!device->public.on)
+		break;
+	    if (pInfo->fd != -1)
+		RemoveEnabledDevice(pInfo->fd);
+
+	    if (device->u.master)
+		dixSetPrivate(&device->u.master->devPrivates, 
+		    HotkeyMapDevicePrivateKey, NULL);
+
+    	    device->public.on = FALSE;
+	    break;
+    }
+
+    return (Success);
+}
+
+static InputInfoPtr
+HkeyPreInit(InputDriverPtr drv, IDevPtr dev, int flags)
+{
+    InputInfoPtr 	pInfo;
+
+    if (!(pInfo = xf86AllocateInput(drv, 0)))
+	return NULL;
+
+    /* Initialize the InputInfoRec. */
+    pInfo->name = xstrdup (dev->identifier);
+    pInfo->type_name = XI_KEYBOARD;
+    pInfo->device_control = HkeyProc;
+    pInfo->read_input = hotkey_read_input;
+    pInfo->fd = -1;
+    pInfo->conf_idev = dev;
+    pInfo->flags = XI86_OPEN_ON_INIT | XI86_ALWAYS_CORE;
+    pInfo->flags |= XI86_CONFIGURED;
+
+    return pInfo;
+}
+
+static void
+HkeyUnInit(InputDriverPtr drv, InputInfoPtr pInfo, int flags)
+{
+    xf86DeleteInput(pInfo, 0);
+}
+
+static void
+HkeyUnplug(pointer p)
+{
+}
+
+static pointer
+HkeyPlug(pointer module, pointer options, int *errmaj, int *errmin)
+{
+    static Bool Initialised = FALSE;
+
+    if (!Initialised)
+        Initialised = TRUE;
+
+    xf86AddInputDriver(&HKEY, module, 0);
+
+    return module;
+}
+
+
+static XF86ModuleVersionInfo HkeyVersionRec = {
+    "hotkey",
+    MODULEVENDORSTRING,
+    MODINFOSTRING1,
+    MODINFOSTRING2,
+    XORG_VERSION_CURRENT,
+    1, 0, 0,
+    ABI_CLASS_XINPUT,
+    ABI_XINPUT_VERSION,
+    MOD_CLASS_XINPUT,
+    {0, 0, 0, 0}                /* signature, to be patched into the file by */
+                                /* a tool */
+};
+
+_X_EXPORT XF86ModuleData hotkeyModuleData = {
+    &HkeyVersionRec,
+    HkeyPlug,
+    HkeyUnplug
+};
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/open-src/xserver/xorg/hotkey.patch	Fri Aug 07 22:52:55 2009 -0700
@@ -0,0 +1,163 @@
+diff -ur old/Xi/exevents.c new/Xi/exevents.c
+--- Xi/exevents.c	Wed May 27 13:40:54 2009
++++ Xi/exevents.c	Thu May 28 16:56:37 2009
+@@ -193,6 +193,10 @@
+     KeyClassPtr mk, dk; /* master, device */
+     BOOL sendNotify = FALSE;
+     int i;
++#ifdef SUNSOFT
++    DeviceIntPtr mdev = dixLookupPrivate(&master->devPrivates,
++	HotkeyMapDevicePrivateKey);
++#endif
+ 
+     if (device == master)
+         return;
+@@ -201,7 +205,11 @@
+     mk = master->key;
+ 
+     if (device != dixLookupPrivate(&master->devPrivates,
++#ifdef SUNSOFT
++                                   CoreDevicePrivateKey) && (device != mdev)) {
++#else
+                                    CoreDevicePrivateKey)) {
++#endif
+         memcpy(mk->modifierMap, dk->modifierMap, MAP_LENGTH);
+ 
+         if (dk->maxKeysPerModifier)
+diff -ur old/config/hal.c new/config/hal.c
+--- config/hal.c	Wed May 27 17:32:59 2009
++++ config/hal.c	Thu Jul 16 18:24:46 2009
+@@ -186,7 +186,63 @@
+     return FALSE;
+ }
+ 
++#ifdef SUNSOFT
+ static void
++add_extra_device(char *driver)
++{
++    DeviceIntPtr	dev;
++    char		*config_info = NULL;
++    InputOption 	*options = NULL, *tmpo = NULL;
++
++    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, &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)
+ {
+     char *path = NULL, *driver = NULL, *name = NULL, *config_info = NULL;
+@@ -195,6 +251,9 @@
+     DBusError error;
+     struct xkb_options xkb_opts = {0};
+     int rc;
++#ifdef SUNSOFT
++    char *mdriver = NULL;
++#endif
+ 
+     LibHalPropertySet *set = NULL;
+ 	LibHalPropertySetIterator set_iter;
+@@ -398,6 +457,16 @@
+     if (xkb_opts.options)
+         add_option(&options, "xkb_options", xkb_opts.options);
+ 
++#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, &dev)) != Success) {
+diff -ur old/config/x11-input.fdi new/config/x11-input.fdi
+--- config/x11-input.fdi	Wed May 27 16:03:27 2009
++++ config/x11-input.fdi	Thu Jul 16 18:01:18 2009
+@@ -76,6 +76,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 -ur old/dix/devices.c new/dix/devices.c
+--- dix/devices.c	Thu Jul 16 18:26:35 2009
++++ dix/devices.c	Thu Jul 16 18:30:12 2009
+@@ -95,6 +95,10 @@
+ 
+ static int CoreDevicePrivateKeyIndex;
+ DevPrivateKey CoreDevicePrivateKey = &CoreDevicePrivateKeyIndex;
++#ifdef SUNSOFT
++static int HotkeyMapDevicePrivateKeyIndex;
++DevPrivateKey HotkeyMapDevicePrivateKey = &HotkeyMapDevicePrivateKeyIndex;
++#endif
+ /* Used to sture classes currently not in use by an MD */
+ static int UnusedClassesPrivateKeyIndex;
+ DevPrivateKey UnusedClassesPrivateKey = &UnusedClassesPrivateKeyIndex;
+diff -ur old/include/inputstr.h new/include/inputstr.h
+--- include/inputstr.h	Wed May 27 13:18:36 2009
++++ include/inputstr.h	Wed May 27 13:18:15 2009
+@@ -64,6 +64,9 @@
+ #define EMASKSIZE	MAXDEVICES + 1
+ 
+ extern DevPrivateKey CoreDevicePrivateKey;
++#ifdef SUNSOFT
++extern DevPrivateKey HotkeyMapDevicePrivateKey;
++#endif
+ 
+ /* Kludge: OtherClients and InputClients must be compatible, see code */
+ 
--- a/open-src/xserver/xorg/patch-list	Wed Aug 05 16:10:40 2009 -0700
+++ b/open-src/xserver/xorg/patch-list	Fri Aug 07 22:52:55 2009 -0700
@@ -35,3 +35,4 @@
 xpstubs.patch
 dixmods-deps.patch
 sparc-initvisuals.patch
+hotkey.patch
--- a/packages/SUNWxorg-server/prototype_i386	Wed Aug 05 16:10:40 2009 -0700
+++ b/packages/SUNWxorg-server/prototype_i386	Fri Aug 07 22:52:55 2009 -0700
@@ -29,7 +29,7 @@
 #
 ###########################################################################
 #
-# ident "@(#)prototype_i386 1.17     09/05/15 SMI"
+# ident "@(#)prototype_i386 1.18     09/07/22 SMI"
 #
 # X.Org Foundation X server for Solaris
 
@@ -102,6 +102,7 @@
 f none X11/lib/modules/input/mutouch_drv.so 0755 root bin
 f none X11/lib/modules/input/penmount_drv.so 0755 root bin
 f none X11/lib/modules/input/vmmouse_drv.so 0755 root bin
+f none X11/lib/modules/input/hotkey_drv.so 0755 root bin
 
 !search $HOME/lib/modules/amd64/input
 d none X11/lib/modules/input/amd64 0755 root bin
@@ -116,6 +117,7 @@
 f none X11/lib/modules/input/amd64/penmount_drv.so 0755 root bin
 f none X11/lib/modules/input/amd64/void_drv.so 0755 root bin
 f none X11/lib/modules/input/amd64/vmmouse_drv.so 0755 root bin
+f none X11/lib/modules/input/amd64/hotkey_drv.so 0755 root bin
 
 !search $HOME/share/man/man7
 f none X11/share/man/man7/acecad.7 0444 root bin