From fe0af9d215088021e2c2a650486fc928787416f5 Mon Sep 17 00:00:00 2001 From: Dannii Willis Date: Sun, 4 Feb 2024 10:58:09 +1000 Subject: [PATCH] A few small things I noticed while working on remglk-rs --- docs/glkapi-differences-c-api.md | 57 ++++++++++++++++++++++++++++++++ src/glkapi/glkapi.ts | 6 ++-- src/glkapi/windows.ts | 4 ++- 3 files changed, 63 insertions(+), 4 deletions(-) create mode 100644 docs/glkapi-differences-c-api.md diff --git a/docs/glkapi-differences-c-api.md b/docs/glkapi-differences-c-api.md new file mode 100644 index 0000000..97a4e69 --- /dev/null +++ b/docs/glkapi-differences-c-api.md @@ -0,0 +1,57 @@ +Differences between GlkApi and the C Glk API +============================================ + +There are a few differences between GlkApi and the [C Glk API](https://eblong.com/zarf/glk/Glk-Spec-075.html). The GlkApi versions are here described as Typescript functions. + +Array parameters +---------------- + +When a function needs an array the C API takes a pointer and a length. One example is `glk_request_line_event`. + +```c +void glk_request_line_event(winid_t win, char *buf, glui32 maxlen, glui32 initlen); +``` + +GlkApi instead takes only one parameter, which is an array of maxlen length. This can be a typed array, or a normal array. + +```ts +type GlkByteArray = Array | Uint8Array +glk_request_line_event(win: GlkWindow, buf: GlkByteArray, initlen?: number): void +``` + +String functions +---------------- + +String functions like `glk_put_string` go one step further, and need the string array to be pre-converted to a JS string. + +```c +void glk_put_string(char *s); +``` + +```ts +glk_put_string(val: string): void +``` + +Structs and out parameters +-------------------------- + +The C API naturally support structs, as well as out parameters: + +```c +void glk_current_time(glktimeval_t *time); +void glk_window_get_size(winid_t win, glui32 *widthptr, glui32 *heightptr); +``` + +The GlkApi versions take either a `RefStruct` or a `RefBox`. You can read the fields of a `RefStruct` with `get_field(index: number)`, and the value of a `RefBox` with `get_value()`. + +```ts +glk_current_time(struct: RefStruct): void +glk_window_get_size(win: GlkWindow, width?: RefBox, height?: RefBox): void, +``` + +`glk_fileref_create_by_prompt` +---------------------------- + +The C API version of `glk_fileref_create_by_prompt` is synchronous: you call it, and (from the perspective of your code) immediately get back the response. + +The GlkApi version is asynchronous: control will be passed to GlkOte, and once the file reference has been created `VM.resume` will be called again, with the fref as the first (and only) argument. If the VM uses GiDispa then the fref is also returned through it. The `VM.resume` function must be written such that it can handle being called after either `glk_fileref_create_by_prompt` or `glk_select`. \ No newline at end of file diff --git a/src/glkapi/glkapi.ts b/src/glkapi/glkapi.ts index e96b870..b2fec0d 100644 --- a/src/glkapi/glkapi.ts +++ b/src/glkapi/glkapi.ts @@ -354,14 +354,14 @@ export class AsyncGlk implements Interface.GlkApi { if (!win) { throw new Error('Invalid Window') } - if (win.input.type !== 'line' || (win.type !== 'buffer' && win.type !== 'grid')) { + if (win.input.type !== 'line') { if (ev) { set_event(ev) } return } - this.handle_line_input(win, this.partial_inputs?.[win.disprock] ?? '', ev) + this.handle_line_input(win as TextWindow, this.partial_inputs?.[win.disprock] ?? '', ev) } glk_cancel_mouse_event(win: Window) { @@ -1071,7 +1071,7 @@ export class AsyncGlk implements Interface.GlkApi { stylevalue = (1 + value * 0.1) + 'em' } if (hint === stylehint_Weight) { - stylevalue = weights[value] + stylevalue = weights[value + 1] } if (hint === stylehint_Oblique) { stylevalue = value ? 'italic' : 'normal' diff --git a/src/glkapi/windows.ts b/src/glkapi/windows.ts index 15ab818..02e49aa 100644 --- a/src/glkapi/windows.ts +++ b/src/glkapi/windows.ts @@ -9,6 +9,8 @@ https://github.com/curiousdannii/asyncglk */ +import {cloneDeep} from 'lodash-es' + import {BufferWindowImage, ContentUpdate, GraphicsWindowOperation, InputUpdate, TextRun, WindowStyles, WindowUpdate as SizeUpdate} from '../common/protocol.js' import {winmethod_Above, winmethod_BorderMask, winmethod_DirMask, winmethod_DivisionMask, winmethod_Fixed, winmethod_Left, winmethod_Right, wintype_Blank, wintype_Graphics, wintype_Pair, wintype_TextBuffer, wintype_TextGrid} from './constants.js' @@ -109,7 +111,7 @@ export abstract class TextWindow extends WindowBase { constructor(rock: number, stylehints: WindowStyles) { super(rock) - this.stylehints = stylehints + this.stylehints = cloneDeep(stylehints) } update(): WindowUpdate {