51 52 private final NativePlatform platform = 53 NativePlatformFactory.getNativePlatform(); 54 private final RunnableProcessor runnableProcessor = platform.getRunnableProcessor(); 55 56 /** Bit to indicate that a device has touch support */ 57 private static final int DEVICE_TOUCH = 0; 58 /** Bit to indicate that a device has multitouch support */ 59 private static final int DEVICE_MULTITOUCH = 1; 60 /** Bit to indicate that a device has relative motion pointer support */ 61 private static final int DEVICE_POINTER = 2; 62 /** Bit to indicate that a device has arrow keys and a select key */ 63 private static final int DEVICE_5WAY = 3; 64 /** Bit to indicate that a device has a full PC keyboard */ 65 private static final int DEVICE_PC_KEYBOARD = 4; 66 /** Largest bit used in device capability bitmasks */ 67 private static final int DEVICE_MAX = 4; 68 /** A running count of the numbers of devices with each device capability */ 69 private int[] deviceFlags = new int[DEVICE_MAX + 1]; 70 71 private Runnable renderEndNotifier = new Runnable() { 72 public void run() { 73 platform.getScreen().swapBuffers(); 74 } 75 }; 76 77 MonocleApplication() { 78 for (InputDevice device : platform.getInputDeviceRegistry().getInputDevices()) { 79 updateDeviceFlags(device, true); 80 } 81 platform.getInputDeviceRegistry().getInputDevices().addListener( 82 new SetChangeListener<InputDevice>() { 83 @Override 84 public void onChanged( 85 Change<? extends InputDevice> change) { 86 if (change.wasAdded()) { 87 InputDevice device = change.getElementAdded(); 88 updateDeviceFlags(device, true); 89 } else if (change.wasRemoved()) { 90 InputDevice device = change.getElementRemoved(); 91 updateDeviceFlags(device, false); 92 } 93 } 94 }); 95 } 96 97 private void updateDeviceFlags(InputDevice device, boolean added) { 98 int modifier = added ? 1 : -1; 99 if (device.isTouch()) { 100 deviceFlags[DEVICE_TOUCH] += modifier; 101 } 102 if (device.isMultiTouch()) { 103 deviceFlags[DEVICE_MULTITOUCH] += modifier; 104 } 105 if (device.isRelative()) { 106 deviceFlags[DEVICE_POINTER] += modifier; 107 } 108 if (device.isFullKeyboard()) { 109 deviceFlags[DEVICE_PC_KEYBOARD] += modifier; 110 } 111 if (device.is5Way()) { 112 deviceFlags[DEVICE_5WAY] += modifier; 113 } 114 } 115 116 @Override 117 protected void runLoop(Runnable launchable) { 118 runnableProcessor.invokeLater(launchable); 119 Thread t = new Thread(runnableProcessor); 120 setEventThread(t); 121 t.start(); 122 } 123 124 @Override 125 protected void _invokeAndWait(Runnable runnable) { 126 runnableProcessor.invokeAndWait(runnable); 127 } 128 129 @Override 130 protected void _invokeLater(Runnable runnable) { 131 runnableProcessor.invokeLater(runnable); 132 } 133 134 @Override 135 protected Object _enterNestedEventLoop() { 136 return runnableProcessor.enterNestedEventLoop(); 137 } 138 139 @Override 140 protected void _leaveNestedEventLoop(Object retValue) { 141 runnableProcessor.leaveNestedEventLoop(retValue); 151 return new MonocleWindow(parent); 152 } 153 154 @Override 155 public View createView() { 156 return new MonocleView(); 157 } 158 159 @Override 160 public Cursor createCursor(int type) { 161 return new MonocleCursor(type); 162 } 163 164 @Override 165 public Cursor createCursor(int x, int y, Pixels pixels) { 166 return new MonocleCursor(x, y, pixels); 167 } 168 169 @Override 170 protected void staticCursor_setVisible(boolean visible) { 171 NativeCursor cursor = NativePlatformFactory.getNativePlatform().getCursor(); 172 cursor.setVisibility(visible); 173 } 174 175 @Override 176 protected Size staticCursor_getBestSize(int width, int height) { 177 NativeCursor cursor = NativePlatformFactory.getNativePlatform().getCursor(); 178 return cursor.getBestSize(); 179 } 180 181 @Override 182 public Pixels createPixels(int width, int height, ByteBuffer data) { 183 return new MonoclePixels(width, height, data); 184 } 185 186 @Override 187 public Pixels createPixels(int width, int height, IntBuffer data) { 188 return new MonoclePixels(width, height, data); 189 } 190 191 @Override 192 public Pixels createPixels(int width, int height, IntBuffer data, 193 float scale) { 333 return deviceFlags[DEVICE_TOUCH] > 0; 334 } 335 336 @Override 337 public boolean hasMultiTouch() { 338 return deviceFlags[DEVICE_MULTITOUCH] > 0; 339 } 340 341 @Override 342 public boolean hasPointer() { 343 return deviceFlags[DEVICE_POINTER] > 0; 344 } 345 346 @Override 347 public void notifyRenderingFinished() { 348 invokeLater(renderEndNotifier); 349 } 350 351 @Override 352 protected void finishTerminating() { 353 setEventThread(null); 354 platform.shutdown(); 355 super.finishTerminating(); 356 } 357 358 } | 51 52 private final NativePlatform platform = 53 NativePlatformFactory.getNativePlatform(); 54 private final RunnableProcessor runnableProcessor = platform.getRunnableProcessor(); 55 56 /** Bit to indicate that a device has touch support */ 57 private static final int DEVICE_TOUCH = 0; 58 /** Bit to indicate that a device has multitouch support */ 59 private static final int DEVICE_MULTITOUCH = 1; 60 /** Bit to indicate that a device has relative motion pointer support */ 61 private static final int DEVICE_POINTER = 2; 62 /** Bit to indicate that a device has arrow keys and a select key */ 63 private static final int DEVICE_5WAY = 3; 64 /** Bit to indicate that a device has a full PC keyboard */ 65 private static final int DEVICE_PC_KEYBOARD = 4; 66 /** Largest bit used in device capability bitmasks */ 67 private static final int DEVICE_MAX = 4; 68 /** A running count of the numbers of devices with each device capability */ 69 private int[] deviceFlags = new int[DEVICE_MAX + 1]; 70 71 private Thread shutdownHookThread; 72 73 private Runnable renderEndNotifier = new Runnable() { 74 public void run() { 75 platform.getScreen().swapBuffers(); 76 } 77 }; 78 79 MonocleApplication() { 80 for (InputDevice device : platform.getInputDeviceRegistry().getInputDevices()) { 81 updateDeviceFlags(device, true); 82 } 83 platform.getInputDeviceRegistry().getInputDevices().addListener( 84 new SetChangeListener<InputDevice>() { 85 @Override 86 public void onChanged( 87 Change<? extends InputDevice> change) { 88 if (change.wasAdded()) { 89 InputDevice device = change.getElementAdded(); 90 updateDeviceFlags(device, true); 91 } else if (change.wasRemoved()) { 92 InputDevice device = change.getElementRemoved(); 93 updateDeviceFlags(device, false); 94 } 95 } 96 }); 97 } 98 99 private void updateDeviceFlags(InputDevice device, boolean added) { 100 int modifier = added ? 1 : -1; 101 if (device.isTouch()) { 102 deviceFlags[DEVICE_TOUCH] += modifier; 103 } 104 if (device.isMultiTouch()) { 105 deviceFlags[DEVICE_MULTITOUCH] += modifier; 106 } 107 if (device.isRelative()) { 108 deviceFlags[DEVICE_POINTER] += modifier; 109 if (deviceFlags[DEVICE_POINTER] >= 1 && added) { 110 staticCursor_setVisible(true); 111 } else if (deviceFlags[DEVICE_POINTER] < 1 && !added) { 112 staticCursor_setVisible(false); 113 } 114 } 115 if (device.isFullKeyboard()) { 116 deviceFlags[DEVICE_PC_KEYBOARD] += modifier; 117 } 118 if (device.is5Way()) { 119 deviceFlags[DEVICE_5WAY] += modifier; 120 } 121 } 122 123 @Override 124 protected void runLoop(Runnable launchable) { 125 runnableProcessor.invokeLater(launchable); 126 Thread t = new Thread(runnableProcessor); 127 setEventThread(t); 128 t.start(); 129 shutdownHookThread = new Thread("Monocle shutdown hook") { 130 @Override public void run() { 131 platform.shutdown(); 132 } 133 }; 134 Runtime.getRuntime().addShutdownHook(shutdownHookThread); 135 } 136 137 @Override 138 protected void _invokeAndWait(Runnable runnable) { 139 runnableProcessor.invokeAndWait(runnable); 140 } 141 142 @Override 143 protected void _invokeLater(Runnable runnable) { 144 runnableProcessor.invokeLater(runnable); 145 } 146 147 @Override 148 protected Object _enterNestedEventLoop() { 149 return runnableProcessor.enterNestedEventLoop(); 150 } 151 152 @Override 153 protected void _leaveNestedEventLoop(Object retValue) { 154 runnableProcessor.leaveNestedEventLoop(retValue); 164 return new MonocleWindow(parent); 165 } 166 167 @Override 168 public View createView() { 169 return new MonocleView(); 170 } 171 172 @Override 173 public Cursor createCursor(int type) { 174 return new MonocleCursor(type); 175 } 176 177 @Override 178 public Cursor createCursor(int x, int y, Pixels pixels) { 179 return new MonocleCursor(x, y, pixels); 180 } 181 182 @Override 183 protected void staticCursor_setVisible(boolean visible) { 184 if ((visible && deviceFlags[DEVICE_POINTER] >= 1) || 185 (!visible && deviceFlags[DEVICE_POINTER] < 1)) { 186 NativeCursor cursor = NativePlatformFactory.getNativePlatform().getCursor(); 187 cursor.setVisibility(visible); 188 } 189 } 190 191 @Override 192 protected Size staticCursor_getBestSize(int width, int height) { 193 NativeCursor cursor = NativePlatformFactory.getNativePlatform().getCursor(); 194 return cursor.getBestSize(); 195 } 196 197 @Override 198 public Pixels createPixels(int width, int height, ByteBuffer data) { 199 return new MonoclePixels(width, height, data); 200 } 201 202 @Override 203 public Pixels createPixels(int width, int height, IntBuffer data) { 204 return new MonoclePixels(width, height, data); 205 } 206 207 @Override 208 public Pixels createPixels(int width, int height, IntBuffer data, 209 float scale) { 349 return deviceFlags[DEVICE_TOUCH] > 0; 350 } 351 352 @Override 353 public boolean hasMultiTouch() { 354 return deviceFlags[DEVICE_MULTITOUCH] > 0; 355 } 356 357 @Override 358 public boolean hasPointer() { 359 return deviceFlags[DEVICE_POINTER] > 0; 360 } 361 362 @Override 363 public void notifyRenderingFinished() { 364 invokeLater(renderEndNotifier); 365 } 366 367 @Override 368 protected void finishTerminating() { 369 //if this method is getting called, we don't need the shutdown hook 370 Runtime.getRuntime().removeShutdownHook(shutdownHookThread); 371 setEventThread(null); 372 platform.shutdown(); 373 super.finishTerminating(); 374 } 375 376 } |