XSendEvent

main.cpp

#include <X11/Xlib.h>
#include <X11/keysym.h>

#include <iostream>
#include <unistd.h>
#include <string.h>
#include <map>

using namespace std;

std::map<const char*, KeyCode> keyMap {
  {"ü", XK_udiaeresis},
  {"Ü", XK_Udiaeresis},
  {"ö", XK_odiaeresis},
  {"Ö", XK_Odiaeresis},
  {"ä", XK_adiaeresis},
  {"Ä", XK_Adiaeresis},
  {"ß", XK_ssharp},
  {"(", XK_braceleft},
  {")", XK_braceright},
  {"[", XK_bracketleft},
  {"]", XK_bracketright},
  {"<", XK_greater},
  {">", XK_less},
  {"{", XK_braceleft},
  {"}", XK_braceright}
};


KeyCode stringToKeysym(const char* character) {
  if (keyMap.count(character) != 0) {
    return keyMap.at(character);
  }

  return XStringToKeysym(character);
}

void sendKeyEvent(Display* display, const char* character) {
  XEvent event;
  XKeyEvent keyEvent;
  Window focusedWindow;
  int revertTo;
  XGetInputFocus(display, &focusedWindow, &revertTo);
  // Set up the event structure
  event.xkey.type = KeyPress;
  event.xkey.window = focusedWindow;
  event.xkey.display = display;
  event.xkey.state = 0;
  KeyCode keycode;
  keycode = XKeysymToKeycode(display, stringToKeysym(character));
  event.xkey.keycode = keycode;

  keyEvent = event.xkey;
  keyEvent.state = event.xkey.state;
  sleep(2);
  // Send the event
  XSendEvent(display, event.xkey.window, True, KeyPressMask, &event);
  XFlush(display);
}

int main() {
  Display* display = XOpenDisplay(NULL);
  if (display == NULL){
    printf("Error: Unable to connect to X11\n");
    return 1;
  }
  std::cout << "Keysim for a : " << (int)stringToKeysym("a") << std::endl;
  std::cout << "Keysim for { : " << (int)stringToKeysym("{") << std::endl;
  std::cout << "Value of constant for { : " << XK_braceleft << std::endl;
  sendKeyEvent(display, "a");
  return 0;
}

code-state.cpp

#include <X11/Xlib.h>
#include <X11/keysym.h>

#include <iostream>
#include <unistd.h>
#include <string.h>
#include <map>

using namespace std;

// Code demonstrates raw keycode and state

void sendKeyPressEvent(Display* display, int code, int state) {
  XEvent event;
  XKeyEvent keyEvent;
  Window focusedWindow;
  int revertTo;
  XGetInputFocus(display, &focusedWindow, &revertTo);
  // Set up the event structure
  event.xkey.type = KeyPress;
  event.xkey.window = focusedWindow;
  event.xkey.display = display;
  event.xkey.state = state;
  event.xkey.keycode = code;

  // Send the event
  XSendEvent(display, event.xkey.window, True, KeyPressMask, &event);
  XFlush(display);
}

void sendKeyReleaseEvent(Display* display, int code, int state) {
  XEvent event;
  XKeyEvent keyEvent;
  Window focusedWindow;
  int revertTo;
  XGetInputFocus(display, &focusedWindow, &revertTo);
  // Set up the event structure
  event.xkey.type = KeyPress;
  event.xkey.window = focusedWindow;
  event.xkey.display = display;
  event.xkey.state = state;
  event.xkey.keycode = code;

  // Send the event
  XSendEvent(display, event.xkey.window, True, KeyPressMask, &event);
  XFlush(display);
}

int main() {
  Display* display = XOpenDisplay(NULL);
  if (display == NULL){
    printf("Error: Unable to connect to X11\n");
    return 1;
  }
  sendKeyPressEvent(display, 44, 128); // Mod3 + n = (
  return 0;
}

CMakeLists.txt

cmake_minimum_required(VERSION 3.10)
project(xsendevent)

set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED True)
find_package(X11 REQUIRED)
INCLUDE_DIRECTORIES(${X11_INCLUDE_DIRS})
add_executable(xsendevent main.cpp)
target_link_libraries(${PROJECT_NAME} ${X11_LIBRARIES})
add_executable(codestate code-state.cpp)
target_link_libraries(codestate ${X11_LIBRARIES})