cmake_minimum_required(VERSION 3.14)

project(wayland)

enable_language(ASM_NASM)

set(CMAKE_ASM_NASM_FLAGS "-f elf64 -I${CMAKE_CURRENT_BINARY_DIR}")
set(CMAKE_ASM_NASM_FLAGS_DEBUG "-gdwarf")

find_package(PkgConfig REQUIRED)

# Находим программу wayland-scanner
find_program(WAYLAND_SCANNER wayland-scanner REQUIRED)

# Ищем директорию с протоколами Wayland
find_path(WAYLAND_PROTOCOLS_DIR
    NAMES stable/xdg-shell/xdg-shell.xml
    PATHS /usr/share/wayland-protocols /usr/local/share/wayland-protocols
    REQUIRED
)

# Путь к протоколу xdg-shell
set(PROTOCOL_XML ${WAYLAND_PROTOCOLS_DIR}/stable/xdg-shell/xdg-shell.xml)

# Генерируем заголовочный файл протокола
add_custom_command(
    OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/xdg-shell-client-protocol.h
    COMMAND ${WAYLAND_SCANNER} client-header ${PROTOCOL_XML} ${CMAKE_CURRENT_BINARY_DIR}/xdg-shell-client-protocol.h
    DEPENDS ${PROTOCOL_XML}
)

# Генерируем исходный файл протокола
add_custom_command(
    OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/xdg-shell-client-protocol.c
    COMMAND ${WAYLAND_SCANNER} private-code ${PROTOCOL_XML} ${CMAKE_CURRENT_BINARY_DIR}/xdg-shell-client-protocol.c
    DEPENDS ${PROTOCOL_XML}
)

# Цель для генерации протокола
add_custom_target(generate-xdg-shell DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/xdg-shell-client-protocol.h ${CMAKE_CURRENT_BINARY_DIR}/xdg-shell-client-protocol.c)

# Генерируем offsets.inc
add_executable(generate-offsets ${CMAKE_CURRENT_SOURCE_DIR}/generate-offsets.c)
target_include_directories(generate-offsets PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include)

add_custom_command(
    OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/offsets.inc
    COMMAND generate-offsets > ${CMAKE_CURRENT_BINARY_DIR}/offsets.inc
    DEPENDS generate-offsets
    COMMENT "Generating offsets.inc"
)

add_custom_target(generate-offsets-file DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/offsets.inc)

# Создаем исполняемый файл из ассемблерного, C и сгенерированного кода
file(GLOB_RECURSE WAYLAND_SOURCES CONFIGURE_DEPENDS
    "${CMAKE_CURRENT_SOURCE_DIR}/src/*.c"
    "${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp"
    "${CMAKE_CURRENT_SOURCE_DIR}/src/*.asm"
)

# Append the generated XDG C source (will be created in the binary dir)
list(APPEND WAYLAND_SOURCES ${CMAKE_CURRENT_BINARY_DIR}/xdg-shell-client-protocol.c)

# Create executable from collected sources
add_executable(wayland ${WAYLAND_SOURCES})

# Ensure generated files are produced before building the target
add_dependencies(wayland generate-xdg-shell generate-offsets-file)

# Include headers and binary dir where generated headers are written
target_include_directories(wayland PRIVATE
    ${CMAKE_CURRENT_SOURCE_DIR}/include
    ${CMAKE_CURRENT_BINARY_DIR}
    ${WAYLAND_CLIENT_INCLUDE_DIRS}
    ${XKBCOMMON_INCLUDE_DIRS}
)

pkg_check_modules(WAYLAND_CLIENT REQUIRED wayland-client)
set(WAYLAND_CLIENT_LIBRARIES ${WAYLAND_CLIENT_LIBRARIES})
set(WAYLAND_CLIENT_INCLUDE_DIRS ${WAYLAND_CLIENT_INCLUDE_DIRS})

# xkbcommon for keyboard layout handling
pkg_check_modules(XKBCOMMON REQUIRED xkbcommon)
set(XKBCOMMON_LIBRARIES ${XKBCOMMON_LIBRARIES})
set(XKBCOMMON_INCLUDE_DIRS ${XKBCOMMON_INCLUDE_DIRS})

find_package(Threads REQUIRED)

# Link to system libraries
target_link_libraries(wayland PRIVATE ${WAYLAND_CLIENT_LIBRARIES} ${XKBCOMMON_LIBRARIES} Threads::Threads)