230 lines
6.8 KiB
C
230 lines
6.8 KiB
C
/*
|
|
* Azeron Linux Configuration Library - Utility Functions
|
|
* Copyright (C) 2024 Azeron Linux Project
|
|
*
|
|
* SPDX-License-Identifier: MIT
|
|
*/
|
|
|
|
#include "azeron.h"
|
|
#include <linux/input-event-codes.h>
|
|
#include <string.h>
|
|
|
|
/* Key name to keycode mapping table */
|
|
static struct {
|
|
const char *name;
|
|
int keycode;
|
|
} keymap[] = {
|
|
/* Letters */
|
|
{"KEY_A", KEY_A}, {"KEY_B", KEY_B}, {"KEY_C", KEY_C}, {"KEY_D", KEY_D},
|
|
{"KEY_E", KEY_E}, {"KEY_F", KEY_F}, {"KEY_G", KEY_G}, {"KEY_H", KEY_H},
|
|
{"KEY_I", KEY_I}, {"KEY_J", KEY_J}, {"KEY_K", KEY_K}, {"KEY_L", KEY_L},
|
|
{"KEY_M", KEY_M}, {"KEY_N", KEY_N}, {"KEY_O", KEY_O}, {"KEY_P", KEY_P},
|
|
{"KEY_Q", KEY_Q}, {"KEY_R", KEY_R}, {"KEY_S", KEY_S}, {"KEY_T", KEY_T},
|
|
{"KEY_U", KEY_U}, {"KEY_V", KEY_V}, {"KEY_W", KEY_W}, {"KEY_X", KEY_X},
|
|
{"KEY_Y", KEY_Y}, {"KEY_Z", KEY_Z},
|
|
|
|
/* Numbers */
|
|
{"KEY_1", KEY_1}, {"KEY_2", KEY_2}, {"KEY_3", KEY_3}, {"KEY_4", KEY_4},
|
|
{"KEY_5", KEY_5}, {"KEY_6", KEY_6}, {"KEY_7", KEY_7}, {"KEY_8", KEY_8},
|
|
{"KEY_9", KEY_9}, {"KEY_0", KEY_0},
|
|
|
|
/* Function keys */
|
|
{"KEY_F1", KEY_F1}, {"KEY_F2", KEY_F2}, {"KEY_F3", KEY_F3}, {"KEY_F4", KEY_F4},
|
|
{"KEY_F5", KEY_F5}, {"KEY_F6", KEY_F6}, {"KEY_F7", KEY_F7}, {"KEY_F8", KEY_F8},
|
|
{"KEY_F9", KEY_F9}, {"KEY_F10", KEY_F10}, {"KEY_F11", KEY_F11}, {"KEY_F12", KEY_F12},
|
|
|
|
/* Special keys */
|
|
{"KEY_ESC", KEY_ESC},
|
|
{"KEY_TAB", KEY_TAB},
|
|
{"KEY_CAPSLOCK", KEY_CAPSLOCK},
|
|
{"KEY_LEFTSHIFT", KEY_LEFTSHIFT}, {"KEY_RIGHTSHIFT", KEY_RIGHTSHIFT},
|
|
{"KEY_LEFTCTRL", KEY_LEFTCTRL}, {"KEY_RIGHTCTRL", KEY_RIGHTCTRL},
|
|
{"KEY_LEFTALT", KEY_LEFTALT}, {"KEY_RIGHTALT", KEY_RIGHTALT},
|
|
{"KEY_SPACE", KEY_SPACE},
|
|
{"KEY_ENTER", KEY_ENTER},
|
|
{"KEY_BACKSPACE", KEY_BACKSPACE},
|
|
{"KEY_DELETE", KEY_DELETE},
|
|
{"KEY_INSERT", KEY_INSERT},
|
|
{"KEY_HOME", KEY_HOME},
|
|
{"KEY_END", KEY_END},
|
|
{"KEY_PAGEUP", KEY_PAGEUP},
|
|
{"KEY_PAGEDOWN", KEY_PAGEDOWN},
|
|
|
|
/* Arrow keys */
|
|
{"KEY_UP", KEY_UP},
|
|
{"KEY_DOWN", KEY_DOWN},
|
|
{"KEY_LEFT", KEY_LEFT},
|
|
{"KEY_RIGHT", KEY_RIGHT},
|
|
|
|
/* Numpad */
|
|
{"KEY_NUMLOCK", KEY_NUMLOCK},
|
|
{"KEY_KP0", KEY_KP0}, {"KEY_KP1", KEY_KP1}, {"KEY_KP2", KEY_KP2}, {"KEY_KP3", KEY_KP3},
|
|
{"KEY_KP4", KEY_KP4}, {"KEY_KP5", KEY_KP5}, {"KEY_KP6", KEY_KP6}, {"KEY_KP7", KEY_KP7},
|
|
{"KEY_KP8", KEY_KP8}, {"KEY_KP9", KEY_KP9},
|
|
{"KEY_KPSLASH", KEY_KPSLASH}, {"KEY_KPASTERISK", KEY_KPASTERISK},
|
|
{"KEY_KPMINUS", KEY_KPMINUS}, {"KEY_KPPLUS", KEY_KPPLUS},
|
|
{"KEY_KPENTER", KEY_KPENTER}, {"KEY_KPDOT", KEY_KPDOT},
|
|
|
|
/* Mouse buttons */
|
|
{"BTN_LEFT", BTN_LEFT},
|
|
{"BTN_RIGHT", BTN_RIGHT},
|
|
{"BTN_MIDDLE", BTN_MIDDLE},
|
|
{"BTN_SIDE", BTN_SIDE},
|
|
{"BTN_EXTRA", BTN_EXTRA},
|
|
|
|
{NULL, 0}
|
|
};
|
|
|
|
/* Convert key name to keycode */
|
|
int azeron_keycode_from_string(const char *key_name)
|
|
{
|
|
int i;
|
|
|
|
if (!key_name) {
|
|
return -1;
|
|
}
|
|
|
|
/* First try exact match */
|
|
for (i = 0; keymap[i].name != NULL; i++) {
|
|
if (strcmp(key_name, keymap[i].name) == 0) {
|
|
return keymap[i].keycode;
|
|
}
|
|
}
|
|
|
|
/* Try without KEY_ prefix */
|
|
if (strncmp(key_name, "KEY_", 4) != 0) {
|
|
char prefixed[64];
|
|
snprintf(prefixed, sizeof(prefixed), "KEY_%s", key_name);
|
|
for (i = 0; keymap[i].name != NULL; i++) {
|
|
if (strcmp(prefixed, keymap[i].name) == 0) {
|
|
return keymap[i].keycode;
|
|
}
|
|
}
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
|
|
/* Convert keycode to string */
|
|
const char *azeron_keycode_to_string(int keycode)
|
|
{
|
|
int i;
|
|
|
|
for (i = 0; keymap[i].name != NULL; i++) {
|
|
if (keymap[i].keycode == keycode) {
|
|
return keymap[i].name;
|
|
}
|
|
}
|
|
|
|
return "UNKNOWN";
|
|
}
|
|
|
|
/* Export configuration to JSON */
|
|
int azeron_device_export_config_json(struct azeron_device *device, struct json_object **json)
|
|
{
|
|
struct json_object *root;
|
|
struct json_object *profiles_array;
|
|
struct azeron_device_info info;
|
|
int ret;
|
|
int i;
|
|
|
|
if (!device || !json) {
|
|
return AZERON_ERROR_INVALID_PARAM;
|
|
}
|
|
|
|
root = json_object_new_object();
|
|
if (!root) {
|
|
return AZERON_ERROR_NO_MEM;
|
|
}
|
|
|
|
/* Add device info */
|
|
ret = azeron_device_get_info(device, &info);
|
|
if (ret == AZERON_SUCCESS) {
|
|
json_object_object_add(root, "vendor_id", json_object_new_int(info.vendor_id));
|
|
json_object_object_add(root, "product_id", json_object_new_int(info.product_id));
|
|
json_object_object_add(root, "serial_number", json_object_new_string(info.serial_number));
|
|
json_object_object_add(root, "firmware_version", json_object_new_int(info.firmware_version));
|
|
}
|
|
|
|
/* Create profiles array */
|
|
profiles_array = json_object_new_array();
|
|
if (!profiles_array) {
|
|
json_object_put(root);
|
|
return AZERON_ERROR_NO_MEM;
|
|
}
|
|
|
|
/* Add placeholder profiles - actual implementation would read from device */
|
|
for (i = 0; i < 3; i++) {
|
|
struct json_object *profile = json_object_new_object();
|
|
char name[32];
|
|
|
|
snprintf(name, sizeof(name), "Profile %d", i + 1);
|
|
json_object_object_add(profile, "id", json_object_new_int(i));
|
|
json_object_object_add(profile, "name", json_object_new_string(name));
|
|
json_object_object_add(profile, "active", json_object_new_boolean(i == 0));
|
|
|
|
json_object_array_add(profiles_array, profile);
|
|
}
|
|
|
|
json_object_object_add(root, "profiles", profiles_array);
|
|
|
|
*json = root;
|
|
return AZERON_SUCCESS;
|
|
}
|
|
|
|
/* Import configuration from JSON */
|
|
int azeron_device_import_config_json(struct azeron_device *device, struct json_object *json)
|
|
{
|
|
(void)device;
|
|
(void)json;
|
|
|
|
AZERON_LOG("Import config from JSON - not yet implemented");
|
|
return AZERON_ERROR_UNSUPPORTED;
|
|
}
|
|
|
|
/* Export configuration to file */
|
|
int azeron_device_export_config(struct azeron_device *device, const char *filename)
|
|
{
|
|
struct json_object *json;
|
|
int ret;
|
|
|
|
if (!device || !filename) {
|
|
return AZERON_ERROR_INVALID_PARAM;
|
|
}
|
|
|
|
ret = azeron_device_export_config_json(device, &json);
|
|
if (ret != AZERON_SUCCESS) {
|
|
return ret;
|
|
}
|
|
|
|
ret = json_object_to_file_ext(filename, json, JSON_C_TO_STRING_PRETTY);
|
|
json_object_put(json);
|
|
|
|
if (ret != 0) {
|
|
return AZERON_ERROR_IO;
|
|
}
|
|
|
|
return AZERON_SUCCESS;
|
|
}
|
|
|
|
/* Import configuration from file */
|
|
int azeron_device_import_config(struct azeron_device *device, const char *filename)
|
|
{
|
|
struct json_object *json;
|
|
int ret;
|
|
|
|
if (!device || !filename) {
|
|
return AZERON_ERROR_INVALID_PARAM;
|
|
}
|
|
|
|
json = json_object_from_file(filename);
|
|
if (!json) {
|
|
return AZERON_ERROR_IO;
|
|
}
|
|
|
|
ret = azeron_device_import_config_json(device, json);
|
|
json_object_put(json);
|
|
|
|
return ret;
|
|
}
|