Fix HID issues
Mixed type HID report descriptor in the current trunk doesn't work
well so this patch fixes the HID creation logic to make it use
composite configuration which has separated keyboard and mouse
HID descriptor using a single USB port.
ikvm service also should be changed using below setting after
applying this patch:
ExecStart=/usr/bin/env obmc-ikvm -v /dev/video0 -k /dev/hidg0 -p /dev/hidg1
Change-Id: I9b2975f4fdade2c6030def829951d02b24bea562
Signed-off-by: Jae Hyun Yoo <jae.hyun.yoo@linux.intel.com>
diff --git a/create_usbhid.sh b/create_usbhid.sh
index c4d9d71..6562991 100644
--- a/create_usbhid.sh
+++ b/create_usbhid.sh
@@ -14,10 +14,6 @@
# add basic information
echo 0x0100 > bcdDevice
echo 0x0200 > bcdUSB
-echo 0x00 > bDeviceClass
-echo 0x00 > bDeviceProtocol
-echo 0x00 > bDeviceSubClass
-echo 0x0b > bMaxPacketSize0
echo 0x0104 > idProduct # Multifunction Composite Gadget
echo 0x1d6b > idVendor # Linux Foundation
@@ -28,15 +24,88 @@
echo "virtual_input" > strings/0x409/product
echo "OBMC0001" > strings/0x409/serialnumber
-# Create HID function
-mkdir functions/hid.usb0
+# Create HID keyboard function
+mkdir functions/hid.0
-echo 1 > functions/hid.usb0/protocol
-echo 11 > functions/hid.usb0/report_length
-echo 1 > functions/hid.usb0/subclass
+echo 1 > functions/hid.0/protocol # 1: keyboard
+echo 8 > functions/hid.0/report_length
+echo 1 > functions/hid.0/subclass
-# Binary HID descriptor
-echo -n -e '\x05\x01\x09\x06\xa1\x01\x85\x01\x05\x07\x19\xe0\x29\xe7\x15\x00\x25\x01\x95\x08\x75\x01\x81\x02\x95\x01\x75\x08\x81\x01\x95\x05\x75\x08\x15\x01\x25\x7f\x05\x07\x19\x01\x29\x7f\x81\x00\xc0\x05\x01\x09\x02\xa1\x01\x85\x02\x09\x01\xa1\x00\x05\x09\x19\x01\x29\x03\x15\x00\x25\x01\x95\x03\x75\x01\x81\x02\x95\x01\x75\x05\x81\x03\x05\x01\x09\x30\x09\x31\x35\x00\x46\xff\x7f\x15\x00\x26\xff\x7f\x75\x10\x95\x02\x81\x02\xc0\xc0' > functions/hid.usb0/report_desc
+# Binary HID keyboard descriptor
+# 0x05, 0x01, // USAGE_PAGE (Generic Desktop)
+# 0x09, 0x06, // USAGE (Keyboard)
+# 0xa1, 0x01, // COLLECTION (Application)
+# 0x05, 0x07, // USAGE_PAGE (Keyboard)
+# 0x19, 0xe0, // USAGE_MINIMUM (Keyboard LeftControl)
+# 0x29, 0xe7, // USAGE_MAXIMUM (Keyboard Right GUI)
+# 0x15, 0x00, // LOGICAL_MINIMUM (0)
+# 0x25, 0x01, // LOGICAL_MAXIMUM (1)
+# 0x75, 0x01, // REPORT_SIZE (1)
+# 0x95, 0x08, // REPORT_COUNT (8)
+# 0x81, 0x02, // INPUT (Data,Var,Abs)
+# 0x95, 0x01, // REPORT_COUNT (1)
+# 0x75, 0x08, // REPORT_SIZE (8)
+# 0x81, 0x03, // INPUT (Data,Var,Abs)
+# 0x95, 0x05, // REPORT_COUNT (5)
+# 0x75, 0x01, // REPORT_SIZE (1)
+# 0x05, 0x08, // USAGE_PAGE (LEDs)
+# 0x19, 0x01, // USAGE_MINIMUM (Num Lock)
+# 0x29, 0x05, // USAGE_MAXIMUM (Kana)
+# 0x91, 0x02, // OUTPUT (Data,Var,Abs)
+# 0x95, 0x01, // REPORT_COUNT (1)
+# 0x75, 0x03, // REPORT_SIZE (3)
+# 0x91, 0x03, // OUTPUT (Cnst,Var,Abs)
+# 0x95, 0x06, // REPORT_COUNT (6)
+# 0x75, 0x08, // REPORT_SIZE (8)
+# 0x15, 0x00, // LOGICAL_MINIMUM (0)
+# 0x25, 0x65, // LOGICAL_MAXIMUM (101)
+# 0x05, 0x07, // USAGE_PAGE (Keyboard)
+# 0x19, 0x00, // USAGE_MINIMUM (Reserved (no event indicated))
+# 0x29, 0x65, // USAGE_MAXIMUM (Keyboard Application)
+# 0x81, 0x00, // INPUT (Data,Ary,Abs)
+# 0xc0 // END_COLLECTION
+echo -ne '\x05\x01\x09\x06\xa1\x01\x05\x07\x19\xe0\x29\xe7\x15\x00\x25\x01\x75\x01\x95\x08\x81\x02\x95\x01\x75\x08\x81\x03\x95\x05\x75\x01\x05\x08\x19\x01\x29\x05\x91\x02\x95\x01\x75\x03\x91\x03\x95\x06\x75\x08\x15\x00\x25\x65\x05\x07\x19\x00\x29\x65\x81\x00\xc0' > functions/hid.0/report_desc
+
+# Create HID mouse function
+mkdir functions/hid.1
+
+echo 2 > functions/hid.1/protocol # 2: mouse
+echo 5 > functions/hid.1/report_length
+echo 1 > functions/hid.1/subclass
+
+# Binary HID mouse descriptor (absolute coordinate)
+# 0x05, 0x01, // USAGE_PAGE (Generic Desktop)
+# 0x09, 0x02, // USAGE (Mouse)
+# 0xa1, 0x01, // COLLECTION (Application)
+# 0x09, 0x01, // USAGE (Pointer)
+# 0xa1, 0x00, // COLLECTION (Physical)
+# 0x05, 0x09, // USAGE_PAGE (Button)
+# 0x19, 0x01, // USAGE_MINIMUM (Button 1)
+# 0x29, 0x03, // USAGE_MAXIMUM (Button 3)
+# 0x15, 0x00, // LOGICAL_MINIMUM (0)
+# 0x25, 0x01, // LOGICAL_MAXIMUM (1)
+# 0x95, 0x03, // REPORT_COUNT (3)
+# 0x75, 0x01, // REPORT_SIZE (1)
+# 0x81, 0x02, // INPUT (Data,Var,Abs)
+# 0x95, 0x01, // REPORT_COUNT (1)
+# 0x75, 0x05, // REPORT_SIZE (5)
+# 0x81, 0x03, // INPUT (Cnst,Var,Abs)
+# 0x05, 0x01, // USAGE_PAGE (Generic Desktop)
+# 0x09, 0x30, // USAGE (X)
+# 0x09, 0x31, // USAGE (Y)
+# 0x35, 0x00, // PHYSICAL_MINIMUM (0)
+# 0x46, 0xff, 0x7f, // PHYSICAL_MAXIMUM (32767)
+# 0x15, 0x00, // LOGICAL_MINIMUM (0)
+# 0x26, 0xff, 0x7f, // LOGICAL_MAXIMUM (32767)
+# 0x65, 0x11, // UNIT (SI Lin:Distance)
+# 0x55, 0x00, // UNIT_EXPONENT (0)
+# 0x75, 0x10, // REPORT_SIZE (16)
+# 0x95, 0x02, // REPORT_COUNT (2)
+# 0x81, 0x02, // INPUT (Data,Var,Abs)
+# 0xc0, // END_COLLECTION
+# 0xc0 // END_COLLECTION
+echo -ne '\x05\x01\x09\x02\xa1\x01\x09\x01\xa1\x00\x05\x09\x19\x01\x29\x03\x15\x00\x25\x01\x95\x03\x75\x01\x81\x02\x95\x01\x75\x05\x81\x03\x05\x01\x09\x30\x09\x31\x35\x00\x46\xff\x7f\x15\x00\x26\xff\x7f\x65\x11\x55\x00\x75\x10\x95\x02\x81\x02\xc0\xc0' > functions/hid.1/report_desc
+
# Create configuration
mkdir configs/c.1
mkdir configs/c.1/strings/0x409
@@ -45,8 +114,9 @@
echo 200 > configs/c.1/MaxPower
echo "" > configs/c.1/strings/0x409/configuration
-# Link HID function to configuration
-ln -s functions/hid.usb0 configs/c.1
+# Link HID functions to configuration
+ln -s functions/hid.0 configs/c.1
+ln -s functions/hid.1 configs/c.1
# Enable gadget
dev_name="1e6a0000.usb-vhub"
diff --git a/ikvm_args.cpp b/ikvm_args.cpp
index 61a773a..ad5b4f7 100644
--- a/ikvm_args.cpp
+++ b/ikvm_args.cpp
@@ -11,10 +11,11 @@
Args::Args(int argc, char* argv[]) : frameRate(30), commandLine(argc, argv)
{
int option;
- const char* opts = "f:hi:v:";
+ const char* opts = "f:h:k:p:v:";
struct option lopts[] = {{"frameRate", 1, 0, 'f'},
{"help", 0, 0, 'h'},
- {"input", 1, 0, 'i'},
+ {"keyboard", 1, 0, 'k'},
+ {"mouse", 1, 0, 'p'},
{"videoDevice", 1, 0, 'v'},
{0, 0, 0, 0}};
@@ -30,8 +31,11 @@
case 'h':
printUsage();
exit(0);
- case 'i':
- inputPath = std::string(optarg);
+ case 'k':
+ keyboardPath = std::string(optarg);
+ break;
+ case 'p':
+ pointerPath = std::string(optarg);
break;
case 'v':
videoPath = std::string(optarg);
@@ -47,7 +51,8 @@
fprintf(stderr, "Usage: obmc-ikvm [options]\n");
fprintf(stderr, "-f frame rate try this frame rate\n");
fprintf(stderr, "-h, --help show this message and exit\n");
- fprintf(stderr, "-i device HID gadget device\n");
+ fprintf(stderr, "-k device HID keyboard gadget device\n");
+ fprintf(stderr, "-p device HID mouse gadget device\n");
fprintf(stderr, "-v device V4L2 device\n");
rfbUsage();
}
diff --git a/ikvm_args.hpp b/ikvm_args.hpp
index 489718b..f877d32 100644
--- a/ikvm_args.hpp
+++ b/ikvm_args.hpp
@@ -72,13 +72,23 @@
}
/*
- * @brief Get the path to the USB input device
+ * @brief Get the path to the USB keyboard device
*
- * @return Reference to the string storing the path to the input device
+ * @return Reference to the string storing the path to the keyboard device
*/
- inline const std::string& getInputPath() const
+ inline const std::string& getKeyboardPath() const
{
- return inputPath;
+ return keyboardPath;
+ }
+
+ /*
+ * @brief Get the path to the USB mouse device
+ *
+ * @return Reference to the string storing the path to the mouse device
+ */
+ inline const std::string& getPointerPath() const
+ {
+ return pointerPath;
}
/*
@@ -100,8 +110,10 @@
* stream
*/
int frameRate;
- /* @brief Path to the USB input device */
- std::string inputPath;
+ /* @brief Path to the USB keyboard device */
+ std::string keyboardPath;
+ /* @brief Path to the USB mouse device */
+ std::string pointerPath;
/* @brief Path to the V4L2 video device */
std::string videoPath;
/* @brief Original command line arguments passed to the application */
diff --git a/ikvm_input.cpp b/ikvm_input.cpp
index 31a7be4..6c17296 100644
--- a/ikvm_input.cpp
+++ b/ikvm_input.cpp
@@ -14,7 +14,7 @@
#include <phosphor-logging/log.hpp>
#include <xyz/openbmc_project/Common/File/error.hpp>
-#include "scancodes.h"
+#include "scancodes.hpp"
namespace ikvm
{
@@ -22,45 +22,50 @@
using namespace phosphor::logging;
using namespace sdbusplus::xyz::openbmc_project::Common::File::Error;
-const char Input::keyboardID = 1;
-const char Input::pointerID = 2;
-
-const char Input::shiftCtrlMap[NUM_MODIFIER_BITS] = {
- 0x02, // left shift
- 0x20, // right shift
- 0x01, // left control
- 0x10 // right control
-};
-
-const char Input::metaAltMap[NUM_MODIFIER_BITS] = {
- 0x08, // left meta
- (char)0x80, // right meta
- 0x04, // left alt
- 0x40 // right alt
-};
-
-Input::Input(const std::string& p) :
- keyboardReport{0}, pointerReport{0}, path(p)
+Input::Input(const std::string& kbdPath, const std::string& ptrPath) :
+ keyboardFd(-1), pointerFd(-1), keyboardReport{0}, pointerReport{0},
+ keyboardPath(kbdPath), pointerPath(ptrPath)
{
- fd = open(path.c_str(), O_RDWR);
- if (fd < 0)
+ if (!keyboardPath.empty())
{
- log<level::ERR>("Failed to open input device",
- entry("PATH=%s", path.c_str()),
- entry("ERROR=%s", strerror(errno)));
- elog<Open>(
- xyz::openbmc_project::Common::File::Open::ERRNO(errno),
- xyz::openbmc_project::Common::File::Open::PATH(path.c_str()));
+ keyboardFd = open(keyboardPath.c_str(), O_RDWR | O_CLOEXEC);
+ if (keyboardFd < 0)
+ {
+ log<level::ERR>("Failed to open input device",
+ entry("PATH=%s", keyboardPath.c_str()),
+ entry("ERROR=%s", strerror(errno)));
+ elog<Open>(xyz::openbmc_project::Common::File::Open::ERRNO(errno),
+ xyz::openbmc_project::Common::File::Open::PATH(
+ keyboardPath.c_str()));
+ }
}
- // set the HID identifier byte because device is combined pointer/keyboard
- keyboardReport[0] = keyboardID;
- pointerReport[0] = pointerID;
+ if (!pointerPath.empty())
+ {
+ pointerFd = open(pointerPath.c_str(), O_RDWR | O_CLOEXEC);
+ if (pointerFd < 0)
+ {
+ log<level::ERR>("Failed to open input device",
+ entry("PATH=%s", pointerPath.c_str()),
+ entry("ERROR=%s", strerror(errno)));
+ elog<Open>(xyz::openbmc_project::Common::File::Open::ERRNO(errno),
+ xyz::openbmc_project::Common::File::Open::PATH(
+ pointerPath.c_str()));
+ }
+ }
}
Input::~Input()
{
- close(fd);
+ if (keyboardFd >= 0)
+ {
+ close(keyboardFd);
+ }
+
+ if (pointerFd >= 0)
+ {
+ close(pointerFd);
+ }
}
void Input::keyEvent(rfbBool down, rfbKeySym key, rfbClientPtr cl)
@@ -70,13 +75,13 @@
if (down)
{
- char sc = keyToScancode(key);
+ uint8_t sc = keyToScancode(key);
if (sc)
{
if (input->keysDown.find(key) == input->keysDown.end())
{
- for (unsigned int i = 3; i < REPORT_LENGTH; ++i)
+ for (unsigned int i = 2; i < KEY_REPORT_LENGTH; ++i)
{
if (!input->keyboardReport[i])
{
@@ -90,11 +95,11 @@
}
else
{
- char mod = keyToMod(key);
+ uint8_t mod = keyToMod(key);
if (mod)
{
- input->keyboardReport[1] |= mod;
+ input->keyboardReport[0] |= mod;
input->sendKeyboard = true;
}
}
@@ -111,11 +116,11 @@
}
else
{
- char mod = keyToMod(key);
+ uint8_t mod = keyToMod(key);
if (mod)
{
- input->keyboardReport[1] &= ~mod;
+ input->keyboardReport[0] &= ~mod;
input->sendKeyboard = true;
}
}
@@ -129,29 +134,40 @@
Server* server = (Server*)cl->screen->screenData;
const Video& video = server->getVideo();
- input->pointerReport[1] = buttonMask & 0xFF;
+ input->pointerReport[0] = buttonMask & 0xFF;
if (x >= 0 && (unsigned int)x < video.getWidth())
{
- unsigned short xx = x * ((SHRT_MAX + 1) / video.getWidth());
+ uint16_t xx = x * ((SHRT_MAX + 1) / video.getWidth());
- memcpy(&input->pointerReport[2], &xx, 2);
+ memcpy(&input->pointerReport[1], &xx, 2);
}
if (y >= 0 && (unsigned int)y < video.getHeight())
{
- unsigned short yy = y * ((SHRT_MAX + 1) / video.getHeight());
+ uint16_t yy = y * ((SHRT_MAX + 1) / video.getHeight());
- memcpy(&input->pointerReport[4], &yy, 2);
+ memcpy(&input->pointerReport[3], &yy, 2);
}
input->sendPointer = true;
rfbDefaultPtrAddEvent(buttonMask, x, y, cl);
}
-void Input::sendRaw(char* data, int size)
+void Input::sendWakeupPacket()
{
- if (write(fd, data, size) != size)
+ uint8_t wakeupReport[PTR_REPORT_LENGTH] = {0};
+ uint16_t xy = SHRT_MAX / 2;
+
+ if (pointerFd < 0)
+ {
+ return;
+ }
+
+ memcpy(&wakeupReport[1], &xy, 2);
+ memcpy(&wakeupReport[3], &xy, 2);
+
+ if (write(pointerFd, wakeupReport, PTR_REPORT_LENGTH) != PTR_REPORT_LENGTH)
{
log<level::ERR>("Failed to write report",
entry("ERROR=%s", strerror(errno)));
@@ -160,9 +176,10 @@
void Input::sendReport()
{
- if (sendKeyboard)
+ if (sendKeyboard && keyboardFd >= 0)
{
- if (write(fd, keyboardReport, REPORT_LENGTH) != REPORT_LENGTH)
+ if (write(keyboardFd, keyboardReport, KEY_REPORT_LENGTH) !=
+ KEY_REPORT_LENGTH)
{
log<level::ERR>("Failed to write keyboard report",
entry("ERROR=%s", strerror(errno)));
@@ -171,9 +188,10 @@
sendKeyboard = false;
}
- if (sendPointer)
+ if (sendPointer && pointerFd >= 0)
{
- if (write(fd, pointerReport, POINTER_LENGTH) != POINTER_LENGTH)
+ if (write(pointerFd, pointerReport, PTR_REPORT_LENGTH) !=
+ PTR_REPORT_LENGTH)
{
log<level::ERR>("Failed to write pointer report",
entry("ERROR=%s", strerror(errno)));
@@ -183,9 +201,9 @@
}
}
-char Input::keyToMod(rfbKeySym key)
+uint8_t Input::keyToMod(rfbKeySym key)
{
- char mod = 0;
+ uint8_t mod = 0;
if (key >= XK_Shift_L && key <= XK_Control_R)
{
@@ -199,9 +217,9 @@
return mod;
}
-char Input::keyToScancode(rfbKeySym key)
+uint8_t Input::keyToScancode(rfbKeySym key)
{
- char scancode = 0;
+ uint8_t scancode = 0;
if ((key >= 'A' && key <= 'Z') || (key >= 'a' && key <= 'z'))
{
diff --git a/ikvm_input.hpp b/ikvm_input.hpp
index 7c8120d..f7413a4 100644
--- a/ikvm_input.hpp
+++ b/ikvm_input.hpp
@@ -19,9 +19,10 @@
/*
* @brief Constructs Input object
*
- * @param[in] p - Path to the USB input device
+ * @param[in] kbdPath - Path to the USB keyboard device
+ * @param[in] ptrPath - Path to the USB mouse device
*/
- Input(const std::string& p);
+ Input(const std::string& kbdPath, const std::string& ptrPath);
~Input();
Input(const Input&) = default;
Input& operator=(const Input&) = default;
@@ -47,58 +48,59 @@
*/
static void pointerEvent(int buttonMask, int x, int y, rfbClientPtr cl);
- /*
- * @brief Sends a data packet to the USB input device
- *
- * @param[in] data - pointer to data
- * @param[in] size - number of bytes to send
- */
- void sendRaw(char* data, int size);
+ /* @brief Sends a wakeup data packet to the USB input device */
+ void sendWakeupPacket();
/* @brief Sends an HID report to the USB input device */
void sendReport();
private:
- enum
- {
- NUM_MODIFIER_BITS = 4,
- POINTER_LENGTH = 6,
- REPORT_LENGTH = 8
- };
+ static constexpr int NUM_MODIFIER_BITS = 4;
+ static constexpr int KEY_REPORT_LENGTH = 8;
+ static constexpr int PTR_REPORT_LENGTH = 5;
- /* @brief Keyboard HID identifier byte */
- static const char keyboardID;
- /* @brief Pointer HID identifier byte */
- static const char pointerID;
/* @brief HID modifier bits mapped to shift and control key codes */
- static const char shiftCtrlMap[NUM_MODIFIER_BITS];
+ static constexpr uint8_t shiftCtrlMap[NUM_MODIFIER_BITS] = {
+ 0x02, // left shift
+ 0x20, // right shift
+ 0x01, // left control
+ 0x10 // right control
+ };
/* @brief HID modifier bits mapped to meta and alt key codes */
- static const char metaAltMap[NUM_MODIFIER_BITS];
-
+ static constexpr uint8_t metaAltMap[NUM_MODIFIER_BITS] = {
+ 0x08, // left meta
+ 0x80, // right meta
+ 0x04, // left alt
+ 0x40 // right alt
+ };
/*
* @brief Translates a RFB-specific key code to HID modifier bit
*
* @param[in] key - key code
*/
- static char keyToMod(rfbKeySym key);
+ static uint8_t keyToMod(rfbKeySym key);
/*
* @brief Translates a RFB-specific key code to HID scancode
*
* @param[in] key - key code
*/
- static char keyToScancode(rfbKeySym key);
+ static uint8_t keyToScancode(rfbKeySym key);
/* @brief Indicates whether or not to send a keyboard report */
bool sendKeyboard;
/* @brief Indicates whether or not to send a pointer report */
bool sendPointer;
- /* @brief File descriptor for the USB input device */
- int fd;
+ /* @brief File descriptor for the USB keyboard device */
+ int keyboardFd;
+ /* @brief File descriptor for the USB mouse device */
+ int pointerFd;
/* @brief Data for keyboard report */
- char keyboardReport[REPORT_LENGTH];
+ uint8_t keyboardReport[KEY_REPORT_LENGTH];
/* @brief Data for pointer report */
- char pointerReport[REPORT_LENGTH];
- /* @brief Path to the USB input device */
- std::string path;
+ uint8_t pointerReport[PTR_REPORT_LENGTH];
+ /* @brief Path to the USB keyboard device */
+ std::string keyboardPath;
+ /* @brief Path to the USB mouse device */
+ std::string pointerPath;
/*
* @brief Mapping of RFB key code to report data index to keep track
* of which keys are down
diff --git a/ikvm_manager.cpp b/ikvm_manager.cpp
index 90a9fce..5e014d0 100644
--- a/ikvm_manager.cpp
+++ b/ikvm_manager.cpp
@@ -7,7 +7,7 @@
Manager::Manager(const Args& args) :
continueExecuting(true), serverDone(false), videoDone(true),
- input(args.getInputPath()),
+ input(args.getKeyboardPath(), args.getPointerPath()),
video(args.getVideoPath(), input, args.getFrameRate()),
server(args, input, video)
{
diff --git a/ikvm_server.cpp b/ikvm_server.cpp
index 98d45ef..37a927b 100644
--- a/ikvm_server.cpp
+++ b/ikvm_server.cpp
@@ -39,6 +39,10 @@
server->desktopName = "OpenBMC IKVM";
server->frameBuffer = framebuffer.data();
server->newClientHook = newClient;
+ server->cursor = rfbMakeXCursor(cursorWidth, cursorHeight, (char*)cursor,
+ (char*)cursorMask);
+ server->cursor->xhot = 1;
+ server->cursor->yhot = 1;
rfbStringToAddr(&ip[0], &server->listenInterface);
diff --git a/ikvm_server.hpp b/ikvm_server.hpp
index ff51cfc..b806201 100644
--- a/ikvm_server.hpp
+++ b/ikvm_server.hpp
@@ -105,7 +105,7 @@
/* @brief Number of frames handled since a client connected */
int frameCounter;
/* @brief Number of connected clients */
- int numClients;
+ unsigned int numClients;
/* @brief Microseconds to process RFB events every frame */
long int processTime;
/* @brief Handle to the RFB server object */
@@ -116,6 +116,52 @@
Video& video;
/* @brief Default framebuffer storage */
std::vector<char> framebuffer;
+ /* @brief Cursor bitmap width */
+ static constexpr int cursorWidth = 20;
+ /* @brief Cursor bitmap height */
+ static constexpr int cursorHeight = 20;
+ /* @brief Cursor bitmap */
+ static constexpr char cursor[] = " "
+ " x "
+ " xx "
+ " xxx "
+ " xxxx "
+ " xxxxx "
+ " xxxxxx "
+ " xxxxxxx "
+ " xxxxxxxx "
+ " xxxxxxxxx "
+ " xxxxxxxxxx "
+ " xxxxxxxxxxx "
+ " xxxxxxx "
+ " xxxxxxx "
+ " xxx xxx "
+ " xx xxx "
+ " x xxx "
+ " xxx "
+ " x "
+ " ";
+ /* @brief Cursor bitmap mask */
+ static constexpr char cursorMask[] = " o "
+ "oxo "
+ "oxxo "
+ "oxxxo "
+ "oxxxxo "
+ "oxxxxxo "
+ "oxxxxxxo "
+ "oxxxxxxxo "
+ "oxxxxxxxxo "
+ "oxxxxxxxxxo "
+ "oxxxxxxxxxxo "
+ "oxxxxxxxxxxxo "
+ "oxxxxxxxoooo "
+ "oxxxxxxxo "
+ "oxxxooxxxo "
+ "oxxo oxxxo "
+ "oxo oxxxo "
+ " o oxxxo "
+ " oxo "
+ " o ";
};
} // namespace ikvm
diff --git a/ikvm_video.cpp b/ikvm_video.cpp
index db074a7..ed5ed92 100644
--- a/ikvm_video.cpp
+++ b/ikvm_video.cpp
@@ -380,13 +380,7 @@
fd = open(path.c_str(), O_RDWR);
if (fd < 0)
{
- unsigned short xx = SHRT_MAX;
- char wakeupReport[6] = {0};
-
- wakeupReport[0] = 2;
- memcpy(&wakeupReport[2], &xx, 2);
-
- input.sendRaw(wakeupReport, 6);
+ input.sendWakeupPacket();
fd = open(path.c_str(), O_RDWR);
if (fd < 0)
diff --git a/scancodes.h b/scancodes.hpp
similarity index 100%
rename from scancodes.h
rename to scancodes.hpp