SideShow Gadgets

Get Started Writing Gadgets For Windows SideShow Devices

Jeffrey Richter

This article discusses:

  • SideShow and its associated APIs
  • Developing, installing, and configuring gadgets
  • Device cache management
  • Gadget events and notifications
This article uses the following technologies:
Windows Vista

Code download available at: Side Show 2007_01.exe(169 KB)

Contents

What Are SideShow Devices?
Use and Configuration
SideShow Gadget and Device Architecture
Gadget Installation
Device Cache Management
Gadget Lifetime
Content
Capabilities, Events, and Notifications
Conclusion

Today's applications have lots of information to share with end users. However, screen real estate is limited and organizing all of the possible information is taxing for software developers as well as end users. Furthermore, people prioritize information in different ways and at different times. For example, when a meeting is imminent, I need to know the time and place right now. When I'm driving, I need to know how soon to make the next turn. In general, I might want to always be able to check newly received e-mail messages. Likewise, you can imagine scenarios where I might want information on traffic, flights, weather, financial transactions, and so on. Trying to get the right information to the user at the right time is a difficult problem.

The Microsoft gadgets initiative is committed to alleviating this problem. A gadget is an application (or part of an application) that can present users with the data they want when and where they want it. Currently, Microsoft offers three different kinds of gadgets: gadgets for Windows® Sidebar present a user's information on the user's desktop or in the Windows Vista™ Sidebar; gadgets for Windows Live™ present a user's information on any computer via a Web browser; and gadgets for Windows SideShow™ present a user's information on an auxiliary hardware device via its SideShow-enabled device driver. In this article, I will focus specifically on SideShow hardware devices and how to write a SideShow gadget to communicate with these devices using the managed API.

What Are SideShow Devices?

Windows Vista supports the ability to communicate with one or more auxiliary display devices. These auxiliary display devices can come in all kinds of shapes and sizes with varying capabilities. Many of these devices have not yet been manufactured, but should be available soon.

Some units will be powered when the computer is turned on while others can be powered whether the computer is on or off. Some units may even have their own separate rechargeable batteries. Some units will be in color and some will be grayscale or monochrome. Some will allow bitmaps to be displayed while some may only allow text. Some units will offer varying amounts of on-board memory for caching data while others may have no on-board memory at all. Some will offer buttons allowing navigation of the cached data. Some may offer touch-sensitive displays.

Some may offer a built-in wireless technology (such as Bluetooth) so that the computer can communicate with the device without it being physically connected to the computer. Some may offer a headphone jack allowing you to listen to music or video that has been downloaded into its memory.

Figure 1 shows a prototype notebook computer with a SideShow device mounted in its cover and a close-up picture of the SideShow device itself. This particular SideShow device has a 220×176 resolution display with each pixel offering 16 bits of color depth. The unit also offers Menu, Left, Right, Up, Down, and Enter buttons. This SideShow device is self-powered, meaning that it is powered using the computer's battery; however, the computer doesn't have to be turned on for the user to interact with the device. When on, this particular device consumes about 4 milliwatts of power, compared to the 75 or so watts of power consumed by the whole computer when it is turned on.

Figure 1 Prototype Notebook with a Mounted SideShow Device

Figure 1** Prototype Notebook with a Mounted SideShow Device **(Click the image for a larger view)

Figure 1b

Figure 1b(Click the image for a larger view)

So, with the computer's lid closed and the computer's power off, the user can still read e-mail, examine his calendar, look at some digital photos, get mapping directions, see the current date/time, and so on. And of course, you can modify your own application to export its data to the SideShow device too. I'll show you how to do this later in this article.Figure 2 shows a prototype for a remote control device for controlling Windows Media® Center. The auxiliary display allows the user to select a song and have Media Center play it. What's cool about this is that the user's television or monitor doesn't have to be turned on in order to listen to a song. Also, while watching a movie, program information can be sent from the Media Center PC to the Windows SideShow device, allowing you to read it without affecting the playback of the movie on the monitor. Furthermore, you can use the remote control in order to view the TV guide data and schedule recordings.

Figure 2

Figure 2(Click the image for a larger view)

Other examples of SideShow devices include keyboards with LCD displays, digital picture frames, and even mobile phones. A single computer can have multiple SideShow devices connected to it simultaneously. For example, the prototype notebook computer shown in Figure 1 could have both a keyboard and a remote control talking to it. Each of these displays could show similar or different kinds of information.

Use and Configuration

End users configure their SideShow devices with the Windows SideShow Control Panel applet. When the user opens this applet, she is greeted by a window similar to the one in Figure 3.

Figure 3 SideShow Applet Controls Devices and Gadgets

Figure 3** SideShow Applet Controls Devices and Gadgets **(Click the image for a larger view)

The leftmost panel shows the SideShow hardware devices currently installed, sorted by the date and time of their installation. In the main panel is a grid. The first column shows the installed applications that know how to communicate with SideShow devices; these are the SideShow gadgets. By default, Windows Vista ships with two gadgets: Inbox—Windows Mail and Windows Media Player. Figure 3 also shows another gadget that I've installed (Office Outlook® 2007 Calendar, which ships with Microsoft® Office Outlook 2007) and a gadget that I've written (called Jeff's SideShow Gadget). Each additional grid column represents a SideShow device attached to the computer. Figure 3 shows two SideShow devices: Windows SideShow Simulator—0 and Logitech G-15 Keyboard.

By selecting the checkboxes in the grid, the user indicates which SideShow devices a gadget can talk to. The user can also configure a specific SideShow device by selecting it at the top of the grid. For example, if I select the Windows SideShow Simulator—0 item, I get a window as shown in Figure 4. Here you can configure screen appearance and behavior (theme, language, font size, brightness, backlight, and so on), configure security and privacy settings (use a PIN to unlock the device, delete all data when the user logs off the computer), configure gadgets (turn gadgets on or off, change order of appearance), and uninstall the device.

Figure 4 Configuring a SideShow Device

Figure 4** Configuring a SideShow Device **(Click the image for a larger view)

Many SideShow devices will have their own on-board memory that is used to cache gadget data. A gadget must be running in order to send data to a SideShow device, meaning that the computer must be powered on. So, Windows Vista allows the user to configure when and how often the computer should wake itself up and run the gadget. The user configures this by selecting the "Set my computer to wake automatically" option shown in Figure 3. When selecting this option, the window shown in Figure 5 appears. After being awakened, the computer will stay awake until the machine has been idle for the amount of time specified using the machine's Power Options Control Panel applet. Note that some computers do not support auto-wake and some applications can prevent a machine from going back to sleep.

Figure 5 Configuring How a Gadget Wakes Up The Device

Figure 5** Configuring How a Gadget Wakes Up The Device **(Click the image for a larger view)

SideShow Gadget and Device Architecture

Figure 6 shows an architectural diagram of how SideShow gadget applications communicate with SideShow hardware devices. Each hardware device must come with a user-mode device driver that will have to be installed into Windows Vista. When Windows communicates with the device, the operating system creates a WUDFHost.exe process and loads the device driver into it; there is an instance of WUDFHost.exe for each device driver. There are many benefits to user-mode device drivers, including easier development, easier debugging, greater system stability, and improved security. For more info about the Windows User-Mode Device Driver Framework, see "User-Mode Driver Framework (UMDF)"

Figure 6 SideShow Gadget Communication Architecture

Figure 6** SideShow Gadget Communication Architecture **(Click the image for a larger view)

A SideShow gadget application can be written in native code or in managed code. A native application will control the devices that the user has connected it to by using COM components and methods implemented in AuxiliaryDisplayApi.dll. (The original name for SideShow was Auxiliary Display.) This DLL ships with Windows Vista and is guaranteed to be available on every Windows Vista machine; however, it does not function on the Starter and Home Basic versions of Windows Vista. The main goal of the COM components is to abstract away from the developer the fact that different devices are or are not connected and that the devices connected support different capabilities (screen size, color, and so on).

A managed SideShow gadget will control the devices connected to it using types defined in the Microsoft.SideShow namespace. These types are implemented in the Microsoft.SideShow.dll assembly file. (I designed and implemented this for the Windows Vista team and it is downloadable via Microsoft Download Center.) Internally these types talk directly to the COM components in AuxiliaryDisplayApi.dll. Unfortunately, due to some timing issues with the release, the assembly is not guaranteed to exist on all installations of Windows Vista. If you write a managed SideShow gadget using this assembly, you will have to ensure that this DLL gets on to the end user's machine.

To help developers test their gadget code, the Windows Vista SDK ships with a SideShow Simulator application. This application runs on Windows Vista and emulates a SideShow hardware device. To get the simulator working, you must first run the following from a command prompt:

WindowsSideShowVirtualDevice.exe /regserver

This registers the COM components required by the simulator. You only need to register the COM components once on a machine. Then, whenever you want to test your gadget, you run the VirtualSideShow.exe app that also comes with the SDK.

The Microsoft.SideShow.dll assembly defines a number of types in the Microsoft.SideShow and the Microsoft.SideShow.SimpleContentFormat namespaces, making it easy to build SideShow gadgets or to integrate SideShow functionality into an already existing application. The most important and most-used classes are described in Figure 7.

Figure 7 Important SideShow-Related Classes

Class Description
GadgetRegistration A static class to aid in setting up the gadget in the registry.
SideShowGadget An abstract base class representing a connection between application code and one or more SideShow hardware devices that the user has connected. This class is derived from Component, allowing it to be dropped on a Windows Form.
ScfSideShowGadget Derived from SideShowGadget, this class allows the application to send Simple Content Format (SCF) XML strings and images down to a SideShow device.
Scf A static class offering static methods, making it easy to create SCF XML strings in source code.
DeviceCapabilities An object of this class represents a hardware device's capabilities. This can be used by a gadget application to fine-tune the data it chooses to send to a device.

Gadget Installation

When developing a SideShow gadget, you must first create a GUID for it; this becomes the gadget's ID and Windows Vista uses this ID to interact with the gadget. When you install a gadget, your setup program should create a new registry subkey based on the GUID you've created for your gadget:

HKEY_CURRENT_USER\SOFTWARE\Microsoft\SideShow\Gadgets\{<GUID>}

If you want to install the gadget for all users on the machine, use HKEY_LOCAL_MACHINE instead of HKEY_CURRENT_USER. Under this registry subkey you then need to add a few registry values, as described in Figure 8.

Figure 8 Registry Values for Gadget Installation

Registry Value Description
Icon The path of the file (and optional Win32® icon resource ID number) that refers to an icon that should appear in Control Panel and on the device itself. If not specified, a default icon is shown. It is recommended that you supply 16x16, 32x32, and 48x48 pixel images using 32-bit color (with alpha channel).
FriendlyName A string, or a pathname and Win32 string resource ID (for a localized string), that should appear as the name of the gadget in Control Panel. If you don't provide this, no string will be shown to the user.
StartCommand The path of the executable file containing the gadget's code. Windows Vista uses this to invoke the application automatically when a user logs on, during fast user switches, when the computer resumes from sleep, or when the user enables a gadget for a device. (There is very little intelligence here; Windows Vista invokes gadget applications fairly frequently,so gadget applications should be kept small. Furthermore, a gadget application should terminate itself if another instance of it is already running or when no devices are connected to it.)
Endpoints The list of supported endpoints, which can be either iCal format or SCF. iCal (see www.ietf.org/rfc/rfc2445.txt) is a text representation designed for publishing calendar information. The Office Outlook 2007 Calendar gadget uses this endpoint to send iCal data to a SideShow device, allowing the device to render the user's calendar data. Few gadgets and devices support the iCal endpoint. In contrast, SCF is a series of XML content pages that reference each other. Since most applications will use the SCF format, it is the focus of this article.
CacheAlgorithm This value gives a hint to the device as to how the gadget would like its content managed (devices tend to have very limited cache memory and many gadgets could be connected to a single device). The gadget can tell the device to keep newest items (0, the default), keep oldest items (1), keep frequently accessed items (2), or keep recently accessed items (4).
OnlineOnly If the value is 1, the user can only work with the gadget on the device if Windows is running and if the gadget application is also running.
PropertyPage A gadget can offer a configuration settings dialog box to its users that can be launched via the Windows Control Panel. To do this, the gadget must define a COM component that implements the IPropertyPage interface. Then, during setup, the gadget would add this registry value indicating the GUID of the COM component. If specified, Control Panel will underline the gadget application, allowing the user to click it to invoke the gadget's configuration dialog box.

Your gadget's setup program should create its own registry subkey and set any of the registry values it desires. Typically, an installation program will place these registry additions in a .reg file and invoke this file upon application setup. When setup is near completion, you should execute the following command, which will cause Windows Vista to display a tooltip alerting the user that your gadget application has been installed:

SchTasks.exe /run /tn Microsoft\Windows\SideShow\GadgetManager

The GadgetManager task will not show the tooltip if no devices are installed, if it detects that no new gadgets have been installed since it ran last, or if the user turned it off by unchecking the "Notify me when new gadgets are installed" checkbox (see Figure 3).

Once the gadget is installed, users can open Control Panel to configure the gadget and connect it to whatever hardware devices they desire. For security reasons, however, by default a newly installed gadget is not allowed to communicate with any devices.

When a gadget is running, it usually sends data to its connected devices periodically. This way, when the user turns off the computer, the devices have cached some data, making it available whenever the user wants it without having to power up the computer. While a gadget is running, it will receive notifications from Windows indicating when the user has added or removed a device from the gadget via the control panel.

A gadget can also be marked as online-only, meaning that the user can only interact with the gadget on the device if both the computer and the gadget on Windows are running. If the computer is sleeping or in hibernation when the user enters this gadget on the device, the device asks the user whether the computer should be turned on. If the user responds yes, the computer powers up. When the computer is running and the user is logged in, the device enters the gadget. If the computer is in full shutdown, the device tells the user to manually power up the computer and log in, which allows the gadget to be entered on the device.

Device Cache Management

Since devices will have limited amounts of cache memory and users can have several gadgets connected to a single device, devices need to manage memory efficiently. Different devices handle this in various ways, but I'll explain how it works for devices using the Microsoft firmware.

The current Microsoft firmware divides the memory on the device equally among all the gadgets connected to the device. So if three gadgets are connected to a device, then each gadget is guaranteed to get a third of the memory. Individual gadgets are allowed to use more than their portion if other gadgets are using less than their portion. If a gadget that is under its minimum wants more memory, it can take that memory from any gadget that is over its minimum.

Similarly, if a gadget that is over its minimum wants more memory, it can take memory away from the lowest-priority gadget that is over its minimum. In Figure 3, you'll notice that there is an option allowing the user to change the order in which gadgets appear. Gadgets that the user puts at the top are high priority and are likely to get more memory; gadgets towards the bottom are lower priority and have memory taken away from them more quickly. When a gadget has memory taken away from it, the device uses the cache policy set by the gadget via its CacheAlgorithm registry value.

For gadget developers, the important thing to realize is that there is no guarantee that any content pushed down to the device will actually remain on it. If the user wants to examine content that has been purged, the device must notify the gadget on Windows so that it can push down the discarded content again. If the gadget does not send the missing content within an acceptable timeframe (which varies by device—on the simulator it is three seconds), then the device will notify the user that the content is missing. Unlike the native SideShow API, the managed SideShow library caches all content on Windows and will automatically send it back to the device as long as the gadget process stays up and running on Windows Vista.

Gadget Lifetime

Windows must be running a gadget in order for the gadget to download information to a SideShow device. There are basically two kinds of gadgets: UI gadgets and non-UI gadgets. A UI gadget is an application the user runs and interacts with. For example, imagine a Windows Forms application that the user invokes via Windows Explorer. As the user manipulates the application, it can download data to the device. If the user terminates the application, the information remains on the device and can be accessed when the computer is turned off. The lifetime of this application is determined completely by the user. The Microsoft Office Outlook 2007 gadget is an example of a UI gadget.

A non-UI gadget doesn't show any user interface at all. It runs in the background, perhaps monitoring something, and periodically sends data to the device, allowing the data to be viewed when the computer is turned off. To allow the user to remain unaware of non-UI gadgets, Windows offers a mechanism that can automatically invoke non-UI gadgets without the user being involved. Whenever the user logs onto his account, resumes the computer from a sleep state, or uses the SideShow control panel applet to connect or disconnect a device from a gadget, Windows automatically invokes all gadgets present in the registry by executing their StartCommand registry values.

Windows doesn't employ any sophisticated algorithm here; it simply invokes all the registered gadgets. This means that a gadget application could already be running and if the user connects or disconnects a device, Windows will simply run the application again. For this reason, non-UI gadgets should immediately check whether another instance is currently running and, if so, additional instances should just kill themselves. Also, a non-UI gadget would normally terminate itself when the user has disconnected all devices from it. See the Events section later in this article for more about this.

UI gadgets may also want to ensure that only one instance is executing to prevent each application from clobbering data sent to the device by another instance. Furthermore, you typically do not want Windows to invoke UI gadgets automatically (as the UI would appear) and therefore, most UI gadgets should not have a StartCommand registry value at all.

Content

All gadgets push content down to a device. The device has a home display that shows all the gadgets that are connected to the device. In Figure 9, the upper-left image shows a sample home screen. As you can see, each gadget appears with an icon, a name, and optionally some text. The icon and name come from the Icon and FriendlyName registry values. The text shown here is called the glance content and is sent from the gadget to the device by calling SideShowGadget's AddGlanceContent method when the gadget is running.

Navigating through Gadget Screens

Figure 9a Device Home Page

Figure 9a** Device Home Page **(Click the image for a larger view)

Figure 9b Gadget Home Page (Content ID 1)

Figure 9b** Gadget Home Page (Content ID 1) **(Click the image for a larger view)

Figure 9c** Text Page (Content ID 2) **(Click the image for a larger view)

Figure 9d** Image Page (Content ID 3 Showing Image (Content ID 1000) **(Click the image for a larger view)

When the user enters the gadget on the device, the device renders the content previously downloaded from the gadget while it was running on Windows. Currently, SideShow supports two different kinds of content: Simple Content Format (SCF) and iCal; the latter is not discussed in this article. SCF content is a set of XML strings sent from the gadget application to the device. The device parses the XML strings in order to render the content on the device.

The new SCF format allows the gadget application to define three types of content: text and images, menus and context menus consisting of items that initiate navigation to other content, and dialogs that present the user with questions resulting in navigation to other content. Details about the SCF XML schema can be found at msdn.microsoft.com/ms744133.aspx.

The managed SideShow assembly (Microsoft.SideShow.dll) includes a public, static Scf class that contains a bunch of static methods allowing you to create the XML string in code easily. The DownloadDataToDevices method, shown in Figure 10, demonstrates how to open an ScfSideShowGadget and send glance string content. The sample also shows how to call ScfSideShowGadget's AddContent method to send SCF menu, SCF text, and SCF image content down to a device. As you can see, each piece of content is identified by a content ID number. The first page of the gadget (the lower-left image in Figure 9) is its home page which always has a content ID of 1 (represented by the ScfSideShowGadget's HomePageContentId constant). When the user selects the See Text menu item, the device will navigate to the content page with an ID of 2 and when the user selects the "See Image" menu item, the device will navigate to the content page with an ID of 3. Page 3, the Image page, contains XML describing how the image should be shown (centered and auto fitting). This page also refers to the actual image, which I've assigned a content ID of 1000. In my code, I've extracted the image from an assembly resource.

Figure 10 DownloadDataToDevices Method

private static void DownloadDataToDevices() {
   // Construct a SCF SideShow gadget for our gadget's Guid
   using (ScfSideShowGadget gadget = new ScfSideShowGadget(s_gadgetId)) 
   {
      // Add Glance content showing date/time of last update
      gadget.AddGlanceContent(
         String.Format("Content updated on {0}{1:D}.", 
            Environment.NewLine, DateTime.Now));

      // The home page is a menu with an item that goes to some 
      // text and another item that goes to an image
      gadget.AddContent(
         Scf.Menu(ScfSideShowGadget.HomePageContentId, 
            "Simple Gadget Menu", ScfSelectAction.Target,
            Scf.Item(2, "See text"), Scf.Item(3, "See image")));

      // This is the text page
      gadget.AddContent(
         Scf.Content(2, "This is the Text Page",
            Scf.Txt(ScfAlign.Left, true, Color.Red, 
               "This is some text")));

      // This is the image page
      gadget.AddContent(
         Scf.Content(3, "This is the Image Page",
            Scf.Img(1000, ScfAlign.Center, ScfImageFit.Auto, 
               "alt picture text")));

      // This is the image itself (that appears on the image page)
      Stream imageStream = Assembly.GetEntryAssembly().
         GetManifestResourceStream(
            "SimpleSideShowGadget.Aidan And Jeff.jpg"); 
      gadget.AddContent(1000, ImageContentTransforms.ReduceColorDepth | 
         ImageContentTransforms.StretchToFit,
         Image.FromStream(imageStream));
   }
}

Capabilities, Events, and Notifications

A gadget application can query Windows, asking it how many devices are connected to it and what the capabilities are of these devices. Examples of capabilities include DeviceId, ScreenType (Bitmap or Text), ScreenWidth, ScreenHeight, ClientAreaWidth, ClientAreaHeight, ColorDepth, and SupportedImageFormats.

A gadget application could use the device capabilities when deciding what content to push down to a device. The sample application associated with this article demonstrates how a gadget application can query the number of devices connected to it and can also query the capabilities of these devices.

When running, a gadget application can receive events (described in Figure 11) from a device by registering with several events. The SideShowGadget type (the base class of the all gadget types) offers events that apply to all gadgets regardless of endpoint. The ScfSideShowGadget type (derived from SideShowGadget) offers additional events specific to the SCF gadget endpoint. An application can respond to these events in order to add or remove content. A sophisticated gadget may require that it always be executing in order to properly respond to these events. If this is required, the gadget should set its OnlineOnly registry value to 1.

Figure 11 Device Events to which Your Gadget Can Respond

Event Description
DeviceAdded Raised when the user connects a device to the gadget application. The receiving method is passed the device capabilities of the device.
DeviceRemoved Raised when the user disconnects a device from the gadget application. The receiving method is passed the device capabilities of the device.
AllDevicesRemoved Raised when the user has disconnected all devices from a gadget. Usually a non-UI gadget will terminate itself when it receives this event.
ContentMissing Raised when the user attempts to navigate to content on the device that is missing. The receiving method is passed the ID of the missing content. As mentioned previously, the managed wrapper saves all content in a collection. If a device discards content due to the gadget's caching policy (as set by its CacheAlgorithm registry value), then the managed wrapper automatically sends the content back to the device and your code will not receive this event. This is one of the big benefits of using the managed API over the native API.
GadgetEnter Raised when the user enters the gadget on the device.
GadgetExit Raised when the user exits the gadget on the device.
ContentNavigate For SCF gadgets only. Raised when the user navigates from one content page to another. The receiving method is passed the previous page ID, the target page ID, and the button that caused the navigation to occur.
MenuSelect For SCF gadgets only. Raised when the user selects an item from a menu. The receiving method is passed the previous page ID, the target page ID, the menu item ID, and the button that caused the menu selection to occur.
ContextMenuSelect For SCF gadgets only. Raised when the user selects an item from a context menu. The receiving method is passed the previous page ID, the target page ID, the previous item ID, the menu page ID, and the menu item ID.

When running, a gadget can send a notification to a SideShow device by calling SideShowGadget's ShowNotification method. A gadget application would show a notification for things such as meeting reminders, e-mail alerts, an incoming instant message, or system alerts. A notification is similar to a message box except that it appears on the hardware device. A notification consists of an ID number, an icon, a string caption, a string message, and an expiration time. The device will then show the notification until it is dismissed by the user or until the expiration time has elapsed. An application can also revoke a notification by calling SideShowGadget's RevokeNotification method passing it the notification's ID number.

Conclusion

In this article, I have covered the goals of the Windows SideShow feature and explained in depth how an end user interacts and configures the gadget. I've also shown how developers can integrate SideShow support into their new or existing managed applications. By using these managed wrappers, you should easily be able to integrate SideShow functionality into your own applications.

Personally, I find the new Windows SideShow feature very exciting as it offers new ways for users to access and interact with their data. I expect a slew of new hardware devices that support SideShow to become available in the next few years. In particular, I can't wait until Media Center remote controls and mobile phones support SideShow. It shouldn't take long for these incredibly useful devices to be as commonplace as a PDA or a cell phone.

Jeffrey Richter is a cofounder of Wintellect (www.Wintellect.com), a training and consulting firm. He is the author of several books, including CLR via C# (Microsoft Press, 2006). Jeffrey is also a contributing editor to MSDN Magazine and has been consulting with Microsoft since 1990.