/// <summary>
    /// This function can be used to call a callback within the context of the message processing thread.
    /// The function waits until the message thread has picked up and executed the callback.
    /// This function is also safe if the current thread is the message processing thread.
    /// </summary>
    /// <param name="callback">Callback to be executed</param>
    /// <param name="param1">Param to callback</param>
    /// <param name="param2">Param to callback</param>
    /// <param name="data">Param to callback</param>
    /// <returns>Return value of callback( param1, param2, data )</returns>
    public static int SendThreadCallbackAndWait(Callback callback, int param1, int param2, object data)
    {
      CallbackEnv env = new CallbackEnv();
      env.callback = callback;
      env.param1 = param1;
      env.param2 = param2;
      env.data = data;

      GUIMessage msg = new GUIMessage(GUIMessage.MessageType.GUI_MSG_CALLBACK, 0, 0, 0, 0, 0, env);
      SendThreadMessage(msg);

      // if this is the main thread, then dispatch the messages
      if (Thread.CurrentThread.Name == "MPMain")
      {
        DispatchThreadMessages();
      }

      env.finished.WaitOne();

      return env.result;
    }
    public static void SendThreadCallback(Callback callback, int param1, int param2, object data)
    {
      CallbackEnv env = new CallbackEnv();
      env.callback = callback;
      env.param1 = param1;
      env.param2 = param2;
      env.data = data;

      GUIMessage msg = new GUIMessage(GUIMessage.MessageType.GUI_MSG_CALLBACK, 0, 0, 0, 0, 0, env);
      SendThreadMessage(msg);
    }
    public static void SendThreadCallback(Callback callback, int param1, int param2, object data)
    {
      CallbackEnv env = new CallbackEnv();
      env.callback = callback;
      env.param1 = param1;
      env.param2 = param2;
      env.data = data;

      GUIMessage msg = new GUIMessage(GUIMessage.MessageType.GUI_MSG_CALLBACK, 0, 0, 0, 0, 0, env);
      SendThreadMessage(msg);

      // if this is the main thread, then dispatch the messages
      if (Thread.CurrentThread.Name == "MPMain" || Thread.CurrentThread.Name == "Config Main")
      {
        DispatchThreadMessages();
      }
    }