예제 #1
0
        public XI2MouseKeyboard()
        {
            window = new X11WindowInfo();

            window.Display = Functions.XOpenDisplay(IntPtr.Zero);
            using (new XLock(window.Display))
            {
                XSetWindowAttributes attr = new XSetWindowAttributes();

                window.Screen     = Functions.XDefaultScreen(window.Display);
                window.RootWindow = Functions.XRootWindow(window.Display, window.Screen);
                window.Handle     = Functions.XCreateWindow(window.Display, window.RootWindow,
                                                            0, 0, 1, 1, 0, 0,
                                                            CreateWindowArgs.InputOnly, IntPtr.Zero,
                                                            SetWindowValuemask.Nothing, attr);

                KeyMap = new X11KeyMap(window.Display);
            }

            if (!IsSupported(window.Display))
            {
                throw new NotSupportedException("XInput2 not supported.");
            }

            // Enable XI2 mouse/keyboard events
            // Note: the input event loop blocks waiting for these events
            // *or* a custom ClientMessage event that instructs us to exit.
            // See SendExitEvent() below.
            using (new XLock(window.Display))
                using (XIEventMask mask = new XIEventMask(1,
                                                          XIEventMasks.RawKeyPressMask |
                                                          XIEventMasks.RawKeyReleaseMask |
                                                          XIEventMasks.RawButtonPressMask |
                                                          XIEventMasks.RawButtonReleaseMask |
                                                          XIEventMasks.RawMotionMask |
                                                          XIEventMasks.MotionMask |
                                                          XIEventMasks.DeviceChangedMask))
                {
                    XI.SelectEvents(window.Display, window.RootWindow, mask);
                    UpdateDevices();
                }

            ProcessingThread = new Thread(ProcessEvents);
            ProcessingThread.IsBackground = true;
            ProcessingThread.Start();
        }
예제 #2
0
        // Checks whether XInput2 is supported on the specified display.
        // If a display is not specified, the default display is used.
        internal static bool IsSupported(IntPtr display)
        {
            try
            {
                if (display == IntPtr.Zero)
                {
                    display = API.DefaultDisplay;
                }

                using (new XLock(display))
                {
                    int major, ev, error;
                    if (Functions.XQueryExtension(display, "XInputExtension", out major, out ev, out error) != 0)
                    {
                        XIOpCode = major;

                        int minor = 2;
                        while (minor >= 0)
                        {
                            if (XI.QueryVersion(display, ref major, ref minor) == ErrorCodes.Success)
                            {
                                XIVersion = major * 100 + minor * 10;
                                return(true);
                            }
                            minor--;
                        }
                    }
                }
            }
            catch (DllNotFoundException e)
            {
                Debug.Print(e.ToString());
                Debug.Print("XInput2 extension not supported. Mouse support will suffer.");
            }

            return(false);
        }
예제 #3
0
        private void UpdateDevices()
        {
            lock (Sync)
            {
                devices.Clear();
                keyboards.Clear();

                int count;
                unsafe
                {
                    XIDeviceInfo *list = (XIDeviceInfo *)XI.QueryDevice(window.Display,
                                                                        XI.XIAllDevices, out count);

                    Debug.Print("Refreshing input device list");
                    Debug.Print("{0} input devices detected", count);

                    for (int i = 0; i < count; i++)
                    {
                        switch ((list + i)->use)
                        {
                        case XIDeviceType.MasterKeyboard:
                            //case XIDeviceType.SlaveKeyboard:
                        {
                            XIKeyboard k = new XIKeyboard();
                            k.DeviceInfo = *(list + i);
                            k.State.SetIsConnected(k.DeviceInfo.enabled);
                            k.Name = Marshal.PtrToStringAnsi(k.DeviceInfo.name);
                            int id = k.DeviceInfo.deviceid;
                            if (!keyboard_ids.ContainsKey(id))
                            {
                                keyboard_ids.Add(k.DeviceInfo.deviceid, 0);
                            }
                            keyboard_ids[id] = keyboards.Count;
                            keyboards.Add(k);
                        }
                        break;

                        case XIDeviceType.MasterPointer:
                        //case XIDeviceType.SlavePointer:
                        case XIDeviceType.FloatingSlave:
                        {
                            XIMouse d = new XIMouse();
                            d.DeviceInfo = *(list + i);

                            d.State.SetIsConnected(d.DeviceInfo.enabled);
                            d.Name = Marshal.PtrToStringAnsi(d.DeviceInfo.name);
                            Debug.Print("Device {0} \"{1}\" is {2} and has:",
                                        i, d.Name, d.DeviceInfo.enabled ? "enabled" : "disabled");

                            // Decode the XIDeviceInfo to axes, buttons and scroll types
                            for (int j = 0; j < d.DeviceInfo.num_classes; j++)
                            {
                                XIAnyClassInfo *class_info = *((XIAnyClassInfo **)d.DeviceInfo.classes + j);
                                switch (class_info->type)
                                {
                                case XIClassType.Button:
                                {
                                    XIButtonClassInfo *button = (XIButtonClassInfo *)class_info;
                                    Debug.Print("\t{0} buttons", button->num_buttons);
                                }
                                break;

                                case XIClassType.Scroll:
                                {
                                    XIScrollClassInfo *scroll = (XIScrollClassInfo *)class_info;
                                    switch (scroll->scroll_type)
                                    {
                                    case XIScrollType.Vertical:
                                        Debug.WriteLine("\tSmooth vertical scrolling");
                                        d.ScrollY = *scroll;
                                        break;

                                    case XIScrollType.Horizontal:
                                        Debug.WriteLine("\tSmooth horizontal scrolling");
                                        d.ScrollX = *scroll;
                                        break;

                                    default:
                                        Debug.Print("\tUnknown scrolling type {0}", scroll->scroll_type);
                                        break;
                                    }
                                }
                                break;

                                case XIClassType.Valuator:
                                {
                                    // We use relative x/y valuators for mouse movement.
                                    // Iff these are not available, we fall back to
                                    // absolute x/y valuators.
                                    XIValuatorClassInfo *valuator = (XIValuatorClassInfo *)class_info;
                                    if (valuator->label == XI.RelativeX)
                                    {
                                        Debug.WriteLine("\tRelative X movement");
                                        d.MotionX = *valuator;
                                    }
                                    else if (valuator->label == XI.RelativeY)
                                    {
                                        Debug.WriteLine("\tRelative Y movement");
                                        d.MotionY = *valuator;
                                    }
                                    else if (valuator->label == XI.AbsoluteX)
                                    {
                                        Debug.WriteLine("\tAbsolute X movement");
                                        if (d.MotionX.number == -1)
                                        {
                                            d.MotionX = *valuator;
                                        }
                                    }
                                    else if (valuator->label == XI.AbsoluteY)
                                    {
                                        Debug.WriteLine("\tAbsolute X movement");
                                        if (d.MotionY.number == -1)
                                        {
                                            d.MotionY = *valuator;
                                        }
                                    }
                                    else
                                    {
                                        IntPtr label = Functions.XGetAtomName(window.Display, valuator->label);
                                        Debug.Print("\tUnknown valuator {0}",
                                                    Marshal.PtrToStringAnsi(label));
                                        Functions.XFree(label);
                                    }
                                }
                                break;
                                }
                            }

                            // Map the hardware device id to the current XIMouse id
                            int id = d.DeviceInfo.deviceid;
                            if (!rawids.ContainsKey(id))
                            {
                                rawids.Add(id, 0);
                            }
                            rawids[id] = devices.Count;
                            devices.Add(d);
                        }
                        break;
                        }
                    }
                    XI.FreeDeviceInfo((IntPtr)list);
                }
            }
        }