Opentk/Source/OpenTK/Platform/X11/Bindings/Xkb.cs
2014-07-21 17:46:39 +02:00

304 lines
9.1 KiB
C#

#region License
//
// Xkb.cs
//
// Author:
// Stefanos Apostolopoulos <stapostol@gmail.com>
//
// Copyright (c) 2006-2014
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
#endregion
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
#pragma warning disable 0169
namespace OpenTK.Platform.X11
{
using Atom = IntPtr;
using KeyCode = Byte;
using XkbControlsPtr = IntPtr;
using XkbServerMapPtr = IntPtr;
using XkbClientMapPtr = IntPtr;
using XkbIndicatorPtr = IntPtr;
using XkbCompatMapPtr = IntPtr;
using XkbGeometryPtr = IntPtr;
class Xkb
{
const string lib = "libX11";
internal const int KeyNameLength = 4;
internal const int NumModifiers = 8;
internal const int NumVirtualMods = 16;
internal const int NumIndicators = 32;
internal const int NumKbdGroups = 4;
internal const int UseCoreKeyboard = 0x0100;
[DllImport(lib, EntryPoint = "XkbFreeKeyboard")]
unsafe internal extern static void FreeKeyboard(XkbDesc* descr, int which, bool free);
[DllImport(lib, EntryPoint = "XkbAllocKeyboard")]
unsafe internal extern static XkbDesc* AllocKeyboard(IntPtr display);
[DllImport(lib, EntryPoint = "XkbGetKeyboard")]
internal extern static IntPtr GetKeyboard(IntPtr display, XkbKeyboardMask which, int device_id);
[DllImport(lib, EntryPoint = "XkbGetMap")]
internal extern static IntPtr GetMap(IntPtr display, XkbKeyboardMask which, int device_spec);
[DllImport(lib, EntryPoint = "XkbGetNames")]
unsafe internal extern static IntPtr GetNames(IntPtr display, XkbNamesMask which, XkbDesc* xkb);
[DllImport(lib, EntryPoint = "XkbKeycodeToKeysym")]
internal extern static XKey KeycodeToKeysym(IntPtr display, int keycode, int group, int level);
[DllImport(lib, EntryPoint = "XkbQueryExtension")]
internal extern static bool QueryExtension(IntPtr display, out int opcode_rtrn, out int event_rtrn,
out int error_rtrn, ref int major_in_out, ref int minor_in_out);
[DllImport(lib, EntryPoint = "XkbSetDetectableAutoRepeat")]
internal extern static bool SetDetectableAutoRepeat(IntPtr display, bool detectable, out bool supported);
internal static bool IsSupported(IntPtr display)
{
// The XkbQueryExtension manpage says that we cannot
// use XQueryExtension with XKB.
int opcode, error, ev;
int major = 1;
int minor = 0;
bool supported = QueryExtension(display, out opcode, out ev, out error, ref major, ref minor);
Debug.Print("XKB extension is {0}.", supported ? "supported" : "not supported");
if (supported)
{
Debug.Print("XKB version is {0}.{1}", major, minor);
}
return supported;
}
}
[Flags]
enum XkbKeyboardMask
{
Controls = 1 << 0,
ServerMap = 1 << 1,
IClientMap = 1 << 2,
IndicatorMap = 1 << 3,
Names = 1 << 4,
CompatibilityMap = 1 << 5,
Geometry = 1 << 6,
AllComponents = 1 << 7,
}
[Flags]
enum XkbNamesMask
{
Keycodes = 1 << 0,
Geometry = 1 << 1,
Symbols = 1 << 2,
PhysSymbols = 1 << 3,
Types = 1 << 4,
Compat = 1 << 5,
KeyType = 1 << 6,
KTLevel = 1 << 7,
Indicator = 1 << 8,
Key = 1 << 9,
KeyAliasesMask = 1 << 10,
VirtualMod = 1 << 11,
Group = 1 << 12,
RG = 1 << 13,
Component = 0x3f,
All = 0x3fff
}
[StructLayout(LayoutKind.Sequential)]
unsafe struct XkbDesc
{
internal IntPtr dpy;
internal ushort flags;
internal ushort device_spec;
internal KeyCode min_key_code;
internal KeyCode max_key_code;
internal XkbControlsPtr ctrls;
internal XkbServerMapPtr server;
internal XkbClientMapPtr map;
internal XkbIndicatorPtr indicators;
internal XkbNames* names;
internal XkbCompatMapPtr compat;
internal XkbGeometryPtr geom;
}
[StructLayout(LayoutKind.Sequential)]
unsafe struct XkbKeyAlias
{
internal fixed byte real[Xkb.KeyNameLength];
internal fixed byte alias[Xkb.KeyNameLength];
}
[StructLayout(LayoutKind.Sequential)]
unsafe struct XkbKeyName
{
internal fixed byte name[Xkb.KeyNameLength];
}
[StructLayout(LayoutKind.Sequential)]
unsafe struct XkbNames
{
#region Structs
[StructLayout(LayoutKind.Sequential)]
internal struct Groups
{
Atom groups0;
Atom groups1;
Atom groups2;
Atom groups3;
internal Atom this[int i]
{
get
{
if (i < 0 || i > 3)
throw new IndexOutOfRangeException();
unsafe
{
fixed (Atom* ptr = &groups0)
{
return *(ptr + i);
}
}
}
}
}
[StructLayout(LayoutKind.Sequential)]
internal struct Indicators
{
Atom indicators0;
Atom indicators1;
Atom indicators2;
Atom indicators3;
Atom indicators4;
Atom indicators5;
Atom indicators6;
Atom indicators7;
Atom indicators8;
Atom indicators9;
Atom indicators10;
Atom indicators11;
Atom indicators12;
Atom indicators13;
Atom indicators14;
Atom indicators15;
Atom indicators16;
Atom indicators17;
Atom indicators18;
Atom indicators19;
Atom indicators20;
Atom indicators21;
Atom indicators22;
Atom indicators23;
Atom indicators24;
Atom indicators25;
Atom indicators26;
Atom indicators27;
Atom indicators28;
Atom indicators29;
Atom indicators30;
Atom indicators31;
internal Atom this[int i]
{
get
{
if (i < 0 || i > 31)
throw new IndexOutOfRangeException();
unsafe
{
fixed (Atom* ptr = &indicators0)
{
return *(ptr + i);
} }
}
}
}
[StructLayout(LayoutKind.Sequential)]
internal struct VMods
{
Atom vmods0;
Atom vmods1;
Atom vmods2;
Atom vmods3;
Atom vmods4;
Atom vmods5;
Atom vmods6;
Atom vmods7;
Atom vmods8;
Atom vmods9;
Atom vmods10;
Atom vmods11;
Atom vmods12;
Atom vmods13;
Atom vmods14;
Atom vmods15;
internal Atom this[int i]
{
get
{
if (i < 0 || i > 15)
throw new IndexOutOfRangeException();
unsafe
{
fixed (Atom* ptr = &vmods0)
{
return *(ptr + i);
}
}
}
}
}
#endregion
internal Atom keycodes;
internal Atom geometry;
internal Atom symbols;
internal Atom types;
internal Atom compat;
internal VMods vmods;
internal Indicators indicators;
internal Groups groups;
internal XkbKeyName* keys;
internal XkbKeyAlias* key_aliases;
internal Atom *radio_groups;
internal Atom phys_symbols;
internal byte num_keys;
internal byte num_key_aliases;
internal byte num_rg;
}
}