2006-11-26 11:13:41 -07:00
|
|
|
/*
|
|
|
|
* Copyright 2002-2003 Red Hat Inc., Durham, North Carolina.
|
|
|
|
*
|
|
|
|
* All Rights Reserved.
|
|
|
|
*
|
|
|
|
* Permission is hereby granted, free of charge, to any person obtaining
|
|
|
|
* a copy of this software and associated documentation files (the
|
|
|
|
* "Software"), to deal in the Software without restriction, including
|
|
|
|
* without limitation on 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 (including the
|
|
|
|
* next paragraph) 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
|
|
|
|
* NON-INFRINGEMENT. IN NO EVENT SHALL RED HAT AND/OR THEIR SUPPLIERS
|
|
|
|
* 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.
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Authors:
|
|
|
|
* Rickard E. (Rik) Faith <faith@redhat.com>
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
/** \file
|
|
|
|
* This file provides generic input support. Functions here set up
|
|
|
|
* input and lead to the calling of low-level device drivers for
|
|
|
|
* input. */
|
|
|
|
|
|
|
|
#ifdef HAVE_DMX_CONFIG_H
|
|
|
|
#include <dmx-config.h>
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#define DMX_WINDOW_DEBUG 0
|
|
|
|
|
|
|
|
#include "dmxinputinit.h"
|
|
|
|
#include "dmxextension.h" /* For dmxInputCount */
|
|
|
|
|
|
|
|
#include "dmxdummy.h"
|
|
|
|
#include "dmxbackend.h"
|
|
|
|
#include "dmxconsole.h"
|
|
|
|
#include "dmxcommon.h"
|
|
|
|
#include "dmxevents.h"
|
|
|
|
#include "dmxmotion.h"
|
|
|
|
#include "dmxprop.h"
|
|
|
|
#include "config/dmxconfig.h"
|
|
|
|
#include "dmxcursor.h"
|
|
|
|
|
|
|
|
#include "lnx-keyboard.h"
|
|
|
|
#include "lnx-ms.h"
|
|
|
|
#include "lnx-ps2.h"
|
|
|
|
#include "usb-keyboard.h"
|
|
|
|
#include "usb-mouse.h"
|
|
|
|
#include "usb-other.h"
|
|
|
|
#include "usb-common.h"
|
|
|
|
|
|
|
|
#include "dmxsigio.h"
|
|
|
|
#include "dmxarg.h"
|
|
|
|
|
|
|
|
#include "inputstr.h"
|
|
|
|
#include "input.h"
|
|
|
|
#include "mipointer.h"
|
|
|
|
#include "windowstr.h"
|
2007-11-24 10:55:21 -07:00
|
|
|
#include "mi.h"
|
2010-07-27 13:02:24 -06:00
|
|
|
#include "xkbsrv.h"
|
2006-11-26 11:13:41 -07:00
|
|
|
|
|
|
|
#include <X11/extensions/XI.h>
|
|
|
|
#include <X11/extensions/XIproto.h>
|
|
|
|
#include "exevents.h"
|
|
|
|
#include "extinit.h"
|
|
|
|
|
|
|
|
DMXLocalInputInfoPtr dmxLocalCorePointer, dmxLocalCoreKeyboard;
|
|
|
|
|
|
|
|
static DMXLocalInputInfoRec DMXDummyMou = {
|
|
|
|
"dummy-mou", DMX_LOCAL_MOUSE, DMX_LOCAL_TYPE_LOCAL, 1,
|
|
|
|
NULL, NULL, NULL, NULL, NULL, dmxDummyMouGetInfo
|
|
|
|
};
|
|
|
|
|
|
|
|
static DMXLocalInputInfoRec DMXDummyKbd = {
|
|
|
|
"dummy-kbd", DMX_LOCAL_KEYBOARD, DMX_LOCAL_TYPE_LOCAL, 1,
|
|
|
|
NULL, NULL, NULL, NULL, NULL, dmxDummyKbdGetInfo
|
|
|
|
};
|
|
|
|
|
|
|
|
static DMXLocalInputInfoRec DMXBackendMou = {
|
|
|
|
"backend-mou", DMX_LOCAL_MOUSE, DMX_LOCAL_TYPE_BACKEND, 2,
|
|
|
|
dmxBackendCreatePrivate, dmxBackendDestroyPrivate,
|
|
|
|
dmxBackendInit, NULL, dmxBackendLateReInit, dmxBackendMouGetInfo,
|
|
|
|
dmxCommonMouOn, dmxCommonMouOff, dmxBackendUpdatePosition,
|
|
|
|
NULL, NULL, NULL,
|
|
|
|
dmxBackendCollectEvents, dmxBackendProcessInput, dmxBackendFunctions, NULL,
|
|
|
|
dmxCommonMouCtrl
|
|
|
|
};
|
|
|
|
|
|
|
|
static DMXLocalInputInfoRec DMXBackendKbd = {
|
|
|
|
"backend-kbd", DMX_LOCAL_KEYBOARD, DMX_LOCAL_TYPE_BACKEND,
|
2012-06-10 07:21:05 -06:00
|
|
|
1, /* With backend-mou or console-mou */
|
2006-11-26 11:13:41 -07:00
|
|
|
dmxCommonCopyPrivate, NULL,
|
|
|
|
dmxBackendInit, NULL, NULL, dmxBackendKbdGetInfo,
|
|
|
|
dmxCommonKbdOn, dmxCommonKbdOff, NULL,
|
|
|
|
NULL, NULL, NULL,
|
|
|
|
NULL, NULL, NULL, NULL,
|
|
|
|
NULL, dmxCommonKbdCtrl, dmxCommonKbdBell
|
|
|
|
};
|
|
|
|
|
|
|
|
static DMXLocalInputInfoRec DMXConsoleMou = {
|
|
|
|
"console-mou", DMX_LOCAL_MOUSE, DMX_LOCAL_TYPE_CONSOLE, 2,
|
|
|
|
dmxConsoleCreatePrivate, dmxConsoleDestroyPrivate,
|
|
|
|
dmxConsoleInit, dmxConsoleReInit, NULL, dmxConsoleMouGetInfo,
|
|
|
|
dmxCommonMouOn, dmxCommonMouOff, dmxConsoleUpdatePosition,
|
|
|
|
NULL, NULL, NULL,
|
|
|
|
dmxConsoleCollectEvents, NULL, dmxConsoleFunctions, dmxConsoleUpdateInfo,
|
|
|
|
dmxCommonMouCtrl
|
|
|
|
};
|
|
|
|
|
|
|
|
static DMXLocalInputInfoRec DMXConsoleKbd = {
|
|
|
|
"console-kbd", DMX_LOCAL_KEYBOARD, DMX_LOCAL_TYPE_CONSOLE,
|
2012-06-10 07:21:05 -06:00
|
|
|
1, /* With backend-mou or console-mou */
|
2006-11-26 11:13:41 -07:00
|
|
|
dmxCommonCopyPrivate, NULL,
|
|
|
|
dmxConsoleInit, dmxConsoleReInit, NULL, dmxConsoleKbdGetInfo,
|
|
|
|
dmxCommonKbdOn, dmxCommonKbdOff, NULL,
|
|
|
|
NULL, NULL, NULL,
|
|
|
|
NULL, NULL, NULL, NULL,
|
|
|
|
NULL, dmxCommonKbdCtrl, dmxCommonKbdBell
|
|
|
|
};
|
|
|
|
|
|
|
|
static DMXLocalInputInfoRec DMXLocalDevices[] = {
|
2012-06-10 07:21:05 -06:00
|
|
|
/* Dummy drivers that can compile on any OS */
|
2006-11-26 11:13:41 -07:00
|
|
|
#ifdef __linux__
|
2012-06-10 07:21:05 -06:00
|
|
|
/* Linux-specific drivers */
|
2006-11-26 11:13:41 -07:00
|
|
|
{
|
2012-06-10 07:21:05 -06:00
|
|
|
"kbd", DMX_LOCAL_KEYBOARD, DMX_LOCAL_TYPE_LOCAL, 1,
|
|
|
|
kbdLinuxCreatePrivate, kbdLinuxDestroyPrivate,
|
|
|
|
kbdLinuxInit, NULL, NULL, kbdLinuxGetInfo,
|
|
|
|
kbdLinuxOn, kbdLinuxOff, NULL,
|
|
|
|
kbdLinuxVTPreSwitch, kbdLinuxVTPostSwitch, kbdLinuxVTSwitch,
|
|
|
|
kbdLinuxRead, NULL, NULL, NULL,
|
|
|
|
NULL, kbdLinuxCtrl, kbdLinuxBell},
|
2006-11-26 11:13:41 -07:00
|
|
|
{
|
2012-06-10 07:21:05 -06:00
|
|
|
"ms", DMX_LOCAL_MOUSE, DMX_LOCAL_TYPE_LOCAL, 1,
|
|
|
|
msLinuxCreatePrivate, msLinuxDestroyPrivate,
|
|
|
|
msLinuxInit, NULL, NULL, msLinuxGetInfo,
|
|
|
|
msLinuxOn, msLinuxOff, NULL,
|
|
|
|
msLinuxVTPreSwitch, msLinuxVTPostSwitch, NULL,
|
|
|
|
msLinuxRead},
|
2006-11-26 11:13:41 -07:00
|
|
|
{
|
2012-06-10 07:21:05 -06:00
|
|
|
"ps2", DMX_LOCAL_MOUSE, DMX_LOCAL_TYPE_LOCAL, 1,
|
|
|
|
ps2LinuxCreatePrivate, ps2LinuxDestroyPrivate,
|
|
|
|
ps2LinuxInit, NULL, NULL, ps2LinuxGetInfo,
|
|
|
|
ps2LinuxOn, ps2LinuxOff, NULL,
|
|
|
|
ps2LinuxVTPreSwitch, ps2LinuxVTPostSwitch, NULL,
|
|
|
|
ps2LinuxRead},
|
2006-11-26 11:13:41 -07:00
|
|
|
#endif
|
|
|
|
#ifdef __linux__
|
2012-06-10 07:21:05 -06:00
|
|
|
/* USB drivers, currently only for
|
|
|
|
Linux, but relatively easy to port to
|
|
|
|
other OSs */
|
2006-11-26 11:13:41 -07:00
|
|
|
{
|
2012-06-10 07:21:05 -06:00
|
|
|
"usb-kbd", DMX_LOCAL_KEYBOARD, DMX_LOCAL_TYPE_LOCAL, 1,
|
|
|
|
usbCreatePrivate, usbDestroyPrivate,
|
|
|
|
kbdUSBInit, NULL, NULL, kbdUSBGetInfo,
|
|
|
|
kbdUSBOn, usbOff, NULL,
|
|
|
|
NULL, NULL, NULL,
|
|
|
|
kbdUSBRead, NULL, NULL, NULL,
|
|
|
|
NULL, kbdUSBCtrl},
|
2006-11-26 11:13:41 -07:00
|
|
|
{
|
2012-06-10 07:21:05 -06:00
|
|
|
"usb-mou", DMX_LOCAL_MOUSE, DMX_LOCAL_TYPE_LOCAL, 1,
|
|
|
|
usbCreatePrivate, usbDestroyPrivate,
|
|
|
|
mouUSBInit, NULL, NULL, mouUSBGetInfo,
|
|
|
|
mouUSBOn, usbOff, NULL,
|
|
|
|
NULL, NULL, NULL,
|
|
|
|
mouUSBRead},
|
2006-11-26 11:13:41 -07:00
|
|
|
{
|
2012-06-10 07:21:05 -06:00
|
|
|
"usb-oth", DMX_LOCAL_OTHER, DMX_LOCAL_TYPE_LOCAL, 1,
|
|
|
|
usbCreatePrivate, usbDestroyPrivate,
|
|
|
|
othUSBInit, NULL, NULL, othUSBGetInfo,
|
|
|
|
othUSBOn, usbOff, NULL,
|
|
|
|
NULL, NULL, NULL,
|
|
|
|
othUSBRead},
|
2006-11-26 11:13:41 -07:00
|
|
|
#endif
|
|
|
|
{
|
2012-06-10 07:21:05 -06:00
|
|
|
"dummy-mou", DMX_LOCAL_MOUSE, DMX_LOCAL_TYPE_LOCAL, 1,
|
|
|
|
NULL, NULL, NULL, NULL, NULL, dmxDummyMouGetInfo},
|
2006-11-26 11:13:41 -07:00
|
|
|
{
|
2012-06-10 07:21:05 -06:00
|
|
|
"dummy-kbd", DMX_LOCAL_KEYBOARD, DMX_LOCAL_TYPE_LOCAL, 1,
|
|
|
|
NULL, NULL, NULL, NULL, NULL, dmxDummyKbdGetInfo},
|
|
|
|
{NULL} /* Must be last */
|
2006-11-26 11:13:41 -07:00
|
|
|
};
|
|
|
|
|
2007-11-24 10:55:21 -07:00
|
|
|
#if 11 /*BP*/
|
2012-06-10 07:21:05 -06:00
|
|
|
void
|
2007-11-24 10:55:21 -07:00
|
|
|
DDXRingBell(int volume, int pitch, int duration)
|
|
|
|
{
|
2012-06-10 07:21:05 -06:00
|
|
|
/* NO-OP */
|
2007-11-24 10:55:21 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
/* taken from kdrive/src/kinput.c: */
|
|
|
|
static void
|
2012-06-10 07:21:05 -06:00
|
|
|
dmxKbdCtrl(DeviceIntPtr pDevice, KeybdCtrl * ctrl)
|
2007-11-24 10:55:21 -07:00
|
|
|
{
|
|
|
|
#if 0
|
|
|
|
KdKeyboardInfo *ki;
|
|
|
|
|
|
|
|
for (ki = kdKeyboards; ki; ki = ki->next) {
|
|
|
|
if (ki->dixdev && ki->dixdev->id == pDevice->id)
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!ki || !ki->dixdev || ki->dixdev->id != pDevice->id || !ki->driver)
|
|
|
|
return;
|
|
|
|
|
|
|
|
KdSetLeds(ki, ctrl->leds);
|
|
|
|
ki->bellPitch = ctrl->bell_pitch;
|
2012-06-10 07:21:05 -06:00
|
|
|
ki->bellDuration = ctrl->bell_duration;
|
2007-11-24 10:55:21 -07:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
/* taken from kdrive/src/kinput.c: */
|
|
|
|
static void
|
2014-09-27 11:52:59 -06:00
|
|
|
dmxBell(int volume, DeviceIntPtr pDev, void *arg, int something)
|
2007-11-24 10:55:21 -07:00
|
|
|
{
|
|
|
|
#if 0
|
|
|
|
KeybdCtrl *ctrl = arg;
|
|
|
|
KdKeyboardInfo *ki = NULL;
|
2012-06-10 07:21:05 -06:00
|
|
|
|
2007-11-24 10:55:21 -07:00
|
|
|
for (ki = kdKeyboards; ki; ki = ki->next) {
|
|
|
|
if (ki->dixdev && ki->dixdev->id == pDev->id)
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!ki || !ki->dixdev || ki->dixdev->id != pDev->id || !ki->driver)
|
|
|
|
return;
|
2012-06-10 07:21:05 -06:00
|
|
|
|
2007-11-24 10:55:21 -07:00
|
|
|
KdRingBell(ki, volume, ctrl->bell_pitch, ctrl->bell_duration);
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif /*BP*/
|
2012-06-10 07:21:05 -06:00
|
|
|
static void
|
|
|
|
_dmxChangePointerControl(DMXLocalInputInfoPtr dmxLocal, PtrCtrl * ctrl)
|
2006-11-26 11:13:41 -07:00
|
|
|
{
|
2012-06-10 07:21:05 -06:00
|
|
|
if (!dmxLocal)
|
|
|
|
return;
|
2006-11-26 11:13:41 -07:00
|
|
|
dmxLocal->mctrl = *ctrl;
|
2012-06-10 07:21:05 -06:00
|
|
|
if (dmxLocal->mCtrl)
|
|
|
|
dmxLocal->mCtrl(&dmxLocal->pDevice->public, ctrl);
|
2006-11-26 11:13:41 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
/** Change the pointer control information for the \a pDevice. If the
|
|
|
|
* device sends core events, then also change the control information
|
|
|
|
* for all of the pointer devices that send core events. */
|
2012-06-10 07:21:05 -06:00
|
|
|
void
|
|
|
|
dmxChangePointerControl(DeviceIntPtr pDevice, PtrCtrl * ctrl)
|
2006-11-26 11:13:41 -07:00
|
|
|
{
|
|
|
|
GETDMXLOCALFROMPDEVICE;
|
|
|
|
int i, j;
|
|
|
|
|
2012-06-10 07:21:05 -06:00
|
|
|
if (dmxLocal->sendsCore) { /* Do for all core devices */
|
2006-11-26 11:13:41 -07:00
|
|
|
for (i = 0; i < dmxNumInputs; i++) {
|
|
|
|
DMXInputInfo *dmxInput = &dmxInputs[i];
|
2012-06-10 07:21:05 -06:00
|
|
|
|
|
|
|
if (dmxInput->detached)
|
|
|
|
continue;
|
2006-11-26 11:13:41 -07:00
|
|
|
for (j = 0; j < dmxInput->numDevs; j++)
|
|
|
|
if (dmxInput->devs[j]->sendsCore)
|
|
|
|
_dmxChangePointerControl(dmxInput->devs[j], ctrl);
|
|
|
|
}
|
2012-06-10 07:21:05 -06:00
|
|
|
}
|
|
|
|
else { /* Do for this device only */
|
2006-11-26 11:13:41 -07:00
|
|
|
_dmxChangePointerControl(dmxLocal, ctrl);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-06-10 07:21:05 -06:00
|
|
|
static void
|
|
|
|
_dmxKeyboardKbdCtrlProc(DMXLocalInputInfoPtr dmxLocal, KeybdCtrl * ctrl)
|
2006-11-26 11:13:41 -07:00
|
|
|
{
|
|
|
|
dmxLocal->kctrl = *ctrl;
|
|
|
|
if (dmxLocal->kCtrl) {
|
|
|
|
dmxLocal->kCtrl(&dmxLocal->pDevice->public, ctrl);
|
2010-07-27 13:02:24 -06:00
|
|
|
if (dmxLocal->pDevice->kbdfeed) {
|
2006-11-26 11:13:41 -07:00
|
|
|
XkbEventCauseRec cause;
|
2012-06-10 07:21:05 -06:00
|
|
|
|
2006-11-26 11:13:41 -07:00
|
|
|
XkbSetCauseUnknown(&cause);
|
|
|
|
/* Generate XKB events, as necessary */
|
|
|
|
XkbUpdateIndicators(dmxLocal->pDevice, XkbAllIndicatorsMask, False,
|
|
|
|
NULL, &cause);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/** Change the keyboard control information for the \a pDevice. If the
|
|
|
|
* device sends core events, then also change the control information
|
|
|
|
* for all of the keyboard devices that send core events. */
|
2012-06-10 07:21:05 -06:00
|
|
|
void
|
|
|
|
dmxKeyboardKbdCtrlProc(DeviceIntPtr pDevice, KeybdCtrl * ctrl)
|
2006-11-26 11:13:41 -07:00
|
|
|
{
|
|
|
|
GETDMXLOCALFROMPDEVICE;
|
|
|
|
int i, j;
|
|
|
|
|
2012-06-10 07:21:05 -06:00
|
|
|
if (dmxLocal->sendsCore) { /* Do for all core devices */
|
2006-11-26 11:13:41 -07:00
|
|
|
for (i = 0; i < dmxNumInputs; i++) {
|
|
|
|
DMXInputInfo *dmxInput = &dmxInputs[i];
|
2012-06-10 07:21:05 -06:00
|
|
|
|
|
|
|
if (dmxInput->detached)
|
|
|
|
continue;
|
2006-11-26 11:13:41 -07:00
|
|
|
for (j = 0; j < dmxInput->numDevs; j++)
|
|
|
|
if (dmxInput->devs[j]->sendsCore)
|
|
|
|
_dmxKeyboardKbdCtrlProc(dmxInput->devs[j], ctrl);
|
|
|
|
}
|
2012-06-10 07:21:05 -06:00
|
|
|
}
|
|
|
|
else { /* Do for this device only */
|
2006-11-26 11:13:41 -07:00
|
|
|
_dmxKeyboardKbdCtrlProc(dmxLocal, ctrl);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-06-10 07:21:05 -06:00
|
|
|
static void
|
|
|
|
_dmxKeyboardBellProc(DMXLocalInputInfoPtr dmxLocal, int percent)
|
2006-11-26 11:13:41 -07:00
|
|
|
{
|
2012-06-10 07:21:05 -06:00
|
|
|
if (dmxLocal->kBell)
|
|
|
|
dmxLocal->kBell(&dmxLocal->pDevice->public,
|
|
|
|
percent,
|
|
|
|
dmxLocal->kctrl.bell,
|
|
|
|
dmxLocal->kctrl.bell_pitch,
|
|
|
|
dmxLocal->kctrl.bell_duration);
|
2006-11-26 11:13:41 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
/** Sound the bell on the device. If the device send core events, then
|
|
|
|
* sound the bell on all of the devices that send core events. */
|
2012-06-10 07:21:05 -06:00
|
|
|
void
|
|
|
|
dmxKeyboardBellProc(int percent, DeviceIntPtr pDevice,
|
2014-09-27 11:52:59 -06:00
|
|
|
void *ctrl, int unknown)
|
2006-11-26 11:13:41 -07:00
|
|
|
{
|
|
|
|
GETDMXLOCALFROMPDEVICE;
|
|
|
|
int i, j;
|
|
|
|
|
2012-06-10 07:21:05 -06:00
|
|
|
if (dmxLocal->sendsCore) { /* Do for all core devices */
|
2006-11-26 11:13:41 -07:00
|
|
|
for (i = 0; i < dmxNumInputs; i++) {
|
|
|
|
DMXInputInfo *dmxInput = &dmxInputs[i];
|
2012-06-10 07:21:05 -06:00
|
|
|
|
|
|
|
if (dmxInput->detached)
|
|
|
|
continue;
|
2006-11-26 11:13:41 -07:00
|
|
|
for (j = 0; j < dmxInput->numDevs; j++)
|
|
|
|
if (dmxInput->devs[j]->sendsCore)
|
|
|
|
_dmxKeyboardBellProc(dmxInput->devs[j], percent);
|
|
|
|
}
|
2012-06-10 07:21:05 -06:00
|
|
|
}
|
|
|
|
else { /* Do for this device only */
|
2006-11-26 11:13:41 -07:00
|
|
|
_dmxKeyboardBellProc(dmxLocal, percent);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-06-10 07:21:05 -06:00
|
|
|
static void
|
|
|
|
dmxKeyboardFreeNames(XkbComponentNamesPtr names)
|
2006-11-26 11:13:41 -07:00
|
|
|
{
|
2012-06-10 07:21:05 -06:00
|
|
|
if (names->keycodes)
|
|
|
|
XFree(names->keycodes);
|
|
|
|
if (names->types)
|
|
|
|
XFree(names->types);
|
|
|
|
if (names->compat)
|
|
|
|
XFree(names->compat);
|
|
|
|
if (names->symbols)
|
|
|
|
XFree(names->symbols);
|
|
|
|
if (names->geometry)
|
|
|
|
XFree(names->geometry);
|
2006-11-26 11:13:41 -07:00
|
|
|
}
|
|
|
|
|
2012-06-10 07:21:05 -06:00
|
|
|
static int
|
|
|
|
dmxKeyboardOn(DeviceIntPtr pDevice, DMXLocalInitInfo * info)
|
2006-11-26 11:13:41 -07:00
|
|
|
{
|
|
|
|
GETDMXINPUTFROMPDEVICE;
|
2010-07-27 13:02:24 -06:00
|
|
|
XkbRMLVOSet rmlvo;
|
|
|
|
|
|
|
|
rmlvo.rules = dmxConfigGetXkbRules();
|
|
|
|
rmlvo.model = dmxConfigGetXkbModel();
|
|
|
|
rmlvo.layout = dmxConfigGetXkbLayout();
|
|
|
|
rmlvo.variant = dmxConfigGetXkbVariant();
|
|
|
|
rmlvo.options = dmxConfigGetXkbOptions();
|
|
|
|
|
|
|
|
XkbSetRulesDflts(&rmlvo);
|
|
|
|
if (!info->force && (dmxInput->keycodes
|
2012-06-10 07:21:05 -06:00
|
|
|
|| dmxInput->symbols || dmxInput->geometry)) {
|
|
|
|
if (info->freenames)
|
|
|
|
dmxKeyboardFreeNames(&info->names);
|
|
|
|
info->freenames = 0;
|
2010-07-27 13:02:24 -06:00
|
|
|
info->names.keycodes = dmxInput->keycodes;
|
2012-06-10 07:21:05 -06:00
|
|
|
info->names.types = NULL;
|
|
|
|
info->names.compat = NULL;
|
|
|
|
info->names.symbols = dmxInput->symbols;
|
2010-07-27 13:02:24 -06:00
|
|
|
info->names.geometry = dmxInput->geometry;
|
|
|
|
|
|
|
|
dmxLogInput(dmxInput, "XKEYBOARD: From command line: %s",
|
|
|
|
info->names.keycodes);
|
|
|
|
if (info->names.symbols && *info->names.symbols)
|
|
|
|
dmxLogInputCont(dmxInput, " %s", info->names.symbols);
|
|
|
|
if (info->names.geometry && *info->names.geometry)
|
|
|
|
dmxLogInputCont(dmxInput, " %s", info->names.geometry);
|
|
|
|
dmxLogInputCont(dmxInput, "\n");
|
2012-06-10 07:21:05 -06:00
|
|
|
}
|
|
|
|
else if (info->names.keycodes) {
|
2010-07-27 13:02:24 -06:00
|
|
|
dmxLogInput(dmxInput, "XKEYBOARD: From device: %s",
|
|
|
|
info->names.keycodes);
|
|
|
|
if (info->names.symbols && *info->names.symbols)
|
|
|
|
dmxLogInputCont(dmxInput, " %s", info->names.symbols);
|
|
|
|
if (info->names.geometry && *info->names.geometry)
|
|
|
|
dmxLogInputCont(dmxInput, " %s", info->names.geometry);
|
|
|
|
dmxLogInputCont(dmxInput, "\n");
|
2012-06-10 07:21:05 -06:00
|
|
|
}
|
|
|
|
else {
|
2010-07-27 13:02:24 -06:00
|
|
|
dmxLogInput(dmxInput, "XKEYBOARD: Defaults: %s %s %s %s %s\n",
|
|
|
|
dmxConfigGetXkbRules(),
|
|
|
|
dmxConfigGetXkbLayout(),
|
2012-06-10 07:21:05 -06:00
|
|
|
dmxConfigGetXkbModel(), dmxConfigGetXkbVariant()
|
|
|
|
? dmxConfigGetXkbVariant() : "", dmxConfigGetXkbOptions()
|
2010-07-27 13:02:24 -06:00
|
|
|
? dmxConfigGetXkbOptions() : "");
|
2006-11-26 11:13:41 -07:00
|
|
|
}
|
2010-07-27 13:02:24 -06:00
|
|
|
InitKeyboardDeviceStruct(pDevice, &rmlvo,
|
2012-06-10 07:21:05 -06:00
|
|
|
dmxKeyboardBellProc, dmxKeyboardKbdCtrlProc);
|
2010-07-27 13:02:24 -06:00
|
|
|
|
2012-06-10 07:21:05 -06:00
|
|
|
if (info->freenames)
|
|
|
|
dmxKeyboardFreeNames(&info->names);
|
2006-11-26 11:13:41 -07:00
|
|
|
|
|
|
|
return Success;
|
|
|
|
}
|
|
|
|
|
2012-06-10 07:21:05 -06:00
|
|
|
static int
|
|
|
|
dmxDeviceOnOff(DeviceIntPtr pDevice, int what)
|
2006-11-26 11:13:41 -07:00
|
|
|
{
|
|
|
|
GETDMXINPUTFROMPDEVICE;
|
2012-06-10 07:21:05 -06:00
|
|
|
int fd;
|
2006-11-26 11:13:41 -07:00
|
|
|
DMXLocalInitInfo info;
|
2012-06-10 07:21:05 -06:00
|
|
|
int i;
|
|
|
|
Atom btn_labels[MAX_BUTTONS] = { 0 }; /* FIXME */
|
|
|
|
Atom axis_labels[MAX_VALUATORS] = { 0 }; /* FIXME */
|
2010-07-27 13:02:24 -06:00
|
|
|
|
2012-06-10 07:21:05 -06:00
|
|
|
if (dmxInput->detached)
|
|
|
|
return Success;
|
2006-11-26 11:13:41 -07:00
|
|
|
|
|
|
|
memset(&info, 0, sizeof(info));
|
|
|
|
switch (what) {
|
|
|
|
case DEVICE_INIT:
|
2007-11-24 10:55:21 -07:00
|
|
|
if (dmxLocal->init)
|
|
|
|
dmxLocal->init(pDev);
|
|
|
|
if (dmxLocal->get_info)
|
|
|
|
dmxLocal->get_info(pDev, &info);
|
2006-11-26 11:13:41 -07:00
|
|
|
if (info.keyboard) { /* XKEYBOARD makes this a special case */
|
|
|
|
dmxKeyboardOn(pDevice, &info);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (info.keyClass) {
|
2010-07-27 13:02:24 -06:00
|
|
|
XkbRMLVOSet rmlvo;
|
|
|
|
|
|
|
|
rmlvo.rules = dmxConfigGetXkbRules();
|
|
|
|
rmlvo.model = dmxConfigGetXkbModel();
|
|
|
|
rmlvo.layout = dmxConfigGetXkbLayout();
|
|
|
|
rmlvo.variant = dmxConfigGetXkbVariant();
|
|
|
|
rmlvo.options = dmxConfigGetXkbOptions();
|
|
|
|
|
2012-06-10 07:21:05 -06:00
|
|
|
InitKeyboardDeviceStruct(pDevice, &rmlvo, dmxBell, dmxKbdCtrl);
|
2006-11-26 11:13:41 -07:00
|
|
|
}
|
|
|
|
if (info.buttonClass) {
|
2010-07-27 13:02:24 -06:00
|
|
|
InitButtonClassDeviceStruct(pDevice, info.numButtons,
|
|
|
|
btn_labels, info.map);
|
2006-11-26 11:13:41 -07:00
|
|
|
}
|
|
|
|
if (info.valuatorClass) {
|
|
|
|
if (info.numRelAxes && dmxLocal->sendsCore) {
|
|
|
|
InitValuatorClassDeviceStruct(pDevice, info.numRelAxes,
|
2010-07-27 13:02:24 -06:00
|
|
|
axis_labels,
|
2012-06-10 07:21:05 -06:00
|
|
|
GetMaximumEventsNum(), Relative);
|
2006-11-26 11:13:41 -07:00
|
|
|
for (i = 0; i < info.numRelAxes; i++)
|
2010-07-27 13:02:24 -06:00
|
|
|
InitValuatorAxisStruct(pDevice, i, axis_labels[i],
|
|
|
|
info.minval[i], info.maxval[i],
|
|
|
|
info.res[i],
|
2011-11-05 07:32:40 -06:00
|
|
|
info.minres[i], info.maxres[i],
|
|
|
|
Relative);
|
2012-06-10 07:21:05 -06:00
|
|
|
}
|
|
|
|
else if (info.numRelAxes) {
|
2006-11-26 11:13:41 -07:00
|
|
|
InitValuatorClassDeviceStruct(pDevice, info.numRelAxes,
|
2010-07-27 13:02:24 -06:00
|
|
|
axis_labels,
|
2006-11-26 11:13:41 -07:00
|
|
|
dmxPointerGetMotionBufferSize(),
|
|
|
|
Relative);
|
|
|
|
for (i = 0; i < info.numRelAxes; i++)
|
2010-07-27 13:02:24 -06:00
|
|
|
InitValuatorAxisStruct(pDevice, i, axis_labels[i],
|
|
|
|
info.minval[i],
|
|
|
|
info.maxval[i], info.res[i],
|
2011-11-05 07:32:40 -06:00
|
|
|
info.minres[i], info.maxres[i],
|
|
|
|
Relative);
|
2012-06-10 07:21:05 -06:00
|
|
|
}
|
|
|
|
else if (info.numAbsAxes) {
|
2006-11-26 11:13:41 -07:00
|
|
|
InitValuatorClassDeviceStruct(pDevice, info.numAbsAxes,
|
2010-07-27 13:02:24 -06:00
|
|
|
axis_labels,
|
2006-11-26 11:13:41 -07:00
|
|
|
dmxPointerGetMotionBufferSize(),
|
|
|
|
Absolute);
|
|
|
|
for (i = 0; i < info.numAbsAxes; i++)
|
2010-07-27 13:02:24 -06:00
|
|
|
InitValuatorAxisStruct(pDevice, i,
|
|
|
|
axis_labels[i],
|
|
|
|
info.minval[i], info.maxval[i],
|
|
|
|
info.res[i], info.minres[i],
|
2011-11-05 07:32:40 -06:00
|
|
|
info.maxres[i], Absolute);
|
2006-11-26 11:13:41 -07:00
|
|
|
}
|
|
|
|
}
|
2012-06-10 07:21:05 -06:00
|
|
|
if (info.focusClass)
|
|
|
|
InitFocusClassDeviceStruct(pDevice);
|
|
|
|
if (info.proximityClass)
|
|
|
|
InitProximityClassDeviceStruct(pDevice);
|
2006-11-26 11:13:41 -07:00
|
|
|
if (info.ptrFeedbackClass)
|
|
|
|
InitPtrFeedbackClassDeviceStruct(pDevice, dmxChangePointerControl);
|
|
|
|
if (info.intFeedbackClass || info.strFeedbackClass)
|
|
|
|
dmxLog(dmxWarning,
|
|
|
|
"Integer and string feedback not supported for %s\n",
|
|
|
|
pDevice->name);
|
|
|
|
if (!info.keyboard && (info.ledFeedbackClass || info.belFeedbackClass))
|
|
|
|
dmxLog(dmxWarning,
|
|
|
|
"Led and bel feedback not supported for non-keyboard %s\n",
|
|
|
|
pDevice->name);
|
|
|
|
break;
|
|
|
|
case DEVICE_ON:
|
|
|
|
if (!pDev->on) {
|
|
|
|
if (dmxLocal->on && (fd = dmxLocal->on(pDev)) >= 0)
|
|
|
|
dmxSigioRegister(dmxInput, fd);
|
|
|
|
pDev->on = TRUE;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case DEVICE_OFF:
|
|
|
|
case DEVICE_CLOSE:
|
2012-06-10 07:21:05 -06:00
|
|
|
/* This can get called twice consecutively: once for a
|
|
|
|
* detached screen (DEVICE_OFF), and then again at server
|
|
|
|
* generation time (DEVICE_CLOSE). */
|
2006-11-26 11:13:41 -07:00
|
|
|
if (pDev->on) {
|
|
|
|
dmxSigioUnregister(dmxInput);
|
2012-06-10 07:21:05 -06:00
|
|
|
if (dmxLocal->off)
|
|
|
|
dmxLocal->off(pDev);
|
2006-11-26 11:13:41 -07:00
|
|
|
pDev->on = FALSE;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (info.keySyms.map && info.freemap) {
|
|
|
|
XFree(info.keySyms.map);
|
|
|
|
info.keySyms.map = NULL;
|
|
|
|
}
|
2012-06-10 07:21:05 -06:00
|
|
|
if (info.xkb)
|
|
|
|
XkbFreeKeyboard(info.xkb, 0, True);
|
2006-11-26 11:13:41 -07:00
|
|
|
return Success;
|
|
|
|
}
|
|
|
|
|
2012-06-10 07:21:05 -06:00
|
|
|
static void
|
|
|
|
dmxProcessInputEvents(DMXInputInfo * dmxInput)
|
2006-11-26 11:13:41 -07:00
|
|
|
{
|
|
|
|
int i;
|
|
|
|
|
2010-07-27 13:02:24 -06:00
|
|
|
mieqProcessInputEvents();
|
2007-11-24 10:55:21 -07:00
|
|
|
#if 00 /*BP*/
|
2012-06-10 07:21:05 -06:00
|
|
|
miPointerUpdate();
|
2007-11-24 10:55:21 -07:00
|
|
|
#endif
|
|
|
|
if (dmxInput->detached)
|
|
|
|
return;
|
2006-11-26 11:13:41 -07:00
|
|
|
for (i = 0; i < dmxInput->numDevs; i += dmxInput->devs[i]->binding)
|
2007-11-24 10:55:21 -07:00
|
|
|
if (dmxInput->devs[i]->process_input) {
|
2006-11-26 11:13:41 -07:00
|
|
|
dmxInput->devs[i]->process_input(dmxInput->devs[i]->private);
|
2007-11-24 10:55:21 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
#if 11 /*BP*/
|
2012-06-10 07:21:05 -06:00
|
|
|
mieqProcessInputEvents();
|
2007-11-24 10:55:21 -07:00
|
|
|
#endif
|
2006-11-26 11:13:41 -07:00
|
|
|
}
|
|
|
|
|
2012-06-10 07:21:05 -06:00
|
|
|
static void
|
|
|
|
dmxUpdateWindowInformation(DMXInputInfo * dmxInput,
|
|
|
|
DMXUpdateType type, WindowPtr pWindow)
|
2006-11-26 11:13:41 -07:00
|
|
|
{
|
|
|
|
int i;
|
|
|
|
|
|
|
|
#ifdef PANORAMIX
|
2012-06-10 07:21:05 -06:00
|
|
|
if (!noPanoramiXExtension && pWindow &&
|
|
|
|
pWindow->parent != screenInfo.screens[0]->root)
|
2006-11-26 11:13:41 -07:00
|
|
|
return;
|
|
|
|
#endif
|
|
|
|
#if DMX_WINDOW_DEBUG
|
|
|
|
{
|
|
|
|
const char *name = "Unknown";
|
2012-06-10 07:21:05 -06:00
|
|
|
|
2006-11-26 11:13:41 -07:00
|
|
|
switch (type) {
|
2012-06-10 07:21:05 -06:00
|
|
|
case DMX_UPDATE_REALIZE:
|
|
|
|
name = "Realize";
|
|
|
|
break;
|
|
|
|
case DMX_UPDATE_UNREALIZE:
|
|
|
|
name = "Unrealize";
|
|
|
|
break;
|
|
|
|
case DMX_UPDATE_RESTACK:
|
|
|
|
name = "Restack";
|
|
|
|
break;
|
|
|
|
case DMX_UPDATE_COPY:
|
|
|
|
name = "Copy";
|
|
|
|
break;
|
|
|
|
case DMX_UPDATE_RESIZE:
|
|
|
|
name = "Resize";
|
|
|
|
break;
|
|
|
|
case DMX_UPDATE_REPARENT:
|
|
|
|
name = "Repaint";
|
|
|
|
break;
|
2006-11-26 11:13:41 -07:00
|
|
|
}
|
|
|
|
dmxLog(dmxDebug, "Window %p changed: %s\n", pWindow, name);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2007-11-24 10:55:21 -07:00
|
|
|
if (dmxInput->detached)
|
|
|
|
return;
|
2006-11-26 11:13:41 -07:00
|
|
|
for (i = 0; i < dmxInput->numDevs; i += dmxInput->devs[i]->binding)
|
|
|
|
if (dmxInput->devs[i]->update_info)
|
|
|
|
dmxInput->devs[i]->update_info(dmxInput->devs[i]->private,
|
|
|
|
type, pWindow);
|
|
|
|
}
|
|
|
|
|
2012-06-10 07:21:05 -06:00
|
|
|
static void
|
|
|
|
dmxCollectAll(DMXInputInfo * dmxInput)
|
2006-11-26 11:13:41 -07:00
|
|
|
{
|
|
|
|
int i;
|
|
|
|
|
2007-11-24 10:55:21 -07:00
|
|
|
if (dmxInput->detached)
|
|
|
|
return;
|
2006-11-26 11:13:41 -07:00
|
|
|
for (i = 0; i < dmxInput->numDevs; i += dmxInput->devs[i]->binding)
|
|
|
|
if (dmxInput->devs[i]->collect_events)
|
2012-06-10 07:21:05 -06:00
|
|
|
dmxInput->devs[i]->collect_events(&dmxInput->devs[i]->pDevice->
|
|
|
|
public, dmxMotion, dmxEnqueue,
|
2006-11-26 11:13:41 -07:00
|
|
|
dmxCheckSpecialKeys, DMX_BLOCK);
|
|
|
|
}
|
|
|
|
|
2012-06-10 07:21:05 -06:00
|
|
|
static void
|
2014-09-27 11:52:59 -06:00
|
|
|
dmxBlockHandler(void *blockData, OSTimePtr pTimeout, void *pReadMask)
|
2006-11-26 11:13:41 -07:00
|
|
|
{
|
2012-06-10 07:21:05 -06:00
|
|
|
DMXInputInfo *dmxInput = &dmxInputs[(uintptr_t) blockData];
|
2006-11-26 11:13:41 -07:00
|
|
|
static unsigned long generation = 0;
|
2012-06-10 07:21:05 -06:00
|
|
|
|
2006-11-26 11:13:41 -07:00
|
|
|
if (generation != serverGeneration) {
|
|
|
|
generation = serverGeneration;
|
|
|
|
dmxCollectAll(dmxInput);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-06-10 07:21:05 -06:00
|
|
|
static void
|
2014-09-27 11:52:59 -06:00
|
|
|
dmxSwitchReturn(void *p)
|
2006-11-26 11:13:41 -07:00
|
|
|
{
|
|
|
|
DMXInputInfo *dmxInput = p;
|
2012-06-10 07:21:05 -06:00
|
|
|
int i;
|
|
|
|
|
2006-11-26 11:13:41 -07:00
|
|
|
dmxLog(dmxInfo, "Returning from VT %d\n", dmxInput->vt_switched);
|
|
|
|
|
|
|
|
if (!dmxInput->vt_switched)
|
|
|
|
dmxLog(dmxFatal, "dmxSwitchReturn called, but not switched\n");
|
|
|
|
dmxSigioEnableInput();
|
|
|
|
for (i = 0; i < dmxInput->numDevs; i++)
|
|
|
|
if (dmxInput->devs[i]->vt_post_switch)
|
|
|
|
dmxInput->devs[i]->vt_post_switch(dmxInput->devs[i]->private);
|
|
|
|
dmxInput->vt_switched = 0;
|
|
|
|
}
|
|
|
|
|
2012-06-10 07:21:05 -06:00
|
|
|
static void
|
2014-09-27 11:52:59 -06:00
|
|
|
dmxWakeupHandler(void *blockData, int result, void *pReadMask)
|
2006-11-26 11:13:41 -07:00
|
|
|
{
|
2012-06-10 07:21:05 -06:00
|
|
|
DMXInputInfo *dmxInput = &dmxInputs[(uintptr_t) blockData];
|
|
|
|
int i;
|
2006-11-26 11:13:41 -07:00
|
|
|
|
|
|
|
if (dmxInput->vt_switch_pending) {
|
|
|
|
dmxLog(dmxInfo, "Switching to VT %d\n", dmxInput->vt_switch_pending);
|
|
|
|
for (i = 0; i < dmxInput->numDevs; i++)
|
|
|
|
if (dmxInput->devs[i]->vt_pre_switch)
|
|
|
|
dmxInput->devs[i]->vt_pre_switch(dmxInput->devs[i]->private);
|
2012-06-10 07:21:05 -06:00
|
|
|
dmxInput->vt_switched = dmxInput->vt_switch_pending;
|
2006-11-26 11:13:41 -07:00
|
|
|
dmxInput->vt_switch_pending = 0;
|
|
|
|
for (i = 0; i < dmxInput->numDevs; i++) {
|
|
|
|
if (dmxInput->devs[i]->vt_switch) {
|
|
|
|
dmxSigioDisableInput();
|
|
|
|
if (!dmxInput->devs[i]->vt_switch(dmxInput->devs[i]->private,
|
|
|
|
dmxInput->vt_switched,
|
2012-06-10 07:21:05 -06:00
|
|
|
dmxSwitchReturn, dmxInput))
|
2006-11-26 11:13:41 -07:00
|
|
|
dmxSwitchReturn(dmxInput);
|
|
|
|
break; /* Only call one vt_switch routine */
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
dmxCollectAll(dmxInput);
|
|
|
|
}
|
|
|
|
|
2012-06-10 07:21:05 -06:00
|
|
|
static char *
|
|
|
|
dmxMakeUniqueDeviceName(DMXLocalInputInfoPtr dmxLocal)
|
2006-11-26 11:13:41 -07:00
|
|
|
{
|
2012-06-10 07:21:05 -06:00
|
|
|
static int k = 0;
|
|
|
|
static int m = 0;
|
|
|
|
static int o = 0;
|
2006-11-26 11:13:41 -07:00
|
|
|
static unsigned long dmxGeneration = 0;
|
2012-06-10 07:21:05 -06:00
|
|
|
|
2006-11-26 11:13:41 -07:00
|
|
|
#define LEN 32
|
2012-06-10 07:21:05 -06:00
|
|
|
char *buf = malloc(LEN);
|
2006-11-26 11:13:41 -07:00
|
|
|
|
|
|
|
if (dmxGeneration != serverGeneration) {
|
2012-06-10 07:21:05 -06:00
|
|
|
k = m = o = 0;
|
2006-11-26 11:13:41 -07:00
|
|
|
dmxGeneration = serverGeneration;
|
|
|
|
}
|
|
|
|
|
|
|
|
switch (dmxLocal->type) {
|
2012-06-10 07:21:05 -06:00
|
|
|
case DMX_LOCAL_KEYBOARD:
|
|
|
|
snprintf(buf, LEN, "Keyboard%d", k++);
|
|
|
|
break;
|
|
|
|
case DMX_LOCAL_MOUSE:
|
|
|
|
snprintf(buf, LEN, "Mouse%d", m++);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
snprintf(buf, LEN, "Other%d", o++);
|
|
|
|
break;
|
2006-11-26 11:13:41 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
return buf;
|
|
|
|
}
|
|
|
|
|
2012-06-10 07:21:05 -06:00
|
|
|
static DeviceIntPtr
|
|
|
|
dmxAddDevice(DMXLocalInputInfoPtr dmxLocal)
|
2006-11-26 11:13:41 -07:00
|
|
|
{
|
|
|
|
DeviceIntPtr pDevice;
|
2012-06-10 07:21:05 -06:00
|
|
|
Atom atom;
|
|
|
|
const char *name = NULL;
|
|
|
|
char *devname;
|
2006-11-26 11:13:41 -07:00
|
|
|
DMXInputInfo *dmxInput;
|
|
|
|
|
2007-11-24 10:55:21 -07:00
|
|
|
if (!dmxLocal)
|
|
|
|
return NULL;
|
2006-11-26 11:13:41 -07:00
|
|
|
dmxInput = &dmxInputs[dmxLocal->inputIdx];
|
|
|
|
|
|
|
|
if (dmxLocal->sendsCore) {
|
|
|
|
if (dmxLocal->type == DMX_LOCAL_KEYBOARD && !dmxLocalCoreKeyboard) {
|
2012-06-10 07:21:05 -06:00
|
|
|
dmxLocal->isCore = 1;
|
2006-11-26 11:13:41 -07:00
|
|
|
dmxLocalCoreKeyboard = dmxLocal;
|
2012-06-10 07:21:05 -06:00
|
|
|
name = "keyboard";
|
2006-11-26 11:13:41 -07:00
|
|
|
}
|
|
|
|
if (dmxLocal->type == DMX_LOCAL_MOUSE && !dmxLocalCorePointer) {
|
2012-06-10 07:21:05 -06:00
|
|
|
dmxLocal->isCore = 1;
|
|
|
|
dmxLocalCorePointer = dmxLocal;
|
|
|
|
name = "pointer";
|
2006-11-26 11:13:41 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!name) {
|
2012-06-10 07:21:05 -06:00
|
|
|
name = "extension";
|
2006-11-26 11:13:41 -07:00
|
|
|
}
|
|
|
|
|
2011-11-05 07:32:40 -06:00
|
|
|
if (!name)
|
2006-11-26 11:13:41 -07:00
|
|
|
dmxLog(dmxFatal, "Cannot add device %s\n", dmxLocal->name);
|
|
|
|
|
2012-06-10 07:21:05 -06:00
|
|
|
pDevice = AddInputDevice(serverClient, dmxDeviceOnOff, TRUE);
|
2006-11-26 11:13:41 -07:00
|
|
|
if (!pDevice) {
|
|
|
|
dmxLog(dmxError, "Too many devices -- cannot add device %s\n",
|
|
|
|
dmxLocal->name);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
pDevice->public.devicePrivate = dmxLocal;
|
2012-06-10 07:21:05 -06:00
|
|
|
dmxLocal->pDevice = pDevice;
|
2006-11-26 11:13:41 -07:00
|
|
|
|
2012-06-10 07:21:05 -06:00
|
|
|
devname = dmxMakeUniqueDeviceName(dmxLocal);
|
|
|
|
atom = MakeAtom((char *) devname, strlen(devname), TRUE);
|
2006-11-26 11:13:41 -07:00
|
|
|
pDevice->type = atom;
|
|
|
|
pDevice->name = devname;
|
|
|
|
|
2007-11-24 10:55:21 -07:00
|
|
|
if (dmxLocal->isCore && dmxLocal->type == DMX_LOCAL_MOUSE) {
|
2012-06-10 07:21:05 -06:00
|
|
|
#if 00 /*BP*/
|
|
|
|
miRegisterPointerDevice(screenInfo.screens[0], pDevice);
|
2007-11-24 10:55:21 -07:00
|
|
|
#else
|
|
|
|
/* Nothing? dmxDeviceOnOff() should get called to init, right? */
|
|
|
|
#endif
|
|
|
|
}
|
2006-11-26 11:13:41 -07:00
|
|
|
|
|
|
|
if (dmxLocal->create_private)
|
|
|
|
dmxLocal->private = dmxLocal->create_private(pDevice);
|
|
|
|
|
|
|
|
dmxLogInput(dmxInput, "Added %s as %s device called %s%s\n",
|
|
|
|
dmxLocal->name, name, devname,
|
|
|
|
dmxLocal->isCore
|
|
|
|
? " [core]"
|
2012-06-10 07:21:05 -06:00
|
|
|
: (dmxLocal->sendsCore ? " [sends core events]" : ""));
|
2006-11-26 11:13:41 -07:00
|
|
|
|
|
|
|
return pDevice;
|
|
|
|
}
|
|
|
|
|
2012-06-10 07:21:05 -06:00
|
|
|
static DMXLocalInputInfoPtr
|
|
|
|
dmxLookupLocal(const char *name)
|
2006-11-26 11:13:41 -07:00
|
|
|
{
|
|
|
|
DMXLocalInputInfoPtr pt;
|
2012-06-10 07:21:05 -06:00
|
|
|
|
2006-11-26 11:13:41 -07:00
|
|
|
for (pt = &DMXLocalDevices[0]; pt->name; ++pt)
|
2012-06-10 07:21:05 -06:00
|
|
|
if (!strcmp(pt->name, name))
|
|
|
|
return pt; /* search for device name */
|
2006-11-26 11:13:41 -07:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
/** Copy the local input information from \a s into a new \a devs slot
|
|
|
|
* in \a dmxInput. */
|
2012-06-10 07:21:05 -06:00
|
|
|
DMXLocalInputInfoPtr
|
|
|
|
dmxInputCopyLocal(DMXInputInfo * dmxInput, DMXLocalInputInfoPtr s)
|
2006-11-26 11:13:41 -07:00
|
|
|
{
|
2010-12-05 08:36:02 -07:00
|
|
|
DMXLocalInputInfoPtr dmxLocal = malloc(sizeof(*dmxLocal));
|
2012-06-10 07:21:05 -06:00
|
|
|
|
2006-11-26 11:13:41 -07:00
|
|
|
if (!dmxLocal)
|
|
|
|
dmxLog(dmxFatal, "DMXLocalInputInfoPtr: out of memory\n");
|
|
|
|
|
|
|
|
memcpy(dmxLocal, s, sizeof(*dmxLocal));
|
2012-06-10 07:21:05 -06:00
|
|
|
dmxLocal->inputIdx = dmxInput->inputIdx;
|
|
|
|
dmxLocal->sendsCore = dmxInput->core;
|
2006-11-26 11:13:41 -07:00
|
|
|
dmxLocal->savedSendsCore = dmxInput->core;
|
2012-06-10 07:21:05 -06:00
|
|
|
dmxLocal->deviceId = -1;
|
2006-11-26 11:13:41 -07:00
|
|
|
|
|
|
|
++dmxInput->numDevs;
|
2016-05-29 06:02:34 -06:00
|
|
|
dmxInput->devs = reallocarray(dmxInput->devs,
|
|
|
|
dmxInput->numDevs, sizeof(*dmxInput->devs));
|
2012-06-10 07:21:05 -06:00
|
|
|
dmxInput->devs[dmxInput->numDevs - 1] = dmxLocal;
|
|
|
|
|
2006-11-26 11:13:41 -07:00
|
|
|
return dmxLocal;
|
|
|
|
}
|
|
|
|
|
2012-06-10 07:21:05 -06:00
|
|
|
static void
|
|
|
|
dmxPopulateLocal(DMXInputInfo * dmxInput, dmxArg a)
|
2006-11-26 11:13:41 -07:00
|
|
|
{
|
2012-06-10 07:21:05 -06:00
|
|
|
int i;
|
|
|
|
int help = 0;
|
2006-11-26 11:13:41 -07:00
|
|
|
DMXLocalInputInfoRec *pt;
|
|
|
|
|
|
|
|
for (i = 1; i < dmxArgC(a); i++) {
|
|
|
|
const char *name = dmxArgV(a, i);
|
2012-06-10 07:21:05 -06:00
|
|
|
|
2006-11-26 11:13:41 -07:00
|
|
|
if ((pt = dmxLookupLocal(name))) {
|
|
|
|
dmxInputCopyLocal(dmxInput, pt);
|
2012-06-10 07:21:05 -06:00
|
|
|
}
|
|
|
|
else {
|
2006-11-26 11:13:41 -07:00
|
|
|
if (strlen(name))
|
2012-06-10 07:21:05 -06:00
|
|
|
dmxLog(dmxWarning, "Could not find a driver called %s\n", name);
|
2006-11-26 11:13:41 -07:00
|
|
|
++help;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (help) {
|
|
|
|
dmxLog(dmxInfo, "Available local device drivers:\n");
|
|
|
|
for (pt = &DMXLocalDevices[0]; pt->name; ++pt) {
|
|
|
|
const char *type;
|
2012-06-10 07:21:05 -06:00
|
|
|
|
2006-11-26 11:13:41 -07:00
|
|
|
switch (pt->type) {
|
2012-06-10 07:21:05 -06:00
|
|
|
case DMX_LOCAL_KEYBOARD:
|
|
|
|
type = "keyboard";
|
|
|
|
break;
|
|
|
|
case DMX_LOCAL_MOUSE:
|
|
|
|
type = "pointer";
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
type = "unknown";
|
|
|
|
break;
|
2006-11-26 11:13:41 -07:00
|
|
|
}
|
|
|
|
dmxLog(dmxInfo, " %s (%s)\n", pt->name, type);
|
|
|
|
}
|
|
|
|
dmxLog(dmxFatal, "Must have valid local device driver\n");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-06-10 07:21:05 -06:00
|
|
|
int
|
|
|
|
dmxInputExtensionErrorHandler(Display * dsp, _Xconst char *name,
|
|
|
|
_Xconst char *reason)
|
2006-11-26 11:13:41 -07:00
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2012-06-10 07:21:05 -06:00
|
|
|
static void
|
|
|
|
dmxInputScanForExtensions(DMXInputInfo * dmxInput, int doXI)
|
2006-11-26 11:13:41 -07:00
|
|
|
{
|
2012-06-10 07:21:05 -06:00
|
|
|
XExtensionVersion *ext;
|
|
|
|
XDeviceInfo *devices;
|
2015-11-07 09:48:51 -07:00
|
|
|
Display *dsp;
|
2012-06-10 07:21:05 -06:00
|
|
|
int num;
|
|
|
|
int i, j;
|
|
|
|
XextErrorHandler handler;
|
|
|
|
|
2015-11-07 09:48:51 -07:00
|
|
|
if (!(dsp = XOpenDisplay(dmxInput->name)))
|
2012-06-10 07:21:05 -06:00
|
|
|
return;
|
|
|
|
|
2006-11-26 11:13:41 -07:00
|
|
|
/* Print out information about the XInput Extension. */
|
|
|
|
handler = XSetExtensionErrorHandler(dmxInputExtensionErrorHandler);
|
2015-11-07 09:48:51 -07:00
|
|
|
ext = XGetExtensionVersion(dsp, INAME);
|
2006-11-26 11:13:41 -07:00
|
|
|
XSetExtensionErrorHandler(handler);
|
2012-06-10 07:21:05 -06:00
|
|
|
|
|
|
|
if (!ext || ext == (XExtensionVersion *) NoSuchExtension) {
|
2006-11-26 11:13:41 -07:00
|
|
|
dmxLogInput(dmxInput, "%s is not available\n", INAME);
|
2012-06-10 07:21:05 -06:00
|
|
|
}
|
|
|
|
else {
|
2006-11-26 11:13:41 -07:00
|
|
|
dmxLogInput(dmxInput, "Locating devices on %s (%s version %d.%d)\n",
|
|
|
|
dmxInput->name, INAME,
|
|
|
|
ext->major_version, ext->minor_version);
|
2015-11-07 09:48:51 -07:00
|
|
|
devices = XListInputDevices(dsp, &num);
|
2006-11-26 11:13:41 -07:00
|
|
|
|
|
|
|
XFree(ext);
|
|
|
|
ext = NULL;
|
|
|
|
|
2012-06-10 07:21:05 -06:00
|
|
|
/* Print a list of all devices */
|
2006-11-26 11:13:41 -07:00
|
|
|
for (i = 0; i < num; i++) {
|
|
|
|
const char *use = "Unknown";
|
2012-06-10 07:21:05 -06:00
|
|
|
|
2006-11-26 11:13:41 -07:00
|
|
|
switch (devices[i].use) {
|
2012-06-10 07:21:05 -06:00
|
|
|
case IsXPointer:
|
|
|
|
use = "XPointer";
|
|
|
|
break;
|
|
|
|
case IsXKeyboard:
|
|
|
|
use = "XKeyboard";
|
|
|
|
break;
|
|
|
|
case IsXExtensionDevice:
|
|
|
|
use = "XExtensionDevice";
|
|
|
|
break;
|
|
|
|
case IsXExtensionPointer:
|
|
|
|
use = "XExtensionPointer";
|
|
|
|
break;
|
|
|
|
case IsXExtensionKeyboard:
|
|
|
|
use = "XExtensionKeyboard";
|
|
|
|
break;
|
2006-11-26 11:13:41 -07:00
|
|
|
}
|
|
|
|
dmxLogInput(dmxInput, " %2d %-10.10s %-16.16s\n",
|
2014-09-27 11:52:59 -06:00
|
|
|
(int) devices[i].id,
|
2012-06-10 07:21:05 -06:00
|
|
|
devices[i].name ? devices[i].name : "", use);
|
2006-11-26 11:13:41 -07:00
|
|
|
}
|
|
|
|
|
2012-06-10 07:21:05 -06:00
|
|
|
/* Search for extensions */
|
2006-11-26 11:13:41 -07:00
|
|
|
for (i = 0; i < num; i++) {
|
|
|
|
switch (devices[i].use) {
|
|
|
|
case IsXKeyboard:
|
|
|
|
for (j = 0; j < dmxInput->numDevs; j++) {
|
|
|
|
DMXLocalInputInfoPtr dmxL = dmxInput->devs[j];
|
2012-06-10 07:21:05 -06:00
|
|
|
|
|
|
|
if (dmxL->type == DMX_LOCAL_KEYBOARD && dmxL->deviceId < 0) {
|
|
|
|
dmxL->deviceId = devices[i].id;
|
2006-11-26 11:13:41 -07:00
|
|
|
dmxL->deviceName = (devices[i].name
|
2010-12-05 08:36:02 -07:00
|
|
|
? strdup(devices[i].name)
|
2006-11-26 11:13:41 -07:00
|
|
|
: NULL);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case IsXPointer:
|
|
|
|
for (j = 0; j < dmxInput->numDevs; j++) {
|
|
|
|
DMXLocalInputInfoPtr dmxL = dmxInput->devs[j];
|
2012-06-10 07:21:05 -06:00
|
|
|
|
2006-11-26 11:13:41 -07:00
|
|
|
if (dmxL->type == DMX_LOCAL_MOUSE && dmxL->deviceId < 0) {
|
2012-06-10 07:21:05 -06:00
|
|
|
dmxL->deviceId = devices[i].id;
|
2006-11-26 11:13:41 -07:00
|
|
|
dmxL->deviceName = (devices[i].name
|
|
|
|
? xstrdup(devices[i].name)
|
|
|
|
: NULL);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
XFreeDeviceList(devices);
|
|
|
|
}
|
2015-11-07 09:48:51 -07:00
|
|
|
XCloseDisplay(dsp);
|
2006-11-26 11:13:41 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
/** Re-initialize all the devices described in \a dmxInput. Called from
|
2010-07-27 13:02:24 -06:00
|
|
|
#dmxAdjustCursorBoundaries before the cursor is redisplayed. */
|
2012-06-10 07:21:05 -06:00
|
|
|
void
|
|
|
|
dmxInputReInit(DMXInputInfo * dmxInput)
|
2006-11-26 11:13:41 -07:00
|
|
|
{
|
|
|
|
int i;
|
|
|
|
|
|
|
|
for (i = 0; i < dmxInput->numDevs; i++) {
|
|
|
|
DMXLocalInputInfoPtr dmxLocal = dmxInput->devs[i];
|
2012-06-10 07:21:05 -06:00
|
|
|
|
2006-11-26 11:13:41 -07:00
|
|
|
if (dmxLocal->reinit)
|
|
|
|
dmxLocal->reinit(&dmxLocal->pDevice->public);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/** Re-initialize all the devices described in \a dmxInput. Called from
|
2010-07-27 13:02:24 -06:00
|
|
|
#dmxAdjustCursorBoundaries after the cursor is redisplayed. */
|
2012-06-10 07:21:05 -06:00
|
|
|
void
|
|
|
|
dmxInputLateReInit(DMXInputInfo * dmxInput)
|
2006-11-26 11:13:41 -07:00
|
|
|
{
|
|
|
|
int i;
|
|
|
|
|
|
|
|
for (i = 0; i < dmxInput->numDevs; i++) {
|
|
|
|
DMXLocalInputInfoPtr dmxLocal = dmxInput->devs[i];
|
2012-06-10 07:21:05 -06:00
|
|
|
|
2006-11-26 11:13:41 -07:00
|
|
|
if (dmxLocal->latereinit)
|
|
|
|
dmxLocal->latereinit(&dmxLocal->pDevice->public);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/** Initialize all of the devices described in \a dmxInput. */
|
2012-06-10 07:21:05 -06:00
|
|
|
void
|
|
|
|
dmxInputInit(DMXInputInfo * dmxInput)
|
2006-11-26 11:13:41 -07:00
|
|
|
{
|
2012-06-10 07:21:05 -06:00
|
|
|
dmxArg a;
|
|
|
|
const char *name;
|
|
|
|
int i;
|
|
|
|
int doXI = 1; /* Include by default */
|
|
|
|
int forceConsole = 0;
|
|
|
|
int doWindows = 1; /* On by default */
|
|
|
|
int hasXkb = 0;
|
2006-11-26 11:13:41 -07:00
|
|
|
|
|
|
|
a = dmxArgParse(dmxInput->name);
|
|
|
|
|
|
|
|
for (i = 1; i < dmxArgC(a); i++) {
|
|
|
|
switch (hasXkb) {
|
|
|
|
case 1:
|
|
|
|
dmxInput->keycodes = xstrdup(dmxArgV(a, i));
|
|
|
|
++hasXkb;
|
|
|
|
break;
|
|
|
|
case 2:
|
2012-06-10 07:21:05 -06:00
|
|
|
dmxInput->symbols = xstrdup(dmxArgV(a, i));
|
2006-11-26 11:13:41 -07:00
|
|
|
++hasXkb;
|
|
|
|
break;
|
|
|
|
case 3:
|
|
|
|
dmxInput->geometry = xstrdup(dmxArgV(a, i));
|
|
|
|
hasXkb = 0;
|
|
|
|
break;
|
|
|
|
case 0:
|
2012-06-10 07:21:05 -06:00
|
|
|
if (!strcmp(dmxArgV(a, i), "noxi"))
|
|
|
|
doXI = 0;
|
|
|
|
else if (!strcmp(dmxArgV(a, i), "xi"))
|
|
|
|
doXI = 1;
|
|
|
|
else if (!strcmp(dmxArgV(a, i), "console"))
|
|
|
|
forceConsole = 1;
|
|
|
|
else if (!strcmp(dmxArgV(a, i), "noconsole"))
|
|
|
|
forceConsole = 0;
|
|
|
|
else if (!strcmp(dmxArgV(a, i), "windows"))
|
|
|
|
doWindows = 1;
|
|
|
|
else if (!strcmp(dmxArgV(a, i), "nowindows"))
|
|
|
|
doWindows = 0;
|
|
|
|
else if (!strcmp(dmxArgV(a, i), "xkb"))
|
|
|
|
hasXkb = 1;
|
2006-11-26 11:13:41 -07:00
|
|
|
else {
|
2012-06-10 07:21:05 -06:00
|
|
|
dmxLog(dmxFatal, "Unknown input argument: %s\n", dmxArgV(a, i));
|
2006-11-26 11:13:41 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
name = dmxArgV(a, 0);
|
|
|
|
|
|
|
|
if (!strcmp(name, "local")) {
|
|
|
|
dmxPopulateLocal(dmxInput, a);
|
2012-06-10 07:21:05 -06:00
|
|
|
}
|
|
|
|
else if (!strcmp(name, "dummy")) {
|
2006-11-26 11:13:41 -07:00
|
|
|
dmxInputCopyLocal(dmxInput, &DMXDummyMou);
|
|
|
|
dmxInputCopyLocal(dmxInput, &DMXDummyKbd);
|
|
|
|
dmxLogInput(dmxInput, "Using dummy input\n");
|
2012-06-10 07:21:05 -06:00
|
|
|
}
|
|
|
|
else {
|
2006-11-26 11:13:41 -07:00
|
|
|
int found;
|
|
|
|
|
|
|
|
for (found = 0, i = 0; i < dmxNumScreens; i++) {
|
|
|
|
if (dmxPropertySameDisplay(&dmxScreens[i], name)) {
|
|
|
|
if (dmxScreens[i].shared)
|
|
|
|
dmxLog(dmxFatal,
|
|
|
|
"Cannot take input from shared backend (%s)\n",
|
|
|
|
name);
|
|
|
|
if (!dmxInput->core) {
|
|
|
|
dmxLog(dmxWarning,
|
|
|
|
"Cannot use core devices on a backend (%s)"
|
|
|
|
" as XInput devices\n", name);
|
2012-06-10 07:21:05 -06:00
|
|
|
}
|
|
|
|
else {
|
2006-11-26 11:13:41 -07:00
|
|
|
char *pt;
|
2012-06-10 07:21:05 -06:00
|
|
|
|
|
|
|
for (pt = (char *) dmxInput->name; pt && *pt; pt++)
|
|
|
|
if (*pt == ',')
|
|
|
|
*pt = '\0';
|
2006-11-26 11:13:41 -07:00
|
|
|
dmxInputCopyLocal(dmxInput, &DMXBackendMou);
|
|
|
|
dmxInputCopyLocal(dmxInput, &DMXBackendKbd);
|
|
|
|
dmxInput->scrnIdx = i;
|
|
|
|
dmxLogInput(dmxInput,
|
|
|
|
"Using backend input from %s\n", name);
|
|
|
|
}
|
|
|
|
++found;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (!found || forceConsole) {
|
|
|
|
char *pt;
|
2012-06-10 07:21:05 -06:00
|
|
|
|
|
|
|
if (found)
|
|
|
|
dmxInput->console = TRUE;
|
|
|
|
for (pt = (char *) dmxInput->name; pt && *pt; pt++)
|
|
|
|
if (*pt == ',')
|
|
|
|
*pt = '\0';
|
2006-11-26 11:13:41 -07:00
|
|
|
dmxInputCopyLocal(dmxInput, &DMXConsoleMou);
|
|
|
|
dmxInputCopyLocal(dmxInput, &DMXConsoleKbd);
|
|
|
|
if (doWindows) {
|
2012-06-10 07:21:05 -06:00
|
|
|
dmxInput->windows = TRUE;
|
2006-11-26 11:13:41 -07:00
|
|
|
dmxInput->updateWindowInfo = dmxUpdateWindowInformation;
|
|
|
|
}
|
|
|
|
dmxLogInput(dmxInput,
|
|
|
|
"Using console input from %s (%s windows)\n",
|
|
|
|
name, doWindows ? "with" : "without");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
dmxArgFree(a);
|
|
|
|
|
2012-06-10 07:21:05 -06:00
|
|
|
/* Locate extensions we may be interested in */
|
2006-11-26 11:13:41 -07:00
|
|
|
dmxInputScanForExtensions(dmxInput, doXI);
|
2012-06-10 07:21:05 -06:00
|
|
|
|
2006-11-26 11:13:41 -07:00
|
|
|
for (i = 0; i < dmxInput->numDevs; i++) {
|
|
|
|
DMXLocalInputInfoPtr dmxLocal = dmxInput->devs[i];
|
2012-06-10 07:21:05 -06:00
|
|
|
|
2006-11-26 11:13:41 -07:00
|
|
|
dmxLocal->pDevice = dmxAddDevice(dmxLocal);
|
|
|
|
}
|
2012-06-10 07:21:05 -06:00
|
|
|
|
|
|
|
dmxInput->processInputEvents = dmxProcessInputEvents;
|
|
|
|
dmxInput->detached = False;
|
|
|
|
|
2011-11-05 07:32:40 -06:00
|
|
|
RegisterBlockAndWakeupHandlers(dmxBlockHandler, dmxWakeupHandler,
|
2012-06-10 07:21:05 -06:00
|
|
|
(void *) (uintptr_t) dmxInput->inputIdx);
|
2006-11-26 11:13:41 -07:00
|
|
|
}
|
|
|
|
|
2012-06-10 07:21:05 -06:00
|
|
|
static void
|
|
|
|
dmxInputFreeLocal(DMXLocalInputInfoRec * local)
|
2006-11-26 11:13:41 -07:00
|
|
|
{
|
2012-06-10 07:21:05 -06:00
|
|
|
if (!local)
|
|
|
|
return;
|
2006-11-26 11:13:41 -07:00
|
|
|
if (local->isCore && local->type == DMX_LOCAL_MOUSE)
|
2012-06-10 07:21:05 -06:00
|
|
|
dmxLocalCorePointer = NULL;
|
2006-11-26 11:13:41 -07:00
|
|
|
if (local->isCore && local->type == DMX_LOCAL_KEYBOARD)
|
|
|
|
dmxLocalCoreKeyboard = NULL;
|
2012-06-10 07:21:05 -06:00
|
|
|
if (local->destroy_private)
|
|
|
|
local->destroy_private(local->private);
|
2010-12-05 08:36:02 -07:00
|
|
|
free(local->history);
|
|
|
|
free(local->valuators);
|
2014-09-27 11:52:59 -06:00
|
|
|
free((void *) local->deviceName);
|
2012-06-10 07:21:05 -06:00
|
|
|
local->private = NULL;
|
|
|
|
local->history = NULL;
|
2006-11-26 11:13:41 -07:00
|
|
|
local->deviceName = NULL;
|
2010-12-05 08:36:02 -07:00
|
|
|
free(local);
|
2006-11-26 11:13:41 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
/** Free all of the memory associated with \a dmxInput */
|
2012-06-10 07:21:05 -06:00
|
|
|
void
|
|
|
|
dmxInputFree(DMXInputInfo * dmxInput)
|
2006-11-26 11:13:41 -07:00
|
|
|
{
|
|
|
|
int i;
|
2012-06-10 07:21:05 -06:00
|
|
|
|
|
|
|
if (!dmxInput)
|
|
|
|
return;
|
2006-11-26 11:13:41 -07:00
|
|
|
|
2010-12-05 08:36:02 -07:00
|
|
|
free(dmxInput->keycodes);
|
|
|
|
free(dmxInput->symbols);
|
|
|
|
free(dmxInput->geometry);
|
2006-11-26 11:13:41 -07:00
|
|
|
|
|
|
|
for (i = 0; i < dmxInput->numDevs; i++) {
|
|
|
|
dmxInputFreeLocal(dmxInput->devs[i]);
|
|
|
|
dmxInput->devs[i] = NULL;
|
|
|
|
}
|
2010-12-05 08:36:02 -07:00
|
|
|
free(dmxInput->devs);
|
2012-06-10 07:21:05 -06:00
|
|
|
dmxInput->devs = NULL;
|
2006-11-26 11:13:41 -07:00
|
|
|
dmxInput->numDevs = 0;
|
2012-06-10 07:21:05 -06:00
|
|
|
if (dmxInput->freename)
|
2014-09-27 11:52:59 -06:00
|
|
|
free((void *) dmxInput->name);
|
2012-06-10 07:21:05 -06:00
|
|
|
dmxInput->name = NULL;
|
2006-11-26 11:13:41 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
/** Log information about all of the known devices using #dmxLog(). */
|
2012-06-10 07:21:05 -06:00
|
|
|
void
|
|
|
|
dmxInputLogDevices(void)
|
2006-11-26 11:13:41 -07:00
|
|
|
{
|
|
|
|
int i, j;
|
|
|
|
|
|
|
|
dmxLog(dmxInfo, "%d devices:\n", dmxGetInputCount());
|
|
|
|
dmxLog(dmxInfo, " Id Name Classes\n");
|
|
|
|
for (j = 0; j < dmxNumInputs; j++) {
|
|
|
|
DMXInputInfo *dmxInput = &dmxInputs[j];
|
2012-06-10 07:21:05 -06:00
|
|
|
const char *pt = strchr(dmxInput->name, ',');
|
|
|
|
int len = (pt ? (size_t) (pt - dmxInput->name)
|
|
|
|
: strlen(dmxInput->name));
|
2006-11-26 11:13:41 -07:00
|
|
|
|
|
|
|
for (i = 0; i < dmxInput->numDevs; i++) {
|
|
|
|
DeviceIntPtr pDevice = dmxInput->devs[i]->pDevice;
|
2012-06-10 07:21:05 -06:00
|
|
|
|
2006-11-26 11:13:41 -07:00
|
|
|
if (pDevice) {
|
|
|
|
dmxLog(dmxInfo, " %2d%c %-20.20s",
|
|
|
|
pDevice->id,
|
2012-06-10 07:21:05 -06:00
|
|
|
dmxInput->detached ? 'D' : ' ', pDevice->name);
|
|
|
|
if (pDevice->key)
|
|
|
|
dmxLogCont(dmxInfo, " key");
|
|
|
|
if (pDevice->valuator)
|
|
|
|
dmxLogCont(dmxInfo, " val");
|
|
|
|
if (pDevice->button)
|
|
|
|
dmxLogCont(dmxInfo, " btn");
|
|
|
|
if (pDevice->focus)
|
|
|
|
dmxLogCont(dmxInfo, " foc");
|
|
|
|
if (pDevice->kbdfeed)
|
|
|
|
dmxLogCont(dmxInfo, " fb/kbd");
|
|
|
|
if (pDevice->ptrfeed)
|
|
|
|
dmxLogCont(dmxInfo, " fb/ptr");
|
|
|
|
if (pDevice->intfeed)
|
|
|
|
dmxLogCont(dmxInfo, " fb/int");
|
|
|
|
if (pDevice->stringfeed)
|
|
|
|
dmxLogCont(dmxInfo, " fb/str");
|
|
|
|
if (pDevice->bell)
|
|
|
|
dmxLogCont(dmxInfo, " fb/bel");
|
|
|
|
if (pDevice->leds)
|
|
|
|
dmxLogCont(dmxInfo, " fb/led");
|
2006-11-26 11:13:41 -07:00
|
|
|
if (!pDevice->key && !pDevice->valuator && !pDevice->button
|
|
|
|
&& !pDevice->focus && !pDevice->kbdfeed
|
|
|
|
&& !pDevice->ptrfeed && !pDevice->intfeed
|
2012-06-10 07:21:05 -06:00
|
|
|
&& !pDevice->stringfeed && !pDevice->bell && !pDevice->leds)
|
|
|
|
dmxLogCont(dmxInfo, " (none)");
|
|
|
|
|
2006-11-26 11:13:41 -07:00
|
|
|
dmxLogCont(dmxInfo, "\t[i%d/%*.*s",
|
|
|
|
dmxInput->inputIdx, len, len, dmxInput->name);
|
|
|
|
if (dmxInput->devs[i]->deviceId >= 0)
|
2014-09-27 11:52:59 -06:00
|
|
|
dmxLogCont(dmxInfo, "/id%d", (int) dmxInput->devs[i]->deviceId);
|
2006-11-26 11:13:41 -07:00
|
|
|
if (dmxInput->devs[i]->deviceName)
|
|
|
|
dmxLogCont(dmxInfo, "=%s", dmxInput->devs[i]->deviceName);
|
|
|
|
dmxLogCont(dmxInfo, "] %s\n",
|
|
|
|
dmxInput->devs[i]->isCore
|
|
|
|
? "core"
|
|
|
|
: (dmxInput->devs[i]->sendsCore
|
2012-06-10 07:21:05 -06:00
|
|
|
? "extension (sends core events)" : "extension"));
|
2006-11-26 11:13:41 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/** Detach an input */
|
2012-06-10 07:21:05 -06:00
|
|
|
int
|
|
|
|
dmxInputDetach(DMXInputInfo * dmxInput)
|
2006-11-26 11:13:41 -07:00
|
|
|
{
|
|
|
|
int i;
|
|
|
|
|
2012-06-10 07:21:05 -06:00
|
|
|
if (dmxInput->detached)
|
|
|
|
return BadAccess;
|
|
|
|
|
2006-11-26 11:13:41 -07:00
|
|
|
for (i = 0; i < dmxInput->numDevs; i++) {
|
|
|
|
DMXLocalInputInfoPtr dmxLocal = dmxInput->devs[i];
|
2012-06-10 07:21:05 -06:00
|
|
|
|
2006-11-26 11:13:41 -07:00
|
|
|
dmxLogInput(dmxInput, "Detaching device id %d: %s%s\n",
|
|
|
|
dmxLocal->pDevice->id,
|
|
|
|
dmxLocal->pDevice->name,
|
|
|
|
dmxLocal->isCore
|
|
|
|
? " [core]"
|
2012-06-10 07:21:05 -06:00
|
|
|
: (dmxLocal->sendsCore ? " [sends core events]" : ""));
|
2010-07-27 13:02:24 -06:00
|
|
|
DisableDevice(dmxLocal->pDevice, TRUE);
|
2006-11-26 11:13:41 -07:00
|
|
|
}
|
|
|
|
dmxInput->detached = True;
|
|
|
|
dmxInputLogDevices();
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/** Search for input associated with \a dmxScreen, and detach. */
|
2012-06-10 07:21:05 -06:00
|
|
|
void
|
|
|
|
dmxInputDetachAll(DMXScreenInfo * dmxScreen)
|
2006-11-26 11:13:41 -07:00
|
|
|
{
|
|
|
|
int i;
|
|
|
|
|
|
|
|
for (i = 0; i < dmxNumInputs; i++) {
|
|
|
|
DMXInputInfo *dmxInput = &dmxInputs[i];
|
2012-06-10 07:21:05 -06:00
|
|
|
|
|
|
|
if (dmxInput->scrnIdx == dmxScreen->index)
|
|
|
|
dmxInputDetach(dmxInput);
|
2006-11-26 11:13:41 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/** Search for input associated with \a deviceId, and detach. */
|
2012-06-10 07:21:05 -06:00
|
|
|
int
|
|
|
|
dmxInputDetachId(int id)
|
2006-11-26 11:13:41 -07:00
|
|
|
{
|
|
|
|
DMXInputInfo *dmxInput = dmxInputLocateId(id);
|
|
|
|
|
2012-06-10 07:21:05 -06:00
|
|
|
if (!dmxInput)
|
|
|
|
return BadValue;
|
|
|
|
|
2006-11-26 11:13:41 -07:00
|
|
|
return dmxInputDetach(dmxInput);
|
|
|
|
}
|
|
|
|
|
2012-06-10 07:21:05 -06:00
|
|
|
DMXInputInfo *
|
|
|
|
dmxInputLocateId(int id)
|
2006-11-26 11:13:41 -07:00
|
|
|
{
|
|
|
|
int i, j;
|
2012-06-10 07:21:05 -06:00
|
|
|
|
2006-11-26 11:13:41 -07:00
|
|
|
for (i = 0; i < dmxNumInputs; i++) {
|
|
|
|
DMXInputInfo *dmxInput = &dmxInputs[i];
|
2012-06-10 07:21:05 -06:00
|
|
|
|
2006-11-26 11:13:41 -07:00
|
|
|
for (j = 0; j < dmxInput->numDevs; j++) {
|
|
|
|
DMXLocalInputInfoPtr dmxLocal = dmxInput->devs[j];
|
2012-06-10 07:21:05 -06:00
|
|
|
|
|
|
|
if (dmxLocal->pDevice->id == id)
|
|
|
|
return dmxInput;
|
2006-11-26 11:13:41 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2012-06-10 07:21:05 -06:00
|
|
|
static int
|
|
|
|
dmxInputAttachNew(DMXInputInfo * dmxInput, int *id)
|
2006-11-26 11:13:41 -07:00
|
|
|
{
|
|
|
|
dmxInputInit(dmxInput);
|
|
|
|
InitAndStartDevices();
|
2012-06-10 07:21:05 -06:00
|
|
|
if (id && dmxInput->devs)
|
|
|
|
*id = dmxInput->devs[0]->pDevice->id;
|
2006-11-26 11:13:41 -07:00
|
|
|
dmxInputLogDevices();
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2012-06-10 07:21:05 -06:00
|
|
|
static int
|
|
|
|
dmxInputAttachOld(DMXInputInfo * dmxInput, int *id)
|
2006-11-26 11:13:41 -07:00
|
|
|
{
|
|
|
|
int i;
|
2012-06-10 07:21:05 -06:00
|
|
|
|
2006-11-26 11:13:41 -07:00
|
|
|
dmxInput->detached = False;
|
|
|
|
for (i = 0; i < dmxInput->numDevs; i++) {
|
|
|
|
DMXLocalInputInfoPtr dmxLocal = dmxInput->devs[i];
|
2012-06-10 07:21:05 -06:00
|
|
|
|
|
|
|
if (id)
|
|
|
|
*id = dmxLocal->pDevice->id;
|
2006-11-26 11:13:41 -07:00
|
|
|
dmxLogInput(dmxInput,
|
|
|
|
"Attaching device id %d: %s%s\n",
|
|
|
|
dmxLocal->pDevice->id,
|
|
|
|
dmxLocal->pDevice->name,
|
|
|
|
dmxLocal->isCore
|
|
|
|
? " [core]"
|
2012-06-10 07:21:05 -06:00
|
|
|
: (dmxLocal->sendsCore ? " [sends core events]" : ""));
|
2010-07-27 13:02:24 -06:00
|
|
|
EnableDevice(dmxLocal->pDevice, TRUE);
|
2006-11-26 11:13:41 -07:00
|
|
|
}
|
|
|
|
dmxInputLogDevices();
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2012-06-10 07:21:05 -06:00
|
|
|
int
|
|
|
|
dmxInputAttachConsole(const char *name, int isCore, int *id)
|
2006-11-26 11:13:41 -07:00
|
|
|
{
|
2012-06-10 07:21:05 -06:00
|
|
|
DMXInputInfo *dmxInput;
|
|
|
|
int i;
|
2006-11-26 11:13:41 -07:00
|
|
|
|
|
|
|
for (i = 0; i < dmxNumInputs; i++) {
|
|
|
|
dmxInput = &dmxInputs[i];
|
|
|
|
if (dmxInput->scrnIdx == -1
|
2012-06-10 07:21:05 -06:00
|
|
|
&& dmxInput->detached && !strcmp(dmxInput->name, name)) {
|
|
|
|
/* Found match */
|
2006-11-26 11:13:41 -07:00
|
|
|
dmxLogInput(dmxInput, "Reattaching detached console input\n");
|
|
|
|
return dmxInputAttachOld(dmxInput, id);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-06-10 07:21:05 -06:00
|
|
|
/* No match found */
|
2006-11-26 11:13:41 -07:00
|
|
|
dmxInput = dmxConfigAddInput(xstrdup(name), isCore);
|
|
|
|
dmxInput->freename = TRUE;
|
|
|
|
dmxLogInput(dmxInput, "Attaching new console input\n");
|
|
|
|
return dmxInputAttachNew(dmxInput, id);
|
|
|
|
}
|
|
|
|
|
2012-06-10 07:21:05 -06:00
|
|
|
int
|
|
|
|
dmxInputAttachBackend(int physicalScreen, int isCore, int *id)
|
2006-11-26 11:13:41 -07:00
|
|
|
{
|
2012-06-10 07:21:05 -06:00
|
|
|
DMXInputInfo *dmxInput;
|
2006-11-26 11:13:41 -07:00
|
|
|
DMXScreenInfo *dmxScreen;
|
2012-06-10 07:21:05 -06:00
|
|
|
int i;
|
|
|
|
|
|
|
|
if (physicalScreen < 0 || physicalScreen >= dmxNumScreens)
|
|
|
|
return BadValue;
|
2006-11-26 11:13:41 -07:00
|
|
|
for (i = 0; i < dmxNumInputs; i++) {
|
|
|
|
dmxInput = &dmxInputs[i];
|
|
|
|
if (dmxInput->scrnIdx != -1 && dmxInput->scrnIdx == physicalScreen) {
|
2012-06-10 07:21:05 -06:00
|
|
|
/* Found match */
|
|
|
|
if (!dmxInput->detached)
|
|
|
|
return BadAccess; /* Already attached */
|
2006-11-26 11:13:41 -07:00
|
|
|
dmxScreen = &dmxScreens[physicalScreen];
|
2012-06-10 07:21:05 -06:00
|
|
|
if (!dmxScreen->beDisplay)
|
|
|
|
return BadAccess; /* Screen detached */
|
2006-11-26 11:13:41 -07:00
|
|
|
dmxLogInput(dmxInput, "Reattaching detached backend input\n");
|
|
|
|
return dmxInputAttachOld(dmxInput, id);
|
|
|
|
}
|
|
|
|
}
|
2012-06-10 07:21:05 -06:00
|
|
|
/* No match found */
|
2006-11-26 11:13:41 -07:00
|
|
|
dmxScreen = &dmxScreens[physicalScreen];
|
2012-06-10 07:21:05 -06:00
|
|
|
if (!dmxScreen->beDisplay)
|
|
|
|
return BadAccess; /* Screen detached */
|
2006-11-26 11:13:41 -07:00
|
|
|
dmxInput = dmxConfigAddInput(dmxScreen->name, isCore);
|
|
|
|
dmxLogInput(dmxInput, "Attaching new backend input\n");
|
|
|
|
return dmxInputAttachNew(dmxInput, id);
|
|
|
|
}
|