mirror of
https://github.com/m1k1o/neko.git
synced 2024-07-24 14:40:50 +12:00
live change resolution (WIP)
This commit is contained in:
49
server/internal/xorg/keycode/button.go
Normal file
49
server/internal/xorg/keycode/button.go
Normal file
@ -0,0 +1,49 @@
|
||||
package keycode
|
||||
|
||||
type Button struct {
|
||||
Name string
|
||||
Code int
|
||||
Keysym int
|
||||
}
|
||||
|
||||
var LEFT_BUTTON = Button{
|
||||
Name: "LEFT",
|
||||
Code: 0,
|
||||
Keysym: 1,
|
||||
}
|
||||
|
||||
var CENTER_BUTTON = Button{
|
||||
Name: "CENTER",
|
||||
Code: 1,
|
||||
Keysym: 2,
|
||||
}
|
||||
|
||||
var RIGHT_BUTTON = Button{
|
||||
Name: "RIGHT",
|
||||
Code: 2,
|
||||
Keysym: 3,
|
||||
}
|
||||
|
||||
var SCROLL_UP_BUTTON = Button{
|
||||
Name: "SCROLL_UP",
|
||||
Code: 3,
|
||||
Keysym: 4,
|
||||
}
|
||||
|
||||
var SCROLL_DOWN_BUTTON = Button{
|
||||
Name: "SCROLL_DOWN",
|
||||
Code: 4,
|
||||
Keysym: 5,
|
||||
}
|
||||
|
||||
var SCROLL_LEFT_BUTTON = Button{
|
||||
Name: "SCROLL_LEFT",
|
||||
Code: 5,
|
||||
Keysym: 6,
|
||||
}
|
||||
|
||||
var SCROLL_RIGHT_BUTTON = Button{
|
||||
Name: "SCROLL_RIGHT",
|
||||
Code: 6,
|
||||
Keysym: 7,
|
||||
}
|
701
server/internal/xorg/keycode/keys.go
Normal file
701
server/internal/xorg/keycode/keys.go
Normal file
@ -0,0 +1,701 @@
|
||||
package keycode
|
||||
|
||||
type Key struct {
|
||||
Name string
|
||||
Value string
|
||||
Code int
|
||||
Keysym int
|
||||
}
|
||||
|
||||
var BACKSPACE = Key{
|
||||
Name: "BACKSPACE",
|
||||
Value: "BackSpace",
|
||||
Code: 8,
|
||||
Keysym: int(0xff08),
|
||||
}
|
||||
|
||||
var TAB = Key{
|
||||
Name: "TAB",
|
||||
Value: "Tab",
|
||||
Code: 9,
|
||||
Keysym: int(0xFF09),
|
||||
}
|
||||
|
||||
var CLEAR = Key{
|
||||
Name: "CLEAR",
|
||||
Value: "Clear",
|
||||
Code: 12,
|
||||
Keysym: int(0xFF0B),
|
||||
}
|
||||
|
||||
var ENTER = Key{
|
||||
Name: "ENTER",
|
||||
Value: "Enter",
|
||||
Code: 13,
|
||||
Keysym: int(0xFF0D),
|
||||
}
|
||||
|
||||
var SHIFT = Key{
|
||||
Name: "SHIFT",
|
||||
Value: "Shift",
|
||||
Code: 16,
|
||||
Keysym: int(0xFFE1),
|
||||
}
|
||||
|
||||
var CTRL = Key{
|
||||
Name: "CTRL",
|
||||
Value: "Ctrl",
|
||||
Code: 17,
|
||||
Keysym: int(0xFFE3),
|
||||
}
|
||||
|
||||
var ALT = Key{
|
||||
Name: "ALT",
|
||||
Value: "Alt",
|
||||
Code: 18,
|
||||
Keysym: int(0xFFE9),
|
||||
}
|
||||
|
||||
var PAUSE = Key{
|
||||
Name: "PAUSE",
|
||||
Value: "Pause",
|
||||
Code: 19,
|
||||
Keysym: int(0xFF13),
|
||||
}
|
||||
|
||||
var CAPS_LOCK = Key{
|
||||
Name: "CAPS_LOCK",
|
||||
Value: "Caps Lock",
|
||||
Code: 20,
|
||||
Keysym: int(0xFFE5),
|
||||
}
|
||||
|
||||
var ESCAPE = Key{
|
||||
Name: "ESCAPE",
|
||||
Value: "Escape",
|
||||
Code: 27,
|
||||
Keysym: int(0xFF1B),
|
||||
}
|
||||
|
||||
var SPACE = Key{
|
||||
Name: "SPACE",
|
||||
Value: " ",
|
||||
Code: 32,
|
||||
Keysym: int(0x0020),
|
||||
}
|
||||
|
||||
var PAGE_UP = Key{
|
||||
Name: "PAGE_UP",
|
||||
Value: "Page Up",
|
||||
Code: 33,
|
||||
Keysym: int(0xFF55),
|
||||
}
|
||||
|
||||
var PAGE_DOWN = Key{
|
||||
Name: "PAGE_DOWN",
|
||||
Value: "Page Down",
|
||||
Code: 34,
|
||||
Keysym: int(0xFF56),
|
||||
}
|
||||
|
||||
var END = Key{
|
||||
Name: "END",
|
||||
Value: "End",
|
||||
Code: 35,
|
||||
Keysym: int(0xFF57),
|
||||
}
|
||||
|
||||
var HOME = Key{
|
||||
Name: "HOME",
|
||||
Value: "Home",
|
||||
Code: 36,
|
||||
Keysym: int(0xFF50),
|
||||
}
|
||||
|
||||
var LEFT_ARROW = Key{
|
||||
Name: "LEFT_ARROW",
|
||||
Value: "Left Arrow",
|
||||
Code: 37,
|
||||
Keysym: int(0xFF51),
|
||||
}
|
||||
|
||||
var UP_ARROW = Key{
|
||||
Name: "UP_ARROW",
|
||||
Value: "Up Arrow",
|
||||
Code: 38,
|
||||
Keysym: int(0xFF52),
|
||||
}
|
||||
|
||||
var RIGHT_ARROW = Key{
|
||||
Name: "RIGHT_ARROW",
|
||||
Value: "Right Arrow",
|
||||
Code: 39,
|
||||
Keysym: int(0xFF53),
|
||||
}
|
||||
|
||||
var DOWN_ARROW = Key{
|
||||
Name: "DOWN_ARROW",
|
||||
Value: "Down Arrow",
|
||||
Code: 40,
|
||||
Keysym: int(0xFF54),
|
||||
}
|
||||
|
||||
var INSERT = Key{
|
||||
Name: "INSERT",
|
||||
Value: "Insert",
|
||||
Code: 45,
|
||||
Keysym: int(0xFF63),
|
||||
}
|
||||
|
||||
var DELETE = Key{
|
||||
Name: "DELETE",
|
||||
Value: "Delete",
|
||||
Code: 46,
|
||||
Keysym: int(0xFFFF),
|
||||
}
|
||||
|
||||
var KEY_0 = Key{
|
||||
Name: "KEY_0",
|
||||
Value: "0",
|
||||
Code: 48,
|
||||
Keysym: int(0x0030),
|
||||
}
|
||||
|
||||
var KEY_1 = Key{
|
||||
Name: "KEY_1",
|
||||
Value: "1",
|
||||
Code: 49,
|
||||
Keysym: int(0x0031),
|
||||
}
|
||||
|
||||
var KEY_2 = Key{
|
||||
Name: "KEY_2",
|
||||
Value: "2",
|
||||
Code: 50,
|
||||
Keysym: int(0x0032),
|
||||
}
|
||||
|
||||
var KEY_3 = Key{
|
||||
Name: "KEY_3",
|
||||
Value: "3",
|
||||
Code: 51,
|
||||
Keysym: int(0x0033),
|
||||
}
|
||||
|
||||
var KEY_4 = Key{
|
||||
Name: "KEY_4",
|
||||
Value: "4",
|
||||
Code: 52,
|
||||
Keysym: int(0x0034),
|
||||
}
|
||||
|
||||
var KEY_5 = Key{
|
||||
Name: "KEY_5",
|
||||
Value: "5",
|
||||
Code: 53,
|
||||
Keysym: int(0x0035),
|
||||
}
|
||||
|
||||
var KEY_6 = Key{
|
||||
Name: "KEY_6",
|
||||
Value: "6",
|
||||
Code: 54,
|
||||
Keysym: int(0x0036),
|
||||
}
|
||||
|
||||
var KEY_7 = Key{
|
||||
Name: "KEY_7",
|
||||
Value: "7",
|
||||
Code: 55,
|
||||
Keysym: int(0x0037),
|
||||
}
|
||||
|
||||
var KEY_8 = Key{
|
||||
Name: "KEY_8",
|
||||
Value: "8",
|
||||
Code: 56,
|
||||
Keysym: int(0x0038),
|
||||
}
|
||||
|
||||
var KEY_9 = Key{
|
||||
Name: "KEY_9",
|
||||
Value: "9",
|
||||
Code: 57,
|
||||
Keysym: int(0x0039),
|
||||
}
|
||||
|
||||
var KEY_A = Key{
|
||||
Name: "KEY_A",
|
||||
Value: "a",
|
||||
Code: 65,
|
||||
Keysym: int(0x0061),
|
||||
}
|
||||
|
||||
var KEY_B = Key{
|
||||
Name: "KEY_B",
|
||||
Value: "b",
|
||||
Code: 66,
|
||||
Keysym: int(0x0062),
|
||||
}
|
||||
|
||||
var KEY_C = Key{
|
||||
Name: "KEY_C",
|
||||
Value: "c",
|
||||
Code: 67,
|
||||
Keysym: int(0x0063),
|
||||
}
|
||||
|
||||
var KEY_D = Key{
|
||||
Name: "KEY_D",
|
||||
Value: "d",
|
||||
Code: 68,
|
||||
Keysym: int(0x0064),
|
||||
}
|
||||
|
||||
var KEY_E = Key{
|
||||
Name: "KEY_E",
|
||||
Value: "e",
|
||||
Code: 69,
|
||||
Keysym: int(0x0065),
|
||||
}
|
||||
|
||||
var KEY_F = Key{
|
||||
Name: "KEY_F",
|
||||
Value: "f",
|
||||
Code: 70,
|
||||
Keysym: int(0x0066),
|
||||
}
|
||||
|
||||
var KEY_G = Key{
|
||||
Name: "KEY_G",
|
||||
Value: "g",
|
||||
Code: 71,
|
||||
Keysym: int(0x0067),
|
||||
}
|
||||
|
||||
var KEY_H = Key{
|
||||
Name: "KEY_H",
|
||||
Value: "h",
|
||||
Code: 72,
|
||||
Keysym: int(0x0068),
|
||||
}
|
||||
|
||||
var KEY_I = Key{
|
||||
Name: "KEY_I",
|
||||
Value: "i",
|
||||
Code: 73,
|
||||
Keysym: int(0x0069),
|
||||
}
|
||||
|
||||
var KEY_J = Key{
|
||||
Name: "KEY_J",
|
||||
Value: "j",
|
||||
Code: 74,
|
||||
Keysym: int(0x006a),
|
||||
}
|
||||
|
||||
var KEY_K = Key{
|
||||
Name: "KEY_K",
|
||||
Value: "k",
|
||||
Code: 75,
|
||||
Keysym: int(0x006b),
|
||||
}
|
||||
|
||||
var KEY_L = Key{
|
||||
Name: "KEY_L",
|
||||
Value: "l",
|
||||
Code: 76,
|
||||
Keysym: int(0x006c),
|
||||
}
|
||||
|
||||
var KEY_M = Key{
|
||||
Name: "KEY_M",
|
||||
Value: "m",
|
||||
Code: 77,
|
||||
Keysym: int(0x006d),
|
||||
}
|
||||
|
||||
var KEY_N = Key{
|
||||
Name: "KEY_N",
|
||||
Value: "n",
|
||||
Code: 78,
|
||||
Keysym: int(0x006e),
|
||||
}
|
||||
|
||||
var KEY_O = Key{
|
||||
Name: "KEY_O",
|
||||
Value: "o",
|
||||
Code: 79,
|
||||
Keysym: int(0x006f),
|
||||
}
|
||||
|
||||
var KEY_P = Key{
|
||||
Name: "KEY_P",
|
||||
Value: "p",
|
||||
Code: 80,
|
||||
Keysym: int(0x0070),
|
||||
}
|
||||
|
||||
var KEY_Q = Key{
|
||||
Name: "KEY_Q",
|
||||
Value: "q",
|
||||
Code: 81,
|
||||
Keysym: int(0x0071),
|
||||
}
|
||||
|
||||
var KEY_R = Key{
|
||||
Name: "KEY_R",
|
||||
Value: "r",
|
||||
Code: 82,
|
||||
Keysym: int(0x0072),
|
||||
}
|
||||
|
||||
var KEY_S = Key{
|
||||
Name: "KEY_S",
|
||||
Value: "s",
|
||||
Code: 83,
|
||||
Keysym: int(0x0073),
|
||||
}
|
||||
|
||||
var KEY_T = Key{
|
||||
Name: "KEY_T",
|
||||
Value: "t",
|
||||
Code: 84,
|
||||
Keysym: int(0x0074),
|
||||
}
|
||||
|
||||
var KEY_U = Key{
|
||||
Name: "KEY_U",
|
||||
Value: "u",
|
||||
Code: 85,
|
||||
Keysym: int(0x0075),
|
||||
}
|
||||
|
||||
var KEY_V = Key{
|
||||
Name: "KEY_V",
|
||||
Value: "v",
|
||||
Code: 86,
|
||||
Keysym: int(0x0076),
|
||||
}
|
||||
|
||||
var KEY_W = Key{
|
||||
Name: "KEY_W",
|
||||
Value: "w",
|
||||
Code: 87,
|
||||
Keysym: int(0x0077),
|
||||
}
|
||||
|
||||
var KEY_X = Key{
|
||||
Name: "KEY_X",
|
||||
Value: "x",
|
||||
Code: 88,
|
||||
Keysym: int(0x0078),
|
||||
}
|
||||
|
||||
var KEY_Y = Key{
|
||||
Name: "KEY_Y",
|
||||
Value: "y",
|
||||
Code: 89,
|
||||
Keysym: int(0x0079),
|
||||
}
|
||||
|
||||
var KEY_Z = Key{
|
||||
Name: "KEY_Z",
|
||||
Value: "z",
|
||||
Code: 90,
|
||||
Keysym: int(0x007a),
|
||||
}
|
||||
|
||||
var WIN_LEFT = Key{
|
||||
Name: "WIN_LEFT",
|
||||
Value: "Win Left",
|
||||
Code: 91,
|
||||
Keysym: int(0xFFEB),
|
||||
}
|
||||
|
||||
var WIN_RIGHT = Key{
|
||||
Name: "WIN_RIGHT",
|
||||
Value: "Win Right",
|
||||
Code: 92,
|
||||
Keysym: int(0xFF67),
|
||||
}
|
||||
|
||||
var PAD_0 = Key{
|
||||
Name: "PAD_0",
|
||||
Value: "Num Pad 0",
|
||||
Code: 96,
|
||||
Keysym: int(0xFFB0),
|
||||
}
|
||||
|
||||
var PAD_1 = Key{
|
||||
Name: "PAD_1",
|
||||
Value: "Num Pad 1",
|
||||
Code: 97,
|
||||
Keysym: int(0xFFB1),
|
||||
}
|
||||
|
||||
var PAD_2 = Key{
|
||||
Name: "PAD_2",
|
||||
Value: "Num Pad 2",
|
||||
Code: 98,
|
||||
Keysym: int(0xFFB2),
|
||||
}
|
||||
|
||||
var PAD_3 = Key{
|
||||
Name: "PAD_3",
|
||||
Value: "Num Pad 3",
|
||||
Code: 99,
|
||||
Keysym: int(0xFFB3),
|
||||
}
|
||||
|
||||
var PAD_4 = Key{
|
||||
Name: "PAD_4",
|
||||
Value: "Num Pad 4",
|
||||
Code: 100,
|
||||
Keysym: int(0xFFB4),
|
||||
}
|
||||
|
||||
var PAD_5 = Key{
|
||||
Name: "PAD_5",
|
||||
Value: "Num Pad 5",
|
||||
Code: 101,
|
||||
Keysym: int(0xFFB5),
|
||||
}
|
||||
|
||||
var PAD_6 = Key{
|
||||
Name: "PAD_6",
|
||||
Value: "Num Pad 6",
|
||||
Code: 102,
|
||||
Keysym: int(0xFFB6),
|
||||
}
|
||||
|
||||
var PAD_7 = Key{
|
||||
Name: "PAD_7",
|
||||
Value: "Num Pad 7",
|
||||
Code: 103,
|
||||
Keysym: int(0xFFB7),
|
||||
}
|
||||
|
||||
var PAD_8 = Key{
|
||||
Name: "PAD_8",
|
||||
Value: "Num Pad 8",
|
||||
Code: 104,
|
||||
Keysym: int(0xFFB8),
|
||||
}
|
||||
|
||||
var PAD_9 = Key{
|
||||
Name: "PAD_9",
|
||||
Value: "Num Pad 9",
|
||||
Code: 105,
|
||||
Keysym: int(0xFFB9),
|
||||
}
|
||||
|
||||
var MULTIPLY = Key{
|
||||
Name: "MULTIPLY",
|
||||
Value: "*",
|
||||
Code: 106,
|
||||
Keysym: int(0xFFAA),
|
||||
}
|
||||
|
||||
var ADD = Key{
|
||||
Name: "ADD",
|
||||
Value: "+",
|
||||
Code: 107,
|
||||
Keysym: int(0xFFAB),
|
||||
}
|
||||
|
||||
var SUBTRACT = Key{
|
||||
Name: "SUBTRACT",
|
||||
Value: "-",
|
||||
Code: 109,
|
||||
Keysym: int(0xFFAD),
|
||||
}
|
||||
|
||||
var DECIMAL = Key{
|
||||
Name: "DECIMAL",
|
||||
Value: ".",
|
||||
Code: 110,
|
||||
Keysym: int(0xFFAE),
|
||||
}
|
||||
|
||||
var DIVIDE = Key{
|
||||
Name: "DIVIDE",
|
||||
Value: "/",
|
||||
Code: 111,
|
||||
Keysym: int(0xFFAF),
|
||||
}
|
||||
|
||||
var KEY_F1 = Key{
|
||||
Name: "KEY_F1",
|
||||
Value: "f1",
|
||||
Code: 112,
|
||||
Keysym: int(0xFFBE),
|
||||
}
|
||||
|
||||
var KEY_F2 = Key{
|
||||
Name: "KEY_F2",
|
||||
Value: "f2",
|
||||
Code: 113,
|
||||
Keysym: int(0xFFBF),
|
||||
}
|
||||
|
||||
var KEY_F3 = Key{
|
||||
Name: "KEY_F3",
|
||||
Value: "f3",
|
||||
Code: 114,
|
||||
Keysym: int(0xFFC0),
|
||||
}
|
||||
|
||||
var KEY_F4 = Key{
|
||||
Name: "KEY_F4",
|
||||
Value: "f4",
|
||||
Code: 115,
|
||||
Keysym: int(0xFFC1),
|
||||
}
|
||||
|
||||
var KEY_F5 = Key{
|
||||
Name: "KEY_F5",
|
||||
Value: "f5",
|
||||
Code: 116,
|
||||
Keysym: int(0xFFC2),
|
||||
}
|
||||
|
||||
var KEY_F6 = Key{
|
||||
Name: "KEY_F6",
|
||||
Value: "f6",
|
||||
Code: 117,
|
||||
Keysym: int(0xFFC3),
|
||||
}
|
||||
|
||||
var KEY_F7 = Key{
|
||||
Name: "KEY_F7",
|
||||
Value: "f7",
|
||||
Code: 118,
|
||||
Keysym: int(0xFFC4),
|
||||
}
|
||||
|
||||
var KEY_F8 = Key{
|
||||
Name: "KEY_F8",
|
||||
Value: "f8",
|
||||
Code: 119,
|
||||
Keysym: int(0xFFC5),
|
||||
}
|
||||
|
||||
var KEY_F9 = Key{
|
||||
Name: "KEY_F9",
|
||||
Value: "f9",
|
||||
Code: 120,
|
||||
Keysym: int(0xFFC6),
|
||||
}
|
||||
|
||||
var KEY_F10 = Key{
|
||||
Name: "KEY_F10",
|
||||
Value: "f10",
|
||||
Code: 121,
|
||||
Keysym: int(0xFFC7),
|
||||
}
|
||||
|
||||
var KEY_F11 = Key{
|
||||
Name: "KEY_F11",
|
||||
Value: "f11",
|
||||
Code: 122,
|
||||
Keysym: int(0xFFC8),
|
||||
}
|
||||
|
||||
var KEY_F12 = Key{
|
||||
Name: "KEY_F12",
|
||||
Value: "f12",
|
||||
Code: 123,
|
||||
Keysym: int(0xFFC9),
|
||||
}
|
||||
|
||||
var NUM_LOCK = Key{
|
||||
Name: "NUM_LOCK",
|
||||
Value: "Num Lock",
|
||||
Code: 144,
|
||||
Keysym: int(0xFF7F),
|
||||
}
|
||||
|
||||
var SCROLL_LOCK = Key{
|
||||
Name: "SCROLL_LOCK",
|
||||
Value: "Scroll Lock",
|
||||
Code: 145,
|
||||
Keysym: int(0xFF14),
|
||||
}
|
||||
|
||||
var SEMI_COLON = Key{
|
||||
Name: "SEMI_COLON",
|
||||
Value: ";",
|
||||
Code: 186,
|
||||
Keysym: int(0x003b),
|
||||
}
|
||||
|
||||
var EQUAL = Key{
|
||||
Name: "EQUAL",
|
||||
Value: "=",
|
||||
Code: 187,
|
||||
Keysym: int(0x003d),
|
||||
}
|
||||
|
||||
var COMMA = Key{
|
||||
Name: "COMMA",
|
||||
Value: ",",
|
||||
Code: 188,
|
||||
Keysym: int(0x002c),
|
||||
}
|
||||
|
||||
var DASH = Key{
|
||||
Name: "DASH",
|
||||
Value: "-",
|
||||
Code: 189,
|
||||
Keysym: int(0x002d),
|
||||
}
|
||||
|
||||
var PERIOD = Key{
|
||||
Name: "PERIOD",
|
||||
Value: ".",
|
||||
Code: 190,
|
||||
Keysym: int(0x002e),
|
||||
}
|
||||
|
||||
var FORWARD_SLASH = Key{
|
||||
Name: "FORWARD_SLASH",
|
||||
Value: "/",
|
||||
Code: 191,
|
||||
Keysym: int(0x002f),
|
||||
}
|
||||
|
||||
var GRAVE = Key{
|
||||
Name: "GRAVE",
|
||||
Value: "`",
|
||||
Code: 192,
|
||||
Keysym: int(0x0060),
|
||||
}
|
||||
|
||||
var OPEN_BRACKET = Key{
|
||||
Name: "OPEN_BRACKET",
|
||||
Value: "[",
|
||||
Code: 219,
|
||||
Keysym: int(0x005b),
|
||||
}
|
||||
|
||||
var BACK_SLASH = Key{
|
||||
Name: "BACK_SLASH",
|
||||
Value: "\\",
|
||||
Code: 220,
|
||||
Keysym: int(0x005c),
|
||||
}
|
||||
|
||||
var CLOSE_BRAKET = Key{
|
||||
Name: "CLOSE_BRAKET",
|
||||
Value: "]",
|
||||
Code: 221,
|
||||
Keysym: int(0x005d),
|
||||
}
|
||||
|
||||
var SINGLE_QUOTE = Key{
|
||||
Name: "SINGLE_QUOTE",
|
||||
Value: "'",
|
||||
Code: 222,
|
||||
Keysym: int(0x0022),
|
||||
}
|
150
server/internal/xorg/xorg.c
Normal file
150
server/internal/xorg/xorg.c
Normal file
@ -0,0 +1,150 @@
|
||||
#include "xorg.h"
|
||||
|
||||
static clipboard_c *CLIPBOARD = NULL;
|
||||
static Display *DISPLAY = NULL;
|
||||
static char *NAME = ":0.0";
|
||||
static int REGISTERED = 0;
|
||||
static int DIRTY = 0;
|
||||
|
||||
Display *getXDisplay(void) {
|
||||
/* Close the display if displayName has changed */
|
||||
if (DIRTY) {
|
||||
XDisplayClose();
|
||||
DIRTY = 0;
|
||||
}
|
||||
|
||||
if (DISPLAY == NULL) {
|
||||
/* First try the user set displayName */
|
||||
DISPLAY = XOpenDisplay(NAME);
|
||||
|
||||
/* Then try using environment variable DISPLAY */
|
||||
if (DISPLAY == NULL) {
|
||||
DISPLAY = XOpenDisplay(NULL);
|
||||
}
|
||||
|
||||
if (DISPLAY == NULL) {
|
||||
fputs("Could not open main display\n", stderr);
|
||||
} else if (!REGISTERED) {
|
||||
atexit(&XDisplayClose);
|
||||
REGISTERED = 1;
|
||||
}
|
||||
}
|
||||
|
||||
return DISPLAY;
|
||||
}
|
||||
|
||||
clipboard_c *getClipboard(void) {
|
||||
if (CLIPBOARD == NULL) {
|
||||
CLIPBOARD = clipboard_new(NULL);
|
||||
}
|
||||
return CLIPBOARD;
|
||||
}
|
||||
|
||||
void XDisplayClose(void) {
|
||||
if (DISPLAY != NULL) {
|
||||
XCloseDisplay(DISPLAY);
|
||||
DISPLAY = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void XDisplaySet(char *input) {
|
||||
NAME = strdup(input);
|
||||
DIRTY = 1;
|
||||
}
|
||||
|
||||
void XMove(int x, int y) {
|
||||
Display *display = getXDisplay();
|
||||
XWarpPointer(display, None, DefaultRootWindow(display), 0, 0, 0, 0, x, y);
|
||||
XSync(display, 0);
|
||||
}
|
||||
|
||||
void XScroll(int x, int y) {
|
||||
int ydir = 4; /* Button 4 is up, 5 is down. */
|
||||
int xdir = 6;
|
||||
|
||||
Display *display = getXDisplay();
|
||||
|
||||
if (y < 0) {
|
||||
ydir = 5;
|
||||
}
|
||||
|
||||
if (x < 0) {
|
||||
xdir = 7;
|
||||
}
|
||||
|
||||
int xi;
|
||||
int yi;
|
||||
|
||||
for (xi = 0; xi < abs(x); xi++) {
|
||||
XTestFakeButtonEvent(display, xdir, 1, CurrentTime);
|
||||
XTestFakeButtonEvent(display, xdir, 0, CurrentTime);
|
||||
}
|
||||
|
||||
for (yi = 0; yi < abs(y); yi++) {
|
||||
XTestFakeButtonEvent(display, ydir, 1, CurrentTime);
|
||||
XTestFakeButtonEvent(display, ydir, 0, CurrentTime);
|
||||
}
|
||||
|
||||
XSync(display, 0);
|
||||
}
|
||||
|
||||
void XButton(unsigned int button, int down) {
|
||||
Display *display = getXDisplay();
|
||||
XTestFakeButtonEvent(display, button, down, CurrentTime);
|
||||
XSync(display, 0);
|
||||
}
|
||||
|
||||
void XKey(unsigned long key, int down) {
|
||||
Display *display = getXDisplay();
|
||||
KeyCode code = XKeysymToKeycode(display, key);
|
||||
XTestFakeKeyEvent(display, code, down, CurrentTime);
|
||||
XSync(display, 0);
|
||||
}
|
||||
|
||||
void XClipboardSet(char *src) {
|
||||
clipboard_c *cb = getClipboard();
|
||||
clipboard_set_text_ex(cb, src, strlen(src), 0);
|
||||
}
|
||||
|
||||
char *XClipboardGet() {
|
||||
clipboard_c *cb = getClipboard();
|
||||
return clipboard_text_ex(cb, NULL, 0);
|
||||
}
|
||||
|
||||
void XGetScreenConfigurations() {
|
||||
Display *display = getXDisplay();
|
||||
Window root = RootWindow(display, 0);
|
||||
XRRScreenSize *xrrs;
|
||||
int num_sizes;
|
||||
|
||||
xrrs = XRRSizes(display, 0, &num_sizes);
|
||||
for(int i = 0; i < num_sizes; i ++) {
|
||||
short *rates;
|
||||
int num_rates;
|
||||
|
||||
goCreateScreenSize(i, xrrs[i].width, xrrs[i].height, xrrs[i].mwidth, xrrs[i].mheight);
|
||||
rates = XRRRates(display, 0, i, &num_rates);
|
||||
for (int j = 0; j < num_rates; j ++) {
|
||||
goSetScreenRates(i, j, rates[j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void XSetScreenConfiguration(int index, short rate) {
|
||||
Display *display = getXDisplay();
|
||||
Window root = RootWindow(display, 0);
|
||||
XRRSetScreenConfigAndRate(display, XRRGetScreenInfo(display, root), root, index, RR_Rotate_0, rate, CurrentTime);
|
||||
}
|
||||
|
||||
int XGetScreenSize() {
|
||||
Display *display = getXDisplay();
|
||||
XRRScreenConfiguration *conf = XRRGetScreenInfo(display, RootWindow(display, 0));
|
||||
Rotation original_rotation;
|
||||
return XRRConfigCurrentConfiguration(conf, &original_rotation);
|
||||
}
|
||||
|
||||
short XGetScreenRate() {
|
||||
Display *display = getXDisplay();
|
||||
XRRScreenConfiguration *conf = XRRGetScreenInfo(display, RootWindow(display, 0));
|
||||
return XRRConfigCurrentRate(conf);
|
||||
}
|
343
server/internal/xorg/xorg.go
Normal file
343
server/internal/xorg/xorg.go
Normal file
@ -0,0 +1,343 @@
|
||||
// NOTE: I have no fucking clue what I'm doing with this,
|
||||
// it works, but I am positive I'm doing this very wrong...
|
||||
// should I be freeing these strings? does go gc them?
|
||||
// pretty sure this *isn't* thread safe either.... /shrug
|
||||
// if you know a better way to get this done *please* make a pr <3
|
||||
|
||||
package xorg
|
||||
|
||||
/*
|
||||
#cgo linux CFLAGS: -I/usr/src
|
||||
#cgo linux LDFLAGS: -L/usr/src -lX11 -lXtst -lXrandr -lclipboard
|
||||
|
||||
#include "xorg.h"
|
||||
*/
|
||||
import "C"
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"sync"
|
||||
"time"
|
||||
"unsafe"
|
||||
|
||||
"n.eko.moe/neko/internal/types"
|
||||
"n.eko.moe/neko/internal/xorg/keycode"
|
||||
)
|
||||
|
||||
var ScreenConfigurations = make(map[int]types.ScreenConfiguration)
|
||||
|
||||
var debounce = make(map[int]time.Time)
|
||||
var buttons = make(map[int]keycode.Button)
|
||||
var keys = make(map[int]keycode.Key)
|
||||
var mu = sync.Mutex{}
|
||||
|
||||
func init() {
|
||||
keys[keycode.BACKSPACE.Code] = keycode.BACKSPACE
|
||||
keys[keycode.TAB.Code] = keycode.TAB
|
||||
keys[keycode.CLEAR.Code] = keycode.CLEAR
|
||||
keys[keycode.ENTER.Code] = keycode.ENTER
|
||||
keys[keycode.SHIFT.Code] = keycode.SHIFT
|
||||
keys[keycode.CTRL.Code] = keycode.CTRL
|
||||
keys[keycode.ALT.Code] = keycode.ALT
|
||||
keys[keycode.PAUSE.Code] = keycode.PAUSE
|
||||
keys[keycode.CAPS_LOCK.Code] = keycode.CAPS_LOCK
|
||||
keys[keycode.ESCAPE.Code] = keycode.ESCAPE
|
||||
keys[keycode.SPACE.Code] = keycode.SPACE
|
||||
keys[keycode.PAGE_UP.Code] = keycode.PAGE_UP
|
||||
keys[keycode.PAGE_DOWN.Code] = keycode.PAGE_DOWN
|
||||
keys[keycode.END.Code] = keycode.END
|
||||
keys[keycode.HOME.Code] = keycode.HOME
|
||||
keys[keycode.LEFT_ARROW.Code] = keycode.LEFT_ARROW
|
||||
keys[keycode.UP_ARROW.Code] = keycode.UP_ARROW
|
||||
keys[keycode.RIGHT_ARROW.Code] = keycode.RIGHT_ARROW
|
||||
keys[keycode.DOWN_ARROW.Code] = keycode.DOWN_ARROW
|
||||
keys[keycode.INSERT.Code] = keycode.INSERT
|
||||
keys[keycode.DELETE.Code] = keycode.DELETE
|
||||
keys[keycode.KEY_0.Code] = keycode.KEY_0
|
||||
keys[keycode.KEY_1.Code] = keycode.KEY_1
|
||||
keys[keycode.KEY_2.Code] = keycode.KEY_2
|
||||
keys[keycode.KEY_3.Code] = keycode.KEY_3
|
||||
keys[keycode.KEY_4.Code] = keycode.KEY_4
|
||||
keys[keycode.KEY_5.Code] = keycode.KEY_5
|
||||
keys[keycode.KEY_6.Code] = keycode.KEY_6
|
||||
keys[keycode.KEY_7.Code] = keycode.KEY_7
|
||||
keys[keycode.KEY_8.Code] = keycode.KEY_8
|
||||
keys[keycode.KEY_9.Code] = keycode.KEY_9
|
||||
keys[keycode.KEY_A.Code] = keycode.KEY_A
|
||||
keys[keycode.KEY_B.Code] = keycode.KEY_B
|
||||
keys[keycode.KEY_C.Code] = keycode.KEY_C
|
||||
keys[keycode.KEY_D.Code] = keycode.KEY_D
|
||||
keys[keycode.KEY_E.Code] = keycode.KEY_E
|
||||
keys[keycode.KEY_F.Code] = keycode.KEY_F
|
||||
keys[keycode.KEY_G.Code] = keycode.KEY_G
|
||||
keys[keycode.KEY_H.Code] = keycode.KEY_H
|
||||
keys[keycode.KEY_I.Code] = keycode.KEY_I
|
||||
keys[keycode.KEY_J.Code] = keycode.KEY_J
|
||||
keys[keycode.KEY_K.Code] = keycode.KEY_K
|
||||
keys[keycode.KEY_L.Code] = keycode.KEY_L
|
||||
keys[keycode.KEY_M.Code] = keycode.KEY_M
|
||||
keys[keycode.KEY_N.Code] = keycode.KEY_N
|
||||
keys[keycode.KEY_O.Code] = keycode.KEY_O
|
||||
keys[keycode.KEY_P.Code] = keycode.KEY_P
|
||||
keys[keycode.KEY_Q.Code] = keycode.KEY_Q
|
||||
keys[keycode.KEY_R.Code] = keycode.KEY_R
|
||||
keys[keycode.KEY_S.Code] = keycode.KEY_S
|
||||
keys[keycode.KEY_T.Code] = keycode.KEY_T
|
||||
keys[keycode.KEY_U.Code] = keycode.KEY_U
|
||||
keys[keycode.KEY_V.Code] = keycode.KEY_V
|
||||
keys[keycode.KEY_W.Code] = keycode.KEY_W
|
||||
keys[keycode.KEY_X.Code] = keycode.KEY_X
|
||||
keys[keycode.KEY_Y.Code] = keycode.KEY_Y
|
||||
keys[keycode.KEY_Z.Code] = keycode.KEY_Z
|
||||
keys[keycode.WIN_LEFT.Code] = keycode.WIN_LEFT
|
||||
keys[keycode.WIN_RIGHT.Code] = keycode.WIN_RIGHT
|
||||
keys[keycode.PAD_0.Code] = keycode.PAD_0
|
||||
keys[keycode.PAD_1.Code] = keycode.PAD_1
|
||||
keys[keycode.PAD_2.Code] = keycode.PAD_2
|
||||
keys[keycode.PAD_3.Code] = keycode.PAD_3
|
||||
keys[keycode.PAD_4.Code] = keycode.PAD_4
|
||||
keys[keycode.PAD_5.Code] = keycode.PAD_5
|
||||
keys[keycode.PAD_6.Code] = keycode.PAD_6
|
||||
keys[keycode.PAD_7.Code] = keycode.PAD_7
|
||||
keys[keycode.PAD_8.Code] = keycode.PAD_8
|
||||
keys[keycode.PAD_9.Code] = keycode.PAD_9
|
||||
keys[keycode.MULTIPLY.Code] = keycode.MULTIPLY
|
||||
keys[keycode.ADD.Code] = keycode.ADD
|
||||
keys[keycode.SUBTRACT.Code] = keycode.SUBTRACT
|
||||
keys[keycode.DECIMAL.Code] = keycode.DECIMAL
|
||||
keys[keycode.DIVIDE.Code] = keycode.DIVIDE
|
||||
keys[keycode.KEY_F1.Code] = keycode.KEY_F1
|
||||
keys[keycode.KEY_F2.Code] = keycode.KEY_F2
|
||||
keys[keycode.KEY_F3.Code] = keycode.KEY_F3
|
||||
keys[keycode.KEY_F4.Code] = keycode.KEY_F4
|
||||
keys[keycode.KEY_F5.Code] = keycode.KEY_F5
|
||||
keys[keycode.KEY_F6.Code] = keycode.KEY_F6
|
||||
keys[keycode.KEY_F7.Code] = keycode.KEY_F7
|
||||
keys[keycode.KEY_F8.Code] = keycode.KEY_F8
|
||||
keys[keycode.KEY_F9.Code] = keycode.KEY_F9
|
||||
keys[keycode.KEY_F10.Code] = keycode.KEY_F10
|
||||
keys[keycode.KEY_F11.Code] = keycode.KEY_F11
|
||||
keys[keycode.KEY_F12.Code] = keycode.KEY_F12
|
||||
keys[keycode.NUM_LOCK.Code] = keycode.NUM_LOCK
|
||||
keys[keycode.SCROLL_LOCK.Code] = keycode.SCROLL_LOCK
|
||||
keys[keycode.SEMI_COLON.Code] = keycode.SEMI_COLON
|
||||
keys[keycode.EQUAL.Code] = keycode.EQUAL
|
||||
keys[keycode.COMMA.Code] = keycode.COMMA
|
||||
keys[keycode.DASH.Code] = keycode.DASH
|
||||
keys[keycode.PERIOD.Code] = keycode.PERIOD
|
||||
keys[keycode.FORWARD_SLASH.Code] = keycode.FORWARD_SLASH
|
||||
keys[keycode.GRAVE.Code] = keycode.GRAVE
|
||||
keys[keycode.OPEN_BRACKET.Code] = keycode.OPEN_BRACKET
|
||||
keys[keycode.BACK_SLASH.Code] = keycode.BACK_SLASH
|
||||
keys[keycode.CLOSE_BRAKET.Code] = keycode.CLOSE_BRAKET
|
||||
keys[keycode.SINGLE_QUOTE.Code] = keycode.SINGLE_QUOTE
|
||||
|
||||
buttons[keycode.LEFT_BUTTON.Code] = keycode.LEFT_BUTTON
|
||||
buttons[keycode.CENTER_BUTTON.Code] = keycode.CENTER_BUTTON
|
||||
buttons[keycode.RIGHT_BUTTON.Code] = keycode.RIGHT_BUTTON
|
||||
buttons[keycode.SCROLL_UP_BUTTON.Code] = keycode.SCROLL_UP_BUTTON
|
||||
buttons[keycode.SCROLL_DOWN_BUTTON.Code] = keycode.SCROLL_DOWN_BUTTON
|
||||
buttons[keycode.SCROLL_LEFT_BUTTON.Code] = keycode.SCROLL_LEFT_BUTTON
|
||||
buttons[keycode.SCROLL_RIGHT_BUTTON.Code] = keycode.SCROLL_RIGHT_BUTTON
|
||||
|
||||
C.XGetScreenConfigurations()
|
||||
}
|
||||
|
||||
func Display(display string) {
|
||||
mu.Lock()
|
||||
defer mu.Unlock()
|
||||
|
||||
displayUnsafe := C.CString(display)
|
||||
defer C.free(unsafe.Pointer(displayUnsafe))
|
||||
|
||||
C.XDisplaySet(displayUnsafe)
|
||||
}
|
||||
|
||||
func Move(x, y int) {
|
||||
mu.Lock()
|
||||
defer mu.Unlock()
|
||||
|
||||
C.XMove(C.int(x), C.int(y))
|
||||
}
|
||||
|
||||
func Scroll(x, y int) {
|
||||
mu.Lock()
|
||||
defer mu.Unlock()
|
||||
|
||||
C.XScroll(C.int(x), C.int(y))
|
||||
}
|
||||
|
||||
func ButtonDown(code int) (*keycode.Button, error) {
|
||||
mu.Lock()
|
||||
defer mu.Unlock()
|
||||
|
||||
button, ok := buttons[code]
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("invalid button %v", code)
|
||||
}
|
||||
|
||||
if _, ok := debounce[code]; ok {
|
||||
return nil, fmt.Errorf("debounced button %v(%v)", button.Name, code)
|
||||
}
|
||||
|
||||
debounce[code] = time.Now()
|
||||
|
||||
C.XButton(C.uint(button.Keysym), C.int(1))
|
||||
return &button, nil
|
||||
}
|
||||
|
||||
func KeyDown(code int) (*keycode.Key, error) {
|
||||
mu.Lock()
|
||||
defer mu.Unlock()
|
||||
|
||||
key, ok := keys[code]
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("invalid key %v", code)
|
||||
}
|
||||
|
||||
if _, ok := debounce[code]; ok {
|
||||
return nil, fmt.Errorf("debounced key %v(%v)", key.Name, code)
|
||||
}
|
||||
|
||||
debounce[code] = time.Now()
|
||||
|
||||
C.XKey(C.ulong(key.Keysym), C.int(1))
|
||||
return &key, nil
|
||||
}
|
||||
|
||||
func ButtonUp(code int) (*keycode.Button, error) {
|
||||
mu.Lock()
|
||||
defer mu.Unlock()
|
||||
|
||||
button, ok := buttons[code]
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("invalid button %v", code)
|
||||
}
|
||||
|
||||
if _, ok := debounce[code]; !ok {
|
||||
return nil, fmt.Errorf("debounced button %v(%v)", button.Name, code)
|
||||
}
|
||||
|
||||
delete(debounce, code)
|
||||
|
||||
C.XButton(C.uint(button.Keysym), C.int(0))
|
||||
return &button, nil
|
||||
}
|
||||
|
||||
func KeyUp(code int) (*keycode.Key, error) {
|
||||
mu.Lock()
|
||||
defer mu.Unlock()
|
||||
|
||||
key, ok := keys[code]
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("invalid key %v", code)
|
||||
}
|
||||
|
||||
if _, ok := debounce[code]; !ok {
|
||||
return nil, fmt.Errorf("debounced key %v(%v)", key.Name, code)
|
||||
}
|
||||
|
||||
delete(debounce, code)
|
||||
|
||||
C.XKey(C.ulong(key.Keysym), C.int(0))
|
||||
return &key, nil
|
||||
}
|
||||
|
||||
func ReadClipboard() string {
|
||||
mu.Lock()
|
||||
defer mu.Unlock()
|
||||
|
||||
clipboardUnsafe := C.XClipboardGet()
|
||||
defer C.free(unsafe.Pointer(clipboardUnsafe))
|
||||
|
||||
return C.GoString(clipboardUnsafe)
|
||||
}
|
||||
|
||||
func WriteClipboard(data string) {
|
||||
mu.Lock()
|
||||
defer mu.Unlock()
|
||||
|
||||
clipboardUnsafe := C.CString(data)
|
||||
defer C.free(unsafe.Pointer(clipboardUnsafe))
|
||||
|
||||
C.XClipboardSet(clipboardUnsafe)
|
||||
}
|
||||
|
||||
func ResetKeys() {
|
||||
for key := range debounce {
|
||||
if key < 8 {
|
||||
ButtonUp(key)
|
||||
} else {
|
||||
KeyUp(key)
|
||||
}
|
||||
|
||||
delete(debounce, key)
|
||||
}
|
||||
}
|
||||
|
||||
func CheckKeys(duration time.Duration) {
|
||||
t := time.Now()
|
||||
for key, start := range debounce {
|
||||
if t.Sub(start) < duration {
|
||||
continue
|
||||
}
|
||||
|
||||
if key < 8 {
|
||||
ButtonUp(key)
|
||||
} else {
|
||||
KeyUp(key)
|
||||
}
|
||||
|
||||
delete(debounce, key)
|
||||
}
|
||||
}
|
||||
|
||||
func ChangeScreenSize(width int, height int, rate int) error {
|
||||
mu.Lock()
|
||||
defer mu.Unlock()
|
||||
|
||||
for index, size := range ScreenConfigurations {
|
||||
if size.Width == width && size.Height == height {
|
||||
for _, srate := range size.Rates {
|
||||
if int16(rate) == srate {
|
||||
C.XSetScreenConfiguration(C.int(index), C.short(srate))
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return fmt.Errorf("unknown configuration")
|
||||
}
|
||||
|
||||
func GetScreenSize() *types.ScreenSize {
|
||||
mu.Lock()
|
||||
defer mu.Unlock()
|
||||
|
||||
index := int(C.XGetScreenSize())
|
||||
rate := int16(C.XGetScreenRate())
|
||||
|
||||
if conf, ok := ScreenConfigurations[index]; ok {
|
||||
return &types.ScreenSize{
|
||||
Width: conf.Width,
|
||||
Height: conf.Height,
|
||||
Rate: rate,
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
//export goCreateScreenSize
|
||||
func goCreateScreenSize(index C.int, width C.int, height C.int, mwidth C.int, mheight C.int) {
|
||||
ScreenConfigurations[int(index)] = types.ScreenConfiguration{
|
||||
Width: int(width),
|
||||
Height: int(height),
|
||||
Rates: make(map[int]int16),
|
||||
}
|
||||
}
|
||||
|
||||
//export goSetScreenRates
|
||||
func goSetScreenRates(index C.int, rate_index C.int, rate C.short) {
|
||||
ScreenConfigurations[int(index)].Rates[int(rate_index)] = int16(rate)
|
||||
}
|
42
server/internal/xorg/xorg.h
Normal file
42
server/internal/xorg/xorg.h
Normal file
@ -0,0 +1,42 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef XDISPLAY_H
|
||||
#define XDISPLAY_H
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/extensions/Xrandr.h>
|
||||
#include <X11/extensions/XTest.h>
|
||||
#include <libclipboard.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h> /* For fputs() */
|
||||
#include <string.h> /* For strdup() */
|
||||
|
||||
extern void goCreateScreenSize(int index, int width, int height, int mwidth, int mheight);
|
||||
extern void goSetScreenRates(int index, int rate_index, short rate);
|
||||
|
||||
/* Returns the main display, closed either on exit or when closeMainDisplay()
|
||||
* is invoked. This removes a bit of the overhead of calling XOpenDisplay() &
|
||||
* XCloseDisplay() everytime the main display needs to be used.
|
||||
*
|
||||
* Note that this is almost certainly not thread safe. */
|
||||
Display *getXDisplay(void);
|
||||
clipboard_c *getClipboard(void);
|
||||
|
||||
void XMove(int x, int y);
|
||||
void XScroll(int x, int y);
|
||||
void XButton(unsigned int button, int down);
|
||||
void XKey(unsigned long key, int down);
|
||||
|
||||
void XClipboardSet(char *src);
|
||||
char *XClipboardGet();
|
||||
|
||||
void XGetScreenConfigurations();
|
||||
void XSetScreenConfiguration(int index, short rate);
|
||||
int XGetScreenSize();
|
||||
short XGetScreenRate();
|
||||
|
||||
void XDisplayClose(void);
|
||||
void XDisplaySet(char *input);
|
||||
#endif
|
||||
|
Reference in New Issue
Block a user