mirror of
https://git.sr.ht/~thestr4ng3r/chiaki
synced 2025-08-20 05:23:12 -07:00
Begin libsetsu with udev scan
This commit is contained in:
parent
2f8d9d189d
commit
ec7b46ac67
7 changed files with 281 additions and 0 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -22,3 +22,5 @@ chiaki.rb
|
|||
*.jks
|
||||
secret.tar
|
||||
keystore-env.sh
|
||||
compile_commands.json
|
||||
.ccls-cache
|
||||
|
|
|
@ -65,6 +65,7 @@ if(CHIAKI_ENABLE_CLI)
|
|||
endif()
|
||||
|
||||
if(CHIAKI_ENABLE_GUI)
|
||||
add_subdirectory(setsu)
|
||||
add_subdirectory(gui)
|
||||
endif()
|
||||
|
||||
|
|
24
setsu/CMakeLists.txt
Normal file
24
setsu/CMakeLists.txt
Normal file
|
@ -0,0 +1,24 @@
|
|||
|
||||
cmake_minimum_required(VERSION 3.2)
|
||||
|
||||
project(libsetsu)
|
||||
|
||||
option(SETSU_BUILD_TEST "Build testing executable for libsetsu" OFF)
|
||||
|
||||
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
|
||||
|
||||
add_library(setsu
|
||||
include/setsu.h
|
||||
src/setsu.c)
|
||||
|
||||
target_include_directories(setsu PUBLIC include)
|
||||
|
||||
find_package(UDEV REQUIRED)
|
||||
target_link_libraries(setsu UDEV::libudev)
|
||||
|
||||
if(SETSU_BUILD_TEST)
|
||||
add_executable(setsutest
|
||||
test/main.c)
|
||||
target_link_libraries(setsutest setsu)
|
||||
endif()
|
||||
|
26
setsu/cmake/FindUDEV.cmake
Normal file
26
setsu/cmake/FindUDEV.cmake
Normal file
|
@ -0,0 +1,26 @@
|
|||
# Provides: UDEV::libudev
|
||||
|
||||
set(_prefix UDEV)
|
||||
set(_target "${_prefix}::libudev")
|
||||
|
||||
find_package(PkgConfig REQUIRED)
|
||||
|
||||
pkg_check_modules("${_prefix}" libudev)
|
||||
|
||||
function(resolve_location)
|
||||
|
||||
endfunction()
|
||||
|
||||
if(${_prefix}_FOUND)
|
||||
add_library("${_target}" INTERFACE IMPORTED)
|
||||
target_link_libraries("${_target}" INTERFACE ${${_prefix}_LIBRARIES})
|
||||
target_include_directories("${_target}" INTERFACE ${${_prefix}_INCLUDE_DIRS})
|
||||
endif()
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args("${_prefix}"
|
||||
REQUIRED_VARS "${_prefix}_LIBRARIES"
|
||||
VERSION_VAR "${_prefix}_VERSION")
|
||||
|
||||
unset(_prefix)
|
||||
unset(_target)
|
26
setsu/include/setsu.h
Normal file
26
setsu/include/setsu.h
Normal file
|
@ -0,0 +1,26 @@
|
|||
/*
|
||||
* This file is part of Chiaki.
|
||||
*
|
||||
* Chiaki 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Chiaki 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 Chiaki. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef _SETSU_H
|
||||
#define _SETSU_H
|
||||
|
||||
typedef struct setsu_ctx_t SetsuCtx;
|
||||
|
||||
SetsuCtx *setsu_ctx_new();
|
||||
void setsu_ctx_free(SetsuCtx *ctx);
|
||||
|
||||
#endif
|
177
setsu/src/setsu.c
Normal file
177
setsu/src/setsu.c
Normal file
|
@ -0,0 +1,177 @@
|
|||
|
||||
#include <setsu.h>
|
||||
|
||||
#include <libudev.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
typedef struct setsu_device_t
|
||||
{
|
||||
struct setsu_device_t *next;
|
||||
char *path;
|
||||
int fd;
|
||||
} SetsuDevice;
|
||||
|
||||
struct setsu_ctx_t
|
||||
{
|
||||
struct udev *udev_ctx;
|
||||
SetsuDevice *dev;
|
||||
};
|
||||
|
||||
|
||||
static void scan(SetsuCtx *ctx);
|
||||
static void update_device(SetsuCtx *ctx, struct udev_device *dev, bool added);
|
||||
static SetsuDevice *connect(SetsuCtx *ctx, const char *path);
|
||||
static void disconnect(SetsuCtx *ctx, SetsuDevice *dev);
|
||||
|
||||
SetsuCtx *setsu_ctx_new()
|
||||
{
|
||||
SetsuCtx *ctx = malloc(sizeof(SetsuCtx));
|
||||
if(!ctx)
|
||||
return NULL;
|
||||
|
||||
ctx->dev = NULL;
|
||||
|
||||
ctx->udev_ctx = udev_new();
|
||||
if(!ctx->udev_ctx)
|
||||
{
|
||||
free(ctx);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// TODO: monitor
|
||||
|
||||
scan(ctx);
|
||||
|
||||
return ctx;
|
||||
}
|
||||
|
||||
void setsu_ctx_free(SetsuCtx *ctx)
|
||||
{
|
||||
while(ctx->dev)
|
||||
disconnect(ctx, ctx->dev);
|
||||
udev_unref(ctx->udev_ctx);
|
||||
free(ctx);
|
||||
}
|
||||
|
||||
static void scan(SetsuCtx *ctx)
|
||||
{
|
||||
struct udev_enumerate *udev_enum = udev_enumerate_new(ctx->udev_ctx);
|
||||
if(!udev_enum)
|
||||
return;
|
||||
|
||||
if(udev_enumerate_add_match_subsystem(udev_enum, "input") < 0)
|
||||
goto beach;
|
||||
|
||||
if(udev_enumerate_add_match_property(udev_enum, "ID_INPUT_TOUCHPAD", "1") < 0)
|
||||
goto beach;
|
||||
|
||||
if(udev_enumerate_scan_devices(udev_enum) < 0)
|
||||
goto beach;
|
||||
|
||||
for(struct udev_list_entry *entry = udev_enumerate_get_list_entry(udev_enum); entry; entry = udev_list_entry_get_next(entry))
|
||||
{
|
||||
const char *path = udev_list_entry_get_name(entry);
|
||||
if(!path)
|
||||
continue;
|
||||
struct udev_device *dev = udev_device_new_from_syspath(ctx->udev_ctx, path);
|
||||
if(!dev)
|
||||
continue;
|
||||
update_device(ctx, dev, true);
|
||||
udev_device_unref(dev);
|
||||
}
|
||||
|
||||
beach:
|
||||
udev_enumerate_unref(udev_enum);
|
||||
}
|
||||
|
||||
static bool is_device_interesting(struct udev_device *dev)
|
||||
{
|
||||
static const char *device_ids[] = {
|
||||
// vendor id, model id
|
||||
"054c", "05c4", // DualShock 4 USB
|
||||
NULL
|
||||
};
|
||||
|
||||
// Filter mouse-device (/dev/input/mouse*) away and only keep the evdev (/dev/input/event*) one:
|
||||
if(!udev_device_get_property_value(dev, "ID_INPUT_TOUCHPAD_INTEGRATION"))
|
||||
return false;
|
||||
|
||||
const char *vendor = udev_device_get_property_value(dev, "ID_VENDOR_ID");
|
||||
const char *model = udev_device_get_property_value(dev, "ID_MODEL_ID");
|
||||
if(!vendor || !model)
|
||||
return false;
|
||||
|
||||
for(const char **dev_id = device_ids; *dev_id; dev_id += 2)
|
||||
{
|
||||
if(!strcmp(vendor, dev_id[0]) && !strcmp(model, dev_id[1]))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static void update_device(SetsuCtx *ctx, struct udev_device *dev, bool added)
|
||||
{
|
||||
if(!is_device_interesting(dev))
|
||||
return;
|
||||
const char *path = udev_device_get_devnode(dev);
|
||||
if(!path)
|
||||
return;
|
||||
|
||||
for(SetsuDevice *dev = ctx->dev; dev; dev=dev->next)
|
||||
{
|
||||
if(!strcmp(dev->path, path))
|
||||
{
|
||||
if(added)
|
||||
return; // already added, do nothing
|
||||
disconnect(ctx, dev);
|
||||
}
|
||||
}
|
||||
connect(ctx, path);
|
||||
}
|
||||
|
||||
static SetsuDevice *connect(SetsuCtx *ctx, const char *path)
|
||||
{
|
||||
SetsuDevice *dev = malloc(sizeof(SetsuDevice));
|
||||
if(!dev)
|
||||
return NULL;
|
||||
dev->path = strdup(path);
|
||||
if(!dev->path)
|
||||
{
|
||||
free(dev);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
printf("connect %s\n", dev->path);
|
||||
//dev->fd = open(dev->path, O_RDONLY | O_NONBLOCK);
|
||||
|
||||
dev->next = ctx->dev;
|
||||
ctx->dev = dev;
|
||||
return dev;
|
||||
}
|
||||
|
||||
static void disconnect(SetsuCtx *ctx, SetsuDevice *dev)
|
||||
{
|
||||
if(ctx->dev == dev)
|
||||
ctx->dev = dev->next;
|
||||
else
|
||||
{
|
||||
for(SetsuDevice *pdev = ctx->dev; pdev; pdev=pdev->next)
|
||||
{
|
||||
if(pdev->next == dev)
|
||||
{
|
||||
pdev->next = dev->next;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
free(dev->path);
|
||||
free(dev);
|
||||
}
|
||||
|
25
setsu/test/main.c
Normal file
25
setsu/test/main.c
Normal file
|
@ -0,0 +1,25 @@
|
|||
|
||||
#include <setsu.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
SetsuCtx *ctx;
|
||||
|
||||
void quit()
|
||||
{
|
||||
setsu_ctx_free(ctx);
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
ctx = setsu_ctx_new();
|
||||
if(!ctx)
|
||||
{
|
||||
printf("Failed to init setsu\n");
|
||||
return 1;
|
||||
}
|
||||
atexit(quit);
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue