// IUserInterfaceProvider.ReceiveUserIO
 /// <summary>
 /// One of the input subsystems has received a charaaction or mouse. Queue the
 /// processing to delink us from the IO thread.
 /// If a typed char, we use it to update the modifiers (alt, ...) and  then
 /// assemble the keycode or'ed with the current modifers into this.LastKeyCode.
 /// Then, anyone waiting is given a callback.
 /// </summary>
 /// <param name="type"></param>
 /// <param name="param1"></param>
 /// <param name="param2"></param>
 /// <param name="param3"></param>
 public void ReceiveUserIO(ReceiveUserIOInputEventTypeCode type, int param1, float param2, float param3) {
     Object[] receiveLaterParams = { type, param1, param2, param3 };
     m_workQueue.DoLater(ReceiveLater, receiveLaterParams);
     return;
 }
 // IUserInterfaceProvider.ReceiveUserIO
 // The codes that come in from Ogre need to be converted into System.Windows.Forms coded
 // Do this and then pass the codes to the common routine
 public void ReceiveUserIO(ReceiveUserIOInputEventTypeCode typ, int param1, float param2, float param3) {
     switch (typ) {
         case ReceiveUserIOInputEventTypeCode.KeyPress:
             m_log.Log(LogLevel.DRENDERDETAIL, "ReceiveUserIO: Key pressed: {0} -> {1}", param1, ConvertScanCodeModifiers(param1));
             m_ui.ReceiveUserIO(typ, ConvertScanCodeModifiers(param1), param2, param3);
             break;
         case ReceiveUserIOInputEventTypeCode.KeyRelease:
             m_log.Log(LogLevel.DRENDERDETAIL, "ReceiveUserIO: Key released: {0} -> {1}", param1, ConvertScanCodeModifiers(param1));
             m_ui.ReceiveUserIO(typ, ConvertScanCodeModifiers(param1), param2, param3);
             break;
         case ReceiveUserIOInputEventTypeCode.MouseButtonDown:
             m_ui.ReceiveUserIO(typ, ConvertMouseCode(param1), param2, param3);
             break;
         case ReceiveUserIOInputEventTypeCode.MouseButtonUp:
             m_ui.ReceiveUserIO(typ, ConvertMouseCode(param1), param2, param3);
             break;
         case ReceiveUserIOInputEventTypeCode.MouseMove:
             m_ui.ReceiveUserIO(typ, param1, param2, param3);
             break;
     }
 }