/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Copyright @ 2015 Atlassian Pty Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.java.sip.communicator.impl.protocol.jabber.extensions.inputevt;
import java.awt.*;
import java.awt.event.*;
import org.jivesoftware.smack.packet.*;
import org.jivesoftware.smack.provider.*;
import org.xmlpull.v1.*;
/**
* This class parses incoming remote-control XML element and extracts
* input events such as keyboard and mouse ones.
*
* @author Sebastien Vincent
*/
public class RemoteControlExtensionProvider
implements PacketExtensionProvider
{
/**
* The name of the remote-info XML element <tt>remote-control</tt>.
*/
public static final String ELEMENT_REMOTE_CONTROL = "remote-control";
/**
* The name of the remote-info XML element <tt>mouse-move</tt>.
*/
public static final String ELEMENT_MOUSE_MOVE = "mouse-move";
/**
* The name of the remote-info XML element <tt>mouse-wheel</tt>.
*/
public static final String ELEMENT_MOUSE_WHEEL = "mouse-wheel";
/**
* The name of the remote-info XML element <tt>mouse-press</tt>.
*/
public static final String ELEMENT_MOUSE_PRESS = "mouse-press";
/**
*The name of the remote-info XML element <tt>mouse-release</tt>.
*/
public static final String ELEMENT_MOUSE_RELEASE = "mouse-release";
/**
* The name of the remote-info XML element <tt>key-press</tt>.
*/
public static final String ELEMENT_KEY_PRESS = "key-press";
/**
* The name of the remote-info XML element <tt>key-release</tt>.
*/
public static final String ELEMENT_KEY_RELEASE = "key-release";
/**
* The name of the remote-info XML element <tt>key-type</tt>.
*/
public static final String ELEMENT_KEY_TYPE = "key-type";
/**
* Namespace of this extension.
*/
public static final String NAMESPACE =
"http://jitsi.org/protocol/inputevt";
/**
* Component to be used in custom generated <tt>MouseEvent</tt> and
* <tt>KeyEvent</tt>.
*/
private static final Component component = new Canvas();
/**
* Constructor.
*/
public RemoteControlExtensionProvider()
{
}
/**
* Parses the extension and returns a <tt>PacketExtension</tt>.
*
* @param parser XML parser
* @return a <tt>PacketExtension</tt> that represents a remote-control
* element.
* @throws Exception if an error occurs during XML parsing
*/
public PacketExtension parseExtension(XmlPullParser parser)
throws Exception
{
RemoteControlExtension result = null;
boolean done = false;
while (!done)
{
try
{
int eventType = parser.next();
if (eventType == XmlPullParser.START_TAG)
{
if(parser.getName().equals(ELEMENT_MOUSE_MOVE))
{
String attr = parser.getAttributeValue("", "x");
String attr2 = parser.getAttributeValue("", "y");
if(attr != null && attr2 != null)
{
int x = (int)(Double.
parseDouble(attr) * 1000);
int y = (int)(Double.
parseDouble(attr2) * 1000);
MouseEvent me = new MouseEvent(component,
MouseEvent.MOUSE_MOVED,
System.currentTimeMillis(),
0, x, y, 0, false, 0);
result = new RemoteControlExtension(me);
continue;
}
}
if(parser.getName().equals(ELEMENT_MOUSE_WHEEL))
{
String attr = parser.getAttributeValue("", "notch");
if(attr != null)
{
MouseWheelEvent me = new MouseWheelEvent(
component, MouseEvent.MOUSE_WHEEL,
System.currentTimeMillis(),
0, 0, 0, 0, false, 0, 0,
Integer.parseInt(attr));
result = new RemoteControlExtension(me);
continue;
}
}
if(parser.getName().equals(ELEMENT_MOUSE_PRESS))
{
String attr = parser.getAttributeValue("", "btns");
if(attr != null)
{
MouseEvent me = new MouseEvent(component,
MouseEvent.MOUSE_PRESSED,
System.currentTimeMillis(),
Integer.parseInt(attr),
0, 0, 0, false, 0);
result = new RemoteControlExtension(me);
continue;
}
}
if(parser.getName().equals(ELEMENT_MOUSE_RELEASE))
{
String attr = parser.getAttributeValue("", "btns");
if(attr != null)
{
MouseEvent me = new MouseEvent(component,
MouseEvent.MOUSE_RELEASED,
System.currentTimeMillis(),
Integer.parseInt(attr),
0, 0, 0, false, 0);
result = new RemoteControlExtension(me);
continue;
}
}
if(parser.getName().equals(ELEMENT_KEY_PRESS))
{
String attr = parser.getAttributeValue("", "keycode");
if(attr != null)
{
KeyEvent ke = new KeyEvent(component,
KeyEvent.KEY_PRESSED,
System.currentTimeMillis(),
0,
Integer.parseInt(attr),
(char)0);
result = new RemoteControlExtension(ke);
continue;
}
}
if(parser.getName().equals(ELEMENT_KEY_RELEASE))
{
String attr = parser.getAttributeValue("", "keycode");
if(attr != null)
{
KeyEvent ke = new KeyEvent(component,
KeyEvent.KEY_RELEASED,
System.currentTimeMillis(),
0,
Integer.parseInt(attr),
(char)0);
result = new RemoteControlExtension(ke);
continue;
}
}
if(parser.getName().equals(ELEMENT_KEY_TYPE))
{
String attr = parser.getAttributeValue("", "keychar");
if(attr != null)
{
KeyEvent ke = new KeyEvent(component,
KeyEvent.KEY_TYPED,
System.currentTimeMillis(),
0,
0,
(char)Integer.parseInt(attr));
result = new RemoteControlExtension(ke);
continue;
}
}
}
else if (eventType == XmlPullParser.END_TAG)
{
if (parser.getName().equals(
RemoteControlExtensionProvider.
ELEMENT_REMOTE_CONTROL))
{
done = true;
}
}
}
catch (Exception e)
{
e.printStackTrace();
}
}
if(result == null)
{
/* we are not allowed to return null otherwise the parser goes
* crazy
*/
result = new RemoteControlExtension(new ComponentEvent(component,
0));
}
return result;
}
/**
* Appends a specific array of <tt>String</tt>s to a specific
* <tt>StringBuffer</tt>.
*
* @param stringBuffer the <tt>StringBuffer</tt> to append the specified
* <tt>strings</tt> to
* @param strings the <tt>String</tt> values to be appended to the specified
* <tt>stringBuffer</tt>
*/
private static void append(StringBuffer stringBuffer, String... strings)
{
for (String str : strings)
stringBuffer.append(str);
}
/**
* Build a key-press remote-control XML element.
*
* @param keycode keyboard's code
* @return raw XML bytes
*/
public static String getKeyPressedXML(int keycode)
{
StringBuffer xml = new StringBuffer();
append(xml, "<" + ELEMENT_REMOTE_CONTROL + " xmlns=\"" + NAMESPACE
+ "\">");
// <key-press>
append(xml, "<", RemoteControlExtensionProvider.ELEMENT_KEY_PRESS);
append(xml, " keycode=\"", Integer.toString(keycode), "\"/>");
append(xml, "</" + ELEMENT_REMOTE_CONTROL + ">");
return xml.toString();
}
/**
* Build a key-release remote-control XML element.
*
* @param keycode keyboard's code
* @return raw XML bytes
*/
public static String getKeyReleasedXML(int keycode)
{
StringBuffer xml = new StringBuffer();
append(xml, "<" + ELEMENT_REMOTE_CONTROL + " xmlns=\"" + NAMESPACE
+ "\">");
// <key-release>
append(xml, "<", RemoteControlExtensionProvider.ELEMENT_KEY_RELEASE);
append(xml, " keycode=\"", Integer.toString(keycode), "\"/>");
append(xml, "</" + ELEMENT_REMOTE_CONTROL + ">");
return xml.toString();
}
/**
* Build a key-typed remote-control XML element.
*
* @param keycode keyboard's code
* @return raw XML bytes
*/
public static String getKeyTypedXML(int keycode)
{
StringBuffer xml = new StringBuffer();
append(xml, "<" + ELEMENT_REMOTE_CONTROL + " xmlns=\"" + NAMESPACE
+ "\">");
// <key-typed>
append(xml, "<", RemoteControlExtensionProvider.ELEMENT_KEY_TYPE);
append(xml, " keychar=\"", Integer.toString(keycode), "\"/>");
append(xml, "</" + ELEMENT_REMOTE_CONTROL + ">");
return xml.toString();
}
/**
* Build a mouse-press remote-control XML element.
*
* @param btns button mask
* @return raw XML bytes
*/
public static String getMousePressedXML(int btns)
{
StringBuffer xml = new StringBuffer();
append(xml, "<" + ELEMENT_REMOTE_CONTROL + " xmlns=\"" + NAMESPACE
+ "\">");
// <mouse-press>
append(xml, "<", RemoteControlExtensionProvider.ELEMENT_MOUSE_PRESS);
append(xml, " btns=\"", Integer.toString(btns), "\"/>");
append(xml, "</" + ELEMENT_REMOTE_CONTROL + ">");
return xml.toString();
}
/**
* Build a remote-info mouse-release remote-control XML element.
*
* @param btns button mask
* @return raw XML bytes
*/
public static String getMouseReleasedXML(int btns)
{
StringBuffer xml = new StringBuffer();
append(xml, "<" + ELEMENT_REMOTE_CONTROL + " xmlns=\"" + NAMESPACE
+ "\">");
// <mouse-release>
append(xml, "<", RemoteControlExtensionProvider.ELEMENT_MOUSE_RELEASE);
append(xml, " btns=\"", Integer.toString(btns), "\"/>");
append(xml, "</" + ELEMENT_REMOTE_CONTROL + ">");
return xml.toString();
}
/**
* Build a remote-info mouse-move remote-control XML element.
*
* @param x x position of the mouse
* @param y y position of the mouse
* @return raw XML bytes
*/
public static String getMouseMovedXML(double x, double y)
{
StringBuffer xml = new StringBuffer();
append(xml, "<" + ELEMENT_REMOTE_CONTROL + " xmlns=\"" + NAMESPACE
+ "\">");
// <mouse-press>
append(xml, "<", RemoteControlExtensionProvider.ELEMENT_MOUSE_MOVE);
append(xml, " x=\"", Double.toString(x), "\" y=\"", Double.toString(y),
"\"/>");
append(xml, "</" + ELEMENT_REMOTE_CONTROL + ">");
return xml.toString();
}
/**
* Build a remote-info mouse-wheel remote-control XML element.
*
* @param notch wheel notch
* @return raw XML bytes
*/
public static String getMouseWheelXML(int notch)
{
StringBuffer xml = new StringBuffer();
append(xml, "<" + ELEMENT_REMOTE_CONTROL + " xmlns=\"" + NAMESPACE
+ "\">");
// <mouse-wheel>
append(xml, "<", RemoteControlExtensionProvider.ELEMENT_MOUSE_WHEEL);
append(xml, " notch=\"", Integer.toString(notch), "\"/>");
append(xml, "</" + ELEMENT_REMOTE_CONTROL + ">");
return xml.toString();
}
}