# java vnc client verbessern: KeyEvent.VK_ALT keine Wirkung?



## jollyroger (14. Mai 2007)

Hallo zusammen, 

ich sitze gerade an folgendem Problem:

Ich versuche den opensource-java-vnc client von ultravnc zu "verbessern".

Dieser hat bisher keine Funktionalität um z.B. eine gedrückte ALT-Taste zu übertragen (um den Fokus auf Menü zu legen).

Genau das möchte ich nun erreichen.

Ich dachte das wäre trivial, ist es aber anscheinend doch nicht.

Schaut man sich mal den Code an, findet man z.B. da sowas wie:



```
switch (evt.getKeyCode()) {

				case KeyEvent.VK_F1 :
					key = 0xffbe;
					break;
```

Drücke ich auf F1 im client geht auch das bekannte Hilfe-Fenster auf, das funktioniert also.

Kommentiere ich nun z.B. den case-Fall aus, mache einen Rebuild und verbinde mich neu zu meinem Testserver, passiert genau das was ich erwarte:

Ein F1-Druck wird nicht mehr übermittelt, sprich es passiert nix.

Dann dachte ich mir, super, das ist ja einfach und hab einfach mal folgende case-Anweisung hinzugefügt:


```
/*		
				 * EDIT
				 */
				// catch the "ALT" key
				case KeyEvent.VK_ALT :
					key = 0xFFE9;
					break;
```

Tja, drücke ich aber nun im Applet "ALT" passiert gar nix.

Den keycode (hier 0xFFE9) hab ich von dieser Seite: klick

Kann mich bitte jemand mal sanft in die richtige Richtung stupsen warum das nicht so einfach geht?

Hier ist noch der komplette relevante Code-Teil, bzw. die Methode:


```
//
	// Write a key event message.  We may need to send modifier key events
	// around it to set the correct modifier state.  Also we need to translate
	// from the Java key values to the X keysym values used by the RFB protocol.
	//

	void writeKeyEvent(KeyEvent evt) throws IOException {
		if (!viewer.ftp.isVisible()) {
		int keyChar = evt.getKeyChar();

		//
		// Ignore event if only modifiers were pressed.
		//

		// Some JVMs return 0 instead of CHAR_UNDEFINED in getKeyChar().
		if (keyChar == 0)
			keyChar = KeyEvent.CHAR_UNDEFINED;

		if (keyChar == KeyEvent.CHAR_UNDEFINED) {
			int code = evt.getKeyCode();
			if (code == KeyEvent.VK_CONTROL
				|| code == KeyEvent.VK_SHIFT
				|| code == KeyEvent.VK_META
				|| code == KeyEvent.VK_ALT)
				return;
		}

		//
		// Key press or key release?
		//

		boolean down = (evt.getID() == KeyEvent.KEY_PRESSED);

		int key;
		if (evt.isActionKey()) {

			//
			// An action key should be one of the following.
			// If not then just ignore the event.
			//

			switch (evt.getKeyCode()) {
				case KeyEvent.VK_HOME :
					key = 0xff50;
					break;
				case KeyEvent.VK_LEFT :
					key = 0xff51;
					break;
				case KeyEvent.VK_UP :
					key = 0xff52;
					break;
				case KeyEvent.VK_RIGHT :
					key = 0xff53;
					break;
				case KeyEvent.VK_DOWN :
					key = 0xff54;
					break;
				case KeyEvent.VK_PAGE_UP :
					key = 0xff55;
					break;
				case KeyEvent.VK_PAGE_DOWN :
					key = 0xff56;
					break;
				case KeyEvent.VK_END :
					key = 0xff57;
					break;
				case KeyEvent.VK_INSERT :
					key = 0xff63;
					break;
				case KeyEvent.VK_F1 :
					key = 0xffbe;
					break;
				case KeyEvent.VK_F2 :
					key = 0xffbf;
					break;
				case KeyEvent.VK_F3 :
					key = 0xffc0;
					break;
				case KeyEvent.VK_F4 :
					key = 0xffc1;
					break;
				case KeyEvent.VK_F5 :
					key = 0xffc2;
					break;
				case KeyEvent.VK_F6 :
					key = 0xffc3;
					break;
				case KeyEvent.VK_F7 :
					key = 0xffc4;
					break;
				case KeyEvent.VK_F8 :
					key = 0xffc5;
					break;
				case KeyEvent.VK_F9 :
					key = 0xffc6;
					break;
				case KeyEvent.VK_F10 :
					key = 0xffc7;
					break;
				case KeyEvent.VK_F11 :
					key = 0xffc8;
					break;
				case KeyEvent.VK_F12 :
					key = 0xffc9;
					break;
				default :
					return;
			}

		} else {

			//
			// A "normal" key press.  Ordinary ASCII characters go straight through.
			// For CTRL-<letter>, CTRL is sent separately so just send <letter>.
			// Backspace, tab, return, escape and delete have special keysyms.
			// Anything else we ignore.
			//

			key = keyChar;

			if (key < 0x20) {
				if (evt.isControlDown()) {
					key += 0x60;
				} else {
					switch (key) {
						case KeyEvent.VK_BACK_SPACE :
							key = 0xff08;
							break;
						case KeyEvent.VK_TAB :
							key = 0xff09;
							break;
						case KeyEvent.VK_ENTER :
							key = 0xff0d;
							break;
						case KeyEvent.VK_ESCAPE :
							key = 0xff1b;
							break;
					}
				}
			} else if (key == 0x7f) {
				// Delete
				key = 0xffff;
			} else if (key > 0xff) {
				// JDK1.1 on X incorrectly passes some keysyms straight through,
				// so we do too.  JDK1.1.4 seems to have fixed this.
				// The keysyms passed are 0xff00 .. XK_BackSpace .. XK_Delete
				if ((key < 0xff00) || (key > 0xffff))
					return;
			}
		}

		// Fake keyPresses for keys that only generates keyRelease events
		if ((key == 0xe5)
			|| (key == 0xc5)
			|| // XK_aring / XK_Aring
		 (key == 0xe4)
			|| (key == 0xc4)
			|| // XK_adiaeresis / XK_Adiaeresis
		 (key == 0xf6)
			|| (key == 0xd6)
			|| // XK_odiaeresis / XK_Odiaeresis
		 (key == 0xa7)
			|| (key == 0xbd)
			|| // XK_section / XK_onehalf
		 (key == 0xa3)) { // XK_sterling
			// Make sure we do not send keypress events twice on platforms
			// with correct JVMs (those that actually report KeyPress for all
			// keys)	
			if (down)
				brokenKeyPressed = true;

			if (!down && !brokenKeyPressed) {
				// We've got a release event for this key, but haven't received
				// a press. Fake it. 
				eventBufLen = 0;
				writeModifierKeyEvents(evt.getModifiers());
				writeKeyEvent(key, true);
				os.write(eventBuf, 0, eventBufLen);
			}

			if (!down)
				brokenKeyPressed = false;
		}

		eventBufLen = 0;
		writeModifierKeyEvents(evt.getModifiers());
		writeKeyEvent(key, down);

		// Always release all modifiers after an "up" event
		if (!down)
			writeModifierKeyEvents(0);

		os.write(eventBuf, 0, eventBufLen);
		}
	}
```


----------



## MQue (14. Mai 2007)

gibts VK_ALT überhaupt, ich habs jetzt auf die schnelle nicht gefunden ind er Tabelle desw Java- Handbuchs.

lg


----------



## jollyroger (14. Mai 2007)

> gibts VK_ALT überhaupt, ich habs jetzt auf die schnelle nicht gefunden ind er Tabelle desw Java- Handbuchs.



Ja, den gibt es. 

Aus der Java-Doc für die Klasse KeyEvent:


```
VK_ALT

public static final int VK_ALT
```


----------



## jollyroger (14. Mai 2007)

Hallo,

nun bin ich ein Stück weiter:

Baue ich ganz am Anfang der Methode ein Stück Code ein:


```
void writeKeyEvent(KeyEvent evt) throws IOException {

		FileWriter logger =  new FileWriter("/home/jollyroger/tmp/vnc.log", true);
		
		if (!viewer.ftp.isVisible()) {

			int keyChar = evt.getKeyChar();

			switch (evt.getKeyCode()) {
				case KeyEvent.VK_F1:
					logger.write("Hit F1 Key!\n");
					break;
				case KeyEvent.VK_WINDOWS:
					logger.write("Hit Windows Super Key!\n");
					break;
					// catch the "ALT" key
				case KeyEvent.VK_ALT:
					logger.write("Hit ALT Key!\n");
					break;	
			}
```

Sehe ich nun in meinem Pseudo-Logfile  die Ausgabe


```
Hit F1 Key!
```

Bei der Windows bzw. der Alt-Taste sehe ich gar nichts, sprich die werden überhaupt nicht verarbeitet?

Wie hab ich denn das zu verstehen?

[/code]


----------



## kleiner_held (14. Mai 2007)

Wo faengst Du denn die Key-Events ab?
Eventuell hat das damit zu tun: java.awt.Component.getFocusTraversalKeysEnabled()


----------



## jollyroger (14. Mai 2007)

Hallo, 

ehrlich gesagt verstehe ich die Erklärung nicht so ganz:



> public boolean getFocusTraversalKeysEnabled()
> 
> Returns whether focus traversal keys are enabled for this Component. Components for which focus traversal keys are disabled receive key events for focus traversal keys. Components for which focus traversal keys are enabled do not see these events; instead, the events are automatically converted to traversal operations.



Was sind denn "focus traversal keys"?

Verwendet wird die oben gepostete Methode in der Klasse VncCanvas:


```
public void processLocalKeyEvent(KeyEvent evt) {
		if (viewer.rfb != null && rfb.inNormalProtocol) {
			if (!inputEnabled) {
				if ((evt.getKeyChar() == 'r' || evt.getKeyChar() == 'R')
					&& evt.getID() == KeyEvent.KEY_PRESSED) {
					// Request screen update.
					try {
						rfb.writeFramebufferUpdateRequest(
							0,
							0,
							rfb.framebufferWidth,
							rfb.framebufferHeight,
							false);
					} catch (IOException e) {
						e.printStackTrace();
					}
				}
			} else {
				// Input enabled.
				synchronized (rfb) {
					try {
						rfb.writeKeyEvent(evt);
					} catch (Exception e) {
						e.printStackTrace();
					}
					rfb.notify();
				}
			}
		}
		// Don't ever pass keyboard events to AWT for default processing. 
		// Otherwise, pressing Tab would switch focus to ButtonPanel etc.
		evt.consume();
	}
```

Was ich auch nicht verstehe, ist:

Schaut man sich die von mir gepostete Methode 


```
void writeKeyEvent(KeyEvent evt) throws IOException {
```

an, sieht man das die Entwickler an diversen Stellen auf "Sondertasten" wie ALT abfragen, wie z.B. hier:


```
if (code == KeyEvent.VK_CONTROL || code == KeyEvent.VK_SHIFT
						|| code == KeyEvent.VK_META || code == KeyEvent.VK_ALT || code == KeyEvent.VK_WINDOWS) {
```

Wenn aber mein vorher erwähnte, von mir eingefügter Code-Block ganz am Anfang der Methode


```
void writeKeyEvent(KeyEvent evt) throws IOException {

		FileWriter logger =  new FileWriter("/home/jollyroger/tmp/vnc.log", true);
		
		if (!viewer.ftp.isVisible()) {

			int keyChar = evt.getKeyChar();

			switch (evt.getKeyCode()) {
				case KeyEvent.VK_F1:
					logger.write("Hit F1 Key!\n");
					break;
				case KeyEvent.VK_WINDOWS:
					logger.write("Hit Windows Super Key!\n");
					break;
					// catch the "ALT" key
				case KeyEvent.VK_ALT:
					logger.write("Hit ALT Key!\n");
					break;	
			}
```

 keine Ausgabe im Logfile erzeugt, dann kann das doch auch im Rest der Methode nicht funktionieren?
Oder überseh ich gerade was Elementares?


----------



## kleiner_held (14. Mai 2007)

Die "focus traversal keys" sind die Sondertasten, die die Focus Aenderung steuern.
Dazu gehoeren mMn Tab und ALT (laesst den Focus ins Menue springen). 

Wenn ein KeyListener an einer Component registriert ist und fuer die Component FocusTraversalKeysEnabled auf true ist, dann kommen KeyEvents, die diese "focus traversal keys" betreffen, gar nicht am KeyListener an.
Die Klasse VncCanvas (ich nehme mal an, dass diese den uebertragenen Desktop-ScreenShot rendert) scheint ein guter Kandidat zu sein um das zu ueberpruefen. Wenn es ein KeyListener an dieser Klasse ist, der processLocalKeyEvent() aufruft, dann ist eventuell setFocusTraversalKeysEnabled(false) an dieser Klasse (z.B.: im Constructor) die Loesung.


----------



## jollyroger (15. Mai 2007)

Hi, 

ich glaube mein Hauptproblem ist, das ich mit AWT leider so gar nicht auskenne.........

Ich hab jetzt mal 


```
setFocusTraversalKeysEnabled(false);
```

im (einzigen) Konstruktor von VNCCanvas hinzugefügt, die Keys kommen leider immer noch nicht an. 

Der Konstruktor sieht nun so aus:


```
VncCanvas(VncViewer v) throws IOException {
		
		setFocusTraversalKeysEnabled(false);

		viewer = v;
		rfb = viewer.rfb;

		tightInflaters = new Inflater[4];

		// sf@2005 - Adding more color modes
		cm8_256c = new DirectColorModel(8, 7, (7 << 3), (3 << 6));
		cm8_64c = new DirectColorModel(8, (3 << 4), (3 << 2), (3 << 0));
		cm8_8c = new DirectColorModel(8, (1 << 2), (1 << 1), (1 << 0));
		
		cm24 = new DirectColorModel(24, 0xFF0000, 0x00FF00, 0x0000FF);

		colors = new Color[256];
		// sf@2005 - Now Default
		for (int i = 0; i < 256; i++)
			colors[i] = new Color(cm8_256c.getRGB(i));

		setPixelFormat();

		inputEnabled = false;
		if (!viewer.options.viewOnly)
			enableInput(true);

		// Keyboard listener is enabled even in view-only mode, to catch
		// 'r' or 'R' key presses used to request screen update.
		addKeyListener(this);
	}
```


----------



## kleiner_held (15. Mai 2007)

wenn da steht

```
addKeyListener(this);
```

dann gibt es in der Klasse die Methoden

```
void 	keyPressed(KeyEvent e)
          Invoked when a key has been pressed.
 void 	keyReleased(KeyEvent e)
          Invoked when a key has been released.
 void 	keyTyped(KeyEvent e)
          Invoked when a key has been typed.
```

Einfach mal den Ablauf von diesen Methoden an verfolgen und schauen ob bei Event-Abarbeitung irgendwo events rausgefiltert werden, bzw an kritischen Stellen einfach mal ein System.out.println(e); einbauen, um zu schauen, ob die KeyEvents ueberhaupt ankommen.


----------



## jollyroger (15. Mai 2007)

Ok, 

jetzt bin ich völlig verwirrt:

In der Klasse VncCanvas sieht das dann so aus:


```
public void keyPressed(KeyEvent evt) {
		processLocalKeyEvent(evt);
	}
	public void keyReleased(KeyEvent evt) {
		processLocalKeyEvent(evt);
	}
	public void keyTyped(KeyEvent evt) {
		evt.consume();
	}
```

keyPressed und keyReleased werden also von processLocalKeyEvent() gehandelt.

processLocalKeyEvent() ruft intern die bereits gepostete writeKeyEvent() auf.

Nun passiert aber etwas merkwürdiges:

Ich modifiziere zunächst mal die processLocalKeyEvent um Debug-Code (spricht nur Ausgabe-Statements):


```
public void processLocalKeyEvent(KeyEvent evt) {
	
		FileWriter logger = null;
		try {
			logger = new FileWriter("/home/jollyroger/tmp/vnc.log", true);
			logger.write("method: processLocalKeyEvent()\n");
			
			switch (evt.getKeyCode()) {
				case KeyEvent.VK_F1:
					logger.write("Hit F1 Key!\n");
					break;
				case KeyEvent.VK_WINDOWS:
					logger.write("Hit Windows Super Key!\n");
					break;
					// catch the "ALT" key
				case KeyEvent.VK_ALT:
					logger.write("Hit ALT Key!\n");
					break;	
				case KeyEvent.VK_CONTROL:
					logger.write("Hit CTRL Key!\n");
					break;						
			}
	
			if (viewer.rfb != null && rfb.inNormalProtocol) {
				if (!inputEnabled) {
					if ((evt.getKeyChar() == 'r' || evt.getKeyChar() == 'R')
						&& (evt.getID() == KeyEvent.KEY_PRESSED)) {
						// Request screen update.
						try {
							logger.write("Entered if!\n");
							rfb.writeFramebufferUpdateRequest(
								0,
								0,
								rfb.framebufferWidth,
								rfb.framebufferHeight,
								false);
						} catch (IOException e) {
							e.printStackTrace();
						}
					}
				} else {
					// Input enabled.
					logger.write("Entered else!\n");
					
					synchronized (rfb) {
						try {
							rfb.writeKeyEvent(evt);
						} catch (Exception e) {
							e.printStackTrace();
						}
						rfb.notify();
					}
				}
			}
			// Don't ever pass keyboard events to AWT for default processing. 
			// Otherwise, pressing Tab would switch focus to ButtonPanel etc.
			evt.consume();
			
			logger.flush();
			logger.close();
		
		}
		catch (IOException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
	}
```

Sowie die writeKeyEvent():


```
void writeKeyEvent(KeyEvent evt) throws IOException {

		FileWriter logger =  new FileWriter("/home/jollyroger/tmp/vnc.log", true);
		logger.write("method: writeKeyEvent()\n");
		
			switch (evt.getKeyCode()) {
				case KeyEvent.VK_F1:
					logger.write("Hit F1 Key!\n");
					break;
				case KeyEvent.VK_WINDOWS:
					logger.write("Hit Windows Super Key!\n");
					break;
					// catch the "ALT" key
				case KeyEvent.VK_ALT:
					logger.write("Hit ALT Key!\n");
					break;	
				case KeyEvent.VK_CONTROL:
					logger.write("Hit CTRL Key!\n");
					break;						
			}
```

Recompile ich nun, rufe den viewer erneut auf und drücke erst "F1", dann "ALT" bzw. "CTRL" auf, sieht die Log-Ausgabe so aus:


```
method: processLocalKeyEvent()
Hit F1 Key!
Entered else!
[color=red]method: writeKeyEvent()
Hit F1 Key![/color]


method: processLocalKeyEvent()
Hit ALT Key!
Entered else!


method: processLocalKeyEvent()
Hit CTRL Key!
Entered else!
```

Wie geht denn das?

Wie ihr seht wird F1 weitergereicht, ALT + CTRL aber nicht?

Aber ich komme doch - wie man am output sieht - direkt hier rein 


```
else {
					// Input enabled.
					logger.write("Entered else!\n");
					
					synchronized (rfb) {
						try {
							rfb.writeKeyEvent(evt);
						} catch (Exception e) {
							e.printStackTrace();
						}
```

und rufe dann ohne Umwege writeKeyEvent() auf?

Dann __MUSS__ ich doch eigentlich die Ausgabe von 


```
logger.write("method: writeKeyEvent()\n");
```

sehen, aber da ist nichts?


----------



## kleiner_held (15. Mai 2007)

Was fuer ein objekt ist dieses *rfb*  an dem das writeKeyEvent(evt); aufgerufen wird?


----------



## jollyroger (15. Mai 2007)

Erst mal danke kleiner_held das du am Ball bleibst........

Ich glaube ich bin dank dir auf der richtigen Spur, es liegt am rfb bzw. an dem synchronized in processLocalKeyEvent(), hab jetzt mal folgende Ausgabe hinzugefügt:


```
} else {
					// Input enabled.
					logger.write("Entered else!\n");
					
					synchronized (rfb) {
						try {
							logger.write("within sync-block, calling writeKeyEvent....");
							rfb.writeKeyEvent(evt);
						} catch (Exception e) {
							logger.write("Exception: ");
							logger.write(e.getMessage());
							e.printStackTrace();
						}
```

Erwartet hätte ich nun eine Ausgabe wie:


```
method: processLocalKeyEvent()
Hit ALT Key!
Entered else!
within sync-block, calling writeKeyEvent....
method: writeKeyEvent()
Hit ALT Key!
```

Aber von wegen


```
method: processLocalKeyEvent()
Hit ALT Key!
Entered else!
within sync-block, calling writeKeyEvent....

method: processLocalKeyEvent()
Hit CTRL Key!
Entered else!
within sync-block, calling writeKeyEvent....
```


 wegen des synchronized (???) wird wohl writeKeyEvent() nicht aufgerufen?

Mir ist  - nach meinem Verständnis von synchronized - allerdings nicht klar warum?



> Was fuer ein objekt ist dieses rfb an dem das writeKeyEvent(evt); aufgerufen wird?



"rfb" ist eine Instanz der Klasse  RfbProto, dies ist die Klasse die die Methode writeKeyEvent() enthält.

Die Methoden, die ich für dieses Problem relevant halte, sind  genau drei, von denen eine "writeKeyEvent()" schon gepostet wurde, ich habs der Vollständigkeit halber nochmal drin(die Klasse hat fast 2000 Zeilen Code, deshalb versuche ich es auf das relevant Aussehende zu beschränken):


```
//
	// Write a key event message. We may need to send modifier key events
	// around it to set the correct modifier state. Also we need to translate
	// from the Java key values to the X keysym values used by the RFB protocol.
	//

	void writeKeyEvent(KeyEvent evt) throws IOException {

		FileWriter logger =  new FileWriter("/home/jollyroger/tmp/vnc.log", true);
		logger.write("method: writeKeyEvent()\n");
		
		if (!viewer.ftp.isVisible()) {

			int keyChar = evt.getKeyChar();

			switch (evt.getKeyCode()) {
				case KeyEvent.VK_F1:
					logger.write("Hit F1 Key!\n");
					break;
				case KeyEvent.VK_WINDOWS:
					logger.write("Hit Windows Super Key!\n");
					break;
					// catch the "ALT" key
				case KeyEvent.VK_ALT:
					logger.write("Hit ALT Key!\n");
					break;	
				case KeyEvent.VK_CONTROL:
					logger.write("Hit CTRL Key!\n");
					break;						
			}

			
			//
			// Ignore event if only modifiers were pressed.
			//

			// Some JVMs return 0 instead of CHAR_UNDEFINED in getKeyChar().
			if (keyChar == 0)
				keyChar = KeyEvent.CHAR_UNDEFINED;

			if (keyChar == KeyEvent.CHAR_UNDEFINED) {
				int code = evt.getKeyCode();

				if (code == KeyEvent.VK_CONTROL || code == KeyEvent.VK_SHIFT
						|| code == KeyEvent.VK_META || code == KeyEvent.VK_ALT || code == KeyEvent.VK_WINDOWS) {
				    
					logger.write("Hit special key!");
					logger.write("Hit special key!" + evt.getKeyChar());
				
					return;
				}
			}

			//
			// Key press or key release?
			//

			boolean down = (evt.getID() == KeyEvent.KEY_PRESSED);

			int key;
			if (evt.isActionKey()) {

				//
				// An action key should be one of the following.
				// If not then just ignore the event.
				//

				switch (evt.getKeyCode()) {
				case KeyEvent.VK_HOME:
					key = 0xff50;
					break;
				case KeyEvent.VK_LEFT:
					key = 0xff51;
					break;
				case KeyEvent.VK_UP:
					key = 0xff52;
					break;
				case KeyEvent.VK_RIGHT:
					key = 0xff53;
					break;
				case KeyEvent.VK_DOWN:
					key = 0xff54;
					break;
				case KeyEvent.VK_PAGE_UP:
					key = 0xff55;
					break;
				case KeyEvent.VK_PAGE_DOWN:
					key = 0xff56;
					break;
				case KeyEvent.VK_END:
					key = 0xff57;
					break;
				case KeyEvent.VK_INSERT:
					key = 0xff63;
					break;
				case KeyEvent.VK_F1:
					key = 0xffbe;
					break;
				case KeyEvent.VK_F2:
					key = 0xffbf;
					break;
				case KeyEvent.VK_F3:
					key = 0xffc0;
					break;
				case KeyEvent.VK_F4:
					key = 0xffc1;
					break;
				case KeyEvent.VK_F5:
					key = 0xffc2;
					break;
				case KeyEvent.VK_F6:
					key = 0xffc3;
					break;
				case KeyEvent.VK_F7:
					key = 0xffc4;
					break;
				case KeyEvent.VK_F8:
					key = 0xffc5;
					break;
				case KeyEvent.VK_F9:
					key = 0xffc6;
					break;
				case KeyEvent.VK_F10:
					key = 0xffc7;
					break;
				case KeyEvent.VK_F11:
					key = 0xffc8;
					break;
				case KeyEvent.VK_F12:
					key = 0xffc9;
					break;

				// catch the "ALT" key
				case KeyEvent.VK_WINDOWS:
					logger.write("Hit Windows Super Key!\n");
					key = 0xFFEB;
					break;
					// catch the "ALT" key
				case KeyEvent.VK_ALT:
					logger.write("Hit ALT Key!\n");
					key = 0xFFE9;
					break;	

				default:
					return;
				}

			} else {

				//
				// A "normal" key press. Ordinary ASCII characters go straight
				// through.
				// For CTRL-<letter>, CTRL is sent separately so just send
				// <letter>.
				// Backspace, tab, return, escape and delete have special
				// keysyms.
				// Anything else we ignore.
				//

				key = keyChar;

				if (key < 0x20) {
					if (evt.isControlDown()) {
						key += 0x60;
					} else {
						switch (key) {
						case KeyEvent.VK_BACK_SPACE:
							key = 0xff08;
							break;

						case KeyEvent.VK_TAB:
							key = 0xff09;
							break;
						case KeyEvent.VK_ENTER:
							key = 0xff0d;
							break;
						case KeyEvent.VK_ESCAPE:
							key = 0xff1b;
							break;

						// catch the "ALT" key
						case KeyEvent.VK_ALT:
							key = 0xFFE9;
							break;
						}
					}
				} else if (key == 0x7f) {
					// Delete
					key = 0xffff;
				} else if (key > 0xff) {
					// JDK1.1 on X incorrectly passes some keysyms straight
					// through,
					// so we do too. JDK1.1.4 seems to have fixed this.
					// The keysyms passed are 0xff00 .. XK_BackSpace ..
					// XK_Delete
					if ((key < 0xff00) || (key > 0xffff))
						return;
				}
			}

			// Fake keyPresses for keys that only generates keyRelease events
			if ((key == 0xe5) || (key == 0xc5) || // XK_aring / XK_Aring
					(key == 0xe4) || (key == 0xc4) || // XK_adiaeresis /
														// XK_Adiaeresis
					(key == 0xf6) || (key == 0xd6) || // XK_odiaeresis /
														// XK_Odiaeresis
					(key == 0xa7) || (key == 0xbd) || // XK_section /
														// XK_onehalf
					(key == 0xa3)) { // XK_sterling
				// Make sure we do not send keypress events twice on platforms
				// with correct JVMs (those that actually report KeyPress for
				// all
				// keys)
				if (down)
					brokenKeyPressed = true;

				if (!down && !brokenKeyPressed) {
					// We've got a release event for this key, but haven't
					// received
					// a press. Fake it.
					eventBufLen = 0;
					writeModifierKeyEvents(evt.getModifiers());
					writeKeyEvent(key, true);
					os.write(eventBuf, 0, eventBufLen);
				}

				if (!down)
					brokenKeyPressed = false;
			}

			eventBufLen = 0;
			writeModifierKeyEvents(evt.getModifiers());
			writeKeyEvent(key, down);

			// Always release all modifiers after an "up" event
			if (!down)
				writeModifierKeyEvents(0);

			os.write(eventBuf, 0, eventBufLen);
		}
		
		logger.flush();
		logger.close();
	}
```


```
//
	// Add a raw key event with the given X keysym to eventBuf.
	//

	void writeKeyEvent(int keysym, boolean down) {
		eventBuf[eventBufLen++] = (byte) KeyboardEvent;
		eventBuf[eventBufLen++] = (byte) (down ? 1 : 0);
		eventBuf[eventBufLen++] = (byte) 0;
		eventBuf[eventBufLen++] = (byte) 0;
		eventBuf[eventBufLen++] = (byte) ((keysym >> 24) & 0xff);
		eventBuf[eventBufLen++] = (byte) ((keysym >> 16) & 0xff);
		eventBuf[eventBufLen++] = (byte) ((keysym >> 8) & 0xff);
		eventBuf[eventBufLen++] = (byte) (keysym & 0xff);
	}
```


```
//
	// Write key events to set the correct modifier state.
	//

	int oldModifiers = 0;

	void writeModifierKeyEvents(int newModifiers) {
		if ((newModifiers & CTRL_MASK) != (oldModifiers & CTRL_MASK))
			writeKeyEvent(0xffe3, (newModifiers & CTRL_MASK) != 0);

		if ((newModifiers & SHIFT_MASK) != (oldModifiers & SHIFT_MASK))
			writeKeyEvent(0xffe1, (newModifiers & SHIFT_MASK) != 0);

		if ((newModifiers & META_MASK) != (oldModifiers & META_MASK))
			writeKeyEvent(0xffe7, (newModifiers & META_MASK) != 0);

		if ((newModifiers & ALT_MASK) != (oldModifiers & ALT_MASK))
			writeKeyEvent(0xffe9, (newModifiers & ALT_MASK) != 0);

		oldModifiers = newModifiers;
	}
```

Hmm, leider sehe ich da nichts was mir irgendwie weiterhelfen würde.....


----------



## kleiner_held (15. Mai 2007)

Hmm ich glaube du solltest am besten mal mit dem Debugger durchgehen. 
Breakpoint am logger.write("Entered else!\n");  und dann schrittweise durch.


----------

