Site hosted by Angelfire.com: Build your free website today!

Hands-on Projects for the Linux Graphics Subsystem

New book from Christos Karayiannis

Available in Amazon Kindle format at:

amazon.com   amazon.co.uk   amazon.de   amazon.es   amazon.fr   amazon.it

SetupMouse()

MouseProc() calls SetupMouse() to set up the mouse parameters.

SetupMouse() makes heavy use of pMse, which of type MouseDevPtr and is the private field of the mouse pInfo:

    pMse = pInfo->private;

autoOSProtocol

SetupMouse() calls autoOSProtocol() to return the Protocol name the mouse uses.

autoOSProtocol() is called as:


	name = autoOSProtocol(pInfo,protoPara);

autoOSProtocol() calls either SetupAuto(), which is for instance the BSD OS case or GuessProtocol(), which is for instance the Linux case. The previous functions are called as:

	name = osInfo->SetupAuto(pInfo, protoPara);

and

	name = osInfo->GuessProtocol(pInfo, 0);

For SetupAuto() we read in xf86OSmouse.h:

 * SetupAuto:	This function can be used to do OS-specific protocol
 *		auto-detection.  It returns the name of the detected protocol,
 *		or NULL when detection fails.  It may also adjust one or more
 *		of the "protoPara" values for the detected protocol by setting
 *		then to something other than -1.  SetupAuto gets called in two
 *		ways.  The first is before any devices have been opened.  This
 *		can be used when the protocol "Auto" always maps to a single
 *		protocol type.  The second is with the device open, allowing
 *		OS-specific probing to be done.

At the same file we read for GuessProtocol():

 * GuessProtocol: A last resort attempt at guessing the mouse protocol by
 *		whatever OS-specific means might be available.  OS-independent
 *		things should be in the mouse driver.  This function gets
 *		called after the mouse driver's OS-independent methods have
 *		failed.

osInfo was filled in MousePreInit(), when InitProtocols() calls xf86OSMouseInit(). Since InitProtocols() was not covered in section 3.2.3, where the MousePreInit() was discussed we comment it next:

static Bool
InitProtocols(void)
{
    int classes;
    int i;
    const char *osname = NULL;

    if (osInfo)
	return TRUE;

    osInfo = xf86OSMouseInit(0);
    if (!osInfo)
	return FALSE;
    if (!osInfo->SupportedInterfaces)
	return FALSE;

    classes = osInfo->SupportedInterfaces();
    if (!classes)
	return FALSE;
    
    /* Mark unsupported interface classes. */
    for (i = 0; mouseProtocols[i].name; i++)
	if (!(mouseProtocols[i].class & classes))
	    mouseProtocols[i].id = PROT_UNSUP;

    for (i = 0; mouseProtocols[i].name; i++)
	if (mouseProtocols[i].class & MSE_MISC)
	    if (!osInfo->CheckProtocol ||
		!osInfo->CheckProtocol(mouseProtocols[i].name))
		mouseProtocols[i].id = PROT_UNSUP;

    /* NetBSD uses PROT_BM for "PS/2". */
    xf86GetOS(&osname, NULL, NULL, NULL);
    if (osname && xf86NameCmp(osname, "netbsd") == 0)
	for (i = 0; mouseProtocols[i].name; i++)
	    if (mouseProtocols[i].id == PROT_PS2)
		mouseProtocols[i].id = PROT_BM;

    return TRUE;
}

xf86OSMouseInit() is an OS (Operating System) specific routine.

For instance for Linux it is implemented in lnx_mouse.c as:

OSMouseInfoPtr
xf86OSMouseInit(int flags)
{
    OSMouseInfoPtr p;

    p = xcalloc(sizeof(OSMouseInfoRec), 1);
    if (!p)
	return NULL;
    p->SupportedInterfaces = SupportedInterfaces;
    p->DefaultProtocol = DefaultProtocol;
    p->FindDevice = FindDevice;
    p->GuessProtocol = GuessProtocol;
    return p;
}

At the same file we find the SupportedInterfaces() Linux implementation as:

static int
SupportedInterfaces(void)
{
    return MSE_SERIAL | MSE_BUS | MSE_PS2 | MSE_XPS2 | MSE_AUTO;
}

If we examine another example, BSD, xf86OSMouseInit() is defined in bsd_mouse.c as:

OSMouseInfoPtr
xf86OSMouseInit(int flags)
{
    OSMouseInfoPtr p;

    p = xcalloc(sizeof(OSMouseInfoRec), 1);
    if (!p)
	return NULL;
    p->SupportedInterfaces = SupportedInterfaces;
    p->BuiltinNames = BuiltinNames;
    p->DefaultProtocol = DefaultProtocol;
    p->CheckProtocol = CheckProtocol;
#if (defined(__FreeBSD__) || defined(__FreeBSD_kernel__)) && defined(MOUSE_PROTO_SYSMOUSE)
    p->SetupAuto = SetupAuto;
    p->SetPS2Res = SetSysMouseRes;
    p->SetBMRes = SetSysMouseRes;
    p->SetMiscRes = SetSysMouseRes;
#endif
#if defined(__OpenBSD__) && defined(WSCONS_SUPPORT)
    p->SetupAuto = SetupAuto;
    p->SetMiscRes = SetMouseRes;
#endif
#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__OpenBSD__)
    p->FindDevice = FindDevice;
#endif
    p->PreInit = bsdMousePreInit;
    return p;
}

Notice in the Linux implementation lacks a SetupAuto and instance it uses a GuessProtocol routine.

mouseProtocols[] is defined in mouse.c as:

static MouseProtocolRec mouseProtocols[] = {

    /* Serial protocols */
    { "Microsoft",		MSE_SERIAL,	msDefaults,	PROT_MS },
    { "MouseSystems",		MSE_SERIAL,	mlDefaults,	PROT_MSC },
    { "MMSeries",		MSE_SERIAL,	mmDefaults,	PROT_MM },
    { "Logitech",		MSE_SERIAL,	mlDefaults,	PROT_LOGI },
    { "MouseMan",		MSE_SERIAL,	msDefaults,	PROT_LOGIMAN },
    { "MMHitTab",		MSE_SERIAL,	mmhitDefaults,	PROT_MMHIT },
    { "GlidePoint",		MSE_SERIAL,	msDefaults,	PROT_GLIDE },
    { "IntelliMouse",		MSE_SERIAL,	msDefaults,	PROT_IMSERIAL },
    { "ThinkingMouse",		MSE_SERIAL,	msDefaults,	PROT_THINKING },
    { "AceCad",			MSE_SERIAL,	acecadDefaults,	PROT_ACECAD },
    { "ValuMouseScroll",	MSE_SERIAL,	msDefaults,	PROT_VALUMOUSESCROLL },

    /* Standard PS/2 */
    { "PS/2",			MSE_PS2,	NULL,		PROT_PS2 },
    { "GenericPS/2",		MSE_PS2,	NULL,		PROT_GENPS2 },

    /* Extended PS/2 */
    { "ImPS/2",			MSE_XPS2,	NULL,		PROT_IMPS2 },
    { "ExplorerPS/2",		MSE_XPS2,	NULL,		PROT_EXPPS2 },
    { "ThinkingMousePS/2",	MSE_XPS2,	NULL,		PROT_THINKPS2 },
    { "MouseManPlusPS/2",	MSE_XPS2,	NULL,		PROT_MMPS2 },
    { "GlidePointPS/2",		MSE_XPS2,	NULL,		PROT_GLIDEPS2 },
    { "NetMousePS/2",		MSE_XPS2,	NULL,		PROT_NETPS2 },
    { "NetScrollPS/2",		MSE_XPS2,	NULL,		PROT_NETSCPS2 },

    /* Bus Mouse */
    { "BusMouse",		MSE_BUS,	NULL,		PROT_BM },

    /* Auto-detect (PnP) */
    { "Auto",			MSE_AUTO,	NULL,		PROT_AUTO },

    /* Misc (usually OS-specific) */
    { "SysMouse",		MSE_MISC,	mlDefaults,	PROT_SYSMOUSE },

    /* end of list */
    { NULL,			MSE_NONE,	NULL,		PROT_UNKNOWN }
};

MouseProtocolRec is defined in mousePriv.h as:

typedef struct {
    const char *	name;
    int			class;
    const char **	defaults;
    MouseProtocolID	id;
} MouseProtocolRec, *MouseProtocolPtr;

Mouse interface classes and Mouse Protocol IDs are defined in xf86OSmouse.h as:

/* Mouse interface classes */
#define MSE_NONE	0x00
#define MSE_SERIAL	0x01		/* serial port */
#define MSE_BUS		0x02		/* old bus mouse */
#define MSE_PS2		0x04		/* standard read-only PS/2 */
#define MSE_XPS2	0x08		/* extended PS/2 */
#define MSE_AUTO	0x10		/* auto-detect (PnP) */
#define MSE_MISC	0x20		/* The OS layer will identify the
					 * specific protocol names that are
					 * supported for this class. */

/* Mouse Protocol IDs. */
typedef enum {
    PROT_UNKNOWN = -2,
    PROT_UNSUP = -1,		/* protocol is not supported */
    PROT_MS = 0,
    PROT_MSC,
    PROT_MM,
    PROT_LOGI,
    PROT_LOGIMAN,
    PROT_MMHIT,
    PROT_GLIDE,
    PROT_IMSERIAL,
    PROT_THINKING,
    PROT_ACECAD,
    PROT_VALUMOUSESCROLL,
    PROT_PS2,
    PROT_GENPS2,
    PROT_IMPS2,
    PROT_EXPPS2,
    PROT_THINKPS2,
    PROT_MMPS2,
    PROT_GLIDEPS2,
    PROT_NETPS2,
    PROT_NETSCPS2,
    PROT_BM,
    PROT_AUTO,
    PROT_SYSMOUSE,
    PROT_NUMPROTOS	/* This must always be last. */
} MouseProtocolID;

InitProtocols changes the mouseProtocols[] array, presented in its original form in mouse.c, via InitProtocols so that records with classes not returned by the Linux specific (in this example) Supported Interfaces mark its id field as PROT_UNSUP and also for the MSE_MISC class the OS must identify the specific protocol names that are supported for this class, via
osInfo->CheckProtocol, otherwise are marked aslo as PROT_UNSUP.

The BSD SetupAuto() is implemented as:

	
static const char *
SetupAuto(InputInfoPtr pInfo, int *protoPara)
{
    int i;
    mousehw_t hw;
    mousemode_t mode;

    if (pInfo->fd == -1)
	return NULL;

    /* set the driver operation level, if applicable */
    i = 1;
    ioctl(pInfo->fd, MOUSE_SETLEVEL, &i);
    
    /* interrogate the driver and get some intelligence on the device. */
    hw.iftype = MOUSE_IF_UNKNOWN;
    hw.model = MOUSE_MODEL_GENERIC;
    ioctl(pInfo->fd, MOUSE_GETHWINFO, &hw);
    xf86MsgVerb(X_INFO, 3, "%s: SetupAuto: hw.iftype is %d, hw.model is %d\n",
		pInfo->name, hw.iftype, hw.model);
    if (ioctl(pInfo->fd, MOUSE_GETMODE, &mode) == 0) {
	for (i = 0; i < sizeof(devproto)/sizeof(devproto[0]); ++i) {
	    if (mode.protocol == devproto[i].dproto) {
		/* override some parameters */
		if (protoPara) {
		    protoPara[4] = mode.packetsize;
		    protoPara[0] = mode.syncmask[0];
		    protoPara[1] = mode.syncmask[1];
		}
		xf86MsgVerb(X_INFO, 3, "%s: SetupAuto: protocol is %s\n",
			    pInfo->name, devproto[i].name);
		return devproto[i].name;
	    }
	}
    }
    return NULL;
}

where devproto is defined in the same file as:

	
static struct {
	int dproto;
	const char *name;
} devproto[] = {
	{ MOUSE_PROTO_MS,		"Microsoft" },
	{ MOUSE_PROTO_MSC,		"MouseSystems" },
	{ MOUSE_PROTO_LOGI,		"Logitech" },
	{ MOUSE_PROTO_MM,		"MMSeries" },
	{ MOUSE_PROTO_LOGIMOUSEMAN,	"MouseMan" },
	{ MOUSE_PROTO_BUS,		"BusMouse" },
	{ MOUSE_PROTO_INPORT,		"BusMouse" },
	{ MOUSE_PROTO_PS2,		"PS/2" },
	{ MOUSE_PROTO_HITTAB,		"MMHitTab" },
	{ MOUSE_PROTO_GLIDEPOINT,	"GlidePoint" },
	{ MOUSE_PROTO_INTELLI,		"Intellimouse" },
	{ MOUSE_PROTO_THINK,		"ThinkingMouse" },
	{ MOUSE_PROTO_SYSMOUSE,		"SysMouse" }
};

SetMouseProto()

Next SetupMouse() calls SetMouseProto() to fill from pMse->protocolID other pMse fields like class, protocol (name), protoPara. Field pMse->protocolID obtained its value from MousePreInit(), which was covered in section 3.2.3 (see this example for the "Protocol" value) with the following code lines:

	
    /* Find the protocol type. */
    protocol = xf86SetStrOption(dev->commonOptions, "Protocol", NULL);
. . .
    protocolID = ProtocolNameToID(protocol);
. . .
    pMse->protocolID = protocolID;

Example

For the example we follow "Protocol" is IMPS/2 and ProtocolNameToID, implemented as:

	
static MouseProtocolID
ProtocolNameToID(const char *name)
{
    int i;

    for (i = 0; mouseProtocols[i].name; i++)
	if (xf86NameCmp(name, mouseProtocols[i].name) == 0)
	    return mouseProtocols[i].id;
    return PROT_UNKNOWN;
}

lookups mouseProtocols[] (see previous paragraphs) and returns to pMse->protocolID the value "PROT_IMPS2".

SetMouseProto() is called as:

	
    SetMouseProto(pMse, pMse->protocolID);

SetMouseProto is implemented in the same file as:

	
static void
SetMouseProto(MouseDevPtr pMse, MouseProtocolID protocolID)
{
    pMse->protocolID = protocolID;
    pMse->protocol = ProtocolIDToName(pMse->protocolID);
    pMse->class = ProtocolIDToClass(pMse->protocolID);
    if ((pMse->protocolID >= 0) && (pMse->protocolID < PROT_NUMPROTOS))
	memcpy(pMse->protoPara, proto[pMse->protocolID],
	       sizeof(pMse->protoPara));
    
    if (pMse->emulate3ButtonsSoft)
	pMse->emulate3Buttons = TRUE;
}

xf86SetSerial()

SetupMouse() calls xf86SetSerial() to set the serial port parameters for the mouse. It is implemented in posix_tty.c, as:

	
    /* Set the port parameters. */
    if (!automatic)
	xf86SetSerial(pInfo->fd, pInfo->options);

xf86SetSerial() calls tcgetattr() (See serial programming and man page) to retrieve the parameters associated with the device referred by the fd to the termios struct t:

	
	SYSCALL (tcgetattr (fd, &t));

A number of xf86SetIntOption() calls is used then to get serial port options from the xorg.conf (see this example) and then accordingly update the termios struct t. The options are:

BaudRate
StopBits
DataBits
Parity
Vmin
Vtime
FlowControl
ClearDTR
ClearRTS
For an explanation on the previous terms see Serial Programming Guide.xf86SetStrOption() was covered in section 3.2.4.

Finally a tcsetattr() call is used to set the new attributes, stored previously in the termios struct t to the mouse serial port.

	SYSCALL (r = tcsetattr (fd, TCSANOW, &t));

initMouseHW

initMouseHW() is called as:

	
    if (!initMouseHW(pInfo))
	return FALSE;  

initMouseHW() is implemented in mouse.c.