pax_global_header00006660000000000000000000000064134134476130014520gustar00rootroot0000000000000052 comment=225ac56fac62c096faa2ac8a39ca2a1a121df0b7 keyman-keyboardprocessor-11.0.101/000077500000000000000000000000001341344761300167635ustar00rootroot00000000000000keyman-keyboardprocessor-11.0.101/doc/000077500000000000000000000000001341344761300175305ustar00rootroot00000000000000keyman-keyboardprocessor-11.0.101/doc/BUILDING.md000066400000000000000000000033101341344761300212440ustar00rootroot00000000000000# How to build the keyboard processor ## Prerequisites - Python 3 - Meson build system. - C++14 or later compiler. - lib std::fs - kmcomp (for tests) -- must be added to path ## Installing Python3 ### Linux You will be able to install a python3 package in any reputable recent version of linux using its package manager if it's not already installed. ### Mac OS X You can get the official installer from the official Python site: [https://www.python.org/downloads/mac-osx/]() ### Windows You can get the official installer from the official Python site: [https://www.python.org/downloads/windows/]() ## Installing Meson Ensure you have Python3 correctly installed and can run the command `pip3`. ``` python3 -m pip install meson ``` ## Building In your source directory do the following: ``` cd keyboardprocessor meson build --werror cd build ninja meson test ``` ## Note on kmcomp kmcomp is the command-line compiler from Keyman Developer, available from https://keyman.com/ or in this repo in /windows/src/developer/kmcomp. The compiler is currently available as a Windows PE executable only, but it does run under WINE. ### Windows The search path can be edited through System settings / Advanced system settings / Environment Variables / User environment variables. If you have Keyman Developer installed, add %KeymanDeveloperPath% to your path. Otherwise, add the path where you extracted the kmcomp archive. ### Linux You need a wrapper `kmcomp` shell script: ``` #!/bin/bash wine `dirname "$0"`/kmcomp.exe "$@" ``` Place this in the same folder as you extracted kmcomp.exe, and `chmod +x kmcomp`. Add the folder to the path (e.g. `export PATH=/path/to/kmcomp:$PATH`, which you can add to `.bashrc`) ### macOS TODOkeyman-keyboardprocessor-11.0.101/doc/hotdoc.json000066400000000000000000000005231341344761300217030ustar00rootroot00000000000000{ "project_name": "@project_name@", "project_version": "@project_version@", "sitemap": "../../doc/sitemap.txt", "index": "../../doc/markdown_files/index.md", "c_sources": [ "../include/keyboardprocessor.h" ], "c_smart_index" : true, "output": ".", "extra_assets": [ "../../assets" ] } keyman-keyboardprocessor-11.0.101/doc/introspection.schema000066400000000000000000000034521341344761300236160ustar00rootroot00000000000000{"$schema": "http://json-schema.org/draft-06/schema#", "$id": "@replace_me_with_introspection_schema_uri@", "$comment": "© 2018 SIL International. MIT Licensed", "title": "Keyboard Processor State object introspection", "description": "Internal data from a Keyboard Processor State object, sufficient for debugging and diagnostics", "type": "object", "definitions": { "options": { "type": "object", "properties": { "scope": { "enum": ["unknown", "environment", "keyboard"] }, "options": { "type": "object", "default": {} } }, "required": ["scope", "options"] }, "rule": { "type": "object" }, "keyboard" : { "type": "object", "properties": { "id": { "type": "string" }, "version": { "type": "string" }, "folder": { "type": "string"}, "options": { "$ref": "#definitions/options" }, "rules": { "type":"array", "items": { "$ref": "#/definitions/rule" } } }, "required": ["id", "version", "folder", "options", "rules"] }, "context": { "type":"array", "items": {"$ref": "#/definitions/context_item"}, "default": [] }, "context_item": { "oneOf": [ {"type": "string", "minLength": 1, "maxLength": 4}, {"type": "number"} ] } }, "properties": { "$schema": { "const": "keyman/keyboardprocessor/doc/introspection.schema" }, "keyboard": { "$ref": "#/definitions/keyboard" }, "options": { "type": "object", "properties": { "enviroment": { "$ref": "#/definitions/options" }, "dynamic": { "$ref": "#/definitions/options" } }, "required": [ "enviroment","dynamic"] }, "context": { "$ref": "#/definitions/context" } } } keyman-keyboardprocessor-11.0.101/doc/markdown_files/000077500000000000000000000000001341344761300225345ustar00rootroot00000000000000keyman-keyboardprocessor-11.0.101/doc/markdown_files/index.md000066400000000000000000000036171341344761300241740ustar00rootroot00000000000000# Keyman Keyboard Processor API ## Requirements 1. Cross platform. 2. Cross language. 3. Facilitate stateless operation of the Engine. 4. Keyboard format agnostic -- support both KMN and future LDML based keyboards. 5. Support querying Engine attributes. 6. Support querying Keyboard attributes. 7. Idempotent ## Design decisions in support of requirements: - Use C or C99 types and calling convention for the interface, it has the broadest language FFI support. [1,2] - Have client (platform glue) code load keyboards, manage & pass state. [3,4,7] - Provide query calls to return static attributes data for keyboards and engine [5,6] - Provide get/set calls for client accessible keyboard state information [3,4] ## Glossary - __Platform layer:__ the code that consumes the Keyman Keyboard Processor API, and provides the operating system-specific handling of keystroke events and integration with applications. - __Client Application:__ the application that has the focus and receives text events from the Platform layer. - __Context:__ Text preceding the insertion point - __Marker:__ Positional state that can be placed in the Context. - __Keyboard:__ A set of rules for execution my an Engine - __Option:__ A variable in a dynamic or static key value store. - __Processor:__ The component that implements this API and can parse and execute a particular keyboard. - __State:__ An object that hold internal state of the Processor for a given insertion point - __Action:__ A directive output by the processor detailing how the Platform layer should transform the Client Application's text buffer. There may be several items produced by a single keyboard event. - __Keyboard Event:__ A virtual key board event and modifier map recevied from the platform to be processed with the state object for this Client application. ## API ### Namespace All calls, types and enums are prefixed with the namespace identifier `km_kbp_` keyman-keyboardprocessor-11.0.101/doc/meson.build000066400000000000000000000017721341344761300217010ustar00rootroot00000000000000# Copyright: © 2018 SIL International. # Description: Cross platform build script to extract and generate # documentation for the API. This is speculative ATM. # Create Date: 5 Oct 2018 # Authors: Tim Eves (TSE) # hotdoc = find_program('hotdoc', required: false) installdir = join_paths(get_option('datadir'), 'doc', meson.project_name()) if hotdoc.found() cfg = configuration_data() cfg.set('project_name', meson.project_name()) cfg.set('project_version', meson.project_version()) configure_file(input: 'hotdoc.json', output: 'hotdoc.json', configuration: cfg) deps = files( '../include/keyboardprocessor.h.in', '../src/json.hpp', '../src/utfcodec.hpp' ) docs = custom_target('docs', output: ['html'], input: ['sitemap.txt', 'markdown_files/index.md'], command: [hotdoc, '--verbose', '--conf-file=doc/hotdoc.json', '--output=doc', 'run'], depend_files: deps, install: true, install_dir: installdir) endif keyman-keyboardprocessor-11.0.101/doc/sitemap.txt000066400000000000000000000000221341344761300217250ustar00rootroot00000000000000index.md c-index keyman-keyboardprocessor-11.0.101/include/000077500000000000000000000000001341344761300204065ustar00rootroot00000000000000keyman-keyboardprocessor-11.0.101/include/keyboardprocessor.h.in000066400000000000000000001001241341344761300247220ustar00rootroot00000000000000/* Copyright: © 2018 SIL International. Description: Cross platform API C/C++ declarations for libkmnkbp keyboard processor. Create Date: 2 Oct 2018 Authors: Tim Eves (TSE) History: 18 Oct 2018 - TSE - Finialised verion of API. 6 Oct 2018 - TSE - Move into keyman folder. */ #pragma once /* # Keyman Keyboard Processor API ## Requirements 1. Cross platform. 2. Cross language. 3. Facilitate stateless operation of the Engine. 4. Keyboard format agnostic -- support both KMN and future LDML based keyboards. 5. Support querying Engine attributes. 6. Support querying Keyboard attributes. 7. Idempotent ## Design decisions in support of requirements: - Use C or C99 types and calling convention for the interface, it has the broadest language FFI support. [1,2] - Have client (Platform layer) code load keyboards, manage & pass state. [3,4,7] - Provide query calls to return static attributes data for keyboards and engine [5,6] - Provide get/set calls for client accessible keyboard state information [3,4] ## Glossary - __Platform layer:__ The code that consumes the Keyman Keyboard Processor API, and provides the operating system-specific handling of keystroke events and integration with applications. - __Client Application:__ The application that has the focus and receives text events from the Platform layer. - __Context:__ Text preceding the insertion point - __Marker:__ Positional state that can be placed in the Context. - __Keyboard:__ A set of rules for execution my an Engine - __Option:__ A variable in a dynamic or static key value store. - __Processor:__ The component that implements this API and can parse and execute a particular keyboard. - __State:__ An object that hold internal state of the Processor for a given insertion point - __Action:__ A directive output by the processor detailing how the Platform layer should transform the Client Application's text buffer. There may be several items produced by a single keyboard event. - __Keyboard Event:__ A virtual key event and modifier map received from the platform to be processed with the state object for this Client application. - __Virtual Key:__ A code based on the US English layout, with values matching the Windows virtual key codes. See keyboardprocessor_vkeys.h for definitions. - __Modifier Key:__ The set of Control, Shift, Alt, Caps Lock keys. On some platforms these may have other names (e.g. Alt is called Option on macOS); other platform-specific modifiers such as Windows key are excluded from this set. Some modifiers are transient, such as Control, and others have long-lasting state, such as Caps Lock. ## API ### Namespace All calls, types and enums are prefixed with the namespace identifier `km_kbp_` ### API idioms Almost all calls marshalling variable length aggregate data in or out of an API object take the form: > km_kbp_status *fn_name*(object_ref, buffer_ptr, size_ptr) where the buffer is nullable and all other arguments are required (will result in an `KM_KBP_STATUS_INVALID_ARGUMENT` status being returned if nulled). When `buffer` is `nullptr` or `0` the function will place the size of the required buffer in the variable pointed to by `size_ptr`. Calls which result in the allocation of resources, regardless of resulting ownership, are of the form: > km_kbp_status *fn_name*(object_ref, out_ptr) where `out_ptr` is a valid pointer to a caller allocated variable to hold the resulting ouput. This is often a reference to a created object. All arguments are required (will result in an `KM_KBP_STATUS_INVALID_ARGUMENT` status being returned if nulled). For accessors to fixed size attributes of an object these will take the form: > attr_value __fn_name__(object_ref) `object_ref` is required to be valid and will result in a nonsense value being returned if `nullptr` or `0`. All dispose calls are designed to accept null as a valid value and will do nothing in that event. ```c */ #include #include #include #include #define KM_KBP_LIB_CURRENT @lib_curr@ #define KM_KBP_LIB_AGE @lib_age@ #define KM_KBP_LIB_REVISION @lib_rev@ #if defined(__cplusplus) extern "C" { #endif // Basic types // #if defined(__cplusplus) typedef char16_t km_kbp_cp; typedef char32_t km_kbp_usv; #else typedef uint16_t km_kbp_cp; // code point typedef uint32_t km_kbp_usv; // Unicode Scalar Value #endif typedef uint16_t km_kbp_virtual_key; // A virtual key code. typedef uint32_t km_kbp_status; // Status return code. // Opaque object types. // typedef struct km_kbp_context km_kbp_context; typedef struct km_kbp_keyboard km_kbp_keyboard; typedef struct km_kbp_state km_kbp_state; typedef struct km_kbp_options km_kbp_options; // Forward declarations // typedef struct km_kbp_option_item km_kbp_option_item; /*``` ### Error Handling Error handling and success failure notification are communicated through a general mechanism similar to COM’s `HRESULT` scheme (unlike COM, any non-zero value is an error). Any functions that can fail will always return a status value and all results are returned via outparams passed to the function. ```c */ enum km_kbp_status_codes { KM_KBP_STATUS_OK = 0, KM_KBP_STATUS_NO_MEM = 1, KM_KBP_STATUS_IO_ERROR = 2, KM_KBP_STATUS_INVALID_ARGUMENT = 3, KM_KBP_STATUS_KEY_ERROR = 4, KM_KBP_STATUS_INSUFFICENT_BUFFER = 5, KM_KBP_STATUS_INVALID_UTF = 6, KM_KBP_STATUS_INVALID_KEYBOARD = 7, KM_KBP_STATUS_OS_ERROR = 0x80000000 }; /* ``` The final status code KM_KBP_STATUS_OS_ERROR is intended to allow encapsulating a platform error code; the remaining 31 low bits are the error code returned by the OS for cases where the failure mode is platform specific. For HRESULT codes this only permits failure codes to be passed. ### Context The context is the text prior to the insertion point (caret, cursor). The context is constructed by the Platform layer, typically by interrogating the Client Application. The context will be updated by the engine for keystroke events. If the Platform layer code caches the context, the context should be reset when a context state change is detected. Context state changes can occur when the user uses the mouse to move the insertion point, uses cursor keys, switches applications or input fields, or presses hotkeys such as Ctrl+N to start a new document. The full set of context state change triggers is up to the Platform layer. Context can also contain positional Markers (also known as 'deadkeys' in kmn keyboards), which are transitory state flags that are erased whenever a context state change is detected. Markers are always controlled by the Engine. Contexts are always owned by their state. They may be set to a list of context_items or interrogated for their current list of context items. ```c */ enum km_kbp_context_type { KM_KBP_CT_END, KM_KBP_CT_CHAR, KM_KBP_CT_MARKER }; typedef struct { uint8_t type; uint8_t _reserved[3]; union { km_kbp_usv character; uint32_t marker; }; } km_kbp_context_item; #define KM_KBP_CONTEXT_ITEM_END {KM_KBP_CT_END, {0,}, {0,}} /* ``` ### `km_kbp_context_items_from_utf16` ##### Description: Convert a UTF16 encoded Unicode string into an array of `km_kbp_context_item` structures. Allocates memory as needed. ##### Return status: - `KM_KBP_STATUS_OK`: On success. - `KM_KBP_STATUS_INVALID_ARGUMENT`: If non-optional parameters are null. - `KM_KBP_STATUS_NO_MEM`: In the event not enough memory can be allocated for the output buffer. - `KM_KBP_STATUS_INVALID_UTF`: In the event the UTF16 string cannot be decoded because it contains unpaired surrogate codeunits. ##### Parameters: - __text__: a pointer to a null terminated array of utf16 encoded data. - __out_ptr__: a pointer to the result variable: A pointer to the start of the `km_kbp_context_item` array containing the representation of the input string. Terminated with a type of `KM_KBP_CT_END`. Must be disposed of with `km_kbp_context_items_dispose`. ```c */ KMN_API km_kbp_status km_kbp_context_items_from_utf16(km_kbp_cp const *text, km_kbp_context_item **out_ptr); /* ``` ### `km_kbp_context_items_from_utf8` ##### Description: Convert an UTF8 encoded Unicode string into an array of `km_kbp_context_item` structures. Allocates memory as needed. ##### Status: - `KM_KBP_STATUS_INVALID_ARGUMENT`: If non-optional parameters are null. - `KM_KBP_STATUS_NO_MEM`: In the event it cannot allocate enough memory for the output buffer. - `KM_KBP_STATUS_INVALID_UTF`: In the event the UTF8 string cannot be decoded. ##### Parameters: - __text__: a pointer to a null terminated array of utf8 encoded data. - __out_ptr__: a pointer to the result variable: A pointer to the start of the `km_kbp_context_item` array containing the representation of the input string. Terminated with a type of `KM_KBP_CT_END`. ```c */ KMN_API km_kbp_status km_kbp_context_items_from_utf8(char const *text, km_kbp_context_item **out_ptr); /* ``` ### `km_kbp_context_items_to_utf16` ##### Description: Convert a context item array into a UTF-16 encoded string placing it into the supplied buffer of specified size, and return the number codepoints actually used in the conversion. If null is passed as the buffer the number codeunits required is returned. This will strip markers from the context during the conversion. ##### Return status: - `KM_KBP_STATUS_OK`: On success. - `KM_KBP_STATUS_INVALID_ARGUMENT`: If non-optional parameters are null. - `KM_KBP_STATUS_INSUFFICENT_BUFFER`: If the buffer is not large enough. `buf_size` will contain the space required. The contents of the buffer are undefined. ##### Parameters: - __context_items__: A pointer to the start of an array `km_kbp_context_item`. Must be terminated with a type of `KM_KBP_CT_END`. - __buf__: A pointer to the buffer to place the UTF-16 string into. May be be null to request size calculation. - __buf_size__: a pointer to the result variable: A pointer the size of the supplied buffer in codeunits or filled with the size required if `buf` is null. ```c */ KMN_API km_kbp_status km_kbp_context_items_to_utf16(km_kbp_context_item const *item, km_kbp_cp *buf, size_t *buf_size); /* ``` ### `km_kbp_context_items_to_utf8` ##### Description: Convert a context item array into a UTF-8 encoded string placing it into the supplied buffer of specified size, and return the number codepoints actually used in the conversion. If null is passed as the buffer the number codeunits required is returned. This will strip markers from the context during the conversion. ##### Return status: - `KM_KBP_STATUS_OK`: On success. - `KM_KBP_STATUS_INVALID_ARGUMENT`: If non-optional parameters are null. - `KM_KBP_STATUS_INSUFFICENT_BUFFER`: If the buffer is not large enough. `buf_size` will contain the space required. The contents of the buffer are undefined. ##### Parameters: - __context_items__: A pointer to the start of an array `km_kbp_context_item`. Must be terminated with a type of `KM_KBP_CT_END`. - __buf__: A pointer to the buffer to place the UTF-8 string into. May be be null to request size calculation. - __buf_size__: a pointer to the result variable: A pointer the size of the supplied buffer in codeunits or filled with the size required if `buf` is null. ```c */ KMN_API km_kbp_status km_kbp_context_items_to_utf8(km_kbp_context_item const *item, char *buf, size_t *buf_size); /* ``` ### `km_kbp_context_items_dispose` ##### Description: Free the allocated memory belonging to a `km_kbp_context_item` array previously returned by `km_kbp_context_items_from_utf16` or `km_kbp_context_get` ##### Parameters: - __context_items__: A pointer to the start of the `km_kbp_context_item` array to be disposed of. ```c */ KMN_API void km_kbp_context_items_dispose(km_kbp_context_item *context_items); /* ``` ### `km_kbp_context_set` ##### Description: Replace the contents of the current context with a new sequence of `km_kbp_context_item` entries. ##### Return status: - `KM_KBP_STATUS_OK`: On success. - `KM_KBP_STATUS_INVALID_ARGUMENT`: If non-optional parameters are null. - `KM_KBP_STATUS_NO_MEM`: In the event not enough memory can be allocated to grow the context buffer internally. ##### Parameters: - __context__: A pointer to an opaque context object - __context_items__: A pointer to the start of the `km_kbp_context_item` array containing the new context. It must be terminated with an item of type `KM_KBP_CT_END`. ```c */ KMN_API km_kbp_status km_kbp_context_set(km_kbp_context *context, km_kbp_context_item const *context_items); /* ``` ### `km_kbp_context_get` ##### Description: Copies all items in the context into a new array and returns the new array. This must be disposed of by caller using `km_kbp_context_items_dispose`. ##### Return status: - `KM_KBP_STATUS_OK`: On success. - `KM_KBP_STATUS_INVALID_ARGUMENT`: If non-optional parameters are null. - `KM_KBP_STATUS_NO_MEM`: In the event not enough memory can be allocated for the output buffer. ##### Parameters: - __context_items__: A pointer to the start of an array `km_kbp_context_item`. - __out__: a pointer to the result variable: A pointer to the start of the `km_kbp_context_item` array containing a copy of the context. Terminated with a type of `KM_KBP_CT_END`. Must be disposed of with `km_kbp_context_items_dispose`. ```c */ KMN_API km_kbp_status km_kbp_context_get(km_kbp_context const *context_items, km_kbp_context_item **out); /* ``` ### `km_kbp_context_clear` ##### Description: Removes all context_items from the internal array. If `context` is null, has no effect. ##### Parameters: - __context__: A pointer to an opaque context object ```c */ KMN_API void km_kbp_context_clear(km_kbp_context *); /* ``` ### `km_kbp_context_length` ##### Description: Return the number of items in the context. ##### Return: The number of items in the context, and will return 0 if passed a null `context` pointer. ##### Parameters: - __context__: A pointer to an opaque context object ```c */ KMN_API size_t km_kbp_context_length(km_kbp_context *); /* ``` ### `km_kbp_context_append` ##### Description: Add more items to the end (insertion point) of the context. If these exceed the maximum context length the same number of items will be dropped from the beginning of the context. ##### Return status: - `KM_KBP_STATUS_OK`: On success. - `KM_KBP_STATUS_INVALID_ARGUMENT`: If non-optional parameters are null. - `KM_KBP_STATUS_NO_MEM`: In the event not enough memory can be allocated to grow the context buffer internally. ##### Parameters: - __context__: A pointer to an opaque context object. - __context_items__: A pointer to the start of the `KM_KBP_CT_END` terminated array of `km_kbp_context_item` to append. ```c */ KMN_API km_kbp_status km_kbp_context_append(km_kbp_context *context, km_kbp_context_item const *context_items); /* ``` ### `km_kbp_context_shrink` ##### Description: Remove a specified number of items from the end of the context, optionally add up to the same number of the supplied items to the front of the context. ##### Return status: - `KM_KBP_STATUS_OK`: On success. - `KM_KBP_STATUS_INVALID_ARGUMENT`: If non-optional parameters are null. - `KM_KBP_STATUS_NO_MEM`: in the event it cannot allocated enough memory to grow the context internally. ##### Parameters: - __context__: A pointer to an opaque context object. - __num__: The number of items to remove from the end of context. - __context_items__: Pointer to the start of the `KM_KBP_CT_END` terminated array of `km_kbp_context_item` to add to the front. Up to `num` items will be prepended. This may be null if not required. ```c */ KMN_API km_kbp_status km_kbp_context_shrink(km_kbp_context *context, size_t num, km_kbp_context_item const *prefix); /* ``` ### Action Items These provide the results of processing a key event to the Platform layer and should be processed by the Platform layer to issue commands to the os text services framework to transform the text store in the Client Application, among other actions. ```c */ typedef struct { uint8_t type; uint8_t _reserved[sizeof(void*)-sizeof(uint8_t)]; union { uintptr_t marker; // MARKER type km_kbp_option_item const * option; // OPT types km_kbp_usv character; // CHAR type km_kbp_virtual_key vkey; // VKEY types size_t erased; // BACK type }; } km_kbp_action_item; enum km_kbp_action_type { KM_KBP_IT_END = 0, // Marks end of action items list. KM_KBP_IT_CHAR = 1, // A Unicode character has been generated. KM_KBP_IT_MARKER = 2, // Correlates to kmn's "deadkey" markers. KM_KBP_IT_ALERT = 3, // The keyboard has triggered a alert/beep/bell. KM_KBP_IT_BACK = 4, // Delete the codepoint preceding the insertion point. KM_KBP_IT_PERSIST_OPT = 5, // The indicated option needs to be stored. KM_KBP_IT_EMIT_KEYSTROKE = 6, // Emit the current keystroke to the application KM_KBP_IT_INVALIDATE_CONTEXT = 7, // The processor requests that the context buffer be cleared; // for applications where context is cached, this clears the context; // for applications where context is read from the focused text store, // the context is just re-read and markers flushed. KM_KBP_IT_MAX_TYPE_ID }; /* ``` ### Options A state’s default options are set from the keyboard at creation time and the environment. The Platform layer is then is expected to apply any persisted options it is maintaining. Options are passed into and out of API functions as simple C arrays of `km_kbp_option_item` terminated with a `KM_KBP_OPTIONS_END` sentinel value. A state's options are exposed and manipulatable via the `km_kbp_options` API. All option values are of type C string. During processing when the Platform layer finds a PERSIST action type it should store the updated option in the appropriate place, based on its scope. For RESET the processor will apply the pristine value from the original scope, the Platform layer should update that only if it manages a previously persisted value. ```c */ enum km_kbp_option_scope { KM_KBP_OPT_UNKNOWN = 0, KM_KBP_OPT_KEYBOARD = 1, KM_KBP_OPT_ENVIRONMENT = 2, KM_KBP_OPT_MAX_SCOPES }; struct km_kbp_option_item { km_kbp_cp const * key; km_kbp_cp const * value; uint8_t scope; // Scope which an option belongs to. }; #define KM_KBP_OPTIONS_END { 0, 0, 0 } /* ``` ### `km_kbp_options_list_size` ##### Description: Return the length of a terminated `km_kbp_option_item` array (options list). ##### Return: The number of items in the list or 0 if `opts` is null. ##### Parameters: - __opts__: A pointer to a `KM_KBP_OPTIONS_END` terminated array of `km_kbp_option_item` values. ```c */ KMN_API size_t km_kbp_options_list_size(km_kbp_option_item const *opts); /* ``` ### `km_kbp_options_lookup` ##### Description: Lookup an option based on its key, in an options list. ##### Return status: - `KM_KBP_STATUS_OK`: On success. - `KM_KBP_STATUS_INVALID_ARGUMENT`: If non-optional parameters are null, or if the scope is invalid. - `KM_KBP_STATUS_KEY_ERROR`: The key cannot be found. ##### Parameters: - __state__: An opaque pointer to a state object. - __scope__: Which key-value store to interrogate. - __key__: A UTF-16 string that matches the key in the target `km_kbp_option_item`. - __value__: A pointer to the result variable: A pointer to a copy of the UTF-16 string value; undefined if return status is anything other than `KM_KBP_STATUS_OK`. This memory must be disposed of with `km_kbp_cp_dispose`. ```c */ KMN_API km_kbp_status km_kbp_options_lookup(km_kbp_state const *state, uint8_t scope, km_kbp_cp const *key, km_kbp_cp const **value); /* ``` ### `km_kbp_options_update` ##### Description: Adds or updates one or more options from a list of `km_kbp_option_item`s. ##### Return status: - `KM_KBP_STATUS_OK`: On success. - `KM_KBP_STATUS_INVALID_ARGUMENT`: If non-optional parameters are null. - `KM_KBP_STATUS_NO_MEM`: In the event an internal memory allocation fails. - `KM_KBP_STATUS_KEY_ERROR`: The key cannot be found. ##### Parameters: - __state__: An opaque pointer to a `km_kbp_state`. - __new_opts__: An array of `km_kbp_option_item` objects to update or add. Must be terminated with `KM_KBP_OPTIONS_END`. ```c */ KMN_API km_kbp_status km_kbp_options_update(km_kbp_state *state, km_kbp_option_item const *new_opts); /* ``` ### `km_kbp_options_to_json` ##### Description: Export the contents of a `km_kbp_options` array to a JSON formatted document and place it in the supplied buffer, reporting how much space was used. If null is passed as the buffer the number of bytes required is returned in `space`. If there is insufficent space to hold the document the contents of the buffer is undefined. The returned buffer uses UTF-8 encoding. ##### Return status: - `KM_KBP_STATUS_OK`: On success. - `KM_KBP_STATUS_INVALID_ARGUMENT`: If non-optional parameters are null. - `KM_KBP_STATUS_NO_MEM`: In the event an internal memory allocation fails. ##### Parameters: - __opts__: An opaque pointer to an options object. - __buf__: A pointer to the buffer to place the C string containing the JSON document into, can be null. - __space__: A pointer to a size_t variable. This variable must contain the number of bytes available in the buffer pointed to by `buf`, unless `buf` is null. On return it will hold how many bytes were used. ```c */ KMN_API km_kbp_status km_kbp_options_to_json(km_kbp_options const *opts, char *buf, size_t *space); /* ``` ### Keyboards A keyboard is a set of rules and transforms in a Processor specific format for transforming key events into action items. The keyboard is parsed and loaded by the processsor and made available in an immutable fashion for use with any number of state objects. ```c */ typedef struct { km_kbp_cp const * version_string; // Processor specific version string. km_kbp_cp const * id; // Keyman keyboard ID string. km_kbp_path_name folder_path; // Path to the unpacked folder containing // the keyboard and associated resources. km_kbp_option_item const * default_options; } km_kbp_keyboard_attrs; /* ``` ### `km_kbp_keyboard_load` ##### Description: Parse and load keyboard from the supplied path and a pointer to the loaded keyboard into the out paramter. ##### Return status: - `KM_KBP_STATUS_OK`: On success. - `KM_KBP_STATUS_NO_MEM`: In the event an internal memory allocation fails. - `KM_KBP_STATUS_IO_ERROR`: In the event the keyboard file is unparseable for any reason - `KM_KBP_STATUS_INVALID_ARGUMENT`: In the event the file doesn't exist or is inaccesible or `keyboard` is null. - `KM_KBP_STATUS_OS_ERROR`: Bit 31 (high bit) set, bits 0-30 are an OS-specific error code. ##### Parameters: - __kb_path__: On Windows, a UTF-16 string; on other platforms, a C string: contains a valid path to the keyboard file. - __keyboard__: A pointer to result variable: A pointer to the opaque keyboard object returned by the Processor. This memory must be freed with a call to `km_kbp_keyboard_dispose`. ```c */ KMN_API km_kbp_status km_kbp_keyboard_load(km_kbp_path_name kb_path, km_kbp_keyboard **keyboard); /* ``` ### `km_kbp_keyboard_dispose` ##### Description: Free the allocated memory belonging to an opaque keyboard object previously returned by `km_kbp_keyboard_load`. ##### Parameters: - __keyboard__: A pointer to the opaque keyboard object to be disposed of. ```c */ KMN_API void km_kbp_keyboard_dispose(km_kbp_keyboard *keyboard); /* ``` ### `km_kbp_keyboard_get_attrs` ##### Description: Returns the const internal attributes of the keyboard. This structure is valid for the lifetime of the opaque keyboard object. Do not modify the returned data. ##### Return status: - `KM_KBP_STATUS_OK`: On success. - `KM_KBP_STATUS_INVALID_ARGUMENT`: If non-optional parameters are null. ##### Parameters: - __keyboard__: A pointer to the opaque keyboard object to be queried. - __out__: A pointer to the result: A pointer to a `km_kbp_keyboard_attrs` structure. ```c */ KMN_API km_kbp_status km_kbp_keyboard_get_attrs(km_kbp_keyboard const *keyboard, km_kbp_keyboard_attrs const **out); /* ``` ### State A State object maintains all per keyboard related state including context and dynamic options ("option stores" in kmn format). ```c */ /* ``` ### `km_kbp_state_create` ##### Description: Create a keyboard processor state object, maintaining state for the keyboard in the environment passed. ##### Return status: - `KM_KBP_STATUS_OK`: On success. - `KM_KBP_STATUS_NO_MEM`: In the event memory is unavailable to allocate a state object. - `KM_KBP_STATUS_INVALID_ARGUMENT`: In the event the `keyboard` or `out` pointer are null. ##### Parameters: - __keyboard__: A pointer to the opaque keyboard object this object will hold state for. - __env__: The array of `km_kbp_option_item` key/value pairs used to initialise the environment, terminated by `KM_KBP_OPTIONS_END`. - __out__: A pointer to result variable: A pointer to the opaque state object returned by the Processor, initalised to maintain state for `keyboard`. This must be disposed of by a call to `km_kbp_state_dispose`. ```c */ KMN_API km_kbp_status km_kbp_state_create(km_kbp_keyboard *keyboard, km_kbp_option_item const *env, km_kbp_state **out); /* ``` ### `km_kbp_state_clone` ##### Description: Clone an existing opaque state object. ##### Return status: - `KM_KBP_STATUS_OK`: On success. - `KM_KBP_STATUS_NO_MEM`: In the event memory is unavailable to allocate a state object. - `KM_KBP_STATUS_INVALID_ARGUMENT`: In the event the `state` or `out` pointer are null. ##### Parameters: - __state__: A pointer to the opaque statea object to be cloned. - __out__: A pointer to result variable: A pointer to the opaque state object returned by the Processor, cloned from the existing object `state`. This must be disposed of by a call to `km_kbp_state_dispose`. ```c */ KMN_API km_kbp_status km_kbp_state_clone(km_kbp_state const *state, km_kbp_state **out); /* ``` ### `km_kbp_state_dispose` ##### Description: Free the allocated resources belonging to a `km_kbp_state` object previously returned by `km_kbp_state_create` or `km_kbp_state_clone`. After this all pointers previously returned by any km_kbp_state family of calls will become invalid. ##### Parameters: - __state__: A pointer to the opaque state object to be disposed. ```c */ KMN_API void km_kbp_state_dispose(km_kbp_state *state); /* ``` ### `km_kbp_state_context` ##### Description: Get access to the state object's context. ##### Return: A pointer to an opaque state object. This pointer is valid for the lifetime of the state object. If null is passed in, then null is returned. ##### Parameters: - __state__: A pointer to the opaque state object to be queried. ```c */ KMN_API km_kbp_context * km_kbp_state_context(km_kbp_state *state); /* ``` ### `km_kpb_state_options` ##### Description: Get access to the state object's options. ##### Return: A pointer to an opaque state object. This pointer is valid for the lifetime of the state object. If null is passed in, then null is returned. ##### Parameters: - __state__: A pointer to the opaque state object to be queried. ```c */ KMN_API km_kbp_options * km_kbp_state_options(km_kbp_state *state); /* ``` ### `km_kbp_state_action_items` ##### Description: Get the list of action items generated by the last call to `km_kbp_process_event`. ##### Return: A pointer to a `km_kbp_action_item` list, of `*num_items` in length. This data becomes invalid when the state object is destroyed, or after a call to `km_kbp_process_event`. Do not modify the contents of this data. The returned array is terminated with a `KM_KBP_IT_END` entry. ##### Parameters: - __state__: A pointer to the opaque `km_kbp_state` object to be queried. - __num_items__: A pointer to a result variable: The number of items in the action item list including the `KM_KBP_IT_END` terminator. May be null if not that information is required. ```c */ KMN_API km_kbp_action_item const * km_kbp_state_action_items(km_kbp_state const *state, size_t *num_items); /* ``` ### `km_kpb_state_to_json` ##### Description: Export the internal state of a `km_kbp_state` object to a JSON format document and place it in the supplied buffer, reporting how much space was used. If null is passed as the buffer the number of bytes required is returned. If there is insufficent space to hold the document, the contents of the buffer is undefined. The encoding of the returned data is UTF-8. __WARNING__: The structure and format of the JSON document while independently versioned is not part of this API and is intended solely for use in diagnostics or by development and debugging tools which are aware of processor implementation details. ##### Return status: - `KM_KBP_STATUS_OK`: On success. - `KM_KBP_STATUS_NO_MEM`: In the event an internal memory allocation fails. ##### Parameters: - __state__: An pointer to an opaque state object. - __buf__: A pointer to the buffer to place the C string containing the JSON document into. May be null. - __space__: A pointer to a size_t variable. This variable must contain the number of bytes available in the buffer pointed to by `buf`, unless `buf` is null. On return it will hold how many bytes were used. ```c */ KMN_API km_kbp_status km_kbp_state_to_json(km_kbp_state const *state, char *buf, size_t *space); /* ``` ### Processor ```c */ typedef struct { size_t max_context; // Maximum context size supported by processor. uint16_t current; // Current API number supported. uint16_t revision; // Implementation number of current API. uint16_t age; // current - age == Oldest API number supported. uint16_t technology; // A bit field specifiying which Keyboard // technologies the engine supports. char const *vendor; // Implementor of the processor. } km_kbp_attr; enum km_kbp_tech_value { KM_KBP_TECH_UNSPECIFIED = 0, KM_KBP_TECH_MOCK = 1 << 0, KM_KBP_TECH_KMX = 1 << 1, KM_KBP_TECH_LDML = 1 << 2 }; /* ``` ### `km_kbp_get_engine_attrs` ##### Description: Get access processors attributes describing version and technology implemented. ##### Return: A pointer to a `km_kbp_attr` structure. Do not modify the contents of this structure. ##### Parameters: - __state__: An opaque pointer to an `km_kbp_state`. ```c */ KMN_API km_kbp_attr const * km_kbp_get_engine_attrs(km_kbp_state const *state); /* ``` ### `km_kbp_cp_dispose` ##### Description: Free the allocated memory belonging to a `km_kbp_cp` array previously returned by `km_kbp_options_lookup`. ##### Parameters: - __cp__: A pointer to the start of the `km_kbp_cp` array to be disposed of. ```c */ KMN_API void km_kbp_cp_dispose(km_kbp_cp const *cp); /* ``` ### `km_kbp_process_event` ##### Description: Run the keyboard on an opaque state object with the provided virtual key and modifer key state. Updates the state object as appropriate and fills out its action list. The action list will be cleared at the start of this call; options and context in the state may also be modified. ##### Return status: - `KM_KBP_STATUS_OK`: On success. - `KM_KBP_STATUS_NO_MEM`: In the event memory is unavailable to allocate internal buffers. - `KM_KBP_STATUS_INVALID_ARGUMENT`: In the event the `state` pointer is null or an invalid virtual key or modifier state is passed. ##### Parameters: - __state__: A pointer to the opaque state object. - __vk__: A virtual key to be processed. - __modifier_state__: The combinations of modifier keys set at the time key `vk` was pressed, bitmask from the `km_kbp_modifier_state` enum. ```c */ KMN_API km_kbp_status km_kbp_process_event(km_kbp_state *state, km_kbp_virtual_key vk, uint16_t modifier_state); #if defined(__cplusplus) } // extern "C" #endif /*``` */ keyman-keyboardprocessor-11.0.101/include/keyman/000077500000000000000000000000001341344761300216725ustar00rootroot00000000000000keyman-keyboardprocessor-11.0.101/include/keyman/keyboardprocessor.h.in000066400000000000000000000764641341344761300262310ustar00rootroot00000000000000/* Copyright: © 2018 SIL International. Description: Cross platform API C/C++ declarations for libkmnkbp keyboard processor. Create Date: 2 Oct 2018 Authors: Tim Eves (TSE) History: 18 Oct 2018 - TSE - Finialised verion of API. 6 Oct 2018 - TSE - Move into keyman folder. */ #pragma once /* # Keyman Keyboard Processor API ## Requirements 1. Cross platform. 2. Cross language. 3. Facilitate stateless operation of the Engine. 4. Keyboard format agnostic -- support both KMN and future LDML based keyboards. 5. Support querying Engine attributes. 6. Support querying Keyboard attributes. 7. Idempotent ## Design decisions in support of requirements: - Use C or C99 types and calling convention for the interface, it has the broadest language FFI support. [1,2] - Have client (Platform layer) code load keyboards, manage & pass state. [3,4,7] - Provide query calls to return static attributes data for keyboards and engine [5,6] - Provide get/set calls for client accessible keyboard state information [3,4] ## Glossary - __Platform layer:__ The code that consumes the Keyman Keyboard Processor API, and provides the operating system-specific handling of keystroke events and integration with applications. - __Client Application:__ The application that has the focus and receives text events from the Platform layer. - __Context:__ Text preceding the insertion point - __Marker:__ Positional state that can be placed in the Context. - __Keyboard:__ A set of rules for execution my an Engine - __Option:__ A variable in a dynamic or static key value store. - __Processor:__ The component that implements this API and can parse and execute a particular keyboard. - __State:__ An object that hold internal state of the Processor for a given insertion point - __Action:__ A directive output by the processor detailing how the Platform layer should transform the Client Application's text buffer. There may be several items produced by a single keyboard event. - __Keyboard Event:__ A virtual key event and modifier map received from the platform to be processed with the state object for this Client application. - __Virtual Key:__ A code based on the US English layout, with values matching the Windows virtual key codes. See keyboardprocessor_vkeys.h for definitions. - __Modifier Key:__ The set of Control, Shift, Alt, Caps Lock keys. On some platforms these may have other names (e.g. Alt is called Option on macOS); other platform-specific modifiers such as Windows key are excluded from this set. Some modifiers are transient, such as Control, and others have long-lasting state, such as Caps Lock. ## API ### Namespace All calls, types and enums are prefixed with the namespace identifier `km_kbp_` ### API idioms Almost all calls marshalling variable length aggregate data in or out of an API object take the form: > km_kbp_status *fn_name*(object_ref, buffer_ptr, size_ptr) where the buffer is nullable and all other arguments are required (will result in an `KM_KBP_STATUS_INVALID_ARGUMENT` status being returned if nulled). When `buffer` is `nullptr` or `0` the function will place the size of the required buffer in the variable pointed to by `size_ptr`. Calls which result in the allocation of resources, regardless of resulting ownership, are of the form: > km_kbp_status *fn_name*(object_ref, out_ptr) where `out_ptr` is a valid pointer to a caller allocated variable to hold the resulting ouput. This is often a reference to a created object. All arguments are required (will result in an `KM_KBP_STATUS_INVALID_ARGUMENT` status being returned if nulled). For accessors to fixed size attributes of an object these will take the form: > attr_value __fn_name__(object_ref) `object_ref` is required to be valid and will result in a nonsense value being returned if `nullptr` or `0`. All dispose calls are designed to accept null as a valid value and will do nothing in that event. ```c */ #include #include #include #include #define KM_KBP_LIB_CURRENT @lib_curr@ #define KM_KBP_LIB_AGE @lib_age@ #define KM_KBP_LIB_REVISION @lib_rev@ #if defined(__cplusplus) extern "C" { #endif // Basic types // #if defined(__cplusplus) typedef char16_t km_kbp_cp; typedef char32_t km_kbp_usv; #else typedef uint16_t km_kbp_cp; // code point typedef uint32_t km_kbp_usv; // Unicode Scalar Value #endif typedef uint16_t km_kbp_virtual_key; // A virtual key code. typedef uint32_t km_kbp_status; // Status return code. // Opaque object types. // typedef struct km_kbp_context km_kbp_context; typedef struct km_kbp_keyboard km_kbp_keyboard; typedef struct km_kbp_state km_kbp_state; typedef struct km_kbp_options km_kbp_options; // Forward declarations // typedef struct km_kbp_option_item km_kbp_option_item; /*``` ### Error Handling Error handling and success failure notification are communicated through a general mechanism similar to COM’s `HRESULT` scheme (unlike COM, any non-zero value is an error). Any functions that can fail will always return a status value and all results are returned via outparams passed to the function. ```c */ enum km_kbp_status_codes { KM_KBP_STATUS_OK = 0, KM_KBP_STATUS_NO_MEM = 1, KM_KBP_STATUS_IO_ERROR = 2, KM_KBP_STATUS_INVALID_ARGUMENT = 3, KM_KBP_STATUS_KEY_ERROR = 4, KM_KBP_STATUS_INSUFFICENT_BUFFER = 5, KM_KBP_STATUS_INVALID_UTF = 6, KM_KBP_STATUS_INVALID_KEYBOARD = 7, KM_KBP_STATUS_OS_ERROR = 0x80000000 }; /* ``` The final status code KM_KBP_STATUS_OS_ERROR is intended to allow encapsulating a platform error code; the remaining 31 low bits are the error code returned by the OS for cases where the failure mode is platform specific. For HRESULT codes this only permits failure codes to be passed. ### Context The context is the text prior to the insertion point (caret, cursor). The context is constructed by the Platform layer, typically by interrogating the Client Application. The context will be updated by the engine for keystroke events. If the Platform layer code caches the context, the context should be reset when a context state change is detected. Context state changes can occur when the user uses the mouse to move the insertion point, uses cursor keys, switches applications or input fields, or presses hotkeys such as Ctrl+N to start a new document. The full set of context state change triggers is up to the Platform layer. Context can also contain positional Markers (also known as 'deadkeys' in kmn keyboards), which are transitory state flags that are erased whenever a context state change is detected. Markers are always controlled by the Engine. Contexts are always owned by their state. They may be set to a list of context_items or interrogated for their current list of context items. ```c */ enum km_kbp_context_type { KM_KBP_CT_END, KM_KBP_CT_CHAR, KM_KBP_CT_MARKER }; typedef struct { uint8_t type; uint8_t _reserved[3]; union { km_kbp_usv character; uint32_t marker; }; } km_kbp_context_item; #define KM_KBP_CONTEXT_ITEM_END {KM_KBP_CT_END, {0,}, {0,}} /* ``` ### `km_kbp_context_items_from_utf16` ##### Description: Convert a UTF16 encoded Unicode string into an array of `km_kbp_context_item` structures. Allocates memory as needed. ##### Return status: - `KM_KBP_STATUS_OK`: On success. - `KM_KBP_STATUS_INVALID_ARGUMENT`: If non-optional parameters are null. - `KM_KBP_STATUS_NO_MEM`: In the event not enough memory can be allocated for the output buffer. - `KM_KBP_STATUS_INVALID_UTF`: In the event the UTF16 string cannot be decoded because it contains unpaired surrogate codeunits. ##### Parameters: - __text__: a pointer to a null terminated array of utf16 encoded data. - __out_ptr__: a pointer to the result variable: A pointer to the start of the `km_kbp_context_item` array containing the representation of the input string. Terminated with a type of `KM_KBP_CT_END`. Must be disposed of with `km_kbp_context_items_dispose`. ```c */ KMN_API km_kbp_status km_kbp_context_items_from_utf16(km_kbp_cp const *text, km_kbp_context_item **out_ptr); /* ``` ### `km_kbp_context_items_from_utf8` ##### Description: Convert an UTF8 encoded Unicode string into an array of `km_kbp_context_item` structures. Allocates memory as needed. ##### Status: - `KM_KBP_STATUS_INVALID_ARGUMENT`: If non-optional parameters are null. - `KM_KBP_STATUS_NO_MEM`: In the event it cannot allocate enough memory for the output buffer. - `KM_KBP_STATUS_INVALID_UTF`: In the event the UTF8 string cannot be decoded. ##### Parameters: - __text__: a pointer to a null terminated array of utf8 encoded data. - __out_ptr__: a pointer to the result variable: A pointer to the start of the `km_kbp_context_item` array containing the representation of the input string. Terminated with a type of `KM_KBP_CT_END`. ```c */ KMN_API km_kbp_status km_kbp_context_items_from_utf8(char const *text, km_kbp_context_item **out_ptr); /* ``` ### `km_kbp_context_items_to_utf16` ##### Description: Convert a context item array into a UTF-16 encoded string placing it into the supplied buffer of specified size, and return the number codepoints actually used in the conversion. If null is passed as the buffer the number codeunits required is returned. This will strip markers from the context during the conversion. ##### Return status: - `KM_KBP_STATUS_OK`: On success. - `KM_KBP_STATUS_INVALID_ARGUMENT`: If non-optional parameters are null. - `KM_KBP_STATUS_INSUFFICENT_BUFFER`: If the buffer is not large enough. `buf_size` will contain the space required. The contents of the buffer are undefined. ##### Parameters: - __context_items__: A pointer to the start of an array `km_kbp_context_item`. Must be terminated with a type of `KM_KBP_CT_END`. - __buf__: A pointer to the buffer to place the UTF-16 string into. May be be null to request size calculation. - __buf_size__: a pointer to the result variable: A pointer the size of the supplied buffer in codeunits or filled with the size required if `buf` is null. ```c */ KMN_API km_kbp_status km_kbp_context_items_to_utf16(km_kbp_context_item const *item, km_kbp_cp *buf, size_t *buf_size); /* ``` ### `km_kbp_context_items_to_utf8` ##### Description: Convert a context item array into a UTF-8 encoded string placing it into the supplied buffer of specified size, and return the number codepoints actually used in the conversion. If null is passed as the buffer the number codeunits required is returned. This will strip markers from the context during the conversion. ##### Return status: - `KM_KBP_STATUS_OK`: On success. - `KM_KBP_STATUS_INVALID_ARGUMENT`: If non-optional parameters are null. - `KM_KBP_STATUS_INSUFFICENT_BUFFER`: If the buffer is not large enough. `buf_size` will contain the space required. The contents of the buffer are undefined. ##### Parameters: - __context_items__: A pointer to the start of an array `km_kbp_context_item`. Must be terminated with a type of `KM_KBP_CT_END`. - __buf__: A pointer to the buffer to place the UTF-8 string into. May be be null to request size calculation. - __buf_size__: a pointer to the result variable: A pointer the size of the supplied buffer in codeunits or filled with the size required if `buf` is null. ```c */ KMN_API km_kbp_status km_kbp_context_items_to_utf8(km_kbp_context_item const *item, char *buf, size_t *buf_size); /* ``` ### `km_kbp_context_items_dispose` ##### Description: Free the allocated memory belonging to a `km_kbp_context_item` array previously returned by `km_kbp_context_items_from_utf16` or `km_kbp_context_get` ##### Parameters: - __context_items__: A pointer to the start of the `km_kbp_context_item` array to be disposed of. ```c */ KMN_API void km_kbp_context_items_dispose(km_kbp_context_item *context_items); /* ``` ### `km_kbp_context_set` ##### Description: Replace the contents of the current context with a new sequence of `km_kbp_context_item` entries. ##### Return status: - `KM_KBP_STATUS_OK`: On success. - `KM_KBP_STATUS_INVALID_ARGUMENT`: If non-optional parameters are null. - `KM_KBP_STATUS_NO_MEM`: In the event not enough memory can be allocated to grow the context buffer internally. ##### Parameters: - __context__: A pointer to an opaque context object - __context_items__: A pointer to the start of the `km_kbp_context_item` array containing the new context. It must be terminated with an item of type `KM_KBP_CT_END`. ```c */ KMN_API km_kbp_status km_kbp_context_set(km_kbp_context *context, km_kbp_context_item const *context_items); /* ``` ### `km_kbp_context_get` ##### Description: Copies all items in the context into a new array and returns the new array. This must be disposed of by caller using `km_kbp_context_items_dispose`. ##### Return status: - `KM_KBP_STATUS_OK`: On success. - `KM_KBP_STATUS_INVALID_ARGUMENT`: If non-optional parameters are null. - `KM_KBP_STATUS_NO_MEM`: In the event not enough memory can be allocated for the output buffer. ##### Parameters: - __context_items__: A pointer to the start of an array `km_kbp_context_item`. - __out__: a pointer to the result variable: A pointer to the start of the `km_kbp_context_item` array containing a copy of the context. Terminated with a type of `KM_KBP_CT_END`. Must be disposed of with `km_kbp_context_items_dispose`. ```c */ KMN_API km_kbp_status km_kbp_context_get(km_kbp_context const *context_items, km_kbp_context_item **out); /* ``` ### `km_kbp_context_clear` ##### Description: Removes all context_items from the internal array. If `context` is null, has no effect. ##### Parameters: - __context__: A pointer to an opaque context object ```c */ KMN_API void km_kbp_context_clear(km_kbp_context *); /* ``` ### `km_kbp_context_length` ##### Description: Return the number of items in the context. ##### Return: The number of items in the context, and will return 0 if passed a null `context` pointer. ##### Parameters: - __context__: A pointer to an opaque context object ```c */ KMN_API size_t km_kbp_context_length(km_kbp_context *); /* ``` ### `km_kbp_context_append` ##### Description: Add more items to the end (insertion point) of the context. If these exceed the maximum context length the same number of items will be dropped from the beginning of the context. ##### Return status: - `KM_KBP_STATUS_OK`: On success. - `KM_KBP_STATUS_INVALID_ARGUMENT`: If non-optional parameters are null. - `KM_KBP_STATUS_NO_MEM`: In the event not enough memory can be allocated to grow the context buffer internally. ##### Parameters: - __context__: A pointer to an opaque context object. - __context_items__: A pointer to the start of the `KM_KBP_CT_END` terminated array of `km_kbp_context_item` to append. ```c */ KMN_API km_kbp_status km_kbp_context_append(km_kbp_context *context, km_kbp_context_item const *context_items); /* ``` ### `km_kbp_context_shrink` ##### Description: Remove a specified number of items from the end of the context, optionally add up to the same number of the supplied items to the front of the context. ##### Return status: - `KM_KBP_STATUS_OK`: On success. - `KM_KBP_STATUS_INVALID_ARGUMENT`: If non-optional parameters are null. - `KM_KBP_STATUS_NO_MEM`: in the event it cannot allocated enough memory to grow the context internally. ##### Parameters: - __context__: A pointer to an opaque context object. - __num__: The number of items to remove from the end of context. - __context_items__: Pointer to the start of the `KM_KBP_CT_END` terminated array of `km_kbp_context_item` to add to the front. Up to `num` items will be prepended. This may be null if not required. ```c */ KMN_API km_kbp_status km_kbp_context_shrink(km_kbp_context *context, size_t num, km_kbp_context_item const *prefix); /* ``` ### Action Items These provide the results of processing a key event to the Platform layer and should be processed by the Platform layer to issue commands to the os text services framework to transform the text store in the Client Application, among other actions. ```c */ typedef struct { uint8_t type; uint8_t _reserved[sizeof(void*)-sizeof(uint8_t)]; union { uintptr_t marker; // MARKER type km_kbp_option_item const * option; // OPT types km_kbp_usv character; // CHAR type }; } km_kbp_action_item; enum km_kbp_action_type { KM_KBP_IT_END = 0, // Marks end of action items list. KM_KBP_IT_CHAR = 1, // A Unicode character has been generated. KM_KBP_IT_MARKER = 2, // Correlates to kmn's "deadkey" markers. KM_KBP_IT_ALERT = 3, // The keyboard has triggered a alert/beep/bell. KM_KBP_IT_BACK = 4, // Delete the codepoint preceding the insertion point. KM_KBP_IT_PERSIST_OPT = 5, // The indicated option needs to be stored. KM_KBP_IT_EMIT_KEYSTROKE = 6, // Emit the current keystroke to the application KM_KBP_IT_INVALIDATE_CONTEXT = 7, // The processor requests that the context buffer be cleared; // for applications where context is cached, this clears the context; // for applications where context is read from the focused text store, // the context is just re-read and markers flushed. KM_KBP_IT_MAX_TYPE_ID }; /* ``` ### Options A state’s default options are set from the keyboard at creation time and the environment. The Platform layer is then is expected to apply any persisted options it is maintaining. Options are passed into and out of API functions as simple C arrays of `km_kbp_option_item` terminated with a `KM_KBP_OPTIONS_END` sentinel value. A state's options are exposed and manipulatable via the `km_kbp_options` API. All option values are of type C string. During processing when the Platform layer finds a PERSIST action type it should store the updated option in the appropriate place, based on its scope. For RESET the processor will apply the pristine value from the original scope, the Platform layer should update that only if it manages a previously persisted value. ```c */ enum km_kbp_option_scope { KM_KBP_OPT_UNKNOWN = 0, KM_KBP_OPT_KEYBOARD = 1, KM_KBP_OPT_ENVIRONMENT = 2, KM_KBP_OPT_MAX_SCOPES }; struct km_kbp_option_item { km_kbp_cp const * key; km_kbp_cp const * value; uint8_t scope; // Scope which an option belongs to. }; #define KM_KBP_OPTIONS_END { 0, 0, 0 } /* ``` ### `km_kbp_options_list_size` ##### Description: Return the length of a terminated `km_kbp_option_item` array (options list). ##### Return: The number of items in the list or 0 if `opts` is null. ##### Parameters: - __opts__: A pointer to a `KM_KBP_OPTIONS_END` terminated array of `km_kbp_option_item` values. ```c */ KMN_API size_t km_kbp_options_list_size(km_kbp_option_item const *opts); /* ``` ### `km_kbp_state_option_lookup` ##### Description: Lookup an option based on its key, in an options list. ##### Return status: - `KM_KBP_STATUS_OK`: On success. - `KM_KBP_STATUS_INVALID_ARGUMENT`: If non-optional parameters are null, or if the scope is invalid. - `KM_KBP_STATUS_KEY_ERROR`: The key cannot be found. ##### Parameters: - __state__: An opaque pointer to a state object. - __scope__: Which key-value store to interrogate. - __key__: A UTF-16 string that matches the key in the target `km_kbp_option_item`. - __value__: A pointer to the result variable: A pointer to a UTF-16 string value owned by the state or keyboard object at the time of the call. This pointer is only valid *until* the next call to any function on this API and should be used immediately. ```c */ KMN_API km_kbp_status km_kbp_state_option_lookup(km_kbp_state const *state, uint8_t scope, km_kbp_cp const *key, km_kbp_cp const **value); /* ``` ### `km_kbp_state_options_update` ##### Description: Adds or updates one or more options from a list of `km_kbp_option_item`s. ##### Return status: - `KM_KBP_STATUS_OK`: On success. - `KM_KBP_STATUS_INVALID_ARGUMENT`: If non-optional parameters are null. - `KM_KBP_STATUS_NO_MEM`: In the event an internal memory allocation fails. - `KM_KBP_STATUS_KEY_ERROR`: The key cannot be found. ##### Parameters: - __state__: An opaque pointer to a state object. - __new_opts__: An array of `km_kbp_option_item` objects to update or add. Must be terminated with `KM_KBP_OPTIONS_END`. ```c */ KMN_API km_kbp_status km_kbp_state_options_update(km_kbp_state *state, km_kbp_option_item const *new_opts); /* ``` ### `km_kbp_state_options_to_json` ##### Description: Export the contents of a `km_kbp_options` array to a JSON formatted document and place it in the supplied buffer, reporting how much space was used. If null is passed as the buffer the number of bytes required is returned in `space`. If there is insufficent space to hold the document the contents of the buffer is undefined. The returned buffer uses UTF-8 encoding. ##### Return status: - `KM_KBP_STATUS_OK`: On success. - `KM_KBP_STATUS_INVALID_ARGUMENT`: If non-optional parameters are null. - `KM_KBP_STATUS_NO_MEM`: In the event an internal memory allocation fails. ##### Parameters: - __opts__: An opaque pointer to a state object. - __buf__: A pointer to the buffer to place the C string containing the JSON document into, can be null. - __space__: A pointer to a size_t variable. This variable must contain the number of bytes available in the buffer pointed to by `buf`, unless `buf` is null. On return it will hold how many bytes were used. ```c */ KMN_API km_kbp_status km_kbp_state_options_to_json(km_kbp_state const *state, char *buf, size_t *space); /* ``` ### Keyboards A keyboard is a set of rules and transforms in a Processor specific format for transforming key events into action items. The keyboard is parsed and loaded by the processsor and made available in an immutable fashion for use with any number of state objects. ```c */ typedef struct { km_kbp_cp const * version_string; // Processor specific version string. km_kbp_cp const * id; // Keyman keyboard ID string. km_kbp_path_name folder_path; // Path to the unpacked folder containing // the keyboard and associated resources. km_kbp_option_item const * default_options; } km_kbp_keyboard_attrs; /* ``` ### `km_kbp_keyboard_load` ##### Description: Parse and load keyboard from the supplied path and a pointer to the loaded keyboard into the out paramter. ##### Return status: - `KM_KBP_STATUS_OK`: On success. - `KM_KBP_STATUS_NO_MEM`: In the event an internal memory allocation fails. - `KM_KBP_STATUS_IO_ERROR`: In the event the keyboard file is unparseable for any reason - `KM_KBP_STATUS_INVALID_ARGUMENT`: In the event the file doesn't exist or is inaccesible or `keyboard` is null. - `KM_KBP_STATUS_OS_ERROR`: Bit 31 (high bit) set, bits 0-30 are an OS-specific error code. ##### Parameters: - __kb_path__: On Windows, a UTF-16 string; on other platforms, a C string: contains a valid path to the keyboard file. - __keyboard__: A pointer to result variable: A pointer to the opaque keyboard object returned by the Processor. This memory must be freed with a call to `km_kbp_keyboard_dispose`. ```c */ KMN_API km_kbp_status km_kbp_keyboard_load(km_kbp_path_name kb_path, km_kbp_keyboard **keyboard); /* ``` ### `km_kbp_keyboard_dispose` ##### Description: Free the allocated memory belonging to an opaque keyboard object previously returned by `km_kbp_keyboard_load`. ##### Parameters: - __keyboard__: A pointer to the opaque keyboard object to be disposed of. ```c */ KMN_API void km_kbp_keyboard_dispose(km_kbp_keyboard *keyboard); /* ``` ### `km_kbp_keyboard_get_attrs` ##### Description: Returns the const internal attributes of the keyboard. This structure is valid for the lifetime of the opaque keyboard object. Do not modify the returned data. ##### Return status: - `KM_KBP_STATUS_OK`: On success. - `KM_KBP_STATUS_INVALID_ARGUMENT`: If non-optional parameters are null. ##### Parameters: - __keyboard__: A pointer to the opaque keyboard object to be queried. - __out__: A pointer to the result: A pointer to a `km_kbp_keyboard_attrs` structure. ```c */ KMN_API km_kbp_status km_kbp_keyboard_get_attrs(km_kbp_keyboard const *keyboard, km_kbp_keyboard_attrs const **out); /* ``` ### State A State object maintains all per keyboard related state including context and dynamic options ("option stores" in kmn format). ```c */ /* ``` ### `km_kbp_state_create` ##### Description: Create a keyboard processor state object, maintaining state for the keyboard in the environment passed. ##### Return status: - `KM_KBP_STATUS_OK`: On success. - `KM_KBP_STATUS_NO_MEM`: In the event memory is unavailable to allocate a state object. - `KM_KBP_STATUS_INVALID_ARGUMENT`: In the event the `keyboard` or `out` pointer are null. ##### Parameters: - __keyboard__: A pointer to the opaque keyboard object this object will hold state for. - __env__: The array of `km_kbp_option_item` key/value pairs used to initialise the environment, terminated by `KM_KBP_OPTIONS_END`. - __out__: A pointer to result variable: A pointer to the opaque state object returned by the Processor, initalised to maintain state for `keyboard`. This must be disposed of by a call to `km_kbp_state_dispose`. ```c */ KMN_API km_kbp_status km_kbp_state_create(km_kbp_keyboard *keyboard, km_kbp_option_item const *env, km_kbp_state **out); /* ``` ### `km_kbp_state_clone` ##### Description: Clone an existing opaque state object. ##### Return status: - `KM_KBP_STATUS_OK`: On success. - `KM_KBP_STATUS_NO_MEM`: In the event memory is unavailable to allocate a state object. - `KM_KBP_STATUS_INVALID_ARGUMENT`: In the event the `state` or `out` pointer are null. ##### Parameters: - __state__: A pointer to the opaque statea object to be cloned. - __out__: A pointer to result variable: A pointer to the opaque state object returned by the Processor, cloned from the existing object `state`. This must be disposed of by a call to `km_kbp_state_dispose`. ```c */ KMN_API km_kbp_status km_kbp_state_clone(km_kbp_state const *state, km_kbp_state **out); /* ``` ### `km_kbp_state_dispose` ##### Description: Free the allocated resources belonging to a `km_kbp_state` object previously returned by `km_kbp_state_create` or `km_kbp_state_clone`. After this all pointers previously returned by any km_kbp_state family of calls will become invalid. ##### Parameters: - __state__: A pointer to the opaque state object to be disposed. ```c */ KMN_API void km_kbp_state_dispose(km_kbp_state *state); /* ``` ### `km_kbp_state_context` ##### Description: Get access to the state object's context. ##### Return: A pointer to an opaque state object. This pointer is valid for the lifetime of the state object. If null is passed in, then null is returned. ##### Parameters: - __state__: A pointer to the opaque state object to be queried. ```c */ KMN_API km_kbp_context * km_kbp_state_context(km_kbp_state *state); /* ``` ### `km_kbp_state_action_items` ##### Description: Get the list of action items generated by the last call to `km_kbp_process_event`. ##### Return: A pointer to a `km_kbp_action_item` list, of `*num_items` in length. This data becomes invalid when the state object is destroyed, or after a call to `km_kbp_process_event`. Do not modify the contents of this data. The returned array is terminated with a `KM_KBP_IT_END` entry. ##### Parameters: - __state__: A pointer to the opaque `km_kbp_state` object to be queried. - __num_items__: A pointer to a result variable: The number of items in the action item list including the `KM_KBP_IT_END` terminator. May be null if not that information is required. ```c */ KMN_API km_kbp_action_item const * km_kbp_state_action_items(km_kbp_state const *state, size_t *num_items); /* ``` ### `km_kpb_state_to_json` ##### Description: Export the internal state of a `km_kbp_state` object to a JSON format document and place it in the supplied buffer, reporting how much space was used. If null is passed as the buffer the number of bytes required is returned. If there is insufficent space to hold the document, the contents of the buffer is undefined. The encoding of the returned data is UTF-8. __WARNING__: The structure and format of the JSON document while independently versioned is not part of this API and is intended solely for use in diagnostics or by development and debugging tools which are aware of processor implementation details. ##### Return status: - `KM_KBP_STATUS_OK`: On success. - `KM_KBP_STATUS_NO_MEM`: In the event an internal memory allocation fails. ##### Parameters: - __state__: An pointer to an opaque state object. - __buf__: A pointer to the buffer to place the C string containing the JSON document into. May be null. - __space__: A pointer to a size_t variable. This variable must contain the number of bytes available in the buffer pointed to by `buf`, unless `buf` is null. On return it will hold how many bytes were used. ```c */ KMN_API km_kbp_status km_kbp_state_to_json(km_kbp_state const *state, char *buf, size_t *space); /* ``` ### Processor ```c */ typedef struct { size_t max_context; // Maximum context size supported by processor. uint16_t current; // Current API number supported. uint16_t revision; // Implementation number of current API. uint16_t age; // current - age == Oldest API number supported. uint16_t technology; // A bit field specifiying which Keyboard // technologies the engine supports. char const *vendor; // Implementor of the processor. } km_kbp_attr; enum km_kbp_tech_value { KM_KBP_TECH_UNSPECIFIED = 0, KM_KBP_TECH_MOCK = 1 << 0, KM_KBP_TECH_KMX = 1 << 1, KM_KBP_TECH_LDML = 1 << 2 }; /* ``` ### `km_kbp_get_engine_attrs` ##### Description: Get access processors attributes describing version and technology implemented. ##### Return: A pointer to a `km_kbp_attr` structure. Do not modify the contents of this structure. ##### Parameters: - __state__: An opaque pointer to an `km_kbp_state`. ```c */ KMN_API km_kbp_attr const * km_kbp_get_engine_attrs(km_kbp_state const *state); /* ``` ### `km_kbp_process_event` ##### Description: Run the keyboard on an opaque state object with the provided virtual key and modifer key state. Updates the state object as appropriate and fills out its action list. The action list will be cleared at the start of this call; options and context in the state may also be modified. ##### Return status: - `KM_KBP_STATUS_OK`: On success. - `KM_KBP_STATUS_NO_MEM`: In the event memory is unavailable to allocate internal buffers. - `KM_KBP_STATUS_INVALID_ARGUMENT`: In the event the `state` pointer is null or an invalid virtual key or modifier state is passed. ##### Parameters: - __state__: A pointer to the opaque state object. - __vk__: A virtual key to be processed. - __modifier_state__: The combinations of modifier keys set at the time key `vk` was pressed, bitmask from the `km_kbp_modifier_state` enum. ```c */ KMN_API km_kbp_status km_kbp_process_event(km_kbp_state *state, km_kbp_virtual_key vk, uint16_t modifier_state); #if defined(__cplusplus) } // extern "C" #endif /*``` */ keyman-keyboardprocessor-11.0.101/include/keyman/keyboardprocessor_bits.h000066400000000000000000000043201341344761300266230ustar00rootroot00000000000000/* Copyright: © 2018 SIL International. Description: Cross platform support macros to define API function declspec/attributes and how each supported compiler or OS allows us to specify them. Create Date: 18 Oct 2018 Authors: Tim Eves (TSE) History: 18 Oct 2018 - TSE - Imported from graphite2 project. 6 Oct 2018 - TSE - Move into keyman folder. */ #pragma once // Define API function declspec/attributes and how each supported compiler or OS // allows us to specify them. #if defined __GNUC__ #define _kmn_and , #define _kmn_tag_fn(a) __attribute__((a)) #define _kmn_deprecated_flag deprecated #define _kmn_export_flag visibility("default") #define _kmn_import_flag visibility("default") #define _kmn_static_flag visibility("hidden") #define _kmn_unused(x) UNUSED_ ## x __attribute__((__unused__)) #else #define _kmn_unused(x) UNUSED_ ## x #endif #if defined _WIN32 || defined __CYGWIN__ typedef wchar_t const * km_kbp_path_name; #define _KM_KBP_PATH_SEPARATOR (L'\\') #define _KM_KBP_EXT_SEPARATOR (L'.') #if defined __GNUC__ // These three will be redefined for Windows #undef _kmn_export_flag #undef _kmn_import_flag #undef _kmn_static_flag #else // How MSVC sepcifies function level attributes adn deprecation #define _kmn_and #define _kmn_tag_fn(a) __declspec(a) #define _kmn_deprecated_flag deprecated #endif #define _kmn_export_flag dllexport #define _kmn_import_flag dllimport #define _kmn_static_flag #else typedef char const * km_kbp_path_name; #define _KM_KBP_PATH_SEPARATOR ('/') #define _KM_KBP_EXT_SEPARATOR ('.') #endif #if defined KMN_KBP_STATIC #define KMN_API _kmn_tag_fn(_kmn_static_flag) #define KMN_DEPRECATED_API _kmn_tag_fn(_kmn_deprecated_flag _kmn_and _kmn_static_flag) #elif defined KMN_KBP_EXPORTING #define KMN_API _kmn_tag_fn(_kmn_export_flag) #define KMN_DEPRECATED_API _kmn_tag_fn(_kmn_deprecated_flag _kmn_and _kmn_export_flag) #else #define KMN_API _kmn_tag_fn(_kmn_import_flag) #define KMN_DEPRECATED_API _kmn_tag_fn(_kmn_deprecated_flag _kmn_and _kmn_import_flag) #endif keyman-keyboardprocessor-11.0.101/include/keyman/keyboardprocessor_consts.h000066400000000000000000000007551341344761300272030ustar00rootroot00000000000000#pragma once // Defined environment options for KMX processor #define KM_KBP_KMX_ENV_PLATFORM u"platform" #define KM_KBP_KMX_ENV_BASELAYOUT u"baseLayout" #define KM_KBP_KMX_ENV_BASELAYOUTALT u"baseLayoutAlt" #define KM_KBP_KMX_ENV_SIMULATEALTGR u"simulateAltgr" #define KM_KBP_KMX_ENV_CAPSLOCK u"capsLock" #define KM_KBP_KMX_ENV_BASELAYOUTGIVESCTRLRALTFORRALT u"baseLayoutGivesCtrlRAltForRAlt" keyman-keyboardprocessor-11.0.101/include/keyman/keyboardprocessor_vkeys.h000066400000000000000000000150701341344761300270270ustar00rootroot00000000000000/* Copyright: © 2018 SIL International. Description: API declarations for modifier keys, handy access masks and Keyman VKEY names. These follow the same keytop->code associations as the Windows API. This is a separate header to maintain readability of the primary API header. Create Date: 17 Oct 2018 Authors: Tim Eves (TSE) History: 17 Oct 2018 - TSE - Moved & refactored km_kbp_modifier_state from keyboardprocessor.h. - Added VKey and mask definitions. 6 Oct 2018 - TSE - Move into keyman folder. */ enum km_kbp_modifier_state { KM_KBP_MODIFIER_LCTRL = 1 << 0, KM_KBP_MODIFIER_RCTRL = 1 << 1, KM_KBP_MODIFIER_LALT = 1 << 2, KM_KBP_MODIFIER_RALT = 1 << 3, KM_KBP_MODIFIER_SHIFT = 1 << 4, KM_KBP_MODIFIER_CTRL = 1 << 5, KM_KBP_MODIFIER_ALT = 1 << 6 /* KM_KBP_MODIFIER_CAPS = 1 << 7, KM_KBP_MODIFIER_NOCAPS = 1 << 8, KM_KBP_MODIFIER_NUMLOCK = 1 << 9, KM_KBP_MODIFIER_NONUMLOCK = 1 << 10, KM_KBP_MODIFIER_SCROLLOCK = 1 << 11, KM_KBP_MODIFIER_NOSCROLLOCK = 1 << 12, KM_KBP_MODIFIER_VIRTUALKEY = 1 << 13, */ }; enum km_kbp_modifier_mask { KM_KBP_MODIFIER_MASK_ALL = 0x7f, KM_KBP_MODIFIER_MASK_ALT_GR_SIM = KM_KBP_MODIFIER_LCTRL|KM_KBP_MODIFIER_LALT, KM_KBP_MODIFIER_MASK_CHIRAL = 0x1f, KM_KBP_MODIFIER_MASK_IS_CHIRAL = 0x0f, KM_KBP_MODIFIER_MASK_NON_CHIRAL = 0x7f /* KM_KBP_MODIFIER_MASK_CAPS = 0x0300, KM_KBP_MODIFIER_MASK_NUMLOCK = 0x0C00, KM_KBP_MODIFIER_MASK_SCROLLLOCK = 0x3000,*/ }; // These are Windows API VKEYs, using Keyman VKEY names. enum km_kpb_virtual_key { KM_KBP_VKEY__00, KM_KBP_VKEY_LBUTTON, KM_KBP_VKEY_RBUTTON, KM_KBP_VKEY_CANCEL, KM_KBP_VKEY_MBUTTON, KM_KBP_VKEY__05, KM_KBP_VKEY__06, KM_KBP_VKEY__07, KM_KBP_VKEY_BKSP, KM_KBP_VKEY_TAB, KM_KBP_VKEY__0A, KM_KBP_VKEY__0B, KM_KBP_VKEY_KP5, KM_KBP_VKEY_ENTER, KM_KBP_VKEY__0E, KM_KBP_VKEY__0F, KM_KBP_VKEY_SHIFT, KM_KBP_VKEY_CONTROL, KM_KBP_VKEY_ALT, KM_KBP_VKEY_PAUSE, KM_KBP_VKEY_CAPS, KM_KBP_VKEY__15, KM_KBP_VKEY__16, KM_KBP_VKEY__17, KM_KBP_VKEY__18, KM_KBP_VKEY__19, KM_KBP_VKEY__1A, KM_KBP_VKEY_ESC, KM_KBP_VKEY__1C, KM_KBP_VKEY__1D, KM_KBP_VKEY__1E, KM_KBP_VKEY__1F, KM_KBP_VKEY_SPACE, KM_KBP_VKEY_PGUP, KM_KBP_VKEY_PGDN, KM_KBP_VKEY_END, KM_KBP_VKEY_HOME, KM_KBP_VKEY_LEFT, KM_KBP_VKEY_UP, KM_KBP_VKEY_RIGHT, KM_KBP_VKEY_DOWN, KM_KBP_VKEY_SEL, KM_KBP_VKEY_PRINT, KM_KBP_VKEY_EXEC, KM_KBP_VKEY_PRTSCN, KM_KBP_VKEY_INS, KM_KBP_VKEY_DEL, KM_KBP_VKEY_HELP, KM_KBP_VKEY_0, KM_KBP_VKEY_1, KM_KBP_VKEY_2, KM_KBP_VKEY_3, KM_KBP_VKEY_4, KM_KBP_VKEY_5, KM_KBP_VKEY_6, KM_KBP_VKEY_7, KM_KBP_VKEY_8, KM_KBP_VKEY_9, KM_KBP_VKEY__3A, KM_KBP_VKEY__3B, KM_KBP_VKEY__3C, KM_KBP_VKEY__3D, KM_KBP_VKEY__3E, KM_KBP_VKEY__3F, KM_KBP_VKEY__40, KM_KBP_VKEY_A, KM_KBP_VKEY_B, KM_KBP_VKEY_C, KM_KBP_VKEY_D, KM_KBP_VKEY_E, KM_KBP_VKEY_F, KM_KBP_VKEY_G, KM_KBP_VKEY_H, KM_KBP_VKEY_I, KM_KBP_VKEY_J, KM_KBP_VKEY_K, KM_KBP_VKEY_L, KM_KBP_VKEY_M, KM_KBP_VKEY_N, KM_KBP_VKEY_O, KM_KBP_VKEY_P, KM_KBP_VKEY_Q, KM_KBP_VKEY_R, KM_KBP_VKEY_S, KM_KBP_VKEY_T, KM_KBP_VKEY_U, KM_KBP_VKEY_V, KM_KBP_VKEY_W, KM_KBP_VKEY_X, KM_KBP_VKEY_Y, KM_KBP_VKEY_Z, KM_KBP_VKEY__5B, KM_KBP_VKEY__5C, KM_KBP_VKEY__5D, KM_KBP_VKEY__5E, KM_KBP_VKEY__5F, KM_KBP_VKEY_NP0, KM_KBP_VKEY_NP1, KM_KBP_VKEY_NP2, KM_KBP_VKEY_NP3, KM_KBP_VKEY_NP4, KM_KBP_VKEY_NP5, KM_KBP_VKEY_NP6, KM_KBP_VKEY_NP7, KM_KBP_VKEY_NP8, KM_KBP_VKEY_NP9, KM_KBP_VKEY_NPSTAR, KM_KBP_VKEY_NPPLUS, KM_KBP_VKEY_SEPARATOR, KM_KBP_VKEY_NPMINUS, KM_KBP_VKEY_NPDOT, KM_KBP_VKEY_NPSLASH, KM_KBP_VKEY_F1, KM_KBP_VKEY_F2, KM_KBP_VKEY_F3, KM_KBP_VKEY_F4, KM_KBP_VKEY_F5, KM_KBP_VKEY_F6, KM_KBP_VKEY_F7, KM_KBP_VKEY_F8, KM_KBP_VKEY_F9, KM_KBP_VKEY_F10, KM_KBP_VKEY_F11, KM_KBP_VKEY_F12, KM_KBP_VKEY_F13, KM_KBP_VKEY_F14, KM_KBP_VKEY_F15, KM_KBP_VKEY_F16, KM_KBP_VKEY_F17, KM_KBP_VKEY_F18, KM_KBP_VKEY_F19, KM_KBP_VKEY_F20, KM_KBP_VKEY_F21, KM_KBP_VKEY_F22, KM_KBP_VKEY_F23, KM_KBP_VKEY_F24, KM_KBP_VKEY__88, KM_KBP_VKEY__89, KM_KBP_VKEY__8A, KM_KBP_VKEY__8B, KM_KBP_VKEY__8C, KM_KBP_VKEY__8D, KM_KBP_VKEY__8E, KM_KBP_VKEY__8F, KM_KBP_VKEY_NUMLOCK, KM_KBP_VKEY_SCROLL, KM_KBP_VKEY__92, KM_KBP_VKEY__93, KM_KBP_VKEY__94, KM_KBP_VKEY__95, KM_KBP_VKEY__96, KM_KBP_VKEY__97, KM_KBP_VKEY__98, KM_KBP_VKEY__99, KM_KBP_VKEY__9A, KM_KBP_VKEY__9B, KM_KBP_VKEY__9C, KM_KBP_VKEY__9D, KM_KBP_VKEY__9E, KM_KBP_VKEY__9F, KM_KBP_VKEY__A0, KM_KBP_VKEY__A1, KM_KBP_VKEY__A2, KM_KBP_VKEY__A3, KM_KBP_VKEY__A4, KM_KBP_VKEY__A5, KM_KBP_VKEY__A6, KM_KBP_VKEY__A7, KM_KBP_VKEY__A8, KM_KBP_VKEY__A9, KM_KBP_VKEY__AA, KM_KBP_VKEY__AB, KM_KBP_VKEY__AC, KM_KBP_VKEY__AD, KM_KBP_VKEY__AE, KM_KBP_VKEY__AF, KM_KBP_VKEY__B0, KM_KBP_VKEY__B1, KM_KBP_VKEY__B2, KM_KBP_VKEY__B3, KM_KBP_VKEY__B4, KM_KBP_VKEY__B5, KM_KBP_VKEY__B6, KM_KBP_VKEY__B7, KM_KBP_VKEY__B8, KM_KBP_VKEY__B9, KM_KBP_VKEY_COLON, KM_KBP_VKEY_EQUAL, KM_KBP_VKEY_COMMA, KM_KBP_VKEY_HYPHEN, KM_KBP_VKEY_PERIOD, KM_KBP_VKEY_SLASH, KM_KBP_VKEY_BKQUOTE, KM_KBP_VKEY__C1, KM_KBP_VKEY__C2, KM_KBP_VKEY__C3, KM_KBP_VKEY__C4, KM_KBP_VKEY__C5, KM_KBP_VKEY__C6, KM_KBP_VKEY__C7, KM_KBP_VKEY__C8, KM_KBP_VKEY__C9, KM_KBP_VKEY__CA, KM_KBP_VKEY__CB, KM_KBP_VKEY__CC, KM_KBP_VKEY__CD, KM_KBP_VKEY__CE, KM_KBP_VKEY__CF, KM_KBP_VKEY__D0, KM_KBP_VKEY__D1, KM_KBP_VKEY__D2, KM_KBP_VKEY__D3, KM_KBP_VKEY__D4, KM_KBP_VKEY__D5, KM_KBP_VKEY__D6, KM_KBP_VKEY__D7, KM_KBP_VKEY__D8, KM_KBP_VKEY__D9, KM_KBP_VKEY__DA, KM_KBP_VKEY_LBRKT, KM_KBP_VKEY_BKSLASH, KM_KBP_VKEY_RBRKT, KM_KBP_VKEY_QUOTE, KM_KBP_VKEY_oDF, KM_KBP_VKEY_oE0, KM_KBP_VKEY_oE1, KM_KBP_VKEY_oE2, // 102nd key on European layouts KM_KBP_VKEY_oE3, KM_KBP_VKEY_oE4, KM_KBP_VKEY__E5, KM_KBP_VKEY_oE6, KM_KBP_VKEY__E7, KM_KBP_VKEY__E8, KM_KBP_VKEY_oE9, KM_KBP_VKEY_oEA, KM_KBP_VKEY_oEB, KM_KBP_VKEY_oEC, KM_KBP_VKEY_oED, KM_KBP_VKEY_oEE, KM_KBP_VKEY_oEF, KM_KBP_VKEY_oF0, KM_KBP_VKEY_oF1, KM_KBP_VKEY_oF2, KM_KBP_VKEY_oF3, KM_KBP_VKEY_oF4, KM_KBP_VKEY_oF5, KM_KBP_VKEY__F6, KM_KBP_VKEY__F7, KM_KBP_VKEY__F8, KM_KBP_VKEY__F9, KM_KBP_VKEY__FA, KM_KBP_VKEY__FB, KM_KBP_VKEY__FC, KM_KBP_VKEY__FD, KM_KBP_VKEY__FE, KM_KBP_VKEY__FF, }; keyman-keyboardprocessor-11.0.101/include/keyman/meson.build000066400000000000000000000013641341344761300240400ustar00rootroot00000000000000# Copyright: © 2018 SIL International. # Description: Cross platform build script to generate installable API header # files with versioning information templated in. # Create Date: 2 Oct 2018 # Authors: Tim Eves (TSE) # History: 6 Oct 2018 - TSE - Move into keyman folder. # ver = lib_version.split('.') cfg = configuration_data() cfg.set('lib_curr', ver[0]) cfg.set('lib_age', ver[1]) cfg.set('lib_rev', ver[2]) configure_file( configuration: cfg, input: 'keyboardprocessor.h.in', output: 'keyboardprocessor.h', ) install_headers(join_paths(meson.current_build_dir(), 'keyboardprocessor.h'), 'keyboardprocessor_vkeys.h', 'keyboardprocessor_bits.h', subdir: 'keyman') keyman-keyboardprocessor-11.0.101/include/meson.build000066400000000000000000000005631341344761300225540ustar00rootroot00000000000000# Copyright: © 2018 SIL International. # Description: Cross platform build script to generate installable API header # files with versioning information templated in. # Create Date: 2 Oct 2018 # Authors: Tim Eves (TSE) # History: 6 Oct 2018 - TSE - Move into keyman folder. # inc = include_directories('.', is_system: true) subdir('keyman') keyman-keyboardprocessor-11.0.101/meson.build000066400000000000000000000012521341344761300211250ustar00rootroot00000000000000# Copyright: © 2018 SIL International. # Description: Cross platform build script to compile libkmnkbp, documentation # and tests. # Create Date: 2 Oct 2018 # Authors: Tim Eves (TSE) # project('keyboardprocessor', 'cpp', 'c', version: '11.0.101', license: 'MIT', default_options : ['buildtype=release', 'cpp_std=c++14']) compiler = meson.get_compiler('cpp') lib_version = '0.0.0' if compiler.get_id() == 'msvc' add_global_arguments('/source-charset:utf-8', language: ['c', 'cpp']) endif py = import('python3') python = py.find_python() subdir('doc') subdir('include') subdir('src') subdir('tests') keyman-keyboardprocessor-11.0.101/python/000077500000000000000000000000001341344761300203045ustar00rootroot00000000000000keyman-keyboardprocessor-11.0.101/python/keyman/000077500000000000000000000000001341344761300215705ustar00rootroot00000000000000keyman-keyboardprocessor-11.0.101/python/keyman/keyboardprocessor/000077500000000000000000000000001341344761300253305ustar00rootroot00000000000000keyman-keyboardprocessor-11.0.101/python/keyman/keyboardprocessor/_api.py000066400000000000000000000305421341344761300266160ustar00rootroot00000000000000# Copyright: © 2018 SIL International. # Description: Lowlevel C style python API. Intended to be wrapped by a more # Pythonic higher level API. # Create Date: 18 Oct 2018 # Authors: Tim Eves (TSE) # import ctypes import ctypes.util import operator import os from enum import auto, IntEnum, IntFlag from ctypes import (c_uint8, c_uint16, c_uint32, c_size_t, c_void_p, c_char_p, Structure, Union, POINTER, CFUNCTYPE) from typing import Any, Tuple CP = c_uint16 USV = c_uint32 VirtualKey = c_uint16 libpath = os.environ.get('PYKMNKBD_LIBRARY_PATH', ctypes.util.find_library("kmnkbp0")) libkbp = ctypes.cdll.LoadLibrary(libpath) # Error handling # ============== class StatusCode(IntEnum): OK = 0 NO_MEM = auto() IO_ERROR = auto() INVALID_ARGUMENT = auto() KEY_ERROR = auto() OS_ERROR = 0x80000000 Status = c_uint32 def __map_oserror(code: Status) -> str: code = StatusCode.OS_ERROR ^ code msg = '{0!s}: OS error code (' + code + '): ' + os.strerror(code) return msg, lambda m: OSError(code, m) __exceptions_map = [ (None, '{0!s}: Success'), (MemoryError, '{0!s}: memory allocation failed.'), (RuntimeError, '{0!s}: IO Error: {1!s}'), (ValueError, '{0!s}: Invalid argument passed.'), (LookupError, '{0!s}: Item does not exist in: {1!s}'), (OSError, __map_oserror)] def status_code(code: Status, func, args): if code == StatusCode.OK: return args exc, msg = __exceptions_map[code] if callable(msg): msg = msg(code) raise exc(msg.format(libkbp._name, *args)) def null_check(code, func, args): if code is not None: return args raise KeyError(args[1] + ': Not found in collection') class Dir(IntFlag): IN = auto() OUT = auto() OPT = auto() def __method(iface: str, method: str, result, *args: Tuple[Any, Dir, str], **kwds): proto = CFUNCTYPE(result, *map(operator.itemgetter(0), args)) params = tuple(a[1:] for a in args) c_name = iface+'_'+method if iface else method f = proto(('km_kbp_' + c_name, libkbp), params) if 'errcheck' in kwds: f.errcheck = kwds.get('errcheck') globals()[c_name] = f # Context processing # ================== Context_p = c_void_p class ContextType(IntEnum): END = 0 CHAR = auto() MARKER = auto() class ContextItem(Structure): class __ContextValue(Union): _fields_ = (('character', USV), ('marker', c_uint32)) _anonymous_ = ('value',) _fields_ = (('type', c_uint8), ('value', __ContextValue)) __method('context_items', 'from_utf16', Status, (c_void_p, Dir.IN, 'text'), (POINTER(POINTER(ContextItem)), Dir.OUT, 'context_items'), errcheck=status_code) __method('context_items', 'to_utf16', c_size_t, (POINTER(ContextItem), Dir.IN, 'context_items'), (c_void_p, Dir.IN | Dir.OPT, 'buffer'), (c_size_t, Dir.IN | Dir.OPT, 'buffer_size')) __method('context_items', 'dispose', None, (POINTER(ContextItem), Dir.IN, 'context_items')) __method('context', 'set', Status, (Context_p, Dir.IN, 'context'), (POINTER(ContextItem), Dir.IN, 'context_items'), errcheck=status_code) __method('context', 'get', POINTER(ContextItem), (Context_p, Dir.IN, 'context')) __method('context', 'clear', None, (Context_p, Dir.IN, 'context')) __method('context', 'length', c_size_t, (Context_p, Dir.IN, 'context')) __method('context', 'append', Status, (Context_p, Dir.IN, 'context'), (POINTER(ContextItem), Dir.IN, 'context_items'), errcheck=status_code) __method('context', 'shrink', Status, (Context_p, Dir.IN, 'context'), (c_size_t, Dir.IN, 'num'), (POINTER(ContextItem), Dir.IN, 'prefix'), errcheck=status_code) class ActionItem(Structure): class __ActionItem(Union): _fields_ = (('marker', c_size_t), ('option', c_char_p), ('character', USV), ('vkey', VirtualKey)) _anonymous_ = ('data',) _fields_ = (('type', c_uint8), ('reserved', c_uint8*3), ('data', __ActionItem)) class ActionType(IntEnum): END = 0 # Marks end of action items list. CHAR = 1 MARKER = 2 # correlates to kmn's "deadkey" markers ALERT = 3 BACK = 4 PERSIST_OPT = 5 RESET_OPT = 6 VKEYDOWN = 7 VKEYUP = 8 VSHIFTDOWN = 9 VSHIFTUP = 10 MAX_TYPE_ID = auto() # Option processing # ================= OptionSet_p = c_void_p class OptionScope(IntEnum): UNKNOWN = auto() KEYBOARD = auto() ENVIRONMENT = auto() class Option(Structure): _fields_ = (('key', c_char_p), ('value', c_char_p), ('scope', c_uint8)) Option.END = Option(None, None) __method('options_set', 'size', c_size_t, (OptionSet_p, Dir.IN, 'opts')) __method('options_set', 'lookup', POINTER(Option), (OptionSet_p, Dir.IN, 'opts'), (c_char_p, Dir.IN, 'key'), errcheck=null_check) __method('options_set', 'update', Status, (OptionSet_p, Dir.IN, 'opts'), (POINTER(Option), Dir.IN, 'new_opts'), errcheck=status_code) __method('options_set', 'to_json', Status, (OptionSet_p, Dir.IN, 'opts'), (c_char_p, Dir.IN | Dir.OPT, 'buffer'), (c_size_t, Dir.IN | Dir.OUT, 'space'), errcheck=status_code) # Keyboards # ========= Keyboard_p = c_void_p class KeyboardAttrs(Structure): _fields_ = (('version_string', c_char_p), ('id', c_char_p), ('folder_path', c_char_p), ('default_options', OptionSet_p)) __method('keyboard', 'load', Status, (c_char_p, Dir.IN, 'path'), (POINTER(Keyboard_p), Dir.OUT, 'kb'), errcheck=status_code) __method('keyboard', 'dispose', None, (Keyboard_p, Dir.IN, 'kb')) __method('keyboard', 'get_attrs', POINTER(KeyboardAttrs), (Keyboard_p, Dir.IN, 'keyboard')) # State processing # ================ State_p = c_void_p __method('state', 'create', Status, (Keyboard_p, Dir.IN, 'keyboard'), (POINTER(Option), Dir.IN, 'env',), (POINTER(State_p), Dir.OUT, 'out'), errcheck=status_code) __method('state', 'clone', Status, (State_p, Dir.IN, 'state'), (POINTER(State_p), Dir.OUT, 'out'), errcheck=status_code) __method('state', 'dispose', None, (State_p, Dir.IN, 'state')) __method('state', 'context', Context_p, (State_p, Dir.IN, 'state')) __method('state', 'options', OptionSet_p, (State_p, Dir.IN, 'state')) __method('state', 'action_items', POINTER(ActionItem), (State_p, Dir.IN, 'state'), (POINTER(c_size_t), Dir.OUT, 'num_items')) __method('state', 'to_json', Status, (State_p, Dir.IN, 'state'), (c_char_p, Dir.IN | Dir.OPT, 'buffer'), (c_size_t, Dir.IN | Dir.OUT, 'space'), errcheck=status_code) # Processor # ========= class Attributes(Structure): _fields_ = (('max_context', c_size_t), ('current', c_uint16), ('revision', c_uint16), ('age', c_uint16), ('technology', c_uint16), ('vendor', c_char_p)) class Tech(IntFlag): UNSPECIFIED = 0 KMN = 1 LDML = 2 __method(None, 'get_engine_attrs', POINTER(Attributes)) __method(None, 'process_event', Status, (State_p, Dir.IN, 'state'), (VirtualKey, Dir.IN, 'vkey'), (c_uint16, Dir.IN, 'modifier_state')) class Modifier(IntFlag): LCTRL = 1 << 0 RCTRL = 1 << 1 LALT = 1 << 2 RALT = 1 << 3 SHIFT = 1 << 4 CTRL = 1 << 5 ALT = 1 << 6 CAPS = 1 << 7 NOCAPS = 1 << 8 NUMLOCK = 1 << 9 NONUMLOCK = 1 << 10 SCROLLOCK = 1 << 11 NOSCROLLOCK = 1 << 12 VIRTUALKEY = 1 << 13 class ModifierMask(IntFlag): ALL = 0x7f ALT_GR_SIM = Modifier.LCTRL | Modifier.LALT CHIRAL = 0x1f IS_CHIRAL = 0x0f NON_CHIRAL = 0x7f CAPS = 0x0300 NUMLOCK = 0x0C00 SCROLLLOCK = 0x3000 class VKey(IntEnum): _00 = auto() LBUTTON = auto() RBUTTON = auto() CANCEL = auto() MBUTTON = auto() _05 = auto() _06 = auto() _07 = auto() BKSP = auto() KTAB = auto() _0A = auto() _0B = auto() KP5 = auto() ENTER = auto() _0E = auto() _0F = auto() SHIFT = auto() CONTROL = auto() ALT = auto() PAUSE = auto() CAPS = auto() _15 = auto() _16 = auto() _17 = auto() _18 = auto() _19 = auto() _1A = auto() ESC = auto() _1C = auto() _1D = auto() _1E = auto() _1F = auto() SPACE = auto() PGUP = auto() PGDN = auto() END = auto() HOME = auto() LEFT = auto() UP = auto() RIGHT = auto() DOWN = auto() SEL = auto() PRINT = auto() EXEC = auto() PRTSCN = auto() INS = auto() DEL = auto() HELP = auto() K0 = auto() K1 = auto() K2 = auto() K3 = auto() K4 = auto() K5 = auto() K6 = auto() K7 = auto() K8 = auto() K9 = auto() _3A = auto() _3B = auto() _3C = auto() _3D = auto() _3E = auto() _3F = auto() _40 = auto() KA = auto() KB = auto() KC = auto() KD = auto() KE = auto() KF = auto() KG = auto() KH = auto() KI = auto() KJ = auto() KK = auto() KL = auto() KM = auto() KN = auto() KO = auto() KP = auto() KQ = auto() KR = auto() KS = auto() KT = auto() KU = auto() KV = auto() KW = auto() KX = auto() KY = auto() KZ = auto() _5B = auto() _5C = auto() _5D = auto() _5E = auto() _5F = auto() NP0 = auto() NP1 = auto() NP2 = auto() NP3 = auto() NP4 = auto() NP5 = auto() NP6 = auto() NP7 = auto() NP8 = auto() NP9 = auto() NPSTAR = auto() NPPLUS = auto() SEPARATOR = auto() NPMINUS = auto() NPDOT = auto() NPSLASH = auto() F1 = auto() F2 = auto() F3 = auto() F4 = auto() F5 = auto() F6 = auto() F7 = auto() F8 = auto() F9 = auto() F10 = auto() F11 = auto() F12 = auto() F13 = auto() F14 = auto() F15 = auto() F16 = auto() F17 = auto() F18 = auto() F19 = auto() F20 = auto() F21 = auto() F22 = auto() F23 = auto() F24 = auto() _88 = auto() _89 = auto() _8A = auto() _8B = auto() _8C = auto() _8D = auto() _8E = auto() _8F = auto() NUMLOCK = auto() SCROLL = auto() _92 = auto() _93 = auto() _94 = auto() _95 = auto() _96 = auto() _97 = auto() _98 = auto() _99 = auto() _9A = auto() _9B = auto() _9C = auto() _9D = auto() _9E = auto() _9F = auto() _A0 = auto() _A1 = auto() _A2 = auto() _A3 = auto() _A4 = auto() _A5 = auto() _A6 = auto() _A7 = auto() _A8 = auto() _A9 = auto() _AA = auto() _AB = auto() _AC = auto() _AD = auto() _AE = auto() _AF = auto() _B0 = auto() _B1 = auto() _B2 = auto() _B3 = auto() _B4 = auto() _B5 = auto() _B6 = auto() _B7 = auto() _B8 = auto() _B9 = auto() COLON = auto() EQUAL = auto() COMMA = auto() HYPHEN = auto() PERIOD = auto() SLASH = auto() BKQUOTE = auto() _C1 = auto() _C2 = auto() _C3 = auto() _C4 = auto() _C5 = auto() _C6 = auto() _C7 = auto() _C8 = auto() _C9 = auto() _CA = auto() _CB = auto() _CC = auto() _CD = auto() _CE = auto() _CF = auto() _D0 = auto() _D1 = auto() _D2 = auto() _D3 = auto() _D4 = auto() _D5 = auto() _D6 = auto() _D7 = auto() _D8 = auto() _D9 = auto() _DA = auto() LBRKT = auto() BKSLASH = auto() RBRKT = auto() QUOTE = auto() oDF = auto() oE0 = auto() oE1 = auto() oE2 = auto() oE3 = auto() oE4 = auto() _E5 = auto() oE6 = auto() _E7 = auto() _E8 = auto() oE9 = auto() oEA = auto() oEB = auto() oEC = auto() oED = auto() oEE = auto() oEF = auto() oF0 = auto() oF1 = auto() oF2 = auto() oF3 = auto() oF4 = auto() oF5 = auto() _F6 = auto() _F7 = auto() _F8 = auto() _F9 = auto() _FA = auto() _FB = auto() _FC = auto() _FD = auto() _FE = auto() _FF = auto() keyman-keyboardprocessor-11.0.101/python/keyman/keyboardprocessor/api.py000066400000000000000000000041301341344761300264510ustar00rootroot00000000000000import pathlib from typing import NamedTuple, NewType, Tuple, List, Union from enum import Enum from collections.abc import Sequence, Mapping USV = int Marker = int VirtualKey = int class Context(Sequence): Item = Union[USV, Marker] def __init__(initial: str): pass def __del__(self): pass def __str__(self): pass def set(self, ctxt: List[Item]): self.clear() self.apped(ctxt) def clear(self): pass def __getitem__(self, key: int) -> Item: pass def __len__(self): pass def append(self, ctxt: List[Item]): pass def delete(self, remove_n: int, prefix: List[Item]): pass Option = Tuple[str, str] class OptionSet(Mapping): def __getitem__(self, key: str) -> Option: pass def __iter__(self): pass def __len__(self): pass def __str__(self): pass class Keyboard(NamedTuple('__kb_attrs', version=str, id=str, folder_path=pathlib.Path, default_options=OptionSet)): def __new__(cls, _): return super(Keyboard, cls).__new__(cls, *[None]*4) def __init__(self, kb_path: pathlib.Path): pass def __del__(self): pass class Action: VKeyDown = NewType('Action.VirtualKey', VirtualKey) # VKeyUp = VirtualKey # VShiftDown = VirtualKey # VShiftUp = VirtualKey # Char = int # Marker = int # Bell = NewType('Bell', None) # Back = NewType('Back', None) # PersistOpt = str # ResetOpt = str ActionList = List[Action] class State: def __init__(self, kb: Keyboard, env: OptionSet): pass def __del__(self): pass @property def flags(self) -> int: pass @property def context(self) -> Context: pass @property def environment(self) -> OptionSet: pass @property def options(self) -> OptionSet: pass def indentify_option_src(opt: Option): pass def process_event(vk: VirtualKey, modifier_state, state: State, acts: ActionList): pass keyman-keyboardprocessor-11.0.101/src/000077500000000000000000000000001341344761300175525ustar00rootroot00000000000000keyman-keyboardprocessor-11.0.101/src/context.hpp000066400000000000000000000021671341344761300217550ustar00rootroot00000000000000/* Copyright: © 2018 SIL International. Description: Internal context class and adaptor class for the API. Create Date: 2 Oct 2018 Authors: Tim Eves (TSE) History: 2 Oct 2018 - TSE - Refactored out of km_kbp_context_api.cpp */ #pragma once #include #include #include // Forward declarations class json; namespace km { namespace kbp { // This will likely be replaced with a class implementing a more space // efficient data structure such as a ring buffer or bounded queue. class context: public std::list { public: void push_character(km_kbp_usv); void push_marker(uint32_t); }; inline void context::push_character(km_kbp_usv usv) { emplace_back(km_kbp_context_item { KM_KBP_CT_CHAR, {0,}, {usv} }); } inline void context::push_marker(uint32_t marker) { emplace_back(km_kbp_context_item { KM_KBP_CT_MARKER, {0,}, {marker} }); } } // namespace kbp } // namespace km json & operator << (json &, km::kbp::context const &); json & operator << (json &, km_kbp_context_item const &); struct km_kbp_context : public km::kbp::context { }; keyman-keyboardprocessor-11.0.101/src/json.cpp000066400000000000000000000067211341344761300212350ustar00rootroot00000000000000/* Copyright: © 2011,2018 SIL International. Description: JSON pretty printer for dumping debug/diagnostic data structure. Create Date: 15 Dec 2011 Authors: Tim Eves (TSE) History: 28 Sep 2018 - TSE - Imported from graphite2 project. - TSE - Refactored to use C++ std::ostream. 25 Oct 2018 - TSE - Relicensed under the MIT license for inclusion in the Keyman project. */ #include #include #include #include "json.hpp" #if defined(_MSC_VER) #define FORMAT_INTMAX "%lli" #define FORMAT_UINTMAX "%llu" #else #define FORMAT_INTMAX "%ji" #define FORMAT_UINTMAX "%ju" #endif namespace { enum { seq = ',', obj='}', member=':', empty_obj='{', arr=']', empty_arr='[' }; } const std::nullptr_t json::null = nullptr; inline void json::context(const char current) throw() { _stream << *_context; indent(); *_context = current; } void json::indent(const int d) throw() { if (*_context == member || (_flatten && _flatten < _context)) _stream.put(' '); else _stream << std::endl << std::setw(4*int(_context - _contexts + d)) << ""; } inline void json::push_context(const char prefix, const char suffix) throw() { assert(_context - _contexts < ptrdiff_t(sizeof _contexts)); if (_context == _contexts) *_context = suffix; else context(suffix); *++_context = prefix; } void json::pop_context() throw() { assert(_context > _contexts); if (*_context == seq) indent(-1); else _stream.put(*_context); _stream.put(*--_context); if (_context == _contexts) _stream << std::endl; _stream.flush(); if (_flatten >= _context) _flatten = 0; *_context = seq; } // These four functions cannot be inlined as pointers to these // functions are needed for operator << (_context_t) to work. void json::flat(json & j) throw() { if (!j._flatten) j._flatten = j._context; } void json::close(json & j) throw() { j.pop_context(); } void json::object(json & j) throw() { j.push_context('{', '}'); } void json::array(json & j) throw() { j.push_context('[', ']'); } void json::item(json & j) throw() { while (j._context > j._contexts+1 && j._context[-1] != arr) j.pop_context(); } json & json::operator << (json::string s) throw() { const char ctxt = _context[-1] == obj ? *_context == member ? seq : member : seq; context(ctxt); _stream << '"' << s << '"'; if (ctxt == member) _stream.put(' '); return *this; } json & json::operator << (json::number f) throw() { context(seq); if (std::numeric_limits::infinity() == f) _stream << "Infinity"; else if (-std::numeric_limits::infinity() == f) _stream << "-Infinity"; else if (std::numeric_limits::quiet_NaN() == f || std::numeric_limits::signaling_NaN() == f) _stream << "NaN"; else _stream << f; return *this; } json & json::operator << (json::integer d) throw() { context(seq); _stream << intmax_t(d); return *this; } json & json::operator << (json::integer_u d) throw(){ context(seq); _stream << uintmax_t(d); return *this; } json & json::operator << (json::boolean b) throw() { context(seq); _stream << (b ? "true" : "false"); return *this; } json & json::operator << (std::nullptr_t) throw() { context(seq); _stream << "null"; return *this; } keyman-keyboardprocessor-11.0.101/src/json.hpp000066400000000000000000000110661341344761300212400ustar00rootroot00000000000000/* Copyright: © 2011,2018 SIL International. Description: JSON pretty printer for dumping debug/diagnostic internal state information. Create Date: 15 Dec 2011 Authors: Tim Eves (TSE) History: 28 Sep 2018 - TSE - Imported from graphite2 project. - TSE - Refactored to use C++ std::ostream. 25 Oct 2018 - TSE - Relicensed under the MIT license for inclusion in the Keyman project. */ #pragma once #include #include #include #include "utfcodec.hpp" class json { // Prevent copying json(const json &); json & operator = (const json &); typedef void (*_context_t)(json &); std::ostream& _stream; char _contexts[128], // context stack * _context, // current context (top of stack) * _flatten; // if !0 points to context above which // pretty printed output should occur. std::vector _env; void context(const char current) throw(); void indent(const int d=0) throw(); void push_context(const char, const char) throw(); void pop_context() throw(); public: class closer; using string = const char *; using number = double; enum class integer : std::intmax_t {}; enum class integer_u : std::uintmax_t {}; using boolean = bool; static const std::nullptr_t null; void setenv(unsigned int index, void *val) { _env.reserve(index + 1); if (index >= _env.size()) _env.insert(_env.end(), _env.size() - index + 1, 0); _env[index] = val; } void *getenv(unsigned int index) const { return _env[index]; } const std::vector &getenvs() const { return _env; } static void flat(json &) throw(); static void close(json &) throw(); static void object(json &) throw(); static void array(json &) throw(); static void item(json &) throw(); json(std::ostream& stream) throw(); ~json() throw (); auto & stream() const throw(); json & operator << (string) throw(); json & operator << (number) throw(); json & operator << (integer) throw(); json & operator << (integer_u) throw(); json & operator << (boolean) throw(); json & operator << (std::nullptr_t) throw(); json & operator << (_context_t) throw(); operator bool() const throw(); bool good() const throw(); bool eof() const throw(); }; class json::closer { // Prevent copying. closer(const closer &); closer & operator = (const closer &); json * const _j; public: closer(json * const j) : _j(j) {} ~closer() throw() { if (_j) *_j << close; } }; inline json::json(std::ostream& s) throw() : _stream(s), _context(_contexts), _flatten(0) { if (_stream.good()) _stream.flush(); } inline json::~json() throw () { while (_context > _contexts) pop_context(); } inline auto & json::stream() const throw() { return _stream; } inline json & json::operator << (json::_context_t ctxt) throw() { ctxt(*this); return *this; } template inline json & operator << (json & j, std::basic_string const & s) throw() { return j << json::string(convert(s).c_str()); } template inline json & operator << (json & j, C const * s) throw() { return j << json::string(convert(s).c_str()); } inline json & operator << (json & j, signed char d) throw() { return j << json::integer(d); } inline json & operator << (json & j, unsigned char d) throw() { return j << json::integer_u(d); } inline json & operator << (json & j, short int d) throw() { return j << json::integer(d); } inline json & operator << (json & j, unsigned short int d) throw() { return j << json::integer_u(d); } inline json & operator << (json & j, int d) throw() { return j << json::integer(d); } inline json & operator << (json & j, unsigned int d) throw() { return j << json::integer_u(d); } inline json & operator << (json & j, long int d) throw() { return j << json::integer(d); } inline json & operator << (json & j, unsigned long int d) throw() { return j << json::integer_u(d); } inline json & operator << (json & j, long long int d) throw() { return j << json::integer(d); } inline json & operator << (json & j, unsigned long long int d) throw() { return j << json::integer_u(d); } inline json::operator bool() const throw() { return good(); } inline bool json::good() const throw() { return _stream.good(); } inline bool json::eof() const throw() { return _stream.eof(); } keyman-keyboardprocessor-11.0.101/src/keyboard.cpp000066400000000000000000000032761341344761300220660ustar00rootroot00000000000000/* Copyright: © 2018 SIL International. Description: Internal keyboard class and adaptor class for the API. Create Date: 2 Oct 2018 Authors: Tim Eves (TSE) History: 7 Oct 2018 - TSE - Refactored out of km_kbp_keyboard_api.cpp */ #include "keyboard.hpp" #include "json.hpp" using namespace km::kbp; inline void keyboard_attributes::render() { // Make attributes point to the stored values above. id = _keyboard_id.c_str(); version_string = _version_string.c_str(); folder_path = _folder_path.c_str(); default_options = _default_opts.data(); } keyboard_attributes::keyboard_attributes(std::u16string const & kbid, std::u16string const & version, path_type const & path, options_store const &opts) : _keyboard_id(kbid), _version_string(version), _folder_path(path), _default_opts(opts) { // Ensure that the default_options array will be properly terminated. _default_opts.emplace_back(); render(); } keyboard_attributes::keyboard_attributes(keyboard_attributes &&rhs) : _keyboard_id(std::move(rhs._keyboard_id)), _version_string(std::move(rhs._version_string)), _folder_path(std::move(rhs._folder_path)), _default_opts(std::move(rhs._default_opts)) { rhs.id = rhs.version_string = nullptr; render(); } keyboard_attributes & keyboard_attributes::operator = (keyboard_attributes &&rhs) { return *new (this) keyboard_attributes(std::move(rhs)); } json & km::kbp::operator << (json & j, km::kbp::keyboard_attributes const & kb) { j << json::object << "id" << kb.id << "folder" << kb._folder_path << "version" << kb.version_string << "rules" << json::array << json::close; return j << json::close; } keyman-keyboardprocessor-11.0.101/src/keyboard.hpp000066400000000000000000000033521341344761300220660ustar00rootroot00000000000000/* Copyright: © 2018 SIL International. Description: Internal keyboard class and adaptor class for the API. Create Date: 2 Oct 2018 Authors: Tim Eves (TSE) History: 2 Oct 2018 - TSE - Refactored out of km_kbp_keyboard_api.cpp */ #pragma once #include #include #include #include "option.hpp" #include "path.hpp" // Forward declarations class json; namespace km { namespace kbp { class keyboard_attributes : public km_kbp_keyboard_attrs { std::u16string _keyboard_id; std::u16string _version_string; kbp::path _folder_path; std::vector