/*
 * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

package com.sun.glass.ui.monocle;

import com.sun.glass.events.MouseEvent;

InputDeviceRegistry used when the system property Dx11.input=true is set, indicating that we would like to receive input events through Xlib instead of directly from Linux input devices.
/** InputDeviceRegistry used when the system property Dx11.input=true is set, * indicating that we would like to receive input events through Xlib instead * of directly from Linux input devices. */
class X11InputDeviceRegistry extends InputDeviceRegistry { private MouseState state; private static X xLib = X.getX(); X11InputDeviceRegistry() { InputDevice device = new InputDevice() { @Override public boolean isTouch() { return false; } @Override public boolean isMultiTouch() { return false; } @Override public boolean isRelative() { return true; } @Override public boolean is5Way() { return false; } @Override public boolean isFullKeyboard() { return false; } }; // Start the thread to listen to the X11 event queue Thread x11InputThread = new Thread(() -> { NativePlatform platform = NativePlatformFactory.getNativePlatform(); X11Screen screen = (X11Screen) platform.getScreen(); long display = screen.getDisplay(); long window = screen.getNativeHandle(); RunnableProcessor runnableProcessor = platform.getRunnableProcessor(); runnableProcessor.invokeLater(() -> { devices.add(device); }); state = new MouseState(); X.XEvent event = new X.XEvent(); while (true) { xLib.XNextEvent(display, event.p); if (X.XEvent.getWindow(event.p) != window) { continue; } processXEvent(event, runnableProcessor); } }); x11InputThread.setName("X11 Input"); x11InputThread.setDaemon(true); x11InputThread.start(); }
Dispatch the X Event to the appropriate processor. All processors run via invokeLater
Params:
  • event –
  • runnableProcessor –
/** Dispatch the X Event to the appropriate processor. All processors run * via invokeLater * @param event * @param runnableProcessor */
private void processXEvent(X.XEvent event, RunnableProcessor runnableProcessor) { switch (X.XEvent.getType(event.p)) { case X.ButtonPress: { X.XButtonEvent buttonEvent = new X.XButtonEvent(event); int button = X.XButtonEvent.getButton(buttonEvent.p); runnableProcessor.invokeLater(new ButtonPressProcessor(button)); break; } case X.ButtonRelease: { X.XButtonEvent buttonEvent = new X.XButtonEvent(event); int button = X.XButtonEvent.getButton(buttonEvent.p); runnableProcessor.invokeLater( new ButtonReleaseProcessor(button)); break; } case X.MotionNotify: { X.XMotionEvent motionEvent = new X.XMotionEvent(event); int x = X.XMotionEvent.getX(motionEvent.p); int y = X.XMotionEvent.getY(motionEvent.p); runnableProcessor.invokeLater(new MotionProcessor(x, y)); break; } } } private class ButtonPressProcessor implements Runnable { private int button; ButtonPressProcessor(int button) { this.button = button; } @Override public void run() { MouseInput.getInstance().getState(state); int glassButton = buttonToGlassButton(button); if (glassButton != MouseEvent.BUTTON_NONE) { state.pressButton(glassButton); } MouseInput.getInstance().setState(state, false); } } private class ButtonReleaseProcessor implements Runnable { private int button; ButtonReleaseProcessor(int button) { this.button = button; } @Override public void run() { MouseInput.getInstance().getState(state); int glassButton = buttonToGlassButton(button); if (glassButton != MouseEvent.BUTTON_NONE) { state.releaseButton(glassButton); } MouseInput.getInstance().setState(state, false); } } private class MotionProcessor implements Runnable { private int x; private int y; MotionProcessor(int x, int y) { this.x = x; this.y = y; } @Override public void run() { MouseInput.getInstance().getState(state); state.setX(x); state.setY(y); MouseInput.getInstance().setState(state, false); } }
Convenience method to convert X11 button codes to glass button codes
Params:
  • button –
/** Convenience method to convert X11 button codes to glass button codes * * @param button */
private static int buttonToGlassButton(int button) { switch (button) { case X.Button1: return MouseEvent.BUTTON_LEFT; case X.Button2: return MouseEvent.BUTTON_OTHER; case X.Button3: return MouseEvent.BUTTON_RIGHT; case X.Button8: return MouseEvent.BUTTON_BACK; case X.Button9: return MouseEvent.BUTTON_FORWARD; default: return MouseEvent.BUTTON_NONE; } } }