For instructions on deploying the sample, please read .NET Sample guides.
This sample illustrates the usage of Coherent UI in a XNA/MonoGame application. The application code is largely the same for both platforms, with exceptions for content loading and input handling, which will be discussed shortly.
The sample is composed of the following files:
Game1.cs - contains the game logic.
InputHandling.cs (used with either Input_Windows.cs or Input_Linux.cs for XNA/MonoGame respectively) - utilities for converting SlimDX supplied input events to Coherent events.
Listeners.cs - classes providing handlers for Coherent UI callbacks
A detailed description of each file follows.
The Game1 class contains the game logic - initialization, content loading, updating and drawing.
In the initialization step the view context and the Input system are initialized normally.
ContextListener class passed as parameter to the view context is saved to a member variable, because the if it wasn't it would be garbage collected and the system would throw an exception. This is valid for the ViewListener as well.In the Update method we update the view context and the Input system. This is where we poll the UI context listener for readiness so we know we can create a View.The view can only be created using shared memory (UsesSharedMemory = true;) because XNA doesn't support shared textures.
The Draw method fetches the composited surfaces from Coherent UI and stretches the texture on the whole window.
This file contains methods for converting KeyEventArgs / MouseEventArgs to Coherent UI events. Some non-essential fields for key/mouse states have been left out (such as IsCapsOn, IsNumLockOn, IsNumPad, IsAutoRepeat) because of platform differences.
The code that actually converts platform specific events to KeyEventArgs / MouseEventArgs is in the Input_Linux.cs and Input_Windows.cs files.
You'll find the ContextListener and MyViewListener classes here.
The ContextListener class is the view context listener, which serves the purpose to notify the user when the view context is ready to operate.
The MyViewListener class is what handles the important events for drawing. Since XNA does not shared textures, we can only use the shared memory transport mechanism.
The ViewListener subscribes for the DrawMemory event and the event handler sets the texture data to the received pixels array. To do that we use the SetData method (and unbind the texture from the graphics device beforehand, because SetData requires it).
There is one other manipulation that we must do before setting the data - swap the red and blue channels of the pixels, because the SurfaceFormat.Color format doesn't match with the one of the array (and there are no other RGBA formats supported by XNA). This is done in an unsafe code block to speed up the operation, since otherwise the runtime does a bounds check which slows down execution.