マウスカーソル位置取得のバグ修正

yaneSDK4Csについてのバグレポートをいただいたので調査。

[ DllImport(DLL_SDL) ]
public static extern Uint8 SDL_GetMouseState(/* int * */out int x, /* int * */out int y);

SDL_GetMouseStateが期待通りの値を返してくれないのが原因でした。マウスを素早く動かすとカーソルがスクリーンの左上にあっても(0, 0)を返してくれません。SDLはイベントドリブンが望まれる使い方だと思うので、ループまわしてポーリングするよーなのが良くないのかも知れません。しかし、ライブラリを変更するのもしんどいのでWin32APIで逃げることにしました。

/**
 * マウスの現在位置を正しく取得できないため、Win32APIを使用
 */
public static void GetMouseState(out int x, out int y) 
{
  GetMouseStateImpl(out x, out y);
}
#if LINUX
private static void GetMouseStateImpl(out int x, out int y) {
  SDL_GetMouseState(out x, out y);
}
#else
private struct Point 
{
  public int x;
  public int y;
}

[DllImport("user32")]
private static extern int GetCursorPos(ref Point pt);

[DllImport("user32")]
private static extern int ScreenToClient(IntPtr hwnd, ref Point pt);

unsafe private static void GetMouseStateImpl(out int x, out int y) 
{
  Point pt = new Point();
  GetCursorPos(ref pt);
  SDL.SDL_SysWMinfo* pinfo = stackalloc SDL.SDL_SysWMinfo[1];
  SDL.SDL_GetWMInfo((IntPtr)(pinfo) );
  ScreenToClient(pinfo->window, ref pt);

  x = pt.x;
  y = pt.y;

  if (x < 0)
    x = 0;
  else if (x > 639)
    x = 639;

  if (y < 0)
    y = 0;
  else if (y > 479)
    y = 479;
}
#endif

Linux側で同様の問題が起こるかは分からないので、とりあえずそのままにしています。