Configure player

Close

WWDC Index does not host video files

If you have access to video files, you can configure a URL pattern to be used in a video player.

URL pattern

preview

Use any of these variables in your URL pattern, the pattern is stored in your browsers' local storage.

$id
ID of session: wwdc2003-509
$eventId
ID of event: wwdc2003
$eventContentId
ID of session without event part: 509
$eventShortId
Shortened ID of event: wwdc03
$year
Year of session: 2003
$extension
Extension of original filename: mov
$filenameAlmostEvery
Filename from "(Almost) Every..." gist: ...

WWDC03 • Session 509

HID and Force Feedback

Hardware • 53:22

This session discusses how to support the latest Human Interface Devices in your application. We present details on the HID Manager and the new Force Feedback Framework delivered in Mac OS X 10.2.3, and show you how to use both to give users the ability to control and feel your application's environment. For Force Feedback device developers, we describe how to add support for your products.

Speakers: Craig Keithley, Rob Yepez, Fernando Urbina

Unlisted on Apple Developer site

Transcript

This transcript was generated using Whisper, it has known transcription errors. We are working on an improved version.

You don't have to install any drivers. It works automatically. So, can we go to demo four, please? Just a couple of quick devices I want to show off. These are products that are coming to the Mac. Thanks. The first one is made by a company called 3D Connection. Ignore the Lab Tech label on here. 3D Connection bought them. It's a six degree of freedom controller, and it allows you to move objects in three-dimensional space automatically. I have a demo app here.

[Transcript missing]

Still not working, Jeff. All right, well, I'm going to skip that demo. I can assure you that it does work. The other product that we have from the same company, 3D Connection, is a keyboard that has one of the 6-degree freedom controllers built in, which is very cool.

These kinds of keyboards can be used to do video editing. Almost anything where you need a jog channel would work. But what I'm mostly interested in seeing happen is CAD CAM applications adopt 6-degree freedom controllers. Afterwards, if you've got an interest in that, please come up and talk to Jeff Lowe and I.

We'd be really keen to work with you to make that happen. The final sample device that I have I want to show off is from ATI. So probably a lot of you think that ATI makes really great video cards, maybe the occasional TV tuner, but they also make a remote.

And the remote has buttons on it that will bring up a web browser. It will play music as well. Oh, I'm going to the Apple internal website. You can play music, you can control iTunes, control TV if you've got a TV tuner. It's a really great little remote. So with that, let me turn it over to the guys and they will go into Hidden Force Feedback. Thanks.

and Fabio Paz, the HIID Manager Engineer on the I/O Kit team for Apple. And today we're just going to briefly go over the HIID Manager. Basically what we'll do is we'll talk about what HIID is, the HIID implementation on Mac OS X, some improvements that we've added since Jaguar 10.2, and some techniques for using the HIID Manager. Hopefully what you'll learn here is how HIID fits into Mac OS X and how to effectively use the HIID Manager.

So first off, what is HIID? Well, HIID stands for Human Interface Device. It was a specification developed by the USB Implementers Forum to cover devices that humans use to interact with the system. Some examples are your standard keyboard and mouse, front panel controls, which actually might be your controls on the front of your monitor, or controls on your USB speakers, gamer simulation devices like this steering wheel over here, or devices that don't actually require human interaction. So that would be like uninterruptible power sources or credit card swipers or badge readers.

So let's cover some brief terminology. The first thing is a HIID report. And basically what this is, is the raw data that's actually sent to or received from the device. It can actually be pulled or interrupt driven. And there's really three types of reports. Input report, which is basically reports that are received from the device, and it's pretty much read only. An output report is a report that's sent to the device, and it's write only. And the feature report is actually a combination of the two. It can be sent to or received from the device.

The next term is an element. And basically an element covers the parsed items from the report. The behaviors are actually covered by its usage and usage page. And there's really two different types of elements. The data element, which there's three subtypes of, the input, output, and feature that we covered earlier, and a collection element.

and collections actually are useful for representing relationships between two or more data objects. And there's five different types of collections. The physical, application, logical, report, and named array. The first two we'll actually cover in more detail. So this is an example descriptor of a, of a HID mouse.

So the first item we're looking at here is actually the application collection. And what this does is actually tip off the system of what the intended behavior of this device is. The next collection is a physical collection for the pointer. And basically what we're doing here is we're grouping together the buttons and the axes because it makes sense for them to be grouped together that way.

And the next example here is the declaration of the actual button elements. So as you see here, we've got a... A report count of three and a report size of one. So basically what we're doing here is declaring three objects that are one bit each. And basically what this will represent is buttons one through three.

The next items that we're declaring here are the X and Y axes. And basically these are two 8-bit values that represent both the X and Y axes. Now one thing you'll notice is that for the buttons, the input was actually absolute, and for the axes they're relative. So basically the absolute type elements are based on a fixed origin, or absolute is based on a fixed origin.

Absolute is based on a fixed origin and Relative is based on changing origins from different, or changing axes from different... So an example of this would be a mouse would be a relative type of value, whereas a tablet would probably want a fixed origin or absolute coordinate system.

So now that we've got pretty much a basic understanding of what HIID is, we'll kind of jump into how the stack is actually implemented on OS X and the HIID Manager. So basically the HIID Manager is the abstraction layer of how to interact with the device for receiving the raw events.

It basically consists of three layers. The HIID drivers at the lowest layer, the kernel architecture, and the user space API. and this is kind of a diagram showing how these actually interact with each other, the application being up at the top portion, communicating with the IOHID lib, which then again crosses the kernel boundary and communicates directly with the devices.

So basically, a HIID driver is an I/O service that's subclassed off of I/O HID device. The transport is not actually restricted to USB, and it actually provides an opportunity for other developers to provide support for serial and FireWire devices. One thing is, we are normalized on the USB HIID specification. So then if you are creating a third-party driver, We do ask that you translate the report descriptor and reports to actually work with the USB spec so that it can work fully with the HID Manager.

So an example of a device that might want to be, have its own HID driver is a serial whiteboard device. Right now, by default, when you plug it in, it will not work with the system. But if somebody writes a specific driver and goes ahead and creates a USB report descriptor and handles and translates the reports, it'll go ahead and behave like, similar to a USB tablet.

So the next layer is the I/O HId family, and it is actually the kind of the meat of the whole HId Manager. It's responsible for doing a lot of the work. And essentially what it does is it'll parse the HId reports and split them up into the individual elements that make more sense to an application developer.

It also interacts directly with the I/O HId lib, and allows like the bridging between the application and the device itself. It maintains a shared memory that, contains the current values of the elements, and it also is responsible for publishing the properties of that device in the I/O registry.

So this is useful for when you want to actually match up the device, locate a device or locate the different elements within the device. So when going through the registry, there are certain key value pairs that are defined, and these are located in iohidkeys.h. So for device-wide constants, they start with kioHID, and element-wide constants start with kioHID_element. And this will show up later on as we show examples of what these things look like in the IO registry.

So this is the example IR registry entry for a HID device. Right here, this is just the mouse. And you know, it has the vendor ID, the location, transport, and any other properties you'd expect for a USB device or any other device that's a HID device. The two properties that you're gonna be interested in as an application developer, are the primary usage and primary usage page.

And essentially what this does is it is the top level application collection. And what it is is it tips off to you, the developer, what this device actually does. So right here, the primary usage page of one is a generic desktop, and the primary usage two is a mouse.

As you see also at the bottom, there's an elements property as well, and that's pretty much the The I-Registry is an array of elements that are defined as well. And so when we go to the next example here, this is a collection element and how it looks inside the registry. Pretty basic.

It has an element cookie, which is basically our unique identifier for that particular element, and it describes the usage page and usage. So you see here, this is the application collection that has the usage page of one and two. So pretty much the mouse, or describing the behavior of the mouse.

And then here is an example of the registry entry for an actual data element. So once again, it does have an element cookie again. So this is the unique identifier for this particular button. This is actually button one of a mouse. And it shows all the other properties such as the type, the size, the min, max, and unit exponent, anything that would be more helpful for you to actually use that particular element.

So now we'll go to the higher level portion of the HIID Manager. And this is mostly what you'll be concerned with as an application developer, is the IOHID lib. And basically it's a CFPlugin architecture, sort of like the USB CFPlugin or FireWire CFPlugin that communicates directly with the device itself, or with the IOHID family. And it's broken up into three different interfaces. The IOHID device interface, the IOHID queue interface, the output transaction interface. And each interface is actually defined by a UUID, or Universally Unique Identification.

So the first interface, of course, is the IOHID device interface. And basically what this is is a CFPlugin interface that communicates directly to the device and establishes its connection to the device. You use this to read and post element values directly. So there's basically two types of APIs.

The standard APIs, which rely on the parsed items or parsed elements of the device, and this is something, as an application developer, probably you're going to use more because you're not really concerned about how data is actually laid out in terms of the report. Now, for more advanced APIs, getReport and setReport, these are intended for developers that actually know that the device that they're communicating with and actually know how the data is laid out. And so you're probably going to want to use these more advanced APIs.

So the next thing is the Q interface, and this is extremely useful for applications that need to respond to every hit event. So for example, it would be a, suppose you have a first person shoot-em-up game. You don't want to actually respond to the current value of that element or, you know, the trigger button, but in fact you want to queue up the trigger button events coming in.

So this will allow you to effectively do that. It can actually, the queue can be set up to be pulled or receive asynchronous notifications. And we actually recommend that you use async notifications as your application will do less work pulling the queue, and you almost receive events almost instantaneously.

And the last kind of interface we have here is the Output Transaction Interface. And essentially what this does is it kind of consolidates the number of reports that you're sending to the device. So let's say, for example, you have a keyboard device and you have basically three LEDs defined on there, and you want to toggle the Caps Lock LED and the Num Lock LED.

Well, if you use just the IOHID device interface, you'd set the element value for the Caps Lock and set the element value for the Num Lock. What this does is actually send two separate reports to the device, and you might actually be blocking. What we do here is you would just add it to Output Transaction, and now instead of sending two separate reports, you'll just send the one down. And this is kind of a replacement for Set Report for less advanced users who don't actually care about how it's laid out in terms of the report.

So we've had some improvements to the HIID Manager since Jaguar or 10.2, and one of the major things we've added is the ability to see a HIID events from a device. And essentially what this does is, suppose you have a credit card swiper or a barcode reader. These devices actually behave and look similar to keyboards, and so when you swipe a credit card or you read a barcode or whatever, it actually spews out key events to the system.

And this isn't necessarily behavior that you actually want to achieve. It's just a way for the system to see what happens. So if you just want your application to interact with it directly and only see those events, you would go ahead and seize that device and make sure that the events only come to you.

We've also added some improvements to the API. Of course, as you may have known, in 10.3, to support Force Feedback, we added two new APIs for GetReport and SetReport, which are the more advanced APIs that I mentioned earlier. And then new in Panther, what I've added is the copy matching elements.

And essentially what this does is instead of you having to traverse through the registry to find what the capabilities are of the device, all you would do is set up a matching dictionary, like you do for finding a particular device, to find an actual element, or to see if that device contains the behavior that you're expecting.

And another API that we've added is SetInterruptReportHandlerCallback. And essentially what this lets you do, instead of polling a device via GetReport to get the current report of that device, this allows you to actually be notified every time an incoming report comes in from the interrupt in pipe of the device. So it's extremely useful for people who need to know that advanced behavior.

And so, let's start off with some basic techniques on how to use the HID Manager in some simple code. So, if you guys have already messed around with I/O Kit and know how to actually match a device, essentially what we're doing here is go ahead and creating a matching dictionary to find a HIID device. What we're doing though is refining the search to actually look for a mouse or all mice devices on the system.

So, what we've done here is create a usage page and usage number ref, and then added it to the matching dictionary, and then gone ahead and tried to find all services matching that particular dictionary or criteria. Now that we've gone ahead and grabbed the iterator, we go ahead and try to cycle through all the devices that we found, or services that we found.

Now that we've found a device and we're on that particular device, the first thing we'll have to do is actually create the IOCF plugin interface. And this is something that you might be used to if you've messed around with USB devices or FireWire devices from user land. Once you've acquired the IOCF plugin interface, let's go ahead and create an interface to the HIID device itself. And so we query the interface of that plugin to acquire the interface of the device.

Now that we've acquired the interface, the first thing we need to do is actually open a device for communication. So like I mentioned earlier, we have actually two different options here for opening the device. We can do a standard open, which will just allow it to communicate like it does before, and everyone, all clients receive events. Or you can actually perform the seize right here, which will just maintain that you will get direct communication with that device. If you do actually aren't able to seize the device, you will get an error return back to you.

Now that we've had the device open, we actually want to find the capabilities of this device. And so let's go ahead and set up a matching dictionary to find all the elements. So what we do here is go ahead and allocate a CFDictionary, and then add-- let's say here that we want to find all the button elements on this device.

So what we do is go ahead and add a usage page item inside the dictionary covering the buttons page, and then go ahead and try to find all the buttons on that device. And what it should do is return back to you a CFArray containing all the CFDictionary, you know, registry entries for that device or for that element, particular elements.

Now that we've found all the elements, we essentially want to store all the cookies, and the cookies are the unique identifier to actually communicate with that particular element. And so we just kind of cycle through the array and store all the cookies into our own internal storage. As kind of a quick test, we should just go ahead and grab the value, the current value of the first button that we saw, and you could easily just do that.

Now that we've basically interacted with the device, we kind of want to see how to actually create a queue interface, or grab all the values from that button behavior that we've seen before. So what we want to do is first create the queue. So we allocate the queue from the device interface, and then we go ahead and create an internal queue within there.

And so in this example, we're only really creating a queue that's about eight fields deep, and that's pretty much what we really need. It's all that's essential for us to interact with that device. Now let's go ahead and cycle through all the buttons that we've collected before and add them individually to that queue.

Now that we've added the elements to that queue, we go ahead and set ourselves up for asynchronous operation. So what we do first is create the async event source, and what we do is we use this in conjunction with the CF run loop. And kind of what we set up here with the HId Manager is we expect this to work only with a CF run loop. So after we've added the event source to the run loop, we go ahead and send the event call out. And this is the callback function that will call into your application to go ahead and drain the queue.

So as soon as, you know, events come on the queue, we go ahead and trigger your application, and we call your callback. And now that we've got this callback being called, you go ahead and cycle through the queue and determine and do whatever operation you want to do on that particular event. And it's pretty straightforward.

So now that we've covered both device and queues, let's go into the output transaction interface. And for this one, we're not actually going to be using the mouse that we described earlier, but instead kind of a keyboard, and assume that we've set it up in the same manner.

So essentially what we have here is a keyboard has both a caps lock, an LED, and a scroll lock, or a caps lock LED, a scroll lock LED, and an unlock LED. So what we do is go ahead and create the transaction interface, and then add those items to the transaction.

Also what I'm going to do is set the default values. So basically what this is, is after you've committed a transaction, this is the value that this element will revert to for the next time, or each subsequent commit that you do on this transaction. So right now we're just going to zero it all out.

Now that we've gone ahead and set the default values and added those elements to the transaction, what we want to do is set the element values. So basically all we're concerned about doing here is setting the LED values for the caps lock and num lock. So we go ahead and turn those on and then set the values. After we've done that, we go ahead and commit the transaction. And essentially what will happen here is both the num lock LED and the caps lock LED will turn on, and the scroll lock LED will remain off.

Had we not actually included the scroll lock LED into the transaction, the value would have remained the same value that it would have been prior to the commit. Because basically what we do is we do not go ahead and change that value, it just remains the same value.

So basically in summary, I hope you've got a better understanding of what a Human Interface Device is. kind of a basic understanding of how HIID is implemented on Mac OS X and basic techniques for using the HIID Manager. Some additional references are, you can look at the HIID pages that we have on our developer tech pubs, or you can look at how to write a device driver if you're so inclined. And if you want a more in-depth knowledge of how HIID actually works, you can look at the USB IF's HIID pages. With that, I'll turn it over to Fernando Urbin, of our USB team, to cover Force Feedback.

Thank you, Rob. We're going to change gears a little bit here and I'll talk about Force Feedback and what we've done on Mac OS X. I will start with a brief introduction on what Force Feedback really is and how we implemented an architecture to support Force Feedback in our system.

Then I'm going to give some hints to application developers on some of the APIs and what they need to do to support Force Feedback. And then for those of you, if there are any, that have Force Feedback devices that are not supported on the system right now, what you will need to do in order to provide support for your devices.

You'll see how Force Feedback fits in our system. Hopefully you'll understand why we did what we did and the way we did it. Perhaps you also know how you can now take advantage of Force Feedback and how you, as I mentioned, will be able to develop a plugin to work in our system. So what is Force Feedback? The official definition by those who know is that it is a technology that enhances the human computer interface by engaging your sense of touch.

Over here on the podium we have this Force Feedback steering wheel, but it is important to know that Force Feedback devices are not limited to gaming devices. Immersion has this medical device that is used to train medical professionals on how to perform or how to put an injection on a person. And it actually provides feedback when the needle pierces the simulated skin.

And once it goes through the skin when it actually finds the vein. And it's really cool. I am not a doctor nor do I play one on TV. But it feels just like the real thing. And personally, you know, I would like more nurses to... Use this type of devices.

I mentioned Immersion. They are the leader in Force Feedback technology. They have several patents, and they actually license their technology to several hardware manufacturers. So you'll see Force Feedback devices that do not have the Immersion, are not produced by Immersion, but they have what they call their TouchSense technology logo on the boxes.

Before we delve further into the APIs, I would like to go through some terminology so that you can understand better what I'm talking about later on. A Force Feedback Device is, first of all, a USB HIID compliant device. Now, the USB HIID working group has a specification for what they call Physical Interface Devices, which are Force Feedback Devices.

Force Feedback devices do not have to be compliant to this physical interface device specification in order to work in the system. That's why we, as we're going to see later, have this hardware plugin architecture. These devices are capable of creating a force, or what is called an effect, that the user can feel when they're using the device.

The effects themselves have to be played through software. You have to do something in order to make that device create that feeling. They can be done in either of two ways. You can have a programmatic interface where you download the effect and then you massage it, modify it, start, stop, etc. Or actually, if you can download something to the device and have that device respond automatically to an action by the user.

So, you know, the most obvious one is when you have a shoot-em-up game and the person playing hits the trigger and you get a recoil right away. And it's a benefit that the device does it automatically because you don't have the latency of going up to the application and coming back down and setting up the effect.

There are really four basic types of effects. A constant force effect, not surprisingly, is a constant effect that varies in any one direction. A ramp effect is an effect that increases in strength or decreases in strength, again, in one direction. Not surprisingly, a periodic effect is one that varies over time or over strength.

And then the final one are the condition effects that are as shown on the slide, the spring or the damper. And those effects increase in force as the device moves away from the center line. So, you know, if you have a spring effect and you're pulling away from the spring, you know, the force is going to increase as you're going farther and farther down.

Briefly, some example of effects. On a racing simulation, you can have the pavement vary, and your feedback is going to change depending on whether you are driving on the paved road or you're going off-road and you're on a dirt road. And if you have a flight simulation, if you have turbulence, of course, your stick can start shaking and everything.

Again, this is not limited just to gaming simulations. There are some programs that make use of Force Feedback on educational settings, and you can have a pendulum or a... We present details on the HID Manager and the new Force Feedback Framework delivered in Mac OS X 10.2.3, and show you how to use both to give users the ability to control and feel your application's environment. For Force Feedback device developers, we describe how to add support for your products.

So, how does Force Feedback work on our system? Last fall, we decided to work with Immersion. As I mentioned, they are the leaders on Force Feedback technology. And we work with them in order to bring Force Feedback support on Mac OS X. What we arrived at was a two-pronged approach. There's a Force Feedback Framework for application developers, and that Force Feedback Framework uses some hardware vendor-specific drivers, which we'll see later, that are actually just CFPlugins, to abstract the hardware so that the Force Feedback Framework itself can use any type of Force Feedback device.

We actually shipped support for Force Feedback in the December of last year, the 10.2.3 release. And initially we had support for several devices with Immersion TouchSense technology from Logitech, from Immersion themselves, from SciTech and several others. A couple of weeks after release, two games came out actually supporting Force Feedback, and that was the F1 Championship Series and NASCAR Racing 2002.

Our goals when we started looking into supporting Force Feedback on Mac OS X was, number one, we had a time to market.

[Transcript missing]

These were F1 Championship Series and NASCAR, you know, those games existed on the PC. We wanted to bring them over and have wheels work with them. And of course, we wanted hardware manufacturers to be able to support their device on Mac OS X fairly easily.

I'm a big proponent on not having to reinvent the wheel when there's something that is acceptable and works. Unfortunately, we had as a partner Immersion, and they have large expertise in supporting Force Feedback in different systems, and they knew what worked in other platforms and what didn't work. So, we were fairly lucky to work with them and leverage their expertise in this field.

We came up with then the following architecture. As you see here at the top, we have an application, be it a game or an educational title. And of course, it is using the HIID Manager to control the application.

[Transcript missing]

The vendor driver itself then uses mostly set reports, and this is why we had to add this advanced APIs to the HIID Manager, to send reports over to the device so that it can do its effects. Over the bubble on the right is the... Vendor-specific code-less kegs, and as we'll see later for hardware developers, it's just a method of allowing the Force Feedback Framework to find the driver that is used by a particular device.

So let's go into the Force Feedback Framework itself and what it is. First of all, it is fairly similar to the Force Feedback API that is found in other architectures. We have three basic types of APIs in the framework. One section is system-wide APIs, and for your convenience, we named them to start just with FF for, not surprisingly, Force Feedback. Then we have device-wide APIs that deal just with effects on one device, and those start with FF device.

And finally, we have effect-wide APIs that, again, not surprisingly, deal with effects on a single device, and those API names start with FF effect. And try saying that three times fast. System-wide Force Feedback APIs. There are really only those three APIs that are on the slide. The most important one, actually, is the FF is Force Feedback API.

As noted on the diagram earlier, the application is already using a HIT device to get input from the user. And so you can use the IO service object for that device to inquire from the Force Feedback framework on whether that device actually has Force Feedback support or not.

And what the Force Feedback framework then does, as we'll see later, is look for the FF. And then you can use the CFPlugin for that device and see if it exists and if it's available, et cetera. But, of course, if it's not supported, then this will return false, and you don't have to provide Force Feedback. Then the other two calls are, and as you'll see there later, everything matches. You have a create device, and once you're finished with it, you have a release device.

Device-wide APIs are those that deal with effects on a single device. These are some examples of the APIs themselves. Again, we have a create effect and a destroy effect or release effect API. Some of the other APIs that you encounter are the Get Force Feedback capabilities that will allow a game to actually know what the device can do. Not all devices support all types of effects at all. If you're a racing game, you need to know which effects you can support. The APIs also allow you to actually send an effect to that device.

Now, effect-wide APIs allows you to actually send the effect down to the device, and then to start, stop it, modify it, and essentially manage that effect on that device. These devices are fairly complex themselves, and they have memory, and memory, there's just a limited amount, and so you sometimes have to manage that memory yourself.

The plugin will do some of it for you, but you'll have to manage some of that yourself in some cases. Again, some of the examples of this API is download the effect, unload the effect, get the current parameters for that effect that is already in the device, so that you know what you need to change, and you can start and stop it.

I'd like to say that the devil in all these APIs are these structures. They're quite complex if you're not familiar with Force Feedback implementation. However, you have to set up all these different structures to have the right data, so the devil is in the details or in the structures used by the API.

Fortunately, these structures are very similar to the structures that are used in other platforms. And if you remember my earlier slide where one of our goals was to make it easy for porting houses to add Force Feedback to the Mac OS X version of their games, you can understand why this is so. We have HeaderDoc'd the header files pretty extensively. And so you'll be able to grasp some of the details from that. And as I understand it, the Microsoft developer side has an extensive and quite complete documentation on Force Feedback.

This is not to scare you, but it's just a sample of what sort of things need to be set up in order to create an effect. When we were working with Immersion, Immersion created a tool to test the Force Feedback API. And now I'm going to give you a little demo of this tool. As you can see, it's almost as complicated as the slide I just showed.

But, It allows you to test, you know, well, it allowed us initially to test whether our API was working. Then hardware vendors used it to test whether their hardware plugin was doing the right thing, because it's an easy way of setting up all the parameters, and I can tell you it's all the parameters. We are going to make this the binary for this tool available on the developer website in the very near future.

And then later on, actually, we're going to release the source code to this tool. I'm just going to go through a quick demo. It'll be hard maybe for you to see the wheel shaking, but... I want to make sure that you know that it is real. Here on the right are the APIs related just like I mentioned in the earlier slide, just Force Feedback APIs, device and effect APIs. The first thing that you need to do is create device. This actually is going to go and tell us whether this is a Force Feedback device.

Over here on the left, it tells us that this is the Logitech Momo Force. It doesn't tell us that it's the nice leather version of it, but it's the expensive one. We went and we created that device. I'm just going to make simple calls. That uses the default values. So we go and we create an effect that is a square effect, a square wave effect, and we go and start it.

and I will be presenting the first part of this session. - Hi, I'm Craig Keithley, and I'm the Director of the Office of the Human Interface Device Development. I'm here to talk about the new Force Feedback Framework. The first thing we're gonna do is to create a new Format, and we're gonna create a new Format. And now it shakes a little harder. And finally, we are going to change the duration from three gazillion to nine gazillion.

And I need to release that effect and create and start, and now it'll go ahead and run for a longer period of time. So again, for application developers, this is useful sort of to test the kind of effects that you can use on the device that you're targeting supports. And of course, for hardware vendors, it's a way of verifying that their plugin does everything that they expect it to do. So we can go back to the slides.

Now I'm going to go and talk for a little bit about what hardware vendors need to do in order to support their devices in our architecture. As I mentioned earlier, the hardware plugin abstracts the hardware so that the Force Feedback Framework can use any type of Force Feedback device.

Second bullet, not surprisingly again, this is very similar to the Force Feedback drivers that are supported in other architectures. So if you have experience with those, you'll feel right at home. I actually, with some of the hardware vendors that I worked with when we were developing their drivers and our support, One of them has exactly the same code base for both the Wintel platform and our platform.

And of course that is a big win. And he was able to give us his driver in a very short amount of time. But compatible and everything. It is a CFPlugin just like IOHitLib, IOUSBlib. Like I mentioned on the diagram, how we use to inform the force feedback framework that a, Particular device supports the Force Feedback is we use this code like text. And if you're not familiar with the USB matching criteria that is used in our system, there's Q&A 1076, if I'm not mistaken, that abstracts what the USB Common Class Specification 1.0 says with respect to how USB devices and interfaces should match.

And we use this to, and a code like text just means that it's a text with no binaries, it's just a plist. And we use this plist to merge a dictionary into a USB interface node of the device, and the Force Feedback Framework later will find this node. And what this dictionary has is a UUID path key value. And it's a UUID pair that tells the Force Feedback Framework where the plugin for this device is, and what the UUID it is, so that it can go ahead and open it.

This is a project builder sample of the P-List for a Codelex text, and actually this is a sample project, the WhizzyBank Force Feedback device that we have. As you can see highlighted, we have a dictionary, the IO-CF Plugin Types Dictionary, and again, this is a standard I/O Kit name for this dictionary, and it has a UUID and a path to the plugin, and in this case, it lives at sampleforcefeedback KEXT. Notice that it starts at the KEXT level, so you don't have to put system library extensions. It assumes that it is there, and so it needs to be there. Again, the matching criteria over here is the matching criteria for an I/O USB interface device.

You should also note that our class for this driver is the system supplied I/O USB HIID driver, com.apple.iop.iousb_hiddriver. And because we added support for setReport and getReport in 10.2.3, you have to depend on version 1.9.4 of the HIID driver and on version 1.2.1 of the I/O USB HIID driver.

Finally, the last item there is the OS bundle required, and it says that it is SafeBoot. And you have to do this because our system supplied HIID driver is SafeBoot as well, and if you didn't do it, then you wouldn't participate in the matching for your device, and it wouldn't work.

Finally, the hardware plugin, as I mentioned earlier, the IO Force Feedback lib.h defines the interface for the plugin. It is a CFPlugin architecture, so it's a COM interface, very similar to other platforms. You need to generate your own UUID for your plugin. Universally unique identifier. Do not use the UUID that is in the sample project.

In fact, it won't compile without having to remove a comment from the UUID that I provide there. So you know that you have to go and generate your own. If not, it's not unique, and another vendor that uses it will clash with it, and things won't work. The system provides a tool to generate a UUID, and so all you need to do is UUID gen, and there you go, it has it. As I mentioned also, the interface file itself is pretty well HeaderDoc'd.

The Microsoft developer site has, again, some good information on Force Feedback. And we will be making available a sample Force Feedback plugin project that, you know, there's a lot of overhead involved in creating a CFPlugin, and, you know, it doesn't change between implementations. So, there's just a skeleton project that provides the required methods, and you just have to go and do the hard part and fill in the blanks to actually use your device.

So I hope that you've gotten an understanding of what Force Feedback devices are and why you would use them in our system, how we actually implemented Force Feedback in Mac OS X. And if you are an application developer or a hardware developer, you know how to start using Force Feedback. Again, I would like to thank Immersion for their partnership in developing the Force Feedback Framework. We did it in, I believe, record time.

It was like, - Three months or four months from when we started, when we decided to support Force Feedback and when we actually delivered it. And we missed an earlier update just by that much, so. Just for the DVD benefit, those are some sessions that would be useful for you if you are learning about Force Feedback. And with that, we'll close the session. There's the emails of the usual suspects.