PageRenderTime 42ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 0ms

/jEdit/tags/jedit-4-2-pre4/org/gjt/sp/jedit/gui/KeyEventWorkaround.java

#
Java | 274 lines | 202 code | 15 blank | 57 comment | 52 complexity | f9cce32a3684715a6161afa83581fab8 MD5 | raw file
Possible License(s): BSD-3-Clause, AGPL-1.0, Apache-2.0, LGPL-2.0, LGPL-3.0, GPL-2.0, CC-BY-SA-3.0, LGPL-2.1, GPL-3.0, MPL-2.0-no-copyleft-exception, IPL-1.0
  1. /*
  2. * KeyEventWorkaround.java - Works around bugs in Java event handling
  3. * :tabSize=8:indentSize=8:noTabs=false:
  4. * :folding=explicit:collapseFolds=1:
  5. *
  6. * Copyright (C) 2000, 2003 Slava Pestov
  7. *
  8. * This program is free software; you can redistribute it and/or
  9. * modify it under the terms of the GNU General Public License
  10. * as published by the Free Software Foundation; either version 2
  11. * of the License, or any later version.
  12. *
  13. * This program is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU General Public License
  19. * along with this program; if not, write to the Free Software
  20. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  21. */
  22. package org.gjt.sp.jedit.gui;
  23. //{{{ Imports
  24. import java.awt.event.*;
  25. import org.gjt.sp.jedit.Debug;
  26. //}}}
  27. /**
  28. * Various hacks to get keyboard event handling to behave in a consistent manner
  29. * across Java implementations.
  30. *
  31. * @author Slava Pestov
  32. * @version $Id: KeyEventWorkaround.java 4841 2003-07-28 21:08:04Z spestov $
  33. */
  34. public class KeyEventWorkaround
  35. {
  36. //{{{ processKeyEvent() method
  37. public static KeyEvent processKeyEvent(KeyEvent evt)
  38. {
  39. int keyCode = evt.getKeyCode();
  40. char ch = evt.getKeyChar();
  41. switch(evt.getID())
  42. {
  43. //{{{ KEY_PRESSED...
  44. case KeyEvent.KEY_PRESSED:
  45. lastKeyTime = System.currentTimeMillis();
  46. // get rid of keys we never need to handle
  47. switch(keyCode)
  48. {
  49. case KeyEvent.VK_DEAD_GRAVE:
  50. case KeyEvent.VK_DEAD_ACUTE:
  51. case KeyEvent.VK_DEAD_CIRCUMFLEX:
  52. case KeyEvent.VK_DEAD_TILDE:
  53. case KeyEvent.VK_DEAD_MACRON:
  54. case KeyEvent.VK_DEAD_BREVE:
  55. case KeyEvent.VK_DEAD_ABOVEDOT:
  56. case KeyEvent.VK_DEAD_DIAERESIS:
  57. case KeyEvent.VK_DEAD_ABOVERING:
  58. case KeyEvent.VK_DEAD_DOUBLEACUTE:
  59. case KeyEvent.VK_DEAD_CARON:
  60. case KeyEvent.VK_DEAD_CEDILLA:
  61. case KeyEvent.VK_DEAD_OGONEK:
  62. case KeyEvent.VK_DEAD_IOTA:
  63. case KeyEvent.VK_DEAD_VOICED_SOUND:
  64. case KeyEvent.VK_DEAD_SEMIVOICED_SOUND:
  65. case '\0':
  66. return null;
  67. case KeyEvent.VK_ALT:
  68. modifiers |= InputEvent.ALT_MASK;
  69. return null;
  70. case KeyEvent.VK_ALT_GRAPH:
  71. modifiers |= InputEvent.ALT_GRAPH_MASK;
  72. return null;
  73. case KeyEvent.VK_CONTROL:
  74. modifiers |= InputEvent.CTRL_MASK;
  75. return null;
  76. case KeyEvent.VK_SHIFT:
  77. modifiers |= InputEvent.SHIFT_MASK;
  78. return null;
  79. case KeyEvent.VK_META:
  80. modifiers |= InputEvent.META_MASK;
  81. return null;
  82. case KeyEvent.VK_NUMPAD0:
  83. case KeyEvent.VK_NUMPAD1:
  84. case KeyEvent.VK_NUMPAD2:
  85. case KeyEvent.VK_NUMPAD3:
  86. case KeyEvent.VK_NUMPAD4:
  87. case KeyEvent.VK_NUMPAD5:
  88. case KeyEvent.VK_NUMPAD6:
  89. case KeyEvent.VK_NUMPAD7:
  90. case KeyEvent.VK_NUMPAD8:
  91. case KeyEvent.VK_NUMPAD9:
  92. case KeyEvent.VK_MULTIPLY:
  93. case KeyEvent.VK_ADD:
  94. /* case KeyEvent.VK_SEPARATOR: */
  95. case KeyEvent.VK_SUBTRACT:
  96. case KeyEvent.VK_DECIMAL:
  97. case KeyEvent.VK_DIVIDE:
  98. System.err.println(evt);
  99. System.err.println("foo");
  100. last = LAST_NUMKEYPAD;
  101. return evt;
  102. default:
  103. if(!evt.isMetaDown())
  104. {
  105. if(evt.isControlDown()
  106. && evt.isAltDown())
  107. {
  108. lastKeyTime = 0L;
  109. }
  110. else if(!evt.isControlDown()
  111. && !evt.isAltDown())
  112. {
  113. lastKeyTime = 0L;
  114. if(keyCode >= KeyEvent.VK_0
  115. && keyCode <= KeyEvent.VK_9)
  116. {
  117. return null;
  118. }
  119. if(keyCode >= KeyEvent.VK_A
  120. && keyCode <= KeyEvent.VK_Z)
  121. {
  122. return null;
  123. }
  124. }
  125. }
  126. if(Debug.ALT_KEY_PRESSED_DISABLED)
  127. {
  128. /* we don't handle key pressed A+ */
  129. /* they're too troublesome */
  130. if((modifiers & InputEvent.ALT_MASK) != 0)
  131. return null;
  132. }
  133. last = LAST_NOTHING;
  134. break;
  135. }
  136. return evt;
  137. //}}}
  138. //{{{ KEY_TYPED...
  139. case KeyEvent.KEY_TYPED:
  140. // need to let \b through so that backspace will work
  141. // in HistoryTextFields
  142. if((ch < 0x20 || ch == 0x7f || ch == 0xff)
  143. && ch != '\b' && ch != '\t' && ch != '\n')
  144. {
  145. return null;
  146. }
  147. if(System.currentTimeMillis() - lastKeyTime < 750)
  148. {
  149. if(!Debug.ALTERNATIVE_DISPATCHER)
  150. {
  151. if(((modifiers & InputEvent.CTRL_MASK) != 0
  152. ^ (modifiers & InputEvent.ALT_MASK) != 0)
  153. || (modifiers & InputEvent.META_MASK) != 0)
  154. {
  155. return null;
  156. }
  157. }
  158. // if the last key was a numeric keypad key
  159. // and NumLock is off, filter it out
  160. if(last == LAST_NUMKEYPAD)
  161. {
  162. System.err.println("last was numpad");
  163. last = LAST_NOTHING;
  164. if((ch >= '0' && ch <= '9') || ch == '.'
  165. || ch == '/' || ch == '*'
  166. || ch == '-' || ch == '+')
  167. {
  168. System.err.println("kill");
  169. return null;
  170. }
  171. }
  172. // Windows JDK workaround
  173. else if(last == LAST_ALT)
  174. {
  175. last = LAST_NOTHING;
  176. switch(ch)
  177. {
  178. case 'B':
  179. case 'M':
  180. case 'X':
  181. case 'c':
  182. case '!':
  183. case ',':
  184. case '?':
  185. return null;
  186. }
  187. }
  188. }
  189. else
  190. {
  191. if((modifiers & InputEvent.SHIFT_MASK) != 0)
  192. {
  193. switch(ch)
  194. {
  195. case '\n':
  196. case '\t':
  197. case ' ':
  198. return null;
  199. }
  200. }
  201. modifiers = 0;
  202. }
  203. return evt;
  204. //}}}
  205. //{{{ KEY_RELEASED...
  206. case KeyEvent.KEY_RELEASED:
  207. switch(keyCode)
  208. {
  209. case KeyEvent.VK_ALT:
  210. modifiers &= ~InputEvent.ALT_MASK;
  211. lastKeyTime = System.currentTimeMillis();
  212. return null;
  213. case KeyEvent.VK_ALT_GRAPH:
  214. modifiers &= ~InputEvent.ALT_GRAPH_MASK;
  215. return null;
  216. case KeyEvent.VK_CONTROL:
  217. modifiers &= ~InputEvent.CTRL_MASK;
  218. return null;
  219. case KeyEvent.VK_SHIFT:
  220. modifiers &= ~InputEvent.SHIFT_MASK;
  221. return null;
  222. case KeyEvent.VK_META:
  223. modifiers &= ~InputEvent.META_MASK;
  224. return null;
  225. case KeyEvent.VK_LEFT:
  226. case KeyEvent.VK_RIGHT:
  227. /* workaround for A+LEFT/RIGHT producing
  228. * garbage on Windows */
  229. if(modifiers == InputEvent.ALT_MASK)
  230. last = LAST_ALT;
  231. break;
  232. }
  233. return evt;
  234. //}}}
  235. default:
  236. return evt;
  237. }
  238. } //}}}
  239. //{{{ numericKeypadKey() method
  240. /**
  241. * A workaround for non-working NumLock status in some Java versions.
  242. * @since jEdit 4.0pre8
  243. */
  244. public static void numericKeypadKey()
  245. {
  246. System.err.println("yank");
  247. last = LAST_NOTHING;
  248. } //}}}
  249. //{{{ Package-private members
  250. static long lastKeyTime;
  251. static int modifiers;
  252. //}}}
  253. //{{{ Private members
  254. private static int last;
  255. private static final int LAST_NOTHING = 0;
  256. private static final int LAST_NUMKEYPAD = 1;
  257. private static final int LAST_ALT = 2;
  258. //}}}
  259. }