From 02a95311568e24e1055ea52c7df8cb7aa3f38ad0 Mon Sep 17 00:00:00 2001 From: Daniel Stone Date: Wed, 19 Jul 2006 10:05:12 -0400 Subject: [PATCH 01/87] add basic D-BUS configuration mechanism Also move LookupDeviceIntRec into the DIX, and add InputOption type, and NewInputDeviceRequest prototype (DIX requests DDX to add a device). Does not link without an implemented NIDR. --- Makefile.am | 1 + config/Makefile.am | 10 ++ config/config.c | 289 ++++++++++++++++++++++++++++++++++++++++ config/xorg-server.conf | 13 ++ configure.ac | 20 ++- dix/dispatch.c | 4 + dix/main.c | 3 + include/config.h | 31 +++++ include/dix-config.h.in | 3 + include/input.h | 13 ++ include/os.h | 4 + os/connection.c | 19 ++- 12 files changed, 404 insertions(+), 6 deletions(-) create mode 100644 config/Makefile.am create mode 100644 config/config.c create mode 100644 config/xorg-server.conf create mode 100644 include/config.h diff --git a/Makefile.am b/Makefile.am index c425cc6bb..799815ee2 100644 --- a/Makefile.am +++ b/Makefile.am @@ -59,6 +59,7 @@ SUBDIRS = \ $(COMPOSITE_DIR) \ $(GLX_DIR) \ exa \ + config \ hw aclocaldir = $(datadir)/aclocal diff --git a/config/Makefile.am b/config/Makefile.am new file mode 100644 index 000000000..1cc9109db --- /dev/null +++ b/config/Makefile.am @@ -0,0 +1,10 @@ +AM_CFLAGS = @DIX_CFLAGS@ + +dbusconfigdir = $(sysconfdir)/dbus-1/system.d +dbusconfig_DATA = xorg-server.conf + +lib_LIBRARIES = libconfig.a + +libconfig_a_SOURCES = config.c + +EXTRA_DIST = xorg-server.conf diff --git a/config/config.c b/config/config.c new file mode 100644 index 000000000..b85b12028 --- /dev/null +++ b/config/config.c @@ -0,0 +1,289 @@ +/* + * Copyright © 2006 Daniel Stone + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of the copyright holders and/or authors + * not be used in advertising or publicity pertaining to distribution of the + * software without specific, written prior permission. The copyright holders + * and/or authors make no representations about the suitability of this + * software for any purpose. It is provided "as is" without express or + * implied warranty. + * + * THE COPYRIGHT HOLDERS AND/OR AUTHORS DISCLAIM ALL WARRANTIES WITH REGARD + * TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS AND/OR AUTHORS BE LIABLE + * FOR 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. + */ + +#ifdef HAVE_DIX_CONFIG_H +#include +#endif + +#ifdef HAVE_DBUS +#define DBUS_API_SUBJECT_TO_CHANGE +#include +#include +#include "opaque.h" /* for 'display': there has to be a better way */ + /* the above comment lies. there is no better way. */ +#include "input.h" +#include "config.h" + +#define MATCH_RULE "type='method_call',interface='org.x.config.input'" + +static DBusConnection *configConnection = NULL; +static int configfd = -1; +static char busobject[32] = { 0 }; +static char busname[64] = { 0 }; + +void +configDispatch() +{ + if (!configConnection) + return; + + dbus_connection_read_write_dispatch(configConnection, 0); +} + +static DBusHandlerResult +configMessage(DBusConnection *connection, DBusMessage *message, void *closure) +{ + InputOption *option = NULL, *ret = NULL; + DBusMessageIter iter, subiter; + DBusError error; + char *tmp = NULL; + int deviceid = -1; + DeviceIntPtr pDev = NULL; + + ErrorF("[dbus] new message!\n"); + ErrorF(" source: %s\n", dbus_message_get_sender(message)); + ErrorF(" destination: %s\n", dbus_message_get_destination(message)); + ErrorF(" signature: %s\n", dbus_message_get_signature(message)); + ErrorF(" path: %s\n", dbus_message_get_path(message)); + ErrorF(" interface: %s\n", dbus_message_get_interface(message)); + ErrorF(" member: %s\n", dbus_message_get_member(message)); + ErrorF(" method call? %s\n", (dbus_message_get_type(message) == + DBUS_MESSAGE_TYPE_METHOD_CALL) ? + "yes" : "no"); + + dbus_error_init(&error); + + if (strcmp(dbus_message_get_interface(message), + "org.x.config.input") == 0) { + if (!dbus_message_iter_init(message, &iter)) { + ErrorF("failed to init iterator! this is probably bad.\n"); + dbus_error_free(&error); + return DBUS_HANDLER_RESULT_NEED_MEMORY; /* ?? */ + } + if (strcmp(dbus_message_get_member(message), "add") == 0) { + ErrorF(" we want to add a device!\n"); + /* signature should be [ss][ss]... */ + while (dbus_message_iter_get_arg_type(&iter) == DBUS_TYPE_ARRAY) { + option = (InputOption *)xcalloc(sizeof(InputOption), 1); + if (!option) { + while (ret) { + option = ret; + ret = ret->next; + xfree(option); + } + dbus_error_free(&error); + return DBUS_HANDLER_RESULT_NEED_MEMORY; + } + + dbus_message_iter_recurse(&iter, &subiter); + + if (dbus_message_iter_get_arg_type(&subiter) != + DBUS_TYPE_STRING) { + ErrorF("couldn't get the arg type\n"); + xfree(option); + dbus_error_free(&error); + return DBUS_HANDLER_RESULT_HANDLED; + } + dbus_message_iter_get_basic(&subiter, &tmp); + if (!tmp) { + ErrorF("couldn't get the key!\n"); + xfree(option); + break; + } + option->key = xstrdup(tmp); + if (!option->key) { + ErrorF("couldn't duplicate the key!\n"); + xfree(option); + break; + } + + if (!dbus_message_iter_has_next(&subiter)) { + ErrorF("broken message: no next\n"); + xfree(option->key); + xfree(option); + dbus_error_free(&error); + return DBUS_HANDLER_RESULT_HANDLED; + } + dbus_message_iter_next(&subiter); + + if (dbus_message_iter_get_arg_type(&subiter) != + DBUS_TYPE_STRING) { + ErrorF("couldn't get the arg type\n"); + xfree(option); + dbus_error_free(&error); + return DBUS_HANDLER_RESULT_HANDLED; + } + dbus_message_iter_get_basic(&subiter, &tmp); + if (!tmp) { + ErrorF("couldn't get the value!\n"); + xfree(option->key); + xfree(option); + break; + } + option->value = xstrdup(tmp); + if (!option->value) { + ErrorF("couldn't duplicate the option!\n"); + xfree(option->value); + xfree(option); + break; + } + + option->next = ret; + ret = option; + dbus_message_iter_next(&iter); + } + + if (NewInputDeviceRequest(ret) != Success) { + ErrorF("[config] NIDR failed\n"); + } + dbus_error_free(&error); + return DBUS_HANDLER_RESULT_HANDLED; + } + else if (strcmp(dbus_message_get_member(message), "remove") == 0) { + ErrorF(" we want to remove a device!\n"); + if (!dbus_message_get_args(message, &error, DBUS_TYPE_INT32, + &deviceid, DBUS_TYPE_INVALID)) { + ErrorF("couldn't get args: %s %s\n", error.name, error.message); + dbus_error_free(&error); + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + } + if (deviceid < 0 || !(pDev = LookupDeviceIntRec(deviceid))) { + ErrorF("bogus device id %d\n", deviceid); + dbus_error_free(&error); + return DBUS_HANDLER_RESULT_HANDLED; + } + ErrorF("pDev is %p\n", pDev); + RemoveDevice(pDev); + dbus_error_free(&error); + return DBUS_HANDLER_RESULT_HANDLED; + } + } + + dbus_error_free(&error); + + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; +} + +void +configInitialise() +{ + DBusConnection *bus = NULL; + DBusError error; + DBusObjectPathVTable vtable; + + configConnection = NULL; + + dbus_error_init(&error); + bus = dbus_bus_get(DBUS_BUS_SYSTEM, &error); + if (!bus || dbus_error_is_set(&error)) { + ErrorF("[dbus] some kind of error occurred: %s (%s)\n", error.name, + error.message); + dbus_error_free(&error); + return; + } + + if (!dbus_connection_get_unix_fd(bus, &configfd)) { + ErrorF("[dbus] couldn't get fd for bus\n"); + dbus_connection_close(bus); + configfd = -1; + return; + } + + snprintf(busname, sizeof(busname), "org.x.config.display%d", atoi(display)); + if (!dbus_bus_request_name(bus, busname, 0, &error) || + dbus_error_is_set(&error)) { + ErrorF("[dbus] couldn't take over org.x.config: %s (%s)\n", + error.name, error.message); + dbus_error_free(&error); + dbus_connection_close(bus); + configfd = -1; + return; + } + + /* blocks until we get a reply. */ + dbus_bus_add_match(bus, MATCH_RULE, &error); + if (dbus_error_is_set(&error)) { + ErrorF("[dbus] couldn't match X.Org rule: %s (%s)\n", error.name, + error.message); + dbus_error_free(&error); + dbus_bus_release_name(bus, busname, &error); + dbus_connection_close(bus); + configfd = -1; + return; + } + + vtable.message_function = configMessage; + snprintf(busobject, sizeof(busobject), "/org/x/config/%d", atoi(display)); + if (!dbus_connection_register_object_path(bus, busobject, &vtable, NULL)) { + ErrorF("[dbus] couldn't register object path\n"); + configfd = -1; + dbus_bus_release_name(bus, busname, &error); + dbus_bus_remove_match(bus, MATCH_RULE, &error); + dbus_connection_close(bus); + configfd = -1; + return; + } + ErrorF("[dbus] registered object path %s\n", busobject); + + ErrorF("[dbus] registered and listening\n"); + + dbus_error_free(&error); + + configConnection = bus; + + AddGeneralSocket(configfd); +} + +void +configFini() +{ + DBusError error; + + if (configConnection) { + dbus_error_init(&error); + ErrorF("configFini being called\n"); + dbus_bus_remove_match(configConnection, MATCH_RULE, &error); + dbus_bus_release_name(configConnection, busname, &error); + dbus_connection_close(configConnection); + RemoveGeneralSocket(configfd); + configConnection = NULL; + configfd = -1; + dbus_error_free(&error); + } +} +#else +void +configDispatch() +{ +} + +void +configInitialise() +{ +} + +void +configFini() +{ +} +#endif diff --git a/config/xorg-server.conf b/config/xorg-server.conf new file mode 100644 index 000000000..47a9a7824 --- /dev/null +++ b/config/xorg-server.conf @@ -0,0 +1,13 @@ + + + + + + + + + + + diff --git a/configure.ac b/configure.ac index a2af59990..41536f74e 100644 --- a/configure.ac +++ b/configure.ac @@ -423,6 +423,7 @@ AC_ARG_ENABLE(dbe, AS_HELP_STRING([--disable-dbe], [Build DBE extensi AC_ARG_ENABLE(xf86bigfont, AS_HELP_STRING([--disable-xf86bigfont], [Build XF86 Big Font extension (default: enabled)]), [XF86BIGFONT=$enableval], [XF86BIGFONT=yes]) AC_ARG_ENABLE(dpms, AS_HELP_STRING([--disable-dpms], [Build DPMS extension (default: enabled)]), [DPMSExtension=$enableval], [DPMSExtension=yes]) AC_ARG_ENABLE(xinput, AS_HELP_STRING([--disable-xinput], [Build XInput Extension (default: enabled)]), [XINPUT=$enableval], [XINPUT=yes]) +AC_ARG_ENABLE(dbus, AS_HELP_STRING([--disable-dbus], [Build D-BUS support (default: auto)]), [DBUS=$enableval], [DBUS=auto]) dnl DDXes. AC_ARG_ENABLE(xorg, AS_HELP_STRING([--enable-xorg], [Build Xorg server (default: auto)]), [XORG=$enableval], [XORG=auto]) @@ -512,6 +513,18 @@ dnl Core modules for most extensions, et al. REQUIRED_MODULES="randrproto renderproto [fixesproto >= 4.0] damageproto xcmiscproto xextproto xproto xtrans xf86miscproto xf86vidmodeproto xf86bigfontproto [scrnsaverproto >= 1.1] bigreqsproto resourceproto fontsproto inputproto xf86dgaproto" REQUIRED_LIBS="xfont xau fontenc" +if test "x$DBUS" = xauto; then + PKG_CHECK_MODULES(DBUS, dbus-1, [DBUS=yes], [DBUS=no]) +fi +if test "x$DBUS" = xyes; then + PKG_CHECK_MODULES(DBUS, dbus-1) + AC_DEFINE(HAVE_DBUS, 1, [Have D-BUS support]) + REQUIRED_MODULES="$REQUIRED_MODULES dbus-1" + REQUIRED_LIBS="$REQUIRED_LIBS dbus-1" +fi +CONFIG_LIB='$(top_builddir)/config/libconfig.a' +AM_CONDITIONAL(DBUS, [test "x$DBUS" = xyes]) + AM_CONDITIONAL(XV, [test "x$XV" = xyes]) if test "x$XV" = xyes; then AC_DEFINE(XV, 1, [Support Xv extension]) @@ -1007,7 +1020,7 @@ if test "x$XGLX" = xyes; then fi # XORG_CORE_LIBS is needed even if you're not building the Xorg DDX -XORG_CORE_LIBS="$DIX_LIB" +XORG_CORE_LIBS="$DIX_LIB $CONFIG_LIB" AC_SUBST([XORG_CORE_LIBS]) xorg_bus_linuxpci=no @@ -1295,7 +1308,7 @@ AC_MSG_RESULT([$XPRINT]) if test "x$XPRINT" = xyes; then PKG_CHECK_MODULES([XPRINT], [printproto x11 xfont $XDMCP_MODULES xau]) XPRINT_EXTENSIONS="$XEXT_LIB $DBE_LIB $XTRAP_LIB $RECORD_LIB $RENDER_LIB $COMPOSITE_LIB $RANDR_LIB $XI_LIB $FIXES_LIB $DAMAGE_LIB $XI_LIB $GLX_LIBS" - XPRINT_LIBS="$XPRINT_LIBS $DIX_LIB $XKB_LIB $XKB_STUB_LIB $XPRINT_EXTENSIONS $MI_LIB $MIEXT_DAMAGE_LIB $CWRAP_LIB $OS_LIB" + XPRINT_LIBS="$XPRINT_LIBS $DIX_LIB $CONFIG_LIB $XKB_LIB $XKB_STUB_LIB $XPRINT_EXTENSIONS $MI_LIB $MIEXT_DAMAGE_LIB $CWRAP_LIB $OS_LIB" AC_SUBST([XPRINT_CFLAGS]) AC_SUBST([XPRINT_LIBS]) @@ -1451,7 +1464,7 @@ if test "$KDRIVE" = yes; then KDRIVE_LIB='$(top_builddir)/hw/kdrive/src/libkdrive.a' KDRIVE_OS_LIB='$(top_builddir)/hw/kdrive/linux/liblinux.a' KDRIVE_STUB_LIB='$(top_builddir)/hw/kdrive/src/libkdrivestubs.a' - KDRIVE_LIBS="$DIX_LIB $KDRIVE_LIB $KDRIVE_OS_LIB $KDRIVE_PURE_LIBS $KDRIVE_STUB_LIB" + KDRIVE_LIBS="$DIX_LIB $CONFIG_LIB $KDRIVE_LIB $KDRIVE_OS_LIB $KDRIVE_PURE_LIBS $KDRIVE_STUB_LIB" # check if we can build Xephyr PKG_CHECK_MODULES(XEPHYR, x11 xext xfont xau xdmcp, [xephyr="yes"], [xephyr="no"]) @@ -1630,6 +1643,7 @@ XTrap/Makefile mfb/Makefile cfb/Makefile cfb32/Makefile +config/Makefile mi/Makefile miext/Makefile miext/damage/Makefile diff --git a/dix/dispatch.c b/dix/dispatch.c index 72d49950b..066b608f2 100644 --- a/dix/dispatch.c +++ b/dix/dispatch.c @@ -103,6 +103,7 @@ int ProcInitialConnection(); #include "dispatch.h" #include "swaprep.h" #include "swapreq.h" +#include "config.h" #ifdef PANORAMIX #include "panoramiX.h" #include "panoramiXsrv.h" @@ -385,6 +386,9 @@ Dispatch(void) nready = WaitForSomething(clientReady); + /* this is an enormous hack and NEEDS TO GO AWAY. */ + configDispatch(); + #ifdef SMART_SCHEDULE if (nready && !SmartScheduleDisable) { diff --git a/dix/main.c b/dix/main.c index 9d66a4fa8..5f539895e 100644 --- a/dix/main.c +++ b/dix/main.c @@ -101,6 +101,7 @@ Equipment Corporation. #include #include "opaque.h" #include "servermd.h" +#include "config.h" #include "site.h" #include "dixfont.h" #include "extnsionst.h" @@ -311,6 +312,7 @@ main(int argc, char *argv[], char *envp[]) DPMSPowerLevel = 0; #endif InitBlockAndWakeupHandlers(); + configInitialise(); /* Perform any operating system dependent initializations you'd like */ OsInit(); if(serverGeneration == 1) @@ -463,6 +465,7 @@ main(int argc, char *argv[], char *envp[]) FreeAllResources(); #endif + configFini(); CloseDownDevices(); for (i = screenInfo.numScreens - 1; i >= 0; i--) { diff --git a/include/config.h b/include/config.h new file mode 100644 index 000000000..0c304b15e --- /dev/null +++ b/include/config.h @@ -0,0 +1,31 @@ +/* + * Copyright © 2006 Daniel Stone + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of the copyright holders and/or authors + * not be used in advertising or publicity pertaining to distribution of the + * software without specific, written prior permission. The copyright holders + * and/or authors make no representations about the suitability of this + * software for any purpose. It is provided "as is" without express or + * implied warranty. + * + * THE COPYRIGHT HOLDERS AND/OR AUTHORS DISCLAIM ALL WARRANTIES WITH REGARD + * TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS AND/OR AUTHORS BE LIABLE + * FOR 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. + */ + +#ifndef CONFIG_H +#define CONFIG_H + +void configInitialise(void); +void configFini(void); +void configDispatch(void); + +#endif /* CONFIG_H */ diff --git a/include/dix-config.h.in b/include/dix-config.h.in index 2b9f273d7..72a329c03 100644 --- a/include/dix-config.h.in +++ b/include/dix-config.h.in @@ -436,4 +436,7 @@ /* Define to 1 if modules should avoid the libcwrapper */ #undef NO_LIBCWRAPPER +/* Support D-BUS */ +#undef HAVE_DBUS + #endif /* _DIX_CONFIG_H_ */ diff --git a/include/input.h b/include/input.h index e32182d4c..3e00be671 100644 --- a/include/input.h +++ b/include/input.h @@ -163,6 +163,12 @@ extern void ResetDevicePrivateIndex(void); extern KeybdCtrl defaultKeyboardControl; extern PtrCtrl defaultPointerControl; +typedef struct _InputOption { + char *key; + char *value; + struct _InputOption *next; +} InputOption; + extern DeviceIntPtr AddInputDevice( DeviceProc /*deviceProc*/, Bool /*autoStart*/); @@ -366,4 +372,11 @@ extern void InitInput( int /*argc*/, char ** /*argv*/); +/* Implemented by the DDX. */ +extern int NewInputDeviceRequest( + InputOption *options); + +extern DeviceIntPtr LookupDeviceIntRec( + CARD8 deviceid); + #endif /* INPUT_H */ diff --git a/include/os.h b/include/os.h index e16839c74..d459e9e2f 100644 --- a/include/os.h +++ b/include/os.h @@ -149,6 +149,10 @@ extern void CheckConnections(void); extern void CloseDownConnection(ClientPtr /*client*/); +extern void AddGeneralSocket(int /*fd*/); + +extern void RemoveGeneralSocket(int /*fd*/); + extern void AddEnabledDevice(int /*fd*/); extern void RemoveEnabledDevice(int /*fd*/); diff --git a/os/connection.c b/os/connection.c index ce765665f..7648a52ca 100644 --- a/os/connection.c +++ b/os/connection.c @@ -1014,16 +1014,22 @@ CloseDownConnection(ClientPtr client) } _X_EXPORT void -AddEnabledDevice(int fd) +AddGeneralSocket(int fd) { - FD_SET(fd, &EnabledDevices); FD_SET(fd, &AllSockets); if (GrabInProgress) FD_SET(fd, &SavedAllSockets); } _X_EXPORT void -RemoveEnabledDevice(int fd) +AddEnabledDevice(int fd) +{ + FD_SET(fd, &EnabledDevices); + AddGeneralSocket(fd); +} + +_X_EXPORT void +RemoveGeneralSocket(int fd) { FD_CLR(fd, &EnabledDevices); FD_CLR(fd, &AllSockets); @@ -1031,6 +1037,13 @@ RemoveEnabledDevice(int fd) FD_CLR(fd, &SavedAllSockets); } +_X_EXPORT void +RemoveEnabledDevice(int fd) +{ + FD_CLR(fd, &EnabledDevices); + RemoveGeneralSocket(fd); +} + /***************** * OnlyListenToOneClient: * Only accept requests from one client. Continue to handle new From c9a3d9baa81ceb940032ffe529d9eadf2d202ab2 Mon Sep 17 00:00:00 2001 From: Daniel Stone Date: Wed, 19 Jul 2006 11:41:16 -0400 Subject: [PATCH 02/87] xorg DDX: implement NewInputDeviceRequest MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Implement NewInputDeviceRequest for Xorg, mainly written by Kristian Høgsberg. Move MatchInput to xf86Helper.c, as xf86LookupInputDriver. --- hw/xfree86/common/xf86Helper.c | 13 ++++++ hw/xfree86/common/xf86InPriv.h | 3 ++ hw/xfree86/common/xf86Init.c | 17 +------- hw/xfree86/common/xf86Xinput.c | 76 ++++++++++++++++++++++++++++++++++ 4 files changed, 93 insertions(+), 16 deletions(-) diff --git a/hw/xfree86/common/xf86Helper.c b/hw/xfree86/common/xf86Helper.c index ebc460f30..05ac5709c 100644 --- a/hw/xfree86/common/xf86Helper.c +++ b/hw/xfree86/common/xf86Helper.c @@ -142,6 +142,19 @@ xf86DeleteInputDriver(int drvIndex) xf86InputDriverList[drvIndex] = NULL; } +InputDriverPtr +xf86LookupInputDriver(const char *name) +{ + int i; + + for (i = 0; i < xf86NumInputDrivers; i++) { + if (xf86InputDriverList[i] && xf86InputDriverList[i]->driverName && + xf86NameCmp(name, xf86InputDriverList[i]->driverName) == 0) + return xf86InputDriverList[i]; + } + return NULL; +} + _X_EXPORT void xf86AddModuleInfo(ModuleInfoPtr info, pointer module) { diff --git a/hw/xfree86/common/xf86InPriv.h b/hw/xfree86/common/xf86InPriv.h index a14e9e7bb..940e8ba1c 100644 --- a/hw/xfree86/common/xf86InPriv.h +++ b/hw/xfree86/common/xf86InPriv.h @@ -41,4 +41,7 @@ extern int xf86NumInputDrivers; /* xf86Xinput.c */ void xf86ActivateDevice(InputInfoPtr pInfo); +/* xf86Helper.c */ +InputDriverPtr xf86LookupInputDriver(const char *name); + #endif /* _xf86InPriv_h */ diff --git a/hw/xfree86/common/xf86Init.c b/hw/xfree86/common/xf86Init.c index 993918426..6defa9465 100644 --- a/hw/xfree86/common/xf86Init.c +++ b/hw/xfree86/common/xf86Init.c @@ -985,21 +985,6 @@ InitOutput(ScreenInfo *pScreenInfo, int argc, char **argv) NULL); } - -static InputDriverPtr -MatchInput(IDevPtr pDev) -{ - int i; - - for (i = 0; i < xf86NumInputDrivers; i++) { - if (xf86InputDriverList[i] && xf86InputDriverList[i]->driverName && - xf86NameCmp(pDev->driver, xf86InputDriverList[i]->driverName) == 0) - return xf86InputDriverList[i]; - } - return NULL; -} - - /* * InitInput -- * Initialize all supported input devices. @@ -1033,7 +1018,7 @@ InitInput(argc, argv) } #endif - if ((pDrv = MatchInput(pDev)) == NULL) { + if ((pDrv = xf86LookupInputDriver(pDev->driver)) == NULL) { xf86Msg(X_ERROR, "No Input driver matching `%s'\n", pDev->driver); /* XXX For now, just continue. */ continue; diff --git a/hw/xfree86/common/xf86Xinput.c b/hw/xfree86/common/xf86Xinput.c index a931a5d60..329dcba98 100644 --- a/hw/xfree86/common/xf86Xinput.c +++ b/hw/xfree86/common/xf86Xinput.c @@ -622,6 +622,82 @@ ChangeDeviceControl (ClientPtr client, DeviceIntPtr dev, xDeviceCtl *control) } #endif +int +NewInputDeviceRequest (InputOption *options) +{ + IDevRec *idev = NULL; + InputDriverPtr drv = NULL; + InputInfoPtr pInfo = NULL; + InputOption *option = NULL; + DeviceIntPtr dev = NULL; + int i; + + idev = xcalloc(sizeof(*idev), 1); + if (!idev) + return BadAlloc; + + for (option = options; option; option = option->next) { + if (strcmp(option->key, "driver") == 0) { + if (!xf86LoadOneModule(option->value, NULL)) + return BadName; + drv = xf86LookupInputDriver(option->value); + if (!drv) { + xf86Msg(X_ERROR, "No input driver matching `%s'\n", + option->value); + return BadName; + } + idev->driver = xstrdup(option->value); + if (!idev->driver) { + xfree(idev); + return BadAlloc; + } + } + if (strcmp(option->key, "name") == 0 || + strcmp(option->key, "identifier") == 0) { + idev->identifier = xstrdup(option->value); + if (!idev->identifier) { + xfree(idev); + return BadAlloc; + } + } + } + + if (!drv->PreInit) { + xf86Msg(X_ERROR, + "Input driver `%s' has no PreInit function (ignoring)\n", + drv->driverName); + return BadImplementation; + } + + idev->commonOptions = NULL; + for (option = options; option; option = option->next) + idev->commonOptions = xf86addNewOption(idev->commonOptions, + option->key, option->value); + idev->extraOptions = NULL; + + pInfo = drv->PreInit(drv, idev, 0); + + if (!pInfo) { + xf86Msg(X_ERROR, "PreInit returned NULL for \"%s\"\n", idev->identifier); + return BadMatch; + } + else if (!(pInfo->flags & XI86_CONFIGURED)) { + xf86Msg(X_ERROR, "PreInit failed for input device \"%s\"\n", + idev->identifier); + xf86DeleteInput(pInfo, 0); + return BadMatch; + } + + xf86ActivateDevice(pInfo); + + dev = pInfo->dev; + dev->inited = ((*dev->deviceProc)(dev, DEVICE_INIT) == Success); + if (dev->inited && dev->startup) + EnableDevice(dev); + + return Success; +} + /* * adapted from mieq.c to support extended events * From b308dbf273f8c26361b0fee7aca64aec3245f60b Mon Sep 17 00:00:00 2001 From: Daniel Stone Date: Wed, 19 Jul 2006 12:15:18 -0400 Subject: [PATCH 03/87] add DEVICE_TOUCHSCREEN and DEVICE_CORE Xi controls (DeviceIntRec ABI break) Add DEVICE_TOUCHSCREEN and DEVICE_CORE controls to the Xi code, and the TouchscreenClassRec and a coreEvents flag, to toggle propagation of core events. --- Xi/chgdctl.c | 50 +++++++++++++++++++++++++++++++++++++++ Xi/getdctl.c | 59 ++++++++++++++++++++++++++++++++++++++++++++++ Xi/getdctl.h | 10 ++++++++ Xi/stubs.c | 4 ++++ include/inputstr.h | 10 ++++++++ 5 files changed, 133 insertions(+) diff --git a/Xi/chgdctl.c b/Xi/chgdctl.c index d507513a9..ebe086548 100644 --- a/Xi/chgdctl.c +++ b/Xi/chgdctl.c @@ -104,6 +104,8 @@ ProcXChangeDeviceControl(ClientPtr client) xChangeDeviceControlReply rep; AxisInfoPtr a; CARD32 *resolution; + xDeviceTSCtl *ts; + xDeviceCoreCtl *c; REQUEST(xChangeDeviceControlReq); REQUEST_AT_LEAST_SIZE(xChangeDeviceControlReq); @@ -168,6 +170,54 @@ ProcXChangeDeviceControl(ClientPtr client) return Success; } break; + case DEVICE_TOUCHSCREEN: + ts = (xDeviceTSCtl *)&stuff[1]; + + if (ts->button_threshold < 0 || ts->button_threshold > 255) { + SendErrorToClient(client, IReqCode, X_ChangeDeviceControl, 0, + BadValue); + return Success; + } + + status = ChangeDeviceControl(client, dev, (xDeviceCtl *) ts); + + if (status == Success) { + dev->touchscreen->min_x = ts->min_x; + dev->touchscreen->max_x = ts->max_x; + dev->touchscreen->min_y = ts->min_y; + dev->touchscreen->max_y = ts->max_y; + dev->touchscreen->button_threshold = ts->button_threshold; + } else if (status == DeviceBusy) { + rep.status = DeviceBusy; + WriteReplyToClient(client, sizeof(xChangeDeviceControlReply), + &rep); + return Success; + } else { + SendErrorToClient(client, IReqCode, X_ChangeDeviceControl, 0, + BadMatch); + return Success; + } + + break; + case DEVICE_CORE: + c = (xDeviceCoreCtl *)&stuff[1]; + + status = ChangeDeviceControl(client, dev, (xDeviceCtl *) c); + + if (status == Success) { + dev->coreEvents = c->status; + } else if (status == DeviceBusy) { + rep.status = DeviceBusy; + WriteReplyToClient(client, sizeof(xChangeDeviceControlReply), + &rep); + return Success; + } else { + SendErrorToClient(client, IReqCode, X_ChangeDeviceControl, 0, + BadMatch); + return Success; + } + + break; default: SendErrorToClient(client, IReqCode, X_ChangeDeviceControl, 0, BadValue); return Success; diff --git a/Xi/getdctl.c b/Xi/getdctl.c index c2b69fd71..66342b340 100644 --- a/Xi/getdctl.c +++ b/Xi/getdctl.c @@ -124,6 +124,18 @@ ProcXGetDeviceControl(ClientPtr client) total_length = sizeof(xDeviceResolutionState) + (3 * sizeof(int) * dev->valuator->numAxes); break; + case DEVICE_TOUCHSCREEN: + if (!dev->touchscreen) { + SendErrorToClient(client, IReqCode, X_GetDeviceControl, 0, + BadMatch); + return Success; + } + + total_length = sizeof(xDeviceTSCtl); + break; + case DEVICE_CORE: + total_length = sizeof(xDeviceCoreCtl); + break; default: SendErrorToClient(client, IReqCode, X_GetDeviceControl, 0, BadValue); return Success; @@ -140,6 +152,11 @@ ProcXGetDeviceControl(ClientPtr client) case DEVICE_RESOLUTION: CopySwapDeviceResolution(client, dev->valuator, buf, total_length); break; + case DEVICE_TOUCHSCREEN: + CopySwapDeviceTouchscreen(client, dev->touchscreen, buf); + break; + case DEVICE_CORE: + CopySwapDeviceCore(client, dev, buf); default: break; } @@ -189,6 +206,48 @@ CopySwapDeviceResolution(ClientPtr client, ValuatorClassPtr v, char *buf, } } +void CopySwapDeviceTouchscreen (ClientPtr client, TouchscreenClassPtr dts, + char *buf) +{ + register char n; + xDeviceTSState *ts = (xDeviceTSState *) buf; + + ts->control = DEVICE_TOUCHSCREEN; + ts->length = sizeof(ts); + ts->min_x = dts->min_x; + ts->max_x = dts->max_x; + ts->min_y = dts->min_y; + ts->max_y = dts->max_y; + ts->button_threshold = dts->button_threshold; + + if (client->swapped) { + swaps(&ts->control, n); + swaps(&ts->length, n); + swapl(&ts->min_x, n); + swapl(&ts->max_x, n); + swapl(&ts->min_y, n); + swapl(&ts->max_y, n); + swapl(&ts->button_threshold, n); + } +} + +void CopySwapDeviceCore (ClientPtr client, DeviceIntPtr dev, char *buf) +{ + register char n; + xDeviceCoreState *c = (xDeviceCoreState *) buf; + + c->control = DEVICE_CORE; + c->length = sizeof(c); + c->status = dev->coreEvents; + + if (client->swapped) { + swaps(&c->control, n); + swaps(&c->length, n); + swaps(&c->status, n); + } +} + + /*********************************************************************** * * This procedure writes the reply for the xGetDeviceControl function, diff --git a/Xi/getdctl.h b/Xi/getdctl.h index c7cfb19d2..1417d1b38 100644 --- a/Xi/getdctl.h +++ b/Xi/getdctl.h @@ -42,6 +42,16 @@ void CopySwapDeviceResolution(ClientPtr /* client */ , int /* length */ ); +void CopySwapDeviceTouchscreen(ClientPtr /* client */ , + TouchscreenClassPtr /* ts */ , + char * /* buf */ + ); + +void CopySwapDeviceCore(ClientPtr /* client */ , + DeviceIntPtr /* dev */ , + char * /* buf */ + ); + void SRepXGetDeviceControl(ClientPtr /* client */ , int /* size */ , xGetDeviceControlReply * /* rep */ diff --git a/Xi/stubs.c b/Xi/stubs.c index 6b9e682b9..90aeddbc7 100644 --- a/Xi/stubs.c +++ b/Xi/stubs.c @@ -287,6 +287,10 @@ ChangeDeviceControl(register ClientPtr client, DeviceIntPtr dev, switch (control->control) { case DEVICE_RESOLUTION: return (BadMatch); + case DEVICE_TOUCHSCREEN: + return (BadMatch); + case DEVICE_CORE: + return (BadMatch); default: return (BadMatch); } diff --git a/include/inputstr.h b/include/inputstr.h index b54e8a1d5..5c294975a 100644 --- a/include/inputstr.h +++ b/include/inputstr.h @@ -177,6 +177,14 @@ typedef struct _ProximityClassRec { char pad; } ProximityClassRec, *ProximityClassPtr; +typedef struct _TouchscreenClassRec { + int min_x; + int max_x; + int min_y; + int max_y; + int button_threshold; +} TouchscreenClassRec, *TouchscreenClassPtr; + typedef struct _KbdFeedbackClassRec *KbdFeedbackPtr; typedef struct _PtrFeedbackClassRec *PtrFeedbackPtr; typedef struct _IntegerFeedbackClassRec *IntegerFeedbackPtr; @@ -250,6 +258,7 @@ typedef struct _DeviceIntRec { used to initialize, turn on, or turn off the device */ Bool inited; /* TRUE if INIT returns Success */ + Bool coreEvents; /* TRUE if device also sends core */ GrabPtr grab; /* the grabber - used by DIX */ struct { Bool frozen; @@ -276,6 +285,7 @@ typedef struct _DeviceIntRec { ButtonClassPtr button; FocusClassPtr focus; ProximityClassPtr proximity; + TouchscreenClassPtr touchscreen; KbdFeedbackPtr kbdfeed; PtrFeedbackPtr ptrfeed; IntegerFeedbackPtr intfeed; From a274e7296b1bdd6f6c921f28b087610cec9548e0 Mon Sep 17 00:00:00 2001 From: Daniel Stone Date: Wed, 19 Jul 2006 13:56:23 -0400 Subject: [PATCH 04/87] add GetPointerEvents/GetKeyboardEvents framework Add GetPointerEvents (with XFree86 pointer acceleration) and GetKeyboardEvents to the DIX. Extend the ValuatorClass structure to account for same. --- dix/devices.c | 4 + dix/events.c | 401 +++++++++++++++++++++++++++++++++++++++++++++ include/input.h | 26 +++ include/inputstr.h | 7 + 4 files changed, 438 insertions(+) diff --git a/dix/devices.c b/dix/devices.c index 40afac96f..37720f3b7 100644 --- a/dix/devices.c +++ b/dix/devices.c @@ -611,6 +611,10 @@ InitValuatorClassDeviceStruct(DeviceIntPtr dev, int numAxes, valc->axisVal = (int *)(valc->axes + numAxes); for (i=0; iaxisVal[i]=0; + valc->lastx = 0; + valc->lasty = 0; + valc->dxremaind = 0; + valc->dyremaind = 0; dev->valuator = valc; return TRUE; } diff --git a/dix/events.c b/dix/events.c index 479b4d80c..1b0aee5fb 100644 --- a/dix/events.c +++ b/dix/events.c @@ -157,6 +157,7 @@ xEvent *xeviexE; #endif #include +#include "exglobals.h" #include "exevents.h" #include "extnsionst.h" @@ -164,6 +165,8 @@ xEvent *xeviexE; #include "dixgrabs.h" #include "dispatch.h" +int CoreDevicePrivatesIndex = 0, CoreDevicePrivatesGeneration = -1; + #define EXTENSION_EVENT_BASE 64 #define NoSuchEvent 0x80000000 /* so doesn't match NoEventMask */ @@ -4660,3 +4663,401 @@ WriteEventsToClient(ClientPtr pClient, int count, xEvent *events) (void)WriteToClient(pClient, count * sizeof(xEvent), (char *) events); } } + +int +GetKeyboardEvents(xEvent **xE, DeviceIntPtr pDev, int type, int key_code) { + return GetKeyboardValuatorEvents(xE, pDev, type, key_code, 0, NULL); +} + +int GetKeyboardValuatorEvents(xEvent **xE, DeviceIntPtr pDev, int type, + int key_code, int num_valuators, + int *valuators) { + int numEvents = 0, ms = 0, first_valuator = 0; + deviceKeyButtonPointer *kbp = NULL; + deviceValuator *xv = NULL; + xEvent *ev = NULL; + KeyClassPtr ckeyc; +#ifdef XKB + xkbNewKeyboardNotify nkn; +#endif + + if (type != KeyPress && type != KeyRelease) + return 0; + + if (!pDev->key || !pDev->focus || + (pDev->coreEvents && !inputInfo.keyboard->key)) + return 0; + + if (pDev->coreEvents) + numEvents = 2; + else + numEvents = 1; + + if (num_valuators) + numEvents += (num_valuators % 6) + 1; + + ev = (xEvent *)xcalloc(sizeof(xEvent), numEvents); + if (!ev) + return 0; + + *xE = ev; + ms = GetTimeInMillis(); + + kbp = (deviceKeyButtonPointer *) ev; + kbp->time = ms; + kbp->deviceid = pDev->id; + if (type == KeyPress) + kbp->type = DeviceKeyPress; + else if (type == KeyRelease) + kbp->type = DeviceKeyRelease; + + if (num_valuators) { + kbp->deviceid |= MORE_EVENTS; + while (first_valuator < num_valuators) { + xv = (deviceValuator *) ++ev; + xv->type = DeviceValuator; + xv->first_valuator = first_valuator; + xv->num_valuators = num_valuators; + xv->deviceid = kbp->deviceid; + switch (num_valuators - first_valuator) { + case 6: + xv->valuator5 = valuators[first_valuator+5]; + case 5: + xv->valuator4 = valuators[first_valuator+4]; + case 4: + xv->valuator3 = valuators[first_valuator+3]; + case 3: + xv->valuator2 = valuators[first_valuator+2]; + case 2: + xv->valuator1 = valuators[first_valuator+1]; + case 1: + xv->valuator0 = valuators[first_valuator]; + } + first_valuator += 6; + } +#ifdef DEBUG + ErrorF("GKVE: DV event with %d valuators\n", xv->num_valuators); +#endif + } + + if (pDev->coreEvents) { + ev++; + ev->u.keyButtonPointer.time = ms; + ev->u.u.type = type; + ev->u.u.detail = key_code; + + if (inputInfo.keyboard->devPrivates[CoreDevicePrivatesIndex].ptr != + pDev) { + ckeyc = inputInfo.keyboard->key; + memcpy(ckeyc->modifierMap, pDev->key->modifierMap, MAP_LENGTH); + if (ckeyc->modifierKeyMap) + xfree(ckeyc->modifierKeyMap); + ckeyc->modifierKeyMap = xalloc(8 * pDev->key->maxKeysPerModifier); + memcpy(ckeyc->modifierKeyMap, pDev->key->modifierKeyMap, + (8 * pDev->key->maxKeysPerModifier)); + ckeyc->maxKeysPerModifier = pDev->key->maxKeysPerModifier; + ckeyc->curKeySyms.map = NULL; + ckeyc->curKeySyms.mapWidth = 0; + ckeyc->curKeySyms.minKeyCode = pDev->key->curKeySyms.minKeyCode; + ckeyc->curKeySyms.maxKeyCode = pDev->key->curKeySyms.maxKeyCode; + SetKeySymsMap(&ckeyc->curKeySyms, &pDev->key->curKeySyms); +#ifdef XKB + if (!noXkbExtension) { + nkn.oldMinKeyCode = ckeyc->xkbInfo->desc->min_key_code; + nkn.oldMaxKeyCode = ckeyc->xkbInfo->desc->max_key_code; + nkn.deviceID = nkn.oldDeviceID = inputInfo.keyboard->id; + nkn.minKeyCode = pDev->key->xkbInfo->desc->min_key_code; + nkn.maxKeyCode = pDev->key->xkbInfo->desc->max_key_code; + nkn.requestMajor = XkbReqCode; + nkn.requestMinor = X_kbSetMap; /* XXX bare-faced lie */ + nkn.changed = XkbAllNewKeyboardEventsMask; + /* Free the map we set up at DEVICE_INIT time, since it's + * going to just quietly disappear. Shameful hack. */ + if (!inputInfo.keyboard->devPrivates[CoreDevicePrivatesIndex].ptr + && ckeyc->xkbInfo) + XkbFreeInfo(ckeyc->xkbInfo); + ckeyc->xkbInfo = pDev->key->xkbInfo; + /* FIXME OH MY GOD SO AWFUL let's hope nobody notices */ + if (nkn.oldMinKeyCode == nkn.minKeyCode) + nkn.oldMinKeyCode--; + if (nkn.oldMaxKeyCode == nkn.maxKeyCode) + nkn.oldMaxKeyCode++; + XkbSendNewKeyboardNotify(inputInfo.keyboard, &nkn); + } +#endif + SendMappingNotify(MappingKeyboard, ckeyc->curKeySyms.minKeyCode, + (ckeyc->curKeySyms.maxKeyCode - + ckeyc->curKeySyms.minKeyCode), + serverClient); + inputInfo.keyboard->devPrivates[CoreDevicePrivatesIndex].ptr = pDev; + } + } + +#ifdef DEBUG + ErrorF("GKE: putting out %d events with detail %d\n", numEvents, key_code); +#endif + + return numEvents; +} + +/* Originally a part of xf86PostMotionEvent. */ +static void +acceleratePointer(DeviceIntPtr pDev, int num_valuators, int *valuators) +{ + float mult = 0.0; + int dx = num_valuators >= 1 ? valuators[0] : 0; + int dy = num_valuators >= 2 ? valuators[1] : 0; + + if (!num_valuators || !valuators) + return; + + /* + * Accelerate + */ + if (pDev->ptrfeed && pDev->ptrfeed->ctrl.num) { + /* modeled from xf86Events.c */ + if (pDev->ptrfeed->ctrl.threshold) { + if ((abs(dx) + abs(dy)) >= pDev->ptrfeed->ctrl.threshold) { + pDev->valuator->dxremaind = ((float)dx * + (float)(pDev->ptrfeed->ctrl.num)) / + (float)(pDev->ptrfeed->ctrl.den) + + pDev->valuator->dxremaind; + valuators[0] = (int)pDev->valuator->dxremaind; + pDev->valuator->dxremaind = pDev->valuator->dxremaind - + (float)valuators[0]; + + pDev->valuator->dyremaind = ((float)dy * + (float)(pDev->ptrfeed->ctrl.num)) / + (float)(pDev->ptrfeed->ctrl.den) + + pDev->valuator->dyremaind; + valuators[1] = (int)pDev->valuator->dyremaind; + pDev->valuator->dyremaind = pDev->valuator->dyremaind - + (float)valuators[1]; + } + } + else if (dx || dy) { + mult = pow((float)(dx * dx + dy * dy), + ((float)(pDev->ptrfeed->ctrl.num) / + (float)(pDev->ptrfeed->ctrl.den) - 1.0) / + 2.0) / 2.0; + if (dx) { + pDev->valuator->dxremaind = mult * (float)dx + + pDev->valuator->dxremaind; + valuators[0] = (int)pDev->valuator->dxremaind; + pDev->valuator->dxremaind = pDev->valuator->dxremaind - + (float)valuators[0]; + } + if (dy) { + pDev->valuator->dyremaind = mult * (float)dy + + pDev->valuator->dyremaind; + valuators[1] = (int)pDev->valuator->dyremaind; + pDev->valuator->dyremaind = pDev->valuator->dyremaind - + (float)valuators[1]; + } + } + } +} + +int +GetPointerEvents(xEvent **xE, DeviceIntPtr pDev, int type, int buttons, + int flags, int num_valuators, int *valuators) { + int numEvents, ms, first_valuator = 0; + deviceKeyButtonPointer *kbp = NULL; + deviceValuator *xv = NULL; + AxisInfoPtr axes = NULL; + xEvent *ev = NULL; + DeviceIntPtr cp = inputInfo.pointer; + + if (type != MotionNotify && type != ButtonPress && type != ButtonRelease) + return 0; + + if (!pDev->button || (pDev->coreEvents && !(cp->button || !cp->valuator))) + return 0; + +#ifdef DEBUG + ErrorF("GPE: called with device %d, type %d\n", pDev->id, type); + ErrorF("GPE: relative %s, accelerate %s\n", flags & POINTER_RELATIVE ? "yes" : "no", + flags & POINTER_ACCELERATE ? "yes" : "no"); +#endif + + if (pDev->coreEvents) + numEvents = 2; + else + numEvents = 1; + + if (type == MotionNotify) { + if (num_valuators > 2) + numEvents += (num_valuators / 6) + 1; + else if (num_valuators < 2) + return 0; + } + + ev = (xEvent *)xcalloc(sizeof(xEvent), numEvents); + if (!ev) + return 0; + + *xE = ev; + ms = GetTimeInMillis(); + + kbp = (deviceKeyButtonPointer *) ev; + kbp->time = ms; + kbp->deviceid = pDev->id; + + if (flags & POINTER_ABSOLUTE) { + if (num_valuators >= 1) { + kbp->root_x = valuators[0]; + } + else { + if (pDev->coreEvents) + kbp->root_x = cp->valuator->lastx; + else + kbp->root_x = pDev->valuator->lastx; + } + if (num_valuators >= 2) { + kbp->root_y = valuators[1]; + } + else { + if (pDev->coreEvents) + kbp->root_x = cp->valuator->lasty; + else + kbp->root_y = pDev->valuator->lasty; + } + } + else { + if (flags & POINTER_ACCELERATE) + acceleratePointer(pDev, num_valuators, valuators); + + if (pDev->coreEvents) { + if (num_valuators >= 1) + kbp->root_x = cp->valuator->lastx + valuators[0]; + else + kbp->root_x = cp->valuator->lastx; + if (num_valuators >= 2) + kbp->root_y = cp->valuator->lasty + valuators[1]; + else + kbp->root_y = cp->valuator->lasty; + } + else { + if (num_valuators >= 1) + kbp->root_x = pDev->valuator->lastx + valuators[0]; + else + kbp->root_x = pDev->valuator->lastx; + if (num_valuators >= 2) + kbp->root_y = pDev->valuator->lasty + valuators[1]; + else + kbp->root_y = pDev->valuator->lasty; + } + } + + /* FIXME: need mipointer-like semantics to move on to different screens. */ + axes = pDev->valuator->axes; + if (kbp->root_x < axes->min_value) + kbp->root_x = axes->min_value; + if (kbp->root_x > axes->max_value) + kbp->root_x = axes->max_value; + axes++; + if (kbp->root_y < axes->min_value) + kbp->root_y = axes->min_value; + if (kbp->root_y > axes->max_value) + kbp->root_y = axes->max_value; + + if (pDev->coreEvents) { +#ifdef DEBUG + ErrorF("warping core lastx from %d to %d\n", cp->valuator->lastx, kbp->root_x); + ErrorF("x value given was %d\n", valuators[0]); +#endif + cp->valuator->lastx = kbp->root_x; +#ifdef DEBUG + ErrorF("warping core lasty from %d to %d\n", cp->valuator->lasty, kbp->root_y); + ErrorF("y value given was %d\n", valuators[1]); +#endif + cp->valuator->lasty = kbp->root_y; + } + pDev->valuator->lastx = kbp->root_x; + pDev->valuator->lasty = kbp->root_y; + + if (type == MotionNotify) { + kbp->type = DeviceMotionNotify; +#ifdef DEBUG + ErrorF("GPE: motion at %d, %d\n", kbp->root_x, kbp->root_y); +#endif + } + else { + if (type == ButtonPress) + kbp->type = DeviceButtonPress; + else if (type == ButtonRelease) + kbp->type = DeviceButtonRelease; +#ifdef DEBUG + ErrorF("GPE: detail is %d\n", buttons); +#endif + kbp->detail = buttons; + } + + /* XXX: the spec says that Device{Key,Button}{Press,Release} events + * for relative devices shouldn't contain valuators since only the + * state field will have meaning, but I don't see why. */ + if (num_valuators > 2 && (type == MotionNotify || + flags & POINTER_ABSOLUTE)) { + kbp->deviceid |= MORE_EVENTS; + while (first_valuator < num_valuators) { + xv = (deviceValuator *) ++ev; + xv->type = DeviceValuator; + xv->first_valuator = first_valuator; + xv->num_valuators = num_valuators; + xv->deviceid = kbp->deviceid; + switch (num_valuators - first_valuator) { + case 6: + xv->valuator5 = valuators[first_valuator+5]; + case 5: + xv->valuator4 = valuators[first_valuator+4]; + case 4: + xv->valuator3 = valuators[first_valuator+3]; + case 3: + xv->valuator2 = valuators[first_valuator+2]; + case 2: + if (first_valuator == 0) + xv->valuator1 = kbp->root_y; + else + xv->valuator1 = valuators[first_valuator+1]; + case 1: + if (first_valuator == 0) + xv->valuator0 = kbp->root_x; + else + xv->valuator0 = valuators[first_valuator]; + } + first_valuator += 6; + } +#ifdef DEBUG + ErrorF("GPE: DV event with %d valuators\n", xv->num_valuators); +#endif + } + + if (pDev->coreEvents) { + ev++; + ev->u.u.type = type; + ev->u.keyButtonPointer.time = ms; + ev->u.keyButtonPointer.rootX = kbp->root_x; + ev->u.keyButtonPointer.rootY = kbp->root_y; + cp->valuator->lastx = kbp->root_x; + cp->valuator->lasty = kbp->root_y; +#ifdef DEBUG + ErrorF("GPE: core co-ords at %d, %d\n", kbp->root_x, kbp->root_y); +#endif + if (type == ButtonPress || type == ButtonRelease) { +#ifdef DEBUG + ErrorF("GPE: core detail is %d\n", buttons); +#endif + /* Core buttons remapping shouldn't be transitive. */ + ev->u.u.detail = pDev->button->map[buttons]; + } + else { + ev->u.u.detail = 0; + } + + if (inputInfo.pointer->devPrivates[CoreDevicePrivatesIndex].ptr != + pDev) + inputInfo.pointer->devPrivates[CoreDevicePrivatesIndex].ptr = pDev; + } + + return numEvents; +} diff --git a/include/input.h b/include/input.h index 3e00be671..d550bbe97 100644 --- a/include/input.h +++ b/include/input.h @@ -372,6 +372,32 @@ extern void InitInput( int /*argc*/, char ** /*argv*/); +extern int GetPointerEvents( + xEvent **xE, + DeviceIntPtr pDev, + int type, + int buttons, + int flags, + int num_axes, + int *valuators); + +extern int GetKeyboardEvents( + xEvent **xE, + DeviceIntPtr pDev, + int type, + int key_code); + +extern int GetKeyboardValuatorEvents( + xEvent **xE, + DeviceIntPtr pDev, + int type, + int key_code, + int num_axes, + int *valuators); + +extern DeviceIntPtr LookupDeviceIntRec( + CARD8 deviceid); + /* Implemented by the DDX. */ extern int NewInputDeviceRequest( InputOption *options); diff --git a/include/inputstr.h b/include/inputstr.h index 5c294975a..8b877bcbd 100644 --- a/include/inputstr.h +++ b/include/inputstr.h @@ -64,6 +64,10 @@ SOFTWARE. #define EMASKSIZE MAX_DEVICES +#define POINTER_RELATIVE (1 << 1) +#define POINTER_ABSOLUTE (1 << 2) +#define POINTER_ACCELERATE (1 << 3) + /* Kludge: OtherClients and InputClients must be compatible, see code */ typedef struct _OtherClients { @@ -150,6 +154,9 @@ typedef struct _ValuatorClassRec { unsigned short numAxes; int *axisVal; CARD8 mode; + int lastx, lasty; /* last event recorded, not posted to + * client; see dix/devices.c */ + int dxremaind, dyremaind; /* for acceleration */ } ValuatorClassRec, *ValuatorClassPtr; typedef struct _ButtonClassRec { From 02d09105113fb9b560a770fe15f7bb041165831c Mon Sep 17 00:00:00 2001 From: Daniel Stone Date: Wed, 19 Jul 2006 16:51:04 -0400 Subject: [PATCH 05/87] new KDrive input world order Convert KDrive to GPE/GKE interface. Add first-class drivers and enumerate every device separately through Xi, instead of lamely attempting to aggregate them. Add XKB support to the Linux keyboard driver. Add 'thumb button' support to the tslib driver. Rejig InitInput, so each DDX has to add a list of drivers it supports. Support NewInputDeviceRequest, et al. --- configure.ac | 187 ++-- hw/kdrive/Makefile.am | 8 +- hw/kdrive/ati/ati_stub.c | 10 +- hw/kdrive/ephyr/Makefile.am | 1 - hw/kdrive/ephyr/ephyr.c | 158 ++- hw/kdrive/ephyr/ephyr.h | 9 +- hw/kdrive/ephyr/ephyrinit.c | 19 +- hw/kdrive/ephyr/hostx.c | 31 +- hw/kdrive/ephyr/hostx.h | 17 +- hw/kdrive/fake/fake.c | 6 +- hw/kdrive/fake/fake.h | 4 +- hw/kdrive/fake/fakeinit.c | 17 +- hw/kdrive/fake/kbd.c | 56 +- hw/kdrive/fake/mouse.c | 26 +- hw/kdrive/fbdev/Makefile.am | 7 +- hw/kdrive/fbdev/fbdev.c | 6 +- hw/kdrive/fbdev/fbinit.c | 14 +- hw/kdrive/itsy/kbd.c | 51 +- hw/kdrive/itsy/ts.c | 7 +- hw/kdrive/linux/bus.c | 75 +- hw/kdrive/linux/evdev.c | 390 ++++---- hw/kdrive/linux/keyboard.c | 466 +++++++-- hw/kdrive/linux/linux.c | 1 + hw/kdrive/linux/mouse.c | 242 ++--- hw/kdrive/linux/ms.c | 61 +- hw/kdrive/linux/ps2.c | 82 +- hw/kdrive/linux/ts.c | 144 ++- hw/kdrive/linux/tslib.c | 389 ++++---- hw/kdrive/src/Makefile.am | 3 +- hw/kdrive/src/kdrive.c | 174 ++-- hw/kdrive/src/kdrive.h | 237 +++-- hw/kdrive/src/kinfo.c | 77 +- hw/kdrive/src/kinput.c | 1811 +++++++++++++++++++++++++---------- hw/kdrive/src/kkeymap.c | 66 +- hw/kdrive/src/kloadmap.c | 1 - hw/kdrive/vesa/vesa.c | 8 +- hw/kdrive/vesa/vesainit.c | 11 +- hw/kdrive/vxworks/vxkbd.c | 4 +- 38 files changed, 3184 insertions(+), 1692 deletions(-) diff --git a/configure.ac b/configure.ac index 41536f74e..186f2f9a1 100644 --- a/configure.ac +++ b/configure.ac @@ -439,6 +439,9 @@ dnl kdrive and its subsystems AC_ARG_ENABLE(kdrive, AS_HELP_STRING([--enable-kdrive], [Build kdrive servers (default: no)]), [KDRIVE=$enableval], [KDRIVE=no]) AC_ARG_ENABLE(xephyr, AS_HELP_STRING([--enable-xephyr], [Build the kdrive Xephyr server (default: auto)]), [XEPHYR=$enableval], [XEPHYR=auto]) AC_ARG_ENABLE(xsdl, AS_HELP_STRING([--enable-xsdl], [Build the kdrive Xsdl server (default: auto)]), [XSDL=$enableval], [XSDL=auto]) +AC_ARG_ENABLE(xfake, AS_HELP_STRING([--enable-xfake], [Build the kdrive 'fake' server (default: auto)]), [XFAKE=$enableval], [XFAKE=auto]) +AC_ARG_ENABLE(xfbdev, AS_HELP_STRING([--enable-xfbdev], [Build the kdrive framebuffer device server (default: auto)]), [XFBDEV=$enableval], [XFBDEV=auto]) +AC_ARG_ENABLE(kdrive-vesa, AS_HELP_STRING([--enable-kdrive-vesa], [Build the kdrive VESA-based servers (default: auto)]), [KDRIVEVESA=$enableval], [KDRIVEVESA=auto]) dnl xprint AC_ARG_ENABLE(freetype, AS_HELP_STRING([ --enable-freetype], [Build Xprint FreeType backend (default: yes)]), [XP_USE_FREETYPE=$enableval],[XP_USE_FREETYPE=no]) AC_ARG_WITH(freetype-config, AS_HELP_STRING([ --with-freetype-config=PROG], [Use FreeType configuration program PROG (default: auto)]), freetype_config=$withval, freetype_config=auto) @@ -510,7 +513,7 @@ XEXT_LIB='$(top_builddir)/Xext/libXext.la' XEXTXORG_LIB='$(top_builddir)/Xext/libXextbuiltin.la' dnl Core modules for most extensions, et al. -REQUIRED_MODULES="randrproto renderproto [fixesproto >= 4.0] damageproto xcmiscproto xextproto xproto xtrans xf86miscproto xf86vidmodeproto xf86bigfontproto [scrnsaverproto >= 1.1] bigreqsproto resourceproto fontsproto inputproto xf86dgaproto" +REQUIRED_MODULES="randrproto renderproto [fixesproto >= 4.0] damageproto xcmiscproto xextproto xproto xtrans [scrnsaverproto >= 1.1] bigreqsproto resourceproto fontsproto [inputproto >= 1.4]" REQUIRED_LIBS="xfont xau fontenc" if test "x$DBUS" = xauto; then @@ -824,11 +827,35 @@ AC_DEFINE(DDXOSINIT, 1, [Use OsVendorInit]) AC_DEFINE(SERVER_LOCK, 1, [Use a lock to prevent multiple servers on a display]) AC_DEFINE(SMART_SCHEDULE, 1, [Include time-based scheduler]) AC_DEFINE(NO_LIBCWRAPPER, 1, [Define to 1 if modules should avoid the libcwrapper]) -AM_CONDITIONAL(DEBUG, test "x$DEBUGGING" = xyes) -if ! test "x$DEBUGGING" = xyes; then - AC_DEFINE(NDEBUG, 1, [Disable some debugging code]) +if test "x$DEBUGGING" = xyes; then + AC_DEFINE(DEBUG, 1, [Enable debugging code]) +else + AC_DEFINE(NDEBUG, 1, [Disable some debugging code]) fi +AM_CONDITIONAL(DEBUG, [test "x$DEBUGGING" = xyes]) + +# The Xorg binary needs to export symbols so that they can be used from modules +# Some platforms require extra flags to do this. gcc should set these flags +# when -rdynamic is passed to it, other compilers/linkers may need to be added +# here. +if test "x$GCC" = "xyes"; then + GCC_WARNINGS1="-Wall -Wpointer-arith -Wstrict-prototypes" + GCC_WARNINGS2="-Wmissing-prototypes -Wmissing-declarations" + GCC_WARNINGS3="-Wnested-externs -fno-strict-aliasing" + GCC_WARNINGS="$GCC_WARNINGS1 $GCC_WARNINGS2 $GCC_WARNINGS3" + if test "x$WERROR" = "xyes"; then + GCC_WARNINGS="${GCC_WARNINGS} -Werror" + fi + XSERVER_CFLAGS="$GCC_WARNINGS $XSERVER_CFLAGS" + LD_EXPORT_SYMBOLS_FLAG="-rdynamic" +fi +case $host_os in + openbsd*) + LD_EXPORT_SYMBOLS_FLAG="-Wl,--export-dynamic" + ;; +esac +AC_SUBST([LD_EXPORT_SYMBOLS_FLAG]) AC_DEFINE(USE_RGB_TXT, 1, [Use rgb.txt directly]) AC_DEFINE(MITMISC, 1, [Support MIT Misc extension]) @@ -1038,6 +1065,14 @@ if test "x$XORG" = xyes -o "x$XGL" = xyes; then XORG_CFLAGS="$XORGSERVER_CFLAGS -DHAVE_XORG_CONFIG_H" XORG_LIBS="$COMPOSITE_LIB $MI_LIB $FIXES_LIB $XEXTXORG_LIB $GLX_LIBS $RENDER_LIB $RANDR_LIB $DAMAGE_LIB $MIEXT_DAMAGE_LIB $MIEXT_SHADOW_LIB $XI_LIB $XKB_LIB $XPSTUBS_LIB $OS_LIB" + AC_DEFINE(XF86VIDMODE, 1, [Support XFree86 Video Mode extension]) + AC_DEFINE(XF86MISC, 1, [Support XFree86 miscellaneous extensions]) + + XORG_MODULES="xf86miscproto xf86vidmodeproto xf86dgaproto" + PKG_CHECK_MODULES(XORG_MODULES, [$XORG_MODULES]) + XORG_CFLAGS="$XORG_CFLAGS $XORG_MODULES_CFLAGS" + XORG_LIBS="$XORG_LIBS $XORG_MODULES_LIBS" + dnl Check to see if dlopen is in default libraries (like Solaris, which dnl has it in libc), or if libdl is needed to get it. AC_CHECK_FUNC([dlopen], [], @@ -1229,28 +1264,7 @@ int main () { fi AC_SUBST(PERL) - # The Xorg binary needs to export symbols so that they can be used from modules - # Some platforms require extra flags to do this. gcc should set these flags - # when -rdynamic is passed to it, other compilers/linkers may need to be added - # here. - if test "x$GCC" = "xyes"; then - GCC_WARNINGS1="-Wall -Wpointer-arith -Wstrict-prototypes" - GCC_WARNINGS2="-Wmissing-prototypes -Wmissing-declarations" - GCC_WARNINGS3="-Wnested-externs -fno-strict-aliasing" - GCC_WARNINGS="$GCC_WARNINGS1 $GCC_WARNINGS2 $GCC_WARNINGS3" - if test "x$WERROR" = "xyes"; then - GCC_WARNINGS="${GCC_WARNINGS} -Werror" - fi - XSERVER_CFLAGS="$GCC_WARNINGS $XSERVER_CFLAGS" - LD_EXPORT_SYMBOLS_FLAG="-rdynamic" - fi - case $host_os in - openbsd*) - LD_EXPORT_SYMBOLS_FLAG="-Wl,--export-dynamic" - ;; - esac AC_SUBST([XORG_CFLAGS]) - AC_SUBST([LD_EXPORT_SYMBOLS_FLAG]) dnl these only go in xorg-config.h XF86CONFIGFILE="xorg.conf" @@ -1438,16 +1452,58 @@ if test "$KDRIVE" = yes; then AC_DEFINE(KDRIVEDDXACTIONS,,[Build kdrive ddx]) AC_CHECK_HEADERS([sys/vm86.h sys/io.h]) - if test "$ac_cv_header_sys_vm86_h" = yes; then + if test "$ac_cv_header_sys_vm86_h" = yes && test "x$KDRIVEVESA" = xauto; then + KDRIVEVESA=yes + fi + + if test "x$KDRIVEVESA" = xyes; then + KDRIVEFBDEVLIB=yes AC_DEFINE(KDRIVEVESA, 1, [Build VESA-based kdrive servers]) fi AC_CHECK_HEADERS([linux/fb.h]) - if test "$ac_cv_header_linux_fb_h" = yes; then + if test "$ac_cv_header_linux_fb_h" = yes && test "x$XFBDEV" = xauto; then + XFBDEV=yes + fi + + if test "x$XFBDEV" = xyes; then + KDRIVEFBDEVLIB=yes AC_DEFINE(KDRIVEFBDEV, 1, [Build fbdev-based kdrive server]) fi # tslib... + AC_CHECK_LIB(ts, ts_open, [HAVE_TSLIB="yes"]) + if test "x$TSLIB" = xauto && test "x$HAVE_TSLIB" = xyes; then + TSLIB=yes + fi + + if test "x$TSLIB" = xyes; then + if ! test "x$HAVE_TSLIB" = xyes; then + AC_MSG_ERROR([tslib must be installed to build the tslib input driver.]) + fi + TSLIB_LIBS="-lts" + AC_DEFINE(TSLIB, 1, [Have tslib support]) + fi + + if test x"$ac_cv_header_SDL_SDL_h" = xyes && "x$XSDL" = xauto; then + XSDL=yes + fi + + if test x"$XSDL" = xyes; then + # PKG_CHECK_MODULES(XSDL_EXTRA, Xfont xau $XDMCP_MODULES) + AC_DEFINE(XSDLSERVER,1,[Build Xsdl server]) + XSDL_LIBS="`sdl-config --libs` $XSERVER_LIBS" + XSDL_INCS="`sdl-config --cflags` $XSERVER_CFLAGS" + fi + + PKG_CHECK_MODULES(XEPHYR, x11 xext xfont xau xdmcp, [xephyr="yes"], [xephyr="no"]) + if test "x$XEPHYR" = xauto; then + XEPHYR=xephyr + fi + # Xephyr needs nanosleep() which is in librt on Solaris + AC_CHECK_FUNC([nanosleep], [], + AC_CHECK_LIB([rt], [nanosleep], XEPHYR_LIBS="$XEPHYR_LIBS -lrt")) + XEPHYR_LIBS="$XEPHYR_LIBS $XSERVER_LIBS" # damage shadow extension glx (NOTYET) fb mi KDRIVE_INC='-I$(top_srcdir)/hw/kdrive/src' @@ -1460,48 +1516,38 @@ if test "$KDRIVE" = yes; then # dix os fb mi extension glx (NOTYET) damage shadow xpstubs #KDRIVE_PURE_LIBS="$DIX_LIB $OS_LIB $FB_LIB $XEXT_LIB $MIEXT_DAMAGE_LIB \ # $MIEXT_SHADOW_LIB $XPSTUBS_LIB" - KDRIVE_PURE_LIBS="$FB_LIB $MI_LIB $FIXES_LIB $XEXT_LIB $DBE_LIB $XTRAP_LIB $RECORD_LIB $GLX_LIBS $RENDER_LIB $RANDR_LIB $DAMAGE_LIB $MIEXT_DAMAGE_LIB $MIEXT_SHADOW_LIB $XI_LIB $XKB_LIB $XKB_STUB_LIB $COMPOSITE_LIB $XPSTUBS_LIB $OS_LIB" + KDRIVE_PURE_LIBS="$FB_LIB $MI_LIB $FIXES_LIB $XEXT_LIB $TSLIB_LIBS $DBE_LIB $XTRAP_LIB $RECORD_LIB $GLX_LIBS $RENDER_LIB $RANDR_LIB $DAMAGE_LIB $MIEXT_DAMAGE_LIB $MIEXT_SHADOW_LIB $XI_LIB $XKB_LIB $XKB_STUB_LIB $COMPOSITE_LIB $XPSTUBS_LIB $OS_LIB" KDRIVE_LIB='$(top_builddir)/hw/kdrive/src/libkdrive.a' KDRIVE_OS_LIB='$(top_builddir)/hw/kdrive/linux/liblinux.a' KDRIVE_STUB_LIB='$(top_builddir)/hw/kdrive/src/libkdrivestubs.a' - KDRIVE_LIBS="$DIX_LIB $CONFIG_LIB $KDRIVE_LIB $KDRIVE_OS_LIB $KDRIVE_PURE_LIBS $KDRIVE_STUB_LIB" + KDRIVE_LIBS="$XSERVERLIBS_LIBS $DIX_LIB $CONFIG_LIB $KDRIVE_LIB $KDRIVE_OS_LIB $KDRIVE_PURE_LIBS $KDRIVE_STUB_LIB" # check if we can build Xephyr PKG_CHECK_MODULES(XEPHYR, x11 xext xfont xau xdmcp, [xephyr="yes"], [xephyr="no"]) - - # check for SDL SDK - AC_CHECK_HEADERS([SDL/SDL.h]) + XEPHYR_LIBS="$XEPHYR_LIBS $XSERVER_LIBS" + + # Xephyr needs nanosleep() which is in librt on Solaris + AC_CHECK_FUNC([nanosleep], [], + AC_CHECK_LIB([rt], [nanosleep], XEPHYR_LIBS="$XEPHYR_LIBS -lrt")) + + AC_SUBST([XEPHYR_LIBS]) + AC_SUBST([XEPHYR_INCS]) + AC_SUBST([XSDL_LIBS]) + AC_SUBST([XSDL_INCS]) fi -AC_SUBST(KDRIVE_INCS) -AC_SUBST(KDRIVE_PURE_INCS) -AC_SUBST(KDRIVE_CFLAGS) -AC_SUBST(KDRIVE_PURE_LIBS) -AC_SUBST(KDRIVE_LIBS) -AM_CONDITIONAL(TSLIB, false) +AC_SUBST([KDRIVE_INCS]) +AC_SUBST([KDRIVE_PURE_INCS]) +AC_SUBST([KDRIVE_CFLAGS]) +AC_SUBST([KDRIVE_PURE_LIBS]) +AC_SUBST([KDRIVE_LIBS]) +AM_CONDITIONAL(TSLIB, [test "x$TSLIB" = xyes]) AM_CONDITIONAL(H3600_TS, false) -AM_CONDITIONAL(KDRIVEVESA, [test x"$ac_cv_header_sys_vm86_h" = xyes]) -AM_CONDITIONAL(KDRIVEFBDEV, [test x"$ac_cv_header_linux_fb_h" = xyes]) -#AM_CONDITIONAL(KDRIVEVESA, false) -#AM_CONDITIONAL(KDRIVEFBDEV, false) - -# Xephyr needs nanosleep() which is in librt on Solaris -AC_CHECK_FUNC([nanosleep], [], - AC_CHECK_LIB([rt], [nanosleep], XEPHYR_LIBS="$XEPHYR_LIBS -lrt")) - -AM_CONDITIONAL(XEPHYR, [test x"$xephyr" = xyes]) -XEPHYR_LIBS="$XEPHYR_LIBS $XSERVER_LIBS" -AC_SUBST([XEPHYR_LIBS]) -AC_SUBST([XEPHYR_INCS]) - -AM_CONDITIONAL(XSDLSERVER, [test x"$ac_cv_header_SDL_SDL_h" = xyes]) -if test x"$ac_cv_header_SDL_SDL_h" = xyes -o x"$XSDL" = xyes; then - # PKG_CHECK_MODULES(XSDL_EXTRA, Xfont xau $XDMCP_MODULES) - AC_DEFINE(XSDLSERVER,,[Build Xsdl server]) - XSDL_LIBS="`sdl-config --libs` $XSERVER_LIBS" - XSDL_INCS="`sdl-config --cflags` $XSERVER_CFLAGS" -fi -AC_SUBST([XSDL_LIBS]) -AC_SUBST([XSDL_INCS]) +AM_CONDITIONAL(KDRIVEVESA, [test "x$KDRIVEVESA" = xyes]) +AM_CONDITIONAL(KDRIVEFBDEV, [test "x$XFBDEV" = xyes]) +AM_CONDITIONAL(XSDLSERVER, [test x"$XSDL" = xyes]) +AM_CONDITIONAL(XEPHYR, [test "x$KDRIVE" = xyes && test "x$xephyr" = xyes]) +AM_CONDITIONAL(BUILD_KDRIVEFBDEVLIB, [test "x$KDRIVE" = xyes && test "x$KDRIVEFBDEVLIB" = xyes]) +AM_CONDITIONAL(XFAKESERVER, [test "x$KDRIVE" = xyes && test "x$XFAKE" = xyes]) dnl these only go in xkb-config.h (which is shared by the Xorg and Xnest servers) @@ -1510,7 +1556,6 @@ AC_DEFINE_DIR(XKB_BASE_DIRECTORY, XKBPATH, [Path to XKB data]) AC_DEFINE_DIR(XKB_BIN_DIRECTORY, bindir, [Path to XKB bin dir]) # Make sure XKM_OUTPUT_DIR is an absolute path - XKBOUTPUT_FIRSTCHAR=`echo $XKBOUTPUT | cut -b 1` if [[ x$XKBOUTPUT_FIRSTCHAR != x/ ]] ; then @@ -1549,15 +1594,21 @@ esac AC_DEFINE_DIR(PROJECTROOT, prefix, [Overall prefix]) dnl xorgconfig CLI configuration utility -PKG_CHECK_MODULES([XORGCONFIG_DEP], [xkbfile x11]) -AC_SUBST(XORGCONFIG_DEP_CFLAGS) -AC_SUBST(XORGCONFIG_DEP_LIBS) +if test "x$XORG" = xyes; then + PKG_CHECK_MODULES([XORGCONFIG_DEP], [xkbfile x11]) + AC_SUBST(XORGCONFIG_DEP_CFLAGS) + AC_SUBST(XORGCONFIG_DEP_LIBS) +fi dnl xorgcfg GUI configuration utility AC_ARG_ENABLE(xorgcfg, AS_HELP_STRING([--enable-xorgcfg], - [Build xorgcfg GUI configuration utility (default: yes)]), - [XORGCFG=$enableval],[XORGCFG=yes]) -if test x$XORGCFG = xyes ; then + [Build xorgcfg GUI configuration utility (default: auto)]), + [XORGCFG=$enableval],[XORGCFG=auto]) +if test "x$XORGCFG" = xauto && test "x$XORG" = xyes; then + XORGCFG=yes +fi + +if test "x$XORGCFG" = xyes; then PKG_CHECK_MODULES([XORGCFG_DEP], [xkbui >= 1.0.2 xkbfile xxf86misc xxf86vm xaw7 xmu xt xpm xext x11]) AC_CHECK_LIB([curses],[waddstr], diff --git a/hw/kdrive/Makefile.am b/hw/kdrive/Makefile.am index c8832ebac..fa1dba90a 100644 --- a/hw/kdrive/Makefile.am +++ b/hw/kdrive/Makefile.am @@ -3,10 +3,14 @@ VESA_SUBDIRS = vesa ati chips epson i810 mach64 mga neomagic nvidia pm2 r128 \ smi via endif -if KDRIVEFBDEV +if BUILD_KDRIVEFBDEVLIB FBDEV_SUBDIRS = fbdev endif +if XFAKESERVER +XFAKE_SUBDIRS = fake +endif + if XSDLSERVER XSDL_SUBDIRS = sdl endif @@ -22,7 +26,7 @@ SUBDIRS = \ $(FBDEV_SUBDIRS) \ $(VESA_SUBDIRS) \ $(XEPHYR_SUBDIRS) \ - fake + $(XFAKE_SUBDIRS) DIST_SUBDIRS = vesa ati chips epson i810 mach64 mga neomagic nvidia pm2 r128 \ smi via fbdev sdl ephyr src linux fake sis300 diff --git a/hw/kdrive/ati/ati_stub.c b/hw/kdrive/ati/ati_stub.c index 01ebc3139..d0bc4ca6b 100644 --- a/hw/kdrive/ati/ati_stub.c +++ b/hw/kdrive/ati/ati_stub.c @@ -53,7 +53,15 @@ InitOutput(ScreenInfo *pScreenInfo, int argc, char **argv) void InitInput(int argc, char **argv) { - KdInitInput(&LinuxMouseFuncs, &LinuxKeyboardFuncs); + KdKeyboardInfo *ki = NULL; + + KdAddPointerDriver(&LinuxMouseDriver); + ki = KdNewKeyboard(); + if (ki) { + ki->driver = &LinuxKeyboardDriver; + KdAddKeyboard(ki); + } + KdInitInput(); } void diff --git a/hw/kdrive/ephyr/Makefile.am b/hw/kdrive/ephyr/Makefile.am index f423bfe40..6982d80d9 100644 --- a/hw/kdrive/ephyr/Makefile.am +++ b/hw/kdrive/ephyr/Makefile.am @@ -33,7 +33,6 @@ Xephyr_LDADD = \ libxephyr-hostx.a \ ../../../exa/libexa.la \ @KDRIVE_LIBS@ \ - @KDRIVE_LIBS@ \ $(TSLIB_LIBS) \ @XEPHYR_LIBS@ diff --git a/hw/kdrive/ephyr/ephyr.c b/hw/kdrive/ephyr/ephyr.c index fbb16a465..92fd83195 100644 --- a/hw/kdrive/ephyr/ephyr.c +++ b/hw/kdrive/ephyr/ephyr.c @@ -36,10 +36,16 @@ #include "inputstr.h" extern int KdTsPhyScreen; -extern DeviceIntPtr pKdKeyboard; +KdKeyboardInfo *ephyrKbd; +KdPointerInfo *ephyrMouse; +EphyrKeySyms ephyrKeySyms; static int mouseState = 0; +typedef struct _EphyrInputPrivate { + Bool enabled; +} EphyrKbdPrivate, EphyrPointerPrivate; + Bool EphyrWantGrayScale = 0; Bool @@ -206,15 +212,14 @@ ephyrMapFramebuffer (KdScreenInfo *screen) { EphyrScrPriv *scrpriv = screen->driver; EphyrPriv *priv = screen->card->driver; - KdMouseMatrix m; + KdPointerMatrix m; int buffer_height; EPHYR_DBG(" screen->width: %d, screen->height: %d", screen->width, screen->height); - KdComputeMouseMatrix (&m, scrpriv->randr, screen->width, screen->height); - - KdSetMouseMatrix (&m); + KdComputePointerMatrix (&m, scrpriv->randr, screen->width, screen->height); + KdSetPointerMatrix (&m); priv->bytes_per_line = ((screen->width * screen->fb[0].bitsPerPixel + 31) >> 5) << 2; @@ -719,8 +724,9 @@ ephyrUpdateModifierState(unsigned int state) kptr = &keyc->down[key >> 3]; bit = 1 << (key & 7); - if (*kptr & bit) - KdEnqueueKeyboardEvent(key, TRUE); /* release */ + if (*kptr & bit && ephyrKbd && + ((EphyrKbdPrivate *)ephyrKbd->driverPrivate)->enabled) + KdEnqueueKeyboardEvent(ephyrKbd, key, TRUE); /* release */ if (--count == 0) break; @@ -732,7 +738,9 @@ ephyrUpdateModifierState(unsigned int state) for (key = 0; key < MAP_LENGTH; key++) if (keyc->modifierMap[key] & mask) { - KdEnqueueKeyboardEvent(key, FALSE); /* press */ + if (keyc->modifierMap[key] & mask && ephyrKbd && + ((EphyrKbdPrivate *)ephyrKbd->driverPrivate)->enabled) + KdEnqueueKeyboardEvent(ephyrKbd, key, FALSE); /* press */ break; } } @@ -748,31 +756,47 @@ ephyrPoll(void) switch (ev.type) { case EPHYR_EV_MOUSE_MOTION: - KdEnqueueMouseEvent(kdMouseInfo, mouseState, - ev.data.mouse_motion.x, - ev.data.mouse_motion.y); + if (!ephyrMouse || + !((EphyrPointerPrivate *)ephyrMouse->driverPrivate)->enabled) + continue; + KdEnqueuePointerEvent(ephyrMouse, mouseState, + ev.data.mouse_motion.x, + ev.data.mouse_motion.y, + 0); break; case EPHYR_EV_MOUSE_PRESS: + if (!ephyrMouse || + !((EphyrPointerPrivate *)ephyrMouse->driverPrivate)->enabled) + continue; ephyrUpdateModifierState(ev.key_state); mouseState |= ev.data.mouse_down.button_num; - KdEnqueueMouseEvent(kdMouseInfo, mouseState|KD_MOUSE_DELTA, 0, 0); + KdEnqueuePointerEvent(ephyrMouse, mouseState|KD_MOUSE_DELTA, 0, 0, 0); break; case EPHYR_EV_MOUSE_RELEASE: + if (!ephyrMouse || + !((EphyrPointerPrivate *)ephyrMouse->driverPrivate)->enabled) + continue; ephyrUpdateModifierState(ev.key_state); mouseState &= ~ev.data.mouse_up.button_num; - KdEnqueueMouseEvent(kdMouseInfo, mouseState|KD_MOUSE_DELTA, 0, 0); + KdEnqueuePointerEvent(ephyrMouse, mouseState|KD_MOUSE_DELTA, 0, 0, 0); break; case EPHYR_EV_KEY_PRESS: + if (!ephyrKbd || + !((EphyrKbdPrivate *)ephyrKbd->driverPrivate)->enabled) + continue; ephyrUpdateModifierState(ev.key_state); - KdEnqueueKeyboardEvent (ev.data.key_down.scancode, FALSE); + KdEnqueueKeyboardEvent (ephyrKbd, ev.data.key_down.scancode, FALSE); break; case EPHYR_EV_KEY_RELEASE: + if (!ephyrKbd || + !((EphyrKbdPrivate *)ephyrKbd->driverPrivate)->enabled) + continue; ephyrUpdateModifierState(ev.key_state); - KdEnqueueKeyboardEvent (ev.data.key_up.scancode, TRUE); + KdEnqueueKeyboardEvent (ephyrKbd, ev.data.key_up.scancode, TRUE); break; default: @@ -833,59 +857,115 @@ ephyrPutColors (ScreenPtr pScreen, int fb, int n, xColorItem *pdefs) /* Mouse calls */ -static Bool -MouseInit (void) +static Status +MouseInit (KdPointerInfo *pi) { - return TRUE; + pi->driverPrivate = (EphyrPointerPrivate *) + xcalloc(sizeof(EphyrPointerPrivate), 1); + ((EphyrPointerPrivate *)pi->driverPrivate)->enabled = FALSE; + ephyrMouse = pi; + /* FIXME DO NOT COMMIT */ + KdAddPointerDriver(&EphyrMouseDriver); + ErrorF("SUCCESS!\n"); + return Success; +} + +static Status +MouseEnable (KdPointerInfo *pi) +{ + ((EphyrPointerPrivate *)pi->driverPrivate)->enabled = TRUE; + ErrorF("SUCCESS ENABLE!\n"); + return Success; } static void -MouseFini (void) +MouseDisable (KdPointerInfo *pi) { - ; + ((EphyrPointerPrivate *)pi->driverPrivate)->enabled = FALSE; + return; } -KdMouseFuncs EphyrMouseFuncs = { +static void +MouseFini (KdPointerInfo *pi) +{ + ephyrMouse = NULL; + return; +} + +KdPointerDriver EphyrMouseDriver = { + "ephyr", MouseInit, + MouseEnable, + MouseDisable, MouseFini, + NULL, }; /* Keyboard */ -static void -EphyrKeyboardLoad (void) +static Status +EphyrKeyboardInit (KdKeyboardInfo *ki) { - EPHYR_DBG("mark"); - - hostx_load_keymap(); + ki->driverPrivate = (EphyrKbdPrivate *) + xcalloc(sizeof(EphyrKbdPrivate), 1); + /* FIXME blah blah overrunning memory blah blah */ + ki->minScanCode = ki->keySyms.minKeyCode = 0; + ki->maxScanCode = ki->keySyms.maxKeyCode = 255; + ephyrKbd = ki; + return Success; } -static int -EphyrKeyboardInit (void) +static Status +EphyrKeyboardEnable (KdKeyboardInfo *ki) { - return 0; + hostx_load_keymap(); + if (!ephyrKeySyms.map) { + ErrorF("Couldn't load keymap from host\n"); + return BadAlloc; + } + ki->keySyms.minKeyCode = ephyrKeySyms.minKeyCode; + ki->keySyms.maxKeyCode = ephyrKeySyms.maxKeyCode; + ki->minScanCode = ki->keySyms.minKeyCode; + ki->maxScanCode = ki->keySyms.maxKeyCode; + ki->keySyms.mapWidth = ephyrKeySyms.mapWidth; + ki->keySyms.map = ephyrKeySyms.map; + ((EphyrKbdPrivate *)ki->driverPrivate)->enabled = TRUE; + + return Success; } static void -EphyrKeyboardFini (void) +EphyrKeyboardDisable (KdKeyboardInfo *ki) +{ + ((EphyrKbdPrivate *)ki->driverPrivate)->enabled = FALSE; +} + +static void +EphyrKeyboardFini (KdKeyboardInfo *ki) +{ + /* not xfree: we call malloc from hostx.c. */ + free(ki->keySyms.map); + ephyrKbd = NULL; + return; +} + +static void +EphyrKeyboardLeds (KdKeyboardInfo *ki, int leds) { } static void -EphyrKeyboardLeds (int leds) +EphyrKeyboardBell (KdKeyboardInfo *ki, int volume, int frequency, int duration) { } -static void -EphyrKeyboardBell (int volume, int frequency, int duration) -{ -} - -KdKeyboardFuncs EphyrKeyboardFuncs = { - EphyrKeyboardLoad, +KdKeyboardDriver EphyrKeyboardDriver = { + "ephyr", EphyrKeyboardInit, + EphyrKeyboardEnable, EphyrKeyboardLeds, EphyrKeyboardBell, + EphyrKeyboardDisable, EphyrKeyboardFini, - 0, + NULL, }; diff --git a/hw/kdrive/ephyr/ephyr.h b/hw/kdrive/ephyr/ephyr.h index 707cb0168..f49d920d1 100644 --- a/hw/kdrive/ephyr/ephyr.h +++ b/hw/kdrive/ephyr/ephyr.h @@ -31,7 +31,6 @@ #include "os.h" /* for OsSignal() */ #include "kdrive.h" -#include "kkeymap.h" #include "hostx.h" #include "exa.h" @@ -68,7 +67,9 @@ typedef struct _ephyrScrPriv { EphyrFakexaPriv *fakexa; } EphyrScrPriv; -extern KdCardFuncs ephyrFuncs; +extern KdCardFuncs ephyrFuncs; +extern KdKeyboardInfo *ephyrKbd; +extern KdPointerInfo *ephyrMouse; Bool ephyrInitialize (KdCardInfo *card, EphyrPriv *priv); @@ -167,9 +168,9 @@ ephyrShadowUpdate (ScreenPtr pScreen, shadowBufPtr pBuf); void ephyrUpdateModifierState(unsigned int state); -extern KdMouseFuncs EphyrMouseFuncs; +extern KdPointerDriver EphyrMouseDriver; -extern KdKeyboardFuncs EphyrKeyboardFuncs; +extern KdKeyboardDriver EphyrKeyboardDriver; extern KdOsFuncs EphyrOsFuncs; diff --git a/hw/kdrive/ephyr/ephyrinit.c b/hw/kdrive/ephyr/ephyrinit.c index 1aa608e93..021abd65f 100644 --- a/hw/kdrive/ephyr/ephyrinit.c +++ b/hw/kdrive/ephyr/ephyrinit.c @@ -51,7 +51,24 @@ InitOutput (ScreenInfo *pScreenInfo, int argc, char **argv) void InitInput (int argc, char **argv) { - KdInitInput (&EphyrMouseFuncs, &EphyrKeyboardFuncs); + KdKeyboardInfo *ki; + KdPointerInfo *pi; + + ki = KdNewKeyboard(); + if (!ki) + FatalError("Couldn't create Xephyr keyboard\n"); + ki->driver = &EphyrKeyboardDriver; + ki->name = KdSaveString("Xephyr virtual keyboard"); + KdAddKeyboard(ki); + + pi = KdNewPointer(); + if (!pi) + FatalError("Couldn't create Xephyr pointer\n"); + pi->driver = &EphyrMouseDriver; + pi->name = KdSaveString("Xephyr virtual mouse"); + KdAddPointer(pi); + + KdInitInput(); } void diff --git a/hw/kdrive/ephyr/hostx.c b/hw/kdrive/ephyr/hostx.c index 32a46dcf4..b23532fe0 100644 --- a/hw/kdrive/ephyr/hostx.c +++ b/hw/kdrive/ephyr/hostx.c @@ -77,14 +77,8 @@ static EphyrHostXVars HostX = { "?", 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; static int HostXWantDamageDebug = 0; -extern KeySym EphyrKeymap[]; +extern EphyrKeySyms ephyrKeySyms; -extern KeySym kdKeymap[]; -extern int kdMinScanCode; -extern int kdMaxScanCode; -extern int kdMinKeyCode; -extern int kdMaxKeyCode; -extern int kdKeymapWidth; extern int monitorResolution; static void @@ -403,9 +397,9 @@ hostx_get_bpp(void) } void -hostx_get_visual_masks (unsigned long *rmsk, - unsigned long *gmsk, - unsigned long *bmsk) +hostx_get_visual_masks (CARD32 *rmsk, + CARD32 *gmsk, + CARD32 *bmsk) { if (host_depth_matches_server()) { @@ -681,6 +675,13 @@ hostx_load_keymap(void) max_keycode - min_keycode + 1, &host_width); + + ephyrKeySyms.map = (KeySym *)calloc(sizeof(KeySym), + (max_keycode - min_keycode + 1) * + width); + if (!ephyrKeySyms.map) + return; + /* Try and copy the hosts keymap into our keymap to avoid loads * of messing around. * @@ -695,13 +696,9 @@ hostx_load_keymap(void) EPHYR_DBG("keymap width, host:%d kdrive:%d", host_width, width); - /* all kdrive vars - see kkeymap.c */ - - kdMinScanCode = min_keycode; - kdMaxScanCode = max_keycode; - kdMinKeyCode = min_keycode; - kdMaxKeyCode = max_keycode; - kdKeymapWidth = width; + ephyrKeySyms.minKeyCode = min_keycode; + ephyrKeySyms.maxKeyCode = max_keycode; + ephyrKeySyms.mapWidth = (width > 4) ? 4 : width; XFree(keymap); } diff --git a/hw/kdrive/ephyr/hostx.h b/hw/kdrive/ephyr/hostx.h index d3f6da3d3..4e3c6af33 100644 --- a/hw/kdrive/ephyr/hostx.h +++ b/hw/kdrive/ephyr/hostx.h @@ -26,6 +26,9 @@ #ifndef _XLIBS_STUFF_H_ #define _XLIBS_STUFF_H_ +#include +#include + #define EPHYR_WANT_DEBUG 0 #if (EPHYR_WANT_DEBUG) @@ -48,6 +51,14 @@ typedef enum EphyrHostXEventType } EphyrHostXEventType; +/* I can't believe it's not a KeySymsRec. */ +typedef struct { + int minKeyCode; + int maxKeyCode; + int mapWidth; + KeySym *map; +} EphyrKeySyms; + struct EphyrHostXEvent { EphyrHostXEventType type; @@ -126,9 +137,9 @@ int hostx_get_bpp(void); void -hostx_get_visual_masks (unsigned long *rmsk, - unsigned long *gmsk, - unsigned long *bmsk); +hostx_get_visual_masks (CARD32 *rmsk, + CARD32 *gmsk, + CARD32 *bmsk); void hostx_set_cmap_entry(unsigned char idx, unsigned char r, diff --git a/hw/kdrive/fake/fake.c b/hw/kdrive/fake/fake.c index d56512b3f..ca515f9b6 100644 --- a/hw/kdrive/fake/fake.c +++ b/hw/kdrive/fake/fake.c @@ -158,7 +158,7 @@ Bool fakeMapFramebuffer (KdScreenInfo *screen) { FakeScrPriv *scrpriv = screen->driver; - KdMouseMatrix m; + KdPointerMatrix m; FakePriv *priv = screen->card->driver; if (scrpriv->randr != RR_Rotate_0) @@ -166,9 +166,9 @@ fakeMapFramebuffer (KdScreenInfo *screen) else scrpriv->shadow = FALSE; - KdComputeMouseMatrix (&m, scrpriv->randr, screen->width, screen->height); + KdComputePointerMatrix (&m, scrpriv->randr, screen->width, screen->height); - KdSetMouseMatrix (&m); + KdSetPointerMatrix (&m); priv->bytes_per_line = ((screen->width * screen->fb[0].bitsPerPixel + 31) >> 5) << 2; if (priv->base) diff --git a/hw/kdrive/fake/fake.h b/hw/kdrive/fake/fake.h index 4d90d3169..f7c8c3431 100644 --- a/hw/kdrive/fake/fake.h +++ b/hw/kdrive/fake/fake.h @@ -130,9 +130,9 @@ fakeRandRInit (ScreenPtr pScreen); #endif -extern KdMouseFuncs FakeMouseFuncs; +extern KdPointerDriver FakePointerDriver; -extern KdKeyboardFuncs FakeKeyboardFuncs; +extern KdKeyboardDriver FakeKeyboardDriver; extern KdOsFuncs FakeOsFuncs; diff --git a/hw/kdrive/fake/fakeinit.c b/hw/kdrive/fake/fakeinit.c index c5ee4bc3f..dd88bc5a7 100644 --- a/hw/kdrive/fake/fakeinit.c +++ b/hw/kdrive/fake/fakeinit.c @@ -44,7 +44,22 @@ InitOutput (ScreenInfo *pScreenInfo, int argc, char **argv) void InitInput (int argc, char **argv) { - KdInitInput (&FakeMouseFuncs, &FakeKeyboardFuncs); + KdPointerInfo *pi; + KdKeyboardInfo *ki; + + pi = KdNewPointer (); + if (!pi) + return; + pi->driver = &FakePointerDriver; + KdAddPointer(pi); + + ki = KdNewKeyboard (); + if (!ki) + return; + ki->driver = &FakeKeyboardDriver; + KdAddKeyboard(ki); + + KdInitInput (); } void diff --git a/hw/kdrive/fake/kbd.c b/hw/kdrive/fake/kbd.c index 9cf4de060..db224c995 100644 --- a/hw/kdrive/fake/kbd.c +++ b/hw/kdrive/fake/kbd.c @@ -27,7 +27,6 @@ #include #endif #include "fake.h" -#include "kkeymap.h" #include #define FAKE_WIDTH 2 @@ -155,41 +154,58 @@ KeySym FakeKeymap[] = { /* 116 123 */ NoSymbol, NoSymbol, /* tiny button */ }; -static void -FakeKeyboardLoad (void) +static Status +FakeKeyboardInit (KdKeyboardInfo *ki) { - kdMinScanCode = 1; - kdKeymapWidth = FAKE_WIDTH; - kdMaxScanCode = (sizeof (FakeKeymap) / sizeof (FakeKeymap[0])) / FAKE_WIDTH; - memcpy (kdKeymap, FakeKeymap, sizeof (FakeKeymap)); + ki->keySyms.minKeyCode = 1; + ki->keySyms.maxKeyCode = (sizeof (FakeKeymap) / sizeof (FakeKeymap[0])) / FAKE_WIDTH; + ki->keySyms.mapWidth = FAKE_WIDTH; + if (ki->keySyms.map) + xfree(ki->keySyms.map); + ki->keySyms.map = (KeySym *)xalloc(sizeof(FakeKeymap)); + if (!ki->keySyms.map) + return BadAlloc; + memcpy (ki->keySyms.map, FakeKeymap, sizeof (FakeKeymap)); + + return Success; } -static int -FakeKeyboardInit (void) +static Status +FakeKeyboardEnable (KdKeyboardInfo *ki) { - return 0; + return Success; } static void -FakeKeyboardFini (void) +FakeKeyboardDisable (KdKeyboardInfo *ki) +{ + return; +} + +static void +FakeKeyboardFini (KdKeyboardInfo *ki) +{ + xfree(ki->keySyms.map); + ki->keySyms.map = NULL; +} + +static void +FakeKeyboardLeds (KdKeyboardInfo *ki, int leds) { } static void -FakeKeyboardLeds (int leds) +FakeKeyboardBell (KdKeyboardInfo *ki, int volume, int frequency, int duration) { } -static void -FakeKeyboardBell (int volume, int frequency, int duration) -{ -} - -KdKeyboardFuncs FakeKeyboardFuncs = { - FakeKeyboardLoad, +KdKeyboardDriver FakeKeyboardDriver = { + "fake", FakeKeyboardInit, + FakeKeyboardEnable, FakeKeyboardLeds, FakeKeyboardBell, + FakeKeyboardDisable, FakeKeyboardFini, - 0, + NULL, }; diff --git a/hw/kdrive/fake/mouse.c b/hw/kdrive/fake/mouse.c index 714a45123..beb6ff524 100644 --- a/hw/kdrive/fake/mouse.c +++ b/hw/kdrive/fake/mouse.c @@ -35,19 +35,35 @@ #include "scrnintstr.h" #include "kdrive.h" -static Bool -MouseInit (void) +static Status +MouseInit (KdPointerInfo *pi) { - return TRUE; + return Success; +} + +static Status +MouseEnable (KdPointerInfo *pi) +{ + return Success; } static void -MouseFini (void) +MouseDisable (KdPointerInfo *pi) { + return; +} + +static void +MouseFini (KdPointerInfo *pi) +{ + return; } -KdMouseFuncs FakeMouseFuncs = { +KdPointerDriver FakePointerDriver = { + "fake", MouseInit, + MouseEnable, + MouseDisable, MouseFini, }; diff --git a/hw/kdrive/fbdev/Makefile.am b/hw/kdrive/fbdev/Makefile.am index fce6df9f4..39e9ba4c6 100644 --- a/hw/kdrive/fbdev/Makefile.am +++ b/hw/kdrive/fbdev/Makefile.am @@ -4,8 +4,6 @@ INCLUDES = \ noinst_LIBRARIES = libfbdev.a -bin_PROGRAMS = Xfbdev - if TSLIB TSLIB_FLAG = -lts endif @@ -14,6 +12,9 @@ libfbdev_a_SOURCES = \ fbdev.c \ fbdev.h +if KDRIVEFBDEV +bin_PROGRAMS = Xfbdev + Xfbdev_SOURCES = \ fbinit.c @@ -26,4 +27,4 @@ Xfbdev_LDADD = \ Xfbdev_DEPENDENCIES = \ libfbdev.a \ @KDRIVE_LIBS@ - +endif diff --git a/hw/kdrive/fbdev/fbdev.c b/hw/kdrive/fbdev/fbdev.c index 86384f0a4..8ff32efcb 100644 --- a/hw/kdrive/fbdev/fbdev.c +++ b/hw/kdrive/fbdev/fbdev.c @@ -323,7 +323,7 @@ Bool fbdevMapFramebuffer (KdScreenInfo *screen) { FbdevScrPriv *scrpriv = screen->driver; - KdMouseMatrix m; + KdPointerMatrix m; FbdevPriv *priv = screen->card->driver; if (scrpriv->randr != RR_Rotate_0) @@ -331,9 +331,9 @@ fbdevMapFramebuffer (KdScreenInfo *screen) else scrpriv->shadow = FALSE; - KdComputeMouseMatrix (&m, scrpriv->randr, screen->width, screen->height); + KdComputePointerMatrix (&m, scrpriv->randr, screen->width, screen->height); - KdSetMouseMatrix (&m); + KdSetPointerMatrix (&m); screen->width = priv->var.xres; screen->height = priv->var.yres; diff --git a/hw/kdrive/fbdev/fbinit.c b/hw/kdrive/fbdev/fbinit.c index ba9d1c695..9d7c492d9 100644 --- a/hw/kdrive/fbdev/fbinit.c +++ b/hw/kdrive/fbdev/fbinit.c @@ -45,10 +45,18 @@ InitOutput (ScreenInfo *pScreenInfo, int argc, char **argv) void InitInput (int argc, char **argv) { - KdInitInput (&LinuxMouseFuncs, &LinuxKeyboardFuncs); -#ifdef TOUCHSCREEN - KdAddMouseDriver (&TsFuncs); + KdKeyboardInfo *ki; + + KdAddKeyboardDriver (&LinuxKeyboardDriver); + KdAddPointerDriver (&LinuxMouseDriver); +#ifdef TSLIB + KdAddPointerDriver (&TsDriver); #endif + + ki = KdParseKeyboard ("keybd"); + KdAddKeyboard(ki); + + KdInitInput (); } void diff --git a/hw/kdrive/itsy/kbd.c b/hw/kdrive/itsy/kbd.c index 76062c5a8..beb4685d4 100644 --- a/hw/kdrive/itsy/kbd.c +++ b/hw/kdrive/itsy/kbd.c @@ -27,7 +27,6 @@ #include #endif #include "itsy.h" -#include "kkeymap.h" #include #include @@ -167,28 +166,44 @@ ItsyKeyboardLoad (void) { KeySym *k; - itsyButtonState = 0; - kdMinScanCode = 1; - kdKeymapWidth = ITSY_WIDTH; - kdMaxScanCode = (sizeof (ItsyKeymap) / sizeof (ItsyKeymap[0])) / ITSY_WIDTH; - memcpy (kdKeymap, ItsyKeymap, sizeof (ItsyKeymap)); } -int -ItsyKeyboardInit (void) +static Status +ItsyKeyboardInit (KdKeyboardInfo *ki) { - int butPort; + if (!ki) + return BadImplementation; - butPort = open ("/dev/buttons", 0); - fprintf (stderr, "butPort %d\n", butPort); - return butPort; + ki->driverPrivate = open ("/dev/buttons", 0); + + itsyButtonState = 0; + ki->keySyms.minKeyCode = 1; + ki->keySyms.maxKeyCode = (sizeof (ItsyKeymap) / sizeof (ItsyKeymap[0])) / ITSY_WIDTH; + ki->minScanCode = ki->keySyms.minKeyCode; + ki->maxScanCode = ki->keySyms.maxKeyCode; + ki->keySyms.mapWidth = ITSY_WIDTH; + + if (ki->keySyms.map) + xfree(ki->keySyms.map); + ki->keySyms.map = xalloc(sizeof(ItsyKeymap)); + if (!ki->keySyms.map) + return BadAlloc; + memcpy (kdKeymap, ItsyKeymap, sizeof (ItsyKeymap)); + + return Success; } -void -ItsyKeyboardFini (int fd) +static void +ItsyKeyboardDisable (KdKeybdInfo *ki) { if (fd >= 0) - close (fd); + close ((int)ki->driverPrivate); +} + +static void +ItsyKeyboardFini (KdKeybdInfo *ki) +{ + return; } void @@ -227,11 +242,13 @@ ItsyKeyboardBell (int volume, int frequency, int duration) } KdKeyboardFuncs itsyKeyboardFuncs = { - ItsyKeyboardLoad, + "itsy", ItsyKeyboardInit, + ItsyKeyboardEnable, ItsyKeyboardRead, ItsyKeyboardLeds, ItsyKeyboardBell, + ItsyKeyboardDisable ItsyKeyboardFini, - 0, + NULL, }; diff --git a/hw/kdrive/itsy/ts.c b/hw/kdrive/itsy/ts.c index c773c0e4f..180d1fd12 100644 --- a/hw/kdrive/itsy/ts.c +++ b/hw/kdrive/itsy/ts.c @@ -63,7 +63,7 @@ itsyTsReadBytes (int fd, char *buf, int len, int min) } void -itsyTsRead (int tsPort) +itsyTsRead (KdPointerInfo *pi, int tsPort) { ts_event event; long buf[3]; @@ -89,7 +89,7 @@ itsyTsRead (int tsPort) x = 0; y = 0; } - KdEnqueueMouseEvent (flags, x, y); + KdEnqueuePointerEvent (pi, flags, x, y, 0); } } @@ -204,7 +204,8 @@ itsyTsFini (int tsPort) close (tsPort); } -KdMouseFuncs itsyTsMouseFuncs = { +KdPointerDriver itsyTsMouseDriver = { + "itsyts", itsyTsInit, itsyTsRead, itsyTsFini diff --git a/hw/kdrive/linux/bus.c b/hw/kdrive/linux/bus.c index be61f891a..8cf5f901f 100644 --- a/hw/kdrive/linux/bus.c +++ b/hw/kdrive/linux/bus.c @@ -55,7 +55,7 @@ BusRead (int adbPort, void *closure) flags |= KD_BUTTON_2; if ((buf[0] & 1) == 0) flags |= KD_BUTTON_3; - KdEnqueueMouseEvent (kdMouseInfo, flags, dx, dy); + KdEnqueuePointerEvent (closure, flags, dx, dy, 0); } } @@ -66,36 +66,71 @@ char *BusNames[] = { #define NUM_BUS_NAMES (sizeof (BusNames) / sizeof (BusNames[0])) -int BusInputType; +static int +BusInit (KdPointerInfo *pi) +{ + int i, fd = 0; + + if (!pi->path || (strcmp(pi->path, "auto") == 0)) + { + for (i = 0; i < NUM_BUS_NAMES; i++) + { + if ((fd = open (BusNames[i], 0)) > 0) + { + close(fd); + if (pi->path) + xfree(pi->path); + pi->path = KdSaveString(BusNames[i]); + return Success; + } + } + } + else + { + if ((fd = open(pi->path, 0)) > 0) + { + close(fd); + return Success; + } + } + + return !Success; +} static int -BusInit (void) +BusEnable (KdPointerInfo *pi) { - int i; - int busPort; - int n = 0; + int fd = open(pi->path, 0); - if (!BusInputType) - BusInputType = KdAllocInputType (); - - for (i = 0; i < NUM_BUS_NAMES; i++) + if (fd > 0) { - busPort = open (BusNames[i], 0); - { - KdRegisterFd (BusInputType, busPort, BusRead, 0); - n++; - } + KdRegisterFd(fd, BusRead, pi); + pi->driverPrivate = (void *)fd; + return Success; + } + else + { + return !Success; } - return n; } static void -BusFini (void) +BusDisable (KdPointerInfo *pi) { - KdUnregisterFds (BusInputType, TRUE); + KdUnregisterFd(pi, (int)pi->driverPrivate, TRUE); } -KdMouseFuncs BusMouseFuncs = { +static void +BusFini (KdPointerInfo *pi) +{ + return; +} + +KdPointerDriver BusMouseDriver = { + "bus", BusInit, - BusFini + BusEnable, + BusDisable, + BusFini, + NULL }; diff --git a/hw/kdrive/linux/evdev.c b/hw/kdrive/linux/evdev.c index d83b13a6e..6c08cfa62 100644 --- a/hw/kdrive/linux/evdev.c +++ b/hw/kdrive/linux/evdev.c @@ -43,98 +43,100 @@ #define ISBITSET(x,y) ((x)[LONG(y)] & BIT(y)) #define OFF(x) ((x)%BITS_PER_LONG) #define LONG(x) ((x)/BITS_PER_LONG) -#define BIT(x) (1 << OFF(x)) +#define BIT(x) (1 << OFF(x)) #define SETBIT(x,y) ((x)[LONG(y)] |= BIT(y)) #define CLRBIT(x,y) ((x)[LONG(y)] &= ~BIT(y)) #define ASSIGNBIT(x,y,z) ((x)[LONG(y)] = ((x)[LONG(y)] & ~BIT(y)) | (z << OFF(y))) typedef struct _kevdevMouse { /* current device state */ - int rel[REL_MAX + 1]; - int abs[ABS_MAX + 1]; - int prevabs[ABS_MAX + 1]; - long key[NBITS(KEY_MAX + 1)]; + int rel[REL_MAX + 1]; + int abs[ABS_MAX + 1]; + int prevabs[ABS_MAX + 1]; + long key[NBITS(KEY_MAX + 1)]; /* supported device info */ - long relbits[NBITS(REL_MAX + 1)]; - long absbits[NBITS(ABS_MAX + 1)]; - long keybits[NBITS(KEY_MAX + 1)]; + long relbits[NBITS(REL_MAX + 1)]; + long absbits[NBITS(ABS_MAX + 1)]; + long keybits[NBITS(KEY_MAX + 1)]; struct input_absinfo absinfo[ABS_MAX + 1]; - int max_rel; - int max_abs; + int max_rel; + int max_abs; + + int fd; } Kevdev; static void -EvdevMotion (KdMouseInfo *mi) +EvdevMotion (KdPointerInfo *pi) { - Kevdev *ke = mi->driver; - int i; + Kevdev *ke = pi->driverPrivate; + int i; for (i = 0; i <= ke->max_rel; i++) - if (ke->rel[i]) - { - int a; - ErrorF ("rel"); - for (a = 0; a <= ke->max_rel; a++) - { - if (ISBITSET (ke->relbits, a)) - ErrorF (" %d=%d", a, ke->rel[a]); - ke->rel[a] = 0; - } - ErrorF ("\n"); - break; - } + if (ke->rel[i]) + { + int a; + ErrorF ("rel"); + for (a = 0; a <= ke->max_rel; a++) + { + if (ISBITSET (ke->relbits, a)) + ErrorF (" %d=%d", a, ke->rel[a]); + ke->rel[a] = 0; + } + ErrorF ("\n"); + break; + } for (i = 0; i < ke->max_abs; i++) - if (ke->abs[i] != ke->prevabs[i]) - { - int a; - ErrorF ("abs"); - for (a = 0; a <= ke->max_abs; a++) - { - if (ISBITSET (ke->absbits, a)) - ErrorF (" %d=%d", a, ke->abs[a]); - ke->prevabs[a] = ke->abs[a]; - } - ErrorF ("\n"); - break; - } + if (ke->abs[i] != ke->prevabs[i]) + { + int a; + ErrorF ("abs"); + for (a = 0; a <= ke->max_abs; a++) + { + if (ISBITSET (ke->absbits, a)) + ErrorF (" %d=%d", a, ke->abs[a]); + ke->prevabs[a] = ke->abs[a]; + } + ErrorF ("\n"); + break; + } } static void EvdevRead (int evdevPort, void *closure) { - KdMouseInfo *mi = closure; - Kevdev *ke = mi->driver; - int i; - struct input_event events[NUM_EVENTS]; - int n; + KdPointerInfo *pi = closure; + Kevdev *ke = pi->driverPrivate; + int i; + struct input_event events[NUM_EVENTS]; + int n; n = read (evdevPort, &events, NUM_EVENTS * sizeof (struct input_event)); if (n <= 0) - return; + return; n /= sizeof (struct input_event); for (i = 0; i < n; i++) { - switch (events[i].type) { - case EV_SYN: - break; - case EV_KEY: - EvdevMotion (mi); - ASSIGNBIT(ke->key,events[i].code, events[i].value); - if (events[i].code < 0x100) - ErrorF ("key %d %d\n", events[i].code, events[i].value); - else - ErrorF ("key 0x%x %d\n", events[i].code, events[i].value); - break; - case EV_REL: - ke->rel[events[i].code] += events[i].value; - break; - case EV_ABS: - ke->abs[events[i].code] = events[i].value; - break; - } + switch (events[i].type) { + case EV_SYN: + break; + case EV_KEY: + EvdevMotion (pi); + ASSIGNBIT(ke->key,events[i].code, events[i].value); + if (events[i].code < 0x100) + ErrorF ("key %d %d\n", events[i].code, events[i].value); + else + ErrorF ("key 0x%x %d\n", events[i].code, events[i].value); + break; + case EV_REL: + ke->rel[events[i].code] += events[i].value; + break; + case EV_ABS: + ke->abs[events[i].code] = events[i].value; + break; + } } - EvdevMotion (mi); + EvdevMotion (pi); } int EvdevInputType; @@ -148,143 +150,153 @@ char *kdefaultEvdev[] = { #define NUM_DEFAULT_EVDEV (sizeof (kdefaultEvdev) / sizeof (kdefaultEvdev[0])) -static Bool -EvdevInit (void) +static Status +EvdevInit (KdPointerInfo *pi) { - int i; - int fd; - KdMouseInfo *mi, *next; - int n = 0; - char *prot; + int i; + int fd; + int n = 0; + char *prot; - if (!EvdevInputType) - EvdevInputType = KdAllocInputType (); - - for (mi = kdMouseInfo; mi; mi = next) - { - next = mi->next; - prot = mi->prot; - if (mi->inputType) - continue; - if (!mi->name) - { - for (i = 0; i < NUM_DEFAULT_EVDEV; i++) - { - fd = open (kdefaultEvdev[i], 2); - if (fd >= 0) - { - mi->name = KdSaveString (kdefaultEvdev[i]); - break; - } - } - } - else - fd = open (mi->name, 2); - - if (fd >= 0) - { - unsigned long ev[NBITS(EV_MAX)]; - Kevdev *ke; - - if (ioctl (fd, EVIOCGBIT(0 /*EV*/, sizeof (ev)), ev) < 0) - { - perror ("EVIOCGBIT 0"); - close (fd); - continue; - } - ke = xalloc (sizeof (Kevdev)); - if (!ke) - { - close (fd); - continue; - } - memset (ke, '\0', sizeof (Kevdev)); - if (ISBITSET (ev, EV_KEY)) - { - if (ioctl (fd, EVIOCGBIT (EV_KEY, sizeof (ke->keybits)), - ke->keybits) < 0) - { - perror ("EVIOCGBIT EV_KEY"); - xfree (ke); - close (fd); - continue; - } - } - if (ISBITSET (ev, EV_REL)) - { - if (ioctl (fd, EVIOCGBIT (EV_REL, sizeof (ke->relbits)), - ke->relbits) < 0) - { - perror ("EVIOCGBIT EV_REL"); - xfree (ke); - close (fd); - continue; - } - for (ke->max_rel = REL_MAX; ke->max_rel >= 0; ke->max_rel--) - if (ISBITSET(ke->relbits, ke->max_rel)) - break; - } - if (ISBITSET (ev, EV_ABS)) - { - int i; - - if (ioctl (fd, EVIOCGBIT (EV_ABS, sizeof (ke->absbits)), - ke->absbits) < 0) - { - perror ("EVIOCGBIT EV_ABS"); - xfree (ke); - close (fd); - continue; - } - for (ke->max_abs = ABS_MAX; ke->max_abs >= 0; ke->max_abs--) - if (ISBITSET(ke->absbits, ke->max_abs)) - break; - for (i = 0; i <= ke->max_abs; i++) - { - if (ISBITSET (ke->absbits, i)) - if (ioctl (fd, EVIOCGABS(i), &ke->absinfo[i]) < 0) - { - perror ("EVIOCGABS"); - break; - } - ke->prevabs[i] = ABS_UNSET; - } - if (i <= ke->max_abs) - { - xfree (ke); - close (fd); - continue; - } - } - mi->driver = ke; - mi->inputType = EvdevInputType; - if (KdRegisterFd (EvdevInputType, fd, EvdevRead, (void *) mi)) - n++; - } + if (!pi->path) { + for (i = 0; i < NUM_DEFAULT_EVDEV; i++) { + fd = open (kdefaultEvdev[i], 2); + if (fd >= 0) { + pi->path = KdSaveString (kdefaultEvdev[i]); + break; + } + } } - return TRUE; + else { + fd = open (pi->path, 2); + if (fd < 0) { + ErrorF("Failed to open evdev device %s\n", pi->path); + return BadMatch; + } + } + + return Success; +} + +static Status +EvdevEnable (KdPointerInfo *pi) +{ + int fd; + + if (!pi || !pi->path) + return BadImplementation; + + fd = open(pi->path, 2); + if (fd < 0) + return BadMatch; + + unsigned long ev[NBITS(EV_MAX)]; + Kevdev *ke; + + if (ioctl (fd, EVIOCGBIT(0 /*EV*/, sizeof (ev)), ev) < 0) + { + perror ("EVIOCGBIT 0"); + close (fd); + return BadMatch; + } + ke = xalloc (sizeof (Kevdev)); + if (!ke) + { + close (fd); + return BadAlloc; + } + memset (ke, '\0', sizeof (Kevdev)); + if (ISBITSET (ev, EV_KEY)) + { + if (ioctl (fd, EVIOCGBIT (EV_KEY, sizeof (ke->keybits)), + ke->keybits) < 0) + { + perror ("EVIOCGBIT EV_KEY"); + xfree (ke); + close (fd); + return BadMatch; + } + } + if (ISBITSET (ev, EV_REL)) + { + if (ioctl (fd, EVIOCGBIT (EV_REL, sizeof (ke->relbits)), + ke->relbits) < 0) + { + perror ("EVIOCGBIT EV_REL"); + xfree (ke); + close (fd); + return BadMatch; + } + for (ke->max_rel = REL_MAX; ke->max_rel >= 0; ke->max_rel--) + if (ISBITSET(ke->relbits, ke->max_rel)) + break; + } + if (ISBITSET (ev, EV_ABS)) + { + int i; + + if (ioctl (fd, EVIOCGBIT (EV_ABS, sizeof (ke->absbits)), + ke->absbits) < 0) + { + perror ("EVIOCGBIT EV_ABS"); + xfree (ke); + close (fd); + return BadMatch; + } + for (ke->max_abs = ABS_MAX; ke->max_abs >= 0; ke->max_abs--) + if (ISBITSET(ke->absbits, ke->max_abs)) + break; + for (i = 0; i <= ke->max_abs; i++) + { + if (ISBITSET (ke->absbits, i)) + if (ioctl (fd, EVIOCGABS(i), &ke->absinfo[i]) < 0) + { + perror ("EVIOCGABS"); + break; + } + ke->prevabs[i] = ABS_UNSET; + } + if (i <= ke->max_abs) + { + xfree (ke); + close (fd); + return BadValue; + } + } + if (!KdRegisterFd (fd, EvdevRead, pi)) { + xfree (ke); + close (fd); + return BadAlloc; + } + pi->driverPrivate = ke; + return Success; } static void -EvdevFini (void) +EvdevDisable (KdPointerInfo *pi) { - KdMouseInfo *mi; + Kevdev *ke; - KdUnregisterFds (EvdevInputType, TRUE); - for (mi = kdMouseInfo; mi; mi = mi->next) - { - if (mi->inputType == EvdevInputType) - { - xfree (mi->driver); - mi->driver = 0; - mi->inputType = 0; - } - } + if (!pi || !pi->driverPrivate) + return; + + KdUnregisterFd (pi, ke->fd, TRUE); + xfree (ke); + pi->driverPrivate = 0; } -KdMouseFuncs LinuxEvdevMouseFuncs = { +static void +EvdevFini (KdPointerInfo *pi) +{ +} + +KdPointerDriver LinuxEvdevMouseDriver = { + "evdev", EvdevInit, + EvdevEnable, + EvdevDisable, EvdevFini, + NULL, }; #if 0 diff --git a/hw/kdrive/linux/keyboard.c b/hw/kdrive/linux/keyboard.c index cfafbb38f..9400e6b28 100644 --- a/hw/kdrive/linux/keyboard.c +++ b/hw/kdrive/linux/keyboard.c @@ -2,31 +2,40 @@ * $RCSId: xc/programs/Xserver/hw/kdrive/linux/keyboard.c,v 1.10 2001/11/08 10:26:24 keithp Exp $ * * Copyright © 1999 Keith Packard + * XKB integration © 2006 Nokia Corporation, author: Tomas Frydrych * - * Permission to use, copy, modify, distribute, and sell this software and its - * documentation for any purpose is hereby granted without fee, provided that - * the above copyright notice appear in all copies and that both that - * copyright notice and this permission notice appear in supporting - * documentation, and that the name of Keith Packard not be used in - * advertising or publicity pertaining to distribution of the software without - * specific, written prior permission. Keith Packard makes no - * representations about the suitability of this software for any purpose. It - * is provided "as is" without express or implied warranty. + * LinuxKeyboardRead() XKB code based on xf86KbdLnx.c: + * Copyright © 1990,91 by Thomas Roell, Dinkelscherben, Germany. + * Copyright © 1994-2001 by The XFree86 Project, Inc. * - * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, - * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO - * EVENT SHALL KEITH PACKARD BE LIABLE FOR 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. + * 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, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * 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. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of the copyright holder(s) + * and author(s) shall not be used in advertising or otherwise to promote + * the sale, use or other dealings in this Software without prior written + * authorization from the copyright holder(s) and author(s). */ #ifdef HAVE_CONFIG_H #include #endif #include "kdrive.h" -#include "kkeymap.h" #include #include #define XK_PUBLISHING @@ -34,7 +43,7 @@ #include #include -extern int LinuxConsoleFd; +extern int LinuxConsoleFd; static const KeySym linux_to_x[256] = { NoSymbol, NoSymbol, NoSymbol, NoSymbol, @@ -103,7 +112,108 @@ static const KeySym linux_to_x[256] = { XK_udiaeresis, XK_yacute, XK_thorn, XK_ydiaeresis }; -static unsigned char tbl[KD_MAX_WIDTH] = +#ifdef XKB +/* + * Getting a keycode from scancode + * + * With XKB + * -------- + * + * We have to enqueue keyboard events using standard X keycodes which correspond + * to AT scancode + 8; this means that we need to translate the Linux scancode + * provided by the kernel to an AT scancode -- this translation is not linear + * and requires that we use a LUT. + * + * + * Without XKB + * ----------- + * + * We can use custom keycodes, which makes things simpler; we define our custom + * keycodes as Linux scancodes + KD_KEY_OFFSET +*/ + +/* + This LUT translates AT scancodes into Linux ones -- the keymap we create + for the core X keyboard protocol has to be AT-scancode based so that it + corresponds to the Xkb keymap. +*/ +static unsigned char at2lnx[] = +{ + 0x0, /* no valid scancode */ + 0x01, /* KEY_Escape */ 0x02, /* KEY_1 */ + 0x03, /* KEY_2 */ 0x04, /* KEY_3 */ + 0x05, /* KEY_4 */ 0x06, /* KEY_5 */ + 0x07, /* KEY_6 */ 0x08, /* KEY_7 */ + 0x09, /* KEY_8 */ 0x0a, /* KEY_9 */ + 0x0b, /* KEY_0 */ 0x0c, /* KEY_Minus */ + 0x0d, /* KEY_Equal */ 0x0e, /* KEY_BackSpace */ + 0x0f, /* KEY_Tab */ 0x10, /* KEY_Q */ + 0x11, /* KEY_W */ 0x12, /* KEY_E */ + 0x13, /* KEY_R */ 0x14, /* KEY_T */ + 0x15, /* KEY_Y */ 0x16, /* KEY_U */ + 0x17, /* KEY_I */ 0x18, /* KEY_O */ + 0x19, /* KEY_P */ 0x1a, /* KEY_LBrace */ + 0x1b, /* KEY_RBrace */ 0x1c, /* KEY_Enter */ + 0x1d, /* KEY_LCtrl */ 0x1e, /* KEY_A */ + 0x1f, /* KEY_S */ 0x20, /* KEY_D */ + 0x21, /* KEY_F */ 0x22, /* KEY_G */ + 0x23, /* KEY_H */ 0x24, /* KEY_J */ + 0x25, /* KEY_K */ 0x26, /* KEY_L */ + 0x27, /* KEY_SemiColon */ 0x28, /* KEY_Quote */ + 0x29, /* KEY_Tilde */ 0x2a, /* KEY_ShiftL */ + 0x2b, /* KEY_BSlash */ 0x2c, /* KEY_Z */ + 0x2d, /* KEY_X */ 0x2e, /* KEY_C */ + 0x2f, /* KEY_V */ 0x30, /* KEY_B */ + 0x31, /* KEY_N */ 0x32, /* KEY_M */ + 0x33, /* KEY_Comma */ 0x34, /* KEY_Period */ + 0x35, /* KEY_Slash */ 0x36, /* KEY_ShiftR */ + 0x37, /* KEY_KP_Multiply */ 0x38, /* KEY_Alt */ + 0x39, /* KEY_Space */ 0x3a, /* KEY_CapsLock */ + 0x3b, /* KEY_F1 */ 0x3c, /* KEY_F2 */ + 0x3d, /* KEY_F3 */ 0x3e, /* KEY_F4 */ + 0x3f, /* KEY_F5 */ 0x40, /* KEY_F6 */ + 0x41, /* KEY_F7 */ 0x42, /* KEY_F8 */ + 0x43, /* KEY_F9 */ 0x44, /* KEY_F10 */ + 0x45, /* KEY_NumLock */ 0x46, /* KEY_ScrollLock */ + 0x47, /* KEY_KP_7 */ 0x48, /* KEY_KP_8 */ + 0x49, /* KEY_KP_9 */ 0x4a, /* KEY_KP_Minus */ + 0x4b, /* KEY_KP_4 */ 0x4c, /* KEY_KP_5 */ + 0x4d, /* KEY_KP_6 */ 0x4e, /* KEY_KP_Plus */ + 0x4f, /* KEY_KP_1 */ 0x50, /* KEY_KP_2 */ + 0x51, /* KEY_KP_3 */ 0x52, /* KEY_KP_0 */ + 0x53, /* KEY_KP_Decimal */ 0x54, /* KEY_SysReqest */ + 0x00, /* 0x55 */ 0x56, /* KEY_Less */ + 0x57, /* KEY_F11 */ 0x58, /* KEY_F12 */ + 0x66, /* KEY_Home */ 0x67, /* KEY_Up */ + 0x68, /* KEY_PgUp */ 0x69, /* KEY_Left */ + 0x5d, /* KEY_Begin */ 0x6a, /* KEY_Right */ + 0x6b, /* KEY_End */ 0x6c, /* KEY_Down */ + 0x6d, /* KEY_PgDown */ 0x6e, /* KEY_Insert */ + 0x6f, /* KEY_Delete */ 0x60, /* KEY_KP_Enter */ + 0x61, /* KEY_RCtrl */ 0x77, /* KEY_Pause */ + 0x63, /* KEY_Print */ 0x62, /* KEY_KP_Divide */ + 0x64, /* KEY_AltLang */ 0x65, /* KEY_Break */ + 0x00, /* KEY_LMeta */ 0x00, /* KEY_RMeta */ + 0x7A, /* KEY_Menu/FOCUS_PF11*/0x00, /* 0x6e */ + 0x7B, /* FOCUS_PF12 */ 0x00, /* 0x70 */ + 0x00, /* 0x71 */ 0x00, /* 0x72 */ + 0x59, /* FOCUS_PF2 */ 0x78, /* FOCUS_PF9 */ + 0x00, /* 0x75 */ 0x00, /* 0x76 */ + 0x5A, /* FOCUS_PF3 */ 0x5B, /* FOCUS_PF4 */ + 0x5C, /* FOCUS_PF5 */ 0x5D, /* FOCUS_PF6 */ + 0x5E, /* FOCUS_PF7 */ 0x5F, /* FOCUS_PF8 */ + 0x7C, /* JAP_86 */ 0x79, /* FOCUS_PF10 */ + 0x00, /* 0x7f */ +}; + +#define NUM_AT_KEYS (sizeof(at2lnx)/sizeof(at2lnx[0])) +#define LNX_KEY_INDEX(n) n < NUM_AT_KEYS ? at2lnx[n] : 0 + +#else /* not XKB */ +#define LNX_KEY_INDEX(n) n +#endif + +static unsigned char tbl[KD_MAX_WIDTH] = { 0, 1 << KG_SHIFT, @@ -112,24 +222,31 @@ static unsigned char tbl[KD_MAX_WIDTH] = }; static void -readKernelMapping(void) +readKernelMapping(KdKeyboardInfo *ki) { KeySym *k; int i, j; struct kbentry kbe; int minKeyCode, maxKeyCode; int row; + int fd; + if (!ki) + return; + + fd = LinuxConsoleFd; + minKeyCode = NR_KEYS; maxKeyCode = 0; row = 0; + ki->keySyms.mapWidth = KD_MAX_WIDTH; for (i = 0; i < NR_KEYS && row < KD_MAX_LENGTH; ++i) { - kbe.kb_index = i; + kbe.kb_index = LNX_KEY_INDEX(i); - k = kdKeymap + row * KD_MAX_WIDTH; + k = ki->keySyms.map + row * ki->keySyms.mapWidth; - for (j = 0; j < KD_MAX_WIDTH; ++j) + for (j = 0; j < ki->keySyms.mapWidth; ++j) { unsigned short kval; @@ -137,7 +254,7 @@ readKernelMapping(void) kbe.kb_table = tbl[j]; kbe.kb_value = 0; - if (ioctl(LinuxConsoleFd, KDGKBENT, &kbe)) + if (ioctl(fd, KDGKBENT, &kbe)) continue; kval = KVAL(kbe.kb_value); @@ -362,7 +479,7 @@ readKernelMapping(void) if (minKeyCode == NR_KEYS) continue; - + if (k[3] == k[2]) k[3] = NoSymbol; if (k[2] == k[1]) k[2] = NoSymbol; if (k[1] == k[0]) k[1] = NoSymbol; @@ -370,28 +487,212 @@ readKernelMapping(void) if (k[3] == k[0] && k[2] == k[1] && k[2] == NoSymbol) k[3] =NoSymbol; row++; } - kdMinScanCode = minKeyCode; - kdMaxScanCode = maxKeyCode; + ki->minScanCode = minKeyCode; + ki->maxScanCode = maxKeyCode; } -static void -LinuxKeyboardLoad (void) -{ - readKernelMapping (); -} +#ifdef XKB + +/* + * We need these to handle extended scancodes correctly (I could just use the + * numbers below, but this makes the code more readable + */ + +/* The prefix codes */ +#define KEY_Prefix0 /* special 0x60 */ 96 +#define KEY_Prefix1 /* special 0x61 */ 97 + +/* The raw scancodes */ +#define KEY_Enter /* Enter 0x1c */ 28 +#define KEY_LCtrl /* Ctrl(left) 0x1d */ 29 +#define KEY_Slash /* / (Slash) ? 0x35 */ 53 +#define KEY_KP_Multiply /* * 0x37 */ 55 +#define KEY_Alt /* Alt(left) 0x38 */ 56 +#define KEY_F3 /* F3 0x3d */ 61 +#define KEY_F4 /* F4 0x3e */ 62 +#define KEY_F5 /* F5 0x3f */ 63 +#define KEY_F6 /* F6 0x40 */ 64 +#define KEY_F7 /* F7 0x41 */ 65 +#define KEY_ScrollLock /* ScrollLock 0x46 */ 70 +#define KEY_KP_7 /* 7 Home 0x47 */ 71 +#define KEY_KP_8 /* 8 Up 0x48 */ 72 +#define KEY_KP_9 /* 9 PgUp 0x49 */ 73 +#define KEY_KP_Minus /* - (Minus) 0x4a */ 74 +#define KEY_KP_4 /* 4 Left 0x4b */ 75 +#define KEY_KP_5 /* 5 0x4c */ 76 +#define KEY_KP_6 /* 6 Right 0x4d */ 77 +#define KEY_KP_Plus /* + (Plus) 0x4e */ 78 +#define KEY_KP_1 /* 1 End 0x4f */ 79 +#define KEY_KP_2 /* 2 Down 0x50 */ 80 +#define KEY_KP_3 /* 3 PgDown 0x51 */ 81 +#define KEY_KP_0 /* 0 Insert 0x52 */ 82 +#define KEY_KP_Decimal /* . (Decimal) Delete 0x53 */ 83 +#define KEY_Home /* Home 0x59 */ 89 +#define KEY_Up /* Up 0x5a */ 90 +#define KEY_PgUp /* PgUp 0x5b */ 91 +#define KEY_Left /* Left 0x5c */ 92 +#define KEY_Begin /* Begin 0x5d */ 93 +#define KEY_Right /* Right 0x5e */ 94 +#define KEY_End /* End 0x5f */ 95 +#define KEY_Down /* Down 0x60 */ 96 +#define KEY_PgDown /* PgDown 0x61 */ 97 +#define KEY_Insert /* Insert 0x62 */ 98 +#define KEY_Delete /* Delete 0x63 */ 99 +#define KEY_KP_Enter /* Enter 0x64 */ 100 +#define KEY_RCtrl /* Ctrl(right) 0x65 */ 101 +#define KEY_Pause /* Pause 0x66 */ 102 +#define KEY_Print /* Print 0x67 */ 103 +#define KEY_KP_Divide /* Divide 0x68 */ 104 +#define KEY_AltLang /* AtlLang(right) 0x69 */ 105 +#define KEY_Break /* Break 0x6a */ 106 +#define KEY_LMeta /* Left Meta 0x6b */ 107 +#define KEY_RMeta /* Right Meta 0x6c */ 108 +#define KEY_Menu /* Menu 0x6d */ 109 +#define KEY_F13 /* F13 0x6e */ 110 +#define KEY_F14 /* F14 0x6f */ 111 +#define KEY_F15 /* F15 0x70 */ 112 +#define KEY_F16 /* F16 0x71 */ 113 +#define KEY_F17 /* F17 0x72 */ 114 +#define KEY_KP_DEC /* KP_DEC 0x73 */ 115 + +#endif /* XKB */ + static void LinuxKeyboardRead (int fd, void *closure) { unsigned char buf[256], *b; int n; + unsigned char prefix = 0, scancode = 0; - while ((n = read (fd, buf, sizeof (buf))) > 0) - { + while ((n = read (fd, buf, sizeof (buf))) > 0) { b = buf; - while (n--) - { - KdEnqueueKeyboardEvent (b[0] & 0x7f, b[0] & 0x80); + while (n--) { +#ifdef XKB + if (!noXkbExtension) { + /* + * With xkb we use RAW mode for reading the console, which allows us + * process extended scancodes. + * + * See if this is a prefix extending the following keycode + */ + if (!prefix && ((b[0] & 0x7f) == KEY_Prefix0)) + { + prefix = KEY_Prefix0; + ErrorF("Prefix0"); + /* swallow this up */ + b++; + continue; + } + else if (!prefix && ((b[0] & 0x7f) == KEY_Prefix1)) + { + prefix = KEY_Prefix1; + ErrorF("Prefix1"); + /* swallow this up */ + b++; + continue; + } + scancode = b[0] & 0x7f; + + switch (prefix) { + /* from xf86Events.c */ + case KEY_Prefix0: + { + ErrorF("Prefix0 scancode: 0x%02x\n", scancode); + switch (scancode) { + case KEY_KP_7: + scancode = KEY_Home; break; /* curs home */ + case KEY_KP_8: + scancode = KEY_Up; break; /* curs up */ + case KEY_KP_9: + scancode = KEY_PgUp; break; /* curs pgup */ + case KEY_KP_4: + scancode = KEY_Left; break; /* curs left */ + case KEY_KP_5: + scancode = KEY_Begin; break; /* curs begin */ + case KEY_KP_6: + scancode = KEY_Right; break; /* curs right */ + case KEY_KP_1: + scancode = KEY_End; break; /* curs end */ + case KEY_KP_2: + scancode = KEY_Down; break; /* curs down */ + case KEY_KP_3: + scancode = KEY_PgDown; break; /* curs pgdown */ + case KEY_KP_0: + scancode = KEY_Insert; break; /* curs insert */ + case KEY_KP_Decimal: + scancode = KEY_Delete; break; /* curs delete */ + case KEY_Enter: + scancode = KEY_KP_Enter; break; /* keypad enter */ + case KEY_LCtrl: + scancode = KEY_RCtrl; break; /* right ctrl */ + case KEY_KP_Multiply: + scancode = KEY_Print; break; /* print */ + case KEY_Slash: + scancode = KEY_KP_Divide; break; /* keyp divide */ + case KEY_Alt: + scancode = KEY_AltLang; break; /* right alt */ + case KEY_ScrollLock: + scancode = KEY_Break; break; /* curs break */ + case 0x5b: + scancode = KEY_LMeta; break; + case 0x5c: + scancode = KEY_RMeta; break; + case 0x5d: + scancode = KEY_Menu; break; + case KEY_F3: + scancode = KEY_F13; break; + case KEY_F4: + scancode = KEY_F14; break; + case KEY_F5: + scancode = KEY_F15; break; + case KEY_F6: + scancode = KEY_F16; break; + case KEY_F7: + scancode = KEY_F17; break; + case KEY_KP_Plus: + scancode = KEY_KP_DEC; break; + /* Ignore virtual shifts (E0 2A, E0 AA, E0 36, E0 B6) */ + case 0x2A: + case 0x36: + b++; + prefix = 0; + continue; + default: + ErrorF("Unreported Prefix0 scancode: 0x%02x\n", + scancode); + /* + * "Internet" keyboards are generating lots of new + * codes. Let them pass. There is little consistency + * between them, so don't bother with symbolic names at + * this level. + */ + scancode += 0x78; + } + break; + } + + case KEY_Prefix1: + { + /* we do no handle these */ + ErrorF("Prefix1 scancode: 0x%02x\n", scancode); + b++; + prefix = 0; + continue; + } + + default: /* should not happen*/ + case 0: /* do nothing */ + ErrorF("Plain scancode: 0x%02x\n", scancode); + } + + prefix = 0; + } + /* without xkb we use mediumraw mode -- enqueue the scancode as is */ + else +#endif + scancode = b[0] & 0x7f; + KdEnqueueKeyboardEvent (closure, scancode, b[0] & 0x80); b++; } } @@ -399,19 +700,30 @@ LinuxKeyboardRead (int fd, void *closure) static int LinuxKbdTrans; static struct termios LinuxTermios; -static int LinuxKbdType; -static int -LinuxKeyboardEnable (int fd, void *closure) +static Status +LinuxKeyboardEnable (KdKeyboardInfo *ki) { struct termios nTty; unsigned char buf[256]; int n; + int fd; + + if (!ki) + return !Success; + + fd = LinuxConsoleFd; + ki->driverPrivate = (void *) fd; ioctl (fd, KDGKBMODE, &LinuxKbdTrans); tcgetattr (fd, &LinuxTermios); - - ioctl(fd, KDSKBMODE, K_MEDIUMRAW); +#ifdef XKB + if (!noXkbExtension) + ioctl(fd, KDSKBMODE, K_RAW); + else +#else + ioctl(fd, KDSKBMODE, K_MEDIUMRAW); +#endif nTty = LinuxTermios; nTty.c_iflag = (IGNPAR | IGNBRK) & (~PARMRK) & (~ISTRIP); nTty.c_oflag = 0; @@ -422,54 +734,74 @@ LinuxKeyboardEnable (int fd, void *closure) cfsetispeed(&nTty, 9600); cfsetospeed(&nTty, 9600); tcsetattr(fd, TCSANOW, &nTty); + /* Our kernel cleverly ignores O_NONBLOCK. Sigh. */ +#if 0 /* * Flush any pending keystrokes */ while ((n = read (fd, buf, sizeof (buf))) > 0) ; - return fd; +#endif + KdRegisterFd (fd, LinuxKeyboardRead, ki); + return Success; } static void -LinuxKeyboardDisable (int fd, void *closure) +LinuxKeyboardDisable (KdKeyboardInfo *ki) { - ioctl(LinuxConsoleFd, KDSKBMODE, LinuxKbdTrans); - tcsetattr(LinuxConsoleFd, TCSANOW, &LinuxTermios); + int fd; + + if (!ki) + return; + + fd = (int) ki->driverPrivate; + + KdUnregisterFd(ki, fd, FALSE); + ioctl(fd, KDSKBMODE, LinuxKbdTrans); + tcsetattr(fd, TCSANOW, &LinuxTermios); } -static int -LinuxKeyboardInit (void) +static Status +LinuxKeyboardInit (KdKeyboardInfo *ki) { - if (!LinuxKbdType) - LinuxKbdType = KdAllocInputType (); + if (!ki) + return !Success; - KdRegisterFd (LinuxKbdType, LinuxConsoleFd, LinuxKeyboardRead, 0); - LinuxKeyboardEnable (LinuxConsoleFd, 0); - KdRegisterFdEnableDisable (LinuxConsoleFd, - LinuxKeyboardEnable, - LinuxKeyboardDisable); - return 1; + if (ki->path) + xfree(ki->path); + ki->path = KdSaveString("console"); + if (ki->name) + xfree(ki->name); + ki->name = KdSaveString("Linux console keyboard"); + + readKernelMapping (ki); + + return Success; } static void -LinuxKeyboardFini (void) +LinuxKeyboardFini (KdKeyboardInfo *ki) { - LinuxKeyboardDisable (LinuxConsoleFd, 0); - KdUnregisterFds (LinuxKbdType, FALSE); } static void -LinuxKeyboardLeds (int leds) +LinuxKeyboardLeds (KdKeyboardInfo *ki, int leds) { - ioctl (LinuxConsoleFd, KDSETLED, leds & 7); + if (!ki) + return; + + ioctl ((int)ki->driverPrivate, KDSETLED, leds & 7); } static void -LinuxKeyboardBell (int volume, int pitch, int duration) +LinuxKeyboardBell (KdKeyboardInfo *ki, int volume, int pitch, int duration) { + if (!ki) + return; + if (volume && pitch) { - ioctl(LinuxConsoleFd, KDMKTONE, + ioctl((int)ki->driverPrivate, KDMKTONE, ((1193190 / pitch) & 0xffff) | (((unsigned long)duration * volume / 50) << 16)); @@ -477,11 +809,13 @@ LinuxKeyboardBell (int volume, int pitch, int duration) } } -KdKeyboardFuncs LinuxKeyboardFuncs = { - LinuxKeyboardLoad, +KdKeyboardDriver LinuxKeyboardDriver = { + "keyboard", LinuxKeyboardInit, + LinuxKeyboardEnable, LinuxKeyboardLeds, LinuxKeyboardBell, + LinuxKeyboardDisable, LinuxKeyboardFini, - 3, + NULL, }; diff --git a/hw/kdrive/linux/linux.c b/hw/kdrive/linux/linux.c index be11ec539..e75f8d55b 100644 --- a/hw/kdrive/linux/linux.c +++ b/hw/kdrive/linux/linux.c @@ -456,6 +456,7 @@ LinuxFini (void) } } close(LinuxConsoleFd); /* make the vt-manager happy */ + LinuxConsoleFd = -1; fd = open ("/dev/tty0", O_RDWR|O_NDELAY, 0); if (fd >= 0) { diff --git a/hw/kdrive/linux/mouse.c b/hw/kdrive/linux/mouse.c index 5fe997864..77ec3b37b 100644 --- a/hw/kdrive/linux/mouse.c +++ b/hw/kdrive/linux/mouse.c @@ -206,10 +206,10 @@ MouseWriteBytes (int fd, unsigned char *c, int n, int timeout) typedef struct _kmouseProt { char *name; - Bool (*Complete) (KdMouseInfo *mi, unsigned char *ev, int ne); - int (*Valid) (KdMouseInfo *mi, unsigned char *ev, int ne); - Bool (*Parse) (KdMouseInfo *mi, unsigned char *ev, int ne); - Bool (*Init) (KdMouseInfo *mi); + Bool (*Complete) (KdPointerInfo *pi, unsigned char *ev, int ne); + int (*Valid) (KdPointerInfo *pi, unsigned char *ev, int ne); + Bool (*Parse) (KdPointerInfo *pi, unsigned char *ev, int ne); + Bool (*Init) (KdPointerInfo *pi); unsigned char headerMask, headerValid; unsigned char dataMask, dataValid; Bool tty; @@ -238,9 +238,9 @@ typedef struct _kmouse { unsigned long state; /* private per protocol, init to prot->state */ } Kmouse; -static int mouseValid (KdMouseInfo *mi, unsigned char *ev, int ne) +static int mouseValid (KdPointerInfo *pi, unsigned char *ev, int ne) { - Kmouse *km = mi->driver; + Kmouse *km = pi->driverPrivate; const KmouseProt *prot = km->prot; int i; @@ -255,24 +255,24 @@ static int mouseValid (KdMouseInfo *mi, unsigned char *ev, int ne) return 0; } -static Bool threeComplete (KdMouseInfo *mi, unsigned char *ev, int ne) +static Bool threeComplete (KdPointerInfo *pi, unsigned char *ev, int ne) { return ne == 3; } -static Bool fourComplete (KdMouseInfo *mi, unsigned char *ev, int ne) +static Bool fourComplete (KdPointerInfo *pi, unsigned char *ev, int ne) { return ne == 4; } -static Bool fiveComplete (KdMouseInfo *mi, unsigned char *ev, int ne) +static Bool fiveComplete (KdPointerInfo *pi, unsigned char *ev, int ne) { return ne == 5; } -static Bool MouseReasonable (KdMouseInfo *mi, unsigned long flags, int dx, int dy) +static Bool MouseReasonable (KdPointerInfo *pi, unsigned long flags, int dx, int dy) { - Kmouse *km = mi->driver; + Kmouse *km = pi->driverPrivate; if (km->stage == MouseWorking) return TRUE; @@ -296,9 +296,9 @@ static Bool MouseReasonable (KdMouseInfo *mi, unsigned long flags, int dx, int d /* * Standard PS/2 mouse protocol */ -static Bool ps2Parse (KdMouseInfo *mi, unsigned char *ev, int ne) +static Bool ps2Parse (KdPointerInfo *pi, unsigned char *ev, int ne) { - Kmouse *km = mi->driver; + Kmouse *km = pi->driverPrivate; int dx, dy, dz; unsigned long flags; unsigned long flagsrelease = 0; @@ -333,21 +333,21 @@ static Bool ps2Parse (KdMouseInfo *mi, unsigned char *ev, int ne) if (ev[0] & 0x20) dy -= 256; dy = -dy; - if (!MouseReasonable (mi, flags, dx, dy)) + if (!MouseReasonable (pi, flags, dx, dy)) return FALSE; if (km->stage == MouseWorking) { - KdEnqueueMouseEvent (mi, flags, dx, dy); + KdEnqueuePointerEvent (pi, flags, dx, dy, 0); if (flagsrelease) { flags &= ~flagsrelease; - KdEnqueueMouseEvent (mi, flags, dx, dy); + KdEnqueuePointerEvent (pi, flags, dx, dy, 0); } } return TRUE; } -static Bool ps2Init (KdMouseInfo *mi); +static Bool ps2Init (KdPointerInfo *pi); static const KmouseProt ps2Prot = { "ps/2", @@ -450,9 +450,9 @@ static unsigned char intelli_init[] = { #define NINIT_INTELLI 3 static int -ps2SkipInit (KdMouseInfo *mi, int ninit, Bool ret_next) +ps2SkipInit (KdPointerInfo *pi, int ninit, Bool ret_next) { - Kmouse *km = mi->driver; + Kmouse *km = pi->driverPrivate; int c = -1; int skipping; Bool waiting; @@ -481,9 +481,9 @@ ps2SkipInit (KdMouseInfo *mi, int ninit, Bool ret_next) } static Bool -ps2Init (KdMouseInfo *mi) +ps2Init (KdPointerInfo *pi) { - Kmouse *km = mi->driver; + Kmouse *km = pi->driverPrivate; int skipping; Bool waiting; int id; @@ -499,7 +499,7 @@ ps2Init (KdMouseInfo *mi) return FALSE; skipping = 0; waiting = FALSE; - id = ps2SkipInit (mi, 0, TRUE); + id = ps2SkipInit (pi, 0, TRUE); switch (id) { case 3: init = wheel_3button_init; @@ -524,13 +524,13 @@ ps2Init (KdMouseInfo *mi) * initialization string. Make sure any partial event is * skipped */ - (void) ps2SkipInit (mi, ninit, FALSE); + (void) ps2SkipInit (pi, ninit, FALSE); return TRUE; } -static Bool busParse (KdMouseInfo *mi, unsigned char *ev, int ne) +static Bool busParse (KdPointerInfo *pi, unsigned char *ev, int ne) { - Kmouse *km = mi->driver; + Kmouse *km = pi->driverPrivate; int dx, dy; unsigned long flags; @@ -543,10 +543,10 @@ static Bool busParse (KdMouseInfo *mi, unsigned char *ev, int ne) flags |= KD_BUTTON_2; if ((ev[0] & 1) == 0) flags |= KD_BUTTON_3; - if (!MouseReasonable (mi, flags, dx, dy)) + if (!MouseReasonable (pi, flags, dx, dy)) return FALSE; if (km->stage == MouseWorking) - KdEnqueueMouseEvent (mi, flags, dx, dy); + KdEnqueuePointerEvent (pi, flags, dx, dy, 0); return TRUE; } @@ -561,9 +561,9 @@ static const KmouseProt busProt = { * Standard MS serial protocol, three bytes */ -static Bool msParse (KdMouseInfo *mi, unsigned char *ev, int ne) +static Bool msParse (KdPointerInfo *pi, unsigned char *ev, int ne) { - Kmouse *km = mi->driver; + Kmouse *km = pi->driverPrivate; int dx, dy; unsigned long flags; @@ -576,10 +576,10 @@ static Bool msParse (KdMouseInfo *mi, unsigned char *ev, int ne) dx = (signed char)(((ev[0] & 0x03) << 6) | (ev[1] & 0x3F)); dy = (signed char)(((ev[0] & 0x0C) << 4) | (ev[2] & 0x3F)); - if (!MouseReasonable (mi, flags, dx, dy)) + if (!MouseReasonable (pi, flags, dx, dy)) return FALSE; if (km->stage == MouseWorking) - KdEnqueueMouseEvent (mi, flags, dx, dy); + KdEnqueuePointerEvent (pi, flags, dx, dy, 0); return TRUE; } @@ -600,9 +600,9 @@ static const KmouseProt msProt = { * first byte of a synchronized protocol stream and see if it's got * any bits turned on that can't occur in that fourth byte */ -static Bool logiComplete (KdMouseInfo *mi, unsigned char *ev, int ne) +static Bool logiComplete (KdPointerInfo *pi, unsigned char *ev, int ne) { - Kmouse *km = mi->driver; + Kmouse *km = pi->driverPrivate; if ((ev[0] & 0x40) == 0x40) return ne == 3; @@ -611,9 +611,9 @@ static Bool logiComplete (KdMouseInfo *mi, unsigned char *ev, int ne) return FALSE; } -static int logiValid (KdMouseInfo *mi, unsigned char *ev, int ne) +static int logiValid (KdPointerInfo *pi, unsigned char *ev, int ne) { - Kmouse *km = mi->driver; + Kmouse *km = pi->driverPrivate; const KmouseProt *prot = km->prot; int i; @@ -632,9 +632,9 @@ static int logiValid (KdMouseInfo *mi, unsigned char *ev, int ne) return 0; } -static Bool logiParse (KdMouseInfo *mi, unsigned char *ev, int ne) +static Bool logiParse (KdPointerInfo *pi, unsigned char *ev, int ne) { - Kmouse *km = mi->driver; + Kmouse *km = pi->driverPrivate; int dx, dy; unsigned long flags; @@ -660,10 +660,10 @@ static Bool logiParse (KdMouseInfo *mi, unsigned char *ev, int ne) flags |= km->state & (KD_BUTTON_1|KD_BUTTON_3); } - if (!MouseReasonable (mi, flags, dx, dy)) + if (!MouseReasonable (pi, flags, dx, dy)) return FALSE; if (km->stage == MouseWorking) - KdEnqueueMouseEvent (mi, flags, dx, dy); + KdEnqueuePointerEvent (pi, flags, dx, dy, 0); return TRUE; } @@ -682,9 +682,9 @@ static const KmouseProt logiProt = { /* * Mouse systems protocol, 5 bytes */ -static Bool mscParse (KdMouseInfo *mi, unsigned char *ev, int ne) +static Bool mscParse (KdPointerInfo *pi, unsigned char *ev, int ne) { - Kmouse *km = mi->driver; + Kmouse *km = pi->driverPrivate; int dx, dy; unsigned long flags; @@ -699,10 +699,10 @@ static Bool mscParse (KdMouseInfo *mi, unsigned char *ev, int ne) dx = (signed char)(ev[1]) + (signed char)(ev[3]); dy = - ((signed char)(ev[2]) + (signed char)(ev[4])); - if (!MouseReasonable (mi, flags, dx, dy)) + if (!MouseReasonable (pi, flags, dx, dy)) return FALSE; if (km->stage == MouseWorking) - KdEnqueueMouseEvent (mi, flags, dx, dy); + KdEnqueuePointerEvent (pi, flags, dx, dy, 0); return TRUE; } @@ -810,8 +810,8 @@ MouseNextProtocol (Kmouse *km) static void MouseRead (int mousePort, void *closure) { - KdMouseInfo *mi = closure; - Kmouse *km = mi->driver; + KdPointerInfo *pi = closure; + Kmouse *km = pi->driverPrivate; unsigned char event[MAX_MOUSE]; int ne; int c; @@ -835,7 +835,7 @@ MouseRead (int mousePort, void *closure) break; } event[ne++] = c; - i = (*km->prot->Valid) (mi, event, ne); + i = (*km->prot->Valid) (pi, event, ne); if (i != 0) { #ifdef DEBUG @@ -867,9 +867,9 @@ MouseRead (int mousePort, void *closure) } else { - if ((*km->prot->Complete) (mi, event, ne)) + if ((*km->prot->Complete) (pi, event, ne)) { - if ((*km->prot->Parse) (mi, event, ne)) + if ((*km->prot->Parse) (pi, event, ne)) { switch (km->stage) { @@ -896,7 +896,7 @@ MouseRead (int mousePort, void *closure) km->invalid = 0; km->tested = 0; km->valid = 0; - if (km->prot->Init && !(*km->prot->Init) (mi)) + if (km->prot->Init && !(*km->prot->Init) (pi)) km->stage = MouseBroken; } break; @@ -923,9 +923,9 @@ MouseRead (int mousePort, void *closure) int MouseInputType; char *kdefaultMouse[] = { + "/dev/input/mice", "/dev/mouse", "/dev/psaux", - "/dev/input/mice", "/dev/adbmouse", "/dev/ttyS0", "/dev/ttyS1", @@ -933,81 +933,97 @@ char *kdefaultMouse[] = { #define NUM_DEFAULT_MOUSE (sizeof (kdefaultMouse) / sizeof (kdefaultMouse[0])) -static Bool -MouseInit (void) +static Status +MouseInit (KdPointerInfo *pi) { int i; int fd; Kmouse *km; - KdMouseInfo *mi, *next; - int n = 0; - char *prot; - if (!MouseInputType) - MouseInputType = KdAllocInputType (); - - for (mi = kdMouseInfo; mi; mi = next) - { - next = mi->next; - prot = mi->prot; - if (mi->inputType) - continue; - if (!mi->name) - { - for (i = 0; i < NUM_DEFAULT_MOUSE; i++) - { - fd = open (kdefaultMouse[i], 2); - if (fd >= 0) - { - mi->name = KdSaveString (kdefaultMouse[i]); - break; - } - } - } - else - fd = open (mi->name, 2); - - if (fd >= 0) - { - km = (Kmouse *) xalloc (sizeof (Kmouse)); - if (km) - { - km->iob.fd = fd; - km->iob.avail = km->iob.used = 0; - km->prot = 0; - km->i_prot = 0; - km->tty = isatty (fd); - mi->driver = km; - mi->inputType = MouseInputType; - MouseFirstProtocol (km, mi->prot); - if (KdRegisterFd (MouseInputType, fd, MouseRead, (void *) mi)) - n++; - } - else - close (fd); - } + if (!pi) + return BadImplementation; + + if (!pi->path || strcmp(pi->path, "auto") == 0) { + for (i = 0; i < NUM_DEFAULT_MOUSE; i++) { + fd = open (kdefaultMouse[i], 2); + if (fd >= 0) { + pi->path = KdSaveString (kdefaultMouse[i]); + break; + } + } } - return TRUE; + else { + fd = open (pi->path, 2); + } + + if (fd < 0) + return BadMatch; + + close(fd); + + km = (Kmouse *) xalloc (sizeof (Kmouse)); + if (km) { + km->iob.avail = km->iob.used = 0; + MouseFirstProtocol(km, "exps/2"); + km->i_prot = 0; + km->tty = isatty (fd); + km->iob.fd = -1; + pi->driverPrivate = km; + } + else { + close (fd); + return BadAlloc; + } + + return Success; +} + +static Status +MouseEnable (KdPointerInfo *pi) +{ + Kmouse *km; + + if (!pi || !pi->driverPrivate || !pi->path) + return BadImplementation; + + km = pi->driverPrivate; + + km->iob.fd = open(pi->path, 2); + if (km->iob.fd < 0) + return BadMatch; + + if (!KdRegisterFd (km->iob.fd, MouseRead, pi)) + { + close(km->iob.fd); + return BadAlloc; + } + + return Success; } static void -MouseFini (void) +MouseDisable (KdPointerInfo *pi) { - KdMouseInfo *mi; - - KdUnregisterFds (MouseInputType, TRUE); - for (mi = kdMouseInfo; mi; mi = mi->next) - { - if (mi->inputType == MouseInputType) - { - xfree (mi->driver); - mi->driver = 0; - mi->inputType = 0; - } - } + Kmouse *km; + if (!pi || !pi->driverPrivate) + return; + + km = pi->driverPrivate; + KdUnregisterFd (pi, km->iob.fd, TRUE); } -KdMouseFuncs LinuxMouseFuncs = { +static void +MouseFini (KdPointerInfo *pi) +{ + xfree (pi->driverPrivate); + pi->driverPrivate = NULL; +} + +KdPointerDriver LinuxMouseDriver = { + "mouse", MouseInit, + MouseEnable, + MouseDisable, MouseFini, + NULL, }; diff --git a/hw/kdrive/linux/ms.c b/hw/kdrive/linux/ms.c index 7f046bdc3..e62cebc39 100644 --- a/hw/kdrive/linux/ms.c +++ b/hw/kdrive/linux/ms.c @@ -90,41 +90,50 @@ MsRead (int port, void *closure) dy = (char)(((b[0] & 0x0C) << 4) | (b[2] & 0x3F)); n -= 3; b += 3; - KdEnqueueMouseEvent (kdMouseInfo, flags, dx, dy); + KdEnqueuePointerEvent (closure, flags, dx, dy, 0); } } } -int MsInputType; +static Status +MsInit (KdPointerInfo *pi) +{ + if (!pi) + return BadImplementation; -static int -MsInit (void) + if (!pi->path || strcmp(pi->path, "auto")) + pi->path = KdSaveString("/dev/mouse"); + if (!pi->name) + pi->name = KdSaveString("Microsoft protocol mouse"); + + return Success; +} + +static Status +MsEnable (KdPointerInfo *pi) { int port; - char *device = "/dev/mouse"; struct termios t; int ret; - if (!MsInputType) - MsInputType = KdAllocInputType (); - port = open (device, O_RDWR | O_NONBLOCK); + port = open (pi->path, O_RDWR | O_NONBLOCK); if(port < 0) { - ErrorF("Couldn't open %s (%d)\n", device, (int)errno); + ErrorF("Couldn't open %s (%d)\n", pi->path, (int)errno); return 0; } else if (port == 0) { ErrorF("Opening %s returned 0! Please complain to Keith.\n", - device); + pi->path); goto bail; } if(!isatty(port)) { - ErrorF("%s is not a tty\n", device); + ErrorF("%s is not a tty\n", pi->path); goto bail; } ret = tcgetattr(port, &t); if(ret < 0) { - ErrorF("Couldn't tcgetattr(%s): %d\n", device, errno); + ErrorF("Couldn't tcgetattr(%s): %d\n", pi->path, errno); goto bail; } t.c_iflag &= ~ (IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | @@ -140,24 +149,36 @@ MsInit (void) t.c_cc[VTIME] = 0; ret = tcsetattr(port, TCSANOW, &t); if(ret < 0) { - ErrorF("Couldn't tcsetattr(%s): %d\n", device, errno); + ErrorF("Couldn't tcsetattr(%s): %d\n", pi->path, errno); goto bail; } - if (KdRegisterFd (MsInputType, port, MsRead, (void *) 0)) - return 1; + if (KdRegisterFd (port, MsRead, pi)) + return TRUE; + pi->driverPrivate = (void *)port; + + return Success; bail: close(port); - return 0; + return BadMatch; } static void -MsFini (void) +MsDisable (KdPointerInfo *pi) { - KdUnregisterFds (MsInputType, TRUE); + KdUnregisterFd (pi, (int)pi->driverPrivate, TRUE); } -KdMouseFuncs MsMouseFuncs = { +static void +MsFini (KdPointerInfo *pi) +{ +} + +KdPointerDriver MsMouseDriver = { + "ms", MsInit, - MsFini + MsEnable, + MsDisable, + MsFini, + NULL, }; diff --git a/hw/kdrive/linux/ps2.c b/hw/kdrive/linux/ps2.c index b59dbfac7..5d523a210 100644 --- a/hw/kdrive/linux/ps2.c +++ b/hw/kdrive/linux/ps2.c @@ -112,42 +112,78 @@ Ps2Read (int ps2Port, void *closure) dy = -dy; n -= 3; b += 3; - KdEnqueueMouseEvent (kdMouseInfo, flags, dx, dy); + KdEnqueuePointerEvent (closure, flags, dx, dy, 0); } } } -int Ps2InputType; - -static int -Ps2Init (void) +static Status +Ps2Init (KdPointerInfo *pi) { - int i; - int ps2Port; - int n; + int ps2Port, i; - if (!Ps2InputType) - Ps2InputType = KdAllocInputType (); - n = 0; - for (i = 0; i < NUM_PS2_NAMES; i++) - { - ps2Port = open (Ps2Names[i], 0); - if (ps2Port >= 0) - { - if (KdRegisterFd (Ps2InputType, ps2Port, Ps2Read, (void *) i)) - n++; + if (!pi->path) { + for (i = 0; i < NUM_PS2_NAMES; i++) { + ps2Port = open (Ps2Names[i], 0); + if (ps2Port >= 0) { + pi->path = KdSaveString (Ps2Names[i]); + break; + } } } - return n; + else { + ps2Port = open (pi->path, 0); + } + + if (ps2Port < 0) + return BadMatch; + + close(ps2Port); + if (!pi->name) + pi->name = KdSaveString ("PS/2 Mouse"); + + return Success; +} + +static Status +Ps2Enable (KdPointerInfo *pi) +{ + int fd; + + if (!pi) + return BadImplementation; + + fd = open (pi->path, 0); + if (fd < 0) + return BadMatch; + + if (!KdRegisterFd (fd, Ps2Read, pi)) { + close(fd); + return BadAlloc; + } + + pi->driverPrivate = (void *)fd; + + return Success; +} + + +static void +Ps2Disable (KdPointerInfo *pi) +{ + KdUnregisterFd (pi, (int)pi->driverPrivate, TRUE); } static void -Ps2Fini (void) +Ps2Fini (KdPointerInfo *pi) { - KdUnregisterFds (Ps2InputType, TRUE); } -KdMouseFuncs Ps2MouseFuncs = { +KdPointerDriver Ps2MouseDriver = { + "ps2", Ps2Init, - Ps2Fini + Ps2Enable, + Ps2Disable, + Ps2Fini, + NULL, }; diff --git a/hw/kdrive/linux/ts.c b/hw/kdrive/linux/ts.c index 70c736117..701fdc891 100644 --- a/hw/kdrive/linux/ts.c +++ b/hw/kdrive/linux/ts.c @@ -75,7 +75,7 @@ TsReadBytes (int fd, char *buf, int len, int min) static void TsRead (int tsPort, void *closure) { - KdMouseInfo *mi = closure; + KdPointerInfo *pi = closure; TS_EVENT event; int n; long x, y; @@ -117,7 +117,7 @@ TsRead (int tsPort, void *closure) lastx = 0; lasty = 0; } - KdEnqueueMouseEvent (mi, flags, x, y); + KdEnqueuePointerEvent (pi, flags, x, y, 0); } } @@ -129,95 +129,83 @@ char *TsNames[] = { #define NUM_TS_NAMES (sizeof (TsNames) / sizeof (TsNames[0])) -int TsInputType; - -static int -TsEnable (int fd, void *closure) -{ - KdMouseInfo *mi = (KdMouseInfo *)closure; - - return open (mi->name, 0); -} - -static void -TsDisable (int fd, void *closure) -{ - close (fd); -} - -static int -TsInit (void) +static Status +TsInit (KdPointerInfo *pi) { int i; int fd; - KdMouseInfo *mi, *next; int n = 0; - if (!TsInputType) - TsInputType = KdAllocInputType (); - - for (mi = kdMouseInfo; mi; mi = next) - { - next = mi->next; - if (mi->inputType) - continue; - if (!mi->name) - { - for (i = 0; i < NUM_TS_NAMES; i++) - { - fd = open (TsNames[i], 0); - if (fd >= 0) - { - mi->name = KdSaveString (TsNames[i]); - break; - } - } - } - else - fd = open (mi->name, 0); - if (fd >= 0) - { - struct h3600_ts_calibration cal; - /* - * Check to see if this is a touch screen - */ - if (ioctl (fd, TS_GET_CAL, &cal) != -1) - { - mi->driver = (void *) fd; - mi->inputType = TsInputType; - if (KdRegisterFd (TsInputType, fd, TsRead, (void *) mi)) - { - /* Set callbacks for vt switches etc */ - KdRegisterFdEnableDisable (fd, TsEnable, TsDisable); - - n++; - } - } - else - close (fd); + if (!pi->path || strcmp(pi->path, "auto") == 0) { + for (i = 0; i < NUM_TS_NAMES; i++) { + fd = open (TsNames[i], 0); + if (fd >= 0) { + pi->path = KdSaveString (TsNames[i]); + break; + } } } + else { + fd = open (pi->path, 0); + } - return 0; + if (fd < 0) { + ErrorF("TsInit: Couldn't open %s\n", pi->path); + return BadMatch; + } + close(fd); + + pi->name = KdSaveString("H3600 Touchscreen"); + + return Success; +} + +static Status +TsEnable (KdPointerInfo *pi) +{ + int fd; + + if (!pi || !pi->path) + return BadImplementation; + + fd = open(pi->path, 0); + + if (fd < 0) { + ErrorF("TsInit: Couldn't open %s\n", pi->path); + return BadMatch; + } + + struct h3600_ts_calibration cal; + /* + * Check to see if this is a touch screen + */ + if (ioctl (fd, TS_GET_CAL, &cal) != -1) { + mi->driverPrivate = (void *) fd; + if (!KdRegisterFd (fd, TsRead, (void *) mi)) { + close(fd); + return BadAlloc; + } + } + else { + ErrorF("TsEnable: %s is not a touchscreen\n", pi->path); + close (fd); + return BadMatch; + } + + return Success; } static void -TsFini (void) +TsFini (KdPointerInfo *pi) { - KdMouseInfo *mi; - - KdUnregisterFds (TsInputType, TRUE); - for (mi = kdMouseInfo; mi; mi = mi->next) - { - if (mi->inputType == TsInputType) - { - mi->driver = 0; - mi->inputType = 0; - } - } + KdUnregisterFds (pi, (int)pi->driverPrivate, TRUE); + mi->driverPrivate = NULL; } -KdMouseFuncs TsFuncs = { +KdPointerDriver TsDriver = { TsInit, - TsFini + TsEnable, + TsDisable, + TsFini, + NULL, }; diff --git a/hw/kdrive/linux/tslib.c b/hw/kdrive/linux/tslib.c index c4caff922..aa57e87bb 100644 --- a/hw/kdrive/linux/tslib.c +++ b/hw/kdrive/linux/tslib.c @@ -1,73 +1,39 @@ /* - * $RCSId: xc/programs/Xserver/hw/kdrive/linux/tslib.c,v 1.1 2002/11/01 22:27:49 keithp Exp $ - * TSLIB based touchscreen driver for TinyX + * TSLIB based touchscreen driver for KDrive + * Porting to new input API and event queueing by Daniel Stone. * Derived from ts.c by Keith Packard * Derived from ps2.c by Jim Gettys * * Copyright © 1999 Keith Packard * Copyright © 2000 Compaq Computer Corporation * Copyright © 2002 MontaVista Software Inc. - * Copyright © 2005 OpenedHand Ltd. + * Copyright © 2006 Nokia Corporation * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that * the above copyright notice appear in all copies and that both that * copyright notice and this permission notice appear in supporting - * documentation, and that the name of Keith Packard or Compaq not be used in - * advertising or publicity pertaining to distribution of the software without - * specific, written prior permission. Keith Packard and Compaq makes no - * representations about the suitability of this software for any purpose. It - * is provided "as is" without express or implied warranty. + * documentation, and that the name of the authors and/or copyright holders + * not be used in advertising or publicity pertaining to distribution of the + * software without specific, written prior permission. The authors and/or + * copyright holders make no representations about the suitability of this + * software for any purpose. It is provided "as is" without express or + * implied warranty. * - * KEITH PACKARD AND COMPAQ DISCLAIM ALL WARRANTIES WITH REGARD TO THIS - * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, - * IN NO EVENT SHALL KEITH PACKARD BE LIABLE FOR 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. - * - * Permission to use, copy, modify, distribute, and sell this software and its - * documentation for any purpose is hereby granted without fee, provided that - * the above copyright notice appear in all copies and that both that - * copyright notice and this permission notice appear in supporting - * documentation, and that the name of Michael Taht or MontaVista not be used in - * advertising or publicity pertaining to distribution of the software without - * specific, written prior permission. Michael Taht and Montavista make no - * representations about the suitability of this software for any purpose. It - * is provided "as is" without express or implied warranty. - * - * MICHAEL TAHT AND MONTAVISTA DISCLAIM ALL WARRANTIES WITH REGARD TO THIS - * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, - * IN NO EVENT SHALL EITHER BE LIABLE FOR 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. - * - * Permission to use, copy, modify, distribute, and sell this software and its - * documentation for any purpose is hereby granted without fee, provided that - * the above copyright notice appear in all copies and that both that - * copyright notice and this permission notice appear in supporting - * documentation, and that the name of Matthew Allum or OpenedHand not be used in - * advertising or publicity pertaining to distribution of the software without - * specific, written prior permission. Matthew Allum and OpenedHand make no - * representations about the suitability of this software for any purpose. It - * is provided "as is" without express or implied warranty. - * - * MATTHEW ALLUM AND OPENEDHAND DISCLAIM ALL WARRANTIES WITH REGARD TO THIS - * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, - * IN NO EVENT SHALL EITHER BE LIABLE FOR 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. + * THE AUTHORS AND/OR COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD + * TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL THE AUTHORS AND/OR COPYRIGHT HOLDERS BE + * LIABLE FOR 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. */ -#ifdef HAVE_CONFIG_H +#ifdef HAVE_KDRIVE_CONFIG_H #include #endif + #define NEED_EVENTS #include #include @@ -77,186 +43,171 @@ #include "kdrive.h" #include #include +#include +#include -static struct tsdev *tsDev = NULL; - -static char *TsNames[] = { - NULL, /* set via TSLIB_TSDEVICE */ - "/dev/ts", - "/dev/touchscreen/0", +struct TslibPrivate { + int fd; + int lastx, lasty; + struct tsdev *tsDev; + void (*raw_event_hook)(int x, int y, int pressure, void *closure); + void *raw_event_closure; + int phys_screen; }; -#define NUM_TS_NAMES (sizeof (TsNames) / sizeof (TsNames[0])) - -/* For XCalibrate extension */ -void (*tslib_raw_event_hook)(int x, int y, int pressure, void *closure); -void *tslib_raw_event_closure; - -int TsInputType = 0; -int KdTsPhyScreen = 0; /* XXX Togo .. */ static void -TsRead (int tsPort, void *closure) +TsRead (int fd, void *closure) { - KdMouseInfo *mi = closure; - struct ts_sample event; - long x, y; - unsigned long flags; + KdPointerInfo *pi = closure; + struct TslibPrivate *private = pi->driverPrivate; + struct ts_sample event; + long x = 0, y = 0; + unsigned long flags; - if (tslib_raw_event_hook) - { - /* XCalibrate Ext */ - if (ts_read_raw(tsDev, &event, 1) == 1) - { - tslib_raw_event_hook (event.x, - event.y, - event.pressure, - tslib_raw_event_closure); - } - return; - } - - while (ts_read(tsDev, &event, 1) == 1) - { - flags = (event.pressure) ? KD_BUTTON_1 : 0; - x = event.x; - y = event.y; - - KdEnqueueMouseEvent (mi, flags, x, y); - } -} - -static int -TsLibOpen(char *dev) -{ - if(!(tsDev = ts_open(dev, 0))) - return -1; - - if (ts_config(tsDev)) - return -1; - - return ts_fd(tsDev); -} - -static int -TslibEnable (int not_needed_fd, void *closure) -{ - KdMouseInfo *mi = closure; - int fd = 0; - - if ((fd = TsLibOpen(mi->name)) == -1) - ErrorF ("Unable to re-enable TSLib ( on %s )", mi->name); - - return fd; -} - -static void -TslibDisable (int fd, void *closure) -{ - if (tsDev) - ts_close(tsDev); - tsDev = NULL; -} - -static int -TslibInit (void) -{ - int i, j = 0; - KdMouseInfo *mi, *next; - int fd = 0; - int req_type; - - if (!TsInputType) - { - TsInputType = KdAllocInputType (); - KdParseMouse(0); /* allocate safe slot in kdMouseInfo */ - req_type = 0; + if (private->raw_event_hook) { + while (ts_read_raw(private->tsDev, &event, 1) == 1) + private->raw_event_hook (event.x, event.y, event.pressure, + private->raw_event_closure); + return; } - else req_type = TsInputType; /* is being re-inited */ - - for (mi = kdMouseInfo; mi; mi = next) - { - next = mi->next; - - /* find a usuable slot */ - if (mi->inputType != req_type) - continue; - - /* Check for tslib env var device setting */ - if ((TsNames[0] = getenv("TSLIB_TSDEVICE")) == NULL) - j++; - - if (!mi->name) - { - for (i = j; i < NUM_TS_NAMES; i++) - { - fd = TsLibOpen(TsNames[i]); - - if (fd >= 0) - { - mi->name = KdSaveString (TsNames[i]); - break; - } - } - } - else - fd = TsLibOpen(mi->name); - - if (fd >= 0 && tsDev != NULL) - { - mi->driver = (void *) fd; - mi->inputType = TsInputType; - - KdRegisterFd (TsInputType, fd, TsRead, (void *) mi); - - /* Set callbacks for vt switches etc */ - KdRegisterFdEnableDisable (fd, TslibEnable, TslibDisable); - - return TRUE; - } - } - - ErrorF ("Failed to open TSLib device, tried "); - for (i = j; i < NUM_TS_NAMES; i++) - ErrorF ("%s ", TsNames[i]); - ErrorF (".\n"); - if (!TsNames[0]) - ErrorF ("Try setting TSLIB_TSDEVICE to valid /dev entry?\n"); - - if (fd > 0) - close(fd); - - return FALSE; -} -static void -TslibFini (void) -{ - KdMouseInfo *mi; + while (ts_read(private->tsDev, &event, 1) == 1) { +#ifdef DEBUG + ErrorF("[tslib] originally from (%d, %d)\n", event.x, event.y); +#endif + if (event.pressure) { + if (event.pressure > pi->dixdev->touchscreen->button_threshold) + flags = KD_BUTTON_8; + else + flags = KD_BUTTON_1; - KdUnregisterFds (TsInputType, TRUE); - for (mi = kdMouseInfo; mi; mi = mi->next) - { - if (mi->inputType == TsInputType) - { - if(mi->driver) - { - ts_close(tsDev); - tsDev = NULL; - } - mi->driver = 0; + /* + * Here we test for the touch screen driver actually being on the + * touch screen, if it is we send absolute coordinates. If not, + * then we send delta's so that we can track the entire vga screen. + */ + if (KdCurScreen == private->phys_screen) { + x = event.x; + y = event.y; + } else { + flags |= KD_MOUSE_DELTA; + if ((private->lastx == 0) || (private->lasty == 0)) { + x = event.x; + y = event.y; + } else { + x = event.x - private->lastx; + y = event.y - private->lasty; + } + } + private->lastx = x; + private->lasty = y; + } else { + flags = 0; + x = private->lastx; + y = private->lasty; + } - /* If below is set to 0, then MouseInit() will trash it, - * setting to 'mouse type' ( via server reset). Therefore - * Leave it alone and work around in TslibInit() ( see - * req_type ). - */ - /* mi->inputType = 0; */ - } +#ifdef DEBUG + ErrorF("event at (%lu, %lu), pressure is %d, sending flags %lu\n", x, y, event.pressure, flags); +#endif + KdEnqueuePointerEvent (pi, flags, x, y, event.pressure); } } -KdMouseFuncs TsFuncs = { +static Status +TslibEnable (KdPointerInfo *pi) +{ + struct TslibPrivate *private = pi->driverPrivate; + + private->holdThumbEvents = 1; + private->raw_event_hook = NULL; + private->raw_event_closure = NULL; + private->tsDev = ts_open(pi->path, 0); + private->fd = ts_fd(private->tsDev); + if (!private->tsDev || ts_config(private->tsDev) || private->fd < 0) { + ErrorF("[tslib/TslibEnable] failed to open %s\n", pi->path); + if (private->fd > 0); + close(private->fd); + return BadAlloc; + } + if (pi->dixdev && pi->dixdev->touchscreen && + pi->dixdev->touchscreen->button_threshold == 0) + pi->dixdev->touchscreen->button_threshold = 115; + +#ifdef DEBUG + ErrorF("[tslib/TslibEnable] successfully enabled %s\n", pi->path); +#endif + + KdRegisterFd(private->fd, TsRead, pi); + + return Success; +} + + +static void +TslibDisable (KdPointerInfo *pi) +{ + struct TslibPrivate *private = pi->driverPrivate; + + if (private->fd) { + KdUnregisterFd(pi, private->fd); + close(private->fd); + } + if (private->tsDev) + ts_close(private->tsDev); + private->fd = 0; + private->tsDev = NULL; +} + + +static Status +TslibInit (KdPointerInfo *pi) +{ + int fd = 0, i = 0; + char devpath[PATH_MAX], devname[TS_NAME_SIZE]; + DIR *inputdir = NULL; + struct dirent *inputent = NULL; + struct tsdev *tsDev = NULL; + struct TslibPrivate *private = NULL; + + if (!pi || !pi->dixdev) + return !Success; + + pi->driverPrivate = (struct TslibPrivate *) + xcalloc(sizeof(struct TslibPrivate), 1); + if (!pi->driverPrivate) + return !Success; + + private = pi->driverPrivate; + /* hacktastic */ + private->phys_screen = 0; + pi->nAxes = 3; + pi->name = KdSaveString("Touchscreen"); + pi->inputClass = KD_TOUCHSCREEN; +#ifdef DEBUG + ErrorF("[tslib/TslibInit] successfully inited for device %s\n", pi->path); +#endif + + return Success; +} + + +static void +TslibFini (KdPointerInfo *pi) +{ + if (pi->driverPrivate) { + xfree(pi->driverPrivate); + pi->driverPrivate = NULL; + } +} + + +KdPointerDriver TsDriver = { + "tslib", TslibInit, - TslibFini + TslibEnable, + TslibDisable, + TslibFini, + NULL, }; diff --git a/hw/kdrive/src/Makefile.am b/hw/kdrive/src/Makefile.am index 53d50950d..20fae554a 100644 --- a/hw/kdrive/src/Makefile.am +++ b/hw/kdrive/src/Makefile.am @@ -24,7 +24,7 @@ libkdrive_a_SOURCES = \ kdrive.h \ kinfo.c \ kinput.c \ - kkeymap.h \ + kkeymap.c \ kmap.c \ kmode.c \ knoop.c \ @@ -37,5 +37,4 @@ libkdrive_a_SOURCES = \ $(top_srcdir)/mi/miinitext.c libkdrivestubs_a_SOURCES = \ - $(top_srcdir)/Xi/stubs.c \ $(top_srcdir)/fb/fbcmap.c diff --git a/hw/kdrive/src/kdrive.c b/hw/kdrive/src/kdrive.c index 52e56e90b..05102ab11 100644 --- a/hw/kdrive/src/kdrive.c +++ b/hw/kdrive/src/kdrive.c @@ -43,6 +43,12 @@ #include "dpmsproc.h" #endif +#ifdef HAVE_EXECINFO_H +#include +#endif + +#include + typedef struct _kdDepths { CARD8 depth; CARD8 bpp; @@ -60,6 +66,8 @@ KdDepths kdDepths[] = { #define NUM_KD_DEPTHS (sizeof (kdDepths) / sizeof (kdDepths[0])) +#define KD_DEFAULT_BUTTONS 5 + int kdScreenPrivateIndex; unsigned long kdGeneration; @@ -76,6 +84,8 @@ Bool kdSwitchPending; char *kdSwitchCmd; DDXPointRec kdOrigin; +static Bool kdCaughtSignal = FALSE; + /* * Carry arguments from InitOutput through driver initialization * to KdScreenInit @@ -368,6 +378,9 @@ AbortDDX(void) (*kdOsFuncs->Fini) (); KdDoSwitchCmd ("stop"); } + + if (kdCaughtSignal) + abort(); } void @@ -379,7 +392,7 @@ ddxGiveUp () Bool kdDumbDriver; Bool kdSoftCursor; -static char * +char * KdParseFindNext (char *cur, char *delim, char *save, char *last) { while (*cur && !strchr (delim, *cur)) @@ -560,97 +573,6 @@ KdSaveString (char *str) return n; } -/* - * Parse mouse information. Syntax: - * - * ,,{,