summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorDaniel Stone <daniel@fooishbar.org>2006-03-01 22:03:04 +0000
committerDaniel Stone <daniel@fooishbar.org>2006-03-01 22:03:04 +0000
commit6b4742d17bcda83c7e23c828e49c04df42e411e2 (patch)
tree3ce0ef817a3e91ef3b1ed2118158464f1b935787 /src
parent8d5332b1d382c450112b4cf1b6813529b429d203 (diff)
Changes from Peter Kunzmann at Citron:
Change most -'s to \-. Update list of supported devices. Call the PostButton event when breaking beams. Added channels for ambient overload, keys and pwmex channels. Beep on keyclicks. Bug #6065: Add NULL to default_options[] to prevent crash. Bump to version 2.15.
Diffstat (limited to 'src')
-rw-r--r--src/citron.c1113
-rw-r--r--src/citron.h146
2 files changed, 859 insertions, 400 deletions
diff --git a/src/citron.c b/src/citron.c
index d604673..ca36dcd 100644
--- a/src/citron.c
+++ b/src/citron.c
@@ -25,13 +25,13 @@
*
*/
-/* $XFree86: xc/programs/Xserver/hw/xfree86/input/citron/citron.c,v 1.11tsi Exp $ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/input/citron/citron.c,v 1.4 2000/11/03 13:13:31 tsi Exp $ */
/*
* Based, in part, on code with the following copyright notice:
*
* Copyright 1999-2001 by Thomas Thanner, Citron GmbH, Germany. <support@citron.de>
- * Copyright 1999-2003 by Peter Kunzmann, Citron GmbH, Germany. <kunzmann@citron.de>
+ * Copyright 1999-2006 by Peter Kunzmann, Citron GmbH, Germany. <kunzmann@citron.de>
*
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that
@@ -114,6 +114,15 @@
command (SendLockZ) for 3-D support added
userstring commands added pk
2.11 07.02.03 Blockduration time raised to 1sec pk
+ 2.12 19.11.03 PostButton Event command when breaking beams pk
+
+ 2.13 23.02.05 xf86ScaleAxis width and height bot (-1) pk
+
+ 2.14 22.03.05 keys, ambient overload and pwmex channels added
+ beep for keyclick added pk
+ 2.15 23.02.06 minor changes, adapted for shared objects
+ if (( res == SUCCESS) ... semicolon deleted
+ default_options[] NULL added
============================================================================
*/
@@ -127,8 +136,8 @@
#define INITT 0 /* Initialisation of touch in first loop */
-#define CITOUCH_VERSION 0x211
-char version[]="Touch Driver V2.1.1 (c) 1999-2003 Citron GmbH";
+#define CITOUCH_VERSION 0x215
+char version[]="Touch Driver V2.1.5 (c) 1999-2006 Citron GmbH";
#define CITOUCH_VERSION_MAJOR ((CITOUCH_VERSION >> 8) & 0xf)
#define CITOUCH_VERSION_MINOR ((CITOUCH_VERSION >> 4) & 0xf)
@@ -144,11 +153,15 @@ char version[]="Touch Driver V2.1.1 (c) 1999-2003 Citron GmbH";
#define NEED_XF86_TYPES
#include "xf86_ansic.h"
#include "xf86_OSproc.h"
+/*#include "xf86Optrec.h" */
#include "xf86Xinput.h"
#include "xisb.h"
#include "exevents.h" /* Needed for InitValuator/Proximity stuff*/
+#include <keysym.h>
+
+
/* I have to explicit declare this function, because I get an error if I compile */
/* with "#define XF86_OS_PRIVS". I also have to put a "SYMVAR(xf86SoundKbdBell)" */
/* statement into the "/loader/xf86sym.c file" to be able to access this function (PK) */
@@ -250,20 +263,29 @@ _X_EXPORT InputDriverRec CITRON = {
0
};
-static char *UserStrNames[] =
+static KeySym cikeymap[] =
{
- "NAME",
- "REV",
- "RECEIVERBOARD",
- "TOUCH",
- "DISPLAY",
- "INVERTER",
- "MECHANICS",
- "PAR1",
- "PAR2",
- NULL
+ /* 0x00 .. 0x07 */
+ NoSymbol,NoSymbol,NoSymbol,NoSymbol,NoSymbol,NoSymbol,NoSymbol,NoSymbol,
+ /* 0x08 .. 0x0f */
+ XK_F1, XK_F2, XK_F3, XK_F4, XK_F5, XK_F6, XK_F7, XK_F8,
+ /* 0x10 .. 0x17 */
+ XK_F9, XK_F10, XK_F11, XK_F12, XK_F13, XK_F14, XK_F15, XK_F16,
+ /* 0x18 .. 0x1f */
+ XK_F17, XK_F18, XK_F19, XK_F20, XK_F21, XK_F22, XK_F23, XK_F24,
+ /* 0x20 .. 0x27 */
+ XK_F25, XK_F26, XK_F27, XK_F28, XK_F29, XK_F30, XK_F31, XK_F32
+};
+
+/* minKeyCode = 8 because this is the min legal key code */
+static KeySymsRec keys =
+{
+ /* map minKeyCode maxKC width */
+ cikeymap, 8, 0x27, 1
};
+
+
#ifdef XFree86LOADER
@@ -282,7 +304,7 @@ static XF86ModuleVersionInfo VersionRec =
MODULEVENDORSTRING, /* vendor specific string */
MODINFOSTRING1,
MODINFOSTRING2,
- XORG_VERSION_CURRENT, /* Current XFree version */
+ XF86_VERSION_CURRENT, /* Current XFree version */
CITOUCH_VERSION_MAJOR, /* Module-specific major version */
CITOUCH_VERSION_MINOR, /* Module-specific minor version */
CITOUCH_VERSION_PATCH, /* Module-specific patch level */
@@ -292,6 +314,21 @@ static XF86ModuleVersionInfo VersionRec =
{0, 0, 0, 0} /* signature of the version info structure */
};
+
+static char *UserStrNames[] =
+{
+ "NAME",
+ "REV",
+ "RECEIVERBOARD",
+ "TOUCH",
+ "DISPLAY",
+ "INVERTER",
+ "MECHANICS",
+ "PAR1",
+ "PAR2",
+ NULL
+};
+
/* ************************************************************************
* [SetupProc] --
*
@@ -386,7 +423,8 @@ static const char *default_options[] =
"Vmin", "1", /* blocking read until 1 chars received */
"Vtime", "1",
"FlowControl", "None",
- "ClearDTR", ""
+ "ClearDTR", "",
+ NULL
};
@@ -462,6 +500,7 @@ cit_ParseCommand(DeviceIntPtr dev)
LocalDevicePtr local = (LocalDevicePtr) dev->public.devicePrivate;
cit_PrivatePtr priv = (cit_PrivatePtr)(local->private);
int i;
+ unsigned short tmp;
DBG(DDS, ErrorF("%scit_ParseCommand: numbytes=0x%02X, data= ", CI_INFO, priv->dds.numbytes));
@@ -470,6 +509,7 @@ cit_ParseCommand(DeviceIntPtr dev)
DBG(DDS,ErrorF("\n"));
+ i=1;
switch(priv->dds.data[0]&0xff)
{
case C_SETPWM:
@@ -515,6 +555,16 @@ cit_ParseCommand(DeviceIntPtr dev)
priv->lockz_enter_time, priv->lockz_exit_time, priv->lockz_lock_time));
break;
+ case C_SETPWMEX:
+ priv->pwmex_channel = priv->dds.data[i++];
+ priv->pwmex_duty = priv->dds.data[i++];
+ tmp = priv->dds.data[i++];
+ tmp += priv->dds.data[i++] << 8;
+ priv->pwmex_freq = tmp;
+ DBG(DDS, ErrorF("%scit_ParseCommand: channel=%02x, duty cycle=%02x, freqency=%04x\n",
+ CI_INFO, priv->pwmex_channel, priv->pwmex_duty, priv->pwmex_freq));
+ break;
+
default:
DBG(DDS, ErrorF("%scit_ParseCommand: Command %d [0x%02x] not found\n", CI_INFO, priv->dds.data[0], priv->dds.data[0]));
break;
@@ -591,6 +641,17 @@ cit_DriverComm(DeviceIntPtr dev)
ErrorF("%spwm_src=%d, pwm_dst=%d \n", CI_INFO, priv->pwm_src, priv->pwm_dst);
break;
+ case D_PWMEX:
+ priv->pwmex_channel = priv->dds.data[i++];
+ priv->pwmex_duty = priv->dds.data[i++];
+ tmp = priv->dds.data[i++];
+ tmp += priv->dds.data[i++] << 8;
+ priv->pwmex_freq = tmp;
+ cit_SendPWMEx(priv); /* Set PWMex values */
+ ErrorF("%sExtended PWM: channel=%02x, duty cycle=%02x, freqency=%04x\n",
+ CI_INFO, priv->pwmex_channel, priv->pwmex_duty, priv->pwmex_freq);
+ break;
+
default:
ErrorF("%sNot known command: %d [0x%02x] - Get a recent driver\n", CI_WARNING, priv->dds.data[1], priv->dds.data[1]);
break;
@@ -603,10 +664,8 @@ xf86CitronPrint (int nr, LedCtrl *ctrl)
{
DBG(8, ErrorF("%s------------------------------------------\n", CI_INFO));
DBG(8, ErrorF("%sxf86CitronFeedback%d(dev, ctrl)\n", CI_INFO, nr));
- DBG(8, ErrorF("%s ctrl->led_values.......:%ld [0x%08lX]\n", CI_INFO,
- ctrl->led_values, ctrl->led_values));
- DBG(8, ErrorF("%s ctrl->led_mask.........:%ld [0x%08lX]\n", CI_INFO,
- (unsigned long)ctrl->led_mask, (unsigned long)ctrl->led_mask));
+ DBG(8, ErrorF("%s ctrl->led_values.......:%d [0x%08lX]\n", CI_INFO, (int)ctrl->led_values, ctrl->led_values));
+ DBG(8, ErrorF("%s ctrl->led_mask.........:%d [0x%08lX]\n", CI_INFO, (int)ctrl->led_mask, ctrl->led_mask));
DBG(8, ErrorF("%s ctrl->id...............:%d\n", CI_INFO, ctrl->id));
}
@@ -628,7 +687,10 @@ xf86CitronFeedback0 (DeviceIntPtr dev, LedCtrl *ctrl)
if(cmd->packet == 0) /* test if first packet has come (with number of bytes in first byte) */
{
if(cmd->par[0] == 0) /* test if something is to do at all */
+ {
+ DBG(DDS, ErrorF("%sxf86CitronFeedback0(): Nothing to do\n", CI_WARNING));
return;
+ }
priv->dds.curbyte = 2;
priv->dds.numbytes = cmd->par[0];
priv->dds.data[0] = cmd->par[1];
@@ -661,10 +723,11 @@ xf86CitronFeedback0 (DeviceIntPtr dev, LedCtrl *ctrl)
}
}
- DBG(DDS, ErrorF("%s 1 led_values = %08lx\n", CI_INFO, ctrl->led_values));
+ DBG(DDS, ErrorF("%s 1 led_values = %08x\n", CI_INFO, (int)ctrl->led_values));
ctrl->led_values = (unsigned long)GetTimeInMillis();
- DBG(DDS, ErrorF("%s 2 led_values = %08lx\n", CI_INFO, ctrl->led_values));
+ DBG(DDS, ErrorF("%s 2 led_values = %08x\n", CI_INFO, (int)ctrl->led_values));
+ DBG(DDS, ErrorF("%sExiting xf86CitronFeedback0()\n",CI_INFO));
}
@@ -722,7 +785,7 @@ cit_StartTimer(cit_PrivatePtr priv, int nr)
{
priv->timer_ptr[nr] = TimerSet(priv->timer_ptr[nr], 0, priv->timer_val1[nr],
priv->timer_callback[nr], (pointer)priv);
- DBG(5, ErrorF ("%scit_StartTimer[%d] called PTR=%p\n", CI_INFO, nr, (void *)priv->timer_ptr));
+ DBG(5, ErrorF ("%scit_StartTimer[%d] called PTR=%08x\n", CI_INFO, nr, (unsigned int)priv->timer_ptr));
}
@@ -733,7 +796,7 @@ static void
cit_CloseTimer(cit_PrivatePtr priv, int nr)
{
- DBG(5, ErrorF ("%scit_CloseTimer[%d] called PTR=%p\n", CI_INFO, nr, (void *)priv->timer_ptr));
+ DBG(5, ErrorF ("%scit_CloseTimer[%d] called PTR=%08x\n", CI_INFO, nr, (unsigned int)priv->timer_ptr));
if(priv->timer_ptr[nr])
{
TimerFree(priv->timer_ptr[nr]);
@@ -754,8 +817,7 @@ cit_SuperVisionTimer(OsTimerPtr timer, CARD32 now, pointer arg)
cit_PrivatePtr priv = (cit_PrivatePtr) arg;
int sigstate;
- DBG(5, ErrorF ("%scit_SuperVisionTimer called %ld\n", CI_INFO,
- (unsigned long)GetTimeInMillis()));
+ DBG(5, ErrorF ("%scit_SuperVisionTimer called %ld\n", CI_INFO, GetTimeInMillis()));
sigstate = xf86BlockSIGIO ();
@@ -813,8 +875,7 @@ CitronPreInit (InputDriverPtr drv, IDevPtr dev, int flags)
int errmaj, errmin;
#endif
- ErrorF ("%sCitronPreInit called - xcalloc=%d\n", CI_INFO,
- (int)sizeof(cit_PrivateRec));
+ ErrorF ("%sCitronPreInit called - xcalloc=%d\n", CI_INFO, sizeof(cit_PrivateRec));
/* DBG(2, ErrorF("\txf86Verbose=%d\n", xf86Verbose));*/
if ((!local) || (!priv))
{
@@ -894,6 +955,10 @@ CitronPreInit (InputDriverPtr drv, IDevPtr dev, int flags)
ErrorF("%sMaximum y position: %d\n", CI_CONFIG, priv->max_y);
priv->button_number = xf86SetIntOption(local->options, "ButtonNumber", 1);
ErrorF("%sButton Number: %d\n", CI_CONFIG, priv->button_number);
+ priv->proximity_number = xf86SetIntOption(local->options, "ProximityNumber", 2);
+ ErrorF("%sProximity Number: %d\n", CI_CONFIG, priv->proximity_number);
+ priv->genproxbutev = xf86SetIntOption(local->options, "GenProximityButtonEvents", 0);
+ ErrorF("%sGenerate Proximity Button Events: %d\n", CI_CONFIG, priv->genproxbutev);
priv->button_threshold = xf86SetIntOption(local->options, "ButtonThreshold", 10);
ErrorF("%sButton Threshold: %d\n", CI_CONFIG, priv->button_threshold);
priv->sleep_mode = xf86SetIntOption(local->options, "SleepMode", 0);
@@ -938,6 +1003,22 @@ CitronPreInit (InputDriverPtr drv, IDevPtr dev, int flags)
ErrorF("%sBeep Release Pitch: %d\n", CI_CONFIG, priv->rel_pitch);
priv->rel_dur = xf86SetIntOption(local->options, "ReleaseDur", 10) & 0xff;
ErrorF("%sBeep Release Duration: %d\n", CI_CONFIG, priv->rel_dur);
+
+ priv->beepkey = xf86SetIntOption(local->options, "BeepKey", 0);
+ ErrorF("%sBeepKey: %s\n", CI_CONFIG, (priv->beep > 0) ? "activated":"not activated");
+ priv->presskey_vol = xf86SetIntOption(local->options, "PressVolKey", 50);
+ ErrorF("%sBeep Pressure Volume Keyboard: %d\n", CI_CONFIG, priv->press_vol);
+ priv->presskey_pitch = xf86SetIntOption(local->options, "PressPitchKey", 1500);
+ ErrorF("%sBeep Pressure Pitch Keyboard: %d\n", CI_CONFIG, priv->press_pitch);
+ priv->presskey_dur = xf86SetIntOption(local->options, "PressDurKey", 120);
+ ErrorF("%sBeep Pressure Duration Keyboard: %d\n", CI_CONFIG, priv->press_dur);
+ priv->relkey_vol = xf86SetIntOption(local->options, "ReleaseVolKey", 50);
+ ErrorF("%sBeep Release Volume Keyboard: %d\n", CI_CONFIG, priv->rel_vol);
+ priv->relkey_pitch = xf86SetIntOption(local->options, "ReleasePitchKey", 1500*2);
+ ErrorF("%sBeep Release Pitch Keyboard: %d\n", CI_CONFIG, priv->rel_pitch);
+ priv->relkey_dur = xf86SetIntOption(local->options, "ReleaseDurKey", 120/2);
+ ErrorF("%sBeep Release Duration Keyboard: %d\n", CI_CONFIG, priv->rel_dur);
+
priv->beam_timeout = xf86SetIntOption(local->options, "BeamTimeout", 30) & 0xffff;
ErrorF("%sBeam Timeout: %d\n", CI_CONFIG, priv->beam_timeout);
priv->touch_time = xf86SetIntOption(local->options, "TouchTime", 0) & 0xff;
@@ -956,6 +1037,10 @@ CitronPreInit (InputDriverPtr drv, IDevPtr dev, int flags)
ErrorF("%sLockZExitTime: %d\n", CI_CONFIG, priv->lockz_exit_time);
priv->lockz_lock_time = xf86SetIntOption(priv->local->options, "LockZLockTime", 10);
ErrorF("%sLockLockTime: %d\n", CI_CONFIG, priv->lockz_lock_time);
+ priv->key_matrix = xf86SetIntOption(priv->local->options, "KeyMatrix", 0);
+ ErrorF("%sKeyMatrix: %s\n", CI_CONFIG, priv->key_matrix > 0 ? "enabled":"disabled");
+ priv->ambient_overload = xf86SetIntOption(priv->local->options, "AmbientOverload", 0);
+ ErrorF("%sAmbientOverload: %s\n", CI_CONFIG, priv->ambient_overload > 0 ? "enabled":"disabled");
cit_SetEnterCount(priv); /* set enter_count according click_mode */
@@ -1003,7 +1088,6 @@ CitronPreInit (InputDriverPtr drv, IDevPtr dev, int flags)
priv->last_y = 0;
priv->query_state = 0; /* first query */
-
#if(INITT)
DBG (8, XisbTrace (priv->buffer, 1));
@@ -1253,8 +1337,7 @@ DeviceInit (DeviceIntPtr dev)
LocalDevicePtr local = (LocalDevicePtr) dev->public.devicePrivate;
cit_PrivatePtr priv = (cit_PrivatePtr) (local->private);
- unsigned char map[] =
- {0, 1};
+ unsigned char map[] = {0, 1, 2, 3, 4, 5};
DBG (5, ErrorF("%sDeviceInit called\n", CI_INFO));
/*
@@ -1268,9 +1351,9 @@ DeviceInit (DeviceIntPtr dev)
priv->screen_num, priv->screen_width, priv->screen_height));
/*
- * Device reports button press for up to 1 button.
+ * Device reports button press for up to 5 buttons.
*/
- if (InitButtonClassDeviceStruct (dev, 1, map) == FALSE)
+ if (InitButtonClassDeviceStruct (dev, 5, map) == FALSE)
{
ErrorF ("%sUnable to allocate Citron touchscreen ButtonClassDeviceStruct\n", CI_ERROR);
return !Success;
@@ -1292,14 +1375,18 @@ DeviceInit (DeviceIntPtr dev)
}
else
{
- InitValuatorAxisStruct (dev, 0, priv->min_x, priv->max_x,
- CIT_DEF_MAX_X,
- CIT_DEF_MIN_X /* min_res */ ,
- CIT_DEF_MAX_X /* max_res */ );
- InitValuatorAxisStruct (dev, 1, priv->min_y, priv->max_y,
- CIT_DEF_MAX_Y,
- CIT_DEF_MIN_Y /* min_res */ ,
- CIT_DEF_MAX_Y /* max_res */ );
+ InitValuatorAxisStruct (dev, 0,
+ priv->min_x, /* min val */
+ priv->max_x, /* max val */
+ CIT_DEF_MAX_X, /* resolution */
+ CIT_DEF_MIN_X, /* min_res */
+ CIT_DEF_MAX_X); /* max_res */
+ InitValuatorAxisStruct (dev, 1,
+ priv->min_y, /* min val */
+ priv->max_y, /* max val */
+ CIT_DEF_MAX_Y, /* resolution */
+ CIT_DEF_MIN_Y, /* min_res */
+ CIT_DEF_MAX_Y); /* max_res */
}
if (InitProximityClassDeviceStruct (dev) == FALSE)
@@ -1308,6 +1395,12 @@ DeviceInit (DeviceIntPtr dev)
return !Success;
}
+ if (InitKeyClassDeviceStruct(dev, &keys, NULL) == FALSE)
+ {
+ ErrorF("%sUnable to init Key Class Device\n", CI_ERROR);
+ return !Success;
+ }
+
/*
* Use the LedFeedbackClass to set some driver parameters
@@ -1349,6 +1442,7 @@ static void
ReadInput (LocalDevicePtr local)
{
int x, y;
+ int motionevent = 0;
cit_PrivatePtr priv = (cit_PrivatePtr) (local->private);
DBG(RI, ErrorF("%sReadInput called\n", CI_INFO));
@@ -1375,9 +1469,9 @@ ReadInput (LocalDevicePtr local)
if (priv->reporting_mode == TS_Scaled)
{
- x = xf86ScaleAxis (priv->raw_x, 0, priv->screen_width, priv->min_x,
+ x = xf86ScaleAxis (priv->raw_x, 0, priv->screen_width-1, priv->min_x,
priv->max_x);
- y = xf86ScaleAxis (priv->raw_y, 0, priv->screen_height, priv->min_y,
+ y = xf86ScaleAxis (priv->raw_y, 0, priv->screen_height-1, priv->min_y,
priv->max_y);
DBG(RI, ErrorF("%s\tscaled coordinates: (%d, %d)\n", CI_INFO, x, y));
}
@@ -1389,12 +1483,6 @@ ReadInput (LocalDevicePtr local)
xf86XInputSetScreen (local, priv->screen_num, x, y);
- if ((priv->proximity == FALSE) && (priv->state & CIT_TOUCHED))
- {
- priv->proximity = TRUE;
- xf86PostProximityEvent (local->dev, 1, 0, 2, x, y);
- DBG(RI, ErrorF("%s\tproximity(TRUE, x=%d, y=%d)\n", CI_INFO, x, y));
- }
/*
* Send events.
@@ -1405,16 +1493,33 @@ ReadInput (LocalDevicePtr local)
* First test if coordinates have changed a predefined amount of pixels
*/
- if ( ((x >= (priv->last_x + priv->delta_x)) ||
+
+ /* If the ccordinates are inside the hysteresis, or the coordinates are outside of a
+ * rectangle with delta_x and delta_y clearence and coordinates have not changed,
+ * no motion event is sent.
+ * Only one motion event per touch event
+ */
+
+
+ if (((x >= (priv->last_x + priv->delta_x)) || /* coordinate inside of hyteresis rectangle */
(x <= (priv->last_x - priv->delta_x)) ||
(y >= (priv->last_y + priv->delta_y)) ||
- (y <= (priv->last_y - priv->delta_y))) ||
- ( ((x < priv->delta_x) ||
+ (y <= (priv->last_y - priv->delta_y)))
+
+ ||
+
+ ( (((x < priv->delta_x) || /* outside of a clearance of delta_x and delta_y */
(x > (priv->screen_width - priv->delta_x))) ||
- ((y < priv->delta_x) ||
- (y > (priv->screen_height - priv->delta_y)))) )
+ ((y < priv->delta_y) ||
+ (y > (priv->screen_height - priv->delta_y))))
+
+ &&
+
+ ( (x != priv->last_x) || (y != priv->last_y) ))) /* but only if the coordinates have changed */
+
{
xf86PostMotionEvent (local->dev, TRUE, 0, 2, x, y);
+ motionevent++; /* motionevent has happened */
DBG(RI, ErrorF("%s\tPostMotionEvent(x=%d, y=%d, last_x=%d, last_y=%d)\n", CI_INFO,
x, y, priv->last_x, priv->last_y));
@@ -1422,6 +1527,23 @@ ReadInput (LocalDevicePtr local)
priv->last_y = y;
}
+
+ if ((priv->proximity == FALSE) && (priv->state & CIT_TOUCHED))
+ {
+ priv->proximity = TRUE;
+ /* We *must* generate a motion before a button change */
+ if(motionevent <= 0) /* send a motion event if not already done */
+ {
+ xf86PostMotionEvent (local->dev, TRUE, 0, 2, x, y);
+ motionevent++; /* motionevent occurered */
+ }
+ xf86PostProximityEvent (local->dev, 1, 0, 2, x, y);
+ if(priv->genproxbutev)
+ xf86PostButtonEvent (local->dev, TRUE, priv->proximity_number, 1, 0, 2, x, y);
+ DBG(RI, ErrorF("%s\tproximity(TRUE, x=%d, y=%d, genproxbutev=%d, prox_num=%d)\n",
+ CI_INFO, x, y, priv->genproxbutev, priv->proximity_number));
+ }
+
/*
* Emit a button press or release.
*/
@@ -1434,6 +1556,13 @@ ReadInput (LocalDevicePtr local)
if(priv->enter_touched == priv->enter_count)
{
priv->enter_touched++; /* increment count one more time to prevent further enter events */
+
+ if(motionevent <= 0) /* send a motion event if not already done */
+ {
+ xf86PostMotionEvent (local->dev, TRUE, 0, 2, x, y);
+ motionevent++;
+ }
+
xf86PostButtonEvent (local->dev, TRUE,
priv->button_number, 1, 0, 2, x, y);
cit_Beep(priv, 1);
@@ -1446,28 +1575,84 @@ ReadInput (LocalDevicePtr local)
if ((priv->button_down == TRUE) && !(priv->state & CIT_BUTTON))
{
+
+ if(motionevent <= 0) /* send a motion event if not already done */
+ {
+ xf86PostMotionEvent (local->dev, TRUE, 0, 2, x, y);
+ motionevent++; /* motionevent occurered */
+ }
xf86PostButtonEvent (local->dev, TRUE,
priv->button_number, 0, 0, 2, x, y);
cit_Beep(priv, 0);
DBG(RI, ErrorF("%s\tPostButtonEvent(UP, x=%d, y=%d)\n", CI_INFO, x, y));
priv->button_down = FALSE;
}
+
+
/*
* the untouch should always come after the button release
*/
if ((priv->proximity == TRUE) && !(priv->state & CIT_TOUCHED))
{
priv->proximity = FALSE;
+
+ if(motionevent <= 0) /* send a motion event if not already done */
+ {
+ xf86PostMotionEvent (local->dev, TRUE, 0, 2, x, y);
+ motionevent++; /* motionevent occurered */
+ }
+
xf86PostProximityEvent (local->dev, 0, 0, 2, x, y);
- DBG(RI, ErrorF("%s\tproximity(FALSE, x=%d, y=%d)\n", CI_INFO, x, y));
+ if(priv->genproxbutev)
+ xf86PostButtonEvent (local->dev, TRUE, priv->proximity_number, 0, 0, 2, x, y);
+ DBG(RI, ErrorF("%s\tproximity(FALSE, x=%d, y=%d, genproxbutev=%d, prox_num=%d)\n",
+ CI_INFO, x, y, priv->genproxbutev, priv->proximity_number));
+ }
+
+
+
+ /*
+ * Any key changed ?
+ */
+
+ if (priv->key_changed == TRUE)
+ {
+ xf86PostKeyEvent(local->dev, priv->key_number, (priv->state & CIT_KEYPRESSED) ? TRUE : FALSE, TRUE, 0, 2, x, y);
+/* xf86PostKeyEvent(local->dev, 0x10, FALSE, TRUE, 0, 2, y, x); */
+
+ DBG (RI, ErrorF ("%s\tPostKeyEvent: key %d %s\n",
+ CI_INFO, priv->key_number,
+ (priv->state & CIT_KEYPRESSED) ? "Pressed" : "Released"));
+
+ cit_BeepKey(priv, (priv->state & CIT_KEYPRESSED) ? 1 : 0);
+ priv->key_changed = FALSE;
}
+
+
+ /*
+ * Ambient light overflow ?
+ */
+
+ if (priv->ambientoverflow_changed == TRUE)
+ {
+ xf86PostKeyEvent(local->dev, AMBIENTOFLOW_KEY, (priv->state & CIT_AMBIENTOVERFLOW) ? TRUE : FALSE, TRUE, 0, 2, x, y);
+/* xf86PostKeyEvent(local->dev, 0x10, FALSE, TRUE, 0, 2, y, x); */
+ DBG (RI, ErrorF ("%s\tPostKeyEvent: key %d %s\n",
+ CI_INFO, AMBIENTOFLOW_KEY,
+ (priv->state & CIT_AMBIENTOVERFLOW) ? "Overflow" : "No Overflow"));
- DBG (RI, ErrorF ("%sTouchScreen: x(%d), y(%d), %s\n",
+ priv->ambientoverflow_changed = FALSE;
+ }
+
+
+ DBG (RI, ErrorF ("%sTouchScreen: x(%d), y(%d), %s, %d motion events\n",
CI_INFO, x, y,
- (priv->state == CIT_TOUCHED) ? "Touched" : "Released"));
+ (priv->state == CIT_TOUCHED) ? "Touched" : "Released", motionevent));
+
#ifdef CIT_TIM
+ DBG (RI, ErrorF ("%s\tFAKE: YES\n", CI_INFO));
if(priv->fake_exit)
{
priv->fake_exit = FALSE; /* do not sent any further faked exit messages */
@@ -1478,6 +1663,356 @@ ReadInput (LocalDevicePtr local)
DBG(RI, ErrorF("%sExit ReadInput\n", CI_INFO));
}
+
+/*****************************************************************************
+ * [cit_GetPacket]
+ ****************************************************************************/
+static Bool
+cit_GetPacket (cit_PrivatePtr priv)
+{
+ int c;
+ int errmaj, errmin;
+ int loop = 0;
+ DBG(GP, ErrorF("%scit_GetPacket called\n", CI_INFO));
+ DBG(GP, ErrorF("%s\t* initial lex_mode =%d (%s)\n", CI_INFO, priv->lex_mode,
+ priv->lex_mode==cit_idle ?"idle":
+ priv->lex_mode==cit_getID ?"getID":
+ priv->lex_mode==cit_collect ?"collect":
+ priv->lex_mode==cit_escape ?"escape":
+ "???"));
+ while ((c = XisbRead (priv->buffer)) >= 0)
+ {
+#if(0)
+ DBG(GP, ErrorF("%s c=%d\n",CI_INFO, c));
+#endif
+ loop++;
+ if (c == CTS_STX)
+ {
+ DBG(GP, ErrorF("%s\t+ STX detected\n", CI_INFO));
+ /* start of report received */
+ if (priv->lex_mode != cit_idle)
+ DBG(7, ErrorF("%s\t- no ETX received before this STX!\n", CI_WARNING));
+ priv->lex_mode = cit_getID;
+ DBG(GP, ErrorF("%s\t+ new lex_mode == getID\n", CI_INFO));
+ /* Start supervision timer at the beginning of a command */
+ priv->timer_val1[SV_TIMER] = 2000; /* Timer delay [ms] 2s */
+ priv->timer_callback[SV_TIMER] = (OsTimerCallback)cit_SuperVisionTimer; /* timer callback routine */
+ cit_StartTimer(priv, SV_TIMER);
+
+ }
+ else if (c == CTS_ETX)
+ {
+ DBG(GP, ErrorF("%s\t+ ETX detected\n", CI_INFO));
+ /* end of command received */
+ /* always IDLE after report completion */
+ DBG(GP, ErrorF("%s\t+ new lex_mode == idle\n", CI_INFO));
+ if (priv->lex_mode == cit_collect)
+ {
+ DBG(GP, ErrorF("%s\t+ Good report received\n", CI_INFO));
+ priv->lex_mode = cit_idle;
+ cit_CloseTimer(priv, SV_TIMER); /* stop supervision */
+ return (Success);
+ }
+ DBG(GP, ErrorF("%s\t- unexpected ETX received!\n", CI_WARNING));
+ priv->lex_mode = cit_idle;
+ }
+ else if (c == CTS_ESC)
+ {
+ DBG(GP, ErrorF("%s\t+ escape detected\n", CI_INFO));
+ /* next character is encoded */
+ if (priv->lex_mode != cit_collect)
+ {
+ DBG(GP, ErrorF("%s\t- unexpected control character received\n", CI_WARNING));
+ }
+ else
+ {
+ priv->lex_mode = cit_escape;
+ DBG(GP, ErrorF("%s\t+ new lex_mode == escape\n", CI_INFO));
+ }
+ }
+ else if ((c < CTS_CTRLMIN) || (c > CTS_CTRLMAX))
+ {
+ /* regular report data received */
+ if (priv->lex_mode == cit_getID)
+ { /* receive report ID */
+ priv->packeti = 0;
+ priv->packet[priv->packeti++] = (unsigned char)c;
+ priv->lex_mode = cit_collect;
+ DBG(GP, ErrorF("%s\t+ identifier captured, new lex_mode == collect\n", CI_INFO));
+ }
+ else if ((priv->lex_mode == cit_collect) || (priv->lex_mode == cit_escape))
+ { /* receive command data */
+ if (priv->lex_mode == cit_escape)
+ { /* decode encoded data byte */
+ c &= CTS_DECODE; /* decode data */
+ priv->lex_mode = cit_collect;
+ DBG(GP, ErrorF("%s\t+ decoded character = 0x%02X\n", CI_INFO, c));
+ DBG(GP, ErrorF("%s\t+ new lex_mode = collect\n", CI_INFO));
+ }
+ if (priv->packeti < CTS_PACKET_SIZE)
+ { /* add data bytes to buffer */
+ priv->packet[priv->packeti++] = (unsigned char)c;
+ }
+ else
+ {
+ DBG(GP, ErrorF("%s\t- command buffer overrun, loop[%d]\n", CI_ERROR, loop));
+ /* let's reinitialize the touch - maybe it sends breaks */
+ /* The touch assembles breaks until the buffer has an overrun */
+ /* 100ms x 256 -> 26 seconds */
+
+ priv->lex_mode = cit_idle;
+ cit_ReinitSerial(priv);
+
+ }
+ }
+ else
+ {
+ /* this happens e.g. when the touch sends breaks, so we try to reconnect */
+ DBG(GP, ErrorF("%s\t- unexpected non control received! [%d, 0x%02x, loop[%d]]\n", CI_WARNING, c, c, loop));
+ DBG(GP, ErrorF("%s\t- Device not connected - trying to reconnect ...\n", CI_WARNING));
+ if (QueryHardware (priv->local, &errmaj, &errmin) != Success)
+ ErrorF ("%s\t- Unable to query/initialize Citron Touch hardware.\n", CI_ERROR);
+ else
+ ErrorF ("%s\t- Citron Touch reconnected\n", CI_INFO);
+
+ return(!Success);
+ }
+ }
+ else if (c != CTS_XON && c != CTS_XOFF)
+ {
+ DBG(GP, ErrorF("%s\t- unhandled control character received! loop[%d]\n", CI_WARNING, loop));
+ }
+ } /* end while */
+ DBG(GP, ErrorF("%scit_GetPacket exit !Success - loop[%d]\n", CI_INFO, loop));
+
+ return (!Success);
+}
+
+
+
+/*****************************************************************************
+ * [cit_ProcessPacket]
+ ****************************************************************************/
+static void cit_ProcessPacket(cit_PrivatePtr priv)
+{
+ int i;
+
+ DBG(PP, ErrorF("%scit_ProcessPacket called\n", CI_INFO));
+ DBG(PP, ErrorF("%s\t+ enter state = 0x%04X, dual touch count=%d\n", CI_INFO, priv->state, priv->dual_touch_count));
+ /* examine message identifier */
+
+ priv->dual_flg = TRUE; /* Dual Touch Error occurred */
+#ifdef CIT_TIM
+ priv->timer_val1[FAKE_TIMER] = 1000; /* Timer delay [ms]*/
+ priv->timer_callback[FAKE_TIMER] = (OsTimerCallback)cit_DualTouchTimer; /* timer callback routine */
+ cit_StartTimer(priv, FAKE_TIMER);
+#endif
+
+ switch (priv->packet[0])
+ {
+ case R_COORD: /* new touch coordinates received */
+ if (priv->packeti < 5)
+ {
+ DBG(PP, ErrorF("%s\t- coordinate message packet too short (%d bytes)\n", CI_ERROR, priv->packeti));
+ break;
+ }
+
+
+ if (priv->dual_touch_count > 0)
+ priv->dual_touch_count--;
+
+ priv->raw_x = 0x0001U * priv->packet[1]
+ + 0x0100U * priv->packet[2];
+ priv->raw_y = 0x0001U * priv->packet[3]
+ + 0x0100U * priv->packet[4];
+
+ priv->raw_min_x = min(priv->raw_min_x, priv->raw_x);
+ priv->raw_max_x = max(priv->raw_max_x, priv->raw_x);
+ priv->raw_min_y = min(priv->raw_min_y, priv->raw_y);
+ priv->raw_max_y = max(priv->raw_max_y, priv->raw_y);
+
+ priv->state |= CIT_TOUCHED;
+
+ DBG(PP, ErrorF("%s\t+ COORD message raw (%d,%d)\n", CI_INFO, priv->raw_x, priv->raw_y));
+ break;
+
+ case R_EXIT: /* touch area no longer interrupted */
+ if (priv->packeti < 5)
+ {
+ DBG(PP, ErrorF("%s\t- exit message packet too short (%d bytes)\n", CI_ERROR, priv->packeti));
+ break;
+ }
+
+ priv->state &= ~(CIT_TOUCHED | CIT_PRESSED);
+ priv->dual_touch_count = 0;
+ priv->enter_touched = 0; /* reset coordinate report counter */
+ priv->raw_x = 0x0001U * priv->packet[1]
+ + 0x0100U * priv->packet[2];
+ priv->raw_y = 0x0001U * priv->packet[3]
+ + 0x0100U * priv->packet[4];
+#ifdef CIT_TIM
+ cit_CloseTimer(priv, FAKE_TIMER); /* close timer if exit message was received */
+#endif
+ DBG(PP, ErrorF("%s\t+ EXIT message (%d,%d)\n", CI_INFO, priv->raw_x, priv->raw_y));
+ break;
+
+ case R_DUALTOUCHERROR:
+ if (priv->dual_touch_count < priv->max_dual_count)
+ priv->dual_touch_count++;
+ DBG(PP, ErrorF("%s\t+ DUAL TOUCH ERROR message received\n", CI_INFO));
+ break;
+
+ case R_PRESSURE: /* pressure message received */
+ if (priv->packeti < 2)
+ {
+ DBG(PP, ErrorF("%s\t- pressure message packet too short (%d bytes)\n", CI_ERROR, priv->packeti));
+ break;
+ }
+ priv->state |= CIT_TOUCHED;
+ if (priv->packet[1] == PRESS_EXCEED)
+ priv->state |= CIT_PRESSED;
+ else if(priv->packet[1] == PRESS_BELOW)
+ {
+ priv->enter_touched = 0; /* reset coordinate report counter */
+ priv->state &= ~CIT_PRESSED;
+ }
+ else
+ DBG(PP, ErrorF("%sPressure Message Error\n", CI_ERROR));
+
+ DBG(PP, ErrorF("%s\t+ pressure %s message\n", CI_INFO, priv->packet[1] ? "enter":"exit"));
+ break;
+
+ case R_KEYCHANGE: /* Key state has changed */
+ if (priv->packeti < CTS_KEYCHANGE_LEN)
+ {
+ DBG(PP, ErrorF("%s\t+ keychange message packet too short (%d bytes)\n", CI_ERROR, priv->packeti));
+ break;
+ }
+
+ priv->key_changed = TRUE;
+ priv->key_number = (int)priv->packet[1];
+
+ if(priv->packet[2])
+ priv->state |= CIT_KEYPRESSED;
+ else
+ priv->state &= ~CIT_KEYPRESSED;
+
+ DBG(PP, ErrorF("%s\t+ key=%d state=%d \n", CI_INFO, priv->packet[1], priv->packet[2]));
+
+ break;
+
+
+ case R_AMBIENTOVERLOADERROR: /* Ambient light overload error*/
+ if (priv->packeti < 2)
+ {
+ DBG(PP, ErrorF("%s\t- ambient overload error message packet too short (%d bytes)\n", CI_ERROR, priv->packeti));
+ break;
+ }
+
+ priv->ambientoverflow_changed = TRUE;
+
+ if(priv->packet[1])
+ priv->state |= CIT_AMBIENTOVERFLOW;
+ else
+ priv->state &= ~CIT_AMBIENTOVERFLOW;
+
+ DBG(PP, ErrorF("%s\t- Ambient overflow %s limit\n", CI_INFO, priv->state & CIT_AMBIENTOVERFLOW ? "exceeds" : "below"));
+ break;
+
+ default:
+ DBG(PP, ErrorF("%s\t* unhandled message:", CI_ERROR));
+ for (i=0; i<priv->packeti; i++)
+ {
+ DBG(PP, ErrorF(" 0x%02X", priv->packet[i]));
+ }
+ DBG(PP, ErrorF("\n"));
+ }
+ /* generate button state */
+ switch (priv->click_mode)
+ {
+ case CM_ZPRESS:
+ DBG(PP, ErrorF("%s\t+ ZPress, button ", CI_INFO));
+ if (priv->state & CIT_PRESSED)
+ {
+ priv->state |= CIT_BUTTON;
+ DBG(PP, ErrorF("down"));
+ }
+ else
+ {
+ priv->state &= ~CIT_BUTTON;
+ DBG(PP, ErrorF("up"));
+ }
+
+ break;
+
+ case CM_ZPRESSEXIT:
+ DBG(PP, ErrorF("%s\t+ ZPressExit, button ", CI_INFO));
+ if (priv->state & CIT_PRESSED)
+ {
+ priv->state |= CIT_BUTTON;
+ DBG(PP, ErrorF("down"));
+ }
+ else if (!(priv->state & CIT_TOUCHED))
+ {
+ priv->state &= ~CIT_BUTTON;
+ DBG(PP, ErrorF("up"));
+ }
+ break;
+
+ case CM_DUAL:
+ DBG(PP, ErrorF("%s\t+ Dual Touch, button ", CI_INFO));
+ if ((priv->dual_touch_count == priv->max_dual_count) && (priv->state & CIT_TOUCHED))
+ {
+ priv->state |= CIT_BUTTON;
+ DBG(PP, ErrorF("down"));
+ }
+ else if (priv->dual_touch_count == 0)
+ {
+ priv->state &= ~CIT_BUTTON;
+ DBG(PP, ErrorF("up"));
+ }
+ break;
+
+ case CM_DUALEXIT:
+ DBG(PP, ErrorF("%s\t+ Dual Exit, button ", CI_INFO));
+ if ((priv->dual_touch_count == priv->max_dual_count) && (priv->state & CIT_TOUCHED))
+ {
+ priv->dual_flg = TRUE;
+ priv->state |= CIT_BUTTON;
+ DBG(PP, ErrorF("down"));
+ }
+ else if (!(priv->state & CIT_TOUCHED))
+ {
+ priv->state &= ~CIT_BUTTON;
+ DBG(PP, ErrorF("up"));
+ }
+ break;
+
+ default: /* default to enter mode */
+ DBG(PP, ErrorF("%s\t+ Enter Mode, button ", CI_INFO));
+ if (priv->state & CIT_TOUCHED)
+ {
+ priv->state |= CIT_BUTTON;
+ DBG(PP, ErrorF("down"));
+ }
+ else
+ {
+ priv->state &= ~CIT_BUTTON;
+ DBG(PP, ErrorF("up"));
+ }
+ break;
+ }
+ DBG(PP, ErrorF("\n"));
+ DBG(PP, ErrorF("%s\t+ Click Mode=%d\n", CI_INFO, priv->click_mode));
+ DBG(PP+1, ErrorF("%s\t+ exit state = 0x%04X, dual touch count=%d\n", CI_INFO, priv->state, priv->dual_touch_count));
+ DBG(PP+1, ErrorF("%s\t raw_x=%d, raw_y=%d\n", CI_INFO, priv->raw_x, priv->raw_y));
+}
+
+
+
+
+
+
/*****************************************************************************
* [ControlProc]
****************************************************************************/
@@ -1577,9 +2112,9 @@ ConvertProc (LocalDevicePtr local,
CI_INFO, first, num, v0, v1, v2, v3));
if (priv->reporting_mode == TS_Raw)
{
- *x = xf86ScaleAxis (v0, 0, priv->screen_width, priv->min_x,
+ *x = xf86ScaleAxis (v0, 0, priv->screen_width-1, priv->min_x,
priv->max_x);
- *y = xf86ScaleAxis (v1, 0, priv->screen_height, priv->min_y,
+ *y = xf86ScaleAxis (v1, 0, priv->screen_height-1, priv->min_y,
priv->max_y);
}
else
@@ -1709,6 +2244,12 @@ QueryHardware (LocalDevicePtr local, int *errmaj, int *errmin)
ErrorF("%sNo pressure sensors report received from Citron Touchscreen!\n",CI_ERROR);
}
+ DBG(6, ErrorF("%s\t+ requesting peripherals report\n",CI_INFO));
+ if (cit_GetPeripherals(priv)!=Success)
+ {
+ ErrorF("%sNo peripheralss report received from Citron Touchscreen!\n",CI_ERROR);
+ }
+
DBG(5, ErrorF("%s ClickMode is %d\n",CI_INFO, priv->click_mode));
if(priv->click_mode == NO_CLICK_MODE) /* if no click mode set in XF86Config set it automatically */
{
@@ -1838,137 +2379,39 @@ QueryHardware (LocalDevicePtr local, int *errmaj, int *errmin)
/* now we can start beam scanning */
cit_SendCommand(priv->buffer, C_SETSCANNING, 1, SC_ENABLE);
- DBG(6, ErrorF("%s\t+ Touch initialized - %d\n",CI_INFO, priv->query_state));
-
- return (Success);
-}
-
-
-/*****************************************************************************
- * [cit_GetPacket]
- ****************************************************************************/
-static Bool
-cit_GetPacket (cit_PrivatePtr priv)
-{
- int c;
- int errmaj, errmin;
- int loop = 0;
- DBG(GP, ErrorF("%scit_GetPacket called\n", CI_INFO));
- DBG(GP, ErrorF("%s\t* initial lex_mode =%d (%s)\n", CI_INFO, priv->lex_mode,
- priv->lex_mode==cit_idle ?"idle":
- priv->lex_mode==cit_getID ?"getID":
- priv->lex_mode==cit_collect ?"collect":
- priv->lex_mode==cit_escape ?"escape":
- "???"));
- while ((c = XisbRead (priv->buffer)) >= 0)
+ /* Test if key matrix is available and enable reports */
+ if(priv->key_matrix)
{
-#if(0)
- DBG(GP, ErrorF("%s c=%d\n",CI_INFO, c));
-#endif
- loop++;
- if (c == CTS_STX)
+ /* at least 1 key has to be defined */
+ if(priv->peripherals & PR_KEYMATRIX)
{
- DBG(GP, ErrorF("%s\t+ STX detected\n", CI_INFO));
- /* start of report received */
- if (priv->lex_mode != cit_idle)
- DBG(7, ErrorF("%s\t- no ETX received before this STX!\n", CI_WARNING));
- priv->lex_mode = cit_getID;
- DBG(GP, ErrorF("%s\t+ new lex_mode == getID\n", CI_INFO));
- /* Start supervision timer at the beginning of a command */
- priv->timer_val1[SV_TIMER] = 2000; /* Timer delay [ms] 2s */
- priv->timer_callback[SV_TIMER] = (OsTimerCallback)cit_SuperVisionTimer; /* timer callback routine */
- cit_StartTimer(priv, SV_TIMER);
-
- }
- else if (c == CTS_ETX)
- {
- DBG(GP, ErrorF("%s\t+ ETX detected\n", CI_INFO));
- /* end of command received */
- /* always IDLE after report completion */
- DBG(GP, ErrorF("%s\t+ new lex_mode == idle\n", CI_INFO));
- if (priv->lex_mode == cit_collect)
- {
- DBG(GP, ErrorF("%s\t+ Good report received\n", CI_INFO));
- priv->lex_mode = cit_idle;
- cit_CloseTimer(priv, SV_TIMER); /* stop supervision */
- return (Success);
- }
- DBG(GP, ErrorF("%s\t- unexpected ETX received!\n", CI_WARNING));
- priv->lex_mode = cit_idle;
- }
- else if (c == CTS_ESC)
- {
- DBG(GP, ErrorF("%s\t+ escape detected\n", CI_INFO));
- /* next character is encoded */
- if (priv->lex_mode != cit_collect)
- {
- DBG(GP, ErrorF("%s\t- unexpected control character received\n", CI_WARNING));
- }
- else
- {
- priv->lex_mode = cit_escape;
- DBG(GP, ErrorF("%s\t+ new lex_mode == escape\n", CI_INFO));
- }
+ cit_SendCommand(priv->buffer, C_SETKEYMODE, 1, KM_ENABLE);
+ DBG(6, ErrorF("%s\t+ Key matrix reports enabled\n",CI_INFO));
}
- else if ((c < CTS_CTRLMIN) || (c > CTS_CTRLMAX))
- {
- /* regular report data received */
- if (priv->lex_mode == cit_getID)
- { /* receive report ID */
- priv->packeti = 0;
- priv->packet[priv->packeti++] = (unsigned char)c;
- priv->lex_mode = cit_collect;
- DBG(GP, ErrorF("%s\t+ identifier captured, new lex_mode == collect\n", CI_INFO));
- }
- else if ((priv->lex_mode == cit_collect) || (priv->lex_mode == cit_escape))
- { /* receive command data */
- if (priv->lex_mode == cit_escape)
- { /* decode encoded data byte */
- c &= CTS_DECODE; /* decode data */
- priv->lex_mode = cit_collect;
- DBG(GP, ErrorF("%s\t+ decoded character = 0x%02X\n", CI_INFO, c));
- DBG(GP, ErrorF("%s\t+ new lex_mode = collect\n", CI_INFO));
- }
- if (priv->packeti < CTS_PACKET_SIZE)
- { /* add data bytes to buffer */
- priv->packet[priv->packeti++] = (unsigned char)c;
- }
- else
- {
- DBG(GP, ErrorF("%s\t- command buffer overrun, loop[%d]\n", CI_ERROR, loop));
- /* let's reinitialize the touch - maybe it sends breaks */
- /* The touch assembles breaks until the buffer has an overrun */
- /* 100ms x 256 -> 26 seconds */
-
- priv->lex_mode = cit_idle;
- cit_ReinitSerial(priv);
-
- }
- }
- else
- {
- /* this happens e.g. when the touch sends breaks, so we try to reconnect */
- DBG(GP, ErrorF("%s\t- unexpected non control received! [%d, 0x%02x, loop[%d]]\n", CI_WARNING, c, c, loop));
- DBG(GP, ErrorF("%s\t- Device not connected - trying to reconnect ...\n", CI_WARNING));
- if (QueryHardware (priv->local, &errmaj, &errmin) != Success)
- ErrorF ("%s\t- Unable to query/initialize Citron Touch hardware.\n", CI_ERROR);
- else
- ErrorF ("%s\t- Citron Touch reconnected\n", CI_INFO);
+ else
+ ErrorF("%sKeys enabled on a touch without key matrix\n",CI_ERROR);
+
+ }
- return(!Success);
- }
- }
- else if (c != CTS_XON && c != CTS_XOFF)
+ /* Test if ambient overload detection has to be enabled */
+ if(priv->ambient_overload)
+ {
+ if(priv->ambient_overload <= 2)
{
- DBG(GP, ErrorF("%s\t- unhandled control character received! loop[%d]\n", CI_WARNING, loop));
+ cit_SendCommand(priv->buffer, C_SETAMBIENTOVERLOAD, 1, priv->ambient_overload);
+ DBG(6, ErrorF("%s\t+ Ambient overload reports enabled in mode %d\n",CI_INFO, priv->ambient_overload));
}
- } /* end while */
- DBG(GP, ErrorF("%scit_GetPacket exit !Success - loop[%d]\n", CI_INFO, loop));
+
+ }
- return (!Success);
+
+ DBG(6, ErrorF("%s\t+ Touch initialized - %d\n",CI_INFO, priv->query_state));
+
+ return (Success);
}
+
/*****************************************************************************
* [cit_ReinitSerial] Reinitialize serial port
****************************************************************************/
@@ -2030,6 +2473,19 @@ cit_Beep(cit_PrivatePtr priv, int press)
/* (((unsigned long)duration * loudness / 50) << 16)) */
/* .. whatever the inventor wants to intend by it, I don't know (PK) */
+ /* Description (PK): The argument (for ioctl) consists of the tone value in
+ the low word and the duration in the high word.
+ The tone value is not the frequency.
+ The PC mainboard timer 8254 is clocked at 1.19 MHz
+ and so it's 1,193,190/frequency. The duration is measured in timer ticks.
+ Formula: (1193190/freq & 0xffff) | (unsigned long) (dur * vol / 50) << 16
+ Example: If you set vol to 50 then dur is the duration of the tone in ms.
+ if you want 100 Hz you have to put 11,931 to freq
+ (1,193,190 / 11,931) = 100
+ */
+
+
+
xf86SoundKbdBell(priv->rel_vol, priv->rel_pitch, priv->rel_dur);
else
@@ -2042,6 +2498,46 @@ cit_Beep(cit_PrivatePtr priv, int press)
/*****************************************************************************
+ * [cit_BeepKey]
+ ****************************************************************************/
+static void
+cit_BeepKey(cit_PrivatePtr priv, int press)
+{
+#ifdef CIT_BEEP
+ if(priv->beepkey == 0)
+ return;
+
+ /* ring release bell */
+ if(press <= 0)
+
+ /* [0]: volume, [1]: pitch, [2]: duration */
+ /* formula is: ((1193190 / freq) & 0xffff) | */
+ /* (((unsigned long)duration * loudness / 50) << 16)) */
+ /* .. whatever the inventor wants to intend by it, I don't know (PK) */
+
+ /* Description (PK): The argument (for ioctl) consists of the tone value in
+ the low word and the duration in the high word.
+ The tone value is not the frequency.
+ The PC mainboard timer 8254 is clocked at 1.19 MHz
+ and so it's 1,193,190/frequency. The duration is measured in timer ticks.
+ Formula: (1193190/freq & 0xffff) | (unsigned long) (dur * vol / 50) << 16
+ Example: If you set vol to 50 then dur is the duration of the tone in ms.
+ if you want 100 Hz you have to put 11,931 to freq
+ (1,193,190 / 11,931) = 100
+ */
+
+ xf86SoundKbdBell(priv->relkey_vol, priv->relkey_pitch, priv->relkey_dur);
+
+ else
+ /* ring press bell */
+ xf86SoundKbdBell(priv->presskey_vol,priv->presskey_pitch, priv->presskey_dur);
+
+ DBG(7, ErrorF("%scit_BeepKey called - %s\n", CI_INFO, (press == 0) ? "release" : "press"));
+#endif
+}
+
+
+/*****************************************************************************
* [cit_SendCommand]
****************************************************************************/
static void
@@ -2535,7 +3031,7 @@ static Bool cit_GetUserString(cit_PrivatePtr priv, char *ustr_name, char *ustr_c
else
{
DBG(5, ErrorF("%s cit_GetUserString: %s != %s\n", CI_ERROR,
- ustr_name, &priv->packet[1]));
+ ustr_name, &priv->packet[1]));
return (!Success);
}
@@ -2543,200 +3039,69 @@ static Bool cit_GetUserString(cit_PrivatePtr priv, char *ustr_name, char *ustr_c
}
-
/*****************************************************************************
- * [cit_ProcessPacket]
+ * [cit_GetPressureSensors]
****************************************************************************/
-static void cit_ProcessPacket(cit_PrivatePtr priv)
+static Bool cit_GetPressureSensors(cit_PrivatePtr priv)
{
- int i;
-
- DBG(PP, ErrorF("%scit_ProcessPacket called\n", CI_INFO));
- DBG(PP, ErrorF("%s\t+ enter state = 0x%04X, dual touch count=%d\n", CI_INFO, priv->state, priv->dual_touch_count));
- /* examine message identifier */
-
- priv->dual_flg = TRUE; /* Dual Touch Error occurred */
-#ifdef CIT_TIM
- priv->timer_val1[FAKE_TIMER] = 1000; /* Timer delay [ms]*/
- priv->timer_callback[FAKE_TIMER] = (OsTimerCallback)cit_DualTouchTimer; /* timer callback routine */
- cit_StartTimer(priv, FAKE_TIMER);
-#endif
+ int i;
+ Bool res;
- switch (priv->packet[0])
+ cit_Flush(priv);
+ cit_SendCommand(priv->buffer, C_GETHARDWARE, 1, GH_SENSORCOUNT);
+ /*
+ touch responds within 1 millisecond,
+ but it takes some time, until the command is sent and received!
+ */
+ for (i=0; i<5; i++)
{
- case R_COORD: /* new touch coordinates received */
- if (priv->packeti < 5)
- {
- DBG(PP, ErrorF("%s\t- coordinate message packet too short (%d bytes)\n", CI_ERROR, priv->packeti));
- break;
- }
-
-
- if (priv->dual_touch_count > 0)
- priv->dual_touch_count--;
-
- priv->raw_x = 0x0001U * priv->packet[1]
- + 0x0100U * priv->packet[2];
- priv->raw_y = 0x0001U * priv->packet[3]
- + 0x0100U * priv->packet[4];
-
- priv->raw_min_x = min(priv->raw_min_x, priv->raw_x);
- priv->raw_max_x = max(priv->raw_max_x, priv->raw_x);
- priv->raw_min_y = min(priv->raw_min_y, priv->raw_y);
- priv->raw_max_y = max(priv->raw_max_y, priv->raw_y);
-
- priv->state |= CIT_TOUCHED;
-
- DBG(PP, ErrorF("%s\t+ COORD message raw (%d,%d)\n", CI_INFO, priv->raw_x, priv->raw_y));
- break;
-
- case R_EXIT: /* touch area no longer interrupted */
- if (priv->packeti < 5)
- {
- DBG(PP, ErrorF("%s\t- exit message packet too short (%d bytes)\n", CI_ERROR, priv->packeti));
- break;
- }
-
- priv->state &= ~(CIT_TOUCHED | CIT_PRESSED);
- priv->dual_touch_count = 0;
- priv->enter_touched = 0; /* reset coordinate report counter */
- priv->raw_x = 0x0001U * priv->packet[1]
- + 0x0100U * priv->packet[2];
- priv->raw_y = 0x0001U * priv->packet[3]
- + 0x0100U * priv->packet[4];
-#ifdef CIT_TIM
- cit_CloseTimer(priv, FAKE_TIMER); /* close timer if exit message was received */
-#endif
- DBG(PP, ErrorF("%s\t+ EXIT message (%d,%d)\n", CI_INFO, priv->raw_x, priv->raw_y));
- break;
-
- case R_DUALTOUCHERROR:
- if (priv->dual_touch_count < priv->max_dual_count)
- priv->dual_touch_count++;
- DBG(PP, ErrorF("%s\t+ DUAL TOUCH ERROR message received\n", CI_INFO));
- break;
-
- case R_PRESSURE: /* pressure message received */
- if (priv->packeti < 2)
- {
- DBG(PP, ErrorF("%s\t- pressure message packet too short (%d bytes)\n", CI_ERROR, priv->packeti));
- break;
- }
- priv->state |= CIT_TOUCHED;
- if (priv->packet[1] == PRESS_EXCEED)
- priv->state |= CIT_PRESSED;
- else if(priv->packet[1] == PRESS_BELOW)
- {
- priv->enter_touched = 0; /* reset coordinate report counter */
- priv->state &= ~CIT_PRESSED;
- }
- else
- DBG(PP, ErrorF("%sPressure Message Error\n", CI_ERROR));
-
- DBG(PP, ErrorF("%s\t+ pressure %s message\n", CI_INFO, priv->packet[1] ? "enter":"exit"));
+ cit_SetBlockDuration(priv, 500000);
+ res = cit_GetPacket(priv);
+ if ((res == Success) || (priv->lex_mode == cit_idle))
break;
-
- default:
- DBG(PP, ErrorF("%s\t* unhandled message:", CI_ERROR));
- for (i=0; i<priv->packeti; i++)
- {
- DBG(PP, ErrorF(" 0x%02X", priv->packet[i]));
- }
- DBG(PP, ErrorF("\n"));
}
- /* generate button state */
- switch (priv->click_mode)
+ if (res != Success)
{
- case CM_ZPRESS:
- DBG(PP, ErrorF("%s\t+ ZPress, button ", CI_INFO));
- if (priv->state & CIT_PRESSED)
- {
- priv->state |= CIT_BUTTON;
- DBG(PP, ErrorF("down"));
- }
- else
- {
- priv->state &= ~CIT_BUTTON;
- DBG(PP, ErrorF("up"));
- }
-
- break;
-
- case CM_ZPRESSEXIT:
- DBG(PP, ErrorF("%s\t+ ZPressExit, button ", CI_INFO));
- if (priv->state & CIT_PRESSED)
- {
- priv->state |= CIT_BUTTON;
- DBG(PP, ErrorF("down"));
- }
- else if (!(priv->state & CIT_TOUCHED))
- {
- priv->state &= ~CIT_BUTTON;
- DBG(PP, ErrorF("up"));
- }
- break;
-
- case CM_DUAL:
- DBG(PP, ErrorF("%s\t+ Dual Touch, button ", CI_INFO));
- if ((priv->dual_touch_count == priv->max_dual_count) && (priv->state & CIT_TOUCHED))
- {
- priv->state |= CIT_BUTTON;
- DBG(PP, ErrorF("down"));
- }
- else if (priv->dual_touch_count == 0)
- {
- priv->state &= ~CIT_BUTTON;
- DBG(PP, ErrorF("up"));
- }
- break;
-
- case CM_DUALEXIT:
- DBG(PP, ErrorF("%s\t+ Dual Exit, button ", CI_INFO));
- if ((priv->dual_touch_count == priv->max_dual_count) && (priv->state & CIT_TOUCHED))
- {
- priv->dual_flg = TRUE;
- priv->state |= CIT_BUTTON;
- DBG(PP, ErrorF("down"));
- }
- else if (!(priv->state & CIT_TOUCHED))
- {
- priv->state &= ~CIT_BUTTON;
- DBG(PP, ErrorF("up"));
- }
- break;
-
- default: /* default to enter mode */
- DBG(PP, ErrorF("%s\t+ Enter Mode, button ", CI_INFO));
- if (priv->state & CIT_TOUCHED)
- {
- priv->state |= CIT_BUTTON;
- DBG(PP, ErrorF("down"));
- }
- else
- {
- priv->state &= ~CIT_BUTTON;
- DBG(PP, ErrorF("up"));
- }
- break;
+ DBG(5, ErrorF("%sNo packet received!\n", CI_NOTICE));
+ return (!Success);
}
- DBG(PP, ErrorF("\n"));
- DBG(PP, ErrorF("%s\t+ Click Mode=%d\n", CI_INFO, priv->click_mode));
- DBG(PP+1, ErrorF("%s\t+ exit state = 0x%04X, dual touch count=%d\n", CI_INFO, priv->state, priv->dual_touch_count));
- DBG(PP+1, ErrorF("%s\t raw_x=%d, raw_y=%d\n", CI_INFO, priv->raw_x, priv->raw_y));
+ /* examine packet */
+ if (priv->packeti < 2+CTS_SENSORCOUNT_LEN)
+ {
+ DBG(5, ErrorF("%sWrong packet length (expected >= %d, received %d bytes)\n", CI_NOTICE,
+ 2+CTS_SENSORCOUNT_LEN,
+ priv->packeti));
+ return (!Success);
+ }
+ if (priv->packet[0] != (C_GETHARDWARE & CMD_REP_CONV))
+ {
+ DBG(5, ErrorF("%sWrong packet identifier (expected 0x%02X, received 0x%02X)\n", CI_NOTICE,
+ (C_GETHARDWARE & CMD_REP_CONV), priv->packet[0]));
+ return (!Success);
+ }
+ if (priv->packet[1] != GH_SENSORCOUNT)
+ {
+ DBG(5, ErrorF("%sWrong packet selector (expected 0x%02X, received 0x%02X)\n", CI_NOTICE,
+ GH_SENSORCOUNT, priv->packet[1]));
+ return (!Success);
+ }
+ /* this is our packet! check contents */
+ ErrorF("%sPressureSensors: \"%d\"\n", CI_INFO, priv->packet[2]);
+ priv->pressure_sensors = priv->packet[2];
+ return (Success);
}
-
/*****************************************************************************
- * [cit_GetPressureSensors]
+ * [cit_GetPeripherals]
****************************************************************************/
-static Bool cit_GetPressureSensors(cit_PrivatePtr priv)
+static Bool cit_GetPeripherals(cit_PrivatePtr priv)
{
int i;
Bool res;
cit_Flush(priv);
- cit_SendCommand(priv->buffer, C_GETHARDWARE, 1, GH_SENSORCOUNT);
+ cit_SendCommand(priv->buffer, C_GETHARDWARE, 1, GH_PERIPHERALS);
/*
touch responds within 1 millisecond,
but it takes some time, until the command is sent and received!
@@ -2750,14 +3115,14 @@ static Bool cit_GetPressureSensors(cit_PrivatePtr priv)
}
if (res != Success)
{
- DBG(5, ErrorF("%sNo packet received!\n", CI_NOTICE));
+ DBG(5, ErrorF("%s cit_GetPeripherals: No packet received!\n", CI_NOTICE));
return (!Success);
}
/* examine packet */
- if (priv->packeti < 2+CTS_SENSORCOUNT_LEN)
+ if (priv->packeti < 2+CTS_PERIPHERAL_LEN)
{
DBG(5, ErrorF("%sWrong packet length (expected >= %d, received %d bytes)\n", CI_NOTICE,
- 2+CTS_SENSORCOUNT_LEN,
+ 2+CTS_PERIPHERAL_LEN,
priv->packeti));
return (!Success);
}
@@ -2767,15 +3132,16 @@ static Bool cit_GetPressureSensors(cit_PrivatePtr priv)
(C_GETHARDWARE & CMD_REP_CONV), priv->packet[0]));
return (!Success);
}
- if (priv->packet[1] != GH_SENSORCOUNT)
+ if (priv->packet[1] != GH_PERIPHERALS)
{
DBG(5, ErrorF("%sWrong packet selector (expected 0x%02X, received 0x%02X)\n", CI_NOTICE,
- GH_SENSORCOUNT, priv->packet[1]));
+ GH_PERIPHERALS, priv->packet[1]));
return (!Success);
}
/* this is our packet! check contents */
- ErrorF("%sPressureSensors: \"%d\"\n", CI_INFO, priv->packet[2]);
- priv->pressure_sensors = priv->packet[2];
+ priv->peripherals = priv->packet[2] + (priv->packet[3] * 0x100) + (priv->packet[4] * 0x10000) + (priv->packet[5] * 0x1000000);
+
+ ErrorF("%sPeripherals: \"%08lx\"\n", CI_INFO, priv->peripherals);
return (Success);
}
@@ -2805,7 +3171,7 @@ static void cit_SetEnterCount(cit_PrivatePtr priv)
/*****************************************************************************
- * [cit_SendPWM] send pwm for acive and sleep
+ * [cit_SendPWM] send pwm for active and sleep mode
****************************************************************************/
static void cit_SendPWM(cit_PrivatePtr priv)
{
@@ -2820,6 +3186,7 @@ static void cit_SendPWM(cit_PrivatePtr priv)
DBG(3,ErrorF("%scit_SendPWM: active=%d, sleep=%d\n", CI_CONFIG, pwm_active, pwm_sleep));
}
+
/*****************************************************************************
* [cit_SendPWMFreq] send pwm frequency of PWM signal to the touch
****************************************************************************/
@@ -2836,6 +3203,21 @@ static void cit_SendPWMFreq(cit_PrivatePtr priv)
DBG(3,ErrorF("%scit_SendPWMFreq: Frequency not set\n", CI_CONFIG));
}
+/*****************************************************************************
+ * [cit_SendPWMEX] send channel, duty cycle and frequency
+ ****************************************************************************/
+static void cit_SendPWMEx(cit_PrivatePtr priv)
+{
+
+ cit_SendCommand(priv->buffer, C_SETPWMEX, 4, LOBYTE(priv->pwmex_channel),
+ LOBYTE(priv->pwmex_duty),
+ LOBYTE(priv->pwmex_freq),
+ HIBYTE(priv->pwmex_freq));
+
+ DBG(3,ErrorF("%scit_SendPWMEX: channel=%02x, duty=%02x, freq=%04x\n",
+ CI_CONFIG, priv->pwmex_channel, priv->pwmex_duty, priv->pwmex_freq));
+}
+
/*****************************************************************************
* [cit_SendLockZ] send LockZ timing to the touch
@@ -2882,4 +3264,3 @@ static int cit_AdjustBright(cit_PrivatePtr priv, int val)
}
-
diff --git a/src/citron.h b/src/citron.h
index e356377..60a5c31 100644
--- a/src/citron.h
+++ b/src/citron.h
@@ -25,13 +25,14 @@
*
*/
-/* $XFree86: xc/programs/Xserver/hw/xfree86/input/citron/citron.h,v 1.4tsi Exp $ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/input/citron/citron.h,v 1.1 2000/11/02 02:51:21 dawes Exp $ */
/*
* Based, in part, on code with the following copyright notice:
*
* Copyright 1999-2001 by Thomas Thanner, Citron GmbH, Germany. <support@citron.de>
- * Copyright 1999-2003 by Peter Kunzmann, Citron GmbH, Germany. <kunzmann@citron.de> *
+ * Copyright 2002-2005 Citron GmbH, Augsburg <support@citron.de>
+ *
* 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
@@ -81,6 +82,8 @@
#define CTS_OEMSTRING_LEN 256 /* Length of the OEM string */
#define CTS_FPGA_LEN 28 /* Length of the FPGA version string */
#define CTS_SENSORCOUNT_LEN 1 /* Length of sensorcount report */
+#define CTS_PERIPHERAL_LEN 4 /* Length of hardware peripheral report */
+#define CTS_KEYCHANGE_LEN 3 /* Length of Key chnage report */
#define CTS_USERNAME_LEN 14 /* User name length without trailing zero (GetUserString) */
#define CTS_USERSTRING_LEN 127 /* Length of the Userstring without trailing zero */
@@ -115,7 +118,7 @@
/* SetTransmission command parameter values */
#define TM_TRANSMIT 0x01 /* Enable the transmission of messages (report will be transmitted always) */
-/* TM_NONE 0x00 */ /* Disable transmission of messages and disable the XON/XOFF protocol */
+#define TM_NONE 0x00 /* Disable transmission of messages and disable the XON/XOFF protocol */
#define TM_RXDFLOW 0x10 /* Enable the XON/XOFF protocol for the transmitter (IRT will send XON/XOFF to the host) */
#define TM_TXDFLOW 0x20 /* Enable the XON/XOFF protocol for the receiver (host will sned XON/XOFF to the IRT) */
@@ -182,6 +185,36 @@
#define GH_SENSORCOUNT 0x02 /* Report the number of pressure sensors */
#define GH_PERIPHERALS 0x04 /* Report a bit vector that identifies all assembled peripherals on the IRT */
+/* Defines for GH_PERIPHERALS (Peripheral identification bit)*/
+#define PR_NONE 0x00000000
+#define PR_OUT0 0x00000001 /* The /OC_OUT0 port is available */
+#define PR_BURNIN 0x00000002 /* The BurnIn jumper is available */
+#define PR_SSAVE 0x00000004 /* The /GP_OUT port is available */
+#define PR_PWM 0x00000008 /* The /OC_PWM port is available */
+#define PR_SOUND 0x00000010 /* The speaker port is available */
+#define PR_OCOUT0 0x00000020
+#define PR_RUNLED 0x00000040 /* The red blinking indication LED is available */
+#define PR_GPIN 0x00000080 /* The /GP_IN port is available */
+#define PR_KEYMATRIX 0xffff0000
+
+
+#define PR_KEYMATRIX0 0x80000000 /* Key 0 available */
+#define PR_KEYMATRIX1 0x40000000 /* Key 1 available */
+#define PR_KEYMATRIX2 0x20000000 /* Key 2 available */
+#define PR_KEYMATRIX3 0x10000000 /* Key 3 available */
+#define PR_KEYMATRIX4 0x08000000 /* Key 4 available */
+#define PR_KEYMATRIX5 0x04000000 /* Key 5 available */
+#define PR_KEYMATRIX6 0x02000000 /* Key 6 available */
+#define PR_KEYMATRIX7 0x01000000 /* Key 7 available */
+#define PR_KEYMATRIX8 0x00800000 /* Key 8 available */
+#define PR_KEYMATRIX9 0x00400000 /* Key 9 available */
+#define PR_KEYMATRIX10 0x00200000 /* Key 10 available */
+#define PR_KEYMATRIX11 0x00100000 /* Key 11 available */
+#define PR_KEYMATRIX12 0x00080000 /* Key 12 available */
+#define PR_KEYMATRIX13 0x00040000 /* Key 13 available */
+#define PR_KEYMATRIX14 0x00020000 /* Key 14 available */
+#define PR_KEYMATRIX15 0x00010000 /* Key 15 available */
+
/* GetHWVersion command parameters */
#define HV_SSNO 0x01 /* Report the silicon serial number */
#define HV_ASSY 0x02 /* Report the hard wired assembly number */
@@ -223,14 +256,6 @@
#define CE_PARAMCNT 0x00000002UL /* Too much or too less parameters received */
#define CE_RANGE 0x00000004UL /* One or more parameters were out of range */
-/* Peripheral indentification bit masks */
-#define PERI_OCOUT0 0x00000001UL /* The /OC_OUT0 port is available */
-#define PERI_BURNIN 0x00000002UL /* The BurnIn jumper is available */
-#define PERI_GP_OUT 0x00000004UL /* The /GP_OUT port is available */
-#define PERI_OCPWM 0x00000008UL /* The /OC_PWM port is available */
-#define PERI_SPEAKER 0x00000010UL /* The speaker port is available */
-#define PERI_GP_IN 0x00000020UL /* The /GP_IN port is available */
-#define PERI_RUNLED 0x00000040UL /* The red blinking indication LED is available */
/* SaveSetup/ReadSetup command parameters */
#define SUP_SERIAL 0x01 /* Save/Read the serial port setup */
@@ -257,25 +282,32 @@
#define D_ENTERCOUNT 0x04
#define D_ZENTERCOUNT 0x05
#define D_PWMADJ 0x06
-
+#define D_PWMEX 0x07
/* Message identifiers */
-#define R_DUALTOUCHERROR 0x18 /* Invalid multiple touches are detected */
-#define R_COORD 0x19 /* Regular coordinate report */
-#define R_EXIT 0x1a /* An area was leaved */
-#define R_PRESSURE 0x1b /* An area was pressed or released */
-#define PRESS_BELOW 0x00 /* Pressure below a certain threshold */
-#define PRESS_EXCEED 0x01 /* Pressure higher than a certain threshold */
+#define R_DUALTOUCHERROR 0x18 /* Invalid multiple touches are detected */
+#define R_COORD 0x19 /* Regular coordinate report */
+#define R_EXIT 0x1a /* An area was leaved */
+#define R_PRESSURE 0x1b /* An area was pressed or released */
+#define R_SLEEPMODE 0x1c /* The sleep-mode was activated or deactivated */
+#define R_DOZEMODE 0x1d /* The doze-mode was activated or deactivated */
+#define R_AMBIENTOVERLOADERROR 0x1e /* Ambient light exceeds or falls below a level proper function can be guaranteed */
+#define R_KEYCHANGE 0x1f /* Report a keychange (4x4 matrix) for special Touches */
+
+#define PRESS_BELOW 0x00 /* Pressure below a certain threshold */
+#define PRESS_EXCEED 0x01 /* Pressure higher than a certain threshold */
-#define R_SLEEPMODE 0x1c /* The sleep-mode was activated or deactivated */
-#define R_DOZEMODE 0x1d /* The doze-mode was activated or deactivated */
/* Special report identifiers */
#define R_POLYAREADEF 0x2a
#define R_IDLE 0x34
#define R_SCANTIMING 0x56
#define R_LOCKZ 0x52 /* LockZ timings report */
+#define R_AMBIENTOVERLOAD 0x58 /* Ambient overload behaviour */
+#define R_KEYSTATE 0x59 /* Report with state of all matrix keys */
#define R_USERSTRING 0x66 /* Userstring report */
+#define R_KEYMODE 0x7d /* Report with current handling of keyboard matrix actions */
+#define R_PWMEX 0x7f /* State of extended PWM Channel */
/* Command identifiers */
#define C_SOFTRESET 0x80
@@ -334,6 +366,10 @@
#define C_SETTOUCHTIME 0xd1
#define C_GETLOCKZ 0xd2
#define C_SETLOCKZ 0xd3
+#define C_SETAMBIENTOVERLOAD 0xd6
+#define C_GETAMBIENTOVERLOAD 0xd8
+#define C_GETKEYSTATE 0xd9
+
#define C_CLEARMACRO 0xe0
#define C_ENDMACRORECORD 0xe1
@@ -355,11 +391,26 @@
#define C_SETDOZEMODE 0xf9
#define C_SETPWMFREQ 0xfa
#define C_GETPWMFREQ 0xfb
+#define C_SETKEYMODE 0xfc
+#define C_GETKEYMODE 0xfd
+#define C_SETPWMEX 0xfe /* Define behaviour of the extended PWM-channels */
+#define C_GETPWMEX 0xff /* Ask for current settings of extended PWM channel */
/* touch states */
#define CIT_TOUCHED 0x01
#define CIT_PRESSED 0x02
#define CIT_BUTTON 0x04
+#define CIT_KEYPRESSED 0x08
+#define CIT_AMBIENTOVERFLOW 0x10
+
+/* Key modes */
+#define KM_ENABLE 0x01 /* Enable keyboard matrix mode */
+
+/* Ambient overload modes */
+#define AO_IGNORE 0x00 /* Ignore ambient overload and generate no error messages */
+#define AO_GENERATE 0x01 /* generate ambient overflow messages */
+#define AO_STOPSCANNING 0x02 /* scanning is stopped in case of ambient light error */
+#define AMBIENTOFLOW_KEY (-1) /* Key sent if ambient overflow error occures */
/* click modes */
#define CM_ENTER 1
@@ -372,6 +423,10 @@
#define NO_CLICK_MODE 255 /* no click mode set in xf86Config */
+
+
+
+
/* command structure for Feedback Functions */
typedef struct {
unsigned char par[3]; /* byte parameter */
@@ -431,19 +486,22 @@ cit_State; /* Citron Infrared Touch Driver State */
typedef struct _cit_privateRec
{
- int min_x; /* Minimum x reported by calibration */
- int max_x; /* Maximum x */
- int min_y; /* Minimum y reported by calibration */
- int max_y; /* Maximum y */
- int button_threshold; /* Z > button threshold = button click */
+ int min_x; /* Minimum x reported by calibration */
+ int max_x; /* Maximum x */
+ int min_y; /* Minimum y reported by calibration */
+ int max_y; /* Maximum y */
+ int button_threshold; /* Z > button threshold = button click */
int axes;
- int dual_touch_count; /* counter for dual touch error events */
- int click_mode; /* one of the CM_ constants */
- int button_number; /* which button to report */
- int reporting_mode; /* TS_Raw or TS_Scaled */
- int screen_num; /* Screen associated with the device */
- int screen_width; /* Width of the associated X screen */
- int screen_height; /* Height of the screen */
+ int dual_touch_count; /* counter for dual touch error events */
+ int click_mode; /* one of the CM_ constants */
+ int button_number; /* which button to report */
+ int proximity_number; /* which button to report if proximity is on*/
+ int key_number; /* which key is pressed or released */
+ int genproxbutev; /* Generate proximity button events if != 0 */
+ int reporting_mode; /* TS_Raw or TS_Scaled */
+ int screen_num; /* Screen associated with the device */
+ int screen_width; /* Width of the associated X screen */
+ int screen_height; /* Height of the screen */
int packeti; /* index into packet */
int raw_x; /* Raw Coordinates */
int raw_y;
@@ -456,6 +514,9 @@ typedef struct _cit_privateRec
int pwm_freq; /* PWM base frequency */
int pwm_src; /* Source for PWM adjust BL_TDK or BL_AC */
int pwm_dst; /* Destination for PWM adjust BL_TDK or BL_AC */
+ int pwmex_channel; /* Bitfield, defining which PWM channel is affected */
+ int pwmex_duty; /* Duty cycle of PWM signal (logical high in 255 steps) */
+ int pwmex_freq; /* Cycle frequency in Hz. 0x0000 means static on or off, depening on duty cycle */
int state;
/* additional parameters */
int last_x; /* last cooked data */
@@ -467,6 +528,7 @@ typedef struct _cit_privateRec
int origin; /* Coordinates origin */
int delta_x; /* Delta x - if coordinate changed less than delta x no motion event */
int delta_y;
+/* Beep in event of touch */
int beep; /* 0= no beep, 1=beep enabled */
int press_vol; /* volume of beep (press event) */
int press_pitch; /* pitch of beep (press event) */
@@ -474,6 +536,16 @@ typedef struct _cit_privateRec
int rel_vol; /* volume of beep (release event) */
int rel_pitch; /* pitch of beep (release event) */
int rel_dur; /* length of beep in 10ms (release event) */
+
+/* Beep in event of keyboard press or release */
+ int beepkey; /* 0= no beep, 1=beep enabled */
+ int presskey_vol; /* volume of beep (press event) */
+ int presskey_pitch; /* pitch of beep (press event) */
+ int presskey_dur; /* length of beep in 10ms (press event) */
+ int relkey_vol; /* volume of beep (release event) */
+ int relkey_pitch; /* pitch of beep (release event) */
+ int relkey_dur; /* length of beep in 10ms (release event) */
+
int beam_timeout; /* Beam timeout 0= no beam timeout */
int touch_time; /* minimum time span for a valid interruption */
int enter_touched; /* button is down due to an enter event */
@@ -491,6 +563,10 @@ typedef struct _cit_privateRec
int lockz_enter_time; /* Minimum duration of AreaPressEnter state before a PressEnter event is issued. Steps: 10ms */
int lockz_exit_time; /* Minimum duration of AreaPressExit state before a PressEnter event is issued. Steps: 10ms */
int lockz_lock_time; /* Minimum gap between PressExit and PressEnter event. Steps: 10ms */
+ int key_matrix; /* if > 0 Enable key matrix (4x4) - only available on special touches with key matrix */
+ int ambient_overload; /* Enable ambient overload report feature */
+ int ambientoverflow_changed;
+ unsigned long peripherals; /* Bitfield of hardware used */
#define MAX_TIMER 2 /* Max. concurrent timers */
@@ -506,6 +582,7 @@ typedef struct _cit_privateRec
LocalDevicePtr local; /* Pointer to local device */
Bool button_down; /* is the "button" currently down */
Bool proximity;
+ Bool key_changed; /* is a key pressed or released */
cit_State lex_mode;
XISBuffer *buffer;
unsigned char packet[CTS_PACKET_SIZE]; /* packet being/just read */
@@ -553,11 +630,9 @@ const unsigned short cit_bright_adjust[2] [256] =
* Declarations
*****************************************************************************/
/*extern void ModuleInit (pointer *, INT32 *);*/
-#ifdef XFree86LOADER
static MODULESETUPPROTO (SetupProc);
static void TearDownProc (pointer p);
/*static void *SetupProc (XF86OptionPtr, int *, int *);*/
-#endif
static Bool DeviceControl (DeviceIntPtr def, int mode);
static Bool DeviceOn (DeviceIntPtr);
static Bool DeviceOff (DeviceIntPtr);
@@ -576,15 +651,18 @@ static Bool cit_GetInitialErrors(cit_PrivatePtr);
static Bool cit_GetDefectiveBeams(cit_PrivatePtr);
static Bool cit_GetDesignator(cit_PrivatePtr);
static Bool cit_GetPressureSensors(cit_PrivatePtr);
+static Bool cit_GetPeripherals(cit_PrivatePtr);
static Bool cit_GetRevision(cit_PrivatePtr, int);
static void cit_ProcessPacket(cit_PrivatePtr);
static void cit_Beep(cit_PrivatePtr priv, int press);
+static void cit_BeepKey(cit_PrivatePtr priv, int press);
static void cit_SetBlockDuration (cit_PrivatePtr priv, int block_duration);
static void cit_ReinitSerial(cit_PrivatePtr priv);
static int cit_ZPress(cit_PrivatePtr priv);
static void cit_SetEnterCount(cit_PrivatePtr priv);
static void cit_SendPWM(cit_PrivatePtr priv);
static void cit_SendPWMFreq(cit_PrivatePtr priv);
+static void cit_SendPWMEx(cit_PrivatePtr priv);
static int cit_AdjustBright(cit_PrivatePtr priv, int val);
#ifdef CIT_TIM