Source to bsd/dev/ppc/drvUSBCMD/mouse/HIDEmulation.c


Enter a symbol's name here to quickly find it.

/*
 * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
 *
 * @APPLE_LICENSE_HEADER_START@
 * 
 * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
 * Reserved.  This file contains Original Code and/or Modifications of
 * Original Code as defined in and that are subject to the Apple Public
 * Source License Version 1.0 (the 'License').  You may not use this file
 * except in compliance with the License.  Please obtain a copy of the
 * License at http://www.apple.com/publicsource and read it before using
 * this file.
 * 
 * The Original Code and all software distributed under the License are
 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
 * License for the specific language governing rights and limitations
 * under the License."
 * 
 * @APPLE_LICENSE_HEADER_END@
 */

/*
	File:		HIDEmulation.c

	Contains:	HID Emulation glue code between the ADB SHIM and the USB Mouse HID Module

	Version:	xxx put version here xxx

	Copyright:	� 1998 by Apple Computer, Inc., all rights reserved.

	File Ownership:

		DRI:				Craig Keithley

		Other Contact:		xxx put other contact here xxx

		Technology:			xxx put technology here xxx

	Writers:

		(BWS)	Brent Schorsch
		(DKF)	David Ferguson
		(CJK)	Craig Keithley

	Change History (most recent first):

	 <USB30>	  7/6/98	CJK		make certain cursor device is removed when interrupt is
									installed
	 <USB29>	 6/22/98	CJK		move cursordevice setup to InterfaceEntry, which is guarenteed
									to be called at task time
	 <USB28>	 6/18/98	BWS		fixed interrupt refcon support
	 <USB27>	 6/18/98	CJK		add interrupt refcon support
	 <USB26>	 5/28/98	CJK		remove pragma unused from NotifyRegisteredHIDUser
	 <USB25>	 5/20/98	CJK		change driver name from USBMouseModule to USBHIDMouseModule
	 <USB24>	 5/13/98	CJK		move DPI setting to interface entry code
	 <USB23>	 4/24/98	CJK		add "get device units per inch" functionality
	 <USB22>	 4/23/98	CJK		add status message when interrupt is installed.
	 <USB21>	 4/23/98	CJK		Reworked mouse functionality to always pass mouse data on to the
									register HID user (even if the data is the same as the last
									read).
	 <USB20>	 4/20/98	CJK		add in mouse demo mode control selector
	 <USB19>	  4/9/98	CJK		remove include of USBClassDrivers.h, USBHIDModules.h, and
									USBDeviceDefines.h
	 <USB18>	  4/9/98	CJK		remove demo mode support
		<17>	  4/8/98	CJK		rework USBMouseIn to work the same way as the standard interrupt
									handler
		<16>	 3/27/98	CJK		only set units per inch to 100 when using a BTC keyboard.
		<15>	 3/25/98	CJK		Move units per inch initialization to here, as we're now using
									interrupt transactions. Remove clip to -90. Change name of
									paramblock pointer to better indicate that it's a pointer to a
									cursor device manager struct.
		<14>	 3/18/98	CJK		Add back in the clip to -90. Seems that this is the cause of the
									mouse skip.
		<13>	 3/18/98	CJK		Remove checks for X & Y deltas of less than -90
		<12>	 3/17/98	CJK		Replace some "};" with just "}" (MetroWerks has a problem with
									it). Add parens around the pragma unused variables. Move
									function prototypes to MouseModule.h
		<11>	  3/9/98	CJK		Add check for BTC mouse port. If that's the mouse we're using,
									then set the DPI to 100.
		<10>	  3/3/98	CJK		change cursor device manager device creation to used 'Fixed'
									data type properly.
		 <9>	  3/2/98	CJK		add check for illegal mouse movement values.  Don't allow
									movement if it's less than negative 90.
		 <8>	  3/2/98	CJK		Add include of USBHIDModules.h. Remove include of HIDEmulation.h
		 <7>	 2/18/98	CJK		change call to mouse buttons to only pass a char.
	  <USB6>	 2/17/98	DKF		Add mouse movement if there is no shim installed
		 <5>	 2/10/98	CJK		change hid notification code to munge X & Y delta values into
									signed 16 bit values.
		 <4>	 2/10/98	CJK		remove debugstr (that is hit when both mouse buttons are
									pressed).
		 <3>	 2/10/98	CJK		Remove keyboard related code
		 <2>	  2/9/98	CJK		remove get descriptor from HID Emulation code
		 <1>	  2/9/98	CJK		First time check in.  Cloned from CompoundDriver.
*/

//#include <Types.h>
//#include <Devices.h>
#include "../driverservices.h"
//#include <CursorDevices.h>
#include "../USB.h"
#include "MouseModule.h"

extern	usbMousePBStruct myMousePB;
extern void mouse_adbhandler(int number, unsigned char *buffer, int count, void * ssp);


void USBMouseIn(UInt32 refcon, void * theData)
{
#pragma unused (refcon)

USBHIDDataPtr	pMouseData;
static UInt16 	oldbuttons = 0;
UInt16 	changedbuttons = 0;

//	DebugStr("In USBMouseIn");
	pMouseData = (USBHIDDataPtr)theData;

	// Tell the Cursor Device Manager that we moved
	if ((pMouseData->mouse.XDelta != 0) || (pMouseData->mouse.YDelta !=0))
	{
		CursorDeviceMove(myMousePB.pCursorDeviceInfo, pMouseData->mouse.XDelta, pMouseData->mouse.YDelta);
	}
	
	// Update with the state of the buttons.
	pMouseData->mouse.buttons &= 0x07;
	changedbuttons = oldbuttons ^ pMouseData->mouse.buttons;
	if (changedbuttons)
	{
		CursorDeviceButtons(myMousePB.pCursorDeviceInfo, (short)pMouseData->mouse.buttons);
	}
	oldbuttons = pMouseData->mouse.buttons;
}

OSStatus USBHIDInstallInterrupt(HIDInterruptProcPtr HIDInterruptFunction, UInt32 refcon)
{
	USBExpertStatus(myMousePB.deviceRef, "USBHIDMouseModule: Demo Mode Disabled (interrupt service routine installed)", myMousePB.deviceRef);
	myMousePB.interruptRefcon = refcon;
	myMousePB.pSHIMInterruptRoutine = HIDInterruptFunction;
	if (myMousePB.pCursorDeviceInfo != 0)
	{
		CursorDeviceDisposeDevice(myMousePB.pCursorDeviceInfo);
		myMousePB.pCursorDeviceInfo = 0;
	}
	return noErr;
}

OSStatus USBHIDPollDevice(void)
{
	return kUSBInternalErr;
}

OSStatus USBHIDControlDevice(UInt32 theControlSelector, void * theControlData)
{
#pragma unused (theControlData)

	switch (theControlSelector)
	{
		case kHIDRemoveInterruptHandler:
			myMousePB.interruptRefcon = nil;
			myMousePB.pSavedInterruptRoutine = nil;
			myMousePB.pSHIMInterruptRoutine = nil;
			break;
			
		case kHIDEnableDemoMode:
			USBExpertStatus(myMousePB.deviceRef, "USBHIDMouseModule: Demo Mode Enabled", myMousePB.deviceRef);
			
			if (myMousePB.pCursorDeviceInfo == 0)
			{
				myMousePB.pCursorDeviceInfo = &myMousePB.cursorDeviceInfo;
				CursorDeviceNewDevice(&myMousePB.pCursorDeviceInfo);
				
				CursorDeviceSetAcceleration(myMousePB.pCursorDeviceInfo, (Fixed)(1<<16));
				
				CursorDeviceSetButtons(myMousePB.pCursorDeviceInfo, 3);			// should actually be set by reading
																				// the HID descriptor, but lacking
																				// a parser, we'll just force it
																				// this way.
				CursorDeviceButtonOp(myMousePB.pCursorDeviceInfo, 0, kButtonSingleClick, 0L);
				CursorDeviceButtonOp(myMousePB.pCursorDeviceInfo, 1, kButtonSingleClick, 0L);
				CursorDeviceButtonOp(myMousePB.pCursorDeviceInfo, 2, kButtonSingleClick, 0L);
				CursorDeviceUnitsPerInch(myMousePB.pCursorDeviceInfo, (Fixed)(myMousePB.unitsPerInch));
			}
		
			myMousePB.pSavedInterruptRoutine = myMousePB.pSHIMInterruptRoutine;
			myMousePB.pSHIMInterruptRoutine = USBMouseIn;
			break;

		case kHIDDisableDemoMode:
			USBExpertStatus(myMousePB.deviceRef, "USBHIDMouseModule: Demo Mode Disabled", myMousePB.deviceRef);
			if (myMousePB.pCursorDeviceInfo != 0)
			{
				CursorDeviceDisposeDevice(myMousePB.pCursorDeviceInfo);
				myMousePB.pCursorDeviceInfo = 0;
			}
			myMousePB.pSHIMInterruptRoutine = myMousePB.pSavedInterruptRoutine;
			break;

		default:
			return paramErr;
	}
	return noErr;
}



OSStatus USBHIDGetDeviceInfo(UInt32 theInfoSelector, void * theInfo)
{
HIDInterruptProcPtr * pHIDIntProcPtr;
UInt32 * pUnits;
UInt32 * pInterruptRefcon;

	switch (theInfoSelector)
	{
		case kHIDGetDeviceUnitsPerInch:
			pUnits = (UInt32*)theInfo;
			*pUnits = (UInt32)(myMousePB.unitsPerInch);
			break;
			
			
		case kHIDGetInterruptHandler:
			pHIDIntProcPtr = (HIDInterruptProcPtr *)theInfo;     
			*pHIDIntProcPtr = myMousePB.pSHIMInterruptRoutine;
			break;

		case kHIDGetInterruptRefcon:
			pInterruptRefcon = (UInt32 *)theInfo;
			*pInterruptRefcon = myMousePB.interruptRefcon;
			break;
		
		default:
			return paramErr;
	}
	return noErr;
}

OSStatus USBHIDEnterPolledMode(void)
{
	return unimpErr;
}

OSStatus USBHIDExitPolledMode(void)
{
	return unimpErr;
}

void NotifyRegisteredHIDUser(UInt32 devicetype, UInt8 hidReport[])
{
#pragma unused (devicetype)

USBHIDData		theMouseData;
SInt8			myXDelta, myYDelta;
UInt8			adb_data[4];

	theMouseData.mouse.buttons = (UInt16)hidReport[0];
	
	myXDelta = (SInt8)hidReport[1];
	myYDelta = (SInt8)hidReport[2];  
//kprintf("***Mouse data: buttons=0x%x, Xdelta=0x%x, YDelta=0x%x***\n",hidReport[0],hidReport[1],hidReport[2]);
	theMouseData.mouse.XDelta = (SInt16)myXDelta;
	theMouseData.mouse.YDelta = (SInt16)myYDelta;
	
	//A.W. call the mouse driver in ADB-land
	adb_data[0] = (SInt8)hidReport[2];
	adb_data[1] = (SInt8)hidReport[1];
	if (hidReport[0] == 1)   /* Clicked */
	{
		adb_data[0] = ((adb_data[0] >>1) & 0x7f);    
	}
	else adb_data[0] = 0x80 | (adb_data[0] >>1);  //button 1 clickif (hidReport[0] == 2)

	if (hidReport[0] == 2)   /* Clicked */
	{
		adb_data[1] = ((adb_data[1] >>1) & 0x7f);    
	}
	else adb_data[1] = 0x80 | (adb_data[1] >>1);  //button 1 clickif (hidReport[0] == 2)

	mouse_adbhandler(3, adb_data, 2, (void *) 0);

	if (myMousePB.pSHIMInterruptRoutine)
	{
		(*myMousePB.pSHIMInterruptRoutine)(myMousePB.interruptRefcon, (void *)&theMouseData);
	}
}
USBHIDModuleDispatchTable TheHIDModuleDispatchTable =
{
	(UInt32)0,
	(USBHIDInstallInterruptProcPtr)USBHIDInstallInterrupt,
	(USBHIDPollDeviceProcPtr)USBHIDPollDevice,
	(USBHIDControlDeviceProcPtr)USBHIDControlDevice,
	(USBHIDGetDeviceInfoProcPtr)USBHIDGetDeviceInfo,
	(USBHIDEnterPolledModeProcPtr)USBHIDEnterPolledMode,
	(USBHIDExitPolledModeProcPtr)USBHIDExitPolledMode
};
CursorDevicePtr gUSBMouse;
CursorDevice	ourDevice;