00001 #region --- License ---
00002
00003
00004
00005 #endregion
00006
00007 using System;
00008 using System.Collections.Generic;
00009 using System.Text;
00010 using System.Windows.Forms;
00011
00012 using OpenTK.Input;
00013 using System.Diagnostics;
00014 using System.Drawing;
00015
00016 namespace OpenTK.Platform.Windows
00017 {
00018
00019 sealed class WMInput : System.Windows.Forms.NativeWindow, IInputDriver
00020 {
00021 #region --- Fields ---
00022
00023 WinMMJoystick joystick_driver = new WinMMJoystick();
00024
00025 KeyboardDevice keyboard = new KeyboardDevice();
00026 MouseDevice mouse = new MouseDevice();
00027 IList<KeyboardDevice> keyboards = new List<KeyboardDevice>(1);
00028 IList<MouseDevice> mice = new List<MouseDevice>(1);
00029 internal static readonly WinKeyMap KeyMap = new WinKeyMap();
00030
00031 const long ExtendedBit = 1 << 24;
00032
00033 static readonly uint ShiftRightScanCode = Functions.MapVirtualKey(VirtualKeys.RSHIFT, 0);
00034
00035 #endregion
00036
00037 #region --- Constructor ---
00038
00039 public WMInput(WinWindowInfo parent)
00040 {
00041 Debug.WriteLine("Initalizing WMInput driver.");
00042 Debug.Indent();
00043
00044 AssignHandle(parent.WindowHandle);
00045 Debug.Print("Input window attached to parent {0}", parent);
00046
00047 Debug.Unindent();
00048
00049 keyboard.Description = "Standard Windows keyboard";
00050 keyboard.NumberOfFunctionKeys = 12;
00051 keyboard.NumberOfKeys = 101;
00052 keyboard.NumberOfLeds = 3;
00053
00054 mouse.Description = "Standard Windows mouse";
00055 mouse.NumberOfButtons = 3;
00056 mouse.NumberOfWheels = 1;
00057
00058 keyboards.Add(keyboard);
00059 mice.Add(mouse);
00060 }
00061
00062 #endregion
00063
00064 #region protected override void WndProc(ref Message msg)
00065
00066 bool mouse_about_to_enter = false;
00067 protected override void WndProc(ref Message msg)
00068 {
00069 UIntPtr lparam, wparam;
00070 unsafe
00071 {
00072 lparam = (UIntPtr)(void*)msg.LParam;
00073 wparam = (UIntPtr)(void*)msg.WParam;
00074 }
00075
00076 switch ((WindowMessage)msg.Msg)
00077 {
00078
00079 case WindowMessage.NCMOUSEMOVE:
00080 mouse_about_to_enter = true;
00081 break;
00082
00083 case WindowMessage.MOUSEMOVE:
00084 mouse.Position = new Point(
00085 (int)(lparam.ToUInt32() & 0x0000FFFF),
00086 (int)(lparam.ToUInt32() & 0xFFFF0000) >> 16);
00087 if (mouse_about_to_enter)
00088 {
00089 Cursor.Current = Cursors.Default;
00090 mouse_about_to_enter = false;
00091 }
00092 return;
00093
00094 case WindowMessage.MOUSEWHEEL:
00095
00096
00097 mouse.Wheel += (int)((long)msg.WParam << 32 >> 48) / 120;
00098 return;
00099
00100 case WindowMessage.LBUTTONDOWN:
00101 mouse[MouseButton.Left] = true;
00102 return;
00103
00104 case WindowMessage.MBUTTONDOWN:
00105 mouse[MouseButton.Middle] = true;
00106 return;
00107
00108 case WindowMessage.RBUTTONDOWN:
00109 mouse[MouseButton.Right] = true;
00110 return;
00111
00112 case WindowMessage.XBUTTONDOWN:
00113 mouse[((wparam.ToUInt32() & 0xFFFF0000) >> 16) != (int)MouseKeys.XButton1 ? MouseButton.Button1 : MouseButton.Button2] = true;
00114 return;
00115
00116 case WindowMessage.LBUTTONUP:
00117 mouse[MouseButton.Left] = false;
00118 return;
00119
00120 case WindowMessage.MBUTTONUP:
00121 mouse[MouseButton.Middle] = false;
00122 return;
00123
00124 case WindowMessage.RBUTTONUP:
00125 mouse[MouseButton.Right] = false;
00126 return;
00127
00128 case WindowMessage.XBUTTONUP:
00129
00130 mouse[((wparam.ToUInt32() & 0xFFFF0000) >> 16) != (int)MouseKeys.XButton1 ? MouseButton.Button1 : MouseButton.Button2] = false;
00131 return;
00132
00133
00134 case WindowMessage.KEYDOWN:
00135 case WindowMessage.KEYUP:
00136 case WindowMessage.SYSKEYDOWN:
00137 case WindowMessage.SYSKEYUP:
00138 bool pressed = (WindowMessage)msg.Msg == WindowMessage.KEYDOWN ||
00139 (WindowMessage)msg.Msg == WindowMessage.SYSKEYDOWN;
00140
00141
00142
00143
00144
00145
00146
00147
00148 bool extended = (msg.LParam.ToInt64() & ExtendedBit) != 0;
00149 switch ((VirtualKeys)wparam)
00150 {
00151 case VirtualKeys.SHIFT:
00152
00153
00154
00155
00156
00157
00158
00159 if (ShiftRightScanCode != 0)
00160 {
00161 unchecked
00162 {
00163 if (((lparam.ToUInt32() >> 16) & 0xFF) == ShiftRightScanCode)
00164 keyboard[Input.Key.ShiftRight] = pressed;
00165 else
00166 keyboard[Input.Key.ShiftLeft] = pressed;
00167 }
00168 }
00169 else
00170 {
00171
00172 keyboard[Input.Key.ShiftLeft] = pressed;
00173 }
00174 return;
00175
00176 case VirtualKeys.CONTROL:
00177 if (extended)
00178 keyboard[Input.Key.ControlRight] = pressed;
00179 else
00180 keyboard[Input.Key.ControlLeft] = pressed;
00181 return;
00182
00183 case VirtualKeys.MENU:
00184 if (extended)
00185 keyboard[Input.Key.AltRight] = pressed;
00186 else
00187 keyboard[Input.Key.AltLeft] = pressed;
00188 return;
00189
00190 case VirtualKeys.RETURN:
00191 if (extended)
00192 keyboard[Key.KeypadEnter] = pressed;
00193 else
00194 keyboard[Key.Enter] = pressed;
00195 return;
00196
00197 default:
00198 if (!WMInput.KeyMap.ContainsKey((VirtualKeys)msg.WParam))
00199 {
00200 Debug.Print("Virtual key {0} ({1}) not mapped.", (VirtualKeys)msg.WParam, (int)msg.WParam);
00201 break;
00202 }
00203 else
00204 {
00205 keyboard[WMInput.KeyMap[(VirtualKeys)msg.WParam]] = pressed;
00206 return;
00207 }
00208 }
00209 break;
00210
00211 case WindowMessage.KILLFOCUS:
00212 keyboard.ClearKeys();
00213 break;
00214
00215 case WindowMessage.DESTROY:
00216 Debug.Print("Input window detached from parent {0}.", Handle);
00217 ReleaseHandle();
00218 break;
00219
00220 case WindowMessage.QUIT:
00221 Debug.WriteLine("Input window quit.");
00222 this.Dispose();
00223 break;
00224 }
00225
00226 base.WndProc(ref msg);
00227 }
00228
00229 #endregion
00230
00231 #region --- IInputDriver Members ---
00232
00233 #region IInputDriver Members
00234
00235 public void Poll()
00236 {
00237 joystick_driver.Poll();
00238 }
00239
00240 #endregion
00241
00242 #region IKeyboardDriver Members
00243
00244 public IList<KeyboardDevice> Keyboard
00245 {
00246 get { return keyboards; }
00247 }
00248
00249 #endregion
00250
00251 #region IMouseDriver Members
00252
00253 public IList<MouseDevice> Mouse
00254 {
00255 get { return mice; }
00256 }
00257
00258 #endregion
00259
00260 #region IJoystickDriver Members
00261
00262 public IList<JoystickDevice> Joysticks
00263 {
00264 get { return joystick_driver.Joysticks; }
00265 }
00266
00267 #endregion
00268
00269 #endregion
00270
00271 #region --- IDisposable Members ---
00272
00273 private bool disposed;
00274
00275 public void Dispose()
00276 {
00277 Dispose(true);
00278 GC.SuppressFinalize(this);
00279 }
00280
00281 private void Dispose(bool manual)
00282 {
00283 if (!disposed)
00284 {
00285 if (manual)
00286 this.ReleaseHandle();
00287
00288 disposed = true;
00289 }
00290 }
00291
00292 ~WMInput()
00293 {
00294 Dispose(false);
00295 }
00296
00297 #endregion
00298 }
00299 }