From c04dcc2e7d834218ef2d4194331e383402495ae1 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Wed, 10 Apr 2024 20:07:22 +0200 Subject: Adding upstream version 2:20.4+dfsg. Signed-off-by: Daniel Baumann --- tools/EventClients/lib/java/build.xml | 72 +++++ .../lib/java/src/org/xbmc/eventclient/Packet.java | 289 +++++++++++++++++++ .../src/org/xbmc/eventclient/PacketACTION.java | 61 ++++ .../src/org/xbmc/eventclient/PacketBUTTON.java | 157 ++++++++++ .../java/src/org/xbmc/eventclient/PacketBYE.java | 37 +++ .../java/src/org/xbmc/eventclient/PacketHELO.java | 64 +++++ .../java/src/org/xbmc/eventclient/PacketLOG.java | 48 ++++ .../java/src/org/xbmc/eventclient/PacketMOUSE.java | 45 +++ .../org/xbmc/eventclient/PacketNOTIFICATION.java | 71 +++++ .../java/src/org/xbmc/eventclient/PacketPING.java | 37 +++ .../java/src/org/xbmc/eventclient/XBMCClient.java | 318 +++++++++++++++++++++ 11 files changed, 1199 insertions(+) create mode 100644 tools/EventClients/lib/java/build.xml create mode 100644 tools/EventClients/lib/java/src/org/xbmc/eventclient/Packet.java create mode 100644 tools/EventClients/lib/java/src/org/xbmc/eventclient/PacketACTION.java create mode 100644 tools/EventClients/lib/java/src/org/xbmc/eventclient/PacketBUTTON.java create mode 100644 tools/EventClients/lib/java/src/org/xbmc/eventclient/PacketBYE.java create mode 100644 tools/EventClients/lib/java/src/org/xbmc/eventclient/PacketHELO.java create mode 100644 tools/EventClients/lib/java/src/org/xbmc/eventclient/PacketLOG.java create mode 100644 tools/EventClients/lib/java/src/org/xbmc/eventclient/PacketMOUSE.java create mode 100644 tools/EventClients/lib/java/src/org/xbmc/eventclient/PacketNOTIFICATION.java create mode 100644 tools/EventClients/lib/java/src/org/xbmc/eventclient/PacketPING.java create mode 100644 tools/EventClients/lib/java/src/org/xbmc/eventclient/XBMCClient.java (limited to 'tools/EventClients/lib/java') diff --git a/tools/EventClients/lib/java/build.xml b/tools/EventClients/lib/java/build.xml new file mode 100644 index 0000000..fe25bde --- /dev/null +++ b/tools/EventClients/lib/java/build.xml @@ -0,0 +1,72 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + use: ant dist -Dversion=x.x + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tools/EventClients/lib/java/src/org/xbmc/eventclient/Packet.java b/tools/EventClients/lib/java/src/org/xbmc/eventclient/Packet.java new file mode 100644 index 0000000..09507cb --- /dev/null +++ b/tools/EventClients/lib/java/src/org/xbmc/eventclient/Packet.java @@ -0,0 +1,289 @@ +/* + * Copyright (C) 2008-2013 Team XBMC + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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 for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +package org.xbmc.eventclient; +import java.io.IOException; +import java.net.DatagramPacket; +import java.net.DatagramSocket; +import java.net.InetAddress; + +/** + * XBMC Event Client Class + *

+ * Implementation of XBMC's UDP based input system. + * A set of classes that abstract the various packets that the event server + * currently supports. In addition, there's also a class, XBMCClient, that + * provides functions that sends the various packets. Use XBMCClient if you + * don't need complete control over packet structure. + *

+ *

+ * The basic workflow involves: + *

    + *
  1. Send a HELO packet
  2. + *
  3. Send x number of valid packets
  4. + *
  5. Send a BYE packet
  6. + *
+ *

+ *

+ * IMPORTANT NOTE ABOUT TIMEOUTS: + * A client is considered to be timed out if XBMC doesn't received a packet + * at least once every 60 seconds. To "ping" XBMC with an empty packet use + * PacketPING or XBMCClient.ping(). See the documentation for details. + *

+ *

+ * Base class that implements a single event packet. + * - Generic packet structure (maximum 1024 bytes per packet) + * - Header is 32 bytes long, so 992 bytes available for payload + * - large payloads can be split into multiple packets using H4 and H5 + * H5 should contain total no. of packets in such a case + * - H6 contains length of P1, which is limited to 992 bytes + * - if H5 is 0 or 1, then H4 will be ignored (single packet msg) + * - H7 must be set to zeros for now + *

+ *
+ *   -----------------------------
+ *   | -H1 Signature ("XBMC")    | - 4  x CHAR                4B
+ *   | -H2 Version (eg. 2.0)     | - 2  x UNSIGNED CHAR       2B
+ *   | -H3 PacketType            | - 1  x UNSIGNED SHORT      2B
+ *   | -H4 Sequence number       | - 1  x UNSIGNED LONG       4B
+ *   | -H5 No. of packets in msg | - 1  x UNSIGNED LONG       4B
+ *   | -H6 Payloadsize of packet | - 1  x UNSIGNED SHORT      2B
+ *   | -H7 Client's unique token | - 1  x UNSIGNED LONG       4B
+ *   | -H8 Reserved              | - 10 x UNSIGNED CHAR      10B
+ *   |---------------------------|
+ *   | -P1 payload               | -
+ *   -----------------------------
+ * 
+ * @author Stefan Agner + * + */ +public abstract class Packet { + + private byte[] sig; + private byte[] payload = new byte[0]; + private byte minver; + private byte majver; + + private short packettype; + + + private final static short MAX_PACKET_SIZE = 1024; + private final static short HEADER_SIZE = 32; + private final static short MAX_PAYLOAD_SIZE = MAX_PACKET_SIZE - HEADER_SIZE; + + protected final static byte PT_HELO = 0x01; + protected final static byte PT_BYE = 0x02; + protected final static byte PT_BUTTON = 0x03; + protected final static byte PT_MOUSE = 0x04; + protected final static byte PT_PING = 0x05; + protected final static byte PT_BROADCAST = 0x06; + protected final static byte PT_NOTIFICATION = 0x07; + protected final static byte PT_BLOB = 0x08; + protected final static byte PT_LOG = 0x09; + protected final static byte PT_ACTION = 0x0A; + protected final static byte PT_DEBUG = (byte)0xFF; + + public final static byte ICON_NONE = 0x00; + public final static byte ICON_JPEG = 0x01; + public final static byte ICON_PNG = 0x02; + public final static byte ICON_GIF = 0x03; + + private static int uid = (int)(Math.random()*Integer.MAX_VALUE); + + /** + * This is an Abstract class and cannot be instanced. Please use one of the Packet implementation Classes + * (PacketXXX). + * + * Implements an XBMC Event Client Packet. Type is to be specified at creation time, Payload can be added + * with the various appendPayload methods. Packet can be sent through UDP-Socket with method "send". + * @param packettype Type of Packet (PT_XXX) + */ + protected Packet(short packettype) + { + sig = new byte[] {'X', 'B', 'M', 'C' }; + minver = 0; + majver = 2; + this.packettype = packettype; + } + + /** + * Appends a String to the payload (terminated with 0x00) + * @param payload Payload as String + */ + protected void appendPayload(String payload) + { + byte[] payloadarr = payload.getBytes(); + int oldpayloadsize = this.payload.length; + byte[] oldpayload = this.payload; + this.payload = new byte[oldpayloadsize+payloadarr.length+1]; // Create new Array with more place (+1 for string terminator) + System.arraycopy(oldpayload, 0, this.payload, 0, oldpayloadsize); + System.arraycopy(payloadarr, 0, this.payload, oldpayloadsize, payloadarr.length); + } + + /** + * Appends a single Byte to the payload + * @param payload Payload + */ + protected void appendPayload(byte payload) + { + appendPayload(new byte[] { payload }); + } + + /** + * Appends a Byte-Array to the payload + * @param payloadarr Payload + */ + protected void appendPayload(byte[] payloadarr) + { + int oldpayloadsize = this.payload.length; + byte[] oldpayload = this.payload; + this.payload = new byte[oldpayloadsize+payloadarr.length]; + System.arraycopy(oldpayload, 0, this.payload, 0, oldpayloadsize); + System.arraycopy(payloadarr, 0, this.payload, oldpayloadsize, payloadarr.length); + } + + /** + * Appends an integer to the payload + * @param i Payload + */ + protected void appendPayload(int i) { + appendPayload(intToByteArray(i)); + } + + /** + * Appends a short to the payload + * @param s Payload + */ + protected void appendPayload(short s) { + appendPayload(shortToByteArray(s)); + } + + /** + * Get Number of Packets which will be sent with current Payload... + * @return Number of Packets + */ + public int getNumPackets() + { + return (int)((payload.length + (MAX_PAYLOAD_SIZE - 1)) / MAX_PAYLOAD_SIZE); + } + + /** + * Get Header for a specific Packet in this sequence... + * @param seq Current sequence number + * @param maxseq Maximal sequence number + * @param actpayloadsize Payloadsize of this packet + * @return Byte-Array with Header information (currently 32-Byte long, see HEADER_SIZE) + */ + private byte[] getHeader(int seq, int maxseq, short actpayloadsize) + { + byte[] header = new byte[HEADER_SIZE]; + System.arraycopy(sig, 0, header, 0, 4); + header[4] = majver; + header[5] = minver; + byte[] packettypearr = shortToByteArray(this.packettype); + System.arraycopy(packettypearr, 0, header, 6, 2); + byte[] seqarr = intToByteArray(seq); + System.arraycopy(seqarr, 0, header, 8, 4); + byte[] maxseqarr = intToByteArray(maxseq); + System.arraycopy(maxseqarr, 0, header, 12, 4); + byte[] payloadsize = shortToByteArray(actpayloadsize); + System.arraycopy(payloadsize, 0, header, 16, 2); + byte[] uid = intToByteArray(Packet.uid); + System.arraycopy(uid, 0, header, 18, 4); + byte[] reserved = new byte[10]; + System.arraycopy(reserved, 0, header, 22, 10); + + return header; + } + + /** + * Generates the whole UDP-Message with Header and Payload of a specific Packet in sequence + * @param seq Current sequence number + * @return Byte-Array with UDP-Message + */ + private byte[] getUDPMessage(int seq) + { + int maxseq = (int)((payload.length + (MAX_PAYLOAD_SIZE - 1)) / MAX_PAYLOAD_SIZE); + if(seq > maxseq) + return null; + + short actpayloadsize; + + if(seq == maxseq) + actpayloadsize = (short)(payload.length%MAX_PAYLOAD_SIZE); + + else + actpayloadsize = (short)MAX_PAYLOAD_SIZE; + + byte[] pack = new byte[HEADER_SIZE+actpayloadsize]; + + System.arraycopy(getHeader(seq, maxseq, actpayloadsize), 0, pack, 0, HEADER_SIZE); + System.arraycopy(payload, (seq-1)*MAX_PAYLOAD_SIZE, pack, HEADER_SIZE, actpayloadsize); + + return pack; + } + + /** + * Sends this packet to the EventServer + * @param adr Address of the EventServer + * @param port Port of the EventServer + * @throws IOException + */ + public void send(InetAddress adr, int port) throws IOException + { + int maxseq = getNumPackets(); + DatagramSocket s = new DatagramSocket(); + + // For each Packet in Sequence... + for(int seq=1;seq<=maxseq;seq++) + { + // Get Message and send them... + byte[] pack = getUDPMessage(seq); + DatagramPacket p = new DatagramPacket(pack, pack.length); + p.setAddress(adr); + p.setPort(port); + s.send(p); + } + } + + /** + * Helper Method to convert an integer to a Byte array + * @param value + * @return Byte-Array + */ + private static final byte[] intToByteArray(int value) { + return new byte[] { + (byte)(value >>> 24), + (byte)(value >>> 16), + (byte)(value >>> 8), + (byte)value}; + } + + /** + * Helper Method to convert an short to a Byte array + * @param value + * @return Byte-Array + */ + private static final byte[] shortToByteArray(short value) { + return new byte[] { + (byte)(value >>> 8), + (byte)value}; + } + + +} diff --git a/tools/EventClients/lib/java/src/org/xbmc/eventclient/PacketACTION.java b/tools/EventClients/lib/java/src/org/xbmc/eventclient/PacketACTION.java new file mode 100644 index 0000000..eb597a2 --- /dev/null +++ b/tools/EventClients/lib/java/src/org/xbmc/eventclient/PacketACTION.java @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2008-2013 Team XBMC + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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 for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +package org.xbmc.eventclient; +/** + * XBMC Event Client Class + * + * An ACTION packet tells XBMC to do the action specified, based on the type it knows were it needs to be sent. + * The idea is that this will be as in scripting/skining and keymapping, just triggered from afar. + * @author Stefan Agner + * + */ +public class PacketACTION extends Packet { + + public final static byte ACTION_EXECBUILTIN = 0x01; + public final static byte ACTION_BUTTON = 0x02; + + + /** + * An ACTION packet tells XBMC to do the action specified, based on the type it knows were it needs to be sent. + * @param actionmessage Actionmessage (as in scripting/skinning) + */ + public PacketACTION(String actionmessage) + { + super(PT_ACTION); + byte actiontype = ACTION_EXECBUILTIN; + appendPayload(actionmessage, actiontype); + } + + /** + * An ACTION packet tells XBMC to do the action specified, based on the type it knows were it needs to be sent. + * @param actionmessage Actionmessage (as in scripting/skinning) + * @param actiontype Actiontype (ACTION_EXECBUILTIN or ACTION_BUTTON) + */ + public PacketACTION(String actionmessage, byte actiontype) + { + super(PT_ACTION); + appendPayload(actionmessage, actiontype); + } + + private void appendPayload(String actionmessage, byte actiontype) + { + appendPayload(actiontype); + appendPayload(actionmessage); + } +} diff --git a/tools/EventClients/lib/java/src/org/xbmc/eventclient/PacketBUTTON.java b/tools/EventClients/lib/java/src/org/xbmc/eventclient/PacketBUTTON.java new file mode 100644 index 0000000..de25a2c --- /dev/null +++ b/tools/EventClients/lib/java/src/org/xbmc/eventclient/PacketBUTTON.java @@ -0,0 +1,157 @@ +/* + * Copyright (C) 2008-2013 Team XBMC + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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 for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +package org.xbmc.eventclient; +/** + * XBMC Event Client Class + * + * A button packet send a key press or release event to XBMC + * @author Stefan Agner + * + */ +public class PacketBUTTON extends Packet { + + protected final static byte BT_USE_NAME = 0x01; + protected final static byte BT_DOWN = 0x02; + protected final static byte BT_UP = 0x04; + protected final static byte BT_USE_AMOUNT = 0x08; + protected final static byte BT_QUEUE = 0x10; + protected final static byte BT_NO_REPEAT = 0x20; + protected final static byte BT_VKEY = 0x40; + protected final static byte BT_AXIS = (byte)0x80; + protected final static byte BT_AXISSINGLE = (byte)0x100; + + /** + * A button packet send a key press or release event to XBMC + * @param code raw button code (default: 0) + * @param repeat this key press should repeat until released (default: 1) + * Note that queued pressed cannot repeat. + * @param down if this is 1, it implies a press event, 0 implies a release + * event. (default: 1) + * @param queue a queued key press means that the button event is + * executed just once after which the next key press is processed. + * It can be used for macros. Currently there is no support for + * time delays between queued presses. (default: 0) + * @param amount unimplemented for now; in the future it will be used for + * specifying magnitude of analog key press events + * @param axis + */ + public PacketBUTTON(short code, boolean repeat, boolean down, boolean queue, short amount, byte axis) + { + super(PT_BUTTON); + String map_name = ""; + String button_name = ""; + short flags = 0; + appendPayload(code, map_name, button_name, repeat, down, queue, amount, axis, flags); + } + + /** + * A button packet send a key press or release event to XBMC + * @param map_name a combination of map_name and button_name refers to a + * mapping in the user's Keymap.xml or Lircmap.xml. + * map_name can be one of the following: + * + * @param button_name a button name defined in the map specified in map_name. + * For example, if map_name is "KB" referring to the section in Keymap.xml + * then, valid button_names include "printscreen", "minus", "x", etc. + * @param repeat this key press should repeat until released (default: 1) + * Note that queued pressed cannot repeat. + * @param down if this is 1, it implies a press event, 0 implies a release + * event. (default: 1) + * @param queue a queued key press means that the button event is + * executed just once after which the next key press is processed. + * It can be used for macros. Currently there is no support for + * time delays between queued presses. (default: 0) + * @param amount unimplemented for now; in the future it will be used for + * specifying magnitude of analog key press events + * @param axis + */ + public PacketBUTTON(String map_name, String button_name, boolean repeat, boolean down, boolean queue, short amount, byte axis) + { + super(PT_BUTTON); + short code = 0; + short flags = BT_USE_NAME; + appendPayload(code, map_name, button_name, repeat, down, queue, amount, axis, flags); + } + + /** + * Appends Payload for a Button Packet (this method is used by the different Constructors of this Packet) + * @param code raw button code (default: 0) + * @param map_name a combination of map_name and button_name refers to a + * mapping in the user's Keymap.xml or Lircmap.xml. + * map_name can be one of the following: + *
    + *
  • "KB" => standard keyboard map ( section )
  • + *
  • "XG" => xbox gamepad map ( section )
  • + *
  • "R1" => xbox remote map ( section )
  • + *
  • "R2" => xbox universal remote map ( section )
  • + *
  • "LI:devicename" => LIRC remote map where 'devicename' is the + * actual device's name
+ * @param button_name a button name defined in the map specified in map_name. + * For example, if map_name is "KB" referring to the section in Keymap.xml + * then, valid button_names include "printscreen", "minus", "x", etc. + * @param repeat this key press should repeat until released (default: 1) + * Note that queued pressed cannot repeat. + * @param down if this is 1, it implies a press event, 0 implies a release + * event. (default: 1) + * @param queue a queued key press means that the button event is + * executed just once after which the next key press is processed. + * It can be used for macros. Currently there is no support for + * time delays between queued presses. (default: 0) + * @param amount unimplemented for now; in the future it will be used for + * specifying magnitude of analog key press events + * @param axis + * @param flags Packet specific flags + */ + private void appendPayload(short code, String map_name, String button_name, boolean repeat, boolean down, boolean queue, short amount, byte axis, short flags) + { + if(amount>0) + flags |= BT_USE_AMOUNT; + else + amount = 0; + + if(down) + flags |= BT_DOWN; + else + flags |= BT_UP; + + if(!repeat) + flags |= BT_NO_REPEAT; + + if(queue) + flags |= BT_QUEUE; + + if(axis == 1) + flags |= BT_AXISSINGLE; + else if (axis == 2) + flags |= BT_AXIS; + + + appendPayload(code); + appendPayload(flags); + appendPayload(amount); + appendPayload(map_name); + appendPayload(button_name); + } +} diff --git a/tools/EventClients/lib/java/src/org/xbmc/eventclient/PacketBYE.java b/tools/EventClients/lib/java/src/org/xbmc/eventclient/PacketBYE.java new file mode 100644 index 0000000..e63a2c6 --- /dev/null +++ b/tools/EventClients/lib/java/src/org/xbmc/eventclient/PacketBYE.java @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2008-2013 Team XBMC + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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 for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +package org.xbmc.eventclient; +/** + * XBMC Event Client Class + * + * A BYE packet terminates the connection to XBMC. + * @author Stefan Agner + * + */ +public class PacketBYE extends Packet +{ + + /** + * A BYE packet terminates the connection to XBMC. + */ + public PacketBYE() + { + super(PT_BYE); + } +} diff --git a/tools/EventClients/lib/java/src/org/xbmc/eventclient/PacketHELO.java b/tools/EventClients/lib/java/src/org/xbmc/eventclient/PacketHELO.java new file mode 100644 index 0000000..95e8fa9 --- /dev/null +++ b/tools/EventClients/lib/java/src/org/xbmc/eventclient/PacketHELO.java @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2008-2013 Team XBMC + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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 for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +package org.xbmc.eventclient; +import java.nio.charset.Charset; + +/** + * XBMC Event Client Class + * + * A HELO packet establishes a valid connection to XBMC. It is the + * first packet that should be sent. + * @author Stefan Agner + * + */ +public class PacketHELO extends Packet { + + + /** + * A HELO packet establishes a valid connection to XBMC. + * @param devicename Name of the device which connects to XBMC + */ + public PacketHELO(String devicename) + { + super(PT_HELO); + this.appendPayload(devicename); + this.appendPayload(ICON_NONE); + this.appendPayload((short)0); // port no + this.appendPayload(0); // reserved1 + this.appendPayload(0); // reserved2 + } + + /** + * A HELO packet establishes a valid connection to XBMC. + * @param devicename Name of the device which connects to XBMC + * @param iconType Type of the icon (Packet.ICON_PNG, Packet.ICON_JPEG or Packet.ICON_GIF) + * @param iconData The icon as a Byte-Array + */ + public PacketHELO(String devicename, byte iconType, byte[] iconData) + { + super(PT_HELO); + this.appendPayload(devicename); + this.appendPayload(iconType); + this.appendPayload((short)0); // port no + this.appendPayload(0); // reserved1 + this.appendPayload(0); // reserved2 + this.appendPayload(iconData); // reserved2 + } + +} diff --git a/tools/EventClients/lib/java/src/org/xbmc/eventclient/PacketLOG.java b/tools/EventClients/lib/java/src/org/xbmc/eventclient/PacketLOG.java new file mode 100644 index 0000000..b0d59bb --- /dev/null +++ b/tools/EventClients/lib/java/src/org/xbmc/eventclient/PacketLOG.java @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2008-2013 Team XBMC + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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 for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +package org.xbmc.eventclient; +/** + * XBMC Event Client Class + * + * A LOG packet tells XBMC to log the message to xbmc.log with the loglevel as specified. + * @author Stefan Agner + * + */ +public class PacketLOG extends Packet { + + /** + * A LOG packet tells XBMC to log the message to xbmc.log with the loglevel as specified. + * @param loglevel the loglevel, follows XBMC standard. + *
    + *
  • 0 = DEBUG
  • + *
  • 1 = INFO
  • + *
  • 2 = NOTICE
  • + *
  • 3 = WARNING
  • + *
  • 4 = ERROR
  • + *
  • 5 = SEVERE
  • + *
+ * @param logmessage the message to log + */ + public PacketLOG(byte loglevel, String logmessage) + { + super(PT_LOG); + appendPayload(loglevel); + appendPayload(logmessage); + } +} diff --git a/tools/EventClients/lib/java/src/org/xbmc/eventclient/PacketMOUSE.java b/tools/EventClients/lib/java/src/org/xbmc/eventclient/PacketMOUSE.java new file mode 100644 index 0000000..816e1a7 --- /dev/null +++ b/tools/EventClients/lib/java/src/org/xbmc/eventclient/PacketMOUSE.java @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2008-2013 Team XBMC + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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 for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +package org.xbmc.eventclient; +/** + * XBMC Event Client Class + * + * A MOUSE packets sets the mouse position in XBMC + * @author Stefan Agner + * + */ +public class PacketMOUSE extends Packet { + + protected final static byte MS_ABSOLUTE = 0x01; + + /** + * A MOUSE packets sets the mouse position in XBMC + * @param x horizontal position ranging from 0 to 65535 + * @param y vertical position ranging from 0 to 65535 + */ + public PacketMOUSE(int x, int y) + { + super(PT_MOUSE); + byte flags = 0; + flags |= MS_ABSOLUTE; + appendPayload(flags); + appendPayload((short)x); + appendPayload((short)y); + } +} diff --git a/tools/EventClients/lib/java/src/org/xbmc/eventclient/PacketNOTIFICATION.java b/tools/EventClients/lib/java/src/org/xbmc/eventclient/PacketNOTIFICATION.java new file mode 100644 index 0000000..7089ad6 --- /dev/null +++ b/tools/EventClients/lib/java/src/org/xbmc/eventclient/PacketNOTIFICATION.java @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2008-2013 Team XBMC + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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 for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +package org.xbmc.eventclient; +/** + * XBMC Event Client Class + * + * This packet displays a notification window in XBMC. It can contain + * a caption, a message and an icon. + * @author Stefan Agner + * + */ +public class PacketNOTIFICATION extends Packet { + + /** + * This packet displays a notification window in XBMC. + * @param title Message title + * @param message The actual message + * @param iconType Type of the icon (Packet.ICON_PNG, Packet.ICON_JPEG or Packet.ICON_GIF) + * @param iconData The icon as a Byte-Array + */ + public PacketNOTIFICATION(String title, String message, byte iconType, byte[] iconData) + { + super(PT_NOTIFICATION); + appendPayload(title, message, iconType, iconData); + } + + /** + * This packet displays a notification window in XBMC. + * @param title Message title + * @param message The actual message + */ + public PacketNOTIFICATION(String title, String message) + { + super(PT_NOTIFICATION); + appendPayload(title, message, Packet.ICON_NONE, null); + } + + /** + * Appends the payload to the packet... + * @param title Message title + * @param message The actual message + * @param iconType Type of the icon (Packet.ICON_PNG, Packet.ICON_JPEG or Packet.ICON_GIF) + * @param iconData The icon as a Byte-Array + */ + private void appendPayload(String title, String message, byte iconType, byte[] iconData) + { + appendPayload(title); + appendPayload(message); + appendPayload(iconType); + appendPayload(0); // reserved + if(iconData!=null) + appendPayload(iconData); + + } +} diff --git a/tools/EventClients/lib/java/src/org/xbmc/eventclient/PacketPING.java b/tools/EventClients/lib/java/src/org/xbmc/eventclient/PacketPING.java new file mode 100644 index 0000000..2afbd8d --- /dev/null +++ b/tools/EventClients/lib/java/src/org/xbmc/eventclient/PacketPING.java @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2008-2013 Team XBMC + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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 for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +package org.xbmc.eventclient; +/** + * XBMC Event Client Class + * + * A PING packet tells XBMC that the client is still alive. All valid + * packets act as ping (not just this one). A client needs to ping + * XBMC at least once in 60 seconds or it will time + * @author Stefan Agner + * + */ +public class PacketPING extends Packet { + /** + * A PING packet tells XBMC that the client is still alive. + */ + public PacketPING() + { + super(PT_PING); + } +} diff --git a/tools/EventClients/lib/java/src/org/xbmc/eventclient/XBMCClient.java b/tools/EventClients/lib/java/src/org/xbmc/eventclient/XBMCClient.java new file mode 100644 index 0000000..322ebf1 --- /dev/null +++ b/tools/EventClients/lib/java/src/org/xbmc/eventclient/XBMCClient.java @@ -0,0 +1,318 @@ +/* + * Copyright (C) 2008-2013 Team XBMC + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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 for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +package org.xbmc.eventclient; + +import java.io.FileInputStream; +import java.io.IOException; +import java.net.InetAddress; + +/** + * XBMC Event Client Class + * + * Implements an XBMC-Client. This class can be used to implement your own application which + * should act as a Input device for XBMC. Also starts a Ping-Thread, which tells the XBMC EventServer + * that the client is alive. Therefore if you close your application you SHOULD call stopClient()! + * @author Stefan Agner + * + */ +public class XBMCClient +{ + private boolean hasIcon = false; + private String deviceName; + private PingThread oPingThread; + private byte iconType = Packet.ICON_PNG; + private byte[] iconData; + private InetAddress hostAddress; + private int hostPort; + + /** + * Starts a XBMC EventClient. + * @param hostAddress Address of the Host running XBMC + * @param hostPort Port of the Host running XBMC (default 9777) + * @param deviceName Name of the Device + * @param iconFile Path to the Iconfile (PNG, JPEG or GIF) + * @throws IOException + */ + public XBMCClient(InetAddress hostAddress, int hostPort, String deviceName, String iconFile) throws IOException + { + byte iconType = Packet.ICON_PNG; + // Assume png as icon type + if(iconFile.toLowerCase().endsWith(".jpeg")) + iconType = Packet.ICON_JPEG; + if(iconFile.toLowerCase().endsWith(".jpg")) + iconType = Packet.ICON_JPEG; + if(iconFile.toLowerCase().endsWith(".gif")) + iconType = Packet.ICON_GIF; + + // Read the icon file to the byte array... + FileInputStream iconFileStream = new FileInputStream(iconFile); + byte[] iconData = new byte[iconFileStream.available()]; + iconFileStream.read(iconData); + + hasIcon = true; + + // Call start-Method... + startClient(hostAddress, hostPort, deviceName, iconType, iconData); + } + + + /** + * Starts a XBMC EventClient. + * @param hostAddress Address of the Host running XBMC + * @param hostPort Port of the Host running XBMC (default 9777) + * @param deviceName Name of the Device + * @param iconType Type of the icon file (see Packet.ICON_PNG, Packet.ICON_JPEG or Packet.ICON_GIF) + * @param iconData The icon itself as a Byte-Array + * @throws IOException + */ + public XBMCClient(InetAddress hostAddress, int hostPort, String deviceName, byte iconType, byte[] iconData) throws IOException + { + hasIcon = true; + startClient(hostAddress, hostPort, deviceName, iconType, iconData); + } + + /** + * Starts a XBMC EventClient without an icon. + * @param hostAddress Address of the Host running XBMC + * @param hostPort Port of the Host running XBMC (default 9777) + * @param deviceName Name of the Device + * @throws IOException + */ + public XBMCClient(InetAddress hostAddress, int hostPort, String deviceName) throws IOException + { + hasIcon = false; + byte iconType = Packet.ICON_NONE; + byte[] iconData = null; + startClient(hostAddress, hostPort, deviceName, iconType, iconData); + } + + + /** + * Starts a XBMC EventClient. + * @param hostAddress Address of the Host running XBMC + * @param hostPort Port of the Host running XBMC (default 9777) + * @param deviceName Name of the Device + * @param iconType Type of the icon file (see Packet.ICON_PNG, Packet.ICON_JPEG or Packet.ICON_GIF) + * @param iconData The icon itself as a Byte-Array + * @throws IOException + */ + private void startClient(InetAddress hostAddress, int hostPort, String deviceName, byte iconType, byte[] iconData) throws IOException + { + // Save host address and port + this.hostAddress = hostAddress; + this.hostPort = hostPort; + this.deviceName = deviceName; + + this.iconType = iconType; + this.iconData = iconData; + + // Send Hello Packet... + PacketHELO p; + if(hasIcon) + p = new PacketHELO(deviceName, iconType, iconData); + else + p = new PacketHELO(deviceName); + + p.send(hostAddress, hostPort); + + // Start Thread (for Ping packets...) + oPingThread = new PingThread(hostAddress, hostPort, 20000); + oPingThread.start(); + } + + /** + * Stops the XBMC EventClient (especially the Ping-Thread) + * @throws IOException + */ + public void stopClient() throws IOException + { + // Stop Ping-Thread... + oPingThread.giveup(); + oPingThread.interrupt(); + + PacketBYE p = new PacketBYE(); + p.send(hostAddress, hostPort); + } + + + /** + * Displays a notification window in XBMC. + * @param title Message title + * @param message The actual message + */ + public void sendNotification(String title, String message) throws IOException + { + PacketNOTIFICATION p; + if(hasIcon) + p = new PacketNOTIFICATION(title, message, iconType, iconData); + else + p = new PacketNOTIFICATION(title, message); + p.send(hostAddress, hostPort); + } + + /** + * Sends a Button event + * @param code raw button code (default: 0) + * @param repeat this key press should repeat until released (default: 1) + * Note that queued pressed cannot repeat. + * @param down if this is 1, it implies a press event, 0 implies a release + * event. (default: 1) + * @param queue a queued key press means that the button event is + * executed just once after which the next key press is processed. + * It can be used for macros. Currently there is no support for + * time delays between queued presses. (default: 0) + * @param amount unimplemented for now; in the future it will be used for + * specifying magnitude of analog key press events + * @param axis + */ + public void sendButton(short code, boolean repeat, boolean down, boolean queue, short amount, byte axis) throws IOException + { + PacketBUTTON p = new PacketBUTTON(code, repeat, down, queue, amount, axis); + p.send(hostAddress, hostPort); + } + + /** + * Sends a Button event + * @param map_name a combination of map_name and button_name refers to a + * mapping in the user's Keymap.xml or Lircmap.xml. + * map_name can be one of the following: + *
    + *
  • "KB" => standard keyboard map ( section )
  • + *
  • "XG" => xbox gamepad map ( section )
  • + *
  • "R1" => xbox remote map ( section )
  • + *
  • "R2" => xbox universal remote map ( section )
  • + *
  • "LI:devicename" => LIRC remote map where 'devicename' is the + * actual device's name
+ * @param button_name a button name defined in the map specified in map_name. + * For example, if map_name is "KB" referring to the section in Keymap.xml + * then, valid button_names include "printscreen", "minus", "x", etc. + * @param repeat this key press should repeat until released (default: 1) + * Note that queued pressed cannot repeat. + * @param down if this is 1, it implies a press event, 0 implies a release + * event. (default: 1) + * @param queue a queued key press means that the button event is + * executed just once after which the next key press is processed. + * It can be used for macros. Currently there is no support for + * time delays between queued presses. (default: 0) + * @param amount unimplemented for now; in the future it will be used for + * specifying magnitude of analog key press events + * @param axis + */ + public void sendButton(String map_name, String button_name, boolean repeat, boolean down, boolean queue, short amount, byte axis) throws IOException + { + PacketBUTTON p = new PacketBUTTON(map_name, button_name, repeat, down, queue, amount, axis); + p.send(hostAddress, hostPort); + } + + /** + * Sets the mouse position in XBMC + * @param x horizontal position ranging from 0 to 65535 + * @param y vertical position ranging from 0 to 65535 + */ + public void sendMouse(int x, int y) throws IOException + { + PacketMOUSE p = new PacketMOUSE(x, y); + p.send(hostAddress, hostPort); + } + + /** + * Sends a ping to the XBMC EventServer + * @throws IOException + */ + public void ping() throws IOException + { + PacketPING p = new PacketPING(); + p.send(hostAddress, hostPort); + } + + /** + * Tells XBMC to log the message to xbmc.log with the loglevel as specified. + * @param loglevel the loglevel, follows XBMC standard. + *
    + *
  • 0 = DEBUG
  • + *
  • 1 = INFO
  • + *
  • 2 = NOTICE
  • + *
  • 3 = WARNING
  • + *
  • 4 = ERROR
  • + *
  • 5 = SEVERE
  • + *
+ * @param logmessage the message to log + */ + public void sendLog(byte loglevel, String logmessage) throws IOException + { + PacketLOG p = new PacketLOG(loglevel, logmessage); + p.send(hostAddress, hostPort); + } + + /** + * Tells XBMC to do the action specified, based on the type it knows were it needs to be sent. + * @param actionmessage Actionmessage (as in scripting/skinning) + */ + public void sendAction(String actionmessage) throws IOException + { + PacketACTION p = new PacketACTION(actionmessage); + p.send(hostAddress, hostPort); + } + + /** + * Implements a PingThread which tells XBMC EventServer that the Client is alive (this should + * be done at least every 60 seconds! + * @author Stefan Agner + * + */ + class PingThread extends Thread + { + private InetAddress hostAddress; + private int hostPort; + private int sleepTime; + private boolean giveup = false; + + public PingThread(InetAddress hostAddress, int hostPort, int sleepTime) + { + super("XBMC EventClient Ping-Thread"); + this.hostAddress = hostAddress; + this.hostPort = hostPort; + this.sleepTime = sleepTime; + } + + public void giveup() + { + giveup = true; + } + + public void run() + { + while(!giveup) + { + try { + PacketPING p = new PacketPING(); + p.send(hostAddress, hostPort); + } catch (IOException e) { + + e.printStackTrace(); + } + + try { + Thread.sleep(sleepTime); + } catch (InterruptedException e) { + } + } + } + } +} -- cgit v1.2.3