Jair Cazarin Villanueva jair.cazarin@gmail.com http://jaircazarin.spaces.live.

com

Multiples ratones para computadoras: MS Multipoint
Hola bienvenidos, este es uno de varios artículos técnicos que pretendo escribir acerca de las nuevas tecnologías que Microsoft está ofreciendo, básicamente con el objetivo de hacerle la vida más fácil a los desarrolladores, ya que aparte de mostrar las bondades de la tecnología también quiero mostrar código base ejemplo. En esta ocasión vamos a hablar acerca de una tecnología desarrollada en la India por parte de Microsoft Research, llamada Microsoft Multipoint [1] y que fue anunciada fuertemente en el concurso Imagine Cup [2], en donde animaron a todos los equipos a desarrollar tecnología que usara Multipoint. Vivimos en una época dónde el poder de cómputo, la cantidad de computadoras por pesona, la velocidad de la Internet, ha aumentado casi exponencialmente, sin embargo, todavía existen comunidades en muchos países, dónde no existe toda esta tecnología y para ellos les es imposible poder comprarla dada sus condiciones. Es por eso que nacen proyectos como “One Laptop per Child” [3] dónde el objetivo es proveer computadoras muy baratas a los niños que viven en países en desarrollo. Y Aunque OLPC (One laptop per child) es una muy buena idea, sigue teniendo varios contras. Por lo tanto Microsoft, anuncia una tecnología que sigue el mismo principio pero de una manera más inteligente: Microsoft Multipoint. Y aunque MS Multipoint no es necesariamente una alternativa a OLPC, es una interesante y simple solución a la problemática de falta de computadoras en escuelas, principalmente en países en vías de desarrollo. (También podría ser muy interesante el hecho de combinar ambas tecnologías, aunque se necesitaría bastante trabajo, ya que MS Multipoint es desarrollado en .net 3.0 [4] y OLPC corre un sistema operativo basado en Linux). ¿Pero que es exactamente Multipoint? Multipoint es un software que permite tener multiples cursores en diferentes colores coexistiendo en un mismo monitor. Lo cuál permite que múltiples estudiantes accesen a una computadora interactivamente al mismo tiempo, solo usando diferentes periféricos.

En un principio esto puede sonar muy extraño, ¿Como es que multiples estudiantes podrán usar la misma computadora al mismo tiempo, sin perder el control? Pero las investigaciones de Microsoft, y sus distintos papers [5] demostaron que grupos de hasta 5 niños se adaptaron totalmente a la tecnología. También Microsoft ha desarrollado ciertas aplicaciones que complementan esta tecnología, como lo son algunos juegos educativos, que permiten a los estudiantes aprender colaborativamente, de una forma rápida y divertida, sin necesidad de demasiados recursos. En este caso pienso que esta es una tecnología muy innovadora pero muy sencilla, que será una herramienta fundamental principalmente para países en desarrollo, que sufren de falta de computadoras, pero también es importante para todo lo que conlleva a la educación, y el desarrollo de nuevas herramientas educativas colaborativas para niños que se pueden crear, y que el mismo Microsoft sugiere como una nueva área de

investigación para la pedagogía (computers in education). Todo esto de Multipoint nace de un área de investigación que se conoce como Single Display Groupware [6] que básicamente es el hecho de tener a un grupo de personas interactuando con un solo dispositivo. Actualmente Windows en varios de sus sabores soportaba tener múltiples dispositivos (mice) pero no con múltiples cursores. La implementación se basa en el hecho de que el la arquitectura de Windows está divido en 2 partes principalmente:

Kernel Mode User Mode

Básicamente la primera parte Kernel Mode, lo componen el sistema operativo en si, y los drivers para todo el hardware, la segunda está compuesta por todas las aplicaciones. Pero ¿Qué sucede cuando se conecta un mouse a una computadora?:

Stack

Driver 2 Driver 1 - delta x - delta y - Unique ID for each mouse

Win32 API

Lo que sucede es que se cargan los drivers encargados del manejo del mouse en el stack que es parte del Kernel Mode, y surge una interacción entre estos drivers y el Win32 API [7] que se encuentra en el User Mode. La información que regresa el API es la que está en el recuadro naranja, que son los valores de las posiciones x,y y el identificador único del mouse. Microsoft cometió el error de asumir que nadie usaría multiples mouses por lo que la variable Unique ID ha sido ignorada en todas las versiones de Windows. Y es aquí donde entra este grupo de desarrolladores en la India, que encontaron que el RawInput API [8] permite el acceso directo a los ID's del mouse desde el user mode. En el cuál se basaron para desarrollar este toolkit que aunque actualmente todavía tiene problemas, cada vez es más sólido. Para la instalación de este SDK solo basta con descargarlo [9], y cumplir con los siguientes requisitos: Requerimientos de Software:

● ●

Microsoft Visual Studio 2005 [10] .Net Framework 3.0 Runtime Components. [11]

● ●

Visual Studio 2005 extensions for .NET framework 3.0 (WCF & WPF) February 2007 CTP. [12] Windows SDK for Windows Vista. [13]

Requerimientos de Hardware:

● ● ● ● ● ●

Procesador: 400-megahertz Pentium Processor. Sistema Operativo: Microsoft Windows XP SP2 (32-bit only), Microsoft Windows Vista (32-bit only) RAM: 512 MB Disco Duro: Menos de 4mb. Monitor: Super VGA (800x600) Por lo menos 2 ratones USB.

Ahora, pasemos a lo interesante, como crear una aplicación que utilize multiples ratones. Lo primero que debemos hacer es crear un proyecto en nuestro Visual Studio del tipo Windows Application pero con WPF.

Una vez creado el proyecto tendremos creada una solución con un proyecto que contiene 4 archivos. App.xaml, Window1.xaml con sus respectivos .xaml.cs cada uno. El primero es la aplicación principal y Window1 es la ventana que lanzará esta aplicación. Lo primero que haremos será importar las librerias DLL's necesarias. Para esto solo necesitamos ir a la carpeta References en nuestro árbol de archivos, menú contextual, y dar click en la opción “Add Reference”.

En la ventana que salga, tendremos que ir al tab “Browse”, y ahí buscaremos el directorio dónde instalamos Windows Multipoint SDK. Nos colocamos en la carpeta “Bin”, y agregamos los 5 dll's que aparecen ahí:

Una vez que añadimos las librerias al proyecto, ahora podemos hacer uso de las clases y métodos que contiene. Para nuestro propósito crearemos solo un butón y cada que algún ratón de click en este botón aparecera el UniqueID en el textbox. Un programa bastante simple pero que servirá como base para crear cosas más complejas. Lo que sigue, entonces será añadir el namespace al xaml de nuestra ventana. Esto lo haremos colocando la siguiente linea como atributo del tag window en el archivo Window1.xaml: xmlns:mps="clrnamespace:Microsoft.MultiPoint.MultiPointControls;assembly=Microsoft.MultiPoint.MultiPointControls"

Lo siguiente será agregar los 2 widgets, el botón y el textbox. Para esto Multipoint nos provee de 2 nuevos widgets llamados MultiPointButton y MultiPointTextBox. Estos los agregamos dentro del tag Grid. <Grid> <mps:MultiPointButton Content="Click Me" Name="MultiPointTestButton" Margin="93.5,123,110.5,59" /> <mps:MultiPointTextBox Margin="75,82,101,0" Name="MultiPointTestTextBox" Height="23" VerticalAlignment="Top" /> </Grid> Y resultará en algo así:

Con esto ya habremos terminado, lo que respecta a la ventana. El siguiente paso es editar el archivo que contendrá la lógica de nuestro programa, el cuál es Window1.xaml.cs, sin embargo antes debemos crear una instancia del objeto MultiPointSDK en nuestro aplicación principal: App.xaml.cs. Añadimos la siguiente linea: public partial class App : System.Windows.Application { static public MultiPointSDK MultiPointObject = new MultiPointSDK(); public App() { } } Este objeto básicamente se encargará de registrar y dibujar los distintos ratones, digamos que en esta clase se encuentra todo el backend encargado de manejar multiples dispositivos. Para que esto funcione debemos agregar las siguientes librerias:

● ● ●

using Microsoft.MultiPoint.MultiPointSDK; using Microsoft.MultiPoint.MultiPointCommonTypes; using Microsoft.MultiPoint.MultiPointMouseFilter;

Después, nos cambiamos al archivo Window1.xaml.cs, en el cuál escribiremos 2 métodos y 2 delegados. Métodos:

● ●

InitialMultipointSDK: Se encargará de mandar a llamar a los métodos, principalmente del objeto MultiPointSDK que sirven para inicializarlo. InitialCheck: Checará que en realidad hay más de un ratón conectado y les asignará un color. En este caso damos por hecho que solo se conectarán 2 ratones.

Delegados:

● ●

Test_Loaded: Este event handler se encargará de que antes de que la aplicación sea inicializada llamar a los 2 métodos anteriores. MultiPointClick_Handler: Este evento es para el botón, y cachará cada click a él, y luego escribirá en el textbox el UniqueID del ratón que dio el click.

En este caso también debemos agregar las siguientes lineas al inicio del archivo:

● ● ● ●

using Microsoft.MultiPoint.MultiPointCommonTypes; using Microsoft.MultiPoint.MultiPointSDK; using Microsoft.MultiPoint.MultiPointMouseFilter; using Microsoft.MultiPoint.MultiPointControls;

Comenzamos modificando el constructor, añadiendo el delegado al evento Loaded. public partial class Window1 : System.Windows.Window { public Window1() { InitializeComponent(); this.Loaded += new RoutedEventHandler(Test_Loaded); } Despues creamos el delegado Test_Loaded: void Test_Loaded(object sender, RoutedEventArgs args) { try { InitialMultipointSDK(); InitialCheck(); this.MultiPointTestButton.MultiPointClick += new RoutedEventHandler(MultiPointClick_Handler); } catch (MultiPointException e) { Console.WriteLine("Error: " + e.Message); } } En este lo que hacemos es llamar a los métodos encargados de inicializar y customizar, y además sobrecargamos el evento MultiPointClick_Handler, al botón de prueba. Ahora el método InitialMultipointSDK(): private void InitialMultipointSDK() { App.MultiPointObject.SystemCursorPosition = new Point((int)this.Left + 10, (int)this.Top + 10); App.MultiPointObject.RegisterMouseDevice(); MultiPointSDK.HideSystemCursor(); App.MultiPointObject.CurrentWindow = this; App.MultiPointObject.DrawDevice(); } En este caso setteamos la posición de los cursores, asegurándonos que estarán dentro de la ventana, luego con el método RegisterMouseDevice() nos encargaremos de registrar los ratones, sin necesidad de interactuar con el API de Raw Input Device. El método HideSystemCursor se encarga de esconder el puntero del sistema, y luego con la propertie CurrentWindow asignamos la ventana Window1, para que trabaje con estos punteros. Una vez creado este método, pasamos a InitialCheck():

private void InitialCheck() { if (App.MultiPointObject.MouseDeviceList.Count == 1) { Console.WriteLine("Two mice are required to watch the features of MS Multipoint"); return; } ((MultiPointMouseDevice)((DeviceInfo)(App.MultiPointObject.MouseDeviceList[0])).DeviceVi sual).CursorColor = System.Windows.Media.Colors.Green; ((MultiPointMouseDevice)((DeviceInfo)(App.MultiPointObject.MouseDeviceList[0])).DeviceVi sual).CursorColor = System.Windows.Media.Colors.Gold; } En este caso, lo único que hacemos es checar que haya más de un ratón conectado, y despues le asignamos a los 2 primeros colores al cursor. Por último implementamos el delegado MultipointClick_Handler: void MultiPointClick_Handler(object sender, RoutedEventArgs args) { MultiPointMouseEventArgs multipointArgs = (MultiPointMouseEventArgs)args; string id = multipointArgs.DeviceInfo.DeviceID; this.MultiPointTestTextBox.Text = id; } Que lo único que hace es obtener el ID del mouse, y plasmarlo en el textbox. Con esto queda termina la aplicación, sin embargo debemos agregar un archivo más de configuración. App.config (Application Configuration File). Agregando lo siguiente a el: <?xml version="1.0" encoding="utf-8" ?> <configuration> <configSections> <section name="FilterConfigSection" requirePermission="false" type="Microsoft.MultiPoint.MultiPointSDK.FilterConfigSectionHandler,Microsoft.MultiPoint.MultiPointS DK"/> </configSections> <FilterConfigSection> <MouseFilter FilterPath="Microsoft.MultiPoint.MultiPointMouseFilter.dll" SuppressDeviceEvents="true" TimeIntervalForEvents="30" Description="This is Mouse Filter"/> </FilterConfigSection> </configuration> Finalmente, podemos probar nuestro programa (ctrl + F5 o F5 si quieres debuggear), y veremos algo así:

Donde podremos observar los 2 punteros con distintos colores, y cada vez que algún ratón de click en el botón aparecerá su ID.

Cualquier duda, comentario, aclaración a: jair.cazarin@gmail.com Referencia: [1] http://www.microsoft.com/presspass/features/2006/dec06/12-14MultiPoint.mspx [2] http://www.imaginecup.com [3] http://laptop.org/ [4] http://www.netfx3.com [5] http://tier.cs.berkeley.edu/docs/ict4d06/multiple_mice-jp.pdf [6] http://citeseer.ist.psu.edu/stewart99single.html [7] http://en.wikipedia.org/wiki/Win32 [8] http://msdn2.microsoft.com/en-us/library/ms645543.aspx [9] http://msdn.microsoft.com/vstudio [10] http://msdn2.microsoft.com/en-us/windowsvista/aa904955.aspx [11] http://www.microsoft.com/downloads/details.aspx?familyid=F54F5537-CC86-4BF5-AE44-F5A1E805680D [12] www.microsoft.com/downloads/details.aspx?familyid=7614FE22-8A64-4DFB-AA0C-DB53035F40A0