// =====================================================================================================================
//  fennec, a free and open source game engine
//  Copyright © 2025  Medusa Slockbower
//
//  This program 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.
//
//  This program 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 this program.  If not, see <https://www.gnu.org/licenses/>.
// =====================================================================================================================

#ifndef FENNEC_PLATFORM_LINUX_XKB_LIB_FWD_H
#define FENNEC_PLATFORM_LINUX_XKB_LIB_FWD_H

#include <fennec/lang/types.h>

/*
 * Copyright © 2009-2012 Daniel Stone
 * Copyright © 2012 Intel Corporation
 * Copyright © 2012 Ran Benita
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice (including the next
 * paragraph) shall be included in all copies or substantial portions of the
 * Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 *
 * Author: Daniel Stone <daniel@fooishbar.org>
 */

struct xkb_context;
struct xkb_keymap;
struct xkb_state;
struct xkb_rule_names;

typedef uint32_t xkb_keycode_t;
typedef uint32_t xkb_keysym_t;
typedef uint32_t xkb_layout_index_t;
typedef uint32_t xkb_layout_mask_t;
typedef uint32_t xkb_level_index_t;
typedef uint32_t xkb_mod_index_t;
typedef uint32_t xkb_mod_mask_t;
typedef uint32_t xkb_led_index_t;
typedef uint32_t xkb_led_mask_t;

/**
 * The iterator used by xkb_keymap_key_for_each().
 *
 * @sa xkb_keymap_key_for_each
 * @memberof xkb_keymap
 * @since 0.3.1
 */
typedef void
(*xkb_keymap_key_iter_t)(struct xkb_keymap *keymap, xkb_keycode_t key,
						 void *data);

/** Flags for xkb_keysym_from_name(). */
enum xkb_keysym_flags {
	/** Do not apply any flags. */
	XKB_KEYSYM_NO_FLAGS = 0,
	/** Find keysym by case-insensitive search. */
	XKB_KEYSYM_CASE_INSENSITIVE = (1 << 0)
};

/** Flags for context creation. */
enum xkb_context_flags {
	/** Do not apply any context flags. */
	XKB_CONTEXT_NO_FLAGS = 0,
	/** Create this context with an empty include path. */
	XKB_CONTEXT_NO_DEFAULT_INCLUDES = (1 << 0),
	/**
	 * Don't take RMLVO names from the environment.
	 *
	 * @since 0.3.0
	 */
	XKB_CONTEXT_NO_ENVIRONMENT_NAMES = (1 << 1),
	/**
	 * Disable the use of secure_getenv for this context, so that privileged
	 * processes can use environment variables. Client uses at their own risk.
	 *
	 * @since 1.5.0
	 */
	XKB_CONTEXT_NO_SECURE_GETENV = (1 << 2)
};

/** Specifies a logging level. */
enum xkb_log_level {
	XKB_LOG_LEVEL_CRITICAL = 10, /**< Log critical internal errors only. */
	XKB_LOG_LEVEL_ERROR = 20,    /**< Log all errors. */
	XKB_LOG_LEVEL_WARNING = 30,  /**< Log warnings and errors. */
	XKB_LOG_LEVEL_INFO = 40,     /**< Log information, warnings, and errors. */
	XKB_LOG_LEVEL_DEBUG = 50     /**< Log everything. */
};

/** Flags for keymap compilation. */
enum xkb_keymap_compile_flags {
	/** Do not apply any flags. */
	XKB_KEYMAP_COMPILE_NO_FLAGS = 0
};

/** The possible keymap formats. */
enum xkb_keymap_format {
	/** The current/classic XKB text format, as generated by xkbcomp -xkb. */
	XKB_KEYMAP_FORMAT_TEXT_V1 = 1
};

/** Specifies the direction of the key (press / release). */
enum xkb_key_direction {
	XKB_KEY_UP,   /**< The key was released. */
	XKB_KEY_DOWN  /**< The key was pressed. */
};

/**
 * Modifier and layout types for state objects.  This enum is bitmaskable,
 * e.g. (XKB_STATE_MODS_DEPRESSED | XKB_STATE_MODS_LATCHED) is valid to
 * exclude locked modifiers.
 *
 * In XKB, the DEPRESSED components are also known as 'base'.
 */
enum xkb_state_component {
	/** Depressed modifiers, i.e. a key is physically holding them. */
	XKB_STATE_MODS_DEPRESSED = (1 << 0),
	/** Latched modifiers, i.e. will be unset after the next non-modifier
	 *  key press. */
	XKB_STATE_MODS_LATCHED = (1 << 1),
	/** Locked modifiers, i.e. will be unset after the key provoking the
	 *  lock has been pressed again. */
	XKB_STATE_MODS_LOCKED = (1 << 2),
	/** Effective modifiers, i.e. currently active and affect key
	 *  processing (derived from the other state components).
	 *  Use this unless you explicitly care how the state came about. */
	XKB_STATE_MODS_EFFECTIVE = (1 << 3),
	/** Depressed layout, i.e. a key is physically holding it. */
	XKB_STATE_LAYOUT_DEPRESSED = (1 << 4),
	/** Latched layout, i.e. will be unset after the next non-modifier
	 *  key press. */
	XKB_STATE_LAYOUT_LATCHED = (1 << 5),
	/** Locked layout, i.e. will be unset after the key provoking the lock
	 *  has been pressed again. */
	XKB_STATE_LAYOUT_LOCKED = (1 << 6),
	/** Effective layout, i.e. currently active and affects key processing
	 *  (derived from the other state components).
	 *  Use this unless you explicitly care how the state came about. */
	XKB_STATE_LAYOUT_EFFECTIVE = (1 << 7),
	/** LEDs (derived from the other state components). */
	XKB_STATE_LEDS = (1 << 8)
};

/**
 * Match flags for xkb_state_mod_indices_are_active() and
 * xkb_state_mod_names_are_active(), specifying the conditions for a
 * successful match.  XKB_STATE_MATCH_NON_EXCLUSIVE is bitmaskable with
 * the other modes.
 */
enum xkb_state_match {
	/** Returns true if any of the modifiers are active. */
	XKB_STATE_MATCH_ANY = (1 << 0),
	/** Returns true if all of the modifiers are active. */
	XKB_STATE_MATCH_ALL = (1 << 1),
	/** Makes matching non-exclusive, i.e. will not return false if a
	 *  modifier not specified in the arguments is active. */
	XKB_STATE_MATCH_NON_EXCLUSIVE = (1 << 16)
};

enum xkb_consumed_mode {
	/**
	 * This is the mode defined in the XKB specification and used by libX11.
	 *
	 * A modifier is consumed if and only if it *may affect* key translation.
	 *
	 * For example, if `Control+Alt+<Backspace>` produces some assigned keysym,
	 * then when pressing just `<Backspace>`, `Control` and `Alt` are consumed,
	 * even though they are not active, since if they *were* active they would
	 * have affected key translation.
	 */
	XKB_CONSUMED_MODE_XKB,
	/**
	 * This is the mode used by the GTK+ toolkit.
	 *
	 * The mode consists of the following two independent heuristics:
	 *
	 * - The currently active set of modifiers, excluding modifiers which do
	 *   not affect the key (as described for @ref XKB_CONSUMED_MODE_XKB), are
	 *   considered consumed, if the keysyms produced when all of them are
	 *   active are different from the keysyms produced when no modifiers are
	 *   active.
	 *
	 * - A single modifier is considered consumed if the keysyms produced for
	 *   the key when it is the only active modifier are different from the
	 *   keysyms produced when no modifiers are active.
	 */
	XKB_CONSUMED_MODE_GTK
};

#endif // FENNEC_PLATFORM_LINUX_XKB_LIB_FWD_H
