* X11KeyMap.cs: Added AltGr keycode.
* X11Mouse.cs: Use XQueryPointer instead of trying to hook events. * X11Keyboard.cs: Improved handling of key modifiers. * X11Factory.cs: Use new X11Mouse API. * Functions.cs: Added XButtonGrab/XButtonUngrab. * API.cs: Added missing XF86 keysyms.
This commit is contained in:
parent
7e344e2ac2
commit
b646cfa06c
6 changed files with 154 additions and 112 deletions
|
@ -1142,6 +1142,8 @@ XF86VidModeGetGammaRampSize(
|
|||
Hyper_L = 0xffed, /* Left hyper */
|
||||
Hyper_R = 0xffee, /* Right hyper */
|
||||
|
||||
ISO_Level3_Shift = 0xfe03,
|
||||
|
||||
/*
|
||||
* Latin 1
|
||||
* (ISO/IEC 8859-1 = Unicode U+0020..U+00FF)
|
||||
|
@ -1245,6 +1247,79 @@ XF86VidModeGetGammaRampSize(
|
|||
bar = 0x007c, /* U+007C VERTICAL LINE */
|
||||
braceright = 0x007d, /* U+007D RIGHT CURLY BRACKET */
|
||||
asciitilde = 0x007e, /* U+007E TILDE */
|
||||
|
||||
// Extra keys
|
||||
|
||||
XF86AudioMute = 0x1008ff12,
|
||||
XF86AudioLowerVolume = 0x1008ff11,
|
||||
XF86AudioRaiseVolume = 0x1008ff13,
|
||||
XF86PowerOff = 0x1008ff2a,
|
||||
XF86Suspend = 0x1008ffa7,
|
||||
XF86Copy = 0x1008ff57,
|
||||
XF86Paste = 0x1008ff6d,
|
||||
XF86Cut = 0x1008ff58,
|
||||
XF86MenuKB = 0x1008ff65,
|
||||
XF86Calculator = 0x1008ff1d,
|
||||
XF86Sleep = 0x1008ff2f,
|
||||
XF86WakeUp = 0x1008ff2b ,
|
||||
XF86Explorer = 0x1008ff5d,
|
||||
XF86Send = 0x1008ff7b,
|
||||
XF86Xfer = 0x1008ff8a,
|
||||
XF86Launch1 = 0x1008ff41,
|
||||
XF86Launch2 = 0x1008ff42,
|
||||
XF86Launch3 = 0x1008ff43,
|
||||
XF86Launch4 = 0x1008ff44,
|
||||
XF86Launch5 = 0x1008ff45,
|
||||
XF86LaunchA = 0x1008ff4a,
|
||||
XF86LaunchB = 0x1008ff4b,
|
||||
XF86WWW = 0x1008ff2e,
|
||||
XF86DOS = 0x1008ff5a,
|
||||
XF86ScreenSaver = 0x1008ff2d,
|
||||
XF86RotateWindows = 0x1008ff74,
|
||||
XF86Mail = 0x1008ff19,
|
||||
XF86Favorites = 0x1008ff30,
|
||||
XF86MyComputer = 0x1008ff33,
|
||||
XF86Back = 0x1008ff26,
|
||||
XF86Forward = 0x1008ff27 ,
|
||||
XF86Eject = 0x1008ff2c,
|
||||
XF86AudioPlay = 0x1008ff14,
|
||||
XF86AudioStop = 0x1008ff15,
|
||||
XF86AudioPrev = 0x1008ff16,
|
||||
XF86AudioNext = 0x1008ff17,
|
||||
XF86AudioRecord = 0x1008ff1c,
|
||||
XF86AudioPause =0x1008ff31,
|
||||
XF86AudioRewind = 0x1008ff3e,
|
||||
XF86AudioForward = 0x1008ff97,
|
||||
XF86Phone = 0x1008ff6e,
|
||||
XF86Tools = 0x1008ff81,
|
||||
XF86HomePage = 0x1008ff18,
|
||||
XF86Close = 0x1008ff56,
|
||||
XF86Reload = 0x1008ff73,
|
||||
XF86ScrollUp = 0x1008ff78,
|
||||
XF86ScrollDown = 0x1008ff79,
|
||||
XF86New = 0x1008ff68,
|
||||
XF86TouchpadToggle = 0x1008ffa9,
|
||||
XF86WebCam = 0x1008ff8f,
|
||||
XF86Search = 0x1008ff1b,
|
||||
XF86Finance = 0x1008ff3c,
|
||||
XF86Shop = 0x1008ff36,
|
||||
XF86MonBrightnessDown = 0x1008ff03,
|
||||
XF86MonBrightnessUp = 0x1008ff02,
|
||||
XF86AudioMedia = 0x1008ff32,
|
||||
XF86Display = 0x1008ff59,
|
||||
XF86KbdLightOnOff = 0x1008ff04,
|
||||
XF86KbdBrightnessDown = 0x1008ff06,
|
||||
XF86KbdBrightnessUp = 0x1008ff05,
|
||||
XF86Reply = 0x1008ff72,
|
||||
XF86MailForward = 0x1008ff90,
|
||||
XF86Save = 0x1008ff77,
|
||||
XF86Documents = 0x1008ff5b,
|
||||
XF86Battery = 0x1008ff93,
|
||||
XF86Bluetooth = 0x1008ff94,
|
||||
XF86WLAN = 0x1008ff95,
|
||||
|
||||
SunProps = 0x1005ff70,
|
||||
SunOpen = 0x1005ff73,
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
|
|
@ -108,8 +108,9 @@ namespace OpenTK.Platform.X11
|
|||
public extern static int XConnectionNumber(IntPtr diplay);
|
||||
[DllImport("libX11")]
|
||||
public extern static int XPending(IntPtr diplay);
|
||||
|
||||
[DllImport("libX11", EntryPoint = "XSelectInput")]
|
||||
public extern static IntPtr XSelectInput(IntPtr display, IntPtr window, IntPtr mask);
|
||||
public extern static int XSelectInput(IntPtr display, IntPtr window, IntPtr mask);
|
||||
|
||||
[DllImport("libX11", EntryPoint = "XDestroyWindow")]
|
||||
public extern static int XDestroyWindow(IntPtr display, IntPtr window);
|
||||
|
@ -179,6 +180,17 @@ namespace OpenTK.Platform.X11
|
|||
[DllImport("libX11", EntryPoint = "XUngrabPointer")]
|
||||
public extern static int XUngrabPointer(IntPtr display, IntPtr timestamp);
|
||||
|
||||
[DllImport("libX11", EntryPoint = "XGrabButton")]
|
||||
public extern static int XGrabButton(IntPtr display,
|
||||
int button, uint modifiers, Window grab_window,
|
||||
Bool owner_events, EventMask event_mask,
|
||||
GrabMode pointer_mode, GrabMode keyboard_mode,
|
||||
Window confine_to, Cursor cursor);
|
||||
|
||||
[DllImport("libX11", EntryPoint = "XUngrabButton")]
|
||||
public extern static int XUngrabButton(IntPtr display, uint button, uint
|
||||
modifiers, Window grab_window);
|
||||
|
||||
[DllImport("libX11", EntryPoint = "XQueryPointer")]
|
||||
public extern static bool XQueryPointer(IntPtr display, IntPtr window, out IntPtr root, out IntPtr child, out int root_x, out int root_y, out int win_x, out int win_y, out int keys_buttons);
|
||||
|
||||
|
|
|
@ -88,7 +88,7 @@ namespace OpenTK.Platform.X11
|
|||
//if (XI2Mouse.IsSupported(IntPtr.Zero))
|
||||
// return new XI2Mouse(null); // Requires xorg 1.7 or higher.
|
||||
//else
|
||||
return new X11Mouse(null); // Always supported.
|
||||
return new X11Mouse(); // Always supported.
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
|
|
@ -36,6 +36,7 @@ namespace OpenTK.Platform.X11
|
|||
this.Add(XKey.Super_R, Key.WinRight);
|
||||
this.Add(XKey.Meta_L, Key.WinLeft);
|
||||
this.Add(XKey.Meta_R, Key.WinRight);
|
||||
this.Add(XKey.ISO_Level3_Shift, Key.AltRight); // Normally AltGr
|
||||
|
||||
this.Add(XKey.Menu, Key.Menu);
|
||||
this.Add(XKey.Tab, Key.Tab);
|
||||
|
|
|
@ -38,12 +38,36 @@ namespace OpenTK.Platform.X11
|
|||
{
|
||||
readonly static X11KeyMap keymap = new X11KeyMap();
|
||||
readonly static string name = "Core X11 keyboard";
|
||||
KeyboardState state = new KeyboardState();
|
||||
readonly byte[] keys = new byte[32];
|
||||
readonly int KeysymsPerKeycode;
|
||||
KeyboardState state = new KeyboardState();
|
||||
|
||||
public X11Keyboard()
|
||||
{
|
||||
Debug.WriteLine("Using X11Keyboard.");
|
||||
state.IsConnected = true;
|
||||
|
||||
IntPtr display = API.DefaultDisplay;
|
||||
using (new XLock(display))
|
||||
{
|
||||
// Find the number of keysyms per keycode.
|
||||
int first = 0, last = 0;
|
||||
API.DisplayKeycodes(display, ref first, ref last);
|
||||
IntPtr keysym_ptr = API.GetKeyboardMapping(display, (byte)first, last - first + 1,
|
||||
ref KeysymsPerKeycode);
|
||||
Functions.XFree(keysym_ptr);
|
||||
|
||||
try
|
||||
{
|
||||
// Request that auto-repeat is only set on devices that support it physically.
|
||||
// This typically means that it's turned off for keyboards what we want).
|
||||
// We prefer this method over XAutoRepeatOff/On, because the latter needs to
|
||||
// be reset before the program exits.
|
||||
bool supported;
|
||||
Functions.XkbSetDetectableAutoRepeat(display, true, out supported);
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
}
|
||||
|
||||
public KeyboardState GetState()
|
||||
|
@ -78,18 +102,20 @@ namespace OpenTK.Platform.X11
|
|||
Functions.XQueryKeymap(display, keys);
|
||||
for (int keycode = 8; keycode < 256; keycode++)
|
||||
{
|
||||
IntPtr keysym = Functions.XKeycodeToKeysym(display, (byte)keycode, 0);
|
||||
IntPtr keysym2 = Functions.XKeycodeToKeysym(display, (byte)keycode, 1);
|
||||
bool pressed = (keys[keycode >> 3] >> (keycode & 0x07) & 0x01) != 0;
|
||||
|
||||
Key key;
|
||||
if (keymap.TryGetValue((XKey)keysym, out key) ||
|
||||
keymap.TryGetValue((XKey)keysym2, out key))
|
||||
|
||||
for (int mod = 0; mod < KeysymsPerKeycode; mod++)
|
||||
{
|
||||
if (pressed)
|
||||
state.EnableBit((int)key);
|
||||
else
|
||||
state.DisableBit((int)key);
|
||||
IntPtr keysym = Functions.XKeycodeToKeysym(display, (byte)keycode, mod);
|
||||
if (keysym != IntPtr.Zero && keymap.TryGetValue((XKey)keysym, out key))
|
||||
{
|
||||
if (pressed)
|
||||
state.EnableBit((int)key);
|
||||
else
|
||||
state.DisableBit((int)key);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -34,41 +34,17 @@ namespace OpenTK.Platform.X11
|
|||
{
|
||||
sealed class X11Mouse : IMouseDriver2
|
||||
{
|
||||
readonly IntPtr display;
|
||||
MouseState mouse = new MouseState();
|
||||
X11WindowInfo window;
|
||||
|
||||
// Can either attach itself to the specified window or can hook the root window.
|
||||
public X11Mouse(X11WindowInfo win)
|
||||
// Can either attach itself to the specified window or can hook the root window.
|
||||
public X11Mouse()
|
||||
{
|
||||
if (win != null)
|
||||
{
|
||||
window = win;
|
||||
}
|
||||
else
|
||||
{
|
||||
using (new XLock(API.DefaultDisplay))
|
||||
{
|
||||
window = new X11WindowInfo();
|
||||
window.Display = API.DefaultDisplay;
|
||||
window.Screen = Functions.XDefaultScreen(window.Display);
|
||||
window.RootWindow = Functions.XRootWindow(window.Display, window.Screen);
|
||||
window.WindowHandle = window.RootWindow;
|
||||
window.EventMask = EventMask.ButtonMotionMask |
|
||||
EventMask.ButtonPressMask | EventMask.ButtonReleaseMask;
|
||||
|
||||
//Functions.XGrabPointer(window.Display, window.RootWindow, true,
|
||||
// window.EventMask, GrabMode.GrabModeAsync, GrabMode.GrabModeAsync, IntPtr.Zero,
|
||||
// IntPtr.Zero, IntPtr.Zero);
|
||||
//Functions.XSelectInput(window.Display, window.RootWindow, new IntPtr((int)window.EventMask));
|
||||
}
|
||||
|
||||
Debug.WriteLine("Using X11Mouse.");
|
||||
}
|
||||
Debug.WriteLine("Using X11Mouse.");
|
||||
mouse.IsConnected = true;
|
||||
display = API.DefaultDisplay;
|
||||
}
|
||||
|
||||
// Todo: remove this
|
||||
public IList<MouseDevice> Mouse { get { throw new NotSupportedException(); } }
|
||||
|
||||
public MouseState GetState()
|
||||
{
|
||||
ProcessEvents();
|
||||
|
@ -98,77 +74,29 @@ namespace OpenTK.Platform.X11
|
|||
IntPtr root, child;
|
||||
int root_x, root_y, win_x, win_y;
|
||||
int buttons;
|
||||
Functions.XQueryPointer(window.Display, window.WindowHandle, out root, out child,
|
||||
out root_x, out root_y, out win_x, out win_y, out buttons);
|
||||
mouse.X = root_x;
|
||||
mouse.Y = root_y;
|
||||
WriteBit(MouseButton.Left, buttons & (int)MouseMask.Button1Mask);
|
||||
WriteBit(MouseButton.Middle, buttons & (int)MouseMask.Button2Mask);
|
||||
WriteBit(MouseButton.Right, buttons & (int)MouseMask.Button3Mask);
|
||||
if ((buttons & (int)MouseMask.Button4Mask) != 0)
|
||||
mouse.WheelPrecise++;
|
||||
if ((buttons & (int)MouseMask.Button5Mask) != 0)
|
||||
mouse.WheelPrecise--;
|
||||
WriteBit(MouseButton.Button1, buttons & (int)MouseMask.Button6Mask);
|
||||
WriteBit(MouseButton.Button2, buttons & (int)MouseMask.Button7Mask);
|
||||
WriteBit(MouseButton.Button3, buttons & (int)MouseMask.Button8Mask);
|
||||
|
||||
// XEvent e = new XEvent();
|
||||
//
|
||||
// while (true)
|
||||
// {
|
||||
// using (new XLock(window.Display))
|
||||
// {
|
||||
// if (!Functions.XCheckWindowEvent(window.Display, window.WindowHandle, window.EventMask, ref e))
|
||||
// break;
|
||||
//
|
||||
// switch (e.type)
|
||||
// {
|
||||
// case XEventName.ButtonPress:
|
||||
// switch (e.ButtonEvent.button)
|
||||
// {
|
||||
// case 1: mouse.EnableBit((int)MouseButton.Left); break;
|
||||
// case 2: mouse.EnableBit((int)MouseButton.Middle); break;
|
||||
// case 3: mouse.EnableBit((int)MouseButton.Right); break;
|
||||
// case 4: mouse.WheelPrecise++; break;
|
||||
// case 5: mouse.WheelPrecise--; break;
|
||||
// case 6: mouse.EnableBit((int)MouseButton.Button1); break;
|
||||
// case 7: mouse.EnableBit((int)MouseButton.Button2); break;
|
||||
// case 8: mouse.EnableBit((int)MouseButton.Button3); break;
|
||||
// case 9: mouse.EnableBit((int)MouseButton.Button4); break;
|
||||
// case 10: mouse.EnableBit((int)MouseButton.Button5); break;
|
||||
// case 11: mouse.EnableBit((int)MouseButton.Button6); break;
|
||||
// case 12: mouse.EnableBit((int)MouseButton.Button7); break;
|
||||
// case 13: mouse.EnableBit((int)MouseButton.Button8); break;
|
||||
// case 15: mouse.EnableBit((int)MouseButton.Button9); break;
|
||||
// }
|
||||
// break;
|
||||
//
|
||||
// case XEventName.ButtonRelease:
|
||||
// switch (e.ButtonEvent.button)
|
||||
// {
|
||||
// case 1: mouse.DisableBit((int)MouseButton.Left); break;
|
||||
// case 2: mouse.DisableBit((int)MouseButton.Middle); break;
|
||||
// case 3: mouse.DisableBit((int)MouseButton.Right); break;
|
||||
// case 6: mouse.DisableBit((int)MouseButton.Button1); break;
|
||||
// case 7: mouse.DisableBit((int)MouseButton.Button2); break;
|
||||
// case 8: mouse.DisableBit((int)MouseButton.Button3); break;
|
||||
// case 9: mouse.DisableBit((int)MouseButton.Button4); break;
|
||||
// case 10: mouse.DisableBit((int)MouseButton.Button5); break;
|
||||
// case 11: mouse.DisableBit((int)MouseButton.Button6); break;
|
||||
// case 12: mouse.DisableBit((int)MouseButton.Button7); break;
|
||||
// case 13: mouse.DisableBit((int)MouseButton.Button8); break;
|
||||
// case 15: mouse.DisableBit((int)MouseButton.Button9); break;
|
||||
// }
|
||||
// break;
|
||||
//
|
||||
// case XEventName.MotionNotify:
|
||||
// mouse.X = e.MotionEvent.x;
|
||||
// mouse.Y = e.MotionEvent.y;
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
using (new XLock(display))
|
||||
{
|
||||
IntPtr window = Functions.XRootWindow(display, Functions.XDefaultScreen(display));
|
||||
Functions.XQueryPointer(display, window, out root, out child,
|
||||
out root_x, out root_y, out win_x, out win_y, out buttons);
|
||||
|
||||
mouse.X = root_x;
|
||||
mouse.Y = root_y;
|
||||
WriteBit(MouseButton.Left, buttons & (int)MouseMask.Button1Mask);
|
||||
WriteBit(MouseButton.Middle, buttons & (int)MouseMask.Button2Mask);
|
||||
WriteBit(MouseButton.Right, buttons & (int)MouseMask.Button3Mask);
|
||||
// Note: this will never work right. After spending a week on this, I simply don't care
|
||||
// anymore. If someone can fix it, please do.
|
||||
// Note 2: I have tried passively grabbing those buttons - no go (BadAccess).
|
||||
if ((buttons & (int)MouseMask.Button4Mask) != 0)
|
||||
mouse.WheelPrecise++;
|
||||
if ((buttons & (int)MouseMask.Button5Mask) != 0)
|
||||
mouse.WheelPrecise--;
|
||||
WriteBit(MouseButton.Button1, buttons & (int)MouseMask.Button6Mask);
|
||||
WriteBit(MouseButton.Button2, buttons & (int)MouseMask.Button7Mask);
|
||||
WriteBit(MouseButton.Button3, buttons & (int)MouseMask.Button8Mask);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue